pngpread.c 48.4 KB
Newer Older
G
Guy Schalnat 已提交
1 2

/* pngpread.c - read a png file in push mode
3
 *
4
 * Last changed in libpng 1.5.0 [October 8, 2010]
5
 * Copyright (c) 1998-2010 Glenn Randers-Pehrson
6 7
 * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
 * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
8
 *
9
 * This code is released under the libpng license.
10
 * For conditions of distribution and use, see the disclaimer
11
 * and license in png.h
12
 */
G
Guy Schalnat 已提交
13

14
#include "pngpriv.h"
G
Guy Schalnat 已提交
15

16 17
#ifdef PNG_PROGRESSIVE_READ_SUPPORTED

18
/* Push model modes */
19 20 21 22 23 24 25 26 27 28
#define PNG_READ_SIG_MODE   0
#define PNG_READ_CHUNK_MODE 1
#define PNG_READ_IDAT_MODE  2
#define PNG_SKIP_MODE       3
#define PNG_READ_tEXt_MODE  4
#define PNG_READ_zTXt_MODE  5
#define PNG_READ_DONE_MODE  6
#define PNG_READ_iTXt_MODE  7
#define PNG_ERROR_MODE      8

29
void PNGAPI
A
Andreas Dilger 已提交
30
png_process_data(png_structp png_ptr, png_infop info_ptr,
31
    png_bytep buffer, png_size_t buffer_size)
G
Guy Schalnat 已提交
32
{
33 34 35
   if (png_ptr == NULL || info_ptr == NULL)
      return;

G
Guy Schalnat 已提交
36
   png_push_restore_buffer(png_ptr, buffer, buffer_size);
G
Guy Schalnat 已提交
37

G
Guy Schalnat 已提交
38 39
   while (png_ptr->buffer_size)
   {
A
Andreas Dilger 已提交
40
      png_process_some_data(png_ptr, info_ptr);
G
Guy Schalnat 已提交
41
   }
G
Guy Schalnat 已提交
42 43
}

A
Andreas Dilger 已提交
44 45 46
/* What we do with the incoming data depends on what we were previously
 * doing before we ran out of data...
 */
47
void /* PRIVATE */
A
Andreas Dilger 已提交
48
png_process_some_data(png_structp png_ptr, png_infop info_ptr)
G
Guy Schalnat 已提交
49
{
50 51 52
   if (png_ptr == NULL)
      return;

G
Guy Schalnat 已提交
53 54 55 56
   switch (png_ptr->process_mode)
   {
      case PNG_READ_SIG_MODE:
      {
A
Andreas Dilger 已提交
57
         png_push_read_sig(png_ptr, info_ptr);
G
Guy Schalnat 已提交
58 59
         break;
      }
60

G
Guy Schalnat 已提交
61 62
      case PNG_READ_CHUNK_MODE:
      {
A
Andreas Dilger 已提交
63
         png_push_read_chunk(png_ptr, info_ptr);
G
Guy Schalnat 已提交
64 65
         break;
      }
66

G
Guy Schalnat 已提交
67 68
      case PNG_READ_IDAT_MODE:
      {
G
Guy Schalnat 已提交
69
         png_push_read_IDAT(png_ptr);
G
Guy Schalnat 已提交
70 71
         break;
      }
72

73
#ifdef PNG_READ_tEXt_SUPPORTED
G
Guy Schalnat 已提交
74 75
      case PNG_READ_tEXt_MODE:
      {
A
Andreas Dilger 已提交
76
         png_push_read_tEXt(png_ptr, info_ptr);
G
Guy Schalnat 已提交
77 78
         break;
      }
79

G
Guy Schalnat 已提交
80
#endif
81
#ifdef PNG_READ_zTXt_SUPPORTED
G
Guy Schalnat 已提交
82 83
      case PNG_READ_zTXt_MODE:
      {
A
Andreas Dilger 已提交
84
         png_push_read_zTXt(png_ptr, info_ptr);
G
Guy Schalnat 已提交
85 86
         break;
      }
87

88
#endif
89
#ifdef PNG_READ_iTXt_SUPPORTED
90 91 92 93 94
      case PNG_READ_iTXt_MODE:
      {
         png_push_read_iTXt(png_ptr, info_ptr);
         break;
      }
95

G
Guy Schalnat 已提交
96 97 98
#endif
      case PNG_SKIP_MODE:
      {
A
Andreas Dilger 已提交
99
         png_push_crc_finish(png_ptr);
G
Guy Schalnat 已提交
100 101
         break;
      }
102

G
Guy Schalnat 已提交
103 104 105 106 107 108
      default:
      {
         png_ptr->buffer_size = 0;
         break;
      }
   }
G
Guy Schalnat 已提交
109 110
}

A
Andreas Dilger 已提交
111 112
/* Read any remaining signature bytes from the stream and compare them with
 * the correct PNG signature.  It is possible that this routine is called
113 114 115
 * with bytes already read from the signature, either because they have been
 * checked by the calling application, or because of multiple calls to this
 * routine.
A
Andreas Dilger 已提交
116
 */
117
void /* PRIVATE */
A
Andreas Dilger 已提交
118
png_push_read_sig(png_structp png_ptr, png_infop info_ptr)
G
Guy Schalnat 已提交
119
{
A
Andreas Dilger 已提交
120 121
   png_size_t num_checked = png_ptr->sig_bytes,
             num_to_check = 8 - num_checked;
G
Guy Schalnat 已提交
122

A
Andreas Dilger 已提交
123
   if (png_ptr->buffer_size < num_to_check)
G
Guy Schalnat 已提交
124
   {
A
Andreas Dilger 已提交
125
      num_to_check = png_ptr->buffer_size;
G
Guy Schalnat 已提交
126 127
   }

128
   png_push_fill_buffer(png_ptr, &(info_ptr->signature[num_checked]),
129
       num_to_check);
130
   png_ptr->sig_bytes = (png_byte)(png_ptr->sig_bytes + num_to_check);
G
Guy Schalnat 已提交
131

A
Andreas Dilger 已提交
132
   if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check))
G
Guy Schalnat 已提交
133
   {
A
Andreas Dilger 已提交
134 135 136
      if (num_checked < 4 &&
          png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4))
         png_error(png_ptr, "Not a PNG file");
137

A
Andreas Dilger 已提交
138 139
      else
         png_error(png_ptr, "PNG file corrupted by ASCII conversion");
G
Guy Schalnat 已提交
140 141 142
   }
   else
   {
A
Andreas Dilger 已提交
143 144 145 146
      if (png_ptr->sig_bytes >= 8)
      {
         png_ptr->process_mode = PNG_READ_CHUNK_MODE;
      }
G
Guy Schalnat 已提交
147
   }
G
Guy Schalnat 已提交
148 149
}

150
void /* PRIVATE */
A
Andreas Dilger 已提交
151
png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
G
Guy Schalnat 已提交
152
{
153 154 155 156
      PNG_IHDR;
      PNG_IDAT;
      PNG_IEND;
      PNG_PLTE;
157
#ifdef PNG_READ_bKGD_SUPPORTED
158
      PNG_bKGD;
159
#endif
160
#ifdef PNG_READ_cHRM_SUPPORTED
161
      PNG_cHRM;
162
#endif
163
#ifdef PNG_READ_gAMA_SUPPORTED
164
      PNG_gAMA;
165
#endif
166
#ifdef PNG_READ_hIST_SUPPORTED
167
      PNG_hIST;
168
#endif
169
#ifdef PNG_READ_iCCP_SUPPORTED
170
      PNG_iCCP;
171
#endif
172
#ifdef PNG_READ_iTXt_SUPPORTED
173
      PNG_iTXt;
174
#endif
175
#ifdef PNG_READ_oFFs_SUPPORTED
176
      PNG_oFFs;
177
#endif
178
#ifdef PNG_READ_pCAL_SUPPORTED
179
      PNG_pCAL;
180
#endif
181
#ifdef PNG_READ_pHYs_SUPPORTED
182
      PNG_pHYs;
183
#endif
184
#ifdef PNG_READ_sBIT_SUPPORTED
185
      PNG_sBIT;
186
#endif
187
#ifdef PNG_READ_sCAL_SUPPORTED
188
      PNG_sCAL;
189
#endif
190
#ifdef PNG_READ_sRGB_SUPPORTED
191
      PNG_sRGB;
192
#endif
193
#ifdef PNG_READ_sPLT_SUPPORTED
194
      PNG_sPLT;
195
#endif
196
#ifdef PNG_READ_tEXt_SUPPORTED
197
      PNG_tEXt;
198
#endif
199
#ifdef PNG_READ_tIME_SUPPORTED
200
      PNG_tIME;
201
#endif
202
#ifdef PNG_READ_tRNS_SUPPORTED
203
      PNG_tRNS;
204
#endif
205
#ifdef PNG_READ_zTXt_SUPPORTED
206
      PNG_zTXt;
207
#endif
208

A
Andreas Dilger 已提交
209
   /* First we make sure we have enough data for the 4 byte chunk name
210 211 212 213 214
    * and the 4 byte chunk length before proceeding with decoding the
    * chunk data.  To fully decode each of these chunks, we also make
    * sure we have enough data in the buffer for the 4 byte CRC at the
    * end of every chunk (except IDAT, which is handled separately).
    */
215
   if (!(png_ptr->mode & PNG_HAVE_CHUNK_HEADER))
G
Guy Schalnat 已提交
216
   {
A
Andreas Dilger 已提交
217
      png_byte chunk_length[4];
G
Guy Schalnat 已提交
218 219 220 221 222 223 224

      if (png_ptr->buffer_size < 8)
      {
         png_push_save_buffer(png_ptr);
         return;
      }

A
Andreas Dilger 已提交
225
      png_push_fill_buffer(png_ptr, chunk_length, 4);
226
      png_ptr->push_length = png_get_uint_31(png_ptr, chunk_length);
G
Guy Schalnat 已提交
227
      png_reset_crc(png_ptr);
A
Andreas Dilger 已提交
228
      png_crc_read(png_ptr, png_ptr->chunk_name, 4);
229
      png_check_chunk_name(png_ptr, png_ptr->chunk_name);
230
      png_ptr->mode |= PNG_HAVE_CHUNK_HEADER;
G
Guy Schalnat 已提交
231 232
   }

233
   if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
234 235
      if (png_ptr->mode & PNG_AFTER_IDAT)
         png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT;
236

A
Andreas Dilger 已提交
237
   if (!png_memcmp(png_ptr->chunk_name, png_IHDR, 4))
G
Guy Schalnat 已提交
238
   {
239 240
      if (png_ptr->push_length != 13)
         png_error(png_ptr, "Invalid IHDR length");
241

242 243 244
      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
      {
         png_push_save_buffer(png_ptr);
G
Guy Schalnat 已提交
245
         return;
246
      }
247

A
Andreas Dilger 已提交
248
      png_handle_IHDR(png_ptr, info_ptr, png_ptr->push_length);
G
Guy Schalnat 已提交
249
   }
250

251 252
   else if (!png_memcmp(png_ptr->chunk_name, png_IEND, 4))
   {
253 254 255
      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
      {
         png_push_save_buffer(png_ptr);
256
         return;
257
      }
258

259 260 261 262 263
      png_handle_IEND(png_ptr, info_ptr, png_ptr->push_length);

      png_ptr->process_mode = PNG_READ_DONE_MODE;
      png_push_have_end(png_ptr, info_ptr);
   }
264

265 266 267
#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
   else if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name))
   {
268 269 270
      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
      {
         png_push_save_buffer(png_ptr);
271
         return;
272
      }
273

274 275
      if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
         png_ptr->mode |= PNG_HAVE_IDAT;
276

277
      png_handle_unknown(png_ptr, info_ptr, png_ptr->push_length);
278

279 280
      if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4))
         png_ptr->mode |= PNG_HAVE_PLTE;
281

282 283 284 285
      else if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
      {
         if (!(png_ptr->mode & PNG_HAVE_IHDR))
            png_error(png_ptr, "Missing IHDR before IDAT");
286

287
         else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
288
             !(png_ptr->mode & PNG_HAVE_PLTE))
289 290 291
            png_error(png_ptr, "Missing PLTE before IDAT");
      }
   }
292

293
#endif
A
Andreas Dilger 已提交
294
   else if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4))
G
Guy Schalnat 已提交
295
   {
296 297 298
      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
      {
         png_push_save_buffer(png_ptr);
A
Andreas Dilger 已提交
299
         return;
300
      }
A
Andreas Dilger 已提交
301
      png_handle_PLTE(png_ptr, info_ptr, png_ptr->push_length);
G
Guy Schalnat 已提交
302
   }
303

304
   else if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
G
Guy Schalnat 已提交
305
   {
A
Andreas Dilger 已提交
306
      /* If we reach an IDAT chunk, this means we have read all of the
307 308 309
       * header chunks, and we can start reading the image (or if this
       * is called after the image has been read - we have an error).
       */
310 311 312 313 314 315 316

      if (!(png_ptr->mode & PNG_HAVE_IHDR))
         png_error(png_ptr, "Missing IHDR before IDAT");

      else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
          !(png_ptr->mode & PNG_HAVE_PLTE))
         png_error(png_ptr, "Missing PLTE before IDAT");
317

A
Andreas Dilger 已提交
318 319
      if (png_ptr->mode & PNG_HAVE_IDAT)
      {
320
         if (!(png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT))
321 322
            if (png_ptr->push_length == 0)
               return;
A
Andreas Dilger 已提交
323 324

         if (png_ptr->mode & PNG_AFTER_IDAT)
325
            png_benign_error(png_ptr, "Too many IDATs found");
A
Andreas Dilger 已提交
326 327
      }

G
Guy Schalnat 已提交
328
      png_ptr->idat_size = png_ptr->push_length;
A
Andreas Dilger 已提交
329
      png_ptr->mode |= PNG_HAVE_IDAT;
G
Guy Schalnat 已提交
330
      png_ptr->process_mode = PNG_READ_IDAT_MODE;
A
Andreas Dilger 已提交
331
      png_push_have_info(png_ptr, info_ptr);
332 333 334
      png_ptr->zstream.avail_out =
          (uInt) PNG_ROWBYTES(png_ptr->pixel_depth,
          png_ptr->iwidth) + 1;
A
Andreas Dilger 已提交
335
      png_ptr->zstream.next_out = png_ptr->row_buf;
G
Guy Schalnat 已提交
336 337
      return;
   }
338

339
#ifdef PNG_READ_gAMA_SUPPORTED
A
Andreas Dilger 已提交
340
   else if (!png_memcmp(png_ptr->chunk_name, png_gAMA, 4))
G
Guy Schalnat 已提交
341
   {
342 343 344
      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
      {
         png_push_save_buffer(png_ptr);
G
Guy Schalnat 已提交
345
         return;
346
      }
347

A
Andreas Dilger 已提交
348
      png_handle_gAMA(png_ptr, info_ptr, png_ptr->push_length);
G
Guy Schalnat 已提交
349
   }
350

G
Guy Schalnat 已提交
351
#endif
352
#ifdef PNG_READ_sBIT_SUPPORTED
A
Andreas Dilger 已提交
353
   else if (!png_memcmp(png_ptr->chunk_name, png_sBIT, 4))
G
Guy Schalnat 已提交
354
   {
355 356 357
      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
      {
         png_push_save_buffer(png_ptr);
G
Guy Schalnat 已提交
358
         return;
359
      }
360

A
Andreas Dilger 已提交
361
      png_handle_sBIT(png_ptr, info_ptr, png_ptr->push_length);
G
Guy Schalnat 已提交
362
   }
363

G
Guy Schalnat 已提交
364
#endif
365
#ifdef PNG_READ_cHRM_SUPPORTED
A
Andreas Dilger 已提交
366
   else if (!png_memcmp(png_ptr->chunk_name, png_cHRM, 4))
G
Guy Schalnat 已提交
367
   {
368 369 370
      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
      {
         png_push_save_buffer(png_ptr);
G
Guy Schalnat 已提交
371
         return;
372
      }
373

A
Andreas Dilger 已提交
374
      png_handle_cHRM(png_ptr, info_ptr, png_ptr->push_length);
G
Guy Schalnat 已提交
375
   }
376

G
Guy Schalnat 已提交
377
#endif
378
#ifdef PNG_READ_sRGB_SUPPORTED
379 380
   else if (!png_memcmp(png_ptr->chunk_name, png_sRGB, 4))
   {
381 382 383
      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
      {
         png_push_save_buffer(png_ptr);
384
         return;
385
      }
386

387 388
      png_handle_sRGB(png_ptr, info_ptr, png_ptr->push_length);
   }
389

390
#endif
391
#ifdef PNG_READ_iCCP_SUPPORTED
392 393
   else if (!png_memcmp(png_ptr->chunk_name, png_iCCP, 4))
   {
394 395 396
      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
      {
         png_push_save_buffer(png_ptr);
397
         return;
398
      }
399

400 401
      png_handle_iCCP(png_ptr, info_ptr, png_ptr->push_length);
   }
402

403
#endif
404
#ifdef PNG_READ_sPLT_SUPPORTED
405 406
   else if (!png_memcmp(png_ptr->chunk_name, png_sPLT, 4))
   {
407 408 409
      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
      {
         png_push_save_buffer(png_ptr);
410
         return;
411
      }
412

413 414
      png_handle_sPLT(png_ptr, info_ptr, png_ptr->push_length);
   }
415

416
#endif
417
#ifdef PNG_READ_tRNS_SUPPORTED
A
Andreas Dilger 已提交
418
   else if (!png_memcmp(png_ptr->chunk_name, png_tRNS, 4))
G
Guy Schalnat 已提交
419
   {
420 421 422
      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
      {
         png_push_save_buffer(png_ptr);
G
Guy Schalnat 已提交
423
         return;
424
      }
425

A
Andreas Dilger 已提交
426
      png_handle_tRNS(png_ptr, info_ptr, png_ptr->push_length);
G
Guy Schalnat 已提交
427
   }
428

G
Guy Schalnat 已提交
429
#endif
430
#ifdef PNG_READ_bKGD_SUPPORTED
A
Andreas Dilger 已提交
431
   else if (!png_memcmp(png_ptr->chunk_name, png_bKGD, 4))
G
Guy Schalnat 已提交
432
   {
433 434 435
      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
      {
         png_push_save_buffer(png_ptr);
G
Guy Schalnat 已提交
436
         return;
437
      }
438

A
Andreas Dilger 已提交
439
      png_handle_bKGD(png_ptr, info_ptr, png_ptr->push_length);
G
Guy Schalnat 已提交
440
   }
441

G
Guy Schalnat 已提交
442
#endif
443
#ifdef PNG_READ_hIST_SUPPORTED
A
Andreas Dilger 已提交
444
   else if (!png_memcmp(png_ptr->chunk_name, png_hIST, 4))
G
Guy Schalnat 已提交
445
   {
446 447 448
      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
      {
         png_push_save_buffer(png_ptr);
G
Guy Schalnat 已提交
449
         return;
450
      }
451

A
Andreas Dilger 已提交
452
      png_handle_hIST(png_ptr, info_ptr, png_ptr->push_length);
G
Guy Schalnat 已提交
453
   }
454

G
Guy Schalnat 已提交
455
#endif
456
#ifdef PNG_READ_pHYs_SUPPORTED
A
Andreas Dilger 已提交
457
   else if (!png_memcmp(png_ptr->chunk_name, png_pHYs, 4))
G
Guy Schalnat 已提交
458 459 460 461 462 463
   {
      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
      {
         png_push_save_buffer(png_ptr);
         return;
      }
464

A
Andreas Dilger 已提交
465
      png_handle_pHYs(png_ptr, info_ptr, png_ptr->push_length);
G
Guy Schalnat 已提交
466
   }
467

G
Guy Schalnat 已提交
468
#endif
469
#ifdef PNG_READ_oFFs_SUPPORTED
A
Andreas Dilger 已提交
470
   else if (!png_memcmp(png_ptr->chunk_name, png_oFFs, 4))
G
Guy Schalnat 已提交
471
   {
472 473 474
      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
      {
         png_push_save_buffer(png_ptr);
G
Guy Schalnat 已提交
475
         return;
476
      }
477

A
Andreas Dilger 已提交
478
      png_handle_oFFs(png_ptr, info_ptr, png_ptr->push_length);
G
Guy Schalnat 已提交
479
   }
G
Guy Schalnat 已提交
480
#endif
481

482
#ifdef PNG_READ_pCAL_SUPPORTED
A
Andreas Dilger 已提交
483 484
   else if (!png_memcmp(png_ptr->chunk_name, png_pCAL, 4))
   {
485 486 487
      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
      {
         png_push_save_buffer(png_ptr);
A
Andreas Dilger 已提交
488
         return;
489
      }
490

A
Andreas Dilger 已提交
491 492
      png_handle_pCAL(png_ptr, info_ptr, png_ptr->push_length);
   }
493

A
Andreas Dilger 已提交
494
#endif
495
#ifdef PNG_READ_sCAL_SUPPORTED
496 497
   else if (!png_memcmp(png_ptr->chunk_name, png_sCAL, 4))
   {
498 499 500
      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
      {
         png_push_save_buffer(png_ptr);
501
         return;
502
      }
503

504 505
      png_handle_sCAL(png_ptr, info_ptr, png_ptr->push_length);
   }
506

507
#endif
508
#ifdef PNG_READ_tIME_SUPPORTED
A
Andreas Dilger 已提交
509
   else if (!png_memcmp(png_ptr->chunk_name, png_tIME, 4))
G
Guy Schalnat 已提交
510
   {
511 512 513
      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
      {
         png_push_save_buffer(png_ptr);
G
Guy Schalnat 已提交
514
         return;
515
      }
516

A
Andreas Dilger 已提交
517
      png_handle_tIME(png_ptr, info_ptr, png_ptr->push_length);
G
Guy Schalnat 已提交
518
   }
519

G
Guy Schalnat 已提交
520
#endif
521
#ifdef PNG_READ_tEXt_SUPPORTED
A
Andreas Dilger 已提交
522
   else if (!png_memcmp(png_ptr->chunk_name, png_tEXt, 4))
G
Guy Schalnat 已提交
523
   {
524 525 526
      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
      {
         png_push_save_buffer(png_ptr);
527
         return;
528
      }
529

A
Andreas Dilger 已提交
530
      png_push_handle_tEXt(png_ptr, info_ptr, png_ptr->push_length);
G
Guy Schalnat 已提交
531
   }
532

G
Guy Schalnat 已提交
533
#endif
534
#ifdef PNG_READ_zTXt_SUPPORTED
A
Andreas Dilger 已提交
535
   else if (!png_memcmp(png_ptr->chunk_name, png_zTXt, 4))
G
Guy Schalnat 已提交
536
   {
537 538 539
      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
      {
         png_push_save_buffer(png_ptr);
540
         return;
541
      }
542

A
Andreas Dilger 已提交
543
      png_push_handle_zTXt(png_ptr, info_ptr, png_ptr->push_length);
G
Guy Schalnat 已提交
544
   }
545

546
#endif
547
#ifdef PNG_READ_iTXt_SUPPORTED
548
   else if (!png_memcmp(png_ptr->chunk_name, png_iTXt, 4))
549
   {
550 551 552
      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
      {
         png_push_save_buffer(png_ptr);
553
         return;
554
      }
555

556 557
      png_push_handle_iTXt(png_ptr, info_ptr, png_ptr->push_length);
   }
558

G
Guy Schalnat 已提交
559
#endif
G
Guy Schalnat 已提交
560 561
   else
   {
562 563 564
      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
      {
         png_push_save_buffer(png_ptr);
565
         return;
566
      }
A
Andreas Dilger 已提交
567
      png_push_handle_unknown(png_ptr, info_ptr, png_ptr->push_length);
G
Guy Schalnat 已提交
568
   }
G
Guy Schalnat 已提交
569

570
   png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
G
Guy Schalnat 已提交
571 572
}

573
void /* PRIVATE */
A
Andreas Dilger 已提交
574
png_push_crc_skip(png_structp png_ptr, png_uint_32 skip)
G
Guy Schalnat 已提交
575
{
G
Guy Schalnat 已提交
576
   png_ptr->process_mode = PNG_SKIP_MODE;
A
Andreas Dilger 已提交
577
   png_ptr->skip_length = skip;
G
Guy Schalnat 已提交
578 579
}

580
void /* PRIVATE */
A
Andreas Dilger 已提交
581
png_push_crc_finish(png_structp png_ptr)
G
Guy Schalnat 已提交
582
{
G
Guy Schalnat 已提交
583 584
   if (png_ptr->skip_length && png_ptr->save_buffer_size)
   {
585 586
      png_size_t save_size = png_ptr->current_buffer_size;
      png_uint_32 skip_length = png_ptr->skip_length;
G
Guy Schalnat 已提交
587

588 589 590 591 592 593 594 595
      /* We want the smaller of 'skip_length' and 'current_buffer_size', but
       * they are of different types and we don't know which variable has the
       * fewest bits.  Carefully select the smaller and cast it to the type of
       * the larger - this cannot overflow.  Do not cast in the following test
       * - it will break on either 16 or 64 bit platforms.
       */
      if (skip_length < save_size)
         save_size = (png_size_t)skip_length;
596

G
Guy Schalnat 已提交
597
      else
598
         skip_length = (png_uint_32)save_size;
G
Guy Schalnat 已提交
599 600 601

      png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size);

602
      png_ptr->skip_length -= skip_length;
G
Guy Schalnat 已提交
603 604
      png_ptr->buffer_size -= save_size;
      png_ptr->save_buffer_size -= save_size;
A
Andreas Dilger 已提交
605
      png_ptr->save_buffer_ptr += save_size;
G
Guy Schalnat 已提交
606 607 608
   }
   if (png_ptr->skip_length && png_ptr->current_buffer_size)
   {
609 610
      png_size_t save_size = png_ptr->current_buffer_size;
      png_uint_32 skip_length = png_ptr->skip_length;
G
Guy Schalnat 已提交
611

612 613 614 615 616 617 618
      /* We want the smaller of 'skip_length' and 'current_buffer_size', but
       * they are of different types and we don't know which variable has the
       * fewest bits.  Carefully select the smaller and cast it to the type of
       * the larger - this cannot overflow.
       */
      if (skip_length < save_size)
         save_size = (png_size_t)skip_length;
619

G
Guy Schalnat 已提交
620
      else
621
         skip_length = (png_uint_32)save_size;
G
Guy Schalnat 已提交
622 623 624

      png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size);

625
      png_ptr->skip_length -= skip_length;
G
Guy Schalnat 已提交
626 627
      png_ptr->buffer_size -= save_size;
      png_ptr->current_buffer_size -= save_size;
A
Andreas Dilger 已提交
628
      png_ptr->current_buffer_ptr += save_size;
G
Guy Schalnat 已提交
629 630 631 632 633 634 635 636
   }
   if (!png_ptr->skip_length)
   {
      if (png_ptr->buffer_size < 4)
      {
         png_push_save_buffer(png_ptr);
         return;
      }
A
Andreas Dilger 已提交
637 638

      png_crc_finish(png_ptr, 0);
A
Andreas Dilger 已提交
639
      png_ptr->process_mode = PNG_READ_CHUNK_MODE;
G
Guy Schalnat 已提交
640
   }
G
Guy Schalnat 已提交
641 642
}

643
void PNGCBAPI
A
Andreas Dilger 已提交
644
png_push_fill_buffer(png_structp png_ptr, png_bytep buffer, png_size_t length)
G
Guy Schalnat 已提交
645
{
G
Guy Schalnat 已提交
646 647
   png_bytep ptr;

648 649 650
   if (png_ptr == NULL)
      return;

G
Guy Schalnat 已提交
651 652 653
   ptr = buffer;
   if (png_ptr->save_buffer_size)
   {
A
Andreas Dilger 已提交
654
      png_size_t save_size;
G
Guy Schalnat 已提交
655 656 657

      if (length < png_ptr->save_buffer_size)
         save_size = length;
658

G
Guy Schalnat 已提交
659 660 661
      else
         save_size = png_ptr->save_buffer_size;

A
Andreas Dilger 已提交
662
      png_memcpy(ptr, png_ptr->save_buffer_ptr, save_size);
G
Guy Schalnat 已提交
663
      length -= save_size;
A
Andreas Dilger 已提交
664
      ptr += save_size;
G
Guy Schalnat 已提交
665 666
      png_ptr->buffer_size -= save_size;
      png_ptr->save_buffer_size -= save_size;
A
Andreas Dilger 已提交
667
      png_ptr->save_buffer_ptr += save_size;
G
Guy Schalnat 已提交
668 669 670
   }
   if (length && png_ptr->current_buffer_size)
   {
A
Andreas Dilger 已提交
671
      png_size_t save_size;
G
Guy Schalnat 已提交
672 673 674

      if (length < png_ptr->current_buffer_size)
         save_size = length;
675

G
Guy Schalnat 已提交
676 677 678
      else
         save_size = png_ptr->current_buffer_size;

A
Andreas Dilger 已提交
679
      png_memcpy(ptr, png_ptr->current_buffer_ptr, save_size);
G
Guy Schalnat 已提交
680 681
      png_ptr->buffer_size -= save_size;
      png_ptr->current_buffer_size -= save_size;
A
Andreas Dilger 已提交
682
      png_ptr->current_buffer_ptr += save_size;
G
Guy Schalnat 已提交
683
   }
G
Guy Schalnat 已提交
684 685
}

686
void /* PRIVATE */
G
Guy Schalnat 已提交
687 688
png_push_save_buffer(png_structp png_ptr)
{
G
Guy Schalnat 已提交
689 690 691 692
   if (png_ptr->save_buffer_size)
   {
      if (png_ptr->save_buffer_ptr != png_ptr->save_buffer)
      {
693
         png_size_t i, istop;
G
Guy Schalnat 已提交
694 695 696
         png_bytep sp;
         png_bytep dp;

697
         istop = png_ptr->save_buffer_size;
G
Guy Schalnat 已提交
698
         for (i = 0, sp = png_ptr->save_buffer_ptr, dp = png_ptr->save_buffer;
699
             i < istop; i++, sp++, dp++)
G
Guy Schalnat 已提交
700 701 702 703 704
         {
            *dp = *sp;
         }
      }
   }
705
   if (png_ptr->save_buffer_size + png_ptr->current_buffer_size >
706
       png_ptr->save_buffer_max)
G
Guy Schalnat 已提交
707
   {
A
Andreas Dilger 已提交
708
      png_size_t new_max;
G
Guy Schalnat 已提交
709 710
      png_bytep old_buffer;

711
      if (png_ptr->save_buffer_size > PNG_SIZE_MAX -
712
          (png_ptr->current_buffer_size + 256))
713
      {
714
         png_error(png_ptr, "Potential overflow of save_buffer");
715
      }
716

717
      new_max = png_ptr->save_buffer_size + png_ptr->current_buffer_size + 256;
G
Guy Schalnat 已提交
718
      old_buffer = png_ptr->save_buffer;
719
      png_ptr->save_buffer = (png_bytep)png_malloc_warn(png_ptr,
720
          (png_size_t)new_max);
721

722 723
      if (png_ptr->save_buffer == NULL)
      {
724 725
         png_free(png_ptr, old_buffer);
         png_error(png_ptr, "Insufficient memory for save_buffer");
726
      }
727

728 729 730
      png_memcpy(png_ptr->save_buffer, old_buffer, png_ptr->save_buffer_size);
      png_free(png_ptr, old_buffer);
      png_ptr->save_buffer_max = new_max;
G
Guy Schalnat 已提交
731 732 733
   }
   if (png_ptr->current_buffer_size)
   {
A
Andreas Dilger 已提交
734 735
      png_memcpy(png_ptr->save_buffer + png_ptr->save_buffer_size,
         png_ptr->current_buffer_ptr, png_ptr->current_buffer_size);
G
Guy Schalnat 已提交
736 737 738 739 740
      png_ptr->save_buffer_size += png_ptr->current_buffer_size;
      png_ptr->current_buffer_size = 0;
   }
   png_ptr->save_buffer_ptr = png_ptr->save_buffer;
   png_ptr->buffer_size = 0;
G
Guy Schalnat 已提交
741 742
}

743
void /* PRIVATE */
G
Guy Schalnat 已提交
744
png_push_restore_buffer(png_structp png_ptr, png_bytep buffer,
A
Andreas Dilger 已提交
745
   png_size_t buffer_length)
G
Guy Schalnat 已提交
746
{
G
Guy Schalnat 已提交
747 748 749 750
   png_ptr->current_buffer = buffer;
   png_ptr->current_buffer_size = buffer_length;
   png_ptr->buffer_size = buffer_length + png_ptr->save_buffer_size;
   png_ptr->current_buffer_ptr = png_ptr->current_buffer;
G
Guy Schalnat 已提交
751 752
}

753
void /* PRIVATE */
G
Guy Schalnat 已提交
754
png_push_read_IDAT(png_structp png_ptr)
G
Guy Schalnat 已提交
755
{
756
   PNG_IDAT;
757
   if (!(png_ptr->mode & PNG_HAVE_CHUNK_HEADER))
G
Guy Schalnat 已提交
758
   {
A
Andreas Dilger 已提交
759
      png_byte chunk_length[4];
G
Guy Schalnat 已提交
760 761 762 763 764 765 766

      if (png_ptr->buffer_size < 8)
      {
         png_push_save_buffer(png_ptr);
         return;
      }

A
Andreas Dilger 已提交
767
      png_push_fill_buffer(png_ptr, chunk_length, 4);
768
      png_ptr->push_length = png_get_uint_31(png_ptr, chunk_length);
G
Guy Schalnat 已提交
769
      png_reset_crc(png_ptr);
A
Andreas Dilger 已提交
770
      png_crc_read(png_ptr, png_ptr->chunk_name, 4);
771
      png_ptr->mode |= PNG_HAVE_CHUNK_HEADER;
A
Andreas Dilger 已提交
772

773
      if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
G
Guy Schalnat 已提交
774
      {
A
Andreas Dilger 已提交
775
         png_ptr->process_mode = PNG_READ_CHUNK_MODE;
776

G
Guy Schalnat 已提交
777
         if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
G
Guy Schalnat 已提交
778
            png_error(png_ptr, "Not enough compressed data");
779

G
Guy Schalnat 已提交
780 781 782 783 784 785 786
         return;
      }

      png_ptr->idat_size = png_ptr->push_length;
   }
   if (png_ptr->idat_size && png_ptr->save_buffer_size)
   {
787 788
      png_size_t save_size = png_ptr->save_buffer_size;
      png_uint_32 idat_size = png_ptr->idat_size;
789

790 791 792 793 794 795 796 797
      /* We want the smaller of 'idat_size' and 'current_buffer_size', but they
       * are of different types and we don't know which variable has the fewest
       * bits.  Carefully select the smaller and cast it to the type of the
       * larger - this cannot overflow.  Do not cast in the following test - it
       * will break on either 16 or 64 bit platforms.
       */
      if (idat_size < save_size)
         save_size = (png_size_t)idat_size;
798

G
Guy Schalnat 已提交
799
      else
800
         idat_size = (png_uint_32)save_size;
G
Guy Schalnat 已提交
801 802

      png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size);
803

804
      png_process_IDAT_data(png_ptr, png_ptr->save_buffer_ptr, save_size);
805

806
      png_ptr->idat_size -= idat_size;
G
Guy Schalnat 已提交
807 808
      png_ptr->buffer_size -= save_size;
      png_ptr->save_buffer_size -= save_size;
A
Andreas Dilger 已提交
809
      png_ptr->save_buffer_ptr += save_size;
G
Guy Schalnat 已提交
810
   }
811

G
Guy Schalnat 已提交
812 813
   if (png_ptr->idat_size && png_ptr->current_buffer_size)
   {
814 815
      png_size_t save_size = png_ptr->current_buffer_size;
      png_uint_32 idat_size = png_ptr->idat_size;
G
Guy Schalnat 已提交
816

817 818 819 820 821 822 823
      /* We want the smaller of 'idat_size' and 'current_buffer_size', but they
       * are of different types and we don't know which variable has the fewest
       * bits.  Carefully select the smaller and cast it to the type of the
       * larger - this cannot overflow.
       */
      if (idat_size < save_size)
         save_size = (png_size_t)idat_size;
824

G
Guy Schalnat 已提交
825
      else
826
         idat_size = (png_uint_32)save_size;
G
Guy Schalnat 已提交
827 828

      png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size);
829

830
      png_process_IDAT_data(png_ptr, png_ptr->current_buffer_ptr, save_size);
G
Guy Schalnat 已提交
831

832
      png_ptr->idat_size -= idat_size;
G
Guy Schalnat 已提交
833 834
      png_ptr->buffer_size -= save_size;
      png_ptr->current_buffer_size -= save_size;
A
Andreas Dilger 已提交
835
      png_ptr->current_buffer_ptr += save_size;
G
Guy Schalnat 已提交
836 837 838 839 840 841 842 843 844
   }
   if (!png_ptr->idat_size)
   {
      if (png_ptr->buffer_size < 4)
      {
         png_push_save_buffer(png_ptr);
         return;
      }

A
Andreas Dilger 已提交
845
      png_crc_finish(png_ptr, 0);
846
      png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
847
      png_ptr->mode |= PNG_AFTER_IDAT;
G
Guy Schalnat 已提交
848
   }
G
Guy Schalnat 已提交
849 850
}

851
void /* PRIVATE */
G
Guy Schalnat 已提交
852
png_process_IDAT_data(png_structp png_ptr, png_bytep buffer,
A
Andreas Dilger 已提交
853
   png_size_t buffer_length)
