blob: 3c666dcbeb44ba01f9669c105b64f0884b826f74 [file] [log] [blame]
Guy Schalnat6d764711995-12-19 03:22:19 -06001
2/* pngpread.c - read a png file in push mode
Glenn Randers-Pehrsonb6ce43d1998-01-01 07:13:13 -06003 *
Glenn Randers-Pehrsonbb5cb142011-09-22 12:41:58 -05004 * Last changed in libpng 1.5.6 [(PENDING RELEASE)]
Glenn Randers-Pehrson64b863c2011-01-04 09:57:06 -06005 * Copyright (c) 1998-2011 Glenn Randers-Pehrson
Glenn Randers-Pehrsond4366722000-06-04 14:29:29 -05006 * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
7 * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
Glenn Randers-Pehrson3e61d792009-06-24 09:31:28 -05008 *
Glenn Randers-Pehrsonbfbf8652009-06-26 21:46:52 -05009 * This code is released under the libpng license.
Glenn Randers-Pehrsonc332bbc2009-06-25 13:43:50 -050010 * For conditions of distribution and use, see the disclaimer
Glenn Randers-Pehrson037023b2009-06-24 10:27:36 -050011 * and license in png.h
Glenn Randers-Pehrsonb6ce43d1998-01-01 07:13:13 -060012 */
Guy Schalnat6d764711995-12-19 03:22:19 -060013
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -050014#include "pngpriv.h"
Guy Schalnat4ee97b01996-01-16 01:51:56 -060015
Glenn Randers-Pehrsonc3cd22b2010-03-08 21:10:25 -060016#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
17
Glenn Randers-Pehrson4bb4d012009-05-20 12:45:29 -050018/* Push model modes */
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -060019#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
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -050029void PNGAPI
Andreas Dilger02ad0ef1997-01-17 01:34:35 -060030png_process_data(png_structp png_ptr, png_infop info_ptr,
Glenn Randers-Pehrson262d0ff2010-03-03 07:06:54 -060031 png_bytep buffer, png_size_t buffer_size)
Guy Schalnat6d764711995-12-19 03:22:19 -060032{
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -050033 if (png_ptr == NULL || info_ptr == NULL)
34 return;
35
Guy Schalnatb2e01bd1996-01-26 01:38:47 -060036 png_push_restore_buffer(png_ptr, buffer, buffer_size);
Guy Schalnat6d764711995-12-19 03:22:19 -060037
Guy Schalnatb2e01bd1996-01-26 01:38:47 -060038 while (png_ptr->buffer_size)
39 {
Andreas Dilger02ad0ef1997-01-17 01:34:35 -060040 png_process_some_data(png_ptr, info_ptr);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -060041 }
Guy Schalnat6d764711995-12-19 03:22:19 -060042}
43
John Bowler0a5c9c02011-01-22 17:36:34 -060044png_size_t PNGAPI
45png_process_data_pause(png_structp png_ptr, int save)
46{
47 if (png_ptr != NULL)
48 {
49 /* It's easiest for the caller if we do the save, then the caller doesn't
50 * have to supply the same data again:
51 */
52 if (save)
53 png_push_save_buffer(png_ptr);
54 else
55 {
56 /* This includes any pending saved bytes: */
57 png_size_t remaining = png_ptr->buffer_size;
58 png_ptr->buffer_size = 0;
59
60 /* So subtract the saved buffer size, unless all the data
61 * is actually 'saved', in which case we just return 0
62 */
63 if (png_ptr->save_buffer_size < remaining)
64 return remaining - png_ptr->save_buffer_size;
65 }
66 }
67
68 return 0;
69}
70
71png_uint_32 PNGAPI
72png_process_data_skip(png_structp png_ptr)
73{
John Bowlerfca50df2011-01-28 06:34:02 -060074 png_uint_32 remaining = 0;
John Bowler0a5c9c02011-01-22 17:36:34 -060075
76 if (png_ptr != NULL && png_ptr->process_mode == PNG_SKIP_MODE &&
77 png_ptr->skip_length > 0)
78 {
79 /* At the end of png_process_data the buffer size must be 0 (see the loop
80 * above) so we can detect a broken call here:
81 */
82 if (png_ptr->buffer_size != 0)
83 png_error(png_ptr,
84 "png_process_data_skip called inside png_process_data");
85
86 /* If is impossible for there to be a saved buffer at this point -
87 * otherwise we could not be in SKIP mode. This will also happen if
88 * png_process_skip is called inside png_process_data (but only very
89 * rarely.)
90 */
91 if (png_ptr->save_buffer_size != 0)
92 png_error(png_ptr, "png_process_data_skip called with saved data");
93
94 remaining = png_ptr->skip_length;
95 png_ptr->skip_length = 0;
96 png_ptr->process_mode = PNG_READ_CHUNK_MODE;
97 }
98
99 return remaining;
100}
101
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600102/* What we do with the incoming data depends on what we were previously
103 * doing before we ran out of data...
104 */
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -0500105void /* PRIVATE */
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600106png_process_some_data(png_structp png_ptr, png_infop info_ptr)
Guy Schalnat6d764711995-12-19 03:22:19 -0600107{
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500108 if (png_ptr == NULL)
109 return;
110
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600111 switch (png_ptr->process_mode)
112 {
113 case PNG_READ_SIG_MODE:
114 {
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600115 png_push_read_sig(png_ptr, info_ptr);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600116 break;
117 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500118
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600119 case PNG_READ_CHUNK_MODE:
120 {
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600121 png_push_read_chunk(png_ptr, info_ptr);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600122 break;
123 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500124
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600125 case PNG_READ_IDAT_MODE:
126 {
Guy Schalnate5a37791996-06-05 15:50:50 -0500127 png_push_read_IDAT(png_ptr);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600128 break;
129 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500130
Glenn Randers-Pehrsone26c0952009-09-23 11:22:08 -0500131#ifdef PNG_READ_tEXt_SUPPORTED
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600132 case PNG_READ_tEXt_MODE:
133 {
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600134 png_push_read_tEXt(png_ptr, info_ptr);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600135 break;
136 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500137
Guy Schalnat6d764711995-12-19 03:22:19 -0600138#endif
Glenn Randers-Pehrsone26c0952009-09-23 11:22:08 -0500139#ifdef PNG_READ_zTXt_SUPPORTED
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600140 case PNG_READ_zTXt_MODE:
141 {
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600142 png_push_read_zTXt(png_ptr, info_ptr);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600143 break;
144 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500145
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600146#endif
Glenn Randers-Pehrsone26c0952009-09-23 11:22:08 -0500147#ifdef PNG_READ_iTXt_SUPPORTED
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -0600148 case PNG_READ_iTXt_MODE:
149 {
150 png_push_read_iTXt(png_ptr, info_ptr);
151 break;
152 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500153
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -0600154#endif
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600155 case PNG_SKIP_MODE:
156 {
Andreas Dilger47a0c421997-05-16 02:46:07 -0500157 png_push_crc_finish(png_ptr);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600158 break;
159 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500160
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600161 default:
162 {
163 png_ptr->buffer_size = 0;
164 break;
165 }
166 }
Guy Schalnat6d764711995-12-19 03:22:19 -0600167}
168
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600169/* Read any remaining signature bytes from the stream and compare them with
170 * the correct PNG signature. It is possible that this routine is called
Glenn Randers-Pehrson345bc271998-06-14 14:43:31 -0500171 * with bytes already read from the signature, either because they have been
172 * checked by the calling application, or because of multiple calls to this
173 * routine.
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600174 */
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -0500175void /* PRIVATE */
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600176png_push_read_sig(png_structp png_ptr, png_infop info_ptr)
Guy Schalnat6d764711995-12-19 03:22:19 -0600177{
Andreas Dilger47a0c421997-05-16 02:46:07 -0500178 png_size_t num_checked = png_ptr->sig_bytes,
179 num_to_check = 8 - num_checked;
Guy Schalnat6d764711995-12-19 03:22:19 -0600180
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600181 if (png_ptr->buffer_size < num_to_check)
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600182 {
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600183 num_to_check = png_ptr->buffer_size;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600184 }
Guy Schalnat6d764711995-12-19 03:22:19 -0600185
Glenn Randers-Pehrson5c6aeb21998-12-29 11:47:59 -0600186 png_push_fill_buffer(png_ptr, &(info_ptr->signature[num_checked]),
Glenn Randers-Pehrson262d0ff2010-03-03 07:06:54 -0600187 num_to_check);
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -0500188 png_ptr->sig_bytes = (png_byte)(png_ptr->sig_bytes + num_to_check);
Guy Schalnat6d764711995-12-19 03:22:19 -0600189
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600190 if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check))
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600191 {
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600192 if (num_checked < 4 &&
193 png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4))
194 png_error(png_ptr, "Not a PNG file");
Glenn Randers-Pehrsonf24daf22010-05-06 09:44:04 -0500195
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600196 else
197 png_error(png_ptr, "PNG file corrupted by ASCII conversion");
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600198 }
199 else
200 {
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600201 if (png_ptr->sig_bytes >= 8)
202 {
203 png_ptr->process_mode = PNG_READ_CHUNK_MODE;
204 }
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600205 }
Guy Schalnat6d764711995-12-19 03:22:19 -0600206}
207
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -0500208void /* PRIVATE */
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600209png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
Guy Schalnat6d764711995-12-19 03:22:19 -0600210{
Glenn Randers-Pehrsonbb5cb142011-09-22 12:41:58 -0500211 png_uint_32 chunk_name;
Glenn Randers-Pehrsona2567be2009-10-19 20:31:31 -0500212
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600213 /* First we make sure we have enough data for the 4 byte chunk name
Glenn Randers-Pehrsonb6ce43d1998-01-01 07:13:13 -0600214 * and the 4 byte chunk length before proceeding with decoding the
215 * chunk data. To fully decode each of these chunks, we also make
216 * sure we have enough data in the buffer for the 4 byte CRC at the
217 * end of every chunk (except IDAT, which is handled separately).
218 */
Glenn Randers-Pehrson5379b241999-11-27 10:22:33 -0600219 if (!(png_ptr->mode & PNG_HAVE_CHUNK_HEADER))
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600220 {
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600221 png_byte chunk_length[4];
Glenn Randers-Pehrsonbb5cb142011-09-22 12:41:58 -0500222 png_byte chunk_tag[4];
Guy Schalnat6d764711995-12-19 03:22:19 -0600223
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600224 if (png_ptr->buffer_size < 8)
225 {
226 png_push_save_buffer(png_ptr);
227 return;
228 }
Guy Schalnat6d764711995-12-19 03:22:19 -0600229
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600230 png_push_fill_buffer(png_ptr, chunk_length, 4);
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -0500231 png_ptr->push_length = png_get_uint_31(png_ptr, chunk_length);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600232 png_reset_crc(png_ptr);
Glenn Randers-Pehrsonbb5cb142011-09-22 12:41:58 -0500233 png_crc_read(png_ptr, chunk_tag, 4);
234 png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(chunk_tag);
Glenn Randers-Pehrsoneb580912008-07-30 14:47:09 -0500235 png_check_chunk_name(png_ptr, png_ptr->chunk_name);
Glenn Randers-Pehrson5379b241999-11-27 10:22:33 -0600236 png_ptr->mode |= PNG_HAVE_CHUNK_HEADER;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600237 }
Guy Schalnat6d764711995-12-19 03:22:19 -0600238
Glenn Randers-Pehrsonbb5cb142011-09-22 12:41:58 -0500239 chunk_name = png_ptr->chunk_name;
240
241 if (chunk_name == png_IDAT)
Glenn Randers-Pehrson262d0ff2010-03-03 07:06:54 -0600242 if (png_ptr->mode & PNG_AFTER_IDAT)
243 png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT;
Glenn Randers-Pehrson6bc53be2006-06-16 07:52:03 -0500244
Glenn Randers-Pehrsonbb5cb142011-09-22 12:41:58 -0500245 if (chunk_name == png_IHDR)
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600246 {
Glenn Randers-Pehrsoneb580912008-07-30 14:47:09 -0500247 if (png_ptr->push_length != 13)
248 png_error(png_ptr, "Invalid IHDR length");
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500249
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500250 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
251 {
252 png_push_save_buffer(png_ptr);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600253 return;
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500254 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500255
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600256 png_handle_IHDR(png_ptr, info_ptr, png_ptr->push_length);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600257 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500258
Glenn Randers-Pehrsonbb5cb142011-09-22 12:41:58 -0500259 else if (chunk_name == png_IEND)
Glenn Randers-Pehrsond029a752004-08-09 21:50:32 -0500260 {
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500261 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
262 {
263 png_push_save_buffer(png_ptr);
Glenn Randers-Pehrsond029a752004-08-09 21:50:32 -0500264 return;
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500265 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500266
Glenn Randers-Pehrsond029a752004-08-09 21:50:32 -0500267 png_handle_IEND(png_ptr, info_ptr, png_ptr->push_length);
268
269 png_ptr->process_mode = PNG_READ_DONE_MODE;
270 png_push_have_end(png_ptr, info_ptr);
271 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500272
Glenn Randers-Pehrsond029a752004-08-09 21:50:32 -0500273#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
Glenn Randers-Pehrsonbb5cb142011-09-22 12:41:58 -0500274 else if (png_chunk_unknown_handling(png_ptr, chunk_name))
Glenn Randers-Pehrsond029a752004-08-09 21:50:32 -0500275 {
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500276 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
277 {
278 png_push_save_buffer(png_ptr);
Glenn Randers-Pehrsond029a752004-08-09 21:50:32 -0500279 return;
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500280 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500281
Glenn Randers-Pehrsonbb5cb142011-09-22 12:41:58 -0500282 if (chunk_name == png_IDAT)
Glenn Randers-Pehrsond029a752004-08-09 21:50:32 -0500283 png_ptr->mode |= PNG_HAVE_IDAT;
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500284
Glenn Randers-Pehrsond029a752004-08-09 21:50:32 -0500285 png_handle_unknown(png_ptr, info_ptr, png_ptr->push_length);
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500286
Glenn Randers-Pehrsonbb5cb142011-09-22 12:41:58 -0500287 if (chunk_name == png_PLTE)
Glenn Randers-Pehrsond029a752004-08-09 21:50:32 -0500288 png_ptr->mode |= PNG_HAVE_PLTE;
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500289
Glenn Randers-Pehrsonbb5cb142011-09-22 12:41:58 -0500290 else if (chunk_name == png_IDAT)
Glenn Randers-Pehrsond029a752004-08-09 21:50:32 -0500291 {
292 if (!(png_ptr->mode & PNG_HAVE_IHDR))
293 png_error(png_ptr, "Missing IHDR before IDAT");
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500294
Glenn Randers-Pehrsond029a752004-08-09 21:50:32 -0500295 else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
Glenn Randers-Pehrson262d0ff2010-03-03 07:06:54 -0600296 !(png_ptr->mode & PNG_HAVE_PLTE))
Glenn Randers-Pehrsond029a752004-08-09 21:50:32 -0500297 png_error(png_ptr, "Missing PLTE before IDAT");
298 }
299 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500300
Glenn Randers-Pehrsond029a752004-08-09 21:50:32 -0500301#endif
Glenn Randers-Pehrsonbb5cb142011-09-22 12:41:58 -0500302 else if (chunk_name == png_PLTE)
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600303 {
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500304 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
305 {
306 png_push_save_buffer(png_ptr);
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600307 return;
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500308 }
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600309 png_handle_PLTE(png_ptr, info_ptr, png_ptr->push_length);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600310 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500311
Glenn Randers-Pehrsonbb5cb142011-09-22 12:41:58 -0500312 else if (chunk_name == png_IDAT)
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600313 {
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600314 /* If we reach an IDAT chunk, this means we have read all of the
Glenn Randers-Pehrsonb6ce43d1998-01-01 07:13:13 -0600315 * header chunks, and we can start reading the image (or if this
316 * is called after the image has been read - we have an error).
317 */
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500318
319 if (!(png_ptr->mode & PNG_HAVE_IHDR))
320 png_error(png_ptr, "Missing IHDR before IDAT");
321
322 else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
323 !(png_ptr->mode & PNG_HAVE_PLTE))
324 png_error(png_ptr, "Missing PLTE before IDAT");
Glenn Randers-Pehrson73d57cb2002-03-25 18:49:08 -0600325
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600326 if (png_ptr->mode & PNG_HAVE_IDAT)
327 {
Glenn Randers-Pehrson6bc53be2006-06-16 07:52:03 -0500328 if (!(png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT))
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500329 if (png_ptr->push_length == 0)
330 return;
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600331
332 if (png_ptr->mode & PNG_AFTER_IDAT)
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -0500333 png_benign_error(png_ptr, "Too many IDATs found");
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600334 }
335
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600336 png_ptr->idat_size = png_ptr->push_length;
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600337 png_ptr->mode |= PNG_HAVE_IDAT;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600338 png_ptr->process_mode = PNG_READ_IDAT_MODE;
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600339 png_push_have_info(png_ptr, info_ptr);
Glenn Randers-Pehrsone3f3c4e2010-02-07 18:08:50 -0600340 png_ptr->zstream.avail_out =
341 (uInt) PNG_ROWBYTES(png_ptr->pixel_depth,
342 png_ptr->iwidth) + 1;
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600343 png_ptr->zstream.next_out = png_ptr->row_buf;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600344 return;
345 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500346
Glenn Randers-Pehrsone26c0952009-09-23 11:22:08 -0500347#ifdef PNG_READ_gAMA_SUPPORTED
Glenn Randers-Pehrsonbb5cb142011-09-22 12:41:58 -0500348 else if (png_ptr->chunk_name == png_gAMA)
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600349 {
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500350 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
351 {
352 png_push_save_buffer(png_ptr);
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600353 return;
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500354 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500355
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600356 png_handle_gAMA(png_ptr, info_ptr, png_ptr->push_length);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600357 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500358
Guy Schalnat6d764711995-12-19 03:22:19 -0600359#endif
Glenn Randers-Pehrsone26c0952009-09-23 11:22:08 -0500360#ifdef PNG_READ_sBIT_SUPPORTED
Glenn Randers-Pehrsonbb5cb142011-09-22 12:41:58 -0500361 else if (png_ptr->chunk_name == png_sBIT)
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600362 {
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500363 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
364 {
365 png_push_save_buffer(png_ptr);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600366 return;
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500367 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500368
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600369 png_handle_sBIT(png_ptr, info_ptr, png_ptr->push_length);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600370 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500371
Guy Schalnat6d764711995-12-19 03:22:19 -0600372#endif
Glenn Randers-Pehrsone26c0952009-09-23 11:22:08 -0500373#ifdef PNG_READ_cHRM_SUPPORTED
Glenn Randers-Pehrsonbb5cb142011-09-22 12:41:58 -0500374 else if (png_ptr->chunk_name == png_cHRM)
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600375 {
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500376 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
377 {
378 png_push_save_buffer(png_ptr);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600379 return;
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500380 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500381
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600382 png_handle_cHRM(png_ptr, info_ptr, png_ptr->push_length);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600383 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500384
Guy Schalnat6d764711995-12-19 03:22:19 -0600385#endif
Glenn Randers-Pehrsone26c0952009-09-23 11:22:08 -0500386#ifdef PNG_READ_sRGB_SUPPORTED
Glenn Randers-Pehrsonbb5cb142011-09-22 12:41:58 -0500387 else if (chunk_name == png_sRGB)
Glenn Randers-Pehrsonb6ce43d1998-01-01 07:13:13 -0600388 {
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500389 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
390 {
391 png_push_save_buffer(png_ptr);
Glenn Randers-Pehrsonb6ce43d1998-01-01 07:13:13 -0600392 return;
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500393 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500394
Glenn Randers-Pehrsonb6ce43d1998-01-01 07:13:13 -0600395 png_handle_sRGB(png_ptr, info_ptr, png_ptr->push_length);
396 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500397
Glenn Randers-Pehrsonb6ce43d1998-01-01 07:13:13 -0600398#endif
Glenn Randers-Pehrsone26c0952009-09-23 11:22:08 -0500399#ifdef PNG_READ_iCCP_SUPPORTED
Glenn Randers-Pehrsonbb5cb142011-09-22 12:41:58 -0500400 else if (png_ptr->chunk_name == png_iCCP)
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -0600401 {
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500402 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
403 {
404 png_push_save_buffer(png_ptr);
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -0600405 return;
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500406 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500407
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -0600408 png_handle_iCCP(png_ptr, info_ptr, png_ptr->push_length);
409 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500410
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -0600411#endif
Glenn Randers-Pehrsone26c0952009-09-23 11:22:08 -0500412#ifdef PNG_READ_sPLT_SUPPORTED
Glenn Randers-Pehrsonbb5cb142011-09-22 12:41:58 -0500413 else if (chunk_name == png_sPLT)
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -0600414 {
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500415 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
416 {
417 png_push_save_buffer(png_ptr);
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -0600418 return;
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500419 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500420
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -0600421 png_handle_sPLT(png_ptr, info_ptr, png_ptr->push_length);
422 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500423
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -0600424#endif
Glenn Randers-Pehrsone26c0952009-09-23 11:22:08 -0500425#ifdef PNG_READ_tRNS_SUPPORTED
Glenn Randers-Pehrsonbb5cb142011-09-22 12:41:58 -0500426 else if (chunk_name == png_tRNS)
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600427 {
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500428 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
429 {
430 png_push_save_buffer(png_ptr);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600431 return;
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500432 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500433
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600434 png_handle_tRNS(png_ptr, info_ptr, png_ptr->push_length);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600435 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500436
Guy Schalnat6d764711995-12-19 03:22:19 -0600437#endif
Glenn Randers-Pehrsone26c0952009-09-23 11:22:08 -0500438#ifdef PNG_READ_bKGD_SUPPORTED
Glenn Randers-Pehrsonbb5cb142011-09-22 12:41:58 -0500439 else if (chunk_name == png_bKGD)
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600440 {
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500441 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
442 {
443 png_push_save_buffer(png_ptr);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600444 return;
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500445 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500446
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600447 png_handle_bKGD(png_ptr, info_ptr, png_ptr->push_length);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600448 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500449
Guy Schalnat6d764711995-12-19 03:22:19 -0600450#endif
Glenn Randers-Pehrsone26c0952009-09-23 11:22:08 -0500451#ifdef PNG_READ_hIST_SUPPORTED
Glenn Randers-Pehrsonbb5cb142011-09-22 12:41:58 -0500452 else if (chunk_name == png_hIST)
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600453 {
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500454 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
455 {
456 png_push_save_buffer(png_ptr);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600457 return;
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500458 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500459
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600460 png_handle_hIST(png_ptr, info_ptr, png_ptr->push_length);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600461 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500462
Guy Schalnat6d764711995-12-19 03:22:19 -0600463#endif
Glenn Randers-Pehrsone26c0952009-09-23 11:22:08 -0500464#ifdef PNG_READ_pHYs_SUPPORTED
Glenn Randers-Pehrsonbb5cb142011-09-22 12:41:58 -0500465 else if (chunk_name == png_pHYs)
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600466 {
467 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
468 {
469 png_push_save_buffer(png_ptr);
470 return;
471 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500472
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600473 png_handle_pHYs(png_ptr, info_ptr, png_ptr->push_length);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600474 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500475
Guy Schalnat6d764711995-12-19 03:22:19 -0600476#endif
Glenn Randers-Pehrsone26c0952009-09-23 11:22:08 -0500477#ifdef PNG_READ_oFFs_SUPPORTED
Glenn Randers-Pehrsonbb5cb142011-09-22 12:41:58 -0500478 else if (chunk_name == png_oFFs)
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600479 {
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500480 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
481 {
482 png_push_save_buffer(png_ptr);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600483 return;
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500484 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500485
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600486 png_handle_oFFs(png_ptr, info_ptr, png_ptr->push_length);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600487 }
Guy Schalnat6d764711995-12-19 03:22:19 -0600488#endif
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500489
Glenn Randers-Pehrsone26c0952009-09-23 11:22:08 -0500490#ifdef PNG_READ_pCAL_SUPPORTED
Glenn Randers-Pehrsonbb5cb142011-09-22 12:41:58 -0500491 else if (chunk_name == png_pCAL)
Andreas Dilger47a0c421997-05-16 02:46:07 -0500492 {
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500493 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
494 {
495 png_push_save_buffer(png_ptr);
Andreas Dilger47a0c421997-05-16 02:46:07 -0500496 return;
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500497 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500498
Andreas Dilger47a0c421997-05-16 02:46:07 -0500499 png_handle_pCAL(png_ptr, info_ptr, png_ptr->push_length);
500 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500501
Andreas Dilger47a0c421997-05-16 02:46:07 -0500502#endif
Glenn Randers-Pehrsone26c0952009-09-23 11:22:08 -0500503#ifdef PNG_READ_sCAL_SUPPORTED
Glenn Randers-Pehrsonbb5cb142011-09-22 12:41:58 -0500504 else if (chunk_name == png_sCAL)
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -0600505 {
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500506 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
507 {
508 png_push_save_buffer(png_ptr);
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -0600509 return;
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500510 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500511
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -0600512 png_handle_sCAL(png_ptr, info_ptr, png_ptr->push_length);
513 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500514
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -0600515#endif
Glenn Randers-Pehrsone26c0952009-09-23 11:22:08 -0500516#ifdef PNG_READ_tIME_SUPPORTED
Glenn Randers-Pehrsonbb5cb142011-09-22 12:41:58 -0500517 else if (chunk_name == png_tIME)
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600518 {
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500519 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
520 {
521 png_push_save_buffer(png_ptr);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600522 return;
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500523 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500524
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600525 png_handle_tIME(png_ptr, info_ptr, png_ptr->push_length);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600526 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500527
Guy Schalnat6d764711995-12-19 03:22:19 -0600528#endif
Glenn Randers-Pehrsone26c0952009-09-23 11:22:08 -0500529#ifdef PNG_READ_tEXt_SUPPORTED
Glenn Randers-Pehrsonbb5cb142011-09-22 12:41:58 -0500530 else if (chunk_name == png_tEXt)
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600531 {
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500532 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
533 {
534 png_push_save_buffer(png_ptr);
Glenn Randers-Pehrsond1e8c862002-06-20 06:54:34 -0500535 return;
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500536 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500537
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600538 png_push_handle_tEXt(png_ptr, info_ptr, png_ptr->push_length);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600539 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500540
Guy Schalnat6d764711995-12-19 03:22:19 -0600541#endif
Glenn Randers-Pehrsone26c0952009-09-23 11:22:08 -0500542#ifdef PNG_READ_zTXt_SUPPORTED
Glenn Randers-Pehrsonbb5cb142011-09-22 12:41:58 -0500543 else if (chunk_name == png_zTXt)
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600544 {
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500545 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
546 {
547 png_push_save_buffer(png_ptr);
Glenn Randers-Pehrsond1e8c862002-06-20 06:54:34 -0500548 return;
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500549 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500550
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600551 png_push_handle_zTXt(png_ptr, info_ptr, png_ptr->push_length);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600552 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500553
Guy Schalnat6d764711995-12-19 03:22:19 -0600554#endif
Glenn Randers-Pehrsone26c0952009-09-23 11:22:08 -0500555#ifdef PNG_READ_iTXt_SUPPORTED
Glenn Randers-Pehrsonbb5cb142011-09-22 12:41:58 -0500556 else if (chunk_name == png_iTXt)
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -0600557 {
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500558 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
559 {
560 png_push_save_buffer(png_ptr);
Glenn Randers-Pehrsond1e8c862002-06-20 06:54:34 -0500561 return;
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500562 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500563
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -0600564 png_push_handle_iTXt(png_ptr, info_ptr, png_ptr->push_length);
565 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500566
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -0600567#endif
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600568 else
569 {
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500570 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
571 {
572 png_push_save_buffer(png_ptr);
Glenn Randers-Pehrsond1e8c862002-06-20 06:54:34 -0500573 return;
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500574 }
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600575 png_push_handle_unknown(png_ptr, info_ptr, png_ptr->push_length);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600576 }
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600577
Glenn Randers-Pehrson5379b241999-11-27 10:22:33 -0600578 png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
Guy Schalnat6d764711995-12-19 03:22:19 -0600579}
580
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -0500581void /* PRIVATE */
Andreas Dilger47a0c421997-05-16 02:46:07 -0500582png_push_crc_skip(png_structp png_ptr, png_uint_32 skip)
Guy Schalnat6d764711995-12-19 03:22:19 -0600583{
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600584 png_ptr->process_mode = PNG_SKIP_MODE;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500585 png_ptr->skip_length = skip;
Guy Schalnat6d764711995-12-19 03:22:19 -0600586}
587
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -0500588void /* PRIVATE */
Andreas Dilger47a0c421997-05-16 02:46:07 -0500589png_push_crc_finish(png_structp png_ptr)
Guy Schalnat6d764711995-12-19 03:22:19 -0600590{
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600591 if (png_ptr->skip_length && png_ptr->save_buffer_size)
592 {
Glenn Randers-Pehrson1408c2a2011-01-16 14:16:28 -0600593 png_size_t save_size = png_ptr->save_buffer_size;
Glenn Randers-Pehrsonbcb3aac2010-09-10 22:05:27 -0500594 png_uint_32 skip_length = png_ptr->skip_length;
Guy Schalnat6d764711995-12-19 03:22:19 -0600595
John Bowler168a4332011-01-16 19:32:22 -0600596 /* We want the smaller of 'skip_length' and 'save_buffer_size', but
Glenn Randers-Pehrsonbcb3aac2010-09-10 22:05:27 -0500597 * they are of different types and we don't know which variable has the
598 * fewest bits. Carefully select the smaller and cast it to the type of
599 * the larger - this cannot overflow. Do not cast in the following test
600 * - it will break on either 16 or 64 bit platforms.
601 */
602 if (skip_length < save_size)
603 save_size = (png_size_t)skip_length;
Glenn Randers-Pehrsonf24daf22010-05-06 09:44:04 -0500604
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600605 else
Glenn Randers-Pehrsonbcb3aac2010-09-10 22:05:27 -0500606 skip_length = (png_uint_32)save_size;
Guy Schalnat6d764711995-12-19 03:22:19 -0600607
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600608 png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size);
Guy Schalnat6d764711995-12-19 03:22:19 -0600609
Glenn Randers-Pehrsonbcb3aac2010-09-10 22:05:27 -0500610 png_ptr->skip_length -= skip_length;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600611 png_ptr->buffer_size -= save_size;
612 png_ptr->save_buffer_size -= save_size;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500613 png_ptr->save_buffer_ptr += save_size;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600614 }
615 if (png_ptr->skip_length && png_ptr->current_buffer_size)
616 {
Glenn Randers-Pehrsonbcb3aac2010-09-10 22:05:27 -0500617 png_size_t save_size = png_ptr->current_buffer_size;
618 png_uint_32 skip_length = png_ptr->skip_length;
Guy Schalnat6d764711995-12-19 03:22:19 -0600619
John Bowler168a4332011-01-16 19:32:22 -0600620 /* We want the smaller of 'skip_length' and 'current_buffer_size', here,
621 * the same problem exists as above and the same solution.
Glenn Randers-Pehrsonbcb3aac2010-09-10 22:05:27 -0500622 */
623 if (skip_length < save_size)
624 save_size = (png_size_t)skip_length;
Glenn Randers-Pehrsonf24daf22010-05-06 09:44:04 -0500625
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600626 else
Glenn Randers-Pehrsonbcb3aac2010-09-10 22:05:27 -0500627 skip_length = (png_uint_32)save_size;
Guy Schalnat6d764711995-12-19 03:22:19 -0600628
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600629 png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size);
Guy Schalnat6d764711995-12-19 03:22:19 -0600630
Glenn Randers-Pehrsonbcb3aac2010-09-10 22:05:27 -0500631 png_ptr->skip_length -= skip_length;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600632 png_ptr->buffer_size -= save_size;
633 png_ptr->current_buffer_size -= save_size;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500634 png_ptr->current_buffer_ptr += save_size;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600635 }
636 if (!png_ptr->skip_length)
637 {
638 if (png_ptr->buffer_size < 4)
639 {
640 png_push_save_buffer(png_ptr);
641 return;
642 }
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600643
644 png_crc_finish(png_ptr, 0);
Andreas Dilger47a0c421997-05-16 02:46:07 -0500645 png_ptr->process_mode = PNG_READ_CHUNK_MODE;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600646 }
Guy Schalnat6d764711995-12-19 03:22:19 -0600647}
648
Glenn Randers-Pehrsoneae8e362010-03-12 17:36:53 -0600649void PNGCBAPI
Andreas Dilger47a0c421997-05-16 02:46:07 -0500650png_push_fill_buffer(png_structp png_ptr, png_bytep buffer, png_size_t length)
Guy Schalnat6d764711995-12-19 03:22:19 -0600651{
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600652 png_bytep ptr;
Guy Schalnat6d764711995-12-19 03:22:19 -0600653
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500654 if (png_ptr == NULL)
655 return;
656
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600657 ptr = buffer;
658 if (png_ptr->save_buffer_size)
659 {
Andreas Dilger47a0c421997-05-16 02:46:07 -0500660 png_size_t save_size;
Guy Schalnat6d764711995-12-19 03:22:19 -0600661
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600662 if (length < png_ptr->save_buffer_size)
663 save_size = length;
Glenn Randers-Pehrsonf24daf22010-05-06 09:44:04 -0500664
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600665 else
666 save_size = png_ptr->save_buffer_size;
Guy Schalnat6d764711995-12-19 03:22:19 -0600667
Andreas Dilger47a0c421997-05-16 02:46:07 -0500668 png_memcpy(ptr, png_ptr->save_buffer_ptr, save_size);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600669 length -= save_size;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500670 ptr += save_size;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600671 png_ptr->buffer_size -= save_size;
672 png_ptr->save_buffer_size -= save_size;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500673 png_ptr->save_buffer_ptr += save_size;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600674 }
675 if (length && png_ptr->current_buffer_size)
676 {
Andreas Dilger47a0c421997-05-16 02:46:07 -0500677 png_size_t save_size;
Guy Schalnat6d764711995-12-19 03:22:19 -0600678
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600679 if (length < png_ptr->current_buffer_size)
680 save_size = length;
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500681
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600682 else
683 save_size = png_ptr->current_buffer_size;
Guy Schalnat6d764711995-12-19 03:22:19 -0600684
Andreas Dilger47a0c421997-05-16 02:46:07 -0500685 png_memcpy(ptr, png_ptr->current_buffer_ptr, save_size);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600686 png_ptr->buffer_size -= save_size;
687 png_ptr->current_buffer_size -= save_size;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500688 png_ptr->current_buffer_ptr += save_size;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600689 }
Guy Schalnat6d764711995-12-19 03:22:19 -0600690}
691
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -0500692void /* PRIVATE */
Guy Schalnat6d764711995-12-19 03:22:19 -0600693png_push_save_buffer(png_structp png_ptr)
694{
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600695 if (png_ptr->save_buffer_size)
696 {
697 if (png_ptr->save_buffer_ptr != png_ptr->save_buffer)
698 {
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -0500699 png_size_t i, istop;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600700 png_bytep sp;
701 png_bytep dp;
Guy Schalnat6d764711995-12-19 03:22:19 -0600702
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500703 istop = png_ptr->save_buffer_size;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600704 for (i = 0, sp = png_ptr->save_buffer_ptr, dp = png_ptr->save_buffer;
Glenn Randers-Pehrson262d0ff2010-03-03 07:06:54 -0600705 i < istop; i++, sp++, dp++)
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600706 {
707 *dp = *sp;
708 }
709 }
710 }
Glenn Randers-Pehrsone00ed362010-02-07 22:42:58 -0600711 if (png_ptr->save_buffer_size + png_ptr->current_buffer_size >
Glenn Randers-Pehrson262d0ff2010-03-03 07:06:54 -0600712 png_ptr->save_buffer_max)
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600713 {
Andreas Dilger47a0c421997-05-16 02:46:07 -0500714 png_size_t new_max;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600715 png_bytep old_buffer;
Guy Schalnat6d764711995-12-19 03:22:19 -0600716
Glenn Randers-Pehrsone3f3c4e2010-02-07 18:08:50 -0600717 if (png_ptr->save_buffer_size > PNG_SIZE_MAX -
Glenn Randers-Pehrson262d0ff2010-03-03 07:06:54 -0600718 (png_ptr->current_buffer_size + 256))
Glenn Randers-Pehrsone00ed362010-02-07 22:42:58 -0600719 {
Glenn Randers-Pehrson262d0ff2010-03-03 07:06:54 -0600720 png_error(png_ptr, "Potential overflow of save_buffer");
Glenn Randers-Pehrsone00ed362010-02-07 22:42:58 -0600721 }
Glenn Randers-Pehrsone3f3c4e2010-02-07 18:08:50 -0600722
Glenn Randers-Pehrsone00ed362010-02-07 22:42:58 -0600723 new_max = png_ptr->save_buffer_size + png_ptr->current_buffer_size + 256;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600724 old_buffer = png_ptr->save_buffer;
Glenn Randers-Pehrsonf1eb9182010-02-08 15:36:41 -0600725 png_ptr->save_buffer = (png_bytep)png_malloc_warn(png_ptr,
Glenn Randers-Pehrson262d0ff2010-03-03 07:06:54 -0600726 (png_size_t)new_max);
Glenn Randers-Pehrsonf24daf22010-05-06 09:44:04 -0500727
Glenn Randers-Pehrsonf1eb9182010-02-08 15:36:41 -0600728 if (png_ptr->save_buffer == NULL)
729 {
Glenn Randers-Pehrson262d0ff2010-03-03 07:06:54 -0600730 png_free(png_ptr, old_buffer);
731 png_error(png_ptr, "Insufficient memory for save_buffer");
Glenn Randers-Pehrsonf1eb9182010-02-08 15:36:41 -0600732 }
Glenn Randers-Pehrsonf24daf22010-05-06 09:44:04 -0500733
Glenn Randers-Pehrson82ae3832001-04-20 10:32:10 -0500734 png_memcpy(png_ptr->save_buffer, old_buffer, png_ptr->save_buffer_size);
735 png_free(png_ptr, old_buffer);
736 png_ptr->save_buffer_max = new_max;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600737 }
738 if (png_ptr->current_buffer_size)
739 {
Andreas Dilger47a0c421997-05-16 02:46:07 -0500740 png_memcpy(png_ptr->save_buffer + png_ptr->save_buffer_size,
741 png_ptr->current_buffer_ptr, png_ptr->current_buffer_size);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600742 png_ptr->save_buffer_size += png_ptr->current_buffer_size;
743 png_ptr->current_buffer_size = 0;
744 }
745 png_ptr->save_buffer_ptr = png_ptr->save_buffer;
746 png_ptr->buffer_size = 0;
Guy Schalnat6d764711995-12-19 03:22:19 -0600747}
748
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -0500749void /* PRIVATE */
Guy Schalnat6d764711995-12-19 03:22:19 -0600750png_push_restore_buffer(png_structp png_ptr, png_bytep buffer,
Andreas Dilger47a0c421997-05-16 02:46:07 -0500751 png_size_t buffer_length)
Guy Schalnat6d764711995-12-19 03:22:19 -0600752{
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600753 png_ptr->current_buffer = buffer;
754 png_ptr->current_buffer_size = buffer_length;
755 png_ptr->buffer_size = buffer_length + png_ptr->save_buffer_size;
756 png_ptr->current_buffer_ptr = png_ptr->current_buffer;
Guy Schalnat6d764711995-12-19 03:22:19 -0600757}
758
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -0500759void /* PRIVATE */
Guy Schalnate5a37791996-06-05 15:50:50 -0500760png_push_read_IDAT(png_structp png_ptr)
Guy Schalnat6d764711995-12-19 03:22:19 -0600761{
Glenn Randers-Pehrson5379b241999-11-27 10:22:33 -0600762 if (!(png_ptr->mode & PNG_HAVE_CHUNK_HEADER))
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600763 {
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600764 png_byte chunk_length[4];
Glenn Randers-Pehrsonbb5cb142011-09-22 12:41:58 -0500765 png_byte chunk_tag[4];
Guy Schalnat6d764711995-12-19 03:22:19 -0600766
Glenn Randers-Pehrsonbb5cb142011-09-22 12:41:58 -0500767 /* TODO: this code can be commoned up with the same code in push_read */
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600768 if (png_ptr->buffer_size < 8)
769 {
770 png_push_save_buffer(png_ptr);
771 return;
772 }
Guy Schalnat6d764711995-12-19 03:22:19 -0600773
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600774 png_push_fill_buffer(png_ptr, chunk_length, 4);
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -0500775 png_ptr->push_length = png_get_uint_31(png_ptr, chunk_length);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600776 png_reset_crc(png_ptr);
Glenn Randers-Pehrsonbb5cb142011-09-22 12:41:58 -0500777 png_crc_read(png_ptr, chunk_tag, 4);
778 png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(chunk_tag);
Glenn Randers-Pehrson5379b241999-11-27 10:22:33 -0600779 png_ptr->mode |= PNG_HAVE_CHUNK_HEADER;
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600780
Glenn Randers-Pehrsonbb5cb142011-09-22 12:41:58 -0500781 if (png_ptr->chunk_name != png_IDAT)
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600782 {
Andreas Dilger47a0c421997-05-16 02:46:07 -0500783 png_ptr->process_mode = PNG_READ_CHUNK_MODE;
Glenn Randers-Pehrsonf24daf22010-05-06 09:44:04 -0500784
Guy Schalnate5a37791996-06-05 15:50:50 -0500785 if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600786 png_error(png_ptr, "Not enough compressed data");
Glenn Randers-Pehrsonf24daf22010-05-06 09:44:04 -0500787
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600788 return;
789 }
Guy Schalnat6d764711995-12-19 03:22:19 -0600790
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600791 png_ptr->idat_size = png_ptr->push_length;
792 }
Glenn Randers-Pehrsonbb5cb142011-09-22 12:41:58 -0500793
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600794 if (png_ptr->idat_size && png_ptr->save_buffer_size)
795 {
Glenn Randers-Pehrsonbcb3aac2010-09-10 22:05:27 -0500796 png_size_t save_size = png_ptr->save_buffer_size;
797 png_uint_32 idat_size = png_ptr->idat_size;
Guy Schalnat6d764711995-12-19 03:22:19 -0600798
Glenn Randers-Pehrsonbcb3aac2010-09-10 22:05:27 -0500799 /* We want the smaller of 'idat_size' and 'current_buffer_size', but they
800 * are of different types and we don't know which variable has the fewest
801 * bits. Carefully select the smaller and cast it to the type of the
802 * larger - this cannot overflow. Do not cast in the following test - it
803 * will break on either 16 or 64 bit platforms.
804 */
805 if (idat_size < save_size)
806 save_size = (png_size_t)idat_size;
Glenn Randers-Pehrsonf24daf22010-05-06 09:44:04 -0500807
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600808 else
Glenn Randers-Pehrsonbcb3aac2010-09-10 22:05:27 -0500809 idat_size = (png_uint_32)save_size;
Guy Schalnat6d764711995-12-19 03:22:19 -0600810
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600811 png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size);
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500812
Glenn Randers-Pehrson57d96172010-06-19 19:25:17 -0500813 png_process_IDAT_data(png_ptr, png_ptr->save_buffer_ptr, save_size);
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500814
Glenn Randers-Pehrsonbcb3aac2010-09-10 22:05:27 -0500815 png_ptr->idat_size -= idat_size;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600816 png_ptr->buffer_size -= save_size;
817 png_ptr->save_buffer_size -= save_size;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500818 png_ptr->save_buffer_ptr += save_size;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600819 }
Glenn Randers-Pehrsonbcb3aac2010-09-10 22:05:27 -0500820
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600821 if (png_ptr->idat_size && png_ptr->current_buffer_size)
822 {
Glenn Randers-Pehrsonbcb3aac2010-09-10 22:05:27 -0500823 png_size_t save_size = png_ptr->current_buffer_size;
824 png_uint_32 idat_size = png_ptr->idat_size;
Guy Schalnat6d764711995-12-19 03:22:19 -0600825
Glenn Randers-Pehrsonbcb3aac2010-09-10 22:05:27 -0500826 /* We want the smaller of 'idat_size' and 'current_buffer_size', but they
827 * are of different types and we don't know which variable has the fewest
828 * bits. Carefully select the smaller and cast it to the type of the
829 * larger - this cannot overflow.
830 */
831 if (idat_size < save_size)
832 save_size = (png_size_t)idat_size;
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500833
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600834 else
Glenn Randers-Pehrsonbcb3aac2010-09-10 22:05:27 -0500835 idat_size = (png_uint_32)save_size;
Guy Schalnat6d764711995-12-19 03:22:19 -0600836
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600837 png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size);
Glenn Randers-Pehrsonf24daf22010-05-06 09:44:04 -0500838
Glenn Randers-Pehrson57d96172010-06-19 19:25:17 -0500839 png_process_IDAT_data(png_ptr, png_ptr->current_buffer_ptr, save_size);
Guy Schalnat6d764711995-12-19 03:22:19 -0600840
Glenn Randers-Pehrsonbcb3aac2010-09-10 22:05:27 -0500841 png_ptr->idat_size -= idat_size;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600842 png_ptr->buffer_size -= save_size;
843 png_ptr->current_buffer_size -= save_size;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500844 png_ptr->current_buffer_ptr += save_size;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600845 }
846 if (!png_ptr->idat_size)
847 {
848 if (png_ptr->buffer_size < 4)
849 {
850 png_push_save_buffer(png_ptr);
851 return;
852 }
853
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600854 png_crc_finish(png_ptr, 0);
Glenn Randers-Pehrson5379b241999-11-27 10:22:33 -0600855 png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
Glenn Randers-Pehrson859665d2002-08-06 18:06:11 -0500856 png_ptr->mode |= PNG_AFTER_IDAT;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600857 }
Guy Schalnat6d764711995-12-19 03:22:19 -0600858}
859
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -0500860void /* PRIVATE */
Guy Schalnat6d764711995-12-19 03:22:19 -0600861png_process_IDAT_data(png_structp png_ptr, png_bytep buffer,
Andreas Dilger47a0c421997-05-16 02:46:07 -0500862 png_size_t buffer_length)
Guy Schalnat6d764711995-12-19 03:22:19 -0600863{
Glenn Randers-Pehrson57d96172010-06-19 19:25:17 -0500864 /* The caller checks for a non-zero buffer length. */
Glenn Randers-Pehrsonef3831a2010-06-22 13:03:32 -0500865 if (!(buffer_length > 0) || buffer == NULL)
Glenn Randers-Pehrson57d96172010-06-19 19:25:17 -0500866 png_error(png_ptr, "No IDAT data (internal error)");
Guy Schalnat6d764711995-12-19 03:22:19 -0600867
Glenn Randers-Pehrson57d96172010-06-19 19:25:17 -0500868 /* This routine must process all the data it has been given
869 * before returning, calling the row callback as required to
Glenn Randers-Pehrson5feb87c2010-06-21 12:28:05 -0500870 * handle the uncompressed results.
Glenn Randers-Pehrson57d96172010-06-19 19:25:17 -0500871 */
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600872 png_ptr->zstream.next_in = buffer;
873 png_ptr->zstream.avail_in = (uInt)buffer_length;
Glenn Randers-Pehrson57d96172010-06-19 19:25:17 -0500874
875 /* Keep going until the decompressed data is all processed
876 * or the stream marked as finished.
877 */
878 while (png_ptr->zstream.avail_in > 0 &&
Glenn Randers-Pehrsond9d4cec2010-07-12 07:12:09 -0500879 !(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600880 {
Glenn Randers-Pehrson57d96172010-06-19 19:25:17 -0500881 int ret;
882
883 /* We have data for zlib, but we must check that zlib
Glenn Randers-Pehrsonef3831a2010-06-22 13:03:32 -0500884 * has someplace to put the results. It doesn't matter
Glenn Randers-Pehrson5feb87c2010-06-21 12:28:05 -0500885 * if we don't expect any results -- it may be the input
Glenn Randers-Pehrson57d96172010-06-19 19:25:17 -0500886 * data is just the LZ end code.
887 */
888 if (!(png_ptr->zstream.avail_out > 0))
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600889 {
Glenn Randers-Pehrsone3f3c4e2010-02-07 18:08:50 -0600890 png_ptr->zstream.avail_out =
891 (uInt) PNG_ROWBYTES(png_ptr->pixel_depth,
892 png_ptr->iwidth) + 1;
Glenn Randers-Pehrson5feb87c2010-06-21 12:28:05 -0500893
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600894 png_ptr->zstream.next_out = png_ptr->row_buf;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600895 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500896
Glenn Randers-Pehrson57d96172010-06-19 19:25:17 -0500897 /* Using Z_SYNC_FLUSH here means that an unterminated
Glenn Randers-Pehrsonef3831a2010-06-22 13:03:32 -0500898 * LZ stream (a stream with a missing end code) can still
899 * be handled, otherwise (Z_NO_FLUSH) a future zlib
900 * implementation might defer output and therefore
901 * change the current behavior (see comments in inflate.c
902 * for why this doesn't happen at present with zlib 1.2.5).
Glenn Randers-Pehrson57d96172010-06-19 19:25:17 -0500903 */
904 ret = inflate(&png_ptr->zstream, Z_SYNC_FLUSH);
905
906 /* Check for any failure before proceeding. */
907 if (ret != Z_OK && ret != Z_STREAM_END)
908 {
Glenn Randers-Pehrsond9d4cec2010-07-12 07:12:09 -0500909 /* Terminate the decompression. */
910 png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
Glenn Randers-Pehrson57d96172010-06-19 19:25:17 -0500911
912 /* This may be a truncated stream (missing or
Glenn Randers-Pehrsond9d4cec2010-07-12 07:12:09 -0500913 * damaged end code). Treat that as a warning.
914 */
Glenn Randers-Pehrson57d96172010-06-19 19:25:17 -0500915 if (png_ptr->row_number >= png_ptr->num_rows ||
Glenn Randers-Pehrsond9d4cec2010-07-12 07:12:09 -0500916 png_ptr->pass > 6)
917 png_warning(png_ptr, "Truncated compressed data in IDAT");
Glenn Randers-Pehrson5feb87c2010-06-21 12:28:05 -0500918
Glenn Randers-Pehrsond9d4cec2010-07-12 07:12:09 -0500919 else
920 png_error(png_ptr, "Decompression error in IDAT");
Glenn Randers-Pehrson57d96172010-06-19 19:25:17 -0500921
Glenn Randers-Pehrsond9d4cec2010-07-12 07:12:09 -0500922 /* Skip the check on unprocessed input */
Glenn Randers-Pehrson57d96172010-06-19 19:25:17 -0500923 return;
924 }
925
926 /* Did inflate output any data? */
927 if (png_ptr->zstream.next_out != png_ptr->row_buf)
928 {
Glenn Randers-Pehrsond9d4cec2010-07-12 07:12:09 -0500929 /* Is this unexpected data after the last row?
930 * If it is, artificially terminate the LZ output
931 * here.
932 */
Glenn Randers-Pehrson57d96172010-06-19 19:25:17 -0500933 if (png_ptr->row_number >= png_ptr->num_rows ||
Glenn Randers-Pehrsond9d4cec2010-07-12 07:12:09 -0500934 png_ptr->pass > 6)
Glenn Randers-Pehrson57d96172010-06-19 19:25:17 -0500935 {
Glenn Randers-Pehrsond9d4cec2010-07-12 07:12:09 -0500936 /* Extra data. */
937 png_warning(png_ptr, "Extra compressed data in IDAT");
Glenn Randers-Pehrson57d96172010-06-19 19:25:17 -0500938 png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
Glenn Randers-Pehrson5feb87c2010-06-21 12:28:05 -0500939
Glenn Randers-Pehrsond9d4cec2010-07-12 07:12:09 -0500940 /* Do no more processing; skip the unprocessed
941 * input check below.
942 */
Glenn Randers-Pehrson57d96172010-06-19 19:25:17 -0500943 return;
Glenn Randers-Pehrsond9d4cec2010-07-12 07:12:09 -0500944 }
Glenn Randers-Pehrson57d96172010-06-19 19:25:17 -0500945
Glenn Randers-Pehrsond9d4cec2010-07-12 07:12:09 -0500946 /* Do we have a complete row? */
947 if (png_ptr->zstream.avail_out == 0)
948 png_push_process_row(png_ptr);
Glenn Randers-Pehrson57d96172010-06-19 19:25:17 -0500949 }
Glenn Randers-Pehrson821b7102010-06-24 16:16:32 -0500950
951 /* And check for the end of the stream. */
952 if (ret == Z_STREAM_END)
Glenn Randers-Pehrsond9d4cec2010-07-12 07:12:09 -0500953 png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500954 }
Glenn Randers-Pehrson57d96172010-06-19 19:25:17 -0500955
956 /* All the data should have been processed, if anything
957 * is left at this point we have bytes of IDAT data
958 * after the zlib end code.
959 */
960 if (png_ptr->zstream.avail_in > 0)
Glenn Randers-Pehrson5feb87c2010-06-21 12:28:05 -0500961 png_warning(png_ptr, "Extra compression data in IDAT");
Guy Schalnat6d764711995-12-19 03:22:19 -0600962}
963
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -0500964void /* PRIVATE */
Guy Schalnat6d764711995-12-19 03:22:19 -0600965png_push_process_row(png_structp png_ptr)
966{
Glenn Randers-Pehrsonbb5cb142011-09-22 12:41:58 -0500967 /* 1.5.6: row_info moved out of png_struct to a local here. */
968 png_row_info row_info;
Glenn Randers-Pehrson5c6aeb21998-12-29 11:47:59 -0600969
Glenn Randers-Pehrsonbb5cb142011-09-22 12:41:58 -0500970 row_info.width = png_ptr->iwidth; /* NOTE: width of current interlaced row */
971 row_info.color_type = png_ptr->color_type;
972 row_info.bit_depth = png_ptr->bit_depth;
973 row_info.channels = png_ptr->channels;
974 row_info.pixel_depth = png_ptr->pixel_depth;
975 row_info.rowbytes = PNG_ROWBYTES(row_info.pixel_depth, row_info.width);
Guy Schalnat6d764711995-12-19 03:22:19 -0600976
Glenn Randers-Pehrsonbb5cb142011-09-22 12:41:58 -0500977 if (png_ptr->row_buf[0] > PNG_FILTER_VALUE_NONE)
978 {
979 if (png_ptr->row_buf[0] < PNG_FILTER_VALUE_LAST)
980 png_read_filter_row(&row_info, png_ptr->row_buf + 1,
981 png_ptr->prev_row + 1, png_ptr->row_buf[0]);
982 else
983 png_error(png_ptr, "bad adaptive filter value");
984 }
Guy Schalnat6d764711995-12-19 03:22:19 -0600985
Glenn Randers-Pehrsonbb5cb142011-09-22 12:41:58 -0500986 /* libpng 1.5.6: the following line was copying png_ptr->rowbytes before
987 * 1.5.6, while the buffer really is this big in current versions of libpng
988 * it may not be in the future, so this was changed just to copy the
989 * interlaced row count:
990 */
991 png_memcpy(png_ptr->prev_row, png_ptr->row_buf, row_info.rowbytes + 1);
Guy Schalnat6d764711995-12-19 03:22:19 -0600992
John Bowler4a12f4a2011-04-17 18:34:22 -0500993#ifdef PNG_READ_TRANSFORMS_SUPPORTED
John Bowler9b872f42011-02-12 09:00:16 -0600994 if (png_ptr->transformations)
Glenn Randers-Pehrsonbb5cb142011-09-22 12:41:58 -0500995 png_do_read_transformations(png_ptr, &row_info);
John Bowler4a12f4a2011-04-17 18:34:22 -0500996#endif
Guy Schalnat6d764711995-12-19 03:22:19 -0600997
Glenn Randers-Pehrsonbb5cb142011-09-22 12:41:58 -0500998 /* The transformed pixel depth should match the depth now in row_info. */
999 if (png_ptr->transformed_pixel_depth == 0)
1000 {
1001 png_ptr->transformed_pixel_depth = row_info.pixel_depth;
1002 if (row_info.pixel_depth > png_ptr->maximum_pixel_depth)
1003 png_error(png_ptr, "progressive row overflow");
1004 }
1005
1006 else if (png_ptr->transformed_pixel_depth != row_info.pixel_depth)
1007 png_error(png_ptr, "internal progressive row size calculation error");
1008
1009
Glenn Randers-Pehrsone26c0952009-09-23 11:22:08 -05001010#ifdef PNG_READ_INTERLACING_SUPPORTED
Glenn Randers-Pehrson4bb4d012009-05-20 12:45:29 -05001011 /* Blow up interlaced rows to full size */
Andreas Dilger47a0c421997-05-16 02:46:07 -05001012 if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE))
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001013 {
1014 if (png_ptr->pass < 6)
Glenn Randers-Pehrsonbb5cb142011-09-22 12:41:58 -05001015 png_do_read_interlace(&row_info, png_ptr->row_buf + 1, png_ptr->pass,
1016 png_ptr->transformations);
Guy Schalnat6d764711995-12-19 03:22:19 -06001017
Glenn Randers-Pehrsoncdf140b2001-01-15 12:22:32 -06001018 switch (png_ptr->pass)
1019 {
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001020 case 0:
1021 {
1022 int i;
1023 for (i = 0; i < 8 && png_ptr->pass == 0; i++)
1024 {
1025 png_push_have_row(png_ptr, png_ptr->row_buf + 1);
Glenn Randers-Pehrson4bb4d012009-05-20 12:45:29 -05001026 png_read_push_finish_row(png_ptr); /* Updates png_ptr->pass */
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001027 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001028
Glenn Randers-Pehrson4bb4d012009-05-20 12:45:29 -05001029 if (png_ptr->pass == 2) /* Pass 1 might be empty */
Glenn Randers-Pehrsoncdf140b2001-01-15 12:22:32 -06001030 {
1031 for (i = 0; i < 4 && png_ptr->pass == 2; i++)
1032 {
Glenn Randers-Pehrsonbeb572e2006-08-19 13:59:24 -05001033 png_push_have_row(png_ptr, NULL);
Glenn Randers-Pehrsoncdf140b2001-01-15 12:22:32 -06001034 png_read_push_finish_row(png_ptr);
1035 }
1036 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001037
Glenn Randers-Pehrsond1e8c862002-06-20 06:54:34 -05001038 if (png_ptr->pass == 4 && png_ptr->height <= 4)
1039 {
1040 for (i = 0; i < 2 && png_ptr->pass == 4; i++)
1041 {
Glenn Randers-Pehrsonbeb572e2006-08-19 13:59:24 -05001042 png_push_have_row(png_ptr, NULL);
Glenn Randers-Pehrsond1e8c862002-06-20 06:54:34 -05001043 png_read_push_finish_row(png_ptr);
1044 }
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -05001045 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001046
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -05001047 if (png_ptr->pass == 6 && png_ptr->height <= 4)
1048 {
Glenn Randers-Pehrsonbeb572e2006-08-19 13:59:24 -05001049 png_push_have_row(png_ptr, NULL);
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -05001050 png_read_push_finish_row(png_ptr);
1051 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001052
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001053 break;
1054 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001055
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001056 case 1:
1057 {
1058 int i;
1059 for (i = 0; i < 8 && png_ptr->pass == 1; i++)
1060 {
1061 png_push_have_row(png_ptr, png_ptr->row_buf + 1);
1062 png_read_push_finish_row(png_ptr);
1063 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001064
Glenn Randers-Pehrson4bb4d012009-05-20 12:45:29 -05001065 if (png_ptr->pass == 2) /* Skip top 4 generated rows */
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001066 {
1067 for (i = 0; i < 4 && png_ptr->pass == 2; i++)
1068 {
Glenn Randers-Pehrsonbeb572e2006-08-19 13:59:24 -05001069 png_push_have_row(png_ptr, NULL);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001070 png_read_push_finish_row(png_ptr);
1071 }
1072 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001073
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001074 break;
1075 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001076
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001077 case 2:
1078 {
1079 int i;
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001080
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001081 for (i = 0; i < 4 && png_ptr->pass == 2; i++)
1082 {
1083 png_push_have_row(png_ptr, png_ptr->row_buf + 1);
1084 png_read_push_finish_row(png_ptr);
1085 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001086
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001087 for (i = 0; i < 4 && png_ptr->pass == 2; i++)
1088 {
Glenn Randers-Pehrsonbeb572e2006-08-19 13:59:24 -05001089 png_push_have_row(png_ptr, NULL);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001090 png_read_push_finish_row(png_ptr);
1091 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001092
Glenn Randers-Pehrson4bb4d012009-05-20 12:45:29 -05001093 if (png_ptr->pass == 4) /* Pass 3 might be empty */
Glenn Randers-Pehrsoncdf140b2001-01-15 12:22:32 -06001094 {
1095 for (i = 0; i < 2 && png_ptr->pass == 4; i++)
1096 {
Glenn Randers-Pehrsonbeb572e2006-08-19 13:59:24 -05001097 png_push_have_row(png_ptr, NULL);
Glenn Randers-Pehrsoncdf140b2001-01-15 12:22:32 -06001098 png_read_push_finish_row(png_ptr);
1099 }
1100 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001101
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001102 break;
1103 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001104
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001105 case 3:
1106 {
1107 int i;
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001108
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001109 for (i = 0; i < 4 && png_ptr->pass == 3; i++)
1110 {
1111 png_push_have_row(png_ptr, png_ptr->row_buf + 1);
1112 png_read_push_finish_row(png_ptr);
1113 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001114
Glenn Randers-Pehrson4bb4d012009-05-20 12:45:29 -05001115 if (png_ptr->pass == 4) /* Skip top two generated rows */
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001116 {
1117 for (i = 0; i < 2 && png_ptr->pass == 4; i++)
1118 {
Glenn Randers-Pehrsonbeb572e2006-08-19 13:59:24 -05001119 png_push_have_row(png_ptr, NULL);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001120 png_read_push_finish_row(png_ptr);
1121 }
1122 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001123
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001124 break;
1125 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001126
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001127 case 4:
1128 {
1129 int i;
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001130
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001131 for (i = 0; i < 2 && png_ptr->pass == 4; i++)
1132 {
1133 png_push_have_row(png_ptr, png_ptr->row_buf + 1);
1134 png_read_push_finish_row(png_ptr);
1135 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001136
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001137 for (i = 0; i < 2 && png_ptr->pass == 4; i++)
1138 {
Glenn Randers-Pehrsonbeb572e2006-08-19 13:59:24 -05001139 png_push_have_row(png_ptr, NULL);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001140 png_read_push_finish_row(png_ptr);
1141 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001142
Glenn Randers-Pehrson4bb4d012009-05-20 12:45:29 -05001143 if (png_ptr->pass == 6) /* Pass 5 might be empty */
Glenn Randers-Pehrsoncdf140b2001-01-15 12:22:32 -06001144 {
Glenn Randers-Pehrsonbeb572e2006-08-19 13:59:24 -05001145 png_push_have_row(png_ptr, NULL);
Glenn Randers-Pehrsoncdf140b2001-01-15 12:22:32 -06001146 png_read_push_finish_row(png_ptr);
1147 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001148
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001149 break;
1150 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001151
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001152 case 5:
1153 {
1154 int i;
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001155
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001156 for (i = 0; i < 2 && png_ptr->pass == 5; i++)
1157 {
1158 png_push_have_row(png_ptr, png_ptr->row_buf + 1);
1159 png_read_push_finish_row(png_ptr);
1160 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001161
Glenn Randers-Pehrson4bb4d012009-05-20 12:45:29 -05001162 if (png_ptr->pass == 6) /* Skip top generated row */
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001163 {
Glenn Randers-Pehrsonbeb572e2006-08-19 13:59:24 -05001164 png_push_have_row(png_ptr, NULL);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001165 png_read_push_finish_row(png_ptr);
1166 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001167
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001168 break;
1169 }
Glenn Randers-Pehrson67439c42010-08-19 07:01:09 -05001170
Glenn Randers-Pehrsonb3edc732010-11-21 14:06:41 -06001171 default:
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001172 case 6:
1173 {
1174 png_push_have_row(png_ptr, png_ptr->row_buf + 1);
1175 png_read_push_finish_row(png_ptr);
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001176
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001177 if (png_ptr->pass != 6)
1178 break;
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001179
Glenn Randers-Pehrsonbeb572e2006-08-19 13:59:24 -05001180 png_push_have_row(png_ptr, NULL);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001181 png_read_push_finish_row(png_ptr);
1182 }
1183 }
1184 }
1185 else
Guy Schalnat6d764711995-12-19 03:22:19 -06001186#endif
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001187 {
1188 png_push_have_row(png_ptr, png_ptr->row_buf + 1);
1189 png_read_push_finish_row(png_ptr);
1190 }
Guy Schalnat6d764711995-12-19 03:22:19 -06001191}
1192
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -05001193void /* PRIVATE */
Guy Schalnat6d764711995-12-19 03:22:19 -06001194png_read_push_finish_row(png_structp png_ptr)
1195{
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001196 /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -06001197
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001198 /* Start of interlace block */
Glenn Randers-Pehrsonbb5cb142011-09-22 12:41:58 -05001199 static PNG_CONST png_byte FARDATA png_pass_start[] = {0, 4, 0, 2, 0, 1, 0};
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -06001200
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001201 /* Offset to next interlace block */
Glenn Randers-Pehrsonbb5cb142011-09-22 12:41:58 -05001202 static PNG_CONST png_byte FARDATA png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1};
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -06001203
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001204 /* Start of interlace block in the y direction */
Glenn Randers-Pehrsonbb5cb142011-09-22 12:41:58 -05001205 static PNG_CONST png_byte FARDATA png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1};
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -06001206
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001207 /* Offset to next interlace block in the y direction */
Glenn Randers-Pehrsonbb5cb142011-09-22 12:41:58 -05001208 static PNG_CONST png_byte FARDATA png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2};
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -06001209
Glenn Randers-Pehrson5379b241999-11-27 10:22:33 -06001210 /* Height of interlace block. This is not currently used - if you need
1211 * it, uncomment it here and in png.h
Glenn Randers-Pehrsonbb5cb142011-09-22 12:41:58 -05001212 static PNG_CONST png_byte FARDATA png_pass_height[] = {8, 8, 4, 4, 2, 2, 1};
Glenn Randers-Pehrson5379b241999-11-27 10:22:33 -06001213 */
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -06001214
Guy Schalnat6d764711995-12-19 03:22:19 -06001215 png_ptr->row_number++;
1216 if (png_ptr->row_number < png_ptr->num_rows)
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001217 return;
Guy Schalnat6d764711995-12-19 03:22:19 -06001218
Glenn Randers-Pehrsone26c0952009-09-23 11:22:08 -05001219#ifdef PNG_READ_INTERLACING_SUPPORTED
Guy Schalnat6d764711995-12-19 03:22:19 -06001220 if (png_ptr->interlaced)
1221 {
1222 png_ptr->row_number = 0;
Glenn Randers-Pehrsonf24daf22010-05-06 09:44:04 -05001223 png_memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1);
1224
Guy Schalnat6d764711995-12-19 03:22:19 -06001225 do
1226 {
1227 png_ptr->pass++;
Glenn Randers-Pehrsoncdf140b2001-01-15 12:22:32 -06001228 if ((png_ptr->pass == 1 && png_ptr->width < 5) ||
1229 (png_ptr->pass == 3 && png_ptr->width < 3) ||
1230 (png_ptr->pass == 5 && png_ptr->width < 2))
Glenn Randers-Pehrson262d0ff2010-03-03 07:06:54 -06001231 png_ptr->pass++;
Glenn Randers-Pehrsoncdf140b2001-01-15 12:22:32 -06001232
Glenn Randers-Pehrson859665d2002-08-06 18:06:11 -05001233 if (png_ptr->pass > 7)
1234 png_ptr->pass--;
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001235
Guy Schalnat6d764711995-12-19 03:22:19 -06001236 if (png_ptr->pass >= 7)
1237 break;
Glenn Randers-Pehrson5c6aeb21998-12-29 11:47:59 -06001238
Guy Schalnat6d764711995-12-19 03:22:19 -06001239 png_ptr->iwidth = (png_ptr->width +
Glenn Randers-Pehrsonf24daf22010-05-06 09:44:04 -05001240 png_pass_inc[png_ptr->pass] - 1 -
1241 png_pass_start[png_ptr->pass]) /
1242 png_pass_inc[png_ptr->pass];
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -06001243
Guy Schalnat6d764711995-12-19 03:22:19 -06001244 if (png_ptr->transformations & PNG_INTERLACE)
1245 break;
Glenn Randers-Pehrson5c6aeb21998-12-29 11:47:59 -06001246
1247 png_ptr->num_rows = (png_ptr->height +
Glenn Randers-Pehrsonf24daf22010-05-06 09:44:04 -05001248 png_pass_yinc[png_ptr->pass] - 1 -
1249 png_pass_ystart[png_ptr->pass]) /
1250 png_pass_yinc[png_ptr->pass];
Glenn Randers-Pehrson5c6aeb21998-12-29 11:47:59 -06001251
1252 } while (png_ptr->iwidth == 0 || png_ptr->num_rows == 0);
Guy Schalnat6d764711995-12-19 03:22:19 -06001253 }
Glenn Randers-Pehrsona31c74f2009-05-18 15:52:01 -05001254#endif /* PNG_READ_INTERLACING_SUPPORTED */
Guy Schalnat6d764711995-12-19 03:22:19 -06001255}
1256
Glenn Randers-Pehrsone26c0952009-09-23 11:22:08 -05001257#ifdef PNG_READ_tEXt_SUPPORTED
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -05001258void /* PRIVATE */
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -05001259png_push_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32
Glenn Randers-Pehrson262d0ff2010-03-03 07:06:54 -06001260 length)
Guy Schalnat6d764711995-12-19 03:22:19 -06001261{
Glenn Randers-Pehrson520a7642000-03-21 05:13:06 -06001262 if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND))
Glenn Randers-Pehrsona357b991998-02-08 20:56:40 -06001263 {
Glenn Randers-Pehrsond546f432010-12-04 20:41:36 -06001264 PNG_UNUSED(info_ptr) /* To quiet some compiler warnings */
Glenn Randers-Pehrson4009a762010-07-31 06:34:36 -05001265 png_error(png_ptr, "Out of place tEXt");
Glenn Randers-Pehrsonb75b2412011-04-16 19:35:05 -05001266 /* NOT REACHED */
Glenn Randers-Pehrsona357b991998-02-08 20:56:40 -06001267 }
Andreas Dilger02ad0ef1997-01-17 01:34:35 -06001268
Andreas Dilger47a0c421997-05-16 02:46:07 -05001269#ifdef PNG_MAX_MALLOC_64K
1270 png_ptr->skip_length = 0; /* This may not be necessary */
1271
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -05001272 if (length > (png_uint_32)65535L) /* Can't hold entire string in memory */
Andreas Dilger47a0c421997-05-16 02:46:07 -05001273 {
1274 png_warning(png_ptr, "tEXt chunk too large to fit in memory");
Glenn Randers-Pehrsonb6ce43d1998-01-01 07:13:13 -06001275 png_ptr->skip_length = length - (png_uint_32)65535L;
1276 length = (png_uint_32)65535L;
Andreas Dilger47a0c421997-05-16 02:46:07 -05001277 }
1278#endif
1279
Glenn Randers-Pehrson5c6aeb21998-12-29 11:47:59 -06001280 png_ptr->current_text = (png_charp)png_malloc(png_ptr,
Glenn Randers-Pehrson262d0ff2010-03-03 07:06:54 -06001281 (png_size_t)(length + 1));
Andreas Dilger47a0c421997-05-16 02:46:07 -05001282 png_ptr->current_text[length] = '\0';
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001283 png_ptr->current_text_ptr = png_ptr->current_text;
Glenn Randers-Pehrson0f881d61998-02-07 10:20:57 -06001284 png_ptr->current_text_size = (png_size_t)length;
1285 png_ptr->current_text_left = (png_size_t)length;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001286 png_ptr->process_mode = PNG_READ_tEXt_MODE;
Guy Schalnat6d764711995-12-19 03:22:19 -06001287}
1288
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -05001289void /* PRIVATE */
Andreas Dilger02ad0ef1997-01-17 01:34:35 -06001290png_push_read_tEXt(png_structp png_ptr, png_infop info_ptr)
Guy Schalnat6d764711995-12-19 03:22:19 -06001291{
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001292 if (png_ptr->buffer_size && png_ptr->current_text_left)
1293 {
Andreas Dilger47a0c421997-05-16 02:46:07 -05001294 png_size_t text_size;
Guy Schalnat6d764711995-12-19 03:22:19 -06001295
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001296 if (png_ptr->buffer_size < png_ptr->current_text_left)
1297 text_size = png_ptr->buffer_size;
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001298
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001299 else
1300 text_size = png_ptr->current_text_left;
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001301
Andreas Dilger47a0c421997-05-16 02:46:07 -05001302 png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001303 png_ptr->current_text_left -= text_size;
Andreas Dilger47a0c421997-05-16 02:46:07 -05001304 png_ptr->current_text_ptr += text_size;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001305 }
1306 if (!(png_ptr->current_text_left))
1307 {
Andreas Dilger47a0c421997-05-16 02:46:07 -05001308 png_textp text_ptr;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001309 png_charp text;
1310 png_charp key;
Glenn Randers-Pehrson07748d12002-05-25 11:12:10 -05001311 int ret;
Guy Schalnat6d764711995-12-19 03:22:19 -06001312
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001313 if (png_ptr->buffer_size < 4)
1314 {
1315 png_push_save_buffer(png_ptr);
1316 return;
1317 }
Guy Schalnat6d764711995-12-19 03:22:19 -06001318
Andreas Dilger47a0c421997-05-16 02:46:07 -05001319 png_push_crc_finish(png_ptr);
1320
Glenn Randers-Pehrsone26c0952009-09-23 11:22:08 -05001321#ifdef PNG_MAX_MALLOC_64K
Andreas Dilger47a0c421997-05-16 02:46:07 -05001322 if (png_ptr->skip_length)
1323 return;
1324#endif
Guy Schalnat6d764711995-12-19 03:22:19 -06001325
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001326 key = png_ptr->current_text;
Guy Schalnat6d764711995-12-19 03:22:19 -06001327
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001328 for (text = key; *text; text++)
Glenn Randers-Pehrson4bb4d012009-05-20 12:45:29 -05001329 /* Empty loop */ ;
Guy Schalnat6d764711995-12-19 03:22:19 -06001330
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -05001331 if (text < key + png_ptr->current_text_size)
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001332 text++;
1333
Glenn Randers-Pehrsonf24daf22010-05-06 09:44:04 -05001334 text_ptr = (png_textp)png_malloc(png_ptr, png_sizeof(png_text));
Andreas Dilger47a0c421997-05-16 02:46:07 -05001335 text_ptr->compression = PNG_TEXT_COMPRESSION_NONE;
1336 text_ptr->key = key;
Glenn Randers-Pehrsondd78d522010-03-30 08:34:02 -05001337 text_ptr->itxt_length = 0;
Glenn Randers-Pehrson3f549252001-10-27 07:35:13 -05001338 text_ptr->lang = NULL;
1339 text_ptr->lang_key = NULL;
Andreas Dilger47a0c421997-05-16 02:46:07 -05001340 text_ptr->text = text;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001341
Glenn Randers-Pehrson07748d12002-05-25 11:12:10 -05001342 ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
Andreas Dilger47a0c421997-05-16 02:46:07 -05001343
Glenn Randers-Pehrson316f97a2000-07-08 13:19:41 -05001344 png_free(png_ptr, key);
Andreas Dilger47a0c421997-05-16 02:46:07 -05001345 png_free(png_ptr, text_ptr);
Glenn Randers-Pehrsond1e8c862002-06-20 06:54:34 -05001346 png_ptr->current_text = NULL;
Glenn Randers-Pehrson07748d12002-05-25 11:12:10 -05001347
1348 if (ret)
Glenn Randers-Pehrson262d0ff2010-03-03 07:06:54 -06001349 png_warning(png_ptr, "Insufficient memory to store text chunk");
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001350 }
Guy Schalnat6d764711995-12-19 03:22:19 -06001351}
1352#endif
1353
Glenn Randers-Pehrsone26c0952009-09-23 11:22:08 -05001354#ifdef PNG_READ_zTXt_SUPPORTED
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -05001355void /* PRIVATE */
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -05001356png_push_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32
1357 length)
Guy Schalnat6d764711995-12-19 03:22:19 -06001358{
Glenn Randers-Pehrson520a7642000-03-21 05:13:06 -06001359 if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND))
Glenn Randers-Pehrsonf24daf22010-05-06 09:44:04 -05001360 {
Glenn Randers-Pehrsond546f432010-12-04 20:41:36 -06001361 PNG_UNUSED(info_ptr) /* To quiet some compiler warnings */
Glenn Randers-Pehrson4009a762010-07-31 06:34:36 -05001362 png_error(png_ptr, "Out of place zTXt");
Glenn Randers-Pehrsonb75b2412011-04-16 19:35:05 -05001363 /* NOT REACHED */
Glenn Randers-Pehrsonf24daf22010-05-06 09:44:04 -05001364 }
Andreas Dilger02ad0ef1997-01-17 01:34:35 -06001365
Andreas Dilger47a0c421997-05-16 02:46:07 -05001366#ifdef PNG_MAX_MALLOC_64K
1367 /* We can't handle zTXt chunks > 64K, since we don't have enough space
1368 * to be able to store the uncompressed data. Actually, the threshold
1369 * is probably around 32K, but it isn't as definite as 64K is.
1370 */
Glenn Randers-Pehrsonb6ce43d1998-01-01 07:13:13 -06001371 if (length > (png_uint_32)65535L)
Andreas Dilger47a0c421997-05-16 02:46:07 -05001372 {
1373 png_warning(png_ptr, "zTXt chunk too large to fit in memory");
1374 png_push_crc_skip(png_ptr, length);
1375 return;
1376 }
1377#endif
1378
Glenn Randers-Pehrson0f881d61998-02-07 10:20:57 -06001379 png_ptr->current_text = (png_charp)png_malloc(png_ptr,
Glenn Randers-Pehrson262d0ff2010-03-03 07:06:54 -06001380 (png_size_t)(length + 1));
Andreas Dilger47a0c421997-05-16 02:46:07 -05001381 png_ptr->current_text[length] = '\0';
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001382 png_ptr->current_text_ptr = png_ptr->current_text;
Glenn Randers-Pehrson0f881d61998-02-07 10:20:57 -06001383 png_ptr->current_text_size = (png_size_t)length;
1384 png_ptr->current_text_left = (png_size_t)length;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001385 png_ptr->process_mode = PNG_READ_zTXt_MODE;
Guy Schalnat6d764711995-12-19 03:22:19 -06001386}
1387
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -05001388void /* PRIVATE */
Andreas Dilger02ad0ef1997-01-17 01:34:35 -06001389png_push_read_zTXt(png_structp png_ptr, png_infop info_ptr)
Guy Schalnat6d764711995-12-19 03:22:19 -06001390{
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001391 if (png_ptr->buffer_size && png_ptr->current_text_left)
1392 {
Andreas Dilger47a0c421997-05-16 02:46:07 -05001393 png_size_t text_size;
Guy Schalnat6d764711995-12-19 03:22:19 -06001394
Andreas Dilger47a0c421997-05-16 02:46:07 -05001395 if (png_ptr->buffer_size < (png_uint_32)png_ptr->current_text_left)
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001396 text_size = png_ptr->buffer_size;
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001397
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001398 else
1399 text_size = png_ptr->current_text_left;
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001400
Andreas Dilger47a0c421997-05-16 02:46:07 -05001401 png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001402 png_ptr->current_text_left -= text_size;
Andreas Dilger47a0c421997-05-16 02:46:07 -05001403 png_ptr->current_text_ptr += text_size;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001404 }
1405 if (!(png_ptr->current_text_left))
1406 {
Andreas Dilger47a0c421997-05-16 02:46:07 -05001407 png_textp text_ptr;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001408 png_charp text;
1409 png_charp key;
1410 int ret;
Andreas Dilger47a0c421997-05-16 02:46:07 -05001411 png_size_t text_size, key_size;
Guy Schalnat6d764711995-12-19 03:22:19 -06001412
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001413 if (png_ptr->buffer_size < 4)
1414 {
1415 png_push_save_buffer(png_ptr);
1416 return;
1417 }
Guy Schalnat6d764711995-12-19 03:22:19 -06001418
Andreas Dilger47a0c421997-05-16 02:46:07 -05001419 png_push_crc_finish(png_ptr);
Guy Schalnat6d764711995-12-19 03:22:19 -06001420
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001421 key = png_ptr->current_text;
Guy Schalnat6d764711995-12-19 03:22:19 -06001422
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001423 for (text = key; *text; text++)
Glenn Randers-Pehrson4bb4d012009-05-20 12:45:29 -05001424 /* Empty loop */ ;
Guy Schalnat6d764711995-12-19 03:22:19 -06001425
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001426 /* zTXt can't have zero text */
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -05001427 if (text >= key + png_ptr->current_text_size)
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001428 {
Glenn Randers-Pehrsond1e8c862002-06-20 06:54:34 -05001429 png_ptr->current_text = NULL;
Andreas Dilger02ad0ef1997-01-17 01:34:35 -06001430 png_free(png_ptr, key);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001431 return;
1432 }
Guy Schalnat6d764711995-12-19 03:22:19 -06001433
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001434 text++;
Guy Schalnat6d764711995-12-19 03:22:19 -06001435
Glenn Randers-Pehrson4bb4d012009-05-20 12:45:29 -05001436 if (*text != PNG_TEXT_COMPRESSION_zTXt) /* Check compression byte */
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001437 {
Glenn Randers-Pehrsond1e8c862002-06-20 06:54:34 -05001438 png_ptr->current_text = NULL;
Andreas Dilger02ad0ef1997-01-17 01:34:35 -06001439 png_free(png_ptr, key);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001440 return;
1441 }
Guy Schalnat6d764711995-12-19 03:22:19 -06001442
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001443 text++;
Guy Schalnat6d764711995-12-19 03:22:19 -06001444
Glenn Randers-Pehrsonbc363ec2010-10-12 21:17:00 -05001445 png_ptr->zstream.next_in = (png_bytep)text;
Andreas Dilger02ad0ef1997-01-17 01:34:35 -06001446 png_ptr->zstream.avail_in = (uInt)(png_ptr->current_text_size -
Glenn Randers-Pehrson262d0ff2010-03-03 07:06:54 -06001447 (text - key));
Andreas Dilger02ad0ef1997-01-17 01:34:35 -06001448 png_ptr->zstream.next_out = png_ptr->zbuf;
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -06001449 png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
Guy Schalnat6d764711995-12-19 03:22:19 -06001450
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001451 key_size = text - key;
1452 text_size = 0;
1453 text = NULL;
1454 ret = Z_STREAM_END;
Guy Schalnat6d764711995-12-19 03:22:19 -06001455
Andreas Dilger02ad0ef1997-01-17 01:34:35 -06001456 while (png_ptr->zstream.avail_in)
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001457 {
Andreas Dilger02ad0ef1997-01-17 01:34:35 -06001458 ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001459 if (ret != Z_OK && ret != Z_STREAM_END)
1460 {
Andreas Dilger02ad0ef1997-01-17 01:34:35 -06001461 inflateReset(&png_ptr->zstream);
1462 png_ptr->zstream.avail_in = 0;
Glenn Randers-Pehrsond1e8c862002-06-20 06:54:34 -05001463 png_ptr->current_text = NULL;
Andreas Dilger02ad0ef1997-01-17 01:34:35 -06001464 png_free(png_ptr, key);
1465 png_free(png_ptr, text);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001466 return;
1467 }
Glenn Randers-Pehrsonf24daf22010-05-06 09:44:04 -05001468
Andreas Dilger47a0c421997-05-16 02:46:07 -05001469 if (!(png_ptr->zstream.avail_out) || ret == Z_STREAM_END)
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001470 {
Andreas Dilger47a0c421997-05-16 02:46:07 -05001471 if (text == NULL)
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001472 {
Andreas Dilger02ad0ef1997-01-17 01:34:35 -06001473 text = (png_charp)png_malloc(png_ptr,
Glenn Randers-Pehrson262d0ff2010-03-03 07:06:54 -06001474 (png_ptr->zbuf_size
1475 - png_ptr->zstream.avail_out + key_size + 1));
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001476
Glenn Randers-Pehrson82ae3832001-04-20 10:32:10 -05001477 png_memcpy(text + key_size, png_ptr->zbuf,
Glenn Randers-Pehrson262d0ff2010-03-03 07:06:54 -06001478 png_ptr->zbuf_size - png_ptr->zstream.avail_out);
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001479
Glenn Randers-Pehrson82ae3832001-04-20 10:32:10 -05001480 png_memcpy(text, key, key_size);
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001481
Glenn Randers-Pehrson82ae3832001-04-20 10:32:10 -05001482 text_size = key_size + png_ptr->zbuf_size -
Glenn Randers-Pehrson262d0ff2010-03-03 07:06:54 -06001483 png_ptr->zstream.avail_out;
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001484
Glenn Randers-Pehrson82ae3832001-04-20 10:32:10 -05001485 *(text + text_size) = '\0';
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001486 }
Glenn Randers-Pehrsonf24daf22010-05-06 09:44:04 -05001487
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001488 else
1489 {
1490 png_charp tmp;
Guy Schalnat6d764711995-12-19 03:22:19 -06001491
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001492 tmp = text;
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -06001493 text = (png_charp)png_malloc(png_ptr, text_size +
Glenn Randers-Pehrson821b7102010-06-24 16:16:32 -05001494 (png_ptr->zbuf_size
Glenn Randers-Pehrson262d0ff2010-03-03 07:06:54 -06001495 - png_ptr->zstream.avail_out + 1));
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001496
Glenn Randers-Pehrson82ae3832001-04-20 10:32:10 -05001497 png_memcpy(text, tmp, text_size);
1498 png_free(png_ptr, tmp);
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001499
Glenn Randers-Pehrson82ae3832001-04-20 10:32:10 -05001500 png_memcpy(text + text_size, png_ptr->zbuf,
Glenn Randers-Pehrson262d0ff2010-03-03 07:06:54 -06001501 png_ptr->zbuf_size - png_ptr->zstream.avail_out);
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001502
Glenn Randers-Pehrson82ae3832001-04-20 10:32:10 -05001503 text_size += png_ptr->zbuf_size - png_ptr->zstream.avail_out;
1504 *(text + text_size) = '\0';
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001505 }
Glenn Randers-Pehrsonf24daf22010-05-06 09:44:04 -05001506
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001507 if (ret != Z_STREAM_END)
1508 {
Andreas Dilger02ad0ef1997-01-17 01:34:35 -06001509 png_ptr->zstream.next_out = png_ptr->zbuf;
1510 png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001511 }
1512 }
1513 else
1514 {
1515 break;
1516 }
Guy Schalnat6d764711995-12-19 03:22:19 -06001517
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001518 if (ret == Z_STREAM_END)
1519 break;
1520 }
Guy Schalnat6d764711995-12-19 03:22:19 -06001521
Andreas Dilger02ad0ef1997-01-17 01:34:35 -06001522 inflateReset(&png_ptr->zstream);
1523 png_ptr->zstream.avail_in = 0;
Guy Schalnat6d764711995-12-19 03:22:19 -06001524
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001525 if (ret != Z_STREAM_END)
1526 {
Glenn Randers-Pehrsond1e8c862002-06-20 06:54:34 -05001527 png_ptr->current_text = NULL;
Andreas Dilger02ad0ef1997-01-17 01:34:35 -06001528 png_free(png_ptr, key);
1529 png_free(png_ptr, text);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001530 return;
1531 }
Guy Schalnat6d764711995-12-19 03:22:19 -06001532
Glenn Randers-Pehrsond1e8c862002-06-20 06:54:34 -05001533 png_ptr->current_text = NULL;
Andreas Dilger02ad0ef1997-01-17 01:34:35 -06001534 png_free(png_ptr, key);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001535 key = text;
Andreas Dilger47a0c421997-05-16 02:46:07 -05001536 text += key_size;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001537
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -05001538 text_ptr = (png_textp)png_malloc(png_ptr,
1539 png_sizeof(png_text));
Glenn Randers-Pehrson82ae3832001-04-20 10:32:10 -05001540 text_ptr->compression = PNG_TEXT_COMPRESSION_zTXt;
1541 text_ptr->key = key;
Glenn Randers-Pehrsondd78d522010-03-30 08:34:02 -05001542 text_ptr->itxt_length = 0;
Glenn Randers-Pehrson3f549252001-10-27 07:35:13 -05001543 text_ptr->lang = NULL;
1544 text_ptr->lang_key = NULL;
Glenn Randers-Pehrson82ae3832001-04-20 10:32:10 -05001545 text_ptr->text = text;
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -06001546
Glenn Randers-Pehrson07748d12002-05-25 11:12:10 -05001547 ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -06001548
Glenn Randers-Pehrson316f97a2000-07-08 13:19:41 -05001549 png_free(png_ptr, key);
Glenn Randers-Pehrson82ae3832001-04-20 10:32:10 -05001550 png_free(png_ptr, text_ptr);
Glenn Randers-Pehrson07748d12002-05-25 11:12:10 -05001551
1552 if (ret)
Glenn Randers-Pehrson262d0ff2010-03-03 07:06:54 -06001553 png_warning(png_ptr, "Insufficient memory to store text chunk");
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -06001554 }
1555}
1556#endif
1557
Glenn Randers-Pehrsone26c0952009-09-23 11:22:08 -05001558#ifdef PNG_READ_iTXt_SUPPORTED
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -05001559void /* PRIVATE */
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -05001560png_push_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32
Glenn Randers-Pehrson262d0ff2010-03-03 07:06:54 -06001561 length)
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -06001562{
Glenn Randers-Pehrson520a7642000-03-21 05:13:06 -06001563 if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND))
Glenn Randers-Pehrsonf24daf22010-05-06 09:44:04 -05001564 {
Glenn Randers-Pehrsond546f432010-12-04 20:41:36 -06001565 PNG_UNUSED(info_ptr) /* To quiet some compiler warnings */
Glenn Randers-Pehrson4009a762010-07-31 06:34:36 -05001566 png_error(png_ptr, "Out of place iTXt");
Glenn Randers-Pehrsonb75b2412011-04-16 19:35:05 -05001567 /* NOT REACHED */
Glenn Randers-Pehrsonf24daf22010-05-06 09:44:04 -05001568 }
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -06001569
1570#ifdef PNG_MAX_MALLOC_64K
1571 png_ptr->skip_length = 0; /* This may not be necessary */
1572
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -05001573 if (length > (png_uint_32)65535L) /* Can't hold entire string in memory */
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -06001574 {
1575 png_warning(png_ptr, "iTXt chunk too large to fit in memory");
1576 png_ptr->skip_length = length - (png_uint_32)65535L;
1577 length = (png_uint_32)65535L;
1578 }
1579#endif
1580
1581 png_ptr->current_text = (png_charp)png_malloc(png_ptr,
Glenn Randers-Pehrson262d0ff2010-03-03 07:06:54 -06001582 (png_size_t)(length + 1));
Glenn Randers-Pehrson82ae3832001-04-20 10:32:10 -05001583 png_ptr->current_text[length] = '\0';
1584 png_ptr->current_text_ptr = png_ptr->current_text;
1585 png_ptr->current_text_size = (png_size_t)length;
1586 png_ptr->current_text_left = (png_size_t)length;
1587 png_ptr->process_mode = PNG_READ_iTXt_MODE;
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -06001588}
1589
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -05001590void /* PRIVATE */
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -06001591png_push_read_iTXt(png_structp png_ptr, png_infop info_ptr)
1592{
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -06001593
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -06001594 if (png_ptr->buffer_size && png_ptr->current_text_left)
1595 {
1596 png_size_t text_size;
1597
1598 if (png_ptr->buffer_size < png_ptr->current_text_left)
1599 text_size = png_ptr->buffer_size;
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001600
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -06001601 else
1602 text_size = png_ptr->current_text_left;
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001603
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -06001604 png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size);
1605 png_ptr->current_text_left -= text_size;
1606 png_ptr->current_text_ptr += text_size;
1607 }
Glenn Randers-Pehrsonf24daf22010-05-06 09:44:04 -05001608
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -06001609 if (!(png_ptr->current_text_left))
1610 {
1611 png_textp text_ptr;
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -06001612 png_charp key;
Glenn Randers-Pehrson520a7642000-03-21 05:13:06 -06001613 int comp_flag;
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -06001614 png_charp lang;
1615 png_charp lang_key;
1616 png_charp text;
Glenn Randers-Pehrson07748d12002-05-25 11:12:10 -05001617 int ret;
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -06001618
1619 if (png_ptr->buffer_size < 4)
1620 {
1621 png_push_save_buffer(png_ptr);
1622 return;
1623 }
1624
1625 png_push_crc_finish(png_ptr);
1626
Glenn Randers-Pehrsone26c0952009-09-23 11:22:08 -05001627#ifdef PNG_MAX_MALLOC_64K
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -06001628 if (png_ptr->skip_length)
1629 return;
1630#endif
1631
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -06001632 key = png_ptr->current_text;
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -06001633
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -06001634 for (lang = key; *lang; lang++)
Glenn Randers-Pehrson4bb4d012009-05-20 12:45:29 -05001635 /* Empty loop */ ;
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -06001636
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -05001637 if (lang < key + png_ptr->current_text_size - 3)
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -06001638 lang++;
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -06001639
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -06001640 comp_flag = *lang++;
Glenn Randers-Pehrson4bb4d012009-05-20 12:45:29 -05001641 lang++; /* Skip comp_type, always zero */
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -06001642
1643 for (lang_key = lang; *lang_key; lang_key++)
Glenn Randers-Pehrson4bb4d012009-05-20 12:45:29 -05001644 /* Empty loop */ ;
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001645
Glenn Randers-Pehrson4bb4d012009-05-20 12:45:29 -05001646 lang_key++; /* Skip NUL separator */
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -06001647
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -05001648 text=lang_key;
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001649
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -05001650 if (lang_key < key + png_ptr->current_text_size - 1)
1651 {
Glenn Randers-Pehrson262d0ff2010-03-03 07:06:54 -06001652 for (; *text; text++)
1653 /* Empty loop */ ;
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -05001654 }
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -06001655
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -05001656 if (text < key + png_ptr->current_text_size)
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -06001657 text++;
1658
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -05001659 text_ptr = (png_textp)png_malloc(png_ptr,
Glenn Randers-Pehrson262d0ff2010-03-03 07:06:54 -06001660 png_sizeof(png_text));
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001661
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -06001662 text_ptr->compression = comp_flag + 2;
Andreas Dilger47a0c421997-05-16 02:46:07 -05001663 text_ptr->key = key;
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -06001664 text_ptr->lang = lang;
1665 text_ptr->lang_key = lang_key;
Andreas Dilger47a0c421997-05-16 02:46:07 -05001666 text_ptr->text = text;
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -06001667 text_ptr->text_length = 0;
1668 text_ptr->itxt_length = png_strlen(text);
Andreas Dilger47a0c421997-05-16 02:46:07 -05001669
Glenn Randers-Pehrson07748d12002-05-25 11:12:10 -05001670 ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
Andreas Dilger47a0c421997-05-16 02:46:07 -05001671
Glenn Randers-Pehrsond1e8c862002-06-20 06:54:34 -05001672 png_ptr->current_text = NULL;
1673
Andreas Dilger47a0c421997-05-16 02:46:07 -05001674 png_free(png_ptr, text_ptr);
Glenn Randers-Pehrson07748d12002-05-25 11:12:10 -05001675 if (ret)
Glenn Randers-Pehrsonf81b50b2009-12-29 16:50:15 -06001676 png_warning(png_ptr, "Insufficient memory to store iTXt chunk");
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001677 }
Guy Schalnat6d764711995-12-19 03:22:19 -06001678}
1679#endif
1680
Andreas Dilger02ad0ef1997-01-17 01:34:35 -06001681/* This function is called when we haven't found a handler for this
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -06001682 * chunk. If there isn't a problem with the chunk itself (ie a bad chunk
1683 * name or a critical chunk), the chunk is (currently) silently ignored.
Glenn Randers-Pehrsonb6ce43d1998-01-01 07:13:13 -06001684 */
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -05001685void /* PRIVATE */
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -05001686png_push_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32
Glenn Randers-Pehrson262d0ff2010-03-03 07:06:54 -06001687 length)
Guy Schalnat6d764711995-12-19 03:22:19 -06001688{
Glenn Randers-Pehrson895a9c92008-07-25 08:51:18 -05001689 png_uint_32 skip = 0;
Glenn Randers-Pehrsonbb5cb142011-09-22 12:41:58 -05001690 png_uint_32 chunk_name = png_ptr->chunk_name;
Andreas Dilger02ad0ef1997-01-17 01:34:35 -06001691
Glenn Randers-Pehrsonbb5cb142011-09-22 12:41:58 -05001692 if (PNG_CHUNK_CRITICAL(chunk_name))
Andreas Dilger02ad0ef1997-01-17 01:34:35 -06001693 {
Glenn Randers-Pehrsone26c0952009-09-23 11:22:08 -05001694#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
Glenn Randers-Pehrsonbb5cb142011-09-22 12:41:58 -05001695 if (png_chunk_unknown_handling(png_ptr, chunk_name) !=
Glenn Randers-Pehrson262d0ff2010-03-03 07:06:54 -06001696 PNG_HANDLE_CHUNK_ALWAYS
Glenn Randers-Pehrsone26c0952009-09-23 11:22:08 -05001697#ifdef PNG_READ_USER_CHUNKS_SUPPORTED
Glenn Randers-Pehrson262d0ff2010-03-03 07:06:54 -06001698 && png_ptr->read_user_chunk_fn == NULL
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -06001699#endif
Glenn Randers-Pehrson262d0ff2010-03-03 07:06:54 -06001700 )
Glenn Randers-Pehrson6942d532000-05-01 09:31:54 -05001701#endif
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -06001702 png_chunk_error(png_ptr, "unknown critical chunk");
1703
Glenn Randers-Pehrsond546f432010-12-04 20:41:36 -06001704 PNG_UNUSED(info_ptr) /* To quiet some compiler warnings */
Andreas Dilger02ad0ef1997-01-17 01:34:35 -06001705 }
1706
Glenn Randers-Pehrsone26c0952009-09-23 11:22:08 -05001707#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
Glenn Randers-Pehrsonbb5cb142011-09-22 12:41:58 -05001708 /* TODO: the code below is apparently just using the
1709 * png_struct::unknown_chunk member as a temporarily variable, it should be
1710 * possible to eliminate both it and the temporary buffer.
1711 */
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -06001712 if (png_ptr->flags & PNG_FLAG_KEEP_UNKNOWN_CHUNKS)
1713 {
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -06001714#ifdef PNG_MAX_MALLOC_64K
Glenn Randers-Pehrsonbb5cb142011-09-22 12:41:58 -05001715 if (length > 65535)
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -05001716 {
Glenn Randers-Pehrson262d0ff2010-03-03 07:06:54 -06001717 png_warning(png_ptr, "unknown chunk too large to fit in memory");
Glenn Randers-Pehrsonbb5cb142011-09-22 12:41:58 -05001718 skip = length - 65535;
1719 length = 65535;
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -05001720 }
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -06001721#endif
Glenn Randers-Pehrsonbb5cb142011-09-22 12:41:58 -05001722 /* This is just a record for the user; libpng doesn't use the character
1723 * form of the name.
1724 */
1725 PNG_CSTRING_FROM_CHUNK(png_ptr->unknown_chunk.name, png_ptr->chunk_name);
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -06001726
Glenn Randers-Pehrsonbb5cb142011-09-22 12:41:58 -05001727 /* The following cast should be safe because of the check above. */
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -05001728 png_ptr->unknown_chunk.size = (png_size_t)length;
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001729
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -05001730 if (length == 0)
1731 png_ptr->unknown_chunk.data = NULL;
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001732
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -05001733 else
1734 {
1735 png_ptr->unknown_chunk.data = (png_bytep)png_malloc(png_ptr,
Glenn Randers-Pehrsonbb5cb142011-09-22 12:41:58 -05001736 png_ptr->unknown_chunk.size);
1737 png_crc_read(png_ptr, (png_bytep)png_ptr->unknown_chunk.data,
1738 png_ptr->unknown_chunk.size);
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -05001739 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001740
Glenn Randers-Pehrsone26c0952009-09-23 11:22:08 -05001741#ifdef PNG_READ_USER_CHUNKS_SUPPORTED
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -05001742 if (png_ptr->read_user_chunk_fn != NULL)
1743 {
Glenn Randers-Pehrson4bb4d012009-05-20 12:45:29 -05001744 /* Callback to user unknown chunk handler */
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -05001745 int ret;
1746 ret = (*(png_ptr->read_user_chunk_fn))
Glenn Randers-Pehrson262d0ff2010-03-03 07:06:54 -06001747 (png_ptr, &png_ptr->unknown_chunk);
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001748
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -05001749 if (ret < 0)
1750 png_chunk_error(png_ptr, "error in user chunk");
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001751
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -05001752 if (ret == 0)
1753 {
Glenn Randers-Pehrsonbb5cb142011-09-22 12:41:58 -05001754 if (PNG_CHUNK_CRITICAL(png_ptr->chunk_name))
1755 if (png_chunk_unknown_handling(png_ptr, chunk_name) !=
Glenn Randers-Pehrson262d0ff2010-03-03 07:06:54 -06001756 PNG_HANDLE_CHUNK_ALWAYS)
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -05001757 png_chunk_error(png_ptr, "unknown critical chunk");
1758 png_set_unknown_chunks(png_ptr, info_ptr,
Glenn Randers-Pehrson262d0ff2010-03-03 07:06:54 -06001759 &png_ptr->unknown_chunk, 1);
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -05001760 }
1761 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001762
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -05001763 else
Glenn Randers-Pehrson82ae3832001-04-20 10:32:10 -05001764#endif
Glenn Randers-Pehrson262d0ff2010-03-03 07:06:54 -06001765 png_set_unknown_chunks(png_ptr, info_ptr, &png_ptr->unknown_chunk, 1);
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -05001766 png_free(png_ptr, png_ptr->unknown_chunk.data);
1767 png_ptr->unknown_chunk.data = NULL;
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -06001768 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001769
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -06001770 else
1771#endif
1772 skip=length;
1773 png_push_crc_skip(png_ptr, skip);
Guy Schalnat6d764711995-12-19 03:22:19 -06001774}
1775
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -05001776void /* PRIVATE */
Andreas Dilger02ad0ef1997-01-17 01:34:35 -06001777png_push_have_info(png_structp png_ptr, png_infop info_ptr)
1778{
Andreas Dilger47a0c421997-05-16 02:46:07 -05001779 if (png_ptr->info_fn != NULL)
Andreas Dilger02ad0ef1997-01-17 01:34:35 -06001780 (*(png_ptr->info_fn))(png_ptr, info_ptr);
1781}
1782
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -05001783void /* PRIVATE */
Andreas Dilger02ad0ef1997-01-17 01:34:35 -06001784png_push_have_end(png_structp png_ptr, png_infop info_ptr)
Guy Schalnat6d764711995-12-19 03:22:19 -06001785{
Andreas Dilger47a0c421997-05-16 02:46:07 -05001786 if (png_ptr->end_fn != NULL)
Andreas Dilger02ad0ef1997-01-17 01:34:35 -06001787 (*(png_ptr->end_fn))(png_ptr, info_ptr);
Guy Schalnat6d764711995-12-19 03:22:19 -06001788}
1789
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -05001790void /* PRIVATE */
Guy Schalnat6d764711995-12-19 03:22:19 -06001791png_push_have_row(png_structp png_ptr, png_bytep row)
1792{
Glenn Randers-Pehrson78d55452010-06-19 07:03:50 -05001793 if (png_ptr->row_fn != NULL)
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001794 (*(png_ptr->row_fn))(png_ptr, row, png_ptr->row_number,
1795 (int)png_ptr->pass);
Guy Schalnat6d764711995-12-19 03:22:19 -06001796}
1797
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -05001798void PNGAPI
Glenn Randers-Pehrsone600c512010-08-18 07:25:46 -05001799png_progressive_combine_row (png_structp png_ptr, png_bytep old_row,
1800 png_const_bytep new_row)
Guy Schalnat6d764711995-12-19 03:22:19 -06001801{
Glenn Randers-Pehrsonbb5cb142011-09-22 12:41:58 -05001802 static PNG_CONST png_byte FARDATA png_pass_dsp_mask[7] =
Glenn Randers-Pehrson5e5c1e12000-11-10 12:26:19 -06001803 {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, 0xff};
Glenn Randers-Pehrson86312502009-08-31 14:17:23 -05001804
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001805 if (png_ptr == NULL)
1806 return;
1807
Glenn Randers-Pehrson345bc271998-06-14 14:43:31 -05001808 if (new_row != NULL) /* new_row must == png_ptr->row_buf here. */
Andreas Dilger02ad0ef1997-01-17 01:34:35 -06001809 png_combine_row(png_ptr, old_row, png_pass_dsp_mask[png_ptr->pass]);
Guy Schalnat6d764711995-12-19 03:22:19 -06001810}
1811
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -05001812void PNGAPI
Guy Schalnat6d764711995-12-19 03:22:19 -06001813png_set_progressive_read_fn(png_structp png_ptr, png_voidp progressive_ptr,
Glenn Randers-Pehrson262d0ff2010-03-03 07:06:54 -06001814 png_progressive_info_ptr info_fn, png_progressive_row_ptr row_fn,
1815 png_progressive_end_ptr end_fn)
Guy Schalnat6d764711995-12-19 03:22:19 -06001816{
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001817 if (png_ptr == NULL)
1818 return;
1819
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001820 png_ptr->info_fn = info_fn;
1821 png_ptr->row_fn = row_fn;
Guy Schalnat6d764711995-12-19 03:22:19 -06001822 png_ptr->end_fn = end_fn;
Guy Schalnate5a37791996-06-05 15:50:50 -05001823
Glenn Randers-Pehrson25d82242002-05-01 11:51:26 -05001824 png_set_read_fn(png_ptr, progressive_ptr, png_push_fill_buffer);
Guy Schalnat6d764711995-12-19 03:22:19 -06001825}
1826
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -05001827png_voidp PNGAPI
John Bowler0a5c9c02011-01-22 17:36:34 -06001828png_get_progressive_ptr(png_const_structp png_ptr)
Guy Schalnat6d764711995-12-19 03:22:19 -06001829{
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001830 if (png_ptr == NULL)
1831 return (NULL);
1832
Andreas Dilger02ad0ef1997-01-17 01:34:35 -06001833 return png_ptr->io_ptr;
Guy Schalnat6d764711995-12-19 03:22:19 -06001834}
Guy Schalnat4ee97b01996-01-16 01:51:56 -06001835#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */