Coverage Report

Created: 2024-05-20 07:14

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