pngpread.c 50.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.6 [(PENDING RELEASE)]
5
 * Copyright (c) 1998-2011 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
}

44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
png_size_t PNGAPI
png_process_data_pause(png_structp png_ptr, int save)
{
   if (png_ptr != NULL)
   {
      /* It's easiest for the caller if we do the save, then the caller doesn't
       * have to supply the same data again:
       */
      if (save)
         png_push_save_buffer(png_ptr);
      else
      {
         /* This includes any pending saved bytes: */
         png_size_t remaining = png_ptr->buffer_size;
         png_ptr->buffer_size = 0;

         /* So subtract the saved buffer size, unless all the data
          * is actually 'saved', in which case we just return 0
          */
         if (png_ptr->save_buffer_size < remaining)
            return remaining - png_ptr->save_buffer_size;
      }
   }

   return 0;
}

png_uint_32 PNGAPI
png_process_data_skip(png_structp png_ptr)
{
74
   png_uint_32 remaining = 0;
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101

   if (png_ptr != NULL && png_ptr->process_mode == PNG_SKIP_MODE &&
      png_ptr->skip_length > 0)
   {
      /* At the end of png_process_data the buffer size must be 0 (see the loop
       * above) so we can detect a broken call here:
       */
      if (png_ptr->buffer_size != 0)
         png_error(png_ptr,
            "png_process_data_skip called inside png_process_data");

      /* If is impossible for there to be a saved buffer at this point -
       * otherwise we could not be in SKIP mode.  This will also happen if
       * png_process_skip is called inside png_process_data (but only very
       * rarely.)
       */
      if (png_ptr->save_buffer_size != 0)
         png_error(png_ptr, "png_process_data_skip called with saved data");

      remaining = png_ptr->skip_length;
      png_ptr->skip_length = 0;
      png_ptr->process_mode = PNG_READ_CHUNK_MODE;
   }

   return remaining;
}

A
Andreas Dilger 已提交
102 103 104
/* What we do with the incoming data depends on what we were previously
 * doing before we ran out of data...
 */
105
void /* PRIVATE */
A
Andreas Dilger 已提交
106
png_process_some_data(png_structp png_ptr, png_infop info_ptr)
G
Guy Schalnat 已提交
107
{
108 109 110
   if (png_ptr == NULL)
      return;

G
Guy Schalnat 已提交
111 112 113 114
   switch (png_ptr->process_mode)
   {
      case PNG_READ_SIG_MODE:
      {
A
Andreas Dilger 已提交
115
         png_push_read_sig(png_ptr, info_ptr);
G
Guy Schalnat 已提交
116 117
         break;
      }
118

G
Guy Schalnat 已提交
119 120
      case PNG_READ_CHUNK_MODE:
      {
A
Andreas Dilger 已提交
121
         png_push_read_chunk(png_ptr, info_ptr);
G
Guy Schalnat 已提交
122 123
         break;
      }
124

G
Guy Schalnat 已提交
125 126
      case PNG_READ_IDAT_MODE:
      {
G
Guy Schalnat 已提交
127
         png_push_read_IDAT(png_ptr);
G
Guy Schalnat 已提交
128 129
         break;
      }
130

131
#ifdef PNG_READ_tEXt_SUPPORTED
G
Guy Schalnat 已提交
132 133
      case PNG_READ_tEXt_MODE:
      {
A
Andreas Dilger 已提交
134
         png_push_read_tEXt(png_ptr, info_ptr);
G
Guy Schalnat 已提交
135 136
         break;
      }
137

G
Guy Schalnat 已提交
138
#endif
139
#ifdef PNG_READ_zTXt_SUPPORTED
G
Guy Schalnat 已提交
140 141
      case PNG_READ_zTXt_MODE:
      {
A
Andreas Dilger 已提交
142
         png_push_read_zTXt(png_ptr, info_ptr);
G
Guy Schalnat 已提交
143 144
         break;
      }
145

146
#endif
147
#ifdef PNG_READ_iTXt_SUPPORTED
148 149 150 151 152
      case PNG_READ_iTXt_MODE:
      {
         png_push_read_iTXt(png_ptr, info_ptr);
         break;
      }
153

G
Guy Schalnat 已提交
154 155 156
#endif
      case PNG_SKIP_MODE:
      {
A
Andreas Dilger 已提交
157
         png_push_crc_finish(png_ptr);
G
Guy Schalnat 已提交
158 159
         break;
      }
160

G
Guy Schalnat 已提交
161 162 163 164 165 166
      default:
      {
         png_ptr->buffer_size = 0;
         break;
      }
   }
G
Guy Schalnat 已提交
167 168
}

A
Andreas Dilger 已提交
169 170
/* Read any remaining signature bytes from the stream and compare them with
 * the correct PNG signature.  It is possible that this routine is called
171 172 173
 * 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 已提交
174
 */
175
void /* PRIVATE */
A
Andreas Dilger 已提交
176
png_push_read_sig(png_structp png_ptr, png_infop info_ptr)
G
Guy Schalnat 已提交
177
{
A
Andreas Dilger 已提交
178 179
   png_size_t num_checked = png_ptr->sig_bytes,
             num_to_check = 8 - num_checked;
G
Guy Schalnat 已提交
180

A
Andreas Dilger 已提交
181
   if (png_ptr->buffer_size < num_to_check)
G
Guy Schalnat 已提交
182
   {
A
Andreas Dilger 已提交
183
      num_to_check = png_ptr->buffer_size;
G
Guy Schalnat 已提交
184 185
   }

186
   png_push_fill_buffer(png_ptr, &(info_ptr->signature[num_checked]),
187
       num_to_check);
188
   png_ptr->sig_bytes = (png_byte)(png_ptr->sig_bytes + num_to_check);
G
Guy Schalnat 已提交
189

A
Andreas Dilger 已提交
190
   if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check))
G
Guy Schalnat 已提交
191
   {
A
Andreas Dilger 已提交
192 193 194
      if (num_checked < 4 &&
          png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4))
         png_error(png_ptr, "Not a PNG file");
195

A
Andreas Dilger 已提交
196 197
      else
         png_error(png_ptr, "PNG file corrupted by ASCII conversion");
G
Guy Schalnat 已提交
198 199 200
   }
   else
   {
A
Andreas Dilger 已提交
201 202 203 204
      if (png_ptr->sig_bytes >= 8)
      {
         png_ptr->process_mode = PNG_READ_CHUNK_MODE;
      }
G
Guy Schalnat 已提交
205
   }
G
Guy Schalnat 已提交
206 207
}

208
void /* PRIVATE */
A
Andreas Dilger 已提交
209
png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
G
Guy Schalnat 已提交
210
{
211
   png_uint_32 chunk_name;
212

A
Andreas Dilger 已提交
213
   /* First we make sure we have enough data for the 4 byte chunk name
214 215 216 217 218
    * 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).
    */
219
   if (!(png_ptr->mode & PNG_HAVE_CHUNK_HEADER))
G
Guy Schalnat 已提交
220
   {
A
Andreas Dilger 已提交
221
      png_byte chunk_length[4];
222
      png_byte chunk_tag[4];
G
Guy Schalnat 已提交
223 224 225 226 227 228 229

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

A
Andreas Dilger 已提交
230
      png_push_fill_buffer(png_ptr, chunk_length, 4);
231
      png_ptr->push_length = png_get_uint_31(png_ptr, chunk_length);
G
Guy Schalnat 已提交
232
      png_reset_crc(png_ptr);
233 234
      png_crc_read(png_ptr, chunk_tag, 4);
      png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(chunk_tag);
235
      png_check_chunk_name(png_ptr, png_ptr->chunk_name);
236
      png_ptr->mode |= PNG_HAVE_CHUNK_HEADER;
G
Guy Schalnat 已提交
237 238
   }

239 240 241
   chunk_name = png_ptr->chunk_name;

   if (chunk_name == png_IDAT)
242 243 244 245 246 247 248
   {
      /* This is here above the if/else case statement below because if the
       * unknown handling marks 'IDAT' as unknown then the IDAT handling case is
       * completely skipped.
       *
       * TODO: there must be a better way of doing this.
       */
249 250
      if (png_ptr->mode & PNG_AFTER_IDAT)
         png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT;
251
   }
252

253
   if (chunk_name == png_IHDR)
G
Guy Schalnat 已提交
254
   {
255 256
      if (png_ptr->push_length != 13)
         png_error(png_ptr, "Invalid IHDR length");
257

258 259 260
      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
      {
         png_push_save_buffer(png_ptr);
G
Guy Schalnat 已提交
261
         return;
262
      }
263

A
Andreas Dilger 已提交
264
      png_handle_IHDR(png_ptr, info_ptr, png_ptr->push_length);
G
Guy Schalnat 已提交
265
   }
266

267
   else if (chunk_name == png_IEND)
268
   {
269 270 271
      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
      {
         png_push_save_buffer(png_ptr);
272
         return;
273
      }
274

275 276 277 278 279
      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);
   }
280

281
#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
282
   else if (png_chunk_unknown_handling(png_ptr, chunk_name))
283
   {
284 285 286
      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
      {
         png_push_save_buffer(png_ptr);
287
         return;
288
      }
289

290
      if (chunk_name == png_IDAT)
291
         png_ptr->mode |= PNG_HAVE_IDAT;
292

293
      png_handle_unknown(png_ptr, info_ptr, png_ptr->push_length);
294

295
      if (chunk_name == png_PLTE)
296
         png_ptr->mode |= PNG_HAVE_PLTE;
297

298
      else if (chunk_name == png_IDAT)
299 300 301
      {
         if (!(png_ptr->mode & PNG_HAVE_IHDR))
            png_error(png_ptr, "Missing IHDR before IDAT");
302

303
         else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
304
             !(png_ptr->mode & PNG_HAVE_PLTE))
305 306 307
            png_error(png_ptr, "Missing PLTE before IDAT");
      }
   }
308

309
#endif
310
   else if (chunk_name == png_PLTE)
G
Guy Schalnat 已提交
311
   {
312 313 314
      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
      {
         png_push_save_buffer(png_ptr);
A
Andreas Dilger 已提交
315
         return;
316
      }
A
Andreas Dilger 已提交
317
      png_handle_PLTE(png_ptr, info_ptr, png_ptr->push_length);
G
Guy Schalnat 已提交
318
   }
319

320
   else if (chunk_name == png_IDAT)
G
Guy Schalnat 已提交
321
   {
A
Andreas Dilger 已提交
322
      /* If we reach an IDAT chunk, this means we have read all of the
323 324 325
       * header chunks, and we can start reading the image (or if this
       * is called after the image has been read - we have an error).
       */
326 327 328 329 330 331 332

      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");
333

A
Andreas Dilger 已提交
334 335
      if (png_ptr->mode & PNG_HAVE_IDAT)
      {
336
         if (!(png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT))
337 338
            if (png_ptr->push_length == 0)
               return;
A
Andreas Dilger 已提交
339 340

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

G
Guy Schalnat 已提交
344
      png_ptr->idat_size = png_ptr->push_length;
A
Andreas Dilger 已提交
345
      png_ptr->mode |= PNG_HAVE_IDAT;
G
Guy Schalnat 已提交
346
      png_ptr->process_mode = PNG_READ_IDAT_MODE;
A
Andreas Dilger 已提交
347
      png_push_have_info(png_ptr, info_ptr);
348 349 350
      png_ptr->zstream.avail_out =
          (uInt) PNG_ROWBYTES(png_ptr->pixel_depth,
          png_ptr->iwidth) + 1;
A
Andreas Dilger 已提交
351
      png_ptr->zstream.next_out = png_ptr->row_buf;
G
Guy Schalnat 已提交
352 353
      return;
   }
354

355
#ifdef PNG_READ_gAMA_SUPPORTED
356
   else if (png_ptr->chunk_name == png_gAMA)
G
Guy Schalnat 已提交
357
   {
358 359 360
      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
      {
         png_push_save_buffer(png_ptr);
G
Guy Schalnat 已提交
361
         return;
362
      }
363

A
Andreas Dilger 已提交
364
      png_handle_gAMA(png_ptr, info_ptr, png_ptr->push_length);
G
Guy Schalnat 已提交
365
   }
366

G
Guy Schalnat 已提交
367
#endif
368
#ifdef PNG_READ_sBIT_SUPPORTED
369
   else if (png_ptr->chunk_name == png_sBIT)
G
Guy Schalnat 已提交
370
   {
371 372 373
      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
      {
         png_push_save_buffer(png_ptr);
G
Guy Schalnat 已提交
374
         return;
375
      }
376

A
Andreas Dilger 已提交
377
      png_handle_sBIT(png_ptr, info_ptr, png_ptr->push_length);
G
Guy Schalnat 已提交
378
   }
379

G
Guy Schalnat 已提交
380
#endif
381
#ifdef PNG_READ_cHRM_SUPPORTED
382
   else if (png_ptr->chunk_name == png_cHRM)
G
Guy Schalnat 已提交
383
   {
384 385 386
      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
      {
         png_push_save_buffer(png_ptr);
G
Guy Schalnat 已提交
387
         return;
388
      }
389

A
Andreas Dilger 已提交
390
      png_handle_cHRM(png_ptr, info_ptr, png_ptr->push_length);
G
Guy Schalnat 已提交
391
   }
392

G
Guy Schalnat 已提交
393
#endif
394
#ifdef PNG_READ_sRGB_SUPPORTED
395
   else if (chunk_name == png_sRGB)
396
   {
397 398 399
      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
      {
         png_push_save_buffer(png_ptr);
400
         return;
401
      }
402

403 404
      png_handle_sRGB(png_ptr, info_ptr, png_ptr->push_length);
   }
405

406
#endif
407
#ifdef PNG_READ_iCCP_SUPPORTED
408
   else if (png_ptr->chunk_name == png_iCCP)
409
   {
410 411 412
      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
      {
         png_push_save_buffer(png_ptr);
413
         return;
414
      }
415

416 417
      png_handle_iCCP(png_ptr, info_ptr, png_ptr->push_length);
   }
418

419
#endif
420
#ifdef PNG_READ_sPLT_SUPPORTED
421
   else if (chunk_name == png_sPLT)
422
   {
423 424 425
      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
      {
         png_push_save_buffer(png_ptr);
426
         return;
427
      }
428

429 430
      png_handle_sPLT(png_ptr, info_ptr, png_ptr->push_length);
   }
431

432
#endif
433
#ifdef PNG_READ_tRNS_SUPPORTED
434
   else if (chunk_name == png_tRNS)
G
Guy Schalnat 已提交
435
   {
436 437 438
      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
      {
         png_push_save_buffer(png_ptr);
G
Guy Schalnat 已提交
439
         return;
440
      }
441

A
Andreas Dilger 已提交
442
      png_handle_tRNS(png_ptr, info_ptr, png_ptr->push_length);
G
Guy Schalnat 已提交
443
   }
444

G
Guy Schalnat 已提交
445
#endif
446
#ifdef PNG_READ_bKGD_SUPPORTED
447
   else if (chunk_name == png_bKGD)
G
Guy Schalnat 已提交
448
   {
449 450 451
      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
      {
         png_push_save_buffer(png_ptr);
G
Guy Schalnat 已提交
452
         return;
453
      }
454

A
Andreas Dilger 已提交
455
      png_handle_bKGD(png_ptr, info_ptr, png_ptr->push_length);
G
Guy Schalnat 已提交
456
   }
457

G
Guy Schalnat 已提交
458
#endif
459
#ifdef PNG_READ_hIST_SUPPORTED
460
   else if (chunk_name == png_hIST)
G
Guy Schalnat 已提交
461
   {
462 463 464
      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
      {
         png_push_save_buffer(png_ptr);
G
Guy Schalnat 已提交
465
         return;
466
      }
467

A
Andreas Dilger 已提交
468
      png_handle_hIST(png_ptr, info_ptr, png_ptr->push_length);
G
Guy Schalnat 已提交
469
   }
470

G
Guy Schalnat 已提交
471
#endif
472
#ifdef PNG_READ_pHYs_SUPPORTED
473
   else if (chunk_name == png_pHYs)
G
Guy Schalnat 已提交
474 475 476 477 478 479
   {
      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
      {
         png_push_save_buffer(png_ptr);
         return;
      }
480

A
Andreas Dilger 已提交
481
      png_handle_pHYs(png_ptr, info_ptr, png_ptr->push_length);
G
Guy Schalnat 已提交
482
   }
483

G
Guy Schalnat 已提交
484
#endif
485
#ifdef PNG_READ_oFFs_SUPPORTED
486
   else if (chunk_name == png_oFFs)
G
Guy Schalnat 已提交
487
   {
488 489 490
      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
      {
         png_push_save_buffer(png_ptr);
G
Guy Schalnat 已提交
491
         return;
492
      }
493

A
Andreas Dilger 已提交
494
      png_handle_oFFs(png_ptr, info_ptr, png_ptr->push_length);
G
Guy Schalnat 已提交
495
   }
G
Guy Schalnat 已提交
496
#endif
497

498
#ifdef PNG_READ_pCAL_SUPPORTED
499
   else if (chunk_name == png_pCAL)
A
Andreas Dilger 已提交
500
   {
501 502 503
      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
      {
         png_push_save_buffer(png_ptr);
A
Andreas Dilger 已提交
504
         return;
505
      }
506

A
Andreas Dilger 已提交
507 508
      png_handle_pCAL(png_ptr, info_ptr, png_ptr->push_length);
   }
509

A
Andreas Dilger 已提交
510
#endif
511
#ifdef PNG_READ_sCAL_SUPPORTED
512
   else if (chunk_name == png_sCAL)
513
   {
514 515 516
      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
      {
         png_push_save_buffer(png_ptr);
517
         return;
518
      }
519

520 521
      png_handle_sCAL(png_ptr, info_ptr, png_ptr->push_length);
   }
522

523
#endif
524
#ifdef PNG_READ_tIME_SUPPORTED
525
   else if (chunk_name == png_tIME)
G
Guy Schalnat 已提交
526
   {
527 528 529
      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
      {
         png_push_save_buffer(png_ptr);
G
Guy Schalnat 已提交
530
         return;
531
      }
532

A
Andreas Dilger 已提交
533
      png_handle_tIME(png_ptr, info_ptr, png_ptr->push_length);
G
Guy Schalnat 已提交
534
   }
535

G
Guy Schalnat 已提交
536
#endif
537
#ifdef PNG_READ_tEXt_SUPPORTED
538
   else if (chunk_name == png_tEXt)
G
Guy Schalnat 已提交
539
   {
540 541 542
      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
      {
         png_push_save_buffer(png_ptr);
543
         return;
544
      }
545

A
Andreas Dilger 已提交
546
      png_push_handle_tEXt(png_ptr, info_ptr, png_ptr->push_length);
G
Guy Schalnat 已提交
547
   }
548

G
Guy Schalnat 已提交
549
#endif
550
#ifdef PNG_READ_zTXt_SUPPORTED
551
   else if (chunk_name == png_zTXt)
G
Guy Schalnat 已提交
552
   {
553 554 555
      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
      {
         png_push_save_buffer(png_ptr);
556
         return;
557
      }
558

A
Andreas Dilger 已提交
559
      png_push_handle_zTXt(png_ptr, info_ptr, png_ptr->push_length);
G
Guy Schalnat 已提交
560
   }
561

562
#endif
563
#ifdef PNG_READ_iTXt_SUPPORTED
564
   else if (chunk_name == png_iTXt)
565
   {
566 567 568
      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
      {
         png_push_save_buffer(png_ptr);
569
         return;
570
      }
571

572 573
      png_push_handle_iTXt(png_ptr, info_ptr, png_ptr->push_length);
   }
574

G
Guy Schalnat 已提交
575
#endif
G
Guy Schalnat 已提交
576 577
   else
   {
578 579 580
      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
      {
         png_push_save_buffer(png_ptr);
581
         return;
582
      }
A
Andreas Dilger 已提交
583
      png_push_handle_unknown(png_ptr, info_ptr, png_ptr->push_length);
G
Guy Schalnat 已提交
584
   }
G
Guy Schalnat 已提交
585

586
   png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
G
Guy Schalnat 已提交
587 588
}

589
void /* PRIVATE */
A
Andreas Dilger 已提交
590
png_push_crc_skip(png_structp png_ptr, png_uint_32 skip)
G
Guy Schalnat 已提交
591
{
G
Guy Schalnat 已提交
592
   png_ptr->process_mode = PNG_SKIP_MODE;
A
Andreas Dilger 已提交
593
   png_ptr->skip_length = skip;
G
Guy Schalnat 已提交
594 595
}

596
void /* PRIVATE */
A
Andreas Dilger 已提交
597
png_push_crc_finish(png_structp png_ptr)
G
Guy Schalnat 已提交
598
{
G
Guy Schalnat 已提交
599 600
   if (png_ptr->skip_length && png_ptr->save_buffer_size)
   {
601
      png_size_t save_size = png_ptr->save_buffer_size;
602
      png_uint_32 skip_length = png_ptr->skip_length;
G
Guy Schalnat 已提交
603

604
      /* We want the smaller of 'skip_length' and 'save_buffer_size', but
605 606 607 608 609 610 611
       * 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;
612

G
Guy Schalnat 已提交
613
      else
614
         skip_length = (png_uint_32)save_size;
G
Guy Schalnat 已提交
615 616 617

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

618
      png_ptr->skip_length -= skip_length;
G
Guy Schalnat 已提交
619 620
      png_ptr->buffer_size -= save_size;
      png_ptr->save_buffer_size -= save_size;
A
Andreas Dilger 已提交
621
      png_ptr->save_buffer_ptr += save_size;
G
Guy Schalnat 已提交
622 623 624
   }
   if (png_ptr->skip_length && png_ptr->current_buffer_size)
   {
625 626
      png_size_t save_size = png_ptr->current_buffer_size;
      png_uint_32 skip_length = png_ptr->skip_length;
G
Guy Schalnat 已提交
627

628 629
      /* We want the smaller of 'skip_length' and 'current_buffer_size', here,
       * the same problem exists as above and the same solution.
630 631 632
       */
      if (skip_length < save_size)
         save_size = (png_size_t)skip_length;
633

G
Guy Schalnat 已提交
634
      else
635
         skip_length = (png_uint_32)save_size;
G
Guy Schalnat 已提交
636 637 638

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

639
      png_ptr->skip_length -= skip_length;
G
Guy Schalnat 已提交
640 641
      png_ptr->buffer_size -= save_size;
      png_ptr->current_buffer_size -= save_size;
A
Andreas Dilger 已提交
642
      png_ptr->current_buffer_ptr += save_size;
G
Guy Schalnat 已提交
643 644 645 646 647 648 649 650
   }
   if (!png_ptr->skip_length)
   {
      if (png_ptr->buffer_size < 4)
      {
         png_push_save_buffer(png_ptr);
         return;
      }
A
Andreas Dilger 已提交
651 652

      png_crc_finish(png_ptr, 0);
A
Andreas Dilger 已提交
653
      png_ptr->process_mode = PNG_READ_CHUNK_MODE;
G
Guy Schalnat 已提交
654
   }
G
Guy Schalnat 已提交
655 656
}

657
void PNGCBAPI
A
Andreas Dilger 已提交
658
png_push_fill_buffer(png_structp png_ptr, png_bytep buffer, png_size_t length)
G
Guy Schalnat 已提交
659
{
G
Guy Schalnat 已提交
660 661
   png_bytep ptr;

662 663 664
   if (png_ptr == NULL)
      return;

G
Guy Schalnat 已提交
665 666 667
   ptr = buffer;
   if (png_ptr->save_buffer_size)
   {
A
Andreas Dilger 已提交
668
      png_size_t save_size;
G
Guy Schalnat 已提交
669 670 671

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

G
Guy Schalnat 已提交
673 674 675
      else
         save_size = png_ptr->save_buffer_size;

A
Andreas Dilger 已提交
676
      png_memcpy(ptr, png_ptr->save_buffer_ptr, save_size);
G
Guy Schalnat 已提交
677
      length -= save_size;
A
Andreas Dilger 已提交
678
      ptr += save_size;
G
Guy Schalnat 已提交
679 680
      png_ptr->buffer_size -= save_size;
      png_ptr->save_buffer_size -= save_size;
A
Andreas Dilger 已提交
681
      png_ptr->save_buffer_ptr += save_size;
G
Guy Schalnat 已提交
682 683 684
   }
   if (length && png_ptr->current_buffer_size)
   {
A
Andreas Dilger 已提交
685
      png_size_t save_size;
G
Guy Schalnat 已提交
686 687 688

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

G
Guy Schalnat 已提交
690 691 692
      else
         save_size = png_ptr->current_buffer_size;

A
Andreas Dilger 已提交
693
      png_memcpy(ptr, png_ptr->current_buffer_ptr, save_size);
G
Guy Schalnat 已提交
694 695
      png_ptr->buffer_size -= save_size;
      png_ptr->current_buffer_size -= save_size;
A
Andreas Dilger 已提交
696
      png_ptr->current_buffer_ptr += save_size;
G
Guy Schalnat 已提交
697
   }
G
Guy Schalnat 已提交
698 699
}

700
void /* PRIVATE */
G
Guy Schalnat 已提交
701 702
png_push_save_buffer(png_structp png_ptr)
{
G
Guy Schalnat 已提交
703 704 705 706
   if (png_ptr->save_buffer_size)
   {
      if (png_ptr->save_buffer_ptr != png_ptr->save_buffer)
      {
707
         png_size_t i, istop;
G
Guy Schalnat 已提交
708 709 710
         png_bytep sp;
         png_bytep dp;

711
         istop = png_ptr->save_buffer_size;
G
Guy Schalnat 已提交
712
         for (i = 0, sp = png_ptr->save_buffer_ptr, dp = png_ptr->save_buffer;
713
             i < istop; i++, sp++, dp++)
G
Guy Schalnat 已提交
714 715 716 717 718
         {
            *dp = *sp;
         }
      }
   }
719
   if (png_ptr->save_buffer_size + png_ptr->current_buffer_size >
720
       png_ptr->save_buffer_max)
G
Guy Schalnat 已提交
721
   {
A
Andreas Dilger 已提交
722
      png_size_t new_max;
G
Guy Schalnat 已提交
723 724
      png_bytep old_buffer;

725
      if (png_ptr->save_buffer_size > PNG_SIZE_MAX -
726
          (png_ptr->current_buffer_size + 256))
727
      {
728
         png_error(png_ptr, "Potential overflow of save_buffer");
729
      }
730

731
      new_max = png_ptr->save_buffer_size + png_ptr->current_buffer_size + 256;
G
Guy Schalnat 已提交
732
      old_buffer = png_ptr->save_buffer;
733
      png_ptr->save_buffer = (png_bytep)png_malloc_warn(png_ptr,
734
          (png_size_t)new_max);
735

736 737
      if (png_ptr->save_buffer == NULL)
      {
738 739
         png_free(png_ptr, old_buffer);
         png_error(png_ptr, "Insufficient memory for save_buffer");
740
      }
741

742 743 744
      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 已提交
745 746 747
   }
   if (png_ptr->current_buffer_size)
   {
A
Andreas Dilger 已提交
748 749
      png_memcpy(png_ptr->save_buffer + png_ptr->save_buffer_size,
         png_ptr->current_buffer_ptr, png_ptr->current_buffer_size);
G
Guy Schalnat 已提交
750 751 752 753 754
      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 已提交
755 756
}

757
void /* PRIVATE */
G
Guy Schalnat 已提交
758
png_push_restore_buffer(png_structp png_ptr, png_bytep buffer,
A
Andreas Dilger 已提交
759
   png_size_t buffer_length)
G
Guy Schalnat 已提交
760
{
G
Guy Schalnat 已提交
761 762 763 764
   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 已提交
765 766
}

767
void /* PRIVATE */
G
Guy Schalnat 已提交
768
png_push_read_IDAT(png_structp png_ptr)
G
Guy Schalnat 已提交
769
{
770
   if (!(png_ptr->mode & PNG_HAVE_CHUNK_HEADER))
G
Guy Schalnat 已提交
771
   {
A
Andreas Dilger 已提交
772
      png_byte chunk_length[4];
773
      png_byte chunk_tag[4];
G
Guy Schalnat 已提交
774

775
      /* TODO: this code can be commoned up with the same code in push_read */
G
Guy Schalnat 已提交
776 777 778 779 780 781
      if (png_ptr->buffer_size < 8)
      {
         png_push_save_buffer(png_ptr);
         return;
      }

A
Andreas Dilger 已提交
782
      png_push_fill_buffer(png_ptr, chunk_length, 4);
783
      png_ptr->push_length = png_get_uint_31(png_ptr, chunk_length);
G
Guy Schalnat 已提交
784
      png_reset_crc(png_ptr);
785 786
      png_crc_read(png_ptr, chunk_tag, 4);
      png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(chunk_tag);
787
      png_ptr->mode |= PNG_HAVE_CHUNK_HEADER;
A
Andreas Dilger 已提交
788

789
      if (png_ptr->chunk_name != png_IDAT)
G
Guy Schalnat 已提交
790
      {
A
Andreas Dilger 已提交
791
         png_ptr->process_mode = PNG_READ_CHUNK_MODE;
792

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

G
Guy Schalnat 已提交
796 797 798 799 800
         return;
      }

      png_ptr->idat_size = png_ptr->push_length;
   }
801

G
Guy Schalnat 已提交
802 803
   if (png_ptr->idat_size && png_ptr->save_buffer_size)
   {
804 805
      png_size_t save_size = png_ptr->save_buffer_size;
      png_uint_32 idat_size = png_ptr->idat_size;
806

807 808 809 810 811 812 813 814
      /* 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;
815

G
Guy Schalnat 已提交
816
      else
817
         idat_size = (png_uint_32)save_size;
G
Guy Schalnat 已提交
818 819

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

821
      png_process_IDAT_data(png_ptr, png_ptr->save_buffer_ptr, save_size);
822

823
      png_ptr->idat_size -= idat_size;
G
Guy Schalnat 已提交
824 825
      png_ptr->buffer_size -= save_size;
      png_ptr->save_buffer_size -= save_size;
A
Andreas Dilger 已提交
826
      png_ptr->save_buffer_ptr += save_size;
G
Guy Schalnat 已提交
827
   }
828

G
Guy Schalnat 已提交
829 830
   if (png_ptr->idat_size && png_ptr->current_buffer_size)
   {
831 832
      png_size_t save_size = png_ptr->current_buffer_size;
      png_uint_32 idat_size = png_ptr->idat_size;
G
Guy Schalnat 已提交
833

834 835 836 837 838 839 840
      /* 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;
841

G
Guy Schalnat 已提交
842
      else
843
         idat_size = (png_uint_32)save_size;
G
Guy Schalnat 已提交
844 845

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

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

849
      png_ptr->idat_size -= idat_size;
G
Guy Schalnat 已提交
850 851
      png_ptr->buffer_size -= save_size;
      png_ptr->current_buffer_size -= save_size;
A
Andreas Dilger 已提交
852
      png_ptr->current_buffer_ptr += save_size;
G
Guy Schalnat 已提交
853 854 855 856 857 858 859 860 861
   }
   if (!png_ptr->idat_size)
   {
      if (png_ptr->buffer_size < 4)
      {
         png_push_save_buffer(png_ptr);
         return;
      }

A
Andreas Dilger 已提交
862
      png_crc_finish(png_ptr, 0);
863
      png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
864
      png_ptr->mode |= PNG_AFTER_IDAT;
G
Guy Schalnat 已提交
865
   }
G
Guy Schalnat 已提交
866 867
}

868
void /* PRIVATE */
G
Guy Schalnat 已提交
869
png_process_IDAT_data(png_structp png_ptr, png_bytep buffer,
A
Andreas Dilger 已提交
870
   png_size_t buffer_length)
G
Guy Schalnat 已提交
871
{
872
   /* The caller checks for a non-zero buffer length. */
873
   if (!(buffer_length > 0) || buffer == NULL)
874
      png_error(png_ptr, "No IDAT data (internal error)");
G
Guy Schalnat 已提交
875

876 877
   /* This routine must process all the data it has been given
    * before returning, calling the row callback as required to
878
    * handle the uncompressed results.
879
    */
A
Andreas Dilger 已提交
880 881
   png_ptr->zstream.next_in = buffer;
   png_ptr->zstream.avail_in = (uInt)buffer_length;
882 883 884 885 886

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

      /* We have data for zlib, but we must check that zlib
892
       * has someplace to put the results.  It doesn't matter
893
       * if we don't expect any results -- it may be the input
894 895 896
       * data is just the LZ end code.
       */
      if (!(png_ptr->zstream.avail_out > 0))
G
Guy Schalnat 已提交
897
      {
898 899 900
         png_ptr->zstream.avail_out =
             (uInt) PNG_ROWBYTES(png_ptr->pixel_depth,
             png_ptr->iwidth) + 1;
901

902 903 904 905
         png_ptr->zstream.next_out = png_ptr->row_buf;
      }

      /* Using Z_SYNC_FLUSH here means that an unterminated
906 907 908 909 910
       * 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).
911 912
       */
      ret = inflate(&png_ptr->zstream, Z_SYNC_FLUSH);
913

914 915 916
      /* Check for any failure before proceeding. */
      if (ret != Z_OK && ret != Z_STREAM_END)
      {
917 918
         /* Terminate the decompression. */
         png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
919

920
         /* This may be a truncated stream (missing or
921 922
          * damaged end code).  Treat that as a warning.
          */
923
         if (png_ptr->row_number >= png_ptr->num_rows ||
924 925
             png_ptr->pass > 6)
            png_warning(png_ptr, "Truncated compressed data in IDAT");
926

927 928
         else
            png_error(png_ptr, "Decompression error in IDAT");
929

930
         /* Skip the check on unprocessed input */
931
         return;
G
Guy Schalnat 已提交
932
      }
933 934 935

      /* Did inflate output any data? */
      if (png_ptr->zstream.next_out != png_ptr->row_buf)
G
Guy Schalnat 已提交
936
      {
937 938 939 940
         /* Is this unexpected data after the last row?
          * If it is, artificially terminate the LZ output
          * here.
          */
941
         if (png_ptr->row_number >= png_ptr->num_rows ||
942
             png_ptr->pass > 6)
943
         {
944 945
            /* Extra data. */
            png_warning(png_ptr, "Extra compressed data in IDAT");
946
            png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
947

948 949 950
            /* Do no more processing; skip the unprocessed
             * input check below.
             */
951
            return;
952
         }
953

954 955 956
         /* Do we have a complete row? */
         if (png_ptr->zstream.avail_out == 0)
            png_push_process_row(png_ptr);
G
Guy Schalnat 已提交
957
      }
958 959 960

      /* And check for the end of the stream. */
      if (ret == Z_STREAM_END)
961
         png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
A
Andreas Dilger 已提交
962
   }
963 964 965 966 967 968

   /* 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)
969
      png_warning(png_ptr, "Extra compression data in IDAT");
G
Guy Schalnat 已提交
970 971
}

972
void /* PRIVATE */
G
Guy Schalnat 已提交
973 974
png_push_process_row(png_structp png_ptr)
{
975 976
   /* 1.5.6: row_info moved out of png_struct to a local here. */
   png_row_info row_info;
977

978 979 980 981 982 983
   row_info.width = png_ptr->iwidth; /* NOTE: width of current interlaced row */
   row_info.color_type = png_ptr->color_type;
   row_info.bit_depth = png_ptr->bit_depth;
   row_info.channels = png_ptr->channels;
   row_info.pixel_depth = png_ptr->pixel_depth;
   row_info.rowbytes = PNG_ROWBYTES(row_info.pixel_depth, row_info.width);
G
Guy Schalnat 已提交
984

985 986 987 988 989 990 991 992
   if (png_ptr->row_buf[0] > PNG_FILTER_VALUE_NONE)
   {
      if (png_ptr->row_buf[0] < PNG_FILTER_VALUE_LAST)
         png_read_filter_row(&row_info, png_ptr->row_buf + 1,
            png_ptr->prev_row + 1, png_ptr->row_buf[0]);
      else
         png_error(png_ptr, "bad adaptive filter value");
   }
G
Guy Schalnat 已提交
993

994 995 996 997 998 999
   /* libpng 1.5.6: the following line was copying png_ptr->rowbytes before
    * 1.5.6, while the buffer really is this big in current versions of libpng
    * it may not be in the future, so this was changed just to copy the
    * interlaced row count:
    */
   png_memcpy(png_ptr->prev_row, png_ptr->row_buf, row_info.rowbytes + 1);
G
Guy Schalnat 已提交
1000

1001
#ifdef PNG_READ_TRANSFORMS_SUPPORTED
1002
   if (png_ptr->transformations)
1003
      png_do_read_transformations(png_ptr, &row_info);
1004
#endif
G
Guy Schalnat 已提交
1005

1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017
   /* The transformed pixel depth should match the depth now in row_info. */
   if (png_ptr->transformed_pixel_depth == 0)
   {
      png_ptr->transformed_pixel_depth = row_info.pixel_depth;
      if (row_info.pixel_depth > png_ptr->maximum_pixel_depth)
         png_error(png_ptr, "progressive row overflow");
   }

   else if (png_ptr->transformed_pixel_depth != row_info.pixel_depth)
      png_error(png_ptr, "internal progressive row size calculation error");


1018
#ifdef PNG_READ_INTERLACING_SUPPORTED
1019
   /* Blow up interlaced rows to full size */
A
Andreas Dilger 已提交
1020
   if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE))
G
Guy Schalnat 已提交
1021 1022
   {
      if (png_ptr->pass < 6)
1023 1024
         png_do_read_interlace(&row_info, png_ptr->row_buf + 1, png_ptr->pass,
            png_ptr->transformations);
G
Guy Schalnat 已提交
1025

1026 1027
    switch (png_ptr->pass)
    {
G
Guy Schalnat 已提交
1028 1029 1030 1031 1032 1033
         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);
1034
               png_read_push_finish_row(png_ptr); /* Updates png_ptr->pass */
G
Guy Schalnat 已提交
1035
            }
1036

1037
            if (png_ptr->pass == 2) /* Pass 1 might be empty */
1038 1039 1040
            {
               for (i = 0; i < 4 && png_ptr->pass == 2; i++)
               {
1041
                  png_push_have_row(png_ptr, NULL);
1042 1043 1044
                  png_read_push_finish_row(png_ptr);
               }
            }
1045

1046 1047 1048 1049
            if (png_ptr->pass == 4 && png_ptr->height <= 4)
            {
               for (i = 0; i < 2 && png_ptr->pass == 4; i++)
               {
1050
                  png_push_have_row(png_ptr, NULL);
1051 1052
                  png_read_push_finish_row(png_ptr);
               }
1053
            }
1054

1055 1056
            if (png_ptr->pass == 6 && png_ptr->height <= 4)
            {
1057
                png_push_have_row(png_ptr, NULL);
1058 1059
                png_read_push_finish_row(png_ptr);
            }
1060

G
Guy Schalnat 已提交
1061 1062
            break;
         }
1063

G
Guy Schalnat 已提交
1064 1065 1066 1067 1068 1069 1070 1071
         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);
            }
1072

1073
            if (png_ptr->pass == 2) /* Skip top 4 generated rows */
G
Guy Schalnat 已提交
1074 1075 1076
            {
               for (i = 0; i < 4 && png_ptr->pass == 2; i++)
               {
1077
                  png_push_have_row(png_ptr, NULL);
G
Guy Schalnat 已提交
1078 1079 1080
                  png_read_push_finish_row(png_ptr);
               }
            }
1081

G
Guy Schalnat 已提交
1082 1083
            break;
         }
1084

G
Guy Schalnat 已提交
1085 1086 1087
         case 2:
         {
            int i;
1088

G
Guy Schalnat 已提交
1089 1090 1091 1092 1093
            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);
            }
1094

G
Guy Schalnat 已提交
1095 1096
            for (i = 0; i < 4 && png_ptr->pass == 2; i++)
            {
1097
               png_push_have_row(png_ptr, NULL);
G
Guy Schalnat 已提交
1098 1099
               png_read_push_finish_row(png_ptr);
            }
1100

1101
            if (png_ptr->pass == 4) /* Pass 3 might be empty */
1102 1103 1104
            {
               for (i = 0; i < 2 && png_ptr->pass == 4; i++)
               {
1105
                  png_push_have_row(png_ptr, NULL);
1106 1107 1108
                  png_read_push_finish_row(png_ptr);
               }
            }
1109

G
Guy Schalnat 已提交
1110 1111
            break;
         }
1112

G
Guy Schalnat 已提交
1113 1114 1115
         case 3:
         {
            int i;
1116

G
Guy Schalnat 已提交
1117 1118 1119 1120 1121
            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);
            }
1122

1123
            if (png_ptr->pass == 4) /* Skip top two generated rows */
G
Guy Schalnat 已提交
1124 1125 1126
            {
               for (i = 0; i < 2 && png_ptr->pass == 4; i++)
               {
1127
                  png_push_have_row(png_ptr, NULL);
G
Guy Schalnat 已提交
1128 1129 1130
                  png_read_push_finish_row(png_ptr);
               }
            }
1131

G
Guy Schalnat 已提交
1132 1133
            break;
         }
1134

G
Guy Schalnat 已提交
1135 1136 1137
         case 4:
         {
            int i;
1138

G
Guy Schalnat 已提交
1139 1140 1141 1142 1143
            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);
            }
1144

G
Guy Schalnat 已提交
1145 1146
            for (i = 0; i < 2 && png_ptr->pass == 4; i++)
            {
1147
               png_push_have_row(png_ptr, NULL);
G
Guy Schalnat 已提交
1148 1149
               png_read_push_finish_row(png_ptr);
            }
1150

1151
            if (png_ptr->pass == 6) /* Pass 5 might be empty */
1152
            {
1153
               png_push_have_row(png_ptr, NULL);
1154 1155
               png_read_push_finish_row(png_ptr);
            }
1156

G
Guy Schalnat 已提交
1157 1158
            break;
         }
1159

G
Guy Schalnat 已提交
1160 1161 1162
         case 5:
         {
            int i;
1163

G
Guy Schalnat 已提交
1164 1165 1166 1167 1168
            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);
            }
1169

1170
            if (png_ptr->pass == 6) /* Skip top generated row */
G
Guy Schalnat 已提交
1171
            {
1172
               png_push_have_row(png_ptr, NULL);
G
Guy Schalnat 已提交
1173 1174
               png_read_push_finish_row(png_ptr);
            }
1175

G
Guy Schalnat 已提交
1176 1177
            break;
         }
1178

1179
         default:
G
Guy Schalnat 已提交
1180 1181 1182 1183
         case 6:
         {
            png_push_have_row(png_ptr, png_ptr->row_buf + 1);
            png_read_push_finish_row(png_ptr);
1184

G
Guy Schalnat 已提交
1185 1186
            if (png_ptr->pass != 6)
               break;
1187

1188
            png_push_have_row(png_ptr, NULL);
G
Guy Schalnat 已提交
1189 1190 1191 1192 1193
            png_read_push_finish_row(png_ptr);
         }
      }
   }
   else
G
Guy Schalnat 已提交
1194
#endif
G
Guy Schalnat 已提交
1195 1196 1197 1198
   {
      png_push_have_row(png_ptr, png_ptr->row_buf + 1);
      png_read_push_finish_row(png_ptr);
   }
G
Guy Schalnat 已提交
1199 1200
}

1201
void /* PRIVATE */
G
Guy Schalnat 已提交
1202 1203
png_read_push_finish_row(png_structp png_ptr)
{
1204
   /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
1205

1206
   /* Start of interlace block */
1207
   static PNG_CONST png_byte FARDATA png_pass_start[] = {0, 4, 0, 2, 0, 1, 0};
1208

1209
   /* Offset to next interlace block */
1210
   static PNG_CONST png_byte FARDATA png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1};
