Compare commits

..

29 Commits

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

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

Bug: chromium:1479274
Change-Id: I31c36dbf3aa78d35ecf38706b50464fd3d375741
(cherry picked from commit 902bc91903)
(cherry picked from commit 2af26267cd)
2023-09-08 19:25:32 -07:00
20ef03ee35 GetBackwardReferences: fail on alloc error
previously failures in the call to
VP8LBackwardReferencesTraceBackwards() would be ignored which, though it
wouldn't result in a crash, would produce non-deterministic output

Change-Id: Id9890a60883c3270ec75e968506d46eea32b76d4
(cherry picked from commit e3cfafaf71)
2022-04-06 21:49:02 -07:00
dd80bb4343 BackwardReferencesHashChainDistanceOnly: fix segfault on OOM
change CostManager to calloc to avoid frees on undefined pointer
values in CostManagerClear() should the cost_model allocation succeed,
but the cost_manager allocation fail

since:
v0.5.0-93-g3e023c17 Speed-up BackwardReferencesHashChainDistanceOnly.

Tested:
for i in `seq 1 639`; do
  export MALLOC_FAIL_AT=$i
  ./examples/cwebp -m 6 -q 100 -lossless jpeg_file
done

Bug: webp:565
Change-Id: I376d81e6f41eb73529053e9e30c142b4b4f6b45b
(cherry picked from commit a828a59b49)
2022-04-06 21:49:02 -07:00
ddd65f0d19 VP8LEncodeStream: fix segfault on OOM
initialize bw_side before calling EncoderAnalyze() & EncoderInit() which
may fail; previously this would cause a free of an invalid pointer in
VP8LBitWriterWipeOut().

since at least:
v0.6.0-120-gf8c2ac15 Multi-thread the lossless cruncher.

Tested:
for i in `seq 1 639`; do
  export MALLOC_FAIL_AT=$i
  ./examples/cwebp -m 6 -q 100 -lossless jpeg_file
done

Bug: webp:565
Change-Id: I1c95883834b6e4b13aee890568ce3bad0f4266f0
(cherry picked from commit fe153fae98)
2022-04-06 21:48:55 -07:00
30956e3aaa alpha_processing_neon.c: fix 0x01... typo
one instance was overlong leading to a int64->uint32 conversion warning

Change-Id: I56d5ab75d89960c79293f62cd489d7ab519bbc34
(cherry picked from commit 03d1219055)
2022-03-08 19:36:12 +00:00
64848839c0 alpha_processing_neon.c: fix Dispatch/ExtractAlpha_NEON
the trailing width % 8 bytes would clear the upper bytes of
alpha_mask as they're done one at a time

since:
49d0280d NEON: implement several alpha-processing functions

Change-Id: Iff76c0af3094597285a6aa6ed032b345f9856aae
(cherry picked from commit 924e7ca654)
2022-03-03 18:03:29 +00:00
b79a8421b8 Fix lossless encoding for MIPS.
Bug: webp:558
Change-Id: I3d3ddb64ed26a8d8ff5664664c5f20f6eadfeb4f
(cherry picked from commit e4cbcdd2b5)
2022-03-02 02:55:26 +00:00
69c7f16111 dsp.h: bump msvc arm64 version requirement to 16.6
there was a bug in 16.4 causing compile failures with vtbl4_u8():

src\dsp\lossless_neon.c(105): error C2143: syntax error: missing ')'
before '{'
src\dsp\lossless_neon.c(105): error C2168: 'neon_tbl2_q8': too few
actual parameters for intrinsic function

https://developercommunity.visualstudio.com/t/cannot-compile-arm64-neon-vtbl4-u8-function-in-c-f/859331

Change-Id: I87c21850b3c597aa5cb41a8105b81e2135a9f890
(cherry picked from commit 4074acf873)
2022-01-20 18:47:51 +00:00
b0a860891d update ChangeLog
Change-Id: I8a18162a178f1686cc8359ce48d90c1c7f65ec91
2022-01-19 15:35:26 -08:00
6db8248c01 libwebp: Fix VP8EncTokenLoop() progress
Encoding the image found in the user bug report below would result in
a progress rising up to 173% because of the extra 20% caused by each
of the 4 extra lossy passes. It happened at methods 3 to 6.

https://groups.google.com/a/webmproject.org/g/webp-discuss/c/yOiP8APubgc/m/FP3r5X2rDAAJ

Change-Id: I95318d0dc4df546044eb926c786c04bb7f915cbe
(cherry picked from commit db25f1b4ed)
2022-01-19 18:07:42 +00:00
827a307fec BMP enc: fix the transparency case
When transparency is present, it's not enough to just write 32bpp samples.
One need to use the full BITMAPV3INFOHEADER syntax and specify the
masks for BGRA.

 see https://en.wikipedia.org/wiki/BMP_file_format#Pixel_storage

Also remove the height-flip trick and write samples bottom-to-top instead.

Change-Id: If5d92c11453b96764b5bfbf19e9678e632bc911f
(cherry picked from commit 480cd51de6)
2022-01-19 18:07:17 +00:00
286e7fceaa libwebp: do not destroy jpeg codec twice on error
WebPPictureImportRGB() can fail on memory allocation. In this case,
jpeg_destroy_decompress() was already called, so do not go to Error.
Free metadata as an error is returned.

Change-Id: I045b072090e9063d3ad10369ad18b0f08bdffe9f
(cherry picked from commit 6e8a4126f2)
2022-01-17 18:47:10 +00:00
9195ea0538 update ChangeLog
Bug: webp:541
Change-Id: I6cfb9da3a3944f66efa681cffec7f3e6a84c8800
2022-01-11 18:46:37 -08:00
4acae017bd update NEWS
Bug: webp:541
Change-Id: I529210f8ecaa8f2e9a6fae2518ba71f7fd56a701
2022-01-11 18:45:55 -08:00
883f063397 man/img2webp.1: update date
after:
a80954a1 Reword img2webp synopsis command line

Change-Id: I0a5c18f7947d15fcd66dc32fab9b525186f7fcc5
(cherry picked from commit 1b0c15db02)
2022-01-11 02:03:24 +00:00
567e1f442b Reword img2webp synopsis command line
See https://bugs.chromium.org/p/webp/issues/detail?id=549

Change-Id: I75562d2ad021d8ec107eb4ced5b28e0abf373324
(cherry picked from commit a80954a1d9)
2022-01-11 02:02:57 +00:00
f084244d9f anim_decode: fix alpha blending with big-endian
images are decoded in RGBA/BGRA, but represented as uint32_t during the
blend process; this fixes the channel extraction

Bug: webp:548
Change-Id: Ie74aa43d8f87d3552d5afc0abba466335f5d1617
(cherry picked from commit e4886716d3)
2021-12-23 14:49:14 +00:00
b217b4fff7 webpinfo: fix fourcc comparison w/big-endian
store the recognized fourccs in little-endian order to match how the
fourcc is being read from the file

Bug: webp:548
Change-Id: I9de77db92208709d5e711846908a51e563102fa5
(cherry picked from commit e3cb052ca5)
2021-12-23 14:48:19 +00:00
f035d2e40d update ChangeLog
Bug: webp:541
Change-Id: Icd9d0bf1a011263108e899b561f7c8e93dc93e2f
2021-12-15 15:43:43 -08:00
7031946ad8 update NEWS
Change-Id: Id53e61bfb1551b04fe57fd095aa7ef860f60b248
2021-12-14 22:00:58 -08:00
973390b618 bump version to 1.2.2
libwebp{,decoder} - 1.2.2
libwebp libtool - 8.3.1
libwebpdecoder libtool - 4.3.1

mux - 1.2.2
libtool - 3.8.0

demux - 1.2.2
libtool - 2.9.0

Bug: webp:541
Change-Id: Ia9adda28f0320714335156552d0f5b563e1babb6
2021-12-14 19:58:29 -08:00
abd6664fee update AUTHORS
Bug: webp:541
Change-Id: I270b606a16d72dd5012253d932905375692b8eb7
2021-12-14 19:52:01 -08:00
5b7e79303a Merge "add missing USE_{MSA,NEON} checks in headers" into main 2021-12-14 23:39:18 +00:00
02ca04c348 add missing USE_{MSA,NEON} checks in headers
msa_macro.h
neon.h

allows the headers to be built / analyzed under different target
configurations

Change-Id: Ibbcfada210b54988aa5279674d53af8e21fd4a97
2021-12-14 22:21:57 +00:00
e94716e27c xcframeworkbuild.sh: place headers in a subdir
Headers/<framework> rather than Headers/ to avoid a Xcode error when
using multiple frameworks:
  error: Multiple commands produce
    '.../Build/Products/Debug-iphoneos/include/types.h'

WebPMux.xcframework/ios-arm64_i386_x86_64-simulator/Headers/WebPMux
WebPMux.xcframework/ios-arm64_armv7_armv7s/Headers/WebPMux
WebPMux.xcframework/macos-arm64_x86_64/Headers/WebPMux
WebPMux.xcframework/ios-arm64_x86_64-maccatalyst/Headers/WebPMux
WebPDecoder.xcframework/ios-arm64_i386_x86_64-simulator/Headers/WebPDecoder
WebPDecoder.xcframework/ios-arm64_armv7_armv7s/Headers/WebPDecoder
WebPDecoder.xcframework/macos-arm64_x86_64/Headers/WebPDecoder
WebPDecoder.xcframework/ios-arm64_x86_64-maccatalyst/Headers/WebPDecoder
WebPDemux.xcframework/ios-arm64_i386_x86_64-simulator/Headers/WebPDemux
WebPDemux.xcframework/ios-arm64_armv7_armv7s/Headers/WebPDemux
WebPDemux.xcframework/macos-arm64_x86_64/Headers/WebPDemux
WebPDemux.xcframework/ios-arm64_x86_64-maccatalyst/Headers/WebPDemux
WebP.xcframework/ios-arm64_i386_x86_64-simulator/Headers/WebP
WebP.xcframework/ios-arm64_armv7_armv7s/Headers/WebP
WebP.xcframework/macos-arm64_x86_64/Headers/WebP
WebP.xcframework/ios-arm64_x86_64-maccatalyst/Headers/WebP

Bug: webp:542
Change-Id: Ic7e03d85d2119597e422b9cf68b3ac5a892d494d
2021-12-10 19:44:36 -08:00
c846efd888 patch-check: commit subject length check
Change-Id: I7a1c7349f4f461c2384cbd1a62d1aa2e4e3be819
Bug: b:185520507
2021-12-08 18:57:13 +00:00
b6f756e82b update http links
- prefer https

- metadataworkinggroup.org/com seem to be offline; the web archive link
  was obtained from exiftool: https://exiftool.org/TagNames/MWG.html

- fix kramdown link, rubyforge has been gone a long time

- fix png/zlib links

Bug: webp:544
Bug: b/202302177
Change-Id: Id69de4553e7baf00393f12a2c1acb262443a1a93
2021-11-23 10:13:40 -08:00
8f5cb4c18e update rfc links
to https://datatracker.ietf.org/doc/html/... the http tools.ietf.org
links redirect here sometimes, in other cases they 404.

Bug: webp:544
Change-Id: I900972070d6c5659c45a86a89e78b870f42fe5bc
2021-11-17 11:03:35 -08:00
8ea81561d2 change VP8LPredictorFunc signature to avoid reading 'left'
... when it's not available. Even if the value was discarded and
never used, some msan config were complaining about reading it
and passing it around.

Change-Id: Iab8d24676c5bb58e607a829121e36c2862da397c
2021-11-05 16:22:31 +01:00
75 changed files with 586 additions and 359 deletions

View File

@ -12,3 +12,4 @@ Tamar Levy <tamar.levy@intel.com>
<qrczak@google.com> <qrczak>
Hui Su <huisu@google.com>
James Zern <jzern@google.com>
Roberto Alanis <alanisbaez@google.com>

View File

@ -32,6 +32,7 @@ Contributors:
- Pascal Massimino (pascal dot massimino at gmail dot com)
- Paweł Hajdan, Jr (phajdan dot jr at chromium dot org)
- Pierre Joye (pierre dot php at gmail dot com)
- Roberto Alanis (alanisbaez at google dot com)
- Sam Clegg (sbc at chromium dot org)
- Scott Hancher (seh at google dot com)
- Scott LaVarnway (slavarnway at google dot com)

View File

@ -22,9 +22,6 @@ if(NOT EMSCRIPTEN)
endif()
option(WEBP_ENABLE_SIMD "Enable any SIMD optimization."
${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_CWEBP "Build the cwebp 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)
set(WEBP_BUILD_ANIM_UTILS OFF)
set(WEBP_BUILD_CWEBP OFF)
set(WEBP_BUILD_DWEBP OFF)
set(WEBP_BUILD_GIF2WEBP OFF)
set(WEBP_BUILD_IMG2WEBP OFF)
set(WEBP_BUILD_VWEBP OFF)
@ -82,9 +80,6 @@ include(GNUInstallDirs)
if(WEBP_ENABLE_SWAP_16BIT_CSP)
add_definitions(-DWEBP_SWAP_16BIT_CSP=1)
endif()
if(WEBP_ENABLE_WASM_SIMD)
add_definitions(-DWEBP_ENABLE_WASM_SIMD_INTRINSICS)
endif()
if(NOT WEBP_BITTRACE STREQUAL "0")
add_definitions(-DBITTRACE=${WEBP_BITTRACE})

View File

@ -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
c5bc3624 fuzzer/*: normalize src/ includes
53b6f762 fix indent
d2caaba4 fix indent
731246ba update ChangeLog (tag: v1.2.1-rc2)
d250f01d dsp/*: use WEBP_HAVE_* to determine Init availability
1fe31625 dsp/*: use WEBP_HAVE_* to determine Init availability
3a4d3ecd update NEWS
b2bc8093 bump version to 1.2.1
e542fc7a update AUTHORS

8
NEWS
View File

@ -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
This is a binary compatible release.
* minor lossless encoder improvements and x86 color conversion speed up

View File

@ -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.
"""
import re
import subprocess2
USE_PYTHON3 = True
_BASH_INDENTATION = "2"
_GIT_COMMIT_SUBJECT_LENGTH = 65
_INCLUDE_BASH_FILES_ONLY = [r".*\.sh$"]
_INCLUDE_MAN_FILES_ONLY = [r"man/.+\.1$"]
_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):
return list(input_api.DEFAULT_FILES_TO_SKIP) + [
r"swig/.*\.py$",
@ -123,6 +153,7 @@ def _CommonChecks(input_api, output_api):
results.extend(
input_api.canned_checks.CheckChangeHasNoStrayWhitespace(
input_api, output_api))
results.append(_CheckCommitSubjectLength(input_api, output_api))
source_file_filter = lambda x: input_api.FilterSourceFile(
x, files_to_skip=_GetFilesToSkip(input_api))

16
README
View File

@ -4,7 +4,7 @@
\__\__/\____/\_____/__/ ____ ___
/ _/ / \ \ / _ \/ _/
/ \_/ / / \ \ __/ \__
\____/____/\_____/_____/____/v1.2.1
\____/____/\_____/_____/____/v1.2.2
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,
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
https://chromium.googlesource.com/webm/libwebp
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
property rights grant can be found in the file PATENTS.
@ -436,8 +436,8 @@ Prerequisites:
2) (Optional) qcms (Quick Color Management System)
i. Download qcms from Mozilla / Chromium:
http://hg.mozilla.org/mozilla-central/file/0e7639e3bdfb/gfx/qcms
http://src.chromium.org/viewvc/chrome/trunk/src/third_party/qcms
https://hg.mozilla.org/mozilla-central/file/0e7639e3bdfb/gfx/qcms
https://source.chromium.org/chromium/chromium/src/+/main:third_party/qcms/;drc=d4a2f8e1ed461d8fc05ed88d1ae2dc94c9773825
ii. Build and archive the source files as libqcms.a / qcms.lib
iii. Update makefile.unix / Makefile.vc
a) Define WEBP_HAVE_QCMS
@ -456,7 +456,7 @@ modes, etc.
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):
-min_size ............ minimize size
@ -786,10 +786,10 @@ Bugs:
Please report all bugs to the issue tracker:
https://bugs.chromium.org/p/webp
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:
========
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

View File

@ -1,7 +1,7 @@
 __ __ ____ ____ ____ __ __ _ __ __
/ \\/ \/ _ \/ _ \/ _ \/ \ \/ \___/_ / _\
\ / __/ _ \ __/ / / (_/ /__
\__\__/\_____/_____/__/ \__//_/\_____/__/___/v1.2.1
\__\__/\_____/_____/__/ \__//_/\_____/__/___/v1.2.2
Description:
@ -249,10 +249,10 @@ Bugs:
Please report all bugs to the issue tracker:
https://bugs.chromium.org/p/webp
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:
========
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

View File

@ -108,9 +108,6 @@
/* Set to 1 if JPEG library is installed */
#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 */
#cmakedefine WEBP_HAVE_NEON

View File

@ -36,9 +36,9 @@ function(webp_check_compiler_flag WEBP_SIMD_FLAG ENABLE_SIMD)
endfunction()
# 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
"_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")
# 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
@ -53,9 +53,9 @@ if(MSVC AND CMAKE_C_COMPILER_ID STREQUAL "MSVC")
set(SIMD_DISABLE_FLAGS)
else()
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
"-mno-simd128;-mno-sse4.1;-mno-sse2;;-mno-dspr2;;-mno-msa")
"-mno-sse4.1;-mno-sse2;;-mno-dspr2;;-mno-msa")
endif()
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})
# With Emscripten 2.0.9 -msimd128 -mfpu=neon will enable NEON, but the
# source will fail to compile.
if(EMSCRIPTEN AND ${I_SIMD} GREATER_EQUAL 5)
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})
if(EMSCRIPTEN AND ${I_SIMD} GREATER_EQUAL 2)
break()
endif()
@ -96,7 +91,6 @@ foreach(I_SIMD RANGE ${WEBP_SIMD_FLAGS_RANGE})
webp_check_compiler_flag(${WEBP_SIMD_FLAG} ${WEBP_ENABLE_SIMD})
if(NOT WEBP_HAVE_${WEBP_SIMD_FLAG})
list(GET SIMD_ENABLE_FLAGS ${I_SIMD} SIMD_COMPILE_FLAG)
# This enables using Emscripten's SSE compatibility headers.
if(EMSCRIPTEN)
set(SIMD_COMPILE_FLAG "-msimd128 ${SIMD_COMPILE_FLAG}")
endif()

