Compare commits

..

6 Commits
1.3.2 ... 1.3.0

Author SHA1 Message Date
904941b437 Fix OOB write in BuildHuffmanTable.
First, BuildHuffmanTable is called to check if the data is valid.
If it is and the table is not big enough, more memory is allocated.

This will make sure that valid (but unoptimized because of unbalanced
codes) streams are still decodable.

Bug: chromium:1479274
Change-Id: I31c36dbf3aa78d35ecf38706b50464fd3d375741
(cherry picked from commit 902bc91903)
(cherry picked from commit 2af26267cd)
2023-09-08 19:23:20 -07:00
1669e0dbac EncodeAlphaInternal: add missing error check
VP8LBitWriterFinish() may cause the VP8LBitWriter's buffer to be grown.
If that allocation fails, VP8LBitWriterNumBytes() will return a size
larger than the current allocation resulting in a heap overwrite of the
missing bytes.

==13==ERROR: AddressSanitizer: heap-buffer-overflow on address
0x61900005b880 at pc 0x00000049ffc1 bp 0x7fff144f5b40 sp 0x7fff144f5310
READ of size 1028 at 0x61900005b880 thread T0
    #0 0x49ffc0 in __asan_memcpy
    #1 0x695861 in VP8BitWriterAppend src/utils/bit_writer_utils.c:186:3
    #2 0x65acf9 in EncodeAlphaInternal src/enc/alpha_enc.c:169:14