1211

1212
   /* Start of interlace block in the y direction */
1213
   static PNG_CONST png_byte FARDATA png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1};
1214

1215
   /* Offset to next interlace block in the y direction */
1216
   static PNG_CONST png_byte FARDATA png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2};
1217

1218 1219
   /* Height of interlace block.  This is not currently used - if you need
    * it, uncomment it here and in png.h
1220
   static PNG_CONST png_byte FARDATA png_pass_height[] = {8, 8, 4, 4, 2, 2, 1};
1221
   */
1222

G
Guy Schalnat 已提交
1223 1224
   png_ptr->row_number++;
   if (png_ptr->row_number < png_ptr->num_rows)
G
Guy Schalnat 已提交
1225
      return;
G
Guy Schalnat 已提交
1226

1227
#ifdef PNG_READ_INTERLACING_SUPPORTED
G
Guy Schalnat 已提交
1228 1229 1230
   if (png_ptr->interlaced)
   {
      png_ptr->row_number = 0;
1231 1232
      png_memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1);

G
Guy Schalnat 已提交
1233 1234 1235
      do
      {
         png_ptr->pass++;
1236 1237 1238
         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))
1239
            png_ptr->pass++;
1240

1241 1242
         if (png_ptr->pass > 7)
            png_ptr->pass--;
1243

G
Guy Schalnat 已提交
1244 1245
         if (png_ptr->pass >= 7)
            break;
1246

G
Guy Schalnat 已提交
1247
         png_ptr->iwidth = (png_ptr->width +
1248 1249 1250
             png_pass_inc[png_ptr->pass] - 1 -
             png_pass_start[png_ptr->pass]) /
             png_pass_inc[png_ptr->pass];
1251

G
Guy Schalnat 已提交
1252 1253
         if (png_ptr->transformations & PNG_INTERLACE)
            break;
1254 1255

         png_ptr->num_rows = (png_ptr->height +
1256 1257 1258
             png_pass_yinc[png_ptr->pass] - 1 -
             png_pass_ystart[png_ptr->pass]) /
             png_pass_yinc[png_ptr->pass];
1259 1260

      } while (png_ptr->iwidth == 0 || png_ptr->num_rows == 0);
G
Guy Schalnat 已提交
1261
   }
1262
#endif /* PNG_READ_INTERLACING_SUPPORTED */
G
Guy Schalnat 已提交
1263 1264
}

1265
#ifdef PNG_READ_tEXt_SUPPORTED
1266
void /* PRIVATE */
1267
png_push_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32
1268
    length)
G
Guy Schalnat 已提交
1269
{
1270
   if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND))
1271
      {
1272
         PNG_UNUSED(info_ptr) /* To quiet some compiler warnings */
1273
         png_error(png_ptr, "Out of place tEXt");
1274
         /* NOT REACHED */
1275
      }
A
Andreas Dilger 已提交
1276

A
Andreas Dilger 已提交
1277 1278 1279
#ifdef PNG_MAX_MALLOC_64K
   png_ptr->skip_length = 0;  /* This may not be necessary */

1280
   if (length > (png_uint_32)65535L) /* Can't hold entire string in memory */
A
Andreas Dilger 已提交
1281 1282
   {
      png_warning(png_ptr, "tEXt chunk too large to fit in memory");
1283 1284
      png_ptr->skip_length = length - (png_uint_32)65535L;
      length = (png_uint_32)65535L;
A
Andreas Dilger 已提交
1285 1286 1287
   }
#endif

1288
   png_ptr->current_text = (png_charp)png_malloc(png_ptr,
1289
       (png_size_t)(length + 1));
A
Andreas Dilger 已提交
1290
   png_ptr->current_text[length] = '\0';
G
Guy Schalnat 已提交
1291
   png_ptr->current_text_ptr = png_ptr->current_text;
1292 1293
   png_ptr->current_text_size = (png_size_t)length;
   png_ptr->current_text_left = (png_size_t)length;
G
Guy Schalnat 已提交
1294
   png_ptr->process_mode = PNG_READ_tEXt_MODE;
G
Guy Schalnat 已提交
1295 1296
}

1297
void /* PRIVATE */
A
Andreas Dilger 已提交
1298
png_push_read_tEXt(png_structp png_ptr, png_infop info_ptr)
G
Guy Schalnat 已提交
1299
{
G
Guy Schalnat 已提交
1300 1301
   if (png_ptr->buffer_size && png_ptr->current_text_left)
   {
A
Andreas Dilger 已提交
1302
      png_size_t text_size;
G
Guy Schalnat 已提交
1303 1304 1305

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

G
Guy Schalnat 已提交
1307 1308
      else
         text_size = png_ptr->current_text_left;
1309

A
Andreas Dilger 已提交
1310
      png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size);
G
Guy Schalnat 已提交
1311
      png_ptr->current_text_left -= text_size;
A
Andreas Dilger 已提交
1312
      png_ptr->current_text_ptr += text_size;
G
Guy Schalnat 已提交
1313 1314 1315
   }
   if (!(png_ptr->current_text_left))
   {
A
Andreas Dilger 已提交
1316
      png_textp text_ptr;
G
Guy Schalnat 已提交
1317 1318
      png_charp text;
      png_charp key;
1319
      int ret;
G
Guy Schalnat 已提交
1320 1321 1322 1323 1324 1325 1326

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

A
Andreas Dilger 已提交
1327 1328
      png_push_crc_finish(png_ptr);

1329
#ifdef PNG_MAX_MALLOC_64K
A
Andreas Dilger 已提交
1330 1331 1332
      if (png_ptr->skip_length)
         return;
#endif
G
Guy Schalnat 已提交
1333 1334 1335 1336

      key = png_ptr->current_text;

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

1339
      if (text < key + png_ptr->current_text_size)
G
Guy Schalnat 已提交
1340 1341
         text++;

1342
      text_ptr = (png_textp)png_malloc(png_ptr, png_sizeof(png_text));
A
Andreas Dilger 已提交
1343 1344
      text_ptr->compression = PNG_TEXT_COMPRESSION_NONE;
      text_ptr->key = key;
1345
      text_ptr->itxt_length = 0;
1346 1347
      text_ptr->lang = NULL;
      text_ptr->lang_key = NULL;
A
Andreas Dilger 已提交
1348
      text_ptr->text = text;
G
Guy Schalnat 已提交
1349

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

1352
      png_free(png_ptr, key);
A
Andreas Dilger 已提交
1353
      png_free(png_ptr, text_ptr);
1354
      png_ptr->current_text = NULL;
1355 1356

      if (ret)
1357
         png_warning(png_ptr, "Insufficient memory to store text chunk");
G
Guy Schalnat 已提交
1358
   }
G
Guy Schalnat 已提交
1359 1360 1361
}
#endif

1362
#ifdef PNG_READ_zTXt_SUPPORTED
1363
void /* PRIVATE */
1364 1365
png_push_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32
   length)
G
Guy Schalnat 已提交
1366
{
1367
   if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND))
1368
   {
1369
      PNG_UNUSED(info_ptr) /* To quiet some compiler warnings */
1370
      png_error(png_ptr, "Out of place zTXt");
1371
      /* NOT REACHED */
1372
   }
A
Andreas Dilger 已提交
1373

A
Andreas Dilger 已提交
1374 1375 1376 1377 1378
#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.
    */
1379
   if (length > (png_uint_32)65535L)
A
Andreas Dilger 已提交
1380 1381 1382 1383 1384 1385 1386
   {
      png_warning(png_ptr, "zTXt chunk too large to fit in memory");
      png_push_crc_skip(png_ptr, length);
      return;
   }
#endif

1387
   png_ptr->current_text = (png_charp)png_malloc(png_ptr,
1388
       (png_size_t)(length + 1));
A
Andreas Dilger 已提交
1389
   png_ptr->current_text[length] = '\0';
G
Guy Schalnat 已提交
1390
   png_ptr->current_text_ptr = png_ptr->current_text;
1391 1392
   png_ptr->current_text_size = (png_size_t)length;
   png_ptr->current_text_left = (png_size_t)length;
G
Guy Schalnat 已提交
1393
   png_ptr->process_mode = PNG_READ_zTXt_MODE;
G
Guy Schalnat 已提交
1394 1395
}

1396
void /* PRIVATE */
A
Andreas Dilger 已提交
1397
png_push_read_zTXt(png_structp png_ptr, png_infop info_ptr)
G
Guy Schalnat 已提交
1398
{
G
Guy Schalnat 已提交
1399 1400
   if (png_ptr->buffer_size && png_ptr->current_text_left)
   {
A
Andreas Dilger 已提交
1401
      png_size_t text_size;
G
Guy Schalnat 已提交
1402

A
Andreas Dilger 已提交
1403
      if (png_ptr->buffer_size < (png_uint_32)png_ptr->current_text_left)
G
Guy Schalnat 已提交
1404
         text_size = png_ptr->buffer_size;
1405

G
Guy Schalnat 已提交
1406 1407
      else
         text_size = png_ptr->current_text_left;
1408

A
Andreas Dilger 已提交
1409
      png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size);
G
Guy Schalnat 已提交
1410
      png_ptr->current_text_left -= text_size;
A
Andreas Dilger 已提交
1411
      png_ptr->current_text_ptr += text_size;
G
Guy Schalnat 已提交
1412 1413 1414
   }
   if (!(png_ptr->current_text_left))
   {
A
Andreas Dilger 已提交
1415
      png_textp text_ptr;
G
Guy Schalnat 已提交
1416 1417 1418
      png_charp text;
      png_charp key;
      int ret;
A
Andreas Dilger 已提交
1419
      png_size_t text_size, key_size;
G
Guy Schalnat 已提交
1420 1421 1422 1423 1424 1425 1426

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

A
Andreas Dilger 已提交
1427
      png_push_crc_finish(png_ptr);
G
Guy Schalnat 已提交
1428 1429 1430 1431

      key = png_ptr->current_text;

      for (text = key; *text; text++)
1432
         /* Empty loop */ ;
G
Guy Schalnat 已提交
1433 1434

      /* zTXt can't have zero text */
1435
      if (text >= key + png_ptr->current_text_size)
G
Guy Schalnat 已提交
1436
      {
1437
         png_ptr->current_text = NULL;
A
Andreas Dilger 已提交
1438
         png_free(png_ptr, key);
G
Guy Schalnat 已提交
1439 1440 1441 1442 1443
         return;
      }

      text++;

1444
      if (*text != PNG_TEXT_COMPRESSION_zTXt) /* Check compression byte */
G
Guy Schalnat 已提交
1445
      {
1446
         png_ptr->current_text = NULL;
A
Andreas Dilger 已提交
1447
         png_free(png_ptr, key);
G
Guy Schalnat 已提交
1448 1449 1450 1451 1452
         return;
      }

      text++;

1453
      png_ptr->zstream.next_in = (png_bytep)text;
A
Andreas Dilger 已提交
1454
      png_ptr->zstream.avail_in = (uInt)(png_ptr->current_text_size -
1455
          (text - key));
A
Andreas Dilger 已提交
1456
      png_ptr->zstream.next_out = png_ptr->zbuf;
1457
      png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
G
Guy Schalnat 已提交
1458 1459 1460 1461 1462 1463

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

A
Andreas Dilger 已提交
1464
      while (png_ptr->zstream.avail_in)
G
Guy Schalnat 已提交
1465
      {
A
Andreas Dilger 已提交
1466
         ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
G
Guy Schalnat 已提交
1467 1468
         if (ret != Z_OK && ret != Z_STREAM_END)
         {
A
Andreas Dilger 已提交
1469 1470
            inflateReset(&png_ptr->zstream);
            png_ptr->zstream.avail_in = 0;
1471
            png_ptr->current_text = NULL;
A
Andreas Dilger 已提交
1472 1473
            png_free(png_ptr, key);
            png_free(png_ptr, text);
G
Guy Schalnat 已提交
1474 1475
            return;
         }
1476

A
Andreas Dilger 已提交
1477
         if (!(png_ptr->zstream.avail_out) || ret == Z_STREAM_END)
G
Guy Schalnat 已提交
1478
         {
A
Andreas Dilger 已提交
1479
            if (text == NULL)
G
Guy Schalnat 已提交
1480
            {
A
Andreas Dilger 已提交
1481
               text = (png_charp)png_malloc(png_ptr,
1482 1483
                   (png_ptr->zbuf_size
                   - png_ptr->zstream.avail_out + key_size + 1));
1484

1485
               png_memcpy(text + key_size, png_ptr->zbuf,
1486
                   png_ptr->zbuf_size - png_ptr->zstream.avail_out);
1487

1488
               png_memcpy(text, key, key_size);
1489

1490
               text_size = key_size + png_ptr->zbuf_size -
1491
                   png_ptr->zstream.avail_out;
1492

1493
               *(text + text_size) = '\0';
G
Guy Schalnat 已提交
1494
            }
1495

G
Guy Schalnat 已提交
1496 1497 1498 1499 1500
            else
            {
               png_charp tmp;

               tmp = text;
1501
               text = (png_charp)png_malloc(png_ptr, text_size +
1502
                   (png_ptr->zbuf_size
1503
                   - png_ptr->zstream.avail_out + 1));
1504

1505 1506
               png_memcpy(text, tmp, text_size);
               png_free(png_ptr, tmp);
1507

1508
               png_memcpy(text + text_size, png_ptr->zbuf,
1509
                   png_ptr->zbuf_size - png_ptr->zstream.avail_out);
1510

1511 1512
               text_size += png_ptr->zbuf_size - png_ptr->zstream.avail_out;
               *(text + text_size) = '\0';
G
Guy Schalnat 已提交
1513
            }
1514

G
Guy Schalnat 已提交
1515 1516
            if (ret != Z_STREAM_END)
            {
A
Andreas Dilger 已提交
1517 1518
               png_ptr->zstream.next_out = png_ptr->zbuf;
               png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
G
Guy Schalnat 已提交
1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529
            }
         }
         else
         {
            break;
         }

         if (ret == Z_STREAM_END)
            break;
      }

A
Andreas Dilger 已提交
1530 1531
      inflateReset(&png_ptr->zstream);
      png_ptr->zstream.avail_in = 0;
G
Guy Schalnat 已提交
1532 1533 1534

      if (ret != Z_STREAM_END)
      {
1535
         png_ptr->current_text = NULL;
A
Andreas Dilger 已提交
1536 1537
         png_free(png_ptr, key);
         png_free(png_ptr, text);
G
Guy Schalnat 已提交
1538 1539 1540
         return;
      }

1541
      png_ptr->current_text = NULL;
A
Andreas Dilger 已提交
1542
      png_free(png_ptr, key);
G
Guy Schalnat 已提交
1543
      key = text;
A
Andreas Dilger 已提交
1544
      text += key_size;
G
Guy Schalnat 已提交
1545

1546 1547
      text_ptr = (png_textp)png_malloc(png_ptr,
          png_sizeof(png_text));
1548 1549
      text_ptr->compression = PNG_TEXT_COMPRESSION_zTXt;
      text_ptr->key = key;
1550
      text_ptr->itxt_length = 0;
1551 1552
      text_ptr->lang = NULL;
      text_ptr->lang_key = NULL;
1553
      text_ptr->text = text;
1554

1555
      ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
1556

1557
      png_free(png_ptr, key);
1558
      png_free(png_ptr, text_ptr);
1559 1560

      if (ret)
1561
         png_warning(png_ptr, "Insufficient memory to store text chunk");
1562 1563 1564 1565
   }
}
#endif

1566
#ifdef PNG_READ_iTXt_SUPPORTED
1567
void /* PRIVATE */
1568
png_push_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32
1569
    length)
1570
{
1571
   if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND))
1572
   {
1573
      PNG_UNUSED(info_ptr) /* To quiet some compiler warnings */
1574
      png_error(png_ptr, "Out of place iTXt");
1575
      /* NOT REACHED */
1576
   }
1577 1578 1579 1580

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

1581
   if (length > (png_uint_32)65535L) /* Can't hold entire string in memory */
1582 1583 1584 1585 1586 1587 1588 1589
   {
      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,
1590
       (png_size_t)(length + 1));
1591 1592 1593 1594 1595
   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;
1596 1597
}

1598
void /* PRIVATE */
1599 1600
png_push_read_iTXt(png_structp png_ptr, png_infop info_ptr)
{
1601

1602 1603 1604 1605 1606 1607
   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;
1608

1609 1610
      else
         text_size = png_ptr->current_text_left;
1611

1612 1613 1614 1615
      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;
   }
1616

1617 1618 1619 1620
   if (!(png_ptr->current_text_left))
   {
      png_textp text_ptr;
      png_charp key;
1621
      int comp_flag;
1622 1623 1624
      png_charp lang;
      png_charp lang_key;
      png_charp text;
1625
      int ret;
1626 1627 1628 1629 1630 1631 1632 1633 1634

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

      png_push_crc_finish(png_ptr);

1635
#ifdef PNG_MAX_MALLOC_64K
1636 1637 1638 1639
      if (png_ptr->skip_length)
         return;
#endif

1640
      key = png_ptr->current_text;
1641

1642
      for (lang = key; *lang; lang++)
1643
         /* Empty loop */ ;
1644

1645
      if (lang < key + png_ptr->current_text_size - 3)
1646
         lang++;
1647

1648
      comp_flag = *lang++;
1649
      lang++;     /* Skip comp_type, always zero */
1650 1651

      for (lang_key = lang; *lang_key; lang_key++)
1652
         /* Empty loop */ ;
1653

1654
      lang_key++;        /* Skip NUL separator */
1655

1656
      text=lang_key;
1657

1658 1659
      if (lang_key < key + png_ptr->current_text_size - 1)
      {
1660 1661
         for (; *text; text++)
            /* Empty loop */ ;
1662
      }
1663

1664
      if (text < key + png_ptr->current_text_size)
1665 1666
         text++;

1667
      text_ptr = (png_textp)png_malloc(png_ptr,
1668
          png_sizeof(png_text));
1669

1670
      text_ptr->compression = comp_flag + 2;
A
Andreas Dilger 已提交
1671
      text_ptr->key = key;
1672 1673
      text_ptr->lang = lang;
      text_ptr->lang_key = lang_key;
A
Andreas Dilger 已提交
1674
      text_ptr->text = text;
1675 1676
      text_ptr->text_length = 0;
      text_ptr->itxt_length = png_strlen(text);
A
Andreas Dilger 已提交
1677

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

1680 1681
      png_ptr->current_text = NULL;

A
Andreas Dilger 已提交
1682
      png_free(png_ptr, text_ptr);
1683
      if (ret)
1684
         png_warning(png_ptr, "Insufficient memory to store iTXt chunk");
G
Guy Schalnat 已提交
1685
   }
G
Guy Schalnat 已提交
1686 1687 1688
}
#endif

A
Andreas Dilger 已提交
1689
/* This function is called when we haven't found a handler for this
1690 1691
 * 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.
1692
 */
1693
void /* PRIVATE */
1694
png_push_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32
1695
    length)
A
Andreas Dilger 已提交
1696
{
1697
   png_uint_32 skip = 0;
1698
   png_uint_32 chunk_name = png_ptr->chunk_name;
A
Andreas Dilger 已提交
1699

1700
   if (PNG_CHUNK_CRITICAL(chunk_name))
A
Andreas Dilger 已提交
1701
   {
1702
#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
1703
      if (png_chunk_unknown_handling(png_ptr, chunk_name) !=
1704
          PNG_HANDLE_CHUNK_ALWAYS
1705
#ifdef PNG_READ_USER_CHUNKS_SUPPORTED
1706
          && png_ptr->read_user_chunk_fn == NULL
1707
#endif
1708
          )
1709
#endif
1710 1711
         png_chunk_error(png_ptr, "unknown critical chunk");

1712
      PNG_UNUSED(info_ptr) /* To quiet some compiler warnings */
A
Andreas Dilger 已提交
1713 1714
   }

1715
#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
1716 1717 1718 1719
   /* TODO: the code below is apparently just using the
    * png_struct::unknown_chunk member as a temporarily variable, it should be
    * possible to eliminate both it and the temporary buffer.
    */
1720 1721 1722
   if (png_ptr->flags & PNG_FLAG_KEEP_UNKNOWN_CHUNKS)
   {
#ifdef PNG_MAX_MALLOC_64K
1723
      if (length > 65535)
1724
      {
1725
         png_warning(png_ptr, "unknown chunk too large to fit in memory");
1726 1727
         skip = length - 65535;
         length = 65535;
1728
      }
1729
#endif
1730 1731 1732 1733
      /* This is just a record for the user; libpng doesn't use the character
       * form of the name.
       */
      PNG_CSTRING_FROM_CHUNK(png_ptr->unknown_chunk.name, png_ptr->chunk_name);
1734

1735
      /* The following cast should be safe because of the check above. */
1736
      png_ptr->unknown_chunk.size = (png_size_t)length;
1737

1738 1739
      if (length == 0)
         png_ptr->unknown_chunk.data = NULL;
1740

1741 1742 1743
      else
      {
         png_ptr->unknown_chunk.data = (png_bytep)png_malloc(png_ptr,
1744 1745 1746
            png_ptr->unknown_chunk.size);
         png_crc_read(png_ptr, (png_bytep)png_ptr->unknown_chunk.data,
            png_ptr->unknown_chunk.size);
1747
      }
1748

1749
#ifdef PNG_READ_USER_CHUNKS_SUPPORTED
1750 1751
      if (png_ptr->read_user_chunk_fn != NULL)
      {
1752
         /* Callback to user unknown chunk handler */
1753 1754
         int ret;
         ret = (*(png_ptr->read_user_chunk_fn))
1755
             (png_ptr, &png_ptr->unknown_chunk);
1756

1757 1758
         if (ret < 0)
            png_chunk_error(png_ptr, "error in user chunk");
1759

1760 1761
         if (ret == 0)
         {
1762 1763
            if (PNG_CHUNK_CRITICAL(png_ptr->chunk_name))
               if (png_chunk_unknown_handling(png_ptr, chunk_name) !=
1764
                   PNG_HANDLE_CHUNK_ALWAYS)
1765 1766
                  png_chunk_error(png_ptr, "unknown critical chunk");
            png_set_unknown_chunks(png_ptr, info_ptr,
1767
                &png_ptr->unknown_chunk, 1);
1768 1769
         }
      }
1770

1771
      else
1772
#endif
1773
         png_set_unknown_chunks(png_ptr, info_ptr, &png_ptr->unknown_chunk, 1);
1774 1775
      png_free(png_ptr, png_ptr->unknown_chunk.data);
      png_ptr->unknown_chunk.data = NULL;
1776
   }
1777

1778 1779 1780 1781
   else
#endif
      skip=length;
   png_push_crc_skip(png_ptr, skip);
A
Andreas Dilger 已提交
1782 1783
}

1784
void /* PRIVATE */
A
Andreas Dilger 已提交
1785
png_push_have_info(png_structp png_ptr, png_infop info_ptr)
G
Guy Schalnat 已提交
1786
{
A
Andreas Dilger 已提交
1787
   if (png_ptr->info_fn != NULL)
A
Andreas Dilger 已提交
1788
      (*(png_ptr->info_fn))(png_ptr, info_ptr);
G
Guy Schalnat 已提交
1789 1790
}

1791
void /* PRIVATE */
A
Andreas Dilger 已提交
1792
png_push_have_end(png_structp png_ptr, png_infop info_ptr)
G
Guy Schalnat 已提交
1793
{
A
Andreas Dilger 已提交
1794
   if (png_ptr->end_fn != NULL)
A
Andreas Dilger 已提交
1795
      (*(png_ptr->end_fn))(png_ptr, info_ptr);
G
Guy Schalnat 已提交
1796 1797
}

1798
void /* PRIVATE */
G
Guy Schalnat 已提交
1799 1800
png_push_have_row(png_structp png_ptr, png_bytep row)
{
1801
   if (png_ptr->row_fn != NULL)
G
Guy Schalnat 已提交
1802 1803
      (*(png_ptr->row_fn))(png_ptr, row, png_ptr->row_number,
         (int)png_ptr->pass);
G
Guy Schalnat 已提交
1804 1805
}

1806
#ifdef PNG_READ_INTERLACING_SUPPORTED
1807
void PNGAPI
1808 1809
png_progressive_combine_row (png_structp png_ptr, png_bytep old_row,
    png_const_bytep new_row)
G
Guy Schalnat 已提交
1810
{
1811 1812 1813
   if (png_ptr == NULL)
      return;

1814 1815 1816 1817 1818 1819
   /* new_row is a flag here - if it is NULL then the app callback was called
    * from an empty row (see the calls to png_struct::row_fn below), otherwise
    * it must be png_ptr->row_buf+1
    */
   if (new_row != NULL)
      png_combine_row(png_ptr, old_row, 1/*display*/);
G
Guy Schalnat 已提交
1820
}
1821
#endif /* PNG_READ_INTERLACING_SUPPORTED */
G
Guy Schalnat 已提交
1822

1823
void PNGAPI
G
Guy Schalnat 已提交
1824
png_set_progressive_read_fn(png_structp png_ptr, png_voidp progressive_ptr,
1825 1826
    png_progressive_info_ptr info_fn, png_progressive_row_ptr row_fn,
    png_progressive_end_ptr end_fn)
G
Guy Schalnat 已提交
1827
{
1828 1829 1830
   if (png_ptr == NULL)
      return;

G
Guy Schalnat 已提交
1831 1832
   png_ptr->info_fn = info_fn;
   png_ptr->row_fn = row_fn;
G
Guy Schalnat 已提交
1833
   png_ptr->end_fn = end_fn;
G
Guy Schalnat 已提交
1834

1835
   png_set_read_fn(png_ptr, progressive_ptr, png_push_fill_buffer);
G
Guy Schalnat 已提交
1836 1837
}

1838
png_voidp PNGAPI
1839
png_get_progressive_ptr(png_const_structp png_ptr)
G
Guy Schalnat 已提交
1840
{
1841 1842 1843
   if (png_ptr == NULL)
      return (NULL);

A
Andreas Dilger 已提交
1844
   return png_ptr->io_ptr;
G
Guy Schalnat 已提交
1845
}
G
Guy Schalnat 已提交
1846
#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */