~ubuntu-branches/ubuntu/dapper/perl-tk/dapper

« back to all changes in this revision

Viewing changes to PNG/libpng/pngpread.c

  • Committer: Bazaar Package Importer
  • Author(s): Michael C. Schultheiss
  • Date: 2006-01-16 16:54:02 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20060116165402-1ppygm8hh8ahel2x
Tags: 1:804.027-2
* Incorporate changes from NMU (Thanks to Steve Kowalik.
  Closes: #348086)
* debian/control: Update Standards-Version (no changes needed)

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