Found by Nallocfuzz (https://github.com/catenacyber/nallocfuzz).

This is the same issue that was fixed in the non-alpha lossless path in:
d49cfbb3 vp8l_enc,WriteImage: add missing error check

Bug: chromium:1455619
Change-Id: I6bd10de213707d3d6b7ce3d0d2b3942af45d317f
(cherry picked from commit c3bd7cff2e)
2023-06-22 01:38:01 +00:00
6a319d4da3 vp8l_enc,WriteImage: add missing error check
VP8LBitWriterFinish() may cause the VP8LBitWriter's buffer to be grown.
If that allocation fails, VP8LBitWriterNumBytes() will return a size
larger than the current allocation resulting in a heap overwrite of the
missing bytes.

==3531848==ERROR: AddressSanitizer: heap-buffer-overflow on address
0x61d000000880 at pc 0x556eddfa1007 bp 0x7ffe434c7a90 sp 0x7ffe434c7260
READ of size 2052 at 0x61d000000880 thread T0
    #0 0x556eddfa1006 in __asan_memcpy
    #1 0x556eddfeeccf in WebPMemoryWrite src/enc/picture_enc.c:220:5
    #2 0x556ede0f9f87 in WriteImage src/enc/vp8l_enc.c:1454:8

Found by Nallocfuzz (https://github.com/catenacyber/nallocfuzz).

Change-Id: Ib1c9454c2c51849b0ba58c5347e6bd5b02a12fbe
(cherry picked from commit d49cfbb348)
2023-06-17 04:49:53 +00:00
fd7b5d4846 Merge "PaletteSortModifiedZeng: fix leak on error" into 1.3.0 2023-03-01 01:02:38 +00:00
4654e1e738 EncodeAlphaInternal: clear result->bw on error
This avoids a double free should the function fail prior to
VP8BitWriterInit() and a previous trial result's buffer carried over.
Previously in ApplyFiltersAndEncode() trial.bw (with a previous
iteration's buffer) would be freed, followed by best.bw pointing to the
same buffer.

Since:
187d379d add a fallback to ALPHA_NO_COMPRESSION

In addition, check the return value of VP8BitWriterInit() in this
function.

Bug: webp:603
Change-Id: Ic258381ee26c8c16bc211d157c8153831c8c6910
(cherry picked from commit a486d800b6)
2023-02-28 00:25:46 +00:00
d23169349f PaletteSortModifiedZeng: fix leak on error
Change-Id: I462bd9a3bc4670efdf251c295f6771a38c08a6ce
(cherry picked from commit 0edbb6ea71)
2023-02-28 00:24:49 +00:00
84 changed files with 389 additions and 1045 deletions

View File

@ -1,240 +0,0 @@
# ----------------------------------
# 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 = {}

View File

@ -16,4 +16,3 @@ James Zern <jzern@google.com>
Roberto Alanis <alanisbaez@google.com>
Brian Ledger <brianpl@google.com>
Maryla Ustarroz-Calonge <maryla@google.com>
Yannis Guyon <yguyon@google.com>

View File

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

View File

@ -32,7 +32,6 @@ Contributors:
- 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)
@ -48,7 +47,6 @@ 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)

View File

@ -82,8 +82,7 @@ if(WEBP_BUILD_WEBP_JS)
set(WEBP_USE_THREAD OFF)
if(WEBP_ENABLE_SIMD)
message(NOTICE
"wasm2js does not support SIMD, disabling webp.js generation.")
message("wasm2js does not support SIMD, disabling webp.js generation.")
endif()
endif()
@ -99,20 +98,10 @@ if(NOT CMAKE_BUILD_TYPE)
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)
if(BUILD_SHARED_LIBS AND NOT 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}")
@ -557,8 +546,7 @@ if(WEBP_BUILD_IMG2WEBP)
add_executable(img2webp ${IMG2WEBP_SRCS})
target_link_libraries(img2webp exampleutil imagedec imageioutil webp
libwebpmux)
target_include_directories(img2webp PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/src
${CMAKE_CURRENT_SOURCE_DIR})
target_include_directories(img2webp PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/src)
install(TARGETS img2webp RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
endif()
@ -651,16 +639,6 @@ if(WEBP_BUILD_EXTRAS)
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
@ -670,7 +648,7 @@ if(WEBP_BUILD_WEBP_JS)
set(WEBP_HAVE_SDL 1)
set_target_properties(
webp_js
PROPERTIES LINK_FLAGS "-sWASM=0 ${emscripten_stack_size} \
PROPERTIES LINK_FLAGS "-sWASM=0 \
-sEXPORTED_FUNCTIONS=_WebPToSDL -sINVOKE_RUN=0 \
-sEXPORTED_RUNTIME_METHODS=cwrap")
set_target_properties(webp_js PROPERTIES OUTPUT_NAME webp)
@ -683,7 +661,7 @@ if(WEBP_BUILD_WEBP_JS)
target_include_directories(webp_wasm PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
set_target_properties(
webp_wasm
PROPERTIES LINK_FLAGS "-sWASM=1 ${emscripten_stack_size} \
PROPERTIES LINK_FLAGS "-sWASM=1 \
-sEXPORTED_FUNCTIONS=_WebPToSDL -sINVOKE_RUN=0 \
-sEXPORTED_RUNTIME_METHODS=cwrap")
target_compile_definitions(webp_wasm PUBLIC EMSCRIPTEN WEBP_HAVE_SDL)
@ -764,8 +742,7 @@ endif()
configure_package_config_file(
${CMAKE_CURRENT_SOURCE_DIR}/cmake/WebPConfig.cmake.in
${CMAKE_CURRENT_BINARY_DIR}/WebPConfig.cmake
INSTALL_DESTINATION ${ConfigPackageLocation}
PATH_VARS CMAKE_INSTALL_INCLUDEDIR)
INSTALL_DESTINATION ${ConfigPackageLocation})
# Install the generated CMake files.
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/WebPConfigVersion.cmake"

View File

@ -19,59 +19,10 @@ 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.
## 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
https://chromium-review.googlesource.com for this purpose. 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

View File

@ -1,82 +1,3 @@
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
@ -182,7 +103,7 @@ 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)
0d1f1254 update ChangeLog (tag: v1.2.4, origin/1.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

View File

@ -400,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) $(LIBSHARPYUV)
$(DIRBIN)\img2webp.exe: $(LIBWEBPDEMUX) $(LIBWEBP)
$(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)

19
NEWS
View File

@ -1,22 +1,3 @@
- 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

View File

@ -7,7 +7,7 @@
\__\__/\____/\_____/__/ ____ ___
/ _/ / \ \ / _ \/ _/
/ \_/ / / \ \ __/ \__
\____/____/\_____/_____/____/v1.3.2
\____/____/\_____/_____/____/v1.3.0
```
WebP codec is a library to encode and decode images in WebP format. This package

View File

@ -8,11 +8,9 @@ if(@WEBP_USE_THREAD@)
find_dependency(Threads REQUIRED)
endif()
include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Targets.cmake")
include ("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Targets.cmake")
set_and_check(WebP_INCLUDE_DIR "@PACKAGE_CMAKE_INSTALL_INCLUDEDIR@")
set(WebP_INCLUDE_DIRS "@CMAKE_INSTALL_FULL_INCLUDEDIR@")
set(WEBP_INCLUDE_DIRS ${WebP_INCLUDE_DIRS})
set(WebP_LIBRARIES "@INSTALLED_LIBRARIES@")
set(WEBP_LIBRARIES "${WebP_LIBRARIES}")
check_required_components(WebP)

View File

@ -16,18 +16,48 @@
/* 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
@ -63,6 +93,9 @@
/* 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@"

View File

@ -43,6 +43,16 @@ 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 Threads::Threads)
endif()
set(WEBP_USE_THREAD ${Threads_FOUND})
@ -74,64 +84,72 @@ endif()
# Find the standard image libraries.
set(WEBP_DEP_IMG_LIBRARIES)
set(WEBP_DEP_IMG_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)
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("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()
# 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)
endif()
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()
# 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)

View File

@ -1,4 +1,4 @@
AC_INIT([libwebp], [1.3.2],
AC_INIT([libwebp], [1.3.0],
[https://bugs.chromium.org/p/webp],,
[https://developers.google.com/speed/webp])
AC_CANONICAL_HOST

View File

@ -82,8 +82,8 @@ Options:
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
-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
@ -295,23 +295,19 @@ etc.
Usage:
```shell
img2webp [file_options] [[frame_options] frame_file]... [-o webp_file]
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
-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

View 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. 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.
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.
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:
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:
* **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.
* **Transparency.** An image may have transparency, that is, an alpha channel.
* **Transparency.** An image may have transparency, i.e., an alpha channel.
* **Color Profile.** An image may have an embedded ICC profile as described
by the [International Color Consortium][iccspec].
@ -57,10 +57,10 @@ Bit numbering in chunk diagrams starts at `0` for the most significant bit
Terminology & Basics
--------------------
A WebP file contains either a still image (that is, an encoded matrix of pixels)
A WebP file contains either a still image (i.e., an encoded matrix of pixels)
or an [animation](#animation). Optionally, it can also contain transparency
information, color profile and metadata. We refer to the matrix of pixels as the
_canvas_ of the image.
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.
Below are additional terms used throughout this document:
@ -89,8 +89,8 @@ _FourCC_
_1-based_
: An unsigned integer field storing values offset by `-1`, for example, such a
field would store value _25_ as _24_.
: An unsigned integer field storing values offset by `-1`. e.g., Such a field
would store value _25_ as _24_.
_ChunkHeader('ABCD')_
@ -168,7 +168,7 @@ in the header is the total size of the chunks that follow plus `4` bytes for
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
also even. The contents of individual chunks will be described in the following
sections.
@ -553,7 +553,7 @@ Pre-processing (P): 2 bits
: These _informative_ bits are used to signal the pre-processing that has
been performed during compression. The decoder can use this information to
for example, dither the values or smooth the gradients prior to display.
e.g. dither the values or smooth the gradients prior to display.
* `0`: No pre-processing.
* `1`: Level reduction.

View File

@ -12,7 +12,13 @@ at the end of this file.
Specification for WebP Lossless Bitstream
=========================================
_Jyrki Alakuijala, Ph.D., Google, Inc., 2023-03-09_
_Jyrki Alakuijala, Ph.D., Google, Inc., 2012-06-19_
Paragraphs marked as \[AMENDED\] were amended on 2014-09-16.
Paragraphs marked as \[AMENDED2\] were amended on 2022-05-13.
Paragraphs marked as \[AMENDED3\] were amended on 2022-11-21.
Abstract
--------
@ -59,7 +65,7 @@ b = ReadBits(1);
b |= ReadBits(1) << 1;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
We assume that each color component, that is, alpha, red, blue and green, is
We assume that each color component (e.g. alpha, red, blue and green) is
represented using an 8-bit byte. We define the corresponding type as uint8. A
whole ARGB pixel is represented by a type called uint32, an unsigned integer
consisting of 32 bits. In the code showing the behavior of the transformations,
@ -101,7 +107,7 @@ distance mapping
entropy image
: A two-dimensional subresolution image indicating which entropy coding should
be used in a respective square in the image, that is, each pixel is a meta
be used in a respective square in the image, i.e., each pixel is a meta
prefix code.
prefix code
@ -156,8 +162,8 @@ int image_width = ReadBits(14) + 1;
int image_height = ReadBits(14) + 1;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The 14-bit precision for image width and height limits the maximum size of a
WebP lossless image to 16384✕16384 pixels.
The 14-bit dynamics for image size limit the maximum size of a WebP lossless
image to 16384✕16384 pixels.
The alpha_is_used bit is a hint only, and should not impact decoding. It should
be set to 0 when all alpha values are 255 in the picture, and 1 otherwise.
@ -167,7 +173,7 @@ int alpha_is_used = ReadBits(1);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The version_number is a 3 bit code that must be set to 0. Any other value should
be treated as an error.
be treated as an error. \[AMENDED\]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
int version_number = ReadBits(3);
@ -235,7 +241,7 @@ two-dimensionally.
int size_bits = ReadBits(3) + 2;
int block_width = (1 << size_bits);
int block_height = (1 << size_bits);
#define DIV_ROUND_UP(num, den) (((num) + (den) - 1) / (den))
#define DIV_ROUND_UP(num, den) ((num) + (den) - 1) / (den))
int block_xsize = DIV_ROUND_UP(image_width, 1 << size_bits);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -319,7 +325,7 @@ uint32 Select(uint32 L, uint32 T, uint32 TL) {
abs(pGreen - GREEN(T)) + abs(pBlue - BLUE(T));
// Return either left or top, the one closer to the prediction.
if (pL < pT) {
if (pL < pT) { // \[AMENDED\]
return L;
} else {
return T;
@ -355,7 +361,7 @@ predicted value for the left-topmost pixel of the image is 0xff000000, L-pixel
for all pixels on the top row, and T-pixel for all pixels on the leftmost
column.
Addressing the TR-pixel for pixels on the rightmost column is
\[AMENDED2\] Addressing the TR-pixel for pixels on the rightmost column is
exceptional. The pixels on the rightmost column are predicted by using the modes
\[0..13\] just like pixels not on the border, but the leftmost pixel on the same
row as the current pixel is instead used as the TR-pixel.
@ -363,6 +369,8 @@ row as the current pixel is instead used as the TR-pixel.
### 4.2 Color Transform
\[AMENDED2\]
The goal of the color transform is to decorrelate the R, G and B values of each
pixel. The color transform keeps the green (G) value as it is, transforms red
(R) based on green and transforms blue (B) based on green and then based on red.
@ -420,7 +428,7 @@ performed using 8-bit two's complement (that is: uint8 range \[128..255\] is
mapped to the \[-128..-1\] range of its converted int8 value).
The multiplication is to be done using more precision (with at least 16-bit
precision). The sign extension property of the shift operation does not matter
dynamics). The sign extension property of the shift operation does not matter
here: only the lowest 8 bits are used from the result, and there the sign
extension shifting and unsigned shifting are consistent with each other.
@ -443,7 +451,7 @@ described in [Chapter 5](#image-data).
During decoding, `ColorTransformElement` instances of the blocks are decoded and
the inverse color transform is applied on the ARGB values of the pixels. As
mentioned earlier, that inverse color transform is just adding
`ColorTransformElement` values to the red and blue channels.
`ColorTransformElement` values to the red and blue channels. \[AMENDED3\]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void InverseTransform(uint8 red, uint8 green, uint8 blue,
@ -481,8 +489,9 @@ void AddGreenToBlueAndRed(uint8 green, uint8 *red, uint8 *blue) {
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This transform is redundant as it can be modeled using the color transform, but
since there is no additional data here, the subtract green transform can be
coded using fewer bits than a full-blown color transform.
it is still often useful. Since it can extend the dynamics of the color
transform and there is no additional data here, the subtract green transform can
be coded using fewer bits than a full-blown color transform.
### 4.4 Color Indexing Transform
@ -527,7 +536,7 @@ argb = color_table[GREEN(argb)];
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
If the index is equal or larger than `color_table_size`, the argb color value
should be set to 0x00000000 (transparent black).
should be set to 0x00000000 (transparent black). \[AMENDED\]
When the color table is small (equal to or less than 16 colors), several pixels
are bundled into a single pixel. The pixel bundling packs several (2, 4, or 8)
@ -556,7 +565,7 @@ bundling is to be done for the image. A value of 1 indicates that two pixels are
combined, and each pixel has a range of \[0..15\]. A value of 2 indicates that
four pixels are combined, and each pixel has a range of \[0..3\]. A value of 3
indicates that eight pixels are combined and each pixel has a range of \[0..1\],
that is, a binary value.
i.e., a binary value.
The values are packed into the green component as follows:
@ -631,8 +640,7 @@ The following subsections describe each of these in detail.
#### 5.2.1 Prefix Coded Literals
The pixel is stored as prefix coded values of green, red, blue and alpha (in
that order). See [Section 6.2.3](#decoding-entropy-coded-image-data) for
details.
that order). See [this section](#decoding-entropy-coded-image-data) for details.
#### 5.2.2 LZ77 Backward Reference
@ -741,6 +749,8 @@ Similarly, the distance code `3` indicates the left-top pixel.
The decoder can convert a distance code `i` to a scan-line order distance `dist`
as follows:
\[AMENDED3\]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
(xi, yi) = distance_map[i - 1]
dist = xi + yi * xsize
@ -811,7 +821,7 @@ potentially better compression.
The encoded image data consists of several parts:
1. Decoding and building the prefix codes
1. Decoding and building the prefix codes \[AMENDED2\]
1. Meta prefix codes
1. Entropy-coded image data
@ -832,15 +842,11 @@ by a 1-bit value.
In both cases, there can be unused code lengths that are still part of the
stream. This may be inefficient, but it is allowed by the format.
The described tree must be a complete binary tree. A single leaf node is
considered a complete binary tree and can be encoded using either the simple
code length code or the normal code length code. When coding a single leaf
node using the _normal code length code_, all but one code length should be
zeros, and the single leaf node value is marked with the length of 1 -- even
when no bits are consumed when that single leaf node tree is used.
**(i) Simple Code Length Code:**
\[AMENDED2\]
This variant is used in the special case when only 1 or 2 prefix symbols are in
the range \[0..255\] with code length `1`. All other prefix code lengths are
implicitly zeros.
@ -884,7 +890,7 @@ First, `num_code_lengths` specifies the number of code lengths.
int num_code_lengths = 4 + ReadBits(4);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
If `num_code_lengths` is > 19, the bitstream is invalid.
If `num_code_lengths` is > 19, the bitstream is invalid. \[AMENDED3\]
The code lengths are themselves encoded using prefix codes: lower level code
lengths, `code_length_code_lengths`, first have to be read. The rest of those
@ -916,12 +922,12 @@ to `max_symbol` code lengths.
* Code \[0..15\] indicates literal code lengths.
* Value 0 means no symbols have been coded.
* Values \[1..15\] indicate the bit length of the respective code.
* Code 16 repeats the previous non-zero value \[3..6\] times, that is,
* Code 16 repeats the previous non-zero value \[3..6\] times, i.e.,
`3 + ReadBits(2)` times. If code 16 is used before a non-zero
value has been emitted, a value of 8 is repeated.
* Code 17 emits a streak of zeros \[3..10\], that is, `3 + ReadBits(3)`
* Code 17 emits a streak of zeros \[3..10\], i.e., `3 + ReadBits(3)`
times.
* Code 18 emits a streak of zeros of length \[11..138\], that is,
* Code 18 emits a streak of zeros of length \[11..138\], i.e.,
`11 + ReadBits(7)` times.
Once code lengths are read, a prefix code for each symbol type (A, R, G, B,
@ -931,11 +937,6 @@ distance) is formed using their respective alphabet sizes:
* other literals (A,R,B): 256
* distance code: 40
The Normal Code Length Code must code a full decision tree, that is, the sum of
`2 ^ (-length)` for all non-zero codes must be exactly one. There is however
one exception to this rule, the single leaf node tree, where the leaf node
value is marked with value 1 and other values are 0s.
#### 6.2.2 Decoding of Meta Prefix Codes
As noted earlier, the format allows the use of different prefix codes for
@ -1007,7 +1008,7 @@ codes to be used as follows:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
int position =
(y >> prefix_bits) * prefix_xsize + (x >> prefix_bits);
int meta_prefix_code = (entropy_image[position] >> 8) & 0xffff;
int meta_prefix_code = (entropy_image[pos] >> 8) & 0xffff;
PrefixCodeGroup prefix_group = prefix_code_groups[meta_prefix_code];
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -1018,7 +1019,9 @@ represents a set of five prefix codes. Also, `prefix_code_groups` is an array of
The decoder then uses prefix code group `prefix_group` to decode the pixel
(x, y) as explained in the [next section](#decoding-entropy-coded-image-data).
#### 6.2.3 Decoding Entropy-Coded Image Data
#### 6.2.3 Decoding Entropy-coded Image Data
\[AMENDED2\]
For the current position (x, y) in the image, the decoder first identifies the
corresponding prefix code group (as explained in the last section). Given the
@ -1062,13 +1065,10 @@ number of pixels (xsize * ysize).
#### 7.1 Basic Structure
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
format = RIFF-header image-header image-stream
RIFF-header = "RIFF" 4OCTET "WEBP" "VP8L" 4OCTET %x2F
image-header = image-size alpha-is-used version
image-size = 14BIT 14BIT ; width - 1, height - 1
alpha-is-used = 1BIT
version = 3BIT ; 0
image-stream = optional-transform spatially-coded-image
format = RIFF-header image-size image-stream
RIFF-header = "RIFF" 4OCTET "WEBP" "VP8L" 4OCTET %x2F
image-size = 14BIT 14BIT ; width - 1, height - 1
image-stream = optional-transform spatially-coded-image
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -1097,6 +1097,8 @@ color-indexing-image = 8BIT ; color count
#### 7.3 Structure of the Image Data
\[AMENDED2\]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
spatially-coded-image = color-cache-info meta-prefix data
entropy-coded-image = color-cache-info data
@ -1118,7 +1120,8 @@ prefix-code-group =
prefix-code = simple-prefix-code / normal-prefix-code
simple-prefix-code = ; see "Simple Code Length Code" for details
normal-prefix-code = ; see "Normal Code Length Code" for details
normal-prefix-code = code-length-code encoded-code-lengths
code-length-code = ; see section "Normal Code Length Code"
lz77-coded-image =
*((argb-pixel / lz77-copy / color-cache-code) lz77-coded-image)

View File

@ -92,7 +92,7 @@ webpmux_LDADD += ../src/mux/libwebpmux.la
webpmux_LDADD += ../src/libwebp.la
img2webp_SOURCES = img2webp.c
img2webp_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_srcdir)
img2webp_CPPFLAGS = $(AM_CPPFLAGS)
img2webp_LDADD =
img2webp_LDADD += libexample_util.la
img2webp_LDADD += ../imageio/libimageio_util.la

View File

@ -592,8 +592,9 @@ 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 preprocessing\n"
" (0..100=off), default=100\n");
printf(" -near_lossless <int> ... use near-lossless image\n"
" preprocessing (0..100=off), "
"default=100\n");
printf(" -hint <string> ......... specify image characteristics hint,\n");
printf(" one of: photo, picture or graph\n");

View File

@ -28,7 +28,6 @@
#include "../imageio/imageio_util.h"
#include "./stopwatch.h"
#include "./unicode.h"
#include "sharpyuv/sharpyuv.h"
#include "webp/encode.h"
#include "webp/mux.h"
@ -36,22 +35,17 @@
static void Help(void) {
printf("Usage:\n\n");
printf(" img2webp [file_options] [[frame_options] frame_file]...");
printf(" [-o webp_file]\n\n");
printf(" img2webp [file_options] [[frame_options] frame_file]...\n");
printf("\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");
@ -190,11 +184,6 @@ 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")) {
@ -203,13 +192,10 @@ int main(int argc, const char* argv[]) {
} 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;

View File

@ -19,7 +19,7 @@
#define XTRA_MAJ_VERSION 1
#define XTRA_MIN_VERSION 3
#define XTRA_REV_VERSION 2
#define XTRA_REV_VERSION 0
//------------------------------------------------------------------------------

View File

@ -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 num_channels;
int has_alpha;
int num_passes;
int p;
volatile int ok = 0;
@ -293,6 +293,9 @@ 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.
@ -307,16 +310,13 @@ 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);
num_channels = png_get_channels(png, info);
if (num_channels != 3 && num_channels != 4) {
goto Error;
}
stride = (int64_t)num_channels * width * sizeof(*rgb);
stride = (int64_t)(has_alpha ? 4 : 3) * 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 = (num_channels == 4) ? WebPPictureImportRGBA(pic, rgb, (int)stride)
: WebPPictureImportRGB(pic, rgb, (int)stride);
ok = has_alpha ? WebPPictureImportRGBA(pic, rgb, (int)stride)
: WebPPictureImportRGB(pic, rgb, (int)stride);
if (!ok) {
goto Error;

View File

@ -41,7 +41,6 @@ readonly TARGETDIR="${TOPDIR}/WebP.framework"
readonly DECTARGETDIR="${TOPDIR}/WebPDecoder.framework"
readonly MUXTARGETDIR="${TOPDIR}/WebPMux.framework"
readonly DEMUXTARGETDIR="${TOPDIR}/WebPDemux.framework"
readonly SHARPYUVTARGETDIR="${TOPDIR}/SharpYuv.framework"
readonly DEVELOPER=$(xcode-select --print-path)
readonly PLATFORMSROOT="${DEVELOPER}/Platforms"
readonly LIPO=$(xcrun -sdk iphoneos${SDK} -find lipo)
@ -64,8 +63,7 @@ echo "Xcode Version: ${XCODE}"
echo "iOS SDK Version: ${SDK}"
if [[ -e "${BUILDDIR}" || -e "${TARGETDIR}" || -e "${DECTARGETDIR}" \
|| -e "${MUXTARGETDIR}" || -e "${DEMUXTARGETDIR}" \
|| -e "${SHARPYUVTARGETDIR}" ]]; then
|| -e "${MUXTARGETDIR}" || -e "${DEMUXTARGETDIR}" ]]; then
cat << EOF
WARNING: The following directories will be deleted:
WARNING: ${BUILDDIR}
@ -73,16 +71,14 @@ WARNING: ${TARGETDIR}
WARNING: ${DECTARGETDIR}
WARNING: ${MUXTARGETDIR}
WARNING: ${DEMUXTARGETDIR}
WARNING: ${SHARPYUVTARGETDIR}
WARNING: The build will continue in 5 seconds...
EOF
sleep 5
fi
rm -rf ${BUILDDIR} ${TARGETDIR} ${DECTARGETDIR} \
${MUXTARGETDIR} ${DEMUXTARGETDIR} ${SHARPYUVTARGETDIR}
${MUXTARGETDIR} ${DEMUXTARGETDIR}
mkdir -p ${BUILDDIR} ${TARGETDIR}/Headers/ ${DECTARGETDIR}/Headers/ \
${MUXTARGETDIR}/Headers/ ${DEMUXTARGETDIR}/Headers/ \
${SHARPYUVTARGETDIR}/Headers/
${MUXTARGETDIR}/Headers/ ${DEMUXTARGETDIR}/Headers/
if [[ ! -e ${SRCDIR}/configure ]]; then
if ! (cd ${SRCDIR} && sh autogen.sh); then
@ -138,14 +134,13 @@ for PLATFORM in ${PLATFORMS}; do
set +x
# Build only the libraries, skip the examples.
make V=0 -C sharpyuv install
make V=0 -C sharpyuv
make V=0 -C src install
LIBLIST+=" ${ROOTDIR}/lib/libwebp.a"
DECLIBLIST+=" ${ROOTDIR}/lib/libwebpdecoder.a"
MUXLIBLIST+=" ${ROOTDIR}/lib/libwebpmux.a"
DEMUXLIBLIST+=" ${ROOTDIR}/lib/libwebpdemux.a"
SHARPYUVLIBLIST+=" ${ROOTDIR}/lib/libsharpyuv.a"
make clean
@ -170,9 +165,4 @@ cp -a ${SRCDIR}/src/webp/{decode,types,mux_types,demux}.h \
${DEMUXTARGETDIR}/Headers/
${LIPO} -create ${DEMUXLIBLIST} -output ${DEMUXTARGETDIR}/WebPDemux
echo "SHARPYUVLIBLIST = ${SHARPYUVLIBLIST}"
cp -a ${SRCDIR}/sharpyuv/{sharpyuv,sharpyuv_csp}.h \
${SHARPYUVTARGETDIR}/Headers/
${LIPO} -create ${SHARPYUVLIBLIST} -output ${SHARPYUVTARGETDIR}/SharpYuv
echo "SUCCESS"

View File

@ -1,10 +1,10 @@
.\" Hey, EMACS: -*- nroff -*-
.TH IMG2WEBP 1 "March 17, 2023"
.TH IMG2WEBP 1 "January 5, 2022"
.SH NAME
img2webp \- create animated WebP file from a sequence of input images.
.SH SYNOPSIS
.B img2webp
[file_options] [[frame_options] frame_file]... [\-o webp_file]
[file_options] [[frame_options] frame_file]...
.br
.B img2webp argument_file_name
.br
@ -44,18 +44,6 @@ 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'.

View File

@ -33,7 +33,7 @@ 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_LDFLAGS = -no-undefined -version-info 0:0:0 -lm
libsharpyuv_la_LIBADD =
libsharpyuv_la_LIBADD += libsharpyuv_sse2.la
libsharpyuv_la_LIBADD += libsharpyuv_neon.la

View File

@ -6,8 +6,8 @@
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
VS_VERSION_INFO VERSIONINFO
FILEVERSION 0,0,2,1
PRODUCTVERSION 0,0,2,1
FILEVERSION 0,0,2,0
PRODUCTVERSION 0,0,2,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@ -24,12 +24,12 @@ BEGIN
BEGIN
VALUE "CompanyName", "Google, Inc."
VALUE "FileDescription", "libsharpyuv DLL"
VALUE "FileVersion", "0.2.1"
VALUE "FileVersion", "0.2.0"
VALUE "InternalName", "libsharpyuv.dll"
VALUE "LegalCopyright", "Copyright (C) 2023"
VALUE "LegalCopyright", "Copyright (C) 2022"
VALUE "OriginalFilename", "libsharpyuv.dll"
VALUE "ProductName", "SharpYuv Library"
VALUE "ProductVersion", "0.2.1"
VALUE "ProductVersion", "0.2.0"
END
END
BLOCK "VarFileInfo"

View File

@ -440,7 +440,6 @@ static int DoSharpArgbToYuv(const uint8_t* r_ptr, const uint8_t* g_ptr,
// 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 =

View File

@ -37,7 +37,7 @@ extern "C" {
// SharpYUV API version following the convention from semver.org
#define SHARPYUV_VERSION_MAJOR 0
#define SHARPYUV_VERSION_MINOR 2
#define SHARPYUV_VERSION_PATCH 1
#define SHARPYUV_VERSION_PATCH 0
// 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) \

View File

@ -72,7 +72,6 @@ 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);

View File

@ -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:8:1
libwebp_la_LDFLAGS = -no-undefined -version-info 8:6: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:8:1
libwebpdecoder_la_LDFLAGS = -no-undefined -version-info 4:6:1
pkgconfig_DATA += libwebpdecoder.pc
endif

View File

@ -12,11 +12,10 @@
// Author: Skal (pascal.massimino@gmail.com)
#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) && !WEBP_AARCH64
#if !defined(__arm__) && !defined(_M_ARM) && !defined(__aarch64__)
// using a table is ~1-2% slower on ARM. Prefer the coded-tree approach then.
#define USE_GENERIC_TREE 1 // ALTERNATE_CODE
#else

View File

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

View File

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

View File

@ -658,26 +658,19 @@ 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) {
// 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);
{
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;
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) {

View File

@ -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:14:0
libwebpdemux_la_LDFLAGS = -no-undefined -version-info 2:12:0
libwebpdemuxincludedir = $(includedir)/webp
pkgconfig_DATA = libwebpdemux.pc

View File

@ -25,7 +25,7 @@
#define DMUX_MAJ_VERSION 1
#define DMUX_MIN_VERSION 3
#define DMUX_REV_VERSION 2
#define DMUX_REV_VERSION 0
typedef struct {
size_t start_; // start location of the data

View File

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

View File

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

View File

@ -425,7 +425,6 @@ 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);

View File

@ -374,7 +374,6 @@ 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);

View File

@ -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));
#if WEBP_AARCH64
#ifdef __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 // WEBP_AARCH64
#endif // __aarch64__
res->coeffs = coeffs;
}

View File

@ -173,7 +173,6 @@ 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) {
@ -185,7 +184,6 @@ 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.
@ -210,7 +208,6 @@ 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
@ -239,7 +236,6 @@ 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)
@ -251,9 +247,7 @@ static int mipsCPUInfo(CPUFeature feature) {
}
}
WEBP_EXTERN VP8CPUInfo VP8GetCPUInfo;
VP8CPUInfo VP8GetCPUInfo = mipsCPUInfo;
#else
WEBP_EXTERN VP8CPUInfo VP8GetCPUInfo;
VP8CPUInfo VP8GetCPUInfo = NULL;
#endif

View File

@ -43,9 +43,6 @@
#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))
@ -83,9 +80,6 @@
#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__)) && \
@ -104,26 +98,16 @@
// 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))))
#if defined(_MSC_VER) && ((_MSC_VER >= 1700 && defined(_M_ARM)) || \
(_MSC_VER >= 1926 && defined(_M_ARM64)))
#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
@ -139,8 +123,6 @@
#define WEBP_USE_MSA
#endif
//------------------------------------------------------------------------------
#ifndef WEBP_DSP_OMIT_C_CODE
#define WEBP_DSP_OMIT_C_CODE 1
#endif
@ -151,14 +133,13 @@
#define WEBP_NEON_OMIT_C_CODE 0
#endif
#if !(LOCAL_CLANG_PREREQ(3, 8) || LOCAL_GCC_PREREQ(4, 8) || WEBP_AARCH64)
#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)
@ -260,7 +241,16 @@ typedef enum {
kMSA
} CPUFeature;
#ifdef __cplusplus
extern "C" {
#endif
// returns true if the CPU supports the feature.
typedef int (*VP8CPUInfo)(CPUFeature feature);
WEBP_EXTERN VP8CPUInfo VP8GetCPUInfo;
#ifdef __cplusplus
} // extern "C"
#endif
#endif // WEBP_DSP_CPU_H_

View File

@ -734,7 +734,6 @@ 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);

View File

@ -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 WEBP_AARCH64
#if defined(__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 WEBP_AARCH64
#if defined(__aarch64__)
const uint16_t p3 = vaddlvq_u8(A);
sum_top = vdupq_n_u16(p3);
#else

View File

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

View File

@ -764,7 +764,7 @@ 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
#if defined(__aarch64__)
return (int)vaddvq_u32(sum);
#else
const uint64x2_t sum2 = vpaddlq_u32(sum);
@ -865,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__) && WEBP_AARCH64 && \
#if defined(__APPLE__) && defined(__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));

View File

@ -25,160 +25,9 @@
//------------------------------------------------------------------------------
// Transforms (Paragraph 14.4)
// Does one inverse transform.
static void ITransform_One_SSE2(const uint8_t* ref, const int16_t* in,
uint8_t* dst) {
// This implementation makes use of 16-bit fixed point versions of two
// multiply constants:
// K1 = sqrt(2) * cos (pi/8) ~= 85627 / 2^16
// K2 = sqrt(2) * sin (pi/8) ~= 35468 / 2^16
//
// To be able to use signed 16-bit integers, we use the following trick to
// have constants within range:
// - Associated constants are obtained by subtracting the 16-bit fixed point
// version of one:
// k = K - (1 << 16) => K = k + (1 << 16)
// K1 = 85267 => k1 = 20091
// K2 = 35468 => k2 = -30068
// - The multiplication of a variable by a constant become the sum of the
// variable and the multiplication of that variable by the associated
// constant:
// (x * K) >> 16 = (x * (k + (1 << 16))) >> 16 = ((x * k ) >> 16) + x
const __m128i k1k2 = _mm_set_epi16(-30068, -30068, -30068, -30068,
20091, 20091, 20091, 20091);
const __m128i k2k1 = _mm_set_epi16(20091, 20091, 20091, 20091,
-30068, -30068, -30068, -30068);
const __m128i zero = _mm_setzero_si128();
const __m128i zero_four = _mm_set_epi16(0, 0, 0, 0, 4, 4, 4, 4);
__m128i T01, T23;
// Load and concatenate the transform coefficients.
const __m128i in01 = _mm_loadu_si128((const __m128i*)&in[0]);
const __m128i in23 = _mm_loadu_si128((const __m128i*)&in[8]);
// a00 a10 a20 a30 a01 a11 a21 a31
// a02 a12 a22 a32 a03 a13 a23 a33
// Vertical pass and subsequent transpose.
{
const __m128i in1 = _mm_unpackhi_epi64(in01, in01);
const __m128i in3 = _mm_unpackhi_epi64(in23, in23);
// First pass, c and d calculations are longer because of the "trick"
// multiplications.
// c = MUL(in1, K2) - MUL(in3, K1) = MUL(in1, k2) - MUL(in3, k1) + in1 - in3
// d = MUL(in1, K1) + MUL(in3, K2) = MUL(in1, k1) + MUL(in3, k2) + in1 + in3
const __m128i a_d3 = _mm_add_epi16(in01, in23);
const __m128i b_c3 = _mm_sub_epi16(in01, in23);
const __m128i c1d1 = _mm_mulhi_epi16(in1, k2k1);
const __m128i c2d2 = _mm_mulhi_epi16(in3, k1k2);
const __m128i c3 = _mm_unpackhi_epi64(b_c3, b_c3);
const __m128i c4 = _mm_sub_epi16(c1d1, c2d2);
const __m128i c = _mm_add_epi16(c3, c4);
const __m128i d4u = _mm_add_epi16(c1d1, c2d2);
const __m128i du = _mm_add_epi16(a_d3, d4u);
const __m128i d = _mm_unpackhi_epi64(du, du);
// Second pass.
const __m128i comb_ab = _mm_unpacklo_epi64(a_d3, b_c3);
const __m128i comb_dc = _mm_unpacklo_epi64(d, c);
const __m128i tmp01 = _mm_add_epi16(comb_ab, comb_dc);
const __m128i tmp32 = _mm_sub_epi16(comb_ab, comb_dc);
const __m128i tmp23 = _mm_shuffle_epi32(tmp32, _MM_SHUFFLE(1, 0, 3, 2));
const __m128i transpose_0 = _mm_unpacklo_epi16(tmp01, tmp23);
const __m128i transpose_1 = _mm_unpackhi_epi16(tmp01, tmp23);
// a00 a20 a01 a21 a02 a22 a03 a23
// a10 a30 a11 a31 a12 a32 a13 a33
T01 = _mm_unpacklo_epi16(transpose_0, transpose_1);
T23 = _mm_unpackhi_epi16(transpose_0, transpose_1);
// a00 a10 a20 a30 a01 a11 a21 a31
// a02 a12 a22 a32 a03 a13 a23 a33
}
// Horizontal pass and subsequent transpose.
{
const __m128i T1 = _mm_unpackhi_epi64(T01, T01);
const __m128i T3 = _mm_unpackhi_epi64(T23, T23);
// First pass, c and d calculations are longer because of the "trick"
// multiplications.
const __m128i dc = _mm_add_epi16(T01, zero_four);
// c = MUL(T1, K2) - MUL(T3, K1) = MUL(T1, k2) - MUL(T3, k1) + T1 - T3
// d = MUL(T1, K1) + MUL(T3, K2) = MUL(T1, k1) + MUL(T3, k2) + T1 + T3
const __m128i a_d3 = _mm_add_epi16(dc, T23);
const __m128i b_c3 = _mm_sub_epi16(dc, T23);
const __m128i c1d1 = _mm_mulhi_epi16(T1, k2k1);
const __m128i c2d2 = _mm_mulhi_epi16(T3, k1k2);
const __m128i c3 = _mm_unpackhi_epi64(b_c3, b_c3);
const __m128i c4 = _mm_sub_epi16(c1d1, c2d2);
const __m128i c = _mm_add_epi16(c3, c4);
const __m128i d4u = _mm_add_epi16(c1d1, c2d2);
const __m128i du = _mm_add_epi16(a_d3, d4u);
const __m128i d = _mm_unpackhi_epi64(du, du);
// Second pass.
const __m128i comb_ab = _mm_unpacklo_epi64(a_d3, b_c3);
const __m128i comb_dc = _mm_unpacklo_epi64(d, c);
const __m128i tmp01 = _mm_add_epi16(comb_ab, comb_dc);
const __m128i tmp32 = _mm_sub_epi16(comb_ab, comb_dc);
const __m128i tmp23 = _mm_shuffle_epi32(tmp32, _MM_SHUFFLE(1, 0, 3, 2));
const __m128i shifted01 = _mm_srai_epi16(tmp01, 3);
const __m128i shifted23 = _mm_srai_epi16(tmp23, 3);
// a00 a01 a02 a03 a10 a11 a12 a13
// a20 a21 a22 a23 a30 a31 a32 a33
const __m128i transpose_0 = _mm_unpacklo_epi16(shifted01, shifted23);
const __m128i transpose_1 = _mm_unpackhi_epi16(shifted01, shifted23);
// a00 a20 a01 a21 a02 a22 a03 a23
// a10 a30 a11 a31 a12 a32 a13 a33
T01 = _mm_unpacklo_epi16(transpose_0, transpose_1);
T23 = _mm_unpackhi_epi16(transpose_0, transpose_1);
// a00 a10 a20 a30 a01 a11 a21 a31
// a02 a12 a22 a32 a03 a13 a23 a33
}
// Add inverse transform to 'ref' and store.
{
// Load the reference(s).
__m128i ref01, ref23, ref0123;
int32_t buf[4];
// Load four bytes/pixels per line.
const __m128i ref0 = _mm_cvtsi32_si128(WebPMemToInt32(&ref[0 * BPS]));
const __m128i ref1 = _mm_cvtsi32_si128(WebPMemToInt32(&ref[1 * BPS]));
const __m128i ref2 = _mm_cvtsi32_si128(WebPMemToInt32(&ref[2 * BPS]));
const __m128i ref3 = _mm_cvtsi32_si128(WebPMemToInt32(&ref[3 * BPS]));
ref01 = _mm_unpacklo_epi32(ref0, ref1);
ref23 = _mm_unpacklo_epi32(ref2, ref3);
// Convert to 16b.
ref01 = _mm_unpacklo_epi8(ref01, zero);
ref23 = _mm_unpacklo_epi8(ref23, zero);
// Add the inverse transform(s).
ref01 = _mm_add_epi16(ref01, T01);
ref23 = _mm_add_epi16(ref23, T23);
// Unsigned saturate to 8b.
ref0123 = _mm_packus_epi16(ref01, ref23);
_mm_storeu_si128((__m128i *)buf, ref0123);
// Store four bytes/pixels per line.
WebPInt32ToMem(&dst[0 * BPS], buf[0]);
WebPInt32ToMem(&dst[1 * BPS], buf[1]);
WebPInt32ToMem(&dst[2 * BPS], buf[2]);
WebPInt32ToMem(&dst[3 * BPS], buf[3]);
}
}
// Does two inverse transforms.
static void ITransform_Two_SSE2(const uint8_t* ref, const int16_t* in,
uint8_t* dst) {
// Does one or two inverse transforms.
static void ITransform_SSE2(const uint8_t* ref, const int16_t* in, uint8_t* dst,
int do_two) {
// This implementation makes use of 16-bit fixed point versions of two
// multiply constants:
// K1 = sqrt(2) * cos (pi/8) ~= 85627 / 2^16
@ -200,21 +49,33 @@ static void ITransform_Two_SSE2(const uint8_t* ref, const int16_t* in,
__m128i T0, T1, T2, T3;
// Load and concatenate the transform coefficients (we'll do two inverse
// transforms in parallel).
// transforms in parallel). In the case of only one inverse transform, the
// second half of the vectors will just contain random value we'll never
// use nor store.
__m128i in0, in1, in2, in3;
{
const __m128i tmp0 = _mm_loadu_si128((const __m128i*)&in[0]);
const __m128i tmp1 = _mm_loadu_si128((const __m128i*)&in[8]);
const __m128i tmp2 = _mm_loadu_si128((const __m128i*)&in[16]);
const __m128i tmp3 = _mm_loadu_si128((const __m128i*)&in[24]);
in0 = _mm_unpacklo_epi64(tmp0, tmp2);
in1 = _mm_unpackhi_epi64(tmp0, tmp2);
in2 = _mm_unpacklo_epi64(tmp1, tmp3);
in3 = _mm_unpackhi_epi64(tmp1, tmp3);
// a00 a10 a20 a30 b00 b10 b20 b30
// a01 a11 a21 a31 b01 b11 b21 b31
// a02 a12 a22 a32 b02 b12 b22 b32
// a03 a13 a23 a33 b03 b13 b23 b33
in0 = _mm_loadl_epi64((const __m128i*)&in[0]);
in1 = _mm_loadl_epi64((const __m128i*)&in[4]);
in2 = _mm_loadl_epi64((const __m128i*)&in[8]);
in3 = _mm_loadl_epi64((const __m128i*)&in[12]);
// a00 a10 a20 a30 x x x x
// a01 a11 a21 a31 x x x x
// a02 a12 a22 a32 x x x x
// a03 a13 a23 a33 x x x x
if (do_two) {
const __m128i inB0 = _mm_loadl_epi64((const __m128i*)&in[16]);
const __m128i inB1 = _mm_loadl_epi64((const __m128i*)&in[20]);
const __m128i inB2 = _mm_loadl_epi64((const __m128i*)&in[24]);
const __m128i inB3 = _mm_loadl_epi64((const __m128i*)&in[28]);
in0 = _mm_unpacklo_epi64(in0, inB0);
in1 = _mm_unpacklo_epi64(in1, inB1);
in2 = _mm_unpacklo_epi64(in2, inB2);
in3 = _mm_unpacklo_epi64(in3, inB3);
// a00 a10 a20 a30 b00 b10 b20 b30
// a01 a11 a21 a31 b01 b11 b21 b31
// a02 a12 a22 a32 b02 b12 b22 b32
// a03 a13 a23 a33 b03 b13 b23 b33
}
}
// Vertical pass and subsequent transpose.
@ -287,11 +148,19 @@ static void ITransform_Two_SSE2(const uint8_t* ref, const int16_t* in,
const __m128i zero = _mm_setzero_si128();
// Load the reference(s).
__m128i ref0, ref1, ref2, ref3;
// Load eight bytes/pixels per line.
ref0 = _mm_loadl_epi64((const __m128i*)&ref[0 * BPS]);
ref1 = _mm_loadl_epi64((const __m128i*)&ref[1 * BPS]);
ref2 = _mm_loadl_epi64((const __m128i*)&ref[2 * BPS]);
ref3 = _mm_loadl_epi64((const __m128i*)&ref[3 * BPS]);
if (do_two) {
// Load eight bytes/pixels per line.
ref0 = _mm_loadl_epi64((const __m128i*)&ref[0 * BPS]);
ref1 = _mm_loadl_epi64((const __m128i*)&ref[1 * BPS]);
ref2 = _mm_loadl_epi64((const __m128i*)&ref[2 * BPS]);
ref3 = _mm_loadl_epi64((const __m128i*)&ref[3 * BPS]);
} else {
// Load four bytes/pixels per line.
ref0 = _mm_cvtsi32_si128(WebPMemToInt32(&ref[0 * BPS]));
ref1 = _mm_cvtsi32_si128(WebPMemToInt32(&ref[1 * BPS]));
ref2 = _mm_cvtsi32_si128(WebPMemToInt32(&ref[2 * BPS]));
ref3 = _mm_cvtsi32_si128(WebPMemToInt32(&ref[3 * BPS]));
}
// Convert to 16b.
ref0 = _mm_unpacklo_epi8(ref0, zero);
ref1 = _mm_unpacklo_epi8(ref1, zero);
@ -307,21 +176,20 @@ static void ITransform_Two_SSE2(const uint8_t* ref, const int16_t* in,
ref1 = _mm_packus_epi16(ref1, ref1);
ref2 = _mm_packus_epi16(ref2, ref2);
ref3 = _mm_packus_epi16(ref3, ref3);
// Store eight bytes/pixels per line.
_mm_storel_epi64((__m128i*)&dst[0 * BPS], ref0);
_mm_storel_epi64((__m128i*)&dst[1 * BPS], ref1);
_mm_storel_epi64((__m128i*)&dst[2 * BPS], ref2);
_mm_storel_epi64((__m128i*)&dst[3 * BPS], ref3);
}
}
// Does one or two inverse transforms.
static void ITransform_SSE2(const uint8_t* ref, const int16_t* in, uint8_t* dst,
int do_two) {
if (do_two) {
ITransform_Two_SSE2(ref, in, dst);
} else {
ITransform_One_SSE2(ref, in, dst);
// Store the results.
if (do_two) {
// Store eight bytes/pixels per line.
_mm_storel_epi64((__m128i*)&dst[0 * BPS], ref0);
_mm_storel_epi64((__m128i*)&dst[1 * BPS], ref1);
_mm_storel_epi64((__m128i*)&dst[2 * BPS], ref2);
_mm_storel_epi64((__m128i*)&dst[3 * BPS], ref3);
} else {
// Store four bytes/pixels per line.
WebPInt32ToMem(&dst[0 * BPS], _mm_cvtsi128_si32(ref0));
WebPInt32ToMem(&dst[1 * BPS], _mm_cvtsi128_si32(ref1));
WebPInt32ToMem(&dst[2 * BPS], _mm_cvtsi128_si32(ref2));
WebPInt32ToMem(&dst[3 * BPS], _mm_cvtsi128_si32(ref3));
}
}
}

View File

@ -233,7 +233,6 @@ static void GradientUnfilter_C(const uint8_t* prev, const uint8_t* in,
WebPFilterFunc WebPFilters[WEBP_FILTER_LAST];
WebPUnfilterFunc WebPUnfilters[WEBP_FILTER_LAST];
extern VP8CPUInfo VP8GetCPUInfo;
extern void VP8FiltersInitMIPSdspR2(void);
extern void VP8FiltersInitMSA(void);
extern void VP8FiltersInitNEON(void);

View File

@ -588,7 +588,6 @@ VP8LConvertFunc VP8LConvertBGRAToBGR;
VP8LMapARGBFunc VP8LMapColor32b;
VP8LMapAlphaFunc VP8LMapColor8b;
extern VP8CPUInfo VP8GetCPUInfo;
extern void VP8LDspInitSSE2(void);
extern void VP8LDspInitSSE41(void);
extern void VP8LDspInitNEON(void);

View File

@ -791,7 +791,6 @@ VP8LBundleColorMapFunc VP8LBundleColorMap;
VP8LPredictorAddSubFunc VP8LPredictorsSub[16];
VP8LPredictorAddSubFunc VP8LPredictorsSub_C[16];
extern VP8CPUInfo VP8GetCPUInfo;
extern void VP8LEncDspInitSSE2(void);
extern void VP8LEncDspInitSSE41(void);
extern void VP8LEncDspInitNEON(void);

View File

@ -25,7 +25,7 @@
// vtbl?_u8 are marked unavailable for iOS arm64 with Xcode < 6.3, use
// non-standard versions there.
#if defined(__APPLE__) && WEBP_AARCH64 && \
#if defined(__APPLE__) && defined(__aarch64__) && \
defined(__apple_build_version__) && (__apple_build_version__< 6020037)
#define USE_VTBLQ
#endif

View File

@ -498,7 +498,7 @@ static void PredictorAdd13_NEON(const uint32_t* in, const uint32_t* upper,
// vtbl?_u8 are marked unavailable for iOS arm64 with Xcode < 6.3, use
// non-standard versions there.
#if defined(__APPLE__) && WEBP_AARCH64 && \
#if defined(__APPLE__) && defined(__aarch64__) && \
defined(__apple_build_version__) && (__apple_build_version__< 6020037)
#define USE_VTBLQ
#endif

View File

@ -21,7 +21,7 @@
// Right now, some intrinsics functions seem slower, so we disable them
// everywhere except newer clang/gcc or aarch64 where the inline assembly is
// incompatible.
#if LOCAL_CLANG_PREREQ(3, 8) || LOCAL_GCC_PREREQ(4, 9) || WEBP_AARCH64
#if LOCAL_CLANG_PREREQ(3,8) || LOCAL_GCC_PREREQ(4,9) || defined(__aarch64__)
#define WEBP_USE_INTRINSICS // use intrinsics when possible
#endif
@ -46,7 +46,7 @@
// if using intrinsics, this flag avoids some functions that make gcc-4.6.3
// crash ("internal compiler error: in immed_double_const, at emit-rtl.").
// (probably similar to gcc.gnu.org/bugzilla/show_bug.cgi?id=48183)
#if !(LOCAL_CLANG_PREREQ(3, 8) || LOCAL_GCC_PREREQ(4, 8) || WEBP_AARCH64)
#if !(LOCAL_CLANG_PREREQ(3,8) || LOCAL_GCC_PREREQ(4,8) || defined(__aarch64__))
#define WORK_AROUND_GCC
#endif

View File

@ -22,7 +22,7 @@
#define IsFlat IsFlat_NEON
static uint32_t horizontal_add_uint32x4(const uint32x4_t a) {
#if WEBP_AARCH64
#if defined(__aarch64__)
return vaddvq_u32(a);
#else
const uint64x2_t b = vpaddlq_u32(a);

View File

@ -197,7 +197,6 @@ WebPRescalerImportRowFunc WebPRescalerImportRowShrink;
WebPRescalerExportRowFunc WebPRescalerExportRowExpand;
WebPRescalerExportRowFunc WebPRescalerExportRowShrink;
extern VP8CPUInfo VP8GetCPUInfo;
extern void WebPRescalerDspInitSSE2(void);
extern void WebPRescalerDspInitMIPS32(void);
extern void WebPRescalerDspInitMIPSdspR2(void);

View File

@ -137,7 +137,6 @@ VP8SSIMGetClippedFunc VP8SSIMGetClipped;
VP8AccumulateSSEFunc VP8AccumulateSSE;
#endif
extern VP8CPUInfo VP8GetCPUInfo;
extern void VP8SSIMDspInitSSE2(void);
WEBP_DSP_INIT_FUNC(VP8SSIMDspInit) {

View File

@ -215,7 +215,6 @@ static void EmptyYuv444Func(const uint8_t* y,
WebPYUV444Converter WebPYUV444Converters[MODE_LAST];
extern VP8CPUInfo VP8GetCPUInfo;
extern void WebPInitYUV444ConvertersMIPSdspR2(void);
extern void WebPInitYUV444ConvertersSSE2(void);
extern void WebPInitYUV444ConvertersSSE41(void);

View File

@ -111,7 +111,7 @@ static const int16_t kCoeffs1[4] = { 19077, 26149, 6419, 13320 };
vst4_u8(out, v255_r_g_b); \
} while (0)
#if (WEBP_SWAP_16BIT_CSP == 0)
#if !defined(WEBP_SWAP_16BIT_CSP)
#define ZIP_U8(lo, hi) vzip_u8((lo), (hi))
#else
#define ZIP_U8(lo, hi) vzip_u8((hi), (lo))

View File

@ -70,7 +70,6 @@ void WebPSamplerProcessPlane(const uint8_t* y, int y_stride,
WebPSamplerRowFunc WebPSamplers[MODE_LAST];
extern VP8CPUInfo VP8GetCPUInfo;
extern void WebPInitSamplersSSE2(void);
extern void WebPInitSamplersSSE41(void);
extern void WebPInitSamplersMIPS32(void);

View File

@ -319,11 +319,11 @@ static int EncodeAlpha(VP8Encoder* const enc,
assert(filter >= WEBP_FILTER_NONE && filter <= WEBP_FILTER_FAST);
if (quality < 0 || quality > 100) {
return WebPEncodingSetError(pic, VP8_ENC_ERROR_INVALID_CONFIGURATION);
return 0;
}
if (method < ALPHA_NO_COMPRESSION || method > ALPHA_LOSSLESS_COMPRESSION) {
return WebPEncodingSetError(pic, VP8_ENC_ERROR_INVALID_CONFIGURATION);
return 0;
}
if (method == ALPHA_NO_COMPRESSION) {
@ -333,7 +333,7 @@ static int EncodeAlpha(VP8Encoder* const enc,
quant_alpha = (uint8_t*)WebPSafeMalloc(1ULL, data_size);
if (quant_alpha == NULL) {
return WebPEncodingSetError(pic, VP8_ENC_ERROR_OUT_OF_MEMORY);
return 0;
}
// Extract alpha data (width x height) from raw_data (stride x height).
@ -353,9 +353,6 @@ static int EncodeAlpha(VP8Encoder* const enc,
ok = ApplyFiltersAndEncode(quant_alpha, width, height, data_size, method,
filter, reduce_levels, effort_level, output,
output_size, pic->stats);
if (!ok) {
WebPEncodingSetError(pic, VP8_ENC_ERROR_OUT_OF_MEMORY); // imprecise
}
#if !defined(WEBP_DISABLE_STATS)
if (pic->stats != NULL) { // need stats?
pic->stats->coded_size += (int)(*output_size);
@ -415,7 +412,7 @@ int VP8EncStartAlpha(VP8Encoder* const enc) {
WebPWorker* const worker = &enc->alpha_worker_;
// Makes sure worker is good to go.
if (!WebPGetWorkerInterface()->Reset(worker)) {
return WebPEncodingSetError(enc->pic_, VP8_ENC_ERROR_OUT_OF_MEMORY);
return 0;
}
WebPGetWorkerInterface()->Launch(worker);
return 1;

View File

@ -474,10 +474,6 @@ int VP8EncAnalyze(VP8Encoder* const enc) {
} else { // Use only one default segment.
ResetAllMBInfo(enc);
}
if (!ok) {
return WebPEncodingSetError(enc->pic_,
VP8_ENC_ERROR_OUT_OF_MEMORY); // imprecise
}
return ok;
}

View File

@ -283,7 +283,8 @@ int VP8LHashChainFill(VP8LHashChain* const p, int quality,
hash_to_first_index =
(int32_t*)WebPSafeMalloc(HASH_SIZE, sizeof(*hash_to_first_index));
if (hash_to_first_index == NULL) {
return WebPEncodingSetError(pic, VP8_ENC_ERROR_OUT_OF_MEMORY);
WebPEncodingSetError(pic, VP8_ENC_ERROR_OUT_OF_MEMORY);
return 0;
}
percent_range = remaining_percent / 2;
@ -1049,7 +1050,8 @@ int VP8LGetBackwardReferences(
refs_best = GetBackwardReferencesLowEffort(
width, height, argb, cache_bits_best, hash_chain, refs);
if (refs_best == NULL) {
return WebPEncodingSetError(pic, VP8_ENC_ERROR_OUT_OF_MEMORY);
WebPEncodingSetError(pic, VP8_ENC_ERROR_OUT_OF_MEMORY);
return 0;
}
// Set it in first position.
BackwardRefsSwap(refs_best, &refs[0]);
@ -1057,7 +1059,8 @@ int VP8LGetBackwardReferences(
if (!GetBackwardReferences(width, height, argb, quality, lz77_types_to_try,
cache_bits_max, do_no_cache, hash_chain, refs,
cache_bits_best)) {
return WebPEncodingSetError(pic, VP8_ENC_ERROR_OUT_OF_MEMORY);
WebPEncodingSetError(pic, VP8_ENC_ERROR_OUT_OF_MEMORY);
return 0;
}
}

View File

@ -689,7 +689,7 @@ static int PreLoopInitialize(VP8Encoder* const enc) {
}
if (!ok) {
VP8EncFreeBitWriters(enc); // malloc error occurred
return WebPEncodingSetError(enc->pic_, VP8_ENC_ERROR_OUT_OF_MEMORY);
WebPEncodingSetError(enc->pic_, VP8_ENC_ERROR_OUT_OF_MEMORY);
}
return ok;
}
@ -719,7 +719,6 @@ static int PostLoopFinalize(VP8EncIterator* const it, int ok) {
} else {
// Something bad happened -> need to do some memory cleanup.
VP8EncFreeBitWriters(enc);
return WebPEncodingSetError(enc->pic_, VP8_ENC_ERROR_OUT_OF_MEMORY);
}
return ok;
}
@ -755,11 +754,6 @@ int VP8EncLoop(VP8Encoder* const enc) {
// *then* decide how to code the skip decision if there's one.
if (!VP8Decimate(&it, &info, rd_opt) || dont_use_skip) {
CodeResiduals(it.bw_, &it, &info);
if (it.bw_->error_) {
// enc->pic_->error_code is set in PostLoopFinalize().
ok = 0;
break;
}
} else { // reset predictors after a skip
ResetAfterSkip(&it);
}

View File

@ -98,7 +98,6 @@ static int kLinearToGammaTab[GAMMA_TAB_SIZE + 1];
static uint16_t kGammaToLinearTab[256];
static volatile int kGammaTablesOk = 0;
static void InitGammaTables(void);
extern VP8CPUInfo VP8GetCPUInfo;
WEBP_DSP_INIT_FUNC(InitGammaTables) {
if (!kGammaTablesOk) {
@ -535,9 +534,7 @@ static int ImportYUVAFromRGBA(const uint8_t* r_ptr,
WebPInitConvertARGBToYUV();
InitGammaTables();
if (tmp_rgb == NULL) {
return WebPEncodingSetError(picture, VP8_ENC_ERROR_OUT_OF_MEMORY);
}
if (tmp_rgb == NULL) return 0; // malloc error
// Downsample Y/U/V planes, two rows at a time
for (y = 0; y < (height >> 1); ++y) {

View File

@ -137,9 +137,7 @@ int WebPPictureCrop(WebPPicture* pic,
PictureGrabSpecs(pic, &tmp);
tmp.width = width;
tmp.height = height;
if (!WebPPictureAlloc(&tmp)) {
return WebPEncodingSetError(pic, tmp.error_code);
}
if (!WebPPictureAlloc(&tmp)) return 0;
if (!pic->use_argb) {
const int y_offset = top * pic->y_stride + left;
@ -214,28 +212,26 @@ int WebPPictureRescale(WebPPicture* picture, int width, int height) {
prev_height = picture->height;
if (!WebPRescalerGetScaledDimensions(
prev_width, prev_height, &width, &height)) {
return WebPEncodingSetError(picture, VP8_ENC_ERROR_BAD_DIMENSION);
return 0;
}
PictureGrabSpecs(picture, &tmp);
tmp.width = width;
tmp.height = height;
if (!WebPPictureAlloc(&tmp)) {
return WebPEncodingSetError(picture, tmp.error_code);
}
if (!WebPPictureAlloc(&tmp)) return 0;
if (!picture->use_argb) {
work = (rescaler_t*)WebPSafeMalloc(2ULL * width, sizeof(*work));
if (work == NULL) {
WebPPictureFree(&tmp);
return WebPEncodingSetError(picture, VP8_ENC_ERROR_OUT_OF_MEMORY);
return 0;
}
// If present, we need to rescale alpha first (for AlphaMultiplyY).
if (picture->a != NULL) {
WebPInitAlphaProcessing();
if (!RescalePlane(picture->a, prev_width, prev_height, picture->a_stride,
tmp.a, width, height, tmp.a_stride, work, 1)) {
return WebPEncodingSetError(picture, VP8_ENC_ERROR_BAD_DIMENSION);
return 0;
}
}
@ -250,14 +246,14 @@ int WebPPictureRescale(WebPPicture* picture, int width, int height) {
!RescalePlane(picture->v, HALVE(prev_width), HALVE(prev_height),
picture->uv_stride, tmp.v, HALVE(width), HALVE(height),
tmp.uv_stride, work, 1)) {
return WebPEncodingSetError(picture, VP8_ENC_ERROR_BAD_DIMENSION);
return 0;
}
AlphaMultiplyY(&tmp, 1);
} else {
work = (rescaler_t*)WebPSafeMalloc(2ULL * width * 4, sizeof(*work));
if (work == NULL) {
WebPPictureFree(&tmp);
return WebPEncodingSetError(picture, VP8_ENC_ERROR_OUT_OF_MEMORY);
return 0;
}
// In order to correctly interpolate colors, we need to apply the alpha
// weighting first (black-matting), scale the RGB values, and remove
@ -267,7 +263,7 @@ int WebPPictureRescale(WebPPicture* picture, int width, int height) {
if (!RescalePlane((const uint8_t*)picture->argb, prev_width, prev_height,
picture->argb_stride * 4, (uint8_t*)tmp.argb, width,
height, tmp.argb_stride * 4, work, 4)) {
return WebPEncodingSetError(picture, VP8_ENC_ERROR_BAD_DIMENSION);
return 0;
}
AlphaMultiplyARGB(&tmp, 1);
}

View File

@ -258,10 +258,7 @@ static int EmitPartitionsSize(const VP8Encoder* const enc,
buf[3 * p + 1] = (part_size >> 8) & 0xff;
buf[3 * p + 2] = (part_size >> 16) & 0xff;
}
if (p && !pic->writer(buf, 3 * p, pic)) {
return WebPEncodingSetError(pic, VP8_ENC_ERROR_BAD_WRITE);
}
return 1;
return p ? pic->writer(buf, 3 * p, pic) : 1;
}
//------------------------------------------------------------------------------
@ -384,7 +381,6 @@ int VP8EncWrite(VP8Encoder* const enc) {
enc->coded_size_ = (int)(CHUNK_HEADER_SIZE + riff_size);
ok = ok && WebPReportProgress(pic, final_percent, &enc->percent_);
if (!ok) WebPEncodingSetError(pic, VP8_ENC_ERROR_BAD_WRITE);
return ok;
}

View File

@ -32,7 +32,7 @@ extern "C" {
// version numbers
#define ENC_MAJ_VERSION 1
#define ENC_MIN_VERSION 3
#define ENC_REV_VERSION 2
#define ENC_REV_VERSION 0
enum { MAX_LF_LEVELS = 64, // Maximum loop filter level
MAX_VARIABLE_LEVEL = 67, // last (inclusive) level with variable cost

View File

@ -196,7 +196,8 @@ static int CoOccurrenceBuild(const WebPPicture* const pic,
uint32_t palette_sorted[MAX_PALETTE_SIZE];
lines = (uint32_t*)WebPSafeMalloc(2 * pic->width, sizeof(*lines));
if (lines == NULL) {
return WebPEncodingSetError(pic, VP8_ENC_ERROR_OUT_OF_MEMORY);
WebPEncodingSetError(pic, VP8_ENC_ERROR_OUT_OF_MEMORY);
return 0;
}
line_top = &lines[0];
line_current = &lines[pic->width];
@ -254,7 +255,8 @@ static int PaletteSortModifiedZeng(
cooccurrence =
(uint32_t*)WebPSafeCalloc(num_colors * num_colors, sizeof(*cooccurrence));
if (cooccurrence == NULL) {
return WebPEncodingSetError(pic, VP8_ENC_ERROR_OUT_OF_MEMORY);
WebPEncodingSetError(pic, VP8_ENC_ERROR_OUT_OF_MEMORY);
return 0;
}
if (!CoOccurrenceBuild(pic, palette_sorted, num_colors, cooccurrence)) {
WebPSafeFree(cooccurrence);
@ -1011,7 +1013,8 @@ static int StoreImageToBitMask(
VP8LRefsCursorNext(&c);
}
if (bw->error_) {
return WebPEncodingSetError(pic, VP8_ENC_ERROR_OUT_OF_MEMORY);
WebPEncodingSetError(pic, VP8_ENC_ERROR_OUT_OF_MEMORY);
return 0;
}
return 1;
}
@ -1295,10 +1298,7 @@ static int EncodeImageInternal(
}
}
tokens = (HuffmanTreeToken*)WebPSafeMalloc(max_tokens, sizeof(*tokens));
if (tokens == NULL) {
WebPEncodingSetError(pic, VP8_ENC_ERROR_OUT_OF_MEMORY);
goto Error;
}
if (tokens == NULL) goto Error;
for (i = 0; i < 5 * histogram_image_size; ++i) {
HuffmanTreeCode* const codes = &huffman_codes[i];
StoreHuffmanCode(bw, huff_tree, tokens, codes);
@ -1457,13 +1457,15 @@ static int WriteImage(const WebPPicture* const pic, VP8LBitWriter* const bw,
if (!WriteRiffHeader(pic, riff_size, vp8l_size) ||
!pic->writer(webpll_data, webpll_size, pic)) {
return WebPEncodingSetError(pic, VP8_ENC_ERROR_BAD_WRITE);
WebPEncodingSetError(pic, VP8_ENC_ERROR_BAD_WRITE);
return 0;
}
if (pad) {
const uint8_t pad_byte[1] = { 0 };
if (!pic->writer(pad_byte, 1, pic)) {
return WebPEncodingSetError(pic, VP8_ENC_ERROR_BAD_WRITE);
WebPEncodingSetError(pic, VP8_ENC_ERROR_BAD_WRITE);
return 0;
}
}
*coded_size = CHUNK_HEADER_SIZE + riff_size;
@ -1508,7 +1510,8 @@ static int AllocateTransformBuffer(VP8LEncoder* const enc, int width,
ClearTransformBuffer(enc);
mem = (uint32_t*)WebPSafeMalloc(mem_size, sizeof(*mem));
if (mem == NULL) {
return WebPEncodingSetError(enc->pic_, VP8_ENC_ERROR_OUT_OF_MEMORY);
WebPEncodingSetError(enc->pic_, VP8_ENC_ERROR_OUT_OF_MEMORY);
return 0;
}
enc->transform_mem_ = mem;
enc->transform_mem_size_ = (size_t)mem_size;
@ -1616,7 +1619,8 @@ static int ApplyPalette(const uint32_t* src, uint32_t src_stride, uint32_t* dst,
int x, y;
if (tmp_row == NULL) {
return WebPEncodingSetError(pic, VP8_ENC_ERROR_OUT_OF_MEMORY);
WebPEncodingSetError(pic, VP8_ENC_ERROR_OUT_OF_MEMORY);
return 0;
}
if (palette_size < APPLY_PALETTE_GREEDY_MAX) {
@ -1970,8 +1974,9 @@ int VP8LEncodeStream(const WebPConfig* const config,
int ok_main;
if (enc_main == NULL || !VP8LBitWriterInit(&bw_side, 0)) {
WebPEncodingSetError(picture, VP8_ENC_ERROR_OUT_OF_MEMORY);
VP8LEncoderDelete(enc_main);
return WebPEncodingSetError(picture, VP8_ENC_ERROR_OUT_OF_MEMORY);
return 0;
}
// Avoid "garbage value" error from Clang's static analysis tool.
@ -2118,7 +2123,8 @@ int VP8LEncodeImage(const WebPConfig* const config,
if (picture == NULL) return 0;
if (config == NULL || picture->argb == NULL) {
return WebPEncodingSetError(picture, VP8_ENC_ERROR_NULL_PARAMETER);
WebPEncodingSetError(picture, VP8_ENC_ERROR_NULL_PARAMETER);
return 0;
}
width = picture->width;

View File

@ -307,10 +307,7 @@ int WebPEncodingSetError(const WebPPicture* const pic,
WebPEncodingError error) {
assert((int)error < VP8_ENC_ERROR_LAST);
assert((int)error >= VP8_ENC_OK);
// The oldest error reported takes precedence over the new one.
if (pic->error_code == VP8_ENC_OK) {
((WebPPicture*)pic)->error_code = error;
}
((WebPPicture*)pic)->error_code = error;
return 0;
}
@ -320,7 +317,8 @@ int WebPReportProgress(const WebPPicture* const pic,
*percent_store = percent;
if (pic->progress_hook && !pic->progress_hook(percent, pic)) {
// user abort requested
return WebPEncodingSetError(pic, VP8_ENC_ERROR_USER_ABORT);
WebPEncodingSetError(pic, VP8_ENC_ERROR_USER_ABORT);
return 0;
}
}
return 1; // ok
@ -331,7 +329,7 @@ int WebPEncode(const WebPConfig* config, WebPPicture* pic) {
int ok = 0;
if (pic == NULL) return 0;
pic->error_code = VP8_ENC_OK; // all ok so far
WebPEncodingSetError(pic, VP8_ENC_OK); // all ok so far
if (config == NULL) { // bad params
return WebPEncodingSetError(pic, VP8_ENC_ERROR_NULL_PARAMETER);
}

View File

@ -6,7 +6,7 @@ includedir=@includedir@
Name: libwebp
Description: Library for the WebP graphics format
Version: @PACKAGE_VERSION@
Requires.private: libsharpyuv
Requires: libsharpyuv
Cflags: -I${includedir}
Libs: -L${libdir} -l@webp_libname_prefix@webp
Libs.private: -lm @PTHREAD_CFLAGS@ @PTHREAD_LIBS@

View File

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

View File

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

View File

@ -17,6 +17,6 @@ noinst_HEADERS =
noinst_HEADERS += ../webp/format_constants.h
libwebpmux_la_LIBADD = ../libwebp.la
libwebpmux_la_LDFLAGS = -no-undefined -version-info 3:13:0 -lm
libwebpmux_la_LDFLAGS = -no-undefined -version-info 3:11:0 -lm
libwebpmuxincludedir = $(includedir)/webp
pkgconfig_DATA = libwebpmux.pc

View File

@ -6,7 +6,7 @@ includedir=@includedir@
Name: libwebpmux
Description: Library for manipulating the WebP graphics format container
Version: @PACKAGE_VERSION@
Requires.private: libwebp >= 0.2.0
Requires: libwebp >= 0.2.0
Cflags: -I${includedir}
Libs: -L${libdir} -l@webp_libname_prefix@webpmux
Libs.private: -lm

View File

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

View File

@ -29,7 +29,7 @@ extern "C" {
#define MUX_MAJ_VERSION 1
#define MUX_MIN_VERSION 3
#define MUX_REV_VERSION 2
#define MUX_REV_VERSION 0
// Chunk object.
typedef struct WebPChunk WebPChunk;

View File

@ -116,12 +116,9 @@ static int MuxImageParse(const WebPChunk* const chunk, int copy_data,
// Each of ANMF chunk contain a header at the beginning. So, its size should
// be at least 'hdr_size'.
if (size < hdr_size) goto Fail;
if (ChunkAssignData(&subchunk, &temp, copy_data,
chunk->tag_) != WEBP_MUX_OK) {
goto Fail;
}
ChunkAssignData(&subchunk, &temp, copy_data, chunk->tag_);
}
if (ChunkSetHead(&subchunk, &wpi->header_) != WEBP_MUX_OK) goto Fail;
ChunkSetHead(&subchunk, &wpi->header_);
wpi->is_partial_ = 1; // Waiting for ALPH and/or VP8/VP8L chunks.
// Rest of the chunks.

View File

@ -15,7 +15,6 @@
#include "src/webp/config.h"
#endif
#include "src/dsp/cpu.h"
#include "src/utils/bit_reader_inl_utils.h"
#include "src/utils/utils.h"
@ -122,7 +121,7 @@ int32_t VP8GetSignedValue(VP8BitReader* const br, int bits,
#define VP8L_LOG8_WBITS 4 // Number of bytes needed to store VP8L_WBITS bits.
#if defined(__arm__) || defined(_M_ARM) || WEBP_AARCH64 || \
#if defined(__arm__) || defined(_M_ARM) || defined(__aarch64__) || \
defined(__i386__) || defined(_M_IX86) || \
defined(__x86_64__) || defined(_M_X64)
#define VP8L_USE_FAST_LOAD

View File

@ -19,7 +19,6 @@
#ifdef _MSC_VER
#include <stdlib.h> // _byteswap_ulong
#endif
#include "src/dsp/cpu.h"
#include "src/webp/types.h"
// Warning! This macro triggers quite some MACRO wizardry around func signature!
@ -65,7 +64,7 @@ extern "C" {
#define BITS 56
#elif defined(__arm__) || defined(_M_ARM) // ARM
#define BITS 24
#elif WEBP_AARCH64 // ARM 64bit
#elif defined(__aarch64__) // ARM 64bit
#define BITS 56
#elif defined(__mips__) // MIPS
#define BITS 24

View File

@ -81,11 +81,10 @@ WEBP_EXTERN uint8_t* WebPDecodeBGR(const uint8_t* data, size_t data_size,
// returned is the Y samples buffer. Upon return, *u and *v will point to
// the U and V chroma data. These U and V buffers need NOT be passed to
// WebPFree(), unlike the returned Y luma one. The dimension of the U and V
// planes are both (*width + 1) / 2 and (*height + 1) / 2.
// planes are both (*width + 1) / 2 and (*height + 1)/ 2.
// Upon return, the Y buffer has a stride returned as '*stride', while U and V
// have a common stride returned as '*uv_stride'.
// 'width' and 'height' may be NULL, the other pointers must not be.
// Returns NULL in case of error.
// Return NULL in case of error.
// (*) Also named Y'CbCr. See: https://en.wikipedia.org/wiki/YCbCr
WEBP_EXTERN uint8_t* WebPDecodeYUV(const uint8_t* data, size_t data_size,
int* width, int* height,

View File

@ -14,14 +14,13 @@
//
////////////////////////////////////////////////////////////////////////////////
#include <stdint.h>
#include <string.h>
#include "./fuzz_utils.h"
#include "src/utils/rescaler_utils.h"
#include "src/webp/decode.h"
int LLVMFuzzerTestOneInput(const uint8_t* const data, size_t size) {
int i;
WebPDecoderConfig config;
if (!WebPInitDecoderConfig(&config)) return 0;
if (WebPGetFeatures(data, size, &config.input) != VP8_STATUS_OK) return 0;
@ -63,41 +62,17 @@ int LLVMFuzzerTestOneInput(const uint8_t* const data, size_t size) {
config.output.colorspace = (WEBP_CSP_MODE)(value % MODE_LAST);
#endif // WEBP_REDUCE_CSP
for (int i = 0; i < 2; ++i) {
for (i = 0; i < 2; ++i) {
if (i == 1) {
// Use the bitstream data to generate extreme ranges for the options. An
// alternative approach would be to use a custom corpus containing webp
// files prepended with sizeof(config.options) zeroes to allow the fuzzer
// to modify these independently.
const int data_offset = 50;
if (data_offset + sizeof(config.options) >= size) break;
memcpy(&config.options, data + data_offset, sizeof(config.options));
// Skip easily avoidable out-of-memory fuzzing errors.
if (config.options.use_scaling) {
int scaled_width = config.options.scaled_width;
int scaled_height = config.options.scaled_height;
if (WebPRescalerGetScaledDimensions(config.input.width,
config.input.height, &scaled_width,
&scaled_height)) {
size_t fuzz_px_limit = kFuzzPxLimit;
if (scaled_width != config.input.width ||
scaled_height != config.input.height) {
// Using the WebPRescalerImport internally can significantly slow
// down the execution. Avoid timeouts due to that.
fuzz_px_limit /= 2;
}
// A big output canvas can lead to out-of-memory and timeout issues,
// but a big internal working buffer can too. Also, rescaling from a
// very wide input image to a very tall canvas can be as slow as
// decoding a huge number of pixels. Avoid timeouts due to these.
const uint64_t max_num_operations =
(uint64_t)Max(scaled_width, config.input.width) *
Max(scaled_height, config.input.height);
if (max_num_operations > fuzz_px_limit) {
break;
}
}
if (size > data_offset + sizeof(config.options)) {
memcpy(&config.options, data + data_offset, sizeof(config.options));
} else {
break;
}
}
if (size % 3) {

View File

@ -28,20 +28,9 @@
//------------------------------------------------------------------------------
// Arbitrary limits to prevent OOM, timeout, or slow execution.
//
// The decoded image size, and for animations additionally the canvas size.
// Enabling some sanitizers slow down runtime significantly.
// Use a very low threshold in this case to avoid timeouts.
#if defined(__SANITIZE_ADDRESS__) // GCC
static const size_t kFuzzPxLimit = 1024 * 1024 / 10;
#elif !defined(__has_feature) // Clang
static const size_t kFuzzPxLimit = 1024 * 1024;
#elif __has_feature(address_sanitizer) || __has_feature(memory_sanitizer)
static const size_t kFuzzPxLimit = 1024 * 1024 / 18;
#else
static const size_t kFuzzPxLimit = 1024 * 1024;
#endif
// Demuxed or decoded animation frames.
static const int kFuzzFrameLimit = 3;
@ -74,11 +63,6 @@ static WEBP_INLINE uint32_t Extract(uint32_t max_value,
//------------------------------------------------------------------------------
// Some functions to override VP8GetCPUInfo and disable some optimizations.
#ifdef __cplusplus
extern "C" VP8CPUInfo VP8GetCPUInfo;
#else
extern VP8CPUInfo VP8GetCPUInfo;
#endif
static VP8CPUInfo GetCPUInfo;
static WEBP_INLINE int GetCPUInfoNoSSE41(CPUFeature feature) {

View File

@ -69,7 +69,6 @@ readonly TARGETDIR="${TOPDIR}/WebP.xcframework"
readonly DECTARGETDIR="${TOPDIR}/WebPDecoder.xcframework"
readonly MUXTARGETDIR="${TOPDIR}/WebPMux.xcframework"
readonly DEMUXTARGETDIR="${TOPDIR}/WebPDemux.xcframework"
readonly SHARPYUVTARGETDIR="${TOPDIR}/SharpYuv.xcframework"
readonly DEVELOPER=$(xcode-select --print-path)
readonly DEVROOT="${DEVELOPER}/Toolchains/XcodeDefault.xctoolchain"
readonly PLATFORMSROOT="${DEVELOPER}/Platforms"
@ -95,15 +94,8 @@ update_headers_path() {
local subdir
for d in $(find "$1" -path "*/Headers"); do
subdir="$d/$framework_name"
if [[ -d "$subdir" ]]; then
# SharpYuv will have a sharpyuv subdirectory. macOS is case insensitive,
# but for consistency with the other frameworks, rename the directory to
# match the case of the framework name.
mv "$(echo ${subdir} | tr 'A-Z' 'a-z')" "$subdir"
else
mkdir "$subdir"
mv "$d/"*.h "$subdir"
fi
mkdir "$subdir"
mv "$d/"*.h "$subdir"
done
}
@ -112,8 +104,7 @@ echo "iOS SDK Version: ${SDK[$IOS]}"
echo "MacOS SDK Version: ${SDK[$MACOS]}"
if [[ -e "${BUILDDIR}" || -e "${TARGETDIR}" || -e "${DECTARGETDIR}" \
|| -e "${MUXTARGETDIR}" || -e "${DEMUXTARGETDIR}" \
|| -e "${SHARPYUVTARGETDIR}" ]]; then
|| -e "${MUXTARGETDIR}" || -e "${DEMUXTARGETDIR}" ]]; then
cat << EOF
WARNING: The following directories will be deleted:
WARNING: ${BUILDDIR}
@ -121,13 +112,12 @@ WARNING: ${TARGETDIR}
WARNING: ${DECTARGETDIR}
WARNING: ${MUXTARGETDIR}
WARNING: ${DEMUXTARGETDIR}
WARNING: ${SHARPYUVTARGETDIR}
WARNING: The build will continue in 5 seconds...
EOF
sleep 5
fi
rm -rf ${BUILDDIR} ${TARGETDIR} ${DECTARGETDIR} \
${MUXTARGETDIR} ${DEMUXTARGETDIR} ${SHARPYUVTARGETDIR}
${MUXTARGETDIR} ${DEMUXTARGETDIR}
if [[ ! -e ${SRCDIR}/configure ]]; then
if ! (cd ${SRCDIR} && sh autogen.sh); then
@ -147,7 +137,6 @@ for (( i = 0; i < $NUM_PLATFORMS; ++i )); do
DECLIBLIST=()
MUXLIBLIST=()
DEMUXLIBLIST=()
SHARPYUVLIBLIST=()
for PLATFORM in ${PLATFORMS[$i]}; do
ROOTDIR="${BUILDDIR}/${PLATFORM}"
@ -198,26 +187,23 @@ for (( i = 0; i < $NUM_PLATFORMS; ++i )); do
set +x
# Build only the libraries, skip the examples.
make V=0 -C sharpyuv install
make V=0 -C sharpyuv
make V=0 -C src install
LIBLIST+=("${ROOTDIR}/lib/libwebp.a")
DECLIBLIST+=("${ROOTDIR}/lib/libwebpdecoder.a")
MUXLIBLIST+=("${ROOTDIR}/lib/libwebpmux.a")
DEMUXLIBLIST+=("${ROOTDIR}/lib/libwebpdemux.a")
SHARPYUVLIBLIST+=("${ROOTDIR}/lib/libsharpyuv.a")
# xcodebuild requires a directory for the -headers option, these will match
# for all builds.
make -C src install-data DESTDIR="${ROOTDIR}/lib-headers"
make -C src install-commonHEADERS DESTDIR="${ROOTDIR}/dec-headers"
make -C src/demux install-data DESTDIR="${ROOTDIR}/demux-headers"
make -C src/mux install-data DESTDIR="${ROOTDIR}/mux-headers"
make -C sharpyuv install-data DESTDIR="${ROOTDIR}/sharpyuv-headers"
LIB_HEADERS="${ROOTDIR}/lib-headers/${ROOTDIR}/include/webp"
DEC_HEADERS="${ROOTDIR}/dec-headers/${ROOTDIR}/include/webp"
DEMUX_HEADERS="${ROOTDIR}/demux-headers/${ROOTDIR}/include/webp"
MUX_HEADERS="${ROOTDIR}/mux-headers/${ROOTDIR}/include/webp"
SHARPYUV_HEADERS="${ROOTDIR}/sharpyuv-headers/${ROOTDIR}/include/webp"
make distclean
@ -234,20 +220,16 @@ for (( i = 0; i < $NUM_PLATFORMS; ++i )); do
target_declib="${target_dir}/$(basename ${DECLIBLIST[0]})"
target_demuxlib="${target_dir}/$(basename ${DEMUXLIBLIST[0]})"
target_muxlib="${target_dir}/$(basename ${MUXLIBLIST[0]})"
target_sharpyuvlib="${target_dir}/$(basename ${SHARPYUVLIBLIST[0]})"
mkdir -p "${target_dir}"
${LIPO} -create ${LIBLIST[@]} -output "${target_lib}"
${LIPO} -create ${DECLIBLIST[@]} -output "${target_declib}"
${LIPO} -create ${DEMUXLIBLIST[@]} -output "${target_demuxlib}"
${LIPO} -create ${MUXLIBLIST[@]} -output "${target_muxlib}"
${LIPO} -create ${SHARPYUVLIBLIST[@]} -output "${target_sharpyuvlib}"
FAT_LIBLIST+=(-library "${target_lib}" -headers "${LIB_HEADERS}")
FAT_DECLIBLIST+=(-library "${target_declib}" -headers "${DEC_HEADERS}")
FAT_DEMUXLIBLIST+=(-library "${target_demuxlib}" -headers "${DEMUX_HEADERS}")
FAT_MUXLIBLIST+=(-library "${target_muxlib}" -headers "${MUX_HEADERS}")
FAT_SHARPYUVLIBLIST+=(-library "${target_sharpyuvlib}")
FAT_SHARPYUVLIBLIST+=(-headers "${SHARPYUV_HEADERS}")
done
# lipo will not put archives with the same architecture (e.g., x86_64
@ -264,13 +246,10 @@ xcodebuild -create-xcframework "${FAT_DEMUXLIBLIST[@]}" \
-output ${DEMUXTARGETDIR}
xcodebuild -create-xcframework "${FAT_MUXLIBLIST[@]}" \
-output ${MUXTARGETDIR}
xcodebuild -create-xcframework "${FAT_SHARPYUVLIBLIST[@]}" \
-output ${SHARPYUVTARGETDIR}
update_headers_path "${TARGETDIR}"
update_headers_path "${DECTARGETDIR}"
update_headers_path "${DEMUXTARGETDIR}"
update_headers_path "${MUXTARGETDIR}"
update_headers_path "${SHARPYUVTARGETDIR}"
set +x
echo "SUCCESS"