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