mirror of
https://github.com/webmproject/libwebp.git
synced 2025-07-15 21:39:59 +02:00
Compare commits
29 Commits
Author | SHA1 | Date | |
---|---|---|---|
801d2be12d | |||
20ef03ee35 | |||
dd80bb4343 | |||
ddd65f0d19 | |||
30956e3aaa | |||
64848839c0 | |||
b79a8421b8 | |||
69c7f16111 | |||
b0a860891d | |||
6db8248c01 | |||
827a307fec | |||
286e7fceaa | |||
9195ea0538 | |||
4acae017bd | |||
883f063397 | |||
567e1f442b | |||
f084244d9f | |||
b217b4fff7 | |||
f035d2e40d | |||
7031946ad8 | |||
973390b618 | |||
abd6664fee | |||
5b7e79303a | |||
02ca04c348 | |||
e94716e27c | |||
c846efd888 | |||
b6f756e82b | |||
8f5cb4c18e | |||
8ea81561d2 |
1
.mailmap
1
.mailmap
@ -12,3 +12,4 @@ Tamar Levy <tamar.levy@intel.com>
|
|||||||
<qrczak@google.com> <qrczak>
|
<qrczak@google.com> <qrczak>
|
||||||
Hui Su <huisu@google.com>
|
Hui Su <huisu@google.com>
|
||||||
James Zern <jzern@google.com>
|
James Zern <jzern@google.com>
|
||||||
|
Roberto Alanis <alanisbaez@google.com>
|
||||||
|
1
AUTHORS
1
AUTHORS
@ -32,6 +32,7 @@ Contributors:
|
|||||||
- Pascal Massimino (pascal dot massimino at gmail dot com)
|
- Pascal Massimino (pascal dot massimino at gmail dot com)
|
||||||
- Paweł Hajdan, Jr (phajdan dot jr at chromium dot org)
|
- Paweł Hajdan, Jr (phajdan dot jr at chromium dot org)
|
||||||
- Pierre Joye (pierre dot php at gmail dot com)
|
- Pierre Joye (pierre dot php at gmail dot com)
|
||||||
|
- Roberto Alanis (alanisbaez at google dot com)
|
||||||
- Sam Clegg (sbc at chromium dot org)
|
- Sam Clegg (sbc at chromium dot org)
|
||||||
- Scott Hancher (seh at google dot com)
|
- Scott Hancher (seh at google dot com)
|
||||||
- Scott LaVarnway (slavarnway at google dot com)
|
- Scott LaVarnway (slavarnway at google dot com)
|
||||||
|
@ -22,9 +22,6 @@ if(NOT EMSCRIPTEN)
|
|||||||
endif()
|
endif()
|
||||||
option(WEBP_ENABLE_SIMD "Enable any SIMD optimization."
|
option(WEBP_ENABLE_SIMD "Enable any SIMD optimization."
|
||||||
${WEBP_ENABLE_SIMD_DEFAULT})
|
${WEBP_ENABLE_SIMD_DEFAULT})
|
||||||
# Emscripten supports SSE builds using its compatibility headers, by default it
|
|
||||||
# will use SSE4 if WEBP_ENABLE_WASM_SIMD is OFF and WEBP_ENABLE_SIMD is ON.
|
|
||||||
option(WEBP_ENABLE_WASM_SIMD "Enable WebAssembly SIMD optimizations" OFF)
|
|
||||||
option(WEBP_BUILD_ANIM_UTILS "Build animation utilities." ON)
|
option(WEBP_BUILD_ANIM_UTILS "Build animation utilities." ON)
|
||||||
option(WEBP_BUILD_CWEBP "Build the cwebp command line tool." ON)
|
option(WEBP_BUILD_CWEBP "Build the cwebp command line tool." ON)
|
||||||
option(WEBP_BUILD_DWEBP "Build the dwebp command line tool." ON)
|
option(WEBP_BUILD_DWEBP "Build the dwebp command line tool." ON)
|
||||||
@ -51,6 +48,7 @@ endif()
|
|||||||
if(WEBP_BUILD_WEBP_JS)
|
if(WEBP_BUILD_WEBP_JS)
|
||||||
set(WEBP_BUILD_ANIM_UTILS OFF)
|
set(WEBP_BUILD_ANIM_UTILS OFF)
|
||||||
set(WEBP_BUILD_CWEBP OFF)
|
set(WEBP_BUILD_CWEBP OFF)
|
||||||
|
set(WEBP_BUILD_DWEBP OFF)
|
||||||
set(WEBP_BUILD_GIF2WEBP OFF)
|
set(WEBP_BUILD_GIF2WEBP OFF)
|
||||||
set(WEBP_BUILD_IMG2WEBP OFF)
|
set(WEBP_BUILD_IMG2WEBP OFF)
|
||||||
set(WEBP_BUILD_VWEBP OFF)
|
set(WEBP_BUILD_VWEBP OFF)
|
||||||
@ -82,9 +80,6 @@ include(GNUInstallDirs)
|
|||||||
if(WEBP_ENABLE_SWAP_16BIT_CSP)
|
if(WEBP_ENABLE_SWAP_16BIT_CSP)
|
||||||
add_definitions(-DWEBP_SWAP_16BIT_CSP=1)
|
add_definitions(-DWEBP_SWAP_16BIT_CSP=1)
|
||||||
endif()
|
endif()
|
||||||
if(WEBP_ENABLE_WASM_SIMD)
|
|
||||||
add_definitions(-DWEBP_ENABLE_WASM_SIMD_INTRINSICS)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(NOT WEBP_BITTRACE STREQUAL "0")
|
if(NOT WEBP_BITTRACE STREQUAL "0")
|
||||||
add_definitions(-DBITTRACE=${WEBP_BITTRACE})
|
add_definitions(-DBITTRACE=${WEBP_BITTRACE})
|
||||||
|
51
ChangeLog
51
ChangeLog
@ -1,7 +1,58 @@
|
|||||||
|
6db8248c libwebp: Fix VP8EncTokenLoop() progress
|
||||||
|
827a307f BMP enc: fix the transparency case
|
||||||
|
286e7fce libwebp: do not destroy jpeg codec twice on error
|
||||||
|
9195ea05 update ChangeLog (tag: v1.2.2-rc2)
|
||||||
|
4acae017 update NEWS
|
||||||
|
883f0633 man/img2webp.1: update date
|
||||||
|
567e1f44 Reword img2webp synopsis command line
|
||||||
|
f084244d anim_decode: fix alpha blending with big-endian
|
||||||
|
b217b4ff webpinfo: fix fourcc comparison w/big-endian
|
||||||
|
f035d2e4 update ChangeLog (tag: v1.2.2-rc1)
|
||||||
|
7031946a update NEWS
|
||||||
|
973390b6 bump version to 1.2.2
|
||||||
|
abd6664f update AUTHORS
|
||||||
|
5b7e7930 Merge "add missing USE_{MSA,NEON} checks in headers" into main
|
||||||
|
02ca04c3 add missing USE_{MSA,NEON} checks in headers
|
||||||
|
e94716e2 xcframeworkbuild.sh: place headers in a subdir
|
||||||
|
c846efd8 patch-check: commit subject length check
|
||||||
|
b6f756e8 update http links
|
||||||
|
8f5cb4c1 update rfc links
|
||||||
|
8ea81561 change VP8LPredictorFunc signature to avoid reading 'left'
|
||||||
|
6b1d18c3 webpmux: fix the -bgcolor description
|
||||||
|
3368d876 Merge "webpmux: add "-set bgcolor A,R,G,B"" into main
|
||||||
|
f213abf6 webpinfo: print the number of warnings
|
||||||
|
50c97c30 webpmux: add "-set bgcolor A,R,G,B"
|
||||||
|
2c206aaf Remove CMakeLists.txt check in compile.sh
|
||||||
|
96e3dfef Merge "infra/common.sh: add shard_should_run()" into main
|
||||||
|
0e0f74b7 infra/common.sh: add shard_should_run()
|
||||||
|
35b7436a Jenkins scripts port: update shell function comments
|
||||||
|
21d24b4c webp-container-spec.txt: remove 'experimental' markers
|
||||||
|
cdcf8902 Merge "Port Jenkins script: compile" into main
|
||||||
|
dc683cde Jenkins scripts port: static analysis
|
||||||
|
0858494e Port Jenkins script: compile
|
||||||
|
c2cf6a93 Jenkins scripts port: android compilation
|
||||||
|
df0e808f presubmit: Add pylint-2.7 and .pylintrc
|
||||||
|
676c57db patch-check: shfmt
|
||||||
|
7bb7f747 patch-check: Add shellcheck
|
||||||
|
abcd1797 Reformat docstrings and imports
|
||||||
|
edaf0895 Port Jenkins scripts: compile js
|
||||||
|
b9622063 Set CheckPatchFormatted flags to fail on diffs
|
||||||
|
e23cd548 dsp.h: enable NEON w/VS2019+ ARM64 targets
|
||||||
|
3875c7de CMakeLists.txt: set minimum version to 3.7
|
||||||
|
1a8f0d45 Have a hard-coded value for memset in TrellisQuantizeBlock.
|
||||||
|
93480160 Speed up TrellisQuantizeBlock
|
||||||
|
45eaacc9 Convert deprecated uint32 to uint32_t.
|
||||||
|
42592af8 webp,cmake: Remove unnecessary include dirs
|
||||||
|
e298e05f Add patch-check steps in PRESUBMIT.py
|
||||||
|
29148919 Merge tag 'v1.2.1'
|
||||||
|
9ce5843d update ChangeLog (tag: v1.2.1, origin/1.2.1)
|
||||||
d9191588 fuzzer/*: normalize src/ includes
|
d9191588 fuzzer/*: normalize src/ includes
|
||||||
|
c5bc3624 fuzzer/*: normalize src/ includes
|
||||||
53b6f762 fix indent
|
53b6f762 fix indent
|
||||||
|
d2caaba4 fix indent
|
||||||
731246ba update ChangeLog (tag: v1.2.1-rc2)
|
731246ba update ChangeLog (tag: v1.2.1-rc2)
|
||||||
d250f01d dsp/*: use WEBP_HAVE_* to determine Init availability
|
d250f01d dsp/*: use WEBP_HAVE_* to determine Init availability
|
||||||
|
1fe31625 dsp/*: use WEBP_HAVE_* to determine Init availability
|
||||||
3a4d3ecd update NEWS
|
3a4d3ecd update NEWS
|
||||||
b2bc8093 bump version to 1.2.1
|
b2bc8093 bump version to 1.2.1
|
||||||
e542fc7a update AUTHORS
|
e542fc7a update AUTHORS
|
||||||
|
8
NEWS
8
NEWS
@ -1,3 +1,11 @@
|
|||||||
|
- 1/11/2022: version 1.2.2
|
||||||
|
This is a binary compatible release.
|
||||||
|
* webpmux: add "-set bgcolor A,R,G,B"
|
||||||
|
* add ARM64 NEON support for MSVC builds (#539)
|
||||||
|
* fix duplicate include error in Xcode when using multiple XCFrameworks in a
|
||||||
|
project (#542)
|
||||||
|
* doc updates and bug fixes (#538, #544, #548, #550)
|
||||||
|
|
||||||
- 7/20/2021: version 1.2.1
|
- 7/20/2021: version 1.2.1
|
||||||
This is a binary compatible release.
|
This is a binary compatible release.
|
||||||
* minor lossless encoder improvements and x86 color conversion speed up
|
* minor lossless encoder improvements and x86 color conversion speed up
|
||||||
|
31
PRESUBMIT.py
31
PRESUBMIT.py
@ -33,15 +33,45 @@ See https://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts for
|
|||||||
details on the presubmit API built into depot_tools.
|
details on the presubmit API built into depot_tools.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
import re
|
||||||
import subprocess2
|
import subprocess2
|
||||||
|
|
||||||
USE_PYTHON3 = True
|
USE_PYTHON3 = True
|
||||||
_BASH_INDENTATION = "2"
|
_BASH_INDENTATION = "2"
|
||||||
|
_GIT_COMMIT_SUBJECT_LENGTH = 65
|
||||||
_INCLUDE_BASH_FILES_ONLY = [r".*\.sh$"]
|
_INCLUDE_BASH_FILES_ONLY = [r".*\.sh$"]
|
||||||
_INCLUDE_MAN_FILES_ONLY = [r"man/.+\.1$"]
|
_INCLUDE_MAN_FILES_ONLY = [r"man/.+\.1$"]
|
||||||
_LIBWEBP_MAX_LINE_LENGTH = 80
|
_LIBWEBP_MAX_LINE_LENGTH = 80
|
||||||
|
|
||||||
|
|
||||||
|
def _CheckCommitSubjectLength(input_api, output_api):
|
||||||
|
"""Ensures commit's subject length is no longer than 65 chars."""
|
||||||
|
name = "git-commit subject"
|
||||||
|
cmd = ["git", "log", "-1", "--pretty=%s"]
|
||||||
|
start = input_api.time.time()
|
||||||
|
proc = subprocess2.Popen(
|
||||||
|
cmd,
|
||||||
|
stderr=subprocess2.PIPE,
|
||||||
|
stdout=subprocess2.PIPE,
|
||||||
|
universal_newlines=True)
|
||||||
|
|
||||||
|
stdout, _ = proc.communicate()
|
||||||
|
duration = input_api.time.time() - start
|
||||||
|
|
||||||
|
if not re.match(r"^Revert",
|
||||||
|
stdout) and (len(stdout) - 1) > _GIT_COMMIT_SUBJECT_LENGTH:
|
||||||
|
failure_msg = (
|
||||||
|
"The commit subject: %s is too long (%d chars)\n"
|
||||||
|
"Try to keep this to 50 or less (up to 65 is permitted for "
|
||||||
|
"non-reverts).\n"
|
||||||
|
"https://www.git-scm.com/book/en/v2/Distributed-Git-Contributing-to-a-"
|
||||||
|
"Project#_commit_guidelines") % (stdout, len(stdout) - 1)
|
||||||
|
return output_api.PresubmitError("%s\n (%4.2fs) failed\n%s" %
|
||||||
|
(name, duration, failure_msg))
|
||||||
|
|
||||||
|
return output_api.PresubmitResult("%s\n (%4.2fs) success" % (name, duration))
|
||||||
|
|
||||||
|
|
||||||
def _GetFilesToSkip(input_api):
|
def _GetFilesToSkip(input_api):
|
||||||
return list(input_api.DEFAULT_FILES_TO_SKIP) + [
|
return list(input_api.DEFAULT_FILES_TO_SKIP) + [
|
||||||
r"swig/.*\.py$",
|
r"swig/.*\.py$",
|
||||||
@ -123,6 +153,7 @@ def _CommonChecks(input_api, output_api):
|
|||||||
results.extend(
|
results.extend(
|
||||||
input_api.canned_checks.CheckChangeHasNoStrayWhitespace(
|
input_api.canned_checks.CheckChangeHasNoStrayWhitespace(
|
||||||
input_api, output_api))
|
input_api, output_api))
|
||||||
|
results.append(_CheckCommitSubjectLength(input_api, output_api))
|
||||||
|
|
||||||
source_file_filter = lambda x: input_api.FilterSourceFile(
|
source_file_filter = lambda x: input_api.FilterSourceFile(
|
||||||
x, files_to_skip=_GetFilesToSkip(input_api))
|
x, files_to_skip=_GetFilesToSkip(input_api))
|
||||||
|
16
README
16
README
@ -4,7 +4,7 @@
|
|||||||
\__\__/\____/\_____/__/ ____ ___
|
\__\__/\____/\_____/__/ ____ ___
|
||||||
/ _/ / \ \ / _ \/ _/
|
/ _/ / \ \ / _ \/ _/
|
||||||
/ \_/ / / \ \ __/ \__
|
/ \_/ / / \ \ __/ \__
|
||||||
\____/____/\_____/_____/____/v1.2.1
|
\____/____/\_____/_____/____/v1.2.2
|
||||||
|
|
||||||
Description:
|
Description:
|
||||||
============
|
============
|
||||||
@ -13,13 +13,13 @@ WebP codec: library to encode and decode images in WebP format. This package
|
|||||||
contains the library that can be used in other programs to add WebP support,
|
contains the library that can be used in other programs to add WebP support,
|
||||||
as well as the command line tools 'cwebp' and 'dwebp'.
|
as well as the command line tools 'cwebp' and 'dwebp'.
|
||||||
|
|
||||||
See http://developers.google.com/speed/webp
|
See https://developers.google.com/speed/webp
|
||||||
|
|
||||||
The latest source tree is available at
|
The latest source tree is available at
|
||||||
https://chromium.googlesource.com/webm/libwebp
|
https://chromium.googlesource.com/webm/libwebp
|
||||||
|
|
||||||
It is released under the same license as the WebM project.
|
It is released under the same license as the WebM project.
|
||||||
See http://www.webmproject.org/license/software/ or the
|
See https://www.webmproject.org/license/software/ or the
|
||||||
"COPYING" file for details. An additional intellectual
|
"COPYING" file for details. An additional intellectual
|
||||||
property rights grant can be found in the file PATENTS.
|
property rights grant can be found in the file PATENTS.
|
||||||
|
|
||||||
@ -436,8 +436,8 @@ Prerequisites:
|
|||||||
|
|
||||||
2) (Optional) qcms (Quick Color Management System)
|
2) (Optional) qcms (Quick Color Management System)
|
||||||
i. Download qcms from Mozilla / Chromium:
|
i. Download qcms from Mozilla / Chromium:
|
||||||
http://hg.mozilla.org/mozilla-central/file/0e7639e3bdfb/gfx/qcms
|
https://hg.mozilla.org/mozilla-central/file/0e7639e3bdfb/gfx/qcms
|
||||||
http://src.chromium.org/viewvc/chrome/trunk/src/third_party/qcms
|
https://source.chromium.org/chromium/chromium/src/+/main:third_party/qcms/;drc=d4a2f8e1ed461d8fc05ed88d1ae2dc94c9773825
|
||||||
ii. Build and archive the source files as libqcms.a / qcms.lib
|
ii. Build and archive the source files as libqcms.a / qcms.lib
|
||||||
iii. Update makefile.unix / Makefile.vc
|
iii. Update makefile.unix / Makefile.vc
|
||||||
a) Define WEBP_HAVE_QCMS
|
a) Define WEBP_HAVE_QCMS
|
||||||
@ -456,7 +456,7 @@ modes, etc.
|
|||||||
|
|
||||||
Usage:
|
Usage:
|
||||||
|
|
||||||
img2webp [file-level options] [image files...] [per-frame options...]
|
img2webp [file_options] [[frame_options] frame_file]...
|
||||||
|
|
||||||
File-level options (only used at the start of compression):
|
File-level options (only used at the start of compression):
|
||||||
-min_size ............ minimize size
|
-min_size ............ minimize size
|
||||||
@ -786,10 +786,10 @@ Bugs:
|
|||||||
Please report all bugs to the issue tracker:
|
Please report all bugs to the issue tracker:
|
||||||
https://bugs.chromium.org/p/webp
|
https://bugs.chromium.org/p/webp
|
||||||
Patches welcome! See this page to get started:
|
Patches welcome! See this page to get started:
|
||||||
http://www.webmproject.org/code/contribute/submitting-patches/
|
https://www.webmproject.org/code/contribute/submitting-patches/
|
||||||
|
|
||||||
Discuss:
|
Discuss:
|
||||||
========
|
========
|
||||||
|
|
||||||
Email: webp-discuss@webmproject.org
|
Email: webp-discuss@webmproject.org
|
||||||
Web: http://groups.google.com/a/webmproject.org/group/webp-discuss
|
Web: https://groups.google.com/a/webmproject.org/group/webp-discuss
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
__ __ ____ ____ ____ __ __ _ __ __
|
__ __ ____ ____ ____ __ __ _ __ __
|
||||||
/ \\/ \/ _ \/ _ \/ _ \/ \ \/ \___/_ / _\
|
/ \\/ \/ _ \/ _ \/ _ \/ \ \/ \___/_ / _\
|
||||||
\ / __/ _ \ __/ / / (_/ /__
|
\ / __/ _ \ __/ / / (_/ /__
|
||||||
\__\__/\_____/_____/__/ \__//_/\_____/__/___/v1.2.1
|
\__\__/\_____/_____/__/ \__//_/\_____/__/___/v1.2.2
|
||||||
|
|
||||||
|
|
||||||
Description:
|
Description:
|
||||||
@ -249,10 +249,10 @@ Bugs:
|
|||||||
Please report all bugs to the issue tracker:
|
Please report all bugs to the issue tracker:
|
||||||
https://bugs.chromium.org/p/webp
|
https://bugs.chromium.org/p/webp
|
||||||
Patches welcome! See this page to get started:
|
Patches welcome! See this page to get started:
|
||||||
http://www.webmproject.org/code/contribute/submitting-patches/
|
https://www.webmproject.org/code/contribute/submitting-patches/
|
||||||
|
|
||||||
Discuss:
|
Discuss:
|
||||||
========
|
========
|
||||||
|
|
||||||
Email: webp-discuss@webmproject.org
|
Email: webp-discuss@webmproject.org
|
||||||
Web: http://groups.google.com/a/webmproject.org/group/webp-discuss
|
Web: https://groups.google.com/a/webmproject.org/group/webp-discuss
|
||||||
|
@ -108,9 +108,6 @@
|
|||||||
/* Set to 1 if JPEG library is installed */
|
/* Set to 1 if JPEG library is installed */
|
||||||
#cmakedefine WEBP_HAVE_JPEG 1
|
#cmakedefine WEBP_HAVE_JPEG 1
|
||||||
|
|
||||||
/* Set to 1 if Wasm SIMD is supported */
|
|
||||||
#cmakedefine WEBP_HAVE_WASM_SIMD
|
|
||||||
|
|
||||||
/* Set to 1 if NEON is supported */
|
/* Set to 1 if NEON is supported */
|
||||||
#cmakedefine WEBP_HAVE_NEON
|
#cmakedefine WEBP_HAVE_NEON
|
||||||
|
|
||||||
|
@ -36,9 +36,9 @@ function(webp_check_compiler_flag WEBP_SIMD_FLAG ENABLE_SIMD)
|
|||||||
endfunction()
|
endfunction()
|
||||||
|
|
||||||
# those are included in the names of WEBP_USE_* in c++ code.
|
# those are included in the names of WEBP_USE_* in c++ code.
|
||||||
set(WEBP_SIMD_FLAGS "WASM_SIMD;SSE41;SSE2;MIPS32;MIPS_DSP_R2;NEON;MSA")
|
set(WEBP_SIMD_FLAGS "SSE41;SSE2;MIPS32;MIPS_DSP_R2;NEON;MSA")
|
||||||
set(WEBP_SIMD_FILE_EXTENSIONS
|
set(WEBP_SIMD_FILE_EXTENSIONS
|
||||||
"_wasm.c;_sse41.c;_sse2.c;_mips32.c;_mips_dsp_r2.c;_neon.c;_msa.c")
|
"_sse41.c;_sse2.c;_mips32.c;_mips_dsp_r2.c;_neon.c;_msa.c")
|
||||||
if(MSVC AND CMAKE_C_COMPILER_ID STREQUAL "MSVC")
|
if(MSVC AND CMAKE_C_COMPILER_ID STREQUAL "MSVC")
|
||||||
# With at least Visual Studio 12 (2013)+ /arch is not necessary to build SSE2
|
# With at least Visual Studio 12 (2013)+ /arch is not necessary to build SSE2
|
||||||
# or SSE4 code unless a lesser /arch is forced. MSVC does not have a SSE4
|
# or SSE4 code unless a lesser /arch is forced. MSVC does not have a SSE4
|
||||||
@ -53,9 +53,9 @@ if(MSVC AND CMAKE_C_COMPILER_ID STREQUAL "MSVC")
|
|||||||
set(SIMD_DISABLE_FLAGS)
|
set(SIMD_DISABLE_FLAGS)
|
||||||
else()
|
else()
|
||||||
set(SIMD_ENABLE_FLAGS
|
set(SIMD_ENABLE_FLAGS
|
||||||
"-msimd128;-msse4.1;-msse2;-mips32;-mdspr2;-mfpu=neon;-mmsa")
|
"-msse4.1;-msse2;-mips32;-mdspr2;-mfpu=neon;-mmsa")
|
||||||
set(SIMD_DISABLE_FLAGS
|
set(SIMD_DISABLE_FLAGS
|
||||||
"-mno-simd128;-mno-sse4.1;-mno-sse2;;-mno-dspr2;;-mno-msa")
|
"-mno-sse4.1;-mno-sse2;;-mno-dspr2;;-mno-msa")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(WEBP_SIMD_FILES_TO_NOT_INCLUDE)
|
set(WEBP_SIMD_FILES_TO_NOT_INCLUDE)
|
||||||
@ -77,12 +77,7 @@ math(EXPR WEBP_SIMD_FLAGS_RANGE "${WEBP_SIMD_FLAGS_LENGTH} - 1")
|
|||||||
foreach(I_SIMD RANGE ${WEBP_SIMD_FLAGS_RANGE})
|
foreach(I_SIMD RANGE ${WEBP_SIMD_FLAGS_RANGE})
|
||||||
# With Emscripten 2.0.9 -msimd128 -mfpu=neon will enable NEON, but the
|
# With Emscripten 2.0.9 -msimd128 -mfpu=neon will enable NEON, but the
|
||||||
# source will fail to compile.
|
# source will fail to compile.
|
||||||
if(EMSCRIPTEN AND ${I_SIMD} GREATER_EQUAL 5)
|
if(EMSCRIPTEN AND ${I_SIMD} GREATER_EQUAL 2)
|
||||||
break()
|
|
||||||
endif()
|
|
||||||
# Emscripten supports SSE via compat headers, if WEBP_ENABLED_WASM_SIMD is
|
|
||||||
# specified skip testing those (because it will succeed).
|
|
||||||
if (EMSCRIPTEN AND ${I_SIMD} GREATER_EQUAL 1 AND ${WEBP_ENABLE_WASM_SIMD})
|
|
||||||
break()
|
break()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
@ -96,7 +91,6 @@ foreach(I_SIMD RANGE ${WEBP_SIMD_FLAGS_RANGE})
|
|||||||
webp_check_compiler_flag(${WEBP_SIMD_FLAG} ${WEBP_ENABLE_SIMD})
|
webp_check_compiler_flag(${WEBP_SIMD_FLAG} ${WEBP_ENABLE_SIMD})
|
||||||
if(NOT WEBP_HAVE_${WEBP_SIMD_FLAG})
|
if(NOT WEBP_HAVE_${WEBP_SIMD_FLAG})
|
||||||
list(GET SIMD_ENABLE_FLAGS ${I_SIMD} SIMD_COMPILE_FLAG)
|
list(GET SIMD_ENABLE_FLAGS ${I_SIMD} SIMD_COMPILE_FLAG)
|
||||||
# This enables using Emscripten's SSE compatibility headers.
|
|
||||||
if(EMSCRIPTEN)
|
if(EMSCRIPTEN)
|
||||||
set(SIMD_COMPILE_FLAG "-msimd128 ${SIMD_COMPILE_FLAG}")
|
set(SIMD_COMPILE_FLAG "-msimd128 ${SIMD_COMPILE_FLAG}")
|
||||||
endif()
|
endif()
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
AC_INIT([libwebp], [1.2.1],
|
AC_INIT([libwebp], [1.2.2],
|
||||||
[https://bugs.chromium.org/p/webp],,
|
[https://bugs.chromium.org/p/webp],,
|
||||||
[http://developers.google.com/speed/webp])
|
[https://developers.google.com/speed/webp])
|
||||||
AC_CANONICAL_HOST
|
AC_CANONICAL_HOST
|
||||||
AC_PREREQ([2.60])
|
AC_PREREQ([2.60])
|
||||||
AM_INIT_AUTOMAKE([-Wall foreign subdir-objects])
|
AM_INIT_AUTOMAKE([-Wall foreign subdir-objects])
|
||||||
|
@ -6,8 +6,8 @@ HTML generation requires kramdown [1], easily installed as a
|
|||||||
rubygem [2]. Rubygems installation should satisfy dependencies
|
rubygem [2]. Rubygems installation should satisfy dependencies
|
||||||
automatically.
|
automatically.
|
||||||
|
|
||||||
[1]: http://kramdown.rubyforge.org/
|
[1]: https://kramdown.gettalong.org/
|
||||||
[2]: http://rubygems.org/
|
[2]: https://rubygems.org/
|
||||||
|
|
||||||
HTML generation can then be done from the project root:
|
HTML generation can then be done from the project root:
|
||||||
|
|
||||||
@ -26,4 +26,4 @@ $ kramdown doc/webp-lossless-bitstream-spec.txt --template \
|
|||||||
|
|
||||||
Optimally, use kramdown 0.13.7 or newer if syntax highlighting desired.
|
Optimally, use kramdown 0.13.7 or newer if syntax highlighting desired.
|
||||||
|
|
||||||
[3]: http://coderay.rubychan.de/
|
[3]: https://github.com/rubychan/coderay
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
Although you may be viewing an alternate representation, this document
|
Although you may be viewing an alternate representation, this document
|
||||||
is sourced in Markdown, a light-duty markup scheme, and is optimized for
|
is sourced in Markdown, a light-duty markup scheme, and is optimized for
|
||||||
the [kramdown](http://kramdown.rubyforge.org/) transformer.
|
the [kramdown](https://kramdown.gettalong.org/) transformer.
|
||||||
|
|
||||||
See the accompanying README. External link targets are referenced at the
|
See the accompanying README. External link targets are referenced at the
|
||||||
end of this file.
|
end of this file.
|
||||||
@ -811,9 +811,9 @@ RIFF/WEBP
|
|||||||
+- EXIF (metadata)
|
+- EXIF (metadata)
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
[vp8spec]: http://tools.ietf.org/html/rfc6386
|
[vp8spec]: https://datatracker.ietf.org/doc/html/rfc6386
|
||||||
[webpllspec]: https://chromium.googlesource.com/webm/libwebp/+/HEAD/doc/webp-lossless-bitstream-spec.txt
|
[webpllspec]: https://chromium.googlesource.com/webm/libwebp/+/HEAD/doc/webp-lossless-bitstream-spec.txt
|
||||||
[iccspec]: http://www.color.org/icc_specs2.xalter
|
[iccspec]: https://www.color.org/icc_specs2.xalter
|
||||||
[metadata]: http://www.metadataworkinggroup.org/pdf/mwg_guidance.pdf
|
[metadata]: https://web.archive.org/web/20180919181934/http://www.metadataworkinggroup.org/pdf/mwg_guidance.pdf
|
||||||
[rfc 1166]: http://tools.ietf.org/html/rfc1166
|
[rfc 1166]: https://datatracker.ietf.org/doc/html/rfc1166
|
||||||
[rfc 2119]: http://tools.ietf.org/html/rfc2119
|
[rfc 2119]: https://datatracker.ietf.org/doc/html/rfc2119
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
Although you may be viewing an alternate representation, this document
|
Although you may be viewing an alternate representation, this document
|
||||||
is sourced in Markdown, a light-duty markup scheme, and is optimized for
|
is sourced in Markdown, a light-duty markup scheme, and is optimized for
|
||||||
the [kramdown](http://kramdown.rubyforge.org/) transformer.
|
the [kramdown](https://kramdown.gettalong.org/) transformer.
|
||||||
|
|
||||||
See the accompanying README. External link targets are referenced at the
|
See the accompanying README. External link targets are referenced at the
|
||||||
end of this file.
|
end of this file.
|
||||||
@ -1087,4 +1087,4 @@ A possible example sequence:
|
|||||||
<lz77-coded image>
|
<lz77-coded image>
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
[canonical_huff]: http://en.wikipedia.org/wiki/Canonical_Huffman_code
|
[canonical_huff]: https://en.wikipedia.org/wiki/Canonical_Huffman_code
|
||||||
|
@ -35,8 +35,7 @@
|
|||||||
|
|
||||||
static void Help(void) {
|
static void Help(void) {
|
||||||
printf("Usage:\n\n");
|
printf("Usage:\n\n");
|
||||||
printf(" img2webp [file-level options] [image files...] "
|
printf(" img2webp [file_options] [[frame_options] frame_file]...\n");
|
||||||
"[per-frame options...]\n");
|
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
|
||||||
printf("File-level options (only used at the start of compression):\n");
|
printf("File-level options (only used at the start of compression):\n");
|
||||||
|
@ -125,16 +125,16 @@ static void WebPInfoInit(WebPInfo* const webp_info) {
|
|||||||
memset(webp_info, 0, sizeof(*webp_info));
|
memset(webp_info, 0, sizeof(*webp_info));
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char kWebPChunkTags[CHUNK_TYPES][4] = {
|
static const uint32_t kWebPChunkTags[CHUNK_TYPES] = {
|
||||||
{ 'V', 'P', '8', ' ' },
|
MKFOURCC('V', 'P', '8', ' '),
|
||||||
{ 'V', 'P', '8', 'L' },
|
MKFOURCC('V', 'P', '8', 'L'),
|
||||||
{ 'V', 'P', '8', 'X' },
|
MKFOURCC('V', 'P', '8', 'X'),
|
||||||
{ 'A', 'L', 'P', 'H' },
|
MKFOURCC('A', 'L', 'P', 'H'),
|
||||||
{ 'A', 'N', 'I', 'M' },
|
MKFOURCC('A', 'N', 'I', 'M'),
|
||||||
{ 'A', 'N', 'M', 'F' },
|
MKFOURCC('A', 'N', 'M', 'F'),
|
||||||
{ 'I', 'C', 'C', 'P' },
|
MKFOURCC('I', 'C', 'C', 'P'),
|
||||||
{ 'E', 'X', 'I', 'F' },
|
MKFOURCC('E', 'X', 'I', 'F'),
|
||||||
{ 'X', 'M', 'P', ' ' },
|
MKFOURCC('X', 'M', 'P', ' '),
|
||||||
};
|
};
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
@ -644,7 +644,7 @@ static WebPInfoStatus ParseChunk(const WebPInfo* const webp_info,
|
|||||||
return WEBP_INFO_TRUNCATED_DATA;
|
return WEBP_INFO_TRUNCATED_DATA;
|
||||||
}
|
}
|
||||||
for (i = 0; i < CHUNK_TYPES; ++i) {
|
for (i = 0; i < CHUNK_TYPES; ++i) {
|
||||||
if (!memcmp(kWebPChunkTags[i], &fourcc, TAG_SIZE)) break;
|
if (kWebPChunkTags[i] == fourcc) break;
|
||||||
}
|
}
|
||||||
chunk_data->offset_ = chunk_start_offset;
|
chunk_data->offset_ = chunk_start_offset;
|
||||||
chunk_data->size_ = chunk_size;
|
chunk_data->size_ = chunk_size;
|
||||||
@ -939,7 +939,13 @@ static WebPInfoStatus ProcessChunk(const ChunkData* const chunk_data,
|
|||||||
LOG_WARN(error_message);
|
LOG_WARN(error_message);
|
||||||
} else {
|
} else {
|
||||||
if (!webp_info->quiet_) {
|
if (!webp_info->quiet_) {
|
||||||
const char* tag = kWebPChunkTags[chunk_data->id_];
|
char tag[4];
|
||||||
|
uint32_t fourcc = kWebPChunkTags[chunk_data->id_];
|
||||||
|
#ifdef WORDS_BIGENDIAN
|
||||||
|
fourcc = (fourcc >> 24) | ((fourcc >> 8) & 0xff00) |
|
||||||
|
((fourcc << 8) & 0xff0000) | (fourcc << 24);
|
||||||
|
#endif
|
||||||
|
memcpy(tag, &fourcc, sizeof(tag));
|
||||||
printf("Chunk %c%c%c%c at offset %6d, length %6d\n",
|
printf("Chunk %c%c%c%c at offset %6d, length %6d\n",
|
||||||
tag[0], tag[1], tag[2], tag[3], (int)chunk_data->offset_,
|
tag[0], tag[1], tag[2], tag[3], (int)chunk_data->offset_,
|
||||||
(int)chunk_data->size_);
|
(int)chunk_data->size_);
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
|
|
||||||
#define XTRA_MAJ_VERSION 1
|
#define XTRA_MAJ_VERSION 1
|
||||||
#define XTRA_MIN_VERSION 2
|
#define XTRA_MIN_VERSION 2
|
||||||
#define XTRA_REV_VERSION 1
|
#define XTRA_REV_VERSION 2
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -280,7 +280,7 @@ int WebPWrite16bAsPGM(FILE* fout, const WebPDecBuffer* const buffer) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// BMP
|
// BMP (see https://en.wikipedia.org/wiki/BMP_file_format#Pixel_storage)
|
||||||
|
|
||||||
static void PutLE16(uint8_t* const dst, uint32_t value) {
|
static void PutLE16(uint8_t* const dst, uint32_t value) {
|
||||||
dst[0] = (value >> 0) & 0xff;
|
dst[0] = (value >> 0) & 0xff;
|
||||||
@ -293,8 +293,11 @@ static void PutLE32(uint8_t* const dst, uint32_t value) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#define BMP_HEADER_SIZE 54
|
#define BMP_HEADER_SIZE 54
|
||||||
|
#define BMP_HEADER_ALPHA_EXTRA_SIZE 16 // for alpha info
|
||||||
int WebPWriteBMP(FILE* fout, const WebPDecBuffer* const buffer) {
|
int WebPWriteBMP(FILE* fout, const WebPDecBuffer* const buffer) {
|
||||||
const int has_alpha = WebPIsAlphaMode(buffer->colorspace);
|
const int has_alpha = WebPIsAlphaMode(buffer->colorspace);
|
||||||
|
const int header_size =
|
||||||
|
BMP_HEADER_SIZE + (has_alpha ? BMP_HEADER_ALPHA_EXTRA_SIZE : 0);
|
||||||
const uint32_t width = buffer->width;
|
const uint32_t width = buffer->width;
|
||||||
const uint32_t height = buffer->height;
|
const uint32_t height = buffer->height;
|
||||||
const uint8_t* rgba = buffer->u.RGBA.rgba;
|
const uint8_t* rgba = buffer->u.RGBA.rgba;
|
||||||
@ -303,8 +306,9 @@ int WebPWriteBMP(FILE* fout, const WebPDecBuffer* const buffer) {
|
|||||||
uint32_t y;
|
uint32_t y;
|
||||||
const uint32_t line_size = bytes_per_px * width;
|
const uint32_t line_size = bytes_per_px * width;
|
||||||
const uint32_t bmp_stride = (line_size + 3) & ~3; // pad to 4
|
const uint32_t bmp_stride = (line_size + 3) & ~3; // pad to 4
|
||||||
const uint32_t total_size = bmp_stride * height + BMP_HEADER_SIZE;
|
const uint32_t image_size = bmp_stride * height;
|
||||||
uint8_t bmp_header[BMP_HEADER_SIZE] = { 0 };
|
const uint32_t total_size = image_size + header_size;
|
||||||
|
uint8_t bmp_header[BMP_HEADER_SIZE + BMP_HEADER_ALPHA_EXTRA_SIZE] = { 0 };
|
||||||
|
|
||||||
if (fout == NULL || buffer == NULL || rgba == NULL) return 0;
|
if (fout == NULL || buffer == NULL || rgba == NULL) return 0;
|
||||||
|
|
||||||
@ -312,30 +316,37 @@ int WebPWriteBMP(FILE* fout, const WebPDecBuffer* const buffer) {
|
|||||||
PutLE16(bmp_header + 0, 0x4d42); // signature 'BM'
|
PutLE16(bmp_header + 0, 0x4d42); // signature 'BM'
|
||||||
PutLE32(bmp_header + 2, total_size); // size including header
|
PutLE32(bmp_header + 2, total_size); // size including header
|
||||||
PutLE32(bmp_header + 6, 0); // reserved
|
PutLE32(bmp_header + 6, 0); // reserved
|
||||||
PutLE32(bmp_header + 10, BMP_HEADER_SIZE); // offset to pixel array
|
PutLE32(bmp_header + 10, header_size); // offset to pixel array
|
||||||
// bitmap info header
|
// bitmap info header
|
||||||
PutLE32(bmp_header + 14, 40); // DIB header size
|
PutLE32(bmp_header + 14, header_size - 14); // DIB header size
|
||||||
PutLE32(bmp_header + 18, width); // dimensions
|
PutLE32(bmp_header + 18, width); // dimensions
|
||||||
PutLE32(bmp_header + 22, -(int)height); // vertical flip!
|
PutLE32(bmp_header + 22, height); // no vertical flip
|
||||||
PutLE16(bmp_header + 26, 1); // number of planes
|
PutLE16(bmp_header + 26, 1); // number of planes
|
||||||
PutLE16(bmp_header + 28, bytes_per_px * 8); // bits per pixel
|
PutLE16(bmp_header + 28, bytes_per_px * 8); // bits per pixel
|
||||||
PutLE32(bmp_header + 30, 0); // no compression (BI_RGB)
|
PutLE32(bmp_header + 30, has_alpha ? 3 : 0); // BI_BITFIELDS or BI_RGB
|
||||||
PutLE32(bmp_header + 34, 0); // image size (placeholder)
|
PutLE32(bmp_header + 34, image_size);
|
||||||
PutLE32(bmp_header + 38, 2400); // x pixels/meter
|
PutLE32(bmp_header + 38, 2400); // x pixels/meter
|
||||||
PutLE32(bmp_header + 42, 2400); // y pixels/meter
|
PutLE32(bmp_header + 42, 2400); // y pixels/meter
|
||||||
PutLE32(bmp_header + 46, 0); // number of palette colors
|
PutLE32(bmp_header + 46, 0); // number of palette colors
|
||||||
PutLE32(bmp_header + 50, 0); // important color count
|
PutLE32(bmp_header + 50, 0); // important color count
|
||||||
|
if (has_alpha) { // BITMAPV3INFOHEADER complement
|
||||||
|
PutLE32(bmp_header + 54, 0x00ff0000); // red mask
|
||||||
|
PutLE32(bmp_header + 58, 0x0000ff00); // green mask
|
||||||
|
PutLE32(bmp_header + 62, 0x000000ff); // blue mask
|
||||||
|
PutLE32(bmp_header + 66, 0xff000000); // alpha mask
|
||||||
|
}
|
||||||
|
|
||||||
// TODO(skal): color profile
|
// TODO(skal): color profile
|
||||||
|
|
||||||
// write header
|
// write header
|
||||||
if (fwrite(bmp_header, sizeof(bmp_header), 1, fout) != 1) {
|
if (fwrite(bmp_header, header_size, 1, fout) != 1) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// write pixel array
|
// write pixel array, bottom to top
|
||||||
for (y = 0; y < height; ++y) {
|
for (y = 0; y < height; ++y) {
|
||||||
if (fwrite(rgba, line_size, 1, fout) != 1) {
|
const uint8_t* const src = &rgba[(uint64_t)(height - 1 - y) * stride];
|
||||||
|
if (fwrite(src, line_size, 1, fout) != 1) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
// write padding zeroes
|
// write padding zeroes
|
||||||
@ -345,11 +356,11 @@ int WebPWriteBMP(FILE* fout, const WebPDecBuffer* const buffer) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
rgba += stride;
|
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
#undef BMP_HEADER_SIZE
|
#undef BMP_HEADER_SIZE
|
||||||
|
#undef BMP_HEADER_ALPHA_EXTRA_SIZE
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// TIFF
|
// TIFF
|
||||||
|
@ -79,7 +79,7 @@ int WebPWriteTIFF(FILE* fout, const struct WebPDecBuffer* const buffer);
|
|||||||
int WebPWriteAlphaPlane(FILE* fout, const struct WebPDecBuffer* const buffer);
|
int WebPWriteAlphaPlane(FILE* fout, const struct WebPDecBuffer* const buffer);
|
||||||
|
|
||||||
// Save as YUV samples as PGM format (using IMC4 layout).
|
// Save as YUV samples as PGM format (using IMC4 layout).
|
||||||
// See: http://www.fourcc.org/yuv.php#IMC4.
|
// See: https://www.fourcc.org/yuv.php#IMC4.
|
||||||
// (very convenient format for viewing the samples, esp. for odd dimensions).
|
// (very convenient format for viewing the samples, esp. for odd dimensions).
|
||||||
int WebPWritePGM(FILE* fout, const struct WebPDecBuffer* const buffer);
|
int WebPWritePGM(FILE* fout, const struct WebPDecBuffer* const buffer);
|
||||||
|
|
||||||
|
@ -336,7 +336,11 @@ int ReadJPEG(const uint8_t* const data, size_t data_size,
|
|||||||
pic->width = width;
|
pic->width = width;
|
||||||
pic->height = height;
|
pic->height = height;
|
||||||
ok = WebPPictureImportRGB(pic, rgb, (int)stride);
|
ok = WebPPictureImportRGB(pic, rgb, (int)stride);
|
||||||
if (!ok) goto Error;
|
if (!ok) {
|
||||||
|
pic->width = 0; // WebPPictureImportRGB() barely touches 'pic' on failure.
|
||||||
|
pic->height = 0; // Just reset dimensions but keep any 'custom_ptr' etc.
|
||||||
|
MetadataFree(metadata); // In case the caller forgets to free it on error.
|
||||||
|
}
|
||||||
|
|
||||||
End:
|
End:
|
||||||
free(rgb);
|
free(rgb);
|
||||||
|
@ -133,7 +133,7 @@ static const struct {
|
|||||||
MetadataPayload* const payload);
|
MetadataPayload* const payload);
|
||||||
size_t storage_offset;
|
size_t storage_offset;
|
||||||
} kPNGMetadataMap[] = {
|
} kPNGMetadataMap[] = {
|
||||||
// http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/PNG.html#TextualData
|
// https://exiftool.org/TagNames/PNG.html#TextualData
|
||||||
// See also: ExifTool on CPAN.
|
// See also: ExifTool on CPAN.
|
||||||
{ "Raw profile type exif", ProcessRawProfile, METADATA_OFFSET(exif) },
|
{ "Raw profile type exif", ProcessRawProfile, METADATA_OFFSET(exif) },
|
||||||
{ "Raw profile type xmp", ProcessRawProfile, METADATA_OFFSET(xmp) },
|
{ "Raw profile type xmp", ProcessRawProfile, METADATA_OFFSET(xmp) },
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
# (the previous build will be erased if it exists).
|
# (the previous build will be erased if it exists).
|
||||||
#
|
#
|
||||||
# This script is inspired by the build script written by Carson McDonald.
|
# This script is inspired by the build script written by Carson McDonald.
|
||||||
# (http://www.ioncannon.net/programming/1483/using-webp-to-reduce-native-ios-app-size/).
|
# (https://www.ioncannon.net/programming/1483/using-webp-to-reduce-native-ios-app-size/).
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
@ -86,7 +86,7 @@ if [[ ! -e ${SRCDIR}/configure ]]; then
|
|||||||
Error creating configure script!
|
Error creating configure script!
|
||||||
This script requires the autoconf/automake and libtool to build. MacPorts can
|
This script requires the autoconf/automake and libtool to build. MacPorts can
|
||||||
be used to obtain these:
|
be used to obtain these:
|
||||||
http://www.macports.org/install.php
|
https://www.macports.org/install.php
|
||||||
EOF
|
EOF
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
@ -47,7 +47,7 @@ else
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
# To install libraries on Mac OS X:
|
# To install libraries on Mac OS X:
|
||||||
# 1. Install MacPorts (http://www.macports.org/install.php)
|
# 1. Install MacPorts (https://www.macports.org/install.php)
|
||||||
# 2. Run "sudo port install jpeg"
|
# 2. Run "sudo port install jpeg"
|
||||||
# 3. Run "sudo port install libpng"
|
# 3. Run "sudo port install libpng"
|
||||||
# 4. Run "sudo port install tiff"
|
# 4. Run "sudo port install tiff"
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
.\" Hey, EMACS: -*- nroff -*-
|
.\" Hey, EMACS: -*- nroff -*-
|
||||||
.TH CWEBP 1 "November 19, 2020"
|
.TH CWEBP 1 "November 17, 2021"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
cwebp \- compress an image file to a WebP file
|
cwebp \- compress an image file to a WebP file
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
@ -222,7 +222,7 @@ Compute and report average PSNR (Peak\-Signal\-To\-Noise ratio).
|
|||||||
.TP
|
.TP
|
||||||
.B \-print_ssim
|
.B \-print_ssim
|
||||||
Compute and report average SSIM (structural similarity
|
Compute and report average SSIM (structural similarity
|
||||||
metric, see http://en.wikipedia.org/wiki/SSIM for additional details).
|
metric, see https://en.wikipedia.org/wiki/SSIM for additional details).
|
||||||
.TP
|
.TP
|
||||||
.B \-print_lsim
|
.B \-print_lsim
|
||||||
Compute and report local similarity metric (sum of lowest error amongst the
|
Compute and report local similarity metric (sum of lowest error amongst the
|
||||||
@ -298,7 +298,7 @@ Please report all bugs to the issue tracker:
|
|||||||
https://bugs.chromium.org/p/webp
|
https://bugs.chromium.org/p/webp
|
||||||
.br
|
.br
|
||||||
Patches welcome! See this page to get started:
|
Patches welcome! See this page to get started:
|
||||||
http://www.webmproject.org/code/contribute/submitting\-patches/
|
https://www.webmproject.org/code/contribute/submitting\-patches/
|
||||||
|
|
||||||
.SH EXAMPLES
|
.SH EXAMPLES
|
||||||
cwebp \-q 50 -lossless picture.png \-o picture_lossless.webp
|
cwebp \-q 50 -lossless picture.png \-o picture_lossless.webp
|
||||||
@ -322,5 +322,5 @@ for the Debian project (and may be used by others).
|
|||||||
.BR dwebp (1),
|
.BR dwebp (1),
|
||||||
.BR gif2webp (1)
|
.BR gif2webp (1)
|
||||||
.br
|
.br
|
||||||
Please refer to http://developers.google.com/speed/webp/ for additional
|
Please refer to https://developers.google.com/speed/webp/ for additional
|
||||||
information.
|
information.
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
.\" Hey, EMACS: -*- nroff -*-
|
.\" Hey, EMACS: -*- nroff -*-
|
||||||
.TH DWEBP 1 "November 19, 2020"
|
.TH DWEBP 1 "November 17, 2021"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
dwebp \- decompress a WebP file to an image file
|
dwebp \- decompress a WebP file to an image file
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
@ -113,7 +113,7 @@ Please report all bugs to the issue tracker:
|
|||||||
https://bugs.chromium.org/p/webp
|
https://bugs.chromium.org/p/webp
|
||||||
.br
|
.br
|
||||||
Patches welcome! See this page to get started:
|
Patches welcome! See this page to get started:
|
||||||
http://www.webmproject.org/code/contribute/submitting-patches/
|
https://www.webmproject.org/code/contribute/submitting\-patches/
|
||||||
|
|
||||||
.SH EXAMPLES
|
.SH EXAMPLES
|
||||||
dwebp picture.webp \-o output.png
|
dwebp picture.webp \-o output.png
|
||||||
@ -138,7 +138,7 @@ for the Debian project (and may be used by others).
|
|||||||
.BR gif2webp (1),
|
.BR gif2webp (1),
|
||||||
.BR webpmux (1)
|
.BR webpmux (1)
|
||||||
.br
|
.br
|
||||||
Please refer to http://developers.google.com/speed/webp/ for additional
|
Please refer to https://developers.google.com/speed/webp/ for additional
|
||||||
information.
|
information.
|
||||||
.SS Output file format details
|
.SS Output file format details
|
||||||
PAM: http://netpbm.sourceforge.net/doc/pam.html
|
PAM: http://netpbm.sourceforge.net/doc/pam.html
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
.\" Hey, EMACS: -*- nroff -*-
|
.\" Hey, EMACS: -*- nroff -*-
|
||||||
.TH GIF2WEBP 1 "May 1, 2020"
|
.TH GIF2WEBP 1 "November 17, 2021"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
gif2webp \- Convert a GIF image to WebP
|
gif2webp \- Convert a GIF image to WebP
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
@ -131,7 +131,7 @@ Please report all bugs to the issue tracker:
|
|||||||
https://bugs.chromium.org/p/webp
|
https://bugs.chromium.org/p/webp
|
||||||
.br
|
.br
|
||||||
Patches welcome! See this page to get started:
|
Patches welcome! See this page to get started:
|
||||||
http://www.webmproject.org/code/contribute/submitting-patches/
|
https://www.webmproject.org/code/contribute/submitting\-patches/
|
||||||
|
|
||||||
.SH EXAMPLES
|
.SH EXAMPLES
|
||||||
gif2webp picture.gif \-o picture.webp
|
gif2webp picture.gif \-o picture.webp
|
||||||
@ -160,5 +160,5 @@ Debian project (and may be used by others).
|
|||||||
.BR dwebp (1),
|
.BR dwebp (1),
|
||||||
.BR webpmux (1)
|
.BR webpmux (1)
|
||||||
.br
|
.br
|
||||||
Please refer to http://developers.google.com/speed/webp/ for additional
|
Please refer to https://developers.google.com/speed/webp/ for additional
|
||||||
information.
|
information.
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
.\" Hey, EMACS: -*- nroff -*-
|
.\" Hey, EMACS: -*- nroff -*-
|
||||||
.TH IMG2WEBP 1 "May 1, 2020"
|
.TH IMG2WEBP 1 "January 5, 2022"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
img2webp \- create animated WebP file from a sequence of input images.
|
img2webp \- create animated WebP file from a sequence of input images.
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
.B img2webp
|
.B img2webp
|
||||||
[file_level_options] [files] [per_frame_options...]
|
[file_options] [[frame_options] frame_file]...
|
||||||
.br
|
.br
|
||||||
.B img2webp argument_file_name
|
.B img2webp argument_file_name
|
||||||
.br
|
.br
|
||||||
@ -86,7 +86,7 @@ Please report all bugs to the issue tracker:
|
|||||||
https://bugs.chromium.org/p/webp
|
https://bugs.chromium.org/p/webp
|
||||||
.br
|
.br
|
||||||
Patches welcome! See this page to get started:
|
Patches welcome! See this page to get started:
|
||||||
http://www.webmproject.org/code/contribute/submitting\-patches/
|
https://www.webmproject.org/code/contribute/submitting\-patches/
|
||||||
|
|
||||||
.SH AUTHORS
|
.SH AUTHORS
|
||||||
\fBimg2webp\fP is a part of libwebp and was written by the WebP team.
|
\fBimg2webp\fP is a part of libwebp and was written by the WebP team.
|
||||||
@ -101,5 +101,5 @@ for the Debian project (and may be used by others).
|
|||||||
.BR webpmux (1),
|
.BR webpmux (1),
|
||||||
.BR gif2webp (1)
|
.BR gif2webp (1)
|
||||||
.br
|
.br
|
||||||
Please refer to http://developers.google.com/speed/webp/ for additional
|
Please refer to https://developers.google.com/speed/webp/ for additional
|
||||||
information.
|
information.
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
.\" Hey, EMACS: -*- nroff -*-
|
.\" Hey, EMACS: -*- nroff -*-
|
||||||
.TH VWEBP 1 "June 5, 2019"
|
.TH VWEBP 1 "November 17, 2021"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
vwebp \- decompress a WebP file and display it in a window
|
vwebp \- decompress a WebP file and display it in a window
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
@ -77,7 +77,7 @@ Please report all bugs to the issue tracker:
|
|||||||
https://bugs.chromium.org/p/webp
|
https://bugs.chromium.org/p/webp
|
||||||
.br
|
.br
|
||||||
Patches welcome! See this page to get started:
|
Patches welcome! See this page to get started:
|
||||||
http://www.webmproject.org/code/contribute/submitting-patches/
|
https://www.webmproject.org/code/contribute/submitting\-patches/
|
||||||
|
|
||||||
.SH EXAMPLES
|
.SH EXAMPLES
|
||||||
vwebp picture.webp
|
vwebp picture.webp
|
||||||
@ -97,5 +97,5 @@ This manual page was written for the Debian project (and may be used by others).
|
|||||||
.SH SEE ALSO
|
.SH SEE ALSO
|
||||||
.BR dwebp (1)
|
.BR dwebp (1)
|
||||||
.br
|
.br
|
||||||
Please refer to http://developers.google.com/speed/webp/ for additional
|
Please refer to https://developers.google.com/speed/webp/ for additional
|
||||||
information.
|
information.
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
.\" Hey, EMACS: -*- nroff -*-
|
.\" Hey, EMACS: -*- nroff -*-
|
||||||
.TH WEBPINFO 1 "November 24, 2017"
|
.TH WEBPINFO 1 "November 17, 2021"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
webpinfo \- print out the chunk level structure of WebP files
|
webpinfo \- print out the chunk level structure of WebP files
|
||||||
along with basic integrity checks.
|
along with basic integrity checks.
|
||||||
@ -52,7 +52,7 @@ Please report all bugs to the issue tracker:
|
|||||||
https://bugs.chromium.org/p/webp
|
https://bugs.chromium.org/p/webp
|
||||||
.br
|
.br
|
||||||
Patches welcome! See this page to get started:
|
Patches welcome! See this page to get started:
|
||||||
http://www.webmproject.org/code/contribute/submitting\-patches/
|
https://www.webmproject.org/code/contribute/submitting\-patches/
|
||||||
|
|
||||||
.SH EXAMPLES
|
.SH EXAMPLES
|
||||||
.br
|
.br
|
||||||
@ -76,5 +76,5 @@ for the Debian project (and may be used by others).
|
|||||||
.SH SEE ALSO
|
.SH SEE ALSO
|
||||||
.BR webpmux (1)
|
.BR webpmux (1)
|
||||||
.br
|
.br
|
||||||
Please refer to http://developers.google.com/speed/webp/ for additional
|
Please refer to https://developers.google.com/speed/webp/ for additional
|
||||||
information.
|
information.
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
.\" Hey, EMACS: -*- nroff -*-
|
.\" Hey, EMACS: -*- nroff -*-
|
||||||
.TH WEBPMUX 1 "November 3, 2021"
|
.TH WEBPMUX 1 "November 17, 2021"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
webpmux \- create animated WebP files from non\-animated WebP images, extract
|
webpmux \- create animated WebP files from non\-animated WebP images, extract
|
||||||
frames from animated WebP images, and manage XMP/EXIF metadata and ICC profile.
|
frames from animated WebP images, and manage XMP/EXIF metadata and ICC profile.
|
||||||
@ -191,7 +191,7 @@ Please report all bugs to the issue tracker:
|
|||||||
https://bugs.chromium.org/p/webp
|
https://bugs.chromium.org/p/webp
|
||||||
.br
|
.br
|
||||||
Patches welcome! See this page to get started:
|
Patches welcome! See this page to get started:
|
||||||
http://www.webmproject.org/code/contribute/submitting\-patches/
|
https://www.webmproject.org/code/contribute/submitting\-patches/
|
||||||
|
|
||||||
.SH EXAMPLES
|
.SH EXAMPLES
|
||||||
.P
|
.P
|
||||||
@ -267,5 +267,5 @@ for the Debian project (and may be used by others).
|
|||||||
.BR dwebp (1),
|
.BR dwebp (1),
|
||||||
.BR gif2webp (1)
|
.BR gif2webp (1)
|
||||||
.br
|
.br
|
||||||
Please refer to http://developers.google.com/speed/webp/ for additional
|
Please refer to https://developers.google.com/speed/webp/ for additional
|
||||||
information.
|
information.
|
||||||
|
@ -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
|
# 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
|
# not have unresolved symbols. Some platforms (Windows among them) require all
|
||||||
# symbols in shared libraries to be resolved at library creation.
|
# symbols in shared libraries to be resolved at library creation.
|
||||||
libwebp_la_LDFLAGS = -no-undefined -version-info 8:2:1
|
libwebp_la_LDFLAGS = -no-undefined -version-info 8:3:1
|
||||||
libwebpincludedir = $(includedir)/webp
|
libwebpincludedir = $(includedir)/webp
|
||||||
pkgconfig_DATA = libwebp.pc
|
pkgconfig_DATA = libwebp.pc
|
||||||
|
|
||||||
@ -48,7 +48,7 @@ if BUILD_LIBWEBPDECODER
|
|||||||
libwebpdecoder_la_LIBADD += dsp/libwebpdspdecode.la
|
libwebpdecoder_la_LIBADD += dsp/libwebpdspdecode.la
|
||||||
libwebpdecoder_la_LIBADD += utils/libwebputilsdecode.la
|
libwebpdecoder_la_LIBADD += utils/libwebputilsdecode.la
|
||||||
|
|
||||||
libwebpdecoder_la_LDFLAGS = -no-undefined -version-info 4:2:1
|
libwebpdecoder_la_LDFLAGS = -no-undefined -version-info 4:3:1
|
||||||
pkgconfig_DATA += libwebpdecoder.pc
|
pkgconfig_DATA += libwebpdecoder.pc
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
@ -403,7 +403,7 @@ static const uint8_t kZigzag[16] = {
|
|||||||
0, 1, 4, 8, 5, 2, 3, 6, 9, 12, 13, 10, 7, 11, 14, 15
|
0, 1, 4, 8, 5, 2, 3, 6, 9, 12, 13, 10, 7, 11, 14, 15
|
||||||
};
|
};
|
||||||
|
|
||||||
// See section 13-2: http://tools.ietf.org/html/rfc6386#section-13.2
|
// See section 13-2: https://datatracker.ietf.org/doc/html/rfc6386#section-13.2
|
||||||
static int GetLargeValue(VP8BitReader* const br, const uint8_t* const p) {
|
static int GetLargeValue(VP8BitReader* const br, const uint8_t* const p) {
|
||||||
int v;
|
int v;
|
||||||
if (!VP8GetBit(br, p[3], "coeffs")) {
|
if (!VP8GetBit(br, p[3], "coeffs")) {
|
||||||
|
@ -32,7 +32,7 @@ extern "C" {
|
|||||||
// version numbers
|
// version numbers
|
||||||
#define DEC_MAJ_VERSION 1
|
#define DEC_MAJ_VERSION 1
|
||||||
#define DEC_MIN_VERSION 2
|
#define DEC_MIN_VERSION 2
|
||||||
#define DEC_REV_VERSION 1
|
#define DEC_REV_VERSION 2
|
||||||
|
|
||||||
// YUV-cache parameters. Cache is 32-bytes wide (= one cacheline).
|
// YUV-cache parameters. Cache is 32-bytes wide (= one cacheline).
|
||||||
// Constraints are: We need to store one 16x16 block of luma samples (y),
|
// Constraints are: We need to store one 16x16 block of luma samples (y),
|
||||||
|
@ -84,7 +84,7 @@ static const uint8_t kCodeToPlane[CODE_TO_PLANE_CODES] = {
|
|||||||
// to 256 (green component values) + 24 (length prefix values)
|
// to 256 (green component values) + 24 (length prefix values)
|
||||||
// + color_cache_size (between 0 and 2048).
|
// + color_cache_size (between 0 and 2048).
|
||||||
// All values computed for 8-bit first level lookup with Mark Adler's tool:
|
// All values computed for 8-bit first level lookup with Mark Adler's tool:
|
||||||
// http://www.hdfgroup.org/ftp/lib-external/zlib/zlib-1.2.5/examples/enough.c
|
// https://github.com/madler/zlib/blob/v1.2.5/examples/enough.c
|
||||||
#define FIXED_TABLE_SIZE (630 * 3 + 410)
|
#define FIXED_TABLE_SIZE (630 * 3 + 410)
|
||||||
static const uint16_t kTableSize[12] = {
|
static const uint16_t kTableSize[12] = {
|
||||||
FIXED_TABLE_SIZE + 654,
|
FIXED_TABLE_SIZE + 654,
|
||||||
@ -253,11 +253,11 @@ static int ReadHuffmanCodeLengths(
|
|||||||
int symbol;
|
int symbol;
|
||||||
int max_symbol;
|
int max_symbol;
|
||||||
int prev_code_len = DEFAULT_CODE_LENGTH;
|
int prev_code_len = DEFAULT_CODE_LENGTH;
|
||||||
HuffmanCode table[1 << LENGTHS_TABLE_BITS];
|
HuffmanTables tables;
|
||||||
|
|
||||||
if (!VP8LBuildHuffmanTable(table, LENGTHS_TABLE_BITS,
|
if (!VP8LHuffmanTablesAllocate(1 << LENGTHS_TABLE_BITS, &tables) ||
|
||||||
code_length_code_lengths,
|
!VP8LBuildHuffmanTable(&tables, LENGTHS_TABLE_BITS,
|
||||||
NUM_CODE_LENGTH_CODES)) {
|
code_length_code_lengths, NUM_CODE_LENGTH_CODES)) {
|
||||||
goto End;
|
goto End;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -277,7 +277,7 @@ static int ReadHuffmanCodeLengths(
|
|||||||
int code_len;
|
int code_len;
|
||||||
if (max_symbol-- == 0) break;
|
if (max_symbol-- == 0) break;
|
||||||
VP8LFillBitWindow(br);
|
VP8LFillBitWindow(br);
|
||||||
p = &table[VP8LPrefetchBits(br) & LENGTHS_TABLE_MASK];
|
p = &tables.curr_segment->start[VP8LPrefetchBits(br) & LENGTHS_TABLE_MASK];
|
||||||
VP8LSetBitPos(br, br->bit_pos_ + p->bits);
|
VP8LSetBitPos(br, br->bit_pos_ + p->bits);
|
||||||
code_len = p->value;
|
code_len = p->value;
|
||||||
if (code_len < kCodeLengthLiterals) {
|
if (code_len < kCodeLengthLiterals) {
|
||||||
@ -300,6 +300,7 @@ static int ReadHuffmanCodeLengths(
|
|||||||
ok = 1;
|
ok = 1;
|
||||||
|
|
||||||
End:
|
End:
|
||||||
|
VP8LHuffmanTablesDeallocate(&tables);
|
||||||
if (!ok) dec->status_ = VP8_STATUS_BITSTREAM_ERROR;
|
if (!ok) dec->status_ = VP8_STATUS_BITSTREAM_ERROR;
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
@ -307,7 +308,8 @@ static int ReadHuffmanCodeLengths(
|
|||||||
// 'code_lengths' is pre-allocated temporary buffer, used for creating Huffman
|
// 'code_lengths' is pre-allocated temporary buffer, used for creating Huffman
|
||||||
// tree.
|
// tree.
|
||||||
static int ReadHuffmanCode(int alphabet_size, VP8LDecoder* const dec,
|
static int ReadHuffmanCode(int alphabet_size, VP8LDecoder* const dec,
|
||||||
int* const code_lengths, HuffmanCode* const table) {
|
int* const code_lengths,
|
||||||
|
HuffmanTables* const table) {
|
||||||
int ok = 0;
|
int ok = 0;
|
||||||
int size = 0;
|
int size = 0;
|
||||||
VP8LBitReader* const br = &dec->br_;
|
VP8LBitReader* const br = &dec->br_;
|
||||||
@ -362,8 +364,7 @@ static int ReadHuffmanCodes(VP8LDecoder* const dec, int xsize, int ysize,
|
|||||||
VP8LMetadata* const hdr = &dec->hdr_;
|
VP8LMetadata* const hdr = &dec->hdr_;
|
||||||
uint32_t* huffman_image = NULL;
|
uint32_t* huffman_image = NULL;
|
||||||
HTreeGroup* htree_groups = NULL;
|
HTreeGroup* htree_groups = NULL;
|
||||||
HuffmanCode* huffman_tables = NULL;
|
HuffmanTables* huffman_tables = &hdr->huffman_tables_;
|
||||||
HuffmanCode* huffman_table = NULL;
|
|
||||||
int num_htree_groups = 1;
|
int num_htree_groups = 1;
|
||||||
int num_htree_groups_max = 1;
|
int num_htree_groups_max = 1;
|
||||||
int max_alphabet_size = 0;
|
int max_alphabet_size = 0;
|
||||||
@ -372,6 +373,10 @@ static int ReadHuffmanCodes(VP8LDecoder* const dec, int xsize, int ysize,
|
|||||||
int* mapping = NULL;
|
int* mapping = NULL;
|
||||||
int ok = 0;
|
int ok = 0;
|
||||||
|
|
||||||
|
// Check the table has been 0 initialized (through InitMetadata).
|
||||||
|
assert(huffman_tables->root.start == NULL);
|
||||||
|
assert(huffman_tables->curr_segment == NULL);
|
||||||
|
|
||||||
if (allow_recursion && VP8LReadBits(br, 1)) {
|
if (allow_recursion && VP8LReadBits(br, 1)) {
|
||||||
// use meta Huffman codes.
|
// use meta Huffman codes.
|
||||||
const int huffman_precision = VP8LReadBits(br, 3) + 2;
|
const int huffman_precision = VP8LReadBits(br, 3) + 2;
|
||||||
@ -434,16 +439,15 @@ static int ReadHuffmanCodes(VP8LDecoder* const dec, int xsize, int ysize,
|
|||||||
|
|
||||||
code_lengths = (int*)WebPSafeCalloc((uint64_t)max_alphabet_size,
|
code_lengths = (int*)WebPSafeCalloc((uint64_t)max_alphabet_size,
|
||||||
sizeof(*code_lengths));
|
sizeof(*code_lengths));
|
||||||
huffman_tables = (HuffmanCode*)WebPSafeMalloc(num_htree_groups * table_size,
|
|
||||||
sizeof(*huffman_tables));
|
|
||||||
htree_groups = VP8LHtreeGroupsNew(num_htree_groups);
|
htree_groups = VP8LHtreeGroupsNew(num_htree_groups);
|
||||||
|
|
||||||
if (htree_groups == NULL || code_lengths == NULL || huffman_tables == NULL) {
|
if (htree_groups == NULL || code_lengths == NULL ||
|
||||||
|
!VP8LHuffmanTablesAllocate(num_htree_groups * table_size,
|
||||||
|
huffman_tables)) {
|
||||||
dec->status_ = VP8_STATUS_OUT_OF_MEMORY;
|
dec->status_ = VP8_STATUS_OUT_OF_MEMORY;
|
||||||
goto Error;
|
goto Error;
|
||||||
}
|
}
|
||||||
|
|
||||||
huffman_table = huffman_tables;
|
|
||||||
for (i = 0; i < num_htree_groups_max; ++i) {
|
for (i = 0; i < num_htree_groups_max; ++i) {
|
||||||
// If the index "i" is unused in the Huffman image, just make sure the
|
// If the index "i" is unused in the Huffman image, just make sure the
|
||||||
// coefficients are valid but do not store them.
|
// coefficients are valid but do not store them.
|
||||||
@ -468,19 +472,20 @@ static int ReadHuffmanCodes(VP8LDecoder* const dec, int xsize, int ysize,
|
|||||||
int max_bits = 0;
|
int max_bits = 0;
|
||||||
for (j = 0; j < HUFFMAN_CODES_PER_META_CODE; ++j) {
|
for (j = 0; j < HUFFMAN_CODES_PER_META_CODE; ++j) {
|
||||||
int alphabet_size = kAlphabetSize[j];
|
int alphabet_size = kAlphabetSize[j];
|
||||||
htrees[j] = huffman_table;
|
|
||||||
if (j == 0 && color_cache_bits > 0) {
|
if (j == 0 && color_cache_bits > 0) {
|
||||||
alphabet_size += (1 << color_cache_bits);
|
alphabet_size += (1 << color_cache_bits);
|
||||||
}
|
}
|
||||||
size = ReadHuffmanCode(alphabet_size, dec, code_lengths, huffman_table);
|
size =
|
||||||
|
ReadHuffmanCode(alphabet_size, dec, code_lengths, huffman_tables);
|
||||||
|
htrees[j] = huffman_tables->curr_segment->curr_table;
|
||||||
if (size == 0) {
|
if (size == 0) {
|
||||||
goto Error;
|
goto Error;
|
||||||
}
|
}
|
||||||
if (is_trivial_literal && kLiteralMap[j] == 1) {
|
if (is_trivial_literal && kLiteralMap[j] == 1) {
|
||||||
is_trivial_literal = (huffman_table->bits == 0);
|
is_trivial_literal = (htrees[j]->bits == 0);
|
||||||
}
|
}
|
||||||
total_size += huffman_table->bits;
|
total_size += htrees[j]->bits;
|
||||||
huffman_table += size;
|
huffman_tables->curr_segment->curr_table += size;
|
||||||
if (j <= ALPHA) {
|
if (j <= ALPHA) {
|
||||||
int local_max_bits = code_lengths[0];
|
int local_max_bits = code_lengths[0];
|
||||||
int k;
|
int k;
|
||||||
@ -515,14 +520,13 @@ static int ReadHuffmanCodes(VP8LDecoder* const dec, int xsize, int ysize,
|
|||||||
hdr->huffman_image_ = huffman_image;
|
hdr->huffman_image_ = huffman_image;
|
||||||
hdr->num_htree_groups_ = num_htree_groups;
|
hdr->num_htree_groups_ = num_htree_groups;
|
||||||
hdr->htree_groups_ = htree_groups;
|
hdr->htree_groups_ = htree_groups;
|
||||||
hdr->huffman_tables_ = huffman_tables;
|
|
||||||
|
|
||||||
Error:
|
Error:
|
||||||
WebPSafeFree(code_lengths);
|
WebPSafeFree(code_lengths);
|
||||||
WebPSafeFree(mapping);
|
WebPSafeFree(mapping);
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
WebPSafeFree(huffman_image);
|
WebPSafeFree(huffman_image);
|
||||||
WebPSafeFree(huffman_tables);
|
VP8LHuffmanTablesDeallocate(huffman_tables);
|
||||||
VP8LHtreeGroupsFree(htree_groups);
|
VP8LHtreeGroupsFree(htree_groups);
|
||||||
}
|
}
|
||||||
return ok;
|
return ok;
|
||||||
@ -1358,7 +1362,7 @@ static void ClearMetadata(VP8LMetadata* const hdr) {
|
|||||||
assert(hdr != NULL);
|
assert(hdr != NULL);
|
||||||
|
|
||||||
WebPSafeFree(hdr->huffman_image_);
|
WebPSafeFree(hdr->huffman_image_);
|
||||||
WebPSafeFree(hdr->huffman_tables_);
|
VP8LHuffmanTablesDeallocate(&hdr->huffman_tables_);
|
||||||
VP8LHtreeGroupsFree(hdr->htree_groups_);
|
VP8LHtreeGroupsFree(hdr->htree_groups_);
|
||||||
VP8LColorCacheClear(&hdr->color_cache_);
|
VP8LColorCacheClear(&hdr->color_cache_);
|
||||||
VP8LColorCacheClear(&hdr->saved_color_cache_);
|
VP8LColorCacheClear(&hdr->saved_color_cache_);
|
||||||
@ -1673,7 +1677,7 @@ int VP8LDecodeImage(VP8LDecoder* const dec) {
|
|||||||
|
|
||||||
if (dec == NULL) return 0;
|
if (dec == NULL) return 0;
|
||||||
|
|
||||||
assert(dec->hdr_.huffman_tables_ != NULL);
|
assert(dec->hdr_.huffman_tables_.root.start != NULL);
|
||||||
assert(dec->hdr_.htree_groups_ != NULL);
|
assert(dec->hdr_.htree_groups_ != NULL);
|
||||||
assert(dec->hdr_.num_htree_groups_ > 0);
|
assert(dec->hdr_.num_htree_groups_ > 0);
|
||||||
|
|
||||||
|
@ -51,7 +51,7 @@ typedef struct {
|
|||||||
uint32_t* huffman_image_;
|
uint32_t* huffman_image_;
|
||||||
int num_htree_groups_;
|
int num_htree_groups_;
|
||||||
HTreeGroup* htree_groups_;
|
HTreeGroup* htree_groups_;
|
||||||
HuffmanCode* huffman_tables_;
|
HuffmanTables huffman_tables_;
|
||||||
} VP8LMetadata;
|
} VP8LMetadata;
|
||||||
|
|
||||||
typedef struct VP8LDecoder VP8LDecoder;
|
typedef struct VP8LDecoder VP8LDecoder;
|
||||||
|
@ -13,6 +13,6 @@ noinst_HEADERS =
|
|||||||
noinst_HEADERS += ../webp/format_constants.h
|
noinst_HEADERS += ../webp/format_constants.h
|
||||||
|
|
||||||
libwebpdemux_la_LIBADD = ../libwebp.la
|
libwebpdemux_la_LIBADD = ../libwebp.la
|
||||||
libwebpdemux_la_LDFLAGS = -no-undefined -version-info 2:8:0
|
libwebpdemux_la_LDFLAGS = -no-undefined -version-info 2:9:0
|
||||||
libwebpdemuxincludedir = $(includedir)/webp
|
libwebpdemuxincludedir = $(includedir)/webp
|
||||||
pkgconfig_DATA = libwebpdemux.pc
|
pkgconfig_DATA = libwebpdemux.pc
|
||||||
|
@ -23,6 +23,14 @@
|
|||||||
|
|
||||||
#define NUM_CHANNELS 4
|
#define NUM_CHANNELS 4
|
||||||
|
|
||||||
|
// Channel extraction from a uint32_t representation of a uint8_t RGBA/BGRA
|
||||||
|
// buffer.
|
||||||
|
#ifdef WORDS_BIGENDIAN
|
||||||
|
#define CHANNEL_SHIFT(i) (24 - (i) * 8)
|
||||||
|
#else
|
||||||
|
#define CHANNEL_SHIFT(i) ((i) * 8)
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef void (*BlendRowFunc)(uint32_t* const, const uint32_t* const, int);
|
typedef void (*BlendRowFunc)(uint32_t* const, const uint32_t* const, int);
|
||||||
static void BlendPixelRowNonPremult(uint32_t* const src,
|
static void BlendPixelRowNonPremult(uint32_t* const src,
|
||||||
const uint32_t* const dst, int num_pixels);
|
const uint32_t* const dst, int num_pixels);
|
||||||
@ -209,35 +217,35 @@ static uint8_t BlendChannelNonPremult(uint32_t src, uint8_t src_a,
|
|||||||
const uint8_t dst_channel = (dst >> shift) & 0xff;
|
const uint8_t dst_channel = (dst >> shift) & 0xff;
|
||||||
const uint32_t blend_unscaled = src_channel * src_a + dst_channel * dst_a;
|
const uint32_t blend_unscaled = src_channel * src_a + dst_channel * dst_a;
|
||||||
assert(blend_unscaled < (1ULL << 32) / scale);
|
assert(blend_unscaled < (1ULL << 32) / scale);
|
||||||
return (blend_unscaled * scale) >> 24;
|
return (blend_unscaled * scale) >> CHANNEL_SHIFT(3);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Blend 'src' over 'dst' assuming they are NOT pre-multiplied by alpha.
|
// Blend 'src' over 'dst' assuming they are NOT pre-multiplied by alpha.
|
||||||
static uint32_t BlendPixelNonPremult(uint32_t src, uint32_t dst) {
|
static uint32_t BlendPixelNonPremult(uint32_t src, uint32_t dst) {
|
||||||
const uint8_t src_a = (src >> 24) & 0xff;
|
const uint8_t src_a = (src >> CHANNEL_SHIFT(3)) & 0xff;
|
||||||
|
|
||||||
if (src_a == 0) {
|
if (src_a == 0) {
|
||||||
return dst;
|
return dst;
|
||||||
} else {
|
} else {
|
||||||
const uint8_t dst_a = (dst >> 24) & 0xff;
|
const uint8_t dst_a = (dst >> CHANNEL_SHIFT(3)) & 0xff;
|
||||||
// This is the approximate integer arithmetic for the actual formula:
|
// This is the approximate integer arithmetic for the actual formula:
|
||||||
// dst_factor_a = (dst_a * (255 - src_a)) / 255.
|
// dst_factor_a = (dst_a * (255 - src_a)) / 255.
|
||||||
const uint8_t dst_factor_a = (dst_a * (256 - src_a)) >> 8;
|
const uint8_t dst_factor_a = (dst_a * (256 - src_a)) >> 8;
|
||||||
const uint8_t blend_a = src_a + dst_factor_a;
|
const uint8_t blend_a = src_a + dst_factor_a;
|
||||||
const uint32_t scale = (1UL << 24) / blend_a;
|
const uint32_t scale = (1UL << 24) / blend_a;
|
||||||
|
|
||||||
const uint8_t blend_r =
|
const uint8_t blend_r = BlendChannelNonPremult(
|
||||||
BlendChannelNonPremult(src, src_a, dst, dst_factor_a, scale, 0);
|
src, src_a, dst, dst_factor_a, scale, CHANNEL_SHIFT(0));
|
||||||
const uint8_t blend_g =
|
const uint8_t blend_g = BlendChannelNonPremult(
|
||||||
BlendChannelNonPremult(src, src_a, dst, dst_factor_a, scale, 8);
|
src, src_a, dst, dst_factor_a, scale, CHANNEL_SHIFT(1));
|
||||||
const uint8_t blend_b =
|
const uint8_t blend_b = BlendChannelNonPremult(
|
||||||
BlendChannelNonPremult(src, src_a, dst, dst_factor_a, scale, 16);
|
src, src_a, dst, dst_factor_a, scale, CHANNEL_SHIFT(2));
|
||||||
assert(src_a + dst_factor_a < 256);
|
assert(src_a + dst_factor_a < 256);
|
||||||
|
|
||||||
return (blend_r << 0) |
|
return ((uint32_t)blend_r << CHANNEL_SHIFT(0)) |
|
||||||
(blend_g << 8) |
|
((uint32_t)blend_g << CHANNEL_SHIFT(1)) |
|
||||||
(blend_b << 16) |
|
((uint32_t)blend_b << CHANNEL_SHIFT(2)) |
|
||||||
((uint32_t)blend_a << 24);
|
((uint32_t)blend_a << CHANNEL_SHIFT(3));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -247,7 +255,7 @@ static void BlendPixelRowNonPremult(uint32_t* const src,
|
|||||||
const uint32_t* const dst, int num_pixels) {
|
const uint32_t* const dst, int num_pixels) {
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < num_pixels; ++i) {
|
for (i = 0; i < num_pixels; ++i) {
|
||||||
const uint8_t src_alpha = (src[i] >> 24) & 0xff;
|
const uint8_t src_alpha = (src[i] >> CHANNEL_SHIFT(3)) & 0xff;
|
||||||
if (src_alpha != 0xff) {
|
if (src_alpha != 0xff) {
|
||||||
src[i] = BlendPixelNonPremult(src[i], dst[i]);
|
src[i] = BlendPixelNonPremult(src[i], dst[i]);
|
||||||
}
|
}
|
||||||
@ -264,7 +272,7 @@ static WEBP_INLINE uint32_t ChannelwiseMultiply(uint32_t pix, uint32_t scale) {
|
|||||||
|
|
||||||
// Blend 'src' over 'dst' assuming they are pre-multiplied by alpha.
|
// Blend 'src' over 'dst' assuming they are pre-multiplied by alpha.
|
||||||
static uint32_t BlendPixelPremult(uint32_t src, uint32_t dst) {
|
static uint32_t BlendPixelPremult(uint32_t src, uint32_t dst) {
|
||||||
const uint8_t src_a = (src >> 24) & 0xff;
|
const uint8_t src_a = (src >> CHANNEL_SHIFT(3)) & 0xff;
|
||||||
return src + ChannelwiseMultiply(dst, 256 - src_a);
|
return src + ChannelwiseMultiply(dst, 256 - src_a);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -274,7 +282,7 @@ static void BlendPixelRowPremult(uint32_t* const src, const uint32_t* const dst,
|
|||||||
int num_pixels) {
|
int num_pixels) {
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < num_pixels; ++i) {
|
for (i = 0; i < num_pixels; ++i) {
|
||||||
const uint8_t src_alpha = (src[i] >> 24) & 0xff;
|
const uint8_t src_alpha = (src[i] >> CHANNEL_SHIFT(3)) & 0xff;
|
||||||
if (src_alpha != 0xff) {
|
if (src_alpha != 0xff) {
|
||||||
src[i] = BlendPixelPremult(src[i], dst[i]);
|
src[i] = BlendPixelPremult(src[i], dst[i]);
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
|
|
||||||
#define DMUX_MAJ_VERSION 1
|
#define DMUX_MAJ_VERSION 1
|
||||||
#define DMUX_MIN_VERSION 2
|
#define DMUX_MIN_VERSION 2
|
||||||
#define DMUX_REV_VERSION 1
|
#define DMUX_REV_VERSION 2
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
size_t start_; // start location of the data
|
size_t start_; // start location of the data
|
||||||
|
@ -6,8 +6,8 @@
|
|||||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||||
|
|
||||||
VS_VERSION_INFO VERSIONINFO
|
VS_VERSION_INFO VERSIONINFO
|
||||||
FILEVERSION 1,0,2,1
|
FILEVERSION 1,0,2,2
|
||||||
PRODUCTVERSION 1,0,2,1
|
PRODUCTVERSION 1,0,2,2
|
||||||
FILEFLAGSMASK 0x3fL
|
FILEFLAGSMASK 0x3fL
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
FILEFLAGS 0x1L
|
FILEFLAGS 0x1L
|
||||||
@ -24,12 +24,12 @@ BEGIN
|
|||||||
BEGIN
|
BEGIN
|
||||||
VALUE "CompanyName", "Google, Inc."
|
VALUE "CompanyName", "Google, Inc."
|
||||||
VALUE "FileDescription", "libwebpdemux DLL"
|
VALUE "FileDescription", "libwebpdemux DLL"
|
||||||
VALUE "FileVersion", "1.2.1"
|
VALUE "FileVersion", "1.2.2"
|
||||||
VALUE "InternalName", "libwebpdemux.dll"
|
VALUE "InternalName", "libwebpdemux.dll"
|
||||||
VALUE "LegalCopyright", "Copyright (C) 2021"
|
VALUE "LegalCopyright", "Copyright (C) 2021"
|
||||||
VALUE "OriginalFilename", "libwebpdemux.dll"
|
VALUE "OriginalFilename", "libwebpdemux.dll"
|
||||||
VALUE "ProductName", "WebP Image Demuxer"
|
VALUE "ProductName", "WebP Image Demuxer"
|
||||||
VALUE "ProductVersion", "1.2.1"
|
VALUE "ProductVersion", "1.2.2"
|
||||||
END
|
END
|
||||||
END
|
END
|
||||||
BLOCK "VarFileInfo"
|
BLOCK "VarFileInfo"
|
||||||
|
@ -13,7 +13,6 @@ noinst_LTLIBRARIES += libwebpdsp_mips32.la
|
|||||||
noinst_LTLIBRARIES += libwebpdspdecode_mips32.la
|
noinst_LTLIBRARIES += libwebpdspdecode_mips32.la
|
||||||
noinst_LTLIBRARIES += libwebpdsp_mips_dsp_r2.la
|
noinst_LTLIBRARIES += libwebpdsp_mips_dsp_r2.la
|
||||||
noinst_LTLIBRARIES += libwebpdspdecode_mips_dsp_r2.la
|
noinst_LTLIBRARIES += libwebpdspdecode_mips_dsp_r2.la
|
||||||
noinst_LTLIBRARIES += libwebpdspdecode_wasm.la
|
|
||||||
|
|
||||||
if BUILD_LIBWEBPDECODER
|
if BUILD_LIBWEBPDECODER
|
||||||
noinst_LTLIBRARIES += libwebpdspdecode.la
|
noinst_LTLIBRARIES += libwebpdspdecode.la
|
||||||
@ -107,8 +106,6 @@ libwebpdspdecode_mips_dsp_r2_la_SOURCES += yuv_mips_dsp_r2.c
|
|||||||
libwebpdspdecode_mips_dsp_r2_la_CPPFLAGS = $(libwebpdsp_mips_dsp_r2_la_CPPFLAGS)
|
libwebpdspdecode_mips_dsp_r2_la_CPPFLAGS = $(libwebpdsp_mips_dsp_r2_la_CPPFLAGS)
|
||||||
libwebpdspdecode_mips_dsp_r2_la_CFLAGS = $(libwebpdsp_mips_dsp_r2_la_CFLAGS)
|
libwebpdspdecode_mips_dsp_r2_la_CFLAGS = $(libwebpdsp_mips_dsp_r2_la_CFLAGS)
|
||||||
|
|
||||||
libwebpdspdecode_wasm_la_SOURCES = dec_wasm.c
|
|
||||||
|
|
||||||
libwebpdsp_sse2_la_SOURCES =
|
libwebpdsp_sse2_la_SOURCES =
|
||||||
libwebpdsp_sse2_la_SOURCES += cost_sse2.c
|
libwebpdsp_sse2_la_SOURCES += cost_sse2.c
|
||||||
libwebpdsp_sse2_la_SOURCES += enc_sse2.c
|
libwebpdsp_sse2_la_SOURCES += enc_sse2.c
|
||||||
|
@ -83,7 +83,7 @@ static void ApplyAlphaMultiply_NEON(uint8_t* rgba, int alpha_first,
|
|||||||
static int DispatchAlpha_NEON(const uint8_t* WEBP_RESTRICT alpha,
|
static int DispatchAlpha_NEON(const uint8_t* WEBP_RESTRICT alpha,
|
||||||
int alpha_stride, int width, int height,
|
int alpha_stride, int width, int height,
|
||||||
uint8_t* WEBP_RESTRICT dst, int dst_stride) {
|
uint8_t* WEBP_RESTRICT dst, int dst_stride) {
|
||||||
uint32_t alpha_mask = 0xffffffffu;
|
uint32_t alpha_mask = 0xffu;
|
||||||
uint8x8_t mask8 = vdup_n_u8(0xff);
|
uint8x8_t mask8 = vdup_n_u8(0xff);
|
||||||
uint32_t tmp[2];
|
uint32_t tmp[2];
|
||||||
int i, j;
|
int i, j;
|
||||||
@ -107,6 +107,7 @@ static int DispatchAlpha_NEON(const uint8_t* WEBP_RESTRICT alpha,
|
|||||||
dst += dst_stride;
|
dst += dst_stride;
|
||||||
}
|
}
|
||||||
vst1_u8((uint8_t*)tmp, mask8);
|
vst1_u8((uint8_t*)tmp, mask8);
|
||||||
|
alpha_mask *= 0x01010101;
|
||||||
alpha_mask &= tmp[0];
|
alpha_mask &= tmp[0];
|
||||||
alpha_mask &= tmp[1];
|
alpha_mask &= tmp[1];
|
||||||
return (alpha_mask != 0xffffffffu);
|
return (alpha_mask != 0xffffffffu);
|
||||||
@ -135,7 +136,7 @@ static void DispatchAlphaToGreen_NEON(const uint8_t* WEBP_RESTRICT alpha,
|
|||||||
static int ExtractAlpha_NEON(const uint8_t* WEBP_RESTRICT argb, int argb_stride,
|
static int ExtractAlpha_NEON(const uint8_t* WEBP_RESTRICT argb, int argb_stride,
|
||||||
int width, int height,
|
int width, int height,
|
||||||
uint8_t* WEBP_RESTRICT alpha, int alpha_stride) {
|
uint8_t* WEBP_RESTRICT alpha, int alpha_stride) {
|
||||||
uint32_t alpha_mask = 0xffffffffu;
|
uint32_t alpha_mask = 0xffu;
|
||||||
uint8x8_t mask8 = vdup_n_u8(0xff);
|
uint8x8_t mask8 = vdup_n_u8(0xff);
|
||||||
uint32_t tmp[2];
|
uint32_t tmp[2];
|
||||||
int i, j;
|
int i, j;
|
||||||
@ -157,6 +158,7 @@ static int ExtractAlpha_NEON(const uint8_t* WEBP_RESTRICT argb, int argb_stride,
|
|||||||
alpha += alpha_stride;
|
alpha += alpha_stride;
|
||||||
}
|
}
|
||||||
vst1_u8((uint8_t*)tmp, mask8);
|
vst1_u8((uint8_t*)tmp, mask8);
|
||||||
|
alpha_mask *= 0x01010101;
|
||||||
alpha_mask &= tmp[0];
|
alpha_mask &= tmp[0];
|
||||||
alpha_mask &= tmp[1];
|
alpha_mask &= tmp[1];
|
||||||
return (alpha_mask == 0xffffffffu);
|
return (alpha_mask == 0xffffffffu);
|
||||||
|
@ -26,10 +26,8 @@
|
|||||||
// SSE2 detection.
|
// SSE2 detection.
|
||||||
//
|
//
|
||||||
|
|
||||||
// Skip SSE detection if using Wasm SIMD build.
|
|
||||||
#if defined(WEBP_USE_WASM_SIMD)
|
|
||||||
// apple/darwin gcc-4.0.1 defines __PIC__, but not __pic__ with -fPIC.
|
// apple/darwin gcc-4.0.1 defines __PIC__, but not __pic__ with -fPIC.
|
||||||
#elif (defined(__pic__) || defined(__PIC__)) && defined(__i386__)
|
#if (defined(__pic__) || defined(__PIC__)) && defined(__i386__)
|
||||||
static WEBP_INLINE void GetCPUInfo(int cpu_info[4], int info_type) {
|
static WEBP_INLINE void GetCPUInfo(int cpu_info[4], int info_type) {
|
||||||
__asm__ volatile (
|
__asm__ volatile (
|
||||||
"mov %%ebx, %%edi\n"
|
"mov %%ebx, %%edi\n"
|
||||||
@ -71,10 +69,8 @@ static WEBP_INLINE void GetCPUInfo(int cpu_info[4], int info_type) {
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Skip xgetbv definition if using Wasm SIMD build.
|
|
||||||
#if defined(WEBP_USE_WASM_SIMD)
|
|
||||||
// NaCl has no support for xgetbv or the raw opcode.
|
// NaCl has no support for xgetbv or the raw opcode.
|
||||||
#elif !defined(__native_client__) && (defined(__i386__) || defined(__x86_64__))
|
#if !defined(__native_client__) && (defined(__i386__) || defined(__x86_64__))
|
||||||
static WEBP_INLINE uint64_t xgetbv(void) {
|
static WEBP_INLINE uint64_t xgetbv(void) {
|
||||||
const uint32_t ecx = 0;
|
const uint32_t ecx = 0;
|
||||||
uint32_t eax, edx;
|
uint32_t eax, edx;
|
||||||
@ -104,13 +100,7 @@ static WEBP_INLINE uint64_t xgetbv(void) {
|
|||||||
#define xgetbv() 0U // no AVX for older x64 or unrecognized toolchains.
|
#define xgetbv() 0U // no AVX for older x64 or unrecognized toolchains.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(WEBP_USE_WASM_SIMD)
|
#if defined(__i386__) || defined(__x86_64__) || defined(WEBP_HAVE_MSC_CPUID)
|
||||||
static int wasmCPUInfo(CPUFeature feature) {
|
|
||||||
if (feature != kWasmSIMD) return 0;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
VP8CPUInfo VP8GetCPUInfo = wasmCPUInfo;
|
|
||||||
#elif defined(__i386__) || defined(__x86_64__) || defined(WEBP_HAVE_MSC_CPUID)
|
|
||||||
|
|
||||||
// helper function for run-time detection of slow SSSE3 platforms
|
// helper function for run-time detection of slow SSSE3 platforms
|
||||||
static int CheckSlowModel(int info) {
|
static int CheckSlowModel(int info) {
|
||||||
|
@ -740,7 +740,6 @@ extern void VP8DspInitNEON(void);
|
|||||||
extern void VP8DspInitMIPS32(void);
|
extern void VP8DspInitMIPS32(void);
|
||||||
extern void VP8DspInitMIPSdspR2(void);
|
extern void VP8DspInitMIPSdspR2(void);
|
||||||
extern void VP8DspInitMSA(void);
|
extern void VP8DspInitMSA(void);
|
||||||
extern void VP8DspInitWasmSIMD(void);
|
|
||||||
|
|
||||||
WEBP_DSP_INIT_FUNC(VP8DspInit) {
|
WEBP_DSP_INIT_FUNC(VP8DspInit) {
|
||||||
VP8InitClipTables();
|
VP8InitClipTables();
|
||||||
@ -832,12 +831,6 @@ WEBP_DSP_INIT_FUNC(VP8DspInit) {
|
|||||||
if (VP8GetCPUInfo(kMSA)) {
|
if (VP8GetCPUInfo(kMSA)) {
|
||||||
VP8DspInitMSA();
|
VP8DspInitMSA();
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
#if defined(WEBP_USE_WASM_SIMD) && defined(WEBP_ENABLE_WASM_SIMD_INTRINSICS)
|
|
||||||
// Check that SIMD is supported and that we want to use Wasm intrinsics.
|
|
||||||
if (VP8GetCPUInfo(kWasmSIMD)) {
|
|
||||||
VP8DspInitWasmSIMD();
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,32 +0,0 @@
|
|||||||
// Copyright 2021 Google Inc. All Rights Reserved.
|
|
||||||
//
|
|
||||||
// Use of this source code is governed by a BSD-style license
|
|
||||||
// that can be found in the COPYING file in the root of the source
|
|
||||||
// tree. An additional intellectual property rights grant can be found
|
|
||||||
// in the file PATENTS. All contributing project authors may
|
|
||||||
// be found in the AUTHORS file in the root of the source tree.
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// WebAssembly (Wasm) version of some decoding functions.
|
|
||||||
//
|
|
||||||
// This will contain Wasm implementation of some decoding functions.
|
|
||||||
|
|
||||||
#include "./dsp.h"
|
|
||||||
|
|
||||||
#if defined(WEBP_USE_WASM_SIMD)
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
// Entry point
|
|
||||||
|
|
||||||
extern void VP8DspInitWasmSIMD(void);
|
|
||||||
|
|
||||||
WEBP_TSAN_IGNORE_FUNCTION void VP8DspInitWasmSIMD(void) {
|
|
||||||
// TODO(crbug.com/v8/12371): No special implementation for Wasm yet, will be
|
|
||||||
// added later.
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
WEBP_DSP_INIT_STUB(VP8DspInitWasmSIMD)
|
|
||||||
|
|
||||||
#endif // WEBP_USE_WASM_SIMD
|
|
@ -80,11 +80,6 @@ extern "C" {
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (defined(EMSCRIPTEN) || defined(WEBP_HAVE_WASM_SIMD)) && \
|
|
||||||
defined(__wasm_simd128__)
|
|
||||||
#define WEBP_USE_WASM_SIMD
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// WEBP_HAVE_* are used to indicate the presence of the instruction set in dsp
|
// WEBP_HAVE_* are used to indicate the presence of the instruction set in dsp
|
||||||
// files without intrinsics, allowing the corresponding Init() to be called.
|
// files without intrinsics, allowing the corresponding Init() to be called.
|
||||||
// Files containing intrinsics will need to be built targeting the instruction
|
// Files containing intrinsics will need to be built targeting the instruction
|
||||||
@ -126,10 +121,11 @@ extern "C" {
|
|||||||
|
|
||||||
// Note: ARM64 is supported in Visual Studio 2017, but requires the direct
|
// Note: ARM64 is supported in Visual Studio 2017, but requires the direct
|
||||||
// inclusion of arm64_neon.h; Visual Studio 2019 includes this file in
|
// inclusion of arm64_neon.h; Visual Studio 2019 includes this file in
|
||||||
// arm_neon.h.
|
// 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) && \
|
#if defined(_MSC_VER) && \
|
||||||
((_MSC_VER >= 1700 && defined(_M_ARM)) || \
|
((_MSC_VER >= 1700 && defined(_M_ARM)) || \
|
||||||
(_MSC_VER >= 1920 && defined(_M_ARM64)))
|
(_MSC_VER >= 1926 && defined(_M_ARM64)))
|
||||||
#define WEBP_USE_NEON
|
#define WEBP_USE_NEON
|
||||||
#define WEBP_USE_INTRINSICS
|
#define WEBP_USE_INTRINSICS
|
||||||
#endif
|
#endif
|
||||||
@ -262,8 +258,7 @@ typedef enum {
|
|||||||
kNEON,
|
kNEON,
|
||||||
kMIPS32,
|
kMIPS32,
|
||||||
kMIPSdspR2,
|
kMIPSdspR2,
|
||||||
kMSA,
|
kMSA
|
||||||
kWasmSIMD
|
|
||||||
} CPUFeature;
|
} CPUFeature;
|
||||||
// returns true if the CPU supports the feature.
|
// returns true if the CPU supports the feature.
|
||||||
typedef int (*VP8CPUInfo)(CPUFeature feature);
|
typedef int (*VP8CPUInfo)(CPUFeature feature);
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
//
|
//
|
||||||
// ARM NEON version of speed-critical encoding functions.
|
// ARM NEON version of speed-critical encoding functions.
|
||||||
//
|
//
|
||||||
// adapted from libvpx (http://www.webmproject.org/code/)
|
// adapted from libvpx (https://www.webmproject.org/code/)
|
||||||
|
|
||||||
#include "src/dsp/dsp.h"
|
#include "src/dsp/dsp.h"
|
||||||
|
|
||||||
|
@ -107,63 +107,77 @@ static WEBP_INLINE uint32_t Select(uint32_t a, uint32_t b, uint32_t c) {
|
|||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Predictors
|
// Predictors
|
||||||
|
|
||||||
uint32_t VP8LPredictor0_C(uint32_t left, const uint32_t* const top) {
|
uint32_t VP8LPredictor0_C(const uint32_t* const left,
|
||||||
|
const uint32_t* const top) {
|
||||||
(void)top;
|
(void)top;
|
||||||
(void)left;
|
(void)left;
|
||||||
return ARGB_BLACK;
|
return ARGB_BLACK;
|
||||||
}
|
}
|
||||||
uint32_t VP8LPredictor1_C(uint32_t left, const uint32_t* const top) {
|
uint32_t VP8LPredictor1_C(const uint32_t* const left,
|
||||||
|
const uint32_t* const top) {
|
||||||
(void)top;
|
(void)top;
|
||||||
return left;
|
return *left;
|
||||||
}
|
}
|
||||||
uint32_t VP8LPredictor2_C(uint32_t left, const uint32_t* const top) {
|
uint32_t VP8LPredictor2_C(const uint32_t* const left,
|
||||||
|
const uint32_t* const top) {
|
||||||
(void)left;
|
(void)left;
|
||||||
return top[0];
|
return top[0];
|
||||||
}
|
}
|
||||||
uint32_t VP8LPredictor3_C(uint32_t left, const uint32_t* const top) {
|
uint32_t VP8LPredictor3_C(const uint32_t* const left,
|
||||||
|
const uint32_t* const top) {
|
||||||
(void)left;
|
(void)left;
|
||||||
return top[1];
|
return top[1];
|
||||||
}
|
}
|
||||||
uint32_t VP8LPredictor4_C(uint32_t left, const uint32_t* const top) {
|
uint32_t VP8LPredictor4_C(const uint32_t* const left,
|
||||||
|
const uint32_t* const top) {
|
||||||
(void)left;
|
(void)left;
|
||||||
return top[-1];
|
return top[-1];
|
||||||
}
|
}
|
||||||
uint32_t VP8LPredictor5_C(uint32_t left, const uint32_t* const top) {
|
uint32_t VP8LPredictor5_C(const uint32_t* const left,
|
||||||
const uint32_t pred = Average3(left, top[0], top[1]);
|
const uint32_t* const top) {
|
||||||
|
const uint32_t pred = Average3(*left, top[0], top[1]);
|
||||||
return pred;
|
return pred;
|
||||||
}
|
}
|
||||||
uint32_t VP8LPredictor6_C(uint32_t left, const uint32_t* const top) {
|
uint32_t VP8LPredictor6_C(const uint32_t* const left,
|
||||||
const uint32_t pred = Average2(left, top[-1]);
|
const uint32_t* const top) {
|
||||||
|
const uint32_t pred = Average2(*left, top[-1]);
|
||||||
return pred;
|
return pred;
|
||||||
}
|
}
|
||||||
uint32_t VP8LPredictor7_C(uint32_t left, const uint32_t* const top) {
|
uint32_t VP8LPredictor7_C(const uint32_t* const left,
|
||||||
const uint32_t pred = Average2(left, top[0]);
|
const uint32_t* const top) {
|
||||||
|
const uint32_t pred = Average2(*left, top[0]);
|
||||||
return pred;
|
return pred;
|
||||||
}
|
}
|
||||||
uint32_t VP8LPredictor8_C(uint32_t left, const uint32_t* const top) {
|
uint32_t VP8LPredictor8_C(const uint32_t* const left,
|
||||||
|
const uint32_t* const top) {
|
||||||
const uint32_t pred = Average2(top[-1], top[0]);
|
const uint32_t pred = Average2(top[-1], top[0]);
|
||||||
(void)left;
|
(void)left;
|
||||||
return pred;
|
return pred;
|
||||||
}
|
}
|
||||||
uint32_t VP8LPredictor9_C(uint32_t left, const uint32_t* const top) {
|
uint32_t VP8LPredictor9_C(const uint32_t* const left,
|
||||||
|
const uint32_t* const top) {
|
||||||
const uint32_t pred = Average2(top[0], top[1]);
|
const uint32_t pred = Average2(top[0], top[1]);
|
||||||
(void)left;
|
(void)left;
|
||||||
return pred;
|
return pred;
|
||||||
}
|
}
|
||||||
uint32_t VP8LPredictor10_C(uint32_t left, const uint32_t* const top) {
|
uint32_t VP8LPredictor10_C(const uint32_t* const left,
|
||||||
const uint32_t pred = Average4(left, top[-1], top[0], top[1]);
|
const uint32_t* const top) {
|
||||||
|
const uint32_t pred = Average4(*left, top[-1], top[0], top[1]);
|
||||||
return pred;
|
return pred;
|
||||||
}
|
}
|
||||||
uint32_t VP8LPredictor11_C(uint32_t left, const uint32_t* const top) {
|
uint32_t VP8LPredictor11_C(const uint32_t* const left,
|
||||||
const uint32_t pred = Select(top[0], left, top[-1]);
|
const uint32_t* const top) {
|
||||||
|
const uint32_t pred = Select(top[0], *left, top[-1]);
|
||||||
return pred;
|
return pred;
|
||||||
}
|
}
|
||||||
uint32_t VP8LPredictor12_C(uint32_t left, const uint32_t* const top) {
|
uint32_t VP8LPredictor12_C(const uint32_t* const left,
|
||||||
const uint32_t pred = ClampedAddSubtractFull(left, top[0], top[-1]);
|
const uint32_t* const top) {
|
||||||
|
const uint32_t pred = ClampedAddSubtractFull(*left, top[0], top[-1]);
|
||||||
return pred;
|
return pred;
|
||||||
}
|
}
|
||||||
uint32_t VP8LPredictor13_C(uint32_t left, const uint32_t* const top) {
|
uint32_t VP8LPredictor13_C(const uint32_t* const left,
|
||||||
const uint32_t pred = ClampedAddSubtractHalf(left, top[0], top[-1]);
|
const uint32_t* const top) {
|
||||||
|
const uint32_t pred = ClampedAddSubtractHalf(*left, top[0], top[-1]);
|
||||||
return pred;
|
return pred;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,23 +28,38 @@ extern "C" {
|
|||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Decoding
|
// Decoding
|
||||||
|
|
||||||
typedef uint32_t (*VP8LPredictorFunc)(uint32_t left, const uint32_t* const top);
|
typedef uint32_t (*VP8LPredictorFunc)(const uint32_t* const left,
|
||||||
|
const uint32_t* const top);
|
||||||
extern VP8LPredictorFunc VP8LPredictors[16];
|
extern VP8LPredictorFunc VP8LPredictors[16];
|
||||||
|
|
||||||
uint32_t VP8LPredictor0_C(uint32_t left, const uint32_t* const top);
|
uint32_t VP8LPredictor0_C(const uint32_t* const left,
|
||||||
uint32_t VP8LPredictor1_C(uint32_t left, const uint32_t* const top);
|
const uint32_t* const top);
|
||||||
uint32_t VP8LPredictor2_C(uint32_t left, const uint32_t* const top);
|
uint32_t VP8LPredictor1_C(const uint32_t* const left,
|
||||||
uint32_t VP8LPredictor3_C(uint32_t left, const uint32_t* const top);
|
const uint32_t* const top);
|
||||||
uint32_t VP8LPredictor4_C(uint32_t left, const uint32_t* const top);
|
uint32_t VP8LPredictor2_C(const uint32_t* const left,
|
||||||
uint32_t VP8LPredictor5_C(uint32_t left, const uint32_t* const top);
|
const uint32_t* const top);
|
||||||
uint32_t VP8LPredictor6_C(uint32_t left, const uint32_t* const top);
|
uint32_t VP8LPredictor3_C(const uint32_t* const left,
|
||||||
uint32_t VP8LPredictor7_C(uint32_t left, const uint32_t* const top);
|
const uint32_t* const top);
|
||||||
uint32_t VP8LPredictor8_C(uint32_t left, const uint32_t* const top);
|
uint32_t VP8LPredictor4_C(const uint32_t* const left,
|
||||||
uint32_t VP8LPredictor9_C(uint32_t left, const uint32_t* const top);
|
const uint32_t* const top);
|
||||||
uint32_t VP8LPredictor10_C(uint32_t left, const uint32_t* const top);
|
uint32_t VP8LPredictor5_C(const uint32_t* const left,
|
||||||
uint32_t VP8LPredictor11_C(uint32_t left, const uint32_t* const top);
|
const uint32_t* const top);
|
||||||
uint32_t VP8LPredictor12_C(uint32_t left, const uint32_t* const top);
|
uint32_t VP8LPredictor6_C(const uint32_t* const left,
|
||||||
uint32_t VP8LPredictor13_C(uint32_t left, const uint32_t* const top);
|
const uint32_t* const top);
|
||||||
|
uint32_t VP8LPredictor7_C(const uint32_t* const left,
|
||||||
|
const uint32_t* const top);
|
||||||
|
uint32_t VP8LPredictor8_C(const uint32_t* const left,
|
||||||
|
const uint32_t* const top);
|
||||||
|
uint32_t VP8LPredictor9_C(const uint32_t* const left,
|
||||||
|
const uint32_t* const top);
|
||||||
|
uint32_t VP8LPredictor10_C(const uint32_t* const left,
|
||||||
|
const uint32_t* const top);
|
||||||
|
uint32_t VP8LPredictor11_C(const uint32_t* const left,
|
||||||
|
const uint32_t* const top);
|
||||||
|
uint32_t VP8LPredictor12_C(const uint32_t* const left,
|
||||||
|
const uint32_t* const top);
|
||||||
|
uint32_t VP8LPredictor13_C(const uint32_t* const left,
|
||||||
|
const uint32_t* const top);
|
||||||
|
|
||||||
// These Add/Sub function expects upper[-1] and out[-1] to be readable.
|
// These Add/Sub function expects upper[-1] and out[-1] to be readable.
|
||||||
typedef void (*VP8LPredictorAddSubFunc)(const uint32_t* in,
|
typedef void (*VP8LPredictorAddSubFunc)(const uint32_t* in,
|
||||||
|
@ -179,7 +179,7 @@ static void PREDICTOR_ADD(const uint32_t* in, const uint32_t* upper, \
|
|||||||
int x; \
|
int x; \
|
||||||
assert(upper != NULL); \
|
assert(upper != NULL); \
|
||||||
for (x = 0; x < num_pixels; ++x) { \
|
for (x = 0; x < num_pixels; ++x) { \
|
||||||
const uint32_t pred = (PREDICTOR)(out[x - 1], upper + x); \
|
const uint32_t pred = (PREDICTOR)(&out[x - 1], upper + x); \
|
||||||
out[x] = VP8LAddPixels(in[x], pred); \
|
out[x] = VP8LAddPixels(in[x], pred); \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
@ -745,7 +745,7 @@ static void PredictorSub##PREDICTOR_I##_C(const uint32_t* in, \
|
|||||||
assert(upper != NULL); \
|
assert(upper != NULL); \
|
||||||
for (x = 0; x < num_pixels; ++x) { \
|
for (x = 0; x < num_pixels; ++x) { \
|
||||||
const uint32_t pred = \
|
const uint32_t pred = \
|
||||||
VP8LPredictor##PREDICTOR_I##_C(in[x - 1], upper + x); \
|
VP8LPredictor##PREDICTOR_I##_C(&in[x - 1], upper + x); \
|
||||||
out[x] = VP8LSubPixels(in[x], pred); \
|
out[x] = VP8LSubPixels(in[x], pred); \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
@ -347,24 +347,24 @@ static void GetCombinedEntropyUnrefined_MIPS32(const uint32_t X[],
|
|||||||
static void AddVector_MIPS32(const uint32_t* pa, const uint32_t* pb,
|
static void AddVector_MIPS32(const uint32_t* pa, const uint32_t* pb,
|
||||||
uint32_t* pout, int size) {
|
uint32_t* pout, int size) {
|
||||||
uint32_t temp0, temp1, temp2, temp3, temp4, temp5, temp6, temp7;
|
uint32_t temp0, temp1, temp2, temp3, temp4, temp5, temp6, temp7;
|
||||||
const uint32_t end = ((size) / 4) * 4;
|
const int end = ((size) / 4) * 4;
|
||||||
const uint32_t* const LoopEnd = pa + end;
|
const uint32_t* const LoopEnd = pa + end;
|
||||||
int i;
|
int i;
|
||||||
ASM_START
|
ASM_START
|
||||||
ADD_TO_OUT(0, 4, 8, 12, 1, pa, pb, pout)
|
ADD_TO_OUT(0, 4, 8, 12, 1, pa, pb, pout)
|
||||||
ASM_END_0
|
ASM_END_0
|
||||||
for (i = end; i < size; ++i) pout[i] = pa[i] + pb[i];
|
for (i = 0; i < size - end; ++i) pout[i] = pa[i] + pb[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
static void AddVectorEq_MIPS32(const uint32_t* pa, uint32_t* pout, int size) {
|
static void AddVectorEq_MIPS32(const uint32_t* pa, uint32_t* pout, int size) {
|
||||||
uint32_t temp0, temp1, temp2, temp3, temp4, temp5, temp6, temp7;
|
uint32_t temp0, temp1, temp2, temp3, temp4, temp5, temp6, temp7;
|
||||||
const uint32_t end = ((size) / 4) * 4;
|
const int end = ((size) / 4) * 4;
|
||||||
const uint32_t* const LoopEnd = pa + end;
|
const uint32_t* const LoopEnd = pa + end;
|
||||||
int i;
|
int i;
|
||||||
ASM_START
|
ASM_START
|
||||||
ADD_TO_OUT(0, 4, 8, 12, 0, pa, pout, pout)
|
ADD_TO_OUT(0, 4, 8, 12, 0, pa, pout, pout)
|
||||||
ASM_END_1
|
ASM_END_1
|
||||||
for (i = end; i < size; ++i) pout[i] += pa[i];
|
for (i = 0; i < size - end; ++i) pout[i] += pa[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef ASM_END_1
|
#undef ASM_END_1
|
||||||
|
@ -188,46 +188,51 @@ static WEBP_INLINE uint32_t Average4(uint32_t a0, uint32_t a1,
|
|||||||
return Average2(Average2(a0, a1), Average2(a2, a3));
|
return Average2(Average2(a0, a1), Average2(a2, a3));
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t Predictor5_MIPSdspR2(uint32_t left, const uint32_t* const top) {
|
static uint32_t Predictor5_MIPSdspR2(const uint32_t* const left,
|
||||||
return Average3(left, top[0], top[1]);
|
const uint32_t* const top) {
|
||||||
|
return Average3(*left, top[0], top[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t Predictor6_MIPSdspR2(uint32_t left, const uint32_t* const top) {
|
static uint32_t Predictor6_MIPSdspR2(const uint32_t* const left,
|
||||||
return Average2(left, top[-1]);
|
const uint32_t* const top) {
|
||||||
|
return Average2(*left, top[-1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t Predictor7_MIPSdspR2(uint32_t left, const uint32_t* const top) {
|
static uint32_t Predictor7_MIPSdspR2(const uint32_t* const left,
|
||||||
return Average2(left, top[0]);
|
const uint32_t* const top) {
|
||||||
|
return Average2(*left, top[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t Predictor8_MIPSdspR2(uint32_t left, const uint32_t* const top) {
|
static uint32_t Predictor8_MIPSdspR2(const uint32_t* const left,
|
||||||
|
const uint32_t* const top) {
|
||||||
(void)left;
|
(void)left;
|
||||||
return Average2(top[-1], top[0]);
|
return Average2(top[-1], top[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t Predictor9_MIPSdspR2(uint32_t left, const uint32_t* const top) {
|
static uint32_t Predictor9_MIPSdspR2(const uint32_t* const left,
|
||||||
|
const uint32_t* const top) {
|
||||||
(void)left;
|
(void)left;
|
||||||
return Average2(top[0], top[1]);
|
return Average2(top[0], top[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t Predictor10_MIPSdspR2(uint32_t left,
|
static uint32_t Predictor10_MIPSdspR2(const uint32_t* const left,
|
||||||
const uint32_t* const top) {
|
const uint32_t* const top) {
|
||||||
return Average4(left, top[-1], top[0], top[1]);
|
return Average4(*left, top[-1], top[0], top[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t Predictor11_MIPSdspR2(uint32_t left,
|
static uint32_t Predictor11_MIPSdspR2(const uint32_t* const left,
|
||||||
const uint32_t* const top) {
|
const uint32_t* const top) {
|
||||||
return Select(top[0], left, top[-1]);
|
return Select(top[0], *left, top[-1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t Predictor12_MIPSdspR2(uint32_t left,
|
static uint32_t Predictor12_MIPSdspR2(const uint32_t* const left,
|
||||||
const uint32_t* const top) {
|
const uint32_t* const top) {
|
||||||
return ClampedAddSubtractFull(left, top[0], top[-1]);
|
return ClampedAddSubtractFull(*left, top[0], top[-1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t Predictor13_MIPSdspR2(uint32_t left,
|
static uint32_t Predictor13_MIPSdspR2(const uint32_t* const left,
|
||||||
const uint32_t* const top) {
|
const uint32_t* const top) {
|
||||||
return ClampedAddSubtractHalf(left, top[0], top[-1]);
|
return ClampedAddSubtractHalf(*left, top[0], top[-1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add green to blue and red channels (i.e. perform the inverse transform of
|
// Add green to blue and red channels (i.e. perform the inverse transform of
|
||||||
|
@ -188,17 +188,21 @@ static WEBP_INLINE uint32_t Average3_NEON(uint32_t a0, uint32_t a1,
|
|||||||
return avg;
|
return avg;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t Predictor5_NEON(uint32_t left, const uint32_t* const top) {
|
static uint32_t Predictor5_NEON(const uint32_t* const left,
|
||||||
return Average3_NEON(left, top[0], top[1]);
|
const uint32_t* const top) {
|
||||||
|
return Average3_NEON(*left, top[0], top[1]);
|
||||||
}
|
}
|
||||||
static uint32_t Predictor6_NEON(uint32_t left, const uint32_t* const top) {
|
static uint32_t Predictor6_NEON(const uint32_t* const left,
|
||||||
return Average2_NEON(left, top[-1]);
|
const uint32_t* const top) {
|
||||||
|
return Average2_NEON(*left, top[-1]);
|
||||||
}
|
}
|
||||||
static uint32_t Predictor7_NEON(uint32_t left, const uint32_t* const top) {
|
static uint32_t Predictor7_NEON(const uint32_t* const left,
|
||||||
return Average2_NEON(left, top[0]);
|
const uint32_t* const top) {
|
||||||
|
return Average2_NEON(*left, top[0]);
|
||||||
}
|
}
|
||||||
static uint32_t Predictor13_NEON(uint32_t left, const uint32_t* const top) {
|
static uint32_t Predictor13_NEON(const uint32_t* const left,
|
||||||
return ClampedAddSubtractHalf_NEON(left, top[0], top[-1]);
|
const uint32_t* const top) {
|
||||||
|
return ClampedAddSubtractHalf_NEON(*left, top[0], top[-1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Batch versions of those functions.
|
// Batch versions of those functions.
|
||||||
|
@ -138,42 +138,51 @@ static WEBP_INLINE uint32_t Average4_SSE2(uint32_t a0, uint32_t a1,
|
|||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t Predictor5_SSE2(uint32_t left, const uint32_t* const top) {
|
static uint32_t Predictor5_SSE2(const uint32_t* const left,
|
||||||
const uint32_t pred = Average3_SSE2(left, top[0], top[1]);
|
const uint32_t* const top) {
|
||||||
|
const uint32_t pred = Average3_SSE2(*left, top[0], top[1]);
|
||||||
return pred;
|
return pred;
|
||||||
}
|
}
|
||||||
static uint32_t Predictor6_SSE2(uint32_t left, const uint32_t* const top) {
|
static uint32_t Predictor6_SSE2(const uint32_t* const left,
|
||||||
const uint32_t pred = Average2_SSE2(left, top[-1]);
|
const uint32_t* const top) {
|
||||||
|
const uint32_t pred = Average2_SSE2(*left, top[-1]);
|
||||||
return pred;
|
return pred;
|
||||||
}
|
}
|
||||||
static uint32_t Predictor7_SSE2(uint32_t left, const uint32_t* const top) {
|
static uint32_t Predictor7_SSE2(const uint32_t* const left,
|
||||||
const uint32_t pred = Average2_SSE2(left, top[0]);
|
const uint32_t* const top) {
|
||||||
|
const uint32_t pred = Average2_SSE2(*left, top[0]);
|
||||||
return pred;
|
return pred;
|
||||||
}
|
}
|
||||||
static uint32_t Predictor8_SSE2(uint32_t left, const uint32_t* const top) {
|
static uint32_t Predictor8_SSE2(const uint32_t* const left,
|
||||||
|
const uint32_t* const top) {
|
||||||
const uint32_t pred = Average2_SSE2(top[-1], top[0]);
|
const uint32_t pred = Average2_SSE2(top[-1], top[0]);
|
||||||
(void)left;
|
(void)left;
|
||||||
return pred;
|
return pred;
|
||||||
}
|
}
|
||||||
static uint32_t Predictor9_SSE2(uint32_t left, const uint32_t* const top) {
|
static uint32_t Predictor9_SSE2(const uint32_t* const left,
|
||||||
|
const uint32_t* const top) {
|
||||||
const uint32_t pred = Average2_SSE2(top[0], top[1]);
|
const uint32_t pred = Average2_SSE2(top[0], top[1]);
|
||||||
(void)left;
|
(void)left;
|
||||||
return pred;
|
return pred;
|
||||||
}
|
}
|
||||||
static uint32_t Predictor10_SSE2(uint32_t left, const uint32_t* const top) {
|
static uint32_t Predictor10_SSE2(const uint32_t* const left,
|
||||||
const uint32_t pred = Average4_SSE2(left, top[-1], top[0], top[1]);
|
const uint32_t* const top) {
|
||||||
|
const uint32_t pred = Average4_SSE2(*left, top[-1], top[0], top[1]);
|
||||||
return pred;
|
return pred;
|
||||||
}
|
}
|
||||||
static uint32_t Predictor11_SSE2(uint32_t left, const uint32_t* const top) {
|
static uint32_t Predictor11_SSE2(const uint32_t* const left,
|
||||||
const uint32_t pred = Select_SSE2(top[0], left, top[-1]);
|
const uint32_t* const top) {
|
||||||
|
const uint32_t pred = Select_SSE2(top[0], *left, top[-1]);
|
||||||
return pred;
|
return pred;
|
||||||
}
|
}
|
||||||
static uint32_t Predictor12_SSE2(uint32_t left, const uint32_t* const top) {
|
static uint32_t Predictor12_SSE2(const uint32_t* const left,
|
||||||
const uint32_t pred = ClampedAddSubtractFull_SSE2(left, top[0], top[-1]);
|
const uint32_t* const top) {
|
||||||
|
const uint32_t pred = ClampedAddSubtractFull_SSE2(*left, top[0], top[-1]);
|
||||||
return pred;
|
return pred;
|
||||||
}
|
}
|
||||||
static uint32_t Predictor13_SSE2(uint32_t left, const uint32_t* const top) {
|
static uint32_t Predictor13_SSE2(const uint32_t* const left,
|
||||||
const uint32_t pred = ClampedAddSubtractHalf_SSE2(left, top[0], top[-1]);
|
const uint32_t* const top) {
|
||||||
|
const uint32_t pred = ClampedAddSubtractHalf_SSE2(*left, top[0], top[-1]);
|
||||||
return pred;
|
return pred;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,6 +14,10 @@
|
|||||||
#ifndef WEBP_DSP_MSA_MACRO_H_
|
#ifndef WEBP_DSP_MSA_MACRO_H_
|
||||||
#define WEBP_DSP_MSA_MACRO_H_
|
#define WEBP_DSP_MSA_MACRO_H_
|
||||||
|
|
||||||
|
#include "src/dsp/dsp.h"
|
||||||
|
|
||||||
|
#if defined(WEBP_USE_MSA)
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <msa.h>
|
#include <msa.h>
|
||||||
|
|
||||||
@ -1389,4 +1393,5 @@ static WEBP_INLINE uint32_t func_hadd_uh_u32(v8u16 in) {
|
|||||||
} while (0)
|
} while (0)
|
||||||
#define AVER_UB2_UB(...) AVER_UB2(v16u8, __VA_ARGS__)
|
#define AVER_UB2_UB(...) AVER_UB2(v16u8, __VA_ARGS__)
|
||||||
|
|
||||||
|
#endif // WEBP_USE_MSA
|
||||||
#endif // WEBP_DSP_MSA_MACRO_H_
|
#endif // WEBP_DSP_MSA_MACRO_H_
|
||||||
|
@ -12,10 +12,12 @@
|
|||||||
#ifndef WEBP_DSP_NEON_H_
|
#ifndef WEBP_DSP_NEON_H_
|
||||||
#define WEBP_DSP_NEON_H_
|
#define WEBP_DSP_NEON_H_
|
||||||
|
|
||||||
#include <arm_neon.h>
|
|
||||||
|
|
||||||
#include "src/dsp/dsp.h"
|
#include "src/dsp/dsp.h"
|
||||||
|
|
||||||
|
#if defined(WEBP_USE_NEON)
|
||||||
|
|
||||||
|
#include <arm_neon.h>
|
||||||
|
|
||||||
// Right now, some intrinsics functions seem slower, so we disable them
|
// Right now, some intrinsics functions seem slower, so we disable them
|
||||||
// everywhere except newer clang/gcc or aarch64 where the inline assembly is
|
// everywhere except newer clang/gcc or aarch64 where the inline assembly is
|
||||||
// incompatible.
|
// incompatible.
|
||||||
@ -98,4 +100,5 @@ static WEBP_INLINE int32x4x4_t Transpose4x4_NEON(const int32x4x4_t rows) {
|
|||||||
} while (0)
|
} while (0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#endif // WEBP_USE_NEON
|
||||||
#endif // WEBP_DSP_NEON_H_
|
#endif // WEBP_DSP_NEON_H_
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
// inline YUV<->RGB conversion function
|
// inline YUV<->RGB conversion function
|
||||||
//
|
//
|
||||||
// The exact naming is Y'CbCr, following the ITU-R BT.601 standard.
|
// The exact naming is Y'CbCr, following the ITU-R BT.601 standard.
|
||||||
// More information at: http://en.wikipedia.org/wiki/YCbCr
|
// More information at: https://en.wikipedia.org/wiki/YCbCr
|
||||||
// Y = 0.2569 * R + 0.5044 * G + 0.0979 * B + 16
|
// Y = 0.2569 * R + 0.5044 * G + 0.0979 * B + 16
|
||||||
// U = -0.1483 * R - 0.2911 * G + 0.4394 * B + 128
|
// U = -0.1483 * R - 0.2911 * G + 0.4394 * B + 128
|
||||||
// V = 0.4394 * R - 0.3679 * G - 0.0715 * B + 128
|
// V = 0.4394 * R - 0.3679 * G - 0.0715 * B + 128
|
||||||
|
@ -577,7 +577,7 @@ static int BackwardReferencesHashChainDistanceOnly(
|
|||||||
(CostModel*)WebPSafeCalloc(1ULL, cost_model_size);
|
(CostModel*)WebPSafeCalloc(1ULL, cost_model_size);
|
||||||
VP8LColorCache hashers;
|
VP8LColorCache hashers;
|
||||||
CostManager* cost_manager =
|
CostManager* cost_manager =
|
||||||
(CostManager*)WebPSafeMalloc(1ULL, sizeof(*cost_manager));
|
(CostManager*)WebPSafeCalloc(1ULL, sizeof(*cost_manager));
|
||||||
int offset_prev = -1, len_prev = -1;
|
int offset_prev = -1, len_prev = -1;
|
||||||
double offset_cost = -1;
|
double offset_cost = -1;
|
||||||
int first_offset_is_constant = -1; // initialized with 'impossible' value
|
int first_offset_is_constant = -1; // initialized with 'impossible' value
|
||||||
|
@ -976,15 +976,16 @@ static int GetBackwardReferences(int width, int height,
|
|||||||
const VP8LHashChain* const hash_chain_tmp =
|
const VP8LHashChain* const hash_chain_tmp =
|
||||||
(lz77_types_best[i] == kLZ77Standard) ? hash_chain : &hash_chain_box;
|
(lz77_types_best[i] == kLZ77Standard) ? hash_chain : &hash_chain_box;
|
||||||
const int cache_bits = (i == 1) ? 0 : *cache_bits_best;
|
const int cache_bits = (i == 1) ? 0 : *cache_bits_best;
|
||||||
if (VP8LBackwardReferencesTraceBackwards(width, height, argb, cache_bits,
|
double bit_cost_trace;
|
||||||
hash_chain_tmp, &refs[i],
|
if (!VP8LBackwardReferencesTraceBackwards(width, height, argb, cache_bits,
|
||||||
refs_tmp)) {
|
hash_chain_tmp, &refs[i],
|
||||||
double bit_cost_trace;
|
refs_tmp)) {
|
||||||
VP8LHistogramCreate(histo, refs_tmp, cache_bits);
|
goto Error;
|
||||||
bit_cost_trace = VP8LHistogramEstimateBits(histo);
|
}
|
||||||
if (bit_cost_trace < bit_costs_best[i]) {
|
VP8LHistogramCreate(histo, refs_tmp, cache_bits);
|
||||||
BackwardRefsSwap(refs_tmp, &refs[i]);
|
bit_cost_trace = VP8LHistogramEstimateBits(histo);
|
||||||
}
|
if (bit_cost_trace < bit_costs_best[i]) {
|
||||||
|
BackwardRefsSwap(refs_tmp, &refs[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -778,6 +778,7 @@ int VP8EncTokenLoop(VP8Encoder* const enc) {
|
|||||||
// Roughly refresh the proba eight times per pass
|
// Roughly refresh the proba eight times per pass
|
||||||
int max_count = (enc->mb_w_ * enc->mb_h_) >> 3;
|
int max_count = (enc->mb_w_ * enc->mb_h_) >> 3;
|
||||||
int num_pass_left = enc->config_->pass;
|
int num_pass_left = enc->config_->pass;
|
||||||
|
int remaining_progress = 40; // percents
|
||||||
const int do_search = enc->do_search_;
|
const int do_search = enc->do_search_;
|
||||||
VP8EncIterator it;
|
VP8EncIterator it;
|
||||||
VP8EncProba* const proba = &enc->proba_;
|
VP8EncProba* const proba = &enc->proba_;
|
||||||
@ -805,6 +806,9 @@ int VP8EncTokenLoop(VP8Encoder* const enc) {
|
|||||||
uint64_t size_p0 = 0;
|
uint64_t size_p0 = 0;
|
||||||
uint64_t distortion = 0;
|
uint64_t distortion = 0;
|
||||||
int cnt = max_count;
|
int cnt = max_count;
|
||||||
|
// The final number of passes is not trivial to know in advance.
|
||||||
|
const int pass_progress = remaining_progress / (2 + num_pass_left);
|
||||||
|
remaining_progress -= pass_progress;
|
||||||
VP8IteratorInit(enc, &it);
|
VP8IteratorInit(enc, &it);
|
||||||
SetLoopParams(enc, stats.q);
|
SetLoopParams(enc, stats.q);
|
||||||
if (is_last_pass) {
|
if (is_last_pass) {
|
||||||
@ -832,7 +836,7 @@ int VP8EncTokenLoop(VP8Encoder* const enc) {
|
|||||||
StoreSideInfo(&it);
|
StoreSideInfo(&it);
|
||||||
VP8StoreFilterStats(&it);
|
VP8StoreFilterStats(&it);
|
||||||
VP8IteratorExport(&it);
|
VP8IteratorExport(&it);
|
||||||
ok = VP8IteratorProgress(&it, 20);
|
ok = VP8IteratorProgress(&it, pass_progress);
|
||||||
}
|
}
|
||||||
VP8IteratorSaveBoundary(&it);
|
VP8IteratorSaveBoundary(&it);
|
||||||
} while (ok && VP8IteratorNext(&it));
|
} while (ok && VP8IteratorNext(&it));
|
||||||
@ -878,7 +882,8 @@ int VP8EncTokenLoop(VP8Encoder* const enc) {
|
|||||||
ok = VP8EmitTokens(&enc->tokens_, enc->parts_ + 0,
|
ok = VP8EmitTokens(&enc->tokens_, enc->parts_ + 0,
|
||||||
(const uint8_t*)proba->coeffs_, 1);
|
(const uint8_t*)proba->coeffs_, 1);
|
||||||
}
|
}
|
||||||
ok = ok && WebPReportProgress(enc->pic_, enc->percent_ + 20, &enc->percent_);
|
ok = ok && WebPReportProgress(enc->pic_, enc->percent_ + remaining_progress,
|
||||||
|
&enc->percent_);
|
||||||
return PostLoopFinalize(&it, ok);
|
return PostLoopFinalize(&it, ok);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -249,7 +249,7 @@ static WEBP_INLINE void GetResidual(
|
|||||||
} else if (x == 0) {
|
} else if (x == 0) {
|
||||||
predict = upper_row[x]; // Top.
|
predict = upper_row[x]; // Top.
|
||||||
} else {
|
} else {
|
||||||
predict = pred_func(current_row[x - 1], upper_row + x);
|
predict = pred_func(¤t_row[x - 1], upper_row + x);
|
||||||
}
|
}
|
||||||
#if (WEBP_NEAR_LOSSLESS == 1)
|
#if (WEBP_NEAR_LOSSLESS == 1)
|
||||||
if (max_quantization == 1 || mode == 0 || y == 0 || y == height - 1 ||
|
if (max_quantization == 1 || mode == 0 || y == 0 || y == height - 1 ||
|
||||||
|
@ -32,7 +32,7 @@ extern "C" {
|
|||||||
// version numbers
|
// version numbers
|
||||||
#define ENC_MAJ_VERSION 1
|
#define ENC_MAJ_VERSION 1
|
||||||
#define ENC_MIN_VERSION 2
|
#define ENC_MIN_VERSION 2
|
||||||
#define ENC_REV_VERSION 1
|
#define ENC_REV_VERSION 2
|
||||||
|
|
||||||
enum { MAX_LF_LEVELS = 64, // Maximum loop filter level
|
enum { MAX_LF_LEVELS = 64, // Maximum loop filter level
|
||||||
MAX_VARIABLE_LEVEL = 67, // last (inclusive) level with variable cost
|
MAX_VARIABLE_LEVEL = 67, // last (inclusive) level with variable cost
|
||||||
|
@ -1912,11 +1912,16 @@ WebPEncodingError VP8LEncodeStream(const WebPConfig* const config,
|
|||||||
const WebPWorkerInterface* const worker_interface = WebPGetWorkerInterface();
|
const WebPWorkerInterface* const worker_interface = WebPGetWorkerInterface();
|
||||||
int ok_main;
|
int ok_main;
|
||||||
|
|
||||||
|
if (enc_main == NULL || !VP8LBitWriterInit(&bw_side, 0)) {
|
||||||
|
WebPEncodingSetError(picture, VP8_ENC_ERROR_OUT_OF_MEMORY);
|
||||||
|
VP8LEncoderDelete(enc_main);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
// Analyze image (entropy, num_palettes etc)
|
// Analyze image (entropy, num_palettes etc)
|
||||||
if (enc_main == NULL ||
|
if (!EncoderAnalyze(enc_main, crunch_configs, &num_crunch_configs_main,
|
||||||
!EncoderAnalyze(enc_main, crunch_configs, &num_crunch_configs_main,
|
|
||||||
&red_and_blue_always_zero) ||
|
&red_and_blue_always_zero) ||
|
||||||
!EncoderInit(enc_main) || !VP8LBitWriterInit(&bw_side, 0)) {
|
!EncoderInit(enc_main)) {
|
||||||
err = VP8_ENC_ERROR_OUT_OF_MEMORY;
|
err = VP8_ENC_ERROR_OUT_OF_MEMORY;
|
||||||
goto Error;
|
goto Error;
|
||||||
}
|
}
|
||||||
|
@ -6,8 +6,8 @@
|
|||||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||||
|
|
||||||
VS_VERSION_INFO VERSIONINFO
|
VS_VERSION_INFO VERSIONINFO
|
||||||
FILEVERSION 1,0,2,1
|
FILEVERSION 1,0,2,2
|
||||||
PRODUCTVERSION 1,0,2,1
|
PRODUCTVERSION 1,0,2,2
|
||||||
FILEFLAGSMASK 0x3fL
|
FILEFLAGSMASK 0x3fL
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
FILEFLAGS 0x1L
|
FILEFLAGS 0x1L
|
||||||
@ -24,12 +24,12 @@ BEGIN
|
|||||||
BEGIN
|
BEGIN
|
||||||
VALUE "CompanyName", "Google, Inc."
|
VALUE "CompanyName", "Google, Inc."
|
||||||
VALUE "FileDescription", "libwebp DLL"
|
VALUE "FileDescription", "libwebp DLL"
|
||||||
VALUE "FileVersion", "1.2.1"
|
VALUE "FileVersion", "1.2.2"
|
||||||
VALUE "InternalName", "libwebp.dll"
|
VALUE "InternalName", "libwebp.dll"
|
||||||
VALUE "LegalCopyright", "Copyright (C) 2021"
|
VALUE "LegalCopyright", "Copyright (C) 2021"
|
||||||
VALUE "OriginalFilename", "libwebp.dll"
|
VALUE "OriginalFilename", "libwebp.dll"
|
||||||
VALUE "ProductName", "WebP Image Codec"
|
VALUE "ProductName", "WebP Image Codec"
|
||||||
VALUE "ProductVersion", "1.2.1"
|
VALUE "ProductVersion", "1.2.2"
|
||||||
END
|
END
|
||||||
END
|
END
|
||||||
BLOCK "VarFileInfo"
|
BLOCK "VarFileInfo"
|
||||||
|
@ -6,8 +6,8 @@
|
|||||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||||
|
|
||||||
VS_VERSION_INFO VERSIONINFO
|
VS_VERSION_INFO VERSIONINFO
|
||||||
FILEVERSION 1,0,2,1
|
FILEVERSION 1,0,2,2
|
||||||
PRODUCTVERSION 1,0,2,1
|
PRODUCTVERSION 1,0,2,2
|
||||||
FILEFLAGSMASK 0x3fL
|
FILEFLAGSMASK 0x3fL
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
FILEFLAGS 0x1L
|
FILEFLAGS 0x1L
|
||||||
@ -24,12 +24,12 @@ BEGIN
|
|||||||
BEGIN
|
BEGIN
|
||||||
VALUE "CompanyName", "Google, Inc."
|
VALUE "CompanyName", "Google, Inc."
|
||||||
VALUE "FileDescription", "libwebpdecoder DLL"
|
VALUE "FileDescription", "libwebpdecoder DLL"
|
||||||
VALUE "FileVersion", "1.2.1"
|
VALUE "FileVersion", "1.2.2"
|
||||||
VALUE "InternalName", "libwebpdecoder.dll"
|
VALUE "InternalName", "libwebpdecoder.dll"
|
||||||
VALUE "LegalCopyright", "Copyright (C) 2021"
|
VALUE "LegalCopyright", "Copyright (C) 2021"
|
||||||
VALUE "OriginalFilename", "libwebpdecoder.dll"
|
VALUE "OriginalFilename", "libwebpdecoder.dll"
|
||||||
VALUE "ProductName", "WebP Image Decoder"
|
VALUE "ProductName", "WebP Image Decoder"
|
||||||
VALUE "ProductVersion", "1.2.1"
|
VALUE "ProductVersion", "1.2.2"
|
||||||
END
|
END
|
||||||
END
|
END
|
||||||
BLOCK "VarFileInfo"
|
BLOCK "VarFileInfo"
|
||||||
|
@ -17,6 +17,6 @@ noinst_HEADERS =
|
|||||||
noinst_HEADERS += ../webp/format_constants.h
|
noinst_HEADERS += ../webp/format_constants.h
|
||||||
|
|
||||||
libwebpmux_la_LIBADD = ../libwebp.la
|
libwebpmux_la_LIBADD = ../libwebp.la
|
||||||
libwebpmux_la_LDFLAGS = -no-undefined -version-info 3:7:0 -lm
|
libwebpmux_la_LDFLAGS = -no-undefined -version-info 3:8:0 -lm
|
||||||
libwebpmuxincludedir = $(includedir)/webp
|
libwebpmuxincludedir = $(includedir)/webp
|
||||||
pkgconfig_DATA = libwebpmux.pc
|
pkgconfig_DATA = libwebpmux.pc
|
||||||
|
@ -6,8 +6,8 @@
|
|||||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||||
|
|
||||||
VS_VERSION_INFO VERSIONINFO
|
VS_VERSION_INFO VERSIONINFO
|
||||||
FILEVERSION 1,0,2,1
|
FILEVERSION 1,0,2,2
|
||||||
PRODUCTVERSION 1,0,2,1
|
PRODUCTVERSION 1,0,2,2
|
||||||
FILEFLAGSMASK 0x3fL
|
FILEFLAGSMASK 0x3fL
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
FILEFLAGS 0x1L
|
FILEFLAGS 0x1L
|
||||||
@ -24,12 +24,12 @@ BEGIN
|
|||||||
BEGIN
|
BEGIN
|
||||||
VALUE "CompanyName", "Google, Inc."
|
VALUE "CompanyName", "Google, Inc."
|
||||||
VALUE "FileDescription", "libwebpmux DLL"
|
VALUE "FileDescription", "libwebpmux DLL"
|
||||||
VALUE "FileVersion", "1.2.1"
|
VALUE "FileVersion", "1.2.2"
|
||||||
VALUE "InternalName", "libwebpmux.dll"
|
VALUE "InternalName", "libwebpmux.dll"
|
||||||
VALUE "LegalCopyright", "Copyright (C) 2021"
|
VALUE "LegalCopyright", "Copyright (C) 2021"
|
||||||
VALUE "OriginalFilename", "libwebpmux.dll"
|
VALUE "OriginalFilename", "libwebpmux.dll"
|
||||||
VALUE "ProductName", "WebP Image Muxer"
|
VALUE "ProductName", "WebP Image Muxer"
|
||||||
VALUE "ProductVersion", "1.2.1"
|
VALUE "ProductVersion", "1.2.2"
|
||||||
END
|
END
|
||||||
END
|
END
|
||||||
BLOCK "VarFileInfo"
|
BLOCK "VarFileInfo"
|
||||||
|
@ -29,7 +29,7 @@ extern "C" {
|
|||||||
|
|
||||||
#define MUX_MAJ_VERSION 1
|
#define MUX_MAJ_VERSION 1
|
||||||
#define MUX_MIN_VERSION 2
|
#define MUX_MIN_VERSION 2
|
||||||
#define MUX_REV_VERSION 1
|
#define MUX_REV_VERSION 2
|
||||||
|
|
||||||
// Chunk object.
|
// Chunk object.
|
||||||
typedef struct WebPChunk WebPChunk;
|
typedef struct WebPChunk WebPChunk;
|
||||||
|
@ -161,7 +161,7 @@ static void SetBitDepths(const HuffmanTree* const tree,
|
|||||||
// especially when population counts are longer than 2**tree_limit, but
|
// especially when population counts are longer than 2**tree_limit, but
|
||||||
// we are not planning to use this with extremely long blocks.
|
// we are not planning to use this with extremely long blocks.
|
||||||
//
|
//
|
||||||
// See http://en.wikipedia.org/wiki/Huffman_coding
|
// See https://en.wikipedia.org/wiki/Huffman_coding
|
||||||
static void GenerateOptimalTree(const uint32_t* const histogram,
|
static void GenerateOptimalTree(const uint32_t* const histogram,
|
||||||
int histogram_size,
|
int histogram_size,
|
||||||
HuffmanTree* tree, int tree_depth_limit,
|
HuffmanTree* tree, int tree_depth_limit,
|
||||||
|
@ -177,21 +177,24 @@ static int BuildHuffmanTable(HuffmanCode* const root_table, int root_bits,
|
|||||||
if (num_open < 0) {
|
if (num_open < 0) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (root_table == NULL) continue;
|
|
||||||
for (; count[len] > 0; --count[len]) {
|
for (; count[len] > 0; --count[len]) {
|
||||||
HuffmanCode code;
|
HuffmanCode code;
|
||||||
if ((key & mask) != low) {
|
if ((key & mask) != low) {
|
||||||
table += table_size;
|
if (root_table != NULL) table += table_size;
|
||||||
table_bits = NextTableBitSize(count, len, root_bits);
|
table_bits = NextTableBitSize(count, len, root_bits);
|
||||||
table_size = 1 << table_bits;
|
table_size = 1 << table_bits;
|
||||||
total_size += table_size;
|
total_size += table_size;
|
||||||
low = key & mask;
|
low = key & mask;
|
||||||
root_table[low].bits = (uint8_t)(table_bits + root_bits);
|
if (root_table != NULL) {
|
||||||
root_table[low].value = (uint16_t)((table - root_table) - low);
|
root_table[low].bits = (uint8_t)(table_bits + root_bits);
|
||||||
|
root_table[low].value = (uint16_t)((table - root_table) - low);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (root_table != NULL) {
|
||||||
|
code.bits = (uint8_t)(len - root_bits);
|
||||||
|
code.value = (uint16_t)sorted[symbol++];
|
||||||
|
ReplicateValue(&table[key >> root_bits], step, table_size, code);
|
||||||
}
|
}
|
||||||
code.bits = (uint8_t)(len - root_bits);
|
|
||||||
code.value = (uint16_t)sorted[symbol++];
|
|
||||||
ReplicateValue(&table[key >> root_bits], step, table_size, code);
|
|
||||||
key = GetNextKey(key, len);
|
key = GetNextKey(key, len);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -211,25 +214,83 @@ static int BuildHuffmanTable(HuffmanCode* const root_table, int root_bits,
|
|||||||
((1 << MAX_CACHE_BITS) + NUM_LITERAL_CODES + NUM_LENGTH_CODES)
|
((1 << MAX_CACHE_BITS) + NUM_LITERAL_CODES + NUM_LENGTH_CODES)
|
||||||
// Cut-off value for switching between heap and stack allocation.
|
// Cut-off value for switching between heap and stack allocation.
|
||||||
#define SORTED_SIZE_CUTOFF 512
|
#define SORTED_SIZE_CUTOFF 512
|
||||||
int VP8LBuildHuffmanTable(HuffmanCode* const root_table, int root_bits,
|
int VP8LBuildHuffmanTable(HuffmanTables* const root_table, int root_bits,
|
||||||
const int code_lengths[], int code_lengths_size) {
|
const int code_lengths[], int code_lengths_size) {
|
||||||
int total_size;
|
const int total_size =
|
||||||
|
BuildHuffmanTable(NULL, root_bits, code_lengths, code_lengths_size, NULL);
|
||||||
assert(code_lengths_size <= MAX_CODE_LENGTHS_SIZE);
|
assert(code_lengths_size <= MAX_CODE_LENGTHS_SIZE);
|
||||||
if (root_table == NULL) {
|
if (total_size == 0 || root_table == NULL) return total_size;
|
||||||
total_size = BuildHuffmanTable(NULL, root_bits,
|
|
||||||
code_lengths, code_lengths_size, NULL);
|
if (root_table->curr_segment->curr_table + total_size >=
|
||||||
} else if (code_lengths_size <= SORTED_SIZE_CUTOFF) {
|
root_table->curr_segment->start + root_table->curr_segment->size) {
|
||||||
|
// If 'root_table' does not have enough memory, allocate a new segment.
|
||||||
|
// The available part of root_table->curr_segment is left unused because we
|
||||||
|
// need a contiguous buffer.
|
||||||
|
const int segment_size = root_table->curr_segment->size;
|
||||||
|
struct HuffmanTablesSegment* next =
|
||||||
|
(HuffmanTablesSegment*)WebPSafeMalloc(1, sizeof(*next));
|
||||||
|
if (next == NULL) return 0;
|
||||||
|
// Fill the new segment.
|
||||||
|
// We need at least 'total_size' but if that value is small, it is better to
|
||||||
|
// allocate a big chunk to prevent more allocations later. 'segment_size' is
|
||||||
|
// therefore chosen (any other arbitrary value could be chosen).
|
||||||
|
next->size = total_size > segment_size ? total_size : segment_size;
|
||||||
|
next->start =
|
||||||
|
(HuffmanCode*)WebPSafeMalloc(next->size, sizeof(*next->start));
|
||||||
|
if (next->start == NULL) {
|
||||||
|
WebPSafeFree(next);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
next->curr_table = next->start;
|
||||||
|
next->next = NULL;
|
||||||
|
// Point to the new segment.
|
||||||
|
root_table->curr_segment->next = next;
|
||||||
|
root_table->curr_segment = next;
|
||||||
|
}
|
||||||
|
if (code_lengths_size <= SORTED_SIZE_CUTOFF) {
|
||||||
// use local stack-allocated array.
|
// use local stack-allocated array.
|
||||||
uint16_t sorted[SORTED_SIZE_CUTOFF];
|
uint16_t sorted[SORTED_SIZE_CUTOFF];
|
||||||
total_size = BuildHuffmanTable(root_table, root_bits,
|
BuildHuffmanTable(root_table->curr_segment->curr_table, root_bits,
|
||||||
code_lengths, code_lengths_size, sorted);
|
code_lengths, code_lengths_size, sorted);
|
||||||
} else { // rare case. Use heap allocation.
|
} else { // rare case. Use heap allocation.
|
||||||
uint16_t* const sorted =
|
uint16_t* const sorted =
|
||||||
(uint16_t*)WebPSafeMalloc(code_lengths_size, sizeof(*sorted));
|
(uint16_t*)WebPSafeMalloc(code_lengths_size, sizeof(*sorted));
|
||||||
if (sorted == NULL) return 0;
|
if (sorted == NULL) return 0;
|
||||||
total_size = BuildHuffmanTable(root_table, root_bits,
|
BuildHuffmanTable(root_table->curr_segment->curr_table, root_bits,
|
||||||
code_lengths, code_lengths_size, sorted);
|
code_lengths, code_lengths_size, sorted);
|
||||||
WebPSafeFree(sorted);
|
WebPSafeFree(sorted);
|
||||||
}
|
}
|
||||||
return total_size;
|
return total_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int VP8LHuffmanTablesAllocate(int size, HuffmanTables* huffman_tables) {
|
||||||
|
// Have 'segment' point to the first segment for now, 'root'.
|
||||||
|
HuffmanTablesSegment* const root = &huffman_tables->root;
|
||||||
|
huffman_tables->curr_segment = root;
|
||||||
|
// Allocate root.
|
||||||
|
root->start = (HuffmanCode*)WebPSafeMalloc(size, sizeof(*root->start));
|
||||||
|
if (root->start == NULL) return 0;
|
||||||
|
root->curr_table = root->start;
|
||||||
|
root->next = NULL;
|
||||||
|
root->size = size;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VP8LHuffmanTablesDeallocate(HuffmanTables* const huffman_tables) {
|
||||||
|
HuffmanTablesSegment *current, *next;
|
||||||
|
if (huffman_tables == NULL) return;
|
||||||
|
// Free the root node.
|
||||||
|
current = &huffman_tables->root;
|
||||||
|
next = current->next;
|
||||||
|
WebPSafeFree(current->start);
|
||||||
|
current->start = NULL;
|
||||||
|
current->next = NULL;
|
||||||
|
current = next;
|
||||||
|
// Free the following nodes.
|
||||||
|
while (current != NULL) {
|
||||||
|
next = current->next;
|
||||||
|
WebPSafeFree(current->start);
|
||||||
|
WebPSafeFree(current);
|
||||||
|
current = next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -43,6 +43,29 @@ typedef struct {
|
|||||||
// or non-literal symbol otherwise
|
// or non-literal symbol otherwise
|
||||||
} HuffmanCode32;
|
} HuffmanCode32;
|
||||||
|
|
||||||
|
// Contiguous memory segment of HuffmanCodes.
|
||||||
|
typedef struct HuffmanTablesSegment {
|
||||||
|
HuffmanCode* start;
|
||||||
|
// Pointer to where we are writing into the segment. Starts at 'start' and
|
||||||
|
// cannot go beyond 'start' + 'size'.
|
||||||
|
HuffmanCode* curr_table;
|
||||||
|
// Pointer to the next segment in the chain.
|
||||||
|
struct HuffmanTablesSegment* next;
|
||||||
|
int size;
|
||||||
|
} HuffmanTablesSegment;
|
||||||
|
|
||||||
|
// Chained memory segments of HuffmanCodes.
|
||||||
|
typedef struct HuffmanTables {
|
||||||
|
HuffmanTablesSegment root;
|
||||||
|
// Currently processed segment. At first, this is 'root'.
|
||||||
|
HuffmanTablesSegment* curr_segment;
|
||||||
|
} HuffmanTables;
|
||||||
|
|
||||||
|
// Allocates a HuffmanTables with 'size' contiguous HuffmanCodes. Returns 0 on
|
||||||
|
// memory allocation error, 1 otherwise.
|
||||||
|
int VP8LHuffmanTablesAllocate(int size, HuffmanTables* huffman_tables);
|
||||||
|
void VP8LHuffmanTablesDeallocate(HuffmanTables* const huffman_tables);
|
||||||
|
|
||||||
#define HUFFMAN_PACKED_BITS 6
|
#define HUFFMAN_PACKED_BITS 6
|
||||||
#define HUFFMAN_PACKED_TABLE_SIZE (1u << HUFFMAN_PACKED_BITS)
|
#define HUFFMAN_PACKED_TABLE_SIZE (1u << HUFFMAN_PACKED_BITS)
|
||||||
|
|
||||||
@ -78,9 +101,7 @@ void VP8LHtreeGroupsFree(HTreeGroup* const htree_groups);
|
|||||||
// the huffman table.
|
// the huffman table.
|
||||||
// Returns built table size or 0 in case of error (invalid tree or
|
// Returns built table size or 0 in case of error (invalid tree or
|
||||||
// memory error).
|
// memory error).
|
||||||
// If root_table is NULL, it returns 0 if a lookup cannot be built, something
|
int VP8LBuildHuffmanTable(HuffmanTables* const root_table, int root_bits,
|
||||||
// > 0 otherwise (but not the table size).
|
|
||||||
int VP8LBuildHuffmanTable(HuffmanCode* const root_table, int root_bits,
|
|
||||||
const int code_lengths[], int code_lengths_size);
|
const int code_lengths[], int code_lengths_size);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
|
|
||||||
#define DFIX 4 // extra precision for ordered dithering
|
#define DFIX 4 // extra precision for ordered dithering
|
||||||
#define DSIZE 4 // dithering size (must be a power of two)
|
#define DSIZE 4 // dithering size (must be a power of two)
|
||||||
// cf. http://en.wikipedia.org/wiki/Ordered_dithering
|
// cf. https://en.wikipedia.org/wiki/Ordered_dithering
|
||||||
static const uint8_t kOrderedDither[DSIZE][DSIZE] = {
|
static const uint8_t kOrderedDither[DSIZE][DSIZE] = {
|
||||||
{ 0, 8, 2, 10 }, // coefficients are in DFIX fixed-point precision
|
{ 0, 8, 2, 10 }, // coefficients are in DFIX fixed-point precision
|
||||||
{ 12, 4, 14, 6 },
|
{ 12, 4, 14, 6 },
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
// alloc/free etc) is printed. For debugging/tuning purpose only (it's slow,
|
// alloc/free etc) is printed. For debugging/tuning purpose only (it's slow,
|
||||||
// and not multi-thread safe!).
|
// and not multi-thread safe!).
|
||||||
// An interesting alternative is valgrind's 'massif' tool:
|
// An interesting alternative is valgrind's 'massif' tool:
|
||||||
// http://valgrind.org/docs/manual/ms-manual.html
|
// https://valgrind.org/docs/manual/ms-manual.html
|
||||||
// Here is an example command line:
|
// Here is an example command line:
|
||||||
/* valgrind --tool=massif --massif-out-file=massif.out \
|
/* valgrind --tool=massif --massif-out-file=massif.out \
|
||||||
--stacks=yes --alloc-fn=WebPSafeMalloc --alloc-fn=WebPSafeCalloc
|
--stacks=yes --alloc-fn=WebPSafeMalloc --alloc-fn=WebPSafeCalloc
|
||||||
|
@ -85,7 +85,7 @@ WEBP_EXTERN uint8_t* WebPDecodeBGR(const uint8_t* data, size_t data_size,
|
|||||||
// Upon return, the Y buffer has a stride returned as '*stride', while U and V
|
// Upon return, the Y buffer has a stride returned as '*stride', while U and V
|
||||||
// have a common stride returned as '*uv_stride'.
|
// have a common stride returned as '*uv_stride'.
|
||||||
// Return NULL in case of error.
|
// Return NULL in case of error.
|
||||||
// (*) Also named Y'CbCr. See: http://en.wikipedia.org/wiki/YCbCr
|
// (*) Also named Y'CbCr. See: https://en.wikipedia.org/wiki/YCbCr
|
||||||
WEBP_EXTERN uint8_t* WebPDecodeYUV(const uint8_t* data, size_t data_size,
|
WEBP_EXTERN uint8_t* WebPDecodeYUV(const uint8_t* data, size_t data_size,
|
||||||
int* width, int* height,
|
int* width, int* height,
|
||||||
uint8_t** u, uint8_t** v,
|
uint8_t** u, uint8_t** v,
|
||||||
|
@ -79,6 +79,26 @@ if [[ -z "${SDK[$IOS]}" ]] || [[ ${SDK[$IOS]%%.*} -lt 8 ]]; then
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
#######################################
|
||||||
|
# Moves Headers/*.h to Headers/<framework>/
|
||||||
|
#
|
||||||
|
# Places framework headers in a subdirectory to avoid Xcode errors when using
|
||||||
|
# multiple frameworks:
|
||||||
|
# error: Multiple commands produce
|
||||||
|
# '.../Build/Products/Debug-iphoneos/include/types.h'
|
||||||
|
# Arguments:
|
||||||
|
# $1 - path to framework
|
||||||
|
#######################################
|
||||||
|
update_headers_path() {
|
||||||
|
local framework_name="$(basename ${1%.xcframework})"
|
||||||
|
local subdir
|
||||||
|
for d in $(find "$1" -path "*/Headers"); do
|
||||||
|
subdir="$d/$framework_name"
|
||||||
|
mkdir "$subdir"
|
||||||
|
mv "$d/"*.h "$subdir"
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
echo "Xcode Version: ${XCODE}"
|
echo "Xcode Version: ${XCODE}"
|
||||||
echo "iOS SDK Version: ${SDK[$IOS]}"
|
echo "iOS SDK Version: ${SDK[$IOS]}"
|
||||||
echo "MacOS SDK Version: ${SDK[$MACOS]}"
|
echo "MacOS SDK Version: ${SDK[$MACOS]}"
|
||||||
@ -105,7 +125,7 @@ if [[ ! -e ${SRCDIR}/configure ]]; then
|
|||||||
Error creating configure script!
|
Error creating configure script!
|
||||||
This script requires the autoconf/automake and libtool to build. MacPorts or
|
This script requires the autoconf/automake and libtool to build. MacPorts or
|
||||||
Homebrew can be used to obtain these:
|
Homebrew can be used to obtain these:
|
||||||
http://www.macports.org/install.php
|
https://www.macports.org/install.php
|
||||||
https://brew.sh/
|
https://brew.sh/
|
||||||
EOF
|
EOF
|
||||||
exit 1
|
exit 1
|
||||||
@ -228,6 +248,10 @@ xcodebuild -create-xcframework "${FAT_DEMUXLIBLIST[@]}" \
|
|||||||
-output ${DEMUXTARGETDIR}
|
-output ${DEMUXTARGETDIR}
|
||||||
xcodebuild -create-xcframework "${FAT_MUXLIBLIST[@]}" \
|
xcodebuild -create-xcframework "${FAT_MUXLIBLIST[@]}" \
|
||||||
-output ${MUXTARGETDIR}
|
-output ${MUXTARGETDIR}
|
||||||
|
update_headers_path "${TARGETDIR}"
|
||||||
|
update_headers_path "${DECTARGETDIR}"
|
||||||
|
update_headers_path "${DEMUXTARGETDIR}"
|
||||||
|
update_headers_path "${MUXTARGETDIR}"
|
||||||
set +x
|
set +x
|
||||||
|
|
||||||
echo "SUCCESS"
|
echo "SUCCESS"
|
||||||
|
Reference in New Issue
Block a user