Browse Source

Merge pull request #26 from bmx-ng/task/libwebp-update

Updated to libwebp 1.3.2.
Brucey 1 year ago
parent
commit
53aab30a0f
100 changed files with 5343 additions and 2531 deletions
  1. 1 1
      webp.mod/common.bmx
  2. 240 0
      webp.mod/libwebp/.cmake-format.py
  3. 1 1
      webp.mod/libwebp/.style.yapf
  4. 9 0
      webp.mod/libwebp/AUTHORS
  5. 14 1
      webp.mod/libwebp/Android.mk
  6. 315 245
      webp.mod/libwebp/CMakeLists.txt
  7. 50 1
      webp.mod/libwebp/CONTRIBUTING.md
  8. 396 1
      webp.mod/libwebp/ChangeLog
  9. 1 1
      webp.mod/libwebp/Makefile.am
  10. 35 31
      webp.mod/libwebp/Makefile.vc
  11. 49 0
      webp.mod/libwebp/NEWS
  12. 0 795
      webp.mod/libwebp/README
  13. 53 0
      webp.mod/libwebp/README.md
  14. 0 258
      webp.mod/libwebp/README.mux
  15. 0 75
      webp.mod/libwebp/README.webp_js
  16. 8 0
      webp.mod/libwebp/build.gradle
  17. 9 2
      webp.mod/libwebp/cmake/WebPConfig.cmake.in
  18. 0 33
      webp.mod/libwebp/cmake/config.h.in
  19. 12 15
      webp.mod/libwebp/cmake/cpu.cmake
  20. 63 71
      webp.mod/libwebp/cmake/deps.cmake
  21. 8 3
      webp.mod/libwebp/configure.ac
  22. 0 29
      webp.mod/libwebp/doc/README
  23. 385 0
      webp.mod/libwebp/doc/api.md
  24. 213 0
      webp.mod/libwebp/doc/building.md
  25. 26 0
      webp.mod/libwebp/doc/specs_generation.md
  26. 516 0
      webp.mod/libwebp/doc/tools.md
  27. 168 119
      webp.mod/libwebp/doc/webp-container-spec.txt
  28. 516 412
      webp.mod/libwebp/doc/webp-lossless-bitstream-spec.txt
  29. 3 0
      webp.mod/libwebp/examples/Android.mk
  30. 2 2
      webp.mod/libwebp/examples/Makefile.am
  31. 5 2
      webp.mod/libwebp/examples/anim_util.c
  32. 13 7
      webp.mod/libwebp/examples/cwebp.c
  33. 1 1
      webp.mod/libwebp/examples/dwebp.c
  34. 5 1
      webp.mod/libwebp/examples/example_util.c
  35. 5 2
      webp.mod/libwebp/examples/gif2webp.c
  36. 20 4
      webp.mod/libwebp/examples/img2webp.c
  37. 17 3
      webp.mod/libwebp/examples/unicode.h
  38. 9 8
      webp.mod/libwebp/examples/unicode_gif.h
  39. 14 1
      webp.mod/libwebp/examples/vwebp.c
  40. 5 4
      webp.mod/libwebp/examples/webpmux.c
  41. 2 2
      webp.mod/libwebp/extras/extras.c
  42. 2 1
      webp.mod/libwebp/extras/get_disto.c
  43. 1 1
      webp.mod/libwebp/extras/vwebp_sdl.c
  44. 1 1
      webp.mod/libwebp/extras/webp_to_sdl.c
  45. 2 2
      webp.mod/libwebp/extras/webp_to_sdl.h
  46. 3 0
      webp.mod/libwebp/imageio/Android.mk
  47. 18 0
      webp.mod/libwebp/imageio/image_dec.c
  48. 3 0
      webp.mod/libwebp/imageio/image_dec.h
  49. 23 12
      webp.mod/libwebp/imageio/image_enc.c
  50. 5 1
      webp.mod/libwebp/imageio/jpegdec.c
  51. 8 8
      webp.mod/libwebp/imageio/pngdec.c
  52. 6 1
      webp.mod/libwebp/imageio/pnmdec.c
  53. 4 2
      webp.mod/libwebp/imageio/tiffdec.c
  54. 2 2
      webp.mod/libwebp/infra/run_static_analysis.sh
  55. 3 5
      webp.mod/libwebp/iosbuild.sh
  56. 40 5
      webp.mod/libwebp/makefile.unix
  57. 8 6
      webp.mod/libwebp/man/cwebp.1
  58. 14 2
      webp.mod/libwebp/man/img2webp.1
  59. 41 0
      webp.mod/libwebp/sharpyuv/Makefile.am
  60. 11 0
      webp.mod/libwebp/sharpyuv/libsharpyuv.pc.in
  61. 41 0
      webp.mod/libwebp/sharpyuv/libsharpyuv.rc
  62. 527 0
      webp.mod/libwebp/sharpyuv/sharpyuv.c
  63. 103 0
      webp.mod/libwebp/sharpyuv/sharpyuv.h
  64. 14 0
      webp.mod/libwebp/sharpyuv/sharpyuv_cpu.c
  65. 22 0
      webp.mod/libwebp/sharpyuv/sharpyuv_cpu.h
  66. 110 0
      webp.mod/libwebp/sharpyuv/sharpyuv_csp.c
  67. 60 0
      webp.mod/libwebp/sharpyuv/sharpyuv_csp.h
  68. 104 0
      webp.mod/libwebp/sharpyuv/sharpyuv_dsp.c
  69. 28 0
      webp.mod/libwebp/sharpyuv/sharpyuv_dsp.h
  70. 113 0
      webp.mod/libwebp/sharpyuv/sharpyuv_gamma.c
  71. 35 0
      webp.mod/libwebp/sharpyuv/sharpyuv_gamma.h
  72. 181 0
      webp.mod/libwebp/sharpyuv/sharpyuv_neon.c
  73. 201 0
      webp.mod/libwebp/sharpyuv/sharpyuv_sse2.c
  74. 2 2
      webp.mod/libwebp/src/Makefile.am
  75. 2 1
      webp.mod/libwebp/src/dec/tree_dec.c
  76. 2 0
      webp.mod/libwebp/src/dec/vp8_dec.c
  77. 2 2
      webp.mod/libwebp/src/dec/vp8i_dec.h
  78. 29 25
      webp.mod/libwebp/src/dec/vp8l_dec.c
  79. 1 1
      webp.mod/libwebp/src/dec/vp8li_dec.h
  80. 21 14
      webp.mod/libwebp/src/dec/webp_dec.c
  81. 1 1
      webp.mod/libwebp/src/demux/Makefile.am
  82. 2 5
      webp.mod/libwebp/src/demux/demux.c
  83. 2 2
      webp.mod/libwebp/src/demux/libwebpdemux.pc.in
  84. 5 5
      webp.mod/libwebp/src/demux/libwebpdemux.rc
  85. 1 0
      webp.mod/libwebp/src/dsp/Makefile.am
  86. 1 0
      webp.mod/libwebp/src/dsp/alpha_processing.c
  87. 4 2
      webp.mod/libwebp/src/dsp/alpha_processing_neon.c
  88. 6 6
      webp.mod/libwebp/src/dsp/alpha_processing_sse2.c
  89. 1 1
      webp.mod/libwebp/src/dsp/alpha_processing_sse41.c
  90. 1 0
      webp.mod/libwebp/src/dsp/cost.c
  91. 2 2
      webp.mod/libwebp/src/dsp/cost_neon.c
  92. 8 2
      webp.mod/libwebp/src/dsp/cpu.c
  93. 266 0
      webp.mod/libwebp/src/dsp/cpu.h
  94. 1 0
      webp.mod/libwebp/src/dsp/dec.c
  95. 2 2
      webp.mod/libwebp/src/dsp/dec_neon.c
  96. 47 46
      webp.mod/libwebp/src/dsp/dec_sse2.c
  97. 1 1
      webp.mod/libwebp/src/dsp/dec_sse41.c
  98. 1 228
      webp.mod/libwebp/src/dsp/dsp.h
  99. 1 0
      webp.mod/libwebp/src/dsp/enc.c
  100. 8 3
      webp.mod/libwebp/src/dsp/enc_neon.c

+ 1 - 1
webp.mod/common.bmx

@@ -1,4 +1,4 @@
-' Copyright (c) 2021 Bruce A Henderson
+' Copyright (c) 2021-2023 Bruce A Henderson
 '
 ' This software is provided 'as-is', without any express or implied
 ' warranty. In no event will the authors be held liable for any damages

+ 240 - 0
webp.mod/libwebp/.cmake-format.py

@@ -0,0 +1,240 @@
+# ----------------------------------
+# Options affecting listfile parsing
+# ----------------------------------
+with section("parse"):
+
+  # Specify structure for custom cmake functions
+  additional_commands = { 'foo': { 'flags': ['BAR', 'BAZ'],
+             'kwargs': {'DEPENDS': '*', 'HEADERS': '*', 'SOURCES': '*'}}}
+
+  # Override configurations per-command where available
+  override_spec = {}
+
+  # Specify variable tags.
+  vartags = []
+
+  # Specify property tags.
+  proptags = []
+
+# -----------------------------
+# Options affecting formatting.
+# -----------------------------
+with section("format"):
+
+  # Disable formatting entirely, making cmake-format a no-op
+  disable = False
+
+  # How wide to allow formatted cmake files
+  line_width = 80
+
+  # How many spaces to tab for indent
+  tab_size = 2
+
+  # If true, lines are indented using tab characters (utf-8 0x09) instead of
+  # <tab_size> space characters (utf-8 0x20). In cases where the layout would
+  # require a fractional tab character, the behavior of the  fractional
+  # indentation is governed by <fractional_tab_policy>
+  use_tabchars = False
+
+  # If <use_tabchars> is True, then the value of this variable indicates how
+  # fractional indentions are handled during whitespace replacement. If set to
+  # 'use-space', fractional indentation is left as spaces (utf-8 0x20). If set
+  # to `round-up` fractional indentation is replaced with a single tab character
+  # (utf-8 0x09) effectively shifting the column to the next tabstop
+  fractional_tab_policy = 'use-space'
+
+  # If an argument group contains more than this many sub-groups (parg or kwarg
+  # groups) then force it to a vertical layout.
+  max_subgroups_hwrap = 3
+
+  # If a positional argument group contains more than this many arguments, then
+  # force it to a vertical layout.
+  max_pargs_hwrap = 6
+
+  # If a cmdline positional group consumes more than this many lines without
+  # nesting, then invalidate the layout (and nest)
+  max_rows_cmdline = 2
+
+  # If true, separate flow control names from their parentheses with a space
+  separate_ctrl_name_with_space = False
+
+  # If true, separate function names from parentheses with a space
+  separate_fn_name_with_space = False
+
+  # If a statement is wrapped to more than one line, than dangle the closing
+  # parenthesis on its own line.
+  dangle_parens = False
+
+  # If the trailing parenthesis must be 'dangled' on its on line, then align it
+  # to this reference: `prefix`: the start of the statement,  `prefix-indent`:
+  # the start of the statement, plus one indentation  level, `child`: align to
+  # the column of the arguments
+  dangle_align = 'prefix'
+
+  # If the statement spelling length (including space and parenthesis) is
+  # smaller than this amount, then force reject nested layouts.
+  min_prefix_chars = 4
+
+  # If the statement spelling length (including space and parenthesis) is larger
+  # than the tab width by more than this amount, then force reject un-nested
+  # layouts.
+  max_prefix_chars = 10
+
+  # If a candidate layout is wrapped horizontally but it exceeds this many
+  # lines, then reject the layout.
+  max_lines_hwrap = 2
+
+  # What style line endings to use in the output.
+  line_ending = 'unix'
+
+  # Format command names consistently as 'lower' or 'upper' case
+  command_case = 'canonical'
+
+  # Format keywords consistently as 'lower' or 'upper' case
+  keyword_case = 'unchanged'
+
+  # A list of command names which should always be wrapped
+  always_wrap = []
+
+  # If true, the argument lists which are known to be sortable will be sorted
+  # lexicographicall
+  enable_sort = True
+
+  # If true, the parsers may infer whether or not an argument list is sortable
+  # (without annotation).
+  autosort = False
+
+  # By default, if cmake-format cannot successfully fit everything into the
+  # desired linewidth it will apply the last, most agressive attempt that it
+  # made. If this flag is True, however, cmake-format will print error, exit
+  # with non-zero status code, and write-out nothing
+  require_valid_layout = False
+
+  # A dictionary mapping layout nodes to a list of wrap decisions. See the
+  # documentation for more information.
+  layout_passes = {}
+
+# ------------------------------------------------
+# Options affecting comment reflow and formatting.
+# ------------------------------------------------
+with section("markup"):
+
+  # What character to use for bulleted lists
+  bullet_char = '*'
+
+  # What character to use as punctuation after numerals in an enumerated list
+  enum_char = '.'
+
+  # If comment markup is enabled, don't reflow the first comment block in each
+  # listfile. Use this to preserve formatting of your copyright/license
+  # statements.
+  first_comment_is_literal = True
+
+  # If comment markup is enabled, don't reflow any comment block which matches
+  # this (regex) pattern. Default is `None` (disabled).
+  literal_comment_pattern = None
+
+  # Regular expression to match preformat fences in comments default=
+  # ``r'^\s*([`~]{3}[`~]*)(.*)$'``
+  fence_pattern = '^\\s*([`~]{3}[`~]*)(.*)$'
+
+  # Regular expression to match rulers in comments default=
+  # ``r'^\s*[^\w\s]{3}.*[^\w\s]{3}$'``
+  ruler_pattern = '^\\s*[^\\w\\s]{3}.*[^\\w\\s]{3}$'
+
+  # If a comment line matches starts with this pattern then it is explicitly a
+  # trailing comment for the preceeding argument. Default is '#<'
+  explicit_trailing_pattern = '#<'
+
+  # If a comment line starts with at least this many consecutive hash
+  # characters, then don't lstrip() them off. This allows for lazy hash rulers
+  # where the first hash char is not separated by space
+  hashruler_min_length = 10
+
+  # If true, then insert a space between the first hash char and remaining hash
+  # chars in a hash ruler, and normalize its length to fill the column
+  canonicalize_hashrulers = True
+
+  # enable comment markup parsing and reflow
+  enable_markup = True
+
+# ----------------------------
+# Options affecting the linter
+# ----------------------------
+with section("lint"):
+
+  # a list of lint codes to disable
+  disabled_codes = []
+
+  # regular expression pattern describing valid function names
+  function_pattern = '[0-9a-z_]+'
+
+  # regular expression pattern describing valid macro names
+  macro_pattern = '[0-9A-Z_]+'
+
+  # regular expression pattern describing valid names for variables with global
+  # (cache) scope
+  global_var_pattern = '[A-Z][0-9A-Z_]+'
+
+  # regular expression pattern describing valid names for variables with global
+  # scope (but internal semantic)
+  internal_var_pattern = '_[A-Z][0-9A-Z_]+'
+
+  # regular expression pattern describing valid names for variables with local
+  # scope
+  local_var_pattern = '[a-z][a-z0-9_]+'
+
+  # regular expression pattern describing valid names for privatedirectory
+  # variables
+  private_var_pattern = '_[0-9a-z_]+'
+
+  # regular expression pattern describing valid names for public directory
+  # variables
+  public_var_pattern = '[A-Z][0-9A-Z_]+'
+
+  # regular expression pattern describing valid names for function/macro
+  # arguments and loop variables.
+  argument_var_pattern = '[a-z][a-z0-9_]+'
+
+  # regular expression pattern describing valid names for keywords used in
+  # functions or macros
+  keyword_pattern = '[A-Z][0-9A-Z_]+'
+
+  # In the heuristic for C0201, how many conditionals to match within a loop in
+  # before considering the loop a parser.
+  max_conditionals_custom_parser = 2
+
+  # Require at least this many newlines between statements
+  min_statement_spacing = 1
+
+  # Require no more than this many newlines between statements
+  max_statement_spacing = 2
+  max_returns = 6
+  max_branches = 12
+  max_arguments = 5
+  max_localvars = 15
+  max_statements = 50
+
+# -------------------------------
+# Options affecting file encoding
+# -------------------------------
+with section("encode"):
+
+  # If true, emit the unicode byte-order mark (BOM) at the start of the file
+  emit_byteorder_mark = False
+
+  # Specify the encoding of the input file. Defaults to utf-8
+  input_encoding = 'utf-8'
+
+  # Specify the encoding of the output file. Defaults to utf-8. Note that cmake
+  # only claims to support utf-8 so be careful when using anything else
+  output_encoding = 'utf-8'
+
+# -------------------------------------
+# Miscellaneous configurations options.
+# -------------------------------------
+with section("misc"):
+
+  # A dictionary containing any per-command configuration overrides. Currently
+  # only `command_case` is supported.
+  per_command = {}

+ 1 - 1
webp.mod/libwebp/.style.yapf

@@ -1,2 +1,2 @@
 [style]
-based_on_style = chromium
+based_on_style = yapf

+ 9 - 0
webp.mod/libwebp/AUTHORS

@@ -1,18 +1,23 @@
 Contributors:
 - Aidan O'Loan (aidanol at gmail dot com)
 - Alan Browning (browning at google dot com)
+- Alexandru Ardelean (ardeleanalex at gmail dot com)
+- Brian Ledger (brianpl at google dot com)
 - Charles Munger (clm at google dot com)
 - Cheng Yi (cyi at google dot com)
 - Christian Duvivier (cduvivier at google dot com)
 - Christopher Degawa (ccom at randomderp dot com)
 - Clement Courbet (courbet at google dot com)
 - Djordje Pesut (djordje dot pesut at imgtec dot com)
+- Frank Barchard (fbarchard at google dot com)
 - Hui Su (huisu at google dot com)
+- H. Vetinari (h dot vetinari at gmx dot com)
 - Ilya Kurdyukov (jpegqs at gmail dot com)
 - Ingvar Stepanyan (rreverser at google dot com)
 - James Zern (jzern at google dot com)
 - Jan Engelhardt (jengelh at medozas dot de)
 - Jehan (jehan at girinstud dot io)
+- Jeremy Maitin-Shepard (jbms at google dot com)
 - Johann Koenig (johann dot koenig at duck dot com)
 - Jovan Zelincevic (jovan dot zelincevic at imgtec dot com)
 - Jyrki Alakuijala (jyrki at google dot com)
@@ -22,16 +27,19 @@ Contributors:
 - Mans Rullgard (mans at mansr dot com)
 - Marcin Kowalczyk (qrczak at google dot com)
 - Martin Olsson (mnemo at minimum dot se)
+- Maryla Ustarroz-Calonge (maryla at google dot com)
 - Mikołaj Zalewski (mikolajz at google dot com)
 - Mislav Bradac (mislavm at google dot com)
 - Nico Weber (thakis at chromium dot org)
 - Noel Chromium (noel at chromium dot org)
+- Nozomi Isozaki (nontan at pixiv dot co dot jp)
 - Oliver Wolff (oliver dot wolff at qt dot io)
 - Owen Rodley (orodley at google dot com)
 - Parag Salasakar (img dot mips1 at gmail dot com)
 - Pascal Massimino (pascal dot massimino at gmail dot com)
 - Paweł Hajdan, Jr (phajdan dot jr at chromium dot org)
 - Pierre Joye (pierre dot php at gmail dot com)
+- Roberto Alanis (alanisbaez at google dot com)
 - Sam Clegg (sbc at chromium dot org)
 - Scott Hancher (seh at google dot com)
 - Scott LaVarnway (slavarnway at google dot com)
@@ -40,6 +48,7 @@ Contributors:
 - Somnath Banerjee (somnath dot banerjee at gmail dot com)
 - Sriraman Tallam (tmsriram at google dot com)
 - Tamar Levy (tamar dot levy at intel dot com)
+- Thiago Perrotta (tperrotta at google dot com)
 - Timothy Gu (timothygu99 at gmail dot com)
 - Urvang Joshi (urvang at google dot com)
 - Vikas Arora (vikasa at google dot com)

+ 14 - 1
webp.mod/libwebp/Android.mk

@@ -1,3 +1,5 @@
+# Ignore this file during non-NDK builds.
+ifdef NDK_ROOT
 LOCAL_PATH := $(call my-dir)
 
 WEBP_CFLAGS := -Wall -DANDROID -DHAVE_MALLOC_H -DHAVE_PTHREAD -DWEBP_USE_THREAD
@@ -33,6 +35,15 @@ else
   NEON := c
 endif
 
+sharpyuv_srcs := \
+    sharpyuv/sharpyuv.c \
+    sharpyuv/sharpyuv_cpu.c \
+    sharpyuv/sharpyuv_csp.c \
+    sharpyuv/sharpyuv_dsp.c \
+    sharpyuv/sharpyuv_gamma.c \
+    sharpyuv/sharpyuv_neon.$(NEON) \
+    sharpyuv/sharpyuv_sse2.c \
+
 dec_srcs := \
     src/dec/alpha_dec.c \
     src/dec/buffer_dec.c \
@@ -204,12 +215,13 @@ endif  # ENABLE_SHARED=1
 include $(CLEAR_VARS)
 
 LOCAL_SRC_FILES := \
+    $(sharpyuv_srcs) \
     $(dsp_enc_srcs) \
     $(enc_srcs) \
     $(utils_enc_srcs) \
 
 LOCAL_CFLAGS := $(WEBP_CFLAGS)
-LOCAL_EXPORT_C_INCLUDES += $(LOCAL_PATH)/src
+LOCAL_EXPORT_C_INCLUDES += $(LOCAL_PATH)/src $(LOCAL_PATH)
 
 # prefer arm over thumb mode for performance gains
 LOCAL_ARM_MODE := arm
@@ -279,3 +291,4 @@ include $(WEBP_SRC_PATH)/examples/Android.mk
 ifeq ($(USE_CPUFEATURES),yes)
   $(call import-module,android/cpufeatures)
 endif
+endif  # NDK_ROOT

+ 315 - 245
webp.mod/libwebp/CMakeLists.txt

@@ -6,7 +6,11 @@
 #  in the file PATENTS.  All contributing project authors may
 #  be found in the AUTHORS file in the root of the source tree.
 
-cmake_minimum_required(VERSION 3.7)
+if(APPLE)
+  cmake_minimum_required(VERSION 3.17)
+else()
+  cmake_minimum_required(VERSION 3.7)
+endif()
 
 if(POLICY CMP0072)
   cmake_policy(SET CMP0072 NEW)
@@ -15,6 +19,14 @@ endif()
 project(WebP C)
 
 # Options for coder / decoder executables.
+if(BUILD_SHARED_LIBS)
+  set(WEBP_LINK_STATIC_DEFAULT OFF)
+else()
+  set(WEBP_LINK_STATIC_DEFAULT ON)
+endif()
+option(WEBP_LINK_STATIC
+       "Link using static libraries. If OFF, use dynamic libraries."
+       ${WEBP_LINK_STATIC_DEFAULT})
 if(NOT EMSCRIPTEN)
   # Disable SIMD on Emscripten by default, as it's a new unstable Wasm feature.
   # Users can still explicitly opt-in to make a SIMD-enabled build.
@@ -40,6 +52,18 @@ option(WEBP_ENABLE_SWAP_16BIT_CSP "Enable byte swap for 16 bit colorspaces."
 set(WEBP_BITTRACE "0" CACHE STRING "Bit trace mode (0=none, 1=bit, 2=bytes)")
 set_property(CACHE WEBP_BITTRACE PROPERTY STRINGS 0 1 2)
 
+if(WEBP_LINK_STATIC)
+  if(WIN32)
+    set(CMAKE_FIND_LIBRARY_SUFFIXES .lib .a ${CMAKE_FIND_LIBRARY_SUFFIXES})
+  else()
+    set(CMAKE_FIND_LIBRARY_SUFFIXES .a ${CMAKE_FIND_LIBRARY_SUFFIXES})
+  endif()
+  set(CMAKE_POSITION_INDEPENDENT_CODE ON)
+  # vwebp does not compile on Ubuntu with static libraries so disabling it for
+  # now.
+  set(WEBP_BUILD_VWEBP OFF)
+endif()
+
 # Option needed for handling Unicode file names on Windows.
 if(WIN32)
   option(WEBP_UNICODE "Build Unicode executables." ON)
@@ -58,23 +82,42 @@ if(WEBP_BUILD_WEBP_JS)
   set(WEBP_USE_THREAD OFF)
 
   if(WEBP_ENABLE_SIMD)
-    message("wasm2js does not support SIMD, disabling webp.js generation.")
+    message(NOTICE
+            "wasm2js does not support SIMD, disabling webp.js generation.")
   endif()
 endif()
 
+set(SHARPYUV_DEP_LIBRARIES)
+set(SHARPYUV_DEP_INCLUDE_DIRS)
 set(WEBP_DEP_LIBRARIES)
 set(WEBP_DEP_INCLUDE_DIRS)
 
 if(NOT CMAKE_BUILD_TYPE)
   set(CMAKE_BUILD_TYPE "Release"
       CACHE STRING "Build type: Release, Debug, MinSizeRel or RelWithDebInfo"
-      FORCE)
+            FORCE)
 endif()
 
 # Include dependencies.
+if(WEBP_BUILD_ANIM_UTILS
+   OR WEBP_BUILD_CWEBP
+   OR WEBP_BUILD_DWEBP
+   OR WEBP_BUILD_EXTRAS
+   OR WEBP_BUILD_GIF2WEBP
+   OR WEBP_BUILD_IMG2WEBP)
+  set(WEBP_FIND_IMG_LIBS TRUE)
+else()
+  set(WEBP_FIND_IMG_LIBS FALSE)
+endif()
 include(cmake/deps.cmake)
 include(GNUInstallDirs)
 
+if(BUILD_SHARED_LIBS AND NOT DEFINED CMAKE_INSTALL_RPATH)
+  # Set the rpath to match autoconf/libtool behavior. Note this must be set
+  # before target creation.
+  set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}")
+endif()
+
 # ##############################################################################
 # Options.
 if(WEBP_ENABLE_SWAP_16BIT_CSP)
@@ -90,24 +133,50 @@ if(WEBP_UNICODE)
   add_definitions(-DUNICODE -D_UNICODE)
 endif()
 
+if(MSVC AND BUILD_SHARED_LIBS)
+  add_definitions(-DWEBP_DLL)
+endif()
+
+# pkg-config variables used by *.pc.in.
 set(prefix ${CMAKE_INSTALL_PREFIX})
-set(exec_prefix "\$\{prefix\}")
-set(libdir "\$\{prefix\}/lib")
-set(includedir "\$\{prefix\}/include")
+set(exec_prefix "\${prefix}")
+if(IS_ABSOLUTE "${CMAKE_INSTALL_LIBDIR}")
+  set(libdir "${CMAKE_INSTALL_LIBDIR}")
+else()
+  set(libdir "\${exec_prefix}/${CMAKE_INSTALL_LIBDIR}")
+endif()
+if(IS_ABSOLUTE "${CMAKE_INSTALL_INCLUDEDIR}")
+  set(includedir "${CMAKE_INSTALL_INCLUDEDIR}")
+else()
+  set(includedir "\${prefix}/${CMAKE_INSTALL_INCLUDEDIR}")
+endif()
 set(PTHREAD_LIBS ${CMAKE_THREAD_LIBS_INIT})
 set(INSTALLED_LIBRARIES)
 
+if(MSVC)
+  # match the naming convention used by nmake
+  set(webp_libname_prefix "lib")
+  set(CMAKE_SHARED_LIBRARY_PREFIX "${webp_libname_prefix}")
+  set(CMAKE_IMPORT_LIBRARY_PREFIX "${webp_libname_prefix}")
+  set(CMAKE_STATIC_LIBRARY_PREFIX "${webp_libname_prefix}")
+endif()
+
+set(CMAKE_C_VISIBILITY_PRESET hidden)
+
 # ##############################################################################
 # Android only.
 if(ANDROID)
   include_directories(${ANDROID_NDK}/sources/android/cpufeatures)
-  add_library(cpufeatures STATIC
+  add_library(cpufeatures-webp STATIC
               ${ANDROID_NDK}/sources/android/cpufeatures/cpu-features.c)
-  list(APPEND INSTALLED_LIBRARIES cpufeatures)
-  target_link_libraries(cpufeatures dl)
-  set(WEBP_DEP_LIBRARIES ${WEBP_DEP_LIBRARIES} cpufeatures)
-  set(WEBP_DEP_INCLUDE_DIRS ${WEBP_DEP_INCLUDE_DIRS}
-      ${ANDROID_NDK}/sources/android/cpufeatures)
+  list(APPEND INSTALLED_LIBRARIES cpufeatures-webp)
+  target_link_libraries(cpufeatures-webp dl)
+  set(SHARPYUV_DEP_LIBRARIES ${SHARPYUV_DEP_LIBRARIES} cpufeatures-webp)
+  set(WEBP_DEP_LIBRARIES ${WEBP_DEP_LIBRARIES} cpufeatures-webp)
+  set(cpufeatures_include_dir ${ANDROID_NDK}/sources/android/cpufeatures)
+  set(SHARPYUV_DEP_INCLUDE_DIRS ${SHARPYUV_DEP_INCLUDE_DIRS}
+                                ${cpufeatures_include_dir})
+  set(WEBP_DEP_INCLUDE_DIRS ${WEBP_DEP_INCLUDE_DIRS} ${cpufeatures_include_dir})
   add_definitions(-DHAVE_CPU_FEATURES_H=1)
   set(HAVE_CPU_FEATURES_H 1)
 else()
@@ -116,7 +185,7 @@ endif()
 
 function(configure_pkg_config FILE)
   configure_file("${CMAKE_CURRENT_SOURCE_DIR}/${FILE}.in"
-                 "${CMAKE_CURRENT_BINARY_DIR}/${FILE}")
+                 "${CMAKE_CURRENT_BINARY_DIR}/${FILE}" @ONLY)
 
   if(HAVE_MATH_LIBRARY)
     # MSVC doesn't have libm
@@ -125,10 +194,8 @@ function(configure_pkg_config FILE)
     file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/${FILE} ${data})
   endif()
 
-  install(
-    FILES "${CMAKE_CURRENT_BINARY_DIR}/${FILE}"
-    DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig
-  )
+  install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${FILE}"
+          DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
 endfunction()
 
 # ##############################################################################
@@ -138,23 +205,15 @@ endfunction()
 # E.g.: libimagedec_la_SOURCES  = image_dec.c image_dec.h
 function(parse_Makefile_am FOLDER VAR SRC_REGEX)
   file(READ ${FOLDER}/Makefile.am MAKEFILE_AM)
-  string(REGEX MATCHALL
-               "${SRC_REGEX}_SOURCES[ ]*\\+?=[ ]+[0-9a-z\\._ ]*"
-               FILES_PER_LINE
-               ${MAKEFILE_AM})
+  string(REGEX MATCHALL "${SRC_REGEX}_SOURCES[ ]*\\+?=[ ]+[0-9a-z\\._ ]*"
+               FILES_PER_LINE ${MAKEFILE_AM})
   set(SRCS ${${VAR}})
   foreach(FILES ${FILES_PER_LINE})
     string(FIND ${FILES} "=" OFFSET)
     math(EXPR OFFSET "${OFFSET} + 2")
-    string(SUBSTRING ${FILES}
-                     ${OFFSET}
-                     -1
-                     FILES)
+    string(SUBSTRING ${FILES} ${OFFSET} -1 FILES)
     if(FILES)
-      string(REGEX MATCHALL
-                   "[0-9a-z\\._]+"
-                   FILES
-                   ${FILES})
+      string(REGEX MATCHALL "[0-9a-z\\._]+" FILES ${FILES})
       foreach(FILE ${FILES})
         list(APPEND SRCS ${FOLDER}/${FILE})
       endforeach()
@@ -183,9 +242,52 @@ endforeach()
 
 # Generate the config.h file.
 configure_file(${CMAKE_CURRENT_LIST_DIR}/cmake/config.h.in
-               ${CMAKE_CURRENT_BINARY_DIR}/src/webp/config.h)
+               ${CMAKE_CURRENT_BINARY_DIR}/src/webp/config.h @ONLY)
 add_definitions(-DHAVE_CONFIG_H)
 
+# Set the version numbers.
+macro(set_version FILE TARGET_NAME NAME_IN_MAKEFILE)
+  file(READ ${CMAKE_CURRENT_SOURCE_DIR}/${FILE} SOURCE_FILE)
+  string(REGEX MATCH
+               "${NAME_IN_MAKEFILE}_la_LDFLAGS[^\n]* -version-info [0-9:]+" TMP
+               ${SOURCE_FILE})
+  string(REGEX MATCH "[0-9:]+" TMP ${TMP})
+  string(REGEX REPLACE ":" " " LT_VERSION ${TMP})
+
+  # See the libtool docs for more information:
+  # https://www.gnu.org/software/libtool/manual/libtool.html#Updating-version-info
+  #
+  # c=<current>, a=<age>, r=<revision>
+  #
+  # libtool generates a .so file as .so.[c-a].a.r, while -version-info c:r:a is
+  # passed to libtool.
+  #
+  # We set FULL = [c-a].a.r and MAJOR = [c-a].
+  separate_arguments(LT_VERSION)
+  list(GET LT_VERSION 0 LT_CURRENT)
+  list(GET LT_VERSION 1 LT_REVISION)
+  list(GET LT_VERSION 2 LT_AGE)
+  math(EXPR LT_CURRENT_MINUS_AGE "${LT_CURRENT} - ${LT_AGE}")
+
+  set_target_properties(
+    ${TARGET_NAME}
+    PROPERTIES VERSION ${LT_CURRENT_MINUS_AGE}.${LT_AGE}.${LT_REVISION}
+               SOVERSION ${LT_CURRENT_MINUS_AGE})
+  if(APPLE)
+    # For compatibility, set MACHO_COMPATIBILITY_VERSION and
+    # MACHO_CURRENT_VERSION to match libtool. These properties were introduced
+    # in 3.17:
+    # https://cmake.org/cmake/help/latest/prop_tgt/MACHO_COMPATIBILITY_VERSION.html
+    math(EXPR LIBWEBP_MACHO_COMPATIBILITY_VERSION "${LT_CURRENT} + 1")
+    set_target_properties(
+      ${TARGET_NAME}
+      PROPERTIES MACHO_COMPATIBILITY_VERSION
+                 ${LIBWEBP_MACHO_COMPATIBILITY_VERSION}
+                 MACHO_CURRENT_VERSION
+                 ${LIBWEBP_MACHO_COMPATIBILITY_VERSION}.${LT_REVISION})
+  endif()
+endmacro()
+
 # ##############################################################################
 # Build the webpdecoder library.
 
@@ -194,13 +296,12 @@ add_definitions(-DHAVE_CONFIG_H)
 #
 # See also:
 # https://cmake.org/cmake/help/v3.18/command/add_library.html#object-libraries
-# "Some native build systems (such as Xcode) may not like targets that have
-# only object files, so consider adding at least one real source file to any
-# target that references $<TARGET_OBJECTS:objlib>."
+# "Some native build systems (such as Xcode) may not like targets that have only
+# object files, so consider adding at least one real source file to any target
+# that references $<TARGET_OBJECTS:objlib>."
 function(libwebp_add_stub_file TARGET)
   set(stub_source_dir "${CMAKE_BINARY_DIR}")
-  set(stub_source_file
-      "${stub_source_dir}/libwebp_${TARGET}_stub.c")
+  set(stub_source_file "${stub_source_dir}/libwebp_${TARGET}_stub.c")
   set(stub_source_code
       "// Generated file. DO NOT EDIT!\n"
       "// C source file created for target ${TARGET}.\n"
@@ -211,39 +312,55 @@ function(libwebp_add_stub_file TARGET)
   target_sources(${TARGET} PRIVATE ${stub_source_file})
 endfunction()
 
+parse_makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/sharpyuv "WEBP_SHARPYUV_SRCS" "")
+add_library(sharpyuv ${WEBP_SHARPYUV_SRCS})
+target_link_libraries(sharpyuv ${SHARPYUV_DEP_LIBRARIES})
+set_version(sharpyuv/Makefile.am sharpyuv sharpyuv)
+target_include_directories(
+  sharpyuv PRIVATE ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}
+                   ${CMAKE_CURRENT_SOURCE_DIR}/src)
+set_target_properties(
+  sharpyuv
+  PROPERTIES PUBLIC_HEADER "${CMAKE_CURRENT_SOURCE_DIR}/sharpyuv/sharpyuv.h;\
+${CMAKE_CURRENT_SOURCE_DIR}/sharpyuv/sharpyuv_csp.h")
+configure_pkg_config("sharpyuv/libsharpyuv.pc")
+install(
+  TARGETS sharpyuv
+  EXPORT ${PROJECT_NAME}Targets
+  PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/webp/sharpyuv
+  INCLUDES
+  DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
+  ${CMAKE_INSTALL_INCLUDEDIR}/webp
+  ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
+  LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+  RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
+
 if(MSVC)
   # avoid security warnings for e.g., fopen() used in the examples.
   add_definitions(-D_CRT_SECURE_NO_WARNINGS)
 else()
-  add_definitions(-Wall)
+  add_compile_options(-Wall)
 endif()
 include_directories(${WEBP_DEP_INCLUDE_DIRS})
 add_library(webpdecode OBJECT ${WEBP_DEC_SRCS})
-target_include_directories(webpdecode
-                           PRIVATE ${CMAKE_CURRENT_BINARY_DIR}
-                                   ${CMAKE_CURRENT_SOURCE_DIR})
+target_include_directories(webpdecode PRIVATE ${CMAKE_CURRENT_BINARY_DIR}
+                                              ${CMAKE_CURRENT_SOURCE_DIR})
 add_library(webpdspdecode OBJECT ${WEBP_DSP_COMMON_SRCS} ${WEBP_DSP_DEC_SRCS})
-target_include_directories(webpdspdecode
-                           PRIVATE ${CMAKE_CURRENT_BINARY_DIR}
-                                   ${CMAKE_CURRENT_SOURCE_DIR})
-add_library(webputilsdecode
-            OBJECT
-            ${WEBP_UTILS_COMMON_SRCS}
-            ${WEBP_UTILS_DEC_SRCS})
-target_include_directories(webputilsdecode
-                           PRIVATE ${CMAKE_CURRENT_BINARY_DIR}
-                                   ${CMAKE_CURRENT_SOURCE_DIR})
-add_library(webpdecoder
-            $<TARGET_OBJECTS:webpdecode>
-            $<TARGET_OBJECTS:webpdspdecode>
-            $<TARGET_OBJECTS:webputilsdecode>)
+target_include_directories(webpdspdecode PRIVATE ${CMAKE_CURRENT_BINARY_DIR}
+                                                 ${CMAKE_CURRENT_SOURCE_DIR})
+add_library(webputilsdecode OBJECT ${WEBP_UTILS_COMMON_SRCS}
+                                   ${WEBP_UTILS_DEC_SRCS})
+target_include_directories(webputilsdecode PRIVATE ${CMAKE_CURRENT_BINARY_DIR}
+                                                   ${CMAKE_CURRENT_SOURCE_DIR})
+add_library(
+  webpdecoder $<TARGET_OBJECTS:webpdecode> $<TARGET_OBJECTS:webpdspdecode>
+              $<TARGET_OBJECTS:webputilsdecode>)
 if(XCODE)
   libwebp_add_stub_file(webpdecoder)
 endif()
 target_link_libraries(webpdecoder ${WEBP_DEP_LIBRARIES})
 target_include_directories(
-  webpdecoder
-  PRIVATE ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}
+  webpdecoder PRIVATE ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}
   INTERFACE $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
             $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>)
 set_target_properties(
@@ -255,38 +372,26 @@ configure_pkg_config("src/libwebpdecoder.pc")
 
 # Build the webp library.
 add_library(webpencode OBJECT ${WEBP_ENC_SRCS})
-target_include_directories(webpencode
-                           PRIVATE ${CMAKE_CURRENT_BINARY_DIR}
-                                   ${CMAKE_CURRENT_SOURCE_DIR})
-add_library(webpdsp
-            OBJECT
-            ${WEBP_DSP_COMMON_SRCS}
-            ${WEBP_DSP_DEC_SRCS}
-            ${WEBP_DSP_ENC_SRCS})
-target_include_directories(webpdsp
-                           PRIVATE ${CMAKE_CURRENT_BINARY_DIR}
-                                   ${CMAKE_CURRENT_SOURCE_DIR})
-add_library(webputils
-            OBJECT
-            ${WEBP_UTILS_COMMON_SRCS}
-            ${WEBP_UTILS_DEC_SRCS}
-            ${WEBP_UTILS_ENC_SRCS})
-target_include_directories(webputils
-                           PRIVATE ${CMAKE_CURRENT_BINARY_DIR}
-                                   ${CMAKE_CURRENT_SOURCE_DIR})
-add_library(webp
-            $<TARGET_OBJECTS:webpdecode>
-            $<TARGET_OBJECTS:webpdsp>
-            $<TARGET_OBJECTS:webpencode>
-            $<TARGET_OBJECTS:webputils>)
+target_include_directories(
+  webpencode PRIVATE ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}
+                     ${CMAKE_CURRENT_SOURCE_DIR}/src)
+add_library(webpdsp OBJECT ${WEBP_DSP_COMMON_SRCS} ${WEBP_DSP_DEC_SRCS}
+                           ${WEBP_DSP_ENC_SRCS})
+target_include_directories(webpdsp PRIVATE ${CMAKE_CURRENT_BINARY_DIR}
+                                           ${CMAKE_CURRENT_SOURCE_DIR})
+add_library(webputils OBJECT ${WEBP_UTILS_COMMON_SRCS} ${WEBP_UTILS_DEC_SRCS}
+                             ${WEBP_UTILS_ENC_SRCS})
+target_include_directories(webputils PRIVATE ${CMAKE_CURRENT_BINARY_DIR}
+                                             ${CMAKE_CURRENT_SOURCE_DIR})
+add_library(webp $<TARGET_OBJECTS:webpdecode> $<TARGET_OBJECTS:webpdsp>
+                 $<TARGET_OBJECTS:webpencode> $<TARGET_OBJECTS:webputils>)
+target_link_libraries(webp sharpyuv)
 if(XCODE)
   libwebp_add_stub_file(webp)
 endif()
 target_link_libraries(webp ${WEBP_DEP_LIBRARIES})
 target_include_directories(
-  webp
-  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
-          ${CMAKE_CURRENT_BINARY_DIR}
+  webp PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}
   PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>
          $<INSTALL_INTERFACE:include>)
 set_target_properties(
@@ -297,82 +402,33 @@ ${CMAKE_CURRENT_SOURCE_DIR}/src/webp/types.h")
 
 # Make sure the OBJECT libraries are built with position independent code (it is
 # not ON by default).
-set_target_properties(webpdecode
-                      webpdspdecode
-                      webputilsdecode
-                      webpencode
-                      webpdsp
-                      webputils
-                      PROPERTIES POSITION_INDEPENDENT_CODE ON)
+set_target_properties(webpdecode webpdspdecode webputilsdecode webpencode
+                      webpdsp webputils PROPERTIES POSITION_INDEPENDENT_CODE ON)
 configure_pkg_config("src/libwebp.pc")
 
 # Build the webp demux library.
 add_library(webpdemux ${WEBP_DEMUX_SRCS})
 target_link_libraries(webpdemux webp)
-target_include_directories(webpdemux
-                           PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
-                                   ${CMAKE_CURRENT_BINARY_DIR}
-                           PUBLIC $<INSTALL_INTERFACE:include>)
+target_include_directories(
+  webpdemux PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}
+  PUBLIC $<INSTALL_INTERFACE:include>)
 set_target_properties(
   webpdemux
-  PROPERTIES PUBLIC_HEADER "${CMAKE_CURRENT_SOURCE_DIR}/src/webp/decode.h;\
+  PROPERTIES
+    PUBLIC_HEADER
+    "${CMAKE_CURRENT_SOURCE_DIR}/src/webp/decode.h;\
 ${CMAKE_CURRENT_SOURCE_DIR}/src/webp/demux.h;\
 ${CMAKE_CURRENT_SOURCE_DIR}/src/webp/mux_types.h;\
 ${CMAKE_CURRENT_SOURCE_DIR}/src/webp/types.h")
 
 configure_pkg_config("src/demux/libwebpdemux.pc")
 
-# Set the version numbers.
-macro(set_version FILE TARGET_NAME NAME_IN_MAKEFILE)
-  file(READ ${CMAKE_CURRENT_SOURCE_DIR}/src/${FILE} SOURCE_FILE)
-  string(REGEX MATCH
-               "${NAME_IN_MAKEFILE}_la_LDFLAGS[^\n]* -version-info [0-9:]+"
-               TMP
-               ${SOURCE_FILE})
-  string(REGEX MATCH
-               "[0-9:]+"
-               TMP
-               ${TMP})
-  string(REGEX
-         REPLACE ":"
-                 " "
-                 LT_VERSION
-                 ${TMP})
-
-  # See the libtool docs for more information:
-  # https://www.gnu.org/software/libtool/manual/libtool.html#Updating-version-info
-  #
-  # c=<current>, a=<age>, r=<revision>
-  #
-  # libtool generates a .so file as .so.[c-a].a.r, while -version-info c:r:a is
-  # passed to libtool.
-  #
-  # We set FULL = [c-a].a.r and MAJOR = [c-a].
-  separate_arguments(LT_VERSION)
-  list(GET LT_VERSION 0 LT_CURRENT)
-  list(GET LT_VERSION 1 LT_REVISION)
-  list(GET LT_VERSION 2 LT_AGE)
-  math(EXPR LT_CURRENT_MINUS_AGE "${LT_CURRENT} - ${LT_AGE}")
-
-  set_target_properties(
-    ${TARGET_NAME}
-    PROPERTIES VERSION
-               ${LT_CURRENT_MINUS_AGE}.${LT_AGE}.${LT_REVISION}
-               SOVERSION
-               ${LT_CURRENT_MINUS_AGE})
-endmacro()
-set_version(Makefile.am webp webp)
-set_version(Makefile.am webpdecoder webpdecoder)
-set_version(demux/Makefile.am webpdemux webpdemux)
+set_version(src/Makefile.am webp webp)
+set_version(src/Makefile.am webpdecoder webpdecoder)
+set_version(src/demux/Makefile.am webpdemux webpdemux)
 file(READ ${CMAKE_CURRENT_SOURCE_DIR}/configure.ac CONFIGURE_FILE)
-string(REGEX MATCH
-             "AC_INIT\\([^\n]*\\[[0-9\\.]+\\]"
-             TMP
-             ${CONFIGURE_FILE})
-string(REGEX MATCH
-             "[0-9\\.]+"
-             PROJECT_VERSION
-             ${TMP})
+string(REGEX MATCH "AC_INIT\\([^\n]*\\[[0-9\\.]+\\]" TMP ${CONFIGURE_FILE})
+string(REGEX MATCH "[0-9\\.]+" PROJECT_VERSION ${TMP})
 
 # Define the libraries to install.
 list(APPEND INSTALLED_LIBRARIES webpdecoder webp webpdemux)
@@ -385,10 +441,8 @@ math(EXPR WEBP_SIMD_FILES_TO_INCLUDE_RANGE
 foreach(I_FILE RANGE ${WEBP_SIMD_FILES_TO_INCLUDE_RANGE})
   list(GET WEBP_SIMD_FILES_TO_INCLUDE ${I_FILE} FILE)
   list(GET WEBP_SIMD_FLAGS_TO_INCLUDE ${I_FILE} SIMD_COMPILE_FLAG)
-  set_source_files_properties(${FILE}
-                              PROPERTIES
-                              COMPILE_FLAGS
-                              ${SIMD_COMPILE_FLAG})
+  set_source_files_properties(${FILE} PROPERTIES COMPILE_FLAGS
+                                                 ${SIMD_COMPILE_FLAG})
 endforeach()
 
 if(NOT WEBP_BUILD_LIBWEBPMUX)
@@ -411,30 +465,28 @@ if(WEBP_BUILD_ANIM_UTILS
    OR WEBP_BUILD_DWEBP
    OR WEBP_BUILD_GIF2WEBP
    OR WEBP_BUILD_IMG2WEBP
-   OR WEBP_BUILD_VWEBP)
+   OR WEBP_BUILD_VWEBP
+   OR WEBP_BUILD_WEBPMUX
+   OR WEBP_BUILD_WEBPINFO)
   # Example utility library.
   parse_makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/examples "EXAMPLEUTIL_SRCS"
                     "example_util_[^ ]*")
   list(APPEND EXAMPLEUTIL_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/examples/stopwatch.h)
   add_library(exampleutil STATIC ${EXAMPLEUTIL_SRCS})
-  target_link_libraries(exampleutil imageioutil)
   target_include_directories(
-    exampleutil
-    PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>)
+    exampleutil PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>)
 
   parse_makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/imageio "IMAGEIOUTILS_SRCS"
                     "imageio_util_[^ ]*")
   add_library(imageioutil STATIC ${IMAGEIOUTILS_SRCS})
   target_link_libraries(imageioutil webp)
+  target_link_libraries(exampleutil imageioutil)
 
   # Image-decoding utility library.
   parse_makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/imageio "IMAGEDEC_SRCS"
                     "imagedec_[^ ]*")
   add_library(imagedec STATIC ${IMAGEDEC_SRCS})
-  target_link_libraries(imagedec
-                        imageioutil
-                        webpdemux
-                        webp
+  target_link_libraries(imagedec imageioutil webpdemux webp
                         ${WEBP_DEP_IMG_LIBRARIES})
 
   # Image-encoding utility library.
@@ -443,12 +495,10 @@ if(WEBP_BUILD_ANIM_UTILS
   add_library(imageenc STATIC ${IMAGEENC_SRCS})
   target_link_libraries(imageenc imageioutil webp)
 
-  set_property(TARGET exampleutil
-                      imageioutil
-                      imagedec
-                      imageenc
-               PROPERTY INCLUDE_DIRECTORIES ${CMAKE_CURRENT_SOURCE_DIR}/src
-                        ${CMAKE_CURRENT_BINARY_DIR}/src)
+  set_property(
+    TARGET exampleutil imageioutil imagedec imageenc
+    PROPERTY INCLUDE_DIRECTORIES ${CMAKE_CURRENT_SOURCE_DIR}/src
+             ${CMAKE_CURRENT_BINARY_DIR}/src)
 endif()
 
 if(WEBP_BUILD_DWEBP)
@@ -465,7 +515,8 @@ if(WEBP_BUILD_CWEBP)
   parse_makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/examples "CWEBP_SRCS" "cwebp")
   add_executable(cwebp ${CWEBP_SRCS})
   target_link_libraries(cwebp exampleutil imagedec webp)
-  target_include_directories(cwebp PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/src)
+  target_include_directories(cwebp PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/src
+                                           ${CMAKE_CURRENT_SOURCE_DIR})
   install(TARGETS cwebp RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
 endif()
 
@@ -473,13 +524,12 @@ if(WEBP_BUILD_LIBWEBPMUX)
   parse_makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/src/mux "WEBP_MUX_SRCS" "")
   add_library(libwebpmux ${WEBP_MUX_SRCS})
   target_link_libraries(libwebpmux webp)
-  target_include_directories(libwebpmux
-                             PRIVATE ${CMAKE_CURRENT_BINARY_DIR}
-                                     ${CMAKE_CURRENT_SOURCE_DIR})
-  set_version(mux/Makefile.am libwebpmux webpmux)
-  set_target_properties(libwebpmux
-                        PROPERTIES PUBLIC_HEADER
-                                   "${CMAKE_CURRENT_SOURCE_DIR}/src/webp/mux.h;\
+  target_include_directories(libwebpmux PRIVATE ${CMAKE_CURRENT_BINARY_DIR}
+                                                ${CMAKE_CURRENT_SOURCE_DIR})
+  set_version(src/mux/Makefile.am libwebpmux webpmux)
+  set_target_properties(
+    libwebpmux
+    PROPERTIES PUBLIC_HEADER "${CMAKE_CURRENT_SOURCE_DIR}/src/webp/mux.h;\
 ${CMAKE_CURRENT_SOURCE_DIR}/src/webp/mux_types.h;\
 ${CMAKE_CURRENT_SOURCE_DIR}/src/webp/types.h;")
   set_target_properties(libwebpmux PROPERTIES OUTPUT_NAME webpmux)
@@ -493,11 +543,7 @@ if(WEBP_BUILD_GIF2WEBP)
   parse_makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/examples "GIF2WEBP_SRCS"
                     "gif2webp")
   add_executable(gif2webp ${GIF2WEBP_SRCS})
-  target_link_libraries(gif2webp
-                        exampleutil
-                        imageioutil
-                        webp
-                        libwebpmux
+  target_link_libraries(gif2webp exampleutil imageioutil webp libwebpmux
                         ${WEBP_DEP_GIF_LIBRARIES})
   target_include_directories(gif2webp PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/src)
   install(TARGETS gif2webp RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
@@ -509,13 +555,10 @@ if(WEBP_BUILD_IMG2WEBP)
   parse_makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/examples "IMG2WEBP_SRCS"
                     "img2webp")
   add_executable(img2webp ${IMG2WEBP_SRCS})
-  target_link_libraries(img2webp
-                        exampleutil
-                        imagedec
-                        imageioutil
-                        webp
+  target_link_libraries(img2webp exampleutil imagedec imageioutil webp
                         libwebpmux)
-  target_include_directories(img2webp PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/src)
+  target_include_directories(img2webp PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/src
+                                              ${CMAKE_CURRENT_SOURCE_DIR})
   install(TARGETS img2webp RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
 endif()
 
@@ -526,17 +569,17 @@ if(WEBP_BUILD_VWEBP)
     include_directories(${WEBP_DEP_IMG_INCLUDE_DIRS})
     parse_makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/examples "VWEBP_SRCS" "vwebp")
     add_executable(vwebp ${VWEBP_SRCS})
-    target_link_libraries(vwebp
-                          ${OPENGL_LIBRARIES}
-                          exampleutil
-                          ${GLUT_glut_LIBRARY}
-                          imageioutil
-                          webp
-                          webpdemux)
-    target_include_directories(vwebp
-                               PRIVATE ${GLUT_INCLUDE_DIR}
-                                       ${CMAKE_CURRENT_BINARY_DIR}/src
-                                       ${OPENGL_INCLUDE_DIR})
+    target_link_libraries(
+      vwebp
+      ${OPENGL_LIBRARIES}
+      exampleutil
+      GLUT::GLUT
+      imageioutil
+      webp
+      webpdemux)
+    target_include_directories(
+      vwebp PRIVATE ${GLUT_INCLUDE_DIR} ${CMAKE_CURRENT_BINARY_DIR}/src
+                    ${OPENGL_INCLUDE_DIR})
     install(TARGETS vwebp RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
     if(${CMAKE_SYSTEM_NAME} STREQUAL "Darwin")
       check_c_compiler_flag("-Wno-deprecated-declarations" HAS_NO_DEPRECATED)
@@ -554,7 +597,8 @@ if(WEBP_BUILD_WEBPINFO)
                     "webpinfo")
   add_executable(webpinfo ${WEBPINFO_SRCS})
   target_link_libraries(webpinfo exampleutil imageioutil)
-  target_include_directories(webpinfo PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/src)
+  target_include_directories(webpinfo PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/src
+                                              ${CMAKE_CURRENT_SOURCE_DIR}/src)
   install(TARGETS webpinfo RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
 endif()
 
@@ -575,36 +619,48 @@ if(WEBP_BUILD_EXTRAS)
   parse_makefile_am(${EXTRAS_MAKEFILE} "WEBP_QUALITY_SRCS" "webp_quality")
   parse_makefile_am(${EXTRAS_MAKEFILE} "VWEBP_SDL_SRCS" "vwebp_sdl")
 
+  # libextras
+  add_library(extras STATIC ${WEBP_EXTRAS_SRCS})
+  target_include_directories(
+    extras PRIVATE ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}
+                   ${CMAKE_CURRENT_SOURCE_DIR}/src)
+
   # get_disto
   add_executable(get_disto ${GET_DISTO_SRCS})
   target_link_libraries(get_disto imagedec)
-  target_include_directories(get_disto
-                             PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
-                                     ${CMAKE_CURRENT_BINARY_DIR}/src)
+  target_include_directories(get_disto PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+                                               ${CMAKE_CURRENT_BINARY_DIR}/src)
 
   # webp_quality
-  add_executable(webp_quality ${WEBP_QUALITY_SRCS} ${WEBP_EXTRAS_SRCS})
-  target_link_libraries(webp_quality exampleutil imagedec)
-  target_include_directories(webp_quality
-                             PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
-                                     ${CMAKE_CURRENT_BINARY_DIR})
+  add_executable(webp_quality ${WEBP_QUALITY_SRCS})
+  target_link_libraries(webp_quality exampleutil imagedec extras)
+  target_include_directories(webp_quality PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+                                                  ${CMAKE_CURRENT_BINARY_DIR})
 
   # vwebp_sdl
   find_package(SDL)
-  if(SDL_FOUND)
+  if(WEBP_BUILD_VWEBP AND SDL_FOUND)
     add_executable(vwebp_sdl ${VWEBP_SDL_SRCS})
     target_link_libraries(vwebp_sdl ${SDL_LIBRARY} imageioutil webp)
-    target_include_directories(vwebp_sdl
-                               PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
-                                       ${CMAKE_CURRENT_BINARY_DIR}
-                                       ${CMAKE_CURRENT_BINARY_DIR}/src
-                                       ${SDL_INCLUDE_DIR})
+    target_include_directories(
+      vwebp_sdl PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}
+                        ${CMAKE_CURRENT_BINARY_DIR}/src ${SDL_INCLUDE_DIR})
     set(WEBP_HAVE_SDL 1)
     target_compile_definitions(vwebp_sdl PUBLIC WEBP_HAVE_SDL)
   endif()
 endif()
 
 if(WEBP_BUILD_WEBP_JS)
+  # The default stack size changed from 5MB to 64KB in 3.1.27. See
+  # https://crbug.com/webp/614.
+  if(EMSCRIPTEN_VERSION VERSION_GREATER_EQUAL "3.1.27")
+    # TOTAL_STACK size was renamed to STACK_SIZE in 3.1.27. The old name was
+    # kept for compatibility, but prefer the new one in case it is removed in
+    # the future.
+    set(emscripten_stack_size "-sSTACK_SIZE=5MB")
+  else()
+    set(emscripten_stack_size "-sTOTAL_STACK=5MB")
+  endif()
   # wasm2js does not support SIMD.
   if(NOT WEBP_ENABLE_SIMD)
     # JavaScript version
@@ -614,9 +670,9 @@ if(WEBP_BUILD_WEBP_JS)
     set(WEBP_HAVE_SDL 1)
     set_target_properties(
       webp_js
-      PROPERTIES LINK_FLAGS "-s WASM=0 \
-         -s EXPORTED_FUNCTIONS='[\"_WebpToSDL\"]' -s INVOKE_RUN=0 \
-         -s EXPORTED_RUNTIME_METHODS='[\"cwrap\"]'")
+      PROPERTIES LINK_FLAGS "-sWASM=0 ${emscripten_stack_size} \
+         -sEXPORTED_FUNCTIONS=_WebPToSDL -sINVOKE_RUN=0 \
+         -sEXPORTED_RUNTIME_METHODS=cwrap")
     set_target_properties(webp_js PROPERTIES OUTPUT_NAME webp)
     target_compile_definitions(webp_js PUBLIC EMSCRIPTEN WEBP_HAVE_SDL)
   endif()
@@ -627,9 +683,9 @@ if(WEBP_BUILD_WEBP_JS)
   target_include_directories(webp_wasm PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
   set_target_properties(
     webp_wasm
-    PROPERTIES LINK_FLAGS "-s WASM=1 \
-       -s EXPORTED_FUNCTIONS='[\"_WebpToSDL\"]' -s INVOKE_RUN=0 \
-       -s EXPORTED_RUNTIME_METHODS='[\"cwrap\"]'")
+    PROPERTIES LINK_FLAGS "-sWASM=1 ${emscripten_stack_size} \
+       -sEXPORTED_FUNCTIONS=_WebPToSDL -sINVOKE_RUN=0 \
+       -sEXPORTED_RUNTIME_METHODS=cwrap")
   target_compile_definitions(webp_wasm PUBLIC EMSCRIPTEN WEBP_HAVE_SDL)
 
   target_compile_definitions(webpdspdecode PUBLIC EMSCRIPTEN)
@@ -641,14 +697,15 @@ if(WEBP_BUILD_ANIM_UTILS)
   parse_makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/examples "ANIM_DIFF_SRCS"
                     "anim_diff")
   add_executable(anim_diff ${ANIM_DIFF_SRCS})
-  target_link_libraries(anim_diff
-                        exampleutil
-                        imagedec
-                        imageenc
-                        imageioutil
-                        webp
-                        webpdemux
-                        ${WEBP_DEP_GIF_LIBRARIES})
+  target_link_libraries(
+    anim_diff
+    exampleutil
+    imagedec
+    imageenc
+    imageioutil
+    webp
+    webpdemux
+    ${WEBP_DEP_GIF_LIBRARIES})
   target_include_directories(anim_diff PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/src)
 
   # anim_dump
@@ -656,45 +713,59 @@ if(WEBP_BUILD_ANIM_UTILS)
   parse_makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/examples "ANIM_DUMP_SRCS"
                     "anim_dump")
   add_executable(anim_dump ${ANIM_DUMP_SRCS})
-  target_link_libraries(anim_dump
-                        exampleutil
-                        imagedec
-                        imageenc
-                        imageioutil
-                        webp
-                        webpdemux
-                        ${WEBP_DEP_GIF_LIBRARIES})
+  target_link_libraries(
+    anim_dump
+    exampleutil
+    imagedec
+    imageenc
+    imageioutil
+    webp
+    webpdemux
+    ${WEBP_DEP_GIF_LIBRARIES})
   target_include_directories(anim_dump PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/src)
 endif()
 
 # Install the different headers and libraries.
-install(TARGETS ${INSTALLED_LIBRARIES}
-        EXPORT ${PROJECT_NAME}Targets
-        PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/webp
-        INCLUDES
-        DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
-        ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
-        LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
-        RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
+install(
+  TARGETS ${INSTALLED_LIBRARIES}
+  EXPORT ${PROJECT_NAME}Targets
+  PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/webp
+  INCLUDES
+  DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
+  ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
+  LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+  RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
 set(ConfigPackageLocation ${CMAKE_INSTALL_DATADIR}/${PROJECT_NAME}/cmake/)
-install(EXPORT ${PROJECT_NAME}Targets
-        NAMESPACE ${PROJECT_NAME}::
+install(EXPORT ${PROJECT_NAME}Targets NAMESPACE ${PROJECT_NAME}::
         DESTINATION ${ConfigPackageLocation})
 
 # Create the CMake version file.
 include(CMakePackageConfigHelpers)
 write_basic_package_version_file(
   "${CMAKE_CURRENT_BINARY_DIR}/WebPConfigVersion.cmake"
-  VERSION ${PACKAGE_VERSION}
-  COMPATIBILITY AnyNewerVersion)
+  VERSION ${PACKAGE_VERSION} COMPATIBILITY AnyNewerVersion)
 
 # Create the Config file.
 include(CMakePackageConfigHelpers)
+# Fix libwebpmux reference. The target name libwebpmux is used for compatibility
+# purposes, but the library mentioned in WebPConfig.cmake should be the
+# unprefixed version. Note string(...) can be replaced with list(TRANSFORM ...)
+# if cmake_minimum_required is >= 3.12.
+string(REGEX REPLACE "libwebpmux" "webpmux" INSTALLED_LIBRARIES
+                     "${INSTALLED_LIBRARIES}")
+
+if(MSVC)
+  # For compatibility with nmake, MSVC builds use a custom prefix (lib) that
+  # needs to be included in the library name.
+  string(REGEX REPLACE "[A-Za-z0-9_]+" "${CMAKE_STATIC_LIBRARY_PREFIX}\\0"
+                       INSTALLED_LIBRARIES "${INSTALLED_LIBRARIES}")
+endif()
+
 configure_package_config_file(
   ${CMAKE_CURRENT_SOURCE_DIR}/cmake/WebPConfig.cmake.in
   ${CMAKE_CURRENT_BINARY_DIR}/WebPConfig.cmake
-  INSTALL_DESTINATION
-  ${ConfigPackageLocation})
+  INSTALL_DESTINATION ${ConfigPackageLocation}
+  PATH_VARS CMAKE_INSTALL_INCLUDEDIR)
 
 # Install the generated CMake files.
 install(FILES "${CMAKE_CURRENT_BINARY_DIR}/WebPConfigVersion.cmake"
@@ -726,7 +797,6 @@ foreach(I_MAN RANGE ${MAN_PAGES_RANGE})
   if(WEBP_BUILD_${EXEC_BUILD})
     list(GET MAN_PAGES ${I_MAN} MAN_PAGE)
     install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/man/${MAN_PAGE}
-            DESTINATION ${CMAKE_INSTALL_MANDIR}/man1
-            COMPONENT doc)
+            DESTINATION ${CMAKE_INSTALL_MANDIR}/man1 COMPONENT doc)
   endif()
 endforeach()

+ 50 - 1
webp.mod/libwebp/CONTRIBUTING.md

@@ -19,10 +19,59 @@ again.
 
 All submissions, including submissions by project members, require review. We
 use a [Gerrit](https://www.gerritcodereview.com) instance hosted at
-https://chromium-review.googlesource.com for this purpose. See the
+https://chromium-review.googlesource.com for this purpose.
+
+## Sending patches
+
+The basic git workflow for modifying libwebp code and sending for review is:
+
+1.  Get the latest version of the repository locally:
+
+    ```sh
+    git clone https://chromium.googlesource.com/webm/libwebp && cd libwebp
+    ```
+
+2.  Copy the commit-msg script into ./git/hooks (this will add an ID to all of
+    your commits):
+
+    ```sh
+    curl -Lo .git/hooks/commit-msg https://chromium-review.googlesource.com/tools/hooks/commit-msg && chmod u+x .git/hooks/commit-msg
+    ```
+
+3.  Modify the local copy of libwebp. Make sure the code
+    [builds successfully](https://chromium.googlesource.com/webm/libwebp/+/HEAD/doc/building.md#cmake).
+
+4.  Choose a short and representative commit message:
+
+    ```sh
+    git commit -a -m "Set commit message here"
+    ```
+
+5.  Send the patch for review:
+
+    ```sh
+    git push https://chromium-review.googlesource.com/webm/libwebp HEAD:refs/for/main
+    ```
+
+    Go to https://chromium-review.googlesource.com to view your patch and
+    request a review from the maintainers.
+
+See the
 [WebM Project page](https://www.webmproject.org/code/contribute/submitting-patches/)
 for additional details.
 
+## Code Style
+
+The C code style is based on the
+[Google C++ Style Guide](https://google.github.io/styleguide/cppguide.html) and
+`clang-format --style=Google`, though this project doesn't use the tool to
+enforce the formatting.
+
+CMake files are formatted with
+[cmake-format](https://cmake-format.readthedocs.io/en/latest/). `cmake-format
+-i` can be used to format individual files, it will use the settings from
+`.cmake-format.py`.
+
 ## Community Guidelines
 
 This project follows

+ 396 - 1
webp.mod/libwebp/ChangeLog

@@ -1,7 +1,402 @@
+1ace578c update NEWS
+63234c42 bump version to 1.3.2
+2af26267 Fix OOB write in BuildHuffmanTable.
+fd7bb21c update ChangeLog (tag: v1.3.1-rc2, tag: v1.3.1)
+e1adea50 update NEWS
+43393320 enc/*: normalize WebPEncodingSetError() calls
+287fdefe enc/*: add missing WebPEncodingSetError() calls
+c3bd7cff EncodeAlphaInternal: add missing error check
+d49cfbb3 vp8l_enc,WriteImage: add missing error check
+2e5a9ec3 muxread,MuxImageParse: add missing error checks
+ebb6f949 cmake,emscripten: explicitly set stack size
+59a2b1f9 WebPDecodeYUV: check u/v/stride/uv_stride ptrs
+8e965ccb Call png_get_channels() to see if image has alpha
+7f0a3419 update ChangeLog (tag: v1.3.1-rc1)
+bab7efbe update NEWS
+7138bf8f bump version to 1.3.1
+435b4ded update AUTHORS
+47351229 update .mailmap
+ff6c7f4e CONTRIBUTING.md: add C style / cmake-format notes
+dd530437 add .cmake-format.py
+adbe2cb1 cmake,cosmetics: apply cmake-format
+15b36508 doc/webp-container-spec: rm future codec comment
+c369c4bf doc/webp-lossless-bitstream-spec: improve link text
+1de35f47 doc/webp-container-spec: don't use 'currently'
+bb06a16e doc/webp-container-spec: prefer present tense
+9f38b71e doc/webp-lossless-bitstream-spec: prefer present tense
+7acb6b82 doc/webp-container-spec: avoid i.e. & e.g.
+4967e7cd doc/webp-lossless-bitstream-spec: avoid i.e. & e.g.
+e3366659 Merge "Do not find_package image libraries if not needed." into main
+428588ef clarify single leaf node trees and use of canonical prefix coding
+709ec152 Do not find_package image libraries if not needed.
+8dd80ef8 fuzz_utils.h: lower kFuzzPxLimit w/ASan
+8f187b9f Clean message calls in CMake
+cba30078 WebPConfig.cmake.in: use calculated include path
+6cf9a76a Merge "webp-lossless-bitstream-spec: remove use of 'dynamics'" into main
+740943b2 Merge "Specialize and optimize ITransform_SSE2 using do_two" into main
+2d547e24 Compare kFuzzPxLimit to max_num_operations
+ac42dde1 Specialize and optimize ITransform_SSE2 using do_two
+17e0ef1d webp-lossless-bitstream-spec: remove use of 'dynamics'
+ed274371 neon.h,cosmetics: clear a couple lint warnings
+3fb82947 cpu.h,cosmetics: segment defines
+0c496a4f cpu.h: add WEBP_AARCH64
+8151f388 move VP8GetCPUInfo declaration to cpu.c
+916548c2 Make kFuzzPxLimit sanitizer dependent
+4070b271 advanced_api_fuzzer: reduce scaling limit
+761f49c3 Merge "webp-lossless-bitstream-spec: add missing bits to ABNF" into main
+84d04c48 webp-lossless-bitstream-spec: add missing bits to ABNF
+0696e1a7 advanced_api_fuzzer: reduce scaling limit
+93d88aa2 Merge "deps.cmake: remove unneeded header checks" into main
+118e0035 deps.cmake: remove unneeded header checks
+4c3d7018 webp-lossless-bitstream-spec: condense normal-prefix-code
+a6a09b32 webp-lossless-bitstream-spec: fix 2 code typos
+50ac4f7c Merge "cpu.h: enable NEON w/_M_ARM64EC" into main
+4b7d7b4f Add contribution instructions
+0afbd97b cpu.h: enable NEON w/_M_ARM64EC
+349f4353 Merge changes Ibd89e56b,Ic57e7f84,I89096614 into main
+8f7513b7 upsampling_neon.c: fix WEBP_SWAP_16BIT_CSP check
+cbf624b5 advanced_api_fuzzer: reduce scaling limit
+89edfdd1 Skip slow scaling in libwebp advanced_api_fuzzer
+859f19f7 Reduce libwebp advanced_api_fuzzer threshold
+a4f04835 Merge changes Ic389aaa2,I329ccd79 into main
+1275fac8 Makefile.vc: fix img2webp link w/dynamic cfg
+2fe27bb9 img2webp: normalize help output
+24bed3d9 cwebp: reflow -near_lossless help text
+0825faa4 img2webp: add -sharp_yuv/-near_lossless
+d64e6d7d Merge "PaletteSortModifiedZeng: fix leak on error" into main
+0e12a22d Merge "EncodeAlphaInternal: clear result->bw on error" into main
+0edbb6ea PaletteSortModifiedZeng: fix leak on error
+41ffe04e Merge "Update yapf style from "chromium" to "yapf"" into main
+2d9d9265 Update yapf style from "chromium" to "yapf"
+a486d800 EncodeAlphaInternal: clear result->bw on error
+1347a32d Skip big scaled advanced_api_fuzzer
+52b6f067 Fix scaling limit in advanced_api_fuzzer.c
+73618428 Limit scaling in libwebp advanced_api_fuzzer.c
+b54d21a0 Merge "CMakeLists.txt: allow CMAKE_INSTALL_RPATH to be set empty" into main
+31c28db5 libwebp{,demux,mux}.pc.in: Requires -> Requires.private
+d9a505ff CMakeLists.txt: allow CMAKE_INSTALL_RPATH to be set empty
+bdf33d03 Merge tag 'v1.3.0'
+b5577769 update ChangeLog (tag: v1.3.0-rc1, tag: v1.3.0)
+0ba77244 update NEWS
+e763eb1e bump version to 1.3.0
+2a8686fc update AUTHORS
+106a57c1 Merge "*/Android.mk: add a check for NDK_ROOT" into main
+c5e841c4 Merge "extras: WebpToSDL -> WebPToSDL" into main
+dbc30715 Merge "xcframeworkbuild.sh: bump MACOSX_CATALYST_MIN_VERSION" into main
+6fc1a9f9 */Android.mk: add a check for NDK_ROOT
+d3e151fc doc/api.md,webp_js/README.md: Webp -> WebP
+ed92a626 extras: WebpToSDL -> WebPToSDL
+6eb0189b xcframeworkbuild.sh: bump MACOSX_CATALYST_MIN_VERSION
+1d58575b CMake: align .pc variables with autoconf
+e5fe2cfc webp-lossless-bitstream-spec,cosmetics: reflow paragraphs
+0ceeeab9 webp-lossless-bitstream-spec: add amendment note
+607611cd Merge "webp-container-spec: normalize section title case" into main
+f853685e lossless: SUBTRACT_GREEN -> SUBTRACT_GREEN_TRANSFORM
+786497e4 webp-lossless-bitstream-spec: fix inv color txfm description
+c6ac672d webp-lossless-bitstream-spec: fix num_code_lengths check
+b5700efb webp-lossless-bitstream-spec,cosmetics: grammar/capitalization
+d8ed8c11 webp-container-spec: normalize section title case
+52ec0b8f Merge changes Ie975dbb5,Ifc8c93af,I6ca7c5d6,I2e8d66f5,I152477b8 into main
+5097ef62 webp-container-spec,cosmetics: grammar/capitalization
+e3ba2b1f webp-lossless-bitstream-spec,cosmetics: reflow abstract
+1e8e3ded webp-lossless-bitstream-spec: reword abstract re alpha
+017cb6fa webp-container-spec,cosmetics: normalize range syntax
+f6a4684b webp-lossless-bitstream-spec,cosmetics: normalize range syntax
+54ebd5a3 webp-lossless-bitstream-spec: limit dist map lut to 69 cols
+44741f9c webp-lossless-bitstream-spec: fix dist mapping example
+fad0ece7 pnmdec.c: use snprintf instead of sprintf
+3f73e8f7 sharpyuv: add SharpYuvGetVersion()
+ce2f2d66 SharpYuvConvert: fix a race on SharpYuvGetCPUInfo
+a458e308 sharpyuv_dsp.h: restore sharpyuv_cpu.h include
+9ba800a7 Merge changes Id72fbf3b,Ic59d23a2 into main
+979c0ebb sharpyuv: add SharpYuvGetCPUInfo
+8bab09a4 Merge "*.pc.in: rename lib_prefix to webp_libname_prefix" into main
+769387c5 cpu.c,cosmetics: fix a typo
+a02978c2 sharpyuv/Makefile.am+cmake: add missing -lm
+28aedcb9 *.pc.in: rename lib_prefix to webp_libname_prefix
+c42e6d5a configure.ac: export an empty lib_prefix variable
+dfc843aa Merge "*.pc.in: add lib prefix to lib names w/MSVC" into main
+2498209b *.pc.in: add lib prefix to lib names w/MSVC
+ac252b61 Merge "analysis_enc.c: fix a dead store warning" into main
+56944762 analysis_enc.c: fix a dead store warning
+d34f9b99 Merge "webp-lossless-bitstream-spec: convert BNF to ABNF" into main
+dc05b4db Merge changes I96bc063c,I45880467,If9e18e5a,I6ee938e4,I0a410b28, ... into main
+83270c7f webp-container-spec: add prose for rendering process
+73b19b64 webp-container-spec: note reserved fields MUST be ignored
+57101d3f webp-lossless-bitstream-spec: improve 'small' color table stmt
+dfd32e45 webp-container-spec: remove redundant sentence
+8a6185dd doc/webp-*: fix some punctuation, grammar
+72776530 webp-lossless-bitstream-spec: convert BNF to ABNF
+d992bb08 cmake: rename cpufeatures target to cpufeatures-webp
+3ed2b275 webp-container-spec: clarify background color note
+951c292d webp-container-spec: come too late -> out of order
+902dd787 webp-container-spec: prefer hex literals
+a8f6b5ee webp-container-spec: change SHOULD to MUST w/ANIM chunk
+1dc59435 webp-container-spec: add unknown fields MUST be ignored
+280a810f webp-container-spec: make padding byte=0 a MUST
+41f0bf68 webp-container-spec: update note on trailing data
+6bdd36db webp-container-spec: clarify Chunk Size is in bytes
+87e36c48 Merge "webp_js/README.md,cosmetics: reflow some lines" into main
+5b01f321 Merge "Update Windows makefile to build libsharpyuv library." into main
+19b1a71c webp_js/README.md,cosmetics: reflow some lines
+780db756 Update Windows makefile to build libsharpyuv library.
+e407d4b3 CMakeLists.txt: replace GLUT_glut_LIBRARY w/GLUT::GLUT
+abf73d62 Merge "WebPConfig.cmake.in: add find_dependency(Threads)" into main
+25807fb4 Merge "cmake: restore compatibility with cmake < 3.12" into main
+5dbc4bfa WebPConfig.cmake.in: add find_dependency(Threads)
+b2a175dd Merge "Update wasm instructions." into main
+cb90f76b Update wasm instructions.
+02d15258 cmake: restore compatibility with cmake < 3.12
+5ba046e2 CMake: add_definitions -> add_compile_options
+e68765af dsp,neon: use vaddv in a few more places
+e8f83de2 Set libsharpyuv include dir to 'webp' subdirectory.
+15a91ab1 cmake,cosmetics: apply cmake-format
+0dd49d1a CMakeLists.txt: set @ONLY in configure_file() calls
+62b1bfe8 Merge changes I2877e7bb,I777cad70,I15af7d1a,I686e6740,If10538a9, ... into main
+95c8fe5f Merge changes Iecea3603,I9dc228ab into main
+e7c805cf picture_csp_enc.c: remove SafeInitSharpYuv
+6af8845a sharpyuv: prefer webp/types.h
+639619ce cmake: fix dll exports
+782ed48c sharpyuv,SharpYuvInit: add mutex protection when available
+cad0d5ad sharyuv_{neon,sse2}.c: merge WEBP_USE_* sections
+ef70ee06 add a few missing <stddef.h> includes for NULL
+f0f9eda4 sharpyuv.h: remove <inttypes.h>
+9b902cba Merge "picture_csp_enc.c,CheckNonOpaque: rm unneeded local" into main
+9c1d457c cmake/cpu.cmake: remove unused variable
+9ac25bcb CMakeLists.txt,win32: match naming convention used by nmake
+76c353ba picture_csp_enc.c,CheckNonOpaque: rm unneeded local
+5000de54 Merge "cwebp: fix WebPPictureHasTransparency call" into main
+e1729309 Merge "WebPPictureHasTransparency: add missing pointer check" into main
+00ff988a vp8l_enc,AddSingleSubGreen: clear int sanitizer warnings
+e2fecc22 dsp/lossless_enc.c: clear int sanitizer warnings
+129cf9e9 dsp/lossless.c: clear int sanitizer warnings
+ad7d1753 dsp/lossless_enc.c: clear int sanitizer warnings
+5037220e VP8LSubtractGreenFromBlueAndRed_C: clear int sanitizer warnings
+2ee786c7 upsampling_sse2.c: clear int sanitizer warnings
+4cc157d4 ParseOptionalChunks: clear int sanitizer warning
+892cf033 BuildHuffmanTable: clear int sanitizer warning
+3a9a4d45 VP8GetSigned: clear int sanitizer warnings
+704a3d0a dsp/lossless.c: quiet int sanitizer warnings
+1a6c109c WebPPictureHasTransparency: add missing pointer check
+c626e7d5 cwebp: fix WebPPictureHasTransparency call
+866e349c Merge tag 'v1.2.4'
+c170df38 Merge "Create libsharpyuv.a in makefile.unix." into main
+9d7ff74a Create libsharpyuv.a in makefile.unix.
+0d1f1254 update ChangeLog (tag: v1.2.4)
+fcbc2d78 Merge "doc/*.txt: restrict code to 69 columns" into main
+4ad0e189 Merge "webp-container-spec.txt: normalize fourcc spelling" into main
+980d2488 update NEWS
+9fde8127 bump version to 1.2.4
+7a0a9935 doc/*.txt: restrict code to 69 columns
+c040a615 webp-container-spec.txt: normalize fourcc spelling
+aff1c546 dsp,x86: normalize types w/_mm_cvtsi128_si32 calls
+ab540ae0 dsp,x86: normalize types w/_mm_cvtsi32_si128 calls
+8980362e dsp,x86: normalize types w/_mm_set* calls (2)
+e626925c lossless: fix crunch mode w/WEBP_REDUCE_SIZE
+83539239 dsp,x86: normalize types w/_mm_set* calls
+8a4576ce webp-container-spec.txt: replace &amp; with &
+db870881 Merge "webp-container-spec.txt: make reserved 0 values a MUST" into main
+01d7d378 webp-lossless-bitstream-spec: number all sections
+337cf69f webp-lossless-bitstream-spec: mv Nomenclature after Intro
+79be856e Merge changes I7111d1f7,I872cd62c into main
+5b87983a webp-container-spec.txt: make reserved 0 values a MUST
+bd939123 Merge changes I7a25b1a6,I51b2c2a0,I87d0cbcf,I6ec60af6,I0a3fe9dc into main
+04764b56 libwebp.pc: add libsharpyuv to requires
+7deee810 libsharpyuv: add pkg-config file
+1a64a7e6 webp-container-spec.txt: clarify some SHOULDs
+bec2c88a webp-container-spec.txt: move ChunkHeader to terminology
+c9359332 webp-container-spec.txt: clarify 'VP8 '/'XMP ' fourccs
+70fe3063 webp-container-spec.txt: rightsize table entries
+ddbf3f3f webp-container-spec.txt: update 'key words' text
+c151e95b utils.h,WEBP_ALIGN: make bitmask unsigned
+748e92bb add WebPInt32ToMem
+3fe15b67 Merge "Build libsharpyuv as a full installable library." into main
+4f402f34 add WebPMemToInt32
+a3b68c19 Build libsharpyuv as a full installable library.
+b4994eaa CMake: set rpath for shared objects
+94cd7117 Merge "CMake: fix dylib versioning" into main
+e91451b6 Fix the lossless specs a bit more.
+231bdfb7 CMake: fix dylib versioning
+bfad7ab5 CMakeLists.txt: correct libwebpmux name in WebPConfig.cmake
+c2e3fd30 Revert "cmake: fix webpmux lib name for cmake linking"
+7366f7f3 Merge "lossless: fix crunch mode w/WEBP_REDUCE_SIZE" into main
+84163d9d lossless: fix crunch mode w/WEBP_REDUCE_SIZE
+d01c1eb3 webp-lossless-bitstream-spec,cosmetics: normalize capitalization
+8813ca8e Merge tag 'v1.2.3'
+3c4a0fbf update ChangeLog (tag: v1.2.3)
+56a480e8 dsp/cpu.h: add missing extern "C"
+62b45bdd update ChangeLog (tag: v1.2.3-rc1)
+8764ec7a Merge changes Idb037953,Id582e395 into 1.2.3
+bcb872c3 vwebp: fix file name display in windows unicode build
+67c44ac5 webpmux: fix -frame option in windows unicode build
+8278825a makefile.unix: add sharpyuv objects to clean target
+14a49e01 update NEWS
+34b1dc33 bump version to 1.2.3
+0b397fda update AUTHORS
+c16488ac update .mailmap
+5a2d929c Merge "unicode.h: set console mode before using wprintf" into main
+169f867f unicode.h: set console mode before using wprintf
+a94b855c Merge "libsharpyuv: add version defines" into main
+f83bdb52 libsharpyuv: add version defines
+bef0d797 unicode_gif.h: fix -Wdeclaration-after-statement
+404c1622 Rename Huffman coding to prefix coding in the bitstream spec
+8895f8a3 Merge "run_static_analysis.sh: fix scan-build archive path" into main
+92a673d2 Merge "Add -fvisibility=hidden flag in CMakeLists." into main
+67c1d722 Merge "add WEBP_MSAN" into main
+1124ff66 Add -fvisibility=hidden flag in CMakeLists.
+e15b3560 add WEBP_MSAN
+ec9e782a sharpyuv: remove minimum image size from sharpyuv library
+7bd07f3b run_static_analysis.sh: fix scan-build archive path
+5ecee06f Merge "sharpyuv: increase precision of gamma<->linear conversion" into main
+f81dd7d6 Merge changes I3d17d529,I53026880,I1bd61639,I6bd4b25d,Icfec8fba into main
+2d607ee6 sharpyuv: increase precision of gamma<->linear conversion
+266cbbc5 sharpyuv: add 32bit version of SharpYuvFilterRow.
+9fc12274 CMake: add src to webpinfo includes
+7d18f40a CMake: add WEBP_BUILD_WEBPINFO to list of checks for exampleutil
+11309aa5 CMake: add WEBP_BUILD_WEBPMUX to list of checks for exampleutil
+4bc762f7 CMake: link imageioutil to exampleutil after defined
+0d1b9bc4 WEBP_DEP_LIBRARIES: use Threads::Threads
+20ef48f0 Merge "sharpyuv: add support for 10/12/16 bit rgb and 10/12 bit yuv." into main
+93c54371 sharpyuv: add support for 10/12/16 bit rgb and 10/12 bit yuv.
+53cf2b49 normalize WebPValidatePicture declaration w/definition
+d3006f4b sharpyuv: slightly improve precision
+ea967098 Merge changes Ia01bd397,Ibf3771af into main
+11bc8410 Merge changes I2d317c4b,I9e77f6db into main
+30453ea4 Add an internal WebPValidatePicture.
+6c43219a Some renamings for consistency.
+4f59fa73 update .mailmap
+e74f8a62 webp-lossless-bitstream-spec,cosmetics: normalize range syntax
+5a709ec0 webp-lossless-bitstream-spec,cosmetics: fix code typo
+a2093acc webp-lossless-bitstream-spec: add amendment note
+86c66930 webp-lossless-bitstream-spec: fix BNF
+232f22da webp-lossless-bitstream-spec: fix 'simple code' snippet
+44dd765d webp-lossless-bitstream-spec: fix ColorTransform impl
+7a7e33e9 webp-lossless-bitstream-spec: fix TR-pixel right border note
+86f94ee0 Update lossless spec with Huffman codes.
+a3927cc8 sharpyuv.c,cosmetics: fix indent
+6c45cef7 Make sure the stride has a minimum value in the importer.
+0c8b0e67 sharpyuv: cleanup/cosmetic changes
+dc3841e0 {histogram,predictor}_enc: quiet int -> float warnings
+a19a25bb Replace doubles by floats in lossless misc cost estimations.
+42888f6c Add an option to enable static builds.
+7efcf3cc Merge "Fix typo in color constants: Marix -> Matrix" into main
+8f4b5c62 Fix typo in color constants: Marix -> Matrix
+90084d84 Merge "demux,IsValidExtendedFormat: remove unused variable" into main
+ed643f61 Merge changes I452d2485,Ic6d75475 into main
+8fa053d1 Rename SharpYUV to SharpYuv for consistency.
+99a87562 SharpYuvComputeConversionMatrix: quiet int->float warnings
+deb426be Makefile.vc: add sharpyuv_csp.obj to SHARPYUV_OBJS
+779597d4 demux,IsValidExtendedFormat: remove unused variable
+40e8aa57 Merge "libsharpyuv: add colorspace utilities" into main
+01a05de1 libsharpyuv: add colorspace utilities
+2de4b05a Merge changes Id9890a60,I376d81e6,I1c958838 into main
+b8bca81f Merge "configure.ac: use LT_INIT if available" into main
+e8e77b9c Merge changes I479bc487,I39864691,I5d486c2c,I186d13be into main
+7e7d5d50 Merge ".gitignore: add Android Studio & VS code dirs" into main
+10c50848 normalize label indent
+89f774e6 mux{edit,internal}: fix leaks on error
+2d3293ad ExUtilInitCommandLineArguments: fix leak on error
+ec34fd70 anim_util: fix leaks on error
+e4717287 gif2webp: fix segfault on OOM
+e3cfafaf GetBackwardReferences: fail on alloc error
+a828a59b BackwardReferencesHashChainDistanceOnly: fix segfault on OOM
+fe153fae VP8LEncodeStream: fix segfault on OOM
+919acc0e .gitignore: add Android Studio & VS code dirs
+efa0731b configure.ac: use LT_INIT if available
+0957fd69 tiffdec: add grayscale support
+e685feef Merge "Make libsharpyuv self-contained by removing dependency on cpu.c" into main
+841960b6 Make libsharpyuv self-contained by removing dependency on cpu.c
+617cf036 image_dec: add WebPGetEnabledInputFileFormats()
+7a68afaa Let SharpArgbToYuv caller pass in an RGB>YUV conversion matrix.
+34bb332c man/cwebp.1: add note about crop/resize order
+f0e9351c webp-lossless-bitstream-spec,cosmetics: fix some typos
+5ccbd6ed vp8l_dec.c,cosmetics: fix a few typos
+c3d0c2d7 fix ios build scripts after sharpyuv dep added
+d0d2292e Merge "Make libwebp depend on libsharpyuv." into main
+03d12190 alpha_processing_neon.c: fix 0x01... typo
+d55d447c Make libwebp depend on libsharpyuv.
+e4cbcdd2 Fix lossless encoding for MIPS.
+924e7ca6 alpha_processing_neon.c: fix Dispatch/ExtractAlpha_NEON
+0fa0ea54 Makefile.vc: use /MANIFEST:EMBED
+29cc95ce Basic version of libsharpyuv in libwebp, in C.
+a30f2190 examples/webpmux.c: fix a couple of typos
+66b3ce23 Fix bad overflow check in ReadTIFF()
+54e61a38 Markdownify libwebp docs and reorganize them.
+b4533deb CMakeLists.txt,cosmetics: break long line
+b9d2f9cd quant_enc.c: use WEBP_RESTRICT qualifier
+ec178f2c Add progress hook granularity in lossless
+26139c73 Rename MAX_COST to MAX_BIT_COST in histogram_enc.c
+13b82816 cmake: fix webpmux lib name for cmake linking
+88b6a396 webp-container-spec.txt,cosmetics: normalize formatting
+6f496540 Merge tag 'v1.2.2'
+4074acf8 dsp.h: bump msvc arm64 version requirement to 16.6
+b0a86089 update ChangeLog (tag: v1.2.2)
+6db8248c libwebp: Fix VP8EncTokenLoop() progress
+827a307f BMP enc: fix the transparency case
+db25f1b4 libwebp: Fix VP8EncTokenLoop() progress
+286e7fce libwebp: do not destroy jpeg codec twice on error
+6e8a4126 libwebp: do not destroy jpeg codec twice on error
+faf21968 Merge "BMP enc: fix the transparency case" into main
+480cd51d BMP enc: fix the transparency case
+9195ea05 update ChangeLog (tag: v1.2.2-rc2)
+4acae017 update NEWS
+883f0633 man/img2webp.1: update date
+567e1f44 Reword img2webp synopsis command line
+1b0c15db man/img2webp.1: update date
+17bade38 Merge "Reword img2webp synopsis command line" into main
+a80954a1 Reword img2webp synopsis command line
+f084244d anim_decode: fix alpha blending with big-endian
+b217b4ff webpinfo: fix fourcc comparison w/big-endian
+ec497b75 Merge "anim_decode: fix alpha blending with big-endian" into main
+e4886716 anim_decode: fix alpha blending with big-endian
+e3cb052c webpinfo: fix fourcc comparison w/big-endian
+a510fedb patch-check: detect duplicated files
+f035d2e4 update ChangeLog (tag: v1.2.2-rc1)
+7031946a update NEWS
+973390b6 bump version to 1.2.2
+abd6664f update AUTHORS
+5b7e7930 Merge "add missing USE_{MSA,NEON} checks in headers" into main
+02ca04c3 add missing USE_{MSA,NEON} checks in headers
+e94716e2 xcframeworkbuild.sh: place headers in a subdir
+c846efd8 patch-check: commit subject length check
+b6f756e8 update http links
+8f5cb4c1 update rfc links
+8ea81561 change VP8LPredictorFunc signature to avoid reading 'left'
+6b1d18c3 webpmux: fix the -bgcolor description
+3368d876 Merge "webpmux: add "-set bgcolor A,R,G,B"" into main
+f213abf6 webpinfo: print the number of warnings
+50c97c30 webpmux: add "-set bgcolor A,R,G,B"
+2c206aaf Remove CMakeLists.txt check in compile.sh
+96e3dfef Merge "infra/common.sh: add shard_should_run()" into main
+0e0f74b7 infra/common.sh: add shard_should_run()
+35b7436a Jenkins scripts port: update shell function comments
+21d24b4c webp-container-spec.txt: remove 'experimental' markers
+cdcf8902 Merge "Port Jenkins script: compile" into main
+dc683cde Jenkins scripts port: static analysis
+0858494e Port Jenkins script: compile
+c2cf6a93 Jenkins scripts port: android compilation
+df0e808f presubmit: Add pylint-2.7 and .pylintrc
+676c57db patch-check: shfmt
+7bb7f747 patch-check: Add shellcheck
+abcd1797 Reformat docstrings and imports
+edaf0895 Port Jenkins scripts: compile js
+b9622063 Set CheckPatchFormatted flags to fail on diffs
+e23cd548 dsp.h: enable NEON w/VS2019+ ARM64 targets
+3875c7de CMakeLists.txt: set minimum version to 3.7
+1a8f0d45 Have a hard-coded value for memset in TrellisQuantizeBlock.
+93480160 Speed up TrellisQuantizeBlock
+45eaacc9 Convert deprecated uint32 to uint32_t.
+42592af8 webp,cmake: Remove unnecessary include dirs
+e298e05f Add patch-check steps in PRESUBMIT.py
+29148919 Merge tag 'v1.2.1'
+9ce5843d update ChangeLog (tag: v1.2.1)
 d9191588 fuzzer/*: normalize src/ includes
+c5bc3624 fuzzer/*: normalize src/ includes
 53b6f762 fix indent
+d2caaba4 fix indent
 731246ba update ChangeLog (tag: v1.2.1-rc2)
 d250f01d dsp/*: use WEBP_HAVE_* to determine Init availability
+1fe31625 dsp/*: use WEBP_HAVE_* to determine Init availability
 3a4d3ecd update NEWS
 b2bc8093 bump version to 1.2.1
 e542fc7a update AUTHORS
@@ -173,7 +568,7 @@ a99078c1 remove call to MBAnalyzeBestIntra4Mode for method >= 5
 6a0ff358 Enc: add a qmin / qmax range for quality factor
 0fa56f30 Merge tag 'v1.1.0'
 6cf504d0 PNM decoding: handle max_value != 255
-d7844e97 update ChangeLog (tag: v1.1.0-rc2, tag: v1.1.0, origin/1.1.0)
+d7844e97 update ChangeLog (tag: v1.1.0-rc2, tag: v1.1.0)
 7f006436 Makefile.vc: fix webp_quality.exe link
 cf047e83 Makefile.vc: fix webp_quality.exe link
 c074c653 update NEWS

+ 1 - 1
webp.mod/libwebp/Makefile.am

@@ -1,5 +1,5 @@
 ACLOCAL_AMFLAGS = -I m4
-SUBDIRS = src imageio man
+SUBDIRS = sharpyuv src imageio man
 EXTRA_DIST = COPYING autogen.sh
 
 if BUILD_EXTRAS

+ 35 - 31
webp.mod/libwebp/Makefile.vc

@@ -5,6 +5,7 @@ LIBWEBPDECODER_BASENAME = libwebpdecoder
 LIBWEBP_BASENAME = libwebp
 LIBWEBPMUX_BASENAME = libwebpmux
 LIBWEBPDEMUX_BASENAME = libwebpdemux
+LIBSHARPYUV_BASENAME = libsharpyuv
 
 !IFNDEF ARCH
 !IF ! [ cl 2>&1 | find "x86" > NUL ]
@@ -31,12 +32,11 @@ CCNODBG    = cl.exe $(NOLOGO) /O2 /DNDEBUG
 CCDEBUG    = cl.exe $(NOLOGO) /Od /Zi /D_DEBUG /RTC1
 CFLAGS     = /I. /Isrc $(NOLOGO) /W3 /EHsc /c
 CFLAGS     = $(CFLAGS) /DWIN32 /D_CRT_SECURE_NO_WARNINGS /DWIN32_LEAN_AND_MEAN
-LDFLAGS    = /LARGEADDRESSAWARE /MANIFEST /NXCOMPAT /DYNAMICBASE
+LDFLAGS    = /LARGEADDRESSAWARE /MANIFEST:EMBED /NXCOMPAT /DYNAMICBASE
 LDFLAGS    = $(LDFLAGS) $(PLATFORM_LDFLAGS)
 LNKDLL     = link.exe /DLL $(NOLOGO)
 LNKEXE     = link.exe $(NOLOGO)
 LNKLIB     = lib.exe $(NOLOGO)
-MT         = mt.exe $(NOLOGO)
 RCNODBG    = rc.exe $(NOLOGO) /l"0x0409"  # 0x409 = U.S. English
 RCDEBUG    = $(RCNODBG) /D_DEBUG
 
@@ -82,6 +82,7 @@ OUTPUT_DIRS = $(DIRBIN) $(DIRINC) $(DIRLIB) \
               $(DIROBJ)\extras \
               $(DIROBJ)\imageio \
               $(DIROBJ)\mux \
+              $(DIROBJ)\sharpyuv \
               $(DIROBJ)\utils \
 
 # Target configuration
@@ -96,6 +97,7 @@ LIBWEBPDECODER_BASENAME = $(LIBWEBPDECODER_BASENAME)_debug
 LIBWEBP_BASENAME = $(LIBWEBP_BASENAME)_debug
 LIBWEBPMUX_BASENAME = $(LIBWEBPMUX_BASENAME)_debug
 LIBWEBPDEMUX_BASENAME = $(LIBWEBPDEMUX_BASENAME)_debug
+LIBSHARPYUV_BASENAME = $(LIBSHARPYUV_BASENAME)_debug
 !ELSE IF "$(CFG)" == "release-dynamic"
 CC        = $(CCNODBG)
 RC        = $(RCNODBG)
@@ -109,6 +111,7 @@ LIBWEBPDECODER_BASENAME = $(LIBWEBPDECODER_BASENAME)_debug
 LIBWEBP_BASENAME = $(LIBWEBP_BASENAME)_debug
 LIBWEBPMUX_BASENAME = $(LIBWEBPMUX_BASENAME)_debug
 LIBWEBPDEMUX_BASENAME = $(LIBWEBPDEMUX_BASENAME)_debug
+LIBSHARPYUV_BASENAME = $(LIBSHARPYUV_BASENAME)_debug
 !ENDIF
 
 !IF "$(STATICLIBBUILD)" == "TRUE"
@@ -118,13 +121,14 @@ LIBWEBPDECODER = $(DIRLIB)\$(LIBWEBPDECODER_BASENAME).lib
 LIBWEBP = $(DIRLIB)\$(LIBWEBP_BASENAME).lib
 LIBWEBPMUX = $(DIRLIB)\$(LIBWEBPMUX_BASENAME).lib
 LIBWEBPDEMUX = $(DIRLIB)\$(LIBWEBPDEMUX_BASENAME).lib
+LIBSHARPYUV = $(DIRLIB)\$(LIBSHARPYUV_BASENAME).lib
 !ELSE IF "$(DLLBUILD)" == "TRUE"
-DLLINC = webp_dll.h
-CC     = $(CC) /I$(DIROBJ) /FI$(DLLINC) $(RTLIB) /DWEBP_DLL
+CC     = $(CC) /I$(DIROBJ) $(RTLIB) /DWEBP_DLL
 LIBWEBPDECODER = $(DIRLIB)\$(LIBWEBPDECODER_BASENAME)_dll.lib
 LIBWEBP = $(DIRLIB)\$(LIBWEBP_BASENAME)_dll.lib
 LIBWEBPMUX = $(DIRLIB)\$(LIBWEBPMUX_BASENAME)_dll.lib
 LIBWEBPDEMUX = $(DIRLIB)\$(LIBWEBPDEMUX_BASENAME)_dll.lib
+LIBSHARPYUV = $(DIRLIB)\$(LIBSHARPYUV_BASENAME)_dll.lib
 LIBWEBP_PDBNAME = $(DIROBJ)\$(LIBWEBP_BASENAME)_dll.pdb
 CFGSET = TRUE
 !ENDIF
@@ -174,6 +178,15 @@ CFLAGS = $(CFLAGS) /D_UNICODE /DUNICODE
 # A config was provided, so the library can be built.
 #
 
+SHARPYUV_OBJS = \
+    $(DIROBJ)\sharpyuv\sharpyuv.obj \
+    $(DIROBJ)\sharpyuv\sharpyuv_cpu.obj \
+    $(DIROBJ)\sharpyuv\sharpyuv_csp.obj \
+    $(DIROBJ)\sharpyuv\sharpyuv_dsp.obj \
+    $(DIROBJ)\sharpyuv\sharpyuv_gamma.obj \
+    $(DIROBJ)\sharpyuv\sharpyuv_neon.obj \
+    $(DIROBJ)\sharpyuv\sharpyuv_sse2.obj \
+
 DEC_OBJS = \
     $(DIROBJ)\dec\alpha_dec.obj \
     $(DIROBJ)\dec\buffer_dec.obj \
@@ -335,12 +348,13 @@ UTILS_ENC_OBJS = \
     $(DIROBJ)\utils\quant_levels_utils.obj \
 
 LIBWEBPDECODER_OBJS = $(DEC_OBJS) $(DSP_DEC_OBJS) $(UTILS_DEC_OBJS)
-LIBWEBP_OBJS = $(LIBWEBPDECODER_OBJS) $(ENC_OBJS) $(DSP_ENC_OBJS) \
-               $(UTILS_ENC_OBJS) $(DLL_OBJS)
+LIBWEBP_OBJS = $(LIBWEBPDECODER_OBJS) $(ENC_OBJS) \
+               $(DSP_ENC_OBJS) $(UTILS_ENC_OBJS) $(DLL_OBJS)
 LIBWEBPMUX_OBJS = $(MUX_OBJS) $(LIBWEBPMUX_OBJS)
 LIBWEBPDEMUX_OBJS = $(DEMUX_OBJS) $(LIBWEBPDEMUX_OBJS)
+LIBSHARPYUV_OBJS = $(SHARPYUV_OBJS)
 
-OUT_LIBS = $(LIBWEBPDECODER) $(LIBWEBP)
+OUT_LIBS = $(LIBWEBPDECODER) $(LIBWEBP) $(LIBSHARPYUV)
 !IF "$(ARCH)" == "ARM"
 ex: $(OUT_LIBS)
 all: ex
@@ -368,7 +382,7 @@ $(DIRBIN)\anim_dump.exe: $(EX_GIF_DEC_OBJS) $(LIBWEBPDEMUX) $(LIBWEBP)
 $(DIRBIN)\anim_dump.exe: $(IMAGEIO_ENC_OBJS)
 $(DIRBIN)\cwebp.exe: $(DIROBJ)\examples\cwebp.obj $(IMAGEIO_DEC_OBJS)
 $(DIRBIN)\cwebp.exe: $(IMAGEIO_UTIL_OBJS)
-$(DIRBIN)\cwebp.exe: $(LIBWEBPDEMUX)
+$(DIRBIN)\cwebp.exe: $(LIBWEBPDEMUX) $(LIBSHARPYUV)
 $(DIRBIN)\dwebp.exe: $(DIROBJ)\examples\dwebp.obj $(IMAGEIO_DEC_OBJS)
 $(DIRBIN)\dwebp.exe: $(IMAGEIO_ENC_OBJS)
 $(DIRBIN)\dwebp.exe: $(IMAGEIO_UTIL_OBJS)
@@ -386,7 +400,7 @@ $(DIRBIN)\webpmux.exe: $(EX_UTIL_OBJS) $(IMAGEIO_UTIL_OBJS) $(LIBWEBP)
 $(DIRBIN)\img2webp.exe: $(DIROBJ)\examples\img2webp.obj $(LIBWEBPMUX)
 $(DIRBIN)\img2webp.exe: $(IMAGEIO_DEC_OBJS)
 $(DIRBIN)\img2webp.exe: $(EX_UTIL_OBJS) $(IMAGEIO_UTIL_OBJS)
-$(DIRBIN)\img2webp.exe: $(LIBWEBPDEMUX) $(LIBWEBP)
+$(DIRBIN)\img2webp.exe: $(LIBWEBPDEMUX) $(LIBWEBP) $(LIBSHARPYUV)
 $(DIRBIN)\get_disto.exe: $(DIROBJ)\extras\get_disto.obj
 $(DIRBIN)\get_disto.exe: $(IMAGEIO_DEC_OBJS) $(IMAGEIO_UTIL_OBJS)
 $(DIRBIN)\get_disto.exe: $(LIBWEBPDEMUX) $(LIBWEBP)
@@ -409,17 +423,16 @@ $(EX_UTIL_OBJS) $(IMAGEIO_UTIL_OBJS): $(OUTPUT_DIRS)
 $(IMAGEIO_DEC_OBJS) $(IMAGEIO_ENC_OBJS) $(EXTRAS_OBJS): $(OUTPUT_DIRS)
 !ENDIF  # ARCH == ARM
 
+$(LIBSHARPYUV): $(LIBSHARPYUV_OBJS)
 $(LIBWEBPDECODER): $(LIBWEBPDECODER_OBJS)
-$(LIBWEBP): $(LIBWEBP_OBJS)
+$(LIBWEBP): $(LIBWEBP_OBJS) $(LIBSHARPYUV)
 $(LIBWEBPMUX): $(LIBWEBPMUX_OBJS)
 $(LIBWEBPDEMUX): $(LIBWEBPDEMUX_OBJS)
 
-$(LIBWEBP_OBJS) $(LIBWEBPMUX_OBJS) $(LIBWEBPDEMUX_OBJS): $(OUTPUT_DIRS)
+$(LIBWEBP_OBJS) $(LIBWEBPMUX_OBJS) $(LIBWEBPDEMUX_OBJS) $(LIBSHARPYUV_OBJS): \
+    $(OUTPUT_DIRS)
 
 !IF "$(DLLBUILD)" == "TRUE"
-$(LIBWEBP_OBJS) $(LIBWEBPMUX_OBJS) $(LIBWEBPDEMUX_OBJS): \
-    $(DIROBJ)\$(DLLINC)
-
 {$(DIROBJ)}.c{$(DIROBJ)}.obj:
 	$(CC) $(CFLAGS) /Fd$(LIBWEBP_PDBNAME) /Fo$@  $<
 
@@ -429,20 +442,20 @@ $(LIBWEBP_OBJS) $(LIBWEBPMUX_OBJS) $(LIBWEBPDEMUX_OBJS): \
 	$(RC) /fo$@ $<
 {src\mux}.rc{$(DIROBJ)\mux}.res:
 	$(RC) /fo$@ $<
+{sharpyuv}.rc{$(DIROBJ)\sharpyuv}.res:
+	$(RC) /fo$@ $<
 
-$(LIBWEBP): $(DIROBJ)\$(LIBWEBP_BASENAME:_debug=).res
+$(LIBSHARPYUV): $(DIROBJ)\sharpyuv\$(LIBSHARPYUV_BASENAME:_debug=).res
+$(LIBWEBP): $(LIBSHARPYUV) $(DIROBJ)\$(LIBWEBP_BASENAME:_debug=).res
 $(LIBWEBPDECODER): $(DIROBJ)\$(LIBWEBPDECODER_BASENAME:_debug=).res
 $(LIBWEBPMUX): $(LIBWEBP) $(DIROBJ)\mux\$(LIBWEBPMUX_BASENAME:_debug=).res
 $(LIBWEBPDEMUX): $(LIBWEBP) $(DIROBJ)\demux\$(LIBWEBPDEMUX_BASENAME:_debug=).res
 
-$(LIBWEBPDECODER) $(LIBWEBP) $(LIBWEBPMUX) $(LIBWEBPDEMUX):
+$(LIBWEBPDECODER) $(LIBWEBP) $(LIBWEBPMUX) $(LIBWEBPDEMUX) $(LIBSHARPYUV):
 	$(LNKDLL) /out:$(DIRBIN)\$(@B:_dll=.dll) /implib:$@ $(LFLAGS) $**
 	-xcopy $(DIROBJ)\*.pdb $(DIRLIB) /y
-
-clean::
-	@-erase /s $(DIROBJ)\$(DLLINC) 2> NUL
 !ELSE
-$(LIBWEBPDECODER) $(LIBWEBP) $(LIBWEBPMUX) $(LIBWEBPDEMUX):
+$(LIBWEBPDECODER) $(LIBWEBP) $(LIBWEBPMUX) $(LIBWEBPDEMUX) $(LIBSHARPYUV):
 	$(LNKLIB) /out:$@ $**
 	-xcopy $(DIROBJ)\*.pdb $(DIRLIB) /y
 !ENDIF
@@ -450,13 +463,6 @@ $(LIBWEBPDECODER) $(LIBWEBP) $(LIBWEBPMUX) $(LIBWEBPDEMUX):
 $(OUTPUT_DIRS):
 	@if not exist "$(@)" mkdir "$(@)"
 
-# generate a helper include to define WEBP_EXTERN suitable for the DLL build
-$(DIROBJ)\$(DLLINC):
-	@echo #ifndef WEBP_DLL_H_ > $@
-	@echo #define WEBP_DLL_H_ >> $@
-	@echo #define WEBP_EXTERN __declspec(dllexport) >> $@
-	@echo #endif  /* WEBP_DLL_H_ */ >> $@
-
 .SUFFIXES: .c .obj .res .exe
 # File-specific flag builds. Note batch rules take precedence over wildcards,
 # so for now name each file individually.
@@ -482,6 +488,8 @@ $(DIROBJ)\examples\gifdec.obj: examples\gifdec.c
 	$(CC) $(CFLAGS) /Fd$(DIROBJ)\extras\ /Fo$(DIROBJ)\extras\ $<
 {imageio}.c{$(DIROBJ)\imageio}.obj::
 	$(CC) $(CFLAGS) /Fd$(DIROBJ)\imageio\ /Fo$(DIROBJ)\imageio\ $<
+{sharpyuv}.c{$(DIROBJ)\sharpyuv}.obj::
+	$(CC) $(CFLAGS) /Fd$(DIROBJ)\sharpyuv\ /Fo$(DIROBJ)\sharpyuv\ $<
 {src\dec}.c{$(DIROBJ)\dec}.obj::
 	$(CC) $(CFLAGS) /Fd$(LIBWEBP_PDBNAME) /Fo$(DIROBJ)\dec\ $<
 {src\demux}.c{$(DIROBJ)\demux}.obj::
@@ -502,13 +510,9 @@ LNKLIBS     = $(LNKLIBS) Shell32.lib
 
 {$(DIROBJ)\examples}.obj{$(DIRBIN)}.exe:
 	$(LNKEXE) $(LDFLAGS) /OUT:$@ $** $(LNKLIBS)
-	$(MT) -manifest [email protected] -outputresource:$@;1
-	del [email protected]
 
 {$(DIROBJ)\extras}.obj{$(DIRBIN)}.exe:
 	$(LNKEXE) $(LDFLAGS) /OUT:$@ $** $(LNKLIBS)
-	$(MT) -manifest [email protected] -outputresource:$@;1
-	del [email protected]
 
 clean::
 	@-erase /s $(DIROBJ)\*.dll 2> NUL

+ 49 - 0
webp.mod/libwebp/NEWS

@@ -1,3 +1,52 @@
+- 9/13/2023: version 1.3.2
+  This is a binary compatible release.
+  * security fix for lossless decoder (chromium: #1479274, CVE-2023-4863)
+
+- 6/23/2023: version 1.3.1
+  This is a binary compatible release.
+  * security fixes for lossless encoder (#603, chromium: #1420107, #1455619,
+    CVE-2023-1999)
+  * improve error reporting through WebPPicture error codes
+  * fix upsampling for RGB565 and RGBA4444 in NEON builds
+  * img2webp: add -sharp_yuv & -near_lossless
+  * Windows builds:
+    - fix compatibility with clang-cl (#607)
+    - improve Arm64 performance with cl.exe
+    - add Arm64EC support
+  * fix webp_js with emcc >= 3.1.27 (stack size change, #614)
+  * CMake fixes (#592, #610, #612)
+  * further updates to the container and lossless bitstream docs (#581, #611)
+
+- 12/16/2022: version 1.3.0
+  This is a binary compatible release.
+  * add libsharpyuv, which exposes -sharp_yuv/config.use_sharp_yuv
+    functionality to other libraries; libwebp now depends on this library
+  * major updates to the container and lossless bitstream docs (#448, #546,
+    #551)
+  * miscellaneous warning, bug & build fixes (#576, #583, #584)
+
+- 8/4/2022: version 1.2.4
+  This is a binary compatible release.
+  * restore CMake libwebpmux target name for compatibility with 1.2.2 (#575)
+  * fix lossless crunch mode encoding with WEBP_REDUCE_SIZE
+    (chromium: #1345547, #1345595, #1345772, #1345804)
+
+- 6/30/2022: version 1.2.3
+  This is a binary compatible release.
+  * security fix for lossless encoder (#565, chromium:1313709)
+  * improved progress granularity in WebPReportProgress() when using lossless
+  * improved precision in Sharp YUV (-sharp_yuv) conversion
+  * many corrections to webp-lossless-bitstream-spec.txt (#551)
+  * crash/leak fixes on error/OOM and other bug fixes (#558, #563, #569, #573)
+
+- 1/11/2022: version 1.2.2
+  This is a binary compatible release.
+  * webpmux: add "-set bgcolor A,R,G,B"
+  * add ARM64 NEON support for MSVC builds (#539)
+  * fix duplicate include error in Xcode when using multiple XCFrameworks in a
+    project (#542)
+  * doc updates and bug fixes (#538, #544, #548, #550)
+
 - 7/20/2021: version 1.2.1
   This is a binary compatible release.
   * minor lossless encoder improvements and x86 color conversion speed up

+ 0 - 795
webp.mod/libwebp/README

@@ -1,795 +0,0 @@
-          __   __  ____  ____  ____
-         /  \\/  \/  _ \/  _ )/  _ \
-         \       /   __/  _  \   __/
-          \__\__/\____/\_____/__/ ____  ___
-                / _/ /    \    \ /  _ \/ _/
-               /  \_/   / /   \ \   __/  \__
-               \____/____/\_____/_____/____/v1.2.1
-
-Description:
-============
-
-WebP codec: library to encode and decode images in WebP format. This package
-contains the library that can be used in other programs to add WebP support,
-as well as the command line tools 'cwebp' and 'dwebp'.
-
-See https://developers.google.com/speed/webp
-
-The latest source tree is available at
-https://chromium.googlesource.com/webm/libwebp
-
-It is released under the same license as the WebM project.
-See https://www.webmproject.org/license/software/ or the
-"COPYING" file for details. An additional intellectual
-property rights grant can be found in the file PATENTS.
-
-Building:
-=========
-
-Windows build:
---------------
-
-By running:
-
-  nmake /f Makefile.vc CFG=release-static RTLIBCFG=static OBJDIR=output
-
-the directory output\release-static\(x64|x86)\bin will contain the tools
-cwebp.exe and dwebp.exe. The directory output\release-static\(x64|x86)\lib will
-contain the libwebp static library.
-The target architecture (x86/x64) is detected by Makefile.vc from the Visual
-Studio compiler (cl.exe) available in the system path.
-
-Unix build using makefile.unix:
--------------------------------
-
-On platforms with GNU tools installed (gcc and make), running
-
-  make -f makefile.unix
-
-will build the binaries examples/cwebp and examples/dwebp, along
-with the static library src/libwebp.a. No system-wide installation
-is supplied, as this is a simple alternative to the full installation
-system based on the autoconf tools (see below).
-Please refer to makefile.unix for additional details and customizations.
-
-Using autoconf tools:
----------------------
-Prerequisites:
-A compiler (e.g., gcc), make, autoconf, automake, libtool.
-On a Debian-like system the following should install everything you need for a
-minimal build:
-$ sudo apt-get install gcc make autoconf automake libtool
-
-When building from git sources, you will need to run autogen.sh to generate the
-configure script.
-
-./configure
-make
-make install
-
-should be all you need to have the following files
-
-/usr/local/include/webp/decode.h
-/usr/local/include/webp/encode.h
-/usr/local/include/webp/types.h
-/usr/local/lib/libwebp.*
-/usr/local/bin/cwebp
-/usr/local/bin/dwebp
-
-installed.
-
-Note: A decode-only library, libwebpdecoder, is available using the
-'--enable-libwebpdecoder' flag. The encode library is built separately and can
-be installed independently using a minor modification in the corresponding
-Makefile.am configure files (see comments there). See './configure --help' for
-more options.
-
-Building for MIPS Linux:
-------------------------
-MIPS Linux toolchain stable available releases can be found at:
-https://community.imgtec.com/developers/mips/tools/codescape-mips-sdk/available-releases/
-
-# Add toolchain to PATH
-export PATH=$PATH:/path/to/toolchain/bin
-
-# 32-bit build for mips32r5 (p5600)
-HOST=mips-mti-linux-gnu
-MIPS_CFLAGS="-O3 -mips32r5 -mabi=32 -mtune=p5600 -mmsa -mfp64 \
-  -msched-weight -mload-store-pairs -fPIE"
-MIPS_LDFLAGS="-mips32r5 -mabi=32 -mmsa -mfp64 -pie"
-
-# 64-bit build for mips64r6 (i6400)
-HOST=mips-img-linux-gnu
-MIPS_CFLAGS="-O3 -mips64r6 -mabi=64 -mtune=i6400 -mmsa -mfp64 \
-  -msched-weight -mload-store-pairs -fPIE"
-MIPS_LDFLAGS="-mips64r6 -mabi=64 -mmsa -mfp64 -pie"
-
-./configure --host=${HOST} --build=`config.guess` \
-  CC="${HOST}-gcc -EL" \
-  CFLAGS="$MIPS_CFLAGS" \
-  LDFLAGS="$MIPS_LDFLAGS"
-make
-make install
-
-CMake:
-------
-With CMake, you can compile libwebp, cwebp, dwebp, gif2webp, img2webp, webpinfo
-and the JS bindings.
-
-Prerequisites:
-A compiler (e.g., gcc with autotools) and CMake.
-On a Debian-like system the following should install everything you need for a
-minimal build:
-$ sudo apt-get install build-essential cmake
-
-When building from git sources, you will need to run cmake to generate the
-makefiles.
-
-mkdir build && cd build && cmake ../
-make
-make install
-
-If you also want any of the executables, you will need to enable them through
-CMake, e.g.:
-
-cmake -DWEBP_BUILD_CWEBP=ON -DWEBP_BUILD_DWEBP=ON ../
-
-or through your favorite interface (like ccmake or cmake-qt-gui).
-
-Use option -DWEBP_UNICODE=ON for Unicode support on Windows (with chcp 65001).
-
-Finally, once installed, you can also use WebP in your CMake project by doing:
-
-find_package(WebP)
-
-which will define the CMake variables WebP_INCLUDE_DIRS and WebP_LIBRARIES.
-
-Gradle:
--------
-The support for Gradle is minimal: it only helps you compile libwebp, cwebp and
-dwebp and webpmux_example.
-
-Prerequisites:
-A compiler (e.g., gcc with autotools) and gradle.
-On a Debian-like system the following should install everything you need for a
-minimal build:
-$ sudo apt-get install build-essential gradle
-
-When building from git sources, you will need to run the Gradle wrapper with the
-appropriate target, e.g. :
-
-./gradlew buildAllExecutables
-
-SWIG bindings:
---------------
-
-To generate language bindings from swig/libwebp.swig at least swig-1.3
-(http://www.swig.org) is required.
-
-Currently the following functions are mapped:
-Decode:
-  WebPGetDecoderVersion
-  WebPGetInfo
-  WebPDecodeRGBA
-  WebPDecodeARGB
-  WebPDecodeBGRA
-  WebPDecodeBGR
-  WebPDecodeRGB
-
-Encode:
-  WebPGetEncoderVersion
-  WebPEncodeRGBA
-  WebPEncodeBGRA
-  WebPEncodeRGB
-  WebPEncodeBGR
-  WebPEncodeLosslessRGBA
-  WebPEncodeLosslessBGRA
-  WebPEncodeLosslessRGB
-  WebPEncodeLosslessBGR
-
-See swig/README for more detailed build instructions.
-
-Java bindings:
-
-To build the swig-generated JNI wrapper code at least JDK-1.5 (or equivalent)
-is necessary for enum support. The output is intended to be a shared object /
-DLL that can be loaded via System.loadLibrary("webp_jni").
-
-Python bindings:
-
-To build the swig-generated Python extension code at least Python 2.6 is
-required. Python < 2.6 may build with some minor changes to libwebp.swig or the
-generated code, but is untested.
-
-Encoding tool:
-==============
-
-The examples/ directory contains tools for encoding (cwebp) and
-decoding (dwebp) images.
-
-The easiest use should look like:
-  cwebp input.png -q 80 -o output.webp
-which will convert the input file to a WebP file using a quality factor of 80
-on a 0->100 scale (0 being the lowest quality, 100 being the best. Default
-value is 75).
-You might want to try the -lossless flag too, which will compress the source
-(in RGBA format) without any loss. The -q quality parameter will in this case
-control the amount of processing time spent trying to make the output file as
-small as possible.
-
-A longer list of options is available using the -longhelp command line flag:
-
-> cwebp -longhelp
-Usage:
- cwebp [-preset <...>] [options] in_file [-o out_file]
-
-If input size (-s) for an image is not specified, it is
-assumed to be a PNG, JPEG, TIFF or WebP file.
-Note: Animated PNG and WebP files are not supported.
-
-Options:
-  -h / -help ............. short help
-  -H / -longhelp ......... long help
-  -q <float> ............. quality factor (0:small..100:big), default=75
-  -alpha_q <int> ......... transparency-compression quality (0..100),
-                           default=100
-  -preset <string> ....... preset setting, one of:
-                            default, photo, picture,
-                            drawing, icon, text
-     -preset must come first, as it overwrites other parameters
-  -z <int> ............... activates lossless preset with given
-                           level in [0:fast, ..., 9:slowest]
-
-  -m <int> ............... compression method (0=fast, 6=slowest), default=4
-  -segments <int> ........ number of segments to use (1..4), default=4
-  -size <int> ............ target size (in bytes)
-  -psnr <float> .......... target PSNR (in dB. typically: 42)
-
-  -s <int> <int> ......... input size (width x height) for YUV
-  -sns <int> ............. spatial noise shaping (0:off, 100:max), default=50
-  -f <int> ............... filter strength (0=off..100), default=60
-  -sharpness <int> ....... filter sharpness (0:most .. 7:least sharp), default=0
-  -strong ................ use strong filter instead of simple (default)
-  -nostrong .............. use simple filter instead of strong
-  -sharp_yuv ............. use sharper (and slower) RGB->YUV conversion
-  -partition_limit <int> . limit quality to fit the 512k limit on
-                           the first partition (0=no degradation ... 100=full)
-  -pass <int> ............ analysis pass number (1..10)
-  -qrange <min> <max> .... specifies the permissible quality range
-                           (default: 0 100)
-  -crop <x> <y> <w> <h> .. crop picture with the given rectangle
-  -resize <w> <h> ........ resize picture (after any cropping)
-  -mt .................... use multi-threading if available
-  -low_memory ............ reduce memory usage (slower encoding)
-  -map <int> ............. print map of extra info
-  -print_psnr ............ prints averaged PSNR distortion
-  -print_ssim ............ prints averaged SSIM distortion
-  -print_lsim ............ prints local-similarity distortion
-  -d <file.pgm> .......... dump the compressed output (PGM file)
-  -alpha_method <int> .... transparency-compression method (0..1), default=1
-  -alpha_filter <string> . predictive filtering for alpha plane,
-                           one of: none, fast (default) or best
-  -exact ................. preserve RGB values in transparent area, default=off
-  -blend_alpha <hex> ..... blend colors against background color
-                           expressed as RGB values written in
-                           hexadecimal, e.g. 0xc0e0d0 for red=0xc0
-                           green=0xe0 and blue=0xd0
-  -noalpha ............... discard any transparency information
-  -lossless .............. encode image losslessly, default=off
-  -near_lossless <int> ... use near-lossless image
-                           preprocessing (0..100=off), default=100
-  -hint <string> ......... specify image characteristics hint,
-                           one of: photo, picture or graph
-
-  -metadata <string> ..... comma separated list of metadata to
-                           copy from the input to the output if present.
-                           Valid values: all, none (default), exif, icc, xmp
-
-  -short ................. condense printed message
-  -quiet ................. don't print anything
-  -version ............... print version number and exit
-  -noasm ................. disable all assembly optimizations
-  -v ..................... verbose, e.g. print encoding/decoding times
-  -progress .............. report encoding progress
-
-Experimental Options:
-  -jpeg_like ............. roughly match expected JPEG size
-  -af .................... auto-adjust filter strength
-  -pre <int> ............. pre-processing filter
-
-
-The main options you might want to try in order to further tune the
-visual quality are:
- -preset
- -sns
- -f
- -m
-
-Namely:
-  * 'preset' will set up a default encoding configuration targeting a
-     particular type of input. It should appear first in the list of options,
-     so that subsequent options can take effect on top of this preset.
-     Default value is 'default'.
-  * 'sns' will progressively turn on (when going from 0 to 100) some additional
-     visual optimizations (like: segmentation map re-enforcement). This option
-     will balance the bit allocation differently. It tries to take bits from the
-     "easy" parts of the picture and use them in the "difficult" ones instead.
-     Usually, raising the sns value (at fixed -q value) leads to larger files,
-     but with better quality.
-     Typical value is around '75'.
-  * 'f' option directly links to the filtering strength used by the codec's
-     in-loop processing. The higher the value, the smoother the
-     highly-compressed area will look. This is particularly useful when aiming
-     at very small files. Typical values are around 20-30. Note that using the
-     option -strong/-nostrong will change the type of filtering. Use "-f 0" to
-     turn filtering off.
-  * 'm' controls the trade-off between encoding speed and quality. Default is 4.
-     You can try -m 5 or -m 6 to explore more (time-consuming) encoding
-     possibilities. A lower value will result in faster encoding at the expense
-     of quality.
-
-Decoding tool:
-==============
-
-There is a decoding sample in examples/dwebp.c which will take
-a .webp file and decode it to a PNG image file (amongst other formats).
-This is simply to demonstrate the use of the API. You can verify the
-file test.webp decodes to exactly the same as test_ref.ppm by using:
-
- cd examples
- ./dwebp test.webp -ppm -o test.ppm
- diff test.ppm test_ref.ppm
-
-The full list of options is available using -h:
-
-> dwebp -h
-Usage: dwebp in_file [options] [-o out_file]
-
-Decodes the WebP image file to PNG format [Default].
-Note: Animated WebP files are not supported.
-
-Use following options to convert into alternate image formats:
-  -pam ......... save the raw RGBA samples as a color PAM
-  -ppm ......... save the raw RGB samples as a color PPM
-  -bmp ......... save as uncompressed BMP format
-  -tiff ........ save as uncompressed TIFF format
-  -pgm ......... save the raw YUV samples as a grayscale PGM
-                 file with IMC4 layout
-  -yuv ......... save the raw YUV samples in flat layout
-
- Other options are:
-  -version ..... print version number and exit
-  -nofancy ..... don't use the fancy YUV420 upscaler
-  -nofilter .... disable in-loop filtering
-  -nodither .... disable dithering
-  -dither <d> .. dithering strength (in 0..100)
-  -alpha_dither  use alpha-plane dithering if needed
-  -mt .......... use multi-threading
-  -crop <x> <y> <w> <h> ... crop output with the given rectangle
-  -resize <w> <h> ......... scale the output (*after* any cropping)
-  -flip ........ flip the output vertically
-  -alpha ....... only save the alpha plane
-  -incremental . use incremental decoding (useful for tests)
-  -h ........... this help message
-  -v ........... verbose (e.g. print encoding/decoding times)
-  -quiet ....... quiet mode, don't print anything
-  -noasm ....... disable all assembly optimizations
-
-WebP file analysis tool:
-========================
-
-'webpinfo' can be used to print out the chunk level structure and bitstream
-header information of WebP files. It can also check if the files are of valid
-WebP format.
-
-Usage: webpinfo [options] in_files
-Note: there could be multiple input files;
-      options must come before input files.
-Options:
-  -version ........... Print version number and exit.
-  -quiet ............. Do not show chunk parsing information.
-  -diag .............. Show parsing error diagnosis.
-  -summary ........... Show chunk stats summary.
-  -bitstream_info .... Parse bitstream header.
-
-Visualization tool:
-===================
-
-There's a little self-serve visualization tool called 'vwebp' under the
-examples/ directory. It uses OpenGL to open a simple drawing window and show
-a decoded WebP file. It's not yet integrated in the automake build system, but
-you can try to manually compile it using the recommendations below.
-
-Usage: vwebp in_file [options]
-
-Decodes the WebP image file and visualize it using OpenGL
-Options are:
-  -version ..... print version number and exit
-  -noicc ....... don't use the icc profile if present
-  -nofancy ..... don't use the fancy YUV420 upscaler
-  -nofilter .... disable in-loop filtering
-  -dither <int>  dithering strength (0..100), default=50
-  -noalphadither disable alpha plane dithering
-  -usebgcolor .. display background color
-  -mt .......... use multi-threading
-  -info ........ print info
-  -h ........... this help message
-
-Keyboard shortcuts:
-  'c' ................ toggle use of color profile
-  'b' ................ toggle background color display
-  'i' ................ overlay file information
-  'd' ................ disable blending & disposal (debug)
-  'q' / 'Q' / ESC .... quit
-
-Building:
----------
-
-Prerequisites:
-1) OpenGL & OpenGL Utility Toolkit (GLUT)
-  Linux:
-    $ sudo apt-get install freeglut3-dev mesa-common-dev
-  Mac + Xcode:
-    - These libraries should be available in the OpenGL / GLUT frameworks.
-  Windows:
-    http://freeglut.sourceforge.net/index.php#download
-
-2) (Optional) qcms (Quick Color Management System)
-  i. Download qcms from Mozilla / Chromium:
-    https://hg.mozilla.org/mozilla-central/file/0e7639e3bdfb/gfx/qcms
-    https://source.chromium.org/chromium/chromium/src/+/main:third_party/qcms/;drc=d4a2f8e1ed461d8fc05ed88d1ae2dc94c9773825
-  ii. Build and archive the source files as libqcms.a / qcms.lib
-  iii. Update makefile.unix / Makefile.vc
-    a) Define WEBP_HAVE_QCMS
-    b) Update include / library paths to reference the qcms directory.
-
-Build using makefile.unix / Makefile.vc:
-$ make -f makefile.unix examples/vwebp
-> nmake /f Makefile.vc CFG=release-static \
-    ../obj/x64/release-static/bin/vwebp.exe
-
-Animation creation tool:
-========================
-The utility 'img2webp' can turn a sequence of input images (PNG, JPEG, ...)
-into an animated WebP file. It offers fine control over duration, encoding
-modes, etc.
-
-Usage:
-
-  img2webp [file_options] [[frame_options] frame_file]...
-
-File-level options (only used at the start of compression):
- -min_size ............ minimize size
- -loop <int> .......... loop count (default: 0, = infinite loop)
- -kmax <int> .......... maximum number of frame between key-frames
-                        (0=only keyframes)
- -kmin <int> .......... minimum number of frame between key-frames
-                        (0=disable key-frames altogether)
- -mixed ............... use mixed lossy/lossless automatic mode
- -v ................... verbose mode
- -h ................... this help
- -version ............. print version number and exit
-
-Per-frame options (only used for subsequent images input):
- -d <int> ............. frame duration in ms (default: 100)
- -lossless  ........... use lossless mode (default)
- -lossy ... ........... use lossy mode
- -q <float> ........... quality
- -m <int> ............. method to use
-
-example: img2webp -loop 2 in0.png -lossy in1.jpg
-                  -d 80 in2.tiff -o out.webp
-
-Note: if a single file name is passed as the argument, the arguments will be
-tokenized from this file. The file name must not start with the character '-'.
-
-Animated GIF conversion:
-========================
-Animated GIF files can be converted to WebP files with animation using the
-gif2webp utility available under examples/. The files can then be viewed using
-vwebp.
-
-Usage:
- gif2webp [options] gif_file -o webp_file
-Options:
-  -h / -help ............. this help
-  -lossy ................. encode image using lossy compression
-  -mixed ................. for each frame in the image, pick lossy
-                           or lossless compression heuristically
-  -q <float> ............. quality factor (0:small..100:big)
-  -m <int> ............... compression method (0=fast, 6=slowest)
-  -min_size .............. minimize output size (default:off)
-                           lossless compression by default; can be
-                           combined with -q, -m, -lossy or -mixed
-                           options
-  -kmin <int> ............ min distance between key frames
-  -kmax <int> ............ max distance between key frames
-  -f <int> ............... filter strength (0=off..100)
-  -metadata <string> ..... comma separated list of metadata to
-                           copy from the input to the output if present
-                           Valid values: all, none, icc, xmp (default)
-  -loop_compatibility .... use compatibility mode for Chrome
-                           version prior to M62 (inclusive)
-  -mt .................... use multi-threading if available
-
-  -version ............... print version number and exit
-  -v ..................... verbose
-  -quiet ................. don't print anything
-
-Building:
----------
-With the libgif development files installed, gif2webp can be built using
-makefile.unix:
-$ make -f makefile.unix examples/gif2webp
-
-or using autoconf:
-$ ./configure --enable-everything
-$ make
-
-Comparison of animated images:
-==============================
-Test utility anim_diff under examples/ can be used to compare two animated
-images (each can be GIF or WebP).
-
-Usage: anim_diff <image1> <image2> [options]
-
-Options:
-  -dump_frames <folder> dump decoded frames in PAM format
-  -min_psnr <float> ... minimum per-frame PSNR
-  -raw_comparison ..... if this flag is not used, RGB is
-                        premultiplied before comparison
-  -max_diff <int> ..... maximum allowed difference per channel
-                        between corresponding pixels in subsequent
-                        frames
-  -h .................. this help
-  -version ............ print version number and exit
-
-Building:
----------
-With the libgif development files and a C++ compiler installed, anim_diff can
-be built using makefile.unix:
-$ make -f makefile.unix examples/anim_diff
-
-or using autoconf:
-$ ./configure --enable-everything
-$ make
-
-Encoding API:
-=============
-
-The main encoding functions are available in the header src/webp/encode.h
-The ready-to-use ones are:
-size_t WebPEncodeRGB(const uint8_t* rgb, int width, int height, int stride,
-                     float quality_factor, uint8_t** output);
-size_t WebPEncodeBGR(const uint8_t* bgr, int width, int height, int stride,
-                     float quality_factor, uint8_t** output);
-size_t WebPEncodeRGBA(const uint8_t* rgba, int width, int height, int stride,
-                      float quality_factor, uint8_t** output);
-size_t WebPEncodeBGRA(const uint8_t* bgra, int width, int height, int stride,
-                      float quality_factor, uint8_t** output);
-
-They will convert raw RGB samples to a WebP data. The only control supplied
-is the quality factor.
-
-There are some variants for using the lossless format:
-
-size_t WebPEncodeLosslessRGB(const uint8_t* rgb, int width, int height,
-                             int stride, uint8_t** output);
-size_t WebPEncodeLosslessBGR(const uint8_t* bgr, int width, int height,
-                             int stride, uint8_t** output);
-size_t WebPEncodeLosslessRGBA(const uint8_t* rgba, int width, int height,
-                              int stride, uint8_t** output);
-size_t WebPEncodeLosslessBGRA(const uint8_t* bgra, int width, int height,
-                              int stride, uint8_t** output);
-
-Of course in this case, no quality factor is needed since the compression
-occurs without loss of the input values, at the expense of larger output sizes.
-
-Advanced encoding API:
-----------------------
-
-A more advanced API is based on the WebPConfig and WebPPicture structures.
-
-WebPConfig contains the encoding settings and is not tied to a particular
-picture.
-WebPPicture contains input data, on which some WebPConfig will be used for
-compression.
-The encoding flow looks like:
-
--------------------------------------- BEGIN PSEUDO EXAMPLE
-
-#include <webp/encode.h>
-
-  // Setup a config, starting form a preset and tuning some additional
-  // parameters
-  WebPConfig config;
-  if (!WebPConfigPreset(&config, WEBP_PRESET_PHOTO, quality_factor)) {
-    return 0;   // version error
-  }
-  // ... additional tuning
-  config.sns_strength = 90;
-  config.filter_sharpness = 6;
-  config_error = WebPValidateConfig(&config);  // not mandatory, but useful
-
-  // Setup the input data
-  WebPPicture pic;
-  if (!WebPPictureInit(&pic)) {
-    return 0;  // version error
-  }
-  pic.width = width;
-  pic.height = height;
-  // allocated picture of dimension width x height
-  if (!WebPPictureAlloc(&pic)) {
-    return 0;   // memory error
-  }
-  // at this point, 'pic' has been initialized as a container,
-  // and can receive the Y/U/V samples.
-  // Alternatively, one could use ready-made import functions like
-  // WebPPictureImportRGB(), which will take care of memory allocation.
-  // In any case, past this point, one will have to call
-  // WebPPictureFree(&pic) to reclaim memory.
-
-  // Set up a byte-output write method. WebPMemoryWriter, for instance.
-  WebPMemoryWriter wrt;
-  WebPMemoryWriterInit(&wrt);     // initialize 'wrt'
-
-  pic.writer = MyFileWriter;
-  pic.custom_ptr = my_opaque_structure_to_make_MyFileWriter_work;
-
-  // Compress!
-  int ok = WebPEncode(&config, &pic);   // ok = 0 => error occurred!
-  WebPPictureFree(&pic);  // must be called independently of the 'ok' result.
-
-  // output data should have been handled by the writer at that point.
-  // -> compressed data is the memory buffer described by wrt.mem / wrt.size
-
-  // deallocate the memory used by compressed data
-  WebPMemoryWriterClear(&wrt);
-
--------------------------------------- END PSEUDO EXAMPLE
-
-Decoding API:
-=============
-
-This is mainly just one function to call:
-
-#include "webp/decode.h"
-uint8_t* WebPDecodeRGB(const uint8_t* data, size_t data_size,
-                       int* width, int* height);
-
-Please have a look at the file src/webp/decode.h for the details.
-There are variants for decoding in BGR/RGBA/ARGB/BGRA order, along with
-decoding to raw Y'CbCr samples. One can also decode the image directly into a
-pre-allocated buffer.
-
-To detect a WebP file and gather the picture's dimensions, the function:
-  int WebPGetInfo(const uint8_t* data, size_t data_size,
-                  int* width, int* height);
-is supplied. No decoding is involved when using it.
-
-Incremental decoding API:
-=========================
-
-In the case when data is being progressively transmitted, pictures can still
-be incrementally decoded using a slightly more complicated API. Decoder state
-is stored into an instance of the WebPIDecoder object. This object can be
-created with the purpose of decoding either RGB or Y'CbCr samples.
-For instance:
-
-  WebPDecBuffer buffer;
-  WebPInitDecBuffer(&buffer);
-  buffer.colorspace = MODE_BGR;
-  ...
-  WebPIDecoder* idec = WebPINewDecoder(&buffer);
-
-As data is made progressively available, this incremental-decoder object
-can be used to decode the picture further. There are two (mutually exclusive)
-ways to pass freshly arrived data:
-
-either by appending the fresh bytes:
-
-  WebPIAppend(idec, fresh_data, size_of_fresh_data);
-
-or by just mentioning the new size of the transmitted data:
-
-  WebPIUpdate(idec, buffer, size_of_transmitted_buffer);
-
-Note that 'buffer' can be modified between each call to WebPIUpdate, in
-particular when the buffer is resized to accommodate larger data.
-
-These functions will return the decoding status: either VP8_STATUS_SUSPENDED if
-decoding is not finished yet or VP8_STATUS_OK when decoding is done. Any other
-status is an error condition.
-
-The 'idec' object must always be released (even upon an error condition) by
-calling: WebPDelete(idec).
-
-To retrieve partially decoded picture samples, one must use the corresponding
-method: WebPIDecGetRGB or WebPIDecGetYUVA.
-It will return the last displayable pixel row.
-
-Lastly, note that decoding can also be performed into a pre-allocated pixel
-buffer. This buffer must be passed when creating a WebPIDecoder, calling
-WebPINewRGB() or WebPINewYUVA().
-
-Please have a look at the src/webp/decode.h header for further details.
-
-Advanced Decoding API:
-======================
-
-WebP decoding supports an advanced API which provides on-the-fly cropping and
-rescaling, something of great usefulness on memory-constrained environments like
-mobile phones. Basically, the memory usage will scale with the output's size,
-not the input's, when one only needs a quick preview or a zoomed in portion of
-an otherwise too-large picture. Some CPU can be saved too, incidentally.
-
--------------------------------------- BEGIN PSEUDO EXAMPLE
-     // A) Init a configuration object
-     WebPDecoderConfig config;
-     CHECK(WebPInitDecoderConfig(&config));
-
-     // B) optional: retrieve the bitstream's features.
-     CHECK(WebPGetFeatures(data, data_size, &config.input) == VP8_STATUS_OK);
-
-     // C) Adjust 'config' options, if needed
-     config.options.no_fancy_upsampling = 1;
-     config.options.use_scaling = 1;
-     config.options.scaled_width = scaledWidth();
-     config.options.scaled_height = scaledHeight();
-     // etc.
-
-     // D) Specify 'config' output options for specifying output colorspace.
-     // Optionally the external image decode buffer can also be specified.
-     config.output.colorspace = MODE_BGRA;
-     // Optionally, the config.output can be pointed to an external buffer as
-     // well for decoding the image. This externally supplied memory buffer
-     // should be big enough to store the decoded picture.
-     config.output.u.RGBA.rgba = (uint8_t*) memory_buffer;
-     config.output.u.RGBA.stride = scanline_stride;
-     config.output.u.RGBA.size = total_size_of_the_memory_buffer;
-     config.output.is_external_memory = 1;
-
-     // E) Decode the WebP image. There are two variants w.r.t decoding image.
-     // The first one (E.1) decodes the full image and the second one (E.2) is
-     // used to incrementally decode the image using small input buffers.
-     // Any one of these steps can be used to decode the WebP image.
-
-     // E.1) Decode full image.
-     CHECK(WebPDecode(data, data_size, &config) == VP8_STATUS_OK);
-
-     // E.2) Decode image incrementally.
-     WebPIDecoder* const idec = WebPIDecode(NULL, NULL, &config);
-     CHECK(idec != NULL);
-     while (bytes_remaining > 0) {
-       VP8StatusCode status = WebPIAppend(idec, input, bytes_read);
-       if (status == VP8_STATUS_OK || status == VP8_STATUS_SUSPENDED) {
-         bytes_remaining -= bytes_read;
-       } else {
-         break;
-       }
-     }
-     WebPIDelete(idec);
-
-     // F) Decoded image is now in config.output (and config.output.u.RGBA).
-     // It can be saved, displayed or otherwise processed.
-
-     // G) Reclaim memory allocated in config's object. It's safe to call
-     // this function even if the memory is external and wasn't allocated
-     // by WebPDecode().
-     WebPFreeDecBuffer(&config.output);
-
--------------------------------------- END PSEUDO EXAMPLE
-
-Bugs:
-=====
-
-Please report all bugs to the issue tracker:
-    https://bugs.chromium.org/p/webp
-Patches welcome! See this page to get started:
-    https://www.webmproject.org/code/contribute/submitting-patches/
-
-Discuss:
-========
-
-Email: [email protected]
-Web: https://groups.google.com/a/webmproject.org/group/webp-discuss

+ 53 - 0
webp.mod/libwebp/README.md

@@ -0,0 +1,53 @@
+# WebP Codec
+
+```
+      __   __  ____  ____  ____
+     /  \\/  \/  _ \/  _ )/  _ \
+     \       /   __/  _  \   __/
+      \__\__/\____/\_____/__/ ____  ___
+            / _/ /    \    \ /  _ \/ _/
+           /  \_/   / /   \ \   __/  \__
+           \____/____/\_____/_____/____/v1.3.2
+```
+
+WebP codec is a library to encode and decode images in WebP format. This package
+contains the library that can be used in other programs to add WebP support, as
+well as the command line tools 'cwebp' and 'dwebp' to compress and decompress
+images respectively.
+
+See https://developers.google.com/speed/webp for details on the image format.
+
+The latest source tree is available at
+https://chromium.googlesource.com/webm/libwebp
+
+It is released under the same license as the WebM project. See
+https://www.webmproject.org/license/software/ or the "COPYING" file for details.
+An additional intellectual property rights grant can be found in the file
+PATENTS.
+
+## Building
+
+See the [building documentation](doc/building.md).
+
+## Encoding and Decoding Tools
+
+The examples/ directory contains tools to encode and decode images and
+animations, view information about WebP images, and more. See the
+[tools documentation](doc/tools.md).
+
+## APIs
+
+See the [APIs documentation](doc/api.md), and API usage examples in the
+`examples/` directory.
+
+## Bugs
+
+Please report all bugs to the issue tracker: https://bugs.chromium.org/p/webp
+
+Patches welcome! See [how to contribute](CONTRIBUTING.md).
+
+## Discuss
+
+Email: [email protected]
+
+Web: https://groups.google.com/a/webmproject.org/group/webp-discuss

+ 0 - 258
webp.mod/libwebp/README.mux

@@ -1,258 +0,0 @@
-          __   __  ____  ____  ____  __ __  _     __ __
-         /  \\/  \/  _ \/  _ \/  _ \/  \  \/ \___/_ / _\
-         \       /   __/  _  \   __/      /  /  (_/  /__
-          \__\__/\_____/_____/__/  \__//_/\_____/__/___/v1.2.1
-
-
-Description:
-============
-
-WebPMux: set of two libraries 'Mux' and 'Demux' for creation, extraction and
-manipulation of an extended format WebP file, which can have features like
-color profile, metadata and animation. Reference command-line tools 'webpmux'
-and 'vwebp' as well as the WebP container specification
-'doc/webp-container-spec.txt' are also provided in this package.
-
-WebP Mux tool:
-==============
-
-The examples/ directory contains a tool (webpmux) for manipulating WebP
-files. The webpmux tool can be used to create an extended format WebP file and
-also to extract or strip relevant data from such a file.
-
-A list of options is available using the -help command line flag:
-
-> webpmux -help
-Usage: webpmux -get GET_OPTIONS INPUT -o OUTPUT
-       webpmux -set SET_OPTIONS INPUT -o OUTPUT
-       webpmux -duration DURATION_OPTIONS [-duration ...]
-               INPUT -o OUTPUT
-       webpmux -strip STRIP_OPTIONS INPUT -o OUTPUT
-       webpmux -frame FRAME_OPTIONS [-frame...] [-loop LOOP_COUNT]
-               [-bgcolor BACKGROUND_COLOR] -o OUTPUT
-       webpmux -info INPUT
-       webpmux [-h|-help]
-       webpmux -version
-       webpmux argument_file_name
-
-GET_OPTIONS:
- Extract relevant data:
-   icc       get ICC profile
-   exif      get EXIF metadata
-   xmp       get XMP metadata
-   frame n   get nth frame
-
-SET_OPTIONS:
- Set color profile/metadata/parameters:
-   loop LOOP_COUNT            set the loop count
-   bgcolor BACKGROUND_COLOR   set the animation background color
-   icc  file.icc              set ICC profile
-   exif file.exif             set EXIF metadata
-   xmp  file.xmp              set XMP metadata
-   where:    'file.icc' contains the ICC profile to be set,
-             'file.exif' contains the EXIF metadata to be set
-             'file.xmp' contains the XMP metadata to be set
-
-DURATION_OPTIONS:
- Set duration of selected frames:
-   duration            set duration for each frames
-   duration,frame      set duration of a particular frame
-   duration,start,end  set duration of frames in the
-                        interval [start,end])
-   where: 'duration' is the duration in milliseconds
-          'start' is the start frame index
-          'end' is the inclusive end frame index
-           The special 'end' value '0' means: last frame.
-
-STRIP_OPTIONS:
- Strip color profile/metadata:
-   icc       strip ICC profile
-   exif      strip EXIF metadata
-   xmp       strip XMP metadata
-
-FRAME_OPTIONS(i):
- Create animation:
-   file_i +di+[xi+yi[+mi[bi]]]
-   where:    'file_i' is the i'th animation frame (WebP format),
-             'di' is the pause duration before next frame,
-             'xi','yi' specify the image offset for this frame,
-             'mi' is the dispose method for this frame (0 or 1),
-             'bi' is the blending method for this frame (+b or -b)
-
-LOOP_COUNT:
- Number of times to repeat the animation.
- Valid range is 0 to 65535 [Default: 0 (infinite)].
-
-BACKGROUND_COLOR:
- Background color of the canvas.
-  A,R,G,B
-  where:    'A', 'R', 'G' and 'B' are integers in the range 0 to 255 specifying
-            the Alpha, Red, Green and Blue component values respectively
-            [Default: 255,255,255,255]
-
-INPUT & OUTPUT are in WebP format.
-
-Note: The nature of EXIF, XMP and ICC data is not checked and is assumed to be
-valid.
-
-Note: if a single file name is passed as the argument, the arguments will be
-tokenized from this file. The file name must not start with the character '-'.
-
-Visualization tool:
-===================
-
-The examples/ directory also contains a tool (vwebp) for viewing WebP files.
-It decodes the image and visualizes it using OpenGL. See the libwebp README
-for details on building and running this program.
-
-Mux API:
-========
-The Mux API contains methods for adding data to and reading data from WebP
-files. This API currently supports XMP/EXIF metadata, ICC profile and animation.
-Other features may be added in subsequent releases.
-
-Example#1 (pseudo code): Creating a WebPMux object with image data, color
-profile and XMP metadata.
-
-  int copy_data = 0;
-  WebPMux* mux = WebPMuxNew();
-  // ... (Prepare image data).
-  WebPMuxSetImage(mux, &image, copy_data);
-  // ... (Prepare ICC profile data).
-  WebPMuxSetChunk(mux, "ICCP", &icc_profile, copy_data);
-  // ... (Prepare XMP metadata).
-  WebPMuxSetChunk(mux, "XMP ", &xmp, copy_data);
-  // Get data from mux in WebP RIFF format.
-  WebPMuxAssemble(mux, &output_data);
-  WebPMuxDelete(mux);
-  // ... (Consume output_data; e.g. write output_data.bytes to file).
-  WebPDataClear(&output_data);
-
-
-Example#2 (pseudo code): Get image and color profile data from a WebP file.
-
-  int copy_data = 0;
-  // ... (Read data from file).
-  WebPMux* mux = WebPMuxCreate(&data, copy_data);
-  WebPMuxGetFrame(mux, 1, &image);
-  // ... (Consume image; e.g. call WebPDecode() to decode the data).
-  WebPMuxGetChunk(mux, "ICCP", &icc_profile);
-  // ... (Consume icc_profile).
-  WebPMuxDelete(mux);
-  free(data);
-
-
-For a detailed Mux API reference, please refer to the header file
-(src/webp/mux.h).
-
-Demux API:
-==========
-The Demux API enables extraction of images and extended format data from
-WebP files. This API currently supports reading of XMP/EXIF metadata, ICC
-profile and animated images. Other features may be added in subsequent
-releases.
-
-Code example: Demuxing WebP data to extract all the frames, ICC profile
-and EXIF/XMP metadata.
-
-  WebPDemuxer* demux = WebPDemux(&webp_data);
-  uint32_t width = WebPDemuxGetI(demux, WEBP_FF_CANVAS_WIDTH);
-  uint32_t height = WebPDemuxGetI(demux, WEBP_FF_CANVAS_HEIGHT);
-  // ... (Get information about the features present in the WebP file).
-  uint32_t flags = WebPDemuxGetI(demux, WEBP_FF_FORMAT_FLAGS);
-
-  // ... (Iterate over all frames).
-  WebPIterator iter;
-  if (WebPDemuxGetFrame(demux, 1, &iter)) {
-    do {
-      // ... (Consume 'iter'; e.g. Decode 'iter.fragment' with WebPDecode(),
-      // ... and get other frame properties like width, height, offsets etc.
-      // ... see 'struct WebPIterator' below for more info).
-    } while (WebPDemuxNextFrame(&iter));
-    WebPDemuxReleaseIterator(&iter);
-  }
-
-  // ... (Extract metadata).
-  WebPChunkIterator chunk_iter;
-  if (flags & ICCP_FLAG) WebPDemuxGetChunk(demux, "ICCP", 1, &chunk_iter);
-  // ... (Consume the ICC profile in 'chunk_iter.chunk').
-  WebPDemuxReleaseChunkIterator(&chunk_iter);
-  if (flags & EXIF_FLAG) WebPDemuxGetChunk(demux, "EXIF", 1, &chunk_iter);
-  // ... (Consume the EXIF metadata in 'chunk_iter.chunk').
-  WebPDemuxReleaseChunkIterator(&chunk_iter);
-  if (flags & XMP_FLAG) WebPDemuxGetChunk(demux, "XMP ", 1, &chunk_iter);
-  // ... (Consume the XMP metadata in 'chunk_iter.chunk').
-  WebPDemuxReleaseChunkIterator(&chunk_iter);
-  WebPDemuxDelete(demux);
-
-
-For a detailed Demux API reference, please refer to the header file
-(src/webp/demux.h).
-
-AnimEncoder API:
-================
-The AnimEncoder API can be used to create animated WebP images.
-
-Code example:
-
-  WebPAnimEncoderOptions enc_options;
-  WebPAnimEncoderOptionsInit(&enc_options);
-  // ... (Tune 'enc_options' as needed).
-  WebPAnimEncoder* enc = WebPAnimEncoderNew(width, height, &enc_options);
-  while(<there are more frames>) {
-    WebPConfig config;
-    WebPConfigInit(&config);
-    // ... (Tune 'config' as needed).
-    WebPAnimEncoderAdd(enc, frame, duration, &config);
-  }
-  WebPAnimEncoderAssemble(enc, webp_data);
-  WebPAnimEncoderDelete(enc);
-  // ... (Write the 'webp_data' to a file, or re-mux it further).
-
-
-For a detailed AnimEncoder API reference, please refer to the header file
-(src/webp/mux.h).
-
-AnimDecoder API:
-================
-This AnimDecoder API allows decoding (possibly) animated WebP images.
-
-Code Example:
-
-  WebPAnimDecoderOptions dec_options;
-  WebPAnimDecoderOptionsInit(&dec_options);
-  // Tune 'dec_options' as needed.
-  WebPAnimDecoder* dec = WebPAnimDecoderNew(webp_data, &dec_options);
-  WebPAnimInfo anim_info;
-  WebPAnimDecoderGetInfo(dec, &anim_info);
-  for (uint32_t i = 0; i < anim_info.loop_count; ++i) {
-    while (WebPAnimDecoderHasMoreFrames(dec)) {
-      uint8_t* buf;
-      int timestamp;
-      WebPAnimDecoderGetNext(dec, &buf, &timestamp);
-      // ... (Render 'buf' based on 'timestamp').
-      // ... (Do NOT free 'buf', as it is owned by 'dec').
-    }
-    WebPAnimDecoderReset(dec);
-  }
-  const WebPDemuxer* demuxer = WebPAnimDecoderGetDemuxer(dec);
-  // ... (Do something using 'demuxer'; e.g. get EXIF/XMP/ICC data).
-  WebPAnimDecoderDelete(dec);
-
-For a detailed AnimDecoder API reference, please refer to the header file
-(src/webp/demux.h).
-
-
-Bugs:
-=====
-
-Please report all bugs to the issue tracker:
-    https://bugs.chromium.org/p/webp
-Patches welcome! See this page to get started:
-    https://www.webmproject.org/code/contribute/submitting-patches/
-
-Discuss:
-========
-
-Email: [email protected]
-Web: https://groups.google.com/a/webmproject.org/group/webp-discuss

+ 0 - 75
webp.mod/libwebp/README.webp_js

@@ -1,75 +0,0 @@
-     __   __ ____ ____ ____     __  ____
-    /  \\/  \  _ \  _ \  _ \   (__)/  __\
-    \       /  __/ _  \  __/   _)  \_   \
-     \__\__/_____/____/_/     /____/____/
-
-Description:
-============
-
-This file describes the compilation of libwebp into a JavaScript decoder
-using Emscripten and CMake.
-
- - install the Emscripten SDK following the procedure described at:
-   https://emscripten.org/docs/getting_started/downloads.html#installation-instructions-using-the-emsdk-recommended
-   After installation, you should have some global variable positioned to the
-   location of the SDK. In particular, $EMSDK should point to the
-   top-level directory containing Emscripten tools.
-
- - configure the project 'WEBP_JS' with CMake using:
-
- cd webp_js && \
- emcmake cmake -DWEBP_BUILD_WEBP_JS=ON \
-       ../
-
- - compile webp.js using 'emmake make'.
-
- - that's it! Upon completion, you should have the webp.js and
-   webp.wasm files generated.
-
-The callable JavaScript function is WebPToSDL(), which decodes a raw WebP
-bitstream into a canvas. See webp_js/index.html for a simple usage sample
-(see below for instructions).
-
-Demo HTML page:
-===============
-
-   The HTML page webp_js/index.html requires an HTTP server to serve the WebP
-   image example. It's easy to just use Python for that.
-
-cd webp_js && python -m SimpleHTTPServer 8080
-
-and then navigate to http://localhost:8080 in your favorite browser.
-
-
-Web-Assembly (WASM) version:
-============================
-
-  CMakeLists.txt is configured to build the WASM version when using
-  the option WEBP_BUILD_WEBP_JS=ON. The compilation step will assemble
-  the files 'webp_wasm.js', 'webp_wasm.wasm' in the webp_js/ directory.
-  See webp_js/index_wasm.html for a simple demo page using the WASM version
-  of the library.
-
-  You will need a fairly recent version of Emscripten (at least 2.0.18,
-  latest-upstream is recommended) and of your WASM-enabled browser to run this
-  version.
-
-Caveat:
-=======
-
-  - First decoding using the library is usually slower, due to just-in-time
-    compilation.
-
-  - Some versions of llvm produce the following compile error when SSE2 is
-    enabled.
-
-"Unsupported:   %516 = bitcast <8 x i16> %481 to i128
- LLVM ERROR: BitCast Instruction not yet supported for integer types larger than 64 bits"
-
-    The corresponding Emscripten bug is at:
-    https://github.com/kripken/emscripten/issues/3788
-
-    Therefore, SSE2 optimization is currently disabled in CMakeLists.txt.
-
-  - If WEBP_ENABLE_SIMD is set to 1 the JavaScript version (webp.js) will be
-    disabled as wasm2js does not support SIMD.

+ 8 - 0
webp.mod/libwebp/build.gradle

@@ -105,6 +105,14 @@ model {
       sources {
         c {
           source {
+            srcDir "sharpyuv"
+            include "sharpyuv.c"
+            include "sharpyuv_cpu.c"
+            include "sharpyuv_csp.c"
+            include "sharpyuv_dsp.c"
+            include "sharpyuv_gamma.c"
+            include "sharpyuv_neon.c"
+            include "sharpyuv_sse2.c"
             srcDir "src/dec"
             include "alpha_dec.c"
             include "buffer_dec.c"

+ 9 - 2
webp.mod/libwebp/cmake/WebPConfig.cmake.in

@@ -3,9 +3,16 @@ set(WEBP_VERSION ${WebP_VERSION})
 
 @PACKAGE_INIT@
 
-include ("${CMAKE_CURRENT_LIST_DIR}/@[email protected]")
+if(@WEBP_USE_THREAD@)
+  include(CMakeFindDependencyMacro)
+  find_dependency(Threads REQUIRED)
+endif()
 
-set(WebP_INCLUDE_DIRS "@CMAKE_INSTALL_FULL_INCLUDEDIR@")
+include("${CMAKE_CURRENT_LIST_DIR}/@[email protected]")
+
+set_and_check(WebP_INCLUDE_DIR "@PACKAGE_CMAKE_INSTALL_INCLUDEDIR@")
 set(WEBP_INCLUDE_DIRS ${WebP_INCLUDE_DIRS})
 set(WebP_LIBRARIES "@INSTALLED_LIBRARIES@")
 set(WEBP_LIBRARIES "${WebP_LIBRARIES}")
+
+check_required_components(WebP)

+ 0 - 33
webp.mod/libwebp/cmake/config.h.in

@@ -16,48 +16,18 @@
 /* Define to 1 if you have the <cpu-features.h> header file. */
 #cmakedefine HAVE_CPU_FEATURES_H 1
 
-/* Define to 1 if you have the <dlfcn.h> header file. */
-#cmakedefine HAVE_DLFCN_H 1
-
 /* Define to 1 if you have the <GLUT/glut.h> header file. */
 #cmakedefine HAVE_GLUT_GLUT_H 1
 
 /* Define to 1 if you have the <GL/glut.h> header file. */
 #cmakedefine HAVE_GL_GLUT_H 1
 
-/* Define to 1 if you have the <inttypes.h> header file. */
-#cmakedefine HAVE_INTTYPES_H 1
-
-/* Define to 1 if you have the <memory.h> header file. */
-#cmakedefine HAVE_MEMORY_H 1
-
 /* Define to 1 if you have the <OpenGL/glut.h> header file. */
 #cmakedefine HAVE_OPENGL_GLUT_H 1
 
-/* Have PTHREAD_PRIO_INHERIT. */
-#cmakedefine HAVE_PTHREAD_PRIO_INHERIT @HAVE_PTHREAD_PRIO_INHERIT@
-
 /* Define to 1 if you have the <shlwapi.h> header file. */
 #cmakedefine HAVE_SHLWAPI_H 1
 
-/* Define to 1 if you have the <stdint.h> header file. */
-#cmakedefine HAVE_STDINT_H 1
-
-/* Define to 1 if you have the <stdlib.h> header file. */
-#cmakedefine HAVE_STDLIB_H 1
-
-/* Define to 1 if you have the <strings.h> header file. */
-#cmakedefine HAVE_STRINGS_H 1
-
-/* Define to 1 if you have the <string.h> header file. */
-#cmakedefine HAVE_STRING_H 1
-
-/* Define to 1 if you have the <sys/stat.h> header file. */
-#cmakedefine HAVE_SYS_STAT_H 1
-
-/* Define to 1 if you have the <sys/types.h> header file. */
-#cmakedefine HAVE_SYS_TYPES_H 1
-
 /* Define to 1 if you have the <unistd.h> header file. */
 #cmakedefine HAVE_UNISTD_H 1
 
@@ -93,9 +63,6 @@
 /* Define to the version of this package. */
 #cmakedefine PACKAGE_VERSION "@PACKAGE_VERSION@"
 
-/* Define to 1 if you have the ANSI C header files. */
-#cmakedefine STDC_HEADERS 1
-
 /* Version number of package */
 #cmakedefine VERSION "@VERSION@"
 

+ 12 - 15
webp.mod/libwebp/cmake/cpu.cmake

@@ -18,7 +18,8 @@ function(webp_check_compiler_flag WEBP_SIMD_FLAG ENABLE_SIMD)
   unset(WEBP_HAVE_FLAG_${WEBP_SIMD_FLAG} CACHE)
   cmake_push_check_state()
   set(CMAKE_REQUIRED_INCLUDES ${CMAKE_CURRENT_SOURCE_DIR})
-  check_c_source_compiles("
+  check_c_source_compiles(
+    "
       #include \"${CMAKE_CURRENT_LIST_DIR}/../src/dsp/dsp.h\"
       int main(void) {
         #if !defined(WEBP_USE_${WEBP_SIMD_FLAG})
@@ -26,7 +27,8 @@ function(webp_check_compiler_flag WEBP_SIMD_FLAG ENABLE_SIMD)
         #endif
         return 0;
       }
-    " WEBP_HAVE_FLAG_${WEBP_SIMD_FLAG})
+    "
+    WEBP_HAVE_FLAG_${WEBP_SIMD_FLAG})
   cmake_pop_check_state()
   if(WEBP_HAVE_FLAG_${WEBP_SIMD_FLAG})
     set(WEBP_HAVE_${WEBP_SIMD_FLAG} 1 PARENT_SCOPE)
@@ -52,13 +54,10 @@ if(MSVC AND CMAKE_C_COMPILER_ID STREQUAL "MSVC")
   endif()
   set(SIMD_DISABLE_FLAGS)
 else()
-  set(SIMD_ENABLE_FLAGS
-      "-msse4.1;-msse2;-mips32;-mdspr2;-mfpu=neon;-mmsa")
-  set(SIMD_DISABLE_FLAGS
-      "-mno-sse4.1;-mno-sse2;;-mno-dspr2;;-mno-msa")
+  set(SIMD_ENABLE_FLAGS "-msse4.1;-msse2;-mips32;-mdspr2;-mfpu=neon;-mmsa")
+  set(SIMD_DISABLE_FLAGS "-mno-sse4.1;-mno-sse2;;-mno-dspr2;;-mno-msa")
 endif()
 
-set(WEBP_SIMD_FILES_TO_NOT_INCLUDE)
 set(WEBP_SIMD_FILES_TO_INCLUDE)
 set(WEBP_SIMD_FLAGS_TO_INCLUDE)
 
@@ -75,8 +74,8 @@ list(LENGTH WEBP_SIMD_FLAGS WEBP_SIMD_FLAGS_LENGTH)
 math(EXPR WEBP_SIMD_FLAGS_RANGE "${WEBP_SIMD_FLAGS_LENGTH} - 1")
 
 foreach(I_SIMD RANGE ${WEBP_SIMD_FLAGS_RANGE})
-  # With Emscripten 2.0.9 -msimd128 -mfpu=neon will enable NEON, but the
-  # source will fail to compile.
+  # With Emscripten 2.0.9 -msimd128 -mfpu=neon will enable NEON, but the source
+  # will fail to compile.
   if(EMSCRIPTEN AND ${I_SIMD} GREATER_EQUAL 2)
     break()
   endif()
@@ -108,7 +107,7 @@ foreach(I_SIMD RANGE ${WEBP_SIMD_FLAGS_RANGE})
   # Check which files we should include or not.
   list(GET WEBP_SIMD_FILE_EXTENSIONS ${I_SIMD} WEBP_SIMD_FILE_EXTENSION)
   file(GLOB SIMD_FILES "${CMAKE_CURRENT_LIST_DIR}/../"
-            "src/dsp/*${WEBP_SIMD_FILE_EXTENSION}")
+       "src/dsp/*${WEBP_SIMD_FILE_EXTENSION}")
   if(WEBP_HAVE_${WEBP_SIMD_FLAG})
     # Memorize the file and flags.
     foreach(FILE ${SIMD_FILES})
@@ -142,11 +141,9 @@ foreach(I_SIMD RANGE ${WEBP_SIMD_FLAGS_RANGE})
             set(COMMON_PATTERNS)
           endif()
           set(CMAKE_REQUIRED_DEFINITIONS ${SIMD_COMPILE_FLAG})
-          check_c_source_compiles("int main(void) {return 0;}"
-                                  FLAG_${SIMD_COMPILE_FLAG}
-                                  FAIL_REGEX
-                                  "warning: argument unused during compilation:"
-                                  ${COMMON_PATTERNS})
+          check_c_source_compiles(
+            "int main(void) {return 0;}" FLAG_${SIMD_COMPILE_FLAG} FAIL_REGEX
+            "warning: argument unused during compilation:" ${COMMON_PATTERNS})
           if(NOT FLAG_${SIMD_COMPILE_FLAG})
             unset(HAS_COMPILE_FLAG)
             unset(HAS_COMPILE_FLAG CACHE)

+ 63 - 71
webp.mod/libwebp/cmake/deps.cmake

@@ -10,24 +10,30 @@
 
 # Check for compiler options.
 include(CheckCSourceCompiles)
-check_c_source_compiles("
+check_c_source_compiles(
+  "
     int main(void) {
       (void)__builtin_bswap16(0);
       return 0;
     }
-  " HAVE_BUILTIN_BSWAP16)
-check_c_source_compiles("
+  "
+  HAVE_BUILTIN_BSWAP16)
+check_c_source_compiles(
+  "
     int main(void) {
       (void)__builtin_bswap32(0);
       return 0;
     }
-  " HAVE_BUILTIN_BSWAP32)
-check_c_source_compiles("
+  "
+  HAVE_BUILTIN_BSWAP32)
+check_c_source_compiles(
+  "
     int main(void) {
       (void)__builtin_bswap64(0);
       return 0;
     }
-  " HAVE_BUILTIN_BSWAP64)
+  "
+  HAVE_BUILTIN_BSWAP64)
 
 # Check for libraries.
 if(WEBP_USE_THREAD)
@@ -37,15 +43,7 @@ if(WEBP_USE_THREAD)
     if(CMAKE_USE_PTHREADS_INIT AND NOT CMAKE_SYSTEM_NAME STREQUAL "QNX")
       set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pthread")
     endif()
-    check_c_source_compiles("
-        #include <pthread.h>
-        int main (void) {
-          int attr = PTHREAD_PRIO_INHERIT;
-          return attr;
-        }
-      " FLAG_HAVE_PTHREAD_PRIO_INHERIT)
-    set(HAVE_PTHREAD_PRIO_INHERIT ${FLAG_HAVE_PTHREAD_PRIO_INHERIT})
-    list(APPEND WEBP_DEP_LIBRARIES ${CMAKE_THREAD_LIBS_INIT})
+    list(APPEND WEBP_DEP_LIBRARIES Threads::Threads)
   endif()
   set(WEBP_USE_THREAD ${Threads_FOUND})
 endif()
@@ -59,89 +57,88 @@ set(WEBP_HAVE_GL ${OPENGL_FOUND})
 
 # Check if we need to link to the C math library. We do not look for it as it is
 # not found when cross-compiling, while it is here.
-check_c_source_compiles("
+check_c_source_compiles(
+  "
     #include <math.h>
     int main(int argc, char** argv) {
       return (int)pow(argc, 2.5);
     }
-  " HAVE_MATH_LIBRARY)
+  "
+  HAVE_MATH_LIBRARY)
 if(NOT HAVE_MATH_LIBRARY)
   message(STATUS "Adding -lm flag.")
+  list(APPEND SHARPYUV_DEP_LIBRARIES m)
   list(APPEND WEBP_DEP_LIBRARIES m)
 endif()
 
 # Find the standard image libraries.
 set(WEBP_DEP_IMG_LIBRARIES)
 set(WEBP_DEP_IMG_INCLUDE_DIRS)
-foreach(I_LIB PNG JPEG TIFF)
-  find_package(${I_LIB})
-  set(WEBP_HAVE_${I_LIB} ${${I_LIB}_FOUND})
-  if(${I_LIB}_FOUND)
-    list(APPEND WEBP_DEP_IMG_LIBRARIES ${${I_LIB}_LIBRARIES})
-    list(APPEND WEBP_DEP_IMG_INCLUDE_DIRS ${${I_LIB}_INCLUDE_DIR}
-                ${${I_LIB}_INCLUDE_DIRS})
+if(WEBP_FIND_IMG_LIBS)
+  foreach(I_LIB PNG JPEG TIFF)
+    # Disable tiff when compiling in static mode as it is failing on Ubuntu.
+    if(WEBP_LINK_STATIC AND ${I_LIB} STREQUAL "TIFF")
+      message(STATUS "TIFF is disabled when statically linking.")
+      continue()
+    endif()
+    find_package(${I_LIB})
+    set(WEBP_HAVE_${I_LIB} ${${I_LIB}_FOUND})
+    if(${I_LIB}_FOUND)
+      list(APPEND WEBP_DEP_IMG_LIBRARIES ${${I_LIB}_LIBRARIES})
+      list(APPEND WEBP_DEP_IMG_INCLUDE_DIRS ${${I_LIB}_INCLUDE_DIR}
+           ${${I_LIB}_INCLUDE_DIRS})
+    endif()
+  endforeach()
+  if(WEBP_DEP_IMG_INCLUDE_DIRS)
+    list(REMOVE_DUPLICATES WEBP_DEP_IMG_INCLUDE_DIRS)
   endif()
-endforeach()
-if(WEBP_DEP_IMG_INCLUDE_DIRS)
-  list(REMOVE_DUPLICATES WEBP_DEP_IMG_INCLUDE_DIRS)
-endif()
 
-# GIF detection, gifdec isn't part of the imageio lib.
-include(CMakePushCheckState)
-set(WEBP_DEP_GIF_LIBRARIES)
-set(WEBP_DEP_GIF_INCLUDE_DIRS)
-find_package(GIF)
-set(WEBP_HAVE_GIF ${GIF_FOUND})
-if(GIF_FOUND)
-  # GIF find_package only locates the header and library, it doesn't fail
-  # compile tests when detecting the version, but falls back to 3 (as of at
-  # least cmake 3.7.2). Make sure the library links to avoid incorrect detection
-  # when cross compiling.
-  cmake_push_check_state()
-  set(CMAKE_REQUIRED_LIBRARIES ${GIF_LIBRARIES})
-  set(CMAKE_REQUIRED_INCLUDES ${GIF_INCLUDE_DIR})
-  check_c_source_compiles("
+  # GIF detection, gifdec isn't part of the imageio lib.
+  include(CMakePushCheckState)
+  set(WEBP_DEP_GIF_LIBRARIES)
+  set(WEBP_DEP_GIF_INCLUDE_DIRS)
+  find_package(GIF)
+  set(WEBP_HAVE_GIF ${GIF_FOUND})
+  if(GIF_FOUND)
+    # GIF find_package only locates the header and library, it doesn't fail
+    # compile tests when detecting the version, but falls back to 3 (as of at
+    # least cmake 3.7.2). Make sure the library links to avoid incorrect
+    # detection when cross compiling.
+    cmake_push_check_state()
+    set(CMAKE_REQUIRED_LIBRARIES ${GIF_LIBRARIES})
+    set(CMAKE_REQUIRED_INCLUDES ${GIF_INCLUDE_DIR})
+    check_c_source_compiles(
+      "
       #include <gif_lib.h>
       int main(void) {
         (void)DGifOpenFileHandle;
         return 0;
       }
-      " GIF_COMPILES)
-  cmake_pop_check_state()
-  if(GIF_COMPILES)
-    list(APPEND WEBP_DEP_GIF_LIBRARIES ${GIF_LIBRARIES})
-    list(APPEND WEBP_DEP_GIF_INCLUDE_DIRS ${GIF_INCLUDE_DIR})
-  else()
-    unset(GIF_FOUND)
+      "
+      GIF_COMPILES)
+    cmake_pop_check_state()
+    if(GIF_COMPILES)
+      list(APPEND WEBP_DEP_GIF_LIBRARIES ${GIF_LIBRARIES})
+      list(APPEND WEBP_DEP_GIF_INCLUDE_DIRS ${GIF_INCLUDE_DIR})
+    else()
+      unset(GIF_FOUND)
+    endif()
   endif()
 endif()
 
 # Check for specific headers.
 include(CheckIncludeFiles)
-check_include_files("stdlib.h;stdarg.h;string.h;float.h" STDC_HEADERS)
-check_include_files(dlfcn.h HAVE_DLFCN_H)
 check_include_files(GLUT/glut.h HAVE_GLUT_GLUT_H)
 check_include_files(GL/glut.h HAVE_GL_GLUT_H)
-check_include_files(inttypes.h HAVE_INTTYPES_H)
-check_include_files(memory.h HAVE_MEMORY_H)
 check_include_files(OpenGL/glut.h HAVE_OPENGL_GLUT_H)
 check_include_files(shlwapi.h HAVE_SHLWAPI_H)
-check_include_files(stdint.h HAVE_STDINT_H)
-check_include_files(stdlib.h HAVE_STDLIB_H)
-check_include_files(strings.h HAVE_STRINGS_H)
-check_include_files(string.h HAVE_STRING_H)
-check_include_files(sys/stat.h HAVE_SYS_STAT_H)
-check_include_files(sys/types.h HAVE_SYS_TYPES_H)
 check_include_files(unistd.h HAVE_UNISTD_H)
 check_include_files(wincodec.h HAVE_WINCODEC_H)
 check_include_files(windows.h HAVE_WINDOWS_H)
 
 # Windows specifics
 if(HAVE_WINCODEC_H)
-  list(APPEND WEBP_DEP_LIBRARIES
-              shlwapi
-              ole32
-              windowscodecs)
+  list(APPEND WEBP_DEP_LIBRARIES shlwapi ole32 windowscodecs)
 endif()
 
 # Check for SIMD extensions.
@@ -153,17 +150,12 @@ set(PACKAGE_NAME ${PROJECT_NAME})
 
 # Read from configure.ac.
 file(READ ${CMAKE_CURRENT_SOURCE_DIR}/configure.ac CONFIGURE_AC)
-string(REGEX MATCHALL
-             "\\[([0-9a-z\\.:/]*)\\]"
-             CONFIGURE_AC_PACKAGE_INFO
+string(REGEX MATCHALL "\\[([0-9a-z\\.:/]*)\\]" CONFIGURE_AC_PACKAGE_INFO
              ${CONFIGURE_AC})
 function(strip_bracket VAR)
   string(LENGTH ${${VAR}} TMP_LEN)
   math(EXPR TMP_LEN ${TMP_LEN}-2)
-  string(SUBSTRING ${${VAR}}
-                   1
-                   ${TMP_LEN}
-                   TMP_SUB)
+  string(SUBSTRING ${${VAR}} 1 ${TMP_LEN} TMP_SUB)
   set(${VAR} ${TMP_SUB} PARENT_SCOPE)
 endfunction()
 

+ 8 - 3
webp.mod/libwebp/configure.ac

@@ -1,4 +1,4 @@
-AC_INIT([libwebp], [1.2.1],
+AC_INIT([libwebp], [1.3.2],
         [https://bugs.chromium.org/p/webp],,
         [https://developers.google.com/speed/webp])
 AC_CANONICAL_HOST
@@ -9,7 +9,8 @@ dnl === automake >= 1.12 requires this for 'unusual archivers' support.
 dnl === it must occur before LT_INIT (AC_PROG_LIBTOOL).
 m4_ifdef([AM_PROG_AR], [AM_PROG_AR])
 
-AC_PROG_LIBTOOL
+dnl === AC_PROG_LIBTOOL is deprecated.
+m4_ifdef([LT_INIT], [LT_INIT], [AC_PROG_LIBTOOL])
 AC_PROG_SED
 AM_PROG_CC_C_O
 
@@ -27,7 +28,8 @@ AC_ARG_ENABLE([everything],
               AS_HELP_STRING([--enable-everything],
                              [Enable all optional targets. These can still be
                               disabled with --disable-target]),
-              [SET_IF_UNSET([enable_libwebpdecoder], [$enableval])
+              [SET_IF_UNSET([enable_libsharpyuv], [$enableval])
+               SET_IF_UNSET([enable_libwebpdecoder], [$enableval])
                SET_IF_UNSET([enable_libwebpdemux], [$enableval])
                SET_IF_UNSET([enable_libwebpextras], [$enableval])
                SET_IF_UNSET([enable_libwebpmux], [$enableval])])
@@ -747,10 +749,13 @@ fi
 
 dnl =========================
 
+dnl Add an empty webp_libname_prefix variable for use in *.pc.in.
+AC_SUBST([webp_libname_prefix])
 AC_CONFIG_MACRO_DIR([m4])
 AC_CONFIG_HEADERS([src/webp/config.h])
 AC_CONFIG_FILES([Makefile src/Makefile man/Makefile \
                  examples/Makefile extras/Makefile imageio/Makefile \
+                 sharpyuv/Makefile sharpyuv/libsharpyuv.pc \
                  src/dec/Makefile src/enc/Makefile src/dsp/Makefile \
                  src/demux/Makefile src/mux/Makefile \
                  src/utils/Makefile \

+ 0 - 29
webp.mod/libwebp/doc/README

@@ -1,29 +0,0 @@
-
-Generate libwebp Container Spec Docs from Text Source
-=====================================================
-
-HTML generation requires kramdown [1], easily installed as a
-rubygem [2].  Rubygems installation should satisfy dependencies
-automatically.
-
-[1]: https://kramdown.gettalong.org/
-[2]: https://rubygems.org/
-
-HTML generation can then be done from the project root:
-
-$ kramdown doc/webp-container-spec.txt --template doc/template.html > \
-  doc/output/webp-container-spec.html
-
-kramdown can optionally syntax highlight code blocks, using CodeRay [3],
-a dependency of kramdown that rubygems will install automatically.  The
-following will apply inline CSS styling; an external stylesheet is not
-needed.
-
-$ kramdown doc/webp-lossless-bitstream-spec.txt --template \
-  doc/template.html --coderay-css style --coderay-line-numbers ' ' \
-  --coderay-default-lang c > \
-  doc/output/webp-lossless-bitstream-spec.html
-
-Optimally, use kramdown 0.13.7 or newer if syntax highlighting desired.
-
-[3]: https://github.com/rubychan/coderay

+ 385 - 0
webp.mod/libwebp/doc/api.md

@@ -0,0 +1,385 @@
+# WebP APIs
+
+## Encoding API
+
+The main encoding functions are available in the header src/webp/encode.h
+
+The ready-to-use ones are:
+
+```c
+size_t WebPEncodeRGB(const uint8_t* rgb, int width, int height, int stride,
+                     float quality_factor, uint8_t** output);
+size_t WebPEncodeBGR(const uint8_t* bgr, int width, int height, int stride,
+                     float quality_factor, uint8_t** output);
+size_t WebPEncodeRGBA(const uint8_t* rgba, int width, int height, int stride,
+                      float quality_factor, uint8_t** output);
+size_t WebPEncodeBGRA(const uint8_t* bgra, int width, int height, int stride,
+                      float quality_factor, uint8_t** output);
+```
+
+They will convert raw RGB samples to a WebP data. The only control supplied is
+the quality factor.
+
+There are some variants for using the lossless format:
+
+```c
+size_t WebPEncodeLosslessRGB(const uint8_t* rgb, int width, int height,
+                             int stride, uint8_t** output);
+size_t WebPEncodeLosslessBGR(const uint8_t* bgr, int width, int height,
+                             int stride, uint8_t** output);
+size_t WebPEncodeLosslessRGBA(const uint8_t* rgba, int width, int height,
+                              int stride, uint8_t** output);
+size_t WebPEncodeLosslessBGRA(const uint8_t* bgra, int width, int height,
+                              int stride, uint8_t** output);
+```
+
+Of course in this case, no quality factor is needed since the compression occurs
+without loss of the input values, at the expense of larger output sizes.
+
+### Advanced encoding API
+
+A more advanced API is based on the WebPConfig and WebPPicture structures.
+
+WebPConfig contains the encoding settings and is not tied to a particular
+picture. WebPPicture contains input data, on which some WebPConfig will be used
+for compression. The encoding flow looks like:
+
+```c
+#include <webp/encode.h>
+
+// Setup a config, starting form a preset and tuning some additional
+// parameters
+WebPConfig config;
+if (!WebPConfigPreset(&config, WEBP_PRESET_PHOTO, quality_factor)) {
+  return 0;   // version error
+}
+// ... additional tuning
+config.sns_strength = 90;
+config.filter_sharpness = 6;
+config_error = WebPValidateConfig(&config);  // not mandatory, but useful
+
+// Setup the input data
+WebPPicture pic;
+if (!WebPPictureInit(&pic)) {
+  return 0;  // version error
+}
+pic.width = width;
+pic.height = height;
+// allocated picture of dimension width x height
+if (!WebPPictureAlloc(&pic)) {
+  return 0;   // memory error
+}
+// at this point, 'pic' has been initialized as a container,
+// and can receive the Y/U/V samples.
+// Alternatively, one could use ready-made import functions like
+// WebPPictureImportRGB(), which will take care of memory allocation.
+// In any case, past this point, one will have to call
+// WebPPictureFree(&pic) to reclaim memory.
+
+// Set up a byte-output write method. WebPMemoryWriter, for instance.
+WebPMemoryWriter wrt;
+WebPMemoryWriterInit(&wrt);     // initialize 'wrt'
+
+pic.writer = MyFileWriter;
+pic.custom_ptr = my_opaque_structure_to_make_MyFileWriter_work;
+
+// Compress!
+int ok = WebPEncode(&config, &pic);   // ok = 0 => error occurred!
+WebPPictureFree(&pic);  // must be called independently of the 'ok' result.
+
+// output data should have been handled by the writer at that point.
+// -> compressed data is the memory buffer described by wrt.mem / wrt.size
+
+// deallocate the memory used by compressed data
+WebPMemoryWriterClear(&wrt);
+```
+
+## Decoding API
+
+This is mainly just one function to call:
+
+```c
+#include "webp/decode.h"
+uint8_t* WebPDecodeRGB(const uint8_t* data, size_t data_size,
+                       int* width, int* height);
+```
+
+Please have a look at the file src/webp/decode.h for the details. There are
+variants for decoding in BGR/RGBA/ARGB/BGRA order, along with decoding to raw
+Y'CbCr samples. One can also decode the image directly into a pre-allocated
+buffer.
+
+To detect a WebP file and gather the picture's dimensions, the function:
+
+```c
+int WebPGetInfo(const uint8_t* data, size_t data_size,
+                int* width, int* height);
+```
+
+is supplied. No decoding is involved when using it.
+
+### Incremental decoding API
+
+In the case when data is being progressively transmitted, pictures can still be
+incrementally decoded using a slightly more complicated API. Decoder state is
+stored into an instance of the WebPIDecoder object. This object can be created
+with the purpose of decoding either RGB or Y'CbCr samples. For instance:
+
+```c
+WebPDecBuffer buffer;
+WebPInitDecBuffer(&buffer);
+buffer.colorspace = MODE_BGR;
+...
+WebPIDecoder* idec = WebPINewDecoder(&buffer);
+```
+
+As data is made progressively available, this incremental-decoder object can be
+used to decode the picture further. There are two (mutually exclusive) ways to
+pass freshly arrived data:
+
+either by appending the fresh bytes:
+
+```c
+WebPIAppend(idec, fresh_data, size_of_fresh_data);
+```
+
+or by just mentioning the new size of the transmitted data:
+
+```c
+WebPIUpdate(idec, buffer, size_of_transmitted_buffer);
+```
+
+Note that 'buffer' can be modified between each call to WebPIUpdate, in
+particular when the buffer is resized to accommodate larger data.
+
+These functions will return the decoding status: either VP8_STATUS_SUSPENDED if
+decoding is not finished yet or VP8_STATUS_OK when decoding is done. Any other
+status is an error condition.
+
+The 'idec' object must always be released (even upon an error condition) by
+calling: WebPDelete(idec).
+
+To retrieve partially decoded picture samples, one must use the corresponding
+method: WebPIDecGetRGB or WebPIDecGetYUVA. It will return the last displayable
+pixel row.
+
+Lastly, note that decoding can also be performed into a pre-allocated pixel
+buffer. This buffer must be passed when creating a WebPIDecoder, calling
+WebPINewRGB() or WebPINewYUVA().
+
+Please have a look at the src/webp/decode.h header for further details.
+
+### Advanced Decoding API
+
+WebP decoding supports an advanced API which provides on-the-fly cropping and
+rescaling, something of great usefulness on memory-constrained environments like
+mobile phones. Basically, the memory usage will scale with the output's size,
+not the input's, when one only needs a quick preview or a zoomed in portion of
+an otherwise too-large picture. Some CPU can be saved too, incidentally.
+
+```c
+// A) Init a configuration object
+WebPDecoderConfig config;
+CHECK(WebPInitDecoderConfig(&config));
+
+// B) optional: retrieve the bitstream's features.
+CHECK(WebPGetFeatures(data, data_size, &config.input) == VP8_STATUS_OK);
+
+// C) Adjust 'config' options, if needed
+config.options.no_fancy_upsampling = 1;
+config.options.use_scaling = 1;
+config.options.scaled_width = scaledWidth();
+config.options.scaled_height = scaledHeight();
+// etc.
+
+// D) Specify 'config' output options for specifying output colorspace.
+// Optionally the external image decode buffer can also be specified.
+config.output.colorspace = MODE_BGRA;
+// Optionally, the config.output can be pointed to an external buffer as
+// well for decoding the image. This externally supplied memory buffer
+// should be big enough to store the decoded picture.
+config.output.u.RGBA.rgba = (uint8_t*) memory_buffer;
+config.output.u.RGBA.stride = scanline_stride;
+config.output.u.RGBA.size = total_size_of_the_memory_buffer;
+config.output.is_external_memory = 1;
+
+// E) Decode the WebP image. There are two variants w.r.t decoding image.
+// The first one (E.1) decodes the full image and the second one (E.2) is
+// used to incrementally decode the image using small input buffers.
+// Any one of these steps can be used to decode the WebP image.
+
+// E.1) Decode full image.
+CHECK(WebPDecode(data, data_size, &config) == VP8_STATUS_OK);
+
+// E.2) Decode image incrementally.
+WebPIDecoder* const idec = WebPIDecode(NULL, NULL, &config);
+CHECK(idec != NULL);
+while (bytes_remaining > 0) {
+  VP8StatusCode status = WebPIAppend(idec, input, bytes_read);
+  if (status == VP8_STATUS_OK || status == VP8_STATUS_SUSPENDED) {
+    bytes_remaining -= bytes_read;
+  } else {
+    break;
+  }
+}
+WebPIDelete(idec);
+
+// F) Decoded image is now in config.output (and config.output.u.RGBA).
+// It can be saved, displayed or otherwise processed.
+
+// G) Reclaim memory allocated in config's object. It's safe to call
+// this function even if the memory is external and wasn't allocated
+// by WebPDecode().
+WebPFreeDecBuffer(&config.output);
+```
+
+## WebP Mux
+
+WebPMux is a set of two libraries 'Mux' and 'Demux' for creation, extraction and
+manipulation of an extended format WebP file, which can have features like color
+profile, metadata and animation. Reference command-line tools `webpmux` and
+`vwebp` as well as the WebP container specification
+'doc/webp-container-spec.txt' are also provided in this package, see the
+[tools documentation](tools.md).
+
+### Mux API
+
+The Mux API contains methods for adding data to and reading data from WebP
+files. This API currently supports XMP/EXIF metadata, ICC profile and animation.
+Other features may be added in subsequent releases.
+
+Example#1 (pseudo code): Creating a WebPMux object with image data, color
+profile and XMP metadata.
+
+```c
+int copy_data = 0;
+WebPMux* mux = WebPMuxNew();
+// ... (Prepare image data).
+WebPMuxSetImage(mux, &image, copy_data);
+// ... (Prepare ICC profile data).
+WebPMuxSetChunk(mux, "ICCP", &icc_profile, copy_data);
+// ... (Prepare XMP metadata).
+WebPMuxSetChunk(mux, "XMP ", &xmp, copy_data);
+// Get data from mux in WebP RIFF format.
+WebPMuxAssemble(mux, &output_data);
+WebPMuxDelete(mux);
+// ... (Consume output_data; e.g. write output_data.bytes to file).
+WebPDataClear(&output_data);
+```
+
+Example#2 (pseudo code): Get image and color profile data from a WebP file.
+
+```c
+int copy_data = 0;
+// ... (Read data from file).
+WebPMux* mux = WebPMuxCreate(&data, copy_data);
+WebPMuxGetFrame(mux, 1, &image);
+// ... (Consume image; e.g. call WebPDecode() to decode the data).
+WebPMuxGetChunk(mux, "ICCP", &icc_profile);
+// ... (Consume icc_profile).
+WebPMuxDelete(mux);
+free(data);
+```
+
+For a detailed Mux API reference, please refer to the header file
+(src/webp/mux.h).
+
+### Demux API
+
+The Demux API enables extraction of images and extended format data from WebP
+files. This API currently supports reading of XMP/EXIF metadata, ICC profile and
+animated images. Other features may be added in subsequent releases.
+
+Code example: Demuxing WebP data to extract all the frames, ICC profile and
+EXIF/XMP metadata.
+
+```c
+WebPDemuxer* demux = WebPDemux(&webp_data);
+uint32_t width = WebPDemuxGetI(demux, WEBP_FF_CANVAS_WIDTH);
+uint32_t height = WebPDemuxGetI(demux, WEBP_FF_CANVAS_HEIGHT);
+// ... (Get information about the features present in the WebP file).
+uint32_t flags = WebPDemuxGetI(demux, WEBP_FF_FORMAT_FLAGS);
+
+// ... (Iterate over all frames).
+WebPIterator iter;
+if (WebPDemuxGetFrame(demux, 1, &iter)) {
+  do {
+    // ... (Consume 'iter'; e.g. Decode 'iter.fragment' with WebPDecode(),
+    // ... and get other frame properties like width, height, offsets etc.
+    // ... see 'struct WebPIterator' below for more info).
+  } while (WebPDemuxNextFrame(&iter));
+  WebPDemuxReleaseIterator(&iter);
+}
+
+// ... (Extract metadata).
+WebPChunkIterator chunk_iter;
+if (flags & ICCP_FLAG) WebPDemuxGetChunk(demux, "ICCP", 1, &chunk_iter);
+// ... (Consume the ICC profile in 'chunk_iter.chunk').
+WebPDemuxReleaseChunkIterator(&chunk_iter);
+if (flags & EXIF_FLAG) WebPDemuxGetChunk(demux, "EXIF", 1, &chunk_iter);
+// ... (Consume the EXIF metadata in 'chunk_iter.chunk').
+WebPDemuxReleaseChunkIterator(&chunk_iter);
+if (flags & XMP_FLAG) WebPDemuxGetChunk(demux, "XMP ", 1, &chunk_iter);
+// ... (Consume the XMP metadata in 'chunk_iter.chunk').
+WebPDemuxReleaseChunkIterator(&chunk_iter);
+WebPDemuxDelete(demux);
+```
+
+For a detailed Demux API reference, please refer to the header file
+(src/webp/demux.h).
+
+## AnimEncoder API
+
+The AnimEncoder API can be used to create animated WebP images.
+
+Code example:
+
+```c
+WebPAnimEncoderOptions enc_options;
+WebPAnimEncoderOptionsInit(&enc_options);
+// ... (Tune 'enc_options' as needed).
+WebPAnimEncoder* enc = WebPAnimEncoderNew(width, height, &enc_options);
+while(<there are more frames>) {
+  WebPConfig config;
+  WebPConfigInit(&config);
+  // ... (Tune 'config' as needed).
+  WebPAnimEncoderAdd(enc, frame, duration, &config);
+}
+WebPAnimEncoderAssemble(enc, webp_data);
+WebPAnimEncoderDelete(enc);
+// ... (Write the 'webp_data' to a file, or re-mux it further).
+```
+
+For a detailed AnimEncoder API reference, please refer to the header file
+(src/webp/mux.h).
+
+## AnimDecoder API
+
+This AnimDecoder API allows decoding (possibly) animated WebP images.
+
+Code Example:
+
+```c
+WebPAnimDecoderOptions dec_options;
+WebPAnimDecoderOptionsInit(&dec_options);
+// Tune 'dec_options' as needed.
+WebPAnimDecoder* dec = WebPAnimDecoderNew(webp_data, &dec_options);
+WebPAnimInfo anim_info;
+WebPAnimDecoderGetInfo(dec, &anim_info);
+for (uint32_t i = 0; i < anim_info.loop_count; ++i) {
+  while (WebPAnimDecoderHasMoreFrames(dec)) {
+    uint8_t* buf;
+    int timestamp;
+    WebPAnimDecoderGetNext(dec, &buf, &timestamp);
+    // ... (Render 'buf' based on 'timestamp').
+    // ... (Do NOT free 'buf', as it is owned by 'dec').
+  }
+  WebPAnimDecoderReset(dec);
+}
+const WebPDemuxer* demuxer = WebPAnimDecoderGetDemuxer(dec);
+// ... (Do something using 'demuxer'; e.g. get EXIF/XMP/ICC data).
+WebPAnimDecoderDelete(dec);
+```
+
+For a detailed AnimDecoder API reference, please refer to the header file
+(src/webp/demux.h).

+ 213 - 0
webp.mod/libwebp/doc/building.md

@@ -0,0 +1,213 @@
+# Building
+
+## Windows build
+
+By running:
+
+```batch
+nmake /f Makefile.vc CFG=release-static RTLIBCFG=static OBJDIR=output
+```
+
+the directory `output\release-static\(x64|x86)\bin` will contain the tools
+cwebp.exe and dwebp.exe. The directory `output\release-static\(x64|x86)\lib`
+will contain the libwebp static library. The target architecture (x86/x64) is
+detected by Makefile.vc from the Visual Studio compiler (cl.exe) available in
+the system path.
+
+## Unix build using makefile.unix
+
+On platforms with GNU tools installed (gcc and make), running
+
+```shell
+make -f makefile.unix
+```
+
+will build the binaries examples/cwebp and examples/dwebp, along with the static
+library src/libwebp.a. No system-wide installation is supplied, as this is a
+simple alternative to the full installation system based on the autoconf tools
+(see below). Please refer to makefile.unix for additional details and
+customizations.
+
+## Using autoconf tools
+
+Prerequisites: a compiler (e.g., gcc), make, autoconf, automake, libtool.
+
+On a Debian-like system the following should install everything you need for a
+minimal build:
+
+```shell
+$ sudo apt-get install gcc make autoconf automake libtool
+```
+
+When building from git sources, you will need to run autogen.sh to generate the
+configure script.
+
+```shell
+./configure
+make
+make install
+```
+
+should be all you need to have the following files
+
+```
+/usr/local/include/webp/decode.h
+/usr/local/include/webp/encode.h
+/usr/local/include/webp/types.h
+/usr/local/lib/libwebp.*
+/usr/local/bin/cwebp
+/usr/local/bin/dwebp
+```
+
+installed.
+
+Note: A decode-only library, libwebpdecoder, is available using the
+`--enable-libwebpdecoder` flag. The encode library is built separately and can
+be installed independently using a minor modification in the corresponding
+Makefile.am configure files (see comments there). See `./configure --help` for
+more options.
+
+## Building for MIPS Linux
+
+MIPS Linux toolchain stable available releases can be found at:
+https://community.imgtec.com/developers/mips/tools/codescape-mips-sdk/available-releases/
+
+```shell
+# Add toolchain to PATH
+export PATH=$PATH:/path/to/toolchain/bin
+
+# 32-bit build for mips32r5 (p5600)
+HOST=mips-mti-linux-gnu
+MIPS_CFLAGS="-O3 -mips32r5 -mabi=32 -mtune=p5600 -mmsa -mfp64 \
+  -msched-weight -mload-store-pairs -fPIE"
+MIPS_LDFLAGS="-mips32r5 -mabi=32 -mmsa -mfp64 -pie"
+
+# 64-bit build for mips64r6 (i6400)
+HOST=mips-img-linux-gnu
+MIPS_CFLAGS="-O3 -mips64r6 -mabi=64 -mtune=i6400 -mmsa -mfp64 \
+  -msched-weight -mload-store-pairs -fPIE"
+MIPS_LDFLAGS="-mips64r6 -mabi=64 -mmsa -mfp64 -pie"
+
+./configure --host=${HOST} --build=`config.guess` \
+  CC="${HOST}-gcc -EL" \
+  CFLAGS="$MIPS_CFLAGS" \
+  LDFLAGS="$MIPS_LDFLAGS"
+make
+make install
+```
+
+## CMake
+
+With CMake, you can compile libwebp, cwebp, dwebp, gif2webp, img2webp, webpinfo
+and the JS bindings.
+
+Prerequisites: a compiler (e.g., gcc with autotools) and CMake.
+
+On a Debian-like system the following should install everything you need for a
+minimal build:
+
+```shell
+$ sudo apt-get install build-essential cmake
+```
+
+When building from git sources, you will need to run cmake to generate the
+makefiles.
+
+```shell
+mkdir build && cd build && cmake ../
+make
+make install
+```
+
+If you also want any of the executables, you will need to enable them through
+CMake, e.g.:
+
+```shell
+cmake -DWEBP_BUILD_CWEBP=ON -DWEBP_BUILD_DWEBP=ON ../
+```
+
+or through your favorite interface (like ccmake or cmake-qt-gui).
+
+Use option `-DWEBP_UNICODE=ON` for Unicode support on Windows (with chcp 65001).
+
+Finally, once installed, you can also use WebP in your CMake project by doing:
+
+```cmake
+find_package(WebP)
+```
+
+which will define the CMake variables WebP_INCLUDE_DIRS and WebP_LIBRARIES.
+
+## Gradle
+
+The support for Gradle is minimal: it only helps you compile libwebp, cwebp and
+dwebp and webpmux_example.
+
+Prerequisites: a compiler (e.g., gcc with autotools) and gradle.
+
+On a Debian-like system the following should install everything you need for a
+minimal build:
+
+```shell
+$ sudo apt-get install build-essential gradle
+```
+
+When building from git sources, you will need to run the Gradle wrapper with the
+appropriate target, e.g. :
+
+```shell
+./gradlew buildAllExecutables
+```
+
+## SWIG bindings
+
+To generate language bindings from swig/libwebp.swig at least swig-1.3
+(http://www.swig.org) is required.
+
+Currently the following functions are mapped:
+
+Decode:
+
+```
+WebPGetDecoderVersion
+WebPGetInfo
+WebPDecodeRGBA
+WebPDecodeARGB
+WebPDecodeBGRA
+WebPDecodeBGR
+WebPDecodeRGB
+```
+
+Encode:
+
+```
+WebPGetEncoderVersion
+WebPEncodeRGBA
+WebPEncodeBGRA
+WebPEncodeRGB
+WebPEncodeBGR
+WebPEncodeLosslessRGBA
+WebPEncodeLosslessBGRA
+WebPEncodeLosslessRGB
+WebPEncodeLosslessBGR
+```
+
+See also the [swig documentation](../swig/README.md) for more detailed build
+instructions and usage examples.
+
+### Java bindings
+
+To build the swig-generated JNI wrapper code at least JDK-1.5 (or equivalent) is
+necessary for enum support. The output is intended to be a shared object / DLL
+that can be loaded via `System.loadLibrary("webp_jni")`.
+
+### Python bindings
+
+To build the swig-generated Python extension code at least Python 2.6 is
+required. Python < 2.6 may build with some minor changes to libwebp.swig or the
+generated code, but is untested.
+
+## Javascript decoder
+
+Libwebp can be compiled into a JavaScript decoder using Emscripten and CMake.
+See the [corresponding documentation](../README.md)

+ 26 - 0
webp.mod/libwebp/doc/specs_generation.md

@@ -0,0 +1,26 @@
+# Generate libwebp Container Spec Docs from Text Source
+
+HTML generation requires [kramdown](https://kramdown.gettalong.org/), easily
+installed as a [rubygem](https://rubygems.org/). Rubygems installation should
+satisfy dependencies automatically.
+
+HTML generation can then be done from the project root:
+
+```shell
+$ kramdown doc/webp-container-spec.txt --template doc/template.html > \
+  doc/output/webp-container-spec.html
+```
+
+kramdown can optionally syntax highlight code blocks, using
+[CodeRay](https://github.com/rubychan/coderay), a dependency of kramdown that
+rubygems will install automatically. The following will apply inline CSS
+styling; an external stylesheet is not needed.
+
+```shell
+$ kramdown doc/webp-lossless-bitstream-spec.txt --template \
+  doc/template.html --coderay-css style --coderay-line-numbers ' ' \
+  --coderay-default-lang c > \
+  doc/output/webp-lossless-bitstream-spec.html
+```
+
+Optimally, use kramdown 0.13.7 or newer if syntax highlighting desired.

+ 516 - 0
webp.mod/libwebp/doc/tools.md

@@ -0,0 +1,516 @@
+# WebP tools
+
+## Encoding tool
+
+The examples/ directory contains tools for encoding (cwebp) and decoding (dwebp)
+images.
+
+The easiest use should look like:
+
+```shell
+cwebp input.png -q 80 -o output.webp
+```
+
+which will convert the input file to a WebP file using a quality factor of 80 on
+a 0->100 scale (0 being the lowest quality, 100 being the best. Default value is
+75).
+
+You might want to try the `-lossless` flag too, which will compress the source
+(in RGBA format) without any loss. The `-q` quality parameter will in this case
+control the amount of processing time spent trying to make the output file as
+small as possible.
+
+A longer list of options is available using the `-longhelp` command line flag:
+
+```shell
+> cwebp -longhelp
+Usage:
+ cwebp [-preset <...>] [options] in_file [-o out_file]
+```
+
+If input size (-s) for an image is not specified, it is assumed to be a PNG,
+JPEG, TIFF or WebP file. Note: Animated PNG and WebP files are not supported.
+
+Options:
+
+```
+-h / -help ............. short help
+-H / -longhelp ......... long help
+-q <float> ............. quality factor (0:small..100:big), default=75
+-alpha_q <int> ......... transparency-compression quality (0..100),
+                         default=100
+-preset <string> ....... preset setting, one of:
+                          default, photo, picture,
+                          drawing, icon, text
+   -preset must come first, as it overwrites other parameters
+-z <int> ............... activates lossless preset with given
+                         level in [0:fast, ..., 9:slowest]
+
+-m <int> ............... compression method (0=fast, 6=slowest), default=4
+-segments <int> ........ number of segments to use (1..4), default=4
+-size <int> ............ target size (in bytes)
+-psnr <float> .......... target PSNR (in dB. typically: 42)
+
+-s <int> <int> ......... input size (width x height) for YUV
+-sns <int> ............. spatial noise shaping (0:off, 100:max), default=50
+-f <int> ............... filter strength (0=off..100), default=60
+-sharpness <int> ....... filter sharpness (0:most .. 7:least sharp), default=0
+-strong ................ use strong filter instead of simple (default)
+-nostrong .............. use simple filter instead of strong
+-sharp_yuv ............. use sharper (and slower) RGB->YUV conversion
+-partition_limit <int> . limit quality to fit the 512k limit on
+                         the first partition (0=no degradation ... 100=full)
+-pass <int> ............ analysis pass number (1..10)
+-qrange <min> <max> .... specifies the permissible quality range
+                         (default: 0 100)
+-crop <x> <y> <w> <h> .. crop picture with the given rectangle
+-resize <w> <h> ........ resize picture (*after* any cropping)
+-mt .................... use multi-threading if available
+-low_memory ............ reduce memory usage (slower encoding)
+-map <int> ............. print map of extra info
+-print_psnr ............ prints averaged PSNR distortion
+-print_ssim ............ prints averaged SSIM distortion
+-print_lsim ............ prints local-similarity distortion
+-d <file.pgm> .......... dump the compressed output (PGM file)
+-alpha_method <int> .... transparency-compression method (0..1), default=1
+-alpha_filter <string> . predictive filtering for alpha plane,
+                         one of: none, fast (default) or best
+-exact ................. preserve RGB values in transparent area, default=off
+-blend_alpha <hex> ..... blend colors against background color
+                         expressed as RGB values written in
+                         hexadecimal, e.g. 0xc0e0d0 for red=0xc0
+                         green=0xe0 and blue=0xd0
+-noalpha ............... discard any transparency information
+-lossless .............. encode image losslessly, default=off
+-near_lossless <int> ... use near-lossless image preprocessing
+                         (0..100=off), default=100
+-hint <string> ......... specify image characteristics hint,
+                         one of: photo, picture or graph
+
+-metadata <string> ..... comma separated list of metadata to
+                         copy from the input to the output if present.
+                         Valid values: all, none (default), exif, icc, xmp
+
+-short ................. condense printed message
+-quiet ................. don't print anything
+-version ............... print version number and exit
+-noasm ................. disable all assembly optimizations
+-v ..................... verbose, e.g. print encoding/decoding times
+-progress .............. report encoding progress
+```
+
+Experimental Options:
+
+```
+-jpeg_like ............. roughly match expected JPEG size
+-af .................... auto-adjust filter strength
+-pre <int> ............. pre-processing filter
+```
+
+The main options you might want to try in order to further tune the visual
+quality are:
+
+-preset -sns -f -m
+
+Namely:
+
+*   `preset` will set up a default encoding configuration targeting a particular
+    type of input. It should appear first in the list of options, so that
+    subsequent options can take effect on top of this preset. Default value is
+    'default'.
+*   `sns` will progressively turn on (when going from 0 to 100) some additional
+    visual optimizations (like: segmentation map re-enforcement). This option
+    will balance the bit allocation differently. It tries to take bits from the
+    "easy" parts of the picture and use them in the "difficult" ones instead.
+    Usually, raising the sns value (at fixed -q value) leads to larger files,
+    but with better quality. Typical value is around '75'.
+*   `f` option directly links to the filtering strength used by the codec's
+    in-loop processing. The higher the value, the smoother the highly-compressed
+    area will look. This is particularly useful when aiming at very small files.
+    Typical values are around 20-30. Note that using the option
+    -strong/-nostrong will change the type of filtering. Use "-f 0" to turn
+    filtering off.
+*   `m` controls the trade-off between encoding speed and quality. Default is 4.
+    You can try -m 5 or -m 6 to explore more (time-consuming) encoding
+    possibilities. A lower value will result in faster encoding at the expense
+    of quality.
+
+## Decoding tool
+
+There is a decoding sample in examples/dwebp.c which will take a .webp file and
+decode it to a PNG image file (amongst other formats). This is simply to
+demonstrate the use of the API. You can verify the file test.webp decodes to
+exactly the same as test_ref.ppm by using:
+
+```shell
+cd examples
+./dwebp test.webp -ppm -o test.ppm
+diff test.ppm test_ref.ppm
+```
+
+The full list of options is available using -h:
+
+```shell
+> dwebp -h
+Usage: dwebp in_file [options] [-o out_file]
+```
+
+Decodes the WebP image file to PNG format [Default]. Note: Animated WebP files
+are not supported.
+
+Use following options to convert into alternate image formats:
+
+```
+-pam ......... save the raw RGBA samples as a color PAM
+-ppm ......... save the raw RGB samples as a color PPM
+-bmp ......... save as uncompressed BMP format
+-tiff ........ save as uncompressed TIFF format
+-pgm ......... save the raw YUV samples as a grayscale PGM
+               file with IMC4 layout
+-yuv ......... save the raw YUV samples in flat layout
+```
+
+Other options are:
+
+```
+-version ..... print version number and exit
+-nofancy ..... don't use the fancy YUV420 upscaler
+-nofilter .... disable in-loop filtering
+-nodither .... disable dithering
+-dither <d> .. dithering strength (in 0..100)
+-alpha_dither  use alpha-plane dithering if needed
+-mt .......... use multi-threading
+-crop <x> <y> <w> <h> ... crop output with the given rectangle
+-resize <w> <h> ......... resize output (*after* any cropping)
+-flip ........ flip the output vertically
+-alpha ....... only save the alpha plane
+-incremental . use incremental decoding (useful for tests)
+-h ........... this help message
+-v ........... verbose (e.g. print encoding/decoding times)
+-quiet ....... quiet mode, don't print anything
+-noasm ....... disable all assembly optimizations
+```
+
+## WebP file analysis tool
+
+`webpinfo` can be used to print out the chunk level structure and bitstream
+header information of WebP files. It can also check if the files are of valid
+WebP format.
+
+Usage:
+
+```shell
+webpinfo [options] in_files
+```
+
+Note: there could be multiple input files; options must come before input files.
+
+Options:
+
+```
+-version ........... Print version number and exit.
+-quiet ............. Do not show chunk parsing information.
+-diag .............. Show parsing error diagnosis.
+-summary ........... Show chunk stats summary.
+-bitstream_info .... Parse bitstream header.
+```
+
+## Visualization tool
+
+There's a little self-serve visualization tool called 'vwebp' under the
+examples/ directory. It uses OpenGL to open a simple drawing window and show a
+decoded WebP file. It's not yet integrated in the automake build system, but you
+can try to manually compile it using the recommendations below.
+
+Usage:
+
+```shell
+vwebp in_file [options]
+```
+
+Decodes the WebP image file and visualize it using OpenGL
+
+Options are:
+
+```
+-version ..... print version number and exit
+-noicc ....... don't use the icc profile if present
+-nofancy ..... don't use the fancy YUV420 upscaler
+-nofilter .... disable in-loop filtering
+-dither <int>  dithering strength (0..100), default=50
+-noalphadither disable alpha plane dithering
+-usebgcolor .. display background color
+-mt .......... use multi-threading
+-info ........ print info
+-h ........... this help message
+```
+
+Keyboard shortcuts:
+
+```
+'c' ................ toggle use of color profile
+'b' ................ toggle background color display
+'i' ................ overlay file information
+'d' ................ disable blending & disposal (debug)
+'q' / 'Q' / ESC .... quit
+```
+
+### Building
+
+Prerequisites:
+
+1.  OpenGL & OpenGL Utility Toolkit (GLUT)
+
+    Linux: `sudo apt-get install freeglut3-dev mesa-common-dev`
+
+    Mac + Xcode: These libraries should be available in the OpenGL / GLUT
+    frameworks.
+
+    Windows: http://freeglut.sourceforge.net/index.php#download
+
+2.  (Optional) qcms (Quick Color Management System)
+
+    1.  Download qcms from Mozilla / Chromium:
+        https://hg.mozilla.org/mozilla-central/file/0e7639e3bdfb/gfx/qcms
+        https://source.chromium.org/chromium/chromium/src/+/main:third_party/qcms/;drc=d4a2f8e1ed461d8fc05ed88d1ae2dc94c9773825
+    2.  Build and archive the source files as libqcms.a / qcms.lib
+    3.  Update makefile.unix / Makefile.vc
+        1.  Define WEBP_HAVE_QCMS
+        2.  Update include / library paths to reference the qcms directory.
+
+Build using makefile.unix / Makefile.vc:
+
+```shell
+$ make -f makefile.unix examples/vwebp
+> nmake /f Makefile.vc CFG=release-static \
+    ../obj/x64/release-static/bin/vwebp.exe
+```
+
+## Animation creation tool
+
+The utility `img2webp` can turn a sequence of input images (PNG, JPEG, ...) into
+an animated WebP file. It offers fine control over duration, encoding modes,
+etc.
+
+Usage:
+
+```shell
+img2webp [file_options] [[frame_options] frame_file]... [-o webp_file]
+```
+
+File-level options (only used at the start of compression):
+
+```
+-min_size ............ minimize size
+-kmax <int> .......... maximum number of frame between key-frames
+                        (0=only keyframes)
+-kmin <int> .......... minimum number of frame between key-frames
+                        (0=disable key-frames altogether)
+-mixed ............... use mixed lossy/lossless automatic mode
+-near_lossless <int> . use near-lossless image preprocessing
+                       (0..100=off), default=100
+-sharp_yuv ........... use sharper (and slower) RGB->YUV conversion
+                       (lossy only)
+-loop <int> .......... loop count (default: 0, = infinite loop)
+-v ................... verbose mode
+-h ................... this help
+-version ............. print version number and exit
+```
+
+Per-frame options (only used for subsequent images input):
+
+```
+-d <int> ............. frame duration in ms (default: 100)
+-lossless  ........... use lossless mode (default)
+-lossy ... ........... use lossy mode
+-q <float> ........... quality
+-m <int> ............. method to use
+```
+
+example: `img2webp -loop 2 in0.png -lossy in1.jpg -d 80 in2.tiff -o out.webp`
+
+Note: if a single file name is passed as the argument, the arguments will be
+tokenized from this file. The file name must not start with the character '-'.
+
+## Animated GIF conversion
+
+Animated GIF files can be converted to WebP files with animation using the
+gif2webp utility available under examples/. The files can then be viewed using
+vwebp.
+
+Usage:
+
+```shell
+gif2webp [options] gif_file -o webp_file
+```
+
+Options:
+
+```
+-h / -help ............. this help
+-lossy ................. encode image using lossy compression
+-mixed ................. for each frame in the image, pick lossy
+                         or lossless compression heuristically
+-q <float> ............. quality factor (0:small..100:big)
+-m <int> ............... compression method (0=fast, 6=slowest)
+-min_size .............. minimize output size (default:off)
+                         lossless compression by default; can be
+                         combined with -q, -m, -lossy or -mixed
+                         options
+-kmin <int> ............ min distance between key frames
+-kmax <int> ............ max distance between key frames
+-f <int> ............... filter strength (0=off..100)
+-metadata <string> ..... comma separated list of metadata to
+                         copy from the input to the output if present
+                         Valid values: all, none, icc, xmp (default)
+-loop_compatibility .... use compatibility mode for Chrome
+                         version prior to M62 (inclusive)
+-mt .................... use multi-threading if available
+
+-version ............... print version number and exit
+-v ..................... verbose
+-quiet ................. don't print anything
+```
+
+### Building
+
+With the libgif development files installed, gif2webp can be built using
+makefile.unix:
+
+```shell
+$ make -f makefile.unix examples/gif2webp
+```
+
+or using autoconf:
+
+```shell
+$ ./configure --enable-everything
+$ make
+```
+
+## Comparison of animated images
+
+Test utility anim_diff under examples/ can be used to compare two animated
+images (each can be GIF or WebP).
+
+Usage:
+
+```shell
+anim_diff <image1> <image2> [options]
+```
+
+Options:
+
+```
+-dump_frames <folder> dump decoded frames in PAM format
+-min_psnr <float> ... minimum per-frame PSNR
+-raw_comparison ..... if this flag is not used, RGB is
+                      premultiplied before comparison
+-max_diff <int> ..... maximum allowed difference per channel
+                      between corresponding pixels in subsequent
+                      frames
+-h .................. this help
+-version ............ print version number and exit
+```
+
+### Building
+
+With the libgif development files installed, anim_diff can be built using
+makefile.unix:
+
+```shell
+$ make -f makefile.unix examples/anim_diff
+```
+
+or using autoconf:
+
+```shell
+$ ./configure --enable-everything
+$ make
+```
+
+## WebP Mux tool
+
+The examples/ directory contains a tool (webpmux) for manipulating WebP files.
+The webpmux tool can be used to create an extended format WebP file and also to
+extract or strip relevant data from such a file.
+
+A list of options is available using the -help command line flag:
+
+```shell
+> webpmux -help
+Usage: webpmux -get GET_OPTIONS INPUT -o OUTPUT
+       webpmux -set SET_OPTIONS INPUT -o OUTPUT
+       webpmux -duration DURATION_OPTIONS [-duration ...]
+               INPUT -o OUTPUT
+       webpmux -strip STRIP_OPTIONS INPUT -o OUTPUT
+       webpmux -frame FRAME_OPTIONS [-frame...] [-loop LOOP_COUNT]
+               [-bgcolor BACKGROUND_COLOR] -o OUTPUT
+       webpmux -info INPUT
+       webpmux [-h|-help]
+       webpmux -version
+       webpmux argument_file_name
+
+GET_OPTIONS:
+ Extract relevant data:
+   icc       get ICC profile
+   exif      get EXIF metadata
+   xmp       get XMP metadata
+   frame n   get nth frame
+
+SET_OPTIONS:
+ Set color profile/metadata/parameters:
+   loop LOOP_COUNT            set the loop count
+   bgcolor BACKGROUND_COLOR   set the animation background color
+   icc  file.icc              set ICC profile
+   exif file.exif             set EXIF metadata
+   xmp  file.xmp              set XMP metadata
+   where:    'file.icc' contains the ICC profile to be set,
+             'file.exif' contains the EXIF metadata to be set
+             'file.xmp' contains the XMP metadata to be set
+
+DURATION_OPTIONS:
+ Set duration of selected frames:
+   duration            set duration for all frames
+   duration,frame      set duration of a particular frame
+   duration,start,end  set duration of frames in the
+                        interval [start,end])
+   where: 'duration' is the duration in milliseconds
+          'start' is the start frame index
+          'end' is the inclusive end frame index
+           The special 'end' value '0' means: last frame.
+
+STRIP_OPTIONS:
+ Strip color profile/metadata:
+   icc       strip ICC profile
+   exif      strip EXIF metadata
+   xmp       strip XMP metadata
+
+FRAME_OPTIONS(i):
+ Create animation:
+   file_i +di[+xi+yi[+mi[bi]]]
+   where:    'file_i' is the i'th animation frame (WebP format),
+             'di' is the pause duration before next frame,
+             'xi','yi' specify the image offset for this frame,
+             'mi' is the dispose method for this frame (0 or 1),
+             'bi' is the blending method for this frame (+b or -b)
+
+LOOP_COUNT:
+ Number of times to repeat the animation.
+ Valid range is 0 to 65535 [Default: 0 (infinite)].
+
+BACKGROUND_COLOR:
+ Background color of the canvas.
+  A,R,G,B
+  where:    'A', 'R', 'G' and 'B' are integers in the range 0 to 255 specifying
+            the Alpha, Red, Green and Blue component values respectively
+            [Default: 255,255,255,255]
+
+INPUT & OUTPUT are in WebP format.
+
+Note: The nature of EXIF, XMP and ICC data is not checked and is assumed to be
+valid.
+
+Note: if a single file name is passed as the argument, the arguments will be
+tokenized from this file. The file name must not start with the character '-'.
+```

+ 168 - 119
webp.mod/libwebp/doc/webp-container-spec.txt

@@ -4,8 +4,8 @@ Although you may be viewing an alternate representation, this document
 is sourced in Markdown, a light-duty markup scheme, and is optimized for
 the [kramdown](https://kramdown.gettalong.org/) transformer.
 
-See the accompanying README. External link targets are referenced at the
-end of this file.
+See the accompanying specs_generation.md. External link targets are referenced
+at the end of this file.
 
 -->
 
@@ -20,25 +20,25 @@ WebP Container Specification
 Introduction
 ------------
 
-WebP is an image format that uses either (i) the VP8 key frame encoding
-to compress image data in a lossy way, or (ii) the WebP lossless encoding
-(and possibly other encodings in the future). These encoding schemes should
-make it more efficient than currently used formats. It is optimized for fast
-image transfer over the network (e.g., for websites). The WebP format has
-feature parity (color profile, metadata, animation etc) with other formats as
-well. This document describes the structure of a WebP file.
+WebP is an image format that uses either (i) the VP8 key frame encoding to
+compress image data in a lossy way, or (ii) the WebP lossless encoding. These
+encoding schemes should make it more efficient than older formats such as JPEG,
+GIF and PNG. It is optimized for fast image transfer over the network (for
+example, for websites). The WebP format has feature parity (color profile,
+metadata, animation, etc.) with other formats as well. This document describes
+the structure of a WebP file.
 
-The WebP container (i.e., RIFF container for WebP) allows feature support over
-and above the basic use case of WebP (i.e., a file containing a single image
-encoded as a VP8 key frame). The WebP container provides additional support
-for:
+The WebP container (that is, the RIFF container for WebP) allows feature support
+over and above the basic use case of WebP (that is, a file containing a single
+image encoded as a VP8 key frame). The WebP container provides additional
+support for:
 
   * **Lossless compression.** An image can be losslessly compressed, using the
     WebP Lossless Format.
 
-  * **Metadata.** An image may have metadata stored in EXIF or XMP formats.
+  * **Metadata.** An image may have metadata stored in Exif or XMP formats.
 
-  * **Transparency.** An image may have transparency, i.e., an alpha channel.
+  * **Transparency.** An image may have transparency, that is, an alpha channel.
 
   * **Color Profile.** An image may have an embedded ICC profile as described
     by the [International Color Consortium][iccspec].
@@ -46,20 +46,21 @@ for:
   * **Animation.** An image may have multiple frames with pauses between them,
     making it an animation.
 
-The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
-"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
-document are to be interpreted as described in [RFC 2119][].
+The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD",
+"SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this
+document are to be interpreted as described in BCP 14 [RFC 2119][] [RFC 8174][]
+when, and only when, they appear in all capitals, as shown here.
 
 Bit numbering in chunk diagrams starts at `0` for the most significant bit
 ('MSB 0') as described in [RFC 1166][].
 
-Terminology &amp; Basics
-------------------------
+Terminology & Basics
+--------------------
 
-A WebP file contains either a still image (i.e., an encoded matrix of pixels)
+A WebP file contains either a still image (that is, an encoded matrix of pixels)
 or an [animation](#animation). Optionally, it can also contain transparency
-information, color profile and metadata. In case we need to refer only to the
-matrix of pixels, we will call it the _canvas_ of the image.
+information, color profile and metadata. We refer to the matrix of pixels as the
+_canvas_ of the image.
 
 Below are additional terms used throughout this document:
 
@@ -83,18 +84,25 @@ _uint32_
 _FourCC_
 
 : A _FourCC_ (four-character code) is a _uint32_ created by concatenating four
-  ASCII characters in little-endian order.
+  ASCII characters in little-endian order. This means 'aaaa' (0x61616161) and
+ 'AAAA' (0x41414141) are treated as different _FourCCs_.
 
 _1-based_
 
-: An unsigned integer field storing values offset by `-1`. e.g., Such a field
-  would store value _25_ as _24_.
+: An unsigned integer field storing values offset by `-1`, for example, such a
+  field would store value _25_ as _24_.
+
+_ChunkHeader('ABCD')_
+
+: This is used to describe the _FourCC_ and _Chunk Size_ header of individual
+  chunks, where 'ABCD' is the FourCC for the chunk. This element's size is 8
+  bytes.
 
 
 RIFF File Format
 ----------------
 
-The WebP file format is based on the RIFF (resource interchange file format)
+The WebP file format is based on the RIFF (Resource Interchange File Format)
 document format.
 
 The basic element of a RIFF file is a _chunk_. It consists of:
@@ -106,7 +114,7 @@ The basic element of a RIFF file is a _chunk_. It consists of:
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |                          Chunk Size                           |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-    |                         Chunk Payload                         |
+    :                         Chunk Payload                         :
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 
 Chunk FourCC: 32 bits
@@ -115,19 +123,13 @@ Chunk FourCC: 32 bits
 
 Chunk Size: 32 bits (_uint32_)
 
-: The size of the chunk not including this field, the chunk identifier or
-  padding.
+: The size of the chunk in bytes, not including this field, the chunk
+  identifier or padding.
 
 Chunk Payload: _Chunk Size_ bytes
 
-: The data payload. If _Chunk Size_ is odd, a single padding byte -- that
-  SHOULD be `0` -- is added.
-
-_ChunkHeader('ABCD')_
-
-: This is used to describe the _FourCC_ and _Chunk Size_ header of individual
-  chunks, where 'ABCD' is the FourCC for the chunk. This element's
-  size is 8 bytes.
+: The data payload. If _Chunk Size_ is odd, a single padding byte -- that MUST
+  be `0` to conform with RIFF -- is added.
 
 **Note:** RIFF has a convention that all-uppercase chunk FourCCs are standard
 chunks that apply to any RIFF file format, while FourCCs specific to a file
@@ -163,9 +165,11 @@ File Size: 32 bits (_uint32_)
 
 A WebP file MUST begin with a RIFF header with the FourCC 'WEBP'. The file size
 in the header is the total size of the chunks that follow plus `4` bytes for
-the 'WEBP' FourCC. The file SHOULD NOT contain anything after it. As the size
-of any chunk is even, the size given by the RIFF header is also even. The
-contents of individual chunks will be described in the following sections.
+the 'WEBP' FourCC. The file SHOULD NOT contain any data after the data
+specified by _File Size_. Readers MAY parse such files, ignoring the trailing
+data. As the size of any chunk is even, the size given by the RIFF header is
+also even. The contents of individual chunks are described in the following
+sections.
 
 
 Simple File Format (Lossy)
@@ -180,9 +184,11 @@ Simple WebP (lossy) file format:
      0                   1                   2                   3
      0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+    |                                                               |
     |                    WebP file header (12 bytes)                |
+    |                                                               |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-    |                          VP8 chunk                            |
+    :                          VP8 chunk                            :
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 
 VP8 chunk:
@@ -191,20 +197,24 @@ VP8 chunk:
      0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |                      ChunkHeader('VP8 ')                      |
+    |                                                               |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-    |                           VP8 data                            |
+    :                           VP8 data                            :
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 
 VP8 data: _Chunk Size_ bytes
 
 : VP8 bitstream data.
 
+Note the fourth character in the 'VP8 ' FourCC is an ASCII space (0x20).
+
 The VP8 bitstream format specification can be found at [VP8 Data Format and
 Decoding Guide][vp8spec]. Note that the VP8 frame header contains the VP8 frame
 width and height. That is assumed to be the width and height of the canvas.
 
-The VP8 specification describes how to decode the image into Y'CbCr
-format. To convert to RGB, Rec. 601 SHOULD be used.
+The VP8 specification describes how to decode the image into Y'CbCr format. To
+convert to RGB, Rec. 601 SHOULD be used. Applications MAY use another
+conversion method, but visual results may differ among decoders.
 
 
 Simple File Format (Lossless)
@@ -221,9 +231,11 @@ Simple WebP (lossless) file format:
      0                   1                   2                   3
      0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+    |                                                               |
     |                    WebP file header (12 bytes)                |
+    |                                                               |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-    |                          VP8L chunk                           |
+    :                          VP8L chunk                           :
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 
 VP8L chunk:
@@ -232,8 +244,9 @@ VP8L chunk:
      0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |                      ChunkHeader('VP8L')                      |
+    |                                                               |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-    |                           VP8L data                           |
+    :                           VP8L data                           :
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 
 VP8L data: _Chunk Size_ bytes
@@ -261,7 +274,7 @@ An extended format file consists of:
 
   * Image data.
 
-  * An optional 'EXIF' chunk with EXIF metadata.
+  * An optional 'EXIF' chunk with Exif metadata.
 
   * An optional 'XMP ' chunk with XMP metadata.
 
@@ -279,7 +292,7 @@ details about frames can be found in the [Animation](#animation) section.
 
 All chunks SHOULD be placed in the same order as listed above. If a chunk
 appears in the wrong place, the file is invalid, but readers MAY parse the
-file, ignoring the chunks that come too late.
+file, ignoring the chunks that are out of order.
 
 **Rationale:** Setting the order of chunks should allow quicker file
 parsing. For example, if an 'ALPH' chunk does not appear in its required
@@ -293,9 +306,12 @@ Extended WebP file header:
      0                   1                   2                   3
      0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+    |                                                               |
     |                   WebP file header (12 bytes)                 |
+    |                                                               |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |                      ChunkHeader('VP8X')                      |
+    |                                                               |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |Rsv|I|L|E|X|A|R|                   Reserved                    |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
@@ -306,7 +322,7 @@ Extended WebP file header:
 
 Reserved (Rsv): 2 bits
 
-: SHOULD be `0`.
+: MUST be `0`. Readers MUST ignore this field.
 
 ICC profile (I): 1 bit
 
@@ -317,9 +333,9 @@ Alpha (L): 1 bit
 : Set if any of the frames of the image contain transparency information
   ("alpha").
 
-EXIF metadata (E): 1 bit
+Exif metadata (E): 1 bit
 
-: Set if the file contains EXIF metadata.
+: Set if the file contains Exif metadata.
 
 XMP metadata (X): 1 bit
 
@@ -332,25 +348,25 @@ Animation (A): 1 bit
 
 Reserved (R): 1 bit
 
-: SHOULD be `0`.
+: MUST be `0`. Readers MUST ignore this field.
 
 Reserved: 24 bits
 
-: SHOULD be `0`.
+: MUST be `0`. Readers MUST ignore this field.
 
 Canvas Width Minus One: 24 bits
 
 : _1-based_ width of the canvas in pixels.
-  The actual canvas width is '1 + Canvas Width Minus One'
+  The actual canvas width is `1 + Canvas Width Minus One`.
 
 Canvas Height Minus One: 24 bits
 
 : _1-based_ height of the canvas in pixels.
-  The actual canvas height is '1 + Canvas Height Minus One'
+  The actual canvas height is `1 + Canvas Height Minus One`.
 
 The product of _Canvas Width_ and _Canvas Height_ MUST be at most `2^32 - 1`.
 
-Future specifications MAY add more fields.
+Future specifications may add more fields. Unknown fields MUST be ignored.
 
 ### Chunks
 
@@ -368,6 +384,7 @@ animation.
      0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |                      ChunkHeader('ANIM')                      |
+    |                                                               |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |                       Background Color                        |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
@@ -383,8 +400,8 @@ Background Color: 32 bits (_uint32_)
 
 **Note**:
 
-  * Background color MAY contain a transparency value (alpha), even if the
-    _Alpha_ flag in [VP8X chunk](#extended_header) is unset.
+  * Background color MAY contain a non-opaque alpha value, even if the _Alpha_
+    flag in [VP8X chunk](#extended_header) is unset.
 
   * Viewer applications SHOULD treat the background color value as a hint, and
     are not required to use it.
@@ -397,8 +414,8 @@ Loop Count: 16 bits (_uint16_)
 : The number of times to loop the animation. `0` means infinitely.
 
 This chunk MUST appear if the _Animation_ flag in the VP8X chunk is set.
-If the _Animation_ flag is not set and this chunk is present, it
-SHOULD be ignored.
+If the _Animation_ flag is not set and this chunk is present, it MUST be
+ignored.
 
 ANMF chunk:
 
@@ -409,6 +426,7 @@ If the _Animation flag_ is not set, then this chunk SHOULD NOT be present.
      0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |                      ChunkHeader('ANMF')                      |
+    |                                                               |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |                        Frame X                |             ...
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
@@ -418,26 +436,26 @@ If the _Animation flag_ is not set, then this chunk SHOULD NOT be present.
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |                 Frame Duration                |  Reserved |B|D|
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-    |                         Frame Data                            |
+    :                         Frame Data                            :
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 
 Frame X: 24 bits (_uint24_)
 
-: The X coordinate of the upper left corner of the frame is `Frame X * 2`
+: The X coordinate of the upper left corner of the frame is `Frame X * 2`.
 
 Frame Y: 24 bits (_uint24_)
 
-: The Y coordinate of the upper left corner of the frame is `Frame Y * 2`
+: The Y coordinate of the upper left corner of the frame is `Frame Y * 2`.
 
 Frame Width Minus One: 24 bits (_uint24_)
 
 : The _1-based_ width of the frame.
-  The frame width is `1 + Frame Width Minus One`
+  The frame width is `1 + Frame Width Minus One`.
 
 Frame Height Minus One: 24 bits (_uint24_)
 
 : The _1-based_ height of the frame.
-  The frame height is `1 + Frame Height Minus One`
+  The frame height is `1 + Frame Height Minus One`.
 
 Frame Duration: 24 bits (_uint24_)
 
@@ -448,7 +466,7 @@ Frame Duration: 24 bits (_uint24_)
 
 Reserved: 6 bits
 
-: SHOULD be 0.
+: MUST be `0`. Readers MUST ignore this field.
 
 Blending method (B): 1 bit
 
@@ -493,8 +511,9 @@ Disposal method (D): 1 bit
     if blend.A = 0 then
       blend.RGB = 0
     else
-      blend.RGB = (src.RGB * src.A +
-                   dst.RGB * dst.A * (1 - src.A / 255)) / blend.A
+      blend.RGB =
+          (src.RGB * src.A +
+           dst.RGB * dst.A * (1 - src.A / 255)) / blend.A
 ~~~~~
 
   * Alpha-blending SHOULD be done in linear color space, by taking into account
@@ -521,22 +540,23 @@ _padded_ chunks as described by the [RIFF file format](#riff-file-format).
      0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |                      ChunkHeader('ALPH')                      |
+    |                                                               |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |Rsv| P | F | C |     Alpha Bitstream...                        |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 
 Reserved (Rsv): 2 bits
 
-: SHOULD be `0`.
+: MUST be `0`. Readers MUST ignore this field.
 
 Pre-processing (P): 2 bits
 
-: These INFORMATIVE bits are used to signal the pre-processing that has
+: These _informative_ bits are used to signal the pre-processing that has
   been performed during compression. The decoder can use this information to
-  e.g. dither the values or smooth the gradients prior to display.
+  for example, dither the values or smooth the gradients prior to display.
 
-    * `0`: no pre-processing
-    * `1`: level reduction
+    * `0`: No pre-processing.
+    * `1`: Level reduction.
 
 Filtering method (F): 2 bits
 
@@ -569,14 +589,14 @@ where `clip(v)` is equal to:
   * v    otherwise
 
 The final value is derived by adding the decompressed value `X` to the
-predictor and using modulo-256 arithmetic to wrap the \[256-511\] range
-into the \[0-255\] one:
+predictor and using modulo-256 arithmetic to wrap the \[256..511\] range
+into the \[0..255\] one:
 
 `alpha = (predictor + X) % 256`
 
-There are special cases for left-most and top-most pixel positions:
+There are special cases for the left-most and top-most pixel positions:
 
-  * Top-left value at location (0,0) uses 0 as predictor value. Otherwise,
+  * The top-left value at location (0, 0) uses 0 as predictor value. Otherwise,
   * For horizontal or gradient filtering methods, the left-most pixels at
     location (0, y) are predicted using the location (0, y-1) just above.
   * For vertical or gradient filtering methods, the top-most pixels at
@@ -638,14 +658,15 @@ The formats of VP8 and VP8L chunks are as described in sections
 [Simple File Format (Lossy)](#simple-file-format-lossy)
 and [Simple File Format (Lossless)](#simple-file-format-lossless) respectively.
 
-#### Color profile
+#### Color Profile
 
      0                   1                   2                   3
      0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |                      ChunkHeader('ICCP')                      |
+    |                                                               |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-    |                       Color Profile                           |
+    :                       Color Profile                           :
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 
 Color Profile: _Chunk Size_ bytes
@@ -665,8 +686,7 @@ If this chunk is not present, sRGB SHOULD be assumed.
 Metadata can be stored in 'EXIF' or 'XMP ' chunks.
 
 There SHOULD be at most one chunk of each type ('EXIF' and 'XMP '). If there
-are more such chunks, readers MAY ignore all except the first one. Also, a file
-may possibly contain both 'EXIF' and 'XMP ' chunks.
+are more such chunks, readers MAY ignore all except the first one.
 
 The chunks are defined as follows:
 
@@ -676,13 +696,14 @@ EXIF chunk:
      0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |                      ChunkHeader('EXIF')                      |
+    |                                                               |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-    |                        EXIF Metadata                          |
+    :                        Exif Metadata                          :
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 
-EXIF Metadata: _Chunk Size_ bytes
+Exif Metadata: _Chunk Size_ bytes
 
-: image metadata in EXIF format.
+: Image metadata in Exif format.
 
 XMP chunk:
 
@@ -690,13 +711,16 @@ XMP chunk:
      0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |                      ChunkHeader('XMP ')                      |
+    |                                                               |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-    |                        XMP Metadata                           |
+    :                        XMP Metadata                           :
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 
 XMP Metadata: _Chunk Size_ bytes
 
-: image metadata in XMP format.
+: Image metadata in XMP format.
+
+Note the fourth character in the 'XMP ' FourCC is an ASCII space (0x20).
 
 Additional guidance about handling metadata can be found in the
 Metadata Working Group's [Guidelines for Handling Metadata][metadata].
@@ -720,49 +744,73 @@ A file MAY contain unknown chunks:
 Readers SHOULD ignore these chunks. Writers SHOULD preserve them in their
 original order (unless they specifically intend to modify these chunks).
 
-### Assembling the Canvas from frames
+### Assembling the Canvas From Frames
+
+Here we provide an overview of how a reader MUST assemble a canvas in the case
+of an animated image.
+
+The process begins with creating a canvas using the dimensions given in the
+'VP8X' chunk, `Canvas Width Minus One + 1` pixels wide by `Canvas Height Minus
+One + 1` pixels high. The `Loop Count` field from the 'ANIM' chunk controls how
+many times the animation process is repeated. This is `Loop Count - 1` for
+non-zero `Loop Count` values or infinitely if `Loop Count` is zero.
+
+At the beginning of each loop iteration the canvas is filled using the
+background color from the 'ANIM' chunk or an application defined color.
+
+'ANMF' chunks contain individual frames given in display order. Before rendering
+each frame, the previous frame's `Disposal method` is applied.
+
+The rendering of the decoded frame begins at the Cartesian coordinates (`2 *
+Frame X`, `2 * Frame Y`) using the top-left corner of the canvas as the origin.
+`Frame Width Minus One + 1` pixels wide by `Frame Height Minus One + 1` pixels
+high are rendered onto the canvas using the `Blending method`.
 
-Here we provide an overview of how a reader should assemble a canvas in the
-case of an animated image. The notation _VP8X.field_ means the field in the
-'VP8X' chunk with the same description.
+The canvas is displayed for `Frame Duration` milliseconds. This continues until
+all frames given by 'ANMF' chunks have been displayed. A new loop iteration is
+then begun or the canvas is left in its final state if all iterations have been
+completed.
 
-Displaying an _animated image_ canvas MUST be equivalent to the following
-pseudocode:
+The following pseudocode illustrates the rendering process. The notation
+_VP8X.field_ means the field in the 'VP8X' chunk with the same description.
 
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 assert VP8X.flags.hasAnimation
 canvas ← new image of size VP8X.canvasWidth x VP8X.canvasHeight with
          background color ANIM.background_color.
 loop_count ← ANIM.loopCount
-dispose_method ← ANIM.disposeMethod
+dispose_method ← Dispose to background color
 if loop_count == 0:
-    loop_count = ∞
+  loop_count = ∞
 frame_params ← nil
 assert next chunk in image_data is ANMF
 for loop = 0..loop_count - 1
-    clear canvas to ANIM.background_color or application defined color
-    until eof or non-ANMF chunk
-        frame_params.frameX = Frame X
-        frame_params.frameY = Frame Y
-        frame_params.frameWidth = Frame Width Minus One + 1
-        frame_params.frameHeight = Frame Height Minus One + 1
-        frame_params.frameDuration = Frame Duration
-        frame_right = frame_params.frameX + frame_params.frameWidth
-        frame_bottom = frame_params.frameY + frame_params.frameHeight
-        assert VP8X.canvasWidth >= frame_right
-        assert VP8X.canvasHeight >= frame_bottom
-        for subchunk in 'Frame Data':
-            if subchunk.tag == "ALPH":
-                assert alpha subchunks not found in 'Frame Data' earlier
-                frame_params.alpha = alpha_data
-            else if subchunk.tag == "VP8 " OR subchunk.tag == "VP8L":
-                assert bitstream subchunks not found in 'Frame Data' earlier
-                frame_params.bitstream = bitstream_data
-        render frame with frame_params.alpha and frame_params.bitstream on
-            canvas with top-left corner at (frame_params.frameX,
-            frame_params.frameY), using dispose method dispose_method.
-        canvas contains the decoded image.
-        Show the contents of the canvas for frame_params.frameDuration * 1ms.
+  clear canvas to ANIM.background_color or application defined color
+  until eof or non-ANMF chunk
+    frame_params.frameX = Frame X
+    frame_params.frameY = Frame Y
+    frame_params.frameWidth = Frame Width Minus One + 1
+    frame_params.frameHeight = Frame Height Minus One + 1
+    frame_params.frameDuration = Frame Duration
+    frame_right = frame_params.frameX + frame_params.frameWidth
+    frame_bottom = frame_params.frameY + frame_params.frameHeight
+    assert VP8X.canvasWidth >= frame_right
+    assert VP8X.canvasHeight >= frame_bottom
+    for subchunk in 'Frame Data':
+      if subchunk.tag == "ALPH":
+        assert alpha subchunks not found in 'Frame Data' earlier
+        frame_params.alpha = alpha_data
+      else if subchunk.tag == "VP8 " OR subchunk.tag == "VP8L":
+        assert bitstream subchunks not found in 'Frame Data' earlier
+        frame_params.bitstream = bitstream_data
+    render frame with frame_params.alpha and frame_params.bitstream
+      on canvas with top-left corner at (frame_params.frameX,
+      frame_params.frameY), using blending method
+      frame_params.blendingMethod.
+    canvas contains the decoded image.
+    Show the contents of the canvas for
+    frame_params.frameDuration * 1ms.
+    dispose_method = frame_params.disposeMethod
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 
@@ -798,7 +846,7 @@ RIFF/WEBP
 +- XMP  (metadata)
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-An animated image with EXIF metadata may look as follows:
+An animated image with Exif metadata may look as follows:
 
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 RIFF/WEBP
@@ -817,3 +865,4 @@ RIFF/WEBP
 [metadata]: https://web.archive.org/web/20180919181934/http://www.metadataworkinggroup.org/pdf/mwg_guidance.pdf
 [rfc 1166]: https://datatracker.ietf.org/doc/html/rfc1166
 [rfc 2119]: https://datatracker.ietf.org/doc/html/rfc2119
+[rfc 8174]: https://datatracker.ietf.org/doc/html/rfc8174

File diff suppressed because it is too large
+ 516 - 412
webp.mod/libwebp/doc/webp-lossless-bitstream-spec.txt


+ 3 - 0
webp.mod/libwebp/examples/Android.mk

@@ -1,3 +1,5 @@
+# Ignore this file during non-NDK builds.
+ifdef NDK_ROOT
 LOCAL_PATH := $(call my-dir)
 
 ################################################################################
@@ -91,3 +93,4 @@ LOCAL_STATIC_LIBRARIES := example_util imageio_util webp
 LOCAL_MODULE := webpinfo_example
 
 include $(BUILD_EXECUTABLE)
+endif  # NDK_ROOT

+ 2 - 2
webp.mod/libwebp/examples/Makefile.am

@@ -47,7 +47,7 @@ anim_dump_LDADD += ../imageio/libimageenc.la
 anim_dump_LDADD += $(PNG_LIBS) $(GIF_LIBS) $(TIFF_LIBS) -lm
 
 cwebp_SOURCES  = cwebp.c stopwatch.h
-cwebp_CPPFLAGS  = $(AM_CPPFLAGS)
+cwebp_CPPFLAGS  = $(AM_CPPFLAGS) -I$(top_srcdir)
 cwebp_LDADD  =
 cwebp_LDADD += libexample_util.la
 cwebp_LDADD += ../imageio/libimageio_util.la
@@ -92,7 +92,7 @@ webpmux_LDADD += ../src/mux/libwebpmux.la
 webpmux_LDADD += ../src/libwebp.la
 
 img2webp_SOURCES = img2webp.c
-img2webp_CPPFLAGS = $(AM_CPPFLAGS)
+img2webp_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_srcdir)
 img2webp_LDADD  =
 img2webp_LDADD += libexample_util.la
 img2webp_LDADD += ../imageio/libimageio_util.la

+ 5 - 2
webp.mod/libwebp/examples/anim_util.c

@@ -241,7 +241,7 @@ static int ReadAnimatedWebP(const char filename[],
   image->bgcolor = anim_info.bgcolor;
 
   // Allocate frames.
-  if (!AllocateFrames(image, anim_info.frame_count)) return 0;
+  if (!AllocateFrames(image, anim_info.frame_count)) goto End;
 
   // Decode frames.
   while (WebPAnimDecoderHasMoreFrames(dec)) {
@@ -558,7 +558,10 @@ static int ReadAnimatedGIF(const char filename[], AnimatedImage* const image,
     }
   }
   // Allocate frames.
-  AllocateFrames(image, frame_count);
+  if (!AllocateFrames(image, frame_count)) {
+    DGifCloseFile(gif, NULL);
+    return 0;
+  }
 
   canvas_width = image->canvas_width;
   canvas_height = image->canvas_height;

+ 13 - 7
webp.mod/libwebp/examples/cwebp.c

@@ -27,6 +27,7 @@
 #include "../imageio/webpdec.h"
 #include "./stopwatch.h"
 #include "./unicode.h"
+#include "sharpyuv/sharpyuv.h"
 #include "webp/encode.h"
 
 #ifndef WEBP_DLL
@@ -571,7 +572,7 @@ static void HelpLong(void) {
   printf("  -qrange <min> <max> .... specifies the permissible quality range\n"
          "                           (default: 0 100)\n");
   printf("  -crop <x> <y> <w> <h> .. crop picture with the given rectangle\n");
-  printf("  -resize <w> <h> ........ resize picture (after any cropping)\n");
+  printf("  -resize <w> <h> ........ resize picture (*after* any cropping)\n");
   printf("  -mt .................... use multi-threading if available\n");
   printf("  -low_memory ............ reduce memory usage (slower encoding)\n");
   printf("  -map <int> ............. print map of extra info\n");
@@ -591,9 +592,8 @@ static void HelpLong(void) {
          "                           green=0xe0 and blue=0xd0\n");
   printf("  -noalpha ............... discard any transparency information\n");
   printf("  -lossless .............. encode image losslessly, default=off\n");
-  printf("  -near_lossless <int> ... use near-lossless image\n"
-         "                           preprocessing (0..100=off), "
-         "default=100\n");
+  printf("  -near_lossless <int> ... use near-lossless image preprocessing\n"
+         "                           (0..100=off), default=100\n");
   printf("  -hint <string> ......... specify image characteristics hint,\n");
   printf("                           one of: photo, picture or graph\n");
 
@@ -620,6 +620,7 @@ static void HelpLong(void) {
   printf("  -af .................... auto-adjust filter strength\n");
   printf("  -pre <int> ............. pre-processing filter\n");
   printf("\n");
+  printf("Supported input formats:\n  %s\n", WebPGetEnabledInputFileFormats());
 }
 
 //------------------------------------------------------------------------------
@@ -831,8 +832,12 @@ int main(int argc, const char* argv[]) {
 #endif
     } else if (!strcmp(argv[c], "-version")) {
       const int version = WebPGetEncoderVersion();
+      const int sharpyuv_version = SharpYuvGetVersion();
       printf("%d.%d.%d\n",
              (version >> 16) & 0xff, (version >> 8) & 0xff, version & 0xff);
+      printf("libsharpyuv: %d.%d.%d\n",
+             (sharpyuv_version >> 24) & 0xff, (sharpyuv_version >> 16) & 0xffff,
+             sharpyuv_version & 0xff);
       FREE_WARGV_AND_RETURN(0);
     } else if (!strcmp(argv[c], "-progress")) {
       show_progress = 1;
@@ -1139,9 +1144,10 @@ int main(int argc, const char* argv[]) {
       }
 
       picture.use_argb = 1;
-      if (!ReadWebP(memory_writer.mem, memory_writer.size, &picture,
-                    /*keep_alpha=*/WebPPictureHasTransparency(&picture),
-                    /*metadata=*/NULL)) {
+      if (!ReadWebP(
+              memory_writer.mem, memory_writer.size, &picture,
+              /*keep_alpha=*/WebPPictureHasTransparency(&original_picture),
+              /*metadata=*/NULL)) {
         fprintf(stderr, "Error! Cannot decode encoded WebP bitstream\n");
         fprintf(stderr, "Error code: %d (%s)\n", picture.error_code,
                 kErrorMessages[picture.error_code]);

+ 1 - 1
webp.mod/libwebp/examples/dwebp.c

@@ -96,7 +96,7 @@ static void Help(void) {
          "  -alpha_dither  use alpha-plane dithering if needed\n"
          "  -mt .......... use multi-threading\n"
          "  -crop <x> <y> <w> <h> ... crop output with the given rectangle\n"
-         "  -resize <w> <h> ......... scale the output (*after* any cropping)\n"
+         "  -resize <w> <h> ......... resize output (*after* any cropping)\n"
          "  -flip ........ flip the output vertically\n"
          "  -alpha ....... only save the alpha plane\n"
          "  -incremental . use incremental decoding (useful for tests)\n"

+ 5 - 1
webp.mod/libwebp/examples/example_util.c

@@ -103,7 +103,10 @@ int ExUtilInitCommandLineArguments(int argc, const char* argv[],
     }
     args->own_argv_ = 1;
     args->argv_ = (const char**)WebPMalloc(MAX_ARGC * sizeof(*args->argv_));
-    if (args->argv_ == NULL) return 0;
+    if (args->argv_ == NULL) {
+      ExUtilDeleteCommandLineArguments(args);
+      return 0;
+    }
 
     argc = 0;
     for (cur = strtok((char*)args->argv_data_.bytes, sep);
@@ -111,6 +114,7 @@ int ExUtilInitCommandLineArguments(int argc, const char* argv[],
          cur = strtok(NULL, sep)) {
       if (argc == MAX_ARGC) {
         fprintf(stderr, "ERROR: Arguments limit %d reached\n", MAX_ARGC);
+        ExUtilDeleteCommandLineArguments(args);
         return 0;
       }
       assert(strlen(cur) != 0);

+ 5 - 2
webp.mod/libwebp/examples/gif2webp.c

@@ -314,8 +314,11 @@ int main(int argc, const char* argv[]) {
           frame.use_argb = 1;
           if (!WebPPictureAlloc(&frame)) goto End;
           GIFClearPic(&frame, NULL);
-          WebPPictureCopy(&frame, &curr_canvas);
-          WebPPictureCopy(&frame, &prev_canvas);
+          if (!(WebPPictureCopy(&frame, &curr_canvas) &&
+                WebPPictureCopy(&frame, &prev_canvas))) {
+            fprintf(stderr, "Error allocating canvas.\n");
+            goto End;
+          }
 
           // Background color.
           GIFGetBackgroundColor(gif->SColorMap, gif->SBackGroundColor,

+ 20 - 4
webp.mod/libwebp/examples/img2webp.c

@@ -28,6 +28,7 @@
 #include "../imageio/imageio_util.h"
 #include "./stopwatch.h"
 #include "./unicode.h"
+#include "sharpyuv/sharpyuv.h"
 #include "webp/encode.h"
 #include "webp/mux.h"
 
@@ -35,17 +36,22 @@
 
 static void Help(void) {
   printf("Usage:\n\n");
-  printf("  img2webp [file_options] [[frame_options] frame_file]...\n");
-  printf("\n");
+  printf("  img2webp [file_options] [[frame_options] frame_file]...");
+  printf(" [-o webp_file]\n\n");
 
   printf("File-level options (only used at the start of compression):\n");
   printf(" -min_size ............ minimize size\n");
-  printf(" -loop <int> .......... loop count (default: 0, = infinite loop)\n");
   printf(" -kmax <int> .......... maximum number of frame between key-frames\n"
          "                        (0=only keyframes)\n");
   printf(" -kmin <int> .......... minimum number of frame between key-frames\n"
          "                        (0=disable key-frames altogether)\n");
   printf(" -mixed ............... use mixed lossy/lossless automatic mode\n");
+  printf(" -near_lossless <int> . use near-lossless image preprocessing\n"
+         "                        (0..100=off), default=100\n");
+  printf(" -sharp_yuv ........... use sharper (and slower) RGB->YUV "
+                                  "conversion\n                        "
+                                  "(lossy only)\n");
+  printf(" -loop <int> .......... loop count (default: 0, = infinite loop)\n");
   printf(" -v ................... verbose mode\n");
   printf(" -h ................... this help\n");
   printf(" -version ............. print version number and exit\n");
@@ -65,6 +71,8 @@ static void Help(void) {
          "arguments will be\n");
   printf("tokenized from this file. The file name must not start with "
          "the character '-'.\n");
+  printf("\nSupported input formats:\n  %s\n",
+         WebPGetEnabledInputFileFormats());
 }
 
 //------------------------------------------------------------------------------
@@ -182,18 +190,26 @@ int main(int argc, const char* argv[]) {
       } else if (!strcmp(argv[c], "-mixed")) {
         anim_config.allow_mixed = 1;
         config.lossless = 0;
+      } else if (!strcmp(argv[c], "-near_lossless") && c + 1 < argc) {
+        argv[c] = NULL;
+        config.near_lossless = ExUtilGetInt(argv[++c], 0, &parse_error);
+      } else if (!strcmp(argv[c], "-sharp_yuv")) {
+        config.use_sharp_yuv = 1;
       } else if (!strcmp(argv[c], "-v")) {
         verbose = 1;
       } else if (!strcmp(argv[c], "-h") || !strcmp(argv[c], "-help")) {
         Help();
-        goto End;
+        FREE_WARGV_AND_RETURN(0);
       } else if (!strcmp(argv[c], "-version")) {
         const int enc_version = WebPGetEncoderVersion();
         const int mux_version = WebPGetMuxVersion();
+        const int sharpyuv_version = SharpYuvGetVersion();
         printf("WebP Encoder version: %d.%d.%d\nWebP Mux version: %d.%d.%d\n",
                (enc_version >> 16) & 0xff, (enc_version >> 8) & 0xff,
                enc_version & 0xff, (mux_version >> 16) & 0xff,
                (mux_version >> 8) & 0xff, mux_version & 0xff);
+        printf("libsharpyuv: %d.%d.%d\n", (sharpyuv_version >> 24) & 0xff,
+               (sharpyuv_version >> 16) & 0xffff, sharpyuv_version & 0xff);
         goto End;
       } else {
         continue;

+ 17 - 3
webp.mod/libwebp/examples/unicode.h

@@ -16,11 +16,15 @@
 #ifndef WEBP_EXAMPLES_UNICODE_H_
 #define WEBP_EXAMPLES_UNICODE_H_
 
+#include <stdio.h>
+
 #if defined(_WIN32) && defined(_UNICODE)
 
 // wchar_t is used instead of TCHAR because we only perform additional work when
 // Unicode is enabled and because the output of CommandLineToArgvW() is wchar_t.
 
+#include <fcntl.h>
+#include <io.h>
 #include <wchar.h>
 #include <windows.h>
 #include <shellapi.h>
@@ -55,8 +59,16 @@
 
 #define WFOPEN(ARG, OPT) _wfopen((const W_CHAR*)ARG, TO_W_CHAR(OPT))
 
-#define WPRINTF(STR, ...) wprintf(TO_W_CHAR(STR), __VA_ARGS__)
-#define WFPRINTF(STDERR, STR, ...) fwprintf(STDERR, TO_W_CHAR(STR), __VA_ARGS__)
+#define WFPRINTF(STREAM, STR, ...)                    \
+  do {                                                \
+    int prev_mode;                                    \
+    fflush(STREAM);                                   \
+    prev_mode = _setmode(_fileno(STREAM), _O_U8TEXT); \
+    fwprintf(STREAM, TO_W_CHAR(STR), __VA_ARGS__);    \
+    fflush(STREAM);                                   \
+    (void)_setmode(_fileno(STREAM), prev_mode);       \
+  } while (0)
+#define WPRINTF(STR, ...) WFPRINTF(stdout, STR, __VA_ARGS__)
 
 #define WSTRLEN(FILENAME) wcslen((const W_CHAR*)FILENAME)
 #define WSTRCMP(FILENAME, STR) wcscmp((const W_CHAR*)FILENAME, TO_W_CHAR(STR))
@@ -65,6 +77,8 @@
 
 #else
 
+#include <string.h>
+
 // Unicode file paths work as is on Unix platforms, and no extra work is done on
 // Windows either if Unicode is disabled.
 
@@ -83,7 +97,7 @@
 #define WFOPEN(ARG, OPT) fopen(ARG, OPT)
 
 #define WPRINTF(STR, ...) printf(STR, __VA_ARGS__)
-#define WFPRINTF(STDERR, STR, ...) fprintf(STDERR, STR, __VA_ARGS__)
+#define WFPRINTF(STREAM, STR, ...) fprintf(STREAM, STR, __VA_ARGS__)
 
 #define WSTRLEN(FILENAME) strlen(FILENAME)
 #define WSTRCMP(FILENAME, STR) strcmp(FILENAME, STR)

+ 9 - 8
webp.mod/libwebp/examples/unicode_gif.h

@@ -45,18 +45,19 @@ static GifFileType* DGifOpenFileUnicode(const W_CHAR* file_name, int* error) {
   }
 
 #if defined(_WIN32) && defined(_UNICODE)
-
-  int file_handle = _wopen(file_name, _O_RDONLY | _O_BINARY);
-  if (file_handle == -1) {
-    if (error != NULL) *error = D_GIF_ERR_OPEN_FAILED;
-    return NULL;
-  }
+  {
+    int file_handle = _wopen(file_name, _O_RDONLY | _O_BINARY);
+    if (file_handle == -1) {
+      if (error != NULL) *error = D_GIF_ERR_OPEN_FAILED;
+      return NULL;
+    }
 
 #if LOCAL_GIF_PREREQ(5, 0)
-  return DGifOpenFileHandle(file_handle, error);
+    return DGifOpenFileHandle(file_handle, error);
 #else
-  return DGifOpenFileHandle(file_handle);
+    return DGifOpenFileHandle(file_handle);
 #endif
+  }
 
 #else
 

+ 14 - 1
webp.mod/libwebp/examples/vwebp.c

@@ -292,6 +292,19 @@ static void PrintString(const char* const text) {
   }
 }
 
+static void PrintStringW(const char* const text) {
+#if defined(_WIN32) && defined(_UNICODE)
+  void* const font = GLUT_BITMAP_9_BY_15;
+  const W_CHAR* const wtext = (const W_CHAR*)text;
+  int i;
+  for (i = 0; wtext[i]; ++i) {
+    glutBitmapCharacter(font, wtext[i]);
+  }
+#else
+  PrintString(text);
+#endif
+}
+
 static float GetColorf(uint32_t color, int shift) {
   return ((color >> shift) & 0xff) / 255.f;
 }
@@ -396,7 +409,7 @@ static void HandleDisplay(void) {
 
     glColor4f(0.90f, 0.0f, 0.90f, 1.0f);
     glRasterPos2f(-0.95f, 0.90f);
-    PrintString(kParams.file_name);
+    PrintStringW(kParams.file_name);
 
     snprintf(tmp, sizeof(tmp), "Dimension:%d x %d", pic->width, pic->height);
     glColor4f(0.90f, 0.0f, 0.90f, 1.0f);

+ 5 - 4
webp.mod/libwebp/examples/webpmux.c

@@ -329,7 +329,7 @@ static void PrintHelp(void) {
   printf("\n");
   printf("DURATION_OPTIONS:\n");
   printf(" Set duration of selected frames:\n");
-  printf("   duration            set duration for each frames\n");
+  printf("   duration            set duration for all frames\n");
   printf("   duration,frame      set duration of a particular frame\n");
   printf("   duration,start,end  set duration of frames in the\n");
   printf("                        interval [start,end])\n");
@@ -348,7 +348,7 @@ static void PrintHelp(void) {
   printf("\n");
   printf("FRAME_OPTIONS(i):\n");
   printf(" Create animation:\n");
-  printf("   file_i +di+[xi+yi[+mi[bi]]]\n");
+  printf("   file_i +di[+xi+yi[+mi[bi]]]\n");
   printf("   where:    'file_i' is the i'th animation frame (WebP format),\n");
   printf("             'di' is the pause duration before next frame,\n");
   printf("             'xi','yi' specify the image offset for this frame,\n");
@@ -460,7 +460,8 @@ static WebPMux* DuplicateMuxHeader(const WebPMux* const mux) {
     if (err == WEBP_MUX_OK && metadata.size > 0) {
       err = WebPMuxSetChunk(new_mux, kFourccList[i], &metadata, 1);
       if (err != WEBP_MUX_OK) {
-        ERROR_GOTO1("Error transferring metadata in DuplicateMux().", End);
+        ERROR_GOTO1("Error transferring metadata in DuplicateMuxHeader().",
+                    End);
       }
     }
   }
@@ -684,7 +685,7 @@ static int ParseCommandLine(Config* config, const W_CHAR** const unicode_argv) {
           ERROR_GOTO1("ERROR: Multiple features specified.\n", ErrParse);
         }
         arg->subtype_ = SUBTYPE_ANMF;
-        arg->filename_ = argv[i + 1];
+        arg->filename_ = wargv[i + 1];
         arg->params_ = argv[i + 2];
         ++feature_arg_index;
         i += 3;

+ 2 - 2
webp.mod/libwebp/extras/extras.c

@@ -18,8 +18,8 @@
 #include <string.h>
 
 #define XTRA_MAJ_VERSION 1
-#define XTRA_MIN_VERSION 2
-#define XTRA_REV_VERSION 1
+#define XTRA_MIN_VERSION 3
+#define XTRA_REV_VERSION 2
 
 //------------------------------------------------------------------------------
 

+ 2 - 1
webp.mod/libwebp/extras/get_disto.c

@@ -223,7 +223,8 @@ static void Help(void) {
           "  -o <file> . save the diff map as a WebP lossless file\n"
           "  -scale .... scale the difference map to fit [0..255] range\n"
           "  -gray ..... use grayscale for difference map (-scale)\n"
-          " Also handles PNG, JPG and TIFF files, in addition to WebP.\n");
+          "\nSupported input formats:\n  %s\n",
+          WebPGetEnabledInputFileFormats());
 }
 
 int main(int argc, const char* argv[]) {

+ 1 - 1
webp.mod/libwebp/extras/vwebp_sdl.c

@@ -75,7 +75,7 @@ int main(int argc, char* argv[]) {
       fprintf(stderr, "File too large.\n");
       goto Error;
     }
-    ok = WebpToSDL((const char*)webp, (int)webp_size);
+    ok = WebPToSDL((const char*)webp, (int)webp_size);
     free((void*)webp);
     if (!ok) {
       WFPRINTF(stderr, "Error decoding file %s\n", (const W_CHAR*)file);

+ 1 - 1
webp.mod/libwebp/extras/webp_to_sdl.c

@@ -29,7 +29,7 @@
 #endif
 
 static int init_ok = 0;
-int WebpToSDL(const char* data, unsigned int data_size) {
+int WebPToSDL(const char* data, unsigned int data_size) {
   int ok = 0;
   VP8StatusCode status;
   WebPDecoderConfig config;

+ 2 - 2
webp.mod/libwebp/extras/webp_to_sdl.h

@@ -14,9 +14,9 @@
 #ifndef WEBP_EXTRAS_WEBP_TO_SDL_H_
 #define WEBP_EXTRAS_WEBP_TO_SDL_H_
 
-// Exports the method WebpToSDL(const char* data, int data_size) which decodes
+// Exports the method WebPToSDL(const char* data, int data_size) which decodes
 // a WebP bitstream into an RGBA SDL surface.
 // Return false on failure.
-extern int WebpToSDL(const char* data, unsigned int data_size);
+extern int WebPToSDL(const char* data, unsigned int data_size);
 
 #endif  // WEBP_EXTRAS_WEBP_TO_SDL_H_

+ 3 - 0
webp.mod/libwebp/imageio/Android.mk

@@ -1,3 +1,5 @@
+# Ignore this file during non-NDK builds.
+ifdef NDK_ROOT
 LOCAL_PATH := $(call my-dir)
 
 ################################################################################
@@ -52,3 +54,4 @@ LOCAL_STATIC_LIBRARIES := imageio_util
 LOCAL_MODULE := imageenc
 
 include $(BUILD_STATIC_LIBRARY)
+endif  # NDK_ROOT

+ 18 - 0
webp.mod/libwebp/imageio/image_dec.c

@@ -11,6 +11,24 @@
 
 #include "./image_dec.h"
 
+const char* WebPGetEnabledInputFileFormats(void) {
+  return "WebP"
+#ifdef WEBP_HAVE_JPEG
+         ", JPEG"
+#endif
+#ifdef WEBP_HAVE_PNG
+         ", PNG"
+#endif
+         ", PNM (PGM, PPM, PAM)"
+#ifdef WEBP_HAVE_TIFF
+         ", TIFF"
+#endif
+#ifdef HAVE_WINCODEC_H
+         ", Windows Imaging Component (WIC)"
+#endif
+         "";
+}
+
 static WEBP_INLINE uint32_t GetBE32(const uint8_t buf[]) {
   return ((uint32_t)buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
 }

+ 3 - 0
webp.mod/libwebp/imageio/image_dec.h

@@ -41,6 +41,9 @@ typedef enum {
   WEBP_UNSUPPORTED_FORMAT
 } WebPInputFileFormat;
 
+// Returns a comma separated list of enabled input formats.
+const char* WebPGetEnabledInputFileFormats(void);
+
 // Try to infer the image format. 'data_size' should be larger than 12.
 // Returns WEBP_UNSUPPORTED_FORMAT if format can't be guess safely.
 WebPInputFileFormat WebPGuessImageType(const uint8_t* const data,

+ 23 - 12
webp.mod/libwebp/imageio/image_enc.c

@@ -280,7 +280,7 @@ int WebPWrite16bAsPGM(FILE* fout, const WebPDecBuffer* const buffer) {
 }
 
 //------------------------------------------------------------------------------
-// BMP
+// BMP (see https://en.wikipedia.org/wiki/BMP_file_format#Pixel_storage)
 
 static void PutLE16(uint8_t* const dst, uint32_t value) {
   dst[0] = (value >> 0) & 0xff;
@@ -293,8 +293,11 @@ static void PutLE32(uint8_t* const dst, uint32_t value) {
 }
 
 #define BMP_HEADER_SIZE 54
+#define BMP_HEADER_ALPHA_EXTRA_SIZE 16  // for alpha info
 int WebPWriteBMP(FILE* fout, const WebPDecBuffer* const buffer) {
   const int has_alpha = WebPIsAlphaMode(buffer->colorspace);
+  const int header_size =
+      BMP_HEADER_SIZE + (has_alpha ? BMP_HEADER_ALPHA_EXTRA_SIZE : 0);
   const uint32_t width = buffer->width;
   const uint32_t height = buffer->height;
   const uint8_t* rgba = buffer->u.RGBA.rgba;
@@ -303,8 +306,9 @@ int WebPWriteBMP(FILE* fout, const WebPDecBuffer* const buffer) {
   uint32_t y;
   const uint32_t line_size = bytes_per_px * width;
   const uint32_t bmp_stride = (line_size + 3) & ~3;   // pad to 4
-  const uint32_t total_size = bmp_stride * height + BMP_HEADER_SIZE;
-  uint8_t bmp_header[BMP_HEADER_SIZE] = { 0 };
+  const uint32_t image_size = bmp_stride * height;
+  const uint32_t total_size =  image_size + header_size;
+  uint8_t bmp_header[BMP_HEADER_SIZE + BMP_HEADER_ALPHA_EXTRA_SIZE] = { 0 };
 
   if (fout == NULL || buffer == NULL || rgba == NULL) return 0;
 
@@ -312,30 +316,37 @@ int WebPWriteBMP(FILE* fout, const WebPDecBuffer* const buffer) {
   PutLE16(bmp_header + 0, 0x4d42);                // signature 'BM'
   PutLE32(bmp_header + 2, total_size);            // size including header
   PutLE32(bmp_header + 6, 0);                     // reserved
-  PutLE32(bmp_header + 10, BMP_HEADER_SIZE);      // offset to pixel array
+  PutLE32(bmp_header + 10, header_size);          // offset to pixel array
   // bitmap info header
-  PutLE32(bmp_header + 14, 40);                   // DIB header size
+  PutLE32(bmp_header + 14, header_size - 14);     // DIB header size
   PutLE32(bmp_header + 18, width);                // dimensions
-  PutLE32(bmp_header + 22, -(int)height);         // vertical flip!
+  PutLE32(bmp_header + 22, height);               // no vertical flip
   PutLE16(bmp_header + 26, 1);                    // number of planes
   PutLE16(bmp_header + 28, bytes_per_px * 8);     // bits per pixel
-  PutLE32(bmp_header + 30, 0);                    // no compression (BI_RGB)
-  PutLE32(bmp_header + 34, 0);                    // image size (placeholder)
+  PutLE32(bmp_header + 30, has_alpha ? 3 : 0);    // BI_BITFIELDS or BI_RGB
+  PutLE32(bmp_header + 34, image_size);
   PutLE32(bmp_header + 38, 2400);                 // x pixels/meter
   PutLE32(bmp_header + 42, 2400);                 // y pixels/meter
   PutLE32(bmp_header + 46, 0);                    // number of palette colors
   PutLE32(bmp_header + 50, 0);                    // important color count
+  if (has_alpha) {  // BITMAPV3INFOHEADER complement
+    PutLE32(bmp_header + 54, 0x00ff0000);         // red mask
+    PutLE32(bmp_header + 58, 0x0000ff00);         // green mask
+    PutLE32(bmp_header + 62, 0x000000ff);         // blue mask
+    PutLE32(bmp_header + 66, 0xff000000);         // alpha mask
+  }
 
   // TODO(skal): color profile
 
   // write header
-  if (fwrite(bmp_header, sizeof(bmp_header), 1, fout) != 1) {
+  if (fwrite(bmp_header, header_size, 1, fout) != 1) {
     return 0;
   }
 
-  // write pixel array
+  // write pixel array, bottom to top
   for (y = 0; y < height; ++y) {
-    if (fwrite(rgba, line_size, 1, fout) != 1) {
+    const uint8_t* const src = &rgba[(uint64_t)(height - 1 - y) * stride];
+    if (fwrite(src, line_size, 1, fout) != 1) {
       return 0;
     }
     // write padding zeroes
@@ -345,11 +356,11 @@ int WebPWriteBMP(FILE* fout, const WebPDecBuffer* const buffer) {
         return 0;
       }
     }
-    rgba += stride;
   }
   return 1;
 }
 #undef BMP_HEADER_SIZE
+#undef BMP_HEADER_ALPHA_EXTRA_SIZE
 
 //------------------------------------------------------------------------------
 // TIFF

+ 5 - 1
webp.mod/libwebp/imageio/jpegdec.c

@@ -336,7 +336,11 @@ int ReadJPEG(const uint8_t* const data, size_t data_size,
   pic->width = width;
   pic->height = height;
   ok = WebPPictureImportRGB(pic, rgb, (int)stride);
-  if (!ok) goto Error;
+  if (!ok) {
+    pic->width = 0;   // WebPPictureImportRGB() barely touches 'pic' on failure.
+    pic->height = 0;  // Just reset dimensions but keep any 'custom_ptr' etc.
+    MetadataFree(metadata);  // In case the caller forgets to free it on error.
+  }
 
  End:
   free(rgb);

+ 8 - 8
webp.mod/libwebp/imageio/pngdec.c

@@ -235,7 +235,7 @@ int ReadPNG(const uint8_t* const data, size_t data_size,
   volatile png_infop end_info = NULL;
   PNGReadContext context = { NULL, 0, 0 };
   int color_type, bit_depth, interlaced;
-  int has_alpha;
+  int num_channels;
   int num_passes;
   int p;
   volatile int ok = 0;
@@ -293,9 +293,6 @@ int ReadPNG(const uint8_t* const data, size_t data_size,
   }
   if (png_get_valid(png, info, PNG_INFO_tRNS)) {
     png_set_tRNS_to_alpha(png);
-    has_alpha = 1;
-  } else {
-    has_alpha = !!(color_type & PNG_COLOR_MASK_ALPHA);
   }
 
   // Apply gamma correction if needed.
@@ -310,13 +307,16 @@ int ReadPNG(const uint8_t* const data, size_t data_size,
 
   if (!keep_alpha) {
     png_set_strip_alpha(png);
-    has_alpha = 0;
   }
 
   num_passes = png_set_interlace_handling(png);
   png_read_update_info(png, info);
 
-  stride = (int64_t)(has_alpha ? 4 : 3) * width * sizeof(*rgb);
+  num_channels = png_get_channels(png, info);
+  if (num_channels != 3 && num_channels != 4) {
+    goto Error;
+  }
+  stride = (int64_t)num_channels * width * sizeof(*rgb);
   if (stride != (int)stride ||
       !ImgIoUtilCheckSizeArgumentsOverflow(stride, height)) {
     goto Error;
@@ -341,8 +341,8 @@ int ReadPNG(const uint8_t* const data, size_t data_size,
 
   pic->width = (int)width;
   pic->height = (int)height;
-  ok = has_alpha ? WebPPictureImportRGBA(pic, rgb, (int)stride)
-                 : WebPPictureImportRGB(pic, rgb, (int)stride);
+  ok = (num_channels == 4) ? WebPPictureImportRGBA(pic, rgb, (int)stride)
+                           : WebPPictureImportRGB(pic, rgb, (int)stride);
 
   if (!ok) {
     goto Error;

+ 6 - 1
webp.mod/libwebp/imageio/pnmdec.c

@@ -20,6 +20,10 @@
 #include "webp/encode.h"
 #include "./imageio_util.h"
 
+#if defined(_MSC_VER) && _MSC_VER < 1900
+#define snprintf _snprintf
+#endif
+
 typedef enum {
   WIDTH_FLAG      = 1 << 0,
   HEIGHT_FLAG     = 1 << 1,
@@ -111,8 +115,9 @@ static size_t ReadPAMFields(PNMInfo* const info, size_t off) {
       break;
     } else {
       static const char kEllipsis[] = " ...";
+      const size_t kLen = strlen(kEllipsis) + 1;  // +1 = trailing \0
       int i;
-      if (out_size > 20) sprintf(out + 20 - strlen(kEllipsis), kEllipsis);
+      if (out_size > 20) snprintf(out + 20 - kLen, kLen, kEllipsis);
       for (i = 0; i < (int)strlen(out); ++i) {
         // isprint() might trigger a "char-subscripts" warning if given a char.
         if (!isprint((int)out[i])) out[i] = ' ';

+ 4 - 2
webp.mod/libwebp/imageio/tiffdec.c

@@ -188,7 +188,9 @@ int ReadTIFF(const uint8_t* const data, size_t data_size,
     fprintf(stderr, "Error! Cannot retrieve TIFF samples-per-pixel info.\n");
     goto End;
   }
-  if (samples_per_px < 3 || samples_per_px > 4) goto End;  // not supported
+  if (!(samples_per_px == 1 || samples_per_px == 3 || samples_per_px == 4)) {
+    goto End;  // not supported
+  }
 
   if (!(TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &image_width) &&
         TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &image_height))) {
@@ -212,7 +214,7 @@ int ReadTIFF(const uint8_t* const data, size_t data_size,
       TIFFGetField(tif, TIFFTAG_TILELENGTH, &tile_height)) {
     if ((tile_width > 32 && tile_width / 2 > image_width) ||
         (tile_height > 32 && tile_height / 2 > image_height) ||
-        ImgIoUtilCheckSizeArgumentsOverflow(
+        !ImgIoUtilCheckSizeArgumentsOverflow(
             (uint64_t)tile_width * sizeof(*raster), tile_height)) {
       fprintf(stderr, "Error! TIFF tile dimension (%d x %d) is too large.\n",
               tile_width, tile_height);

+ 2 - 2
webp.mod/libwebp/infra/run_static_analysis.sh

@@ -85,10 +85,10 @@ scan_build make -j4
 
 index="$(find "${OUTPUT_DIR}" -name index.html)"
 if [[ -f "${index}" ]]; then
-  mv "$(dirname "${index}")/"* .
+  mv "$(dirname "${index}")/"* "${OUTPUT_DIR}"
 else
   # make a empty report to wipe out any old bug reports.
-  cat << EOT > index.html
+  cat << EOT > "${OUTPUT_DIR}/index.html"
 <html>
 <body>
 No bugs reported.

+ 3 - 5
webp.mod/libwebp/iosbuild.sh

@@ -133,10 +133,9 @@ for PLATFORM in ${PLATFORMS}; do
     CFLAGS="${CFLAGS}"
   set +x
 
-  # run make only in the src/ directory to create libwebp.a/libwebpdecoder.a
-  cd src/
-  make V=0
-  make install
+  # Build only the libraries, skip the examples.
+  make V=0 -C sharpyuv
+  make V=0 -C src install
 
   LIBLIST+=" ${ROOTDIR}/lib/libwebp.a"
   DECLIBLIST+=" ${ROOTDIR}/lib/libwebpdecoder.a"
@@ -144,7 +143,6 @@ for PLATFORM in ${PLATFORMS}; do
   DEMUXLIBLIST+=" ${ROOTDIR}/lib/libwebpdemux.a"
 
   make clean
-  cd ..
 
   export PATH=${OLDPATH}
 done

+ 40 - 5
webp.mod/libwebp/makefile.unix

@@ -3,7 +3,8 @@
 # It will not install the libraries system-wide, but just create the 'cwebp'
 # and 'dwebp' tools in the examples/ directory, along with the static
 # libraries 'src/libwebp.a', 'src/libwebpdecoder.a', 'src/mux/libwebpmux.a',
-# 'src/demux/libwebpdemux.a' and 'extras/libwebpextras.a'.
+# 'src/demux/libwebpdemux.a', 'extras/libwebpextras.a' and
+# 'sharpyuv/libsharpyuv.a'.
 #
 # To build the library and examples, use:
 #    make -f makefile.unix
@@ -125,6 +126,15 @@ endif
 ANIM_UTIL_OBJS = \
     examples/anim_util.o \
 
+SHARPYUV_OBJS = \
+    sharpyuv/sharpyuv.o \
+    sharpyuv/sharpyuv_cpu.o \
+    sharpyuv/sharpyuv_csp.o \
+    sharpyuv/sharpyuv_dsp.o \
+    sharpyuv/sharpyuv_gamma.o \
+    sharpyuv/sharpyuv_neon.o \
+    sharpyuv/sharpyuv_sse2.o \
+
 DEC_OBJS = \
     src/dec/alpha_dec.o \
     src/dec/buffer_dec.o \
@@ -282,11 +292,12 @@ EXTRA_OBJS = \
     extras/quality_estimate.o \
 
 LIBWEBPDECODER_OBJS = $(DEC_OBJS) $(DSP_DEC_OBJS) $(UTILS_DEC_OBJS)
-LIBWEBP_OBJS = $(LIBWEBPDECODER_OBJS) $(ENC_OBJS) $(DSP_ENC_OBJS) \
-               $(UTILS_ENC_OBJS)
+LIBWEBP_OBJS = $(LIBWEBPDECODER_OBJS) $(ENC_OBJS) \
+               $(DSP_ENC_OBJS) $(UTILS_ENC_OBJS)
 LIBWEBPMUX_OBJS = $(MUX_OBJS)
 LIBWEBPDEMUX_OBJS = $(DEMUX_OBJS)
 LIBWEBPEXTRA_OBJS = $(EXTRA_OBJS)
+LIBSHARPYUV_OBJS = $(SHARPYUV_OBJS)
 
 HDRS_INSTALLED = \
     src/webp/decode.h \
@@ -296,6 +307,11 @@ HDRS_INSTALLED = \
     src/webp/mux_types.h \
     src/webp/types.h \
 
+SHARPYUV_HDRS_INSTALLED = \
+    sharpyuv/sharpyuv.h \
+    sharpyuv/sharpyuv_cpu.h \
+    sharpyuv/sharpyuv_csp.h \
+
 HDRS = \
     src/dec/alphai_dec.h \
     src/dec/common_dec.h \
@@ -304,6 +320,7 @@ HDRS = \
     src/dec/vp8li_dec.h \
     src/dec/webpi_dec.h \
     src/dsp/common_sse2.h \
+    src/dsp/cpu.h \
     src/dsp/dsp.h \
     src/dsp/lossless.h \
     src/dsp/lossless_common.h \
@@ -334,6 +351,7 @@ HDRS = \
     src/utils/utils.h \
     src/webp/format_constants.h \
     $(HDRS_INSTALLED) \
+    $(SHARPYUV_HDRS_INSTALLED) \
 
 OUT_LIBS = examples/libexample_util.a
 OUT_LIBS += imageio/libimageio_util.a
@@ -341,6 +359,7 @@ OUT_LIBS += imageio/libimagedec.a
 OUT_LIBS += imageio/libimageenc.a
 OUT_LIBS += src/libwebpdecoder.a
 OUT_LIBS += src/libwebp.a
+OUT_LIBS += sharpyuv/libsharpyuv.a
 EXTRA_LIB = extras/libwebpextras.a
 OUT_EXAMPLES = examples/cwebp examples/dwebp
 EXTRA_EXAMPLES = examples/gif2webp examples/vwebp examples/webpmux \
@@ -386,6 +405,7 @@ src/libwebpdecoder.a: $(LIBWEBPDECODER_OBJS)
 src/libwebp.a: $(LIBWEBP_OBJS)
 src/mux/libwebpmux.a: $(LIBWEBPMUX_OBJS)
 src/demux/libwebpdemux.a: $(LIBWEBPDEMUX_OBJS)
+sharpyuv/libsharpyuv.a: $(LIBSHARPYUV_OBJS)
 
 %.a:
 	$(AR) $(ARFLAGS) $@ $^
@@ -403,6 +423,7 @@ examples/webpinfo: examples/webpinfo.o
 examples/anim_diff: examples/libanim_util.a examples/libgifdec.a
 examples/anim_diff: src/demux/libwebpdemux.a examples/libexample_util.a
 examples/anim_diff: imageio/libimageio_util.a src/libwebp.a
+examples/anim_diff: sharpyuv/libsharpyuv.a
 examples/anim_diff: override EXTRA_LIBS += $(GIF_LIBS)
 examples/anim_diff: EXTRA_FLAGS += -DWEBP_HAVE_GIF
 examples/anim_dump: examples/libanim_util.a examples/libgifdec.a
@@ -411,12 +432,14 @@ examples/anim_dump: examples/libexample_util.a
 examples/anim_dump: imageio/libimageio_util.a
 examples/anim_dump: imageio/libimageenc.a
 examples/anim_dump: src/libwebp.a
+examples/anim_dump: sharpyuv/libsharpyuv.a
 examples/anim_dump: override EXTRA_LIBS += $(GIF_LIBS) $(DWEBP_LIBS)
 examples/cwebp: examples/libexample_util.a
 examples/cwebp: imageio/libimagedec.a
 examples/cwebp: src/demux/libwebpdemux.a
 examples/cwebp: imageio/libimageio_util.a
 examples/cwebp: src/libwebp.a
+examples/cwebp: sharpyuv/libsharpyuv.a
 examples/cwebp: override EXTRA_LIBS += $(CWEBP_LIBS)
 examples/dwebp: examples/libexample_util.a
 examples/dwebp: imageio/libimagedec.a
@@ -424,13 +447,16 @@ examples/dwebp: src/demux/libwebpdemux.a
 examples/dwebp: imageio/libimageenc.a
 examples/dwebp: imageio/libimageio_util.a
 examples/dwebp: src/libwebp.a
+examples/dwebp: sharpyuv/libsharpyuv.a
 examples/dwebp: override EXTRA_LIBS += $(DWEBP_LIBS)
 examples/gif2webp: examples/libexample_util.a imageio/libimageio_util.a
 examples/gif2webp: examples/libgifdec.a src/mux/libwebpmux.a src/libwebp.a
+examples/gif2webp: sharpyuv/libsharpyuv.a
 examples/gif2webp: override EXTRA_LIBS += $(GIF_LIBS)
 examples/gif2webp: EXTRA_FLAGS += -DWEBP_HAVE_GIF
 examples/vwebp: examples/libexample_util.a src/demux/libwebpdemux.a
 examples/vwebp: imageio/libimageio_util.a src/libwebp.a
+examples/vwebp: sharpyuv/libsharpyuv.a
 examples/vwebp: override EXTRA_LIBS += $(GL_LIBS)
 examples/vwebp: EXTRA_FLAGS += -DWEBP_HAVE_GL
 examples/webpmux: examples/libexample_util.a imageio/libimageio_util.a
@@ -438,7 +464,9 @@ examples/webpmux: src/mux/libwebpmux.a src/libwebpdecoder.a
 examples/img2webp: examples/libexample_util.a imageio/libimageio_util.a
 examples/img2webp: imageio/libimagedec.a
 examples/img2webp: src/demux/libwebpdemux.a
-examples/img2webp: src/mux/libwebpmux.a src/libwebp.a
+examples/img2webp: src/mux/libwebpmux.a
+examples/img2webp: src/libwebp.a
+examples/img2webp: sharpyuv/libsharpyuv.a
 examples/img2webp: override EXTRA_LIBS += $(CWEBP_LIBS)
 examples/webpinfo: examples/libexample_util.a imageio/libimageio_util.a
 examples/webpinfo: src/libwebpdecoder.a
@@ -448,16 +476,19 @@ extras/get_disto: imageio/libimagedec.a
 extras/get_disto: src/demux/libwebpdemux.a
 extras/get_disto: imageio/libimageio_util.a
 extras/get_disto: src/libwebp.a
+extras/get_disto: sharpyuv/libsharpyuv.a
 extras/get_disto: override EXTRA_LIBS += $(CWEBP_LIBS)
 
 extras/webp_quality: extras/webp_quality.o
 extras/webp_quality: imageio/libimageio_util.a
 extras/webp_quality: $(EXTRA_LIB) src/libwebp.a
+extras/webp_quality: sharpyuv/libsharpyuv.a
 
 extras/vwebp_sdl: extras/vwebp_sdl.o
 extras/vwebp_sdl: extras/webp_to_sdl.o
 extras/vwebp_sdl: imageio/libimageio_util.a
 extras/vwebp_sdl: src/libwebp.a
+extras/vwebp_sdl: sharpyuv/libsharpyuv.a
 extras/vwebp_sdl: EXTRA_FLAGS += -DWEBP_HAVE_SDL $(SDL_FLAGS)
 extras/vwebp_sdl: override EXTRA_LIBS += $(SDL_LIBS)
 
@@ -468,12 +499,15 @@ dist: DESTDIR := dist
 dist: OUT_EXAMPLES += $(EXTRA_EXAMPLES)
 dist: all
 	$(INSTALL) -m755 -d $(DESTDIR)/include/webp \
-	           $(DESTDIR)/bin $(DESTDIR)/doc $(DESTDIR)/lib
+	            $(DESTDIR)/include/webp/sharpyuv \
+	            $(DESTDIR)/bin $(DESTDIR)/doc $(DESTDIR)/lib
 	$(INSTALL) -m755 -s $(OUT_EXAMPLES) $(DESTDIR)/bin
 	$(INSTALL) -m644 $(HDRS_INSTALLED) $(DESTDIR)/include/webp
+	$(INSTALL) -m644 $(SHARPYUV_HDRS_INSTALLED) $(DESTDIR)/include/webp/sharpyuv
 	$(INSTALL) -m644 src/libwebp.a $(DESTDIR)/lib
 	$(INSTALL) -m644 src/demux/libwebpdemux.a $(DESTDIR)/lib
 	$(INSTALL) -m644 src/mux/libwebpmux.a $(DESTDIR)/lib
+	$(INSTALL) -m644 sharpyuv/libsharpyuv.a $(DESTDIR)/lib
 	umask 022; \
 	for m in man/[cdv]webp.1 man/gif2webp.1 man/webpmux.1 \
                  man/img2webp.1 man/webpinfo.1; do \
@@ -489,6 +523,7 @@ clean:
               examples/*.o examples/*~ \
               extras/*.o extras/*~ \
               imageio/*.o imageio/*~ \
+              sharpyuv/*.o sharpyuv/*~ \
               src/dec/*.o src/dec/*~ \
               src/demux/*.o src/demux/*~ \
               src/dsp/*.o src/dsp/*~ \

+ 8 - 6
webp.mod/libwebp/man/cwebp.1

@@ -1,5 +1,5 @@
 .\"                                      Hey, EMACS: -*- nroff -*-
-.TH CWEBP 1 "November 17, 2021"
+.TH CWEBP 1 "March 17, 2022"
 .SH NAME
 cwebp \- compress an image file to a WebP file
 .SH SYNOPSIS
@@ -90,15 +90,17 @@ additional encoding possibilities and decide on the quality gain.
 Lower value can result in faster processing time at the expense of
 larger file size and lower compression quality.
 .TP
-.BI \-resize " width height
-Resize the source to a rectangle with size \fBwidth\fP x \fBheight\fP.
-If either (but not both) of the \fBwidth\fP or \fBheight\fP parameters is 0,
-the value will be calculated preserving the aspect\-ratio.
-.TP
 .BI \-crop " x_position y_position width height
 Crop the source to a rectangle with top\-left corner at coordinates
 (\fBx_position\fP, \fBy_position\fP) and size \fBwidth\fP x \fBheight\fP.
 This cropping area must be fully contained within the source rectangle.
+Note: the cropping is applied \fIbefore\fP any scaling.
+.TP
+.BI \-resize " width height
+Resize the source to a rectangle with size \fBwidth\fP x \fBheight\fP.
+If either (but not both) of the \fBwidth\fP or \fBheight\fP parameters is 0,
+the value will be calculated preserving the aspect\-ratio. Note: scaling
+is applied \fIafter\fP cropping.
 .TP
 .B \-mt
 Use multi\-threading for encoding, if possible.

+ 14 - 2
webp.mod/libwebp/man/img2webp.1

@@ -1,10 +1,10 @@
 .\"                                      Hey, EMACS: -*- nroff -*-
-.TH IMG2WEBP 1 "November 17, 2021"
+.TH IMG2WEBP 1 "March 17, 2023"
 .SH NAME
 img2webp \- create animated WebP file from a sequence of input images.
 .SH SYNOPSIS
 .B img2webp
-[file_options] [[frame_options] frame_file]...
+[file_options] [[frame_options] frame_file]... [\-o webp_file]
 .br
 .B img2webp argument_file_name
 .br
@@ -44,6 +44,18 @@ Mixed compression mode: optimize compression of the image by picking either
 lossy or lossless compression for each frame heuristically. This global
 option disables the local option \fB-lossy\fP and \fB-lossless\fP .
 .TP
+.BI \-near_lossless " int
+Specify the level of near\-lossless image preprocessing. This option adjusts
+pixel values to help compressibility, but has minimal impact on the visual
+quality. It triggers lossless compression mode automatically. The range is 0
+(maximum preprocessing) to 100 (no preprocessing, the default). The typical
+value is around 60. Note that lossy with \fB\-q 100\fP can at times yield
+better results.
+.TP
+.B \-sharp_yuv
+Use more accurate and sharper RGB->YUV conversion if needed. Note that this
+process is slower than the default 'fast' RGB->YUV conversion.
+.TP
 .BI \-loop " int
 Specifies the number of times the animation should loop. Using '0'
 means 'loop indefinitely'.

+ 41 - 0
webp.mod/libwebp/sharpyuv/Makefile.am

@@ -0,0 +1,41 @@
+AM_CPPFLAGS += -I$(top_builddir) -I$(top_srcdir)
+AM_CPPFLAGS += -I$(top_builddir)/src -I$(top_srcdir)/src
+
+lib_LTLIBRARIES = libsharpyuv.la
+
+noinst_LTLIBRARIES =
+noinst_LTLIBRARIES += libsharpyuv_sse2.la
+noinst_LTLIBRARIES += libsharpyuv_neon.la
+
+libsharpyuvinclude_HEADERS =
+libsharpyuvinclude_HEADERS += sharpyuv.h
+libsharpyuvinclude_HEADERS += sharpyuv_csp.h
+noinst_HEADERS =
+noinst_HEADERS += ../src/dsp/cpu.c
+noinst_HEADERS += ../src/dsp/cpu.h
+noinst_HEADERS += ../src/webp/types.h
+
+libsharpyuv_sse2_la_SOURCES =
+libsharpyuv_sse2_la_SOURCES += sharpyuv_sse2.c
+libsharpyuv_sse2_la_CPPFLAGS = $(libsharpyuv_la_CPPFLAGS)
+libsharpyuv_sse2_la_CFLAGS = $(AM_CFLAGS) $(SSE2_FLAGS)
+
+libsharpyuv_neon_la_SOURCES =
+libsharpyuv_neon_la_SOURCES += sharpyuv_neon.c
+libsharpyuv_neon_la_CPPFLAGS = $(libsharpyuv_la_CPPFLAGS)
+libsharpyuv_neon_la_CFLAGS = $(AM_CFLAGS) $(NEON_FLAGS)
+
+libsharpyuv_la_SOURCES =
+libsharpyuv_la_SOURCES += sharpyuv_cpu.c sharpyuv_cpu.h
+libsharpyuv_la_SOURCES += sharpyuv_csp.c sharpyuv_csp.h
+libsharpyuv_la_SOURCES += sharpyuv_dsp.c sharpyuv_dsp.h
+libsharpyuv_la_SOURCES += sharpyuv_gamma.c sharpyuv_gamma.h
+libsharpyuv_la_SOURCES += sharpyuv.c sharpyuv.h
+
+libsharpyuv_la_CPPFLAGS = $(AM_CPPFLAGS)
+libsharpyuv_la_LDFLAGS = -no-undefined -version-info 0:1:0 -lm
+libsharpyuv_la_LIBADD =
+libsharpyuv_la_LIBADD += libsharpyuv_sse2.la
+libsharpyuv_la_LIBADD += libsharpyuv_neon.la
+libsharpyuvincludedir = $(includedir)/webp/sharpyuv
+pkgconfig_DATA = libsharpyuv.pc

+ 11 - 0
webp.mod/libwebp/sharpyuv/libsharpyuv.pc.in

@@ -0,0 +1,11 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@/webp
+
+Name: libsharpyuv
+Description: Library for sharp RGB to YUV conversion
+Version: @PACKAGE_VERSION@
+Cflags: -I${includedir}
+Libs: -L${libdir} -l@webp_libname_prefix@sharpyuv
+Libs.private: -lm @PTHREAD_CFLAGS@ @PTHREAD_LIBS@

+ 41 - 0
webp.mod/libwebp/sharpyuv/libsharpyuv.rc

@@ -0,0 +1,41 @@
+#define APSTUDIO_READONLY_SYMBOLS
+#include "winres.h"
+#undef APSTUDIO_READONLY_SYMBOLS
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 0,0,2,1
+ PRODUCTVERSION 0,0,2,1
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x40004L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+    BLOCK "StringFileInfo"
+    BEGIN
+        BLOCK "040904b0"
+        BEGIN
+            VALUE "CompanyName", "Google, Inc."
+            VALUE "FileDescription", "libsharpyuv DLL"
+            VALUE "FileVersion", "0.2.1"
+            VALUE "InternalName", "libsharpyuv.dll"
+            VALUE "LegalCopyright", "Copyright (C) 2023"
+            VALUE "OriginalFilename", "libsharpyuv.dll"
+            VALUE "ProductName", "SharpYuv Library"
+            VALUE "ProductVersion", "0.2.1"
+        END
+    END
+    BLOCK "VarFileInfo"
+    BEGIN
+        VALUE "Translation", 0x409, 1200
+    END
+END
+
+#endif    // English (United States) resources

+ 527 - 0
webp.mod/libwebp/sharpyuv/sharpyuv.c

@@ -0,0 +1,527 @@
+// Copyright 2022 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Sharp RGB to YUV conversion.
+//
+// Author: Skal ([email protected])
+
+#include "sharpyuv/sharpyuv.h"
+
+#include <assert.h>
+#include <limits.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "src/webp/types.h"
+#include "sharpyuv/sharpyuv_cpu.h"
+#include "sharpyuv/sharpyuv_dsp.h"
+#include "sharpyuv/sharpyuv_gamma.h"
+
+//------------------------------------------------------------------------------
+
+int SharpYuvGetVersion(void) {
+  return SHARPYUV_VERSION;
+}
+
+//------------------------------------------------------------------------------
+// Sharp RGB->YUV conversion
+
+static const int kNumIterations = 4;
+
+#define YUV_FIX 16  // fixed-point precision for RGB->YUV
+static const int kYuvHalf = 1 << (YUV_FIX - 1);
+
+// Max bit depth so that intermediate calculations fit in 16 bits.
+static const int kMaxBitDepth = 14;
+
+// Returns the precision shift to use based on the input rgb_bit_depth.
+static int GetPrecisionShift(int rgb_bit_depth) {
+  // Try to add 2 bits of precision if it fits in kMaxBitDepth. Otherwise remove
+  // bits if needed.
+  return ((rgb_bit_depth + 2) <= kMaxBitDepth) ? 2
+                                               : (kMaxBitDepth - rgb_bit_depth);
+}
+
+typedef int16_t fixed_t;      // signed type with extra precision for UV
+typedef uint16_t fixed_y_t;   // unsigned type with extra precision for W
+
+//------------------------------------------------------------------------------
+
+static uint8_t clip_8b(fixed_t v) {
+  return (!(v & ~0xff)) ? (uint8_t)v : (v < 0) ? 0u : 255u;
+}
+
+static uint16_t clip(fixed_t v, int max) {
+  return (v < 0) ? 0 : (v > max) ? max : (uint16_t)v;
+}
+
+static fixed_y_t clip_bit_depth(int y, int bit_depth) {
+  const int max = (1 << bit_depth) - 1;
+  return (!(y & ~max)) ? (fixed_y_t)y : (y < 0) ? 0 : max;
+}
+
+//------------------------------------------------------------------------------
+
+static int RGBToGray(int64_t r, int64_t g, int64_t b) {
+  const int64_t luma = 13933 * r + 46871 * g + 4732 * b + kYuvHalf;
+  return (int)(luma >> YUV_FIX);
+}
+
+static uint32_t ScaleDown(uint16_t a, uint16_t b, uint16_t c, uint16_t d,
+                          int rgb_bit_depth) {
+  const int bit_depth = rgb_bit_depth + GetPrecisionShift(rgb_bit_depth);
+  const uint32_t A = SharpYuvGammaToLinear(a, bit_depth);
+  const uint32_t B = SharpYuvGammaToLinear(b, bit_depth);
+  const uint32_t C = SharpYuvGammaToLinear(c, bit_depth);
+  const uint32_t D = SharpYuvGammaToLinear(d, bit_depth);
+  return SharpYuvLinearToGamma((A + B + C + D + 2) >> 2, bit_depth);
+}
+
+static WEBP_INLINE void UpdateW(const fixed_y_t* src, fixed_y_t* dst, int w,
+                                int rgb_bit_depth) {
+  const int bit_depth = rgb_bit_depth + GetPrecisionShift(rgb_bit_depth);
+  int i;
+  for (i = 0; i < w; ++i) {
+    const uint32_t R = SharpYuvGammaToLinear(src[0 * w + i], bit_depth);
+    const uint32_t G = SharpYuvGammaToLinear(src[1 * w + i], bit_depth);
+    const uint32_t B = SharpYuvGammaToLinear(src[2 * w + i], bit_depth);
+    const uint32_t Y = RGBToGray(R, G, B);
+    dst[i] = (fixed_y_t)SharpYuvLinearToGamma(Y, bit_depth);
+  }
+}
+
+static void UpdateChroma(const fixed_y_t* src1, const fixed_y_t* src2,
+                         fixed_t* dst, int uv_w, int rgb_bit_depth) {
+  int i;
+  for (i = 0; i < uv_w; ++i) {
+    const int r =
+        ScaleDown(src1[0 * uv_w + 0], src1[0 * uv_w + 1], src2[0 * uv_w + 0],
+                  src2[0 * uv_w + 1], rgb_bit_depth);
+    const int g =
+        ScaleDown(src1[2 * uv_w + 0], src1[2 * uv_w + 1], src2[2 * uv_w + 0],
+                  src2[2 * uv_w + 1], rgb_bit_depth);
+    const int b =
+        ScaleDown(src1[4 * uv_w + 0], src1[4 * uv_w + 1], src2[4 * uv_w + 0],
+                  src2[4 * uv_w + 1], rgb_bit_depth);
+    const int W = RGBToGray(r, g, b);
+    dst[0 * uv_w] = (fixed_t)(r - W);
+    dst[1 * uv_w] = (fixed_t)(g - W);
+    dst[2 * uv_w] = (fixed_t)(b - W);
+    dst  += 1;
+    src1 += 2;
+    src2 += 2;
+  }
+}
+
+static void StoreGray(const fixed_y_t* rgb, fixed_y_t* y, int w) {
+  int i;
+  assert(w > 0);
+  for (i = 0; i < w; ++i) {
+    y[i] = RGBToGray(rgb[0 * w + i], rgb[1 * w + i], rgb[2 * w + i]);
+  }
+}
+
+//------------------------------------------------------------------------------
+
+static WEBP_INLINE fixed_y_t Filter2(int A, int B, int W0, int bit_depth) {
+  const int v0 = (A * 3 + B + 2) >> 2;
+  return clip_bit_depth(v0 + W0, bit_depth);
+}
+
+//------------------------------------------------------------------------------
+
+static WEBP_INLINE int Shift(int v, int shift) {
+  return (shift >= 0) ? (v << shift) : (v >> -shift);
+}
+
+static void ImportOneRow(const uint8_t* const r_ptr,
+                         const uint8_t* const g_ptr,
+                         const uint8_t* const b_ptr,
+                         int rgb_step,
+                         int rgb_bit_depth,
+                         int pic_width,
+                         fixed_y_t* const dst) {
+  // Convert the rgb_step from a number of bytes to a number of uint8_t or
+  // uint16_t values depending the bit depth.
+  const int step = (rgb_bit_depth > 8) ? rgb_step / 2 : rgb_step;
+  int i;
+  const int w = (pic_width + 1) & ~1;
+  for (i = 0; i < pic_width; ++i) {
+    const int off = i * step;
+    const int shift = GetPrecisionShift(rgb_bit_depth);
+    if (rgb_bit_depth == 8) {
+      dst[i + 0 * w] = Shift(r_ptr[off], shift);
+      dst[i + 1 * w] = Shift(g_ptr[off], shift);
+      dst[i + 2 * w] = Shift(b_ptr[off], shift);
+    } else {
+      dst[i + 0 * w] = Shift(((uint16_t*)r_ptr)[off], shift);
+      dst[i + 1 * w] = Shift(((uint16_t*)g_ptr)[off], shift);
+      dst[i + 2 * w] = Shift(((uint16_t*)b_ptr)[off], shift);
+    }
+  }
+  if (pic_width & 1) {  // replicate rightmost pixel
+    dst[pic_width + 0 * w] = dst[pic_width + 0 * w - 1];
+    dst[pic_width + 1 * w] = dst[pic_width + 1 * w - 1];
+    dst[pic_width + 2 * w] = dst[pic_width + 2 * w - 1];
+  }
+}
+
+static void InterpolateTwoRows(const fixed_y_t* const best_y,
+                               const fixed_t* prev_uv,
+                               const fixed_t* cur_uv,
+                               const fixed_t* next_uv,
+                               int w,
+                               fixed_y_t* out1,
+                               fixed_y_t* out2,
+                               int rgb_bit_depth) {
+  const int uv_w = w >> 1;
+  const int len = (w - 1) >> 1;   // length to filter
+  int k = 3;
+  const int bit_depth = rgb_bit_depth + GetPrecisionShift(rgb_bit_depth);
+  while (k-- > 0) {   // process each R/G/B segments in turn
+    // special boundary case for i==0
+    out1[0] = Filter2(cur_uv[0], prev_uv[0], best_y[0], bit_depth);
+    out2[0] = Filter2(cur_uv[0], next_uv[0], best_y[w], bit_depth);
+
+    SharpYuvFilterRow(cur_uv, prev_uv, len, best_y + 0 + 1, out1 + 1,
+                      bit_depth);
+    SharpYuvFilterRow(cur_uv, next_uv, len, best_y + w + 1, out2 + 1,
+                      bit_depth);
+
+    // special boundary case for i == w - 1 when w is even
+    if (!(w & 1)) {
+      out1[w - 1] = Filter2(cur_uv[uv_w - 1], prev_uv[uv_w - 1],
+                            best_y[w - 1 + 0], bit_depth);
+      out2[w - 1] = Filter2(cur_uv[uv_w - 1], next_uv[uv_w - 1],
+                            best_y[w - 1 + w], bit_depth);
+    }
+    out1 += w;
+    out2 += w;
+    prev_uv += uv_w;
+    cur_uv  += uv_w;
+    next_uv += uv_w;
+  }
+}
+
+static WEBP_INLINE int RGBToYUVComponent(int r, int g, int b,
+                                         const int coeffs[4], int sfix) {
+  const int srounder = 1 << (YUV_FIX + sfix - 1);
+  const int luma = coeffs[0] * r + coeffs[1] * g + coeffs[2] * b +
+                   coeffs[3] + srounder;
+  return (luma >> (YUV_FIX + sfix));
+}
+
+static int ConvertWRGBToYUV(const fixed_y_t* best_y, const fixed_t* best_uv,
+                            uint8_t* y_ptr, int y_stride, uint8_t* u_ptr,
+                            int u_stride, uint8_t* v_ptr, int v_stride,
+                            int rgb_bit_depth,
+                            int yuv_bit_depth, int width, int height,
+                            const SharpYuvConversionMatrix* yuv_matrix) {
+  int i, j;
+  const fixed_t* const best_uv_base = best_uv;
+  const int w = (width + 1) & ~1;
+  const int h = (height + 1) & ~1;
+  const int uv_w = w >> 1;
+  const int uv_h = h >> 1;
+  const int sfix = GetPrecisionShift(rgb_bit_depth);
+  const int yuv_max = (1 << yuv_bit_depth) - 1;
+
+  for (best_uv = best_uv_base, j = 0; j < height; ++j) {
+    for (i = 0; i < width; ++i) {
+      const int off = (i >> 1);
+      const int W = best_y[i];
+      const int r = best_uv[off + 0 * uv_w] + W;
+      const int g = best_uv[off + 1 * uv_w] + W;
+      const int b = best_uv[off + 2 * uv_w] + W;
+      const int y = RGBToYUVComponent(r, g, b, yuv_matrix->rgb_to_y, sfix);
+      if (yuv_bit_depth <= 8) {
+        y_ptr[i] = clip_8b(y);
+      } else {
+        ((uint16_t*)y_ptr)[i] = clip(y, yuv_max);
+      }
+    }
+    best_y += w;
+    best_uv += (j & 1) * 3 * uv_w;
+    y_ptr += y_stride;
+  }
+  for (best_uv = best_uv_base, j = 0; j < uv_h; ++j) {
+    for (i = 0; i < uv_w; ++i) {
+      const int off = i;
+      // Note r, g and b values here are off by W, but a constant offset on all
+      // 3 components doesn't change the value of u and v with a YCbCr matrix.
+      const int r = best_uv[off + 0 * uv_w];
+      const int g = best_uv[off + 1 * uv_w];
+      const int b = best_uv[off + 2 * uv_w];
+      const int u = RGBToYUVComponent(r, g, b, yuv_matrix->rgb_to_u, sfix);
+      const int v = RGBToYUVComponent(r, g, b, yuv_matrix->rgb_to_v, sfix);
+      if (yuv_bit_depth <= 8) {
+        u_ptr[i] = clip_8b(u);
+        v_ptr[i] = clip_8b(v);
+      } else {
+        ((uint16_t*)u_ptr)[i] = clip(u, yuv_max);
+        ((uint16_t*)v_ptr)[i] = clip(v, yuv_max);
+      }
+    }
+    best_uv += 3 * uv_w;
+    u_ptr += u_stride;
+    v_ptr += v_stride;
+  }
+  return 1;
+}
+
+//------------------------------------------------------------------------------
+// Main function
+
+static void* SafeMalloc(uint64_t nmemb, size_t size) {
+  const uint64_t total_size = nmemb * (uint64_t)size;
+  if (total_size != (size_t)total_size) return NULL;
+  return malloc((size_t)total_size);
+}
+
+#define SAFE_ALLOC(W, H, T) ((T*)SafeMalloc((W) * (H), sizeof(T)))
+
+static int DoSharpArgbToYuv(const uint8_t* r_ptr, const uint8_t* g_ptr,
+                            const uint8_t* b_ptr, int rgb_step, int rgb_stride,
+                            int rgb_bit_depth, uint8_t* y_ptr, int y_stride,
+                            uint8_t* u_ptr, int u_stride, uint8_t* v_ptr,
+                            int v_stride, int yuv_bit_depth, int width,
+                            int height,
+                            const SharpYuvConversionMatrix* yuv_matrix) {
+  // we expand the right/bottom border if needed
+  const int w = (width + 1) & ~1;
+  const int h = (height + 1) & ~1;
+  const int uv_w = w >> 1;
+  const int uv_h = h >> 1;
+  uint64_t prev_diff_y_sum = ~0;
+  int j, iter;
+
+  // TODO(skal): allocate one big memory chunk. But for now, it's easier
+  // for valgrind debugging to have several chunks.
+  fixed_y_t* const tmp_buffer = SAFE_ALLOC(w * 3, 2, fixed_y_t);   // scratch
+  fixed_y_t* const best_y_base = SAFE_ALLOC(w, h, fixed_y_t);
+  fixed_y_t* const target_y_base = SAFE_ALLOC(w, h, fixed_y_t);
+  fixed_y_t* const best_rgb_y = SAFE_ALLOC(w, 2, fixed_y_t);
+  fixed_t* const best_uv_base = SAFE_ALLOC(uv_w * 3, uv_h, fixed_t);
+  fixed_t* const target_uv_base = SAFE_ALLOC(uv_w * 3, uv_h, fixed_t);
+  fixed_t* const best_rgb_uv = SAFE_ALLOC(uv_w * 3, 1, fixed_t);
+  fixed_y_t* best_y = best_y_base;
+  fixed_y_t* target_y = target_y_base;
+  fixed_t* best_uv = best_uv_base;
+  fixed_t* target_uv = target_uv_base;
+  const uint64_t diff_y_threshold = (uint64_t)(3.0 * w * h);
+  int ok;
+  assert(w > 0);
+  assert(h > 0);
+
+  if (best_y_base == NULL || best_uv_base == NULL ||
+      target_y_base == NULL || target_uv_base == NULL ||
+      best_rgb_y == NULL || best_rgb_uv == NULL ||
+      tmp_buffer == NULL) {
+    ok = 0;
+    goto End;
+  }
+
+  // Import RGB samples to W/RGB representation.
+  for (j = 0; j < height; j += 2) {
+    const int is_last_row = (j == height - 1);
+    fixed_y_t* const src1 = tmp_buffer + 0 * w;
+    fixed_y_t* const src2 = tmp_buffer + 3 * w;
+
+    // prepare two rows of input
+    ImportOneRow(r_ptr, g_ptr, b_ptr, rgb_step, rgb_bit_depth, width,
+                 src1);
+    if (!is_last_row) {
+      ImportOneRow(r_ptr + rgb_stride, g_ptr + rgb_stride, b_ptr + rgb_stride,
+                   rgb_step, rgb_bit_depth, width, src2);
+    } else {
+      memcpy(src2, src1, 3 * w * sizeof(*src2));
+    }
+    StoreGray(src1, best_y + 0, w);
+    StoreGray(src2, best_y + w, w);
+
+    UpdateW(src1, target_y, w, rgb_bit_depth);
+    UpdateW(src2, target_y + w, w, rgb_bit_depth);
+    UpdateChroma(src1, src2, target_uv, uv_w, rgb_bit_depth);
+    memcpy(best_uv, target_uv, 3 * uv_w * sizeof(*best_uv));
+    best_y += 2 * w;
+    best_uv += 3 * uv_w;
+    target_y += 2 * w;
+    target_uv += 3 * uv_w;
+    r_ptr += 2 * rgb_stride;
+    g_ptr += 2 * rgb_stride;
+    b_ptr += 2 * rgb_stride;
+  }
+
+  // Iterate and resolve clipping conflicts.
+  for (iter = 0; iter < kNumIterations; ++iter) {
+    const fixed_t* cur_uv = best_uv_base;
+    const fixed_t* prev_uv = best_uv_base;
+    uint64_t diff_y_sum = 0;
+
+    best_y = best_y_base;
+    best_uv = best_uv_base;
+    target_y = target_y_base;
+    target_uv = target_uv_base;
+    for (j = 0; j < h; j += 2) {
+      fixed_y_t* const src1 = tmp_buffer + 0 * w;
+      fixed_y_t* const src2 = tmp_buffer + 3 * w;
+      {
+        const fixed_t* const next_uv = cur_uv + ((j < h - 2) ? 3 * uv_w : 0);
+        InterpolateTwoRows(best_y, prev_uv, cur_uv, next_uv, w,
+                           src1, src2, rgb_bit_depth);
+        prev_uv = cur_uv;
+        cur_uv = next_uv;
+      }
+
+      UpdateW(src1, best_rgb_y + 0 * w, w, rgb_bit_depth);
+      UpdateW(src2, best_rgb_y + 1 * w, w, rgb_bit_depth);
+      UpdateChroma(src1, src2, best_rgb_uv, uv_w, rgb_bit_depth);
+
+      // update two rows of Y and one row of RGB
+      diff_y_sum +=
+          SharpYuvUpdateY(target_y, best_rgb_y, best_y, 2 * w,
+                          rgb_bit_depth + GetPrecisionShift(rgb_bit_depth));
+      SharpYuvUpdateRGB(target_uv, best_rgb_uv, best_uv, 3 * uv_w);
+
+      best_y += 2 * w;
+      best_uv += 3 * uv_w;
+      target_y += 2 * w;
+      target_uv += 3 * uv_w;
+    }
+    // test exit condition
+    if (iter > 0) {
+      if (diff_y_sum < diff_y_threshold) break;
+      if (diff_y_sum > prev_diff_y_sum) break;
+    }
+    prev_diff_y_sum = diff_y_sum;
+  }
+
+  // final reconstruction
+  ok = ConvertWRGBToYUV(best_y_base, best_uv_base, y_ptr, y_stride, u_ptr,
+                        u_stride, v_ptr, v_stride, rgb_bit_depth, yuv_bit_depth,
+                        width, height, yuv_matrix);
+
+ End:
+  free(best_y_base);
+  free(best_uv_base);
+  free(target_y_base);
+  free(target_uv_base);
+  free(best_rgb_y);
+  free(best_rgb_uv);
+  free(tmp_buffer);
+  return ok;
+}
+#undef SAFE_ALLOC
+
+#if defined(WEBP_USE_THREAD) && !defined(_WIN32)
+#include <pthread.h>  // NOLINT
+
+#define LOCK_ACCESS \
+    static pthread_mutex_t sharpyuv_lock = PTHREAD_MUTEX_INITIALIZER; \
+    if (pthread_mutex_lock(&sharpyuv_lock)) return
+#define UNLOCK_ACCESS_AND_RETURN                  \
+    do {                                          \
+      (void)pthread_mutex_unlock(&sharpyuv_lock); \
+      return;                                     \
+    } while (0)
+#else  // !(defined(WEBP_USE_THREAD) && !defined(_WIN32))
+#define LOCK_ACCESS do {} while (0)
+#define UNLOCK_ACCESS_AND_RETURN return
+#endif  // defined(WEBP_USE_THREAD) && !defined(_WIN32)
+
+// Hidden exported init function.
+// By default SharpYuvConvert calls it with SharpYuvGetCPUInfo. If needed,
+// users can declare it as extern and call it with an alternate VP8CPUInfo
+// function.
+extern VP8CPUInfo SharpYuvGetCPUInfo;
+SHARPYUV_EXTERN void SharpYuvInit(VP8CPUInfo cpu_info_func);
+void SharpYuvInit(VP8CPUInfo cpu_info_func) {
+  static volatile VP8CPUInfo sharpyuv_last_cpuinfo_used =
+      (VP8CPUInfo)&sharpyuv_last_cpuinfo_used;
+  LOCK_ACCESS;
+  // Only update SharpYuvGetCPUInfo when called from external code to avoid a
+  // race on reading the value in SharpYuvConvert().
+  if (cpu_info_func != (VP8CPUInfo)&SharpYuvGetCPUInfo) {
+    SharpYuvGetCPUInfo = cpu_info_func;
+  }
+  if (sharpyuv_last_cpuinfo_used == SharpYuvGetCPUInfo) {
+    UNLOCK_ACCESS_AND_RETURN;
+  }
+
+  SharpYuvInitDsp();
+  SharpYuvInitGammaTables();
+
+  sharpyuv_last_cpuinfo_used = SharpYuvGetCPUInfo;
+  UNLOCK_ACCESS_AND_RETURN;
+}
+
+int SharpYuvConvert(const void* r_ptr, const void* g_ptr,
+                    const void* b_ptr, int rgb_step, int rgb_stride,
+                    int rgb_bit_depth, void* y_ptr, int y_stride,
+                    void* u_ptr, int u_stride, void* v_ptr,
+                    int v_stride, int yuv_bit_depth, int width,
+                    int height, const SharpYuvConversionMatrix* yuv_matrix) {
+  SharpYuvConversionMatrix scaled_matrix;
+  const int rgb_max = (1 << rgb_bit_depth) - 1;
+  const int rgb_round = 1 << (rgb_bit_depth - 1);
+  const int yuv_max = (1 << yuv_bit_depth) - 1;
+  const int sfix = GetPrecisionShift(rgb_bit_depth);
+
+  if (width < 1 || height < 1 || width == INT_MAX || height == INT_MAX ||
+      r_ptr == NULL || g_ptr == NULL || b_ptr == NULL || y_ptr == NULL ||
+      u_ptr == NULL || v_ptr == NULL) {
+    return 0;
+  }
+  if (rgb_bit_depth != 8 && rgb_bit_depth != 10 && rgb_bit_depth != 12 &&
+      rgb_bit_depth != 16) {
+    return 0;
+  }
+  if (yuv_bit_depth != 8 && yuv_bit_depth != 10 && yuv_bit_depth != 12) {
+    return 0;
+  }
+  if (rgb_bit_depth > 8 && (rgb_step % 2 != 0 || rgb_stride %2 != 0)) {
+    // Step/stride should be even for uint16_t buffers.
+    return 0;
+  }
+  if (yuv_bit_depth > 8 &&
+      (y_stride % 2 != 0 || u_stride % 2 != 0 || v_stride % 2 != 0)) {
+    // Stride should be even for uint16_t buffers.
+    return 0;
+  }
+  // The address of the function pointer is used to avoid a read race.
+  SharpYuvInit((VP8CPUInfo)&SharpYuvGetCPUInfo);
+
+  // Add scaling factor to go from rgb_bit_depth to yuv_bit_depth, to the
+  // rgb->yuv conversion matrix.
+  if (rgb_bit_depth == yuv_bit_depth) {
+    memcpy(&scaled_matrix, yuv_matrix, sizeof(scaled_matrix));
+  } else {
+    int i;
+    for (i = 0; i < 3; ++i) {
+      scaled_matrix.rgb_to_y[i] =
+          (yuv_matrix->rgb_to_y[i] * yuv_max + rgb_round) / rgb_max;
+      scaled_matrix.rgb_to_u[i] =
+          (yuv_matrix->rgb_to_u[i] * yuv_max + rgb_round) / rgb_max;
+      scaled_matrix.rgb_to_v[i] =
+          (yuv_matrix->rgb_to_v[i] * yuv_max + rgb_round) / rgb_max;
+    }
+  }
+  // Also incorporate precision change scaling.
+  scaled_matrix.rgb_to_y[3] = Shift(yuv_matrix->rgb_to_y[3], sfix);
+  scaled_matrix.rgb_to_u[3] = Shift(yuv_matrix->rgb_to_u[3], sfix);
+  scaled_matrix.rgb_to_v[3] = Shift(yuv_matrix->rgb_to_v[3], sfix);
+
+  return DoSharpArgbToYuv(r_ptr, g_ptr, b_ptr, rgb_step, rgb_stride,
+                          rgb_bit_depth, y_ptr, y_stride, u_ptr, u_stride,
+                          v_ptr, v_stride, yuv_bit_depth, width, height,
+                          &scaled_matrix);
+}
+
+//------------------------------------------------------------------------------

+ 103 - 0
webp.mod/libwebp/sharpyuv/sharpyuv.h

@@ -0,0 +1,103 @@
+// Copyright 2022 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Sharp RGB to YUV conversion.
+
+#ifndef WEBP_SHARPYUV_SHARPYUV_H_
+#define WEBP_SHARPYUV_SHARPYUV_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef SHARPYUV_EXTERN
+#ifdef WEBP_EXTERN
+#define SHARPYUV_EXTERN WEBP_EXTERN
+#else
+// This explicitly marks library functions and allows for changing the
+// signature for e.g., Windows DLL builds.
+#if defined(__GNUC__) && __GNUC__ >= 4
+#define SHARPYUV_EXTERN extern __attribute__((visibility("default")))
+#else
+#if defined(_MSC_VER) && defined(WEBP_DLL)
+#define SHARPYUV_EXTERN __declspec(dllexport)
+#else
+#define SHARPYUV_EXTERN extern
+#endif /* _MSC_VER && WEBP_DLL */
+#endif /* __GNUC__ >= 4 */
+#endif /* WEBP_EXTERN */
+#endif /* SHARPYUV_EXTERN */
+
+// SharpYUV API version following the convention from semver.org
+#define SHARPYUV_VERSION_MAJOR 0
+#define SHARPYUV_VERSION_MINOR 2
+#define SHARPYUV_VERSION_PATCH 1
+// Version as a uint32_t. The major number is the high 8 bits.
+// The minor number is the middle 8 bits. The patch number is the low 16 bits.
+#define SHARPYUV_MAKE_VERSION(MAJOR, MINOR, PATCH) \
+  (((MAJOR) << 24) | ((MINOR) << 16) | (PATCH))
+#define SHARPYUV_VERSION                                                \
+  SHARPYUV_MAKE_VERSION(SHARPYUV_VERSION_MAJOR, SHARPYUV_VERSION_MINOR, \
+                        SHARPYUV_VERSION_PATCH)
+
+// Returns the library's version number, packed in hexadecimal. See
+// SHARPYUV_VERSION.
+SHARPYUV_EXTERN int SharpYuvGetVersion(void);
+
+// RGB to YUV conversion matrix, in 16 bit fixed point.
+// y = rgb_to_y[0] * r + rgb_to_y[1] * g + rgb_to_y[2] * b + rgb_to_y[3]
+// u = rgb_to_u[0] * r + rgb_to_u[1] * g + rgb_to_u[2] * b + rgb_to_u[3]
+// v = rgb_to_v[0] * r + rgb_to_v[1] * g + rgb_to_v[2] * b + rgb_to_v[3]
+// Then y, u and v values are divided by 1<<16 and rounded.
+typedef struct {
+  int rgb_to_y[4];
+  int rgb_to_u[4];
+  int rgb_to_v[4];
+} SharpYuvConversionMatrix;
+
+// Converts RGB to YUV420 using a downsampling algorithm that minimizes
+// artefacts caused by chroma subsampling.
+// This is slower than standard downsampling (averaging of 4 UV values).
+// Assumes that the image will be upsampled using a bilinear filter. If nearest
+// neighbor is used instead, the upsampled image might look worse than with
+// standard downsampling.
+// r_ptr, g_ptr, b_ptr: pointers to the source r, g and b channels. Should point
+//     to uint8_t buffers if rgb_bit_depth is 8, or uint16_t buffers otherwise.
+// rgb_step: distance in bytes between two horizontally adjacent pixels on the
+//     r, g and b channels. If rgb_bit_depth is > 8, it should be a
+//     multiple of 2.
+// rgb_stride: distance in bytes between two vertically adjacent pixels on the
+//     r, g, and b channels. If rgb_bit_depth is > 8, it should be a
+//     multiple of 2.
+// rgb_bit_depth: number of bits for each r/g/b value. One of: 8, 10, 12, 16.
+//     Note: 16 bit input is truncated to 14 bits before conversion to yuv.
+// yuv_bit_depth: number of bits for each y/u/v value. One of: 8, 10, 12.
+// y_ptr, u_ptr, v_ptr: pointers to the destination y, u and v channels.  Should
+//     point to uint8_t buffers if yuv_bit_depth is 8, or uint16_t buffers
+//     otherwise.
+// y_stride, u_stride, v_stride: distance in bytes between two vertically
+//     adjacent pixels on the y, u and v channels. If yuv_bit_depth > 8, they
+//     should be multiples of 2.
+// width, height: width and height of the image in pixels
+SHARPYUV_EXTERN int SharpYuvConvert(const void* r_ptr, const void* g_ptr,
+                                    const void* b_ptr, int rgb_step,
+                                    int rgb_stride, int rgb_bit_depth,
+                                    void* y_ptr, int y_stride, void* u_ptr,
+                                    int u_stride, void* v_ptr, int v_stride,
+                                    int yuv_bit_depth, int width, int height,
+                                    const SharpYuvConversionMatrix* yuv_matrix);
+
+// TODO(b/194336375): Add YUV444 to YUV420 conversion. Maybe also add 422
+// support (it's rarely used in practice, especially for images).
+
+#ifdef __cplusplus
+}  // extern "C"
+#endif
+
+#endif  // WEBP_SHARPYUV_SHARPYUV_H_

+ 14 - 0
webp.mod/libwebp/sharpyuv/sharpyuv_cpu.c

@@ -0,0 +1,14 @@
+// Copyright 2022 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+#include "sharpyuv/sharpyuv_cpu.h"
+
+// Include src/dsp/cpu.c to create SharpYuvGetCPUInfo from VP8GetCPUInfo. The
+// function pointer is renamed in sharpyuv_cpu.h.
+#include "src/dsp/cpu.c"

+ 22 - 0
webp.mod/libwebp/sharpyuv/sharpyuv_cpu.h

@@ -0,0 +1,22 @@
+// Copyright 2022 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+#ifndef WEBP_SHARPYUV_SHARPYUV_CPU_H_
+#define WEBP_SHARPYUV_SHARPYUV_CPU_H_
+
+#include "sharpyuv/sharpyuv.h"
+
+// Avoid exporting SharpYuvGetCPUInfo in shared object / DLL builds.
+// SharpYuvInit() replaces the use of the function pointer.
+#undef WEBP_EXTERN
+#define WEBP_EXTERN extern
+#define VP8GetCPUInfo SharpYuvGetCPUInfo
+#include "src/dsp/cpu.h"
+
+#endif  // WEBP_SHARPYUV_SHARPYUV_CPU_H_

+ 110 - 0
webp.mod/libwebp/sharpyuv/sharpyuv_csp.c

@@ -0,0 +1,110 @@
+// Copyright 2022 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Colorspace utilities.
+
+#include "sharpyuv/sharpyuv_csp.h"
+
+#include <assert.h>
+#include <math.h>
+#include <stddef.h>
+
+static int ToFixed16(float f) { return (int)floor(f * (1 << 16) + 0.5f); }
+
+void SharpYuvComputeConversionMatrix(const SharpYuvColorSpace* yuv_color_space,
+                                     SharpYuvConversionMatrix* matrix) {
+  const float kr = yuv_color_space->kr;
+  const float kb = yuv_color_space->kb;
+  const float kg = 1.0f - kr - kb;
+  const float cr = 0.5f / (1.0f - kb);
+  const float cb = 0.5f / (1.0f - kr);
+
+  const int shift = yuv_color_space->bit_depth - 8;
+
+  const float denom = (float)((1 << yuv_color_space->bit_depth) - 1);
+  float scale_y = 1.0f;
+  float add_y = 0.0f;
+  float scale_u = cr;
+  float scale_v = cb;
+  float add_uv = (float)(128 << shift);
+  assert(yuv_color_space->bit_depth >= 8);
+
+  if (yuv_color_space->range == kSharpYuvRangeLimited) {
+    scale_y *= (219 << shift) / denom;
+    scale_u *= (224 << shift) / denom;
+    scale_v *= (224 << shift) / denom;
+    add_y = (float)(16 << shift);
+  }
+
+  matrix->rgb_to_y[0] = ToFixed16(kr * scale_y);
+  matrix->rgb_to_y[1] = ToFixed16(kg * scale_y);
+  matrix->rgb_to_y[2] = ToFixed16(kb * scale_y);
+  matrix->rgb_to_y[3] = ToFixed16(add_y);
+
+  matrix->rgb_to_u[0] = ToFixed16(-kr * scale_u);
+  matrix->rgb_to_u[1] = ToFixed16(-kg * scale_u);
+  matrix->rgb_to_u[2] = ToFixed16((1 - kb) * scale_u);
+  matrix->rgb_to_u[3] = ToFixed16(add_uv);
+
+  matrix->rgb_to_v[0] = ToFixed16((1 - kr) * scale_v);
+  matrix->rgb_to_v[1] = ToFixed16(-kg * scale_v);
+  matrix->rgb_to_v[2] = ToFixed16(-kb * scale_v);
+  matrix->rgb_to_v[3] = ToFixed16(add_uv);
+}
+
+// Matrices are in YUV_FIX fixed point precision.
+// WebP's matrix, similar but not identical to kRec601LimitedMatrix.
+static const SharpYuvConversionMatrix kWebpMatrix = {
+  {16839, 33059, 6420, 16 << 16},
+  {-9719, -19081, 28800, 128 << 16},
+  {28800, -24116, -4684, 128 << 16},
+};
+// Kr=0.2990f Kb=0.1140f bits=8 range=kSharpYuvRangeLimited
+static const SharpYuvConversionMatrix kRec601LimitedMatrix = {
+  {16829, 33039, 6416, 16 << 16},
+  {-9714, -19071, 28784, 128 << 16},
+  {28784, -24103, -4681, 128 << 16},
+};
+// Kr=0.2990f Kb=0.1140f bits=8 range=kSharpYuvRangeFull
+static const SharpYuvConversionMatrix kRec601FullMatrix = {
+  {19595, 38470, 7471, 0},
+  {-11058, -21710, 32768, 128 << 16},
+  {32768, -27439, -5329, 128 << 16},
+};
+// Kr=0.2126f Kb=0.0722f bits=8 range=kSharpYuvRangeLimited
+static const SharpYuvConversionMatrix kRec709LimitedMatrix = {
+  {11966, 40254, 4064, 16 << 16},
+  {-6596, -22189, 28784, 128 << 16},
+  {28784, -26145, -2639, 128 << 16},
+};
+// Kr=0.2126f Kb=0.0722f bits=8 range=kSharpYuvRangeFull
+static const SharpYuvConversionMatrix kRec709FullMatrix = {
+  {13933, 46871, 4732, 0},
+  {-7509, -25259, 32768, 128 << 16},
+  {32768, -29763, -3005, 128 << 16},
+};
+
+const SharpYuvConversionMatrix* SharpYuvGetConversionMatrix(
+    SharpYuvMatrixType matrix_type) {
+  switch (matrix_type) {
+    case kSharpYuvMatrixWebp:
+      return &kWebpMatrix;
+    case kSharpYuvMatrixRec601Limited:
+      return &kRec601LimitedMatrix;
+    case kSharpYuvMatrixRec601Full:
+      return &kRec601FullMatrix;
+    case kSharpYuvMatrixRec709Limited:
+      return &kRec709LimitedMatrix;
+    case kSharpYuvMatrixRec709Full:
+      return &kRec709FullMatrix;
+    case kSharpYuvMatrixNum:
+      return NULL;
+  }
+  return NULL;
+}

+ 60 - 0
webp.mod/libwebp/sharpyuv/sharpyuv_csp.h

@@ -0,0 +1,60 @@
+// Copyright 2022 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Colorspace utilities.
+
+#ifndef WEBP_SHARPYUV_SHARPYUV_CSP_H_
+#define WEBP_SHARPYUV_SHARPYUV_CSP_H_
+
+#include "sharpyuv/sharpyuv.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// Range of YUV values.
+typedef enum {
+  kSharpYuvRangeFull,     // YUV values between [0;255] (for 8 bit)
+  kSharpYuvRangeLimited   // Y in [16;235], YUV in [16;240] (for 8 bit)
+} SharpYuvRange;
+
+// Constants that define a YUV color space.
+typedef struct {
+  // Kr and Kb are defined such that:
+  // Y = Kr * r + Kg * g + Kb * b where Kg = 1 - Kr - Kb.
+  float kr;
+  float kb;
+  int bit_depth;  // 8, 10 or 12
+  SharpYuvRange range;
+} SharpYuvColorSpace;
+
+// Fills in 'matrix' for the given YUVColorSpace.
+SHARPYUV_EXTERN void SharpYuvComputeConversionMatrix(
+    const SharpYuvColorSpace* yuv_color_space,
+    SharpYuvConversionMatrix* matrix);
+
+// Enums for precomputed conversion matrices.
+typedef enum {
+  kSharpYuvMatrixWebp = 0,
+  kSharpYuvMatrixRec601Limited,
+  kSharpYuvMatrixRec601Full,
+  kSharpYuvMatrixRec709Limited,
+  kSharpYuvMatrixRec709Full,
+  kSharpYuvMatrixNum
+} SharpYuvMatrixType;
+
+// Returns a pointer to a matrix for one of the predefined colorspaces.
+SHARPYUV_EXTERN const SharpYuvConversionMatrix* SharpYuvGetConversionMatrix(
+    SharpYuvMatrixType matrix_type);
+
+#ifdef __cplusplus
+}  // extern "C"
+#endif
+
+#endif  // WEBP_SHARPYUV_SHARPYUV_CSP_H_

+ 104 - 0
webp.mod/libwebp/sharpyuv/sharpyuv_dsp.c

@@ -0,0 +1,104 @@
+// Copyright 2022 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Speed-critical functions for Sharp YUV.
+//
+// Author: Skal ([email protected])
+
+#include "sharpyuv/sharpyuv_dsp.h"
+
+#include <assert.h>
+#include <stdlib.h>
+
+#include "sharpyuv/sharpyuv_cpu.h"
+
+//-----------------------------------------------------------------------------
+
+#if !WEBP_NEON_OMIT_C_CODE
+static uint16_t clip(int v, int max) {
+  return (v < 0) ? 0 : (v > max) ? max : (uint16_t)v;
+}
+
+static uint64_t SharpYuvUpdateY_C(const uint16_t* ref, const uint16_t* src,
+                                  uint16_t* dst, int len, int bit_depth) {
+  uint64_t diff = 0;
+  int i;
+  const int max_y = (1 << bit_depth) - 1;
+  for (i = 0; i < len; ++i) {
+    const int diff_y = ref[i] - src[i];
+    const int new_y = (int)dst[i] + diff_y;
+    dst[i] = clip(new_y, max_y);
+    diff += (uint64_t)abs(diff_y);
+  }
+  return diff;
+}
+
+static void SharpYuvUpdateRGB_C(const int16_t* ref, const int16_t* src,
+                                int16_t* dst, int len) {
+  int i;
+  for (i = 0; i < len; ++i) {
+    const int diff_uv = ref[i] - src[i];
+    dst[i] += diff_uv;
+  }
+}
+
+static void SharpYuvFilterRow_C(const int16_t* A, const int16_t* B, int len,
+                                const uint16_t* best_y, uint16_t* out,
+                                int bit_depth) {
+  int i;
+  const int max_y = (1 << bit_depth) - 1;
+  for (i = 0; i < len; ++i, ++A, ++B) {
+    const int v0 = (A[0] * 9 + A[1] * 3 + B[0] * 3 + B[1] + 8) >> 4;
+    const int v1 = (A[1] * 9 + A[0] * 3 + B[1] * 3 + B[0] + 8) >> 4;
+    out[2 * i + 0] = clip(best_y[2 * i + 0] + v0, max_y);
+    out[2 * i + 1] = clip(best_y[2 * i + 1] + v1, max_y);
+  }
+}
+#endif  // !WEBP_NEON_OMIT_C_CODE
+
+//-----------------------------------------------------------------------------
+
+uint64_t (*SharpYuvUpdateY)(const uint16_t* src, const uint16_t* ref,
+                            uint16_t* dst, int len, int bit_depth);
+void (*SharpYuvUpdateRGB)(const int16_t* src, const int16_t* ref, int16_t* dst,
+                          int len);
+void (*SharpYuvFilterRow)(const int16_t* A, const int16_t* B, int len,
+                          const uint16_t* best_y, uint16_t* out,
+                          int bit_depth);
+
+extern VP8CPUInfo SharpYuvGetCPUInfo;
+extern void InitSharpYuvSSE2(void);
+extern void InitSharpYuvNEON(void);
+
+void SharpYuvInitDsp(void) {
+#if !WEBP_NEON_OMIT_C_CODE
+  SharpYuvUpdateY = SharpYuvUpdateY_C;
+  SharpYuvUpdateRGB = SharpYuvUpdateRGB_C;
+  SharpYuvFilterRow = SharpYuvFilterRow_C;
+#endif
+
+  if (SharpYuvGetCPUInfo != NULL) {
+#if defined(WEBP_HAVE_SSE2)
+    if (SharpYuvGetCPUInfo(kSSE2)) {
+      InitSharpYuvSSE2();
+    }
+#endif  // WEBP_HAVE_SSE2
+  }
+
+#if defined(WEBP_HAVE_NEON)
+  if (WEBP_NEON_OMIT_C_CODE ||
+      (SharpYuvGetCPUInfo != NULL && SharpYuvGetCPUInfo(kNEON))) {
+    InitSharpYuvNEON();
+  }
+#endif  // WEBP_HAVE_NEON
+
+  assert(SharpYuvUpdateY != NULL);
+  assert(SharpYuvUpdateRGB != NULL);
+  assert(SharpYuvFilterRow != NULL);
+}

+ 28 - 0
webp.mod/libwebp/sharpyuv/sharpyuv_dsp.h

@@ -0,0 +1,28 @@
+// Copyright 2022 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Speed-critical functions for Sharp YUV.
+
+#ifndef WEBP_SHARPYUV_SHARPYUV_DSP_H_
+#define WEBP_SHARPYUV_SHARPYUV_DSP_H_
+
+#include "sharpyuv/sharpyuv_cpu.h"
+#include "src/webp/types.h"
+
+extern uint64_t (*SharpYuvUpdateY)(const uint16_t* src, const uint16_t* ref,
+                                   uint16_t* dst, int len, int bit_depth);
+extern void (*SharpYuvUpdateRGB)(const int16_t* src, const int16_t* ref,
+                                 int16_t* dst, int len);
+extern void (*SharpYuvFilterRow)(const int16_t* A, const int16_t* B, int len,
+                                 const uint16_t* best_y, uint16_t* out,
+                                 int bit_depth);
+
+void SharpYuvInitDsp(void);
+
+#endif  // WEBP_SHARPYUV_SHARPYUV_DSP_H_

+ 113 - 0
webp.mod/libwebp/sharpyuv/sharpyuv_gamma.c

@@ -0,0 +1,113 @@
+// Copyright 2022 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Gamma correction utilities.
+
+#include "sharpyuv/sharpyuv_gamma.h"
+
+#include <assert.h>
+#include <math.h>
+
+#include "src/webp/types.h"
+
+// Gamma correction compensates loss of resolution during chroma subsampling.
+// Size of pre-computed table for converting from gamma to linear.
+#define GAMMA_TO_LINEAR_TAB_BITS 10
+#define GAMMA_TO_LINEAR_TAB_SIZE (1 << GAMMA_TO_LINEAR_TAB_BITS)
+static uint32_t kGammaToLinearTabS[GAMMA_TO_LINEAR_TAB_SIZE + 2];
+#define LINEAR_TO_GAMMA_TAB_BITS 9
+#define LINEAR_TO_GAMMA_TAB_SIZE (1 << LINEAR_TO_GAMMA_TAB_BITS)
+static uint32_t kLinearToGammaTabS[LINEAR_TO_GAMMA_TAB_SIZE + 2];
+
+static const double kGammaF = 1. / 0.45;
+#define GAMMA_TO_LINEAR_BITS 16
+
+static volatile int kGammaTablesSOk = 0;
+void SharpYuvInitGammaTables(void) {
+  assert(GAMMA_TO_LINEAR_BITS <= 16);
+  if (!kGammaTablesSOk) {
+    int v;
+    const double a = 0.09929682680944;
+    const double thresh = 0.018053968510807;
+    const double final_scale = 1 << GAMMA_TO_LINEAR_BITS;
+    // Precompute gamma to linear table.
+    {
+      const double norm = 1. / GAMMA_TO_LINEAR_TAB_SIZE;
+      const double a_rec = 1. / (1. + a);
+      for (v = 0; v <= GAMMA_TO_LINEAR_TAB_SIZE; ++v) {
+        const double g = norm * v;
+        double value;
+        if (g <= thresh * 4.5) {
+          value = g / 4.5;
+        } else {
+          value = pow(a_rec * (g + a), kGammaF);
+        }
+        kGammaToLinearTabS[v] = (uint32_t)(value * final_scale + .5);
+      }
+      // to prevent small rounding errors to cause read-overflow:
+      kGammaToLinearTabS[GAMMA_TO_LINEAR_TAB_SIZE + 1] =
+          kGammaToLinearTabS[GAMMA_TO_LINEAR_TAB_SIZE];
+    }
+    // Precompute linear to gamma table.
+    {
+      const double scale = 1. / LINEAR_TO_GAMMA_TAB_SIZE;
+      for (v = 0; v <= LINEAR_TO_GAMMA_TAB_SIZE; ++v) {
+        const double g = scale * v;
+        double value;
+        if (g <= thresh) {
+          value = 4.5 * g;
+        } else {
+          value = (1. + a) * pow(g, 1. / kGammaF) - a;
+        }
+        kLinearToGammaTabS[v] =
+            (uint32_t)(final_scale * value + 0.5);
+      }
+      // to prevent small rounding errors to cause read-overflow:
+      kLinearToGammaTabS[LINEAR_TO_GAMMA_TAB_SIZE + 1] =
+          kLinearToGammaTabS[LINEAR_TO_GAMMA_TAB_SIZE];
+    }
+    kGammaTablesSOk = 1;
+  }
+}
+
+static WEBP_INLINE int Shift(int v, int shift) {
+  return (shift >= 0) ? (v << shift) : (v >> -shift);
+}
+
+static WEBP_INLINE uint32_t FixedPointInterpolation(int v, uint32_t* tab,
+                                                    int tab_pos_shift_right,
+                                                    int tab_value_shift) {
+  const uint32_t tab_pos = Shift(v, -tab_pos_shift_right);
+  // fractional part, in 'tab_pos_shift' fixed-point precision
+  const uint32_t x = v - (tab_pos << tab_pos_shift_right);  // fractional part
+  // v0 / v1 are in kGammaToLinearBits fixed-point precision (range [0..1])
+  const uint32_t v0 = Shift(tab[tab_pos + 0], tab_value_shift);
+  const uint32_t v1 = Shift(tab[tab_pos + 1], tab_value_shift);
+  // Final interpolation.
+  const uint32_t v2 = (v1 - v0) * x;  // note: v1 >= v0.
+  const int half =
+      (tab_pos_shift_right > 0) ? 1 << (tab_pos_shift_right - 1) : 0;
+  const uint32_t result = v0 + ((v2 + half) >> tab_pos_shift_right);
+  return result;
+}
+
+uint32_t SharpYuvGammaToLinear(uint16_t v, int bit_depth) {
+  const int shift = GAMMA_TO_LINEAR_TAB_BITS - bit_depth;
+  if (shift > 0) {
+    return kGammaToLinearTabS[v << shift];
+  }
+  return FixedPointInterpolation(v, kGammaToLinearTabS, -shift, 0);
+}
+
+uint16_t SharpYuvLinearToGamma(uint32_t value, int bit_depth) {
+  return FixedPointInterpolation(
+      value, kLinearToGammaTabS,
+      (GAMMA_TO_LINEAR_BITS - LINEAR_TO_GAMMA_TAB_BITS),
+      bit_depth - GAMMA_TO_LINEAR_BITS);
+}

+ 35 - 0
webp.mod/libwebp/sharpyuv/sharpyuv_gamma.h

@@ -0,0 +1,35 @@
+// Copyright 2022 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Gamma correction utilities.
+
+#ifndef WEBP_SHARPYUV_SHARPYUV_GAMMA_H_
+#define WEBP_SHARPYUV_SHARPYUV_GAMMA_H_
+
+#include "src/webp/types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// Initializes precomputed tables. Must be called once before calling
+// SharpYuvGammaToLinear or SharpYuvLinearToGamma.
+void SharpYuvInitGammaTables(void);
+
+// Converts a gamma color value on 'bit_depth' bits to a 16 bit linear value.
+uint32_t SharpYuvGammaToLinear(uint16_t v, int bit_depth);
+
+// Converts a 16 bit linear color value to a gamma value on 'bit_depth' bits.
+uint16_t SharpYuvLinearToGamma(uint32_t value, int bit_depth);
+
+#ifdef __cplusplus
+}  // extern "C"
+#endif
+
+#endif  // WEBP_SHARPYUV_SHARPYUV_GAMMA_H_

+ 181 - 0
webp.mod/libwebp/sharpyuv/sharpyuv_neon.c

@@ -0,0 +1,181 @@
+// Copyright 2022 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Speed-critical functions for Sharp YUV.
+//
+// Author: Skal ([email protected])
+
+#include "sharpyuv/sharpyuv_dsp.h"
+
+#if defined(WEBP_USE_NEON)
+#include <assert.h>
+#include <stdlib.h>
+#include <arm_neon.h>
+
+static uint16_t clip_NEON(int v, int max) {
+  return (v < 0) ? 0 : (v > max) ? max : (uint16_t)v;
+}
+
+static uint64_t SharpYuvUpdateY_NEON(const uint16_t* ref, const uint16_t* src,
+                                     uint16_t* dst, int len, int bit_depth) {
+  const int max_y = (1 << bit_depth) - 1;
+  int i;
+  const int16x8_t zero = vdupq_n_s16(0);
+  const int16x8_t max = vdupq_n_s16(max_y);
+  uint64x2_t sum = vdupq_n_u64(0);
+  uint64_t diff;
+
+  for (i = 0; i + 8 <= len; i += 8) {
+    const int16x8_t A = vreinterpretq_s16_u16(vld1q_u16(ref + i));
+    const int16x8_t B = vreinterpretq_s16_u16(vld1q_u16(src + i));
+    const int16x8_t C = vreinterpretq_s16_u16(vld1q_u16(dst + i));
+    const int16x8_t D = vsubq_s16(A, B);       // diff_y
+    const int16x8_t F = vaddq_s16(C, D);       // new_y
+    const uint16x8_t H =
+        vreinterpretq_u16_s16(vmaxq_s16(vminq_s16(F, max), zero));
+    const int16x8_t I = vabsq_s16(D);          // abs(diff_y)
+    vst1q_u16(dst + i, H);
+    sum = vpadalq_u32(sum, vpaddlq_u16(vreinterpretq_u16_s16(I)));
+  }
+  diff = vgetq_lane_u64(sum, 0) + vgetq_lane_u64(sum, 1);
+  for (; i < len; ++i) {
+    const int diff_y = ref[i] - src[i];
+    const int new_y = (int)(dst[i]) + diff_y;
+    dst[i] = clip_NEON(new_y, max_y);
+    diff += (uint64_t)(abs(diff_y));
+  }
+  return diff;
+}
+
+static void SharpYuvUpdateRGB_NEON(const int16_t* ref, const int16_t* src,
+                                   int16_t* dst, int len) {
+  int i;
+  for (i = 0; i + 8 <= len; i += 8) {
+    const int16x8_t A = vld1q_s16(ref + i);
+    const int16x8_t B = vld1q_s16(src + i);
+    const int16x8_t C = vld1q_s16(dst + i);
+    const int16x8_t D = vsubq_s16(A, B);   // diff_uv
+    const int16x8_t E = vaddq_s16(C, D);   // new_uv
+    vst1q_s16(dst + i, E);
+  }
+  for (; i < len; ++i) {
+    const int diff_uv = ref[i] - src[i];
+    dst[i] += diff_uv;
+  }
+}
+
+static void SharpYuvFilterRow16_NEON(const int16_t* A, const int16_t* B,
+                                     int len, const uint16_t* best_y,
+                                     uint16_t* out, int bit_depth) {
+  const int max_y = (1 << bit_depth) - 1;
+  int i;
+  const int16x8_t max = vdupq_n_s16(max_y);
+  const int16x8_t zero = vdupq_n_s16(0);
+  for (i = 0; i + 8 <= len; i += 8) {
+    const int16x8_t a0 = vld1q_s16(A + i + 0);
+    const int16x8_t a1 = vld1q_s16(A + i + 1);
+    const int16x8_t b0 = vld1q_s16(B + i + 0);
+    const int16x8_t b1 = vld1q_s16(B + i + 1);
+    const int16x8_t a0b1 = vaddq_s16(a0, b1);
+    const int16x8_t a1b0 = vaddq_s16(a1, b0);
+    const int16x8_t a0a1b0b1 = vaddq_s16(a0b1, a1b0);  // A0+A1+B0+B1
+    const int16x8_t a0b1_2 = vaddq_s16(a0b1, a0b1);    // 2*(A0+B1)
+    const int16x8_t a1b0_2 = vaddq_s16(a1b0, a1b0);    // 2*(A1+B0)
+    const int16x8_t c0 = vshrq_n_s16(vaddq_s16(a0b1_2, a0a1b0b1), 3);
+    const int16x8_t c1 = vshrq_n_s16(vaddq_s16(a1b0_2, a0a1b0b1), 3);
+    const int16x8_t e0 = vrhaddq_s16(c1, a0);
+    const int16x8_t e1 = vrhaddq_s16(c0, a1);
+    const int16x8x2_t f = vzipq_s16(e0, e1);
+    const int16x8_t g0 = vreinterpretq_s16_u16(vld1q_u16(best_y + 2 * i + 0));
+    const int16x8_t g1 = vreinterpretq_s16_u16(vld1q_u16(best_y + 2 * i + 8));
+    const int16x8_t h0 = vaddq_s16(g0, f.val[0]);
+    const int16x8_t h1 = vaddq_s16(g1, f.val[1]);
+    const int16x8_t i0 = vmaxq_s16(vminq_s16(h0, max), zero);
+    const int16x8_t i1 = vmaxq_s16(vminq_s16(h1, max), zero);
+    vst1q_u16(out + 2 * i + 0, vreinterpretq_u16_s16(i0));
+    vst1q_u16(out + 2 * i + 8, vreinterpretq_u16_s16(i1));
+  }
+  for (; i < len; ++i) {
+    const int a0b1 = A[i + 0] + B[i + 1];
+    const int a1b0 = A[i + 1] + B[i + 0];
+    const int a0a1b0b1 = a0b1 + a1b0 + 8;
+    const int v0 = (8 * A[i + 0] + 2 * a1b0 + a0a1b0b1) >> 4;
+    const int v1 = (8 * A[i + 1] + 2 * a0b1 + a0a1b0b1) >> 4;
+    out[2 * i + 0] = clip_NEON(best_y[2 * i + 0] + v0, max_y);
+    out[2 * i + 1] = clip_NEON(best_y[2 * i + 1] + v1, max_y);
+  }
+}
+
+static void SharpYuvFilterRow32_NEON(const int16_t* A, const int16_t* B,
+                                     int len, const uint16_t* best_y,
+                                     uint16_t* out, int bit_depth) {
+  const int max_y = (1 << bit_depth) - 1;
+  int i;
+  const uint16x8_t max = vdupq_n_u16(max_y);
+  for (i = 0; i + 4 <= len; i += 4) {
+    const int16x4_t a0 = vld1_s16(A + i + 0);
+    const int16x4_t a1 = vld1_s16(A + i + 1);
+    const int16x4_t b0 = vld1_s16(B + i + 0);
+    const int16x4_t b1 = vld1_s16(B + i + 1);
+    const int32x4_t a0b1 = vaddl_s16(a0, b1);
+    const int32x4_t a1b0 = vaddl_s16(a1, b0);
+    const int32x4_t a0a1b0b1 = vaddq_s32(a0b1, a1b0);  // A0+A1+B0+B1
+    const int32x4_t a0b1_2 = vaddq_s32(a0b1, a0b1);    // 2*(A0+B1)
+    const int32x4_t a1b0_2 = vaddq_s32(a1b0, a1b0);    // 2*(A1+B0)
+    const int32x4_t c0 = vshrq_n_s32(vaddq_s32(a0b1_2, a0a1b0b1), 3);
+    const int32x4_t c1 = vshrq_n_s32(vaddq_s32(a1b0_2, a0a1b0b1), 3);
+    const int32x4_t e0 = vrhaddq_s32(c1, vmovl_s16(a0));
+    const int32x4_t e1 = vrhaddq_s32(c0, vmovl_s16(a1));
+    const int32x4x2_t f = vzipq_s32(e0, e1);
+
+    const int16x8_t g = vreinterpretq_s16_u16(vld1q_u16(best_y + 2 * i));
+    const int32x4_t h0 = vaddw_s16(f.val[0], vget_low_s16(g));
+    const int32x4_t h1 = vaddw_s16(f.val[1], vget_high_s16(g));
+    const uint16x8_t i_16 = vcombine_u16(vqmovun_s32(h0), vqmovun_s32(h1));
+    const uint16x8_t i_clamped = vminq_u16(i_16, max);
+    vst1q_u16(out + 2 * i + 0, i_clamped);
+  }
+  for (; i < len; ++i) {
+    const int a0b1 = A[i + 0] + B[i + 1];
+    const int a1b0 = A[i + 1] + B[i + 0];
+    const int a0a1b0b1 = a0b1 + a1b0 + 8;
+    const int v0 = (8 * A[i + 0] + 2 * a1b0 + a0a1b0b1) >> 4;
+    const int v1 = (8 * A[i + 1] + 2 * a0b1 + a0a1b0b1) >> 4;
+    out[2 * i + 0] = clip_NEON(best_y[2 * i + 0] + v0, max_y);
+    out[2 * i + 1] = clip_NEON(best_y[2 * i + 1] + v1, max_y);
+  }
+}
+
+static void SharpYuvFilterRow_NEON(const int16_t* A, const int16_t* B, int len,
+                                   const uint16_t* best_y, uint16_t* out,
+                                   int bit_depth) {
+  if (bit_depth <= 10) {
+    SharpYuvFilterRow16_NEON(A, B, len, best_y, out, bit_depth);
+  } else {
+    SharpYuvFilterRow32_NEON(A, B, len, best_y, out, bit_depth);
+  }
+}
+
+//------------------------------------------------------------------------------
+
+extern void InitSharpYuvNEON(void);
+
+WEBP_TSAN_IGNORE_FUNCTION void InitSharpYuvNEON(void) {
+  SharpYuvUpdateY = SharpYuvUpdateY_NEON;
+  SharpYuvUpdateRGB = SharpYuvUpdateRGB_NEON;
+  SharpYuvFilterRow = SharpYuvFilterRow_NEON;
+}
+
+#else  // !WEBP_USE_NEON
+
+extern void InitSharpYuvNEON(void);
+
+void InitSharpYuvNEON(void) {}
+
+#endif  // WEBP_USE_NEON

+ 201 - 0
webp.mod/libwebp/sharpyuv/sharpyuv_sse2.c

@@ -0,0 +1,201 @@
+// Copyright 2022 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+// Speed-critical functions for Sharp YUV.
+//
+// Author: Skal ([email protected])
+
+#include "sharpyuv/sharpyuv_dsp.h"
+
+#if defined(WEBP_USE_SSE2)
+#include <stdlib.h>
+#include <emmintrin.h>
+
+static uint16_t clip_SSE2(int v, int max) {
+  return (v < 0) ? 0 : (v > max) ? max : (uint16_t)v;
+}
+
+static uint64_t SharpYuvUpdateY_SSE2(const uint16_t* ref, const uint16_t* src,
+                                     uint16_t* dst, int len, int bit_depth) {
+  const int max_y = (1 << bit_depth) - 1;
+  uint64_t diff = 0;
+  uint32_t tmp[4];
+  int i;
+  const __m128i zero = _mm_setzero_si128();
+  const __m128i max = _mm_set1_epi16(max_y);
+  const __m128i one = _mm_set1_epi16(1);
+  __m128i sum = zero;
+
+  for (i = 0; i + 8 <= len; i += 8) {
+    const __m128i A = _mm_loadu_si128((const __m128i*)(ref + i));
+    const __m128i B = _mm_loadu_si128((const __m128i*)(src + i));
+    const __m128i C = _mm_loadu_si128((const __m128i*)(dst + i));
+    const __m128i D = _mm_sub_epi16(A, B);       // diff_y
+    const __m128i E = _mm_cmpgt_epi16(zero, D);  // sign (-1 or 0)
+    const __m128i F = _mm_add_epi16(C, D);       // new_y
+    const __m128i G = _mm_or_si128(E, one);      // -1 or 1
+    const __m128i H = _mm_max_epi16(_mm_min_epi16(F, max), zero);
+    const __m128i I = _mm_madd_epi16(D, G);      // sum(abs(...))
+    _mm_storeu_si128((__m128i*)(dst + i), H);
+    sum = _mm_add_epi32(sum, I);
+  }
+  _mm_storeu_si128((__m128i*)tmp, sum);
+  diff = tmp[3] + tmp[2] + tmp[1] + tmp[0];
+  for (; i < len; ++i) {
+    const int diff_y = ref[i] - src[i];
+    const int new_y = (int)dst[i] + diff_y;
+    dst[i] = clip_SSE2(new_y, max_y);
+    diff += (uint64_t)abs(diff_y);
+  }
+  return diff;
+}
+
+static void SharpYuvUpdateRGB_SSE2(const int16_t* ref, const int16_t* src,
+                                   int16_t* dst, int len) {
+  int i = 0;
+  for (i = 0; i + 8 <= len; i += 8) {
+    const __m128i A = _mm_loadu_si128((const __m128i*)(ref + i));
+    const __m128i B = _mm_loadu_si128((const __m128i*)(src + i));
+    const __m128i C = _mm_loadu_si128((const __m128i*)(dst + i));
+    const __m128i D = _mm_sub_epi16(A, B);   // diff_uv
+    const __m128i E = _mm_add_epi16(C, D);   // new_uv
+    _mm_storeu_si128((__m128i*)(dst + i), E);
+  }
+  for (; i < len; ++i) {
+    const int diff_uv = ref[i] - src[i];
+    dst[i] += diff_uv;
+  }
+}
+
+static void SharpYuvFilterRow16_SSE2(const int16_t* A, const int16_t* B,
+                                     int len, const uint16_t* best_y,
+                                     uint16_t* out, int bit_depth) {
+  const int max_y = (1 << bit_depth) - 1;
+  int i;
+  const __m128i kCst8 = _mm_set1_epi16(8);
+  const __m128i max = _mm_set1_epi16(max_y);
+  const __m128i zero = _mm_setzero_si128();
+  for (i = 0; i + 8 <= len; i += 8) {
+    const __m128i a0 = _mm_loadu_si128((const __m128i*)(A + i + 0));
+    const __m128i a1 = _mm_loadu_si128((const __m128i*)(A + i + 1));
+    const __m128i b0 = _mm_loadu_si128((const __m128i*)(B + i + 0));
+    const __m128i b1 = _mm_loadu_si128((const __m128i*)(B + i + 1));
+    const __m128i a0b1 = _mm_add_epi16(a0, b1);
+    const __m128i a1b0 = _mm_add_epi16(a1, b0);
+    const __m128i a0a1b0b1 = _mm_add_epi16(a0b1, a1b0);  // A0+A1+B0+B1
+    const __m128i a0a1b0b1_8 = _mm_add_epi16(a0a1b0b1, kCst8);
+    const __m128i a0b1_2 = _mm_add_epi16(a0b1, a0b1);    // 2*(A0+B1)
+    const __m128i a1b0_2 = _mm_add_epi16(a1b0, a1b0);    // 2*(A1+B0)
+    const __m128i c0 = _mm_srai_epi16(_mm_add_epi16(a0b1_2, a0a1b0b1_8), 3);
+    const __m128i c1 = _mm_srai_epi16(_mm_add_epi16(a1b0_2, a0a1b0b1_8), 3);
+    const __m128i d0 = _mm_add_epi16(c1, a0);
+    const __m128i d1 = _mm_add_epi16(c0, a1);
+    const __m128i e0 = _mm_srai_epi16(d0, 1);
+    const __m128i e1 = _mm_srai_epi16(d1, 1);
+    const __m128i f0 = _mm_unpacklo_epi16(e0, e1);
+    const __m128i f1 = _mm_unpackhi_epi16(e0, e1);
+    const __m128i g0 = _mm_loadu_si128((const __m128i*)(best_y + 2 * i + 0));
+    const __m128i g1 = _mm_loadu_si128((const __m128i*)(best_y + 2 * i + 8));
+    const __m128i h0 = _mm_add_epi16(g0, f0);
+    const __m128i h1 = _mm_add_epi16(g1, f1);
+    const __m128i i0 = _mm_max_epi16(_mm_min_epi16(h0, max), zero);
+    const __m128i i1 = _mm_max_epi16(_mm_min_epi16(h1, max), zero);
+    _mm_storeu_si128((__m128i*)(out + 2 * i + 0), i0);
+    _mm_storeu_si128((__m128i*)(out + 2 * i + 8), i1);
+  }
+  for (; i < len; ++i) {
+    //   (9 * A0 + 3 * A1 + 3 * B0 + B1 + 8) >> 4 =
+    // = (8 * A0 + 2 * (A1 + B0) + (A0 + A1 + B0 + B1 + 8)) >> 4
+    // We reuse the common sub-expressions.
+    const int a0b1 = A[i + 0] + B[i + 1];
+    const int a1b0 = A[i + 1] + B[i + 0];
+    const int a0a1b0b1 = a0b1 + a1b0 + 8;
+    const int v0 = (8 * A[i + 0] + 2 * a1b0 + a0a1b0b1) >> 4;
+    const int v1 = (8 * A[i + 1] + 2 * a0b1 + a0a1b0b1) >> 4;
+    out[2 * i + 0] = clip_SSE2(best_y[2 * i + 0] + v0, max_y);
+    out[2 * i + 1] = clip_SSE2(best_y[2 * i + 1] + v1, max_y);
+  }
+}
+
+static WEBP_INLINE __m128i s16_to_s32(__m128i in) {
+  return _mm_srai_epi32(_mm_unpacklo_epi16(in, in), 16);
+}
+
+static void SharpYuvFilterRow32_SSE2(const int16_t* A, const int16_t* B,
+                                     int len, const uint16_t* best_y,
+                                     uint16_t* out, int bit_depth) {
+  const int max_y = (1 << bit_depth) - 1;
+  int i;
+  const __m128i kCst8 = _mm_set1_epi32(8);
+  const __m128i max = _mm_set1_epi16(max_y);
+  const __m128i zero = _mm_setzero_si128();
+  for (i = 0; i + 4 <= len; i += 4) {
+    const __m128i a0 = s16_to_s32(_mm_loadl_epi64((const __m128i*)(A + i + 0)));
+    const __m128i a1 = s16_to_s32(_mm_loadl_epi64((const __m128i*)(A + i + 1)));
+    const __m128i b0 = s16_to_s32(_mm_loadl_epi64((const __m128i*)(B + i + 0)));
+    const __m128i b1 = s16_to_s32(_mm_loadl_epi64((const __m128i*)(B + i + 1)));
+    const __m128i a0b1 = _mm_add_epi32(a0, b1);
+    const __m128i a1b0 = _mm_add_epi32(a1, b0);
+    const __m128i a0a1b0b1 = _mm_add_epi32(a0b1, a1b0);  // A0+A1+B0+B1
+    const __m128i a0a1b0b1_8 = _mm_add_epi32(a0a1b0b1, kCst8);
+    const __m128i a0b1_2 = _mm_add_epi32(a0b1, a0b1);  // 2*(A0+B1)
+    const __m128i a1b0_2 = _mm_add_epi32(a1b0, a1b0);  // 2*(A1+B0)
+    const __m128i c0 = _mm_srai_epi32(_mm_add_epi32(a0b1_2, a0a1b0b1_8), 3);
+    const __m128i c1 = _mm_srai_epi32(_mm_add_epi32(a1b0_2, a0a1b0b1_8), 3);
+    const __m128i d0 = _mm_add_epi32(c1, a0);
+    const __m128i d1 = _mm_add_epi32(c0, a1);
+    const __m128i e0 = _mm_srai_epi32(d0, 1);
+    const __m128i e1 = _mm_srai_epi32(d1, 1);
+    const __m128i f0 = _mm_unpacklo_epi32(e0, e1);
+    const __m128i f1 = _mm_unpackhi_epi32(e0, e1);
+    const __m128i g = _mm_loadu_si128((const __m128i*)(best_y + 2 * i + 0));
+    const __m128i h_16 = _mm_add_epi16(g, _mm_packs_epi32(f0, f1));
+    const __m128i final = _mm_max_epi16(_mm_min_epi16(h_16, max), zero);
+    _mm_storeu_si128((__m128i*)(out + 2 * i + 0), final);
+  }
+  for (; i < len; ++i) {
+    //   (9 * A0 + 3 * A1 + 3 * B0 + B1 + 8) >> 4 =
+    // = (8 * A0 + 2 * (A1 + B0) + (A0 + A1 + B0 + B1 + 8)) >> 4
+    // We reuse the common sub-expressions.
+    const int a0b1 = A[i + 0] + B[i + 1];
+    const int a1b0 = A[i + 1] + B[i + 0];
+    const int a0a1b0b1 = a0b1 + a1b0 + 8;
+    const int v0 = (8 * A[i + 0] + 2 * a1b0 + a0a1b0b1) >> 4;
+    const int v1 = (8 * A[i + 1] + 2 * a0b1 + a0a1b0b1) >> 4;
+    out[2 * i + 0] = clip_SSE2(best_y[2 * i + 0] + v0, max_y);
+    out[2 * i + 1] = clip_SSE2(best_y[2 * i + 1] + v1, max_y);
+  }
+}
+
+static void SharpYuvFilterRow_SSE2(const int16_t* A, const int16_t* B, int len,
+                                   const uint16_t* best_y, uint16_t* out,
+                                   int bit_depth) {
+  if (bit_depth <= 10) {
+    SharpYuvFilterRow16_SSE2(A, B, len, best_y, out, bit_depth);
+  } else {
+    SharpYuvFilterRow32_SSE2(A, B, len, best_y, out, bit_depth);
+  }
+}
+
+//------------------------------------------------------------------------------
+
+extern void InitSharpYuvSSE2(void);
+
+WEBP_TSAN_IGNORE_FUNCTION void InitSharpYuvSSE2(void) {
+  SharpYuvUpdateY = SharpYuvUpdateY_SSE2;
+  SharpYuvUpdateRGB = SharpYuvUpdateRGB_SSE2;
+  SharpYuvFilterRow = SharpYuvFilterRow_SSE2;
+}
+#else  // !WEBP_USE_SSE2
+
+extern void InitSharpYuvSSE2(void);
+
+void InitSharpYuvSSE2(void) {}
+
+#endif  // WEBP_USE_SSE2

+ 2 - 2
webp.mod/libwebp/src/Makefile.am

@@ -36,7 +36,7 @@ libwebp_la_LIBADD += utils/libwebputils.la
 # other than the ones listed on the command line, i.e., after linking, it will
 # not have unresolved symbols. Some platforms (Windows among them) require all
 # symbols in shared libraries to be resolved at library creation.
-libwebp_la_LDFLAGS = -no-undefined -version-info 8:2:1
+libwebp_la_LDFLAGS = -no-undefined -version-info 8:8:1
 libwebpincludedir = $(includedir)/webp
 pkgconfig_DATA = libwebp.pc
 
@@ -48,7 +48,7 @@ if BUILD_LIBWEBPDECODER
   libwebpdecoder_la_LIBADD += dsp/libwebpdspdecode.la
   libwebpdecoder_la_LIBADD += utils/libwebputilsdecode.la
 
-  libwebpdecoder_la_LDFLAGS = -no-undefined -version-info 4:2:1
+  libwebpdecoder_la_LDFLAGS = -no-undefined -version-info 4:8:1
   pkgconfig_DATA += libwebpdecoder.pc
 endif
 

+ 2 - 1
webp.mod/libwebp/src/dec/tree_dec.c

@@ -12,10 +12,11 @@
 // Author: Skal ([email protected])
 
 #include "src/dec/vp8i_dec.h"
+#include "src/dsp/cpu.h"
 #include "src/utils/bit_reader_inl_utils.h"
 
 #if !defined(USE_GENERIC_TREE)
-#if !defined(__arm__) && !defined(_M_ARM) && !defined(__aarch64__)
+#if !defined(__arm__) && !defined(_M_ARM) && !WEBP_AARCH64
 // using a table is ~1-2% slower on ARM. Prefer the coded-tree approach then.
 #define USE_GENERIC_TREE 1   // ALTERNATE_CODE
 #else

+ 2 - 0
webp.mod/libwebp/src/dec/vp8_dec.c

@@ -494,6 +494,8 @@ static int GetCoeffsAlt(VP8BitReader* const br,
   return 16;
 }
 
+extern VP8CPUInfo VP8GetCPUInfo;
+
 WEBP_DSP_INIT_FUNC(InitGetCoeffs) {
   if (VP8GetCPUInfo != NULL && VP8GetCPUInfo(kSlowSSSE3)) {
     GetCoeffs = GetCoeffsAlt;

+ 2 - 2
webp.mod/libwebp/src/dec/vp8i_dec.h

@@ -31,8 +31,8 @@ extern "C" {
 
 // version numbers
 #define DEC_MAJ_VERSION 1
-#define DEC_MIN_VERSION 2
-#define DEC_REV_VERSION 1
+#define DEC_MIN_VERSION 3
+#define DEC_REV_VERSION 2
 
 // YUV-cache parameters. Cache is 32-bytes wide (= one cacheline).
 // Constraints are: We need to store one 16x16 block of luma samples (y),

+ 29 - 25
webp.mod/libwebp/src/dec/vp8l_dec.c

@@ -178,7 +178,7 @@ static WEBP_INLINE int PlaneCodeToDistance(int xsize, int plane_code) {
 
 //------------------------------------------------------------------------------
 // Decodes the next Huffman code from bit-stream.
-// FillBitWindow(br) needs to be called at minimum every second call
+// VP8LFillBitWindow(br) needs to be called at minimum every second call
 // to ReadSymbol, in order to pre-fetch enough bits.
 static WEBP_INLINE int ReadSymbol(const HuffmanCode* table,
                                   VP8LBitReader* const br) {
@@ -253,11 +253,11 @@ static int ReadHuffmanCodeLengths(
   int symbol;
   int max_symbol;
   int prev_code_len = DEFAULT_CODE_LENGTH;
-  HuffmanCode table[1 << LENGTHS_TABLE_BITS];
+  HuffmanTables tables;
 
-  if (!VP8LBuildHuffmanTable(table, LENGTHS_TABLE_BITS,
-                             code_length_code_lengths,
-                             NUM_CODE_LENGTH_CODES)) {
+  if (!VP8LHuffmanTablesAllocate(1 << LENGTHS_TABLE_BITS, &tables) ||
+      !VP8LBuildHuffmanTable(&tables, LENGTHS_TABLE_BITS,
+                             code_length_code_lengths, NUM_CODE_LENGTH_CODES)) {
     goto End;
   }
 
@@ -277,7 +277,7 @@ static int ReadHuffmanCodeLengths(
     int code_len;
     if (max_symbol-- == 0) break;
     VP8LFillBitWindow(br);
-    p = &table[VP8LPrefetchBits(br) & LENGTHS_TABLE_MASK];
+    p = &tables.curr_segment->start[VP8LPrefetchBits(br) & LENGTHS_TABLE_MASK];
     VP8LSetBitPos(br, br->bit_pos_ + p->bits);
     code_len = p->value;
     if (code_len < kCodeLengthLiterals) {
@@ -300,6 +300,7 @@ static int ReadHuffmanCodeLengths(
   ok = 1;
 
  End:
+  VP8LHuffmanTablesDeallocate(&tables);
   if (!ok) dec->status_ = VP8_STATUS_BITSTREAM_ERROR;
   return ok;
 }
@@ -307,7 +308,8 @@ static int ReadHuffmanCodeLengths(
 // 'code_lengths' is pre-allocated temporary buffer, used for creating Huffman
 // tree.
 static int ReadHuffmanCode(int alphabet_size, VP8LDecoder* const dec,
-                           int* const code_lengths, HuffmanCode* const table) {
+                           int* const code_lengths,
+                           HuffmanTables* const table) {
   int ok = 0;
   int size = 0;
   VP8LBitReader* const br = &dec->br_;
@@ -321,7 +323,7 @@ static int ReadHuffmanCode(int alphabet_size, VP8LDecoder* const dec,
     // The first code is either 1 bit or 8 bit code.
     int symbol = VP8LReadBits(br, (first_symbol_len_code == 0) ? 1 : 8);
     code_lengths[symbol] = 1;
-    // The second code (if present), is always 8 bit long.
+    // The second code (if present), is always 8 bits long.
     if (num_symbols == 2) {
       symbol = VP8LReadBits(br, 8);
       code_lengths[symbol] = 1;
@@ -362,8 +364,7 @@ static int ReadHuffmanCodes(VP8LDecoder* const dec, int xsize, int ysize,
   VP8LMetadata* const hdr = &dec->hdr_;
   uint32_t* huffman_image = NULL;
   HTreeGroup* htree_groups = NULL;
-  HuffmanCode* huffman_tables = NULL;
-  HuffmanCode* huffman_table = NULL;
+  HuffmanTables* huffman_tables = &hdr->huffman_tables_;
   int num_htree_groups = 1;
   int num_htree_groups_max = 1;
   int max_alphabet_size = 0;
@@ -372,6 +373,10 @@ static int ReadHuffmanCodes(VP8LDecoder* const dec, int xsize, int ysize,
   int* mapping = NULL;
   int ok = 0;
 
+  // Check the table has been 0 initialized (through InitMetadata).
+  assert(huffman_tables->root.start == NULL);
+  assert(huffman_tables->curr_segment == NULL);
+
   if (allow_recursion && VP8LReadBits(br, 1)) {
     // use meta Huffman codes.
     const int huffman_precision = VP8LReadBits(br, 3) + 2;
@@ -434,16 +439,15 @@ static int ReadHuffmanCodes(VP8LDecoder* const dec, int xsize, int ysize,
 
   code_lengths = (int*)WebPSafeCalloc((uint64_t)max_alphabet_size,
                                       sizeof(*code_lengths));
-  huffman_tables = (HuffmanCode*)WebPSafeMalloc(num_htree_groups * table_size,
-                                                sizeof(*huffman_tables));
   htree_groups = VP8LHtreeGroupsNew(num_htree_groups);
 
-  if (htree_groups == NULL || code_lengths == NULL || huffman_tables == NULL) {
+  if (htree_groups == NULL || code_lengths == NULL ||
+      !VP8LHuffmanTablesAllocate(num_htree_groups * table_size,
+                                 huffman_tables)) {
     dec->status_ = VP8_STATUS_OUT_OF_MEMORY;
     goto Error;
   }
 
-  huffman_table = huffman_tables;
   for (i = 0; i < num_htree_groups_max; ++i) {
     // If the index "i" is unused in the Huffman image, just make sure the
     // coefficients are valid but do not store them.
@@ -468,19 +472,20 @@ static int ReadHuffmanCodes(VP8LDecoder* const dec, int xsize, int ysize,
       int max_bits = 0;
       for (j = 0; j < HUFFMAN_CODES_PER_META_CODE; ++j) {
         int alphabet_size = kAlphabetSize[j];
-        htrees[j] = huffman_table;
         if (j == 0 && color_cache_bits > 0) {
           alphabet_size += (1 << color_cache_bits);
         }
-        size = ReadHuffmanCode(alphabet_size, dec, code_lengths, huffman_table);
+        size =
+            ReadHuffmanCode(alphabet_size, dec, code_lengths, huffman_tables);
+        htrees[j] = huffman_tables->curr_segment->curr_table;
         if (size == 0) {
           goto Error;
         }
         if (is_trivial_literal && kLiteralMap[j] == 1) {
-          is_trivial_literal = (huffman_table->bits == 0);
+          is_trivial_literal = (htrees[j]->bits == 0);
         }
-        total_size += huffman_table->bits;
-        huffman_table += size;
+        total_size += htrees[j]->bits;
+        huffman_tables->curr_segment->curr_table += size;
         if (j <= ALPHA) {
           int local_max_bits = code_lengths[0];
           int k;
@@ -515,14 +520,13 @@ static int ReadHuffmanCodes(VP8LDecoder* const dec, int xsize, int ysize,
   hdr->huffman_image_ = huffman_image;
   hdr->num_htree_groups_ = num_htree_groups;
   hdr->htree_groups_ = htree_groups;
-  hdr->huffman_tables_ = huffman_tables;
 
  Error:
   WebPSafeFree(code_lengths);
   WebPSafeFree(mapping);
   if (!ok) {
     WebPSafeFree(huffman_image);
-    WebPSafeFree(huffman_tables);
+    VP8LHuffmanTablesDeallocate(huffman_tables);
     VP8LHtreeGroupsFree(htree_groups);
   }
   return ok;
@@ -1281,7 +1285,7 @@ static int ExpandColorMap(int num_colors, VP8LTransform* const transform) {
     uint8_t* const new_data = (uint8_t*)new_color_map;
     new_color_map[0] = transform->data_[0];
     for (i = 4; i < 4 * num_colors; ++i) {
-      // Equivalent to AddPixelEq(), on a byte-basis.
+      // Equivalent to VP8LAddPixels(), on a byte-basis.
       new_data[i] = (data[i] + new_data[i - 4]) & 0xff;
     }
     for (; i < 4 * final_num_colors; ++i) {
@@ -1336,7 +1340,7 @@ static int ReadTransform(int* const xsize, int const* ysize,
        ok = ok && ExpandColorMap(num_colors, transform);
       break;
     }
-    case SUBTRACT_GREEN:
+    case SUBTRACT_GREEN_TRANSFORM:
       break;
     default:
       assert(0);    // can't happen
@@ -1358,7 +1362,7 @@ static void ClearMetadata(VP8LMetadata* const hdr) {
   assert(hdr != NULL);
 
   WebPSafeFree(hdr->huffman_image_);
-  WebPSafeFree(hdr->huffman_tables_);
+  VP8LHuffmanTablesDeallocate(&hdr->huffman_tables_);
   VP8LHtreeGroupsFree(hdr->htree_groups_);
   VP8LColorCacheClear(&hdr->color_cache_);
   VP8LColorCacheClear(&hdr->saved_color_cache_);
@@ -1673,7 +1677,7 @@ int VP8LDecodeImage(VP8LDecoder* const dec) {
 
   if (dec == NULL) return 0;
 
-  assert(dec->hdr_.huffman_tables_ != NULL);
+  assert(dec->hdr_.huffman_tables_.root.start != NULL);
   assert(dec->hdr_.htree_groups_ != NULL);
   assert(dec->hdr_.num_htree_groups_ > 0);
 

+ 1 - 1
webp.mod/libwebp/src/dec/vp8li_dec.h

@@ -51,7 +51,7 @@ typedef struct {
   uint32_t*       huffman_image_;
   int             num_htree_groups_;
   HTreeGroup*     htree_groups_;
-  HuffmanCode*    huffman_tables_;
+  HuffmanTables   huffman_tables_;
 } VP8LMetadata;
 
 typedef struct VP8LDecoder VP8LDecoder;

+ 21 - 14
webp.mod/libwebp/src/dec/webp_dec.c

@@ -179,7 +179,7 @@ static VP8StatusCode ParseOptionalChunks(const uint8_t** const data,
       return VP8_STATUS_BITSTREAM_ERROR;          // Not a valid chunk size.
     }
     // For odd-sized chunk-payload, there's one byte padding at the end.
-    disk_chunk_size = (CHUNK_HEADER_SIZE + chunk_size + 1) & ~1;
+    disk_chunk_size = (CHUNK_HEADER_SIZE + chunk_size + 1) & ~1u;
     total_size += disk_chunk_size;
 
     // Check that total bytes skipped so far does not exceed riff_size.
@@ -658,19 +658,26 @@ uint8_t* WebPDecodeBGRA(const uint8_t* data, size_t data_size,
 uint8_t* WebPDecodeYUV(const uint8_t* data, size_t data_size,
                        int* width, int* height, uint8_t** u, uint8_t** v,
                        int* stride, int* uv_stride) {
-  WebPDecBuffer output;   // only to preserve the side-infos
-  uint8_t* const out = Decode(MODE_YUV, data, data_size,
-                              width, height, &output);
-
-  if (out != NULL) {
-    const WebPYUVABuffer* const buf = &output.u.YUVA;
-    *u = buf->u;
-    *v = buf->v;
-    *stride = buf->y_stride;
-    *uv_stride = buf->u_stride;
-    assert(buf->u_stride == buf->v_stride);
-  }
-  return out;
+  // data, width and height are checked by Decode().
+  if (u == NULL || v == NULL || stride == NULL || uv_stride == NULL) {
+    return NULL;
+  }
+
+  {
+    WebPDecBuffer output;   // only to preserve the side-infos
+    uint8_t* const out = Decode(MODE_YUV, data, data_size,
+                                width, height, &output);
+
+    if (out != NULL) {
+      const WebPYUVABuffer* const buf = &output.u.YUVA;
+      *u = buf->u;
+      *v = buf->v;
+      *stride = buf->y_stride;
+      *uv_stride = buf->u_stride;
+      assert(buf->u_stride == buf->v_stride);
+    }
+    return out;
+  }
 }
 
 static void DefaultFeatures(WebPBitstreamFeatures* const features) {

+ 1 - 1
webp.mod/libwebp/src/demux/Makefile.am

@@ -13,6 +13,6 @@ noinst_HEADERS =
 noinst_HEADERS += ../webp/format_constants.h
 
 libwebpdemux_la_LIBADD = ../libwebp.la
-libwebpdemux_la_LDFLAGS = -no-undefined -version-info 2:8:0
+libwebpdemux_la_LDFLAGS = -no-undefined -version-info 2:14:0
 libwebpdemuxincludedir = $(includedir)/webp
 pkgconfig_DATA = libwebpdemux.pc

+ 2 - 5
webp.mod/libwebp/src/demux/demux.c

@@ -24,8 +24,8 @@
 #include "src/webp/format_constants.h"
 
 #define DMUX_MAJ_VERSION 1
-#define DMUX_MIN_VERSION 2
-#define DMUX_REV_VERSION 1
+#define DMUX_MIN_VERSION 3
+#define DMUX_REV_VERSION 2
 
 typedef struct {
   size_t start_;        // start location of the data
@@ -614,7 +614,6 @@ static int IsValidExtendedFormat(const WebPDemuxer* const dmux) {
 
   while (f != NULL) {
     const int cur_frame_set = f->frame_num_;
-    int frame_count = 0;
 
     // Check frame properties.
     for (; f != NULL && f->frame_num_ == cur_frame_set; f = f->next_) {
@@ -649,8 +648,6 @@ static int IsValidExtendedFormat(const WebPDemuxer* const dmux) {
                             dmux->canvas_width_, dmux->canvas_height_)) {
         return 0;
       }
-
-      ++frame_count;
     }
   }
   return 1;

+ 2 - 2
webp.mod/libwebp/src/demux/libwebpdemux.pc.in

@@ -6,6 +6,6 @@ includedir=@includedir@
 Name: libwebpdemux
 Description: Library for parsing the WebP graphics format container
 Version: @PACKAGE_VERSION@
-Requires: libwebp >= 0.2.0
+Requires.private: libwebp >= 0.2.0
 Cflags: -I${includedir}
-Libs: -L${libdir} -lwebpdemux
+Libs: -L${libdir} -l@webp_libname_prefix@webpdemux

+ 5 - 5
webp.mod/libwebp/src/demux/libwebpdemux.rc

@@ -6,8 +6,8 @@
 LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
 
 VS_VERSION_INFO VERSIONINFO
- FILEVERSION 1,0,2,1
- PRODUCTVERSION 1,0,2,1
+ FILEVERSION 1,0,3,2
+ PRODUCTVERSION 1,0,3,2
  FILEFLAGSMASK 0x3fL
 #ifdef _DEBUG
  FILEFLAGS 0x1L
@@ -24,12 +24,12 @@ BEGIN
         BEGIN
             VALUE "CompanyName", "Google, Inc."
             VALUE "FileDescription", "libwebpdemux DLL"
-            VALUE "FileVersion", "1.2.1"
+            VALUE "FileVersion", "1.3.2"
             VALUE "InternalName", "libwebpdemux.dll"
-            VALUE "LegalCopyright", "Copyright (C) 2021"
+            VALUE "LegalCopyright", "Copyright (C) 2023"
             VALUE "OriginalFilename", "libwebpdemux.dll"
             VALUE "ProductName", "WebP Image Demuxer"
-            VALUE "ProductVersion", "1.2.1"
+            VALUE "ProductVersion", "1.3.2"
         END
     END
     BLOCK "VarFileInfo"

+ 1 - 0
webp.mod/libwebp/src/dsp/Makefile.am

@@ -24,6 +24,7 @@ commondir = $(includedir)/webp
 COMMON_SOURCES =
 COMMON_SOURCES += alpha_processing.c
 COMMON_SOURCES += cpu.c
+COMMON_SOURCES += cpu.h
 COMMON_SOURCES += dec.c
 COMMON_SOURCES += dec_clip_tables.c
 COMMON_SOURCES += dsp.h

+ 1 - 0
webp.mod/libwebp/src/dsp/alpha_processing.c

@@ -425,6 +425,7 @@ void (*WebPAlphaReplace)(uint32_t* src, int length, uint32_t color);
 //------------------------------------------------------------------------------
 // Init function
 
+extern VP8CPUInfo VP8GetCPUInfo;
 extern void WebPInitAlphaProcessingMIPSdspR2(void);
 extern void WebPInitAlphaProcessingSSE2(void);
 extern void WebPInitAlphaProcessingSSE41(void);

+ 4 - 2
webp.mod/libwebp/src/dsp/alpha_processing_neon.c

@@ -83,7 +83,7 @@ static void ApplyAlphaMultiply_NEON(uint8_t* rgba, int alpha_first,
 static int DispatchAlpha_NEON(const uint8_t* WEBP_RESTRICT alpha,
                               int alpha_stride, int width, int height,
                               uint8_t* WEBP_RESTRICT dst, int dst_stride) {
-  uint32_t alpha_mask = 0xffffffffu;
+  uint32_t alpha_mask = 0xffu;
   uint8x8_t mask8 = vdup_n_u8(0xff);
   uint32_t tmp[2];
   int i, j;
@@ -107,6 +107,7 @@ static int DispatchAlpha_NEON(const uint8_t* WEBP_RESTRICT alpha,
     dst += dst_stride;
   }
   vst1_u8((uint8_t*)tmp, mask8);
+  alpha_mask *= 0x01010101;
   alpha_mask &= tmp[0];
   alpha_mask &= tmp[1];
   return (alpha_mask != 0xffffffffu);
@@ -135,7 +136,7 @@ static void DispatchAlphaToGreen_NEON(const uint8_t* WEBP_RESTRICT alpha,
 static int ExtractAlpha_NEON(const uint8_t* WEBP_RESTRICT argb, int argb_stride,
                              int width, int height,
                              uint8_t* WEBP_RESTRICT alpha, int alpha_stride) {
-  uint32_t alpha_mask = 0xffffffffu;
+  uint32_t alpha_mask = 0xffu;
   uint8x8_t mask8 = vdup_n_u8(0xff);
   uint32_t tmp[2];
   int i, j;
@@ -157,6 +158,7 @@ static int ExtractAlpha_NEON(const uint8_t* WEBP_RESTRICT argb, int argb_stride,
     alpha += alpha_stride;
   }
   vst1_u8((uint8_t*)tmp, mask8);
+  alpha_mask *= 0x01010101;
   alpha_mask &= tmp[0];
   alpha_mask &= tmp[1];
   return (alpha_mask == 0xffffffffu);

+ 6 - 6
webp.mod/libwebp/src/dsp/alpha_processing_sse2.c

@@ -26,8 +26,8 @@ static int DispatchAlpha_SSE2(const uint8_t* WEBP_RESTRICT alpha,
   uint32_t alpha_and = 0xff;
   int i, j;
   const __m128i zero = _mm_setzero_si128();
-  const __m128i rgb_mask = _mm_set1_epi32(0xffffff00u);  // to preserve RGB
-  const __m128i all_0xff = _mm_set_epi32(0, 0, ~0u, ~0u);
+  const __m128i rgb_mask = _mm_set1_epi32((int)0xffffff00);  // to preserve RGB
+  const __m128i all_0xff = _mm_set_epi32(0, 0, ~0, ~0);
   __m128i all_alphas = all_0xff;
 
   // We must be able to access 3 extra bytes after the last written byte
@@ -106,8 +106,8 @@ static int ExtractAlpha_SSE2(const uint8_t* WEBP_RESTRICT argb, int argb_stride,
   // value is not 0xff if any of the alpha[] is not equal to 0xff.
   uint32_t alpha_and = 0xff;
   int i, j;
-  const __m128i a_mask = _mm_set1_epi32(0xffu);  // to preserve alpha
-  const __m128i all_0xff = _mm_set_epi32(0, 0, ~0u, ~0u);
+  const __m128i a_mask = _mm_set1_epi32(0xff);  // to preserve alpha
+  const __m128i all_0xff = _mm_set_epi32(0, 0, ~0, ~0);
   __m128i all_alphas = all_0xff;
 
   // We must be able to access 3 extra bytes after the last written byte
@@ -178,7 +178,7 @@ static int ExtractAlpha_SSE2(const uint8_t* WEBP_RESTRICT argb, int argb_stride,
 static void ApplyAlphaMultiply_SSE2(uint8_t* rgba, int alpha_first,
                                     int w, int h, int stride) {
   const __m128i zero = _mm_setzero_si128();
-  const __m128i kMult = _mm_set1_epi16(0x8081u);
+  const __m128i kMult = _mm_set1_epi16((short)0x8081);
   const __m128i kMask = _mm_set_epi16(0, 0xff, 0xff, 0, 0, 0xff, 0xff, 0);
   const int kSpan = 4;
   while (h-- > 0) {
@@ -267,7 +267,7 @@ static int HasAlpha32b_SSE2(const uint8_t* src, int length) {
 }
 
 static void AlphaReplace_SSE2(uint32_t* src, int length, uint32_t color) {
-  const __m128i m_color = _mm_set1_epi32(color);
+  const __m128i m_color = _mm_set1_epi32((int)color);
   const __m128i zero = _mm_setzero_si128();
   int i = 0;
   for (; i + 8 <= length; i += 8) {

+ 1 - 1
webp.mod/libwebp/src/dsp/alpha_processing_sse41.c

@@ -26,7 +26,7 @@ static int ExtractAlpha_SSE41(const uint8_t* WEBP_RESTRICT argb,
   // value is not 0xff if any of the alpha[] is not equal to 0xff.
   uint32_t alpha_and = 0xff;
   int i, j;
-  const __m128i all_0xff = _mm_set1_epi32(~0u);
+  const __m128i all_0xff = _mm_set1_epi32(~0);
   __m128i all_alphas = all_0xff;
 
   // We must be able to access 3 extra bytes after the last written byte

+ 1 - 0
webp.mod/libwebp/src/dsp/cost.c

@@ -374,6 +374,7 @@ static void SetResidualCoeffs_C(const int16_t* const coeffs,
 VP8GetResidualCostFunc VP8GetResidualCost;
 VP8SetResidualCoeffsFunc VP8SetResidualCoeffs;
 
+extern VP8CPUInfo VP8GetCPUInfo;
 extern void VP8EncDspCostInitMIPS32(void);
 extern void VP8EncDspCostInitMIPSdspR2(void);
 extern void VP8EncDspCostInitSSE2(void);

+ 2 - 2
webp.mod/libwebp/src/dsp/cost_neon.c

@@ -29,7 +29,7 @@ static void SetResidualCoeffs_NEON(const int16_t* const coeffs,
   const uint8x16_t eob = vcombine_u8(vqmovn_u16(eob_0), vqmovn_u16(eob_1));
   const uint8x16_t masked = vandq_u8(eob, vld1q_u8(position));
 
-#ifdef __aarch64__
+#if WEBP_AARCH64
   res->last = vmaxvq_u8(masked) - 1;
 #else
   const uint8x8_t eob_8x8 = vmax_u8(vget_low_u8(masked), vget_high_u8(masked));
@@ -43,7 +43,7 @@ static void SetResidualCoeffs_NEON(const int16_t* const coeffs,
 
   vst1_lane_s32(&res->last, vreinterpret_s32_u32(eob_32x2), 0);
   --res->last;
-#endif  // __aarch64__
+#endif  // WEBP_AARCH64
 
   res->coeffs = coeffs;
 }

+ 8 - 2
webp.mod/libwebp/src/dsp/cpu.c

@@ -11,7 +11,7 @@
 //
 // Author: Christian Duvivier ([email protected])
 
-#include "src/dsp/dsp.h"
+#include "src/dsp/cpu.h"
 
 #if defined(WEBP_HAVE_NEON_RTCD)
 #include <stdio.h>
@@ -173,6 +173,7 @@ static int x86CPUInfo(CPUFeature feature) {
   }
   return 0;
 }
+WEBP_EXTERN VP8CPUInfo VP8GetCPUInfo;
 VP8CPUInfo VP8GetCPUInfo = x86CPUInfo;
 #elif defined(WEBP_ANDROID_NEON)  // NB: needs to be before generic NEON test.
 static int AndroidCPUInfo(CPUFeature feature) {
@@ -184,6 +185,7 @@ static int AndroidCPUInfo(CPUFeature feature) {
   }
   return 0;
 }
+WEBP_EXTERN VP8CPUInfo VP8GetCPUInfo;
 VP8CPUInfo VP8GetCPUInfo = AndroidCPUInfo;
 #elif defined(EMSCRIPTEN) // also needs to be before generic NEON test
 // Use compile flags as an indicator of SIMD support instead of a runtime check.
@@ -208,11 +210,12 @@ static int wasmCPUInfo(CPUFeature feature) {
   }
   return 0;
 }
+WEBP_EXTERN VP8CPUInfo VP8GetCPUInfo;
 VP8CPUInfo VP8GetCPUInfo = wasmCPUInfo;
 #elif defined(WEBP_HAVE_NEON)
 // In most cases this function doesn't check for NEON support (it's assumed by
 // the configuration), but enables turning off NEON at runtime, for testing
-// purposes, by setting VP8DecGetCPUInfo = NULL.
+// purposes, by setting VP8GetCPUInfo = NULL.
 static int armCPUInfo(CPUFeature feature) {
   if (feature != kNEON) return 0;
 #if defined(__linux__) && defined(WEBP_HAVE_NEON_RTCD)
@@ -236,6 +239,7 @@ static int armCPUInfo(CPUFeature feature) {
   return 1;
 #endif
 }
+WEBP_EXTERN VP8CPUInfo VP8GetCPUInfo;
 VP8CPUInfo VP8GetCPUInfo = armCPUInfo;
 #elif defined(WEBP_USE_MIPS32) || defined(WEBP_USE_MIPS_DSP_R2) || \
       defined(WEBP_USE_MSA)
@@ -247,7 +251,9 @@ static int mipsCPUInfo(CPUFeature feature) {
   }
 
 }
+WEBP_EXTERN VP8CPUInfo VP8GetCPUInfo;
 VP8CPUInfo VP8GetCPUInfo = mipsCPUInfo;
 #else
+WEBP_EXTERN VP8CPUInfo VP8GetCPUInfo;
 VP8CPUInfo VP8GetCPUInfo = NULL;
 #endif

+ 266 - 0
webp.mod/libwebp/src/dsp/cpu.h

@@ -0,0 +1,266 @@
+// Copyright 2022 Google Inc. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the COPYING file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+// -----------------------------------------------------------------------------
+//
+//   CPU detection functions and macros.
+//
+// Author: Skal ([email protected])
+
+#ifndef WEBP_DSP_CPU_H_
+#define WEBP_DSP_CPU_H_
+
+#include <stddef.h>
+
+#ifdef HAVE_CONFIG_H
+#include "src/webp/config.h"
+#endif
+
+#include "src/webp/types.h"
+
+#if defined(__GNUC__)
+#define LOCAL_GCC_VERSION ((__GNUC__ << 8) | __GNUC_MINOR__)
+#define LOCAL_GCC_PREREQ(maj, min) (LOCAL_GCC_VERSION >= (((maj) << 8) | (min)))
+#else
+#define LOCAL_GCC_VERSION 0
+#define LOCAL_GCC_PREREQ(maj, min) 0
+#endif
+
+#if defined(__clang__)
+#define LOCAL_CLANG_VERSION ((__clang_major__ << 8) | __clang_minor__)
+#define LOCAL_CLANG_PREREQ(maj, min) \
+  (LOCAL_CLANG_VERSION >= (((maj) << 8) | (min)))
+#else
+#define LOCAL_CLANG_VERSION 0
+#define LOCAL_CLANG_PREREQ(maj, min) 0
+#endif
+
+#ifndef __has_builtin
+#define __has_builtin(x) 0
+#endif
+
+//------------------------------------------------------------------------------
+// x86 defines.
+
+#if !defined(HAVE_CONFIG_H)
+#if defined(_MSC_VER) && _MSC_VER > 1310 && \
+    (defined(_M_X64) || defined(_M_IX86))
+#define WEBP_MSC_SSE2  // Visual C++ SSE2 targets
+#endif
+
+#if defined(_MSC_VER) && _MSC_VER >= 1500 && \
+    (defined(_M_X64) || defined(_M_IX86))
+#define WEBP_MSC_SSE41  // Visual C++ SSE4.1 targets
+#endif
+#endif
+
+// WEBP_HAVE_* are used to indicate the presence of the instruction set in dsp
+// files without intrinsics, allowing the corresponding Init() to be called.
+// Files containing intrinsics will need to be built targeting the instruction
+// set so should succeed on one of the earlier tests.
+#if (defined(__SSE2__) || defined(WEBP_MSC_SSE2)) && \
+    (!defined(HAVE_CONFIG_H) || defined(WEBP_HAVE_SSE2))
+#define WEBP_USE_SSE2
+#endif
+
+#if defined(WEBP_USE_SSE2) && !defined(WEBP_HAVE_SSE2)
+#define WEBP_HAVE_SSE2
+#endif
+
+#if (defined(__SSE4_1__) || defined(WEBP_MSC_SSE41)) && \
+    (!defined(HAVE_CONFIG_H) || defined(WEBP_HAVE_SSE41))
+#define WEBP_USE_SSE41
+#endif
+
+#if defined(WEBP_USE_SSE41) && !defined(WEBP_HAVE_SSE41)
+#define WEBP_HAVE_SSE41
+#endif
+
+#undef WEBP_MSC_SSE41
+#undef WEBP_MSC_SSE2
+
+//------------------------------------------------------------------------------
+// Arm defines.
+
+// The intrinsics currently cause compiler errors with arm-nacl-gcc and the
+// inline assembly would need to be modified for use with Native Client.
+#if ((defined(__ARM_NEON__) || defined(__aarch64__)) &&       \
+     (!defined(HAVE_CONFIG_H) || defined(WEBP_HAVE_NEON))) && \
+    !defined(__native_client__)
+#define WEBP_USE_NEON
+#endif
+
+#if !defined(WEBP_USE_NEON) && defined(__ANDROID__) && \
+    defined(__ARM_ARCH_7A__) && defined(HAVE_CPU_FEATURES_H)
+#define WEBP_ANDROID_NEON  // Android targets that may have NEON
+#define WEBP_USE_NEON
+#endif
+
+// Note: ARM64 is supported in Visual Studio 2017, but requires the direct
+// inclusion of arm64_neon.h; Visual Studio 2019 includes this file in
+// arm_neon.h. Compile errors were seen with Visual Studio 2019 16.4 with
+// vtbl4_u8(); a fix was made in 16.6.
+#if defined(_MSC_VER) && \
+    ((_MSC_VER >= 1700 && defined(_M_ARM)) || \
+     (_MSC_VER >= 1926 && (defined(_M_ARM64) || defined(_M_ARM64EC))))
+#define WEBP_USE_NEON
+#define WEBP_USE_INTRINSICS
+#endif
+
+#if defined(__aarch64__) || defined(_M_ARM64) || defined(_M_ARM64EC)
+#define WEBP_AARCH64 1
+#else
+#define WEBP_AARCH64 0
+#endif
+
+#if defined(WEBP_USE_NEON) && !defined(WEBP_HAVE_NEON)
+#define WEBP_HAVE_NEON
+#endif
+
+//------------------------------------------------------------------------------
+// MIPS defines.
+
+#if defined(__mips__) && !defined(__mips64) && defined(__mips_isa_rev) && \
+    (__mips_isa_rev >= 1) && (__mips_isa_rev < 6)
+#define WEBP_USE_MIPS32
+#if (__mips_isa_rev >= 2)
+#define WEBP_USE_MIPS32_R2
+#if defined(__mips_dspr2) || (defined(__mips_dsp_rev) && __mips_dsp_rev >= 2)
+#define WEBP_USE_MIPS_DSP_R2
+#endif
+#endif
+#endif
+
+#if defined(__mips_msa) && defined(__mips_isa_rev) && (__mips_isa_rev >= 5)
+#define WEBP_USE_MSA
+#endif
+
+//------------------------------------------------------------------------------
+
+#ifndef WEBP_DSP_OMIT_C_CODE
+#define WEBP_DSP_OMIT_C_CODE 1
+#endif
+
+#if defined(WEBP_USE_NEON) && WEBP_DSP_OMIT_C_CODE
+#define WEBP_NEON_OMIT_C_CODE 1
+#else
+#define WEBP_NEON_OMIT_C_CODE 0
+#endif
+
+#if !(LOCAL_CLANG_PREREQ(3, 8) || LOCAL_GCC_PREREQ(4, 8) || WEBP_AARCH64)
+#define WEBP_NEON_WORK_AROUND_GCC 1
+#else
+#define WEBP_NEON_WORK_AROUND_GCC 0
+#endif
+
+//------------------------------------------------------------------------------
+
+// This macro prevents thread_sanitizer from reporting known concurrent writes.
+#define WEBP_TSAN_IGNORE_FUNCTION
+#if defined(__has_feature)
+#if __has_feature(thread_sanitizer)
+#undef WEBP_TSAN_IGNORE_FUNCTION
+#define WEBP_TSAN_IGNORE_FUNCTION __attribute__((no_sanitize_thread))
+#endif
+#endif
+
+#if defined(__has_feature)
+#if __has_feature(memory_sanitizer)
+#define WEBP_MSAN
+#endif
+#endif
+
+#if defined(WEBP_USE_THREAD) && !defined(_WIN32)
+#include <pthread.h>  // NOLINT
+
+#define WEBP_DSP_INIT(func)                                         \
+  do {                                                              \
+    static volatile VP8CPUInfo func##_last_cpuinfo_used =           \
+        (VP8CPUInfo)&func##_last_cpuinfo_used;                      \
+    static pthread_mutex_t func##_lock = PTHREAD_MUTEX_INITIALIZER; \
+    if (pthread_mutex_lock(&func##_lock)) break;                    \
+    if (func##_last_cpuinfo_used != VP8GetCPUInfo) func();          \
+    func##_last_cpuinfo_used = VP8GetCPUInfo;                       \
+    (void)pthread_mutex_unlock(&func##_lock);                       \
+  } while (0)
+#else  // !(defined(WEBP_USE_THREAD) && !defined(_WIN32))
+#define WEBP_DSP_INIT(func)                               \
+  do {                                                    \
+    static volatile VP8CPUInfo func##_last_cpuinfo_used = \
+        (VP8CPUInfo)&func##_last_cpuinfo_used;            \
+    if (func##_last_cpuinfo_used == VP8GetCPUInfo) break; \
+    func();                                               \
+    func##_last_cpuinfo_used = VP8GetCPUInfo;             \
+  } while (0)
+#endif  // defined(WEBP_USE_THREAD) && !defined(_WIN32)
+
+// Defines an Init + helper function that control multiple initialization of
+// function pointers / tables.
+/* Usage:
+   WEBP_DSP_INIT_FUNC(InitFunc) {
+     ...function body
+   }
+*/
+#define WEBP_DSP_INIT_FUNC(name)                                            \
+  static WEBP_TSAN_IGNORE_FUNCTION void name##_body(void);                  \
+  WEBP_TSAN_IGNORE_FUNCTION void name(void) { WEBP_DSP_INIT(name##_body); } \
+  static WEBP_TSAN_IGNORE_FUNCTION void name##_body(void)
+
+#define WEBP_UBSAN_IGNORE_UNDEF
+#define WEBP_UBSAN_IGNORE_UNSIGNED_OVERFLOW
+#if defined(__clang__) && defined(__has_attribute)
+#if __has_attribute(no_sanitize)
+// This macro prevents the undefined behavior sanitizer from reporting
+// failures. This is only meant to silence unaligned loads on platforms that
+// are known to support them.
+#undef WEBP_UBSAN_IGNORE_UNDEF
+#define WEBP_UBSAN_IGNORE_UNDEF __attribute__((no_sanitize("undefined")))
+
+// This macro prevents the undefined behavior sanitizer from reporting
+// failures related to unsigned integer overflows. This is only meant to
+// silence cases where this well defined behavior is expected.
+#undef WEBP_UBSAN_IGNORE_UNSIGNED_OVERFLOW
+#define WEBP_UBSAN_IGNORE_UNSIGNED_OVERFLOW \
+  __attribute__((no_sanitize("unsigned-integer-overflow")))
+#endif
+#endif
+
+// If 'ptr' is NULL, returns NULL. Otherwise returns 'ptr + off'.
+// Prevents undefined behavior sanitizer nullptr-with-nonzero-offset warning.
+#if !defined(WEBP_OFFSET_PTR)
+#define WEBP_OFFSET_PTR(ptr, off) (((ptr) == NULL) ? NULL : ((ptr) + (off)))
+#endif
+
+// Regularize the definition of WEBP_SWAP_16BIT_CSP (backward compatibility)
+#if !defined(WEBP_SWAP_16BIT_CSP)
+#define WEBP_SWAP_16BIT_CSP 0
+#endif
+
+// some endian fix (e.g.: mips-gcc doesn't define __BIG_ENDIAN__)
+#if !defined(WORDS_BIGENDIAN) &&                   \
+    (defined(__BIG_ENDIAN__) || defined(_M_PPC) || \
+     (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)))
+#define WORDS_BIGENDIAN
+#endif
+
+typedef enum {
+  kSSE2,
+  kSSE3,
+  kSlowSSSE3,  // special feature for slow SSSE3 architectures
+  kSSE4_1,
+  kAVX,
+  kAVX2,
+  kNEON,
+  kMIPS32,
+  kMIPSdspR2,
+  kMSA
+} CPUFeature;
+
+// returns true if the CPU supports the feature.
+typedef int (*VP8CPUInfo)(CPUFeature feature);
+
+#endif  // WEBP_DSP_CPU_H_

+ 1 - 0
webp.mod/libwebp/src/dsp/dec.c

@@ -734,6 +734,7 @@ VP8SimpleFilterFunc VP8SimpleHFilter16i;
 void (*VP8DitherCombine8x8)(const uint8_t* dither, uint8_t* dst,
                             int dst_stride);
 
+extern VP8CPUInfo VP8GetCPUInfo;
 extern void VP8DspInitSSE2(void);
 extern void VP8DspInitSSE41(void);
 extern void VP8DspInitNEON(void);

+ 2 - 2
webp.mod/libwebp/src/dsp/dec_neon.c

@@ -1428,7 +1428,7 @@ static WEBP_INLINE void DC8_NEON(uint8_t* dst, int do_top, int do_left) {
 
   if (do_top) {
     const uint8x8_t A = vld1_u8(dst - BPS);  // top row
-#if defined(__aarch64__)
+#if WEBP_AARCH64
     const uint16_t p2 = vaddlv_u8(A);
     sum_top = vdupq_n_u16(p2);
 #else
@@ -1511,7 +1511,7 @@ static WEBP_INLINE void DC16_NEON(uint8_t* dst, int do_top, int do_left) {
 
   if (do_top) {
     const uint8x16_t A = vld1q_u8(dst - BPS);  // top row
-#if defined(__aarch64__)
+#if WEBP_AARCH64
     const uint16_t p3 = vaddlvq_u8(A);
     sum_top = vdupq_n_u16(p3);
 #else

+ 47 - 46
webp.mod/libwebp/src/dsp/dec_sse2.c

@@ -158,10 +158,10 @@ static void Transform_SSE2(const int16_t* in, uint8_t* dst, int do_two) {
       dst3 = _mm_loadl_epi64((__m128i*)(dst + 3 * BPS));
     } else {
       // Load four bytes/pixels per line.
-      dst0 = _mm_cvtsi32_si128(WebPMemToUint32(dst + 0 * BPS));
-      dst1 = _mm_cvtsi32_si128(WebPMemToUint32(dst + 1 * BPS));
-      dst2 = _mm_cvtsi32_si128(WebPMemToUint32(dst + 2 * BPS));
-      dst3 = _mm_cvtsi32_si128(WebPMemToUint32(dst + 3 * BPS));
+      dst0 = _mm_cvtsi32_si128(WebPMemToInt32(dst + 0 * BPS));
+      dst1 = _mm_cvtsi32_si128(WebPMemToInt32(dst + 1 * BPS));
+      dst2 = _mm_cvtsi32_si128(WebPMemToInt32(dst + 2 * BPS));
+      dst3 = _mm_cvtsi32_si128(WebPMemToInt32(dst + 3 * BPS));
     }
     // Convert to 16b.
     dst0 = _mm_unpacklo_epi8(dst0, zero);
@@ -187,10 +187,10 @@ static void Transform_SSE2(const int16_t* in, uint8_t* dst, int do_two) {
       _mm_storel_epi64((__m128i*)(dst + 3 * BPS), dst3);
     } else {
       // Store four bytes/pixels per line.
-      WebPUint32ToMem(dst + 0 * BPS, _mm_cvtsi128_si32(dst0));
-      WebPUint32ToMem(dst + 1 * BPS, _mm_cvtsi128_si32(dst1));
-      WebPUint32ToMem(dst + 2 * BPS, _mm_cvtsi128_si32(dst2));
-      WebPUint32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32(dst3));
+      WebPInt32ToMem(dst + 0 * BPS, _mm_cvtsi128_si32(dst0));
+      WebPInt32ToMem(dst + 1 * BPS, _mm_cvtsi128_si32(dst1));
+      WebPInt32ToMem(dst + 2 * BPS, _mm_cvtsi128_si32(dst2));
+      WebPInt32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32(dst3));
     }
   }
 }
@@ -213,10 +213,10 @@ static void TransformAC3(const int16_t* in, uint8_t* dst) {
   const __m128i m3 = _mm_subs_epi16(B, d4);
   const __m128i zero = _mm_setzero_si128();
   // Load the source pixels.
-  __m128i dst0 = _mm_cvtsi32_si128(WebPMemToUint32(dst + 0 * BPS));
-  __m128i dst1 = _mm_cvtsi32_si128(WebPMemToUint32(dst + 1 * BPS));
-  __m128i dst2 = _mm_cvtsi32_si128(WebPMemToUint32(dst + 2 * BPS));
-  __m128i dst3 = _mm_cvtsi32_si128(WebPMemToUint32(dst + 3 * BPS));
+  __m128i dst0 = _mm_cvtsi32_si128(WebPMemToInt32(dst + 0 * BPS));
+  __m128i dst1 = _mm_cvtsi32_si128(WebPMemToInt32(dst + 1 * BPS));
+  __m128i dst2 = _mm_cvtsi32_si128(WebPMemToInt32(dst + 2 * BPS));
+  __m128i dst3 = _mm_cvtsi32_si128(WebPMemToInt32(dst + 3 * BPS));
   // Convert to 16b.
   dst0 = _mm_unpacklo_epi8(dst0, zero);
   dst1 = _mm_unpacklo_epi8(dst1, zero);
@@ -233,10 +233,10 @@ static void TransformAC3(const int16_t* in, uint8_t* dst) {
   dst2 = _mm_packus_epi16(dst2, dst2);
   dst3 = _mm_packus_epi16(dst3, dst3);
   // Store the results.
-  WebPUint32ToMem(dst + 0 * BPS, _mm_cvtsi128_si32(dst0));
-  WebPUint32ToMem(dst + 1 * BPS, _mm_cvtsi128_si32(dst1));
-  WebPUint32ToMem(dst + 2 * BPS, _mm_cvtsi128_si32(dst2));
-  WebPUint32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32(dst3));
+  WebPInt32ToMem(dst + 0 * BPS, _mm_cvtsi128_si32(dst0));
+  WebPInt32ToMem(dst + 1 * BPS, _mm_cvtsi128_si32(dst1));
+  WebPInt32ToMem(dst + 2 * BPS, _mm_cvtsi128_si32(dst2));
+  WebPInt32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32(dst3));
 }
 #undef MUL
 #endif   // USE_TRANSFORM_AC3
@@ -477,11 +477,11 @@ static WEBP_INLINE void Load8x4_SSE2(const uint8_t* const b, int stride,
   // A0 = 63 62 61 60 23 22 21 20 43 42 41 40 03 02 01 00
   // A1 = 73 72 71 70 33 32 31 30 53 52 51 50 13 12 11 10
   const __m128i A0 = _mm_set_epi32(
-      WebPMemToUint32(&b[6 * stride]), WebPMemToUint32(&b[2 * stride]),
-      WebPMemToUint32(&b[4 * stride]), WebPMemToUint32(&b[0 * stride]));
+      WebPMemToInt32(&b[6 * stride]), WebPMemToInt32(&b[2 * stride]),
+      WebPMemToInt32(&b[4 * stride]), WebPMemToInt32(&b[0 * stride]));
   const __m128i A1 = _mm_set_epi32(
-      WebPMemToUint32(&b[7 * stride]), WebPMemToUint32(&b[3 * stride]),
-      WebPMemToUint32(&b[5 * stride]), WebPMemToUint32(&b[1 * stride]));
+      WebPMemToInt32(&b[7 * stride]), WebPMemToInt32(&b[3 * stride]),
+      WebPMemToInt32(&b[5 * stride]), WebPMemToInt32(&b[1 * stride]));
 
   // B0 = 53 43 52 42 51 41 50 40 13 03 12 02 11 01 10 00
   // B1 = 73 63 72 62 71 61 70 60 33 23 32 22 31 21 30 20
@@ -540,7 +540,7 @@ static WEBP_INLINE void Store4x4_SSE2(__m128i* const x,
                                       uint8_t* dst, int stride) {
   int i;
   for (i = 0; i < 4; ++i, dst += stride) {
-    WebPUint32ToMem(dst, _mm_cvtsi128_si32(*x));
+    WebPInt32ToMem(dst, _mm_cvtsi128_si32(*x));
     *x = _mm_srli_si128(*x, 4);
   }
 }
@@ -908,10 +908,10 @@ static void VE4_SSE2(uint8_t* dst) {    // vertical
   const __m128i lsb = _mm_and_si128(_mm_xor_si128(ABCDEFGH, CDEFGH00), one);
   const __m128i b = _mm_subs_epu8(a, lsb);
   const __m128i avg = _mm_avg_epu8(b, BCDEFGH0);
-  const uint32_t vals = _mm_cvtsi128_si32(avg);
+  const int vals = _mm_cvtsi128_si32(avg);
   int i;
   for (i = 0; i < 4; ++i) {
-    WebPUint32ToMem(dst + i * BPS, vals);
+    WebPInt32ToMem(dst + i * BPS, vals);
   }
 }
 
@@ -925,10 +925,10 @@ static void LD4_SSE2(uint8_t* dst) {   // Down-Left
   const __m128i lsb = _mm_and_si128(_mm_xor_si128(ABCDEFGH, CDEFGHH0), one);
   const __m128i avg2 = _mm_subs_epu8(avg1, lsb);
   const __m128i abcdefg = _mm_avg_epu8(avg2, BCDEFGH0);
-  WebPUint32ToMem(dst + 0 * BPS, _mm_cvtsi128_si32(               abcdefg    ));
-  WebPUint32ToMem(dst + 1 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 1)));
-  WebPUint32ToMem(dst + 2 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 2)));
-  WebPUint32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 3)));
+  WebPInt32ToMem(dst + 0 * BPS, _mm_cvtsi128_si32(               abcdefg    ));
+  WebPInt32ToMem(dst + 1 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 1)));
+  WebPInt32ToMem(dst + 2 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 2)));
+  WebPInt32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 3)));
 }
 
 static void VR4_SSE2(uint8_t* dst) {   // Vertical-Right
@@ -946,10 +946,10 @@ static void VR4_SSE2(uint8_t* dst) {   // Vertical-Right
   const __m128i lsb = _mm_and_si128(_mm_xor_si128(IXABCD, ABCD0), one);
   const __m128i avg2 = _mm_subs_epu8(avg1, lsb);
   const __m128i efgh = _mm_avg_epu8(avg2, XABCD);
-  WebPUint32ToMem(dst + 0 * BPS, _mm_cvtsi128_si32(               abcd    ));
-  WebPUint32ToMem(dst + 1 * BPS, _mm_cvtsi128_si32(               efgh    ));
-  WebPUint32ToMem(dst + 2 * BPS, _mm_cvtsi128_si32(_mm_slli_si128(abcd, 1)));
-  WebPUint32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32(_mm_slli_si128(efgh, 1)));
+  WebPInt32ToMem(dst + 0 * BPS, _mm_cvtsi128_si32(               abcd    ));
+  WebPInt32ToMem(dst + 1 * BPS, _mm_cvtsi128_si32(               efgh    ));
+  WebPInt32ToMem(dst + 2 * BPS, _mm_cvtsi128_si32(_mm_slli_si128(abcd, 1)));
+  WebPInt32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32(_mm_slli_si128(efgh, 1)));
 
   // these two are hard to implement in SSE2, so we keep the C-version:
   DST(0, 2) = AVG3(J, I, X);
@@ -970,11 +970,12 @@ static void VL4_SSE2(uint8_t* dst) {   // Vertical-Left
   const __m128i abbc = _mm_or_si128(ab, bc);
   const __m128i lsb2 = _mm_and_si128(abbc, lsb1);
   const __m128i avg4 = _mm_subs_epu8(avg3, lsb2);
-  const uint32_t extra_out = _mm_cvtsi128_si32(_mm_srli_si128(avg4, 4));
-  WebPUint32ToMem(dst + 0 * BPS, _mm_cvtsi128_si32(               avg1    ));
-  WebPUint32ToMem(dst + 1 * BPS, _mm_cvtsi128_si32(               avg4    ));
-  WebPUint32ToMem(dst + 2 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(avg1, 1)));
-  WebPUint32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(avg4, 1)));
+  const uint32_t extra_out =
+      (uint32_t)_mm_cvtsi128_si32(_mm_srli_si128(avg4, 4));
+  WebPInt32ToMem(dst + 0 * BPS, _mm_cvtsi128_si32(               avg1    ));
+  WebPInt32ToMem(dst + 1 * BPS, _mm_cvtsi128_si32(               avg4    ));
+  WebPInt32ToMem(dst + 2 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(avg1, 1)));
+  WebPInt32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(avg4, 1)));
 
   // these two are hard to get and irregular
   DST(3, 2) = (extra_out >> 0) & 0xff;
@@ -990,7 +991,7 @@ static void RD4_SSE2(uint8_t* dst) {   // Down-right
   const uint32_t K = dst[-1 + 2 * BPS];
   const uint32_t L = dst[-1 + 3 * BPS];
   const __m128i LKJI_____ =
-      _mm_cvtsi32_si128(L | (K << 8) | (J << 16) | (I << 24));
+      _mm_cvtsi32_si128((int)(L | (K << 8) | (J << 16) | (I << 24)));
   const __m128i LKJIXABCD = _mm_or_si128(LKJI_____, ____XABCD);
   const __m128i KJIXABCD_ = _mm_srli_si128(LKJIXABCD, 1);
   const __m128i JIXABCD__ = _mm_srli_si128(LKJIXABCD, 2);
@@ -998,10 +999,10 @@ static void RD4_SSE2(uint8_t* dst) {   // Down-right
   const __m128i lsb = _mm_and_si128(_mm_xor_si128(JIXABCD__, LKJIXABCD), one);
   const __m128i avg2 = _mm_subs_epu8(avg1, lsb);
   const __m128i abcdefg = _mm_avg_epu8(avg2, KJIXABCD_);
-  WebPUint32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32(               abcdefg    ));
-  WebPUint32ToMem(dst + 2 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 1)));
-  WebPUint32ToMem(dst + 1 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 2)));
-  WebPUint32ToMem(dst + 0 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 3)));
+  WebPInt32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32(               abcdefg    ));
+  WebPInt32ToMem(dst + 2 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 1)));
+  WebPInt32ToMem(dst + 1 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 2)));
+  WebPInt32ToMem(dst + 0 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 3)));
 }
 
 #undef DST
@@ -1015,13 +1016,13 @@ static WEBP_INLINE void TrueMotion_SSE2(uint8_t* dst, int size) {
   const __m128i zero = _mm_setzero_si128();
   int y;
   if (size == 4) {
-    const __m128i top_values = _mm_cvtsi32_si128(WebPMemToUint32(top));
+    const __m128i top_values = _mm_cvtsi32_si128(WebPMemToInt32(top));
     const __m128i top_base = _mm_unpacklo_epi8(top_values, zero);
     for (y = 0; y < 4; ++y, dst += BPS) {
       const int val = dst[-1] - top[-1];
       const __m128i base = _mm_set1_epi16(val);
       const __m128i out = _mm_packus_epi16(_mm_add_epi16(base, top_base), zero);
-      WebPUint32ToMem(dst, _mm_cvtsi128_si32(out));
+      WebPInt32ToMem(dst, _mm_cvtsi128_si32(out));
     }
   } else if (size == 8) {
     const __m128i top_values = _mm_loadl_epi64((const __m128i*)top);
@@ -1062,7 +1063,7 @@ static void VE16_SSE2(uint8_t* dst) {
 static void HE16_SSE2(uint8_t* dst) {     // horizontal
   int j;
   for (j = 16; j > 0; --j) {
-    const __m128i values = _mm_set1_epi8(dst[-1]);
+    const __m128i values = _mm_set1_epi8((char)dst[-1]);
     _mm_storeu_si128((__m128i*)dst, values);
     dst += BPS;
   }
@@ -1070,7 +1071,7 @@ static void HE16_SSE2(uint8_t* dst) {     // horizontal
 
 static WEBP_INLINE void Put16_SSE2(uint8_t v, uint8_t* dst) {
   int j;
-  const __m128i values = _mm_set1_epi8(v);
+  const __m128i values = _mm_set1_epi8((char)v);
   for (j = 0; j < 16; ++j) {
     _mm_storeu_si128((__m128i*)(dst + j * BPS), values);
   }
@@ -1130,7 +1131,7 @@ static void VE8uv_SSE2(uint8_t* dst) {    // vertical
 // helper for chroma-DC predictions
 static WEBP_INLINE void Put8x8uv_SSE2(uint8_t v, uint8_t* dst) {
   int j;
-  const __m128i values = _mm_set1_epi8(v);
+  const __m128i values = _mm_set1_epi8((char)v);
   for (j = 0; j < 8; ++j) {
     _mm_storel_epi64((__m128i*)(dst + j * BPS), values);
   }

+ 1 - 1
webp.mod/libwebp/src/dsp/dec_sse41.c

@@ -23,7 +23,7 @@ static void HE16_SSE41(uint8_t* dst) {     // horizontal
   int j;
   const __m128i kShuffle3 = _mm_set1_epi8(3);
   for (j = 16; j > 0; --j) {
-    const __m128i in = _mm_cvtsi32_si128(WebPMemToUint32(dst - 4));
+    const __m128i in = _mm_cvtsi32_si128(WebPMemToInt32(dst - 4));
     const __m128i values = _mm_shuffle_epi8(in, kShuffle3);
     _mm_storeu_si128((__m128i*)dst, values);
     dst += BPS;

+ 1 - 228
webp.mod/libwebp/src/dsp/dsp.h

@@ -18,6 +18,7 @@
 #include "src/webp/config.h"
 #endif
 
+#include "src/dsp/cpu.h"
 #include "src/webp/types.h"
 
 #ifdef __cplusplus
@@ -43,225 +44,6 @@ extern "C" {
 #define WEBP_RESTRICT
 #endif
 
-//------------------------------------------------------------------------------
-// CPU detection
-
-#if defined(__GNUC__)
-# define LOCAL_GCC_VERSION ((__GNUC__ << 8) | __GNUC_MINOR__)
-# define LOCAL_GCC_PREREQ(maj, min) \
-    (LOCAL_GCC_VERSION >= (((maj) << 8) | (min)))
-#else
-# define LOCAL_GCC_VERSION 0
-# define LOCAL_GCC_PREREQ(maj, min) 0
-#endif
-
-#if defined(__clang__)
-# define LOCAL_CLANG_VERSION ((__clang_major__ << 8) | __clang_minor__)
-# define LOCAL_CLANG_PREREQ(maj, min) \
-    (LOCAL_CLANG_VERSION >= (((maj) << 8) | (min)))
-#else
-# define LOCAL_CLANG_VERSION 0
-# define LOCAL_CLANG_PREREQ(maj, min) 0
-#endif
-
-#ifndef __has_builtin
-# define __has_builtin(x) 0
-#endif
-
-#if !defined(HAVE_CONFIG_H)
-#if defined(_MSC_VER) && _MSC_VER > 1310 && \
-    (defined(_M_X64) || defined(_M_IX86))
-#define WEBP_MSC_SSE2  // Visual C++ SSE2 targets
-#endif
-
-#if defined(_MSC_VER) && _MSC_VER >= 1500 && \
-    (defined(_M_X64) || defined(_M_IX86))
-#define WEBP_MSC_SSE41  // Visual C++ SSE4.1 targets
-#endif
-#endif
-
-// WEBP_HAVE_* are used to indicate the presence of the instruction set in dsp
-// files without intrinsics, allowing the corresponding Init() to be called.
-// Files containing intrinsics will need to be built targeting the instruction
-// set so should succeed on one of the earlier tests.
-#if (defined(__SSE2__) || defined(WEBP_MSC_SSE2)) && \
-    (!defined(HAVE_CONFIG_H) || defined(WEBP_HAVE_SSE2))
-#define WEBP_USE_SSE2
-#endif
-
-#if defined(WEBP_USE_SSE2) && !defined(WEBP_HAVE_SSE2)
-#define WEBP_HAVE_SSE2
-#endif
-
-#if (defined(__SSE4_1__) || defined(WEBP_MSC_SSE41)) && \
-    (!defined(HAVE_CONFIG_H) || defined(WEBP_HAVE_SSE41))
-#define WEBP_USE_SSE41
-#endif
-
-#if defined(WEBP_USE_SSE41) && !defined(WEBP_HAVE_SSE41)
-#define WEBP_HAVE_SSE41
-#endif
-
-#undef WEBP_MSC_SSE41
-#undef WEBP_MSC_SSE2
-
-// The intrinsics currently cause compiler errors with arm-nacl-gcc and the
-// inline assembly would need to be modified for use with Native Client.
-#if ((defined(__ARM_NEON__) || defined(__aarch64__)) && \
-     (!defined(HAVE_CONFIG_H) || defined(WEBP_HAVE_NEON))) && \
-    !defined(__native_client__)
-#define WEBP_USE_NEON
-#endif
-
-#if !defined(WEBP_USE_NEON) && defined(__ANDROID__) && \
-    defined(__ARM_ARCH_7A__) && defined(HAVE_CPU_FEATURES_H)
-#define WEBP_ANDROID_NEON  // Android targets that may have NEON
-#define WEBP_USE_NEON
-#endif
-
-// Note: ARM64 is supported in Visual Studio 2017, but requires the direct
-// inclusion of arm64_neon.h; Visual Studio 2019 includes this file in
-// arm_neon.h.
-#if defined(_MSC_VER) && \
-  ((_MSC_VER >= 1700 && defined(_M_ARM)) || \
-   (_MSC_VER >= 1920 && defined(_M_ARM64)))
-#define WEBP_USE_NEON
-#define WEBP_USE_INTRINSICS
-#endif
-
-#if defined(WEBP_USE_NEON) && !defined(WEBP_HAVE_NEON)
-#define WEBP_HAVE_NEON
-#endif
-
-#if defined(__mips__) && !defined(__mips64) && \
-    defined(__mips_isa_rev) && (__mips_isa_rev >= 1) && (__mips_isa_rev < 6)
-#define WEBP_USE_MIPS32
-#if (__mips_isa_rev >= 2)
-#define WEBP_USE_MIPS32_R2
-#if defined(__mips_dspr2) || (defined(__mips_dsp_rev) && __mips_dsp_rev >= 2)
-#define WEBP_USE_MIPS_DSP_R2
-#endif
-#endif
-#endif
-
-#if defined(__mips_msa) && defined(__mips_isa_rev) && (__mips_isa_rev >= 5)
-#define WEBP_USE_MSA
-#endif
-
-#ifndef WEBP_DSP_OMIT_C_CODE
-#define WEBP_DSP_OMIT_C_CODE 1
-#endif
-
-#if defined(WEBP_USE_NEON) && WEBP_DSP_OMIT_C_CODE
-#define WEBP_NEON_OMIT_C_CODE 1
-#else
-#define WEBP_NEON_OMIT_C_CODE 0
-#endif
-
-#if !(LOCAL_CLANG_PREREQ(3,8) || LOCAL_GCC_PREREQ(4,8) || defined(__aarch64__))
-#define WEBP_NEON_WORK_AROUND_GCC 1
-#else
-#define WEBP_NEON_WORK_AROUND_GCC 0
-#endif
-
-// This macro prevents thread_sanitizer from reporting known concurrent writes.
-#define WEBP_TSAN_IGNORE_FUNCTION
-#if defined(__has_feature)
-#if __has_feature(thread_sanitizer)
-#undef WEBP_TSAN_IGNORE_FUNCTION
-#define WEBP_TSAN_IGNORE_FUNCTION __attribute__((no_sanitize_thread))
-#endif
-#endif
-
-#if defined(WEBP_USE_THREAD) && !defined(_WIN32)
-#include <pthread.h>  // NOLINT
-
-#define WEBP_DSP_INIT(func) do {                                    \
-  static volatile VP8CPUInfo func ## _last_cpuinfo_used =           \
-      (VP8CPUInfo)&func ## _last_cpuinfo_used;                      \
-  static pthread_mutex_t func ## _lock = PTHREAD_MUTEX_INITIALIZER; \
-  if (pthread_mutex_lock(&func ## _lock)) break;                    \
-  if (func ## _last_cpuinfo_used != VP8GetCPUInfo) func();          \
-  func ## _last_cpuinfo_used = VP8GetCPUInfo;                       \
-  (void)pthread_mutex_unlock(&func ## _lock);                       \
-} while (0)
-#else  // !(defined(WEBP_USE_THREAD) && !defined(_WIN32))
-#define WEBP_DSP_INIT(func) do {                                    \
-  static volatile VP8CPUInfo func ## _last_cpuinfo_used =           \
-      (VP8CPUInfo)&func ## _last_cpuinfo_used;                      \
-  if (func ## _last_cpuinfo_used == VP8GetCPUInfo) break;           \
-  func();                                                           \
-  func ## _last_cpuinfo_used = VP8GetCPUInfo;                       \
-} while (0)
-#endif  // defined(WEBP_USE_THREAD) && !defined(_WIN32)
-
-// Defines an Init + helper function that control multiple initialization of
-// function pointers / tables.
-/* Usage:
-   WEBP_DSP_INIT_FUNC(InitFunc) {
-     ...function body
-   }
-*/
-#define WEBP_DSP_INIT_FUNC(name)                             \
-  static WEBP_TSAN_IGNORE_FUNCTION void name ## _body(void); \
-  WEBP_TSAN_IGNORE_FUNCTION void name(void) {                \
-    WEBP_DSP_INIT(name ## _body);                            \
-  }                                                          \
-  static WEBP_TSAN_IGNORE_FUNCTION void name ## _body(void)
-
-#define WEBP_UBSAN_IGNORE_UNDEF
-#define WEBP_UBSAN_IGNORE_UNSIGNED_OVERFLOW
-#if defined(__clang__) && defined(__has_attribute)
-#if __has_attribute(no_sanitize)
-// This macro prevents the undefined behavior sanitizer from reporting
-// failures. This is only meant to silence unaligned loads on platforms that
-// are known to support them.
-#undef WEBP_UBSAN_IGNORE_UNDEF
-#define WEBP_UBSAN_IGNORE_UNDEF \
-  __attribute__((no_sanitize("undefined")))
-
-// This macro prevents the undefined behavior sanitizer from reporting
-// failures related to unsigned integer overflows. This is only meant to
-// silence cases where this well defined behavior is expected.
-#undef WEBP_UBSAN_IGNORE_UNSIGNED_OVERFLOW
-#define WEBP_UBSAN_IGNORE_UNSIGNED_OVERFLOW \
-  __attribute__((no_sanitize("unsigned-integer-overflow")))
-#endif
-#endif
-
-// If 'ptr' is NULL, returns NULL. Otherwise returns 'ptr + off'.
-// Prevents undefined behavior sanitizer nullptr-with-nonzero-offset warning.
-#if !defined(WEBP_OFFSET_PTR)
-#define WEBP_OFFSET_PTR(ptr, off) (((ptr) == NULL) ? NULL : ((ptr) + (off)))
-#endif
-
-// Regularize the definition of WEBP_SWAP_16BIT_CSP (backward compatibility)
-#if !defined(WEBP_SWAP_16BIT_CSP)
-#define WEBP_SWAP_16BIT_CSP 0
-#endif
-
-// some endian fix (e.g.: mips-gcc doesn't define __BIG_ENDIAN__)
-#if !defined(WORDS_BIGENDIAN) && \
-    (defined(__BIG_ENDIAN__) || defined(_M_PPC) || \
-     (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)))
-#define WORDS_BIGENDIAN
-#endif
-
-typedef enum {
-  kSSE2,
-  kSSE3,
-  kSlowSSSE3,  // special feature for slow SSSE3 architectures
-  kSSE4_1,
-  kAVX,
-  kAVX2,
-  kNEON,
-  kMIPS32,
-  kMIPSdspR2,
-  kMSA
-} CPUFeature;
-// returns true if the CPU supports the feature.
-typedef int (*VP8CPUInfo)(CPUFeature feature);
-WEBP_EXTERN VP8CPUInfo VP8GetCPUInfo;
 
 //------------------------------------------------------------------------------
 // Init stub generator
@@ -550,15 +332,6 @@ extern void WebPConvertARGBToUV_C(const uint32_t* argb, uint8_t* u, uint8_t* v,
 extern void WebPConvertRGBA32ToUV_C(const uint16_t* rgb,
                                     uint8_t* u, uint8_t* v, int width);
 
-// utilities for accurate RGB->YUV conversion
-extern uint64_t (*WebPSharpYUVUpdateY)(const uint16_t* src, const uint16_t* ref,
-                                       uint16_t* dst, int len);
-extern void (*WebPSharpYUVUpdateRGB)(const int16_t* src, const int16_t* ref,
-                                     int16_t* dst, int len);
-extern void (*WebPSharpYUVFilterRow)(const int16_t* A, const int16_t* B,
-                                     int len,
-                                     const uint16_t* best_y, uint16_t* out);
-
 // Must be called before using the above.
 void WebPInitConvertARGBToYUV(void);
 

+ 1 - 0
webp.mod/libwebp/src/dsp/enc.c

@@ -732,6 +732,7 @@ VP8QuantizeBlockWHT VP8EncQuantizeBlockWHT;
 VP8BlockCopy VP8Copy4x4;
 VP8BlockCopy VP8Copy16x8;
 
+extern VP8CPUInfo VP8GetCPUInfo;
 extern void VP8EncDspInitSSE2(void);
 extern void VP8EncDspInitSSE41(void);
 extern void VP8EncDspInitNEON(void);

+ 8 - 3
webp.mod/libwebp/src/dsp/enc_neon.c

@@ -764,9 +764,14 @@ static WEBP_INLINE void AccumulateSSE16_NEON(const uint8_t* const a,
 
 // Horizontal sum of all four uint32_t values in 'sum'.
 static int SumToInt_NEON(uint32x4_t sum) {
+#if WEBP_AARCH64
+  return (int)vaddvq_u32(sum);
+#else
   const uint64x2_t sum2 = vpaddlq_u32(sum);
-  const uint64_t sum3 = vgetq_lane_u64(sum2, 0) + vgetq_lane_u64(sum2, 1);
-  return (int)sum3;
+  const uint32x2_t sum3 = vadd_u32(vreinterpret_u32_u64(vget_low_u64(sum2)),
+                                   vreinterpret_u32_u64(vget_high_u64(sum2)));
+  return (int)vget_lane_u32(sum3, 0);
+#endif
 }
 
 static int SSE16x16_NEON(const uint8_t* a, const uint8_t* b) {
@@ -860,7 +865,7 @@ static int QuantizeBlock_NEON(int16_t in[16], int16_t out[16],
   uint8x8x4_t shuffles;
   // vtbl?_u8 are marked unavailable for iOS arm64 with Xcode < 6.3, use
   // non-standard versions there.
-#if defined(__APPLE__) && defined(__aarch64__) && \
+#if defined(__APPLE__) && WEBP_AARCH64 && \
     defined(__apple_build_version__) && (__apple_build_version__< 6020037)
   uint8x16x2_t all_out;
   INIT_VECTOR2(all_out, vreinterpretq_u8_s16(out0), vreinterpretq_u8_s16(out1));

Some files were not shown because too many files changed in this diff