CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
hrydgard

CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!

GitHub Repository: hrydgard/ppsspp
Path: blob/master/ext/libpng17/pngpread.c
Views: 1401
1
2
/* pngpread.c - read a png file in push mode
3
*
4
* Last changed in libpng 1.7.0 [(PENDING RELEASE)]
5
* Copyright (c) 1998-2002,2004,2006-2016 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
#define PNG_SRC_FILE PNG_SRC_FILE_pngpread
16
17
#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
18
19
/* Standard callbacks */
20
static void PNGCBAPI
21
png_push_fill_buffer(png_structp png_ptr, png_bytep buffer, png_size_t length)
22
{
23
png_bytep ptr;
24
25
if (png_ptr == NULL)
26
return;
27
28
ptr = buffer;
29
debug(length > 0);
30
31
if (length > 0 && png_ptr->save_buffer_size > 0)
32
{
33
png_size_t save_size;
34
35
if (length < png_ptr->save_buffer_size)
36
save_size = length;
37
38
else
39
save_size = png_ptr->save_buffer_size;
40
41
memcpy(ptr, png_ptr->save_buffer_ptr, save_size);
42
length -= save_size;
43
ptr += save_size;
44
png_ptr->buffer_size -= save_size;
45
png_ptr->save_buffer_size -= save_size;
46
png_ptr->save_buffer_ptr += save_size;
47
}
48
49
if (length > 0 && png_ptr->current_buffer_size > 0)
50
{
51
png_size_t save_size;
52
53
if (length < png_ptr->current_buffer_size)
54
save_size = length;
55
56
else
57
save_size = png_ptr->current_buffer_size;
58
59
memcpy(ptr, png_ptr->current_buffer_ptr, save_size);
60
png_ptr->buffer_size -= save_size;
61
png_ptr->current_buffer_size -= save_size;
62
png_ptr->current_buffer_ptr += save_size;
63
}
64
}
65
66
/* Push model modes: png_chunk_op plus extras */
67
typedef enum
68
{
69
/* all the png_chunk_op codes, plus: */
70
png_read_signature = 0, /* starting value */
71
png_read_chunk_header,
72
png_read_end_IDAT,
73
png_read_done,
74
png_read_chunk, /* Not a state, use these derived from png_chunk_op: */
75
png_read_chunk_skip = png_read_chunk+png_chunk_skip,
76
png_read_chunk_unknown = png_read_chunk+png_chunk_unknown,
77
png_read_chunk_process_all = png_read_chunk+png_chunk_process_all,
78
png_read_chunk_process_part = png_read_chunk+png_chunk_process_part
79
} png_read_mode;
80
81
static void
82
png_push_save_buffer_partial(png_structrp png_ptr, size_t amount)
83
{
84
/* Copy 'amount' bytes to the end of the save buffer from the current
85
* buffer.
86
*/
87
png_bytep buffer;
88
size_t save_size = png_ptr->save_buffer_size;
89
90
if (save_size > PNG_SIZE_MAX - amount)
91
png_error(png_ptr, "save buffer overflow");
92
93
if (png_ptr->save_buffer_max < save_size + amount)
94
{
95
/* Reallocate the save buffer. */
96
buffer = png_voidcast(png_bytep, png_malloc(png_ptr, save_size + amount));
97
memcpy(buffer, png_ptr->save_buffer_ptr, save_size);
98
png_free(png_ptr, png_ptr->save_buffer);
99
png_ptr->save_buffer_ptr = png_ptr->save_buffer = buffer;
100
}
101
102
else if (png_ptr->save_buffer_max -
103
(png_ptr->save_buffer_ptr - png_ptr->save_buffer) < save_size + amount)
104
{
105
/* Move the existing saved data */
106
buffer = png_ptr->save_buffer;
107
memmove(buffer, png_ptr->save_buffer_ptr, save_size);
108
png_ptr->save_buffer_ptr = buffer;
109
}
110
111
else /* Just copy the data */
112
buffer = png_ptr->save_buffer_ptr;
113
114
memcpy(buffer+save_size, png_ptr->current_buffer_ptr, amount);
115
png_ptr->save_buffer_size = save_size + amount;
116
png_ptr->current_buffer_ptr += amount;
117
png_ptr->current_buffer_size -= amount;
118
png_ptr->buffer_size -= amount;
119
}
120
121
static void
122
png_push_save_buffer(png_structrp png_ptr)
123
{
124
png_push_save_buffer_partial(png_ptr, png_ptr->current_buffer_size);
125
/* This terminates the process loop. */
126
png_ptr->buffer_size = 0;
127
}
128
129
#define PNG_PUSH_SAVE_BUFFER_IF_FULL \
130
if (png_ptr->chunk_length + 4 > png_ptr->buffer_size) \
131
{ png_push_save_buffer(png_ptr); return; }
132
#define PNG_PUSH_SAVE_BUFFER_IF_LT(N) \
133
if (png_ptr->buffer_size < N) \
134
{ png_push_save_buffer(png_ptr); return; }
135
136
png_size_t PNGAPI
137
png_process_data_pause(png_structrp png_ptr, int save)
138
{
139
if (png_ptr != NULL)
140
{
141
/* It's easiest for the caller if we do the save; then the caller doesn't
142
* have to supply the same data again:
143
*/
144
if (save != 0)
145
png_push_save_buffer(png_ptr);
146
else
147
{
148
/* This includes any pending saved bytes: */
149
png_size_t remaining = png_ptr->buffer_size;
150
png_ptr->buffer_size = 0; /* Terminate the process loop */
151
152
/* So subtract the saved buffer size, unless all the data
153
* is actually 'saved', in which case we just return 0
154
*/
155
if (png_ptr->save_buffer_size < remaining)
156
return remaining - png_ptr->save_buffer_size;
157
}
158
}
159
160
return 0;
161
}
162
163
png_uint_32 PNGAPI
164
png_process_data_skip(png_structrp png_ptr)
165
{
166
if (png_ptr != NULL && png_ptr->process_mode == png_read_chunk_skip)
167
{
168
/* At the end of png_process_data the buffer size must be 0 (see the loop
169
* above) so we can detect a broken call here:
170
*/
171
if (png_ptr->buffer_size != 0)
172
png_app_error(png_ptr,
173
"png_process_data_skip called inside png_process_data");
174
175
/* If is impossible for there to be a saved buffer at this point -
176
* otherwise we could not be in SKIP mode. This will also happen if
177
* png_process_skip is called inside png_process_data (but only very
178
* rarely.)
179
*/
180
else if (png_ptr->save_buffer_size != 0)
181
png_app_error(png_ptr, "png_process_data_skip called with saved data");
182
183
else
184
{
185
/* Skipping png_ptr->chunk_length of data then checking the CRC, after
186
* that a new chunk header will be read.
187
*/
188
png_ptr->process_mode = png_read_chunk_header;
189
return png_ptr->chunk_length + 4;
190
}
191
}
192
193
return 0;
194
}
195
196
static void
197
png_push_restore_buffer(png_structrp png_ptr, png_bytep buffer,
198
png_size_t buffer_length)
199
{
200
png_ptr->current_buffer_size = buffer_length;
201
png_ptr->buffer_size = buffer_length + png_ptr->save_buffer_size;
202
png_ptr->current_buffer_ptr = buffer;
203
}
204
205
/* Read any remaining signature bytes from the stream and compare them with
206
* the correct PNG signature. It is possible that this routine is called
207
* with bytes already read from the signature, either because they have been
208
* checked by the calling application, or because of multiple calls to this
209
* routine.
210
*/
211
static void
212
png_push_read_signature(png_structrp png_ptr, png_inforp info_ptr)
213
{
214
unsigned int num_checked = png_ptr->sig_bytes;
215
unsigned int num_to_check = 8 - num_checked;
216
217
if (png_ptr->buffer_size < num_to_check)
218
num_to_check = (int)/*SAFE*/png_ptr->buffer_size;
219
220
png_push_fill_buffer(png_ptr, &(info_ptr->signature[num_checked]),
221
num_to_check);
222
png_ptr->sig_bytes = png_check_byte(png_ptr,
223
png_ptr->sig_bytes + num_to_check);
224
225
if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check))
226
{
227
if (num_checked < 4 &&
228
png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4))
229
png_error(png_ptr, "Not a PNG file");
230
231
else
232
png_error(png_ptr, "PNG file corrupted by ASCII conversion");
233
}
234
235
else if (png_ptr->sig_bytes >= 8)
236
png_ptr->process_mode = png_read_chunk_header;
237
}
238
239
static void
240
png_push_crc_finish(png_structrp png_ptr)
241
/* CRC the remainder of the chunk data; png_struct::chunk_length must be the
242
* amount of data left to read excluding the CRC.
243
*/
244
{
245
if (png_ptr->chunk_length != 0 && png_ptr->save_buffer_size != 0)
246
{
247
png_size_t save_size = png_ptr->save_buffer_size;
248
png_uint_32 skip_length = png_ptr->chunk_length;
249
250
/* We want the smaller of 'skip_length' and 'save_buffer_size', but
251
* they are of different types and we don't know which variable has the
252
* fewest bits. Carefully select the smaller and cast it to the type of
253
* the larger - this cannot overflow. Do not cast in the following test
254
* - it will break on either 16 or 64 bit platforms.
255
*/
256
if (skip_length < save_size)
257
save_size = (png_size_t)/*SAFE*/skip_length;
258
259
else
260
skip_length = (png_uint_32)/*SAFE*/save_size;
261
262
png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size);
263
264
png_ptr->chunk_length -= skip_length;
265
png_ptr->buffer_size -= save_size;
266
png_ptr->save_buffer_size -= save_size;
267
png_ptr->save_buffer_ptr += save_size;
268
}
269
270
if (png_ptr->chunk_length != 0 && png_ptr->current_buffer_size != 0)
271
{
272
png_size_t save_size = png_ptr->current_buffer_size;
273
png_uint_32 skip_length = png_ptr->chunk_length;
274
275
/* We want the smaller of 'skip_length' and 'current_buffer_size', here,
276
* the same problem exists as above and the same solution.
277
*/
278
if (skip_length < save_size)
279
save_size = (png_size_t)/*SAFE*/skip_length;
280
281
else
282
skip_length = (png_uint_32)/*SAFE*/save_size;
283
284
png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size);
285
286
png_ptr->chunk_length -= skip_length;
287
png_ptr->buffer_size -= save_size;
288
png_ptr->current_buffer_size -= save_size;
289
png_ptr->current_buffer_ptr += save_size;
290
}
291
292
if (png_ptr->chunk_length == 0)
293
{
294
PNG_PUSH_SAVE_BUFFER_IF_LT(4)
295
png_crc_finish(png_ptr, 0);
296
png_ptr->process_mode = png_read_chunk_header;
297
}
298
}
299
300
static void
301
png_push_read_unknown(png_structrp png_ptr, png_inforp info_ptr)
302
{
303
/* Handle an unknown chunk. All the data is available but it may not
304
* all be in the same buffer. png_handle_unknown needs the chunk data in
305
* just one buffer.
306
*/
307
png_bytep buffer;
308
png_uint_32 chunk_length = png_ptr->chunk_length;
309
310
if (png_ptr->save_buffer_size > 0)
311
{
312
png_size_t save_size = png_ptr->save_buffer_size;
313
314
if (save_size < chunk_length)
315
{
316
/* Copy the current_buffer_ptr data into the save buffer. */
317
png_push_save_buffer_partial(png_ptr, chunk_length - save_size);
318
save_size = chunk_length;
319
}
320
321
buffer = png_ptr->save_buffer_ptr;
322
png_ptr->save_buffer_ptr = buffer+chunk_length;
323
png_ptr->save_buffer_size = save_size-chunk_length;
324
png_ptr->buffer_size -= chunk_length;
325
affirm(png_ptr->buffer_size >= 4);
326
}
327
328
else
329
{
330
affirm(png_ptr->current_buffer_size >= chunk_length+4);
331
buffer = png_ptr->current_buffer_ptr;
332
png_ptr->current_buffer_ptr = buffer+chunk_length;
333
png_ptr->current_buffer_size -= chunk_length;
334
png_ptr->buffer_size -= chunk_length;
335
}
336
337
/* Now check the CRC, before attempting the unknown handling. */
338
png_calculate_crc(png_ptr, buffer, chunk_length);
339
png_crc_finish(png_ptr, 0);
340
# ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
341
png_handle_unknown(png_ptr, info_ptr, buffer);
342
# else /* !READ_UNKNOWN_CHUNKS */
343
PNG_UNUSED(info_ptr)
344
# endif /* !READ_UNKNOWN_CHUNKS */
345
png_ptr->process_mode = png_read_chunk_header;
346
}
347
348
static void
349
png_push_have_row(png_structrp png_ptr, png_bytep row)
350
{
351
if (png_ptr->row_fn != NULL)
352
{
353
png_uint_32 row_number = png_ptr->row_number;
354
png_byte pass = png_ptr->pass;
355
356
if (png_ptr->interlaced)
357
{
358
/* If the row de-interlace is not being done by PNG this wacky API
359
* delivers the row number in the pass to the caller. We know that
360
* if we get here the row exists, so the number is just one less than
361
* the height of an interlaced image with just the rows up to this
362
* one:
363
*/
364
# ifdef PNG_READ_INTERLACING_SUPPORTED
365
if (!png_ptr->do_interlace)
366
# endif /* READ_INTERLACING */
367
{
368
affirm(PNG_ROW_IN_INTERLACE_PASS(row_number, pass) && row != NULL);
369
row_number = PNG_PASS_ROWS(row_number+1, pass);
370
affirm(row_number > 0);
371
--row_number;
372
}
373
}
374
375
(*(png_ptr->row_fn))(png_ptr, row, row_number, pass);
376
}
377
}
378
379
static void
380
png_push_read_sync_zstream(png_structp png_ptr, png_bytep *bufferp,
381
size_t *buffer_lengthp)
382
/* Synchronize the png_struct progressive read buffer
383
* {*bufferp,*buffer_lengthp} with png_struct::zstream.next_in, on the
384
* assumption that the zstream had previously been set up with *bufferp.
385
*/
386
{
387
png_bytep original_start = *bufferp;
388
png_alloc_size_t bytes_consumed = png_ptr->zstream.next_in - original_start;
389
390
affirm(buffer_lengthp != NULL);
391
392
/* Calculate the CRC for the consumed data: */
393
png_calculate_crc(png_ptr, original_start, bytes_consumed);
394
395
/* Update the buffer pointers and the various lengths: */
396
*bufferp = original_start + bytes_consumed; /* == png_ptr->zstream.next_in */
397
398
affirm(bytes_consumed <= *buffer_lengthp);
399
*buffer_lengthp -= (size_t)/*SAFE*/bytes_consumed;
400
401
affirm(bytes_consumed <= png_ptr->chunk_length);
402
png_ptr->chunk_length -= (png_uint_32)/*SAFE*/bytes_consumed;
403
404
affirm(bytes_consumed <= png_ptr->buffer_size);
405
png_ptr->buffer_size -= (size_t)/*SAFE*/bytes_consumed;
406
}
407
408
static void
409
png_push_read_process_IDAT(png_structp png_ptr, png_bytep *bufferp,
410
size_t *buffer_lengthp)
411
/* If the the *buffer_lengthp parameter is NULL there is no more input,
412
* png_struct::mode & PNG_AFTER_IDAT must be set at this point.
413
*/
414
{
415
png_alloc_size_t buffer_length;
416
417
if (buffer_lengthp != NULL)
418
buffer_length = *buffer_lengthp;
419
420
else /* end of IDAT */
421
{
422
/* SECURITY: if this affirm fails the code would go into an infinite loop;
423
* see the handling of avail_in == 0 in png_inflate_IDAT.
424
*/
425
affirm(png_ptr->mode & PNG_AFTER_IDAT);
426
buffer_length = 0;
427
}
428
429
/* This routine attempts to process all the data it has been given before
430
* returning, calling the row callback as required to handle the
431
* uncompressed results.
432
*
433
* If a pause happens during processing (png_ptr->buffer_size is set to 0)
434
* or the end of the chunk is encountered the routine may return without
435
* handling all the input data.
436
*/
437
if (buffer_length > png_ptr->chunk_length)
438
{
439
buffer_length = png_ptr->chunk_length;
440
441
/* This works because the last part of a 'skip' is to read and check the
442
* CRC, then the process mode is set to png_read_chunk_header.
443
*/
444
if (buffer_length == 0)
445
png_ptr->process_mode = png_read_chunk_skip;
446
}
447
448
/* It is possble for buffer_length to be zero at this point if the stream
449
* caontains a zero length IDAT. This is handled below.
450
*/
451
png_ptr->zstream.next_in = *bufferp;
452
453
while (buffer_length > 0 || buffer_lengthp == NULL)
454
{
455
if (buffer_length >= ZLIB_IO_MAX)
456
{
457
png_ptr->zstream.avail_in = ZLIB_IO_MAX;
458
buffer_length -= ZLIB_IO_MAX;
459
}
460
461
else
462
{
463
png_ptr->zstream.avail_in = (uInt)/*SAFE*/buffer_length;
464
buffer_length = 0;
465
}
466
467
/* The last row may already have been processed.
468
*
469
* row_number is the *current* row number in the range 0..height-1. It is
470
* updated only by the call to png_read_process_IDAT that follows the call
471
* which returns something other than png_row_incomplete.
472
*
473
* At the end of the image that call must *NOT* be made; png_process_IDAT
474
* must not be called after the last row. png_struct::zstream_eod is set
475
* below to allow this condition to be detected.
476
*
477
* Note that png_read_process_IDAT handles errors in the LZ compressed
478
* data (i.e. the cases where png_struct::zstream_error is set) by filling
479
* the rows in with 0, which is a safe value, so keep calling it until we
480
* reach the end of the image.
481
*/
482
if (!png_ptr->zstream_eod)
483
{
484
png_bytep row_buffer = NULL;
485
png_row_op row_op =
486
png_read_process_IDAT(png_ptr, NULL, NULL, 1/*save row*/);
487
488
if (row_op != png_row_incomplete)
489
{
490
/* Have a complete row, so check for end-of-image; do this here
491
* because interlaced images can end on earlier rows or passes but
492
* we keep calling png_read_process_IDAT until it updates row_number
493
* to the last row of the actual image:
494
*/
495
if (png_ptr->row_number+1 >= png_ptr->height &&
496
(!png_ptr->interlaced || png_ptr->pass == 6))
497
png_ptr->zstream_eod = 1; /* end of image */
498
}
499
500
switch (row_op)
501
{
502
case png_row_incomplete:
503
/* more IDAT data needed for row */
504
debug(png_ptr->zstream.avail_in == 0);
505
506
/* png_inflate_IDAT is supposed to handle this and recognize a
507
* call with 0 avail_in as end of stream:
508
*/
509
affirm(buffer_lengthp != NULL);
510
continue;
511
512
case png_row_process:
513
/* If a row was obtained after the end of the IDAT this was done
514
* by fabricating data, ensure this is reported, else there is a
515
* security issue; normally libpng does a png_error in this
516
* case, even if the error is ignored png_struct::zstream_error
517
* should be set so somehow the error wasn't noticed!
518
*/
519
affirm(buffer_lengthp != NULL || png_ptr->zstream_error);
520
521
/* png_struct::transformed_row contains a complete, transformed,
522
* row; this is processed in both 'sparkle' and 'block' mode.
523
*/
524
# ifdef PNG_TRANSFORM_MECH_SUPPORTED
525
row_buffer = png_ptr->transformed_row;
526
if (row_buffer == NULL)
527
# endif /* TRANSFORM_MECH */
528
row_buffer = png_ptr->row_buffer;
529
break;
530
531
case png_row_repeat:
532
/* row not in this pass, but the existing row in
533
* png_struct::transformed_row may be used, this is only required
534
* if the 'block' or 'rectangle' mode of display is done and
535
* libpng is handling the de-interlace; when the app does it it
536
* only see the real rows.
537
*/
538
# ifdef PNG_READ_INTERLACING_SUPPORTED
539
if (png_ptr->do_interlace)
540
{
541
# ifdef PNG_TRANSFORM_MECH_SUPPORTED
542
row_buffer = png_ptr->transformed_row;
543
if (row_buffer == NULL)
544
# endif /* TRANSFORM_MECH */
545
row_buffer = png_ptr->row_buffer;
546
break;
547
}
548
# endif /* READ_INTERLACING */
549
continue;
550
551
case png_row_skip:
552
/* row not in pass and no appropriate data; skip this row,
553
* nothing more need be done, except the read_row_fn. The use
554
* of 'NULL' to mean this row doesn't contribute to the output
555
* is historical and not documented;
556
*/
557
# ifdef PNG_READ_INTERLACING_SUPPORTED
558
if (png_ptr->do_interlace)
559
break;
560
# endif /* READ_INTERLACING */
561
continue;
562
563
default:
564
impossible("not reached");
565
}
566
567
/* Here if there is a row to process. */
568
569
/* Now adjust the buffer pointers before calling png_push_have_row
570
* because the callback might call png_process_data_pause and that
571
* calls png_push_save_row. (Yes, this is insane; it was forced on
572
* libpng by writers of an external app that ignored the instructions
573
* not to fiddle with the insides of png_struct in version 1.4. It
574
* will probably be fixed here before 1.7.0 is released by removing
575
* the need for the save buffer entirely.)
576
*/
577
if (buffer_lengthp != NULL)
578
png_push_read_sync_zstream(png_ptr, bufferp, buffer_lengthp);
579
580
/* Process one row: */
581
png_push_have_row(png_ptr, row_buffer);
582
583
/* The buffer pointer and size may have changed at this point,
584
* so everything needs to be reloaded if we can continue reading.
585
*/
586
if (buffer_lengthp != NULL) /* not at end of IDATs */
587
{
588
if (png_ptr->chunk_length == 0)
589
png_ptr->process_mode = png_read_chunk_skip;
590
591
/* If the buffer_size has been set to zero more input is required,
592
* this may be a 'pause', and if the specific input buffer being
593
* processed has been exhaused then more input is also required.
594
* Otherwise we can keep going, however the input buffer may have
595
* been changed by the app callback, so do a complete reload:
596
*/
597
else if (png_ptr->buffer_size > 0 && *buffer_lengthp > 0)
598
png_push_read_process_IDAT(png_ptr, bufferp, buffer_lengthp);
599
600
return;
601
}
602
603
/* If we can't continue reading because there is no more IDAT data this
604
* may still be a pause.
605
*/
606
if (png_ptr->buffer_size == 0)
607
return;
608
609
/* Else continue, with zero data: */
610
continue;
611
}
612
613
affirm(png_ptr->zstream_eod);
614
615
if (png_ptr->zowner == 0 || png_read_finish_IDAT(png_ptr))
616
{
617
/* The zlib stream has ended, there may still be input data in
618
* png_ptr->zstream.next_in, restore this.
619
*/
620
debug(png_ptr->zowner == 0 && png_ptr->zstream_ended);
621
622
if (buffer_lengthp != NULL)
623
{
624
png_push_read_sync_zstream(png_ptr, bufferp, buffer_lengthp);
625
626
/* If the chunk_length is greater than 0 then there is extra data,
627
* report this once. Notice that for IDAT after the end of the
628
* stream we keep coming to this point and doing the skip.
629
*/
630
if (png_ptr->chunk_length > 0)
631
{
632
if (!png_ptr->zstream_error)
633
{
634
png_chunk_benign_error(png_ptr,
635
"too much IDAT data (progressive read)");
636
png_ptr->zstream_error = 1;
637
}
638
}
639
640
/* In any case CRC the chunk, skipping any unneeded data: */
641
png_ptr->process_mode = png_read_chunk_skip;
642
}
643
return;
644
}
645
646
/* else more input is required */
647
/* NOTE: this test only fires on a small (less than 5 byte) IDAT chunk
648
* which just contains the LZ EOF and the Adler32 CRC.
649
*/
650
affirm(png_ptr->zowner == png_IDAT && !png_ptr->zstream_ended);
651
}
652
653
/* At this point all the input has been consumed, however the CRC has not
654
* been done and the three length fields in png_struct, *buffer_lengthp,
655
* buffer_size and chunk_length, all need updating.
656
*/
657
png_push_read_sync_zstream(png_ptr, bufferp, buffer_lengthp);
658
}
659
660
static void
661
png_push_read_IDAT(png_structrp png_ptr)
662
{
663
if (png_ptr->save_buffer_size > 0)
664
{
665
png_push_read_process_IDAT(png_ptr, &png_ptr->save_buffer_ptr,
666
&png_ptr->save_buffer_size);
667
668
/* This is a slight optimization; normally when the process mode changes
669
* there will still be something in the buffer:
670
*/
671
if (png_ptr->save_buffer_size > 0)
672
return;
673
674
/* Check for a change in process mode or an application pause before
675
* checking the current input buffer. This is only rarely reached.
676
*/
677
if (png_ptr->process_mode != png_read_chunk_process_part ||
678
png_ptr->buffer_size == 0)
679
return;
680
}
681
682
if (png_ptr->current_buffer_size > 0)
683
png_push_read_process_IDAT(png_ptr, &png_ptr->current_buffer_ptr,
684
&png_ptr->current_buffer_size);
685
}
686
687
static void
688
png_push_finish_IDAT(png_structrp png_ptr)
689
/* Called once when the first chunk after IDAT is seen. */
690
{
691
/* All of the IDAT data has been processed, however the stream may have
692
* been truncated and the image rows may not all have been processed.
693
* Clean up here (this doesn't read anything.)
694
*
695
* 1.7.0: this attempts some measure of compatibility with the sequential
696
* API, if the IDAT is truncated and the resultant error reporting doesn't
697
* abort the read the image is filled in using zeros of pixel data. This
698
* actually happens inside png_inflate_IDAT (pngrutil.c) when called with
699
* z_stream::avail_in == 0.
700
*/
701
while (png_ptr->zowner == png_IDAT)
702
{
703
png_byte b = 0, *pb = &b;
704
705
png_push_read_process_IDAT(png_ptr, &pb, NULL/*end of IDAT*/);
706
707
if (png_ptr->zowner == 0)
708
break;
709
710
if (png_ptr->buffer_size == 0) /* pause */
711
return;
712
}
713
714
png_ptr->process_mode = png_check_bits(png_ptr, png_ptr->process_mode >> 4,
715
4);
716
}
717
718
static void
719
png_push_have_info(png_structrp png_ptr, png_inforp info_ptr)
720
{
721
if (png_ptr->info_fn != NULL)
722
(*(png_ptr->info_fn))(png_ptr, info_ptr);
723
}
724
725
static void
726
png_push_have_end(png_structrp png_ptr, png_inforp info_ptr)
727
{
728
if (png_ptr->end_fn != NULL)
729
(*(png_ptr->end_fn))(png_ptr, info_ptr);
730
}
731
732
static void
733
png_push_read_chunk_header(png_structrp png_ptr, png_infop info_ptr)
734
{
735
/* Called to read a new chunk header and work out how to handle the remainder
736
* of the data.
737
*/
738
unsigned int mode; /* mode prior to the header */
739
png_byte chunk_header[8];
740
741
PNG_PUSH_SAVE_BUFFER_IF_LT(8)
742
png_push_fill_buffer(png_ptr, chunk_header, 8);
743
png_ptr->chunk_length = png_get_uint_31(png_ptr, chunk_header);
744
png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(chunk_header+4);
745
png_reset_crc(png_ptr, chunk_header+4);
746
png_check_chunk_name(png_ptr, png_ptr->chunk_name);
747
png_check_chunk_length(png_ptr, png_ptr->chunk_length);
748
mode = png_ptr->mode;
749
png_ptr->process_mode = png_check_bits(png_ptr,
750
png_read_chunk+png_find_chunk_op(png_ptr), 4);
751
752
/* Is this the first IDAT chunk? */
753
if ((mode ^ png_ptr->mode) & PNG_HAVE_IDAT)
754
png_push_have_info(png_ptr, info_ptr);
755
756
/* Is it the chunk after the last IDAT chunk? */
757
else if (((mode ^ png_ptr->mode) & PNG_AFTER_IDAT) != 0)
758
png_ptr->process_mode = png_check_bits(png_ptr,
759
(png_ptr->process_mode << 4) + png_read_end_IDAT, 8);
760
}
761
762
/* What we do with the incoming data depends on what we were previously
763
* doing before we ran out of data...
764
*/
765
static void
766
png_process_some_data(png_structrp png_ptr, png_inforp info_ptr)
767
{
768
if (png_ptr == NULL)
769
return;
770
771
switch (png_ptr->process_mode & 0xf)
772
{
773
case png_read_signature:
774
png_push_read_signature(png_ptr, info_ptr);
775
return;
776
777
case png_read_chunk_header:
778
png_push_read_chunk_header(png_ptr, info_ptr);
779
return;
780
781
case png_read_chunk_skip:
782
png_push_crc_finish(png_ptr);
783
return;
784
785
case png_read_chunk_unknown:
786
PNG_PUSH_SAVE_BUFFER_IF_FULL
787
png_push_read_unknown(png_ptr, info_ptr);
788
return;
789
790
case png_read_chunk_process_all:
791
PNG_PUSH_SAVE_BUFFER_IF_FULL
792
png_handle_chunk(png_ptr, info_ptr);
793
794
if (png_ptr->mode & PNG_HAVE_IEND)
795
{
796
png_ptr->process_mode = png_read_done;
797
png_push_have_end(png_ptr, info_ptr);
798
png_ptr->buffer_size = 0;
799
}
800
801
else
802
png_ptr->process_mode = png_read_chunk_header;
803
return;
804
805
case png_read_chunk_process_part:
806
debug(png_ptr->chunk_name == png_IDAT &&
807
(png_ptr->mode & PNG_HAVE_IDAT) &&
808
!(png_ptr->mode & PNG_AFTER_IDAT));
809
810
if (png_ptr->zowner == 0 && !png_ptr->zstream_ended) /* first time */
811
png_read_start_IDAT(png_ptr);
812
813
png_push_read_IDAT(png_ptr);
814
return;
815
816
case png_read_end_IDAT:
817
png_push_finish_IDAT(png_ptr);
818
return;
819
820
case png_read_done:
821
png_app_error(png_ptr, "read beyond end of stream");
822
png_ptr->buffer_size = 0;
823
return;
824
825
default:
826
impossible("invalid process mode");
827
}
828
}
829
830
void PNGAPI
831
png_process_data(png_structrp png_ptr, png_inforp info_ptr,
832
png_bytep buffer, png_size_t buffer_size)
833
{
834
if (png_ptr == NULL || info_ptr == NULL)
835
return;
836
837
png_push_restore_buffer(png_ptr, buffer, buffer_size);
838
839
while (png_ptr->buffer_size)
840
png_process_some_data(png_ptr, info_ptr);
841
}
842
843
void PNGAPI
844
png_set_progressive_read_fn(png_structrp png_ptr, png_voidp progressive_ptr,
845
png_progressive_info_ptr info_fn, png_progressive_row_ptr row_fn,
846
png_progressive_end_ptr end_fn)
847
{
848
if (png_ptr == NULL)
849
return;
850
851
png_ptr->info_fn = info_fn;
852
png_ptr->row_fn = row_fn;
853
png_ptr->end_fn = end_fn;
854
855
png_set_read_fn(png_ptr, progressive_ptr, png_push_fill_buffer);
856
}
857
858
png_voidp PNGAPI
859
png_get_progressive_ptr(png_const_structrp png_ptr)
860
{
861
if (png_ptr == NULL)
862
return (NULL);
863
864
return png_ptr->io_ptr;
865
}
866
#endif /* PROGRESSIVE_READ */
867
868