ReactOS 0.4.16-dev-2613-g9533ad7
pngpread.c
Go to the documentation of this file.
1/* pngpread.c - read a png file in push mode
2 *
3 * Copyright (c) 2018-2025 Cosmin Truta
4 * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
5 * Copyright (c) 1996-1997 Andreas Dilger
6 * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
7 *
8 * This code is released under the libpng license.
9 * For conditions of distribution and use, see the disclaimer
10 * and license in png.h
11 */
12
13#include "pngpriv.h"
14
15#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
16
17/* Push model modes */
18#define PNG_READ_SIG_MODE 0
19#define PNG_READ_CHUNK_MODE 1
20#define PNG_READ_IDAT_MODE 2
21#define PNG_READ_tEXt_MODE 4
22#define PNG_READ_zTXt_MODE 5
23#define PNG_READ_DONE_MODE 6
24#define PNG_READ_iTXt_MODE 7
25#define PNG_ERROR_MODE 8
26
27#define PNG_PUSH_SAVE_BUFFER_IF_FULL \
28if (png_ptr->push_length + 4 > png_ptr->buffer_size) \
29 { png_push_save_buffer(png_ptr); return; }
30#define PNG_PUSH_SAVE_BUFFER_IF_LT(N) \
31if (png_ptr->buffer_size < N) \
32 { png_push_save_buffer(png_ptr); return; }
33
34#ifdef PNG_READ_INTERLACING_SUPPORTED
35/* Arrays to facilitate interlacing - use pass (0 - 6) as index. */
36
37/* Start of interlace block */
38static const png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
39/* Offset to next interlace block */
40static const png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
41/* Start of interlace block in the y direction */
42static const png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
43/* Offset to next interlace block in the y direction */
44static const png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
45
46/* TODO: Move these arrays to a common utility module to avoid duplication. */
47#endif
48
49void PNGAPI
50png_process_data(png_structrp png_ptr, png_inforp info_ptr,
52{
53 if (png_ptr == NULL || info_ptr == NULL)
54 return;
55
56 png_push_restore_buffer(png_ptr, buffer, buffer_size);
57
58 while (png_ptr->buffer_size)
59 {
60 png_process_some_data(png_ptr, info_ptr);
61 }
62}
63
64size_t PNGAPI
65png_process_data_pause(png_structrp png_ptr, int save)
66{
67 if (png_ptr != NULL)
68 {
69 /* It's easiest for the caller if we do the save; then the caller doesn't
70 * have to supply the same data again:
71 */
72 if (save != 0)
73 png_push_save_buffer(png_ptr);
74 else
75 {
76 /* This includes any pending saved bytes: */
77 size_t remaining = png_ptr->buffer_size;
78 png_ptr->buffer_size = 0;
79
80 /* So subtract the saved buffer size, unless all the data
81 * is actually 'saved', in which case we just return 0
82 */
83 if (png_ptr->save_buffer_size < remaining)
84 return remaining - png_ptr->save_buffer_size;
85 }
86 }
87
88 return 0;
89}
90
92png_process_data_skip(png_structrp png_ptr)
93{
94/* TODO: Deprecate and remove this API.
95 * Somewhere the implementation of this seems to have been lost,
96 * or abandoned. It was only to support some internal back-door access
97 * to png_struct) in libpng-1.4.x.
98 */
100"png_process_data_skip is not implemented in any current version of libpng");
101 return 0;
102}
103
104/* What we do with the incoming data depends on what we were previously
105 * doing before we ran out of data...
106 */
107void /* PRIVATE */
108png_process_some_data(png_structrp png_ptr, png_inforp info_ptr)
109{
110 if (png_ptr == NULL)
111 return;
112
113 switch (png_ptr->process_mode)
114 {
115 case PNG_READ_SIG_MODE:
116 {
117 png_push_read_sig(png_ptr, info_ptr);
118 break;
119 }
120
121 case PNG_READ_CHUNK_MODE:
122 {
123 png_push_read_chunk(png_ptr, info_ptr);
124 break;
125 }
126
127 case PNG_READ_IDAT_MODE:
128 {
129 png_push_read_IDAT(png_ptr);
130 break;
131 }
132
133 default:
134 {
135 png_ptr->buffer_size = 0;
136 break;
137 }
138 }
139}
140
141/* Read any remaining signature bytes from the stream and compare them with
142 * the correct PNG signature. It is possible that this routine is called
143 * with bytes already read from the signature, either because they have been
144 * checked by the calling application, or because of multiple calls to this
145 * routine.
146 */
147void /* PRIVATE */
148png_push_read_sig(png_structrp png_ptr, png_inforp info_ptr)
149{
150 size_t num_checked = png_ptr->sig_bytes; /* SAFE, does not exceed 8 */
151 size_t num_to_check = 8 - num_checked;
152
153 if (png_ptr->buffer_size < num_to_check)
154 {
155 num_to_check = png_ptr->buffer_size;
156 }
157
158 png_push_fill_buffer(png_ptr, &(info_ptr->signature[num_checked]),
159 num_to_check);
160 png_ptr->sig_bytes = (png_byte)(png_ptr->sig_bytes + num_to_check);
161
162 if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check) != 0)
163 {
164 if (num_checked < 4 &&
165 png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4) != 0)
166 png_error(png_ptr, "Not a PNG file");
167
168 else
169 png_error(png_ptr, "PNG file corrupted by ASCII conversion");
170 }
171 else
172 {
173 if (png_ptr->sig_bytes >= 8)
174 {
175 png_ptr->process_mode = PNG_READ_CHUNK_MODE;
176 }
177 }
178}
179
180void /* PRIVATE */
181png_push_read_chunk(png_structrp png_ptr, png_inforp info_ptr)
182{
183 png_uint_32 chunk_name;
184#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
185 int keep; /* unknown handling method */
186#endif
187
188 /* First we make sure we have enough data for the 4-byte chunk name
189 * and the 4-byte chunk length before proceeding with decoding the
190 * chunk data. To fully decode each of these chunks, we also make
191 * sure we have enough data in the buffer for the 4-byte CRC at the
192 * end of every chunk (except IDAT, which is handled separately).
193 */
194 if ((png_ptr->mode & PNG_HAVE_CHUNK_HEADER) == 0)
195 {
196 PNG_PUSH_SAVE_BUFFER_IF_LT(8)
197 png_ptr->push_length = png_read_chunk_header(png_ptr);
199 }
200
201 chunk_name = png_ptr->chunk_name;
202
203 if (chunk_name == png_IDAT)
204 {
205 if ((png_ptr->mode & PNG_AFTER_IDAT) != 0)
207
208 /* If we reach an IDAT chunk, this means we have read all of the
209 * header chunks, and we can start reading the image (or if this
210 * is called after the image has been read - we have an error).
211 */
212 if ((png_ptr->mode & PNG_HAVE_IHDR) == 0)
213 png_error(png_ptr, "Missing IHDR before IDAT");
214
215 else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
216 (png_ptr->mode & PNG_HAVE_PLTE) == 0)
217 png_error(png_ptr, "Missing PLTE before IDAT");
218
219 png_ptr->process_mode = PNG_READ_IDAT_MODE;
220
221 if ((png_ptr->mode & PNG_HAVE_IDAT) != 0)
222 if ((png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT) == 0)
223 if (png_ptr->push_length == 0)
224 return;
225
226 png_ptr->mode |= PNG_HAVE_IDAT;
227
228 if ((png_ptr->mode & PNG_AFTER_IDAT) != 0)
229 png_benign_error(png_ptr, "Too many IDATs found");
230 }
231
232 else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0)
233 {
234 /* These flags must be set consistently for all non-IDAT chunks,
235 * including the unknown chunks.
236 */
238 }
239
240 if (chunk_name == png_IHDR)
241 {
242 if (png_ptr->push_length != 13)
243 png_error(png_ptr, "Invalid IHDR length");
244
245 PNG_PUSH_SAVE_BUFFER_IF_FULL
246 png_handle_chunk(png_ptr, info_ptr, png_ptr->push_length);
247 }
248
249 else if (chunk_name == png_IEND)
250 {
251 PNG_PUSH_SAVE_BUFFER_IF_FULL
252 png_handle_chunk(png_ptr, info_ptr, png_ptr->push_length);
253
254 png_ptr->process_mode = PNG_READ_DONE_MODE;
255 png_push_have_end(png_ptr, info_ptr);
256 }
257
258#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
259 else if ((keep = png_chunk_unknown_handling(png_ptr, chunk_name)) != 0)
260 {
261 PNG_PUSH_SAVE_BUFFER_IF_FULL
262 png_handle_unknown(png_ptr, info_ptr, png_ptr->push_length, keep);
263
264 if (chunk_name == png_PLTE)
265 png_ptr->mode |= PNG_HAVE_PLTE;
266 }
267#endif
268
269 else if (chunk_name == png_IDAT)
270 {
271 png_ptr->idat_size = png_ptr->push_length;
272 png_ptr->process_mode = PNG_READ_IDAT_MODE;
273 png_push_have_info(png_ptr, info_ptr);
274 png_ptr->zstream.avail_out =
275 (uInt) PNG_ROWBYTES(png_ptr->pixel_depth,
276 png_ptr->iwidth) + 1;
277 png_ptr->zstream.next_out = png_ptr->row_buf;
278 return;
279 }
280
281 else
282 {
283 PNG_PUSH_SAVE_BUFFER_IF_FULL
284 png_handle_chunk(png_ptr, info_ptr, png_ptr->push_length);
285 }
286
287 png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
288}
289
290void PNGCBAPI
291png_push_fill_buffer(png_structp png_ptr, png_bytep buffer, size_t length)
292{
294
295 if (png_ptr == NULL)
296 return;
297
298 ptr = buffer;
299 if (png_ptr->save_buffer_size != 0)
300 {
301 size_t save_size;
302
303 if (length < png_ptr->save_buffer_size)
304 save_size = length;
305
306 else
307 save_size = png_ptr->save_buffer_size;
308
309 memcpy(ptr, png_ptr->save_buffer_ptr, save_size);
310 length -= save_size;
311 ptr += save_size;
312 png_ptr->buffer_size -= save_size;
313 png_ptr->save_buffer_size -= save_size;
314 png_ptr->save_buffer_ptr += save_size;
315 }
316 if (length != 0 && png_ptr->current_buffer_size != 0)
317 {
318 size_t save_size;
319
320 if (length < png_ptr->current_buffer_size)
321 save_size = length;
322
323 else
324 save_size = png_ptr->current_buffer_size;
325
326 memcpy(ptr, png_ptr->current_buffer_ptr, save_size);
327 png_ptr->buffer_size -= save_size;
328 png_ptr->current_buffer_size -= save_size;
329 png_ptr->current_buffer_ptr += save_size;
330 }
331}
332
333void /* PRIVATE */
334png_push_save_buffer(png_structrp png_ptr)
335{
336 if (png_ptr->save_buffer_size != 0)
337 {
338 if (png_ptr->save_buffer_ptr != png_ptr->save_buffer)
339 {
340 size_t i, istop;
342 png_bytep dp;
343
344 istop = png_ptr->save_buffer_size;
345 for (i = 0, sp = png_ptr->save_buffer_ptr, dp = png_ptr->save_buffer;
346 i < istop; i++, sp++, dp++)
347 {
348 *dp = *sp;
349 }
350 }
351 }
352 if (png_ptr->save_buffer_size + png_ptr->current_buffer_size >
353 png_ptr->save_buffer_max)
354 {
355 size_t new_max;
356 png_bytep old_buffer;
357
358 if (png_ptr->save_buffer_size > PNG_SIZE_MAX -
359 (png_ptr->current_buffer_size + 256))
360 {
361 png_error(png_ptr, "Potential overflow of save_buffer");
362 }
363
364 new_max = png_ptr->save_buffer_size + png_ptr->current_buffer_size + 256;
365 old_buffer = png_ptr->save_buffer;
366 png_ptr->save_buffer = (png_bytep)png_malloc_warn(png_ptr,
367 (size_t)new_max);
368
369 if (png_ptr->save_buffer == NULL)
370 {
371 png_free(png_ptr, old_buffer);
372 png_error(png_ptr, "Insufficient memory for save_buffer");
373 }
374
375 if (old_buffer)
376 memcpy(png_ptr->save_buffer, old_buffer, png_ptr->save_buffer_size);
377 else if (png_ptr->save_buffer_size)
378 png_error(png_ptr, "save_buffer error");
379 png_free(png_ptr, old_buffer);
380 png_ptr->save_buffer_max = new_max;
381 }
382 if (png_ptr->current_buffer_size)
383 {
384 memcpy(png_ptr->save_buffer + png_ptr->save_buffer_size,
385 png_ptr->current_buffer_ptr, png_ptr->current_buffer_size);
386 png_ptr->save_buffer_size += png_ptr->current_buffer_size;
387 png_ptr->current_buffer_size = 0;
388 }
389 png_ptr->save_buffer_ptr = png_ptr->save_buffer;
390 png_ptr->buffer_size = 0;
391}
392
393void /* PRIVATE */
394png_push_restore_buffer(png_structrp png_ptr, png_bytep buffer,
395 size_t buffer_length)
396{
397 png_ptr->current_buffer = buffer;
398 png_ptr->current_buffer_size = buffer_length;
399 png_ptr->buffer_size = buffer_length + png_ptr->save_buffer_size;
400 png_ptr->current_buffer_ptr = png_ptr->current_buffer;
401}
402
403void /* PRIVATE */
404png_push_read_IDAT(png_structrp png_ptr)
405{
406 if ((png_ptr->mode & PNG_HAVE_CHUNK_HEADER) == 0)
407 {
408 png_byte chunk_length[4];
409 png_byte chunk_tag[4];
410
411 /* TODO: this code can be commoned up with the same code in push_read */
412 PNG_PUSH_SAVE_BUFFER_IF_LT(8)
413 png_push_fill_buffer(png_ptr, chunk_length, 4);
414 png_ptr->push_length = png_get_uint_31(png_ptr, chunk_length);
415 png_reset_crc(png_ptr);
416 png_crc_read(png_ptr, chunk_tag, 4);
417 png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(chunk_tag);
419
420 if (png_ptr->chunk_name != png_IDAT)
421 {
422 png_ptr->process_mode = PNG_READ_CHUNK_MODE;
423
424 if ((png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED) == 0)
425 png_error(png_ptr, "Not enough compressed data");
426
427 return;
428 }
429
430 png_ptr->idat_size = png_ptr->push_length;
431 }
432
433 if (png_ptr->idat_size != 0 && png_ptr->save_buffer_size != 0)
434 {
435 size_t save_size = png_ptr->save_buffer_size;
436 png_uint_32 idat_size = png_ptr->idat_size;
437
438 /* We want the smaller of 'idat_size' and 'current_buffer_size', but they
439 * are of different types and we don't know which variable has the fewest
440 * bits. Carefully select the smaller and cast it to the type of the
441 * larger - this cannot overflow. Do not cast in the following test - it
442 * will break on either 16-bit or 64-bit platforms.
443 */
444 if (idat_size < save_size)
445 save_size = (size_t)idat_size;
446
447 else
448 idat_size = (png_uint_32)save_size;
449
450 png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size);
451
452 png_process_IDAT_data(png_ptr, png_ptr->save_buffer_ptr, save_size);
453
454 png_ptr->idat_size -= idat_size;
455 png_ptr->buffer_size -= save_size;
456 png_ptr->save_buffer_size -= save_size;
457 png_ptr->save_buffer_ptr += save_size;
458 }
459
460 if (png_ptr->idat_size != 0 && png_ptr->current_buffer_size != 0)
461 {
462 size_t save_size = png_ptr->current_buffer_size;
463 png_uint_32 idat_size = png_ptr->idat_size;
464
465 /* We want the smaller of 'idat_size' and 'current_buffer_size', but they
466 * are of different types and we don't know which variable has the fewest
467 * bits. Carefully select the smaller and cast it to the type of the
468 * larger - this cannot overflow.
469 */
470 if (idat_size < save_size)
471 save_size = (size_t)idat_size;
472
473 else
474 idat_size = (png_uint_32)save_size;
475
476 png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size);
477
478 png_process_IDAT_data(png_ptr, png_ptr->current_buffer_ptr, save_size);
479
480 png_ptr->idat_size -= idat_size;
481 png_ptr->buffer_size -= save_size;
482 png_ptr->current_buffer_size -= save_size;
483 png_ptr->current_buffer_ptr += save_size;
484 }
485
486 if (png_ptr->idat_size == 0)
487 {
488 PNG_PUSH_SAVE_BUFFER_IF_LT(4)
489 png_crc_finish(png_ptr, 0);
492 png_ptr->zowner = 0;
493 }
494}
495
496void /* PRIVATE */
497png_process_IDAT_data(png_structrp png_ptr, png_bytep buffer,
498 size_t buffer_length)
499{
500 /* The caller checks for a non-zero buffer length. */
501 if (!(buffer_length > 0) || buffer == NULL)
502 png_error(png_ptr, "No IDAT data (internal error)");
503
504 /* This routine must process all the data it has been given
505 * before returning, calling the row callback as required to
506 * handle the uncompressed results.
507 */
508 png_ptr->zstream.next_in = buffer;
509 /* TODO: WARNING: TRUNCATION ERROR: DANGER WILL ROBINSON: */
510 png_ptr->zstream.avail_in = (uInt)buffer_length;
511
512 /* Keep going until the decompressed data is all processed
513 * or the stream marked as finished.
514 */
515 while (png_ptr->zstream.avail_in > 0 &&
516 (png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED) == 0)
517 {
518 int ret;
519
520 /* We have data for zlib, but we must check that zlib
521 * has someplace to put the results. It doesn't matter
522 * if we don't expect any results -- it may be the input
523 * data is just the LZ end code.
524 */
525 if (!(png_ptr->zstream.avail_out > 0))
526 {
527 /* TODO: WARNING: TRUNCATION ERROR: DANGER WILL ROBINSON: */
528 png_ptr->zstream.avail_out = (uInt)(PNG_ROWBYTES(png_ptr->pixel_depth,
529 png_ptr->iwidth) + 1);
530
531 png_ptr->zstream.next_out = png_ptr->row_buf;
532 }
533
534 /* Using Z_SYNC_FLUSH here means that an unterminated
535 * LZ stream (a stream with a missing end code) can still
536 * be handled, otherwise (Z_NO_FLUSH) a future zlib
537 * implementation might defer output and therefore
538 * change the current behavior (see comments in inflate.c
539 * for why this doesn't happen at present with zlib 1.2.5).
540 */
542
543 /* Check for any failure before proceeding. */
544 if (ret != Z_OK && ret != Z_STREAM_END)
545 {
546 /* Terminate the decompression. */
548 png_ptr->zowner = 0;
549
550 /* This may be a truncated stream (missing or
551 * damaged end code). Treat that as a warning.
552 */
553 if (png_ptr->row_number >= png_ptr->num_rows ||
554 png_ptr->pass > 6)
555 png_warning(png_ptr, "Truncated compressed data in IDAT");
556
557 else
558 {
559 if (ret == Z_DATA_ERROR)
560 png_benign_error(png_ptr, "IDAT: ADLER32 checksum mismatch");
561 else
562 png_error(png_ptr, "Decompression error in IDAT");
563 }
564
565 /* Skip the check on unprocessed input */
566 return;
567 }
568
569 /* Did inflate output any data? */
570 if (png_ptr->zstream.next_out != png_ptr->row_buf)
571 {
572 /* Is this unexpected data after the last row?
573 * If it is, artificially terminate the LZ output
574 * here.
575 */
576 if (png_ptr->row_number >= png_ptr->num_rows ||
577 png_ptr->pass > 6)
578 {
579 /* Extra data. */
580 png_warning(png_ptr, "Extra compressed data in IDAT");
582 png_ptr->zowner = 0;
583
584 /* Do no more processing; skip the unprocessed
585 * input check below.
586 */
587 return;
588 }
589
590 /* Do we have a complete row? */
591 if (png_ptr->zstream.avail_out == 0)
592 png_push_process_row(png_ptr);
593 }
594
595 /* And check for the end of the stream. */
596 if (ret == Z_STREAM_END)
598 }
599
600 /* All the data should have been processed, if anything
601 * is left at this point we have bytes of IDAT data
602 * after the zlib end code.
603 */
604 if (png_ptr->zstream.avail_in > 0)
605 png_warning(png_ptr, "Extra compression data in IDAT");
606}
607
608void /* PRIVATE */
609png_push_process_row(png_structrp png_ptr)
610{
611 /* 1.5.6: row_info moved out of png_struct to a local here. */
612 png_row_info row_info;
613
614 row_info.width = png_ptr->iwidth; /* NOTE: width of current interlaced row */
615 row_info.color_type = png_ptr->color_type;
616 row_info.bit_depth = png_ptr->bit_depth;
617 row_info.channels = png_ptr->channels;
618 row_info.pixel_depth = png_ptr->pixel_depth;
619 row_info.rowbytes = PNG_ROWBYTES(row_info.pixel_depth, row_info.width);
620
621 if (png_ptr->row_buf[0] > PNG_FILTER_VALUE_NONE)
622 {
623 if (png_ptr->row_buf[0] < PNG_FILTER_VALUE_LAST)
624 png_read_filter_row(png_ptr, &row_info, png_ptr->row_buf + 1,
625 png_ptr->prev_row + 1, png_ptr->row_buf[0]);
626 else
627 png_error(png_ptr, "bad adaptive filter value");
628 }
629
630 /* libpng 1.5.6: the following line was copying png_ptr->rowbytes before
631 * 1.5.6, while the buffer really is this big in current versions of libpng
632 * it may not be in the future, so this was changed just to copy the
633 * interlaced row count:
634 */
635 memcpy(png_ptr->prev_row, png_ptr->row_buf, row_info.rowbytes + 1);
636
637#ifdef PNG_READ_TRANSFORMS_SUPPORTED
638 if (png_ptr->transformations != 0)
639 png_do_read_transformations(png_ptr, &row_info);
640#endif
641
642 /* The transformed pixel depth should match the depth now in row_info. */
643 if (png_ptr->transformed_pixel_depth == 0)
644 {
645 png_ptr->transformed_pixel_depth = row_info.pixel_depth;
646 if (row_info.pixel_depth > png_ptr->maximum_pixel_depth)
647 png_error(png_ptr, "progressive row overflow");
648 }
649
650 else if (png_ptr->transformed_pixel_depth != row_info.pixel_depth)
651 png_error(png_ptr, "internal progressive row size calculation error");
652
653
654#ifdef PNG_READ_INTERLACING_SUPPORTED
655 /* Expand interlaced rows to full size */
656 if (png_ptr->interlaced != 0 &&
657 (png_ptr->transformations & PNG_INTERLACE) != 0)
658 {
659 if (png_ptr->pass < 6)
660 png_do_read_interlace(&row_info, png_ptr->row_buf + 1, png_ptr->pass,
661 png_ptr->transformations);
662
663 switch (png_ptr->pass)
664 {
665 case 0:
666 {
667 int i;
668 for (i = 0; i < 8 && png_ptr->pass == 0; i++)
669 {
670 png_push_have_row(png_ptr, png_ptr->row_buf + 1);
671 png_read_push_finish_row(png_ptr); /* Updates png_ptr->pass */
672 }
673
674 if (png_ptr->pass == 2) /* Pass 1 might be empty */
675 {
676 for (i = 0; i < 4 && png_ptr->pass == 2; i++)
677 {
678 png_push_have_row(png_ptr, NULL);
679 png_read_push_finish_row(png_ptr);
680 }
681 }
682
683 if (png_ptr->pass == 4 && png_ptr->height <= 4)
684 {
685 for (i = 0; i < 2 && png_ptr->pass == 4; i++)
686 {
687 png_push_have_row(png_ptr, NULL);
688 png_read_push_finish_row(png_ptr);
689 }
690 }
691
692 if (png_ptr->pass == 6 && png_ptr->height <= 4)
693 {
694 png_push_have_row(png_ptr, NULL);
695 png_read_push_finish_row(png_ptr);
696 }
697
698 break;
699 }
700
701 case 1:
702 {
703 int i;
704 for (i = 0; i < 8 && png_ptr->pass == 1; i++)
705 {
706 png_push_have_row(png_ptr, png_ptr->row_buf + 1);
707 png_read_push_finish_row(png_ptr);
708 }
709
710 if (png_ptr->pass == 2) /* Skip top 4 generated rows */
711 {
712 for (i = 0; i < 4 && png_ptr->pass == 2; i++)
713 {
714 png_push_have_row(png_ptr, NULL);
715 png_read_push_finish_row(png_ptr);
716 }
717 }
718
719 break;
720 }
721
722 case 2:
723 {
724 int i;
725
726 for (i = 0; i < 4 && png_ptr->pass == 2; i++)
727 {
728 png_push_have_row(png_ptr, png_ptr->row_buf + 1);
729 png_read_push_finish_row(png_ptr);
730 }
731
732 for (i = 0; i < 4 && png_ptr->pass == 2; i++)
733 {
734 png_push_have_row(png_ptr, NULL);
735 png_read_push_finish_row(png_ptr);
736 }
737
738 if (png_ptr->pass == 4) /* Pass 3 might be empty */
739 {
740 for (i = 0; i < 2 && png_ptr->pass == 4; i++)
741 {
742 png_push_have_row(png_ptr, NULL);
743 png_read_push_finish_row(png_ptr);
744 }
745 }
746
747 break;
748 }
749
750 case 3:
751 {
752 int i;
753
754 for (i = 0; i < 4 && png_ptr->pass == 3; i++)
755 {
756 png_push_have_row(png_ptr, png_ptr->row_buf + 1);
757 png_read_push_finish_row(png_ptr);
758 }
759
760 if (png_ptr->pass == 4) /* Skip top two generated rows */
761 {
762 for (i = 0; i < 2 && png_ptr->pass == 4; i++)
763 {
764 png_push_have_row(png_ptr, NULL);
765 png_read_push_finish_row(png_ptr);
766 }
767 }
768
769 break;
770 }
771
772 case 4:
773 {
774 int i;
775
776 for (i = 0; i < 2 && png_ptr->pass == 4; i++)
777 {
778 png_push_have_row(png_ptr, png_ptr->row_buf + 1);
779 png_read_push_finish_row(png_ptr);
780 }
781
782 for (i = 0; i < 2 && png_ptr->pass == 4; i++)
783 {
784 png_push_have_row(png_ptr, NULL);
785 png_read_push_finish_row(png_ptr);
786 }
787
788 if (png_ptr->pass == 6) /* Pass 5 might be empty */
789 {
790 png_push_have_row(png_ptr, NULL);
791 png_read_push_finish_row(png_ptr);
792 }
793
794 break;
795 }
796
797 case 5:
798 {
799 int i;
800
801 for (i = 0; i < 2 && png_ptr->pass == 5; i++)
802 {
803 png_push_have_row(png_ptr, png_ptr->row_buf + 1);
804 png_read_push_finish_row(png_ptr);
805 }
806
807 if (png_ptr->pass == 6) /* Skip top generated row */
808 {
809 png_push_have_row(png_ptr, NULL);
810 png_read_push_finish_row(png_ptr);
811 }
812
813 break;
814 }
815
816 default:
817 case 6:
818 {
819 png_push_have_row(png_ptr, png_ptr->row_buf + 1);
820 png_read_push_finish_row(png_ptr);
821
822 if (png_ptr->pass != 6)
823 break;
824
825 png_push_have_row(png_ptr, NULL);
826 png_read_push_finish_row(png_ptr);
827 }
828 }
829 }
830 else
831#endif
832 {
833 png_push_have_row(png_ptr, png_ptr->row_buf + 1);
834 png_read_push_finish_row(png_ptr);
835 }
836}
837
838void /* PRIVATE */
839png_read_push_finish_row(png_structrp png_ptr)
840{
841 png_ptr->row_number++;
842 if (png_ptr->row_number < png_ptr->num_rows)
843 return;
844
845#ifdef PNG_READ_INTERLACING_SUPPORTED
846 if (png_ptr->interlaced != 0)
847 {
848 png_ptr->row_number = 0;
849 memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1);
850
851 do
852 {
853 png_ptr->pass++;
854 if ((png_ptr->pass == 1 && png_ptr->width < 5) ||
855 (png_ptr->pass == 3 && png_ptr->width < 3) ||
856 (png_ptr->pass == 5 && png_ptr->width < 2))
857 png_ptr->pass++;
858
859 if (png_ptr->pass > 7)
860 png_ptr->pass--;
861
862 if (png_ptr->pass >= 7)
863 break;
864
865 png_ptr->iwidth = (png_ptr->width +
866 png_pass_inc[png_ptr->pass] - 1 -
867 png_pass_start[png_ptr->pass]) /
868 png_pass_inc[png_ptr->pass];
869
870 if ((png_ptr->transformations & PNG_INTERLACE) != 0)
871 break;
872
873 png_ptr->num_rows = (png_ptr->height +
874 png_pass_yinc[png_ptr->pass] - 1 -
875 png_pass_ystart[png_ptr->pass]) /
876 png_pass_yinc[png_ptr->pass];
877
878 } while (png_ptr->iwidth == 0 || png_ptr->num_rows == 0);
879 }
880#endif /* READ_INTERLACING */
881}
882
883void /* PRIVATE */
884png_push_have_info(png_structrp png_ptr, png_inforp info_ptr)
885{
886 if (png_ptr->info_fn != NULL)
887 (*(png_ptr->info_fn))(png_ptr, info_ptr);
888}
889
890void /* PRIVATE */
891png_push_have_end(png_structrp png_ptr, png_inforp info_ptr)
892{
893 if (png_ptr->end_fn != NULL)
894 (*(png_ptr->end_fn))(png_ptr, info_ptr);
895}
896
897void /* PRIVATE */
898png_push_have_row(png_structrp png_ptr, png_bytep row)
899{
900 if (png_ptr->row_fn != NULL)
901 (*(png_ptr->row_fn))(png_ptr, row, png_ptr->row_number,
902 (int)png_ptr->pass);
903}
904
905#ifdef PNG_READ_INTERLACING_SUPPORTED
906void PNGAPI
907png_progressive_combine_row(png_const_structrp png_ptr, png_bytep old_row,
908 png_const_bytep new_row)
909{
910 if (png_ptr == NULL)
911 return;
912
913 /* new_row is a flag here - if it is NULL then the app callback was called
914 * from an empty row (see the calls to png_struct::row_fn below), otherwise
915 * it must be png_ptr->row_buf+1
916 */
917 if (new_row != NULL)
918 png_combine_row(png_ptr, old_row, 1/*blocky display*/);
919}
920#endif /* READ_INTERLACING */
921
922void PNGAPI
923png_set_progressive_read_fn(png_structrp png_ptr, png_voidp progressive_ptr,
924 png_progressive_info_ptr info_fn, png_progressive_row_ptr row_fn,
925 png_progressive_end_ptr end_fn)
926{
927 if (png_ptr == NULL)
928 return;
929
930 png_ptr->info_fn = info_fn;
931 png_ptr->row_fn = row_fn;
932 png_ptr->end_fn = end_fn;
933
934 png_set_read_fn(png_ptr, progressive_ptr, png_push_fill_buffer);
935}
936
938png_get_progressive_ptr(png_const_structrp png_ptr)
939{
940 if (png_ptr == NULL)
941 return NULL;
942
943 return png_ptr->io_ptr;
944}
945#endif /* PROGRESSIVE_READ */
#define NULL
Definition: types.h:112
#define Z_STREAM_END
Definition: zlib.h:115
unsigned int uInt
Definition: zlib.h:38
#define Z_OK
Definition: zlib.h:114
#define Z_DATA_ERROR
Definition: zlib.h:119
#define Z_SYNC_FLUSH
Definition: zlib.h:107
unsigned int size_t
Definition: corecrt.h:203
struct png_info_def *typedef unsigned char **typedef struct png_info_def *typedef struct png_info_def *typedef struct png_info_def *typedef unsigned char ** row
Definition: typeof.h:78
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
return ret
Definition: mutex.c:146
GLuint buffer
Definition: glext.h:5915
GLenum mode
Definition: glext.h:6217
GLuint GLsizei GLsizei * length
Definition: glext.h:6040
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
if(dx< 0)
Definition: linetemp.h:194
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
static PVOID ptr
Definition: dispmode.c:27
#define PNG_COLOR_TYPE_PALETTE
Definition: image.c:5166
static const WCHAR sp[]
Definition: suminfo.c:287
#define PNG_HAVE_PLTE
Definition: png.h:640
png_structrp png_ptr
Definition: png.h:1122
png_uint_32
Definition: png.h:2036
#define PNG_FILTER_VALUE_LAST
Definition: png.h:1543
#define PNG_AFTER_IDAT
Definition: png.h:641
#define PNG_HAVE_IHDR
Definition: png.h:639
#define PNG_SIZE_MAX
Definition: png.h:646
const png_struct *PNG_RESTRICT png_const_structrp
Definition: png.h:465
#define PNG_FILTER_VALUE_NONE
Definition: png.h:1538
png_info *PNG_RESTRICT png_inforp
Definition: png.h:466
png_struct *PNG_RESTRICT png_structrp
Definition: png.h:464
png_const_structrp png_const_inforp info_ptr
Definition: png.h:2037
const png_byte * png_const_bytep
Definition: pngconf.h:567
#define PNGAPI
Definition: pngconf.h:248
png_byte * png_bytep
Definition: pngconf.h:566
#define PNGCBAPI
Definition: pngconf.h:245
#define PNG_INTERLACE
Definition: pngpriv.h:659
#define PNG_ROWBYTES(pixel_bits, width)
Definition: pngpriv.h:754
#define PNG_HAVE_CHUNK_HEADER
Definition: pngpriv.h:648
#define png_app_warning(pp, s)
Definition: pngpriv.h:2037
#define png_IHDR
Definition: pngpriv.h:888
#define PNG_INFLATE(pp, flush)
Definition: pngpriv.h:1731
#define png_IEND
Definition: pngpriv.h:887
#define PNG_HAVE_CHUNK_AFTER_IDAT
Definition: pngpriv.h:653
#define PNG_HAVE_IDAT
Definition: pngpriv.h:642
#define PNG_CHUNK_FROM_STRING(s)
Definition: pngpriv.h:923
#define PNG_FLAG_ZSTREAM_ENDED
Definition: pngpriv.h:698
#define png_PLTE
Definition: pngpriv.h:889
#define png_IDAT
Definition: pngpriv.h:886
#define memset(x, y, z)
Definition: compat.h:39
wchar_t const *const size_t const buffer_size
Definition: stat.cpp:95
png_uint_32 width
Definition: png.h:766
png_byte color_type
Definition: png.h:768
png_byte bit_depth
Definition: png.h:769
png_byte pixel_depth
Definition: png.h:771
png_byte channels
Definition: png.h:770
size_t rowbytes
Definition: png.h:767