galeb

Једноставна статичка дистрибуција заснована на musl-у
git clone https://git.sr.ht/~strahinja/galeb
Дневник | Датотеке | Референце | ПРОЧИТАЈМЕ | ЛИЦЕНЦА

apng.patch (56710B)


      1 diff -Naru libpng-1.6.37.org/png.h libpng-1.6.37/png.h
      2 --- libpng-1.6.37.org/png.h	2019-04-19 07:21:37.398024800 +0900
      3 +++ libpng-1.6.37/png.h	2019-04-19 07:22:37.871245630 +0900
      4 @@ -330,6 +330,10 @@
      5  #   include "pnglibconf.h"
      6  #endif
      7  
      8 +#define PNG_APNG_SUPPORTED
      9 +#define PNG_READ_APNG_SUPPORTED
     10 +#define PNG_WRITE_APNG_SUPPORTED
     11 +
     12  #ifndef PNG_VERSION_INFO_ONLY
     13  /* Machine specific configuration. */
     14  #  include "pngconf.h"
     15 @@ -425,6 +429,17 @@
     16   * See pngconf.h for base types that vary by machine/system
     17   */
     18  
     19 +#ifdef PNG_APNG_SUPPORTED
     20 +/* dispose_op flags from inside fcTL */
     21 +#define PNG_DISPOSE_OP_NONE        0x00U
     22 +#define PNG_DISPOSE_OP_BACKGROUND  0x01U
     23 +#define PNG_DISPOSE_OP_PREVIOUS    0x02U
     24 +
     25 +/* blend_op flags from inside fcTL */
     26 +#define PNG_BLEND_OP_SOURCE        0x00U
     27 +#define PNG_BLEND_OP_OVER          0x01U
     28 +#endif /* PNG_APNG_SUPPORTED */
     29 +
     30  /* This triggers a compiler error in png.c, if png.c and png.h
     31   * do not agree upon the version number.
     32   */
     33 @@ -746,6 +761,10 @@
     34  #define PNG_INFO_sCAL 0x4000U  /* ESR, 1.0.6 */
     35  #define PNG_INFO_IDAT 0x8000U  /* ESR, 1.0.6 */
     36  #define PNG_INFO_eXIf 0x10000U /* GR-P, 1.6.31 */
     37 +#ifdef PNG_APNG_SUPPORTED
     38 +#define PNG_INFO_acTL 0x20000U
     39 +#define PNG_INFO_fcTL 0x40000U
     40 +#endif
     41  
     42  /* This is used for the transformation routines, as some of them
     43   * change these values for the row.  It also should enable using
     44 @@ -783,6 +802,10 @@
     45  #ifdef PNG_PROGRESSIVE_READ_SUPPORTED
     46  typedef PNG_CALLBACK(void, *png_progressive_info_ptr, (png_structp, png_infop));
     47  typedef PNG_CALLBACK(void, *png_progressive_end_ptr, (png_structp, png_infop));
     48 +#ifdef PNG_APNG_SUPPORTED
     49 +typedef PNG_CALLBACK(void, *png_progressive_frame_ptr, (png_structp,
     50 +    png_uint_32));
     51 +#endif
     52  
     53  /* The following callback receives png_uint_32 row_number, int pass for the
     54   * png_bytep data of the row.  When transforming an interlaced image the
     55 @@ -3226,6 +3249,74 @@
     56  /*******************************************************************************
     57   *  END OF HARDWARE AND SOFTWARE OPTIONS
     58   ******************************************************************************/
     59 +#ifdef PNG_APNG_SUPPORTED
     60 +PNG_EXPORT(250, png_uint_32, png_get_acTL, (png_structp png_ptr,
     61 +   png_infop info_ptr, png_uint_32 *num_frames, png_uint_32 *num_plays));
     62 +
     63 +PNG_EXPORT(251, png_uint_32, png_set_acTL, (png_structp png_ptr,
     64 +   png_infop info_ptr, png_uint_32 num_frames, png_uint_32 num_plays));
     65 +
     66 +PNG_EXPORT(252, png_uint_32, png_get_num_frames, (png_structp png_ptr,
     67 +   png_infop info_ptr));
     68 +
     69 +PNG_EXPORT(253, png_uint_32, png_get_num_plays, (png_structp png_ptr,
     70 +   png_infop info_ptr));
     71 +
     72 +PNG_EXPORT(254, png_uint_32, png_get_next_frame_fcTL,
     73 +   (png_structp png_ptr, png_infop info_ptr, png_uint_32 *width,
     74 +   png_uint_32 *height, png_uint_32 *x_offset, png_uint_32 *y_offset,
     75 +   png_uint_16 *delay_num, png_uint_16 *delay_den, png_byte *dispose_op,
     76 +   png_byte *blend_op));
     77 +
     78 +PNG_EXPORT(255, png_uint_32, png_set_next_frame_fcTL,
     79 +   (png_structp png_ptr, png_infop info_ptr, png_uint_32 width,
     80 +   png_uint_32 height, png_uint_32 x_offset, png_uint_32 y_offset,
     81 +   png_uint_16 delay_num, png_uint_16 delay_den, png_byte dispose_op,
     82 +   png_byte blend_op));
     83 +
     84 +PNG_EXPORT(256, png_uint_32, png_get_next_frame_width,
     85 +   (png_structp png_ptr, png_infop info_ptr));
     86 +PNG_EXPORT(257, png_uint_32, png_get_next_frame_height,
     87 +   (png_structp png_ptr, png_infop info_ptr));
     88 +PNG_EXPORT(258, png_uint_32, png_get_next_frame_x_offset,
     89 +   (png_structp png_ptr, png_infop info_ptr));
     90 +PNG_EXPORT(259, png_uint_32, png_get_next_frame_y_offset,
     91 +   (png_structp png_ptr, png_infop info_ptr));
     92 +PNG_EXPORT(260, png_uint_16, png_get_next_frame_delay_num,
     93 +   (png_structp png_ptr, png_infop info_ptr));
     94 +PNG_EXPORT(261, png_uint_16, png_get_next_frame_delay_den,
     95 +   (png_structp png_ptr, png_infop info_ptr));
     96 +PNG_EXPORT(262, png_byte, png_get_next_frame_dispose_op,
     97 +   (png_structp png_ptr, png_infop info_ptr));
     98 +PNG_EXPORT(263, png_byte, png_get_next_frame_blend_op,
     99 +   (png_structp png_ptr, png_infop info_ptr));
    100 +PNG_EXPORT(264, png_byte, png_get_first_frame_is_hidden,
    101 +   (png_structp png_ptr, png_infop info_ptr));
    102 +PNG_EXPORT(265, png_uint_32, png_set_first_frame_is_hidden,
    103 +   (png_structp png_ptr, png_infop info_ptr, png_byte is_hidden));
    104 +
    105 +#ifdef PNG_READ_APNG_SUPPORTED
    106 +PNG_EXPORT(266, void, png_read_frame_head, (png_structp png_ptr,
    107 +   png_infop info_ptr));
    108 +#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
    109 +PNG_EXPORT(267, void, png_set_progressive_frame_fn, (png_structp png_ptr,
    110 +   png_progressive_frame_ptr frame_info_fn,
    111 +   png_progressive_frame_ptr frame_end_fn));
    112 +#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */
    113 +#endif /* PNG_READ_APNG_SUPPORTED */
    114 +
    115 +#ifdef PNG_WRITE_APNG_SUPPORTED
    116 +PNG_EXPORT(268, void, png_write_frame_head, (png_structp png_ptr,
    117 +   png_infop info_ptr, png_bytepp row_pointers,
    118 +   png_uint_32 width, png_uint_32 height,
    119 +   png_uint_32 x_offset, png_uint_32 y_offset,
    120 +   png_uint_16 delay_num, png_uint_16 delay_den, png_byte dispose_op,
    121 +   png_byte blend_op));
    122 +
    123 +PNG_EXPORT(269, void, png_write_frame_tail, (png_structp png_ptr,
    124 +   png_infop info_ptr));
    125 +#endif /* PNG_WRITE_APNG_SUPPORTED */
    126 +#endif /* PNG_APNG_SUPPORTED */
    127  
    128  /* Maintainer: Put new public prototypes here ^, in libpng.3, in project
    129   * defs, and in scripts/symbols.def.
    130 @@ -3235,7 +3326,11 @@
    131   * one to use is one more than this.)
    132   */
    133  #ifdef PNG_EXPORT_LAST_ORDINAL
    134 +#ifdef PNG_APNG_SUPPORTED
    135 +  PNG_EXPORT_LAST_ORDINAL(269);
    136 +#else
    137    PNG_EXPORT_LAST_ORDINAL(249);
    138 +#endif /* PNG_APNG_SUPPORTED */
    139  #endif
    140  
    141  #ifdef __cplusplus
    142 diff -Naru libpng-1.6.37.org/pngget.c libpng-1.6.37/pngget.c
    143 --- libpng-1.6.37.org/pngget.c	2019-04-19 07:21:37.399024787 +0900
    144 +++ libpng-1.6.37/pngget.c	2019-04-19 07:22:37.850245901 +0900
    145 @@ -1246,4 +1246,166 @@
    146  #  endif
    147  #endif
    148  
    149 +#ifdef PNG_APNG_SUPPORTED
    150 +png_uint_32 PNGAPI
    151 +png_get_acTL(png_structp png_ptr, png_infop info_ptr,
    152 +             png_uint_32 *num_frames, png_uint_32 *num_plays)
    153 +{
    154 +    png_debug1(1, "in %s retrieval function", "acTL");
    155 +
    156 +    if (png_ptr != NULL && info_ptr != NULL &&
    157 +        (info_ptr->valid & PNG_INFO_acTL) &&
    158 +        num_frames != NULL && num_plays != NULL)
    159 +    {
    160 +        *num_frames = info_ptr->num_frames;
    161 +        *num_plays = info_ptr->num_plays;
    162 +        return (1);
    163 +    }
    164 +
    165 +    return (0);
    166 +}
    167 +
    168 +png_uint_32 PNGAPI
    169 +png_get_num_frames(png_structp png_ptr, png_infop info_ptr)
    170 +{
    171 +    png_debug(1, "in png_get_num_frames()");
    172 +
    173 +    if (png_ptr != NULL && info_ptr != NULL)
    174 +        return (info_ptr->num_frames);
    175 +    return (0);
    176 +}
    177 +
    178 +png_uint_32 PNGAPI
    179 +png_get_num_plays(png_structp png_ptr, png_infop info_ptr)
    180 +{
    181 +    png_debug(1, "in png_get_num_plays()");
    182 +
    183 +    if (png_ptr != NULL && info_ptr != NULL)
    184 +        return (info_ptr->num_plays);
    185 +    return (0);
    186 +}
    187 +
    188 +png_uint_32 PNGAPI
    189 +png_get_next_frame_fcTL(png_structp png_ptr, png_infop info_ptr,
    190 +             png_uint_32 *width, png_uint_32 *height,
    191 +             png_uint_32 *x_offset, png_uint_32 *y_offset,
    192 +             png_uint_16 *delay_num, png_uint_16 *delay_den,
    193 +             png_byte *dispose_op, png_byte *blend_op)
    194 +{
    195 +    png_debug1(1, "in %s retrieval function", "fcTL");
    196 +
    197 +    if (png_ptr != NULL && info_ptr != NULL &&
    198 +        (info_ptr->valid & PNG_INFO_fcTL) &&
    199 +        width != NULL && height != NULL &&
    200 +        x_offset != NULL && y_offset != NULL &&
    201 +        delay_num != NULL && delay_den != NULL &&
    202 +        dispose_op != NULL && blend_op != NULL)
    203 +    {
    204 +        *width = info_ptr->next_frame_width;
    205 +        *height = info_ptr->next_frame_height;
    206 +        *x_offset = info_ptr->next_frame_x_offset;
    207 +        *y_offset = info_ptr->next_frame_y_offset;
    208 +        *delay_num = info_ptr->next_frame_delay_num;
    209 +        *delay_den = info_ptr->next_frame_delay_den;
    210 +        *dispose_op = info_ptr->next_frame_dispose_op;
    211 +        *blend_op = info_ptr->next_frame_blend_op;
    212 +        return (1);
    213 +    }
    214 +
    215 +    return (0);
    216 +}
    217 +
    218 +png_uint_32 PNGAPI
    219 +png_get_next_frame_width(png_structp png_ptr, png_infop info_ptr)
    220 +{
    221 +    png_debug(1, "in png_get_next_frame_width()");
    222 +
    223 +    if (png_ptr != NULL && info_ptr != NULL)
    224 +        return (info_ptr->next_frame_width);
    225 +    return (0);
    226 +}
    227 +
    228 +png_uint_32 PNGAPI
    229 +png_get_next_frame_height(png_structp png_ptr, png_infop info_ptr)
    230 +{
    231 +    png_debug(1, "in png_get_next_frame_height()");
    232 +
    233 +    if (png_ptr != NULL && info_ptr != NULL)
    234 +        return (info_ptr->next_frame_height);
    235 +    return (0);
    236 +}
    237 +
    238 +png_uint_32 PNGAPI
    239 +png_get_next_frame_x_offset(png_structp png_ptr, png_infop info_ptr)
    240 +{
    241 +    png_debug(1, "in png_get_next_frame_x_offset()");
    242 +
    243 +    if (png_ptr != NULL && info_ptr != NULL)
    244 +        return (info_ptr->next_frame_x_offset);
    245 +    return (0);
    246 +}
    247 +
    248 +png_uint_32 PNGAPI
    249 +png_get_next_frame_y_offset(png_structp png_ptr, png_infop info_ptr)
    250 +{
    251 +    png_debug(1, "in png_get_next_frame_y_offset()");
    252 +
    253 +    if (png_ptr != NULL && info_ptr != NULL)
    254 +        return (info_ptr->next_frame_y_offset);
    255 +    return (0);
    256 +}
    257 +
    258 +png_uint_16 PNGAPI
    259 +png_get_next_frame_delay_num(png_structp png_ptr, png_infop info_ptr)
    260 +{
    261 +    png_debug(1, "in png_get_next_frame_delay_num()");
    262 +
    263 +    if (png_ptr != NULL && info_ptr != NULL)
    264 +        return (info_ptr->next_frame_delay_num);
    265 +    return (0);
    266 +}
    267 +
    268 +png_uint_16 PNGAPI
    269 +png_get_next_frame_delay_den(png_structp png_ptr, png_infop info_ptr)
    270 +{
    271 +    png_debug(1, "in png_get_next_frame_delay_den()");
    272 +
    273 +    if (png_ptr != NULL && info_ptr != NULL)
    274 +        return (info_ptr->next_frame_delay_den);
    275 +    return (0);
    276 +}
    277 +
    278 +png_byte PNGAPI
    279 +png_get_next_frame_dispose_op(png_structp png_ptr, png_infop info_ptr)
    280 +{
    281 +    png_debug(1, "in png_get_next_frame_dispose_op()");
    282 +
    283 +    if (png_ptr != NULL && info_ptr != NULL)
    284 +        return (info_ptr->next_frame_dispose_op);
    285 +    return (0);
    286 +}
    287 +
    288 +png_byte PNGAPI
    289 +png_get_next_frame_blend_op(png_structp png_ptr, png_infop info_ptr)
    290 +{
    291 +    png_debug(1, "in png_get_next_frame_blend_op()");
    292 +
    293 +    if (png_ptr != NULL && info_ptr != NULL)
    294 +        return (info_ptr->next_frame_blend_op);
    295 +    return (0);
    296 +}
    297 +
    298 +png_byte PNGAPI
    299 +png_get_first_frame_is_hidden(png_structp png_ptr, png_infop info_ptr)
    300 +{
    301 +    png_debug(1, "in png_first_frame_is_hidden()");
    302 +
    303 +    if (png_ptr != NULL)
    304 +       return (png_byte)(png_ptr->apng_flags & PNG_FIRST_FRAME_HIDDEN);
    305 +
    306 +    PNG_UNUSED(info_ptr)
    307 +
    308 +    return 0;
    309 +}
    310 +#endif /* PNG_APNG_SUPPORTED */
    311  #endif /* READ || WRITE */
    312 diff -Naru libpng-1.6.37.org/pnginfo.h libpng-1.6.37/pnginfo.h
    313 --- libpng-1.6.37.org/pnginfo.h	2019-04-19 07:21:37.399024787 +0900
    314 +++ libpng-1.6.37/pnginfo.h	2019-04-19 07:22:37.850245901 +0900
    315 @@ -263,5 +263,18 @@
    316     png_bytepp row_pointers;        /* the image bits */
    317  #endif
    318  
    319 +#ifdef PNG_APNG_SUPPORTED
    320 +   png_uint_32 num_frames; /* including default image */
    321 +   png_uint_32 num_plays;
    322 +   png_uint_32 next_frame_width;
    323 +   png_uint_32 next_frame_height;
    324 +   png_uint_32 next_frame_x_offset;
    325 +   png_uint_32 next_frame_y_offset;
    326 +   png_uint_16 next_frame_delay_num;
    327 +   png_uint_16 next_frame_delay_den;
    328 +   png_byte next_frame_dispose_op;
    329 +   png_byte next_frame_blend_op;
    330 +#endif
    331 +
    332  };
    333  #endif /* PNGINFO_H */
    334 diff -Naru libpng-1.6.37.org/pngpread.c libpng-1.6.37/pngpread.c
    335 --- libpng-1.6.37.org/pngpread.c	2019-04-19 07:21:37.399024787 +0900
    336 +++ libpng-1.6.37/pngpread.c	2019-04-19 07:22:37.850245901 +0900
    337 @@ -195,6 +195,106 @@
    338  
    339     chunk_name = png_ptr->chunk_name;
    340  
    341 +#ifdef PNG_READ_APNG_SUPPORTED
    342 +   if (png_ptr->num_frames_read > 0 &&
    343 +       png_ptr->num_frames_read < info_ptr->num_frames)
    344 +   {
    345 +      if (chunk_name == png_IDAT)
    346 +      {
    347 +         /* Discard trailing IDATs for the first frame */
    348 +         if (png_ptr->mode & PNG_HAVE_fcTL || png_ptr->num_frames_read > 1)
    349 +            png_error(png_ptr, "out of place IDAT");
    350 +
    351 +         if (png_ptr->push_length + 4 > png_ptr->buffer_size)
    352 +         {
    353 +            png_push_save_buffer(png_ptr);
    354 +            return;
    355 +         }
    356 +
    357 +         png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
    358 +         return;
    359 +      }
    360 +      else if (chunk_name == png_fdAT)
    361 +      {
    362 +         if (png_ptr->buffer_size < 4)
    363 +         {
    364 +            png_push_save_buffer(png_ptr);
    365 +            return;
    366 +         }
    367 +
    368 +         png_ensure_sequence_number(png_ptr, 4);
    369 +
    370 +         if (!(png_ptr->mode & PNG_HAVE_fcTL))
    371 +         {
    372 +            /* Discard trailing fdATs for frames other than the first */
    373 +            if (png_ptr->num_frames_read < 2)
    374 +               png_error(png_ptr, "out of place fdAT");
    375 +
    376 +            if (png_ptr->push_length + 4 > png_ptr->buffer_size)
    377 +            {
    378 +               png_push_save_buffer(png_ptr);
    379 +               return;
    380 +            }
    381 +
    382 +            png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
    383 +            return;
    384 +         }
    385 +
    386 +         else
    387 +         {
    388 +            /* frame data follows */
    389 +            png_ptr->idat_size = png_ptr->push_length - 4;
    390 +            png_ptr->mode |= PNG_HAVE_IDAT;
    391 +            png_ptr->process_mode = PNG_READ_IDAT_MODE;
    392 +
    393 +            return;
    394 +         }
    395 +      }
    396 +
    397 +      else if (chunk_name == png_fcTL)
    398 +      {
    399 +         if (png_ptr->push_length + 4 > png_ptr->buffer_size)
    400 +         {
    401 +            png_push_save_buffer(png_ptr);
    402 +            return;
    403 +         }
    404 +
    405 +         png_read_reset(png_ptr);
    406 +         png_ptr->mode &= ~PNG_HAVE_fcTL;
    407 +
    408 +         png_handle_fcTL(png_ptr, info_ptr, png_ptr->push_length);
    409 +
    410 +         if (!(png_ptr->mode & PNG_HAVE_fcTL))
    411 +            png_error(png_ptr, "missing required fcTL chunk");
    412 +
    413 +         png_read_reinit(png_ptr, info_ptr);
    414 +         png_progressive_read_reset(png_ptr);
    415 +
    416 +         if (png_ptr->frame_info_fn != NULL)
    417 +            (*(png_ptr->frame_info_fn))(png_ptr, png_ptr->num_frames_read);
    418 +
    419 +         png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
    420 +
    421 +         return;
    422 +      }
    423 +
    424 +      else
    425 +      {
    426 +         if (png_ptr->push_length + 4 > png_ptr->buffer_size)
    427 +         {
    428 +            png_push_save_buffer(png_ptr);
    429 +            return;
    430 +         }
    431 +         png_warning(png_ptr, "Skipped (ignored) a chunk "
    432 +                              "between APNG chunks");
    433 +         png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
    434 +         return;
    435 +      }
    436 +
    437 +      return;
    438 +   }
    439 +#endif /* PNG_READ_APNG_SUPPORTED */
    440 +
    441     if (chunk_name == png_IDAT)
    442     {
    443        if ((png_ptr->mode & PNG_AFTER_IDAT) != 0)
    444 @@ -261,6 +361,9 @@
    445  
    446     else if (chunk_name == png_IDAT)
    447     {
    448 +#ifdef PNG_READ_APNG_SUPPORTED
    449 +      png_have_info(png_ptr, info_ptr);
    450 +#endif
    451        png_ptr->idat_size = png_ptr->push_length;
    452        png_ptr->process_mode = PNG_READ_IDAT_MODE;
    453        png_push_have_info(png_ptr, info_ptr);
    454 @@ -406,6 +509,30 @@
    455        png_handle_iTXt(png_ptr, info_ptr, png_ptr->push_length);
    456     }
    457  #endif
    458 +#ifdef PNG_READ_APNG_SUPPORTED
    459 +   else if (chunk_name == png_acTL)
    460 +   {
    461 +      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
    462 +      {
    463 +         png_push_save_buffer(png_ptr);
    464 +         return;
    465 +      }
    466 +
    467 +      png_handle_acTL(png_ptr, info_ptr, png_ptr->push_length);
    468 +   }
    469 +
    470 +   else if (chunk_name == png_fcTL)
    471 +   {
    472 +      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
    473 +      {
    474 +         png_push_save_buffer(png_ptr);
    475 +         return;
    476 +      }
    477 +
    478 +      png_handle_fcTL(png_ptr, info_ptr, png_ptr->push_length);
    479 +   }
    480 +
    481 +#endif /* PNG_READ_APNG_SUPPORTED */
    482  
    483     else
    484     {
    485 @@ -539,7 +666,11 @@
    486        png_byte chunk_tag[4];
    487  
    488        /* TODO: this code can be commoned up with the same code in push_read */
    489 +#ifdef PNG_READ_APNG_SUPPORTED
    490 +      PNG_PUSH_SAVE_BUFFER_IF_LT(12)
    491 +#else
    492        PNG_PUSH_SAVE_BUFFER_IF_LT(8)
    493 +#endif
    494        png_push_fill_buffer(png_ptr, chunk_length, 4);
    495        png_ptr->push_length = png_get_uint_31(png_ptr, chunk_length);
    496        png_reset_crc(png_ptr);
    497 @@ -547,17 +678,64 @@
    498        png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(chunk_tag);
    499        png_ptr->mode |= PNG_HAVE_CHUNK_HEADER;
    500  
    501 +#ifdef PNG_READ_APNG_SUPPORTED
    502 +      if (png_ptr->chunk_name != png_fdAT && png_ptr->num_frames_read > 0)
    503 +      {
    504 +          if (png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED)
    505 +          {
    506 +              png_ptr->process_mode = PNG_READ_CHUNK_MODE;
    507 +              if (png_ptr->frame_end_fn != NULL)
    508 +                 (*(png_ptr->frame_end_fn))(png_ptr, png_ptr->num_frames_read);
    509 +              png_ptr->num_frames_read++;
    510 +              return;
    511 +          }
    512 +          else
    513 +          {
    514 +              if (png_ptr->chunk_name == png_IEND)
    515 +                  png_error(png_ptr, "Not enough image data");
    516 +              if (png_ptr->push_length + 4 > png_ptr->buffer_size)
    517 +              {
    518 +                 png_push_save_buffer(png_ptr);
    519 +                 return;
    520 +              }
    521 +              png_warning(png_ptr, "Skipping (ignoring) a chunk between "
    522 +                                   "APNG chunks");
    523 +              png_crc_finish(png_ptr, png_ptr->push_length);
    524 +              png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
    525 +              return;
    526 +          }
    527 +      }
    528 +      else
    529 +#endif
    530 +#ifdef PNG_READ_APNG_SUPPORTED
    531 +      if (png_ptr->chunk_name != png_IDAT && png_ptr->num_frames_read == 0)
    532 +#else
    533        if (png_ptr->chunk_name != png_IDAT)
    534 +#endif
    535        {
    536           png_ptr->process_mode = PNG_READ_CHUNK_MODE;
    537  
    538           if ((png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED) == 0)
    539              png_error(png_ptr, "Not enough compressed data");
    540  
    541 +#ifdef PNG_READ_APNG_SUPPORTED
    542 +         if (png_ptr->frame_end_fn != NULL)
    543 +            (*(png_ptr->frame_end_fn))(png_ptr, png_ptr->num_frames_read);
    544 +         png_ptr->num_frames_read++;
    545 +#endif
    546 +
    547           return;
    548        }
    549  
    550        png_ptr->idat_size = png_ptr->push_length;
    551 +
    552 +#ifdef PNG_READ_APNG_SUPPORTED
    553 +      if (png_ptr->num_frames_read > 0)
    554 +      {
    555 +         png_ensure_sequence_number(png_ptr, 4);
    556 +         png_ptr->idat_size -= 4;
    557 +      }
    558 +#endif
    559     }
    560  
    561     if (png_ptr->idat_size != 0 && png_ptr->save_buffer_size != 0)
    562 @@ -631,6 +809,15 @@
    563     if (!(buffer_length > 0) || buffer == NULL)
    564        png_error(png_ptr, "No IDAT data (internal error)");
    565  
    566 +#ifdef PNG_READ_APNG_SUPPORTED
    567 +   /* If the app is not APNG-aware, decode only the first frame */
    568 +   if (!(png_ptr->apng_flags & PNG_APNG_APP) && png_ptr->num_frames_read > 0)
    569 +   {
    570 +     png_ptr->flags |= PNG_FLAG_ZSTREAM_ENDED;
    571 +     return;
    572 +   }
    573 +#endif
    574 +
    575     /* This routine must process all the data it has been given
    576      * before returning, calling the row callback as required to
    577      * handle the uncompressed results.
    578 @@ -1085,6 +1272,18 @@
    579     png_set_read_fn(png_ptr, progressive_ptr, png_push_fill_buffer);
    580  }
    581  
    582 +#ifdef PNG_READ_APNG_SUPPORTED
    583 +void PNGAPI
    584 +png_set_progressive_frame_fn(png_structp png_ptr,
    585 +   png_progressive_frame_ptr frame_info_fn,
    586 +   png_progressive_frame_ptr frame_end_fn)
    587 +{
    588 +   png_ptr->frame_info_fn = frame_info_fn;
    589 +   png_ptr->frame_end_fn = frame_end_fn;
    590 +   png_ptr->apng_flags |= PNG_APNG_APP;
    591 +}
    592 +#endif
    593 +
    594  png_voidp PNGAPI
    595  png_get_progressive_ptr(png_const_structrp png_ptr)
    596  {
    597 diff -Naru libpng-1.6.37.org/pngpriv.h libpng-1.6.37/pngpriv.h
    598 --- libpng-1.6.37.org/pngpriv.h	2019-04-19 07:21:37.399024787 +0900
    599 +++ libpng-1.6.37/pngpriv.h	2019-04-19 07:22:37.850245901 +0900
    600 @@ -637,6 +637,10 @@
    601  #define PNG_HAVE_CHUNK_AFTER_IDAT 0x2000U /* Have another chunk after IDAT */
    602                     /*             0x4000U (unused) */
    603  #define PNG_IS_READ_STRUCT        0x8000U /* Else is a write struct */
    604 +#ifdef PNG_APNG_SUPPORTED
    605 +#define PNG_HAVE_acTL            0x10000U
    606 +#define PNG_HAVE_fcTL            0x20000U
    607 +#endif
    608  
    609  /* Flags for the transformations the PNG library does on the image data */
    610  #define PNG_BGR                 0x0001U
    611 @@ -873,6 +877,16 @@
    612  #define png_tRNS PNG_U32(116,  82,  78,  83)
    613  #define png_zTXt PNG_U32(122,  84,  88, 116)
    614  
    615 +#ifdef PNG_APNG_SUPPORTED
    616 +#define png_acTL PNG_U32( 97,  99,  84,  76)
    617 +#define png_fcTL PNG_U32(102,  99,  84,  76)
    618 +#define png_fdAT PNG_U32(102, 100,  65,  84)
    619 +
    620 +/* For png_struct.apng_flags: */
    621 +#define PNG_FIRST_FRAME_HIDDEN       0x0001U
    622 +#define PNG_APNG_APP                 0x0002U
    623 +#endif
    624 +
    625  /* The following will work on (signed char*) strings, whereas the get_uint_32
    626   * macro will fail on top-bit-set values because of the sign extension.
    627   */
    628 @@ -1644,6 +1658,47 @@
    629      */
    630  #endif
    631  
    632 +#ifdef PNG_APNG_SUPPORTED
    633 +PNG_INTERNAL_FUNCTION(void,png_ensure_fcTL_is_valid,(png_structp png_ptr,
    634 +   png_uint_32 width, png_uint_32 height,
    635 +   png_uint_32 x_offset, png_uint_32 y_offset,
    636 +   png_uint_16 delay_num, png_uint_16 delay_den,
    637 +   png_byte dispose_op, png_byte blend_op), PNG_EMPTY);
    638 +
    639 +#ifdef PNG_READ_APNG_SUPPORTED
    640 +PNG_INTERNAL_FUNCTION(void,png_handle_acTL,(png_structp png_ptr, png_infop info_ptr,
    641 +   png_uint_32 length),PNG_EMPTY);
    642 +PNG_INTERNAL_FUNCTION(void,png_handle_fcTL,(png_structp png_ptr, png_infop info_ptr,
    643 +   png_uint_32 length),PNG_EMPTY);
    644 +PNG_INTERNAL_FUNCTION(void,png_handle_fdAT,(png_structp png_ptr, png_infop info_ptr,
    645 +   png_uint_32 length),PNG_EMPTY);
    646 +PNG_INTERNAL_FUNCTION(void,png_have_info,(png_structp png_ptr, png_infop info_ptr),PNG_EMPTY);
    647 +PNG_INTERNAL_FUNCTION(void,png_ensure_sequence_number,(png_structp png_ptr,
    648 +   png_uint_32 length),PNG_EMPTY);
    649 +PNG_INTERNAL_FUNCTION(void,png_read_reset,(png_structp png_ptr),PNG_EMPTY);
    650 +PNG_INTERNAL_FUNCTION(void,png_read_reinit,(png_structp png_ptr,
    651 +   png_infop info_ptr),PNG_EMPTY);
    652 +#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
    653 +PNG_INTERNAL_FUNCTION(void,png_progressive_read_reset,(png_structp png_ptr),PNG_EMPTY);
    654 +#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */
    655 +#endif /* PNG_READ_APNG_SUPPORTED */
    656 +
    657 +#ifdef PNG_WRITE_APNG_SUPPORTED
    658 +PNG_INTERNAL_FUNCTION(void,png_write_acTL,(png_structp png_ptr,
    659 +   png_uint_32 num_frames, png_uint_32 num_plays),PNG_EMPTY);
    660 +PNG_INTERNAL_FUNCTION(void,png_write_fcTL,(png_structp png_ptr,
    661 +   png_uint_32 width, png_uint_32 height,
    662 +   png_uint_32 x_offset, png_uint_32 y_offset,
    663 +   png_uint_16 delay_num, png_uint_16 delay_den,
    664 +   png_byte dispose_op, png_byte blend_op),PNG_EMPTY);
    665 +PNG_INTERNAL_FUNCTION(void,png_write_fdAT,(png_structp png_ptr,
    666 +   png_const_bytep data, png_size_t length),PNG_EMPTY);
    667 +PNG_INTERNAL_FUNCTION(void,png_write_reset,(png_structp png_ptr),PNG_EMPTY);
    668 +PNG_INTERNAL_FUNCTION(void,png_write_reinit,(png_structp png_ptr,
    669 +   png_infop info_ptr, png_uint_32 width, png_uint_32 height),PNG_EMPTY);
    670 +#endif /* PNG_WRITE_APNG_SUPPORTED */
    671 +#endif /* PNG_APNG_SUPPORTED */
    672 +
    673  /* Added at libpng version 1.4.0 */
    674  #ifdef PNG_COLORSPACE_SUPPORTED
    675  /* These internal functions are for maintaining the colorspace structure within
    676 diff -Naru libpng-1.6.37.org/pngread.c libpng-1.6.37/pngread.c
    677 --- libpng-1.6.37.org/pngread.c	2019-04-19 07:21:37.400024774 +0900
    678 +++ libpng-1.6.37/pngread.c	2019-04-19 07:22:37.851245887 +0900
    679 @@ -161,6 +161,9 @@
    680  
    681        else if (chunk_name == png_IDAT)
    682        {
    683 +#ifdef PNG_READ_APNG_SUPPORTED
    684 +         png_have_info(png_ptr, info_ptr);
    685 +#endif
    686           png_ptr->idat_size = length;
    687           break;
    688        }
    689 @@ -255,6 +258,17 @@
    690           png_handle_iTXt(png_ptr, info_ptr, length);
    691  #endif
    692  
    693 +#ifdef PNG_READ_APNG_SUPPORTED
    694 +      else if (chunk_name == png_acTL)
    695 +         png_handle_acTL(png_ptr, info_ptr, length);
    696 +
    697 +      else if (chunk_name == png_fcTL)
    698 +         png_handle_fcTL(png_ptr, info_ptr, length);
    699 +
    700 +      else if (chunk_name == png_fdAT)
    701 +         png_handle_fdAT(png_ptr, info_ptr, length);
    702 +#endif
    703 +
    704        else
    705           png_handle_unknown(png_ptr, info_ptr, length,
    706               PNG_HANDLE_CHUNK_AS_DEFAULT);
    707 @@ -262,6 +276,72 @@
    708  }
    709  #endif /* SEQUENTIAL_READ */
    710  
    711 +#ifdef PNG_READ_APNG_SUPPORTED
    712 +void PNGAPI
    713 +png_read_frame_head(png_structp png_ptr, png_infop info_ptr)
    714 +{
    715 +    png_byte have_chunk_after_DAT; /* after IDAT or after fdAT */
    716 +
    717 +    png_debug(0, "Reading frame head");
    718 +
    719 +    if (!(png_ptr->mode & PNG_HAVE_acTL))
    720 +        png_error(png_ptr, "attempt to png_read_frame_head() but "
    721 +                           "no acTL present");
    722 +
    723 +    /* do nothing for the main IDAT */
    724 +    if (png_ptr->num_frames_read == 0)
    725 +        return;
    726 +
    727 +    png_read_reset(png_ptr);
    728 +    png_ptr->flags &= ~PNG_FLAG_ROW_INIT;
    729 +    png_ptr->mode &= ~PNG_HAVE_fcTL;
    730 +
    731 +    have_chunk_after_DAT = 0;
    732 +    for (;;)
    733 +    {
    734 +        png_uint_32 length = png_read_chunk_header(png_ptr);
    735 +
    736 +        if (png_ptr->chunk_name == png_IDAT)
    737 +        {
    738 +            /* discard trailing IDATs for the first frame */
    739 +            if (have_chunk_after_DAT || png_ptr->num_frames_read > 1)
    740 +                png_error(png_ptr, "png_read_frame_head(): out of place IDAT");
    741 +            png_crc_finish(png_ptr, length);
    742 +        }
    743 +
    744 +        else if (png_ptr->chunk_name == png_fcTL)
    745 +        {
    746 +            png_handle_fcTL(png_ptr, info_ptr, length);
    747 +            have_chunk_after_DAT = 1;
    748 +        }
    749 +
    750 +        else if (png_ptr->chunk_name == png_fdAT)
    751 +        {
    752 +            png_ensure_sequence_number(png_ptr, length);
    753 +
    754 +            /* discard trailing fdATs for frames other than the first */
    755 +            if (!have_chunk_after_DAT && png_ptr->num_frames_read > 1)
    756 +                png_crc_finish(png_ptr, length - 4);
    757 +            else if(png_ptr->mode & PNG_HAVE_fcTL)
    758 +            {
    759 +                png_ptr->idat_size = length - 4;
    760 +                png_ptr->mode |= PNG_HAVE_IDAT;
    761 +
    762 +                break;
    763 +            }
    764 +            else
    765 +                png_error(png_ptr, "png_read_frame_head(): out of place fdAT");
    766 +        }
    767 +        else
    768 +        {
    769 +            png_warning(png_ptr, "Skipped (ignored) a chunk "
    770 +                                 "between APNG chunks");
    771 +            png_crc_finish(png_ptr, length);
    772 +        }
    773 +    }
    774 +}
    775 +#endif /* PNG_READ_APNG_SUPPORTED */
    776 +
    777  /* Optional call to update the users info_ptr structure */
    778  void PNGAPI
    779  png_read_update_info(png_structrp png_ptr, png_inforp info_ptr)
    780 diff -Naru libpng-1.6.37.org/pngrutil.c libpng-1.6.37/pngrutil.c
    781 --- libpng-1.6.37.org/pngrutil.c	2019-04-19 07:21:37.401024761 +0900
    782 +++ libpng-1.6.37/pngrutil.c	2019-04-19 07:22:37.853245862 +0900
    783 @@ -865,6 +865,11 @@
    784     filter_type = buf[11];
    785     interlace_type = buf[12];
    786  
    787 +#ifdef PNG_READ_APNG_SUPPORTED
    788 +   png_ptr->first_frame_width = width;
    789 +   png_ptr->first_frame_height = height;
    790 +#endif
    791 +
    792     /* Set internal variables */
    793     png_ptr->width = width;
    794     png_ptr->height = height;
    795 @@ -2857,6 +2862,179 @@
    796  }
    797  #endif
    798  
    799 +#ifdef PNG_READ_APNG_SUPPORTED
    800 +void /* PRIVATE */
    801 +png_handle_acTL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
    802 +{
    803 +    png_byte data[8];
    804 +    png_uint_32 num_frames;
    805 +    png_uint_32 num_plays;
    806 +    png_uint_32 didSet;
    807 +
    808 +    png_debug(1, "in png_handle_acTL");
    809 +
    810 +    if (!(png_ptr->mode & PNG_HAVE_IHDR))
    811 +    {
    812 +        png_error(png_ptr, "Missing IHDR before acTL");
    813 +    }
    814 +    else if (png_ptr->mode & PNG_HAVE_IDAT)
    815 +    {
    816 +        png_warning(png_ptr, "Invalid acTL after IDAT skipped");
    817 +        png_crc_finish(png_ptr, length);
    818 +        return;
    819 +    }
    820 +    else if (png_ptr->mode & PNG_HAVE_acTL)
    821 +    {
    822 +        png_warning(png_ptr, "Duplicate acTL skipped");
    823 +        png_crc_finish(png_ptr, length);
    824 +        return;
    825 +    }
    826 +    else if (length != 8)
    827 +    {
    828 +        png_warning(png_ptr, "acTL with invalid length skipped");
    829 +        png_crc_finish(png_ptr, length);
    830 +        return;
    831 +    }
    832 +
    833 +    png_crc_read(png_ptr, data, 8);
    834 +    png_crc_finish(png_ptr, 0);
    835 +
    836 +    num_frames = png_get_uint_31(png_ptr, data);
    837 +    num_plays = png_get_uint_31(png_ptr, data + 4);
    838 +
    839 +    /* the set function will do error checking on num_frames */
    840 +    didSet = png_set_acTL(png_ptr, info_ptr, num_frames, num_plays);
    841 +    if(didSet)
    842 +        png_ptr->mode |= PNG_HAVE_acTL;
    843 +}
    844 +
    845 +void /* PRIVATE */
    846 +png_handle_fcTL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
    847 +{
    848 +    png_byte data[22];
    849 +    png_uint_32 width;
    850 +    png_uint_32 height;
    851 +    png_uint_32 x_offset;
    852 +    png_uint_32 y_offset;
    853 +    png_uint_16 delay_num;
    854 +    png_uint_16 delay_den;
    855 +    png_byte dispose_op;
    856 +    png_byte blend_op;
    857 +
    858 +    png_debug(1, "in png_handle_fcTL");
    859 +
    860 +    png_ensure_sequence_number(png_ptr, length);
    861 +
    862 +    if (!(png_ptr->mode & PNG_HAVE_IHDR))
    863 +    {
    864 +        png_error(png_ptr, "Missing IHDR before fcTL");
    865 +    }
    866 +    else if (png_ptr->mode & PNG_HAVE_IDAT)
    867 +    {
    868 +        /* for any frames other then the first this message may be misleading,
    869 +        * but correct. PNG_HAVE_IDAT is unset before the frame head is read
    870 +        * i can't think of a better message */
    871 +        png_warning(png_ptr, "Invalid fcTL after IDAT skipped");
    872 +        png_crc_finish(png_ptr, length-4);
    873 +        return;
    874 +    }
    875 +    else if (png_ptr->mode & PNG_HAVE_fcTL)
    876 +    {
    877 +        png_warning(png_ptr, "Duplicate fcTL within one frame skipped");
    878 +        png_crc_finish(png_ptr, length-4);
    879 +        return;
    880 +    }
    881 +    else if (length != 26)
    882 +    {
    883 +        png_warning(png_ptr, "fcTL with invalid length skipped");
    884 +        png_crc_finish(png_ptr, length-4);
    885 +        return;
    886 +    }
    887 +
    888 +    png_crc_read(png_ptr, data, 22);
    889 +    png_crc_finish(png_ptr, 0);
    890 +
    891 +    width = png_get_uint_31(png_ptr, data);
    892 +    height = png_get_uint_31(png_ptr, data + 4);
    893 +    x_offset = png_get_uint_31(png_ptr, data + 8);
    894 +    y_offset = png_get_uint_31(png_ptr, data + 12);
    895 +    delay_num = png_get_uint_16(data + 16);
    896 +    delay_den = png_get_uint_16(data + 18);
    897 +    dispose_op = data[20];
    898 +    blend_op = data[21];
    899 +
    900 +    if (png_ptr->num_frames_read == 0 && (x_offset != 0 || y_offset != 0))
    901 +    {
    902 +        png_warning(png_ptr, "fcTL for the first frame must have zero offset");
    903 +        return;
    904 +    }
    905 +
    906 +    if (info_ptr != NULL)
    907 +    {
    908 +        if (png_ptr->num_frames_read == 0 &&
    909 +            (width != info_ptr->width || height != info_ptr->height))
    910 +        {
    911 +            png_warning(png_ptr, "size in first frame's fcTL must match "
    912 +                               "the size in IHDR");
    913 +            return;
    914 +        }
    915 +
    916 +        /* The set function will do more error checking */
    917 +        png_set_next_frame_fcTL(png_ptr, info_ptr, width, height,
    918 +                                x_offset, y_offset, delay_num, delay_den,
    919 +                                dispose_op, blend_op);
    920 +
    921 +        png_read_reinit(png_ptr, info_ptr);
    922 +
    923 +        png_ptr->mode |= PNG_HAVE_fcTL;
    924 +    }
    925 +}
    926 +
    927 +void /* PRIVATE */
    928 +png_have_info(png_structp png_ptr, png_infop info_ptr)
    929 +{
    930 +    if((info_ptr->valid & PNG_INFO_acTL) && !(info_ptr->valid & PNG_INFO_fcTL))
    931 +    {
    932 +        png_ptr->apng_flags |= PNG_FIRST_FRAME_HIDDEN;
    933 +        info_ptr->num_frames++;
    934 +    }
    935 +}
    936 +
    937 +void /* PRIVATE */
    938 +png_handle_fdAT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
    939 +{
    940 +    png_ensure_sequence_number(png_ptr, length);
    941 +
    942 +    /* This function is only called from png_read_end(), png_read_info(),
    943 +    * and png_push_read_chunk() which means that:
    944 +    * - the user doesn't want to read this frame
    945 +    * - or this is an out-of-place fdAT
    946 +    * in either case it is safe to ignore the chunk with a warning */
    947 +    png_warning(png_ptr, "ignoring fdAT chunk");
    948 +    png_crc_finish(png_ptr, length - 4);
    949 +    PNG_UNUSED(info_ptr)
    950 +}
    951 +
    952 +void /* PRIVATE */
    953 +png_ensure_sequence_number(png_structp png_ptr, png_uint_32 length)
    954 +{
    955 +    png_byte data[4];
    956 +    png_uint_32 sequence_number;
    957 +
    958 +    if (length < 4)
    959 +        png_error(png_ptr, "invalid fcTL or fdAT chunk found");
    960 +
    961 +    png_crc_read(png_ptr, data, 4);
    962 +    sequence_number = png_get_uint_31(png_ptr, data);
    963 +
    964 +    if (sequence_number != png_ptr->next_seq_num)
    965 +        png_error(png_ptr, "fcTL or fdAT chunk with out-of-order sequence "
    966 +                           "number found");
    967 +
    968 +    png_ptr->next_seq_num++;
    969 +}
    970 +#endif /* PNG_READ_APNG_SUPPORTED */
    971 +
    972  #ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
    973  /* Utility function for png_handle_unknown; set up png_ptr::unknown_chunk */
    974  static int
    975 @@ -4165,7 +4343,38 @@
    976        {
    977           uInt avail_in;
    978           png_bytep buffer;
    979 +#ifdef PNG_READ_APNG_SUPPORTED
    980 +         png_uint_32 bytes_to_skip = 0;
    981 +
    982 +         while (png_ptr->idat_size == 0 || bytes_to_skip != 0)
    983 +         {
    984 +            png_crc_finish(png_ptr, bytes_to_skip);
    985 +            bytes_to_skip = 0;
    986  
    987 +            png_ptr->idat_size = png_read_chunk_header(png_ptr);
    988 +            if (png_ptr->num_frames_read == 0)
    989 +            {
    990 +               if (png_ptr->chunk_name != png_IDAT)
    991 +                  png_error(png_ptr, "Not enough image data");
    992 +            }
    993 +            else
    994 +            {
    995 +               if (png_ptr->chunk_name == png_IEND)
    996 +                  png_error(png_ptr, "Not enough image data");
    997 +               if (png_ptr->chunk_name != png_fdAT)
    998 +               {
    999 +                  png_warning(png_ptr, "Skipped (ignored) a chunk "
   1000 +                                       "between APNG chunks");
   1001 +                  bytes_to_skip = png_ptr->idat_size;
   1002 +                  continue;
   1003 +               }
   1004 +
   1005 +               png_ensure_sequence_number(png_ptr, png_ptr->idat_size);
   1006 +
   1007 +               png_ptr->idat_size -= 4;
   1008 +            }
   1009 +         }
   1010 +#else
   1011           while (png_ptr->idat_size == 0)
   1012           {
   1013              png_crc_finish(png_ptr, 0);
   1014 @@ -4177,7 +4386,7 @@
   1015              if (png_ptr->chunk_name != png_IDAT)
   1016                 png_error(png_ptr, "Not enough image data");
   1017           }
   1018 -
   1019 +#endif /* PNG_READ_APNG_SUPPORTED */
   1020           avail_in = png_ptr->IDAT_read_size;
   1021  
   1022           if (avail_in > png_ptr->idat_size)
   1023 @@ -4240,6 +4449,9 @@
   1024  
   1025           png_ptr->mode |= PNG_AFTER_IDAT;
   1026           png_ptr->flags |= PNG_FLAG_ZSTREAM_ENDED;
   1027 +#ifdef PNG_READ_APNG_SUPPORTED
   1028 +         png_ptr->num_frames_read++;
   1029 +#endif
   1030  
   1031           if (png_ptr->zstream.avail_in > 0 || png_ptr->idat_size > 0)
   1032              png_chunk_benign_error(png_ptr, "Extra compressed data");
   1033 @@ -4678,4 +4890,80 @@
   1034  
   1035     png_ptr->flags |= PNG_FLAG_ROW_INIT;
   1036  }
   1037 +
   1038 +#ifdef PNG_READ_APNG_SUPPORTED
   1039 +/* This function is to be called after the main IDAT set has been read and
   1040 + * before a new IDAT is read. It resets some parts of png_ptr
   1041 + * to make them usable by the read functions again */
   1042 +void /* PRIVATE */
   1043 +png_read_reset(png_structp png_ptr)
   1044 +{
   1045 +    png_ptr->mode &= ~PNG_HAVE_IDAT;
   1046 +    png_ptr->mode &= ~PNG_AFTER_IDAT;
   1047 +    png_ptr->row_number = 0;
   1048 +    png_ptr->pass = 0;
   1049 +}
   1050 +
   1051 +void /* PRIVATE */
   1052 +png_read_reinit(png_structp png_ptr, png_infop info_ptr)
   1053 +{
   1054 +    png_ptr->width = info_ptr->next_frame_width;
   1055 +    png_ptr->height = info_ptr->next_frame_height;
   1056 +    png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth,png_ptr->width);
   1057 +    png_ptr->info_rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth,
   1058 +        png_ptr->width);
   1059 +    if (png_ptr->prev_row)
   1060 +        memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1);
   1061 +}
   1062 +
   1063 +#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
   1064 +/* same as png_read_reset() but for the progressive reader */
   1065 +void /* PRIVATE */
   1066 +png_progressive_read_reset(png_structp png_ptr)
   1067 +{
   1068 +#ifdef PNG_READ_INTERLACING_SUPPORTED
   1069 +   /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
   1070 +
   1071 +   /* Start of interlace block */
   1072 +    const int png_pass_start[] = {0, 4, 0, 2, 0, 1, 0};
   1073 +
   1074 +    /* Offset to next interlace block */
   1075 +    const int png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1};
   1076 +
   1077 +    /* Start of interlace block in the y direction */
   1078 +    const int png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1};
   1079 +
   1080 +    /* Offset to next interlace block in the y direction */
   1081 +    const int png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2};
   1082 +
   1083 +    if (png_ptr->interlaced)
   1084 +    {
   1085 +        if (!(png_ptr->transformations & PNG_INTERLACE))
   1086 +            png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 -
   1087 +                                png_pass_ystart[0]) / png_pass_yinc[0];
   1088 +        else
   1089 +            png_ptr->num_rows = png_ptr->height;
   1090 +
   1091 +        png_ptr->iwidth = (png_ptr->width +
   1092 +                           png_pass_inc[png_ptr->pass] - 1 -
   1093 +                           png_pass_start[png_ptr->pass]) /
   1094 +                           png_pass_inc[png_ptr->pass];
   1095 +    }
   1096 +    else
   1097 +#endif /* PNG_READ_INTERLACING_SUPPORTED */
   1098 +    {
   1099 +        png_ptr->num_rows = png_ptr->height;
   1100 +        png_ptr->iwidth = png_ptr->width;
   1101 +    }
   1102 +    png_ptr->flags &= ~PNG_FLAG_ZSTREAM_ENDED;
   1103 +    if (inflateReset(&(png_ptr->zstream)) != Z_OK)
   1104 +        png_error(png_ptr, "inflateReset failed");
   1105 +    png_ptr->zstream.avail_in = 0;
   1106 +    png_ptr->zstream.next_in = 0;
   1107 +    png_ptr->zstream.next_out = png_ptr->row_buf;
   1108 +    png_ptr->zstream.avail_out = (uInt)PNG_ROWBYTES(png_ptr->pixel_depth,
   1109 +        png_ptr->iwidth) + 1;
   1110 +}
   1111 +#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */
   1112 +#endif /* PNG_READ_APNG_SUPPORTED */
   1113  #endif /* READ */
   1114 diff -Naru libpng-1.6.37.org/pngset.c libpng-1.6.37/pngset.c
   1115 --- libpng-1.6.37.org/pngset.c	2019-04-19 07:21:37.401024761 +0900
   1116 +++ libpng-1.6.37/pngset.c	2019-04-19 07:22:37.858245798 +0900
   1117 @@ -288,6 +288,11 @@
   1118     info_ptr->pixel_depth = (png_byte)(info_ptr->channels * info_ptr->bit_depth);
   1119  
   1120     info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth, width);
   1121 +
   1122 +#ifdef PNG_APNG_SUPPORTED
   1123 +   /* for non-animated png. this may be overwritten from an acTL chunk later */
   1124 +   info_ptr->num_frames = 1;
   1125 +#endif
   1126  }
   1127  
   1128  #ifdef PNG_oFFs_SUPPORTED
   1129 @@ -1158,6 +1163,147 @@
   1130  }
   1131  #endif /* sPLT */
   1132  
   1133 +#ifdef PNG_APNG_SUPPORTED
   1134 +png_uint_32 PNGAPI
   1135 +png_set_acTL(png_structp png_ptr, png_infop info_ptr,
   1136 +    png_uint_32 num_frames, png_uint_32 num_plays)
   1137 +{
   1138 +    png_debug1(1, "in %s storage function", "acTL");
   1139 +
   1140 +    if (png_ptr == NULL || info_ptr == NULL)
   1141 +    {
   1142 +        png_warning(png_ptr,
   1143 +                    "Call to png_set_acTL() with NULL png_ptr "
   1144 +                    "or info_ptr ignored");
   1145 +        return (0);
   1146 +    }
   1147 +    if (num_frames == 0)
   1148 +    {
   1149 +        png_warning(png_ptr,
   1150 +                    "Ignoring attempt to set acTL with num_frames zero");
   1151 +        return (0);
   1152 +    }
   1153 +    if (num_frames > PNG_UINT_31_MAX)
   1154 +    {
   1155 +        png_warning(png_ptr,
   1156 +                    "Ignoring attempt to set acTL with num_frames > 2^31-1");
   1157 +        return (0);
   1158 +    }
   1159 +    if (num_plays > PNG_UINT_31_MAX)
   1160 +    {
   1161 +        png_warning(png_ptr,
   1162 +                    "Ignoring attempt to set acTL with num_plays "
   1163 +                    "> 2^31-1");
   1164 +        return (0);
   1165 +    }
   1166 +
   1167 +    info_ptr->num_frames = num_frames;
   1168 +    info_ptr->num_plays = num_plays;
   1169 +
   1170 +    info_ptr->valid |= PNG_INFO_acTL;
   1171 +
   1172 +    return (1);
   1173 +}
   1174 +
   1175 +/* delay_num and delay_den can hold any 16-bit values including zero */
   1176 +png_uint_32 PNGAPI
   1177 +png_set_next_frame_fcTL(png_structp png_ptr, png_infop info_ptr,
   1178 +    png_uint_32 width, png_uint_32 height,
   1179 +    png_uint_32 x_offset, png_uint_32 y_offset,
   1180 +    png_uint_16 delay_num, png_uint_16 delay_den,
   1181 +    png_byte dispose_op, png_byte blend_op)
   1182 +{
   1183 +    png_debug1(1, "in %s storage function", "fcTL");
   1184 +
   1185 +    if (png_ptr == NULL || info_ptr == NULL)
   1186 +    {
   1187 +        png_warning(png_ptr,
   1188 +                    "Call to png_set_fcTL() with NULL png_ptr or info_ptr "
   1189 +                    "ignored");
   1190 +        return (0);
   1191 +    }
   1192 +
   1193 +    png_ensure_fcTL_is_valid(png_ptr, width, height, x_offset, y_offset,
   1194 +                             delay_num, delay_den, dispose_op, blend_op);
   1195 +
   1196 +    if (blend_op == PNG_BLEND_OP_OVER)
   1197 +    {
   1198 +        if (!(png_ptr->color_type & PNG_COLOR_MASK_ALPHA) &&
   1199 +            !(png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)))
   1200 +        {
   1201 +          png_warning(png_ptr, "PNG_BLEND_OP_OVER is meaningless "
   1202 +                               "and wasteful for opaque images, ignored");
   1203 +          blend_op = PNG_BLEND_OP_SOURCE;
   1204 +        }
   1205 +    }
   1206 +
   1207 +    info_ptr->next_frame_width = width;
   1208 +    info_ptr->next_frame_height = height;
   1209 +    info_ptr->next_frame_x_offset = x_offset;
   1210 +    info_ptr->next_frame_y_offset = y_offset;
   1211 +    info_ptr->next_frame_delay_num = delay_num;
   1212 +    info_ptr->next_frame_delay_den = delay_den;
   1213 +    info_ptr->next_frame_dispose_op = dispose_op;
   1214 +    info_ptr->next_frame_blend_op = blend_op;
   1215 +
   1216 +    info_ptr->valid |= PNG_INFO_fcTL;
   1217 +
   1218 +    return (1);
   1219 +}
   1220 +
   1221 +void /* PRIVATE */
   1222 +png_ensure_fcTL_is_valid(png_structp png_ptr,
   1223 +    png_uint_32 width, png_uint_32 height,
   1224 +    png_uint_32 x_offset, png_uint_32 y_offset,
   1225 +    png_uint_16 delay_num, png_uint_16 delay_den,
   1226 +    png_byte dispose_op, png_byte blend_op)
   1227 +{
   1228 +    if (width == 0 || width > PNG_UINT_31_MAX)
   1229 +        png_error(png_ptr, "invalid width in fcTL (> 2^31-1)");
   1230 +    if (height == 0 || height > PNG_UINT_31_MAX)
   1231 +        png_error(png_ptr, "invalid height in fcTL (> 2^31-1)");
   1232 +    if (x_offset > PNG_UINT_31_MAX)
   1233 +        png_error(png_ptr, "invalid x_offset in fcTL (> 2^31-1)");
   1234 +    if (y_offset > PNG_UINT_31_MAX)
   1235 +        png_error(png_ptr, "invalid y_offset in fcTL (> 2^31-1)");
   1236 +    if (width + x_offset > png_ptr->first_frame_width ||
   1237 +        height + y_offset > png_ptr->first_frame_height)
   1238 +        png_error(png_ptr, "dimensions of a frame are greater than"
   1239 +                           "the ones in IHDR");
   1240 +
   1241 +    if (dispose_op != PNG_DISPOSE_OP_NONE &&
   1242 +        dispose_op != PNG_DISPOSE_OP_BACKGROUND &&
   1243 +        dispose_op != PNG_DISPOSE_OP_PREVIOUS)
   1244 +        png_error(png_ptr, "invalid dispose_op in fcTL");
   1245 +
   1246 +    if (blend_op != PNG_BLEND_OP_SOURCE &&
   1247 +        blend_op != PNG_BLEND_OP_OVER)
   1248 +        png_error(png_ptr, "invalid blend_op in fcTL");
   1249 +
   1250 +    PNG_UNUSED(delay_num)
   1251 +    PNG_UNUSED(delay_den)
   1252 +}
   1253 +
   1254 +png_uint_32 PNGAPI
   1255 +png_set_first_frame_is_hidden(png_structp png_ptr, png_infop info_ptr,
   1256 +                              png_byte is_hidden)
   1257 +{
   1258 +    png_debug(1, "in png_first_frame_is_hidden()");
   1259 +
   1260 +    if (png_ptr == NULL)
   1261 +        return 0;
   1262 +
   1263 +    if (is_hidden)
   1264 +        png_ptr->apng_flags |= PNG_FIRST_FRAME_HIDDEN;
   1265 +    else
   1266 +        png_ptr->apng_flags &= ~PNG_FIRST_FRAME_HIDDEN;
   1267 +
   1268 +    PNG_UNUSED(info_ptr)
   1269 +
   1270 +    return 1;
   1271 +}
   1272 +#endif /* PNG_APNG_SUPPORTED */
   1273 +
   1274  #ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED
   1275  static png_byte
   1276  check_location(png_const_structrp png_ptr, int location)
   1277 diff -Naru libpng-1.6.37.org/pngstruct.h libpng-1.6.37/pngstruct.h
   1278 --- libpng-1.6.37.org/pngstruct.h	2019-04-19 07:21:37.401024761 +0900
   1279 +++ libpng-1.6.37/pngstruct.h	2019-04-19 07:22:37.854245849 +0900
   1280 @@ -409,6 +409,27 @@
   1281     png_byte filter_type;
   1282  #endif
   1283  
   1284 +#ifdef PNG_APNG_SUPPORTED
   1285 +   png_uint_32 apng_flags;
   1286 +   png_uint_32 next_seq_num;         /* next fcTL/fdAT chunk sequence number */
   1287 +   png_uint_32 first_frame_width;
   1288 +   png_uint_32 first_frame_height;
   1289 +
   1290 +#ifdef PNG_READ_APNG_SUPPORTED
   1291 +   png_uint_32 num_frames_read;      /* incremented after all image data of */
   1292 +                                     /* a frame is read */
   1293 +#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
   1294 +   png_progressive_frame_ptr frame_info_fn; /* frame info read callback */
   1295 +   png_progressive_frame_ptr frame_end_fn;  /* frame data read callback */
   1296 +#endif
   1297 +#endif
   1298 +
   1299 +#ifdef PNG_WRITE_APNG_SUPPORTED
   1300 +   png_uint_32 num_frames_to_write;
   1301 +   png_uint_32 num_frames_written;
   1302 +#endif
   1303 +#endif /* PNG_APNG_SUPPORTED */
   1304 +
   1305  /* New members added in libpng-1.2.0 */
   1306  
   1307  /* New members added in libpng-1.0.2 but first enabled by default in 1.2.0 */
   1308 diff -Naru libpng-1.6.37.org/pngtest.c libpng-1.6.37/pngtest.c
   1309 --- libpng-1.6.37.org/pngtest.c	2019-04-19 07:21:37.401024761 +0900
   1310 +++ libpng-1.6.37/pngtest.c	2019-04-19 07:22:37.854245849 +0900
   1311 @@ -875,6 +875,10 @@
   1312     volatile int num_passes;
   1313     int pass;
   1314     int bit_depth, color_type;
   1315 +#ifdef PNG_APNG_SUPPORTED
   1316 +   png_uint_32 num_frames;
   1317 +   png_uint_32 num_plays;
   1318 +#endif
   1319  
   1320     row_buf = NULL;
   1321     error_parameters.file_name = inname;
   1322 @@ -1383,6 +1387,22 @@
   1323        }
   1324     }
   1325  #endif
   1326 +
   1327 +#ifdef PNG_APNG_SUPPORTED
   1328 +   if (png_get_valid(read_ptr, read_info_ptr, PNG_INFO_acTL))
   1329 +   {
   1330 +      if (png_get_acTL(read_ptr, read_info_ptr, &num_frames, &num_plays))
   1331 +      {
   1332 +         png_byte is_hidden;
   1333 +         pngtest_debug2("Handling acTL chunks (frames %ld, plays %ld)",
   1334 +                    num_frames, num_plays);
   1335 +         png_set_acTL(write_ptr, write_info_ptr, num_frames, num_plays);
   1336 +         is_hidden = png_get_first_frame_is_hidden(read_ptr, read_info_ptr);
   1337 +         png_set_first_frame_is_hidden(write_ptr, write_info_ptr, is_hidden);
   1338 +      }
   1339 +   }
   1340 +#endif
   1341 +
   1342  #ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED
   1343     {
   1344        png_unknown_chunkp unknowns;
   1345 @@ -1463,6 +1483,110 @@
   1346     t_misc += (t_stop - t_start);
   1347     t_start = t_stop;
   1348  #endif
   1349 +#ifdef PNG_APNG_SUPPORTED
   1350 +   if (png_get_valid(read_ptr, read_info_ptr, PNG_INFO_acTL))
   1351 +   {
   1352 +      png_uint_32 frame;
   1353 +      for (frame = 0; frame < num_frames; frame++)
   1354 +      {
   1355 +         png_uint_32 frame_width;
   1356 +         png_uint_32 frame_height;
   1357 +         png_uint_32 x_offset;
   1358 +         png_uint_32 y_offset;
   1359 +         png_uint_16 delay_num;
   1360 +         png_uint_16 delay_den;
   1361 +         png_byte dispose_op;
   1362 +         png_byte blend_op;
   1363 +         png_read_frame_head(read_ptr, read_info_ptr);
   1364 +         if (png_get_valid(read_ptr, read_info_ptr, PNG_INFO_fcTL))
   1365 +         {
   1366 +            png_get_next_frame_fcTL(read_ptr, read_info_ptr,
   1367 +                                    &frame_width, &frame_height,
   1368 +                                    &x_offset, &y_offset,
   1369 +                                    &delay_num, &delay_den,
   1370 +                                    &dispose_op, &blend_op);
   1371 +         }
   1372 +         else
   1373 +         {
   1374 +            frame_width = width;
   1375 +            frame_height = height;
   1376 +            x_offset = 0;
   1377 +            y_offset = 0;
   1378 +            delay_num = 1;
   1379 +            delay_den = 1;
   1380 +            dispose_op = PNG_DISPOSE_OP_NONE;
   1381 +            blend_op = PNG_BLEND_OP_SOURCE;
   1382 +         }
   1383 +#ifdef PNG_WRITE_APNG_SUPPORTED
   1384 +         png_write_frame_head(write_ptr, write_info_ptr, (png_bytepp)&row_buf,
   1385 +                              frame_width, frame_height,
   1386 +                              x_offset, y_offset,
   1387 +                              delay_num, delay_den,
   1388 +                              dispose_op, blend_op);
   1389 +#endif
   1390 +         for (pass = 0; pass < num_passes; pass++)
   1391 +         {
   1392 +#           ifdef calc_pass_height
   1393 +               png_uint_32 pass_height;
   1394 +
   1395 +               if (num_passes == 7) /* interlaced */
   1396 +               {
   1397 +                  if (PNG_PASS_COLS(frame_width, pass) > 0)
   1398 +                     pass_height = PNG_PASS_ROWS(frame_height, pass);
   1399 +
   1400 +                  else
   1401 +                     pass_height = 0;
   1402 +               }
   1403 +
   1404 +               else /* not interlaced */
   1405 +                  pass_height = frame_height;
   1406 +#           else
   1407 +#              define pass_height frame_height
   1408 +#           endif
   1409 +
   1410 +            pngtest_debug1("Writing row data for pass %d", pass);
   1411 +            for (y = 0; y < pass_height; y++)
   1412 +            {
   1413 +#ifndef SINGLE_ROWBUF_ALLOC
   1414 +               pngtest_debug2("Allocating row buffer (pass %d, y = %u)...", pass, y);
   1415 +
   1416 +               row_buf = (png_bytep)png_malloc(read_ptr,
   1417 +                  png_get_rowbytes(read_ptr, read_info_ptr));
   1418 +
   1419 +               pngtest_debug2("\t0x%08lx (%lu bytes)", (unsigned long)row_buf,
   1420 +                  (unsigned long)png_get_rowbytes(read_ptr, read_info_ptr));
   1421 +
   1422 +#endif /* !SINGLE_ROWBUF_ALLOC */
   1423 +               png_read_rows(read_ptr, (png_bytepp)&row_buf, NULL, 1);
   1424 +
   1425 +#ifdef PNG_WRITE_SUPPORTED
   1426 +#ifdef PNGTEST_TIMING
   1427 +               t_stop = (float)clock();
   1428 +               t_decode += (t_stop - t_start);
   1429 +               t_start = t_stop;
   1430 +#endif
   1431 +               png_write_rows(write_ptr, (png_bytepp)&row_buf, 1);
   1432 +#ifdef PNGTEST_TIMING
   1433 +               t_stop = (float)clock();
   1434 +               t_encode += (t_stop - t_start);
   1435 +               t_start = t_stop;
   1436 +#endif
   1437 +#endif /* PNG_WRITE_SUPPORTED */
   1438 +
   1439 +#ifndef SINGLE_ROWBUF_ALLOC
   1440 +               pngtest_debug2("Freeing row buffer (pass %d, y = %u)", pass, y);
   1441 +               png_free(read_ptr, row_buf);
   1442 +               row_buf = NULL;
   1443 +#endif /* !SINGLE_ROWBUF_ALLOC */
   1444 +            }
   1445 +         }
   1446 +#ifdef PNG_WRITE_APNG_SUPPORTED
   1447 +         png_write_frame_tail(write_ptr, write_info_ptr);
   1448 +#endif
   1449 +      }
   1450 +   }
   1451 +   else
   1452 +#endif
   1453     for (pass = 0; pass < num_passes; pass++)
   1454     {
   1455  #     ifdef calc_pass_height
   1456 diff -Naru libpng-1.6.37.org/pngwrite.c libpng-1.6.37/pngwrite.c
   1457 --- libpng-1.6.37.org/pngwrite.c	2019-04-19 07:21:37.402024748 +0900
   1458 +++ libpng-1.6.37/pngwrite.c	2019-04-19 07:22:37.855245836 +0900
   1459 @@ -128,6 +128,10 @@
   1460         * the application continues writing the PNG.  So check the 'invalid'
   1461         * flag here too.
   1462         */
   1463 +#ifdef PNG_WRITE_APNG_SUPPORTED
   1464 +      if (info_ptr->valid & PNG_INFO_acTL)
   1465 +         png_write_acTL(png_ptr, info_ptr->num_frames, info_ptr->num_plays);
   1466 +#endif
   1467  #ifdef PNG_GAMMA_SUPPORTED
   1468  #  ifdef PNG_WRITE_gAMA_SUPPORTED
   1469        if ((info_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) == 0 &&
   1470 @@ -370,6 +374,11 @@
   1471        png_benign_error(png_ptr, "Wrote palette index exceeding num_palette");
   1472  #endif
   1473  
   1474 +#ifdef PNG_WRITE_APNG_SUPPORTED
   1475 +   if (png_ptr->num_frames_written != png_ptr->num_frames_to_write)
   1476 +      png_error(png_ptr, "Not enough frames written");
   1477 +#endif
   1478 +
   1479     /* See if user wants us to write information chunks */
   1480     if (info_ptr != NULL)
   1481     {
   1482 @@ -1461,6 +1470,43 @@
   1483  }
   1484  #endif
   1485  
   1486 +#ifdef PNG_WRITE_APNG_SUPPORTED
   1487 +void PNGAPI
   1488 +png_write_frame_head(png_structp png_ptr, png_infop info_ptr,
   1489 +    png_bytepp row_pointers, png_uint_32 width, png_uint_32 height,
   1490 +    png_uint_32 x_offset, png_uint_32 y_offset,
   1491 +    png_uint_16 delay_num, png_uint_16 delay_den, png_byte dispose_op,
   1492 +    png_byte blend_op)
   1493 +{
   1494 +    png_debug(1, "in png_write_frame_head");
   1495 +
   1496 +    /* there is a chance this has been set after png_write_info was called,
   1497 +    * so it would be set but not written. is there a way to be sure? */
   1498 +    if (!(info_ptr->valid & PNG_INFO_acTL))
   1499 +        png_error(png_ptr, "png_write_frame_head(): acTL not set");
   1500 +
   1501 +    png_write_reset(png_ptr);
   1502 +
   1503 +    png_write_reinit(png_ptr, info_ptr, width, height);
   1504 +
   1505 +    if ( !(png_ptr->num_frames_written == 0 &&
   1506 +           (png_ptr->apng_flags & PNG_FIRST_FRAME_HIDDEN) ) )
   1507 +        png_write_fcTL(png_ptr, width, height, x_offset, y_offset,
   1508 +                       delay_num, delay_den, dispose_op, blend_op);
   1509 +
   1510 +    PNG_UNUSED(row_pointers)
   1511 +}
   1512 +
   1513 +void PNGAPI
   1514 +png_write_frame_tail(png_structp png_ptr, png_infop info_ptr)
   1515 +{
   1516 +    png_debug(1, "in png_write_frame_tail");
   1517 +
   1518 +    png_ptr->num_frames_written++;
   1519 +
   1520 +    PNG_UNUSED(info_ptr)
   1521 +}
   1522 +#endif /* PNG_WRITE_APNG_SUPPORTED */
   1523  
   1524  #ifdef PNG_SIMPLIFIED_WRITE_SUPPORTED
   1525  /* Initialize the write structure - general purpose utility. */
   1526 diff -Naru libpng-1.6.37.org/pngwutil.c libpng-1.6.37/pngwutil.c
   1527 --- libpng-1.6.37.org/pngwutil.c	2019-04-19 07:21:37.402024748 +0900
   1528 +++ libpng-1.6.37/pngwutil.c	2019-04-19 07:22:37.867245682 +0900
   1529 @@ -821,6 +821,11 @@
   1530     /* Write the chunk */
   1531     png_write_complete_chunk(png_ptr, png_IHDR, buf, 13);
   1532  
   1533 +#ifdef PNG_WRITE_APNG_SUPPORTED
   1534 +   png_ptr->first_frame_width = width;
   1535 +   png_ptr->first_frame_height = height;
   1536 +#endif
   1537 +
   1538     if ((png_ptr->do_filter) == PNG_NO_FILTERS)
   1539     {
   1540        if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE ||
   1541 @@ -1002,8 +1007,17 @@
   1542                 optimize_cmf(data, png_image_size(png_ptr));
   1543  #endif
   1544  
   1545 -         if (size > 0)
   1546 -            png_write_complete_chunk(png_ptr, png_IDAT, data, size);
   1547 +            if (size > 0)
   1548 +#ifdef PNG_WRITE_APNG_SUPPORTED
   1549 +            {
   1550 +               if (png_ptr->num_frames_written == 0)
   1551 +#endif
   1552 +               png_write_complete_chunk(png_ptr, png_IDAT, data, size);
   1553 +#ifdef PNG_WRITE_APNG_SUPPORTED
   1554 +               else
   1555 +                  png_write_fdAT(png_ptr, data, size);
   1556 +            }
   1557 +#endif /* PNG_WRITE_APNG_SUPPORTED */
   1558           png_ptr->mode |= PNG_HAVE_IDAT;
   1559  
   1560           png_ptr->zstream.next_out = data;
   1561 @@ -1050,7 +1064,17 @@
   1562  #endif
   1563  
   1564           if (size > 0)
   1565 +#ifdef PNG_WRITE_APNG_SUPPORTED
   1566 +         {
   1567 +            if (png_ptr->num_frames_written == 0)
   1568 +#endif
   1569              png_write_complete_chunk(png_ptr, png_IDAT, data, size);
   1570 +#ifdef PNG_WRITE_APNG_SUPPORTED
   1571 +            else
   1572 +               png_write_fdAT(png_ptr, data, size);
   1573 +         }
   1574 +#endif /* PNG_WRITE_APNG_SUPPORTED */
   1575 +
   1576           png_ptr->zstream.avail_out = 0;
   1577           png_ptr->zstream.next_out = NULL;
   1578           png_ptr->mode |= PNG_HAVE_IDAT | PNG_AFTER_IDAT;
   1579 @@ -1885,6 +1909,82 @@
   1580  }
   1581  #endif
   1582  
   1583 +#ifdef PNG_WRITE_APNG_SUPPORTED
   1584 +void /* PRIVATE */
   1585 +png_write_acTL(png_structp png_ptr,
   1586 +    png_uint_32 num_frames, png_uint_32 num_plays)
   1587 +{
   1588 +    png_byte buf[8];
   1589 +
   1590 +    png_debug(1, "in png_write_acTL");
   1591 +
   1592 +    png_ptr->num_frames_to_write = num_frames;
   1593 +
   1594 +    if (png_ptr->apng_flags & PNG_FIRST_FRAME_HIDDEN)
   1595 +        num_frames--;
   1596 +
   1597 +    png_save_uint_32(buf, num_frames);
   1598 +    png_save_uint_32(buf + 4, num_plays);
   1599 +
   1600 +    png_write_complete_chunk(png_ptr, png_acTL, buf, (png_size_t)8);
   1601 +}
   1602 +
   1603 +void /* PRIVATE */
   1604 +png_write_fcTL(png_structp png_ptr, png_uint_32 width, png_uint_32 height,
   1605 +    png_uint_32 x_offset, png_uint_32 y_offset,
   1606 +    png_uint_16 delay_num, png_uint_16 delay_den, png_byte dispose_op,
   1607 +    png_byte blend_op)
   1608 +{
   1609 +    png_byte buf[26];
   1610 +
   1611 +    png_debug(1, "in png_write_fcTL");
   1612 +
   1613 +    if (png_ptr->num_frames_written == 0 && (x_offset != 0 || y_offset != 0))
   1614 +        png_error(png_ptr, "x and/or y offset for the first frame aren't 0");
   1615 +    if (png_ptr->num_frames_written == 0 &&
   1616 +        (width != png_ptr->first_frame_width ||
   1617 +         height != png_ptr->first_frame_height))
   1618 +        png_error(png_ptr, "width and/or height in the first frame's fcTL "
   1619 +                           "don't match the ones in IHDR");
   1620 +
   1621 +    /* more error checking */
   1622 +    png_ensure_fcTL_is_valid(png_ptr, width, height, x_offset, y_offset,
   1623 +                             delay_num, delay_den, dispose_op, blend_op);
   1624 +
   1625 +    png_save_uint_32(buf, png_ptr->next_seq_num);
   1626 +    png_save_uint_32(buf + 4, width);
   1627 +    png_save_uint_32(buf + 8, height);
   1628 +    png_save_uint_32(buf + 12, x_offset);
   1629 +    png_save_uint_32(buf + 16, y_offset);
   1630 +    png_save_uint_16(buf + 20, delay_num);
   1631 +    png_save_uint_16(buf + 22, delay_den);
   1632 +    buf[24] = dispose_op;
   1633 +    buf[25] = blend_op;
   1634 +
   1635 +    png_write_complete_chunk(png_ptr, png_fcTL, buf, (png_size_t)26);
   1636 +
   1637 +    png_ptr->next_seq_num++;
   1638 +}
   1639 +
   1640 +void /* PRIVATE */
   1641 +png_write_fdAT(png_structp png_ptr,
   1642 +    png_const_bytep data, png_size_t length)
   1643 +{
   1644 +    png_byte buf[4];
   1645 +
   1646 +    png_write_chunk_header(png_ptr, png_fdAT, (png_uint_32)(4 + length));
   1647 +
   1648 +    png_save_uint_32(buf, png_ptr->next_seq_num);
   1649 +    png_write_chunk_data(png_ptr, buf, 4);
   1650 +
   1651 +    png_write_chunk_data(png_ptr, data, length);
   1652 +
   1653 +    png_write_chunk_end(png_ptr);
   1654 +
   1655 +    png_ptr->next_seq_num++;
   1656 +}
   1657 +#endif /* PNG_WRITE_APNG_SUPPORTED */
   1658 +
   1659  /* Initializes the row writing capability of libpng */
   1660  void /* PRIVATE */
   1661  png_write_start_row(png_structrp png_ptr)
   1662 @@ -2778,4 +2878,39 @@
   1663     }
   1664  #endif /* WRITE_FLUSH */
   1665  }
   1666 +
   1667 +#ifdef PNG_WRITE_APNG_SUPPORTED
   1668 +void /* PRIVATE */
   1669 +png_write_reset(png_structp png_ptr)
   1670 +{
   1671 +    png_ptr->row_number = 0;
   1672 +    png_ptr->pass = 0;
   1673 +    png_ptr->mode &= ~PNG_HAVE_IDAT;
   1674 +}
   1675 +
   1676 +void /* PRIVATE */
   1677 +png_write_reinit(png_structp png_ptr, png_infop info_ptr,
   1678 +                 png_uint_32 width, png_uint_32 height)
   1679 +{
   1680 +    if (png_ptr->num_frames_written == 0 &&
   1681 +        (width != png_ptr->first_frame_width ||
   1682 +         height != png_ptr->first_frame_height))
   1683 +        png_error(png_ptr, "width and/or height in the first frame's fcTL "
   1684 +                           "don't match the ones in IHDR");
   1685 +    if (width > png_ptr->first_frame_width ||
   1686 +        height > png_ptr->first_frame_height)
   1687 +        png_error(png_ptr, "width and/or height for a frame greater than"
   1688 +                           "the ones in IHDR");
   1689 +
   1690 +    png_set_IHDR(png_ptr, info_ptr, width, height,
   1691 +                 info_ptr->bit_depth, info_ptr->color_type,
   1692 +                 info_ptr->interlace_type, info_ptr->compression_type,
   1693 +                 info_ptr->filter_type);
   1694 +
   1695 +    png_ptr->width = width;
   1696 +    png_ptr->height = height;
   1697 +    png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth, width);
   1698 +    png_ptr->usr_width = png_ptr->width;
   1699 +}
   1700 +#endif /* PNG_WRITE_APNG_SUPPORTED */
   1701  #endif /* WRITE */
   1702 diff -Naru libpng-1.6.37.org/scripts/symbols.def libpng-1.6.37/scripts/symbols.def
   1703 --- libpng-1.6.37.org/scripts/symbols.def	2019-04-19 07:21:37.405024710 +0900
   1704 +++ libpng-1.6.37/scripts/symbols.def	2019-04-19 07:22:37.856245823 +0900
   1705 @@ -253,3 +253,23 @@
   1706   png_set_eXIf @247
   1707   png_get_eXIf_1 @248
   1708   png_set_eXIf_1 @249
   1709 + png_get_acTL @250
   1710 + png_set_acTL @251
   1711 + png_get_num_frames @252
   1712 + png_get_num_plays @253
   1713 + png_get_next_frame_fcTL @254
   1714 + png_set_next_frame_fcTL @255
   1715 + png_get_next_frame_width @256
   1716 + png_get_next_frame_height @257
   1717 + png_get_next_frame_x_offset @258
   1718 + png_get_next_frame_y_offset @259
   1719 + png_get_next_frame_delay_num @260
   1720 + png_get_next_frame_delay_den @261
   1721 + png_get_next_frame_dispose_op @262
   1722 + png_get_next_frame_blend_op @263
   1723 + png_get_first_frame_is_hidden @264
   1724 + png_set_first_frame_is_hidden @265
   1725 + png_read_frame_head @266
   1726 + png_set_progressive_frame_fn @267
   1727 + png_write_frame_head @268
   1728 + png_write_frame_tail @269