Bump to 1.6.39 16/285216/2 accepted/tizen_8.0_unified tizen_8.0 accepted/tizen/8.0/unified/20231005.095108 accepted/tizen/unified/20221216.024038 tizen_8.0_m2_release
authorjiyong.min <jiyong.min@samsung.com>
Wed, 7 Dec 2022 22:41:13 +0000 (07:41 +0900)
committerjiyong.min <jiyong.min@samsung.com>
Thu, 8 Dec 2022 04:04:11 +0000 (13:04 +0900)
Change-Id: I97907bc7bf2cde599b03b28eefa7fe5ca28030d0

14 files changed:
1  2 
arm/filter_neon.S
packaging/libpng.spec
png.c
png.h
pngget.c
pngpriv.h
pngread.c
pngrutil.c
pngset.c
pngstruct.h
pngtest.c
pngwrite.c
pngwutil.c
scripts/pnglibconf.dfa

diff --combined arm/filter_neon.S
@@@ -14,6 -14,6 +14,7 @@@
   * definitions (or not) of PNG_ARM_NEON_OPT and PNG_ARM_NEON_IMPLEMENTATION.
   */
  #define PNG_VERSION_INFO_ONLY
++#define PNG_ARM_NEON_IMPLEMENTATION 1 // apply patch for tizen
  #include "../pngpriv.h"
  
  #if (defined(__linux__) || defined(__FreeBSD__)) && defined(__ELF__)
diff --combined packaging/libpng.spec
index 10b6ca9,0000000..df06560
mode 100644,000000..100644
--- /dev/null
@@@ -1,73 -1,0 +1,73 @@@
- Version:        1.6.37
- Release:        3
 +Name:           libpng
-          -DPNG_ARM_NEON=check \
++Version:        1.6.39
++Release:        0
 +License:        Libpng
 +Summary:        A library of functions for manipulating PNG image format files
 +Url:            http://www.libpng.org/pub/png/libpng.html
 +Group:          System/Libraries
 +Source:         %{name}-%{version}.tar.bz2
 +Source1001:     libpng.manifest
 +
 +BuildRequires:  cmake
 +BuildRequires:  zlib-devel
 +
 +%description
 +The libpng package contains a library of functions for creating and
 +manipulating PNG (Portable Network Graphics) image format files.  PNG
 +is a bit-mapped graphics format similar to the GIF format.  PNG was
 +created to replace the GIF format, since GIF uses a patented data
 +compression algorithm.
 +
 +Libpng should be installed if you need to manipulate PNG format image
 +files.
 +
 +%package devel
 +Summary:        Development tools for programs to manipulate PNG image format files
 +Group:          Development/Libraries
 +Requires:       %{name} = %{version}-%{release}
 +Requires:       zlib-devel
 +
 +%description devel
 +The libpng-devel package contains header files and documentation necessary
 +for developing programs using the PNG (Portable Network Graphics) library.
 +
 +%prep
 +%setup -q
 +cp %{SOURCE1001} .
 +
 +%build
 +%ifarch %{arm}
 +CFLAGS+=" -D_ARCH_ARM_ -mfpu=neon"
 +%endif
 +
 +%cmake . -DPNG_STATIC=OFF \
 +         -DSKIP_INSTALL_PROGRAMS=ON \
 +         -DSKIP_INSTALL_EXPORT=ON \
 +%ifarch %{arm}
++         -DPNG_ARM_NEON=on \
 +%else
 +         -DPNG_ARM_NEON=off \
 +%endif
 +         %{?ubsan: -DPNG_ARM_NEON=off}
 +
 +make %{?jobs:-j%jobs}
 +
 +%install
 +%make_install
 +rm -rf %{buildroot}/usr/share/man
 +
 +%post -p /sbin/ldconfig
 +%postun -p /sbin/ldconfig
 +
 +%files
 +%manifest %{name}.manifest
 +%license LICENSE
 +%{_libdir}/libpng*.so.*
 +
 +%files devel
 +%manifest %{name}.manifest
 +%{_bindir}/*
 +%{_includedir}/*
 +%{_libdir}/libpng*.so
 +%{_libdir}/pkgconfig/*
 +
diff --combined png.c
index 757c755,4f3e8bb..4f3e8bb
mode 100755,100644..100755
--- 1/png.c
--- 2/png.c
+++ b/png.c
@@@ -1,7 -1,7 +1,7 @@@
  
  /* png.c - location for general purpose libpng functions
   *
-  * Copyright (c) 2018-2019 Cosmin Truta
+  * Copyright (c) 2018-2022 Cosmin Truta
   * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
   * Copyright (c) 1996-1997 Andreas Dilger
   * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
@@@ -14,7 -14,7 +14,7 @@@
  #include "pngpriv.h"
  
  /* Generate a compiler error if there is an old png.h in the search path. */
- typedef png_libpng_version_1_6_37 Your_png_h_is_not_version_1_6_37;
+ typedef png_libpng_version_1_6_39 Your_png_h_is_not_version_1_6_39;
  
  #ifdef __GNUC__
  /* The version tests may need to be added to, but the problem warning has
@@@ -720,7 -720,7 +720,7 @@@ png_init_io(png_structrp png_ptr, png_F
   *
   * Where UNSIGNED_MAX is the appropriate maximum unsigned value, so when the
   * negative integral value is added the result will be an unsigned value
-  * correspnding to the 2's complement representation.
+  * corresponding to the 2's complement representation.
   */
  void PNGAPI
  png_save_int_32(png_bytep buf, png_int_32 i)
@@@ -815,8 -815,8 +815,8 @@@ png_get_copyright(png_const_structrp pn
     return PNG_STRING_COPYRIGHT
  #else
     return PNG_STRING_NEWLINE \
-       "libpng version 1.6.37" PNG_STRING_NEWLINE \
-       "Copyright (c) 2018-2019 Cosmin Truta" PNG_STRING_NEWLINE \
+       "libpng version 1.6.39" PNG_STRING_NEWLINE \
+       "Copyright (c) 2018-2022 Cosmin Truta" PNG_STRING_NEWLINE \
        "Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson" \
        PNG_STRING_NEWLINE \
        "Copyright (c) 1996-1997 Andreas Dilger" PNG_STRING_NEWLINE \
@@@ -1843,12 -1843,12 +1843,12 @@@ png_icc_profile_error(png_const_structr
  #  ifdef PNG_WARNINGS_SUPPORTED
     else
        {
-          char number[PNG_NUMBER_BUFFER_SIZE]; /* +24 = 114*/
+          char number[PNG_NUMBER_BUFFER_SIZE]; /* +24 = 114 */
  
           pos = png_safecat(message, (sizeof message), pos,
               png_format_number(number, number+(sizeof number),
               PNG_NUMBER_FORMAT_x, value));
-          pos = png_safecat(message, (sizeof message), pos, "h: "); /*+2 = 116*/
+          pos = png_safecat(message, (sizeof message), pos, "h: "); /* +2 = 116 */
        }
  #  endif
     /* The 'reason' is an arbitrary message, allow +79 maximum 195 */
@@@ -2710,7 -2710,7 +2710,7 @@@ png_check_IHDR(png_const_structrp png_p
  
  int /* PRIVATE */
  png_check_fp_number(png_const_charp string, size_t size, int *statep,
-     png_size_tp whereami)
+     size_t *whereami)
  {
     int state = *statep;
     size_t i = *whereami;
diff --combined png.h
--- 1/png.h
--- 2/png.h
+++ b/png.h
@@@ -1,9 -1,9 +1,9 @@@
  
  /* png.h - header file for PNG reference library
   *
-  * libpng version 1.6.37 - April 14, 2019
+  * libpng version 1.6.39 - November 20, 2022
   *
-  * Copyright (c) 2018-2019 Cosmin Truta
+  * Copyright (c) 2018-2022 Cosmin Truta
   * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
   * Copyright (c) 1996-1997 Andreas Dilger
   * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
@@@ -15,7 -15,7 +15,7 @@@
   *   libpng versions 0.89, June 1996, through 0.96, May 1997: Andreas Dilger
   *   libpng versions 0.97, January 1998, through 1.6.35, July 2018:
   *     Glenn Randers-Pehrson
-  *   libpng versions 1.6.36, December 2018, through 1.6.37, April 2019:
+  *   libpng versions 1.6.36, December 2018, through 1.6.39, November 2022:
   *     Cosmin Truta
   *   See also "Contributing Authors", below.
   */
@@@ -27,8 -27,8 +27,8 @@@
   * PNG Reference Library License version 2
   * ---------------------------------------
   *
-  *  * Copyright (c) 1995-2019 The PNG Reference Library Authors.
-  *  * Copyright (c) 2018-2019 Cosmin Truta.
+  *  * Copyright (c) 1995-2022 The PNG Reference Library Authors.
+  *  * Copyright (c) 2018-2022 Cosmin Truta.
   *  * Copyright (c) 2000-2002, 2004, 2006-2018 Glenn Randers-Pehrson.
   *  * Copyright (c) 1996-1997 Andreas Dilger.
   *  * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
   *    ...
   *    1.5.30                  15    10530  15.so.15.30[.0]
   *    ...
-  *    1.6.37                  16    10637  16.so.16.37[.0]
+  *    1.6.39                  16    10639  16.so.16.39[.0]
   *
   *    Henceforth the source version will match the shared-library major and
   *    minor numbers; the shared-library major version number will be used for
   */
  
  /* Version information for png.h - this should match the version in png.c */
- #define PNG_LIBPNG_VER_STRING "1.6.37"
- #define PNG_HEADER_VERSION_STRING " libpng version 1.6.37 - April 14, 2019\n"
+ #define PNG_LIBPNG_VER_STRING "1.6.39"
+ #define PNG_HEADER_VERSION_STRING " libpng version 1.6.39 - November 20, 2022\n"
  
  #define PNG_LIBPNG_VER_SONUM   16
  #define PNG_LIBPNG_VER_DLLNUM  16
  /* These should match the first 3 components of PNG_LIBPNG_VER_STRING: */
  #define PNG_LIBPNG_VER_MAJOR   1
  #define PNG_LIBPNG_VER_MINOR   6
- #define PNG_LIBPNG_VER_RELEASE 37
+ #define PNG_LIBPNG_VER_RELEASE 39
  
  /* This should be zero for a public release, or non-zero for a
   * development version.  [Deprecated]
   * From version 1.0.1 it is:
   * XXYYZZ, where XX=major, YY=minor, ZZ=release
   */
- #define PNG_LIBPNG_VER 10637 /* 1.6.37 */
+ #define PNG_LIBPNG_VER 10639 /* 1.6.39 */
  
  /* Library configuration: these options cannot be changed after
   * the library has been built.
  #   include "pnglibconf.h"
  #endif
  
 +#define PNG_APNG_SUPPORTED
 +#define PNG_READ_APNG_SUPPORTED
 +#define PNG_WRITE_APNG_SUPPORTED
 +
  #ifndef PNG_VERSION_INFO_ONLY
  /* Machine specific configuration. */
  #  include "pngconf.h"
@@@ -429,21 -425,10 +429,21 @@@ extern "C" 
   * See pngconf.h for base types that vary by machine/system
   */
  
 +#ifdef PNG_APNG_SUPPORTED
 +/* dispose_op flags from inside fcTL */
 +#define PNG_DISPOSE_OP_NONE        0x00U
 +#define PNG_DISPOSE_OP_BACKGROUND  0x01U
 +#define PNG_DISPOSE_OP_PREVIOUS    0x02U
 +
 +/* blend_op flags from inside fcTL */
 +#define PNG_BLEND_OP_SOURCE        0x00U
 +#define PNG_BLEND_OP_OVER          0x01U
 +#endif /* PNG_APNG_SUPPORTED */
 +
  /* This triggers a compiler error in png.c, if png.c and png.h
   * do not agree upon the version number.
   */
- typedef char* png_libpng_version_1_6_37;
+ typedef char* png_libpng_version_1_6_39;
  
  /* Basic control structions.  Read libpng-manual.txt or libpng.3 for more info.
   *
@@@ -591,32 -576,6 +591,32 @@@ typedef struct png_text_struc
     png_charp lang_key;     /* keyword translated UTF-8 string, 0 or more
                                chars or a NULL pointer */
  } png_text;
 +
 +/* VD_TIZEN_ONLY */
 +/* Adding PNG Color pick feature.*/
 +typedef enum _Png_Color_Pick_Region_
 +{
 +        PNG_COLORPICK_TOP = 0,
 +        PNG_COLORPICK_MIDDLE,
 +        PNG_COLORPICK_BOTTOM,
 +}PngColorPickRegion;
 +
 +struct _Png_Color_Pick_Struct_
 +{
 +      unsigned int sumR;
 +      unsigned int sumG;
 +      unsigned int sumB;
 +      int enable;
 +      int     perc;
 +      int x1;
 +      int y1;
 +      int x2;
 +      int y2;
 +      PngColorPickRegion region;
 +};
 +typedef struct _Png_Color_Pick_Struct_ PngPickColor; /* TODO : PngPickColor will be changed to PngColorPick in future*/
 +/* VD_TIZEN_ONLY_END */
 +
  typedef png_text * png_textp;
  typedef const png_text * png_const_textp;
  typedef png_text * * png_textpp;
@@@ -787,10 -746,6 +787,10 @@@ typedef png_unknown_chunk * * png_unkno
  #define PNG_INFO_sCAL 0x4000U  /* ESR, 1.0.6 */
  #define PNG_INFO_IDAT 0x8000U  /* ESR, 1.0.6 */
  #define PNG_INFO_eXIf 0x10000U /* GR-P, 1.6.31 */
 +#ifdef PNG_APNG_SUPPORTED
 +#define PNG_INFO_acTL 0x20000U
 +#define PNG_INFO_fcTL 0x40000U
 +#endif
  
  /* This is used for the transformation routines, as some of them
   * change these values for the row.  It also should enable using
@@@ -828,10 -783,6 +828,10 @@@ typedef PNG_CALLBACK(void, *png_write_s
  #ifdef PNG_PROGRESSIVE_READ_SUPPORTED
  typedef PNG_CALLBACK(void, *png_progressive_info_ptr, (png_structp, png_infop));
  typedef PNG_CALLBACK(void, *png_progressive_end_ptr, (png_structp, png_infop));
 +#ifdef PNG_APNG_SUPPORTED
 +typedef PNG_CALLBACK(void, *png_progressive_frame_ptr, (png_structp,
 +    png_uint_32));
 +#endif
  
  /* The following callback receives png_uint_32 row_number, int pass for the
   * png_bytep data of the row.  When transforming an interlaced image the
@@@ -1495,7 -1446,7 +1495,7 @@@ PNG_EXPORT(66, void, png_set_crc_action
   * mainly useful for testing, as the defaults should work with most users.
   * Those users who are tight on memory or want faster performance at the
   * expense of compression can modify them.  See the compression library
-  * header file (zlib.h) for an explination of the compression functions.
+  * header file (zlib.h) for an explanation of the compression functions.
   */
  
  /* Set the filtering method(s) used by libpng.  Currently, the only valid
@@@ -1550,7 -1501,7 +1550,7 @@@ PNG_FIXED_EXPORT(209, void, png_set_fil
   * 0 - 9, corresponding directly to the zlib compression levels 0 - 9
   * (0 - no compression, 9 - "maximal" compression).  Note that tests have
   * shown that zlib compression levels 3-6 usually perform as well as level 9
-  * for PNG images, and do considerably fewer caclulations.  In the future,
+  * for PNG images, and do considerably fewer calculations.  In the future,
   * these values may not correspond directly to the zlib compression levels.
   */
  #ifdef PNG_WRITE_CUSTOMIZE_COMPRESSION_SUPPORTED
@@@ -3275,90 -3226,6 +3275,90 @@@ PNG_EXPORT(244, int, png_set_option, (p
  /*******************************************************************************
   *  END OF HARDWARE AND SOFTWARE OPTIONS
   ******************************************************************************/
 +#ifdef PNG_APNG_SUPPORTED
 +PNG_EXPORT(250, png_uint_32, png_get_acTL, (png_structp png_ptr,
 +   png_infop info_ptr, png_uint_32 *num_frames, png_uint_32 *num_plays));
 +
 +PNG_EXPORT(251, png_uint_32, png_set_acTL, (png_structp png_ptr,
 +   png_infop info_ptr, png_uint_32 num_frames, png_uint_32 num_plays));
 +
 +PNG_EXPORT(252, png_uint_32, png_get_num_frames, (png_structp png_ptr,
 +   png_infop info_ptr));
 +
 +PNG_EXPORT(253, png_uint_32, png_get_num_plays, (png_structp png_ptr,
 +   png_infop info_ptr));
 +
 +PNG_EXPORT(254, png_uint_32, png_get_next_frame_fcTL,
 +   (png_structp png_ptr, png_infop info_ptr, png_uint_32 *width,
 +   png_uint_32 *height, png_uint_32 *x_offset, png_uint_32 *y_offset,
 +   png_uint_16 *delay_num, png_uint_16 *delay_den, png_byte *dispose_op,
 +   png_byte *blend_op));
 +
 +PNG_EXPORT(255, png_uint_32, png_set_next_frame_fcTL,
 +   (png_structp png_ptr, png_infop info_ptr, png_uint_32 width,
 +   png_uint_32 height, png_uint_32 x_offset, png_uint_32 y_offset,
 +   png_uint_16 delay_num, png_uint_16 delay_den, png_byte dispose_op,
 +   png_byte blend_op));
 +
 +PNG_EXPORT(256, png_uint_32, png_get_next_frame_width,
 +   (png_structp png_ptr, png_infop info_ptr));
 +PNG_EXPORT(257, png_uint_32, png_get_next_frame_height,
 +   (png_structp png_ptr, png_infop info_ptr));
 +PNG_EXPORT(258, png_uint_32, png_get_next_frame_x_offset,
 +   (png_structp png_ptr, png_infop info_ptr));
 +PNG_EXPORT(259, png_uint_32, png_get_next_frame_y_offset,
 +   (png_structp png_ptr, png_infop info_ptr));
 +PNG_EXPORT(260, png_uint_16, png_get_next_frame_delay_num,
 +   (png_structp png_ptr, png_infop info_ptr));
 +PNG_EXPORT(261, png_uint_16, png_get_next_frame_delay_den,
 +   (png_structp png_ptr, png_infop info_ptr));
 +PNG_EXPORT(262, png_byte, png_get_next_frame_dispose_op,
 +   (png_structp png_ptr, png_infop info_ptr));
 +PNG_EXPORT(263, png_byte, png_get_next_frame_blend_op,
 +   (png_structp png_ptr, png_infop info_ptr));
 +PNG_EXPORT(264, png_byte, png_get_first_frame_is_hidden,
 +   (png_structp png_ptr, png_infop info_ptr));
 +PNG_EXPORT(265, png_uint_32, png_set_first_frame_is_hidden,
 +   (png_structp png_ptr, png_infop info_ptr, png_byte is_hidden));
 +
 +#ifdef PNG_READ_APNG_SUPPORTED
 +PNG_EXPORT(266, void, png_read_frame_head, (png_structp png_ptr,
 +   png_infop info_ptr));
 +#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
 +PNG_EXPORT(267, void, png_set_progressive_frame_fn, (png_structp png_ptr,
 +   png_progressive_frame_ptr frame_info_fn,
 +   png_progressive_frame_ptr frame_end_fn));
 +#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */
 +#endif /* PNG_READ_APNG_SUPPORTED */
 +
 +#ifdef PNG_WRITE_APNG_SUPPORTED
 +PNG_EXPORT(268, void, png_write_frame_head, (png_structp png_ptr,
 +   png_infop info_ptr, png_bytepp row_pointers,
 +   png_uint_32 width, png_uint_32 height,
 +   png_uint_32 x_offset, png_uint_32 y_offset,
 +   png_uint_16 delay_num, png_uint_16 delay_den, png_byte dispose_op,
 +   png_byte blend_op));
 +
 +PNG_EXPORT(269, void, png_write_frame_tail, (png_structp png_ptr,
 +   png_infop info_ptr));
 +#endif /* PNG_WRITE_APNG_SUPPORTED */
 +#endif /* PNG_APNG_SUPPORTED */
 +
 +#ifndef __TIZEN__
 +#define __TIZEN__
 +#endif
 +#ifdef __TIZEN__
 +/* Read the whole image into memory at once. */
 +#ifdef PNG_APNG_SUPPORTED
 +PNG_EXPORT(270, void, png_read_image_with_pick_color, (png_structp png_ptr,
 +   png_bytepp image,
 +   PngPickColor *pickcolor));
 +#else
 +PNG_EXPORT(250, void, png_read_image_with_pick_color, (png_structp png_ptr,
 +   png_bytepp image,
 +   PngPickColor *pickcolor));
 +#endif
 +#endif
  
  /* Maintainer: Put new public prototypes here ^, in libpng.3, in project
   * defs, and in scripts/symbols.def.
   * one to use is one more than this.)
   */
  #ifdef PNG_EXPORT_LAST_ORDINAL
 +#ifdef __TIZEN__
 +#ifdef PNG_APNG_SUPPORTED
 +  PNG_EXPORT_LAST_ORDINAL(270);
 +#else
 +  PNG_EXPORT_LAST_ORDINAL(250);
 +#endif /* PNG_APNG_SUPPORTED */
 +#else
 +#ifdef PNG_APNG_SUPPORTED
 +  PNG_EXPORT_LAST_ORDINAL(269);
 +#else
    PNG_EXPORT_LAST_ORDINAL(249);
 +#endif /* PNG_APNG_SUPPORTED */
 +#endif /* __TIZEN__ */
  #endif
  
  #ifdef __cplusplus
diff --combined pngget.c
+++ b/pngget.c
@@@ -1151,7 -1151,7 +1151,7 @@@ png_get_unknown_chunks(png_const_struct
  
  #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
  png_byte PNGAPI
- png_get_rgb_to_gray_status (png_const_structrp png_ptr)
+ png_get_rgb_to_gray_status(png_const_structrp png_ptr)
  {
     return (png_byte)(png_ptr ? png_ptr->rgb_to_gray_status : 0);
  }
@@@ -1192,27 -1192,27 +1192,27 @@@ png_get_compression_buffer_size(png_con
  /* These functions were added to libpng 1.2.6 and were enabled
   * by default in libpng-1.4.0 */
  png_uint_32 PNGAPI
- png_get_user_width_max (png_const_structrp png_ptr)
+ png_get_user_width_max(png_const_structrp png_ptr)
  {
     return (png_ptr ? png_ptr->user_width_max : 0);
  }
  
  png_uint_32 PNGAPI
- png_get_user_height_max (png_const_structrp png_ptr)
+ png_get_user_height_max(png_const_structrp png_ptr)
  {
     return (png_ptr ? png_ptr->user_height_max : 0);
  }
  
  /* This function was added to libpng 1.4.0 */
  png_uint_32 PNGAPI
- png_get_chunk_cache_max (png_const_structrp png_ptr)
+ png_get_chunk_cache_max(png_const_structrp png_ptr)
  {
     return (png_ptr ? png_ptr->user_chunk_cache_max : 0);
  }
  
  /* This function was added to libpng 1.4.1 */
  png_alloc_size_t PNGAPI
- png_get_chunk_malloc_max (png_const_structrp png_ptr)
+ png_get_chunk_malloc_max(png_const_structrp png_ptr)
  {
     return (png_ptr ? png_ptr->user_chunk_malloc_max : 0);
  }
  /* These functions were added to libpng 1.4.0 */
  #ifdef PNG_IO_STATE_SUPPORTED
  png_uint_32 PNGAPI
- png_get_io_state (png_const_structrp png_ptr)
+ png_get_io_state(png_const_structrp png_ptr)
  {
     return png_ptr->io_state;
  }
  
  png_uint_32 PNGAPI
- png_get_io_chunk_type (png_const_structrp png_ptr)
+ png_get_io_chunk_type(png_const_structrp png_ptr)
  {
     return png_ptr->chunk_name;
  }
@@@ -1246,166 -1246,4 +1246,166 @@@ png_get_palette_max(png_const_structp p
  #  endif
  #endif
  
 +#ifdef PNG_APNG_SUPPORTED
 +png_uint_32 PNGAPI
 +png_get_acTL(png_structp png_ptr, png_infop info_ptr,
 +             png_uint_32 *num_frames, png_uint_32 *num_plays)
 +{
 +    png_debug1(1, "in %s retrieval function", "acTL");
 +
 +    if (png_ptr != NULL && info_ptr != NULL &&
 +        (info_ptr->valid & PNG_INFO_acTL) &&
 +        num_frames != NULL && num_plays != NULL)
 +    {
 +        *num_frames = info_ptr->num_frames;
 +        *num_plays = info_ptr->num_plays;
 +        return (1);
 +    }
 +
 +    return (0);
 +}
 +
 +png_uint_32 PNGAPI
 +png_get_num_frames(png_structp png_ptr, png_infop info_ptr)
 +{
 +    png_debug(1, "in png_get_num_frames()");
 +
 +    if (png_ptr != NULL && info_ptr != NULL)
 +        return (info_ptr->num_frames);
 +    return (0);
 +}
 +
 +png_uint_32 PNGAPI
 +png_get_num_plays(png_structp png_ptr, png_infop info_ptr)
 +{
 +    png_debug(1, "in png_get_num_plays()");
 +
 +    if (png_ptr != NULL && info_ptr != NULL)
 +        return (info_ptr->num_plays);
 +    return (0);
 +}
 +
 +png_uint_32 PNGAPI
 +png_get_next_frame_fcTL(png_structp png_ptr, png_infop info_ptr,
 +             png_uint_32 *width, png_uint_32 *height,
 +             png_uint_32 *x_offset, png_uint_32 *y_offset,
 +             png_uint_16 *delay_num, png_uint_16 *delay_den,
 +             png_byte *dispose_op, png_byte *blend_op)
 +{
 +    png_debug1(1, "in %s retrieval function", "fcTL");
 +
 +    if (png_ptr != NULL && info_ptr != NULL &&
 +        (info_ptr->valid & PNG_INFO_fcTL) &&
 +        width != NULL && height != NULL &&
 +        x_offset != NULL && y_offset != NULL &&
 +        delay_num != NULL && delay_den != NULL &&
 +        dispose_op != NULL && blend_op != NULL)
 +    {
 +        *width = info_ptr->next_frame_width;
 +        *height = info_ptr->next_frame_height;
 +        *x_offset = info_ptr->next_frame_x_offset;
 +        *y_offset = info_ptr->next_frame_y_offset;
 +        *delay_num = info_ptr->next_frame_delay_num;
 +        *delay_den = info_ptr->next_frame_delay_den;
 +        *dispose_op = info_ptr->next_frame_dispose_op;
 +        *blend_op = info_ptr->next_frame_blend_op;
 +        return (1);
 +    }
 +
 +    return (0);
 +}
 +
 +png_uint_32 PNGAPI
 +png_get_next_frame_width(png_structp png_ptr, png_infop info_ptr)
 +{
 +    png_debug(1, "in png_get_next_frame_width()");
 +
 +    if (png_ptr != NULL && info_ptr != NULL)
 +        return (info_ptr->next_frame_width);
 +    return (0);
 +}
 +
 +png_uint_32 PNGAPI
 +png_get_next_frame_height(png_structp png_ptr, png_infop info_ptr)
 +{
 +    png_debug(1, "in png_get_next_frame_height()");
 +
 +    if (png_ptr != NULL && info_ptr != NULL)
 +        return (info_ptr->next_frame_height);
 +    return (0);
 +}
 +
 +png_uint_32 PNGAPI
 +png_get_next_frame_x_offset(png_structp png_ptr, png_infop info_ptr)
 +{
 +    png_debug(1, "in png_get_next_frame_x_offset()");
 +
 +    if (png_ptr != NULL && info_ptr != NULL)
 +        return (info_ptr->next_frame_x_offset);
 +    return (0);
 +}
 +
 +png_uint_32 PNGAPI
 +png_get_next_frame_y_offset(png_structp png_ptr, png_infop info_ptr)
 +{
 +    png_debug(1, "in png_get_next_frame_y_offset()");
 +
 +    if (png_ptr != NULL && info_ptr != NULL)
 +        return (info_ptr->next_frame_y_offset);
 +    return (0);
 +}
 +
 +png_uint_16 PNGAPI
 +png_get_next_frame_delay_num(png_structp png_ptr, png_infop info_ptr)
 +{
 +    png_debug(1, "in png_get_next_frame_delay_num()");
 +
 +    if (png_ptr != NULL && info_ptr != NULL)
 +        return (info_ptr->next_frame_delay_num);
 +    return (0);
 +}
 +
 +png_uint_16 PNGAPI
 +png_get_next_frame_delay_den(png_structp png_ptr, png_infop info_ptr)
 +{
 +    png_debug(1, "in png_get_next_frame_delay_den()");
 +
 +    if (png_ptr != NULL && info_ptr != NULL)
 +        return (info_ptr->next_frame_delay_den);
 +    return (0);
 +}
 +
 +png_byte PNGAPI
 +png_get_next_frame_dispose_op(png_structp png_ptr, png_infop info_ptr)
 +{
 +    png_debug(1, "in png_get_next_frame_dispose_op()");
 +
 +    if (png_ptr != NULL && info_ptr != NULL)
 +        return (info_ptr->next_frame_dispose_op);
 +    return (0);
 +}
 +
 +png_byte PNGAPI
 +png_get_next_frame_blend_op(png_structp png_ptr, png_infop info_ptr)
 +{
 +    png_debug(1, "in png_get_next_frame_blend_op()");
 +
 +    if (png_ptr != NULL && info_ptr != NULL)
 +        return (info_ptr->next_frame_blend_op);
 +    return (0);
 +}
 +
 +png_byte PNGAPI
 +png_get_first_frame_is_hidden(png_structp png_ptr, png_infop info_ptr)
 +{
 +    png_debug(1, "in png_first_frame_is_hidden()");
 +
 +    if (png_ptr != NULL)
 +       return (png_byte)(png_ptr->apng_flags & PNG_FIRST_FRAME_HIDDEN);
 +
 +    PNG_UNUSED(info_ptr)
 +
 +    return 0;
 +}
 +#endif /* PNG_APNG_SUPPORTED */
  #endif /* READ || WRITE */
diff --combined pngpriv.h
+++ b/pngpriv.h
@@@ -1,7 -1,7 +1,7 @@@
  
  /* pngpriv.h - private declarations for use inside libpng
   *
-  * Copyright (c) 2018-2019 Cosmin Truta
+  * Copyright (c) 2018-2022 Cosmin Truta
   * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
   * Copyright (c) 1996-1997 Andreas Dilger
   * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
  #     else /* !defined __ARM_NEON__ */
           /* The 'intrinsics' code simply won't compile without this -mfpu=neon:
            */
- #        if !defined(__aarch64__)
+ #        if !defined(__aarch64__) && !defined(_M_ARM64)
              /* The assembler code currently does not work on ARM64 */
  #          define PNG_ARM_NEON_IMPLEMENTATION 2
  #        endif /* __aarch64__ */
        /* Use the intrinsics code by default. */
  #     define PNG_ARM_NEON_IMPLEMENTATION 1
  #  endif
+ #else /* PNG_ARM_NEON_OPT == 0 */
+ #     define PNG_ARM_NEON_IMPLEMENTATION 0
  #endif /* PNG_ARM_NEON_OPT > 0 */
  
  #ifndef PNG_MIPS_MSA_OPT
  #  ifndef PNG_MIPS_MSA_IMPLEMENTATION
  #     define PNG_MIPS_MSA_IMPLEMENTATION 1
  #  endif
+ #else
+ #  define PNG_MIPS_MSA_IMPLEMENTATION 0
  #endif /* PNG_MIPS_MSA_OPT > 0 */
  
  #if PNG_POWERPC_VSX_OPT > 0
  #  define PNG_FILTER_OPTIMIZATIONS png_init_filter_functions_vsx
  #  define PNG_POWERPC_VSX_IMPLEMENTATION 1
+ #else
+ #  define PNG_POWERPC_VSX_IMPLEMENTATION 0
  #endif
  
  
     static_cast<type>(static_cast<const void*>(value))
  #else
  #  define png_voidcast(type, value) (value)
- #  ifdef _WIN64
- #     ifdef __GNUC__
-          typedef unsigned long long png_ptruint;
- #     else
-          typedef unsigned __int64 png_ptruint;
- #     endif
- #  else
-       typedef unsigned long png_ptruint;
- #  endif
- #  define png_constcast(type, value) ((type)(png_ptruint)(const void*)(value))
+ #  define png_constcast(type, value) ((type)(void*)(const void*)(value))
  #  define png_aligncast(type, value) ((void*)(value))
  #  define png_aligncastconst(type, value) ((const void*)(value))
  #endif /* __cplusplus */
  #  include <alloc.h>
  #endif
  
- #if defined(WIN32) || defined(_Windows) || defined(_WINDOWS) || \
-     defined(_WIN32) || defined(__WIN32__)
- #  include <windows.h>  /* defines _WINDOWS_ macro */
+ #if defined(_WIN32) || defined(__WIN32__) || defined(__NT__)
+ #  include <windows.h>
  #endif
  #endif /* PNG_VERSION_INFO_ONLY */
  
   * functions that are passed far data must be model-independent.
   */
  
- /* Memory model/platform independent fns */
+ /* Platform-independent functions */
  #ifndef PNG_ABORT
- #  ifdef _WINDOWS_
- #    define PNG_ABORT() ExitProcess(0)
- #  else
- #    define PNG_ABORT() abort()
- #  endif
+ #  define PNG_ABORT() abort()
  #endif
  
  /* These macros may need to be architecture dependent. */
- #define PNG_ALIGN_NONE   0 /* do not use data alignment */
- #define PNG_ALIGN_ALWAYS 1 /* assume unaligned accesses are OK */
+ #define PNG_ALIGN_NONE      0 /* do not use data alignment */
+ #define PNG_ALIGN_ALWAYS    1 /* assume unaligned accesses are OK */
  #ifdef offsetof
- #  define PNG_ALIGN_OFFSET 2 /* use offsetof to determine alignment */
+ #  define PNG_ALIGN_OFFSET  2 /* use offsetof to determine alignment */
  #else
  #  define PNG_ALIGN_OFFSET -1 /* prevent the use of this */
  #endif
- #define PNG_ALIGN_SIZE   3 /* use sizeof to determine alignment */
+ #define PNG_ALIGN_SIZE      3 /* use sizeof to determine alignment */
  
  #ifndef PNG_ALIGN_TYPE
     /* Default to using aligned access optimizations and requiring alignment to a
     /* This is used because in some compiler implementations non-aligned
      * structure members are supported, so the offsetof approach below fails.
      * Set PNG_ALIGN_SIZE=0 for compiler combinations where unaligned access
-     * is good for performance.  Do not do this unless you have tested the result
-     * and understand it.
+     * is good for performance.  Do not do this unless you have tested the
+     * result and understand it.
      */
- #  define png_alignof(type) (sizeof (type))
+ #  define png_alignof(type) (sizeof(type))
  #else
  #  if PNG_ALIGN_TYPE == PNG_ALIGN_OFFSET
- #     define png_alignof(type) offsetof(struct{char c; type t;}, t)
+ #    define png_alignof(type) offsetof(struct{char c; type t;}, t)
  #  else
- #     if PNG_ALIGN_TYPE == PNG_ALIGN_ALWAYS
- #        define png_alignof(type) (1)
- #     endif
-       /* Else leave png_alignof undefined to prevent use thereof */
+ #    if PNG_ALIGN_TYPE == PNG_ALIGN_ALWAYS
+ #      define png_alignof(type) 1
+ #    endif
+      /* Else leave png_alignof undefined to prevent use thereof */
  #  endif
  #endif
  
- /* This implicitly assumes alignment is always to a power of 2. */
+ /* This implicitly assumes alignment is always a multiple of 2. */
  #ifdef png_alignof
- #  define png_isaligned(ptr, type)\
-    (((type)((const char*)ptr-(const char*)0) & \
-    (type)(png_alignof(type)-1)) == 0)
+ #  define png_isaligned(ptr, type) \
+    (((type)(size_t)((const void*)(ptr)) & (type)(png_alignof(type)-1)) == 0)
  #else
  #  define png_isaligned(ptr, type) 0
  #endif
  #define PNG_HAVE_CHUNK_AFTER_IDAT 0x2000U /* Have another chunk after IDAT */
                     /*             0x4000U (unused) */
  #define PNG_IS_READ_STRUCT        0x8000U /* Else is a write struct */
 +#ifdef PNG_APNG_SUPPORTED
 +#define PNG_HAVE_acTL            0x10000U
 +#define PNG_HAVE_fcTL            0x20000U
 +#endif
  
  /* Flags for the transformations the PNG library does on the image data */
  #define PNG_BGR                 0x0001U
  #define png_tRNS PNG_U32(116,  82,  78,  83)
  #define png_zTXt PNG_U32(122,  84,  88, 116)
  
 +#ifdef PNG_APNG_SUPPORTED
 +#define png_acTL PNG_U32( 97,  99,  84,  76)
 +#define png_fcTL PNG_U32(102,  99,  84,  76)
 +#define png_fdAT PNG_U32(102, 100,  65,  84)
 +
 +/* For png_struct.apng_flags: */
 +#define PNG_FIRST_FRAME_HIDDEN       0x0001U
 +#define PNG_APNG_APP                 0x0002U
 +#endif
 +
  /* The following will work on (signed char*) strings, whereas the get_uint_32
   * macro will fail on top-bit-set values because of the sign extension.
   */
@@@ -1658,47 -1635,6 +1649,47 @@@ PNG_INTERNAL_FUNCTION(void,png_colorspa
      */
  #endif
  
 +#ifdef PNG_APNG_SUPPORTED
 +PNG_INTERNAL_FUNCTION(void,png_ensure_fcTL_is_valid,(png_structp png_ptr,
 +   png_uint_32 width, png_uint_32 height,
 +   png_uint_32 x_offset, png_uint_32 y_offset,
 +   png_uint_16 delay_num, png_uint_16 delay_den,
 +   png_byte dispose_op, png_byte blend_op), PNG_EMPTY);
 +
 +#ifdef PNG_READ_APNG_SUPPORTED
 +PNG_INTERNAL_FUNCTION(void,png_handle_acTL,(png_structp png_ptr, png_infop info_ptr,
 +   png_uint_32 length),PNG_EMPTY);
 +PNG_INTERNAL_FUNCTION(void,png_handle_fcTL,(png_structp png_ptr, png_infop info_ptr,
 +   png_uint_32 length),PNG_EMPTY);
 +PNG_INTERNAL_FUNCTION(void,png_handle_fdAT,(png_structp png_ptr, png_infop info_ptr,
 +   png_uint_32 length),PNG_EMPTY);
 +PNG_INTERNAL_FUNCTION(void,png_have_info,(png_structp png_ptr, png_infop info_ptr),PNG_EMPTY);
 +PNG_INTERNAL_FUNCTION(void,png_ensure_sequence_number,(png_structp png_ptr,
 +   png_uint_32 length),PNG_EMPTY);
 +PNG_INTERNAL_FUNCTION(void,png_read_reset,(png_structp png_ptr),PNG_EMPTY);
 +PNG_INTERNAL_FUNCTION(void,png_read_reinit,(png_structp png_ptr,
 +   png_infop info_ptr),PNG_EMPTY);
 +#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
 +PNG_INTERNAL_FUNCTION(void,png_progressive_read_reset,(png_structp png_ptr),PNG_EMPTY);
 +#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */
 +#endif /* PNG_READ_APNG_SUPPORTED */
 +
 +#ifdef PNG_WRITE_APNG_SUPPORTED
 +PNG_INTERNAL_FUNCTION(void,png_write_acTL,(png_structp png_ptr,
 +   png_uint_32 num_frames, png_uint_32 num_plays),PNG_EMPTY);
 +PNG_INTERNAL_FUNCTION(void,png_write_fcTL,(png_structp png_ptr,
 +   png_uint_32 width, png_uint_32 height,
 +   png_uint_32 x_offset, png_uint_32 y_offset,
 +   png_uint_16 delay_num, png_uint_16 delay_den,
 +   png_byte dispose_op, png_byte blend_op),PNG_EMPTY);
 +PNG_INTERNAL_FUNCTION(void,png_write_fdAT,(png_structp png_ptr,
 +   png_const_bytep data, png_size_t length),PNG_EMPTY);
 +PNG_INTERNAL_FUNCTION(void,png_write_reset,(png_structp png_ptr),PNG_EMPTY);
 +PNG_INTERNAL_FUNCTION(void,png_write_reinit,(png_structp png_ptr,
 +   png_infop info_ptr, png_uint_32 width, png_uint_32 height),PNG_EMPTY);
 +#endif /* PNG_WRITE_APNG_SUPPORTED */
 +#endif /* PNG_APNG_SUPPORTED */
 +
  /* Added at libpng version 1.4.0 */
  #ifdef PNG_COLORSPACE_SUPPORTED
  /* These internal functions are for maintaining the colorspace structure within
@@@ -2010,7 -1946,7 +2001,7 @@@ PNG_INTERNAL_FUNCTION(void,png_ascii_fr
   * the problem character.)  This has not been tested within libpng.
   */
  PNG_INTERNAL_FUNCTION(int,png_check_fp_number,(png_const_charp string,
-    size_t size, int *statep, png_size_tp whereami),PNG_EMPTY);
+    size_t size, int *statep, size_t *whereami),PNG_EMPTY);
  
  /* This is the same but it checks a complete string and returns true
   * only if it just contains a floating point number.  As of 1.5.4 this
diff --combined pngread.c
+++ b/pngread.c
@@@ -161,9 -161,6 +161,9 @@@ png_read_info(png_structrp png_ptr, png
  
        else if (chunk_name == png_IDAT)
        {
 +#ifdef PNG_READ_APNG_SUPPORTED
 +         png_have_info(png_ptr, info_ptr);
 +#endif
           png_ptr->idat_size = length;
           break;
        }
           png_handle_iTXt(png_ptr, info_ptr, length);
  #endif
  
 +#ifdef PNG_READ_APNG_SUPPORTED
 +      else if (chunk_name == png_acTL)
 +         png_handle_acTL(png_ptr, info_ptr, length);
 +
 +      else if (chunk_name == png_fcTL)
 +         png_handle_fcTL(png_ptr, info_ptr, length);
 +
 +      else if (chunk_name == png_fdAT)
 +         png_handle_fdAT(png_ptr, info_ptr, length);
 +#endif
 +
        else
           png_handle_unknown(png_ptr, info_ptr, length,
               PNG_HANDLE_CHUNK_AS_DEFAULT);
  }
  #endif /* SEQUENTIAL_READ */
  
 +#ifdef PNG_READ_APNG_SUPPORTED
 +void PNGAPI
 +png_read_frame_head(png_structp png_ptr, png_infop info_ptr)
 +{
 +    png_byte have_chunk_after_DAT; /* after IDAT or after fdAT */
 +
 +    png_debug(0, "Reading frame head");
 +
 +    if (!(png_ptr->mode & PNG_HAVE_acTL))
 +        png_error(png_ptr, "attempt to png_read_frame_head() but "
 +                           "no acTL present");
 +
 +    /* do nothing for the main IDAT */
 +    if (png_ptr->num_frames_read == 0)
 +        return;
 +
 +    png_read_reset(png_ptr);
 +    png_ptr->flags &= ~PNG_FLAG_ROW_INIT;
 +    png_ptr->mode &= ~PNG_HAVE_fcTL;
 +
 +    have_chunk_after_DAT = 0;
 +    for (;;)
 +    {
 +        png_uint_32 length = png_read_chunk_header(png_ptr);
 +
 +        if (png_ptr->chunk_name == png_IDAT)
 +        {
 +            /* discard trailing IDATs for the first frame */
 +            if (have_chunk_after_DAT || png_ptr->num_frames_read > 1)
 +                png_error(png_ptr, "png_read_frame_head(): out of place IDAT");
 +            png_crc_finish(png_ptr, length);
 +        }
 +
 +        else if (png_ptr->chunk_name == png_fcTL)
 +        {
 +            png_handle_fcTL(png_ptr, info_ptr, length);
 +            have_chunk_after_DAT = 1;
 +        }
 +
 +        else if (png_ptr->chunk_name == png_fdAT)
 +        {
 +            png_ensure_sequence_number(png_ptr, length);
 +
 +            /* discard trailing fdATs for frames other than the first */
 +            if (!have_chunk_after_DAT && png_ptr->num_frames_read > 1)
 +                png_crc_finish(png_ptr, length - 4);
 +            else if(png_ptr->mode & PNG_HAVE_fcTL)
 +            {
 +                png_ptr->idat_size = length - 4;
 +                png_ptr->mode |= PNG_HAVE_IDAT;
 +
 +                break;
 +            }
 +            else
 +                png_error(png_ptr, "png_read_frame_head(): out of place fdAT");
 +        }
 +        else
 +        {
 +            png_warning(png_ptr, "Skipped (ignored) a chunk "
 +                                 "between APNG chunks");
 +            png_crc_finish(png_ptr, length);
 +        }
 +    }
 +}
 +#endif /* PNG_READ_APNG_SUPPORTED */
 +
  /* Optional call to update the users info_ptr structure */
  void PNGAPI
  png_read_update_info(png_structrp png_ptr, png_inforp info_ptr)
@@@ -835,130 -755,6 +835,130 @@@ png_read_image(png_structrp png_ptr, pn
        }
     }
  }
 +
 +#ifdef __TIZEN__
 +void PNGAPI
 +png_read_image_with_pick_color(png_structp png_ptr, png_bytepp image, PngPickColor *pickcolor)
 +{
 +   png_uint_32 i, image_height;
 +   int pass, j;
 +   png_uint_32 /*k = 0,*/ image_bpp = 0, image_width;
 +   png_bytepp rp;
 +   //png_bytep rc;
 +   unsigned int npixels;
 +      int perc_enable_y1, perc_enable_y2;
 +   png_debug(1, "in png_read_image");
 +
 +   if (png_ptr == NULL || pickcolor == NULL)
 +      return;
 +
 +#ifdef PNG_READ_INTERLACING_SUPPORTED
 +   if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
 +   {
 +      pass = png_set_interlace_handling(png_ptr);
 +      /* And make sure transforms are initialized. */
 +      png_start_read_image(png_ptr);
 +   }
 +   else
 +   {
 +      if (png_ptr->interlaced && !(png_ptr->transformations & PNG_INTERLACE))
 +      {
 +         /* Caller called png_start_read_image or png_read_update_info without
 +          * first turning on the PNG_INTERLACE transform.  We can fix this here,
 +          * but the caller should do it!
 +          */
 +         png_warning(png_ptr, "Interlace handling should be turned on when "
 +            "using png_read_image");
 +         /* Make sure this is set correctly */
 +         png_ptr->num_rows = png_ptr->height;
 +      }
 +
 +      /* Obtain the pass number, which also turns on the PNG_INTERLACE flag in
 +       * the above error case.
 +       */
 +      pass = png_set_interlace_handling(png_ptr);
 +   }
 +#else
 +   if (png_ptr->interlaced)
 +      png_error(png_ptr,
 +          "Cannot read interlaced image -- interlace handler disabled");
 +
 +   pass = 1;
 +#endif
 +
 +   image_height=png_ptr->height;
 +   image_bpp=png_ptr->rowbytes;
 +   image_width=png_ptr->width;
 +   png_ptr->user_chunk_ptr = pickcolor;
 +
 +   if(pickcolor->perc < 0)
 +   {
 +      png_error(png_ptr, "ColorPick percentage is negative");
 +      return;
 +   }
 +   if( (pickcolor->region < PNG_COLORPICK_TOP) || (pickcolor->region > PNG_COLORPICK_BOTTOM))
 +   {
 +      png_error(png_ptr, "ColorPick Region is out of bound");
 +      return;
 +   }
 +   if(pickcolor->region == PNG_COLORPICK_TOP)
 +   {
 +      perc_enable_y1 = 0;
 +      perc_enable_y2 = (pickcolor->perc*image_height/100) - 1;
 +   }
 +   else if(pickcolor->region == PNG_COLORPICK_MIDDLE)
 +   {
 +      perc_enable_y1 = (image_height/2) - (((pickcolor->perc/2)*image_height)/100);
 +      perc_enable_y2 = perc_enable_y1 + ((pickcolor->perc*image_height)/100) - 1;
 +   }
 +   else
 +   {
 +      perc_enable_y1 = (image_height) - ( pickcolor->perc * image_height / 100  );
 +      perc_enable_y2 = image_height - 1;
 +   }
 +
 +   for (j = 0; j < pass; j++)
 +   {
 +      rp = image;
 +      for (i = 0; i < image_height; i++)
 +      {
 +         pickcolor->enable = 0;
 +         if( pickcolor->perc > 0 )
 +         {
 +            if( (int)i >= perc_enable_y1 && (int)i <= perc_enable_y2)
 +            {
 +               pickcolor->enable = 1;
 +            }
 +         }
 +         else
 +         {
 +            if( ((int)i >= pickcolor->y1) && ((int)i <= pickcolor->y2) )
 +            {
 +               pickcolor->enable = 1;
 +            }
 +         }
 +         png_read_row(png_ptr, *rp, NULL);
 +         rp++;
 +      }
 +   }
 +
 +
 +   if(pickcolor->perc > 0)
 +   {
 +      npixels = (pickcolor->perc*image_height*image_width)/100;
 +   }
 +   else
 +   {
 +      npixels = (pickcolor->x2-pickcolor->x1+1)*(pickcolor->y2-pickcolor->y1+1);
 +   }
 +   if(npixels > 0)
 +   {
 +      pickcolor->sumR = pickcolor->sumR/npixels;
 +      pickcolor->sumG = pickcolor->sumG/npixels;
 +      pickcolor->sumB = pickcolor->sumB/npixels;
 +   }
 +}
 +#endif /* __TIZEN__ */
  #endif /* SEQUENTIAL_READ */
  
  #ifdef PNG_SEQUENTIAL_READ_SUPPORTED
@@@ -3656,7 -3452,6 +3656,6 @@@ png_image_read_background(png_voidp arg
  
              for (pass = 0; pass < passes; ++pass)
              {
-                png_bytep row = png_voidcast(png_bytep, display->first_row);
                 unsigned int     startx, stepx, stepy;
                 png_uint_32      y;
  
  
                          inrow += 2; /* gray and alpha channel */
                       }
-                      row += display->row_bytes;
                    }
                 }
              }
diff --combined pngrutil.c
@@@ -1,7 -1,7 +1,7 @@@
  
  /* pngrutil.c - utilities to read a PNG file
   *
-  * Copyright (c) 2018 Cosmin Truta
+  * Copyright (c) 2018-2022 Cosmin Truta
   * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
   * Copyright (c) 1996-1997 Andreas Dilger
   * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
@@@ -14,9 -14,6 +14,9 @@@
   * libpng itself during the course of reading an image.
   */
  
 +#ifdef _ARCH_ARM_
 +#include "arm_neon.h"
 +#endif
  #include "pngpriv.h"
  
  #ifdef PNG_READ_SUPPORTED
@@@ -305,7 -302,6 +305,6 @@@ png_read_buffer(png_structrp png_ptr, p
     if (buffer != NULL && new_size > png_ptr->read_buffer_size)
     {
        png_ptr->read_buffer = NULL;
-       png_ptr->read_buffer = NULL;
        png_ptr->read_buffer_size = 0;
        png_free(png_ptr, buffer);
        buffer = NULL;
@@@ -868,11 -864,6 +867,11 @@@ png_handle_IHDR(png_structrp png_ptr, p
     filter_type = buf[11];
     interlace_type = buf[12];
  
 +#ifdef PNG_READ_APNG_SUPPORTED
 +   png_ptr->first_frame_width = width;
 +   png_ptr->first_frame_height = height;
 +#endif
 +
     /* Set internal variables */
     png_ptr->width = width;
     png_ptr->height = height;
@@@ -2084,21 -2075,22 +2083,22 @@@ png_handle_eXIf(png_structrp png_ptr, p
        png_byte buf[1];
        png_crc_read(png_ptr, buf, 1);
        info_ptr->eXIf_buf[i] = buf[0];
-       if (i == 1 && buf[0] != 'M' && buf[0] != 'I'
-                  && info_ptr->eXIf_buf[0] != buf[0])
+       if (i == 1)
        {
-          png_crc_finish(png_ptr, length);
-          png_chunk_benign_error(png_ptr, "incorrect byte-order specifier");
-          png_free(png_ptr, info_ptr->eXIf_buf);
-          info_ptr->eXIf_buf = NULL;
-          return;
+          if ((buf[0] != 'M' && buf[0] != 'I') ||
+              (info_ptr->eXIf_buf[0] != buf[0]))
+          {
+             png_crc_finish(png_ptr, length - 2);
+             png_chunk_benign_error(png_ptr, "incorrect byte-order specifier");
+             png_free(png_ptr, info_ptr->eXIf_buf);
+             info_ptr->eXIf_buf = NULL;
+             return;
+          }
        }
     }
  
-    if (png_crc_finish(png_ptr, 0) != 0)
-       return;
-    png_set_eXIf_1(png_ptr, info_ptr, length, info_ptr->eXIf_buf);
+    if (png_crc_finish(png_ptr, 0) == 0)
+       png_set_eXIf_1(png_ptr, info_ptr, length, info_ptr->eXIf_buf);
  
     png_free(png_ptr, info_ptr->eXIf_buf);
     info_ptr->eXIf_buf = NULL;
@@@ -2134,8 -2126,9 +2134,9 @@@ png_handle_hIST(png_structrp png_ptr, p
  
     num = length / 2 ;
  
-    if (num != (unsigned int) png_ptr->num_palette ||
-        num > (unsigned int) PNG_MAX_PALETTE_LENGTH)
+    if (length != num * 2 ||
+        num != (unsigned int)png_ptr->num_palette ||
+        num > (unsigned int)PNG_MAX_PALETTE_LENGTH)
     {
        png_crc_finish(png_ptr, length);
        png_chunk_benign_error(png_ptr, "invalid");
@@@ -2865,179 -2858,6 +2866,179 @@@ png_handle_iTXt(png_structrp png_ptr, p
  }
  #endif
  
 +#ifdef PNG_READ_APNG_SUPPORTED
 +void /* PRIVATE */
 +png_handle_acTL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
 +{
 +    png_byte data[8];
 +    png_uint_32 num_frames;
 +    png_uint_32 num_plays;
 +    png_uint_32 didSet;
 +
 +    png_debug(1, "in png_handle_acTL");
 +
 +    if (!(png_ptr->mode & PNG_HAVE_IHDR))
 +    {
 +        png_error(png_ptr, "Missing IHDR before acTL");
 +    }
 +    else if (png_ptr->mode & PNG_HAVE_IDAT)
 +    {
 +        png_warning(png_ptr, "Invalid acTL after IDAT skipped");
 +        png_crc_finish(png_ptr, length);
 +        return;
 +    }
 +    else if (png_ptr->mode & PNG_HAVE_acTL)
 +    {
 +        png_warning(png_ptr, "Duplicate acTL skipped");
 +        png_crc_finish(png_ptr, length);
 +        return;
 +    }
 +    else if (length != 8)
 +    {
 +        png_warning(png_ptr, "acTL with invalid length skipped");
 +        png_crc_finish(png_ptr, length);
 +        return;
 +    }
 +
 +    png_crc_read(png_ptr, data, 8);
 +    png_crc_finish(png_ptr, 0);
 +
 +    num_frames = png_get_uint_31(png_ptr, data);
 +    num_plays = png_get_uint_31(png_ptr, data + 4);
 +
 +    /* the set function will do error checking on num_frames */
 +    didSet = png_set_acTL(png_ptr, info_ptr, num_frames, num_plays);
 +    if(didSet)
 +        png_ptr->mode |= PNG_HAVE_acTL;
 +}
 +
 +void /* PRIVATE */
 +png_handle_fcTL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
 +{
 +    png_byte data[22];
 +    png_uint_32 width;
 +    png_uint_32 height;
 +    png_uint_32 x_offset;
 +    png_uint_32 y_offset;
 +    png_uint_16 delay_num;
 +    png_uint_16 delay_den;
 +    png_byte dispose_op;
 +    png_byte blend_op;
 +
 +    png_debug(1, "in png_handle_fcTL");
 +
 +    png_ensure_sequence_number(png_ptr, length);
 +
 +    if (!(png_ptr->mode & PNG_HAVE_IHDR))
 +    {
 +        png_error(png_ptr, "Missing IHDR before fcTL");
 +    }
 +    else if (png_ptr->mode & PNG_HAVE_IDAT)
 +    {
 +        /* for any frames other then the first this message may be misleading,
 +        * but correct. PNG_HAVE_IDAT is unset before the frame head is read
 +        * i can't think of a better message */
 +        png_warning(png_ptr, "Invalid fcTL after IDAT skipped");
 +        png_crc_finish(png_ptr, length-4);
 +        return;
 +    }
 +    else if (png_ptr->mode & PNG_HAVE_fcTL)
 +    {
 +        png_warning(png_ptr, "Duplicate fcTL within one frame skipped");
 +        png_crc_finish(png_ptr, length-4);
 +        return;
 +    }
 +    else if (length != 26)
 +    {
 +        png_warning(png_ptr, "fcTL with invalid length skipped");
 +        png_crc_finish(png_ptr, length-4);
 +        return;
 +    }
 +
 +    png_crc_read(png_ptr, data, 22);
 +    png_crc_finish(png_ptr, 0);
 +
 +    width = png_get_uint_31(png_ptr, data);
 +    height = png_get_uint_31(png_ptr, data + 4);
 +    x_offset = png_get_uint_31(png_ptr, data + 8);
 +    y_offset = png_get_uint_31(png_ptr, data + 12);
 +    delay_num = png_get_uint_16(data + 16);
 +    delay_den = png_get_uint_16(data + 18);
 +    dispose_op = data[20];
 +    blend_op = data[21];
 +
 +    if (png_ptr->num_frames_read == 0 && (x_offset != 0 || y_offset != 0))
 +    {
 +        png_warning(png_ptr, "fcTL for the first frame must have zero offset");
 +        return;
 +    }
 +
 +    if (info_ptr != NULL)
 +    {
 +        if (png_ptr->num_frames_read == 0 &&
 +            (width != info_ptr->width || height != info_ptr->height))
 +        {
 +            png_warning(png_ptr, "size in first frame's fcTL must match "
 +                               "the size in IHDR");
 +            return;
 +        }
 +
 +        /* The set function will do more error checking */
 +        png_set_next_frame_fcTL(png_ptr, info_ptr, width, height,
 +                                x_offset, y_offset, delay_num, delay_den,
 +                                dispose_op, blend_op);
 +
 +        png_read_reinit(png_ptr, info_ptr);
 +
 +        png_ptr->mode |= PNG_HAVE_fcTL;
 +    }
 +}
 +
 +void /* PRIVATE */
 +png_have_info(png_structp png_ptr, png_infop info_ptr)
 +{
 +    if((info_ptr->valid & PNG_INFO_acTL) && !(info_ptr->valid & PNG_INFO_fcTL))
 +    {
 +        png_ptr->apng_flags |= PNG_FIRST_FRAME_HIDDEN;
 +        info_ptr->num_frames++;
 +    }
 +}
 +
 +void /* PRIVATE */
 +png_handle_fdAT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
 +{
 +    png_ensure_sequence_number(png_ptr, length);
 +
 +    /* This function is only called from png_read_end(), png_read_info(),
 +    * and png_push_read_chunk() which means that:
 +    * - the user doesn't want to read this frame
 +    * - or this is an out-of-place fdAT
 +    * in either case it is safe to ignore the chunk with a warning */
 +    png_warning(png_ptr, "ignoring fdAT chunk");
 +    png_crc_finish(png_ptr, length - 4);
 +    PNG_UNUSED(info_ptr)
 +}
 +
 +void /* PRIVATE */
 +png_ensure_sequence_number(png_structp png_ptr, png_uint_32 length)
 +{
 +    png_byte data[4];
 +    png_uint_32 sequence_number;
 +
 +    if (length < 4)
 +        png_error(png_ptr, "invalid fcTL or fdAT chunk found");
 +
 +    png_crc_read(png_ptr, data, 4);
 +    sequence_number = png_get_uint_31(png_ptr, data);
 +
 +    if (sequence_number != png_ptr->next_seq_num)
 +        png_error(png_ptr, "fcTL or fdAT chunk with out-of-order sequence "
 +                           "number found");
 +
 +    png_ptr->next_seq_num++;
 +}
 +#endif /* PNG_READ_APNG_SUPPORTED */
 +
  #ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
  /* Utility function for png_handle_unknown; set up png_ptr::unknown_chunk */
  static int
@@@ -3366,171 -3186,10 +3367,171 @@@ png_check_chunk_length(png_const_struct
     {
        png_debug2(0," length = %lu, limit = %lu",
           (unsigned long)length,(unsigned long)limit);
-       png_chunk_error(png_ptr, "chunk data is too large");
+       png_benign_error(png_ptr, "chunk data is too large");
     }
  }
  
 +#ifdef __TIZEN__
 +#ifdef _ARCH_ARM_
 +void
 +copy_src_to_dst(png_bytep dp, png_bytep sp, int width,
 +                  int row_stride, int nplanes, PngPickColor *png_pickcolor)
 +{
 +   int j;
 +   unsigned char *src = (unsigned char *)sp;
 +   unsigned char *dst = (unsigned char *)dp;
 +
 +   unsigned long long sumRGBA[4] = {0, 0, 0, 0};
 +   const int const0 = 0;
 +
 +
 +   uint32x4_t sumR_32x4 = vmovq_n_u32 ( 0 );
 +   uint32x4_t sumG_32x4 = vmovq_n_u32 ( 0 );
 +   uint32x4_t sumB_32x4 = vmovq_n_u32 ( 0 );
 +
 +   uint8x16_t R_8x16;
 +   uint8x16_t G_8x16;
 +   uint8x16_t B_8x16;
 +
 +   uint64x1x3_t sumRGB_64x1;
 +
 +   for(j = 0; j < width-(width&0xf); j += 16)
 +   {
 +      if(nplanes == 3)
 +      {
 +         uint8x16x3_t rgb = vld3q_u8 ( src );
 +         vst3q_u8(dst, rgb);
 +         R_8x16 = rgb.val[0];
 +         G_8x16 = rgb.val[1];
 +         B_8x16 = rgb.val[2];
 +      }
 +      else
 +      {
 +         uint8x16x4_t rgb = vld4q_u8 ( src );
 +         vst4q_u8(dst, rgb);
 +         R_8x16 = rgb.val[0];
 +         G_8x16 = rgb.val[1];
 +         B_8x16 = rgb.val[2];
 +      }
 +
 +      if(png_pickcolor && png_pickcolor->enable)
 +      {
 +         if(png_pickcolor->perc > 0)
 +         {
 +            uint16x8_t sumR_16x8 = vpaddlq_u8 ( R_8x16 );
 +            uint16x8_t sumG_16x8 = vpaddlq_u8 ( G_8x16 );
 +            uint16x8_t sumB_16x8 = vpaddlq_u8 ( B_8x16 );
 +
 +            sumR_32x4 = vpadalq_u16 ( sumR_32x4, sumR_16x8 );
 +            sumG_32x4 = vpadalq_u16 ( sumG_32x4, sumG_16x8 );
 +            sumB_32x4 = vpadalq_u16 ( sumB_32x4, sumB_16x8 );
 +         }
 +         else if( (png_pickcolor->x1 > j) && (png_pickcolor->x1 < j + 16) )
 +         {
 +            int x = png_pickcolor->x1;
 +            unsigned char *from = sp + (png_pickcolor->x1 * nplanes);
 +            while( x < j + 16 )
 +            {
 +               png_pickcolor->sumR += from[0];
 +               png_pickcolor->sumG += from[1];
 +               png_pickcolor->sumB += from[2];
 +               from += nplanes;
 +               x ++;
 +            }
 +         }
 +         else if( (png_pickcolor->x2 >= j) && (png_pickcolor->x2 < j + 16) )
 +         {
 +            int x = j;
 +            unsigned char *from = sp + (j * nplanes);
 +            while(x <= png_pickcolor->x2)
 +            {
 +               png_pickcolor->sumR += from[0];
 +               png_pickcolor->sumG += from[1];
 +               png_pickcolor->sumB += from[2];
 +               from += nplanes;
 +               x ++;
 +            }
 +         }
 +         else if ( (j >= png_pickcolor->x1) && (j+15 <= png_pickcolor->x2) )
 +         {
 +            uint16x8_t sumR_16x8 = vpaddlq_u8 ( R_8x16 );
 +            uint16x8_t sumG_16x8 = vpaddlq_u8 ( G_8x16 );
 +            uint16x8_t sumB_16x8 = vpaddlq_u8 ( B_8x16 );
 +
 +            sumR_32x4 = vpadalq_u16 ( sumR_32x4, sumR_16x8 );
 +            sumG_32x4 = vpadalq_u16 ( sumG_32x4, sumG_16x8 );
 +            sumB_32x4 = vpadalq_u16 ( sumB_32x4, sumB_16x8 );
 +         }
 +      }
 +      dst += (nplanes*16);
 +      src += (nplanes*16);
 +   }
 +
 +   if(png_pickcolor && png_pickcolor->enable)
 +   {
 +
 +      uint64x2_t sumR_64x2 = vpaddlq_u32 ( sumR_32x4 );
 +      uint64x2_t sumG_64x2 = vpaddlq_u32 ( sumG_32x4 );
 +      uint64x2_t sumB_64x2 = vpaddlq_u32 ( sumB_32x4 );
 +
 +      uint64x1_t sumR_Lo_64x1 = vget_low_u64 ( sumR_64x2 );
 +      uint64x1_t sumR_Hi_64x1 = vget_high_u64 ( sumR_64x2 );
 +
 +      uint64x1_t sumG_Lo_64x1 = vget_low_u64 ( sumG_64x2 );
 +      uint64x1_t sumG_Hi_64x1 = vget_high_u64 ( sumG_64x2 );
 +
 +      uint64x1_t sumB_Lo_64x1 = vget_low_u64 ( sumB_64x2 );
 +      uint64x1_t sumB_Hi_64x1 = vget_high_u64 ( sumB_64x2 );
 +
 +      sumRGB_64x1.val[0] = vadd_u64 ( sumR_Lo_64x1, sumR_Hi_64x1 );
 +      sumRGB_64x1.val[1] = vadd_u64 ( sumG_Lo_64x1, sumG_Hi_64x1 );
 +      sumRGB_64x1.val[2] = vadd_u64 ( sumB_Lo_64x1, sumB_Hi_64x1 );
 +
 +      vst3_u64( sumRGBA, sumRGB_64x1);
 +
 +      png_pickcolor->sumR += sumRGBA[0];
 +      png_pickcolor->sumG += sumRGBA[1];
 +      png_pickcolor->sumB += sumRGBA[2];
 +   }
 +
 +   memcpy(dst, src, (width-j)*nplanes);
 +   if(png_pickcolor && png_pickcolor->enable)
 +   {
 +      if(png_pickcolor->perc <= 0)
 +      {
 +         if(j < png_pickcolor->x1)
 +         {
 +            j = png_pickcolor->x1;
 +            dst = dp + (j*nplanes);
 +         }
 +         width = png_pickcolor->x2;
 +      }
 +      for(; j < width ; j ++)
 +      {
 +         png_pickcolor->sumR += dst[0];
 +         png_pickcolor->sumG += dst[1];
 +         png_pickcolor->sumB += dst[2];
 +         dst += nplanes;
 +      }
 +   }
 +}
 +
 +void copy_row(png_bytep dp, png_bytep sp, int width, int pixel_bits, PngPickColor *png_pickcolor)
 +{
 +   int row_stride = PNG_ROWBYTES(pixel_bits, width);
 +   if(pixel_bits == 24 || pixel_bits == 32)
 +   {
 +      copy_src_to_dst(dp, sp, width, row_stride, pixel_bits >> 3, png_pickcolor);
 +   }
 +   else
 +   {
 +      memcpy(dp, sp, row_stride);
 +   }
 +
 +}
 +#endif
 +#endif /* __TIZEN__ */
 +
  /* Combines the row recently read in with the existing pixels in the row.  This
   * routine takes care of alpha and transparency if requested.  This routine also
   * handles the two methods of progressive display of interlaced images,
@@@ -4507,38 -4166,7 +4508,38 @@@ png_read_IDAT_data(png_structrp png_ptr
        {
           uInt avail_in;
           png_bytep buffer;
 +#ifdef PNG_READ_APNG_SUPPORTED
 +         png_uint_32 bytes_to_skip = 0;
 +
 +         while (png_ptr->idat_size == 0 || bytes_to_skip != 0)
 +         {
 +            png_crc_finish(png_ptr, bytes_to_skip);
 +            bytes_to_skip = 0;
 +
 +            png_ptr->idat_size = png_read_chunk_header(png_ptr);
 +            if (png_ptr->num_frames_read == 0)
 +            {
 +               if (png_ptr->chunk_name != png_IDAT)
 +                  png_error(png_ptr, "Not enough image data");
 +            }
 +            else
 +            {
 +               if (png_ptr->chunk_name == png_IEND)
 +                  png_error(png_ptr, "Not enough image data");
 +               if (png_ptr->chunk_name != png_fdAT)
 +               {
 +                  png_warning(png_ptr, "Skipped (ignored) a chunk "
 +                                       "between APNG chunks");
 +                  bytes_to_skip = png_ptr->idat_size;
 +                  continue;
 +               }
 +
 +               png_ensure_sequence_number(png_ptr, png_ptr->idat_size);
  
 +               png_ptr->idat_size -= 4;
 +            }
 +         }
 +#else
           while (png_ptr->idat_size == 0)
           {
              png_crc_finish(png_ptr, 0);
              if (png_ptr->chunk_name != png_IDAT)
                 png_error(png_ptr, "Not enough image data");
           }
 -
 +#endif /* PNG_READ_APNG_SUPPORTED */
           avail_in = png_ptr->IDAT_read_size;
  
           if (avail_in > png_ptr->idat_size)
  
           png_ptr->mode |= PNG_AFTER_IDAT;
           png_ptr->flags |= PNG_FLAG_ZSTREAM_ENDED;
 +#ifdef PNG_READ_APNG_SUPPORTED
 +         png_ptr->num_frames_read++;
 +#endif
  
           if (png_ptr->zstream.avail_in > 0 || png_ptr->idat_size > 0)
              png_chunk_benign_error(png_ptr, "Extra compressed data");
@@@ -4997,14 -4622,13 +4998,13 @@@ defined(PNG_USER_TRANSFORM_PTR_SUPPORTE
         */
        {
           png_bytep temp = png_ptr->big_row_buf + 32;
-          int extra = (int)((temp - (png_bytep)0) & 0x0f);
+          size_t extra = (size_t)temp & 0x0f;
           png_ptr->row_buf = temp - extra - 1/*filter byte*/;
  
           temp = png_ptr->big_prev_row + 32;
-          extra = (int)((temp - (png_bytep)0) & 0x0f);
+          extra = (size_t)temp & 0x0f;
           png_ptr->prev_row = temp - extra - 1/*filter byte*/;
        }
  #else
        /* Use 31 bytes of padding before and 17 bytes after row_buf. */
        png_ptr->row_buf = png_ptr->big_row_buf + 31;
  
     png_ptr->flags |= PNG_FLAG_ROW_INIT;
  }
 +
 +#ifdef PNG_READ_APNG_SUPPORTED
 +/* This function is to be called after the main IDAT set has been read and
 + * before a new IDAT is read. It resets some parts of png_ptr
 + * to make them usable by the read functions again */
 +void /* PRIVATE */
 +png_read_reset(png_structp png_ptr)
 +{
 +    png_ptr->mode &= ~PNG_HAVE_IDAT;
 +    png_ptr->mode &= ~PNG_AFTER_IDAT;
 +    png_ptr->row_number = 0;
 +    png_ptr->pass = 0;
 +}
 +
 +void /* PRIVATE */
 +png_read_reinit(png_structp png_ptr, png_infop info_ptr)
 +{
 +    png_ptr->width = info_ptr->next_frame_width;
 +    png_ptr->height = info_ptr->next_frame_height;
 +    png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth,png_ptr->width);
 +    png_ptr->info_rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth,
 +        png_ptr->width);
 +    if (png_ptr->prev_row)
 +        memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1);
 +}
 +
 +#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
 +/* same as png_read_reset() but for the progressive reader */
 +void /* PRIVATE */
 +png_progressive_read_reset(png_structp png_ptr)
 +{
 +#ifdef PNG_READ_INTERLACING_SUPPORTED
 +   /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
 +
 +   /* Start of interlace block */
 +    const int png_pass_start[] = {0, 4, 0, 2, 0, 1, 0};
 +
 +    /* Offset to next interlace block */
 +    const int png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1};
 +
 +    /* Start of interlace block in the y direction */
 +    const int png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1};
 +
 +    /* Offset to next interlace block in the y direction */
 +    const int png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2};
 +
 +    if (png_ptr->interlaced)
 +    {
 +        if (!(png_ptr->transformations & PNG_INTERLACE))
 +            png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 -
 +                                png_pass_ystart[0]) / png_pass_yinc[0];
 +        else
 +            png_ptr->num_rows = png_ptr->height;
 +
 +        png_ptr->iwidth = (png_ptr->width +
 +                           png_pass_inc[png_ptr->pass] - 1 -
 +                           png_pass_start[png_ptr->pass]) /
 +                           png_pass_inc[png_ptr->pass];
 +    }
 +    else
 +#endif /* PNG_READ_INTERLACING_SUPPORTED */
 +    {
 +        png_ptr->num_rows = png_ptr->height;
 +        png_ptr->iwidth = png_ptr->width;
 +    }
 +    png_ptr->flags &= ~PNG_FLAG_ZSTREAM_ENDED;
 +    if (inflateReset(&(png_ptr->zstream)) != Z_OK)
 +        png_error(png_ptr, "inflateReset failed");
 +    png_ptr->zstream.avail_in = 0;
 +    png_ptr->zstream.next_in = 0;
 +    png_ptr->zstream.next_out = png_ptr->row_buf;
 +    png_ptr->zstream.avail_out = (uInt)PNG_ROWBYTES(png_ptr->pixel_depth,
 +        png_ptr->iwidth) + 1;
 +}
 +#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */
 +#endif /* PNG_READ_APNG_SUPPORTED */
  #endif /* READ */
diff --combined pngset.c
+++ b/pngset.c
@@@ -1,7 -1,7 +1,7 @@@
  
  /* pngset.c - storage of image information into info struct
   *
-  * Copyright (c) 2018 Cosmin Truta
+  * Copyright (c) 2018-2022 Cosmin Truta
   * Copyright (c) 1998-2018 Glenn Randers-Pehrson
   * Copyright (c) 1996-1997 Andreas Dilger
   * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
@@@ -288,11 -288,6 +288,11 @@@ png_set_IHDR(png_const_structrp png_ptr
     info_ptr->pixel_depth = (png_byte)(info_ptr->channels * info_ptr->bit_depth);
  
     info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth, width);
 +
 +#ifdef PNG_APNG_SUPPORTED
 +   /* for non-animated png. this may be overwritten from an acTL chunk later */
 +   info_ptr->num_frames = 1;
 +#endif
  }
  
  #ifdef PNG_oFFs_SUPPORTED
@@@ -1024,6 -1019,9 +1024,9 @@@ png_set_tRNS(png_structrp png_ptr, png_
            info_ptr->trans_alpha = png_voidcast(png_bytep,
                png_malloc(png_ptr, PNG_MAX_PALETTE_LENGTH));
            memcpy(info_ptr->trans_alpha, trans_alpha, (size_t)num_trans);
+           info_ptr->valid |= PNG_INFO_tRNS;
+           info_ptr->free_me |= PNG_FREE_TRNS;
         }
         png_ptr->trans_alpha = info_ptr->trans_alpha;
     }
@@@ -1163,147 -1161,6 +1166,147 @@@ png_set_sPLT(png_const_structrp png_ptr
  }
  #endif /* sPLT */
  
 +#ifdef PNG_APNG_SUPPORTED
 +png_uint_32 PNGAPI
 +png_set_acTL(png_structp png_ptr, png_infop info_ptr,
 +    png_uint_32 num_frames, png_uint_32 num_plays)
 +{
 +    png_debug1(1, "in %s storage function", "acTL");
 +
 +    if (png_ptr == NULL || info_ptr == NULL)
 +    {
 +        png_warning(png_ptr,
 +                    "Call to png_set_acTL() with NULL png_ptr "
 +                    "or info_ptr ignored");
 +        return (0);
 +    }
 +    if (num_frames == 0)
 +    {
 +        png_warning(png_ptr,
 +                    "Ignoring attempt to set acTL with num_frames zero");
 +        return (0);
 +    }
 +    if (num_frames > PNG_UINT_31_MAX)
 +    {
 +        png_warning(png_ptr,
 +                    "Ignoring attempt to set acTL with num_frames > 2^31-1");
 +        return (0);
 +    }
 +    if (num_plays > PNG_UINT_31_MAX)
 +    {
 +        png_warning(png_ptr,
 +                    "Ignoring attempt to set acTL with num_plays "
 +                    "> 2^31-1");
 +        return (0);
 +    }
 +
 +    info_ptr->num_frames = num_frames;
 +    info_ptr->num_plays = num_plays;
 +
 +    info_ptr->valid |= PNG_INFO_acTL;
 +
 +    return (1);
 +}
 +
 +/* delay_num and delay_den can hold any 16-bit values including zero */
 +png_uint_32 PNGAPI
 +png_set_next_frame_fcTL(png_structp png_ptr, png_infop info_ptr,
 +    png_uint_32 width, png_uint_32 height,
 +    png_uint_32 x_offset, png_uint_32 y_offset,
 +    png_uint_16 delay_num, png_uint_16 delay_den,
 +    png_byte dispose_op, png_byte blend_op)
 +{
 +    png_debug1(1, "in %s storage function", "fcTL");
 +
 +    if (png_ptr == NULL || info_ptr == NULL)
 +    {
 +        png_warning(png_ptr,
 +                    "Call to png_set_fcTL() with NULL png_ptr or info_ptr "
 +                    "ignored");
 +        return (0);
 +    }
 +
 +    png_ensure_fcTL_is_valid(png_ptr, width, height, x_offset, y_offset,
 +                             delay_num, delay_den, dispose_op, blend_op);
 +
 +    if (blend_op == PNG_BLEND_OP_OVER)
 +    {
 +        if (!(png_ptr->color_type & PNG_COLOR_MASK_ALPHA) &&
 +            !(png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)))
 +        {
 +          png_warning(png_ptr, "PNG_BLEND_OP_OVER is meaningless "
 +                               "and wasteful for opaque images, ignored");
 +          blend_op = PNG_BLEND_OP_SOURCE;
 +        }
 +    }
 +
 +    info_ptr->next_frame_width = width;
 +    info_ptr->next_frame_height = height;
 +    info_ptr->next_frame_x_offset = x_offset;
 +    info_ptr->next_frame_y_offset = y_offset;
 +    info_ptr->next_frame_delay_num = delay_num;
 +    info_ptr->next_frame_delay_den = delay_den;
 +    info_ptr->next_frame_dispose_op = dispose_op;
 +    info_ptr->next_frame_blend_op = blend_op;
 +
 +    info_ptr->valid |= PNG_INFO_fcTL;
 +
 +    return (1);
 +}
 +
 +void /* PRIVATE */
 +png_ensure_fcTL_is_valid(png_structp png_ptr,
 +    png_uint_32 width, png_uint_32 height,
 +    png_uint_32 x_offset, png_uint_32 y_offset,
 +    png_uint_16 delay_num, png_uint_16 delay_den,
 +    png_byte dispose_op, png_byte blend_op)
 +{
 +    if (width == 0 || width > PNG_UINT_31_MAX)
 +        png_error(png_ptr, "invalid width in fcTL (> 2^31-1)");
 +    if (height == 0 || height > PNG_UINT_31_MAX)
 +        png_error(png_ptr, "invalid height in fcTL (> 2^31-1)");
 +    if (x_offset > PNG_UINT_31_MAX)
 +        png_error(png_ptr, "invalid x_offset in fcTL (> 2^31-1)");
 +    if (y_offset > PNG_UINT_31_MAX)
 +        png_error(png_ptr, "invalid y_offset in fcTL (> 2^31-1)");
 +    if (width + x_offset > png_ptr->first_frame_width ||
 +        height + y_offset > png_ptr->first_frame_height)
 +        png_error(png_ptr, "dimensions of a frame are greater than"
 +                           "the ones in IHDR");
 +
 +    if (dispose_op != PNG_DISPOSE_OP_NONE &&
 +        dispose_op != PNG_DISPOSE_OP_BACKGROUND &&
 +        dispose_op != PNG_DISPOSE_OP_PREVIOUS)
 +        png_error(png_ptr, "invalid dispose_op in fcTL");
 +
 +    if (blend_op != PNG_BLEND_OP_SOURCE &&
 +        blend_op != PNG_BLEND_OP_OVER)
 +        png_error(png_ptr, "invalid blend_op in fcTL");
 +
 +    PNG_UNUSED(delay_num)
 +    PNG_UNUSED(delay_den)
 +}
 +
 +png_uint_32 PNGAPI
 +png_set_first_frame_is_hidden(png_structp png_ptr, png_infop info_ptr,
 +                              png_byte is_hidden)
 +{
 +    png_debug(1, "in png_first_frame_is_hidden()");
 +
 +    if (png_ptr == NULL)
 +        return 0;
 +
 +    if (is_hidden)
 +        png_ptr->apng_flags |= PNG_FIRST_FRAME_HIDDEN;
 +    else
 +        png_ptr->apng_flags &= ~PNG_FIRST_FRAME_HIDDEN;
 +
 +    PNG_UNUSED(info_ptr)
 +
 +    return 1;
 +}
 +#endif /* PNG_APNG_SUPPORTED */
 +
  #ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED
  static png_byte
  check_location(png_const_structrp png_ptr, int location)
@@@ -1472,7 -1329,7 +1475,7 @@@ png_set_unknown_chunk_location(png_cons
  
  #ifdef PNG_MNG_FEATURES_SUPPORTED
  png_uint_32 PNGAPI
- png_permit_mng_features (png_structrp png_ptr, png_uint_32 mng_features)
+ png_permit_mng_features(png_structrp png_ptr, png_uint_32 mng_features)
  {
     png_debug(1, "in png_permit_mng_features");
  
@@@ -1779,7 -1636,7 +1782,7 @@@ png_set_invalid(png_const_structrp png_
  #ifdef PNG_SET_USER_LIMITS_SUPPORTED
  /* This function was added to libpng 1.2.6 */
  void PNGAPI
- png_set_user_limits (png_structrp png_ptr, png_uint_32 user_width_max,
+ png_set_user_limits(png_structrp png_ptr, png_uint_32 user_width_max,
      png_uint_32 user_height_max)
  {
     /* Images with dimensions larger than these limits will be
  
  /* This function was added to libpng 1.4.0 */
  void PNGAPI
- png_set_chunk_cache_max (png_structrp png_ptr, png_uint_32 user_chunk_cache_max)
+ png_set_chunk_cache_max(png_structrp png_ptr, png_uint_32 user_chunk_cache_max)
  {
     if (png_ptr != NULL)
        png_ptr->user_chunk_cache_max = user_chunk_cache_max;
  
  /* This function was added to libpng 1.4.1 */
  void PNGAPI
- png_set_chunk_malloc_max (png_structrp png_ptr,
+ png_set_chunk_malloc_max(png_structrp png_ptr,
      png_alloc_size_t user_chunk_malloc_max)
  {
     if (png_ptr != NULL)
diff --combined pngstruct.h
@@@ -1,7 -1,7 +1,7 @@@
  
  /* pngstruct.h - header file for PNG reference library
   *
-  * Copyright (c) 2018-2019 Cosmin Truta
+  * Copyright (c) 2018-2022 Cosmin Truta
   * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
   * Copyright (c) 1996-1997 Andreas Dilger
   * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
@@@ -334,18 -334,8 +334,8 @@@ struct png_struct_de
     size_t current_buffer_size;       /* amount of data now in current_buffer */
     int process_mode;                 /* what push library is currently doing */
     int cur_palette;                  /* current push library palette index */
  #endif /* PROGRESSIVE_READ */
  
- #if defined(__TURBOC__) && !defined(_Windows) && !defined(__FLAT__)
- /* For the Borland special 64K segment handler */
-    png_bytepp offset_table_ptr;
-    png_bytep offset_table;
-    png_uint_16 offset_table_number;
-    png_uint_16 offset_table_count;
-    png_uint_16 offset_table_count_free;
- #endif
  #ifdef PNG_READ_QUANTIZE_SUPPORTED
     png_bytep palette_lookup; /* lookup table for quantizing */
     png_bytep quantize_index; /* index translation for palette files */
     png_byte filter_type;
  #endif
  
 +#ifdef PNG_APNG_SUPPORTED
 +   png_uint_32 apng_flags;
 +   png_uint_32 next_seq_num;         /* next fcTL/fdAT chunk sequence number */
 +   png_uint_32 first_frame_width;
 +   png_uint_32 first_frame_height;
 +
 +#ifdef PNG_READ_APNG_SUPPORTED
 +   png_uint_32 num_frames_read;      /* incremented after all image data of */
 +                                     /* a frame is read */
 +#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
 +   png_progressive_frame_ptr frame_info_fn; /* frame info read callback */
 +   png_progressive_frame_ptr frame_end_fn;  /* frame data read callback */
 +#endif
 +#endif
 +
 +#ifdef PNG_WRITE_APNG_SUPPORTED
 +   png_uint_32 num_frames_to_write;
 +   png_uint_32 num_frames_written;
 +#endif
 +#endif /* PNG_APNG_SUPPORTED */
 +
  /* New members added in libpng-1.2.0 */
  
  /* New members added in libpng-1.0.2 but first enabled by default in 1.2.0 */
diff --combined pngtest.c
+++ b/pngtest.c
@@@ -875,10 -875,6 +875,10 @@@ test_one_file(const char *inname, cons
     volatile int num_passes;
     int pass;
     int bit_depth, color_type;
 +#ifdef PNG_APNG_SUPPORTED
 +   png_uint_32 num_frames;
 +   png_uint_32 num_plays;
 +#endif
  
     row_buf = NULL;
     error_parameters.file_name = inname;
        }
     }
  #endif
 +
 +#ifdef PNG_APNG_SUPPORTED
 +   if (png_get_valid(read_ptr, read_info_ptr, PNG_INFO_acTL))
 +   {
 +      if (png_get_acTL(read_ptr, read_info_ptr, &num_frames, &num_plays))
 +      {
 +         png_byte is_hidden;
 +         pngtest_debug2("Handling acTL chunks (frames %ld, plays %ld)",
 +                    num_frames, num_plays);
 +         png_set_acTL(write_ptr, write_info_ptr, num_frames, num_plays);
 +         is_hidden = png_get_first_frame_is_hidden(read_ptr, read_info_ptr);
 +         png_set_first_frame_is_hidden(write_ptr, write_info_ptr, is_hidden);
 +      }
 +   }
 +#endif
 +
  #ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED
     {
        png_unknown_chunkp unknowns;
     t_misc += (t_stop - t_start);
     t_start = t_stop;
  #endif
 +#ifdef PNG_APNG_SUPPORTED
 +   if (png_get_valid(read_ptr, read_info_ptr, PNG_INFO_acTL))
 +   {
 +      png_uint_32 frame;
 +      for (frame = 0; frame < num_frames; frame++)
 +      {
 +         png_uint_32 frame_width;
 +         png_uint_32 frame_height;
 +         png_uint_32 x_offset;
 +         png_uint_32 y_offset;
 +         png_uint_16 delay_num;
 +         png_uint_16 delay_den;
 +         png_byte dispose_op;
 +         png_byte blend_op;
 +         png_read_frame_head(read_ptr, read_info_ptr);
 +         if (png_get_valid(read_ptr, read_info_ptr, PNG_INFO_fcTL))
 +         {
 +            png_get_next_frame_fcTL(read_ptr, read_info_ptr,
 +                                    &frame_width, &frame_height,
 +                                    &x_offset, &y_offset,
 +                                    &delay_num, &delay_den,
 +                                    &dispose_op, &blend_op);
 +         }
 +         else
 +         {
 +            frame_width = width;
 +            frame_height = height;
 +            x_offset = 0;
 +            y_offset = 0;
 +            delay_num = 1;
 +            delay_den = 1;
 +            dispose_op = PNG_DISPOSE_OP_NONE;
 +            blend_op = PNG_BLEND_OP_SOURCE;
 +         }
 +#ifdef PNG_WRITE_APNG_SUPPORTED
 +         png_write_frame_head(write_ptr, write_info_ptr, (png_bytepp)&row_buf,
 +                              frame_width, frame_height,
 +                              x_offset, y_offset,
 +                              delay_num, delay_den,
 +                              dispose_op, blend_op);
 +#endif
 +         for (pass = 0; pass < num_passes; pass++)
 +         {
 +#           ifdef calc_pass_height
 +               png_uint_32 pass_height;
 +
 +               if (num_passes == 7) /* interlaced */
 +               {
 +                  if (PNG_PASS_COLS(frame_width, pass) > 0)
 +                     pass_height = PNG_PASS_ROWS(frame_height, pass);
 +
 +                  else
 +                     pass_height = 0;
 +               }
 +
 +               else /* not interlaced */
 +                  pass_height = frame_height;
 +#           else
 +#              define pass_height frame_height
 +#           endif
 +
 +            pngtest_debug1("Writing row data for pass %d", pass);
 +            for (y = 0; y < pass_height; y++)
 +            {
 +#ifndef SINGLE_ROWBUF_ALLOC
 +               pngtest_debug2("Allocating row buffer (pass %d, y = %u)...", pass, y);
 +
 +               row_buf = (png_bytep)png_malloc(read_ptr,
 +                  png_get_rowbytes(read_ptr, read_info_ptr));
 +
 +               pngtest_debug2("\t0x%08lx (%lu bytes)", (unsigned long)row_buf,
 +                  (unsigned long)png_get_rowbytes(read_ptr, read_info_ptr));
 +
 +#endif /* !SINGLE_ROWBUF_ALLOC */
 +               png_read_rows(read_ptr, (png_bytepp)&row_buf, NULL, 1);
 +
 +#ifdef PNG_WRITE_SUPPORTED
 +#ifdef PNGTEST_TIMING
 +               t_stop = (float)clock();
 +               t_decode += (t_stop - t_start);
 +               t_start = t_stop;
 +#endif
 +               png_write_rows(write_ptr, (png_bytepp)&row_buf, 1);
 +#ifdef PNGTEST_TIMING
 +               t_stop = (float)clock();
 +               t_encode += (t_stop - t_start);
 +               t_start = t_stop;
 +#endif
 +#endif /* PNG_WRITE_SUPPORTED */
 +
 +#ifndef SINGLE_ROWBUF_ALLOC
 +               pngtest_debug2("Freeing row buffer (pass %d, y = %u)", pass, y);
 +               png_free(read_ptr, row_buf);
 +               row_buf = NULL;
 +#endif /* !SINGLE_ROWBUF_ALLOC */
 +            }
 +         }
 +#ifdef PNG_WRITE_APNG_SUPPORTED
 +         png_write_frame_tail(write_ptr, write_info_ptr);
 +#endif
 +      }
 +   }
 +   else
 +#endif
     for (pass = 0; pass < num_passes; pass++)
     {
  #     ifdef calc_pass_height
@@@ -2279,4 -2155,4 +2279,4 @@@ main(void
  #endif
  
  /* Generate a compiler error if there is an old png.h in the search path. */
- typedef png_libpng_version_1_6_37 Your_png_h_is_not_version_1_6_37;
+ typedef png_libpng_version_1_6_39 Your_png_h_is_not_version_1_6_39;
diff --combined pngwrite.c
@@@ -1,7 -1,7 +1,7 @@@
  
  /* pngwrite.c - general routines to write a PNG file
   *
-  * Copyright (c) 2018-2019 Cosmin Truta
+  * Copyright (c) 2018-2022 Cosmin Truta
   * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
   * Copyright (c) 1996-1997 Andreas Dilger
   * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
@@@ -75,10 -75,10 +75,10 @@@ write_unknown_chunks(png_structrp png_p
   * library.  If you have a new chunk to add, make a function to write it,
   * and put it in the correct location here.  If you want the chunk written
   * after the image data, put it in png_write_end().  I strongly encourage
-  * you to supply a PNG_INFO_ flag, and check info_ptr->valid before writing
-  * the chunk, as that will keep the code from breaking if you want to just
-  * write a plain PNG file.  If you have long comments, I suggest writing
-  * them in png_write_end(), and compressing them.
+  * you to supply a PNG_INFO_<chunk> flag, and check info_ptr->valid before
+  * writing the chunk, as that will keep the code from breaking if you want
+  * to just write a plain PNG file.  If you have long comments, I suggest
+  * writing them in png_write_end(), and compressing them.
   */
  void PNGAPI
  png_write_info_before_PLTE(png_structrp png_ptr, png_const_inforp info_ptr)
         * the application continues writing the PNG.  So check the 'invalid'
         * flag here too.
         */
 +#ifdef PNG_WRITE_APNG_SUPPORTED
 +      if (info_ptr->valid & PNG_INFO_acTL)
 +         png_write_acTL(png_ptr, info_ptr->num_frames, info_ptr->num_plays);
 +#endif
  #ifdef PNG_GAMMA_SUPPORTED
  #  ifdef PNG_WRITE_gAMA_SUPPORTED
        if ((info_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) == 0 &&
@@@ -374,11 -370,6 +374,11 @@@ png_write_end(png_structrp png_ptr, png
        png_benign_error(png_ptr, "Wrote palette index exceeding num_palette");
  #endif
  
 +#ifdef PNG_WRITE_APNG_SUPPORTED
 +   if (png_ptr->num_frames_written != png_ptr->num_frames_to_write)
 +      png_error(png_ptr, "Not enough frames written");
 +#endif
 +
     /* See if user wants us to write information chunks */
     if (info_ptr != NULL)
     {
@@@ -498,6 -489,16 +498,16 @@@ png_convert_from_time_t(png_timep ptime
     png_debug(1, "in png_convert_from_time_t");
  
     tbuf = gmtime(&ttime);
+    if (tbuf == NULL)
+    {
+       /* TODO: add a safe function which takes a png_ptr argument and raises
+        * a png_error if the ttime argument is invalid and the call to gmtime
+        * fails as a consequence.
+        */
+       memset(ptime, 0, sizeof(*ptime));
+       return;
+    }
     png_convert_from_struct_tm(ptime, tbuf);
  }
  #endif
@@@ -1029,38 -1030,10 +1039,38 @@@ png_set_filter(png_structrp png_ptr, in
           case 7: png_app_error(png_ptr, "Unknown row filter for method 0");
  #endif /* WRITE_FILTER */
              /* FALLTHROUGH */
 +#ifdef __TIZEN__
 +            /* 'switch ~ case' is dead code.
 +             * If filters is #PNG_FILTER_VALUE_NONE, #PNG_FILTER_VALUE_SUB ...,
 +             * filter flag will be assigned to 'png_ptr->do_filter'. But
 +             * 'png_ptr->do_filter' is overwritten as 'filters' at below code.
 +             * Issue code(#1155) is 'png_ptr->do_filter = (png_byte)filters;'.
 +             * So the result of 'switch ~ case' has been lost at the line.
 +             * To keep the value of 'switch ~ case', we fixed it to apply
 +             * the result into 'filters'.
 +             * It will be updated into 'png_ptr->do_filter' at #1155 line.
 +             */
 +         case PNG_FILTER_VALUE_NONE:
 +            filters = PNG_FILTER_NONE; break;
 +#else
           case PNG_FILTER_VALUE_NONE:
              png_ptr->do_filter = PNG_FILTER_NONE; break;
 +#endif /* __TIZEN__ */
  
  #ifdef PNG_WRITE_FILTER_SUPPORTED
 +#ifdef __TIZEN__
 +         case PNG_FILTER_VALUE_SUB:
 +            filters = PNG_FILTER_SUB; break;
 +
 +         case PNG_FILTER_VALUE_UP:
 +            filters = PNG_FILTER_UP; break;
 +
 +         case PNG_FILTER_VALUE_AVG:
 +            filters = PNG_FILTER_AVG; break;
 +
 +         case PNG_FILTER_VALUE_PAETH:
 +            filters = PNG_FILTER_PAETH; break;
 +#else
           case PNG_FILTER_VALUE_SUB:
              png_ptr->do_filter = PNG_FILTER_SUB; break;
  
  
           case PNG_FILTER_VALUE_PAETH:
              png_ptr->do_filter = PNG_FILTER_PAETH; break;
 -
 +#endif /* __TIZEN__ */
           default:
              png_ptr->do_filter = (png_byte)filters; break;
  #else
@@@ -1498,43 -1471,6 +1508,43 @@@ png_write_png(png_structrp png_ptr, png
  }
  #endif
  
 +#ifdef PNG_WRITE_APNG_SUPPORTED
 +void PNGAPI
 +png_write_frame_head(png_structp png_ptr, png_infop info_ptr,
 +    png_bytepp row_pointers, png_uint_32 width, png_uint_32 height,
 +    png_uint_32 x_offset, png_uint_32 y_offset,
 +    png_uint_16 delay_num, png_uint_16 delay_den, png_byte dispose_op,
 +    png_byte blend_op)
 +{
 +    png_debug(1, "in png_write_frame_head");
 +
 +    /* there is a chance this has been set after png_write_info was called,
 +    * so it would be set but not written. is there a way to be sure? */
 +    if (!(info_ptr->valid & PNG_INFO_acTL))
 +        png_error(png_ptr, "png_write_frame_head(): acTL not set");
 +
 +    png_write_reset(png_ptr);
 +
 +    png_write_reinit(png_ptr, info_ptr, width, height);
 +
 +    if ( !(png_ptr->num_frames_written == 0 &&
 +           (png_ptr->apng_flags & PNG_FIRST_FRAME_HIDDEN) ) )
 +        png_write_fcTL(png_ptr, width, height, x_offset, y_offset,
 +                       delay_num, delay_den, dispose_op, blend_op);
 +
 +    PNG_UNUSED(row_pointers)
 +}
 +
 +void PNGAPI
 +png_write_frame_tail(png_structp png_ptr, png_infop info_ptr)
 +{
 +    png_debug(1, "in png_write_frame_tail");
 +
 +    png_ptr->num_frames_written++;
 +
 +    PNG_UNUSED(info_ptr)
 +}
 +#endif /* PNG_WRITE_APNG_SUPPORTED */
  
  #ifdef PNG_SIMPLIFIED_WRITE_SUPPORTED
  /* Initialize the write structure - general purpose utility. */
diff --combined pngwutil.c
@@@ -1,7 -1,7 +1,7 @@@
  
  /* pngwutil.c - utilities to write a PNG file
   *
-  * Copyright (c) 2018 Cosmin Truta
+  * Copyright (c) 2018-2022 Cosmin Truta
   * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
   * Copyright (c) 1996-1997 Andreas Dilger
   * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
@@@ -821,11 -821,6 +821,11 @@@ png_write_IHDR(png_structrp png_ptr, pn
     /* Write the chunk */
     png_write_complete_chunk(png_ptr, png_IHDR, buf, 13);
  
 +#ifdef PNG_WRITE_APNG_SUPPORTED
 +   png_ptr->first_frame_width = width;
 +   png_ptr->first_frame_height = height;
 +#endif
 +
     if ((png_ptr->do_filter) == PNG_NO_FILTERS)
     {
        if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE ||
@@@ -1007,17 -1002,8 +1007,17 @@@ png_compress_IDAT(png_structrp png_ptr
                 optimize_cmf(data, png_image_size(png_ptr));
  #endif
  
 -         if (size > 0)
 -            png_write_complete_chunk(png_ptr, png_IDAT, data, size);
 +            if (size > 0)
 +#ifdef PNG_WRITE_APNG_SUPPORTED
 +            {
 +               if (png_ptr->num_frames_written == 0)
 +#endif
 +               png_write_complete_chunk(png_ptr, png_IDAT, data, size);
 +#ifdef PNG_WRITE_APNG_SUPPORTED
 +               else
 +                  png_write_fdAT(png_ptr, data, size);
 +            }
 +#endif /* PNG_WRITE_APNG_SUPPORTED */
           png_ptr->mode |= PNG_HAVE_IDAT;
  
           png_ptr->zstream.next_out = data;
  #endif
  
           if (size > 0)
 +#ifdef PNG_WRITE_APNG_SUPPORTED
 +         {
 +            if (png_ptr->num_frames_written == 0)
 +#endif
              png_write_complete_chunk(png_ptr, png_IDAT, data, size);
 +#ifdef PNG_WRITE_APNG_SUPPORTED
 +            else
 +               png_write_fdAT(png_ptr, data, size);
 +         }
 +#endif /* PNG_WRITE_APNG_SUPPORTED */
 +
           png_ptr->zstream.avail_out = 0;
           png_ptr->zstream.next_out = NULL;
           png_ptr->mode |= PNG_HAVE_IDAT | PNG_AFTER_IDAT;
@@@ -1771,7 -1747,7 +1771,7 @@@ png_write_pCAL(png_structrp png_ptr, pn
  {
     png_uint_32 purpose_len;
     size_t units_len, total_len;
-    png_size_tp params_len;
+    size_t *params_len;
     png_byte buf[10];
     png_byte new_purpose[80];
     int i;
     png_debug1(3, "pCAL units length = %d", (int)units_len);
     total_len = purpose_len + units_len + 10;
  
-    params_len = (png_size_tp)png_malloc(png_ptr,
+    params_len = (size_t *)png_malloc(png_ptr,
         (png_alloc_size_t)((png_alloc_size_t)nparams * (sizeof (size_t))));
  
     /* Find the length of each parameter, making sure we don't count the
@@@ -1909,82 -1885,6 +1909,82 @@@ png_write_tIME(png_structrp png_ptr, pn
  }
  #endif
  
 +#ifdef PNG_WRITE_APNG_SUPPORTED
 +void /* PRIVATE */
 +png_write_acTL(png_structp png_ptr,
 +    png_uint_32 num_frames, png_uint_32 num_plays)
 +{
 +    png_byte buf[8];
 +
 +    png_debug(1, "in png_write_acTL");
 +
 +    png_ptr->num_frames_to_write = num_frames;
 +
 +    if (png_ptr->apng_flags & PNG_FIRST_FRAME_HIDDEN)
 +        num_frames--;
 +
 +    png_save_uint_32(buf, num_frames);
 +    png_save_uint_32(buf + 4, num_plays);
 +
 +    png_write_complete_chunk(png_ptr, png_acTL, buf, (png_size_t)8);
 +}
 +
 +void /* PRIVATE */
 +png_write_fcTL(png_structp png_ptr, png_uint_32 width, png_uint_32 height,
 +    png_uint_32 x_offset, png_uint_32 y_offset,
 +    png_uint_16 delay_num, png_uint_16 delay_den, png_byte dispose_op,
 +    png_byte blend_op)
 +{
 +    png_byte buf[26];
 +
 +    png_debug(1, "in png_write_fcTL");
 +
 +    if (png_ptr->num_frames_written == 0 && (x_offset != 0 || y_offset != 0))
 +        png_error(png_ptr, "x and/or y offset for the first frame aren't 0");
 +    if (png_ptr->num_frames_written == 0 &&
 +        (width != png_ptr->first_frame_width ||
 +         height != png_ptr->first_frame_height))
 +        png_error(png_ptr, "width and/or height in the first frame's fcTL "
 +                           "don't match the ones in IHDR");
 +
 +    /* more error checking */
 +    png_ensure_fcTL_is_valid(png_ptr, width, height, x_offset, y_offset,
 +                             delay_num, delay_den, dispose_op, blend_op);
 +
 +    png_save_uint_32(buf, png_ptr->next_seq_num);
 +    png_save_uint_32(buf + 4, width);
 +    png_save_uint_32(buf + 8, height);
 +    png_save_uint_32(buf + 12, x_offset);
 +    png_save_uint_32(buf + 16, y_offset);
 +    png_save_uint_16(buf + 20, delay_num);
 +    png_save_uint_16(buf + 22, delay_den);
 +    buf[24] = dispose_op;
 +    buf[25] = blend_op;
 +
 +    png_write_complete_chunk(png_ptr, png_fcTL, buf, (png_size_t)26);
 +
 +    png_ptr->next_seq_num++;
 +}
 +
 +void /* PRIVATE */
 +png_write_fdAT(png_structp png_ptr,
 +    png_const_bytep data, png_size_t length)
 +{
 +    png_byte buf[4];
 +
 +    png_write_chunk_header(png_ptr, png_fdAT, (png_uint_32)(4 + length));
 +
 +    png_save_uint_32(buf, png_ptr->next_seq_num);
 +    png_write_chunk_data(png_ptr, buf, 4);
 +
 +    png_write_chunk_data(png_ptr, data, length);
 +
 +    png_write_chunk_end(png_ptr);
 +
 +    png_ptr->next_seq_num++;
 +}
 +#endif /* PNG_WRITE_APNG_SUPPORTED */
 +
  /* Initializes the row writing capability of libpng */
  void /* PRIVATE */
  png_write_start_row(png_structrp png_ptr)
@@@ -2878,39 -2778,4 +2878,39 @@@ png_write_filtered_row(png_structrp png
     }
  #endif /* WRITE_FLUSH */
  }
 +
 +#ifdef PNG_WRITE_APNG_SUPPORTED
 +void /* PRIVATE */
 +png_write_reset(png_structp png_ptr)
 +{
 +    png_ptr->row_number = 0;
 +    png_ptr->pass = 0;
 +    png_ptr->mode &= ~PNG_HAVE_IDAT;
 +}
 +
 +void /* PRIVATE */
 +png_write_reinit(png_structp png_ptr, png_infop info_ptr,
 +                 png_uint_32 width, png_uint_32 height)
 +{
 +    if (png_ptr->num_frames_written == 0 &&
 +        (width != png_ptr->first_frame_width ||
 +         height != png_ptr->first_frame_height))
 +        png_error(png_ptr, "width and/or height in the first frame's fcTL "
 +                           "don't match the ones in IHDR");
 +    if (width > png_ptr->first_frame_width ||
 +        height > png_ptr->first_frame_height)
 +        png_error(png_ptr, "width and/or height for a frame greater than"
 +                           "the ones in IHDR");
 +
 +    png_set_IHDR(png_ptr, info_ptr, width, height,
 +                 info_ptr->bit_depth, info_ptr->color_type,
 +                 info_ptr->interlace_type, info_ptr->compression_type,
 +                 info_ptr->filter_type);
 +
 +    png_ptr->width = width;
 +    png_ptr->height = height;
 +    png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth, width);
 +    png_ptr->usr_width = png_ptr->width;
 +}
 +#endif /* PNG_WRITE_APNG_SUPPORTED */
  #endif /* WRITE */
diff --combined scripts/pnglibconf.dfa
@@@ -8,7 -8,7 +8,7 @@@ com pnglibconf.h - library build config
  com
  version
  com
- com Copyright (c) 2018-2019 Cosmin Truta
+ com Copyright (c) 2018-2022 Cosmin Truta
  com Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
  com
  com This code is released under the libpng license.
@@@ -328,7 -328,7 +328,7 @@@ option WRITE_INT_FUNCTIONS disable
  #     because it means that a failure to write an ancillary chunk can often be
  #     ignored.
  
 -option WARNINGS
 +option WARNINGS disabled
  option ERROR_TEXT
  option ERROR_NUMBERS disabled