~baltix/+junk/irrlicht-test

« back to all changes in this revision

Viewing changes to source/Irrlicht/libpng/pngpread.c

  • Committer: Mantas Kriaučiūnas
  • Date: 2011-07-18 13:06:25 UTC
  • Revision ID: mantas@akl.lt-20110718130625-c5pvifp61e7kj1ol
Included whole irrlicht SVN libraries to work around launchpad recipe issue with quilt, see https://answers.launchpad.net/launchpad/+question/165193

Show diffs side-by-side

added added

removed removed

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