G
Guy Schalnat 已提交
854
{
855
   /* The caller checks for a non-zero buffer length. */
856
   if (!(buffer_length > 0) || buffer == NULL)
857
      png_error(png_ptr, "No IDAT data (internal error)");
G
Guy Schalnat 已提交
858

859 860
   /* This routine must process all the data it has been given
    * before returning, calling the row callback as required to
861
    * handle the uncompressed results.
862
    */
A
Andreas Dilger 已提交
863 864
   png_ptr->zstream.next_in = buffer;
   png_ptr->zstream.avail_in = (uInt)buffer_length;
865 866 867 868 869

   /* Keep going until the decompressed data is all processed
    * or the stream marked as finished.
    */
   while (png_ptr->zstream.avail_in > 0 &&
870
          !(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
G
Guy Schalnat 已提交
871
   {
872 873 874
      int ret;

      /* We have data for zlib, but we must check that zlib
875
       * has someplace to put the results.  It doesn't matter
876
       * if we don't expect any results -- it may be the input
877 878 879
       * data is just the LZ end code.
       */
      if (!(png_ptr->zstream.avail_out > 0))
G
Guy Schalnat 已提交
880
      {
881 882 883
         png_ptr->zstream.avail_out =
             (uInt) PNG_ROWBYTES(png_ptr->pixel_depth,
             png_ptr->iwidth) + 1;
884

885 886 887 888
         png_ptr->zstream.next_out = png_ptr->row_buf;
      }

      /* Using Z_SYNC_FLUSH here means that an unterminated
889 890 891 892 893
       * LZ stream (a stream with a missing end code) can still
       * be handled, otherwise (Z_NO_FLUSH) a future zlib
       * implementation might defer output and therefore
       * change the current behavior (see comments in inflate.c
       * for why this doesn't happen at present with zlib 1.2.5).
894 895
       */
      ret = inflate(&png_ptr->zstream, Z_SYNC_FLUSH);
896

897 898 899
      /* Check for any failure before proceeding. */
      if (ret != Z_OK && ret != Z_STREAM_END)
      {
900 901
         /* Terminate the decompression. */
         png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
902

903
         /* This may be a truncated stream (missing or
904 905
          * damaged end code).  Treat that as a warning.
          */
906
         if (png_ptr->row_number >= png_ptr->num_rows ||
907 908
             png_ptr->pass > 6)
            png_warning(png_ptr, "Truncated compressed data in IDAT");
909

910 911
         else
            png_error(png_ptr, "Decompression error in IDAT");
912

913
         /* Skip the check on unprocessed input */
914
         return;
G
Guy Schalnat 已提交
915
      }
916 917 918

      /* Did inflate output any data? */
      if (png_ptr->zstream.next_out != png_ptr->row_buf)
G
Guy Schalnat 已提交
919
      {
920 921 922 923
         /* Is this unexpected data after the last row?
          * If it is, artificially terminate the LZ output
          * here.
          */
924
         if (png_ptr->row_number >= png_ptr->num_rows ||
925
             png_ptr->pass > 6)
926
         {
927 928
            /* Extra data. */
            png_warning(png_ptr, "Extra compressed data in IDAT");
929
            png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
930

931 932 933
            /* Do no more processing; skip the unprocessed
             * input check below.
             */
934
            return;
935
         }
936

937 938 939
         /* Do we have a complete row? */
         if (png_ptr->zstream.avail_out == 0)
            png_push_process_row(png_ptr);
G
Guy Schalnat 已提交
940
      }
941 942 943

      /* And check for the end of the stream. */
      if (ret == Z_STREAM_END)
944
         png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
A
Andreas Dilger 已提交
945
   }
946 947 948 949 950 951

   /* All the data should have been processed, if anything
    * is left at this point we have bytes of IDAT data
    * after the zlib end code.
    */
   if (png_ptr->zstream.avail_in > 0)
952
      png_warning(png_ptr, "Extra compression data in IDAT");
G
Guy Schalnat 已提交
953 954
}

955
void /* PRIVATE */
G
Guy Schalnat 已提交
956 957
png_push_process_row(png_structp png_ptr)
{
G
Guy Schalnat 已提交
958
   png_ptr->row_info.color_type = png_ptr->color_type;
G
Guy Schalnat 已提交
959 960 961 962
   png_ptr->row_info.width = png_ptr->iwidth;
   png_ptr->row_info.channels = png_ptr->channels;
   png_ptr->row_info.bit_depth = png_ptr->bit_depth;
   png_ptr->row_info.pixel_depth = png_ptr->pixel_depth;
963

964 965
   png_ptr->row_info.rowbytes = PNG_ROWBYTES(png_ptr->row_info.pixel_depth,
       png_ptr->row_info.width);
G
Guy Schalnat 已提交
966

G
Guy Schalnat 已提交
967
   png_read_filter_row(png_ptr, &(png_ptr->row_info),
968 969
       png_ptr->row_buf + 1, png_ptr->prev_row + 1,
       (int)(png_ptr->row_buf[0]));
G
Guy Schalnat 已提交
970

971
   png_memcpy(png_ptr->prev_row, png_ptr->row_buf, png_ptr->rowbytes + 1);
G
Guy Schalnat 已提交
972

973
   if (png_ptr->transformations || (png_ptr->flags&PNG_FLAG_STRIP_ALPHA))
G
Guy Schalnat 已提交
974 975
      png_do_read_transformations(png_ptr);

976
#ifdef PNG_READ_INTERLACING_SUPPORTED
977
   /* Blow up interlaced rows to full size */
A
Andreas Dilger 已提交
978
   if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE))
G
Guy Schalnat 已提交
979 980
   {
      if (png_ptr->pass < 6)
981
/*       old interface (pre-1.0.9):
G
Guy Schalnat 已提交
982
         png_do_read_interlace(&(png_ptr->row_info),
983
             png_ptr->row_buf + 1, png_ptr->pass, png_ptr->transformations);
984 985
 */
         png_do_read_interlace(png_ptr);
G
Guy Schalnat 已提交
986

987 988
    switch (png_ptr->pass)
    {
G
Guy Schalnat 已提交
989 990 991 992 993 994
         case 0:
         {
            int i;
            for (i = 0; i < 8 && png_ptr->pass == 0; i++)
            {
               png_push_have_row(png_ptr, png_ptr->row_buf + 1);
995
               png_read_push_finish_row(png_ptr); /* Updates png_ptr->pass */
G
Guy Schalnat 已提交
996
            }
997

998
            if (png_ptr->pass == 2) /* Pass 1 might be empty */
999 1000 1001
            {
               for (i = 0; i < 4 && png_ptr->pass == 2; i++)
               {
1002
                  png_push_have_row(png_ptr, NULL);
1003 1004 1005
                  png_read_push_finish_row(png_ptr);
               }
            }
1006

1007 1008 1009 1010
            if (png_ptr->pass == 4 && png_ptr->height <= 4)
            {
               for (i = 0; i < 2 && png_ptr->pass == 4; i++)
               {
1011
                  png_push_have_row(png_ptr, NULL);
1012 1013
                  png_read_push_finish_row(png_ptr);
               }
1014
            }
1015

1016 1017
            if (png_ptr->pass == 6 && png_ptr->height <= 4)
            {
1018
                png_push_have_row(png_ptr, NULL);
1019 1020
                png_read_push_finish_row(png_ptr);
            }
1021

G
Guy Schalnat 已提交
1022 1023
            break;
         }
1024

G
Guy Schalnat 已提交
1025 1026 1027 1028 1029 1030 1031 1032
         case 1:
         {
            int i;
            for (i = 0; i < 8 && png_ptr->pass == 1; i++)
            {
               png_push_have_row(png_ptr, png_ptr->row_buf + 1);
               png_read_push_finish_row(png_ptr);
            }
1033

1034
            if (png_ptr->pass == 2) /* Skip top 4 generated rows */
G
Guy Schalnat 已提交
1035 1036 1037
            {
               for (i = 0; i < 4 && png_ptr->pass == 2; i++)
               {
1038
                  png_push_have_row(png_ptr, NULL);
G
Guy Schalnat 已提交
1039 1040 1041
                  png_read_push_finish_row(png_ptr);
               }
            }
1042

G
Guy Schalnat 已提交
1043 1044
            break;
         }
1045

G
Guy Schalnat 已提交
1046 1047 1048
         case 2:
         {
            int i;
1049

G
Guy Schalnat 已提交
1050 1051 1052 1053 1054
            for (i = 0; i < 4 && png_ptr->pass == 2; i++)
            {
               png_push_have_row(png_ptr, png_ptr->row_buf + 1);
               png_read_push_finish_row(png_ptr);
            }
1055

G
Guy Schalnat 已提交
1056 1057
            for (i = 0; i < 4 && png_ptr->pass == 2; i++)
            {
1058
               png_push_have_row(png_ptr, NULL);
G
Guy Schalnat 已提交
1059 1060
               png_read_push_finish_row(png_ptr);
            }
1061

1062
            if (png_ptr->pass == 4) /* Pass 3 might be empty */
1063 1064 1065
            {
               for (i = 0; i < 2 && png_ptr->pass == 4; i++)
               {
1066
                  png_push_have_row(png_ptr, NULL);
1067 1068 1069
                  png_read_push_finish_row(png_ptr);
               }
            }
1070

G
Guy Schalnat 已提交
1071 1072
            break;
         }
1073

G
Guy Schalnat 已提交
1074 1075 1076
         case 3:
         {
            int i;
1077

G
Guy Schalnat 已提交
1078 1079 1080 1081 1082
            for (i = 0; i < 4 && png_ptr->pass == 3; i++)
            {
               png_push_have_row(png_ptr, png_ptr->row_buf + 1);
               png_read_push_finish_row(png_ptr);
            }
1083

1084
            if (png_ptr->pass == 4) /* Skip top two generated rows */
G
Guy Schalnat 已提交
1085 1086 1087
            {
               for (i = 0; i < 2 && png_ptr->pass == 4; i++)
               {
1088
                  png_push_have_row(png_ptr, NULL);
G
Guy Schalnat 已提交
1089 1090 1091
                  png_read_push_finish_row(png_ptr);
               }
            }
1092

G
Guy Schalnat 已提交
1093 1094
            break;
         }
1095

G
Guy Schalnat 已提交
1096 1097 1098
         case 4:
         {
            int i;
1099

G
Guy Schalnat 已提交
1100 1101 1102 1103 1104
            for (i = 0; i < 2 && png_ptr->pass == 4; i++)
            {
               png_push_have_row(png_ptr, png_ptr->row_buf + 1);
               png_read_push_finish_row(png_ptr);
            }
1105

G
Guy Schalnat 已提交
1106 1107
            for (i = 0; i < 2 && png_ptr->pass == 4; i++)
            {
1108
               png_push_have_row(png_ptr, NULL);
G
Guy Schalnat 已提交
1109 1110
               png_read_push_finish_row(png_ptr);
            }
1111

1112
            if (png_ptr->pass == 6) /* Pass 5 might be empty */
1113
            {
1114
               png_push_have_row(png_ptr, NULL);
1115 1116
               png_read_push_finish_row(png_ptr);
            }
1117

G
Guy Schalnat 已提交
1118 1119
            break;
         }
1120

G
Guy Schalnat 已提交
1121 1122 1123
         case 5:
         {
            int i;
1124

G
Guy Schalnat 已提交
1125 1126 1127 1128 1129
            for (i = 0; i < 2 && png_ptr->pass == 5; i++)
            {
               png_push_have_row(png_ptr, png_ptr->row_buf + 1);
               png_read_push_finish_row(png_ptr);
            }
1130

1131
            if (png_ptr->pass == 6) /* Skip top generated row */
G
Guy Schalnat 已提交
1132
            {
1133
               png_push_have_row(png_ptr, NULL);
G
Guy Schalnat 已提交
1134 1135
               png_read_push_finish_row(png_ptr);
            }
1136

G
Guy Schalnat 已提交
1137 1138
            break;
         }
1139

G
Guy Schalnat 已提交
1140 1141 1142 1143
         case 6:
         {
            png_push_have_row(png_ptr, png_ptr->row_buf + 1);
            png_read_push_finish_row(png_ptr);
1144

G
Guy Schalnat 已提交
1145 1146
            if (png_ptr->pass != 6)
               break;
1147

1148
            png_push_have_row(png_ptr, NULL);
G
Guy Schalnat 已提交
1149 1150 1151 1152 1153
            png_read_push_finish_row(png_ptr);
         }
      }
   }
   else
G
Guy Schalnat 已提交
1154
#endif
G
Guy Schalnat 已提交
1155 1156 1157 1158
   {
      png_push_have_row(png_ptr, png_ptr->row_buf + 1);
      png_read_push_finish_row(png_ptr);
   }
G
Guy Schalnat 已提交
1159 1160
}

1161
void /* PRIVATE */
G
Guy Schalnat 已提交
1162 1163
png_read_push_finish_row(png_structp png_ptr)
{
1164
   /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
1165

1166
   /* Start of interlace block */
1167
   PNG_CONST int FARDATA png_pass_start[] = {0, 4, 0, 2, 0, 1, 0};
1168

1169
   /* Offset to next interlace block */
1170
   PNG_CONST int FARDATA png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1};
1171

1172
   /* Start of interlace block in the y direction */
1173
   PNG_CONST int FARDATA png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1};
1174

1175
   /* Offset to next interlace block in the y direction */
1176
   PNG_CONST int FARDATA png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2};
1177

1178 1179
   /* Height of interlace block.  This is not currently used - if you need
    * it, uncomment it here and in png.h
1180
   PNG_CONST int FARDATA png_pass_height[] = {8, 8, 4, 4, 2, 2, 1};
1181
   */
1182

G
Guy Schalnat 已提交
1183 1184
   png_ptr->row_number++;
   if (png_ptr->row_number < png_ptr->num_rows)
G
Guy Schalnat 已提交
1185
      return;
G
Guy Schalnat 已提交
1186

1187
#ifdef PNG_READ_INTERLACING_SUPPORTED
G
Guy Schalnat 已提交
1188 1189 1190
   if (png_ptr->interlaced)
   {
      png_ptr->row_number = 0;
1191 1192
      png_memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1);

G
Guy Schalnat 已提交
1193 1194 1195
      do
      {
         png_ptr->pass++;
1196 1197 1198
         if ((png_ptr->pass == 1 && png_ptr->width < 5) ||
             (png_ptr->pass == 3 && png_ptr->width < 3) ||
             (png_ptr->pass == 5 && png_ptr->width < 2))
1199
            png_ptr->pass++;
1200

1201 1202
         if (png_ptr->pass > 7)
            png_ptr->pass--;
1203

G
Guy Schalnat 已提交
1204 1205
         if (png_ptr->pass >= 7)
            break;
1206

G
Guy Schalnat 已提交
1207
         png_ptr->iwidth = (png_ptr->width +
1208 1209 1210
             png_pass_inc[png_ptr->pass] - 1 -
             png_pass_start[png_ptr->pass]) /
             png_pass_inc[png_ptr->pass];
1211

G
Guy Schalnat 已提交
1212 1213
         if (png_ptr->transformations & PNG_INTERLACE)
            break;
1214 1215

         png_ptr->num_rows = (png_ptr->height +
1216 1217 1218
             png_pass_yinc[png_ptr->pass] - 1 -
             png_pass_ystart[png_ptr->pass]) /
             png_pass_yinc[png_ptr->pass];
1219 1220

      } while (png_ptr->iwidth == 0 || png_ptr->num_rows == 0);
G
Guy Schalnat 已提交
1221
   }
1222
#endif /* PNG_READ_INTERLACING_SUPPORTED */
G
Guy Schalnat 已提交
1223 1224
}

1225
#ifdef PNG_READ_tEXt_SUPPORTED
1226
void /* PRIVATE */
1227
png_push_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32
1228
    length)
G
Guy Schalnat 已提交
1229
{
1230
   if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND))
1231
      {
1232
         info_ptr = info_ptr; /* To quiet some compiler warnings */
1233
         png_error(png_ptr, "Out of place tEXt");
1234
         /*NOT REACHED*/
1235
      }
A
Andreas Dilger 已提交
1236

A
Andreas Dilger 已提交
1237 1238 1239
#ifdef PNG_MAX_MALLOC_64K
   png_ptr->skip_length = 0;  /* This may not be necessary */

1240
   if (length > (png_uint_32)65535L) /* Can't hold entire string in memory */
A
Andreas Dilger 已提交
1241 1242
   {
      png_warning(png_ptr, "tEXt chunk too large to fit in memory");
1243 1244
      png_ptr->skip_length = length - (png_uint_32)65535L;
      length = (png_uint_32)65535L;
A
Andreas Dilger 已提交
1245 1246 1247
   }
#endif

1248
   png_ptr->current_text = (png_charp)png_malloc(png_ptr,
1249
       (png_size_t)(length + 1));
A
Andreas Dilger 已提交
1250
   png_ptr->current_text[length] = '\0';
G
Guy Schalnat 已提交
1251
   png_ptr->current_text_ptr = png_ptr->current_text;
1252 1253
   png_ptr->current_text_size = (png_size_t)length;
   png_ptr->current_text_left = (png_size_t)length;
G
Guy Schalnat 已提交
1254
   png_ptr->process_mode = PNG_READ_tEXt_MODE;
G
Guy Schalnat 已提交
1255 1256
}

1257
void /* PRIVATE */
A
Andreas Dilger 已提交
1258
png_push_read_tEXt(png_structp png_ptr, png_infop info_ptr)
G
Guy Schalnat 已提交
1259
{
G
Guy Schalnat 已提交
1260 1261
   if (png_ptr->buffer_size && png_ptr->current_text_left)
   {
A
Andreas Dilger 已提交
1262
      png_size_t text_size;
G
Guy Schalnat 已提交
1263 1264 1265

      if (png_ptr->buffer_size < png_ptr->current_text_left)
         text_size = png_ptr->buffer_size;
1266

G
Guy Schalnat 已提交
1267 1268
      else
         text_size = png_ptr->current_text_left;
1269

A
Andreas Dilger 已提交
1270
      png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size);
G
Guy Schalnat 已提交
1271
      png_ptr->current_text_left -= text_size;
A
Andreas Dilger 已提交
1272
      png_ptr->current_text_ptr += text_size;
G
Guy Schalnat 已提交
1273 1274 1275
   }
   if (!(png_ptr->current_text_left))
   {
A
Andreas Dilger 已提交
1276
      png_textp text_ptr;
G
Guy Schalnat 已提交
1277 1278
      png_charp text;
      png_charp key;
1279
      int ret;
G
Guy Schalnat 已提交
1280 1281 1282 1283 1284 1285 1286

      if (png_ptr->buffer_size < 4)
      {
         png_push_save_buffer(png_ptr);
         return;
      }

A
Andreas Dilger 已提交
1287 1288
      png_push_crc_finish(png_ptr);

1289
#ifdef PNG_MAX_MALLOC_64K
A
Andreas Dilger 已提交
1290 1291 1292
      if (png_ptr->skip_length)
         return;
#endif
G
Guy Schalnat 已提交
1293 1294 1295 1296

      key = png_ptr->current_text;

      for (text = key; *text; text++)
1297
         /* Empty loop */ ;
G
Guy Schalnat 已提交
1298

1299
      if (text < key + png_ptr->current_text_size)
G
Guy Schalnat 已提交
1300 1301
         text++;

1302
      text_ptr = (png_textp)png_malloc(png_ptr, png_sizeof(png_text));
A
Andreas Dilger 已提交
1303 1304
      text_ptr->compression = PNG_TEXT_COMPRESSION_NONE;
      text_ptr->key = key;
1305
      text_ptr->itxt_length = 0;
1306 1307
      text_ptr->lang = NULL;
      text_ptr->lang_key = NULL;
A
Andreas Dilger 已提交
1308
      text_ptr->text = text;
G
Guy Schalnat 已提交
1309

1310
      ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
A
Andreas Dilger 已提交
1311

1312
      png_free(png_ptr, key);
A
Andreas Dilger 已提交
1313
      png_free(png_ptr, text_ptr);
1314
      png_ptr->current_text = NULL;
1315 1316

      if (ret)
1317
         png_warning(png_ptr, "Insufficient memory to store text chunk");
G
Guy Schalnat 已提交
1318
   }
G
Guy Schalnat 已提交
1319 1320 1321
}
#endif

1322
#ifdef PNG_READ_zTXt_SUPPORTED
1323
void /* PRIVATE */
1324 1325
png_push_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32
   length)
G
Guy Schalnat 已提交
1326
{
1327
   if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND))
1328 1329
   {
      info_ptr = info_ptr; /* To quiet some compiler warnings */
1330 1331
      png_error(png_ptr, "Out of place zTXt");
      /*NOT REACHED*/
1332
   }
A
Andreas Dilger 已提交
1333

A
Andreas Dilger 已提交
1334 1335 1336 1337 1338
#ifdef PNG_MAX_MALLOC_64K
   /* We can't handle zTXt chunks > 64K, since we don't have enough space
    * to be able to store the uncompressed data.  Actually, the threshold
    * is probably around 32K, but it isn't as definite as 64K is.
    */
1339
   if (length > (png_uint_32)65535L)
A
Andreas Dilger 已提交
1340 1341 1342 1343 1344 1345 1346
   {
      png_warning(png_ptr, "zTXt chunk too large to fit in memory");
      png_push_crc_skip(png_ptr, length);
      return;
   }
#endif

1347
   png_ptr->current_text = (png_charp)png_malloc(png_ptr,
1348
       (png_size_t)(length + 1));
A
Andreas Dilger 已提交
1349
   png_ptr->current_text[length] = '\0';
G
Guy Schalnat 已提交
1350
   png_ptr->current_text_ptr = png_ptr->current_text;
1351 1352
   png_ptr->current_text_size = (png_size_t)length;
   png_ptr->current_text_left = (png_size_t)length;
G
Guy Schalnat 已提交
1353
   png_ptr->process_mode = PNG_READ_zTXt_MODE;
G
Guy Schalnat 已提交
1354 1355
}

1356
void /* PRIVATE */
A
Andreas Dilger 已提交
1357
png_push_read_zTXt(png_structp png_ptr, png_infop info_ptr)
G
Guy Schalnat 已提交
1358
{
G
Guy Schalnat 已提交
1359 1360
   if (png_ptr->buffer_size && png_ptr->current_text_left)
   {
A
Andreas Dilger 已提交
1361
      png_size_t text_size;
G
Guy Schalnat 已提交
1362

A
Andreas Dilger 已提交
1363
      if (png_ptr->buffer_size < (png_uint_32)png_ptr->current_text_left)
G
Guy Schalnat 已提交
1364
         text_size = png_ptr->buffer_size;
1365

G
Guy Schalnat 已提交
1366 1367
      else
         text_size = png_ptr->current_text_left;
1368

A
Andreas Dilger 已提交
1369
      png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size);
G
Guy Schalnat 已提交
1370
      png_ptr->current_text_left -= text_size;
A
Andreas Dilger 已提交
1371
      png_ptr->current_text_ptr += text_size;
G
Guy Schalnat 已提交
1372 1373 1374
   }
   if (!(png_ptr->current_text_left))
   {
A
Andreas Dilger 已提交
1375
      png_textp text_ptr;
G
Guy Schalnat 已提交
1376 1377 1378
      png_charp text;
      png_charp key;
      int ret;
A
Andreas Dilger 已提交
1379
      png_size_t text_size, key_size;
G
Guy Schalnat 已提交
1380 1381 1382 1383 1384 1385 1386

      if (png_ptr->buffer_size < 4)
      {
         png_push_save_buffer(png_ptr);
         return;
      }

A
Andreas Dilger 已提交
1387
      png_push_crc_finish(png_ptr);
G
Guy Schalnat 已提交
1388 1389 1390 1391

      key = png_ptr->current_text;

      for (text = key; *text; text++)
1392
         /* Empty loop */ ;
G
Guy Schalnat 已提交
1393 1394

      /* zTXt can't have zero text */
1395
      if (text >= key + png_ptr->current_text_size)
G
Guy Schalnat 已提交
1396
      {
1397
         png_ptr->current_text = NULL;
A
Andreas Dilger 已提交
1398
         png_free(png_ptr, key);
G
Guy Schalnat 已提交
1399 1400 1401 1402 1403
         return;
      }

      text++;

1404
      if (*text != PNG_TEXT_COMPRESSION_zTXt) /* Check compression byte */
G
Guy Schalnat 已提交
1405
      {
1406
         png_ptr->current_text = NULL;
A
Andreas Dilger 已提交
1407
         png_free(png_ptr, key);
G
Guy Schalnat 已提交
1408 1409 1410 1411 1412
         return;
      }

      text++;

A
Andreas Dilger 已提交
1413 1414
      png_ptr->zstream.next_in = (png_bytep )text;
      png_ptr->zstream.avail_in = (uInt)(png_ptr->current_text_size -
1415
          (text - key));
A
Andreas Dilger 已提交
1416
      png_ptr->zstream.next_out = png_ptr->zbuf;
1417
      png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
G
Guy Schalnat 已提交
1418 1419 1420 1421 1422 1423

      key_size = text - key;
      text_size = 0;
      text = NULL;
      ret = Z_STREAM_END;

A
Andreas Dilger 已提交
1424
      while (png_ptr->zstream.avail_in)
G
Guy Schalnat 已提交
1425
      {
A
Andreas Dilger 已提交
1426
         ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
G
Guy Schalnat 已提交
1427 1428
         if (ret != Z_OK && ret != Z_STREAM_END)
         {
A
Andreas Dilger 已提交
1429 1430
            inflateReset(&png_ptr->zstream);
            png_ptr->zstream.avail_in = 0;
1431
            png_ptr->current_text = NULL;
A
Andreas Dilger 已提交
1432 1433
            png_free(png_ptr, key);
            png_free(png_ptr, text);
G
Guy Schalnat 已提交
1434 1435
            return;
         }
1436

A
Andreas Dilger 已提交
1437
         if (!(png_ptr->zstream.avail_out) || ret == Z_STREAM_END)
G
Guy Schalnat 已提交
1438
         {
A
Andreas Dilger 已提交
1439
            if (text == NULL)
G
Guy Schalnat 已提交
1440
            {
A
Andreas Dilger 已提交
1441
               text = (png_charp)png_malloc(png_ptr,
1442 1443
                   (png_ptr->zbuf_size
                   - png_ptr->zstream.avail_out + key_size + 1));
1444

1445
               png_memcpy(text + key_size, png_ptr->zbuf,
1446
                   png_ptr->zbuf_size - png_ptr->zstream.avail_out);
1447

1448
               png_memcpy(text, key, key_size);
1449

1450
               text_size = key_size + png_ptr->zbuf_size -
1451
                   png_ptr->zstream.avail_out;
1452

1453
               *(text + text_size) = '\0';
G
Guy Schalnat 已提交
1454
            }
1455

G
Guy Schalnat 已提交
1456 1457 1458 1459 1460
            else
            {
               png_charp tmp;

               tmp = text;
1461
               text = (png_charp)png_malloc(png_ptr, text_size +
1462
                   (png_ptr->zbuf_size
1463
                   - png_ptr->zstream.avail_out + 1));
1464

1465 1466
               png_memcpy(text, tmp, text_size);
               png_free(png_ptr, tmp);
1467

1468
               png_memcpy(text + text_size, png_ptr->zbuf,
1469
                   png_ptr->zbuf_size - png_ptr->zstream.avail_out);
1470

1471 1472
               text_size += png_ptr->zbuf_size - png_ptr->zstream.avail_out;
               *(text + text_size) = '\0';
G
Guy Schalnat 已提交
1473
            }
1474

G
Guy Schalnat 已提交
1475 1476
            if (ret != Z_STREAM_END)
            {
A
Andreas Dilger 已提交
1477 1478
               png_ptr->zstream.next_out = png_ptr->zbuf;
               png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
G
Guy Schalnat 已提交
1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489
            }
         }
         else
         {
            break;
         }

         if (ret == Z_STREAM_END)
            break;
      }

A
Andreas Dilger 已提交
1490 1491
      inflateReset(&png_ptr->zstream);
      png_ptr->zstream.avail_in = 0;
G
Guy Schalnat 已提交
1492 1493 1494

      if (ret != Z_STREAM_END)
      {
1495
         png_ptr->current_text = NULL;
A
Andreas Dilger 已提交
1496 1497
         png_free(png_ptr, key);
         png_free(png_ptr, text);
G
Guy Schalnat 已提交
1498 1499 1500
         return;
      }

1501
      png_ptr->current_text = NULL;
A
Andreas Dilger 已提交
1502
      png_free(png_ptr, key);
G
Guy Schalnat 已提交
1503
      key = text;
A
Andreas Dilger 已提交
1504
      text += key_size;
G
Guy Schalnat 已提交
1505

1506 1507
      text_ptr = (png_textp)png_malloc(png_ptr,
          png_sizeof(png_text));
1508 1509
      text_ptr->compression = PNG_TEXT_COMPRESSION_zTXt;
      text_ptr->key = key;
1510
      text_ptr->itxt_length = 0;
1511 1512
      text_ptr->lang = NULL;
      text_ptr->lang_key = NULL;
1513
      text_ptr->text = text;
1514

1515
      ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
1516

1517
      png_free(png_ptr, key);
1518
      png_free(png_ptr, text_ptr);
1519 1520

      if (ret)
1521
         png_warning(png_ptr, "Insufficient memory to store text chunk");
1522 1523 1524 1525
   }
}
#endif

1526
#ifdef PNG_READ_iTXt_SUPPORTED
1527
void /* PRIVATE */
1528
png_push_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32
1529
    length)
1530
{
1531
   if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND))
1532 1533
   {
      info_ptr = info_ptr; /* To quiet some compiler warnings */
1534 1535
      png_error(png_ptr, "Out of place iTXt");
      /*NOT REACHED*/
1536
   }
1537 1538 1539 1540

#ifdef PNG_MAX_MALLOC_64K
   png_ptr->skip_length = 0;  /* This may not be necessary */

1541
   if (length > (png_uint_32)65535L) /* Can't hold entire string in memory */
1542 1543 1544 1545 1546 1547 1548 1549
   {
      png_warning(png_ptr, "iTXt chunk too large to fit in memory");
      png_ptr->skip_length = length - (png_uint_32)65535L;
      length = (png_uint_32)65535L;
   }
#endif

   png_ptr->current_text = (png_charp)png_malloc(png_ptr,
1550
       (png_size_t)(length + 1));
1551 1552 1553 1554 1555
   png_ptr->current_text[length] = '\0';
   png_ptr->current_text_ptr = png_ptr->current_text;
   png_ptr->current_text_size = (png_size_t)length;
   png_ptr->current_text_left = (png_size_t)length;
   png_ptr->process_mode = PNG_READ_iTXt_MODE;
1556 1557
}

1558
void /* PRIVATE */
1559 1560
png_push_read_iTXt(png_structp png_ptr, png_infop info_ptr)
{
1561

1562 1563 1564 1565 1566 1567
   if (png_ptr->buffer_size && png_ptr->current_text_left)
   {
      png_size_t text_size;

      if (png_ptr->buffer_size < png_ptr->current_text_left)
         text_size = png_ptr->buffer_size;
1568

1569 1570
      else
         text_size = png_ptr->current_text_left;
1571

1572 1573 1574 1575
      png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size);
      png_ptr->current_text_left -= text_size;
      png_ptr->current_text_ptr += text_size;
   }
1576

1577 1578 1579 1580
   if (!(png_ptr->current_text_left))
   {
      png_textp text_ptr;
      png_charp key;
1581
      int comp_flag;
1582 1583 1584
      png_charp lang;
      png_charp lang_key;
      png_charp text;
1585
      int ret;
1586 1587 1588 1589 1590 1591 1592 1593 1594

      if (png_ptr->buffer_size < 4)
      {
         png_push_save_buffer(png_ptr);
         return;
      }

      png_push_crc_finish(png_ptr);

1595
#ifdef PNG_MAX_MALLOC_64K
1596 1597 1598 1599
      if (png_ptr->skip_length)
         return;
#endif

1600
      key = png_ptr->current_text;
1601

1602
      for (lang = key; *lang; lang++)
1603
         /* Empty loop */ ;
1604

1605
      if (lang < key + png_ptr->current_text_size - 3)
1606
         lang++;
1607

1608
      comp_flag = *lang++;
1609
      lang++;     /* Skip comp_type, always zero */
1610 1611

      for (lang_key = lang; *lang_key; lang_key++)
1612
         /* Empty loop */ ;
1613

1614
      lang_key++;        /* Skip NUL separator */
1615

1616
      text=lang_key;
1617

1618 1619
      if (lang_key < key + png_ptr->current_text_size - 1)
      {
1620 1621
         for (; *text; text++)
            /* Empty loop */ ;
1622
      }
1623

1624
      if (text < key + png_ptr->current_text_size)
1625 1626
         text++;

1627
      text_ptr = (png_textp)png_malloc(png_ptr,
1628
          png_sizeof(png_text));
1629

1630
      text_ptr->compression = comp_flag + 2;
A
Andreas Dilger 已提交
1631
      text_ptr->key = key;
1632 1633
      text_ptr->lang = lang;
      text_ptr->lang_key = lang_key;
A
Andreas Dilger 已提交
1634
      text_ptr->text = text;
1635 1636
      text_ptr->text_length = 0;
      text_ptr->itxt_length = png_strlen(text);
A
Andreas Dilger 已提交
1637

1638
      ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
A
Andreas Dilger 已提交
1639

1640 1641
      png_ptr->current_text = NULL;

A
Andreas Dilger 已提交
1642
      png_free(png_ptr, text_ptr);
1643
      if (ret)
1644
         png_warning(png_ptr, "Insufficient memory to store iTXt chunk");
G
Guy Schalnat 已提交
1645
   }
G
Guy Schalnat 已提交
1646 1647 1648
}
#endif

A
Andreas Dilger 已提交
1649
/* This function is called when we haven't found a handler for this
1650 1651
 * chunk.  If there isn't a problem with the chunk itself (ie a bad chunk
 * name or a critical chunk), the chunk is (currently) silently ignored.
1652
 */
1653
void /* PRIVATE */
1654
png_push_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32
1655
    length)
A
Andreas Dilger 已提交
1656
{
1657
   png_uint_32 skip = 0;
A
Andreas Dilger 已提交
1658 1659 1660

   if (!(png_ptr->chunk_name[0] & 0x20))
   {
1661
#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
1662
      if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
1663
          PNG_HANDLE_CHUNK_ALWAYS
1664
#ifdef PNG_READ_USER_CHUNKS_SUPPORTED
1665
          && png_ptr->read_user_chunk_fn == NULL
1666
#endif
1667
          )
1668
#endif
1669 1670
         png_chunk_error(png_ptr, "unknown critical chunk");

1671
      info_ptr = info_ptr; /* To quiet some compiler warnings */
A
Andreas Dilger 已提交
1672 1673
   }

1674
#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
1675 1676 1677
   if (png_ptr->flags & PNG_FLAG_KEEP_UNKNOWN_CHUNKS)
   {
#ifdef PNG_MAX_MALLOC_64K
1678 1679
      if (length > (png_uint_32)65535L)
      {
1680 1681 1682
         png_warning(png_ptr, "unknown chunk too large to fit in memory");
         skip = length - (png_uint_32)65535L;
         length = (png_uint_32)65535L;
1683
      }
1684
#endif
1685
      png_memcpy((png_charp)png_ptr->unknown_chunk.name,
1686
          (png_charp)png_ptr->chunk_name,
1687
          png_sizeof(png_ptr->unknown_chunk.name));
1688
      png_ptr->unknown_chunk.name[png_sizeof(png_ptr->unknown_chunk.name) - 1]
1689
          = '\0';
1690 1691

      png_ptr->unknown_chunk.size = (png_size_t)length;
1692

1693 1694
      if (length == 0)
         png_ptr->unknown_chunk.data = NULL;
1695

1696 1697 1698
      else
      {
         png_ptr->unknown_chunk.data = (png_bytep)png_malloc(png_ptr,
1699
             (png_size_t)length);
1700 1701
         png_crc_read(png_ptr, (png_bytep)png_ptr->unknown_chunk.data, length);
      }
1702

1703
#ifdef PNG_READ_USER_CHUNKS_SUPPORTED
1704 1705
      if (png_ptr->read_user_chunk_fn != NULL)
      {
1706
         /* Callback to user unknown chunk handler */
1707 1708
         int ret;
         ret = (*(png_ptr->read_user_chunk_fn))
1709
             (png_ptr, &png_ptr->unknown_chunk);
1710

1711 1712
         if (ret < 0)
            png_chunk_error(png_ptr, "error in user chunk");
1713

1714 1715 1716 1717
         if (ret == 0)
         {
            if (!(png_ptr->chunk_name[0] & 0x20))
               if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
1718
                   PNG_HANDLE_CHUNK_ALWAYS)
1719 1720
                  png_chunk_error(png_ptr, "unknown critical chunk");
            png_set_unknown_chunks(png_ptr, info_ptr,
1721
                &png_ptr->unknown_chunk, 1);
1722 1723
         }
      }
1724

1725
      else
1726
#endif
1727
         png_set_unknown_chunks(png_ptr, info_ptr, &png_ptr->unknown_chunk, 1);
1728 1729
      png_free(png_ptr, png_ptr->unknown_chunk.data);
      png_ptr->unknown_chunk.data = NULL;
1730
   }
1731

1732 1733 1734 1735
   else
#endif
      skip=length;
   png_push_crc_skip(png_ptr, skip);
A
Andreas Dilger 已提交
1736 1737
}

1738
void /* PRIVATE */
A
Andreas Dilger 已提交
1739
png_push_have_info(png_structp png_ptr, png_infop info_ptr)
G
Guy Schalnat 已提交
1740
{
A
Andreas Dilger 已提交
1741
   if (png_ptr->info_fn != NULL)
A
Andreas Dilger 已提交
1742
      (*(png_ptr->info_fn))(png_ptr, info_ptr);
G
Guy Schalnat 已提交
1743 1744
}

1745
void /* PRIVATE */
A
Andreas Dilger 已提交
1746
png_push_have_end(png_structp png_ptr, png_infop info_ptr)
G
Guy Schalnat 已提交
1747
{
A
Andreas Dilger 已提交
1748
   if (png_ptr->end_fn != NULL)
A
Andreas Dilger 已提交
1749
      (*(png_ptr->end_fn))(png_ptr, info_ptr);
G
Guy Schalnat 已提交
1750 1751
}

1752
void /* PRIVATE */
G
Guy Schalnat 已提交
1753 1754
png_push_have_row(png_structp png_ptr, png_bytep row)
{
1755
   if (png_ptr->row_fn != NULL)
G
Guy Schalnat 已提交
1756 1757
      (*(png_ptr->row_fn))(png_ptr, row, png_ptr->row_number,
         (int)png_ptr->pass);
G
Guy Schalnat 已提交
1758 1759
}

1760
void PNGAPI
1761 1762
png_progressive_combine_row (png_structp png_ptr, png_bytep old_row,
    png_const_bytep new_row)
G
Guy Schalnat 已提交
1763
{
1764
   PNG_CONST int FARDATA png_pass_dsp_mask[7] =
1765
      {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, 0xff};
1766

1767 1768 1769
   if (png_ptr == NULL)
      return;

1770
   if (new_row != NULL)    /* new_row must == png_ptr->row_buf here. */
A
Andreas Dilger 已提交
1771
      png_combine_row(png_ptr, old_row, png_pass_dsp_mask[png_ptr->pass]);
G
Guy Schalnat 已提交
1772 1773
}

1774
void PNGAPI
G
Guy Schalnat 已提交
1775
png_set_progressive_read_fn(png_structp png_ptr, png_voidp progressive_ptr,
1776 1777
    png_progressive_info_ptr info_fn, png_progressive_row_ptr row_fn,
    png_progressive_end_ptr end_fn)
G
Guy Schalnat 已提交
1778
{
1779 1780 1781
   if (png_ptr == NULL)
      return;

G
Guy Schalnat 已提交
1782 1783
   png_ptr->info_fn = info_fn;
   png_ptr->row_fn = row_fn;
G
Guy Schalnat 已提交
1784
   png_ptr->end_fn = end_fn;
G
Guy Schalnat 已提交
1785

1786
   png_set_read_fn(png_ptr, progressive_ptr, png_push_fill_buffer);
G
Guy Schalnat 已提交
1787 1788
}

1789
png_voidp PNGAPI
A
Andreas Dilger 已提交
1790
png_get_progressive_ptr(png_structp png_ptr)
G
Guy Schalnat 已提交
1791
{
1792 1793 1794
   if (png_ptr == NULL)
      return (NULL);

A
Andreas Dilger 已提交
1795
   return png_ptr->io_ptr;
G
Guy Schalnat 已提交
1796
}
G
Guy Schalnat 已提交
1797
#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */