pngpread.c 34.7 KB
Newer Older
D
duke 已提交
1 2 3 4 5
/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
6
 * published by the Free Software Foundation.  Oracle designates this
D
duke 已提交
7
 * particular file as subject to the "Classpath" exception as provided
8
 * by Oracle in the LICENSE file that accompanied this code.
D
duke 已提交
9 10 11 12 13 14 15 16 17 18 19
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
20 21 22
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
D
duke 已提交
23 24 25 26 27 28 29 30 31
 */

/* pngpread.c - read a png file in push mode
 *
 * This file is available under and governed by the GNU General Public
 * License version 2 only, as published by the Free Software Foundation.
 * However, the following notice accompanied the original version of this
 * file and, per its terms, should not be removed:
 *
A
azvegint 已提交
32 33
 * Last changed in libpng 1.6.15 [November 20, 2014]
 * Copyright (c) 1998-2014 Glenn Randers-Pehrson
D
duke 已提交
34 35
 * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
 * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
B
bae 已提交
36 37 38 39
 *
 * This code is released under the libpng license.
 * For conditions of distribution and use, see the disclaimer
 * and license in png.h
D
duke 已提交
40 41
 */

B
bae 已提交
42
#include "pngpriv.h"
D
duke 已提交
43 44 45

#ifdef PNG_PROGRESSIVE_READ_SUPPORTED

B
bae 已提交
46
/* Push model modes */
D
duke 已提交
47 48 49 50 51 52 53 54 55 56
#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

A
azvegint 已提交
57 58 59 60 61 62 63
#define PNG_PUSH_SAVE_BUFFER_IF_FULL \
if (png_ptr->push_length + 4 > png_ptr->buffer_size) \
   { png_push_save_buffer(png_ptr); return; }
#define PNG_PUSH_SAVE_BUFFER_IF_LT(N) \
if (png_ptr->buffer_size < N) \
   { png_push_save_buffer(png_ptr); return; }

D
duke 已提交
64
void PNGAPI
A
azvegint 已提交
65
png_process_data(png_structrp png_ptr, png_inforp info_ptr,
B
bae 已提交
66
    png_bytep buffer, png_size_t buffer_size)
D
duke 已提交
67
{
B
bae 已提交
68 69 70
   if (png_ptr == NULL || info_ptr == NULL)
      return;

D
duke 已提交
71 72 73 74 75 76 77 78
   png_push_restore_buffer(png_ptr, buffer, buffer_size);

   while (png_ptr->buffer_size)
   {
      png_process_some_data(png_ptr, info_ptr);
   }
}

B
bae 已提交
79
png_size_t PNGAPI
A
azvegint 已提交
80
png_process_data_pause(png_structrp png_ptr, int save)
B
bae 已提交
81 82 83
{
   if (png_ptr != NULL)
   {
A
azvegint 已提交
84
      /* It's easiest for the caller if we do the save; then the caller doesn't
B
bae 已提交
85 86
       * have to supply the same data again:
       */
A
azvegint 已提交
87
      if (save != 0)
B
bae 已提交
88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
         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
A
azvegint 已提交
107
png_process_data_skip(png_structrp png_ptr)
B
bae 已提交
108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
{
   png_uint_32 remaining = 0;

   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;
}

D
duke 已提交
137 138 139 140
/* What we do with the incoming data depends on what we were previously
 * doing before we ran out of data...
 */
void /* PRIVATE */
A
azvegint 已提交
141
png_process_some_data(png_structrp png_ptr, png_inforp info_ptr)
D
duke 已提交
142
{
B
bae 已提交
143 144 145
   if (png_ptr == NULL)
      return;

D
duke 已提交
146 147 148 149 150 151 152
   switch (png_ptr->process_mode)
   {
      case PNG_READ_SIG_MODE:
      {
         png_push_read_sig(png_ptr, info_ptr);
         break;
      }
B
bae 已提交
153

D
duke 已提交
154 155 156 157 158
      case PNG_READ_CHUNK_MODE:
      {
         png_push_read_chunk(png_ptr, info_ptr);
         break;
      }
B
bae 已提交
159

D
duke 已提交
160 161 162 163 164
      case PNG_READ_IDAT_MODE:
      {
         png_push_read_IDAT(png_ptr);
         break;
      }
B
bae 已提交
165

D
duke 已提交
166 167 168 169 170
      case PNG_SKIP_MODE:
      {
         png_push_crc_finish(png_ptr);
         break;
      }
B
bae 已提交
171

D
duke 已提交
172 173 174 175 176 177 178 179 180 181 182 183 184 185 186
      default:
      {
         png_ptr->buffer_size = 0;
         break;
      }
   }
}

/* Read any remaining signature bytes from the stream and compare them with
 * the correct PNG signature.  It is possible that this routine is called
 * 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.
 */
void /* PRIVATE */
A
azvegint 已提交
187
png_push_read_sig(png_structrp png_ptr, png_inforp info_ptr)
D
duke 已提交
188
{
A
azvegint 已提交
189
   png_size_t num_checked = png_ptr->sig_bytes, /* SAFE, does not exceed 8 */
D
duke 已提交
190 191 192 193 194 195 196 197
             num_to_check = 8 - num_checked;

   if (png_ptr->buffer_size < num_to_check)
   {
      num_to_check = png_ptr->buffer_size;
   }

   png_push_fill_buffer(png_ptr, &(info_ptr->signature[num_checked]),
B
bae 已提交
198 199
       num_to_check);
   png_ptr->sig_bytes = (png_byte)(png_ptr->sig_bytes + num_to_check);
D
duke 已提交
200 201 202 203 204 205

   if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check))
   {
      if (num_checked < 4 &&
          png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4))
         png_error(png_ptr, "Not a PNG file");
B
bae 已提交
206

D
duke 已提交
207 208 209 210 211 212 213 214 215 216 217 218 219
      else
         png_error(png_ptr, "PNG file corrupted by ASCII conversion");
   }
   else
   {
      if (png_ptr->sig_bytes >= 8)
      {
         png_ptr->process_mode = PNG_READ_CHUNK_MODE;
      }
   }
}

void /* PRIVATE */
A
azvegint 已提交
220
png_push_read_chunk(png_structrp png_ptr, png_inforp info_ptr)
D
duke 已提交
221
{
A
azvegint 已提交
222 223 224
   png_uint_32 chunk_name;
#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
   int keep; /* unknown handling method */
D
duke 已提交
225
#endif
B
bae 已提交
226

A
azvegint 已提交
227 228
   /* First we make sure we have enough data for the 4-byte chunk name
    * and the 4-byte chunk length before proceeding with decoding the
D
duke 已提交
229
    * chunk data.  To fully decode each of these chunks, we also make
A
azvegint 已提交
230
    * sure we have enough data in the buffer for the 4-byte CRC at the
D
duke 已提交
231 232
    * end of every chunk (except IDAT, which is handled separately).
    */
A
azvegint 已提交
233
   if ((png_ptr->mode & PNG_HAVE_CHUNK_HEADER) == 0)
D
duke 已提交
234 235
   {
      png_byte chunk_length[4];
A
azvegint 已提交
236
      png_byte chunk_tag[4];
D
duke 已提交
237

A
azvegint 已提交
238
      PNG_PUSH_SAVE_BUFFER_IF_LT(8)
D
duke 已提交
239
      png_push_fill_buffer(png_ptr, chunk_length, 4);
B
bae 已提交
240
      png_ptr->push_length = png_get_uint_31(png_ptr, chunk_length);
D
duke 已提交
241
      png_reset_crc(png_ptr);
A
azvegint 已提交
242 243
      png_crc_read(png_ptr, chunk_tag, 4);
      png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(chunk_tag);
B
bae 已提交
244
      png_check_chunk_name(png_ptr, png_ptr->chunk_name);
D
duke 已提交
245 246 247
      png_ptr->mode |= PNG_HAVE_CHUNK_HEADER;
   }

A
azvegint 已提交
248 249 250 251 252
   chunk_name = png_ptr->chunk_name;

   if (chunk_name == png_IDAT)
   {
      if ((png_ptr->mode & PNG_AFTER_IDAT) != 0)
B
bae 已提交
253
         png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT;
D
duke 已提交
254

A
azvegint 已提交
255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277
      /* If we reach an IDAT chunk, this means we have read all of the
       * header chunks, and we can start reading the image (or if this
       * is called after the image has been read - we have an error).
       */
      if ((png_ptr->mode & PNG_HAVE_IHDR) == 0)
         png_error(png_ptr, "Missing IHDR before IDAT");

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

      png_ptr->mode |= PNG_HAVE_IDAT;
      png_ptr->process_mode = PNG_READ_IDAT_MODE;

      if ((png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT) == 0)
         if (png_ptr->push_length == 0)
            return;

      if ((png_ptr->mode & PNG_AFTER_IDAT) != 0)
         png_benign_error(png_ptr, "Too many IDATs found");
   }

   if (chunk_name == png_IHDR)
D
duke 已提交
278
   {
B
bae 已提交
279 280 281
      if (png_ptr->push_length != 13)
         png_error(png_ptr, "Invalid IHDR length");

A
azvegint 已提交
282
      PNG_PUSH_SAVE_BUFFER_IF_FULL
D
duke 已提交
283 284
      png_handle_IHDR(png_ptr, info_ptr, png_ptr->push_length);
   }
B
bae 已提交
285

A
azvegint 已提交
286
   else if (chunk_name == png_IEND)
D
duke 已提交
287
   {
A
azvegint 已提交
288
      PNG_PUSH_SAVE_BUFFER_IF_FULL
D
duke 已提交
289 290 291 292 293
      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);
   }
B
bae 已提交
294

D
duke 已提交
295
#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
A
azvegint 已提交
296
   else if ((keep = png_chunk_unknown_handling(png_ptr, chunk_name)) != 0)
D
duke 已提交
297
   {
A
azvegint 已提交
298 299
      PNG_PUSH_SAVE_BUFFER_IF_FULL
      png_handle_unknown(png_ptr, info_ptr, png_ptr->push_length, keep);
B
bae 已提交
300

A
azvegint 已提交
301
      if (chunk_name == png_PLTE)
D
duke 已提交
302 303 304
         png_ptr->mode |= PNG_HAVE_PLTE;
   }
#endif
A
azvegint 已提交
305 306

   else if (chunk_name == png_PLTE)
D
duke 已提交
307
   {
A
azvegint 已提交
308
      PNG_PUSH_SAVE_BUFFER_IF_FULL
D
duke 已提交
309 310
      png_handle_PLTE(png_ptr, info_ptr, png_ptr->push_length);
   }
B
bae 已提交
311

A
azvegint 已提交
312
   else if (chunk_name == png_IDAT)
D
duke 已提交
313 314 315 316
   {
      png_ptr->idat_size = png_ptr->push_length;
      png_ptr->process_mode = PNG_READ_IDAT_MODE;
      png_push_have_info(png_ptr, info_ptr);
B
bae 已提交
317 318 319
      png_ptr->zstream.avail_out =
          (uInt) PNG_ROWBYTES(png_ptr->pixel_depth,
          png_ptr->iwidth) + 1;
D
duke 已提交
320 321 322
      png_ptr->zstream.next_out = png_ptr->row_buf;
      return;
   }
B
bae 已提交
323 324

#ifdef PNG_READ_gAMA_SUPPORTED
A
azvegint 已提交
325
   else if (png_ptr->chunk_name == png_gAMA)
D
duke 已提交
326
   {
A
azvegint 已提交
327
      PNG_PUSH_SAVE_BUFFER_IF_FULL
D
duke 已提交
328 329
      png_handle_gAMA(png_ptr, info_ptr, png_ptr->push_length);
   }
B
bae 已提交
330

D
duke 已提交
331
#endif
B
bae 已提交
332
#ifdef PNG_READ_sBIT_SUPPORTED
A
azvegint 已提交
333
   else if (png_ptr->chunk_name == png_sBIT)
D
duke 已提交
334
   {
A
azvegint 已提交
335
      PNG_PUSH_SAVE_BUFFER_IF_FULL
D
duke 已提交
336 337
      png_handle_sBIT(png_ptr, info_ptr, png_ptr->push_length);
   }
B
bae 已提交
338

D
duke 已提交
339
#endif
B
bae 已提交
340
#ifdef PNG_READ_cHRM_SUPPORTED
A
azvegint 已提交
341
   else if (png_ptr->chunk_name == png_cHRM)
D
duke 已提交
342
   {
A
azvegint 已提交
343
      PNG_PUSH_SAVE_BUFFER_IF_FULL
D
duke 已提交
344 345
      png_handle_cHRM(png_ptr, info_ptr, png_ptr->push_length);
   }
B
bae 已提交
346

D
duke 已提交
347
#endif
B
bae 已提交
348
#ifdef PNG_READ_sRGB_SUPPORTED
A
azvegint 已提交
349
   else if (chunk_name == png_sRGB)
D
duke 已提交
350
   {
A
azvegint 已提交
351
      PNG_PUSH_SAVE_BUFFER_IF_FULL
D
duke 已提交
352 353
      png_handle_sRGB(png_ptr, info_ptr, png_ptr->push_length);
   }
B
bae 已提交
354

D
duke 已提交
355
#endif
B
bae 已提交
356
#ifdef PNG_READ_iCCP_SUPPORTED
A
azvegint 已提交
357
   else if (png_ptr->chunk_name == png_iCCP)
D
duke 已提交
358
   {
A
azvegint 已提交
359
      PNG_PUSH_SAVE_BUFFER_IF_FULL
D
duke 已提交
360 361
      png_handle_iCCP(png_ptr, info_ptr, png_ptr->push_length);
   }
B
bae 已提交
362

D
duke 已提交
363
#endif
B
bae 已提交
364
#ifdef PNG_READ_sPLT_SUPPORTED
A
azvegint 已提交
365
   else if (chunk_name == png_sPLT)
D
duke 已提交
366
   {
A
azvegint 已提交
367
      PNG_PUSH_SAVE_BUFFER_IF_FULL
D
duke 已提交
368 369
      png_handle_sPLT(png_ptr, info_ptr, png_ptr->push_length);
   }
B
bae 已提交
370

D
duke 已提交
371
#endif
B
bae 已提交
372
#ifdef PNG_READ_tRNS_SUPPORTED
A
azvegint 已提交
373
   else if (chunk_name == png_tRNS)
D
duke 已提交
374
   {
A
azvegint 已提交
375
      PNG_PUSH_SAVE_BUFFER_IF_FULL
D
duke 已提交
376 377
      png_handle_tRNS(png_ptr, info_ptr, png_ptr->push_length);
   }
B
bae 已提交
378

D
duke 已提交
379
#endif
B
bae 已提交
380
#ifdef PNG_READ_bKGD_SUPPORTED
A
azvegint 已提交
381
   else if (chunk_name == png_bKGD)
D
duke 已提交
382
   {
A
azvegint 已提交
383
      PNG_PUSH_SAVE_BUFFER_IF_FULL
D
duke 已提交
384 385
      png_handle_bKGD(png_ptr, info_ptr, png_ptr->push_length);
   }
B
bae 已提交
386

D
duke 已提交
387
#endif
B
bae 已提交
388
#ifdef PNG_READ_hIST_SUPPORTED
A
azvegint 已提交
389
   else if (chunk_name == png_hIST)
D
duke 已提交
390
   {
A
azvegint 已提交
391
      PNG_PUSH_SAVE_BUFFER_IF_FULL
D
duke 已提交
392 393
      png_handle_hIST(png_ptr, info_ptr, png_ptr->push_length);
   }
B
bae 已提交
394

D
duke 已提交
395
#endif
B
bae 已提交
396
#ifdef PNG_READ_pHYs_SUPPORTED
A
azvegint 已提交
397
   else if (chunk_name == png_pHYs)
D
duke 已提交
398
   {
A
azvegint 已提交
399
      PNG_PUSH_SAVE_BUFFER_IF_FULL
D
duke 已提交
400 401
      png_handle_pHYs(png_ptr, info_ptr, png_ptr->push_length);
   }
B
bae 已提交
402

D
duke 已提交
403
#endif
B
bae 已提交
404
#ifdef PNG_READ_oFFs_SUPPORTED
A
azvegint 已提交
405
   else if (chunk_name == png_oFFs)
D
duke 已提交
406
   {
A
azvegint 已提交
407
      PNG_PUSH_SAVE_BUFFER_IF_FULL
D
duke 已提交
408 409 410
      png_handle_oFFs(png_ptr, info_ptr, png_ptr->push_length);
   }
#endif
B
bae 已提交
411 412

#ifdef PNG_READ_pCAL_SUPPORTED
A
azvegint 已提交
413
   else if (chunk_name == png_pCAL)
D
duke 已提交
414
   {
A
azvegint 已提交
415
      PNG_PUSH_SAVE_BUFFER_IF_FULL
D
duke 已提交
416 417
      png_handle_pCAL(png_ptr, info_ptr, png_ptr->push_length);
   }
B
bae 已提交
418

D
duke 已提交
419
#endif
B
bae 已提交
420
#ifdef PNG_READ_sCAL_SUPPORTED
A
azvegint 已提交
421
   else if (chunk_name == png_sCAL)
D
duke 已提交
422
   {
A
azvegint 已提交
423
      PNG_PUSH_SAVE_BUFFER_IF_FULL
D
duke 已提交
424 425
      png_handle_sCAL(png_ptr, info_ptr, png_ptr->push_length);
   }
B
bae 已提交
426

D
duke 已提交
427
#endif
B
bae 已提交
428
#ifdef PNG_READ_tIME_SUPPORTED
A
azvegint 已提交
429
   else if (chunk_name == png_tIME)
D
duke 已提交
430
   {
A
azvegint 已提交
431
      PNG_PUSH_SAVE_BUFFER_IF_FULL
D
duke 已提交
432 433
      png_handle_tIME(png_ptr, info_ptr, png_ptr->push_length);
   }
B
bae 已提交
434

D
duke 已提交
435
#endif
B
bae 已提交
436
#ifdef PNG_READ_tEXt_SUPPORTED
A
azvegint 已提交
437
   else if (chunk_name == png_tEXt)
D
duke 已提交
438
   {
A
azvegint 已提交
439 440
      PNG_PUSH_SAVE_BUFFER_IF_FULL
      png_handle_tEXt(png_ptr, info_ptr, png_ptr->push_length);
D
duke 已提交
441
   }
B
bae 已提交
442

D
duke 已提交
443
#endif
B
bae 已提交
444
#ifdef PNG_READ_zTXt_SUPPORTED
A
azvegint 已提交
445
   else if (chunk_name == png_zTXt)
D
duke 已提交
446
   {
A
azvegint 已提交
447 448
      PNG_PUSH_SAVE_BUFFER_IF_FULL
      png_handle_zTXt(png_ptr, info_ptr, png_ptr->push_length);
D
duke 已提交
449
   }
B
bae 已提交
450

D
duke 已提交
451
#endif
B
bae 已提交
452
#ifdef PNG_READ_iTXt_SUPPORTED
A
azvegint 已提交
453
   else if (chunk_name == png_iTXt)
D
duke 已提交
454
   {
A
azvegint 已提交
455 456
      PNG_PUSH_SAVE_BUFFER_IF_FULL
      png_handle_iTXt(png_ptr, info_ptr, png_ptr->push_length);
D
duke 已提交
457 458
   }
#endif
A
azvegint 已提交
459

D
duke 已提交
460 461
   else
   {
A
azvegint 已提交
462 463 464
      PNG_PUSH_SAVE_BUFFER_IF_FULL
      png_handle_unknown(png_ptr, info_ptr, png_ptr->push_length,
         PNG_HANDLE_CHUNK_AS_DEFAULT);
D
duke 已提交
465 466 467 468 469 470
   }

   png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
}

void /* PRIVATE */
A
azvegint 已提交
471
png_push_crc_skip(png_structrp png_ptr, png_uint_32 skip)
D
duke 已提交
472 473 474 475 476 477
{
   png_ptr->process_mode = PNG_SKIP_MODE;
   png_ptr->skip_length = skip;
}

void /* PRIVATE */
A
azvegint 已提交
478
png_push_crc_finish(png_structrp png_ptr)
D
duke 已提交
479
{
A
azvegint 已提交
480
   if (png_ptr->skip_length != 0 && png_ptr->save_buffer_size != 0)
D
duke 已提交
481
   {
B
bae 已提交
482 483 484 485 486 487 488 489 490 491 492
      png_size_t save_size = png_ptr->save_buffer_size;
      png_uint_32 skip_length = png_ptr->skip_length;

      /* We want the smaller of 'skip_length' and 'save_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;
D
duke 已提交
493 494

      else
B
bae 已提交
495
         skip_length = (png_uint_32)save_size;
D
duke 已提交
496 497 498

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

B
bae 已提交
499
      png_ptr->skip_length -= skip_length;
D
duke 已提交
500 501 502 503
      png_ptr->buffer_size -= save_size;
      png_ptr->save_buffer_size -= save_size;
      png_ptr->save_buffer_ptr += save_size;
   }
A
azvegint 已提交
504
   if (png_ptr->skip_length != 0 && png_ptr->current_buffer_size != 0)
D
duke 已提交
505
   {
B
bae 已提交
506 507 508 509 510 511 512 513
      png_size_t save_size = png_ptr->current_buffer_size;
      png_uint_32 skip_length = png_ptr->skip_length;

      /* We want the smaller of 'skip_length' and 'current_buffer_size', here,
       * the same problem exists as above and the same solution.
       */
      if (skip_length < save_size)
         save_size = (png_size_t)skip_length;
D
duke 已提交
514 515

      else
B
bae 已提交
516
         skip_length = (png_uint_32)save_size;
D
duke 已提交
517 518 519

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

B
bae 已提交
520
      png_ptr->skip_length -= skip_length;
D
duke 已提交
521 522 523 524
      png_ptr->buffer_size -= save_size;
      png_ptr->current_buffer_size -= save_size;
      png_ptr->current_buffer_ptr += save_size;
   }
A
azvegint 已提交
525
   if (png_ptr->skip_length == 0)
D
duke 已提交
526
   {
A
azvegint 已提交
527
      PNG_PUSH_SAVE_BUFFER_IF_LT(4)
D
duke 已提交
528 529 530 531 532
      png_crc_finish(png_ptr, 0);
      png_ptr->process_mode = PNG_READ_CHUNK_MODE;
   }
}

B
bae 已提交
533
void PNGCBAPI
D
duke 已提交
534 535 536 537
png_push_fill_buffer(png_structp png_ptr, png_bytep buffer, png_size_t length)
{
   png_bytep ptr;

B
bae 已提交
538 539 540
   if (png_ptr == NULL)
      return;

D
duke 已提交
541
   ptr = buffer;
A
azvegint 已提交
542
   if (png_ptr->save_buffer_size != 0)
D
duke 已提交
543 544 545 546 547
   {
      png_size_t save_size;

      if (length < png_ptr->save_buffer_size)
         save_size = length;
B
bae 已提交
548

D
duke 已提交
549 550 551
      else
         save_size = png_ptr->save_buffer_size;

A
azvegint 已提交
552
      memcpy(ptr, png_ptr->save_buffer_ptr, save_size);
D
duke 已提交
553 554 555 556 557 558
      length -= save_size;
      ptr += save_size;
      png_ptr->buffer_size -= save_size;
      png_ptr->save_buffer_size -= save_size;
      png_ptr->save_buffer_ptr += save_size;
   }
A
azvegint 已提交
559
   if (length != 0 && png_ptr->current_buffer_size != 0)
D
duke 已提交
560 561 562 563 564
   {
      png_size_t save_size;

      if (length < png_ptr->current_buffer_size)
         save_size = length;
B
bae 已提交
565

D
duke 已提交
566 567 568
      else
         save_size = png_ptr->current_buffer_size;

A
azvegint 已提交
569
      memcpy(ptr, png_ptr->current_buffer_ptr, save_size);
D
duke 已提交
570 571 572 573 574 575 576
      png_ptr->buffer_size -= save_size;
      png_ptr->current_buffer_size -= save_size;
      png_ptr->current_buffer_ptr += save_size;
   }
}

void /* PRIVATE */
A
azvegint 已提交
577
png_push_save_buffer(png_structrp png_ptr)
D
duke 已提交
578
{
A
azvegint 已提交
579
   if (png_ptr->save_buffer_size != 0)
D
duke 已提交
580 581 582
   {
      if (png_ptr->save_buffer_ptr != png_ptr->save_buffer)
      {
B
bae 已提交
583
         png_size_t i, istop;
D
duke 已提交
584 585 586 587 588
         png_bytep sp;
         png_bytep dp;

         istop = png_ptr->save_buffer_size;
         for (i = 0, sp = png_ptr->save_buffer_ptr, dp = png_ptr->save_buffer;
B
bae 已提交
589
             i < istop; i++, sp++, dp++)
D
duke 已提交
590 591 592 593 594 595
         {
            *dp = *sp;
         }
      }
   }
   if (png_ptr->save_buffer_size + png_ptr->current_buffer_size >
B
bae 已提交
596
       png_ptr->save_buffer_max)
D
duke 已提交
597 598 599 600 601
   {
      png_size_t new_max;
      png_bytep old_buffer;

      if (png_ptr->save_buffer_size > PNG_SIZE_MAX -
B
bae 已提交
602
          (png_ptr->current_buffer_size + 256))
D
duke 已提交
603
      {
B
bae 已提交
604
         png_error(png_ptr, "Potential overflow of save_buffer");
D
duke 已提交
605
      }
B
bae 已提交
606

D
duke 已提交
607 608
      new_max = png_ptr->save_buffer_size + png_ptr->current_buffer_size + 256;
      old_buffer = png_ptr->save_buffer;
B
bae 已提交
609 610 611 612 613 614
      png_ptr->save_buffer = (png_bytep)png_malloc_warn(png_ptr,
          (png_size_t)new_max);

      if (png_ptr->save_buffer == NULL)
      {
         png_free(png_ptr, old_buffer);
A
azvegint 已提交
615
         old_buffer = NULL;
B
bae 已提交
616 617 618
         png_error(png_ptr, "Insufficient memory for save_buffer");
      }

A
azvegint 已提交
619
      memcpy(png_ptr->save_buffer, old_buffer, png_ptr->save_buffer_size);
D
duke 已提交
620
      png_free(png_ptr, old_buffer);
A
azvegint 已提交
621
      old_buffer = NULL;
D
duke 已提交
622 623 624 625
      png_ptr->save_buffer_max = new_max;
   }
   if (png_ptr->current_buffer_size)
   {
A
azvegint 已提交
626
      memcpy(png_ptr->save_buffer + png_ptr->save_buffer_size,
D
duke 已提交
627 628 629 630 631 632 633 634 635
         png_ptr->current_buffer_ptr, png_ptr->current_buffer_size);
      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;
}

void /* PRIVATE */
A
azvegint 已提交
636
png_push_restore_buffer(png_structrp png_ptr, png_bytep buffer,
D
duke 已提交
637 638 639 640 641 642 643 644 645
   png_size_t buffer_length)
{
   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;
}

void /* PRIVATE */
A
azvegint 已提交
646
png_push_read_IDAT(png_structrp png_ptr)
D
duke 已提交
647
{
A
azvegint 已提交
648
   if ((png_ptr->mode & PNG_HAVE_CHUNK_HEADER) == 0)
D
duke 已提交
649 650
   {
      png_byte chunk_length[4];
A
azvegint 已提交
651
      png_byte chunk_tag[4];
D
duke 已提交
652

A
azvegint 已提交
653 654
      /* TODO: this code can be commoned up with the same code in push_read */
      PNG_PUSH_SAVE_BUFFER_IF_LT(8)
D
duke 已提交
655
      png_push_fill_buffer(png_ptr, chunk_length, 4);
B
bae 已提交
656
      png_ptr->push_length = png_get_uint_31(png_ptr, chunk_length);
D
duke 已提交
657
      png_reset_crc(png_ptr);
A
azvegint 已提交
658 659
      png_crc_read(png_ptr, chunk_tag, 4);
      png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(chunk_tag);
D
duke 已提交
660 661
      png_ptr->mode |= PNG_HAVE_CHUNK_HEADER;

A
azvegint 已提交
662
      if (png_ptr->chunk_name != png_IDAT)
D
duke 已提交
663 664
      {
         png_ptr->process_mode = PNG_READ_CHUNK_MODE;
B
bae 已提交
665

A
azvegint 已提交
666
         if ((png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED) == 0)
D
duke 已提交
667
            png_error(png_ptr, "Not enough compressed data");
B
bae 已提交
668

D
duke 已提交
669 670 671 672 673
         return;
      }

      png_ptr->idat_size = png_ptr->push_length;
   }
A
azvegint 已提交
674 675

   if (png_ptr->idat_size != 0 && png_ptr->save_buffer_size != 0)
D
duke 已提交
676
   {
B
bae 已提交
677 678 679 680 681 682 683 684 685 686 687
      png_size_t save_size = png_ptr->save_buffer_size;
      png_uint_32 idat_size = png_ptr->idat_size;

      /* 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;
D
duke 已提交
688 689

      else
B
bae 已提交
690
         idat_size = (png_uint_32)save_size;
D
duke 已提交
691 692

      png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size);
B
bae 已提交
693 694 695 696

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

      png_ptr->idat_size -= idat_size;
D
duke 已提交
697 698 699 700
      png_ptr->buffer_size -= save_size;
      png_ptr->save_buffer_size -= save_size;
      png_ptr->save_buffer_ptr += save_size;
   }
B
bae 已提交
701

A
azvegint 已提交
702
   if (png_ptr->idat_size != 0 && png_ptr->current_buffer_size != 0)
D
duke 已提交
703
   {
B
bae 已提交
704 705 706 707 708 709 710 711 712 713
      png_size_t save_size = png_ptr->current_buffer_size;
      png_uint_32 idat_size = png_ptr->idat_size;

      /* 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;
D
duke 已提交
714 715

      else
B
bae 已提交
716
         idat_size = (png_uint_32)save_size;
D
duke 已提交
717 718 719

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

B
bae 已提交
720 721 722
      png_process_IDAT_data(png_ptr, png_ptr->current_buffer_ptr, save_size);

      png_ptr->idat_size -= idat_size;
D
duke 已提交
723 724 725 726
      png_ptr->buffer_size -= save_size;
      png_ptr->current_buffer_size -= save_size;
      png_ptr->current_buffer_ptr += save_size;
   }
A
azvegint 已提交
727
   if (png_ptr->idat_size == 0)
D
duke 已提交
728
   {
A
azvegint 已提交
729
      PNG_PUSH_SAVE_BUFFER_IF_LT(4)
D
duke 已提交
730 731 732
      png_crc_finish(png_ptr, 0);
      png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
      png_ptr->mode |= PNG_AFTER_IDAT;
A
azvegint 已提交
733
      png_ptr->zowner = 0;
D
duke 已提交
734 735 736 737
   }
}

void /* PRIVATE */
A
azvegint 已提交
738
png_process_IDAT_data(png_structrp png_ptr, png_bytep buffer,
D
duke 已提交
739 740
   png_size_t buffer_length)
{
B
bae 已提交
741 742 743
   /* The caller checks for a non-zero buffer length. */
   if (!(buffer_length > 0) || buffer == NULL)
      png_error(png_ptr, "No IDAT data (internal error)");
D
duke 已提交
744

B
bae 已提交
745 746 747 748
   /* This routine must process all the data it has been given
    * before returning, calling the row callback as required to
    * handle the uncompressed results.
    */
D
duke 已提交
749
   png_ptr->zstream.next_in = buffer;
A
azvegint 已提交
750
   /* TODO: WARNING: TRUNCATION ERROR: DANGER WILL ROBINSON: */
D
duke 已提交
751
   png_ptr->zstream.avail_in = (uInt)buffer_length;
B
bae 已提交
752 753 754 755 756

   /* Keep going until the decompressed data is all processed
    * or the stream marked as finished.
    */
   while (png_ptr->zstream.avail_in > 0 &&
A
azvegint 已提交
757
      !(png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED))
D
duke 已提交
758
   {
B
bae 已提交
759 760 761 762 763 764 765 766
      int ret;

      /* We have data for zlib, but we must check that zlib
       * has someplace to put the results.  It doesn't matter
       * if we don't expect any results -- it may be the input
       * data is just the LZ end code.
       */
      if (!(png_ptr->zstream.avail_out > 0))
D
duke 已提交
767
      {
A
azvegint 已提交
768 769 770
         /* TODO: WARNING: TRUNCATION ERROR: DANGER WILL ROBINSON: */
         png_ptr->zstream.avail_out = (uInt)(PNG_ROWBYTES(png_ptr->pixel_depth,
             png_ptr->iwidth) + 1);
B
bae 已提交
771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787

         png_ptr->zstream.next_out = png_ptr->row_buf;
      }

      /* Using Z_SYNC_FLUSH here means that an unterminated
       * 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).
       */
      ret = inflate(&png_ptr->zstream, Z_SYNC_FLUSH);

      /* Check for any failure before proceeding. */
      if (ret != Z_OK && ret != Z_STREAM_END)
      {
         /* Terminate the decompression. */
A
azvegint 已提交
788 789
         png_ptr->flags |= PNG_FLAG_ZSTREAM_ENDED;
         png_ptr->zowner = 0;
B
bae 已提交
790 791 792 793 794 795 796

         /* This may be a truncated stream (missing or
          * damaged end code).  Treat that as a warning.
          */
         if (png_ptr->row_number >= png_ptr->num_rows ||
             png_ptr->pass > 6)
            png_warning(png_ptr, "Truncated compressed data in IDAT");
D
duke 已提交
797 798

         else
B
bae 已提交
799 800 801 802
            png_error(png_ptr, "Decompression error in IDAT");

         /* Skip the check on unprocessed input */
         return;
D
duke 已提交
803
      }
B
bae 已提交
804 805 806

      /* Did inflate output any data? */
      if (png_ptr->zstream.next_out != png_ptr->row_buf)
D
duke 已提交
807
      {
B
bae 已提交
808 809 810 811 812 813
         /* Is this unexpected data after the last row?
          * If it is, artificially terminate the LZ output
          * here.
          */
         if (png_ptr->row_number >= png_ptr->num_rows ||
             png_ptr->pass > 6)
D
duke 已提交
814
         {
B
bae 已提交
815 816
            /* Extra data. */
            png_warning(png_ptr, "Extra compressed data in IDAT");
A
azvegint 已提交
817 818
            png_ptr->flags |= PNG_FLAG_ZSTREAM_ENDED;
            png_ptr->zowner = 0;
B
bae 已提交
819 820 821 822 823

            /* Do no more processing; skip the unprocessed
             * input check below.
             */
            return;
D
duke 已提交
824
         }
B
bae 已提交
825 826 827 828

         /* Do we have a complete row? */
         if (png_ptr->zstream.avail_out == 0)
            png_push_process_row(png_ptr);
D
duke 已提交
829
      }
B
bae 已提交
830 831 832

      /* And check for the end of the stream. */
      if (ret == Z_STREAM_END)
A
azvegint 已提交
833
         png_ptr->flags |= PNG_FLAG_ZSTREAM_ENDED;
D
duke 已提交
834
   }
B
bae 已提交
835 836 837 838 839 840 841

   /* 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)
      png_warning(png_ptr, "Extra compression data in IDAT");
D
duke 已提交
842 843 844
}

void /* PRIVATE */
A
azvegint 已提交
845
png_push_process_row(png_structrp png_ptr)
D
duke 已提交
846
{
A
azvegint 已提交
847 848
   /* 1.5.6: row_info moved out of png_struct to a local here. */
   png_row_info row_info;
D
duke 已提交
849

A
azvegint 已提交
850 851 852 853 854 855
   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);
D
duke 已提交
856

A
azvegint 已提交
857 858 859 860 861 862 863 864
   if (png_ptr->row_buf[0] > PNG_FILTER_VALUE_NONE)
   {
      if (png_ptr->row_buf[0] < PNG_FILTER_VALUE_LAST)
         png_read_filter_row(png_ptr, &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");
   }
D
duke 已提交
865

A
azvegint 已提交
866 867 868 869 870 871
   /* 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:
    */
   memcpy(png_ptr->prev_row, png_ptr->row_buf, row_info.rowbytes + 1);
D
duke 已提交
872

B
bae 已提交
873
#ifdef PNG_READ_TRANSFORMS_SUPPORTED
A
azvegint 已提交
874 875
   if (png_ptr->transformations != 0)
      png_do_read_transformations(png_ptr, &row_info);
B
bae 已提交
876
#endif
D
duke 已提交
877

A
azvegint 已提交
878 879 880 881 882 883 884 885 886 887 888 889
   /* 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");


B
bae 已提交
890
#ifdef PNG_READ_INTERLACING_SUPPORTED
A
azvegint 已提交
891 892 893
   /* Expand interlaced rows to full size */
   if (png_ptr->interlaced != 0 &&
       (png_ptr->transformations & PNG_INTERLACE) != 0)
D
duke 已提交
894 895
   {
      if (png_ptr->pass < 6)
A
azvegint 已提交
896 897
         png_do_read_interlace(&row_info, png_ptr->row_buf + 1, png_ptr->pass,
            png_ptr->transformations);
D
duke 已提交
898

A
azvegint 已提交
899 900
      switch (png_ptr->pass)
      {
D
duke 已提交
901 902 903 904 905 906
         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);
B
bae 已提交
907
               png_read_push_finish_row(png_ptr); /* Updates png_ptr->pass */
D
duke 已提交
908
            }
B
bae 已提交
909 910

            if (png_ptr->pass == 2) /* Pass 1 might be empty */
D
duke 已提交
911 912 913
            {
               for (i = 0; i < 4 && png_ptr->pass == 2; i++)
               {
B
bae 已提交
914
                  png_push_have_row(png_ptr, NULL);
D
duke 已提交
915 916 917
                  png_read_push_finish_row(png_ptr);
               }
            }
B
bae 已提交
918

D
duke 已提交
919 920 921 922
            if (png_ptr->pass == 4 && png_ptr->height <= 4)
            {
               for (i = 0; i < 2 && png_ptr->pass == 4; i++)
               {
B
bae 已提交
923
                  png_push_have_row(png_ptr, NULL);
D
duke 已提交
924 925 926
                  png_read_push_finish_row(png_ptr);
               }
            }
B
bae 已提交
927

D
duke 已提交
928 929
            if (png_ptr->pass == 6 && png_ptr->height <= 4)
            {
B
bae 已提交
930
                png_push_have_row(png_ptr, NULL);
D
duke 已提交
931 932
                png_read_push_finish_row(png_ptr);
            }
B
bae 已提交
933

D
duke 已提交
934 935
            break;
         }
B
bae 已提交
936

D
duke 已提交
937 938 939 940 941 942 943 944
         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);
            }
B
bae 已提交
945 946

            if (png_ptr->pass == 2) /* Skip top 4 generated rows */
D
duke 已提交
947 948 949
            {
               for (i = 0; i < 4 && png_ptr->pass == 2; i++)
               {
B
bae 已提交
950
                  png_push_have_row(png_ptr, NULL);
D
duke 已提交
951 952 953
                  png_read_push_finish_row(png_ptr);
               }
            }
B
bae 已提交
954

D
duke 已提交
955 956
            break;
         }
B
bae 已提交
957

D
duke 已提交
958 959 960
         case 2:
         {
            int i;
B
bae 已提交
961

D
duke 已提交
962 963 964 965 966
            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);
            }
B
bae 已提交
967

D
duke 已提交
968 969
            for (i = 0; i < 4 && png_ptr->pass == 2; i++)
            {
B
bae 已提交
970
               png_push_have_row(png_ptr, NULL);
D
duke 已提交
971 972
               png_read_push_finish_row(png_ptr);
            }
B
bae 已提交
973 974

            if (png_ptr->pass == 4) /* Pass 3 might be empty */
D
duke 已提交
975 976 977
            {
               for (i = 0; i < 2 && png_ptr->pass == 4; i++)
               {
B
bae 已提交
978
                  png_push_have_row(png_ptr, NULL);
D
duke 已提交
979 980 981
                  png_read_push_finish_row(png_ptr);
               }
            }
B
bae 已提交
982

D
duke 已提交
983 984
            break;
         }
B
bae 已提交
985

D
duke 已提交
986 987 988
         case 3:
         {
            int i;
B
bae 已提交
989

D
duke 已提交
990 991 992 993 994
            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);
            }
B
bae 已提交
995 996

            if (png_ptr->pass == 4) /* Skip top two generated rows */
D
duke 已提交
997 998 999
            {
               for (i = 0; i < 2 && png_ptr->pass == 4; i++)
               {
B
bae 已提交
1000
                  png_push_have_row(png_ptr, NULL);
D
duke 已提交
1001 1002 1003
                  png_read_push_finish_row(png_ptr);
               }
            }
B
bae 已提交
1004

D
duke 已提交
1005 1006
            break;
         }
B
bae 已提交
1007

D
duke 已提交
1008 1009 1010
         case 4:
         {
            int i;
B
bae 已提交
1011

D
duke 已提交
1012 1013 1014 1015 1016
            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);
            }
B
bae 已提交
1017

D
duke 已提交
1018 1019
            for (i = 0; i < 2 && png_ptr->pass == 4; i++)
            {
B
bae 已提交
1020
               png_push_have_row(png_ptr, NULL);
D
duke 已提交
1021 1022
               png_read_push_finish_row(png_ptr);
            }
B
bae 已提交
1023 1024

            if (png_ptr->pass == 6) /* Pass 5 might be empty */
D
duke 已提交
1025
            {
B
bae 已提交
1026
               png_push_have_row(png_ptr, NULL);
D
duke 已提交
1027 1028
               png_read_push_finish_row(png_ptr);
            }
B
bae 已提交
1029

D
duke 已提交
1030 1031
            break;
         }
B
bae 已提交
1032

D
duke 已提交
1033 1034 1035
         case 5:
         {
            int i;
B
bae 已提交
1036

D
duke 已提交
1037 1038 1039 1040 1041
            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);
            }
B
bae 已提交
1042 1043

            if (png_ptr->pass == 6) /* Skip top generated row */
D
duke 已提交
1044
            {
B
bae 已提交
1045
               png_push_have_row(png_ptr, NULL);
D
duke 已提交
1046 1047
               png_read_push_finish_row(png_ptr);
            }
B
bae 已提交
1048

D
duke 已提交
1049 1050
            break;
         }
B
bae 已提交
1051 1052

         default:
D
duke 已提交
1053 1054 1055 1056
         case 6:
         {
            png_push_have_row(png_ptr, png_ptr->row_buf + 1);
            png_read_push_finish_row(png_ptr);
B
bae 已提交
1057

D
duke 已提交
1058 1059
            if (png_ptr->pass != 6)
               break;
B
bae 已提交
1060 1061

            png_push_have_row(png_ptr, NULL);
D
duke 已提交
1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073
            png_read_push_finish_row(png_ptr);
         }
      }
   }
   else
   {
      png_push_have_row(png_ptr, png_ptr->row_buf + 1);
      png_read_push_finish_row(png_ptr);
   }
}

void /* PRIVATE */
A
azvegint 已提交
1074
png_read_push_finish_row(png_structrp png_ptr)
D
duke 已提交
1075
{
B
bae 已提交
1076
   /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
D
duke 已提交
1077

B
bae 已提交
1078
   /* Start of interlace block */
A
azvegint 已提交
1079
   static PNG_CONST png_byte png_pass_start[] = {0, 4, 0, 2, 0, 1, 0};
D
duke 已提交
1080

B
bae 已提交
1081
   /* Offset to next interlace block */
A
azvegint 已提交
1082
   static PNG_CONST png_byte png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1};
D
duke 已提交
1083

B
bae 已提交
1084
   /* Start of interlace block in the y direction */
A
azvegint 已提交
1085
   static PNG_CONST png_byte png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1};
D
duke 已提交
1086

B
bae 已提交
1087
   /* Offset to next interlace block in the y direction */
A
azvegint 已提交
1088
   static PNG_CONST png_byte png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2};
D
duke 已提交
1089 1090 1091

   /* Height of interlace block.  This is not currently used - if you need
    * it, uncomment it here and in png.h
A
azvegint 已提交
1092
   static PNG_CONST png_byte png_pass_height[] = {8, 8, 4, 4, 2, 2, 1};
D
duke 已提交
1093
   */
A
azvegint 已提交
1094
#endif
D
duke 已提交
1095 1096 1097 1098 1099

   png_ptr->row_number++;
   if (png_ptr->row_number < png_ptr->num_rows)
      return;

A
azvegint 已提交
1100
   if (png_ptr->interlaced != 0)
D
duke 已提交
1101 1102
   {
      png_ptr->row_number = 0;
A
azvegint 已提交
1103
      memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1);
B
bae 已提交
1104

D
duke 已提交
1105 1106 1107 1108 1109 1110
      do
      {
         png_ptr->pass++;
         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))
B
bae 已提交
1111
            png_ptr->pass++;
D
duke 已提交
1112 1113 1114

         if (png_ptr->pass > 7)
            png_ptr->pass--;
B
bae 已提交
1115

D
duke 已提交
1116 1117 1118 1119
         if (png_ptr->pass >= 7)
            break;

         png_ptr->iwidth = (png_ptr->width +
B
bae 已提交
1120 1121 1122
             png_pass_inc[png_ptr->pass] - 1 -
             png_pass_start[png_ptr->pass]) /
             png_pass_inc[png_ptr->pass];
D
duke 已提交
1123

A
azvegint 已提交
1124
         if ((png_ptr->transformations & PNG_INTERLACE) != 0)
D
duke 已提交
1125 1126 1127
            break;

         png_ptr->num_rows = (png_ptr->height +
B
bae 已提交
1128 1129 1130
             png_pass_yinc[png_ptr->pass] - 1 -
             png_pass_ystart[png_ptr->pass]) /
             png_pass_yinc[png_ptr->pass];
D
duke 已提交
1131 1132 1133 1134 1135 1136

      } while (png_ptr->iwidth == 0 || png_ptr->num_rows == 0);
   }
}

void /* PRIVATE */
A
azvegint 已提交
1137
png_push_have_info(png_structrp png_ptr, png_inforp info_ptr)
D
duke 已提交
1138 1139 1140 1141 1142 1143
{
   if (png_ptr->info_fn != NULL)
      (*(png_ptr->info_fn))(png_ptr, info_ptr);
}

void /* PRIVATE */
A
azvegint 已提交
1144
png_push_have_end(png_structrp png_ptr, png_inforp info_ptr)
D
duke 已提交
1145 1146 1147 1148 1149 1150
{
   if (png_ptr->end_fn != NULL)
      (*(png_ptr->end_fn))(png_ptr, info_ptr);
}

void /* PRIVATE */
A
azvegint 已提交
1151
png_push_have_row(png_structrp png_ptr, png_bytep row)
D
duke 已提交
1152 1153 1154 1155 1156 1157 1158
{
   if (png_ptr->row_fn != NULL)
      (*(png_ptr->row_fn))(png_ptr, row, png_ptr->row_number,
         (int)png_ptr->pass);
}

void PNGAPI
A
azvegint 已提交
1159
png_progressive_combine_row(png_const_structrp png_ptr, png_bytep old_row,
B
bae 已提交
1160
    png_const_bytep new_row)
D
duke 已提交
1161
{
B
bae 已提交
1162 1163 1164
   if (png_ptr == NULL)
      return;

A
azvegint 已提交
1165 1166 1167 1168 1169 1170
   /* 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/*blocky display*/);
D
duke 已提交
1171 1172 1173
}

void PNGAPI
A
azvegint 已提交
1174
png_set_progressive_read_fn(png_structrp png_ptr, png_voidp progressive_ptr,
B
bae 已提交
1175 1176
    png_progressive_info_ptr info_fn, png_progressive_row_ptr row_fn,
    png_progressive_end_ptr end_fn)
D
duke 已提交
1177
{
B
bae 已提交
1178 1179 1180
   if (png_ptr == NULL)
      return;

D
duke 已提交
1181 1182 1183 1184 1185 1186 1187 1188
   png_ptr->info_fn = info_fn;
   png_ptr->row_fn = row_fn;
   png_ptr->end_fn = end_fn;

   png_set_read_fn(png_ptr, progressive_ptr, png_push_fill_buffer);
}

png_voidp PNGAPI
A
azvegint 已提交
1189
png_get_progressive_ptr(png_const_structrp png_ptr)
D
duke 已提交
1190
{
B
bae 已提交
1191 1192 1193
   if (png_ptr == NULL)
      return (NULL);

D
duke 已提交
1194 1195
   return png_ptr->io_ptr;
}
A
azvegint 已提交
1196
#endif /* PROGRESSIVE_READ */