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