View File

@ -1,6 +1,6 @@
AC_INIT([libwebp], [1.2.1],
AC_INIT([libwebp], [1.2.2],
[https://bugs.chromium.org/p/webp],,
[http://developers.google.com/speed/webp])
[https://developers.google.com/speed/webp])
AC_CANONICAL_HOST
AC_PREREQ([2.60])
AM_INIT_AUTOMAKE([-Wall foreign subdir-objects])

View File

@ -6,8 +6,8 @@ HTML generation requires kramdown [1], easily installed as a
rubygem [2]. Rubygems installation should satisfy dependencies
automatically.
[1]: http://kramdown.rubyforge.org/
[2]: http://rubygems.org/
[1]: https://kramdown.gettalong.org/
[2]: https://rubygems.org/
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.
[3]: http://coderay.rubychan.de/
[3]: https://github.com/rubychan/coderay

View File

@ -2,7 +2,7 @@
Although you may be viewing an alternate representation, this document
is sourced in Markdown, a light-duty markup scheme, and is optimized for
the [kramdown](http://kramdown.rubyforge.org/) transformer.
the [kramdown](https://kramdown.gettalong.org/) transformer.
See the accompanying README. External link targets are referenced at the
end of this file.
@ -811,9 +811,9 @@ RIFF/WEBP
+- 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
[iccspec]: http://www.color.org/icc_specs2.xalter
[metadata]: http://www.metadataworkinggroup.org/pdf/mwg_guidance.pdf
[rfc 1166]: http://tools.ietf.org/html/rfc1166
[rfc 2119]: http://tools.ietf.org/html/rfc2119
[iccspec]: https://www.color.org/icc_specs2.xalter
[metadata]: https://web.archive.org/web/20180919181934/http://www.metadataworkinggroup.org/pdf/mwg_guidance.pdf
[rfc 1166]: https://datatracker.ietf.org/doc/html/rfc1166
[rfc 2119]: https://datatracker.ietf.org/doc/html/rfc2119

View File

@ -2,7 +2,7 @@
Although you may be viewing an alternate representation, this document
is sourced in Markdown, a light-duty markup scheme, and is optimized for
the [kramdown](http://kramdown.rubyforge.org/) transformer.
the [kramdown](https://kramdown.gettalong.org/) transformer.
See the accompanying README. External link targets are referenced at the
end of this file.
@ -1087,4 +1087,4 @@ A possible example sequence:
<lz77-coded image>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[canonical_huff]: http://en.wikipedia.org/wiki/Canonical_Huffman_code
[canonical_huff]: https://en.wikipedia.org/wiki/Canonical_Huffman_code

View File

@ -35,8 +35,7 @@
static void Help(void) {
printf("Usage:\n\n");
printf(" img2webp [file-level options] [image files...] "
"[per-frame options...]\n");
printf(" img2webp [file_options] [[frame_options] frame_file]...\n");
printf("\n");
printf("File-level options (only used at the start of compression):\n");

View File

@ -125,16 +125,16 @@ static void WebPInfoInit(WebPInfo* const webp_info) {
memset(webp_info, 0, sizeof(*webp_info));
}
static const char kWebPChunkTags[CHUNK_TYPES][4] = {
{ 'V', 'P', '8', ' ' },
{ 'V', 'P', '8', 'L' },
{ 'V', 'P', '8', 'X' },
{ 'A', 'L', 'P', 'H' },
{ 'A', 'N', 'I', 'M' },
{ 'A', 'N', 'M', 'F' },
{ 'I', 'C', 'C', 'P' },
{ 'E', 'X', 'I', 'F' },
{ 'X', 'M', 'P', ' ' },
static const uint32_t kWebPChunkTags[CHUNK_TYPES] = {
MKFOURCC('V', 'P', '8', ' '),
MKFOURCC('V', 'P', '8', 'L'),
MKFOURCC('V', 'P', '8', 'X'),
MKFOURCC('A', 'L', 'P', 'H'),
MKFOURCC('A', 'N', 'I', 'M'),
MKFOURCC('A', 'N', 'M', 'F'),
MKFOURCC('I', 'C', 'C', 'P'),
MKFOURCC('E', 'X', 'I', 'F'),
MKFOURCC('X', 'M', 'P', ' '),
};
// -----------------------------------------------------------------------------
@ -644,7 +644,7 @@ static WebPInfoStatus ParseChunk(const WebPInfo* const webp_info,
return WEBP_INFO_TRUNCATED_DATA;
}
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->size_ = chunk_size;
@ -939,7 +939,13 @@ static WebPInfoStatus ProcessChunk(const ChunkData* const chunk_data,
LOG_WARN(error_message);
} else {
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",
tag[0], tag[1], tag[2], tag[3], (int)chunk_data->offset_,
(int)chunk_data->size_);

View File

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

View File

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

View File

@ -79,7 +79,7 @@ int WebPWriteTIFF(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).
// 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).
int WebPWritePGM(FILE* fout, const struct WebPDecBuffer* const buffer);

View File

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

View File

@ -133,7 +133,7 @@ static const struct {
MetadataPayload* const payload);
size_t storage_offset;
} 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.
{ "Raw profile type exif", ProcessRawProfile, METADATA_OFFSET(exif) },
{ "Raw profile type xmp", ProcessRawProfile, METADATA_OFFSET(xmp) },

View File

@ -9,7 +9,7 @@
# (the previous build will be erased if it exists).
#
# 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
@ -86,7 +86,7 @@ if [[ ! -e ${SRCDIR}/configure ]]; then
Error creating configure script!
This script requires the autoconf/automake and libtool to build. MacPorts can
be used to obtain these:
http://www.macports.org/install.php
https://www.macports.org/install.php
EOF
exit 1
fi

View File

@ -47,7 +47,7 @@ else
endif
# 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"
# 3. Run "sudo port install libpng"
# 4. Run "sudo port install tiff"

View File

@ -1,5 +1,5 @@
.\" Hey, EMACS: -*- nroff -*-
.TH CWEBP 1 "November 19, 2020"
.TH CWEBP 1 "November 17, 2021"
.SH NAME
cwebp \- compress an image file to a WebP file
.SH SYNOPSIS
@ -222,7 +222,7 @@ Compute and report average PSNR (Peak\-Signal\-To\-Noise ratio).
.TP
.B \-print_ssim
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
.B \-print_lsim
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
.br
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
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 gif2webp (1)
.br
Please refer to http://developers.google.com/speed/webp/ for additional
Please refer to https://developers.google.com/speed/webp/ for additional
information.

View File

@ -1,5 +1,5 @@
.\" Hey, EMACS: -*- nroff -*-
.TH DWEBP 1 "November 19, 2020"
.TH DWEBP 1 "November 17, 2021"
.SH NAME
dwebp \- decompress a WebP file to an image file
.SH SYNOPSIS
@ -113,7 +113,7 @@ Please report all bugs to the issue tracker:
https://bugs.chromium.org/p/webp
.br
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
dwebp picture.webp \-o output.png
@ -138,7 +138,7 @@ for the Debian project (and may be used by others).
.BR gif2webp (1),
.BR webpmux (1)
.br
Please refer to http://developers.google.com/speed/webp/ for additional
Please refer to https://developers.google.com/speed/webp/ for additional
information.
.SS Output file format details
PAM: http://netpbm.sourceforge.net/doc/pam.html

View File

@ -1,5 +1,5 @@
.\" Hey, EMACS: -*- nroff -*-
.TH GIF2WEBP 1 "May 1, 2020"
.TH GIF2WEBP 1 "November 17, 2021"
.SH NAME
gif2webp \- Convert a GIF image to WebP
.SH SYNOPSIS
@ -131,7 +131,7 @@ Please report all bugs to the issue tracker:
https://bugs.chromium.org/p/webp
.br
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
gif2webp picture.gif \-o picture.webp
@ -160,5 +160,5 @@ Debian project (and may be used by others).
.BR dwebp (1),
.BR webpmux (1)
.br
Please refer to http://developers.google.com/speed/webp/ for additional
Please refer to https://developers.google.com/speed/webp/ for additional
information.

View File

@ -1,10 +1,10 @@
.\" Hey, EMACS: -*- nroff -*-
.TH IMG2WEBP 1 "May 1, 2020"
.TH IMG2WEBP 1 "January 5, 2022"
.SH NAME
img2webp \- create animated WebP file from a sequence of input images.
.SH SYNOPSIS
.B img2webp
[file_level_options] [files] [per_frame_options...]
[file_options] [[frame_options] frame_file]...
.br
.B img2webp argument_file_name
.br
@ -86,7 +86,7 @@ Please report all bugs to the issue tracker:
https://bugs.chromium.org/p/webp
.br
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
\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 gif2webp (1)
.br
Please refer to http://developers.google.com/speed/webp/ for additional
Please refer to https://developers.google.com/speed/webp/ for additional
information.

View File

@ -1,5 +1,5 @@
.\" Hey, EMACS: -*- nroff -*-
.TH VWEBP 1 "June 5, 2019"
.TH VWEBP 1 "November 17, 2021"
.SH NAME
vwebp \- decompress a WebP file and display it in a window
.SH SYNOPSIS
@ -77,7 +77,7 @@ Please report all bugs to the issue tracker:
https://bugs.chromium.org/p/webp
.br
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
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
.BR dwebp (1)
.br
Please refer to http://developers.google.com/speed/webp/ for additional
Please refer to https://developers.google.com/speed/webp/ for additional
information.

View File

@ -1,5 +1,5 @@
.\" Hey, EMACS: -*- nroff -*-
.TH WEBPINFO 1 "November 24, 2017"
.TH WEBPINFO 1 "November 17, 2021"
.SH NAME
webpinfo \- print out the chunk level structure of WebP files
along with basic integrity checks.
@ -52,7 +52,7 @@ Please report all bugs to the issue tracker:
https://bugs.chromium.org/p/webp
.br
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
.br
@ -76,5 +76,5 @@ for the Debian project (and may be used by others).
.SH SEE ALSO
.BR webpmux (1)
.br
Please refer to http://developers.google.com/speed/webp/ for additional
Please refer to https://developers.google.com/speed/webp/ for additional
information.

View File

@ -1,5 +1,5 @@
.\" Hey, EMACS: -*- nroff -*-
.TH WEBPMUX 1 "November 3, 2021"
.TH WEBPMUX 1 "November 17, 2021"
.SH NAME
webpmux \- create animated WebP files from non\-animated WebP images, extract
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
.br
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
.P
@ -267,5 +267,5 @@ for the Debian project (and may be used by others).
.BR dwebp (1),
.BR gif2webp (1)
.br
Please refer to http://developers.google.com/speed/webp/ for additional
Please refer to https://developers.google.com/speed/webp/ for additional
information.

View File

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

View File

@ -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
};
// 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) {
int v;
if (!VP8GetBit(br, p[3], "coeffs")) {

View File

@ -32,7 +32,7 @@ extern "C" {
// version numbers
#define DEC_MAJ_VERSION 1
#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).
// Constraints are: We need to store one 16x16 block of luma samples (y),

View File

@ -84,7 +84,7 @@ static const uint8_t kCodeToPlane[CODE_TO_PLANE_CODES] = {
// to 256 (green component values) + 24 (length prefix values)
// + color_cache_size (between 0 and 2048).
// 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)
static const uint16_t kTableSize[12] = {
FIXED_TABLE_SIZE + 654,
@ -253,11 +253,11 @@ static int ReadHuffmanCodeLengths(
int symbol;
int max_symbol;
int prev_code_len = DEFAULT_CODE_LENGTH;
HuffmanCode table[1 << LENGTHS_TABLE_BITS];
HuffmanTables tables;
if (!VP8LBuildHuffmanTable(table, LENGTHS_TABLE_BITS,
code_length_code_lengths,
NUM_CODE_LENGTH_CODES)) {
if (!VP8LHuffmanTablesAllocate(1 << LENGTHS_TABLE_BITS, &tables) ||
!VP8LBuildHuffmanTable(&tables, LENGTHS_TABLE_BITS,
code_length_code_lengths, NUM_CODE_LENGTH_CODES)) {
goto End;
}
@ -277,7 +277,7 @@ static int ReadHuffmanCodeLengths(
int code_len;
if (max_symbol-- == 0) break;
VP8LFillBitWindow(br);
p = &table[VP8LPrefetchBits(br) & LENGTHS_TABLE_MASK];
p = &tables.curr_segment->start[VP8LPrefetchBits(br) & LENGTHS_TABLE_MASK];
VP8LSetBitPos(br, br->bit_pos_ + p->bits);
code_len = p->value;
if (code_len < kCodeLengthLiterals) {
@ -300,6 +300,7 @@ static int ReadHuffmanCodeLengths(
ok = 1;
End:
VP8LHuffmanTablesDeallocate(&tables);
if (!ok) dec->status_ = VP8_STATUS_BITSTREAM_ERROR;
return ok;
}
@ -307,7 +308,8 @@ static int ReadHuffmanCodeLengths(
// 'code_lengths' is pre-allocated temporary buffer, used for creating Huffman
// tree.
static int ReadHuffmanCode(int alphabet_size, VP8LDecoder* const dec,
int* const code_lengths, HuffmanCode* const table) {
int* const code_lengths,
HuffmanTables* const table) {
int ok = 0;
int size = 0;
VP8LBitReader* const br = &dec->br_;
@ -362,8 +364,7 @@ static int ReadHuffmanCodes(VP8LDecoder* const dec, int xsize, int ysize,
VP8LMetadata* const hdr = &dec->hdr_;
uint32_t* huffman_image = NULL;
HTreeGroup* htree_groups = NULL;
HuffmanCode* huffman_tables = NULL;
HuffmanCode* huffman_table = NULL;
HuffmanTables* huffman_tables = &hdr->huffman_tables_;
int num_htree_groups = 1;
int num_htree_groups_max = 1;
int max_alphabet_size = 0;
@ -372,6 +373,10 @@ static int ReadHuffmanCodes(VP8LDecoder* const dec, int xsize, int ysize,
int* mapping = NULL;
int ok = 0;
// Check the table has been 0 initialized (through InitMetadata).
assert(huffman_tables->root.start == NULL);
assert(huffman_tables->curr_segment == NULL);
if (allow_recursion && VP8LReadBits(br, 1)) {
// use meta Huffman codes.
const int huffman_precision = VP8LReadBits(br, 3) + 2;
@ -434,16 +439,15 @@ static int ReadHuffmanCodes(VP8LDecoder* const dec, int xsize, int ysize,
code_lengths = (int*)WebPSafeCalloc((uint64_t)max_alphabet_size,
sizeof(*code_lengths));
huffman_tables = (HuffmanCode*)WebPSafeMalloc(num_htree_groups * table_size,
sizeof(*huffman_tables));
htree_groups = VP8LHtreeGroupsNew(num_htree_groups);
if (htree_groups == NULL || code_lengths == NULL || huffman_tables == NULL) {
if (htree_groups == NULL || code_lengths == NULL ||
!VP8LHuffmanTablesAllocate(num_htree_groups * table_size,
huffman_tables)) {
dec->status_ = VP8_STATUS_OUT_OF_MEMORY;
goto Error;
}
huffman_table = huffman_tables;
for (i = 0; i < num_htree_groups_max; ++i) {
// If the index "i" is unused in the Huffman image, just make sure the
// coefficients are valid but do not store them.
@ -468,19 +472,20 @@ static int ReadHuffmanCodes(VP8LDecoder* const dec, int xsize, int ysize,
int max_bits = 0;
for (j = 0; j < HUFFMAN_CODES_PER_META_CODE; ++j) {
int alphabet_size = kAlphabetSize[j];
htrees[j] = huffman_table;
if (j == 0 && color_cache_bits > 0) {
alphabet_size += (1 << color_cache_bits);
}
size = ReadHuffmanCode(alphabet_size, dec, code_lengths, huffman_table);
size =
ReadHuffmanCode(alphabet_size, dec, code_lengths, huffman_tables);
htrees[j] = huffman_tables->curr_segment->curr_table;
if (size == 0) {
goto Error;
}
if (is_trivial_literal && kLiteralMap[j] == 1) {
is_trivial_literal = (huffman_table->bits == 0);
is_trivial_literal = (htrees[j]->bits == 0);
}
total_size += huffman_table->bits;
huffman_table += size;
total_size += htrees[j]->bits;
huffman_tables->curr_segment->curr_table += size;
if (j <= ALPHA) {
int local_max_bits = code_lengths[0];
int k;
@ -515,14 +520,13 @@ static int ReadHuffmanCodes(VP8LDecoder* const dec, int xsize, int ysize,
hdr->huffman_image_ = huffman_image;
hdr->num_htree_groups_ = num_htree_groups;
hdr->htree_groups_ = htree_groups;
hdr->huffman_tables_ = huffman_tables;
Error:
WebPSafeFree(code_lengths);
WebPSafeFree(mapping);
if (!ok) {
WebPSafeFree(huffman_image);
WebPSafeFree(huffman_tables);
VP8LHuffmanTablesDeallocate(huffman_tables);
VP8LHtreeGroupsFree(htree_groups);
}
return ok;
@ -1358,7 +1362,7 @@ static void ClearMetadata(VP8LMetadata* const hdr) {
assert(hdr != NULL);
WebPSafeFree(hdr->huffman_image_);
WebPSafeFree(hdr->huffman_tables_);
VP8LHuffmanTablesDeallocate(&hdr->huffman_tables_);
VP8LHtreeGroupsFree(hdr->htree_groups_);
VP8LColorCacheClear(&hdr->color_cache_);
VP8LColorCacheClear(&hdr->saved_color_cache_);
@ -1673,7 +1677,7 @@ int VP8LDecodeImage(VP8LDecoder* const dec) {
if (dec == NULL) return 0;
assert(dec->hdr_.huffman_tables_ != NULL);
assert(dec->hdr_.huffman_tables_.root.start != NULL);
assert(dec->hdr_.htree_groups_ != NULL);
assert(dec->hdr_.num_htree_groups_ > 0);

View File

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

View File

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

View File

@ -23,6 +23,14 @@
#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);
static void BlendPixelRowNonPremult(uint32_t* const src,
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 uint32_t blend_unscaled = src_channel * src_a + dst_channel * dst_a;
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.
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) {
return dst;
} 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:
// dst_factor_a = (dst_a * (255 - src_a)) / 255.
const uint8_t dst_factor_a = (dst_a * (256 - src_a)) >> 8;
const uint8_t blend_a = src_a + dst_factor_a;
const uint32_t scale = (1UL << 24) / blend_a;
const uint8_t blend_r =
BlendChannelNonPremult(src, src_a, dst, dst_factor_a, scale, 0);
const uint8_t blend_g =
BlendChannelNonPremult(src, src_a, dst, dst_factor_a, scale, 8);
const uint8_t blend_b =
BlendChannelNonPremult(src, src_a, dst, dst_factor_a, scale, 16);
const uint8_t blend_r = BlendChannelNonPremult(
src, src_a, dst, dst_factor_a, scale, CHANNEL_SHIFT(0));
const uint8_t blend_g = BlendChannelNonPremult(
src, src_a, dst, dst_factor_a, scale, CHANNEL_SHIFT(1));
const uint8_t blend_b = BlendChannelNonPremult(
src, src_a, dst, dst_factor_a, scale, CHANNEL_SHIFT(2));
assert(src_a + dst_factor_a < 256);
return (blend_r << 0) |
(blend_g << 8) |
(blend_b << 16) |
((uint32_t)blend_a << 24);
return ((uint32_t)blend_r << CHANNEL_SHIFT(0)) |
((uint32_t)blend_g << CHANNEL_SHIFT(1)) |
((uint32_t)blend_b << CHANNEL_SHIFT(2)) |
((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) {
int 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) {
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.
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);
}
@ -274,7 +282,7 @@ static void BlendPixelRowPremult(uint32_t* const src, const uint32_t* const dst,
int num_pixels) {
int 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) {
src[i] = BlendPixelPremult(src[i], dst[i]);
}

View File

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

View File

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

View File

@ -13,7 +13,6 @@ noinst_LTLIBRARIES += libwebpdsp_mips32.la
noinst_LTLIBRARIES += libwebpdspdecode_mips32.la
noinst_LTLIBRARIES += libwebpdsp_mips_dsp_r2.la
noinst_LTLIBRARIES += libwebpdspdecode_mips_dsp_r2.la
noinst_LTLIBRARIES += libwebpdspdecode_wasm.la
if BUILD_LIBWEBPDECODER
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_CFLAGS = $(libwebpdsp_mips_dsp_r2_la_CFLAGS)
libwebpdspdecode_wasm_la_SOURCES = dec_wasm.c
libwebpdsp_sse2_la_SOURCES =
libwebpdsp_sse2_la_SOURCES += cost_sse2.c
libwebpdsp_sse2_la_SOURCES += enc_sse2.c

View File

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

View File

@ -26,10 +26,8 @@
// 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.
#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) {
__asm__ volatile (
"mov %%ebx, %%edi\n"
@ -71,10 +69,8 @@ static WEBP_INLINE void GetCPUInfo(int cpu_info[4], int info_type) {
#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.
#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) {
const uint32_t ecx = 0;
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.
#endif
#if defined(WEBP_USE_WASM_SIMD)
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)
#if defined(__i386__) || defined(__x86_64__) || defined(WEBP_HAVE_MSC_CPUID)
// helper function for run-time detection of slow SSSE3 platforms
static int CheckSlowModel(int info) {

View File

@ -740,7 +740,6 @@ extern void VP8DspInitNEON(void);
extern void VP8DspInitMIPS32(void);
extern void VP8DspInitMIPSdspR2(void);
extern void VP8DspInitMSA(void);
extern void VP8DspInitWasmSIMD(void);
WEBP_DSP_INIT_FUNC(VP8DspInit) {
VP8InitClipTables();
@ -832,12 +831,6 @@ WEBP_DSP_INIT_FUNC(VP8DspInit) {
if (VP8GetCPUInfo(kMSA)) {
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
}

View File

@ -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

View File

@ -80,11 +80,6 @@ extern "C" {
#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
// files without intrinsics, allowing the corresponding Init() to be called.
// 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
// 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) && \
((_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_INTRINSICS
#endif
@ -262,8 +258,7 @@ typedef enum {
kNEON,
kMIPS32,
kMIPSdspR2,
kMSA,
kWasmSIMD
kMSA
} CPUFeature;
// returns true if the CPU supports the feature.
typedef int (*VP8CPUInfo)(CPUFeature feature);

View File

@ -9,7 +9,7 @@
//
// 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"

View File

@ -107,63 +107,77 @@ static WEBP_INLINE uint32_t Select(uint32_t a, uint32_t b, uint32_t c) {
//------------------------------------------------------------------------------
// 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)left;
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;
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;
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;
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;
return top[-1];
}
uint32_t VP8LPredictor5_C(uint32_t left, const uint32_t* const top) {
const uint32_t pred = Average3(left, top[0], top[1]);
uint32_t VP8LPredictor5_C(const uint32_t* const left,
const uint32_t* const top) {
const uint32_t pred = Average3(*left, top[0], top[1]);
return pred;
}
uint32_t VP8LPredictor6_C(uint32_t left, const uint32_t* const top) {
const uint32_t pred = Average2(left, top[-1]);
uint32_t VP8LPredictor6_C(const uint32_t* const left,
const uint32_t* const top) {
const uint32_t pred = Average2(*left, top[-1]);
return pred;
}
uint32_t VP8LPredictor7_C(uint32_t left, const uint32_t* const top) {
const uint32_t pred = Average2(left, top[0]);
uint32_t VP8LPredictor7_C(const uint32_t* const left,
const uint32_t* const top) {
const uint32_t pred = Average2(*left, top[0]);
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]);
(void)left;
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]);
(void)left;
return pred;
}
uint32_t VP8LPredictor10_C(uint32_t left, const uint32_t* const top) {
const uint32_t pred = Average4(left, top[-1], top[0], top[1]);
uint32_t VP8LPredictor10_C(const uint32_t* const left,
const uint32_t* const top) {
const uint32_t pred = Average4(*left, top[-1], top[0], top[1]);
return pred;
}
uint32_t VP8LPredictor11_C(uint32_t left, const uint32_t* const top) {
const uint32_t pred = Select(top[0], left, top[-1]);
uint32_t VP8LPredictor11_C(const uint32_t* const left,
const uint32_t* const top) {
const uint32_t pred = Select(top[0], *left, top[-1]);
return pred;
}
uint32_t VP8LPredictor12_C(uint32_t left, const uint32_t* const top) {
const uint32_t pred = ClampedAddSubtractFull(left, top[0], top[-1]);
uint32_t VP8LPredictor12_C(const uint32_t* const left,
const uint32_t* const top) {
const uint32_t pred = ClampedAddSubtractFull(*left, top[0], top[-1]);
return pred;
}
uint32_t VP8LPredictor13_C(uint32_t left, const uint32_t* const top) {
const uint32_t pred = ClampedAddSubtractHalf(left, top[0], top[-1]);
uint32_t VP8LPredictor13_C(const uint32_t* const left,
const uint32_t* const top) {
const uint32_t pred = ClampedAddSubtractHalf(*left, top[0], top[-1]);
return pred;
}

View File

@ -28,23 +28,38 @@ extern "C" {
//------------------------------------------------------------------------------
// 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];
uint32_t VP8LPredictor0_C(uint32_t left, const uint32_t* const top);
uint32_t VP8LPredictor1_C(uint32_t left, const uint32_t* const top);
uint32_t VP8LPredictor2_C(uint32_t left, const uint32_t* const top);
uint32_t VP8LPredictor3_C(uint32_t left, const uint32_t* const top);
uint32_t VP8LPredictor4_C(uint32_t left, const uint32_t* const top);
uint32_t VP8LPredictor5_C(uint32_t left, const uint32_t* const top);
uint32_t VP8LPredictor6_C(uint32_t left, const uint32_t* const top);
uint32_t VP8LPredictor7_C(uint32_t left, const uint32_t* const top);
uint32_t VP8LPredictor8_C(uint32_t left, const uint32_t* const top);
uint32_t VP8LPredictor9_C(uint32_t left, const uint32_t* const top);
uint32_t VP8LPredictor10_C(uint32_t left, const uint32_t* const top);
uint32_t VP8LPredictor11_C(uint32_t left, const uint32_t* const top);
uint32_t VP8LPredictor12_C(uint32_t left, const uint32_t* const top);
uint32_t VP8LPredictor13_C(uint32_t left, const uint32_t* const top);
uint32_t VP8LPredictor0_C(const uint32_t* const left,
const uint32_t* const top);
uint32_t VP8LPredictor1_C(const uint32_t* const left,
const uint32_t* const top);
uint32_t VP8LPredictor2_C(const uint32_t* const left,
const uint32_t* const top);
uint32_t VP8LPredictor3_C(const uint32_t* const left,
const uint32_t* const top);
uint32_t VP8LPredictor4_C(const uint32_t* const left,
const uint32_t* const top);
uint32_t VP8LPredictor5_C(const uint32_t* const left,
const uint32_t* const top);
uint32_t VP8LPredictor6_C(const uint32_t* const left,
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.
typedef void (*VP8LPredictorAddSubFunc)(const uint32_t* in,

View File

@ -179,7 +179,7 @@ static void PREDICTOR_ADD(const uint32_t* in, const uint32_t* upper, \
int x; \
assert(upper != NULL); \
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); \
} \
}

View File

@ -745,7 +745,7 @@ static void PredictorSub##PREDICTOR_I##_C(const uint32_t* in, \
assert(upper != NULL); \
for (x = 0; x < num_pixels; ++x) { \
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); \
} \
}

View File

@ -347,24 +347,24 @@ static void GetCombinedEntropyUnrefined_MIPS32(const uint32_t X[],
static void AddVector_MIPS32(const uint32_t* pa, const uint32_t* pb,
uint32_t* pout, int size) {
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;
int i;
ASM_START
ADD_TO_OUT(0, 4, 8, 12, 1, pa, pb, pout)
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) {
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;
int i;
ASM_START
ADD_TO_OUT(0, 4, 8, 12, 0, pa, pout, pout)
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

View File

@ -188,46 +188,51 @@ static WEBP_INLINE uint32_t Average4(uint32_t a0, uint32_t a1,
return Average2(Average2(a0, a1), Average2(a2, a3));
}
static uint32_t Predictor5_MIPSdspR2(uint32_t left, const uint32_t* const top) {
return Average3(left, top[0], top[1]);
static uint32_t Predictor5_MIPSdspR2(const uint32_t* const left,
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) {
return Average2(left, top[-1]);
static uint32_t Predictor6_MIPSdspR2(const uint32_t* const left,
const uint32_t* const top) {
return Average2(*left, top[-1]);
}
static uint32_t Predictor7_MIPSdspR2(uint32_t left, const uint32_t* const top) {
return Average2(left, top[0]);
static uint32_t Predictor7_MIPSdspR2(const uint32_t* const left,
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;
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;
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) {
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) {
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) {
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) {
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

View File

@ -188,17 +188,21 @@ static WEBP_INLINE uint32_t Average3_NEON(uint32_t a0, uint32_t a1,
return avg;
}
static uint32_t Predictor5_NEON(uint32_t left, const uint32_t* const top) {
return Average3_NEON(left, top[0], top[1]);
static uint32_t Predictor5_NEON(const uint32_t* const left,
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) {
return Average2_NEON(left, top[-1]);
static uint32_t Predictor6_NEON(const uint32_t* const left,
const uint32_t* const top) {
return Average2_NEON(*left, top[-1]);
}
static uint32_t Predictor7_NEON(uint32_t left, const uint32_t* const top) {
return Average2_NEON(left, top[0]);
static uint32_t Predictor7_NEON(const uint32_t* const left,
const uint32_t* const top) {
return Average2_NEON(*left, top[0]);
}
static uint32_t Predictor13_NEON(uint32_t left, const uint32_t* const top) {
return ClampedAddSubtractHalf_NEON(left, top[0], top[-1]);
static uint32_t Predictor13_NEON(const uint32_t* const left,
const uint32_t* const top) {
return ClampedAddSubtractHalf_NEON(*left, top[0], top[-1]);
}
// Batch versions of those functions.

View File

@ -138,42 +138,51 @@ static WEBP_INLINE uint32_t Average4_SSE2(uint32_t a0, uint32_t a1,
return output;
}
static uint32_t Predictor5_SSE2(uint32_t left, const uint32_t* const top) {
const uint32_t pred = Average3_SSE2(left, top[0], top[1]);
static uint32_t Predictor5_SSE2(const uint32_t* const left,
const uint32_t* const top) {
const uint32_t pred = Average3_SSE2(*left, top[0], top[1]);
return pred;
}
static uint32_t Predictor6_SSE2(uint32_t left, const uint32_t* const top) {
const uint32_t pred = Average2_SSE2(left, top[-1]);
static uint32_t Predictor6_SSE2(const uint32_t* const left,
const uint32_t* const top) {
const uint32_t pred = Average2_SSE2(*left, top[-1]);
return pred;
}
static uint32_t Predictor7_SSE2(uint32_t left, const uint32_t* const top) {
const uint32_t pred = Average2_SSE2(left, top[0]);
static uint32_t Predictor7_SSE2(const uint32_t* const left,
const uint32_t* const top) {
const uint32_t pred = Average2_SSE2(*left, top[0]);
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]);
(void)left;
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]);
(void)left;
return pred;
}
static uint32_t Predictor10_SSE2(uint32_t left, const uint32_t* const top) {
const uint32_t pred = Average4_SSE2(left, top[-1], top[0], top[1]);
static uint32_t Predictor10_SSE2(const uint32_t* const left,
const uint32_t* const top) {
const uint32_t pred = Average4_SSE2(*left, top[-1], top[0], top[1]);
return pred;
}
static uint32_t Predictor11_SSE2(uint32_t left, const uint32_t* const top) {
const uint32_t pred = Select_SSE2(top[0], left, top[-1]);
static uint32_t Predictor11_SSE2(const uint32_t* const left,
const uint32_t* const top) {
const uint32_t pred = Select_SSE2(top[0], *left, top[-1]);
return pred;
}
static uint32_t Predictor12_SSE2(uint32_t left, const uint32_t* const top) {
const uint32_t pred = ClampedAddSubtractFull_SSE2(left, top[0], top[-1]);
static uint32_t Predictor12_SSE2(const uint32_t* const left,
const uint32_t* const top) {
const uint32_t pred = ClampedAddSubtractFull_SSE2(*left, top[0], top[-1]);
return pred;
}
static uint32_t Predictor13_SSE2(uint32_t left, const uint32_t* const top) {
const uint32_t pred = ClampedAddSubtractHalf_SSE2(left, top[0], top[-1]);
static uint32_t Predictor13_SSE2(const uint32_t* const left,
const uint32_t* const top) {
const uint32_t pred = ClampedAddSubtractHalf_SSE2(*left, top[0], top[-1]);
return pred;
}

View File

@ -14,6 +14,10 @@
#ifndef 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 <msa.h>
@ -1389,4 +1393,5 @@ static WEBP_INLINE uint32_t func_hadd_uh_u32(v8u16 in) {
} while (0)
#define AVER_UB2_UB(...) AVER_UB2(v16u8, __VA_ARGS__)
#endif // WEBP_USE_MSA
#endif // WEBP_DSP_MSA_MACRO_H_

View File

@ -12,10 +12,12 @@
#ifndef WEBP_DSP_NEON_H_
#define WEBP_DSP_NEON_H_
#include <arm_neon.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
// everywhere except newer clang/gcc or aarch64 where the inline assembly is
// incompatible.
@ -98,4 +100,5 @@ static WEBP_INLINE int32x4x4_t Transpose4x4_NEON(const int32x4x4_t rows) {
} while (0)
#endif
#endif // WEBP_USE_NEON
#endif // WEBP_DSP_NEON_H_

View File

@ -10,7 +10,7 @@
// inline YUV<->RGB conversion function
//
// 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
// U = -0.1483 * R - 0.2911 * G + 0.4394 * B + 128
// V = 0.4394 * R - 0.3679 * G - 0.0715 * B + 128

View File

@ -577,7 +577,7 @@ static int BackwardReferencesHashChainDistanceOnly(
(CostModel*)WebPSafeCalloc(1ULL, cost_model_size);
VP8LColorCache hashers;
CostManager* cost_manager =
(CostManager*)WebPSafeMalloc(1ULL, sizeof(*cost_manager));
(CostManager*)WebPSafeCalloc(1ULL, sizeof(*cost_manager));
int offset_prev = -1, len_prev = -1;
double offset_cost = -1;
int first_offset_is_constant = -1; // initialized with 'impossible' value

View File

@ -976,15 +976,16 @@ static int GetBackwardReferences(int width, int height,
const VP8LHashChain* const hash_chain_tmp =
(lz77_types_best[i] == kLZ77Standard) ? hash_chain : &hash_chain_box;
const int cache_bits = (i == 1) ? 0 : *cache_bits_best;
if (VP8LBackwardReferencesTraceBackwards(width, height, argb, cache_bits,
hash_chain_tmp, &refs[i],
refs_tmp)) {
double bit_cost_trace;
VP8LHistogramCreate(histo, refs_tmp, cache_bits);
bit_cost_trace = VP8LHistogramEstimateBits(histo);
if (bit_cost_trace < bit_costs_best[i]) {
BackwardRefsSwap(refs_tmp, &refs[i]);
}
double bit_cost_trace;
if (!VP8LBackwardReferencesTraceBackwards(width, height, argb, cache_bits,
hash_chain_tmp, &refs[i],
refs_tmp)) {
goto Error;
}
VP8LHistogramCreate(histo, refs_tmp, cache_bits);
bit_cost_trace = VP8LHistogramEstimateBits(histo);
if (bit_cost_trace < bit_costs_best[i]) {
BackwardRefsSwap(refs_tmp, &refs[i]);
}
}

View File

@ -778,6 +778,7 @@ int VP8EncTokenLoop(VP8Encoder* const enc) {
// Roughly refresh the proba eight times per pass
int max_count = (enc->mb_w_ * enc->mb_h_) >> 3;
int num_pass_left = enc->config_->pass;
int remaining_progress = 40; // percents
const int do_search = enc->do_search_;
VP8EncIterator it;
VP8EncProba* const proba = &enc->proba_;
@ -805,6 +806,9 @@ int VP8EncTokenLoop(VP8Encoder* const enc) {
uint64_t size_p0 = 0;
uint64_t distortion = 0;
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);
SetLoopParams(enc, stats.q);
if (is_last_pass) {
@ -832,7 +836,7 @@ int VP8EncTokenLoop(VP8Encoder* const enc) {
StoreSideInfo(&it);
VP8StoreFilterStats(&it);
VP8IteratorExport(&it);
ok = VP8IteratorProgress(&it, 20);
ok = VP8IteratorProgress(&it, pass_progress);
}
VP8IteratorSaveBoundary(&it);
} while (ok && VP8IteratorNext(&it));
@ -878,7 +882,8 @@ int VP8EncTokenLoop(VP8Encoder* const enc) {
ok = VP8EmitTokens(&enc->tokens_, enc->parts_ + 0,
(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);
}

View File

@ -249,7 +249,7 @@ static WEBP_INLINE void GetResidual(
} else if (x == 0) {
predict = upper_row[x]; // Top.
} else {
predict = pred_func(current_row[x - 1], upper_row + x);
predict = pred_func(&current_row[x - 1], upper_row + x);
}
#if (WEBP_NEAR_LOSSLESS == 1)
if (max_quantization == 1 || mode == 0 || y == 0 || y == height - 1 ||

View File

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

View File

@ -1912,11 +1912,16 @@ WebPEncodingError VP8LEncodeStream(const WebPConfig* const config,
const WebPWorkerInterface* const worker_interface = WebPGetWorkerInterface();
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)
if (enc_main == NULL ||
!EncoderAnalyze(enc_main, crunch_configs, &num_crunch_configs_main,
if (!EncoderAnalyze(enc_main, crunch_configs, &num_crunch_configs_main,
&red_and_blue_always_zero) ||
!EncoderInit(enc_main) || !VP8LBitWriterInit(&bw_side, 0)) {
!EncoderInit(enc_main)) {
err = VP8_ENC_ERROR_OUT_OF_MEMORY;
goto Error;
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -161,7 +161,7 @@ static void SetBitDepths(const HuffmanTree* const tree,
// especially when population counts are longer than 2**tree_limit, but
// 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,
int histogram_size,
HuffmanTree* tree, int tree_depth_limit,

View File

@ -177,21 +177,24 @@ static int BuildHuffmanTable(HuffmanCode* const root_table, int root_bits,
if (num_open < 0) {
return 0;
}
if (root_table == NULL) continue;
for (; count[len] > 0; --count[len]) {
HuffmanCode code;
if ((key & mask) != low) {
table += table_size;
if (root_table != NULL) table += table_size;
table_bits = NextTableBitSize(count, len, root_bits);
table_size = 1 << table_bits;
total_size += table_size;
low = key & mask;
root_table[low].bits = (uint8_t)(table_bits + root_bits);
root_table[low].value = (uint16_t)((table - root_table) - low);
if (root_table != NULL) {
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);
}
}
@ -211,25 +214,83 @@ static int BuildHuffmanTable(HuffmanCode* const root_table, int root_bits,
((1 << MAX_CACHE_BITS) + NUM_LITERAL_CODES + NUM_LENGTH_CODES)
// Cut-off value for switching between heap and stack allocation.
#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) {
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);
if (root_table == NULL) {
total_size = BuildHuffmanTable(NULL, root_bits,
code_lengths, code_lengths_size, NULL);
} else if (code_lengths_size <= SORTED_SIZE_CUTOFF) {
if (total_size == 0 || root_table == NULL) return total_size;
if (root_table->curr_segment->curr_table + total_size >=
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.
uint16_t sorted[SORTED_SIZE_CUTOFF];
total_size = BuildHuffmanTable(root_table, root_bits,
code_lengths, code_lengths_size, sorted);
} else { // rare case. Use heap allocation.
BuildHuffmanTable(root_table->curr_segment->curr_table, root_bits,
code_lengths, code_lengths_size, sorted);
} else { // rare case. Use heap allocation.
uint16_t* const sorted =
(uint16_t*)WebPSafeMalloc(code_lengths_size, sizeof(*sorted));
if (sorted == NULL) return 0;
total_size = BuildHuffmanTable(root_table, root_bits,
code_lengths, code_lengths_size, sorted);
BuildHuffmanTable(root_table->curr_segment->curr_table, root_bits,
code_lengths, code_lengths_size, sorted);
WebPSafeFree(sorted);
}
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;
}
}

View File

@ -43,6 +43,29 @@ typedef struct {
// or non-literal symbol otherwise
} 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_TABLE_SIZE (1u << HUFFMAN_PACKED_BITS)
@ -78,9 +101,7 @@ void VP8LHtreeGroupsFree(HTreeGroup* const htree_groups);
// the huffman table.
// Returns built table size or 0 in case of error (invalid tree or
// memory error).
// If root_table is NULL, it returns 0 if a lookup cannot be built, something
// > 0 otherwise (but not the table size).
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);
#ifdef __cplusplus

View File

@ -30,7 +30,7 @@
#define DFIX 4 // extra precision for ordered dithering
#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] = {
{ 0, 8, 2, 10 }, // coefficients are in DFIX fixed-point precision
{ 12, 4, 14, 6 },

View File

@ -23,7 +23,7 @@
// alloc/free etc) is printed. For debugging/tuning purpose only (it's slow,
// and not multi-thread safe!).
// 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:
/* valgrind --tool=massif --massif-out-file=massif.out \
--stacks=yes --alloc-fn=WebPSafeMalloc --alloc-fn=WebPSafeCalloc

View File

@ -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
// have a common stride returned as '*uv_stride'.
// 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,
int* width, int* height,
uint8_t** u, uint8_t** v,

View File

@ -79,6 +79,26 @@ if [[ -z "${SDK[$IOS]}" ]] || [[ ${SDK[$IOS]%%.*} -lt 8 ]]; then
exit 1
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 "iOS SDK Version: ${SDK[$IOS]}"
echo "MacOS SDK Version: ${SDK[$MACOS]}"
@ -105,7 +125,7 @@ if [[ ! -e ${SRCDIR}/configure ]]; then
Error creating configure script!
This script requires the autoconf/automake and libtool to build. MacPorts or
Homebrew can be used to obtain these:
http://www.macports.org/install.php
https://www.macports.org/install.php
https://brew.sh/
EOF
exit 1
@ -228,6 +248,10 @@ xcodebuild -create-xcframework "${FAT_DEMUXLIBLIST[@]}" \
-output ${DEMUXTARGETDIR}
xcodebuild -create-xcframework "${FAT_MUXLIBLIST[@]}" \
-output ${MUXTARGETDIR}
update_headers_path "${TARGETDIR}"
update_headers_path "${DECTARGETDIR}"
update_headers_path "${DEMUXTARGETDIR}"
update_headers_path "${MUXTARGETDIR}"
set +x
echo "SUCCESS"