Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

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