wok-next diff libpng/stuff/patches/libpng-1.6.35-apng.patch @ rev 21072

Update Xorg packages
author Aleksej Bobylev <al.bobylev@gmail.com>
date Thu Dec 20 17:55:43 2018 +0200 (2018-12-20)
parents libpng16/stuff/patches/libpng-1.6.35-apng.patch@e7a485521d6a
children
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/libpng/stuff/patches/libpng-1.6.35-apng.patch	Thu Dec 20 17:55:43 2018 +0200
     1.3 @@ -0,0 +1,1728 @@
     1.4 +diff -Naru libpng-1.6.35.org/png.h libpng-1.6.35/png.h
     1.5 +--- libpng-1.6.35.org/png.h	2018-07-21 19:16:37.185142931 +0900
     1.6 ++++ libpng-1.6.35/png.h	2018-07-21 19:16:16.327364638 +0900
     1.7 +@@ -361,6 +361,10 @@
     1.8 + #   include "pnglibconf.h"
     1.9 + #endif
    1.10 + 
    1.11 ++#define PNG_APNG_SUPPORTED
    1.12 ++#define PNG_READ_APNG_SUPPORTED
    1.13 ++#define PNG_WRITE_APNG_SUPPORTED
    1.14 ++
    1.15 + #ifndef PNG_VERSION_INFO_ONLY
    1.16 + /* Machine specific configuration. */
    1.17 + #  include "pngconf.h"
    1.18 +@@ -456,6 +460,17 @@
    1.19 +  * See pngconf.h for base types that vary by machine/system
    1.20 +  */
    1.21 + 
    1.22 ++#ifdef PNG_APNG_SUPPORTED
    1.23 ++/* dispose_op flags from inside fcTL */
    1.24 ++#define PNG_DISPOSE_OP_NONE        0x00U
    1.25 ++#define PNG_DISPOSE_OP_BACKGROUND  0x01U
    1.26 ++#define PNG_DISPOSE_OP_PREVIOUS    0x02U
    1.27 ++
    1.28 ++/* blend_op flags from inside fcTL */
    1.29 ++#define PNG_BLEND_OP_SOURCE        0x00U
    1.30 ++#define PNG_BLEND_OP_OVER          0x01U
    1.31 ++#endif /* PNG_APNG_SUPPORTED */
    1.32 ++
    1.33 + /* This triggers a compiler error in png.c, if png.c and png.h
    1.34 +  * do not agree upon the version number.
    1.35 +  */
    1.36 +@@ -777,6 +792,10 @@
    1.37 + #define PNG_INFO_sCAL 0x4000U  /* ESR, 1.0.6 */
    1.38 + #define PNG_INFO_IDAT 0x8000U  /* ESR, 1.0.6 */
    1.39 + #define PNG_INFO_eXIf 0x10000U /* GR-P, 1.6.31 */
    1.40 ++#ifdef PNG_APNG_SUPPORTED
    1.41 ++#define PNG_INFO_acTL 0x20000U
    1.42 ++#define PNG_INFO_fcTL 0x40000U
    1.43 ++#endif
    1.44 + 
    1.45 + /* This is used for the transformation routines, as some of them
    1.46 +  * change these values for the row.  It also should enable using
    1.47 +@@ -814,6 +833,10 @@
    1.48 + #ifdef PNG_PROGRESSIVE_READ_SUPPORTED
    1.49 + typedef PNG_CALLBACK(void, *png_progressive_info_ptr, (png_structp, png_infop));
    1.50 + typedef PNG_CALLBACK(void, *png_progressive_end_ptr, (png_structp, png_infop));
    1.51 ++#ifdef PNG_APNG_SUPPORTED
    1.52 ++typedef PNG_CALLBACK(void, *png_progressive_frame_ptr, (png_structp,
    1.53 ++    png_uint_32));
    1.54 ++#endif
    1.55 + 
    1.56 + /* The following callback receives png_uint_32 row_number, int pass for the
    1.57 +  * png_bytep data of the row.  When transforming an interlaced image the
    1.58 +@@ -3257,6 +3280,74 @@
    1.59 + /*******************************************************************************
    1.60 +  *  END OF HARDWARE AND SOFTWARE OPTIONS
    1.61 +  ******************************************************************************/
    1.62 ++#ifdef PNG_APNG_SUPPORTED
    1.63 ++PNG_EXPORT(250, png_uint_32, png_get_acTL, (png_structp png_ptr,
    1.64 ++   png_infop info_ptr, png_uint_32 *num_frames, png_uint_32 *num_plays));
    1.65 ++
    1.66 ++PNG_EXPORT(251, png_uint_32, png_set_acTL, (png_structp png_ptr,
    1.67 ++   png_infop info_ptr, png_uint_32 num_frames, png_uint_32 num_plays));
    1.68 ++
    1.69 ++PNG_EXPORT(252, png_uint_32, png_get_num_frames, (png_structp png_ptr,
    1.70 ++   png_infop info_ptr));
    1.71 ++
    1.72 ++PNG_EXPORT(253, png_uint_32, png_get_num_plays, (png_structp png_ptr,
    1.73 ++   png_infop info_ptr));
    1.74 ++
    1.75 ++PNG_EXPORT(254, png_uint_32, png_get_next_frame_fcTL,
    1.76 ++   (png_structp png_ptr, png_infop info_ptr, png_uint_32 *width,
    1.77 ++   png_uint_32 *height, png_uint_32 *x_offset, png_uint_32 *y_offset,
    1.78 ++   png_uint_16 *delay_num, png_uint_16 *delay_den, png_byte *dispose_op,
    1.79 ++   png_byte *blend_op));
    1.80 ++
    1.81 ++PNG_EXPORT(255, png_uint_32, png_set_next_frame_fcTL,
    1.82 ++   (png_structp png_ptr, png_infop info_ptr, png_uint_32 width,
    1.83 ++   png_uint_32 height, png_uint_32 x_offset, png_uint_32 y_offset,
    1.84 ++   png_uint_16 delay_num, png_uint_16 delay_den, png_byte dispose_op,
    1.85 ++   png_byte blend_op));
    1.86 ++
    1.87 ++PNG_EXPORT(256, png_uint_32, png_get_next_frame_width,
    1.88 ++   (png_structp png_ptr, png_infop info_ptr));
    1.89 ++PNG_EXPORT(257, png_uint_32, png_get_next_frame_height,
    1.90 ++   (png_structp png_ptr, png_infop info_ptr));
    1.91 ++PNG_EXPORT(258, png_uint_32, png_get_next_frame_x_offset,
    1.92 ++   (png_structp png_ptr, png_infop info_ptr));
    1.93 ++PNG_EXPORT(259, png_uint_32, png_get_next_frame_y_offset,
    1.94 ++   (png_structp png_ptr, png_infop info_ptr));
    1.95 ++PNG_EXPORT(260, png_uint_16, png_get_next_frame_delay_num,
    1.96 ++   (png_structp png_ptr, png_infop info_ptr));
    1.97 ++PNG_EXPORT(261, png_uint_16, png_get_next_frame_delay_den,
    1.98 ++   (png_structp png_ptr, png_infop info_ptr));
    1.99 ++PNG_EXPORT(262, png_byte, png_get_next_frame_dispose_op,
   1.100 ++   (png_structp png_ptr, png_infop info_ptr));
   1.101 ++PNG_EXPORT(263, png_byte, png_get_next_frame_blend_op,
   1.102 ++   (png_structp png_ptr, png_infop info_ptr));
   1.103 ++PNG_EXPORT(264, png_byte, png_get_first_frame_is_hidden,
   1.104 ++   (png_structp png_ptr, png_infop info_ptr));
   1.105 ++PNG_EXPORT(265, png_uint_32, png_set_first_frame_is_hidden,
   1.106 ++   (png_structp png_ptr, png_infop info_ptr, png_byte is_hidden));
   1.107 ++
   1.108 ++#ifdef PNG_READ_APNG_SUPPORTED
   1.109 ++PNG_EXPORT(266, void, png_read_frame_head, (png_structp png_ptr,
   1.110 ++   png_infop info_ptr));
   1.111 ++#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
   1.112 ++PNG_EXPORT(267, void, png_set_progressive_frame_fn, (png_structp png_ptr,
   1.113 ++   png_progressive_frame_ptr frame_info_fn,
   1.114 ++   png_progressive_frame_ptr frame_end_fn));
   1.115 ++#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */
   1.116 ++#endif /* PNG_READ_APNG_SUPPORTED */
   1.117 ++
   1.118 ++#ifdef PNG_WRITE_APNG_SUPPORTED
   1.119 ++PNG_EXPORT(268, void, png_write_frame_head, (png_structp png_ptr,
   1.120 ++   png_infop info_ptr, png_bytepp row_pointers,
   1.121 ++   png_uint_32 width, png_uint_32 height,
   1.122 ++   png_uint_32 x_offset, png_uint_32 y_offset,
   1.123 ++   png_uint_16 delay_num, png_uint_16 delay_den, png_byte dispose_op,
   1.124 ++   png_byte blend_op));
   1.125 ++
   1.126 ++PNG_EXPORT(269, void, png_write_frame_tail, (png_structp png_ptr,
   1.127 ++   png_infop info_ptr));
   1.128 ++#endif /* PNG_WRITE_APNG_SUPPORTED */
   1.129 ++#endif /* PNG_APNG_SUPPORTED */
   1.130 + 
   1.131 + /* Maintainer: Put new public prototypes here ^, in libpng.3, in project
   1.132 +  * defs, and in scripts/symbols.def.
   1.133 +@@ -3266,7 +3357,11 @@
   1.134 +  * one to use is one more than this.)
   1.135 +  */
   1.136 + #ifdef PNG_EXPORT_LAST_ORDINAL
   1.137 ++#ifdef PNG_APNG_SUPPORTED
   1.138 ++  PNG_EXPORT_LAST_ORDINAL(269);
   1.139 ++#else
   1.140 +   PNG_EXPORT_LAST_ORDINAL(249);
   1.141 ++#endif /* PNG_APNG_SUPPORTED */
   1.142 + #endif
   1.143 + 
   1.144 + #ifdef __cplusplus
   1.145 +diff -Naru libpng-1.6.35.org/pngget.c libpng-1.6.35/pngget.c
   1.146 +--- libpng-1.6.35.org/pngget.c	2018-07-21 19:16:37.185142931 +0900
   1.147 ++++ libpng-1.6.35/pngget.c	2018-07-21 19:16:16.229356281 +0900
   1.148 +@@ -1246,4 +1246,166 @@
   1.149 + #  endif
   1.150 + #endif
   1.151 + 
   1.152 ++#ifdef PNG_APNG_SUPPORTED
   1.153 ++png_uint_32 PNGAPI
   1.154 ++png_get_acTL(png_structp png_ptr, png_infop info_ptr,
   1.155 ++             png_uint_32 *num_frames, png_uint_32 *num_plays)
   1.156 ++{
   1.157 ++    png_debug1(1, "in %s retrieval function", "acTL");
   1.158 ++
   1.159 ++    if (png_ptr != NULL && info_ptr != NULL &&
   1.160 ++        (info_ptr->valid & PNG_INFO_acTL) &&
   1.161 ++        num_frames != NULL && num_plays != NULL)
   1.162 ++    {
   1.163 ++        *num_frames = info_ptr->num_frames;
   1.164 ++        *num_plays = info_ptr->num_plays;
   1.165 ++        return (1);
   1.166 ++    }
   1.167 ++
   1.168 ++    return (0);
   1.169 ++}
   1.170 ++
   1.171 ++png_uint_32 PNGAPI
   1.172 ++png_get_num_frames(png_structp png_ptr, png_infop info_ptr)
   1.173 ++{
   1.174 ++    png_debug(1, "in png_get_num_frames()");
   1.175 ++
   1.176 ++    if (png_ptr != NULL && info_ptr != NULL)
   1.177 ++        return (info_ptr->num_frames);
   1.178 ++    return (0);
   1.179 ++}
   1.180 ++
   1.181 ++png_uint_32 PNGAPI
   1.182 ++png_get_num_plays(png_structp png_ptr, png_infop info_ptr)
   1.183 ++{
   1.184 ++    png_debug(1, "in png_get_num_plays()");
   1.185 ++
   1.186 ++    if (png_ptr != NULL && info_ptr != NULL)
   1.187 ++        return (info_ptr->num_plays);
   1.188 ++    return (0);
   1.189 ++}
   1.190 ++
   1.191 ++png_uint_32 PNGAPI
   1.192 ++png_get_next_frame_fcTL(png_structp png_ptr, png_infop info_ptr,
   1.193 ++             png_uint_32 *width, png_uint_32 *height,
   1.194 ++             png_uint_32 *x_offset, png_uint_32 *y_offset,
   1.195 ++             png_uint_16 *delay_num, png_uint_16 *delay_den,
   1.196 ++             png_byte *dispose_op, png_byte *blend_op)
   1.197 ++{
   1.198 ++    png_debug1(1, "in %s retrieval function", "fcTL");
   1.199 ++
   1.200 ++    if (png_ptr != NULL && info_ptr != NULL &&
   1.201 ++        (info_ptr->valid & PNG_INFO_fcTL) &&
   1.202 ++        width != NULL && height != NULL &&
   1.203 ++        x_offset != NULL && y_offset != NULL &&
   1.204 ++        delay_num != NULL && delay_den != NULL &&
   1.205 ++        dispose_op != NULL && blend_op != NULL)
   1.206 ++    {
   1.207 ++        *width = info_ptr->next_frame_width;
   1.208 ++        *height = info_ptr->next_frame_height;
   1.209 ++        *x_offset = info_ptr->next_frame_x_offset;
   1.210 ++        *y_offset = info_ptr->next_frame_y_offset;
   1.211 ++        *delay_num = info_ptr->next_frame_delay_num;
   1.212 ++        *delay_den = info_ptr->next_frame_delay_den;
   1.213 ++        *dispose_op = info_ptr->next_frame_dispose_op;
   1.214 ++        *blend_op = info_ptr->next_frame_blend_op;
   1.215 ++        return (1);
   1.216 ++    }
   1.217 ++
   1.218 ++    return (0);
   1.219 ++}
   1.220 ++
   1.221 ++png_uint_32 PNGAPI
   1.222 ++png_get_next_frame_width(png_structp png_ptr, png_infop info_ptr)
   1.223 ++{
   1.224 ++    png_debug(1, "in png_get_next_frame_width()");
   1.225 ++
   1.226 ++    if (png_ptr != NULL && info_ptr != NULL)
   1.227 ++        return (info_ptr->next_frame_width);
   1.228 ++    return (0);
   1.229 ++}
   1.230 ++
   1.231 ++png_uint_32 PNGAPI
   1.232 ++png_get_next_frame_height(png_structp png_ptr, png_infop info_ptr)
   1.233 ++{
   1.234 ++    png_debug(1, "in png_get_next_frame_height()");
   1.235 ++
   1.236 ++    if (png_ptr != NULL && info_ptr != NULL)
   1.237 ++        return (info_ptr->next_frame_height);
   1.238 ++    return (0);
   1.239 ++}
   1.240 ++
   1.241 ++png_uint_32 PNGAPI
   1.242 ++png_get_next_frame_x_offset(png_structp png_ptr, png_infop info_ptr)
   1.243 ++{
   1.244 ++    png_debug(1, "in png_get_next_frame_x_offset()");
   1.245 ++
   1.246 ++    if (png_ptr != NULL && info_ptr != NULL)
   1.247 ++        return (info_ptr->next_frame_x_offset);
   1.248 ++    return (0);
   1.249 ++}
   1.250 ++
   1.251 ++png_uint_32 PNGAPI
   1.252 ++png_get_next_frame_y_offset(png_structp png_ptr, png_infop info_ptr)
   1.253 ++{
   1.254 ++    png_debug(1, "in png_get_next_frame_y_offset()");
   1.255 ++
   1.256 ++    if (png_ptr != NULL && info_ptr != NULL)
   1.257 ++        return (info_ptr->next_frame_y_offset);
   1.258 ++    return (0);
   1.259 ++}
   1.260 ++
   1.261 ++png_uint_16 PNGAPI
   1.262 ++png_get_next_frame_delay_num(png_structp png_ptr, png_infop info_ptr)
   1.263 ++{
   1.264 ++    png_debug(1, "in png_get_next_frame_delay_num()");
   1.265 ++
   1.266 ++    if (png_ptr != NULL && info_ptr != NULL)
   1.267 ++        return (info_ptr->next_frame_delay_num);
   1.268 ++    return (0);
   1.269 ++}
   1.270 ++
   1.271 ++png_uint_16 PNGAPI
   1.272 ++png_get_next_frame_delay_den(png_structp png_ptr, png_infop info_ptr)
   1.273 ++{
   1.274 ++    png_debug(1, "in png_get_next_frame_delay_den()");
   1.275 ++
   1.276 ++    if (png_ptr != NULL && info_ptr != NULL)
   1.277 ++        return (info_ptr->next_frame_delay_den);
   1.278 ++    return (0);
   1.279 ++}
   1.280 ++
   1.281 ++png_byte PNGAPI
   1.282 ++png_get_next_frame_dispose_op(png_structp png_ptr, png_infop info_ptr)
   1.283 ++{
   1.284 ++    png_debug(1, "in png_get_next_frame_dispose_op()");
   1.285 ++
   1.286 ++    if (png_ptr != NULL && info_ptr != NULL)
   1.287 ++        return (info_ptr->next_frame_dispose_op);
   1.288 ++    return (0);
   1.289 ++}
   1.290 ++
   1.291 ++png_byte PNGAPI
   1.292 ++png_get_next_frame_blend_op(png_structp png_ptr, png_infop info_ptr)
   1.293 ++{
   1.294 ++    png_debug(1, "in png_get_next_frame_blend_op()");
   1.295 ++
   1.296 ++    if (png_ptr != NULL && info_ptr != NULL)
   1.297 ++        return (info_ptr->next_frame_blend_op);
   1.298 ++    return (0);
   1.299 ++}
   1.300 ++
   1.301 ++png_byte PNGAPI
   1.302 ++png_get_first_frame_is_hidden(png_structp png_ptr, png_infop info_ptr)
   1.303 ++{
   1.304 ++    png_debug(1, "in png_first_frame_is_hidden()");
   1.305 ++
   1.306 ++    if (png_ptr != NULL)
   1.307 ++       return (png_byte)(png_ptr->apng_flags & PNG_FIRST_FRAME_HIDDEN);
   1.308 ++
   1.309 ++    PNG_UNUSED(info_ptr)
   1.310 ++
   1.311 ++    return 0;
   1.312 ++}
   1.313 ++#endif /* PNG_APNG_SUPPORTED */
   1.314 + #endif /* READ || WRITE */
   1.315 +diff -Naru libpng-1.6.35.org/pnginfo.h libpng-1.6.35/pnginfo.h
   1.316 +--- libpng-1.6.35.org/pnginfo.h	2018-07-21 19:16:37.185142931 +0900
   1.317 ++++ libpng-1.6.35/pnginfo.h	2018-07-21 19:16:16.228356197 +0900
   1.318 +@@ -263,5 +263,18 @@
   1.319 +    png_bytepp row_pointers;        /* the image bits */
   1.320 + #endif
   1.321 + 
   1.322 ++#ifdef PNG_APNG_SUPPORTED
   1.323 ++   png_uint_32 num_frames; /* including default image */
   1.324 ++   png_uint_32 num_plays;
   1.325 ++   png_uint_32 next_frame_width;
   1.326 ++   png_uint_32 next_frame_height;
   1.327 ++   png_uint_32 next_frame_x_offset;
   1.328 ++   png_uint_32 next_frame_y_offset;
   1.329 ++   png_uint_16 next_frame_delay_num;
   1.330 ++   png_uint_16 next_frame_delay_den;
   1.331 ++   png_byte next_frame_dispose_op;
   1.332 ++   png_byte next_frame_blend_op;
   1.333 ++#endif
   1.334 ++
   1.335 + };
   1.336 + #endif /* PNGINFO_H */
   1.337 +diff -Naru libpng-1.6.35.org/pngpread.c libpng-1.6.35/pngpread.c
   1.338 +--- libpng-1.6.35.org/pngpread.c	2018-07-21 19:16:37.185142931 +0900
   1.339 ++++ libpng-1.6.35/pngpread.c	2018-07-21 19:16:16.228356197 +0900
   1.340 +@@ -195,6 +195,106 @@
   1.341 + 
   1.342 +    chunk_name = png_ptr->chunk_name;
   1.343 + 
   1.344 ++#ifdef PNG_READ_APNG_SUPPORTED
   1.345 ++   if (png_ptr->num_frames_read > 0 &&
   1.346 ++       png_ptr->num_frames_read < info_ptr->num_frames)
   1.347 ++   {
   1.348 ++      if (chunk_name == png_IDAT)
   1.349 ++      {
   1.350 ++         /* Discard trailing IDATs for the first frame */
   1.351 ++         if (png_ptr->mode & PNG_HAVE_fcTL || png_ptr->num_frames_read > 1)
   1.352 ++            png_error(png_ptr, "out of place IDAT");
   1.353 ++
   1.354 ++         if (png_ptr->push_length + 4 > png_ptr->buffer_size)
   1.355 ++         {
   1.356 ++            png_push_save_buffer(png_ptr);
   1.357 ++            return;
   1.358 ++         }
   1.359 ++
   1.360 ++         png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
   1.361 ++         return;
   1.362 ++      }
   1.363 ++      else if (chunk_name == png_fdAT)
   1.364 ++      {
   1.365 ++         if (png_ptr->buffer_size < 4)
   1.366 ++         {
   1.367 ++            png_push_save_buffer(png_ptr);
   1.368 ++            return;
   1.369 ++         }
   1.370 ++
   1.371 ++         png_ensure_sequence_number(png_ptr, 4);
   1.372 ++
   1.373 ++         if (!(png_ptr->mode & PNG_HAVE_fcTL))
   1.374 ++         {
   1.375 ++            /* Discard trailing fdATs for frames other than the first */
   1.376 ++            if (png_ptr->num_frames_read < 2)
   1.377 ++               png_error(png_ptr, "out of place fdAT");
   1.378 ++
   1.379 ++            if (png_ptr->push_length + 4 > png_ptr->buffer_size)
   1.380 ++            {
   1.381 ++               png_push_save_buffer(png_ptr);
   1.382 ++               return;
   1.383 ++            }
   1.384 ++
   1.385 ++            png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
   1.386 ++            return;
   1.387 ++         }
   1.388 ++
   1.389 ++         else
   1.390 ++         {
   1.391 ++            /* frame data follows */
   1.392 ++            png_ptr->idat_size = png_ptr->push_length - 4;
   1.393 ++            png_ptr->mode |= PNG_HAVE_IDAT;
   1.394 ++            png_ptr->process_mode = PNG_READ_IDAT_MODE;
   1.395 ++
   1.396 ++            return;
   1.397 ++         }
   1.398 ++      }
   1.399 ++
   1.400 ++      else if (chunk_name == png_fcTL)
   1.401 ++      {
   1.402 ++         if (png_ptr->push_length + 4 > png_ptr->buffer_size)
   1.403 ++         {
   1.404 ++            png_push_save_buffer(png_ptr);
   1.405 ++            return;
   1.406 ++         }
   1.407 ++
   1.408 ++         png_read_reset(png_ptr);
   1.409 ++         png_ptr->mode &= ~PNG_HAVE_fcTL;
   1.410 ++
   1.411 ++         png_handle_fcTL(png_ptr, info_ptr, png_ptr->push_length);
   1.412 ++
   1.413 ++         if (!(png_ptr->mode & PNG_HAVE_fcTL))
   1.414 ++            png_error(png_ptr, "missing required fcTL chunk");
   1.415 ++
   1.416 ++         png_read_reinit(png_ptr, info_ptr);
   1.417 ++         png_progressive_read_reset(png_ptr);
   1.418 ++
   1.419 ++         if (png_ptr->frame_info_fn != NULL)
   1.420 ++            (*(png_ptr->frame_info_fn))(png_ptr, png_ptr->num_frames_read);
   1.421 ++
   1.422 ++         png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
   1.423 ++
   1.424 ++         return;
   1.425 ++      }
   1.426 ++
   1.427 ++      else
   1.428 ++      {
   1.429 ++         if (png_ptr->push_length + 4 > png_ptr->buffer_size)
   1.430 ++         {
   1.431 ++            png_push_save_buffer(png_ptr);
   1.432 ++            return;
   1.433 ++         }
   1.434 ++         png_warning(png_ptr, "Skipped (ignored) a chunk "
   1.435 ++                              "between APNG chunks");
   1.436 ++         png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
   1.437 ++         return;
   1.438 ++      }
   1.439 ++
   1.440 ++      return;
   1.441 ++   }
   1.442 ++#endif /* PNG_READ_APNG_SUPPORTED */
   1.443 ++
   1.444 +    if (chunk_name == png_IDAT)
   1.445 +    {
   1.446 +       if ((png_ptr->mode & PNG_AFTER_IDAT) != 0)
   1.447 +@@ -261,6 +361,9 @@
   1.448 + 
   1.449 +    else if (chunk_name == png_IDAT)
   1.450 +    {
   1.451 ++#ifdef PNG_READ_APNG_SUPPORTED
   1.452 ++      png_have_info(png_ptr, info_ptr);
   1.453 ++#endif
   1.454 +       png_ptr->idat_size = png_ptr->push_length;
   1.455 +       png_ptr->process_mode = PNG_READ_IDAT_MODE;
   1.456 +       png_push_have_info(png_ptr, info_ptr);
   1.457 +@@ -406,6 +509,30 @@
   1.458 +       png_handle_iTXt(png_ptr, info_ptr, png_ptr->push_length);
   1.459 +    }
   1.460 + #endif
   1.461 ++#ifdef PNG_READ_APNG_SUPPORTED
   1.462 ++   else if (chunk_name == png_acTL)
   1.463 ++   {
   1.464 ++      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
   1.465 ++      {
   1.466 ++         png_push_save_buffer(png_ptr);
   1.467 ++         return;
   1.468 ++      }
   1.469 ++
   1.470 ++      png_handle_acTL(png_ptr, info_ptr, png_ptr->push_length);
   1.471 ++   }
   1.472 ++
   1.473 ++   else if (chunk_name == png_fcTL)
   1.474 ++   {
   1.475 ++      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
   1.476 ++      {
   1.477 ++         png_push_save_buffer(png_ptr);
   1.478 ++         return;
   1.479 ++      }
   1.480 ++
   1.481 ++      png_handle_fcTL(png_ptr, info_ptr, png_ptr->push_length);
   1.482 ++   }
   1.483 ++
   1.484 ++#endif /* PNG_READ_APNG_SUPPORTED */
   1.485 + 
   1.486 +    else
   1.487 +    {
   1.488 +@@ -539,7 +666,11 @@
   1.489 +       png_byte chunk_tag[4];
   1.490 + 
   1.491 +       /* TODO: this code can be commoned up with the same code in push_read */
   1.492 ++#ifdef PNG_READ_APNG_SUPPORTED
   1.493 ++      PNG_PUSH_SAVE_BUFFER_IF_LT(12)
   1.494 ++#else
   1.495 +       PNG_PUSH_SAVE_BUFFER_IF_LT(8)
   1.496 ++#endif
   1.497 +       png_push_fill_buffer(png_ptr, chunk_length, 4);
   1.498 +       png_ptr->push_length = png_get_uint_31(png_ptr, chunk_length);
   1.499 +       png_reset_crc(png_ptr);
   1.500 +@@ -547,17 +678,64 @@
   1.501 +       png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(chunk_tag);
   1.502 +       png_ptr->mode |= PNG_HAVE_CHUNK_HEADER;
   1.503 + 
   1.504 ++#ifdef PNG_READ_APNG_SUPPORTED
   1.505 ++      if (png_ptr->chunk_name != png_fdAT && png_ptr->num_frames_read > 0)
   1.506 ++      {
   1.507 ++          if (png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED)
   1.508 ++          {
   1.509 ++              png_ptr->process_mode = PNG_READ_CHUNK_MODE;
   1.510 ++              if (png_ptr->frame_end_fn != NULL)
   1.511 ++                 (*(png_ptr->frame_end_fn))(png_ptr, png_ptr->num_frames_read);
   1.512 ++              png_ptr->num_frames_read++;
   1.513 ++              return;
   1.514 ++          }
   1.515 ++          else
   1.516 ++          {
   1.517 ++              if (png_ptr->chunk_name == png_IEND)
   1.518 ++                  png_error(png_ptr, "Not enough image data");
   1.519 ++              if (png_ptr->push_length + 4 > png_ptr->buffer_size)
   1.520 ++              {
   1.521 ++                 png_push_save_buffer(png_ptr);
   1.522 ++                 return;
   1.523 ++              }
   1.524 ++              png_warning(png_ptr, "Skipping (ignoring) a chunk between "
   1.525 ++                                   "APNG chunks");
   1.526 ++              png_crc_finish(png_ptr, png_ptr->push_length);
   1.527 ++              png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
   1.528 ++              return;
   1.529 ++          }
   1.530 ++      }
   1.531 ++      else
   1.532 ++#endif
   1.533 ++#ifdef PNG_READ_APNG_SUPPORTED
   1.534 ++      if (png_ptr->chunk_name != png_IDAT && png_ptr->num_frames_read == 0)
   1.535 ++#else
   1.536 +       if (png_ptr->chunk_name != png_IDAT)
   1.537 ++#endif
   1.538 +       {
   1.539 +          png_ptr->process_mode = PNG_READ_CHUNK_MODE;
   1.540 + 
   1.541 +          if ((png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED) == 0)
   1.542 +             png_error(png_ptr, "Not enough compressed data");
   1.543 + 
   1.544 ++#ifdef PNG_READ_APNG_SUPPORTED
   1.545 ++         if (png_ptr->frame_end_fn != NULL)
   1.546 ++            (*(png_ptr->frame_end_fn))(png_ptr, png_ptr->num_frames_read);
   1.547 ++         png_ptr->num_frames_read++;
   1.548 ++#endif
   1.549 ++
   1.550 +          return;
   1.551 +       }
   1.552 + 
   1.553 +       png_ptr->idat_size = png_ptr->push_length;
   1.554 ++
   1.555 ++#ifdef PNG_READ_APNG_SUPPORTED
   1.556 ++      if (png_ptr->num_frames_read > 0)
   1.557 ++      {
   1.558 ++         png_ensure_sequence_number(png_ptr, 4);
   1.559 ++         png_ptr->idat_size -= 4;
   1.560 ++      }
   1.561 ++#endif
   1.562 +    }
   1.563 + 
   1.564 +    if (png_ptr->idat_size != 0 && png_ptr->save_buffer_size != 0)
   1.565 +@@ -631,6 +809,15 @@
   1.566 +    if (!(buffer_length > 0) || buffer == NULL)
   1.567 +       png_error(png_ptr, "No IDAT data (internal error)");
   1.568 + 
   1.569 ++#ifdef PNG_READ_APNG_SUPPORTED
   1.570 ++   /* If the app is not APNG-aware, decode only the first frame */
   1.571 ++   if (!(png_ptr->apng_flags & PNG_APNG_APP) && png_ptr->num_frames_read > 0)
   1.572 ++   {
   1.573 ++     png_ptr->flags |= PNG_FLAG_ZSTREAM_ENDED;
   1.574 ++     return;
   1.575 ++   }
   1.576 ++#endif
   1.577 ++
   1.578 +    /* This routine must process all the data it has been given
   1.579 +     * before returning, calling the row callback as required to
   1.580 +     * handle the uncompressed results.
   1.581 +@@ -1085,6 +1272,18 @@
   1.582 +    png_set_read_fn(png_ptr, progressive_ptr, png_push_fill_buffer);
   1.583 + }
   1.584 + 
   1.585 ++#ifdef PNG_READ_APNG_SUPPORTED
   1.586 ++void PNGAPI
   1.587 ++png_set_progressive_frame_fn(png_structp png_ptr,
   1.588 ++   png_progressive_frame_ptr frame_info_fn,
   1.589 ++   png_progressive_frame_ptr frame_end_fn)
   1.590 ++{
   1.591 ++   png_ptr->frame_info_fn = frame_info_fn;
   1.592 ++   png_ptr->frame_end_fn = frame_end_fn;
   1.593 ++   png_ptr->apng_flags |= PNG_APNG_APP;
   1.594 ++}
   1.595 ++#endif
   1.596 ++
   1.597 + png_voidp PNGAPI
   1.598 + png_get_progressive_ptr(png_const_structrp png_ptr)
   1.599 + {
   1.600 +diff -Naru libpng-1.6.35.org/pngpriv.h libpng-1.6.35/pngpriv.h
   1.601 +--- libpng-1.6.35.org/pngpriv.h	2018-07-21 19:16:37.185142931 +0900
   1.602 ++++ libpng-1.6.35/pngpriv.h	2018-07-21 19:16:16.226356026 +0900
   1.603 +@@ -634,6 +634,10 @@
   1.604 + #define PNG_HAVE_CHUNK_AFTER_IDAT 0x2000U /* Have another chunk after IDAT */
   1.605 +                    /*             0x4000U (unused) */
   1.606 + #define PNG_IS_READ_STRUCT        0x8000U /* Else is a write struct */
   1.607 ++#ifdef PNG_APNG_SUPPORTED
   1.608 ++#define PNG_HAVE_acTL            0x10000U
   1.609 ++#define PNG_HAVE_fcTL            0x20000U
   1.610 ++#endif
   1.611 + 
   1.612 + /* Flags for the transformations the PNG library does on the image data */
   1.613 + #define PNG_BGR                 0x0001U
   1.614 +@@ -870,6 +874,16 @@
   1.615 + #define png_tRNS PNG_U32(116,  82,  78,  83)
   1.616 + #define png_zTXt PNG_U32(122,  84,  88, 116)
   1.617 + 
   1.618 ++#ifdef PNG_APNG_SUPPORTED
   1.619 ++#define png_acTL PNG_U32( 97,  99,  84,  76)
   1.620 ++#define png_fcTL PNG_U32(102,  99,  84,  76)
   1.621 ++#define png_fdAT PNG_U32(102, 100,  65,  84)
   1.622 ++
   1.623 ++/* For png_struct.apng_flags: */
   1.624 ++#define PNG_FIRST_FRAME_HIDDEN       0x0001U
   1.625 ++#define PNG_APNG_APP                 0x0002U
   1.626 ++#endif
   1.627 ++
   1.628 + /* The following will work on (signed char*) strings, whereas the get_uint_32
   1.629 +  * macro will fail on top-bit-set values because of the sign extension.
   1.630 +  */
   1.631 +@@ -1641,6 +1655,47 @@
   1.632 +     */
   1.633 + #endif
   1.634 + 
   1.635 ++#ifdef PNG_APNG_SUPPORTED
   1.636 ++PNG_INTERNAL_FUNCTION(void,png_ensure_fcTL_is_valid,(png_structp png_ptr,
   1.637 ++   png_uint_32 width, png_uint_32 height,
   1.638 ++   png_uint_32 x_offset, png_uint_32 y_offset,
   1.639 ++   png_uint_16 delay_num, png_uint_16 delay_den,
   1.640 ++   png_byte dispose_op, png_byte blend_op), PNG_EMPTY);
   1.641 ++
   1.642 ++#ifdef PNG_READ_APNG_SUPPORTED
   1.643 ++PNG_INTERNAL_FUNCTION(void,png_handle_acTL,(png_structp png_ptr, png_infop info_ptr,
   1.644 ++   png_uint_32 length),PNG_EMPTY);
   1.645 ++PNG_INTERNAL_FUNCTION(void,png_handle_fcTL,(png_structp png_ptr, png_infop info_ptr,
   1.646 ++   png_uint_32 length),PNG_EMPTY);
   1.647 ++PNG_INTERNAL_FUNCTION(void,png_handle_fdAT,(png_structp png_ptr, png_infop info_ptr,
   1.648 ++   png_uint_32 length),PNG_EMPTY);
   1.649 ++PNG_INTERNAL_FUNCTION(void,png_have_info,(png_structp png_ptr, png_infop info_ptr),PNG_EMPTY);
   1.650 ++PNG_INTERNAL_FUNCTION(void,png_ensure_sequence_number,(png_structp png_ptr,
   1.651 ++   png_uint_32 length),PNG_EMPTY);
   1.652 ++PNG_INTERNAL_FUNCTION(void,png_read_reset,(png_structp png_ptr),PNG_EMPTY);
   1.653 ++PNG_INTERNAL_FUNCTION(void,png_read_reinit,(png_structp png_ptr,
   1.654 ++   png_infop info_ptr),PNG_EMPTY);
   1.655 ++#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
   1.656 ++PNG_INTERNAL_FUNCTION(void,png_progressive_read_reset,(png_structp png_ptr),PNG_EMPTY);
   1.657 ++#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */
   1.658 ++#endif /* PNG_READ_APNG_SUPPORTED */
   1.659 ++
   1.660 ++#ifdef PNG_WRITE_APNG_SUPPORTED
   1.661 ++PNG_INTERNAL_FUNCTION(void,png_write_acTL,(png_structp png_ptr,
   1.662 ++   png_uint_32 num_frames, png_uint_32 num_plays),PNG_EMPTY);
   1.663 ++PNG_INTERNAL_FUNCTION(void,png_write_fcTL,(png_structp png_ptr,
   1.664 ++   png_uint_32 width, png_uint_32 height,
   1.665 ++   png_uint_32 x_offset, png_uint_32 y_offset,
   1.666 ++   png_uint_16 delay_num, png_uint_16 delay_den,
   1.667 ++   png_byte dispose_op, png_byte blend_op),PNG_EMPTY);
   1.668 ++PNG_INTERNAL_FUNCTION(void,png_write_fdAT,(png_structp png_ptr,
   1.669 ++   png_const_bytep data, png_size_t length),PNG_EMPTY);
   1.670 ++PNG_INTERNAL_FUNCTION(void,png_write_reset,(png_structp png_ptr),PNG_EMPTY);
   1.671 ++PNG_INTERNAL_FUNCTION(void,png_write_reinit,(png_structp png_ptr,
   1.672 ++   png_infop info_ptr, png_uint_32 width, png_uint_32 height),PNG_EMPTY);
   1.673 ++#endif /* PNG_WRITE_APNG_SUPPORTED */
   1.674 ++#endif /* PNG_APNG_SUPPORTED */
   1.675 ++
   1.676 + /* Added at libpng version 1.4.0 */
   1.677 + #ifdef PNG_COLORSPACE_SUPPORTED
   1.678 + /* These internal functions are for maintaining the colorspace structure within
   1.679 +diff -Naru libpng-1.6.35.org/pngread.c libpng-1.6.35/pngread.c
   1.680 +--- libpng-1.6.35.org/pngread.c	2018-07-21 19:16:37.186143016 +0900
   1.681 ++++ libpng-1.6.35/pngread.c	2018-07-21 19:16:16.224355855 +0900
   1.682 +@@ -161,6 +161,9 @@
   1.683 + 
   1.684 +       else if (chunk_name == png_IDAT)
   1.685 +       {
   1.686 ++#ifdef PNG_READ_APNG_SUPPORTED
   1.687 ++         png_have_info(png_ptr, info_ptr);
   1.688 ++#endif
   1.689 +          png_ptr->idat_size = length;
   1.690 +          break;
   1.691 +       }
   1.692 +@@ -255,6 +258,17 @@
   1.693 +          png_handle_iTXt(png_ptr, info_ptr, length);
   1.694 + #endif
   1.695 + 
   1.696 ++#ifdef PNG_READ_APNG_SUPPORTED
   1.697 ++      else if (chunk_name == png_acTL)
   1.698 ++         png_handle_acTL(png_ptr, info_ptr, length);
   1.699 ++
   1.700 ++      else if (chunk_name == png_fcTL)
   1.701 ++         png_handle_fcTL(png_ptr, info_ptr, length);
   1.702 ++
   1.703 ++      else if (chunk_name == png_fdAT)
   1.704 ++         png_handle_fdAT(png_ptr, info_ptr, length);
   1.705 ++#endif
   1.706 ++
   1.707 +       else
   1.708 +          png_handle_unknown(png_ptr, info_ptr, length,
   1.709 +              PNG_HANDLE_CHUNK_AS_DEFAULT);
   1.710 +@@ -262,6 +276,72 @@
   1.711 + }
   1.712 + #endif /* SEQUENTIAL_READ */
   1.713 + 
   1.714 ++#ifdef PNG_READ_APNG_SUPPORTED
   1.715 ++void PNGAPI
   1.716 ++png_read_frame_head(png_structp png_ptr, png_infop info_ptr)
   1.717 ++{
   1.718 ++    png_byte have_chunk_after_DAT; /* after IDAT or after fdAT */
   1.719 ++
   1.720 ++    png_debug(0, "Reading frame head");
   1.721 ++
   1.722 ++    if (!(png_ptr->mode & PNG_HAVE_acTL))
   1.723 ++        png_error(png_ptr, "attempt to png_read_frame_head() but "
   1.724 ++                           "no acTL present");
   1.725 ++
   1.726 ++    /* do nothing for the main IDAT */
   1.727 ++    if (png_ptr->num_frames_read == 0)
   1.728 ++        return;
   1.729 ++
   1.730 ++    png_read_reset(png_ptr);
   1.731 ++    png_ptr->flags &= ~PNG_FLAG_ROW_INIT;
   1.732 ++    png_ptr->mode &= ~PNG_HAVE_fcTL;
   1.733 ++
   1.734 ++    have_chunk_after_DAT = 0;
   1.735 ++    for (;;)
   1.736 ++    {
   1.737 ++        png_uint_32 length = png_read_chunk_header(png_ptr);
   1.738 ++
   1.739 ++        if (png_ptr->chunk_name == png_IDAT)
   1.740 ++        {
   1.741 ++            /* discard trailing IDATs for the first frame */
   1.742 ++            if (have_chunk_after_DAT || png_ptr->num_frames_read > 1)
   1.743 ++                png_error(png_ptr, "png_read_frame_head(): out of place IDAT");
   1.744 ++            png_crc_finish(png_ptr, length);
   1.745 ++        }
   1.746 ++
   1.747 ++        else if (png_ptr->chunk_name == png_fcTL)
   1.748 ++        {
   1.749 ++            png_handle_fcTL(png_ptr, info_ptr, length);
   1.750 ++            have_chunk_after_DAT = 1;
   1.751 ++        }
   1.752 ++
   1.753 ++        else if (png_ptr->chunk_name == png_fdAT)
   1.754 ++        {
   1.755 ++            png_ensure_sequence_number(png_ptr, length);
   1.756 ++
   1.757 ++            /* discard trailing fdATs for frames other than the first */
   1.758 ++            if (!have_chunk_after_DAT && png_ptr->num_frames_read > 1)
   1.759 ++                png_crc_finish(png_ptr, length - 4);
   1.760 ++            else if(png_ptr->mode & PNG_HAVE_fcTL)
   1.761 ++            {
   1.762 ++                png_ptr->idat_size = length - 4;
   1.763 ++                png_ptr->mode |= PNG_HAVE_IDAT;
   1.764 ++
   1.765 ++                break;
   1.766 ++            }
   1.767 ++            else
   1.768 ++                png_error(png_ptr, "png_read_frame_head(): out of place fdAT");
   1.769 ++        }
   1.770 ++        else
   1.771 ++        {
   1.772 ++            png_warning(png_ptr, "Skipped (ignored) a chunk "
   1.773 ++                                 "between APNG chunks");
   1.774 ++            png_crc_finish(png_ptr, length);
   1.775 ++        }
   1.776 ++    }
   1.777 ++}
   1.778 ++#endif /* PNG_READ_APNG_SUPPORTED */
   1.779 ++
   1.780 + /* Optional call to update the users info_ptr structure */
   1.781 + void PNGAPI
   1.782 + png_read_update_info(png_structrp png_ptr, png_inforp info_ptr)
   1.783 +diff -Naru libpng-1.6.35.org/pngrutil.c libpng-1.6.35/pngrutil.c
   1.784 +--- libpng-1.6.35.org/pngrutil.c	2018-07-21 19:16:37.187143101 +0900
   1.785 ++++ libpng-1.6.35/pngrutil.c	2018-07-21 19:16:16.220355514 +0900
   1.786 +@@ -865,6 +865,11 @@
   1.787 +    filter_type = buf[11];
   1.788 +    interlace_type = buf[12];
   1.789 + 
   1.790 ++#ifdef PNG_READ_APNG_SUPPORTED
   1.791 ++   png_ptr->first_frame_width = width;
   1.792 ++   png_ptr->first_frame_height = height;
   1.793 ++#endif
   1.794 ++
   1.795 +    /* Set internal variables */
   1.796 +    png_ptr->width = width;
   1.797 +    png_ptr->height = height;
   1.798 +@@ -2858,6 +2863,179 @@
   1.799 + }
   1.800 + #endif
   1.801 + 
   1.802 ++#ifdef PNG_READ_APNG_SUPPORTED
   1.803 ++void /* PRIVATE */
   1.804 ++png_handle_acTL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
   1.805 ++{
   1.806 ++    png_byte data[8];
   1.807 ++    png_uint_32 num_frames;
   1.808 ++    png_uint_32 num_plays;
   1.809 ++    png_uint_32 didSet;
   1.810 ++
   1.811 ++    png_debug(1, "in png_handle_acTL");
   1.812 ++
   1.813 ++    if (!(png_ptr->mode & PNG_HAVE_IHDR))
   1.814 ++    {
   1.815 ++        png_error(png_ptr, "Missing IHDR before acTL");
   1.816 ++    }
   1.817 ++    else if (png_ptr->mode & PNG_HAVE_IDAT)
   1.818 ++    {
   1.819 ++        png_warning(png_ptr, "Invalid acTL after IDAT skipped");
   1.820 ++        png_crc_finish(png_ptr, length);
   1.821 ++        return;
   1.822 ++    }
   1.823 ++    else if (png_ptr->mode & PNG_HAVE_acTL)
   1.824 ++    {
   1.825 ++        png_warning(png_ptr, "Duplicate acTL skipped");
   1.826 ++        png_crc_finish(png_ptr, length);
   1.827 ++        return;
   1.828 ++    }
   1.829 ++    else if (length != 8)
   1.830 ++    {
   1.831 ++        png_warning(png_ptr, "acTL with invalid length skipped");
   1.832 ++        png_crc_finish(png_ptr, length);
   1.833 ++        return;
   1.834 ++    }
   1.835 ++
   1.836 ++    png_crc_read(png_ptr, data, 8);
   1.837 ++    png_crc_finish(png_ptr, 0);
   1.838 ++
   1.839 ++    num_frames = png_get_uint_31(png_ptr, data);
   1.840 ++    num_plays = png_get_uint_31(png_ptr, data + 4);
   1.841 ++
   1.842 ++    /* the set function will do error checking on num_frames */
   1.843 ++    didSet = png_set_acTL(png_ptr, info_ptr, num_frames, num_plays);
   1.844 ++    if(didSet)
   1.845 ++        png_ptr->mode |= PNG_HAVE_acTL;
   1.846 ++}
   1.847 ++
   1.848 ++void /* PRIVATE */
   1.849 ++png_handle_fcTL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
   1.850 ++{
   1.851 ++    png_byte data[22];
   1.852 ++    png_uint_32 width;
   1.853 ++    png_uint_32 height;
   1.854 ++    png_uint_32 x_offset;
   1.855 ++    png_uint_32 y_offset;
   1.856 ++    png_uint_16 delay_num;
   1.857 ++    png_uint_16 delay_den;
   1.858 ++    png_byte dispose_op;
   1.859 ++    png_byte blend_op;
   1.860 ++
   1.861 ++    png_debug(1, "in png_handle_fcTL");
   1.862 ++
   1.863 ++    png_ensure_sequence_number(png_ptr, length);
   1.864 ++
   1.865 ++    if (!(png_ptr->mode & PNG_HAVE_IHDR))
   1.866 ++    {
   1.867 ++        png_error(png_ptr, "Missing IHDR before fcTL");
   1.868 ++    }
   1.869 ++    else if (png_ptr->mode & PNG_HAVE_IDAT)
   1.870 ++    {
   1.871 ++        /* for any frames other then the first this message may be misleading,
   1.872 ++        * but correct. PNG_HAVE_IDAT is unset before the frame head is read
   1.873 ++        * i can't think of a better message */
   1.874 ++        png_warning(png_ptr, "Invalid fcTL after IDAT skipped");
   1.875 ++        png_crc_finish(png_ptr, length-4);
   1.876 ++        return;
   1.877 ++    }
   1.878 ++    else if (png_ptr->mode & PNG_HAVE_fcTL)
   1.879 ++    {
   1.880 ++        png_warning(png_ptr, "Duplicate fcTL within one frame skipped");
   1.881 ++        png_crc_finish(png_ptr, length-4);
   1.882 ++        return;
   1.883 ++    }
   1.884 ++    else if (length != 26)
   1.885 ++    {
   1.886 ++        png_warning(png_ptr, "fcTL with invalid length skipped");
   1.887 ++        png_crc_finish(png_ptr, length-4);
   1.888 ++        return;
   1.889 ++    }
   1.890 ++
   1.891 ++    png_crc_read(png_ptr, data, 22);
   1.892 ++    png_crc_finish(png_ptr, 0);
   1.893 ++
   1.894 ++    width = png_get_uint_31(png_ptr, data);
   1.895 ++    height = png_get_uint_31(png_ptr, data + 4);
   1.896 ++    x_offset = png_get_uint_31(png_ptr, data + 8);
   1.897 ++    y_offset = png_get_uint_31(png_ptr, data + 12);
   1.898 ++    delay_num = png_get_uint_16(data + 16);
   1.899 ++    delay_den = png_get_uint_16(data + 18);
   1.900 ++    dispose_op = data[20];
   1.901 ++    blend_op = data[21];
   1.902 ++
   1.903 ++    if (png_ptr->num_frames_read == 0 && (x_offset != 0 || y_offset != 0))
   1.904 ++    {
   1.905 ++        png_warning(png_ptr, "fcTL for the first frame must have zero offset");
   1.906 ++        return;
   1.907 ++    }
   1.908 ++
   1.909 ++    if (info_ptr != NULL)
   1.910 ++    {
   1.911 ++        if (png_ptr->num_frames_read == 0 &&
   1.912 ++            (width != info_ptr->width || height != info_ptr->height))
   1.913 ++        {
   1.914 ++            png_warning(png_ptr, "size in first frame's fcTL must match "
   1.915 ++                               "the size in IHDR");
   1.916 ++            return;
   1.917 ++        }
   1.918 ++
   1.919 ++        /* The set function will do more error checking */
   1.920 ++        png_set_next_frame_fcTL(png_ptr, info_ptr, width, height,
   1.921 ++                                x_offset, y_offset, delay_num, delay_den,
   1.922 ++                                dispose_op, blend_op);
   1.923 ++
   1.924 ++        png_read_reinit(png_ptr, info_ptr);
   1.925 ++
   1.926 ++        png_ptr->mode |= PNG_HAVE_fcTL;
   1.927 ++    }
   1.928 ++}
   1.929 ++
   1.930 ++void /* PRIVATE */
   1.931 ++png_have_info(png_structp png_ptr, png_infop info_ptr)
   1.932 ++{
   1.933 ++    if((info_ptr->valid & PNG_INFO_acTL) && !(info_ptr->valid & PNG_INFO_fcTL))
   1.934 ++    {
   1.935 ++        png_ptr->apng_flags |= PNG_FIRST_FRAME_HIDDEN;
   1.936 ++        info_ptr->num_frames++;
   1.937 ++    }
   1.938 ++}
   1.939 ++
   1.940 ++void /* PRIVATE */
   1.941 ++png_handle_fdAT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
   1.942 ++{
   1.943 ++    png_ensure_sequence_number(png_ptr, length);
   1.944 ++
   1.945 ++    /* This function is only called from png_read_end(), png_read_info(),
   1.946 ++    * and png_push_read_chunk() which means that:
   1.947 ++    * - the user doesn't want to read this frame
   1.948 ++    * - or this is an out-of-place fdAT
   1.949 ++    * in either case it is safe to ignore the chunk with a warning */
   1.950 ++    png_warning(png_ptr, "ignoring fdAT chunk");
   1.951 ++    png_crc_finish(png_ptr, length - 4);
   1.952 ++    PNG_UNUSED(info_ptr)
   1.953 ++}
   1.954 ++
   1.955 ++void /* PRIVATE */
   1.956 ++png_ensure_sequence_number(png_structp png_ptr, png_uint_32 length)
   1.957 ++{
   1.958 ++    png_byte data[4];
   1.959 ++    png_uint_32 sequence_number;
   1.960 ++
   1.961 ++    if (length < 4)
   1.962 ++        png_error(png_ptr, "invalid fcTL or fdAT chunk found");
   1.963 ++
   1.964 ++    png_crc_read(png_ptr, data, 4);
   1.965 ++    sequence_number = png_get_uint_31(png_ptr, data);
   1.966 ++
   1.967 ++    if (sequence_number != png_ptr->next_seq_num)
   1.968 ++        png_error(png_ptr, "fcTL or fdAT chunk with out-of-order sequence "
   1.969 ++                           "number found");
   1.970 ++
   1.971 ++    png_ptr->next_seq_num++;
   1.972 ++}
   1.973 ++#endif /* PNG_READ_APNG_SUPPORTED */
   1.974 ++
   1.975 + #ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
   1.976 + /* Utility function for png_handle_unknown; set up png_ptr::unknown_chunk */
   1.977 + static int
   1.978 +@@ -4166,7 +4344,38 @@
   1.979 +       {
   1.980 +          uInt avail_in;
   1.981 +          png_bytep buffer;
   1.982 ++#ifdef PNG_READ_APNG_SUPPORTED
   1.983 ++         png_uint_32 bytes_to_skip = 0;
   1.984 ++
   1.985 ++         while (png_ptr->idat_size == 0 || bytes_to_skip != 0)
   1.986 ++         {
   1.987 ++            png_crc_finish(png_ptr, bytes_to_skip);
   1.988 ++            bytes_to_skip = 0;
   1.989 + 
   1.990 ++            png_ptr->idat_size = png_read_chunk_header(png_ptr);
   1.991 ++            if (png_ptr->num_frames_read == 0)
   1.992 ++            {
   1.993 ++               if (png_ptr->chunk_name != png_IDAT)
   1.994 ++                  png_error(png_ptr, "Not enough image data");
   1.995 ++            }
   1.996 ++            else
   1.997 ++            {
   1.998 ++               if (png_ptr->chunk_name == png_IEND)
   1.999 ++                  png_error(png_ptr, "Not enough image data");
  1.1000 ++               if (png_ptr->chunk_name != png_fdAT)
  1.1001 ++               {
  1.1002 ++                  png_warning(png_ptr, "Skipped (ignored) a chunk "
  1.1003 ++                                       "between APNG chunks");
  1.1004 ++                  bytes_to_skip = png_ptr->idat_size;
  1.1005 ++                  continue;
  1.1006 ++               }
  1.1007 ++
  1.1008 ++               png_ensure_sequence_number(png_ptr, png_ptr->idat_size);
  1.1009 ++
  1.1010 ++               png_ptr->idat_size -= 4;
  1.1011 ++            }
  1.1012 ++         }
  1.1013 ++#else
  1.1014 +          while (png_ptr->idat_size == 0)
  1.1015 +          {
  1.1016 +             png_crc_finish(png_ptr, 0);
  1.1017 +@@ -4178,7 +4387,7 @@
  1.1018 +             if (png_ptr->chunk_name != png_IDAT)
  1.1019 +                png_error(png_ptr, "Not enough image data");
  1.1020 +          }
  1.1021 +-
  1.1022 ++#endif /* PNG_READ_APNG_SUPPORTED */
  1.1023 +          avail_in = png_ptr->IDAT_read_size;
  1.1024 + 
  1.1025 +          if (avail_in > png_ptr->idat_size)
  1.1026 +@@ -4241,6 +4450,9 @@
  1.1027 + 
  1.1028 +          png_ptr->mode |= PNG_AFTER_IDAT;
  1.1029 +          png_ptr->flags |= PNG_FLAG_ZSTREAM_ENDED;
  1.1030 ++#ifdef PNG_READ_APNG_SUPPORTED
  1.1031 ++         png_ptr->num_frames_read++;
  1.1032 ++#endif
  1.1033 + 
  1.1034 +          if (png_ptr->zstream.avail_in > 0 || png_ptr->idat_size > 0)
  1.1035 +             png_chunk_benign_error(png_ptr, "Extra compressed data");
  1.1036 +@@ -4679,4 +4891,80 @@
  1.1037 + 
  1.1038 +    png_ptr->flags |= PNG_FLAG_ROW_INIT;
  1.1039 + }
  1.1040 ++
  1.1041 ++#ifdef PNG_READ_APNG_SUPPORTED
  1.1042 ++/* This function is to be called after the main IDAT set has been read and
  1.1043 ++ * before a new IDAT is read. It resets some parts of png_ptr
  1.1044 ++ * to make them usable by the read functions again */
  1.1045 ++void /* PRIVATE */
  1.1046 ++png_read_reset(png_structp png_ptr)
  1.1047 ++{
  1.1048 ++    png_ptr->mode &= ~PNG_HAVE_IDAT;
  1.1049 ++    png_ptr->mode &= ~PNG_AFTER_IDAT;
  1.1050 ++    png_ptr->row_number = 0;
  1.1051 ++    png_ptr->pass = 0;
  1.1052 ++}
  1.1053 ++
  1.1054 ++void /* PRIVATE */
  1.1055 ++png_read_reinit(png_structp png_ptr, png_infop info_ptr)
  1.1056 ++{
  1.1057 ++    png_ptr->width = info_ptr->next_frame_width;
  1.1058 ++    png_ptr->height = info_ptr->next_frame_height;
  1.1059 ++    png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth,png_ptr->width);
  1.1060 ++    png_ptr->info_rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth,
  1.1061 ++        png_ptr->width);
  1.1062 ++    if (png_ptr->prev_row)
  1.1063 ++        memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1);
  1.1064 ++}
  1.1065 ++
  1.1066 ++#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
  1.1067 ++/* same as png_read_reset() but for the progressive reader */
  1.1068 ++void /* PRIVATE */
  1.1069 ++png_progressive_read_reset(png_structp png_ptr)
  1.1070 ++{
  1.1071 ++#ifdef PNG_READ_INTERLACING_SUPPORTED
  1.1072 ++   /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
  1.1073 ++
  1.1074 ++   /* Start of interlace block */
  1.1075 ++    const int png_pass_start[] = {0, 4, 0, 2, 0, 1, 0};
  1.1076 ++
  1.1077 ++    /* Offset to next interlace block */
  1.1078 ++    const int png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1};
  1.1079 ++
  1.1080 ++    /* Start of interlace block in the y direction */
  1.1081 ++    const int png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1};
  1.1082 ++
  1.1083 ++    /* Offset to next interlace block in the y direction */
  1.1084 ++    const int png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2};
  1.1085 ++
  1.1086 ++    if (png_ptr->interlaced)
  1.1087 ++    {
  1.1088 ++        if (!(png_ptr->transformations & PNG_INTERLACE))
  1.1089 ++            png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 -
  1.1090 ++                                png_pass_ystart[0]) / png_pass_yinc[0];
  1.1091 ++        else
  1.1092 ++            png_ptr->num_rows = png_ptr->height;
  1.1093 ++
  1.1094 ++        png_ptr->iwidth = (png_ptr->width +
  1.1095 ++                           png_pass_inc[png_ptr->pass] - 1 -
  1.1096 ++                           png_pass_start[png_ptr->pass]) /
  1.1097 ++                           png_pass_inc[png_ptr->pass];
  1.1098 ++    }
  1.1099 ++    else
  1.1100 ++#endif /* PNG_READ_INTERLACING_SUPPORTED */
  1.1101 ++    {
  1.1102 ++        png_ptr->num_rows = png_ptr->height;
  1.1103 ++        png_ptr->iwidth = png_ptr->width;
  1.1104 ++    }
  1.1105 ++    png_ptr->flags &= ~PNG_FLAG_ZSTREAM_ENDED;
  1.1106 ++    if (inflateReset(&(png_ptr->zstream)) != Z_OK)
  1.1107 ++        png_error(png_ptr, "inflateReset failed");
  1.1108 ++    png_ptr->zstream.avail_in = 0;
  1.1109 ++    png_ptr->zstream.next_in = 0;
  1.1110 ++    png_ptr->zstream.next_out = png_ptr->row_buf;
  1.1111 ++    png_ptr->zstream.avail_out = (uInt)PNG_ROWBYTES(png_ptr->pixel_depth,
  1.1112 ++        png_ptr->iwidth) + 1;
  1.1113 ++}
  1.1114 ++#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */
  1.1115 ++#endif /* PNG_READ_APNG_SUPPORTED */
  1.1116 + #endif /* READ */
  1.1117 +diff -Naru libpng-1.6.35.org/pngset.c libpng-1.6.35/pngset.c
  1.1118 +--- libpng-1.6.35.org/pngset.c	2018-07-21 19:16:37.188143186 +0900
  1.1119 ++++ libpng-1.6.35/pngset.c	2018-07-21 19:16:16.256358584 +0900
  1.1120 +@@ -288,6 +288,11 @@
  1.1121 +    info_ptr->pixel_depth = (png_byte)(info_ptr->channels * info_ptr->bit_depth);
  1.1122 + 
  1.1123 +    info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth, width);
  1.1124 ++
  1.1125 ++#ifdef PNG_APNG_SUPPORTED
  1.1126 ++   /* for non-animated png. this may be overwritten from an acTL chunk later */
  1.1127 ++   info_ptr->num_frames = 1;
  1.1128 ++#endif
  1.1129 + }
  1.1130 + 
  1.1131 + #ifdef PNG_oFFs_SUPPORTED
  1.1132 +@@ -1158,6 +1163,147 @@
  1.1133 + }
  1.1134 + #endif /* sPLT */
  1.1135 + 
  1.1136 ++#ifdef PNG_APNG_SUPPORTED
  1.1137 ++png_uint_32 PNGAPI
  1.1138 ++png_set_acTL(png_structp png_ptr, png_infop info_ptr,
  1.1139 ++    png_uint_32 num_frames, png_uint_32 num_plays)
  1.1140 ++{
  1.1141 ++    png_debug1(1, "in %s storage function", "acTL");
  1.1142 ++
  1.1143 ++    if (png_ptr == NULL || info_ptr == NULL)
  1.1144 ++    {
  1.1145 ++        png_warning(png_ptr,
  1.1146 ++                    "Call to png_set_acTL() with NULL png_ptr "
  1.1147 ++                    "or info_ptr ignored");
  1.1148 ++        return (0);
  1.1149 ++    }
  1.1150 ++    if (num_frames == 0)
  1.1151 ++    {
  1.1152 ++        png_warning(png_ptr,
  1.1153 ++                    "Ignoring attempt to set acTL with num_frames zero");
  1.1154 ++        return (0);
  1.1155 ++    }
  1.1156 ++    if (num_frames > PNG_UINT_31_MAX)
  1.1157 ++    {
  1.1158 ++        png_warning(png_ptr,
  1.1159 ++                    "Ignoring attempt to set acTL with num_frames > 2^31-1");
  1.1160 ++        return (0);
  1.1161 ++    }
  1.1162 ++    if (num_plays > PNG_UINT_31_MAX)
  1.1163 ++    {
  1.1164 ++        png_warning(png_ptr,
  1.1165 ++                    "Ignoring attempt to set acTL with num_plays "
  1.1166 ++                    "> 2^31-1");
  1.1167 ++        return (0);
  1.1168 ++    }
  1.1169 ++
  1.1170 ++    info_ptr->num_frames = num_frames;
  1.1171 ++    info_ptr->num_plays = num_plays;
  1.1172 ++
  1.1173 ++    info_ptr->valid |= PNG_INFO_acTL;
  1.1174 ++
  1.1175 ++    return (1);
  1.1176 ++}
  1.1177 ++
  1.1178 ++/* delay_num and delay_den can hold any 16-bit values including zero */
  1.1179 ++png_uint_32 PNGAPI
  1.1180 ++png_set_next_frame_fcTL(png_structp png_ptr, png_infop info_ptr,
  1.1181 ++    png_uint_32 width, png_uint_32 height,
  1.1182 ++    png_uint_32 x_offset, png_uint_32 y_offset,
  1.1183 ++    png_uint_16 delay_num, png_uint_16 delay_den,
  1.1184 ++    png_byte dispose_op, png_byte blend_op)
  1.1185 ++{
  1.1186 ++    png_debug1(1, "in %s storage function", "fcTL");
  1.1187 ++
  1.1188 ++    if (png_ptr == NULL || info_ptr == NULL)
  1.1189 ++    {
  1.1190 ++        png_warning(png_ptr,
  1.1191 ++                    "Call to png_set_fcTL() with NULL png_ptr or info_ptr "
  1.1192 ++                    "ignored");
  1.1193 ++        return (0);
  1.1194 ++    }
  1.1195 ++
  1.1196 ++    png_ensure_fcTL_is_valid(png_ptr, width, height, x_offset, y_offset,
  1.1197 ++                             delay_num, delay_den, dispose_op, blend_op);
  1.1198 ++
  1.1199 ++    if (blend_op == PNG_BLEND_OP_OVER)
  1.1200 ++    {
  1.1201 ++        if (!(png_ptr->color_type & PNG_COLOR_MASK_ALPHA) &&
  1.1202 ++            !(png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)))
  1.1203 ++        {
  1.1204 ++          png_warning(png_ptr, "PNG_BLEND_OP_OVER is meaningless "
  1.1205 ++                               "and wasteful for opaque images, ignored");
  1.1206 ++          blend_op = PNG_BLEND_OP_SOURCE;
  1.1207 ++        }
  1.1208 ++    }
  1.1209 ++
  1.1210 ++    info_ptr->next_frame_width = width;
  1.1211 ++    info_ptr->next_frame_height = height;
  1.1212 ++    info_ptr->next_frame_x_offset = x_offset;
  1.1213 ++    info_ptr->next_frame_y_offset = y_offset;
  1.1214 ++    info_ptr->next_frame_delay_num = delay_num;
  1.1215 ++    info_ptr->next_frame_delay_den = delay_den;
  1.1216 ++    info_ptr->next_frame_dispose_op = dispose_op;
  1.1217 ++    info_ptr->next_frame_blend_op = blend_op;
  1.1218 ++
  1.1219 ++    info_ptr->valid |= PNG_INFO_fcTL;
  1.1220 ++
  1.1221 ++    return (1);
  1.1222 ++}
  1.1223 ++
  1.1224 ++void /* PRIVATE */
  1.1225 ++png_ensure_fcTL_is_valid(png_structp png_ptr,
  1.1226 ++    png_uint_32 width, png_uint_32 height,
  1.1227 ++    png_uint_32 x_offset, png_uint_32 y_offset,
  1.1228 ++    png_uint_16 delay_num, png_uint_16 delay_den,
  1.1229 ++    png_byte dispose_op, png_byte blend_op)
  1.1230 ++{
  1.1231 ++    if (width == 0 || width > PNG_UINT_31_MAX)
  1.1232 ++        png_error(png_ptr, "invalid width in fcTL (> 2^31-1)");
  1.1233 ++    if (height == 0 || height > PNG_UINT_31_MAX)
  1.1234 ++        png_error(png_ptr, "invalid height in fcTL (> 2^31-1)");
  1.1235 ++    if (x_offset > PNG_UINT_31_MAX)
  1.1236 ++        png_error(png_ptr, "invalid x_offset in fcTL (> 2^31-1)");
  1.1237 ++    if (y_offset > PNG_UINT_31_MAX)
  1.1238 ++        png_error(png_ptr, "invalid y_offset in fcTL (> 2^31-1)");
  1.1239 ++    if (width + x_offset > png_ptr->first_frame_width ||
  1.1240 ++        height + y_offset > png_ptr->first_frame_height)
  1.1241 ++        png_error(png_ptr, "dimensions of a frame are greater than"
  1.1242 ++                           "the ones in IHDR");
  1.1243 ++
  1.1244 ++    if (dispose_op != PNG_DISPOSE_OP_NONE &&
  1.1245 ++        dispose_op != PNG_DISPOSE_OP_BACKGROUND &&
  1.1246 ++        dispose_op != PNG_DISPOSE_OP_PREVIOUS)
  1.1247 ++        png_error(png_ptr, "invalid dispose_op in fcTL");
  1.1248 ++
  1.1249 ++    if (blend_op != PNG_BLEND_OP_SOURCE &&
  1.1250 ++        blend_op != PNG_BLEND_OP_OVER)
  1.1251 ++        png_error(png_ptr, "invalid blend_op in fcTL");
  1.1252 ++
  1.1253 ++    PNG_UNUSED(delay_num)
  1.1254 ++    PNG_UNUSED(delay_den)
  1.1255 ++}
  1.1256 ++
  1.1257 ++png_uint_32 PNGAPI
  1.1258 ++png_set_first_frame_is_hidden(png_structp png_ptr, png_infop info_ptr,
  1.1259 ++                              png_byte is_hidden)
  1.1260 ++{
  1.1261 ++    png_debug(1, "in png_first_frame_is_hidden()");
  1.1262 ++
  1.1263 ++    if (png_ptr == NULL)
  1.1264 ++        return 0;
  1.1265 ++
  1.1266 ++    if (is_hidden)
  1.1267 ++        png_ptr->apng_flags |= PNG_FIRST_FRAME_HIDDEN;
  1.1268 ++    else
  1.1269 ++        png_ptr->apng_flags &= ~PNG_FIRST_FRAME_HIDDEN;
  1.1270 ++
  1.1271 ++    PNG_UNUSED(info_ptr)
  1.1272 ++
  1.1273 ++    return 1;
  1.1274 ++}
  1.1275 ++#endif /* PNG_APNG_SUPPORTED */
  1.1276 ++
  1.1277 + #ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED
  1.1278 + static png_byte
  1.1279 + check_location(png_const_structrp png_ptr, int location)
  1.1280 +diff -Naru libpng-1.6.35.org/pngstruct.h libpng-1.6.35/pngstruct.h
  1.1281 +--- libpng-1.6.35.org/pngstruct.h	2018-07-21 19:16:37.188143186 +0900
  1.1282 ++++ libpng-1.6.35/pngstruct.h	2018-07-21 19:16:16.214355003 +0900
  1.1283 +@@ -403,6 +403,27 @@
  1.1284 +    png_byte filter_type;
  1.1285 + #endif
  1.1286 + 
  1.1287 ++#ifdef PNG_APNG_SUPPORTED
  1.1288 ++   png_uint_32 apng_flags;
  1.1289 ++   png_uint_32 next_seq_num;         /* next fcTL/fdAT chunk sequence number */
  1.1290 ++   png_uint_32 first_frame_width;
  1.1291 ++   png_uint_32 first_frame_height;
  1.1292 ++
  1.1293 ++#ifdef PNG_READ_APNG_SUPPORTED
  1.1294 ++   png_uint_32 num_frames_read;      /* incremented after all image data of */
  1.1295 ++                                     /* a frame is read */
  1.1296 ++#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
  1.1297 ++   png_progressive_frame_ptr frame_info_fn; /* frame info read callback */
  1.1298 ++   png_progressive_frame_ptr frame_end_fn;  /* frame data read callback */
  1.1299 ++#endif
  1.1300 ++#endif
  1.1301 ++
  1.1302 ++#ifdef PNG_WRITE_APNG_SUPPORTED
  1.1303 ++   png_uint_32 num_frames_to_write;
  1.1304 ++   png_uint_32 num_frames_written;
  1.1305 ++#endif
  1.1306 ++#endif /* PNG_APNG_SUPPORTED */
  1.1307 ++
  1.1308 + /* New members added in libpng-1.2.0 */
  1.1309 + 
  1.1310 + /* New members added in libpng-1.0.2 but first enabled by default in 1.2.0 */
  1.1311 +diff -Naru libpng-1.6.35.org/pngtest.c libpng-1.6.35/pngtest.c
  1.1312 +--- libpng-1.6.35.org/pngtest.c	2018-07-21 19:16:37.188143186 +0900
  1.1313 ++++ libpng-1.6.35/pngtest.c	2018-07-21 19:16:16.213354917 +0900
  1.1314 +@@ -875,6 +875,10 @@
  1.1315 +    volatile int num_passes;
  1.1316 +    int pass;
  1.1317 +    int bit_depth, color_type;
  1.1318 ++#ifdef PNG_APNG_SUPPORTED
  1.1319 ++   png_uint_32 num_frames;
  1.1320 ++   png_uint_32 num_plays;
  1.1321 ++#endif
  1.1322 + 
  1.1323 +    row_buf = NULL;
  1.1324 +    error_parameters.file_name = inname;
  1.1325 +@@ -1381,6 +1385,22 @@
  1.1326 +       }
  1.1327 +    }
  1.1328 + #endif
  1.1329 ++
  1.1330 ++#ifdef PNG_APNG_SUPPORTED
  1.1331 ++   if (png_get_valid(read_ptr, read_info_ptr, PNG_INFO_acTL))
  1.1332 ++   {
  1.1333 ++      if (png_get_acTL(read_ptr, read_info_ptr, &num_frames, &num_plays))
  1.1334 ++      {
  1.1335 ++         png_byte is_hidden;
  1.1336 ++         pngtest_debug2("Handling acTL chunks (frames %ld, plays %ld)",
  1.1337 ++                    num_frames, num_plays);
  1.1338 ++         png_set_acTL(write_ptr, write_info_ptr, num_frames, num_plays);
  1.1339 ++         is_hidden = png_get_first_frame_is_hidden(read_ptr, read_info_ptr);
  1.1340 ++         png_set_first_frame_is_hidden(write_ptr, write_info_ptr, is_hidden);
  1.1341 ++      }
  1.1342 ++   }
  1.1343 ++#endif
  1.1344 ++
  1.1345 + #ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED
  1.1346 +    {
  1.1347 +       png_unknown_chunkp unknowns;
  1.1348 +@@ -1461,6 +1481,110 @@
  1.1349 +    t_misc += (t_stop - t_start);
  1.1350 +    t_start = t_stop;
  1.1351 + #endif
  1.1352 ++#ifdef PNG_APNG_SUPPORTED
  1.1353 ++   if (png_get_valid(read_ptr, read_info_ptr, PNG_INFO_acTL))
  1.1354 ++   {
  1.1355 ++      png_uint_32 frame;
  1.1356 ++      for (frame = 0; frame < num_frames; frame++)
  1.1357 ++      {
  1.1358 ++         png_uint_32 frame_width;
  1.1359 ++         png_uint_32 frame_height;
  1.1360 ++         png_uint_32 x_offset;
  1.1361 ++         png_uint_32 y_offset;
  1.1362 ++         png_uint_16 delay_num;
  1.1363 ++         png_uint_16 delay_den;
  1.1364 ++         png_byte dispose_op;
  1.1365 ++         png_byte blend_op;
  1.1366 ++         png_read_frame_head(read_ptr, read_info_ptr);
  1.1367 ++         if (png_get_valid(read_ptr, read_info_ptr, PNG_INFO_fcTL))
  1.1368 ++         {
  1.1369 ++            png_get_next_frame_fcTL(read_ptr, read_info_ptr,
  1.1370 ++                                    &frame_width, &frame_height,
  1.1371 ++                                    &x_offset, &y_offset,
  1.1372 ++                                    &delay_num, &delay_den,
  1.1373 ++                                    &dispose_op, &blend_op);
  1.1374 ++         }
  1.1375 ++         else
  1.1376 ++         {
  1.1377 ++            frame_width = width;
  1.1378 ++            frame_height = height;
  1.1379 ++            x_offset = 0;
  1.1380 ++            y_offset = 0;
  1.1381 ++            delay_num = 1;
  1.1382 ++            delay_den = 1;
  1.1383 ++            dispose_op = PNG_DISPOSE_OP_NONE;
  1.1384 ++            blend_op = PNG_BLEND_OP_SOURCE;
  1.1385 ++         }
  1.1386 ++#ifdef PNG_WRITE_APNG_SUPPORTED
  1.1387 ++         png_write_frame_head(write_ptr, write_info_ptr, (png_bytepp)&row_buf,
  1.1388 ++                              frame_width, frame_height,
  1.1389 ++                              x_offset, y_offset,
  1.1390 ++                              delay_num, delay_den,
  1.1391 ++                              dispose_op, blend_op);
  1.1392 ++#endif
  1.1393 ++         for (pass = 0; pass < num_passes; pass++)
  1.1394 ++         {
  1.1395 ++#           ifdef calc_pass_height
  1.1396 ++               png_uint_32 pass_height;
  1.1397 ++
  1.1398 ++               if (num_passes == 7) /* interlaced */
  1.1399 ++               {
  1.1400 ++                  if (PNG_PASS_COLS(frame_width, pass) > 0)
  1.1401 ++                     pass_height = PNG_PASS_ROWS(frame_height, pass);
  1.1402 ++
  1.1403 ++                  else
  1.1404 ++                     pass_height = 0;
  1.1405 ++               }
  1.1406 ++
  1.1407 ++               else /* not interlaced */
  1.1408 ++                  pass_height = frame_height;
  1.1409 ++#           else
  1.1410 ++#              define pass_height frame_height
  1.1411 ++#           endif
  1.1412 ++
  1.1413 ++            pngtest_debug1("Writing row data for pass %d", pass);
  1.1414 ++            for (y = 0; y < pass_height; y++)
  1.1415 ++            {
  1.1416 ++#ifndef SINGLE_ROWBUF_ALLOC
  1.1417 ++               pngtest_debug2("Allocating row buffer (pass %d, y = %u)...", pass, y);
  1.1418 ++
  1.1419 ++               row_buf = (png_bytep)png_malloc(read_ptr,
  1.1420 ++                  png_get_rowbytes(read_ptr, read_info_ptr));
  1.1421 ++
  1.1422 ++               pngtest_debug2("\t0x%08lx (%lu bytes)", (unsigned long)row_buf,
  1.1423 ++                  (unsigned long)png_get_rowbytes(read_ptr, read_info_ptr));
  1.1424 ++
  1.1425 ++#endif /* !SINGLE_ROWBUF_ALLOC */
  1.1426 ++               png_read_rows(read_ptr, (png_bytepp)&row_buf, NULL, 1);
  1.1427 ++
  1.1428 ++#ifdef PNG_WRITE_SUPPORTED
  1.1429 ++#ifdef PNGTEST_TIMING
  1.1430 ++               t_stop = (float)clock();
  1.1431 ++               t_decode += (t_stop - t_start);
  1.1432 ++               t_start = t_stop;
  1.1433 ++#endif
  1.1434 ++               png_write_rows(write_ptr, (png_bytepp)&row_buf, 1);
  1.1435 ++#ifdef PNGTEST_TIMING
  1.1436 ++               t_stop = (float)clock();
  1.1437 ++               t_encode += (t_stop - t_start);
  1.1438 ++               t_start = t_stop;
  1.1439 ++#endif
  1.1440 ++#endif /* PNG_WRITE_SUPPORTED */
  1.1441 ++
  1.1442 ++#ifndef SINGLE_ROWBUF_ALLOC
  1.1443 ++               pngtest_debug2("Freeing row buffer (pass %d, y = %u)", pass, y);
  1.1444 ++               png_free(read_ptr, row_buf);
  1.1445 ++               row_buf = NULL;
  1.1446 ++#endif /* !SINGLE_ROWBUF_ALLOC */
  1.1447 ++            }
  1.1448 ++         }
  1.1449 ++#ifdef PNG_WRITE_APNG_SUPPORTED
  1.1450 ++         png_write_frame_tail(write_ptr, write_info_ptr);
  1.1451 ++#endif
  1.1452 ++      }
  1.1453 ++   }
  1.1454 ++   else
  1.1455 ++#endif
  1.1456 +    for (pass = 0; pass < num_passes; pass++)
  1.1457 +    {
  1.1458 + #     ifdef calc_pass_height
  1.1459 +diff -Naru libpng-1.6.35.org/pngwrite.c libpng-1.6.35/pngwrite.c
  1.1460 +--- libpng-1.6.35.org/pngwrite.c	2018-07-21 19:16:37.188143186 +0900
  1.1461 ++++ libpng-1.6.35/pngwrite.c	2018-07-21 19:16:16.211354747 +0900
  1.1462 +@@ -128,6 +128,10 @@
  1.1463 +        * the application continues writing the PNG.  So check the 'invalid'
  1.1464 +        * flag here too.
  1.1465 +        */
  1.1466 ++#ifdef PNG_WRITE_APNG_SUPPORTED
  1.1467 ++      if (info_ptr->valid & PNG_INFO_acTL)
  1.1468 ++         png_write_acTL(png_ptr, info_ptr->num_frames, info_ptr->num_plays);
  1.1469 ++#endif
  1.1470 + #ifdef PNG_GAMMA_SUPPORTED
  1.1471 + #  ifdef PNG_WRITE_gAMA_SUPPORTED
  1.1472 +       if ((info_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) == 0 &&
  1.1473 +@@ -370,6 +374,11 @@
  1.1474 +       png_benign_error(png_ptr, "Wrote palette index exceeding num_palette");
  1.1475 + #endif
  1.1476 + 
  1.1477 ++#ifdef PNG_WRITE_APNG_SUPPORTED
  1.1478 ++   if (png_ptr->num_frames_written != png_ptr->num_frames_to_write)
  1.1479 ++      png_error(png_ptr, "Not enough frames written");
  1.1480 ++#endif
  1.1481 ++
  1.1482 +    /* See if user wants us to write information chunks */
  1.1483 +    if (info_ptr != NULL)
  1.1484 +    {
  1.1485 +@@ -1461,6 +1470,43 @@
  1.1486 + }
  1.1487 + #endif
  1.1488 + 
  1.1489 ++#ifdef PNG_WRITE_APNG_SUPPORTED
  1.1490 ++void PNGAPI
  1.1491 ++png_write_frame_head(png_structp png_ptr, png_infop info_ptr,
  1.1492 ++    png_bytepp row_pointers, png_uint_32 width, png_uint_32 height,
  1.1493 ++    png_uint_32 x_offset, png_uint_32 y_offset,
  1.1494 ++    png_uint_16 delay_num, png_uint_16 delay_den, png_byte dispose_op,
  1.1495 ++    png_byte blend_op)
  1.1496 ++{
  1.1497 ++    png_debug(1, "in png_write_frame_head");
  1.1498 ++
  1.1499 ++    /* there is a chance this has been set after png_write_info was called,
  1.1500 ++    * so it would be set but not written. is there a way to be sure? */
  1.1501 ++    if (!(info_ptr->valid & PNG_INFO_acTL))
  1.1502 ++        png_error(png_ptr, "png_write_frame_head(): acTL not set");
  1.1503 ++
  1.1504 ++    png_write_reset(png_ptr);
  1.1505 ++
  1.1506 ++    png_write_reinit(png_ptr, info_ptr, width, height);
  1.1507 ++
  1.1508 ++    if ( !(png_ptr->num_frames_written == 0 &&
  1.1509 ++           (png_ptr->apng_flags & PNG_FIRST_FRAME_HIDDEN) ) )
  1.1510 ++        png_write_fcTL(png_ptr, width, height, x_offset, y_offset,
  1.1511 ++                       delay_num, delay_den, dispose_op, blend_op);
  1.1512 ++
  1.1513 ++    PNG_UNUSED(row_pointers)
  1.1514 ++}
  1.1515 ++
  1.1516 ++void PNGAPI
  1.1517 ++png_write_frame_tail(png_structp png_ptr, png_infop info_ptr)
  1.1518 ++{
  1.1519 ++    png_debug(1, "in png_write_frame_tail");
  1.1520 ++
  1.1521 ++    png_ptr->num_frames_written++;
  1.1522 ++
  1.1523 ++    PNG_UNUSED(info_ptr)
  1.1524 ++}
  1.1525 ++#endif /* PNG_WRITE_APNG_SUPPORTED */
  1.1526 + 
  1.1527 + #ifdef PNG_SIMPLIFIED_WRITE_SUPPORTED
  1.1528 + /* Initialize the write structure - general purpose utility. */
  1.1529 +diff -Naru libpng-1.6.35.org/pngwutil.c libpng-1.6.35/pngwutil.c
  1.1530 +--- libpng-1.6.35.org/pngwutil.c	2018-07-21 19:16:37.189143271 +0900
  1.1531 ++++ libpng-1.6.35/pngwutil.c	2018-07-21 19:16:16.303362592 +0900
  1.1532 +@@ -821,6 +821,11 @@
  1.1533 +    /* Write the chunk */
  1.1534 +    png_write_complete_chunk(png_ptr, png_IHDR, buf, 13);
  1.1535 + 
  1.1536 ++#ifdef PNG_WRITE_APNG_SUPPORTED
  1.1537 ++   png_ptr->first_frame_width = width;
  1.1538 ++   png_ptr->first_frame_height = height;
  1.1539 ++#endif
  1.1540 ++
  1.1541 +    if ((png_ptr->do_filter) == PNG_NO_FILTERS)
  1.1542 +    {
  1.1543 +       if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE ||
  1.1544 +@@ -1002,8 +1007,17 @@
  1.1545 +                optimize_cmf(data, png_image_size(png_ptr));
  1.1546 + #endif
  1.1547 + 
  1.1548 +-         if (size > 0)
  1.1549 +-            png_write_complete_chunk(png_ptr, png_IDAT, data, size);
  1.1550 ++            if (size > 0)
  1.1551 ++#ifdef PNG_WRITE_APNG_SUPPORTED
  1.1552 ++            {
  1.1553 ++               if (png_ptr->num_frames_written == 0)
  1.1554 ++#endif
  1.1555 ++               png_write_complete_chunk(png_ptr, png_IDAT, data, size);
  1.1556 ++#ifdef PNG_WRITE_APNG_SUPPORTED
  1.1557 ++               else
  1.1558 ++                  png_write_fdAT(png_ptr, data, size);
  1.1559 ++            }
  1.1560 ++#endif /* PNG_WRITE_APNG_SUPPORTED */
  1.1561 +          png_ptr->mode |= PNG_HAVE_IDAT;
  1.1562 + 
  1.1563 +          png_ptr->zstream.next_out = data;
  1.1564 +@@ -1050,7 +1064,17 @@
  1.1565 + #endif
  1.1566 + 
  1.1567 +          if (size > 0)
  1.1568 ++#ifdef PNG_WRITE_APNG_SUPPORTED
  1.1569 ++         {
  1.1570 ++            if (png_ptr->num_frames_written == 0)
  1.1571 ++#endif
  1.1572 +             png_write_complete_chunk(png_ptr, png_IDAT, data, size);
  1.1573 ++#ifdef PNG_WRITE_APNG_SUPPORTED
  1.1574 ++            else
  1.1575 ++               png_write_fdAT(png_ptr, data, size);
  1.1576 ++         }
  1.1577 ++#endif /* PNG_WRITE_APNG_SUPPORTED */
  1.1578 ++
  1.1579 +          png_ptr->zstream.avail_out = 0;
  1.1580 +          png_ptr->zstream.next_out = NULL;
  1.1581 +          png_ptr->mode |= PNG_HAVE_IDAT | PNG_AFTER_IDAT;
  1.1582 +@@ -1885,6 +1909,82 @@
  1.1583 + }
  1.1584 + #endif
  1.1585 + 
  1.1586 ++#ifdef PNG_WRITE_APNG_SUPPORTED
  1.1587 ++void /* PRIVATE */
  1.1588 ++png_write_acTL(png_structp png_ptr,
  1.1589 ++    png_uint_32 num_frames, png_uint_32 num_plays)
  1.1590 ++{
  1.1591 ++    png_byte buf[8];
  1.1592 ++
  1.1593 ++    png_debug(1, "in png_write_acTL");
  1.1594 ++
  1.1595 ++    png_ptr->num_frames_to_write = num_frames;
  1.1596 ++
  1.1597 ++    if (png_ptr->apng_flags & PNG_FIRST_FRAME_HIDDEN)
  1.1598 ++        num_frames--;
  1.1599 ++
  1.1600 ++    png_save_uint_32(buf, num_frames);
  1.1601 ++    png_save_uint_32(buf + 4, num_plays);
  1.1602 ++
  1.1603 ++    png_write_complete_chunk(png_ptr, png_acTL, buf, (png_size_t)8);
  1.1604 ++}
  1.1605 ++
  1.1606 ++void /* PRIVATE */
  1.1607 ++png_write_fcTL(png_structp png_ptr, png_uint_32 width, png_uint_32 height,
  1.1608 ++    png_uint_32 x_offset, png_uint_32 y_offset,
  1.1609 ++    png_uint_16 delay_num, png_uint_16 delay_den, png_byte dispose_op,
  1.1610 ++    png_byte blend_op)
  1.1611 ++{
  1.1612 ++    png_byte buf[26];
  1.1613 ++
  1.1614 ++    png_debug(1, "in png_write_fcTL");
  1.1615 ++
  1.1616 ++    if (png_ptr->num_frames_written == 0 && (x_offset != 0 || y_offset != 0))
  1.1617 ++        png_error(png_ptr, "x and/or y offset for the first frame aren't 0");
  1.1618 ++    if (png_ptr->num_frames_written == 0 &&
  1.1619 ++        (width != png_ptr->first_frame_width ||
  1.1620 ++         height != png_ptr->first_frame_height))
  1.1621 ++        png_error(png_ptr, "width and/or height in the first frame's fcTL "
  1.1622 ++                           "don't match the ones in IHDR");
  1.1623 ++
  1.1624 ++    /* more error checking */
  1.1625 ++    png_ensure_fcTL_is_valid(png_ptr, width, height, x_offset, y_offset,
  1.1626 ++                             delay_num, delay_den, dispose_op, blend_op);
  1.1627 ++
  1.1628 ++    png_save_uint_32(buf, png_ptr->next_seq_num);
  1.1629 ++    png_save_uint_32(buf + 4, width);
  1.1630 ++    png_save_uint_32(buf + 8, height);
  1.1631 ++    png_save_uint_32(buf + 12, x_offset);
  1.1632 ++    png_save_uint_32(buf + 16, y_offset);
  1.1633 ++    png_save_uint_16(buf + 20, delay_num);
  1.1634 ++    png_save_uint_16(buf + 22, delay_den);
  1.1635 ++    buf[24] = dispose_op;
  1.1636 ++    buf[25] = blend_op;
  1.1637 ++
  1.1638 ++    png_write_complete_chunk(png_ptr, png_fcTL, buf, (png_size_t)26);
  1.1639 ++
  1.1640 ++    png_ptr->next_seq_num++;
  1.1641 ++}
  1.1642 ++
  1.1643 ++void /* PRIVATE */
  1.1644 ++png_write_fdAT(png_structp png_ptr,
  1.1645 ++    png_const_bytep data, png_size_t length)
  1.1646 ++{
  1.1647 ++    png_byte buf[4];
  1.1648 ++
  1.1649 ++    png_write_chunk_header(png_ptr, png_fdAT, (png_uint_32)(4 + length));
  1.1650 ++
  1.1651 ++    png_save_uint_32(buf, png_ptr->next_seq_num);
  1.1652 ++    png_write_chunk_data(png_ptr, buf, 4);
  1.1653 ++
  1.1654 ++    png_write_chunk_data(png_ptr, data, length);
  1.1655 ++
  1.1656 ++    png_write_chunk_end(png_ptr);
  1.1657 ++
  1.1658 ++    png_ptr->next_seq_num++;
  1.1659 ++}
  1.1660 ++#endif /* PNG_WRITE_APNG_SUPPORTED */
  1.1661 ++
  1.1662 + /* Initializes the row writing capability of libpng */
  1.1663 + void /* PRIVATE */
  1.1664 + png_write_start_row(png_structrp png_ptr)
  1.1665 +@@ -2778,4 +2878,39 @@
  1.1666 +    }
  1.1667 + #endif /* WRITE_FLUSH */
  1.1668 + }
  1.1669 ++
  1.1670 ++#ifdef PNG_WRITE_APNG_SUPPORTED
  1.1671 ++void /* PRIVATE */
  1.1672 ++png_write_reset(png_structp png_ptr)
  1.1673 ++{
  1.1674 ++    png_ptr->row_number = 0;
  1.1675 ++    png_ptr->pass = 0;
  1.1676 ++    png_ptr->mode &= ~PNG_HAVE_IDAT;
  1.1677 ++}
  1.1678 ++
  1.1679 ++void /* PRIVATE */
  1.1680 ++png_write_reinit(png_structp png_ptr, png_infop info_ptr,
  1.1681 ++                 png_uint_32 width, png_uint_32 height)
  1.1682 ++{
  1.1683 ++    if (png_ptr->num_frames_written == 0 &&
  1.1684 ++        (width != png_ptr->first_frame_width ||
  1.1685 ++         height != png_ptr->first_frame_height))
  1.1686 ++        png_error(png_ptr, "width and/or height in the first frame's fcTL "
  1.1687 ++                           "don't match the ones in IHDR");
  1.1688 ++    if (width > png_ptr->first_frame_width ||
  1.1689 ++        height > png_ptr->first_frame_height)
  1.1690 ++        png_error(png_ptr, "width and/or height for a frame greater than"
  1.1691 ++                           "the ones in IHDR");
  1.1692 ++
  1.1693 ++    png_set_IHDR(png_ptr, info_ptr, width, height,
  1.1694 ++                 info_ptr->bit_depth, info_ptr->color_type,
  1.1695 ++                 info_ptr->interlace_type, info_ptr->compression_type,
  1.1696 ++                 info_ptr->filter_type);
  1.1697 ++
  1.1698 ++    png_ptr->width = width;
  1.1699 ++    png_ptr->height = height;
  1.1700 ++    png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth, width);
  1.1701 ++    png_ptr->usr_width = png_ptr->width;
  1.1702 ++}
  1.1703 ++#endif /* PNG_WRITE_APNG_SUPPORTED */
  1.1704 + #endif /* WRITE */
  1.1705 +diff -Naru libpng-1.6.35.org/scripts/symbols.def libpng-1.6.35/scripts/symbols.def
  1.1706 +--- libpng-1.6.35.org/scripts/symbols.def	2018-07-21 19:16:37.192143527 +0900
  1.1707 ++++ libpng-1.6.35/scripts/symbols.def	2018-07-21 19:16:16.206354321 +0900
  1.1708 +@@ -254,3 +254,23 @@
  1.1709 +  png_set_eXIf @247
  1.1710 +  png_get_eXIf_1 @248
  1.1711 +  png_set_eXIf_1 @249
  1.1712 ++ png_get_acTL @250
  1.1713 ++ png_set_acTL @251
  1.1714 ++ png_get_num_frames @252
  1.1715 ++ png_get_num_plays @253
  1.1716 ++ png_get_next_frame_fcTL @254
  1.1717 ++ png_set_next_frame_fcTL @255
  1.1718 ++ png_get_next_frame_width @256
  1.1719 ++ png_get_next_frame_height @257
  1.1720 ++ png_get_next_frame_x_offset @258
  1.1721 ++ png_get_next_frame_y_offset @259
  1.1722 ++ png_get_next_frame_delay_num @260
  1.1723 ++ png_get_next_frame_delay_den @261
  1.1724 ++ png_get_next_frame_dispose_op @262
  1.1725 ++ png_get_next_frame_blend_op @263
  1.1726 ++ png_get_first_frame_is_hidden @264
  1.1727 ++ png_set_first_frame_is_hidden @265
  1.1728 ++ png_read_frame_head @266
  1.1729 ++ png_set_progressive_frame_fn @267
  1.1730 ++ png_write_frame_head @268
  1.1731 ++ png_write_frame_tail @269