Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.desktop/share/native/libsplashscreen/libpng/pngpread.c
41154 views
1
/*
2
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
3
*
4
* This code is free software; you can redistribute it and/or modify it
5
* under the terms of the GNU General Public License version 2 only, as
6
* published by the Free Software Foundation. Oracle designates this
7
* particular file as subject to the "Classpath" exception as provided
8
* by Oracle in the LICENSE file that accompanied this code.
9
*
10
* This code is distributed in the hope that it will be useful, but WITHOUT
11
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13
* version 2 for more details (a copy is included in the LICENSE file that
14
* accompanied this code).
15
*
16
* You should have received a copy of the GNU General Public License version
17
* 2 along with this work; if not, write to the Free Software Foundation,
18
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19
*
20
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21
* or visit www.oracle.com if you need additional information or have any
22
* questions.
23
*/
24
25
/* pngpread.c - read a png file in push mode
26
*
27
* This file is available under and governed by the GNU General Public
28
* License version 2 only, as published by the Free Software Foundation.
29
* However, the following notice accompanied the original version of this
30
* file and, per its terms, should not be removed:
31
*
32
* Copyright (c) 2018 Cosmin Truta
33
* Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
34
* Copyright (c) 1996-1997 Andreas Dilger
35
* Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
36
*
37
* This code is released under the libpng license.
38
* For conditions of distribution and use, see the disclaimer
39
* and license in png.h
40
*/
41
42
#include "pngpriv.h"
43
44
#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
45
46
/* Push model modes */
47
#define PNG_READ_SIG_MODE 0
48
#define PNG_READ_CHUNK_MODE 1
49
#define PNG_READ_IDAT_MODE 2
50
#define PNG_READ_tEXt_MODE 4
51
#define PNG_READ_zTXt_MODE 5
52
#define PNG_READ_DONE_MODE 6
53
#define PNG_READ_iTXt_MODE 7
54
#define PNG_ERROR_MODE 8
55
56
#define PNG_PUSH_SAVE_BUFFER_IF_FULL \
57
if (png_ptr->push_length + 4 > png_ptr->buffer_size) \
58
{ png_push_save_buffer(png_ptr); return; }
59
#define PNG_PUSH_SAVE_BUFFER_IF_LT(N) \
60
if (png_ptr->buffer_size < N) \
61
{ png_push_save_buffer(png_ptr); return; }
62
63
void PNGAPI
64
png_process_data(png_structrp png_ptr, png_inforp info_ptr,
65
png_bytep buffer, size_t buffer_size)
66
{
67
if (png_ptr == NULL || info_ptr == NULL)
68
return;
69
70
png_push_restore_buffer(png_ptr, buffer, buffer_size);
71
72
while (png_ptr->buffer_size)
73
{
74
png_process_some_data(png_ptr, info_ptr);
75
}
76
}
77
78
size_t PNGAPI
79
png_process_data_pause(png_structrp png_ptr, int save)
80
{
81
if (png_ptr != NULL)
82
{
83
/* It's easiest for the caller if we do the save; then the caller doesn't
84
* have to supply the same data again:
85
*/
86
if (save != 0)
87
png_push_save_buffer(png_ptr);
88
else
89
{
90
/* This includes any pending saved bytes: */
91
size_t remaining = png_ptr->buffer_size;
92
png_ptr->buffer_size = 0;
93
94
/* So subtract the saved buffer size, unless all the data
95
* is actually 'saved', in which case we just return 0
96
*/
97
if (png_ptr->save_buffer_size < remaining)
98
return remaining - png_ptr->save_buffer_size;
99
}
100
}
101
102
return 0;
103
}
104
105
png_uint_32 PNGAPI
106
png_process_data_skip(png_structrp png_ptr)
107
{
108
/* TODO: Deprecate and remove this API.
109
* Somewhere the implementation of this seems to have been lost,
110
* or abandoned. It was only to support some internal back-door access
111
* to png_struct) in libpng-1.4.x.
112
*/
113
png_app_warning(png_ptr,
114
"png_process_data_skip is not implemented in any current version of libpng");
115
return 0;
116
}
117
118
/* What we do with the incoming data depends on what we were previously
119
* doing before we ran out of data...
120
*/
121
void /* PRIVATE */
122
png_process_some_data(png_structrp png_ptr, png_inforp info_ptr)
123
{
124
if (png_ptr == NULL)
125
return;
126
127
switch (png_ptr->process_mode)
128
{
129
case PNG_READ_SIG_MODE:
130
{
131
png_push_read_sig(png_ptr, info_ptr);
132
break;
133
}
134
135
case PNG_READ_CHUNK_MODE:
136
{
137
png_push_read_chunk(png_ptr, info_ptr);
138
break;
139
}
140
141
case PNG_READ_IDAT_MODE:
142
{
143
png_push_read_IDAT(png_ptr);
144
break;
145
}
146
147
default:
148
{
149
png_ptr->buffer_size = 0;
150
break;
151
}
152
}
153
}
154
155
/* Read any remaining signature bytes from the stream and compare them with
156
* the correct PNG signature. It is possible that this routine is called
157
* with bytes already read from the signature, either because they have been
158
* checked by the calling application, or because of multiple calls to this
159
* routine.
160
*/
161
void /* PRIVATE */
162
png_push_read_sig(png_structrp png_ptr, png_inforp info_ptr)
163
{
164
size_t num_checked = png_ptr->sig_bytes; /* SAFE, does not exceed 8 */
165
size_t num_to_check = 8 - num_checked;
166
167
if (png_ptr->buffer_size < num_to_check)
168
{
169
num_to_check = png_ptr->buffer_size;
170
}
171
172
png_push_fill_buffer(png_ptr, &(info_ptr->signature[num_checked]),
173
num_to_check);
174
png_ptr->sig_bytes = (png_byte)(png_ptr->sig_bytes + num_to_check);
175
176
if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check))
177
{
178
if (num_checked < 4 &&
179
png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4))
180
png_error(png_ptr, "Not a PNG file");
181
182
else
183
png_error(png_ptr, "PNG file corrupted by ASCII conversion");
184
}
185
else
186
{
187
if (png_ptr->sig_bytes >= 8)
188
{
189
png_ptr->process_mode = PNG_READ_CHUNK_MODE;
190
}
191
}
192
}
193
194
void /* PRIVATE */
195
png_push_read_chunk(png_structrp png_ptr, png_inforp info_ptr)
196
{
197
png_uint_32 chunk_name;
198
#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
199
int keep; /* unknown handling method */
200
#endif
201
202
/* First we make sure we have enough data for the 4-byte chunk name
203
* and the 4-byte chunk length before proceeding with decoding the
204
* chunk data. To fully decode each of these chunks, we also make
205
* sure we have enough data in the buffer for the 4-byte CRC at the
206
* end of every chunk (except IDAT, which is handled separately).
207
*/
208
if ((png_ptr->mode & PNG_HAVE_CHUNK_HEADER) == 0)
209
{
210
png_byte chunk_length[4];
211
png_byte chunk_tag[4];
212
213
PNG_PUSH_SAVE_BUFFER_IF_LT(8)
214
png_push_fill_buffer(png_ptr, chunk_length, 4);
215
png_ptr->push_length = png_get_uint_31(png_ptr, chunk_length);
216
png_reset_crc(png_ptr);
217
png_crc_read(png_ptr, chunk_tag, 4);
218
png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(chunk_tag);
219
png_check_chunk_name(png_ptr, png_ptr->chunk_name);
220
png_check_chunk_length(png_ptr, png_ptr->push_length);
221
png_ptr->mode |= PNG_HAVE_CHUNK_HEADER;
222
}
223
224
chunk_name = png_ptr->chunk_name;
225
226
if (chunk_name == png_IDAT)
227
{
228
if ((png_ptr->mode & PNG_AFTER_IDAT) != 0)
229
png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT;
230
231
/* If we reach an IDAT chunk, this means we have read all of the
232
* header chunks, and we can start reading the image (or if this
233
* is called after the image has been read - we have an error).
234
*/
235
if ((png_ptr->mode & PNG_HAVE_IHDR) == 0)
236
png_error(png_ptr, "Missing IHDR before IDAT");
237
238
else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
239
(png_ptr->mode & PNG_HAVE_PLTE) == 0)
240
png_error(png_ptr, "Missing PLTE before IDAT");
241
242
png_ptr->process_mode = PNG_READ_IDAT_MODE;
243
244
if ((png_ptr->mode & PNG_HAVE_IDAT) != 0)
245
if ((png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT) == 0)
246
if (png_ptr->push_length == 0)
247
return;
248
249
png_ptr->mode |= PNG_HAVE_IDAT;
250
251
if ((png_ptr->mode & PNG_AFTER_IDAT) != 0)
252
png_benign_error(png_ptr, "Too many IDATs found");
253
}
254
255
if (chunk_name == png_IHDR)
256
{
257
if (png_ptr->push_length != 13)
258
png_error(png_ptr, "Invalid IHDR length");
259
260
PNG_PUSH_SAVE_BUFFER_IF_FULL
261
png_handle_IHDR(png_ptr, info_ptr, png_ptr->push_length);
262
}
263
264
else if (chunk_name == png_IEND)
265
{
266
PNG_PUSH_SAVE_BUFFER_IF_FULL
267
png_handle_IEND(png_ptr, info_ptr, png_ptr->push_length);
268
269
png_ptr->process_mode = PNG_READ_DONE_MODE;
270
png_push_have_end(png_ptr, info_ptr);
271
}
272
273
#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
274
else if ((keep = png_chunk_unknown_handling(png_ptr, chunk_name)) != 0)
275
{
276
PNG_PUSH_SAVE_BUFFER_IF_FULL
277
png_handle_unknown(png_ptr, info_ptr, png_ptr->push_length, keep);
278
279
if (chunk_name == png_PLTE)
280
png_ptr->mode |= PNG_HAVE_PLTE;
281
}
282
#endif
283
284
else if (chunk_name == png_PLTE)
285
{
286
PNG_PUSH_SAVE_BUFFER_IF_FULL
287
png_handle_PLTE(png_ptr, info_ptr, png_ptr->push_length);
288
}
289
290
else if (chunk_name == png_IDAT)
291
{
292
png_ptr->idat_size = png_ptr->push_length;
293
png_ptr->process_mode = PNG_READ_IDAT_MODE;
294
png_push_have_info(png_ptr, info_ptr);
295
png_ptr->zstream.avail_out =
296
(uInt) PNG_ROWBYTES(png_ptr->pixel_depth,
297
png_ptr->iwidth) + 1;
298
png_ptr->zstream.next_out = png_ptr->row_buf;
299
return;
300
}
301
302
#ifdef PNG_READ_gAMA_SUPPORTED
303
else if (png_ptr->chunk_name == png_gAMA)
304
{
305
PNG_PUSH_SAVE_BUFFER_IF_FULL
306
png_handle_gAMA(png_ptr, info_ptr, png_ptr->push_length);
307
}
308
309
#endif
310
#ifdef PNG_READ_sBIT_SUPPORTED
311
else if (png_ptr->chunk_name == png_sBIT)
312
{
313
PNG_PUSH_SAVE_BUFFER_IF_FULL
314
png_handle_sBIT(png_ptr, info_ptr, png_ptr->push_length);
315
}
316
317
#endif
318
#ifdef PNG_READ_cHRM_SUPPORTED
319
else if (png_ptr->chunk_name == png_cHRM)
320
{
321
PNG_PUSH_SAVE_BUFFER_IF_FULL
322
png_handle_cHRM(png_ptr, info_ptr, png_ptr->push_length);
323
}
324
325
#endif
326
#ifdef PNG_READ_sRGB_SUPPORTED
327
else if (chunk_name == png_sRGB)
328
{
329
PNG_PUSH_SAVE_BUFFER_IF_FULL
330
png_handle_sRGB(png_ptr, info_ptr, png_ptr->push_length);
331
}
332
333
#endif
334
#ifdef PNG_READ_iCCP_SUPPORTED
335
else if (png_ptr->chunk_name == png_iCCP)
336
{
337
PNG_PUSH_SAVE_BUFFER_IF_FULL
338
png_handle_iCCP(png_ptr, info_ptr, png_ptr->push_length);
339
}
340
341
#endif
342
#ifdef PNG_READ_sPLT_SUPPORTED
343
else if (chunk_name == png_sPLT)
344
{
345
PNG_PUSH_SAVE_BUFFER_IF_FULL
346
png_handle_sPLT(png_ptr, info_ptr, png_ptr->push_length);
347
}
348
349
#endif
350
#ifdef PNG_READ_tRNS_SUPPORTED
351
else if (chunk_name == png_tRNS)
352
{
353
PNG_PUSH_SAVE_BUFFER_IF_FULL
354
png_handle_tRNS(png_ptr, info_ptr, png_ptr->push_length);
355
}
356
357
#endif
358
#ifdef PNG_READ_bKGD_SUPPORTED
359
else if (chunk_name == png_bKGD)
360
{
361
PNG_PUSH_SAVE_BUFFER_IF_FULL
362
png_handle_bKGD(png_ptr, info_ptr, png_ptr->push_length);
363
}
364
365
#endif
366
#ifdef PNG_READ_hIST_SUPPORTED
367
else if (chunk_name == png_hIST)
368
{
369
PNG_PUSH_SAVE_BUFFER_IF_FULL
370
png_handle_hIST(png_ptr, info_ptr, png_ptr->push_length);
371
}
372
373
#endif
374
#ifdef PNG_READ_pHYs_SUPPORTED
375
else if (chunk_name == png_pHYs)
376
{
377
PNG_PUSH_SAVE_BUFFER_IF_FULL
378
png_handle_pHYs(png_ptr, info_ptr, png_ptr->push_length);
379
}
380
381
#endif
382
#ifdef PNG_READ_oFFs_SUPPORTED
383
else if (chunk_name == png_oFFs)
384
{
385
PNG_PUSH_SAVE_BUFFER_IF_FULL
386
png_handle_oFFs(png_ptr, info_ptr, png_ptr->push_length);
387
}
388
#endif
389
390
#ifdef PNG_READ_pCAL_SUPPORTED
391
else if (chunk_name == png_pCAL)
392
{
393
PNG_PUSH_SAVE_BUFFER_IF_FULL
394
png_handle_pCAL(png_ptr, info_ptr, png_ptr->push_length);
395
}
396
397
#endif
398
#ifdef PNG_READ_sCAL_SUPPORTED
399
else if (chunk_name == png_sCAL)
400
{
401
PNG_PUSH_SAVE_BUFFER_IF_FULL
402
png_handle_sCAL(png_ptr, info_ptr, png_ptr->push_length);
403
}
404
405
#endif
406
#ifdef PNG_READ_tIME_SUPPORTED
407
else if (chunk_name == png_tIME)
408
{
409
PNG_PUSH_SAVE_BUFFER_IF_FULL
410
png_handle_tIME(png_ptr, info_ptr, png_ptr->push_length);
411
}
412
413
#endif
414
#ifdef PNG_READ_tEXt_SUPPORTED
415
else if (chunk_name == png_tEXt)
416
{
417
PNG_PUSH_SAVE_BUFFER_IF_FULL
418
png_handle_tEXt(png_ptr, info_ptr, png_ptr->push_length);
419
}
420
421
#endif
422
#ifdef PNG_READ_zTXt_SUPPORTED
423
else if (chunk_name == png_zTXt)
424
{
425
PNG_PUSH_SAVE_BUFFER_IF_FULL
426
png_handle_zTXt(png_ptr, info_ptr, png_ptr->push_length);
427
}
428
429
#endif
430
#ifdef PNG_READ_iTXt_SUPPORTED
431
else if (chunk_name == png_iTXt)
432
{
433
PNG_PUSH_SAVE_BUFFER_IF_FULL
434
png_handle_iTXt(png_ptr, info_ptr, png_ptr->push_length);
435
}
436
#endif
437
438
else
439
{
440
PNG_PUSH_SAVE_BUFFER_IF_FULL
441
png_handle_unknown(png_ptr, info_ptr, png_ptr->push_length,
442
PNG_HANDLE_CHUNK_AS_DEFAULT);
443
}
444
445
png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
446
}
447
448
void PNGCBAPI
449
png_push_fill_buffer(png_structp png_ptr, png_bytep buffer, size_t length)
450
{
451
png_bytep ptr;
452
453
if (png_ptr == NULL)
454
return;
455
456
ptr = buffer;
457
if (png_ptr->save_buffer_size != 0)
458
{
459
size_t save_size;
460
461
if (length < png_ptr->save_buffer_size)
462
save_size = length;
463
464
else
465
save_size = png_ptr->save_buffer_size;
466
467
memcpy(ptr, png_ptr->save_buffer_ptr, save_size);
468
length -= save_size;
469
ptr += save_size;
470
png_ptr->buffer_size -= save_size;
471
png_ptr->save_buffer_size -= save_size;
472
png_ptr->save_buffer_ptr += save_size;
473
}
474
if (length != 0 && png_ptr->current_buffer_size != 0)
475
{
476
size_t save_size;
477
478
if (length < png_ptr->current_buffer_size)
479
save_size = length;
480
481
else
482
save_size = png_ptr->current_buffer_size;
483
484
memcpy(ptr, png_ptr->current_buffer_ptr, save_size);
485
png_ptr->buffer_size -= save_size;
486
png_ptr->current_buffer_size -= save_size;
487
png_ptr->current_buffer_ptr += save_size;
488
}
489
}
490
491
void /* PRIVATE */
492
png_push_save_buffer(png_structrp png_ptr)
493
{
494
if (png_ptr->save_buffer_size != 0)
495
{
496
if (png_ptr->save_buffer_ptr != png_ptr->save_buffer)
497
{
498
size_t i, istop;
499
png_bytep sp;
500
png_bytep dp;
501
502
istop = png_ptr->save_buffer_size;
503
for (i = 0, sp = png_ptr->save_buffer_ptr, dp = png_ptr->save_buffer;
504
i < istop; i++, sp++, dp++)
505
{
506
*dp = *sp;
507
}
508
}
509
}
510
if (png_ptr->save_buffer_size + png_ptr->current_buffer_size >
511
png_ptr->save_buffer_max)
512
{
513
size_t new_max;
514
png_bytep old_buffer;
515
516
if (png_ptr->save_buffer_size > PNG_SIZE_MAX -
517
(png_ptr->current_buffer_size + 256))
518
{
519
png_error(png_ptr, "Potential overflow of save_buffer");
520
}
521
522
new_max = png_ptr->save_buffer_size + png_ptr->current_buffer_size + 256;
523
old_buffer = png_ptr->save_buffer;
524
png_ptr->save_buffer = (png_bytep)png_malloc_warn(png_ptr,
525
(size_t)new_max);
526
527
if (png_ptr->save_buffer == NULL)
528
{
529
png_free(png_ptr, old_buffer);
530
png_error(png_ptr, "Insufficient memory for save_buffer");
531
}
532
533
if (old_buffer)
534
memcpy(png_ptr->save_buffer, old_buffer, png_ptr->save_buffer_size);
535
else if (png_ptr->save_buffer_size)
536
png_error(png_ptr, "save_buffer error");
537
png_free(png_ptr, old_buffer);
538
png_ptr->save_buffer_max = new_max;
539
}
540
if (png_ptr->current_buffer_size)
541
{
542
memcpy(png_ptr->save_buffer + png_ptr->save_buffer_size,
543
png_ptr->current_buffer_ptr, png_ptr->current_buffer_size);
544
png_ptr->save_buffer_size += png_ptr->current_buffer_size;
545
png_ptr->current_buffer_size = 0;
546
}
547
png_ptr->save_buffer_ptr = png_ptr->save_buffer;
548
png_ptr->buffer_size = 0;
549
}
550
551
void /* PRIVATE */
552
png_push_restore_buffer(png_structrp png_ptr, png_bytep buffer,
553
size_t buffer_length)
554
{
555
png_ptr->current_buffer = buffer;
556
png_ptr->current_buffer_size = buffer_length;
557
png_ptr->buffer_size = buffer_length + png_ptr->save_buffer_size;
558
png_ptr->current_buffer_ptr = png_ptr->current_buffer;
559
}
560
561
void /* PRIVATE */
562
png_push_read_IDAT(png_structrp png_ptr)
563
{
564
if ((png_ptr->mode & PNG_HAVE_CHUNK_HEADER) == 0)
565
{
566
png_byte chunk_length[4];
567
png_byte chunk_tag[4];
568
569
/* TODO: this code can be commoned up with the same code in push_read */
570
PNG_PUSH_SAVE_BUFFER_IF_LT(8)
571
png_push_fill_buffer(png_ptr, chunk_length, 4);
572
png_ptr->push_length = png_get_uint_31(png_ptr, chunk_length);
573
png_reset_crc(png_ptr);
574
png_crc_read(png_ptr, chunk_tag, 4);
575
png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(chunk_tag);
576
png_ptr->mode |= PNG_HAVE_CHUNK_HEADER;
577
578
if (png_ptr->chunk_name != png_IDAT)
579
{
580
png_ptr->process_mode = PNG_READ_CHUNK_MODE;
581
582
if ((png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED) == 0)
583
png_error(png_ptr, "Not enough compressed data");
584
585
return;
586
}
587
588
png_ptr->idat_size = png_ptr->push_length;
589
}
590
591
if (png_ptr->idat_size != 0 && png_ptr->save_buffer_size != 0)
592
{
593
size_t save_size = png_ptr->save_buffer_size;
594
png_uint_32 idat_size = png_ptr->idat_size;
595
596
/* We want the smaller of 'idat_size' and 'current_buffer_size', but they
597
* are of different types and we don't know which variable has the fewest
598
* bits. Carefully select the smaller and cast it to the type of the
599
* larger - this cannot overflow. Do not cast in the following test - it
600
* will break on either 16-bit or 64-bit platforms.
601
*/
602
if (idat_size < save_size)
603
save_size = (size_t)idat_size;
604
605
else
606
idat_size = (png_uint_32)save_size;
607
608
png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size);
609
610
png_process_IDAT_data(png_ptr, png_ptr->save_buffer_ptr, save_size);
611
612
png_ptr->idat_size -= idat_size;
613
png_ptr->buffer_size -= save_size;
614
png_ptr->save_buffer_size -= save_size;
615
png_ptr->save_buffer_ptr += save_size;
616
}
617
618
if (png_ptr->idat_size != 0 && png_ptr->current_buffer_size != 0)
619
{
620
size_t save_size = png_ptr->current_buffer_size;
621
png_uint_32 idat_size = png_ptr->idat_size;
622
623
/* We want the smaller of 'idat_size' and 'current_buffer_size', but they
624
* are of different types and we don't know which variable has the fewest
625
* bits. Carefully select the smaller and cast it to the type of the
626
* larger - this cannot overflow.
627
*/
628
if (idat_size < save_size)
629
save_size = (size_t)idat_size;
630
631
else
632
idat_size = (png_uint_32)save_size;
633
634
png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size);
635
636
png_process_IDAT_data(png_ptr, png_ptr->current_buffer_ptr, save_size);
637
638
png_ptr->idat_size -= idat_size;
639
png_ptr->buffer_size -= save_size;
640
png_ptr->current_buffer_size -= save_size;
641
png_ptr->current_buffer_ptr += save_size;
642
}
643
644
if (png_ptr->idat_size == 0)
645
{
646
PNG_PUSH_SAVE_BUFFER_IF_LT(4)
647
png_crc_finish(png_ptr, 0);
648
png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
649
png_ptr->mode |= PNG_AFTER_IDAT;
650
png_ptr->zowner = 0;
651
}
652
}
653
654
void /* PRIVATE */
655
png_process_IDAT_data(png_structrp png_ptr, png_bytep buffer,
656
size_t buffer_length)
657
{
658
/* The caller checks for a non-zero buffer length. */
659
if (!(buffer_length > 0) || buffer == NULL)
660
png_error(png_ptr, "No IDAT data (internal error)");
661
662
/* This routine must process all the data it has been given
663
* before returning, calling the row callback as required to
664
* handle the uncompressed results.
665
*/
666
png_ptr->zstream.next_in = buffer;
667
/* TODO: WARNING: TRUNCATION ERROR: DANGER WILL ROBINSON: */
668
png_ptr->zstream.avail_in = (uInt)buffer_length;
669
670
/* Keep going until the decompressed data is all processed
671
* or the stream marked as finished.
672
*/
673
while (png_ptr->zstream.avail_in > 0 &&
674
(png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED) == 0)
675
{
676
int ret;
677
678
/* We have data for zlib, but we must check that zlib
679
* has someplace to put the results. It doesn't matter
680
* if we don't expect any results -- it may be the input
681
* data is just the LZ end code.
682
*/
683
if (!(png_ptr->zstream.avail_out > 0))
684
{
685
/* TODO: WARNING: TRUNCATION ERROR: DANGER WILL ROBINSON: */
686
png_ptr->zstream.avail_out = (uInt)(PNG_ROWBYTES(png_ptr->pixel_depth,
687
png_ptr->iwidth) + 1);
688
689
png_ptr->zstream.next_out = png_ptr->row_buf;
690
}
691
692
/* Using Z_SYNC_FLUSH here means that an unterminated
693
* LZ stream (a stream with a missing end code) can still
694
* be handled, otherwise (Z_NO_FLUSH) a future zlib
695
* implementation might defer output and therefore
696
* change the current behavior (see comments in inflate.c
697
* for why this doesn't happen at present with zlib 1.2.5).
698
*/
699
ret = PNG_INFLATE(png_ptr, Z_SYNC_FLUSH);
700
701
/* Check for any failure before proceeding. */
702
if (ret != Z_OK && ret != Z_STREAM_END)
703
{
704
/* Terminate the decompression. */
705
png_ptr->flags |= PNG_FLAG_ZSTREAM_ENDED;
706
png_ptr->zowner = 0;
707
708
/* This may be a truncated stream (missing or
709
* damaged end code). Treat that as a warning.
710
*/
711
if (png_ptr->row_number >= png_ptr->num_rows ||
712
png_ptr->pass > 6)
713
png_warning(png_ptr, "Truncated compressed data in IDAT");
714
715
else
716
{
717
if (ret == Z_DATA_ERROR)
718
png_benign_error(png_ptr, "IDAT: ADLER32 checksum mismatch");
719
else
720
png_error(png_ptr, "Decompression error in IDAT");
721
}
722
723
/* Skip the check on unprocessed input */
724
return;
725
}
726
727
/* Did inflate output any data? */
728
if (png_ptr->zstream.next_out != png_ptr->row_buf)
729
{
730
/* Is this unexpected data after the last row?
731
* If it is, artificially terminate the LZ output
732
* here.
733
*/
734
if (png_ptr->row_number >= png_ptr->num_rows ||
735
png_ptr->pass > 6)
736
{
737
/* Extra data. */
738
png_warning(png_ptr, "Extra compressed data in IDAT");
739
png_ptr->flags |= PNG_FLAG_ZSTREAM_ENDED;
740
png_ptr->zowner = 0;
741
742
/* Do no more processing; skip the unprocessed
743
* input check below.
744
*/
745
return;
746
}
747
748
/* Do we have a complete row? */
749
if (png_ptr->zstream.avail_out == 0)
750
png_push_process_row(png_ptr);
751
}
752
753
/* And check for the end of the stream. */
754
if (ret == Z_STREAM_END)
755
png_ptr->flags |= PNG_FLAG_ZSTREAM_ENDED;
756
}
757
758
/* All the data should have been processed, if anything
759
* is left at this point we have bytes of IDAT data
760
* after the zlib end code.
761
*/
762
if (png_ptr->zstream.avail_in > 0)
763
png_warning(png_ptr, "Extra compression data in IDAT");
764
}
765
766
void /* PRIVATE */
767
png_push_process_row(png_structrp png_ptr)
768
{
769
/* 1.5.6: row_info moved out of png_struct to a local here. */
770
png_row_info row_info;
771
772
row_info.width = png_ptr->iwidth; /* NOTE: width of current interlaced row */
773
row_info.color_type = png_ptr->color_type;
774
row_info.bit_depth = png_ptr->bit_depth;
775
row_info.channels = png_ptr->channels;
776
row_info.pixel_depth = png_ptr->pixel_depth;
777
row_info.rowbytes = PNG_ROWBYTES(row_info.pixel_depth, row_info.width);
778
779
if (png_ptr->row_buf[0] > PNG_FILTER_VALUE_NONE)
780
{
781
if (png_ptr->row_buf[0] < PNG_FILTER_VALUE_LAST)
782
png_read_filter_row(png_ptr, &row_info, png_ptr->row_buf + 1,
783
png_ptr->prev_row + 1, png_ptr->row_buf[0]);
784
else
785
png_error(png_ptr, "bad adaptive filter value");
786
}
787
788
/* libpng 1.5.6: the following line was copying png_ptr->rowbytes before
789
* 1.5.6, while the buffer really is this big in current versions of libpng
790
* it may not be in the future, so this was changed just to copy the
791
* interlaced row count:
792
*/
793
memcpy(png_ptr->prev_row, png_ptr->row_buf, row_info.rowbytes + 1);
794
795
#ifdef PNG_READ_TRANSFORMS_SUPPORTED
796
if (png_ptr->transformations != 0)
797
png_do_read_transformations(png_ptr, &row_info);
798
#endif
799
800
/* The transformed pixel depth should match the depth now in row_info. */
801
if (png_ptr->transformed_pixel_depth == 0)
802
{
803
png_ptr->transformed_pixel_depth = row_info.pixel_depth;
804
if (row_info.pixel_depth > png_ptr->maximum_pixel_depth)
805
png_error(png_ptr, "progressive row overflow");
806
}
807
808
else if (png_ptr->transformed_pixel_depth != row_info.pixel_depth)
809
png_error(png_ptr, "internal progressive row size calculation error");
810
811
812
#ifdef PNG_READ_INTERLACING_SUPPORTED
813
/* Expand interlaced rows to full size */
814
if (png_ptr->interlaced != 0 &&
815
(png_ptr->transformations & PNG_INTERLACE) != 0)
816
{
817
if (png_ptr->pass < 6)
818
png_do_read_interlace(&row_info, png_ptr->row_buf + 1, png_ptr->pass,
819
png_ptr->transformations);
820
821
switch (png_ptr->pass)
822
{
823
case 0:
824
{
825
int i;
826
for (i = 0; i < 8 && png_ptr->pass == 0; i++)
827
{
828
png_push_have_row(png_ptr, png_ptr->row_buf + 1);
829
png_read_push_finish_row(png_ptr); /* Updates png_ptr->pass */
830
}
831
832
if (png_ptr->pass == 2) /* Pass 1 might be empty */
833
{
834
for (i = 0; i < 4 && png_ptr->pass == 2; i++)
835
{
836
png_push_have_row(png_ptr, NULL);
837
png_read_push_finish_row(png_ptr);
838
}
839
}
840
841
if (png_ptr->pass == 4 && png_ptr->height <= 4)
842
{
843
for (i = 0; i < 2 && png_ptr->pass == 4; i++)
844
{
845
png_push_have_row(png_ptr, NULL);
846
png_read_push_finish_row(png_ptr);
847
}
848
}
849
850
if (png_ptr->pass == 6 && png_ptr->height <= 4)
851
{
852
png_push_have_row(png_ptr, NULL);
853
png_read_push_finish_row(png_ptr);
854
}
855
856
break;
857
}
858
859
case 1:
860
{
861
int i;
862
for (i = 0; i < 8 && png_ptr->pass == 1; i++)
863
{
864
png_push_have_row(png_ptr, png_ptr->row_buf + 1);
865
png_read_push_finish_row(png_ptr);
866
}
867
868
if (png_ptr->pass == 2) /* Skip top 4 generated rows */
869
{
870
for (i = 0; i < 4 && png_ptr->pass == 2; i++)
871
{
872
png_push_have_row(png_ptr, NULL);
873
png_read_push_finish_row(png_ptr);
874
}
875
}
876
877
break;
878
}
879
880
case 2:
881
{
882
int i;
883
884
for (i = 0; i < 4 && png_ptr->pass == 2; i++)
885
{
886
png_push_have_row(png_ptr, png_ptr->row_buf + 1);
887
png_read_push_finish_row(png_ptr);
888
}
889
890
for (i = 0; i < 4 && png_ptr->pass == 2; i++)
891
{
892
png_push_have_row(png_ptr, NULL);
893
png_read_push_finish_row(png_ptr);
894
}
895
896
if (png_ptr->pass == 4) /* Pass 3 might be empty */
897
{
898
for (i = 0; i < 2 && png_ptr->pass == 4; i++)
899
{
900
png_push_have_row(png_ptr, NULL);
901
png_read_push_finish_row(png_ptr);
902
}
903
}
904
905
break;
906
}
907
908
case 3:
909
{
910
int i;
911
912
for (i = 0; i < 4 && png_ptr->pass == 3; i++)
913
{
914
png_push_have_row(png_ptr, png_ptr->row_buf + 1);
915
png_read_push_finish_row(png_ptr);
916
}
917
918
if (png_ptr->pass == 4) /* Skip top two generated rows */
919
{
920
for (i = 0; i < 2 && png_ptr->pass == 4; i++)
921
{
922
png_push_have_row(png_ptr, NULL);
923
png_read_push_finish_row(png_ptr);
924
}
925
}
926
927
break;
928
}
929
930
case 4:
931
{
932
int i;
933
934
for (i = 0; i < 2 && png_ptr->pass == 4; i++)
935
{
936
png_push_have_row(png_ptr, png_ptr->row_buf + 1);
937
png_read_push_finish_row(png_ptr);
938
}
939
940
for (i = 0; i < 2 && png_ptr->pass == 4; i++)
941
{
942
png_push_have_row(png_ptr, NULL);
943
png_read_push_finish_row(png_ptr);
944
}
945
946
if (png_ptr->pass == 6) /* Pass 5 might be empty */
947
{
948
png_push_have_row(png_ptr, NULL);
949
png_read_push_finish_row(png_ptr);
950
}
951
952
break;
953
}
954
955
case 5:
956
{
957
int i;
958
959
for (i = 0; i < 2 && png_ptr->pass == 5; i++)
960
{
961
png_push_have_row(png_ptr, png_ptr->row_buf + 1);
962
png_read_push_finish_row(png_ptr);
963
}
964
965
if (png_ptr->pass == 6) /* Skip top generated row */
966
{
967
png_push_have_row(png_ptr, NULL);
968
png_read_push_finish_row(png_ptr);
969
}
970
971
break;
972
}
973
974
default:
975
case 6:
976
{
977
png_push_have_row(png_ptr, png_ptr->row_buf + 1);
978
png_read_push_finish_row(png_ptr);
979
980
if (png_ptr->pass != 6)
981
break;
982
983
png_push_have_row(png_ptr, NULL);
984
png_read_push_finish_row(png_ptr);
985
}
986
}
987
}
988
else
989
#endif
990
{
991
png_push_have_row(png_ptr, png_ptr->row_buf + 1);
992
png_read_push_finish_row(png_ptr);
993
}
994
}
995
996
void /* PRIVATE */
997
png_read_push_finish_row(png_structrp png_ptr)
998
{
999
#ifdef PNG_READ_INTERLACING_SUPPORTED
1000
/* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
1001
1002
/* Start of interlace block */
1003
static const png_byte png_pass_start[] = {0, 4, 0, 2, 0, 1, 0};
1004
1005
/* Offset to next interlace block */
1006
static const png_byte png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1};
1007
1008
/* Start of interlace block in the y direction */
1009
static const png_byte png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1};
1010
1011
/* Offset to next interlace block in the y direction */
1012
static const png_byte png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2};
1013
1014
/* Height of interlace block. This is not currently used - if you need
1015
* it, uncomment it here and in png.h
1016
static const png_byte png_pass_height[] = {8, 8, 4, 4, 2, 2, 1};
1017
*/
1018
#endif
1019
1020
png_ptr->row_number++;
1021
if (png_ptr->row_number < png_ptr->num_rows)
1022
return;
1023
1024
#ifdef PNG_READ_INTERLACING_SUPPORTED
1025
if (png_ptr->interlaced != 0)
1026
{
1027
png_ptr->row_number = 0;
1028
memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1);
1029
1030
do
1031
{
1032
png_ptr->pass++;
1033
if ((png_ptr->pass == 1 && png_ptr->width < 5) ||
1034
(png_ptr->pass == 3 && png_ptr->width < 3) ||
1035
(png_ptr->pass == 5 && png_ptr->width < 2))
1036
png_ptr->pass++;
1037
1038
if (png_ptr->pass > 7)
1039
png_ptr->pass--;
1040
1041
if (png_ptr->pass >= 7)
1042
break;
1043
1044
png_ptr->iwidth = (png_ptr->width +
1045
png_pass_inc[png_ptr->pass] - 1 -
1046
png_pass_start[png_ptr->pass]) /
1047
png_pass_inc[png_ptr->pass];
1048
1049
if ((png_ptr->transformations & PNG_INTERLACE) != 0)
1050
break;
1051
1052
png_ptr->num_rows = (png_ptr->height +
1053
png_pass_yinc[png_ptr->pass] - 1 -
1054
png_pass_ystart[png_ptr->pass]) /
1055
png_pass_yinc[png_ptr->pass];
1056
1057
} while (png_ptr->iwidth == 0 || png_ptr->num_rows == 0);
1058
}
1059
#endif /* READ_INTERLACING */
1060
}
1061
1062
void /* PRIVATE */
1063
png_push_have_info(png_structrp png_ptr, png_inforp info_ptr)
1064
{
1065
if (png_ptr->info_fn != NULL)
1066
(*(png_ptr->info_fn))(png_ptr, info_ptr);
1067
}
1068
1069
void /* PRIVATE */
1070
png_push_have_end(png_structrp png_ptr, png_inforp info_ptr)
1071
{
1072
if (png_ptr->end_fn != NULL)
1073
(*(png_ptr->end_fn))(png_ptr, info_ptr);
1074
}
1075
1076
void /* PRIVATE */
1077
png_push_have_row(png_structrp png_ptr, png_bytep row)
1078
{
1079
if (png_ptr->row_fn != NULL)
1080
(*(png_ptr->row_fn))(png_ptr, row, png_ptr->row_number,
1081
(int)png_ptr->pass);
1082
}
1083
1084
#ifdef PNG_READ_INTERLACING_SUPPORTED
1085
void PNGAPI
1086
png_progressive_combine_row(png_const_structrp png_ptr, png_bytep old_row,
1087
png_const_bytep new_row)
1088
{
1089
if (png_ptr == NULL)
1090
return;
1091
1092
/* new_row is a flag here - if it is NULL then the app callback was called
1093
* from an empty row (see the calls to png_struct::row_fn below), otherwise
1094
* it must be png_ptr->row_buf+1
1095
*/
1096
if (new_row != NULL)
1097
png_combine_row(png_ptr, old_row, 1/*blocky display*/);
1098
}
1099
#endif /* READ_INTERLACING */
1100
1101
void PNGAPI
1102
png_set_progressive_read_fn(png_structrp png_ptr, png_voidp progressive_ptr,
1103
png_progressive_info_ptr info_fn, png_progressive_row_ptr row_fn,
1104
png_progressive_end_ptr end_fn)
1105
{
1106
if (png_ptr == NULL)
1107
return;
1108
1109
png_ptr->info_fn = info_fn;
1110
png_ptr->row_fn = row_fn;
1111
png_ptr->end_fn = end_fn;
1112
1113
png_set_read_fn(png_ptr, progressive_ptr, png_push_fill_buffer);
1114
}
1115
1116
png_voidp PNGAPI
1117
png_get_progressive_ptr(png_const_structrp png_ptr)
1118
{
1119
if (png_ptr == NULL)
1120
return (NULL);
1121
1122
return png_ptr->io_ptr;
1123
}
1124
#endif /* PROGRESSIVE_READ */
1125
1126