Compare commits

..

10 Commits

Author SHA1 Message Date
7b75522d5e 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)
(cherry picked from commit 20ef03ee35)
(cherry picked from commit 89e226a3c7)
2022-04-06 21:56:38 -07:00
3180b6f4b7 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)
(cherry picked from commit dd80bb4343)
(cherry picked from commit 4d0964cd0c)
2022-04-06 21:56:38 -07:00
16f36e4e39 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)
(cherry picked from commit ddd65f0d19)
(cherry picked from commit 5d805f7205)
2022-04-06 21:56:38 -07:00
df9e129b0d 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:37:29 +00:00
28b53efd6f 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:06:50 +00:00
81efa2a3f1 Fix lossless encoding for MIPS.
Bug: webp:558
Change-Id: I3d3ddb64ed26a8d8ff5664664c5f20f6eadfeb4f
(cherry picked from commit e4cbcdd2b5)
2022-03-02 02:56:38 +00:00
d8481223b3 Rescaler: fix rounding error
We saturate the result to [0..255]
It's the easiest and safest, given the wide variety of scaling
range we cover: we're not using floats, so precision is always
an issue at one end or the other of the scaling spectrum.

we also use:
  round(a - floor(b))
instead of:
  floor(a - round(b))
to handle difficult cases (ratio ~= .99, e.g.)

MIPS code is still disabled (and wrong)

Change-Id: I18d3f5ddc4c524879c257b928329b1c648fa7fb5
(cherry picked from commit ab2dc8939f)
2019-04-01 16:22:10 -07:00
4fdc903597 HistogramCombineStochastic: fix free of uninit value
previously if the mappings allocation failed histo_queue->queue would be
uninitialized; split the conditionals

Change-Id: I1b50b987e734393893dc8a83a3f314522ccd0c83
(cherry picked from commit aa65f89a8f)
2019-03-30 00:06:25 -07:00
fa58371c6a unicode,INIT_WARGV: add missing cast
CommandLineToArgvW() returns a LPWSTR*, storing to const LPWSTR* is
incorrect without a cast; fixes gcc -Wincompatible-pointer-types
and clang(-cl) -Wincompatible-pointer-types-discads-qualifiers warnings

Change-Id: Iad5b49c4862c7be68251272e50d3c751099559bc
(cherry picked from commit 2b7214ab99)
2019-01-25 01:33:20 -08:00
84fdd0d12e Remove BINARYEN_METHOD in wasm settings.
This was removed according to https://kripken.github.io/emscripten-site/docs/compiling/WebAssembly.html#debugging

BUG=webp:413

Change-Id: If8f1a3f1260d34cdd2b937b286e4c57fb48ed828
(cherry picked from commit 6bcf876980)
2019-01-25 01:33:11 -08:00
58 changed files with 542 additions and 1064 deletions

View File

@ -1,5 +1,4 @@
Contributors: Contributors:
- Aidan O'Loan (aidanol at gmail dot com)
- Alan Browning (browning at google dot com) - Alan Browning (browning at google dot com)
- Charles Munger (clm at google dot com) - Charles Munger (clm at google dot com)
- Christian Duvivier (cduvivier at google dot com) - Christian Duvivier (cduvivier at google dot com)

View File

@ -17,8 +17,6 @@ option(WEBP_BUILD_WEBP_JS "Emscripten build of webp.js." OFF)
option(WEBP_NEAR_LOSSLESS "Enable near-lossless encoding" ON) option(WEBP_NEAR_LOSSLESS "Enable near-lossless encoding" ON)
option(WEBP_ENABLE_SWAP_16BIT_CSP "Enable byte swap for 16 bit colorspaces." option(WEBP_ENABLE_SWAP_16BIT_CSP "Enable byte swap for 16 bit colorspaces."
OFF) OFF)
set(WEBP_BITTRACE "0" CACHE STRING "Bit trace mode (0=none, 1=bit, 2=bytes)")
set_property(CACHE WEBP_BITTRACE PROPERTY STRINGS 0 1 2)
# Option needed for handling Unicode file names on Windows. # Option needed for handling Unicode file names on Windows.
if(WIN32) if(WIN32)
@ -57,10 +55,6 @@ if(WEBP_ENABLE_SWAP_16BIT_CSP)
add_definitions(-DWEBP_SWAP_16BIT_CSP=1) add_definitions(-DWEBP_SWAP_16BIT_CSP=1)
endif() endif()
if(NOT WEBP_BITTRACE STREQUAL "0")
add_definitions(-DBITTRACE=${WEBP_BITTRACE})
endif()
if(WEBP_UNICODE) if(WEBP_UNICODE)
# Windows recommends setting both UNICODE and _UNICODE. # Windows recommends setting both UNICODE and _UNICODE.
add_definitions(-DUNICODE -D_UNICODE) add_definitions(-DUNICODE -D_UNICODE)
@ -71,7 +65,6 @@ set(exec_prefix "\$\{prefix\}")
set(libdir "\$\{prefix\}/lib") set(libdir "\$\{prefix\}/lib")
set(includedir "\$\{prefix\}/include") set(includedir "\$\{prefix\}/include")
set(PTHREAD_LIBS ${CMAKE_THREAD_LIBS_INIT}) set(PTHREAD_LIBS ${CMAKE_THREAD_LIBS_INIT})
set(INSTALLED_LIBRARIES)
# ############################################################################## # ##############################################################################
# Android only. # Android only.
@ -79,7 +72,6 @@ if(ANDROID)
include_directories(${ANDROID_NDK}/sources/android/cpufeatures) include_directories(${ANDROID_NDK}/sources/android/cpufeatures)
add_library(cpufeatures STATIC add_library(cpufeatures STATIC
${ANDROID_NDK}/sources/android/cpufeatures/cpu-features.c) ${ANDROID_NDK}/sources/android/cpufeatures/cpu-features.c)
list(APPEND INSTALLED_LIBRARIES cpufeatures)
target_link_libraries(cpufeatures dl) target_link_libraries(cpufeatures dl)
set(WEBP_DEP_LIBRARIES ${WEBP_DEP_LIBRARIES} cpufeatures) set(WEBP_DEP_LIBRARIES ${WEBP_DEP_LIBRARIES} cpufeatures)
set(WEBP_DEP_INCLUDE_DIRS ${WEBP_DEP_INCLUDE_DIRS} set(WEBP_DEP_INCLUDE_DIRS ${WEBP_DEP_INCLUDE_DIRS}
@ -314,7 +306,7 @@ string(REGEX MATCH
${TMP}) ${TMP})
# Define the libraries to install. # Define the libraries to install.
list(APPEND INSTALLED_LIBRARIES webpdecoder webp webpdemux) set(INSTALLED_LIBRARIES webpdecoder webp webpdemux)
# Deal with SIMD. Change the compile flags for SIMD files we use. # Deal with SIMD. Change the compile flags for SIMD files we use.
list(LENGTH WEBP_SIMD_FILES_TO_INCLUDE WEBP_SIMD_FILES_TO_INCLUDE_LENGTH) list(LENGTH WEBP_SIMD_FILES_TO_INCLUDE WEBP_SIMD_FILES_TO_INCLUDE_LENGTH)

View File

@ -1,54 +1,3 @@
2ad0916d update NEWS
1287362b bump version to 1.0.3
7b968cc2 update AUTHORS
9d6988f4 Fix the oscillating prediction problem at low quality
312f74d0 makefile.unix: allow *_LIBS to be overridden w/EXTRA_LIBS
92dbf237 filters_sse2,cosmetics: shorten some long lines
a277d197 filters_sse2.c: quiet integer sanitizer warnings
804540f1 Fix cpufeatures in CMake.
bf00c15b Add CMake option for bittrace.
a788b498 filters_sse2.c: quiet integer sanitizer warnings
e6a92c5e filters.c: quiet integer sanitizer warnings
ec1cc40a lossless.c: remove U32 -> S8 conversion warnings
1106478f remove conversion U32 -> S8 warnings
812a6b49 lossless_enc: fix some conversion warning
4627c1c9 lossless_enc,TransformColorBlue: quiet uint32_t conv warning
c84673a6 lossless_enc_sse{2,41}: quiet signed conv warnings
776a7757 dec_sse2: quiet signed conv warnings
bd39c063 Merge "thread_utils: release mutex before signaling"
0550576f Merge "(alpha_processing,enc}_sse2: quiet signed conv warnings"
6682f2c4 thread_utils: release mutex before signaling
e78dea75 (alpha_processing,enc}_sse2: quiet signed conv warnings
9acf18ba iosbuild.sh: add WebP{Demux,Mux}.framework
b9be7e65 vwebp: remove the -fit option (and make it default)
1394a2bb Merge "README.webp_js: update Emscripten.cmake note"
dd3e7f8a README.webp_js: update Emscripten.cmake note
32cf8801 predictor_enc,GetBestGreenRedToBlue: quiet implicit conv warnings
e1c8acb5 Merge "vwebp: add a -fit option"
cbd23dd5 vwebp: add a -fit option
2e672351 bit_writer_utils,Flush: quiet implicit conversion warnings
1326988d swig: update libwebp_python_wrap.c
0e7f8548 update generated swig files
17ed1438 Merge "PutLE{16,24}: quiet implicit conversion warnings"
24686538 PutLE{16,24}: quiet implicit conversion warnings
153bb3a0 fix some clang-7 warnings:
ab2dc893 Rescaler: fix rounding error
aa65f89a HistogramCombineStochastic: fix free of uninit value
af0bac64 Merge "encode.h: mention 'exact' default in WebPEncodeLossless*"
6d2e11ec encode.h: mention 'exact' default in WebPEncodeLossless*
8c3f04fe AndroidCPUInfo: reorder terms in conditional
fcfd9c71 BitTrace: if BITTRACE is > 0, record and print syntax bits used
067031ea Speedups for unused Huffman groups.
01ac46ba libwebp: Display "libjpeg error:" in imageio/jpegdec
d9a662e1 WebPRescalerGetScaledDimensions: round scaled dimension up
62eb3f08 libwebp: Fix missing '{' in README
e05f785a Merge "unicode,INIT_WARGV: add missing cast"
63c9a69f tag the VP8LHashPix() function for potential uint roll-over
2b7214ab unicode,INIT_WARGV: add missing cast
bf424b46 tag the GetPixPairHash64() function for potential uint roll-over
7d05d6ca Have the color cache computation be u32-bit only.
6bcf8769 Remove BINARYEN_METHOD in wasm settings.
2b98df90 update ChangeLog (tag: v1.0.2-rc1, tag: v1.0.2)
61e372b7 update NEWS 61e372b7 update NEWS
7ae658a0 bump version to 1.0.2 7ae658a0 bump version to 1.0.2
51c4907d update AUTHORS 51c4907d update AUTHORS
@ -67,7 +16,7 @@ f435de95 IsFlat: return int
9f4d4a3f neon: GetResidualCost 9f4d4a3f neon: GetResidualCost
0fd7514b neon: SetResidualCoeffs 0fd7514b neon: SetResidualCoeffs
f95a996c Simpler histogram clustering. f95a996c Simpler histogram clustering.
e85d3313 update ChangeLog (tag: v1.0.1-rc2, tag: v1.0.1) e85d3313 update ChangeLog (tag: v1.0.1-rc2, tag: v1.0.1, origin/1.0.1, 1.0.1)
fa8210e4 Fix pair update in stochastic entropy merging. fa8210e4 Fix pair update in stochastic entropy merging.
fd198f73 add codereview.settings fd198f73 add codereview.settings
825389ac README.mux: add a reference to the AnimDecoder API 825389ac README.mux: add a reference to the AnimDecoder API
@ -536,7 +485,7 @@ dcf9d82a imageio: add limited PNM support for reading
6524fcd6 vwebp_sdl: simple viewer based on SDL 6524fcd6 vwebp_sdl: simple viewer based on SDL
6cf24a24 get_disto: fix reference file read 6cf24a24 get_disto: fix reference file read
43d472aa Merge tag 'v0.6.0' 43d472aa Merge tag 'v0.6.0'
50d1a848 update ChangeLog (tag: v0.6.0, origin/0.6.0) 50d1a848 update ChangeLog (tag: v0.6.0, origin/0.6.0, 0.6.0)
20a7fea0 extras/Makefile.am: fix libwebpextras.la reference 20a7fea0 extras/Makefile.am: fix libwebpextras.la reference
415f3ffe update ChangeLog (tag: v0.6.0-rc3) 415f3ffe update ChangeLog (tag: v0.6.0-rc3)
3c6d1224 update NEWS 3c6d1224 update NEWS
@ -613,7 +562,7 @@ b016cb91 NEON: faster fancy upsampling
f04eb376 Merge tag 'v0.5.2' f04eb376 Merge tag 'v0.5.2'
341d711c NEON: 5% faster conversion to RGB565 and RGBA4444 341d711c NEON: 5% faster conversion to RGB565 and RGBA4444
abb54827 remove Clang warnings with unused arch arguments. abb54827 remove Clang warnings with unused arch arguments.
ece9684f update ChangeLog (tag: v0.5.2-rc2, tag: v0.5.2, origin/0.5.2) ece9684f update ChangeLog (tag: v0.5.2-rc2, tag: v0.5.2, origin/0.5.2, 0.5.2)
aa7744ca anim_util: quiet implicit conv warnings in 32-bit aa7744ca anim_util: quiet implicit conv warnings in 32-bit
d9120271 jpegdec: correct ContextFill signature d9120271 jpegdec: correct ContextFill signature
24eb3940 Remove some errors when compiling the code as C++. 24eb3940 Remove some errors when compiling the code as C++.
@ -900,7 +849,7 @@ bbb6ecd9 Merge "Add MSA optimized distortion functions"
c0991a14 io,EmitRescaledAlphaYUV: factor out a common expr c0991a14 io,EmitRescaledAlphaYUV: factor out a common expr
48bf5ed1 build.gradle: remove tab 48bf5ed1 build.gradle: remove tab
bfef6c9f Merge tag 'v0.5.1' bfef6c9f Merge tag 'v0.5.1'
3d97bb75 update ChangeLog (tag: v0.5.1, origin/0.5.1) 3d97bb75 update ChangeLog (tag: v0.5.1, origin/0.5.1, 0.5.1)
deb54d91 Clarify the expected 'config' lifespan in WebPIDecode() deb54d91 Clarify the expected 'config' lifespan in WebPIDecode()
435308e0 Add MSA optimized encoder transform functions 435308e0 Add MSA optimized encoder transform functions
dce64bfa Add MSA optimized alpha filter functions dce64bfa Add MSA optimized alpha filter functions
@ -1094,7 +1043,7 @@ b74657fb configure: fix builtin detection w/-Werror
6c1d7631 avoid Yoda style for comparison 6c1d7631 avoid Yoda style for comparison
8ce975ac SSE optimization for vector mismatch. 8ce975ac SSE optimization for vector mismatch.
7db53831 Merge tag 'v0.5.0' 7db53831 Merge tag 'v0.5.0'
37f04949 update ChangeLog (tag: v0.5.0-rc1, tag: v0.5.0, origin/0.5.0) 37f04949 update ChangeLog (tag: v0.5.0-rc1, tag: v0.5.0, origin/0.5.0, 0.5.0)
7e7b6ccc faster rgb565/rgb4444/argb output 7e7b6ccc faster rgb565/rgb4444/argb output
4c7f565f update NEWS 4c7f565f update NEWS
1f62b6b2 update AUTHORS 1f62b6b2 update AUTHORS
@ -1878,7 +1827,7 @@ b5a36cc9 add -near_lossless [0..100] experimental option
0524d9e5 dsp: detect mips64 & disable mips32 code 0524d9e5 dsp: detect mips64 & disable mips32 code
d3485d96 cwebp.1: fix quality description placement d3485d96 cwebp.1: fix quality description placement
29a9fe22 Merge tag 'v0.4.1' 29a9fe22 Merge tag 'v0.4.1'
8af27718 update ChangeLog (tag: v0.4.1, origin/0.4.1) 8af27718 update ChangeLog (tag: v0.4.1, origin/0.4.1, 0.4.1)
e09e9ff6 Record & log the image pre-processing time. e09e9ff6 Record & log the image pre-processing time.
f59c0b4b iosbuild.sh: specify optimization flags f59c0b4b iosbuild.sh: specify optimization flags
8d34ea3e update ChangeLog (tag: v0.4.1-rc1) 8d34ea3e update ChangeLog (tag: v0.4.1-rc1)
@ -2263,7 +2212,7 @@ ea59a8e9 Merge "Merge tag 'v0.4.0'"
effcb0fd Merge tag 'v0.4.0' effcb0fd Merge tag 'v0.4.0'
7c76255d autoconf: update ax_pthread.m4 7c76255d autoconf: update ax_pthread.m4
fff2a11b make -short work with -print_ssim, -print_psnr, etc. fff2a11b make -short work with -print_ssim, -print_psnr, etc.
68e7901d update ChangeLog (tag: v0.4.0-rc1, tag: v0.4.0, origin/0.4.0) 68e7901d update ChangeLog (tag: v0.4.0-rc1, tag: v0.4.0, origin/0.4.0, 0.4.0)
256e4333 update NEWS description with new general features 256e4333 update NEWS description with new general features
29625340 Merge "gif2webp: don't use C99 %zu" into 0.4.0 29625340 Merge "gif2webp: don't use C99 %zu" into 0.4.0
3b9f9dd0 gif2webp: don't use C99 %zu 3b9f9dd0 gif2webp: don't use C99 %zu
@ -3039,7 +2988,7 @@ a61a824b Merge "Add NULL check in chunk APIs"
a0770727 mux struct naming a0770727 mux struct naming
6c66dde8 Merge "Tune Lossless encoder" 6c66dde8 Merge "Tune Lossless encoder"
ab5ea217 Tune Lossless encoder ab5ea217 Tune Lossless encoder
74fefc8c Update ChangeLog (tag: v0.2.1, origin/0.2.0) 74fefc8c Update ChangeLog (tag: v0.2.1, origin/0.2.0, 0.2.0)
92f8059c Rename some chunks: 92f8059c Rename some chunks:
3bb4bbeb Merge "Mux API change:" 3bb4bbeb Merge "Mux API change:"
d0c79f05 Mux API change: d0c79f05 Mux API change:

12
NEWS
View File

@ -1,15 +1,3 @@
- 7/4/2019: version 1.0.3
This is a binary compatible release.
* resize fixes for Nx1 sizes and the addition of non-opaque alpha values for
odd sizes (issues #418, #434)
* lossless encode/decode performance improvements
* lossy compression performance improvement at low quality levels with flat
content (issue #432)
* python swig files updated to support python 3
Tool updates:
vwebp will now preserve the aspect ratio of images that exceed monitor
resolution by scaling the image to fit (issue #433)
- 1/14/2019: version 1.0.2 - 1/14/2019: version 1.0.2
This is a binary compatible release. This is a binary compatible release.
* (Windows) unicode file support in the tools (linux and mac already had * (Windows) unicode file support in the tools (linux and mac already had

4
README
View File

@ -4,7 +4,7 @@
\__\__/\____/\_____/__/ ____ ___ \__\__/\____/\_____/__/ ____ ___
/ _/ / \ \ / _ \/ _/ / _/ / \ \ / _ \/ _/
/ \_/ / / \ \ __/ \__ / \_/ / / \ \ __/ \__
\____/____/\_____/_____/____/v1.0.3 \____/____/\_____/_____/____/v1.0.2
Description: Description:
============ ============
@ -597,7 +597,7 @@ The encoding flow looks like:
// Setup a config, starting form a preset and tuning some additional // Setup a config, starting form a preset and tuning some additional
// parameters // parameters
WebPConfig config; WebPConfig config;
if (!WebPConfigPreset(&config, WEBP_PRESET_PHOTO, quality_factor)) { if (!WebPConfigPreset(&config, WEBP_PRESET_PHOTO, quality_factor))
return 0; // version error return 0; // version error
} }
// ... additional tuning // ... additional tuning

View File

@ -1,7 +1,7 @@
 __ __ ____ ____ ____ __ __ _ __ __  __ __ ____ ____ ____ __ __ _ __ __
/ \\/ \/ _ \/ _ \/ _ \/ \ \/ \___/_ / _\ / \\/ \/ _ \/ _ \/ _ \/ \ \/ \___/_ / _\
\ / __/ _ \ __/ / / (_/ /__ \ / __/ _ \ __/ / / (_/ /__
\__\__/\_____/_____/__/ \__//_/\_____/__/___/v1.0.3 \__\__/\_____/_____/__/ \__//_/\_____/__/___/v1.0.2
Description: Description:

View File

@ -17,10 +17,6 @@ using Emscripten and CMake.
- make sure the file $EMSCRIPTEN/cmake/Modules/Platform/Emscripten.cmake is - make sure the file $EMSCRIPTEN/cmake/Modules/Platform/Emscripten.cmake is
accessible. This is the toolchain file used by CMake to invoke Emscripten. accessible. This is the toolchain file used by CMake to invoke Emscripten.
If $EMSCRIPTEN is unset search for Emscripten.cmake under $EMSDK and set
$EMSCRIPTEN accordingly, for example:
unix-like environments: export EMSCRIPTEN=$EMSDK/fastcomp/emscripten
windows: set EMSCRIPTEN=%EMSDK%\fastcomp\emscripten
- configure the project 'WEBP_JS' with CMake using: - configure the project 'WEBP_JS' with CMake using:

View File

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

View File

@ -418,9 +418,8 @@ static void HandleDisplay(void) {
} }
static void StartDisplay(void) { static void StartDisplay(void) {
int width = kParams.canvas_width; const int width = kParams.canvas_width;
int height = kParams.canvas_height; const int height = kParams.canvas_height;
int screen_width, screen_height;
// TODO(webp:365) GLUT_DOUBLE results in flickering / old frames to be // TODO(webp:365) GLUT_DOUBLE results in flickering / old frames to be
// partially displayed with animated webp + alpha. // partially displayed with animated webp + alpha.
#if defined(__APPLE__) || defined(_WIN32) #if defined(__APPLE__) || defined(_WIN32)
@ -428,18 +427,6 @@ static void StartDisplay(void) {
#else #else
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);
#endif #endif
screen_width = glutGet(GLUT_SCREEN_WIDTH);
screen_height = glutGet(GLUT_SCREEN_HEIGHT);
if (width > screen_width || height > screen_height) {
if (width > screen_width) {
height = (height * screen_width + width - 1) / width;
width = screen_width;
}
if (height > screen_height) {
width = (width * screen_height + height - 1) / height;
height = screen_height;
}
}
glutInitWindowSize(width, height); glutInitWindowSize(width, height);
glutCreateWindow("WebP viewer"); glutCreateWindow("WebP viewer");
glutDisplayFunc(HandleDisplay); glutDisplayFunc(HandleDisplay);

View File

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

View File

@ -206,7 +206,6 @@ struct my_error_mgr {
static void my_error_exit(j_common_ptr dinfo) { static void my_error_exit(j_common_ptr dinfo) {
struct my_error_mgr* myerr = (struct my_error_mgr*)dinfo->err; struct my_error_mgr* myerr = (struct my_error_mgr*)dinfo->err;
fprintf(stderr, "libjpeg error: ");
dinfo->err->output_message(dinfo); dinfo->err->output_message(dinfo);
longjmp(myerr->setjmp_buffer, 1); longjmp(myerr->setjmp_buffer, 1);
} }

View File

@ -35,15 +35,11 @@ readonly TOPDIR=$(pwd)
readonly BUILDDIR="${TOPDIR}/iosbuild" readonly BUILDDIR="${TOPDIR}/iosbuild"
readonly TARGETDIR="${TOPDIR}/WebP.framework" readonly TARGETDIR="${TOPDIR}/WebP.framework"
readonly DECTARGETDIR="${TOPDIR}/WebPDecoder.framework" readonly DECTARGETDIR="${TOPDIR}/WebPDecoder.framework"
readonly MUXTARGETDIR="${TOPDIR}/WebPMux.framework"
readonly DEMUXTARGETDIR="${TOPDIR}/WebPDemux.framework"
readonly DEVELOPER=$(xcode-select --print-path) readonly DEVELOPER=$(xcode-select --print-path)
readonly PLATFORMSROOT="${DEVELOPER}/Platforms" readonly PLATFORMSROOT="${DEVELOPER}/Platforms"
readonly LIPO=$(xcrun -sdk iphoneos${SDK} -find lipo) readonly LIPO=$(xcrun -sdk iphoneos${SDK} -find lipo)
LIBLIST='' LIBLIST=''
DECLIBLIST='' DECLIBLIST=''
MUXLIBLIST=''
DEMUXLIBLIST=''
if [[ -z "${SDK}" ]]; then if [[ -z "${SDK}" ]]; then
echo "iOS SDK not available" echo "iOS SDK not available"
@ -57,10 +53,8 @@ else
echo "iOS SDK Version ${SDK}" echo "iOS SDK Version ${SDK}"
fi fi
rm -rf ${BUILDDIR} ${TARGETDIR} ${DECTARGETDIR} \ rm -rf ${BUILDDIR} ${TARGETDIR} ${DECTARGETDIR}
${MUXTARGETDIR} ${DEMUXTARGETDIR} mkdir -p ${BUILDDIR} ${TARGETDIR}/Headers/ ${DECTARGETDIR}/Headers/
mkdir -p ${BUILDDIR} ${TARGETDIR}/Headers/ ${DECTARGETDIR}/Headers/ \
${MUXTARGETDIR}/Headers/ ${DEMUXTARGETDIR}/Headers/
if [[ ! -e ${SRCDIR}/configure ]]; then if [[ ! -e ${SRCDIR}/configure ]]; then
if ! (cd ${SRCDIR} && sh autogen.sh); then if ! (cd ${SRCDIR} && sh autogen.sh); then
@ -111,7 +105,6 @@ for PLATFORM in ${PLATFORMS}; do
--build=$(${SRCDIR}/config.guess) \ --build=$(${SRCDIR}/config.guess) \
--disable-shared --enable-static \ --disable-shared --enable-static \
--enable-libwebpdecoder --enable-swap-16bit-csp \ --enable-libwebpdecoder --enable-swap-16bit-csp \
--enable-libwebpmux \
CFLAGS="${CFLAGS}" CFLAGS="${CFLAGS}"
set +x set +x
@ -122,8 +115,6 @@ for PLATFORM in ${PLATFORMS}; do
LIBLIST+=" ${ROOTDIR}/lib/libwebp.a" LIBLIST+=" ${ROOTDIR}/lib/libwebp.a"
DECLIBLIST+=" ${ROOTDIR}/lib/libwebpdecoder.a" DECLIBLIST+=" ${ROOTDIR}/lib/libwebpdecoder.a"
MUXLIBLIST+=" ${ROOTDIR}/lib/libwebpmux.a"
DEMUXLIBLIST+=" ${ROOTDIR}/lib/libwebpdemux.a"
make clean make clean
cd .. cd ..
@ -131,20 +122,8 @@ for PLATFORM in ${PLATFORMS}; do
export PATH=${OLDPATH} export PATH=${OLDPATH}
done done
echo "LIBLIST = ${LIBLIST}"
cp -a ${SRCDIR}/src/webp/{decode,encode,types}.h ${TARGETDIR}/Headers/ cp -a ${SRCDIR}/src/webp/{decode,encode,types}.h ${TARGETDIR}/Headers/
${LIPO} -create ${LIBLIST} -output ${TARGETDIR}/WebP ${LIPO} -create ${LIBLIST} -output ${TARGETDIR}/WebP
echo "DECLIBLIST = ${DECLIBLIST}"
cp -a ${SRCDIR}/src/webp/{decode,types}.h ${DECTARGETDIR}/Headers/ cp -a ${SRCDIR}/src/webp/{decode,types}.h ${DECTARGETDIR}/Headers/
${LIPO} -create ${DECLIBLIST} -output ${DECTARGETDIR}/WebPDecoder ${LIPO} -create ${DECLIBLIST} -output ${DECTARGETDIR}/WebPDecoder
echo "MUXLIBLIST = ${MUXLIBLIST}"
cp -a ${SRCDIR}/src/webp/{types,mux,mux_types}.h \
${MUXTARGETDIR}/Headers/
${LIPO} -create ${MUXLIBLIST} -output ${MUXTARGETDIR}/WebPMux
echo "DEMUXLIBLIST = ${DEMUXLIBLIST}"
cp -a ${SRCDIR}/src/webp/{decode,types,mux_types,demux}.h \
${DEMUXTARGETDIR}/Headers/
${LIPO} -create ${DEMUXLIBLIST} -output ${DEMUXTARGETDIR}/WebPDemux

View File

@ -118,10 +118,6 @@ GROFF = /usr/bin/groff
COL = /usr/bin/col COL = /usr/bin/col
LDFLAGS = $(EXTRA_LIBS) $(EXTRA_FLAGS) -lm LDFLAGS = $(EXTRA_LIBS) $(EXTRA_FLAGS) -lm
ifdef BITTRACE
CFLAGS += -DBITTRACE=$(BITTRACE)
endif
ANIM_UTIL_OBJS = \ ANIM_UTIL_OBJS = \
examples/anim_util.o \ examples/anim_util.o \
@ -402,7 +398,7 @@ examples/webpinfo: examples/webpinfo.o
examples/anim_diff: examples/libanim_util.a examples/libgifdec.a examples/anim_diff: examples/libanim_util.a examples/libgifdec.a
examples/anim_diff: src/demux/libwebpdemux.a examples/libexample_util.a examples/anim_diff: src/demux/libwebpdemux.a examples/libexample_util.a
examples/anim_diff: imageio/libimageio_util.a src/libwebp.a examples/anim_diff: imageio/libimageio_util.a src/libwebp.a
examples/anim_diff: override EXTRA_LIBS += $(GIF_LIBS) examples/anim_diff: EXTRA_LIBS += $(GIF_LIBS)
examples/anim_diff: EXTRA_FLAGS += -DWEBP_HAVE_GIF examples/anim_diff: EXTRA_FLAGS += -DWEBP_HAVE_GIF
examples/anim_dump: examples/libanim_util.a examples/libgifdec.a examples/anim_dump: examples/libanim_util.a examples/libgifdec.a
examples/anim_dump: src/demux/libwebpdemux.a examples/anim_dump: src/demux/libwebpdemux.a
@ -410,27 +406,27 @@ examples/anim_dump: examples/libexample_util.a
examples/anim_dump: imageio/libimageio_util.a examples/anim_dump: imageio/libimageio_util.a
examples/anim_dump: imageio/libimageenc.a examples/anim_dump: imageio/libimageenc.a
examples/anim_dump: src/libwebp.a examples/anim_dump: src/libwebp.a
examples/anim_dump: override EXTRA_LIBS += $(GIF_LIBS) $(DWEBP_LIBS) examples/anim_dump: EXTRA_LIBS += $(GIF_LIBS) $(DWEBP_LIBS)
examples/cwebp: examples/libexample_util.a examples/cwebp: examples/libexample_util.a
examples/cwebp: imageio/libimagedec.a examples/cwebp: imageio/libimagedec.a
examples/cwebp: src/demux/libwebpdemux.a examples/cwebp: src/demux/libwebpdemux.a
examples/cwebp: imageio/libimageio_util.a examples/cwebp: imageio/libimageio_util.a
examples/cwebp: src/libwebp.a examples/cwebp: src/libwebp.a
examples/cwebp: override EXTRA_LIBS += $(CWEBP_LIBS) examples/cwebp: EXTRA_LIBS += $(CWEBP_LIBS)
examples/dwebp: examples/libexample_util.a examples/dwebp: examples/libexample_util.a
examples/dwebp: imageio/libimagedec.a examples/dwebp: imageio/libimagedec.a
examples/dwebp: src/demux/libwebpdemux.a examples/dwebp: src/demux/libwebpdemux.a
examples/dwebp: imageio/libimageenc.a examples/dwebp: imageio/libimageenc.a
examples/dwebp: imageio/libimageio_util.a examples/dwebp: imageio/libimageio_util.a
examples/dwebp: src/libwebp.a examples/dwebp: src/libwebp.a
examples/dwebp: override EXTRA_LIBS += $(DWEBP_LIBS) examples/dwebp: EXTRA_LIBS += $(DWEBP_LIBS)
examples/gif2webp: examples/libexample_util.a imageio/libimageio_util.a examples/gif2webp: examples/libexample_util.a imageio/libimageio_util.a
examples/gif2webp: examples/libgifdec.a src/mux/libwebpmux.a src/libwebp.a examples/gif2webp: examples/libgifdec.a src/mux/libwebpmux.a src/libwebp.a
examples/gif2webp: override EXTRA_LIBS += $(GIF_LIBS) examples/gif2webp: EXTRA_LIBS += $(GIF_LIBS)
examples/gif2webp: EXTRA_FLAGS += -DWEBP_HAVE_GIF examples/gif2webp: EXTRA_FLAGS += -DWEBP_HAVE_GIF
examples/vwebp: examples/libexample_util.a src/demux/libwebpdemux.a examples/vwebp: examples/libexample_util.a src/demux/libwebpdemux.a
examples/vwebp: imageio/libimageio_util.a src/libwebp.a examples/vwebp: imageio/libimageio_util.a src/libwebp.a
examples/vwebp: override EXTRA_LIBS += $(GL_LIBS) examples/vwebp: EXTRA_LIBS += $(GL_LIBS)
examples/vwebp: EXTRA_FLAGS += -DWEBP_HAVE_GL examples/vwebp: EXTRA_FLAGS += -DWEBP_HAVE_GL
examples/webpmux: examples/libexample_util.a imageio/libimageio_util.a examples/webpmux: examples/libexample_util.a imageio/libimageio_util.a
examples/webpmux: src/mux/libwebpmux.a src/libwebpdecoder.a examples/webpmux: src/mux/libwebpmux.a src/libwebpdecoder.a
@ -438,7 +434,7 @@ examples/img2webp: examples/libexample_util.a imageio/libimageio_util.a
examples/img2webp: imageio/libimagedec.a examples/img2webp: imageio/libimagedec.a
examples/img2webp: src/demux/libwebpdemux.a examples/img2webp: src/demux/libwebpdemux.a
examples/img2webp: src/mux/libwebpmux.a src/libwebp.a examples/img2webp: src/mux/libwebpmux.a src/libwebp.a
examples/img2webp: override EXTRA_LIBS += $(CWEBP_LIBS) examples/img2webp: EXTRA_LIBS += $(CWEBP_LIBS)
examples/webpinfo: examples/libexample_util.a imageio/libimageio_util.a examples/webpinfo: examples/libexample_util.a imageio/libimageio_util.a
examples/webpinfo: src/libwebpdecoder.a examples/webpinfo: src/libwebpdecoder.a
@ -447,7 +443,7 @@ extras/get_disto: imageio/libimagedec.a
extras/get_disto: src/demux/libwebpdemux.a extras/get_disto: src/demux/libwebpdemux.a
extras/get_disto: imageio/libimageio_util.a extras/get_disto: imageio/libimageio_util.a
extras/get_disto: src/libwebp.a extras/get_disto: src/libwebp.a
extras/get_disto: override EXTRA_LIBS += $(CWEBP_LIBS) extras/get_disto: EXTRA_LIBS += $(CWEBP_LIBS)
extras/webp_quality: extras/webp_quality.o extras/webp_quality: extras/webp_quality.o
extras/webp_quality: imageio/libimageio_util.a extras/webp_quality: imageio/libimageio_util.a
@ -458,7 +454,7 @@ extras/vwebp_sdl: extras/webp_to_sdl.o
extras/vwebp_sdl: imageio/libimageio_util.a extras/vwebp_sdl: imageio/libimageio_util.a
extras/vwebp_sdl: src/libwebp.a extras/vwebp_sdl: src/libwebp.a
extras/vwebp_sdl: EXTRA_FLAGS += -DWEBP_HAVE_SDL $(SDL_FLAGS) extras/vwebp_sdl: EXTRA_FLAGS += -DWEBP_HAVE_SDL $(SDL_FLAGS)
extras/vwebp_sdl: override EXTRA_LIBS += $(SDL_LIBS) extras/vwebp_sdl: EXTRA_LIBS += $(SDL_LIBS)
$(OUT_EXAMPLES) $(EXTRA_EXAMPLES) $(OTHER_EXAMPLES): $(OUT_EXAMPLES) $(EXTRA_EXAMPLES) $(OTHER_EXAMPLES):
$(CC) -o $@ $^ $(LDFLAGS) $(CC) -o $@ $^ $(LDFLAGS)

View File

@ -1,5 +1,5 @@
.\" Hey, EMACS: -*- nroff -*- .\" Hey, EMACS: -*- nroff -*-
.TH VWEBP 1 "June 5, 2019" .TH VWEBP 1 "July 20, 2018"
.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

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 # 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 7:5:0 libwebp_la_LDFLAGS = -no-undefined -version-info 7:4:0
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 3:5:0 libwebpdecoder_la_LDFLAGS = -no-undefined -version-info 3:4:0
pkgconfig_DATA += libwebpdecoder.pc pkgconfig_DATA += libwebpdecoder.pc
endif endif

View File

@ -61,17 +61,12 @@ static const uint16_t kAcTable[128] = {
void VP8ParseQuant(VP8Decoder* const dec) { void VP8ParseQuant(VP8Decoder* const dec) {
VP8BitReader* const br = &dec->br_; VP8BitReader* const br = &dec->br_;
const int base_q0 = VP8GetValue(br, 7, "global-header"); const int base_q0 = VP8GetValue(br, 7);
const int dqy1_dc = VP8Get(br, "global-header") ? const int dqy1_dc = VP8Get(br) ? VP8GetSignedValue(br, 4) : 0;
VP8GetSignedValue(br, 4, "global-header") : 0; const int dqy2_dc = VP8Get(br) ? VP8GetSignedValue(br, 4) : 0;
const int dqy2_dc = VP8Get(br, "global-header") ? const int dqy2_ac = VP8Get(br) ? VP8GetSignedValue(br, 4) : 0;
VP8GetSignedValue(br, 4, "global-header") : 0; const int dquv_dc = VP8Get(br) ? VP8GetSignedValue(br, 4) : 0;
const int dqy2_ac = VP8Get(br, "global-header") ? const int dquv_ac = VP8Get(br) ? VP8GetSignedValue(br, 4) : 0;
VP8GetSignedValue(br, 4, "global-header") : 0;
const int dquv_dc = VP8Get(br, "global-header") ?
VP8GetSignedValue(br, 4, "global-header") : 0;
const int dquv_ac = VP8Get(br, "global-header") ?
VP8GetSignedValue(br, 4, "global-header") : 0;
const VP8SegmentHeader* const hdr = &dec->segment_hdr_; const VP8SegmentHeader* const hdr = &dec->segment_hdr_;
int i; int i;

View File

@ -296,21 +296,20 @@ static void ParseIntraMode(VP8BitReader* const br,
// to decode more than 1 keyframe. // to decode more than 1 keyframe.
if (dec->segment_hdr_.update_map_) { if (dec->segment_hdr_.update_map_) {
// Hardcoded tree parsing // Hardcoded tree parsing
block->segment_ = !VP8GetBit(br, dec->proba_.segments_[0], "segments") block->segment_ = !VP8GetBit(br, dec->proba_.segments_[0])
? VP8GetBit(br, dec->proba_.segments_[1], "segments") ? VP8GetBit(br, dec->proba_.segments_[1])
: VP8GetBit(br, dec->proba_.segments_[2], "segments") + 2; : 2 + VP8GetBit(br, dec->proba_.segments_[2]);
} else { } else {
block->segment_ = 0; // default for intra block->segment_ = 0; // default for intra
} }
if (dec->use_skip_proba_) block->skip_ = VP8GetBit(br, dec->skip_p_, "skip"); if (dec->use_skip_proba_) block->skip_ = VP8GetBit(br, dec->skip_p_);
block->is_i4x4_ = !VP8GetBit(br, 145, "block-size"); block->is_i4x4_ = !VP8GetBit(br, 145); // decide for B_PRED first
if (!block->is_i4x4_) { if (!block->is_i4x4_) {
// Hardcoded 16x16 intra-mode decision tree. // Hardcoded 16x16 intra-mode decision tree.
const int ymode = const int ymode =
VP8GetBit(br, 156, "pred-modes") ? VP8GetBit(br, 156) ? (VP8GetBit(br, 128) ? TM_PRED : H_PRED)
(VP8GetBit(br, 128, "pred-modes") ? TM_PRED : H_PRED) : : (VP8GetBit(br, 163) ? V_PRED : DC_PRED);
(VP8GetBit(br, 163, "pred-modes") ? V_PRED : DC_PRED);
block->imodes_[0] = ymode; block->imodes_[0] = ymode;
memset(top, ymode, 4 * sizeof(*top)); memset(top, ymode, 4 * sizeof(*top));
memset(left, ymode, 4 * sizeof(*left)); memset(left, ymode, 4 * sizeof(*left));
@ -324,25 +323,22 @@ static void ParseIntraMode(VP8BitReader* const br,
const uint8_t* const prob = kBModesProba[top[x]][ymode]; const uint8_t* const prob = kBModesProba[top[x]][ymode];
#if (USE_GENERIC_TREE == 1) #if (USE_GENERIC_TREE == 1)
// Generic tree-parsing // Generic tree-parsing
int i = kYModesIntra4[VP8GetBit(br, prob[0], "pred-modes")]; int i = kYModesIntra4[VP8GetBit(br, prob[0])];
while (i > 0) { while (i > 0) {
i = kYModesIntra4[2 * i + VP8GetBit(br, prob[i], "pred-modes")]; i = kYModesIntra4[2 * i + VP8GetBit(br, prob[i])];
} }
ymode = -i; ymode = -i;
#else #else
// Hardcoded tree parsing // Hardcoded tree parsing
ymode = !VP8GetBit(br, prob[0], "pred-modes") ? B_DC_PRED : ymode = !VP8GetBit(br, prob[0]) ? B_DC_PRED :
!VP8GetBit(br, prob[1], "pred-modes") ? B_TM_PRED : !VP8GetBit(br, prob[1]) ? B_TM_PRED :
!VP8GetBit(br, prob[2], "pred-modes") ? B_VE_PRED : !VP8GetBit(br, prob[2]) ? B_VE_PRED :
!VP8GetBit(br, prob[3], "pred-modes") ? !VP8GetBit(br, prob[3]) ?
(!VP8GetBit(br, prob[4], "pred-modes") ? B_HE_PRED : (!VP8GetBit(br, prob[4]) ? B_HE_PRED :
(!VP8GetBit(br, prob[5], "pred-modes") ? B_RD_PRED (!VP8GetBit(br, prob[5]) ? B_RD_PRED : B_VR_PRED)) :
: B_VR_PRED)) : (!VP8GetBit(br, prob[6]) ? B_LD_PRED :
(!VP8GetBit(br, prob[6], "pred-modes") ? B_LD_PRED : (!VP8GetBit(br, prob[7]) ? B_VL_PRED :
(!VP8GetBit(br, prob[7], "pred-modes") ? B_VL_PRED : (!VP8GetBit(br, prob[8]) ? B_HD_PRED : B_HU_PRED)));
(!VP8GetBit(br, prob[8], "pred-modes") ? B_HD_PRED
: B_HU_PRED))
);
#endif // USE_GENERIC_TREE #endif // USE_GENERIC_TREE
top[x] = ymode; top[x] = ymode;
} }
@ -352,9 +348,9 @@ static void ParseIntraMode(VP8BitReader* const br,
} }
} }
// Hardcoded UVMode decision tree // Hardcoded UVMode decision tree
block->uvmode_ = !VP8GetBit(br, 142, "pred-modes-uv") ? DC_PRED block->uvmode_ = !VP8GetBit(br, 142) ? DC_PRED
: !VP8GetBit(br, 114, "pred-modes-uv") ? V_PRED : !VP8GetBit(br, 114) ? V_PRED
: VP8GetBit(br, 183, "pred-modes-uv") ? TM_PRED : H_PRED; : VP8GetBit(br, 183) ? TM_PRED : H_PRED;
} }
int VP8ParseIntraModeRow(VP8BitReader* const br, VP8Decoder* const dec) { int VP8ParseIntraModeRow(VP8BitReader* const br, VP8Decoder* const dec) {
@ -518,10 +514,8 @@ void VP8ParseProba(VP8BitReader* const br, VP8Decoder* const dec) {
for (b = 0; b < NUM_BANDS; ++b) { for (b = 0; b < NUM_BANDS; ++b) {
for (c = 0; c < NUM_CTX; ++c) { for (c = 0; c < NUM_CTX; ++c) {
for (p = 0; p < NUM_PROBAS; ++p) { for (p = 0; p < NUM_PROBAS; ++p) {
const int v = const int v = VP8GetBit(br, CoeffsUpdateProba[t][b][c][p]) ?
VP8GetBit(br, CoeffsUpdateProba[t][b][c][p], "global-header") ? VP8GetValue(br, 8) : CoeffsProba0[t][b][c][p];
VP8GetValue(br, 8, "global-header") :
CoeffsProba0[t][b][c][p];
proba->bands_[t][b].probas_[c][p] = v; proba->bands_[t][b].probas_[c][p] = v;
} }
} }
@ -530,8 +524,9 @@ void VP8ParseProba(VP8BitReader* const br, VP8Decoder* const dec) {
proba->bands_ptr_[t][b] = &proba->bands_[t][kBands[b]]; proba->bands_ptr_[t][b] = &proba->bands_[t][kBands[b]];
} }
} }
dec->use_skip_proba_ = VP8Get(br, "global-header"); dec->use_skip_proba_ = VP8Get(br);
if (dec->use_skip_proba_) { if (dec->use_skip_proba_) {
dec->skip_p_ = VP8GetValue(br, 8, "global-header"); dec->skip_p_ = VP8GetValue(br, 8);
} }
} }

View File

@ -161,26 +161,23 @@ static int ParseSegmentHeader(VP8BitReader* br,
VP8SegmentHeader* hdr, VP8Proba* proba) { VP8SegmentHeader* hdr, VP8Proba* proba) {
assert(br != NULL); assert(br != NULL);
assert(hdr != NULL); assert(hdr != NULL);
hdr->use_segment_ = VP8Get(br, "global-header"); hdr->use_segment_ = VP8Get(br);
if (hdr->use_segment_) { if (hdr->use_segment_) {
hdr->update_map_ = VP8Get(br, "global-header"); hdr->update_map_ = VP8Get(br);
if (VP8Get(br, "global-header")) { // update data if (VP8Get(br)) { // update data
int s; int s;
hdr->absolute_delta_ = VP8Get(br, "global-header"); hdr->absolute_delta_ = VP8Get(br);
for (s = 0; s < NUM_MB_SEGMENTS; ++s) { for (s = 0; s < NUM_MB_SEGMENTS; ++s) {
hdr->quantizer_[s] = VP8Get(br, "global-header") ? hdr->quantizer_[s] = VP8Get(br) ? VP8GetSignedValue(br, 7) : 0;
VP8GetSignedValue(br, 7, "global-header") : 0;
} }
for (s = 0; s < NUM_MB_SEGMENTS; ++s) { for (s = 0; s < NUM_MB_SEGMENTS; ++s) {
hdr->filter_strength_[s] = VP8Get(br, "global-header") ? hdr->filter_strength_[s] = VP8Get(br) ? VP8GetSignedValue(br, 6) : 0;
VP8GetSignedValue(br, 6, "global-header") : 0;
} }
} }
if (hdr->update_map_) { if (hdr->update_map_) {
int s; int s;
for (s = 0; s < MB_FEATURE_TREE_PROBS; ++s) { for (s = 0; s < MB_FEATURE_TREE_PROBS; ++s) {
proba->segments_[s] = VP8Get(br, "global-header") ? proba->segments_[s] = VP8Get(br) ? VP8GetValue(br, 8) : 255u;
VP8GetValue(br, 8, "global-header") : 255u;
} }
} }
} else { } else {
@ -208,7 +205,7 @@ static VP8StatusCode ParsePartitions(VP8Decoder* const dec,
size_t last_part; size_t last_part;
size_t p; size_t p;
dec->num_parts_minus_one_ = (1 << VP8GetValue(br, 2, "global-header")) - 1; dec->num_parts_minus_one_ = (1 << VP8GetValue(br, 2)) - 1;
last_part = dec->num_parts_minus_one_; last_part = dec->num_parts_minus_one_;
if (size < 3 * last_part) { if (size < 3 * last_part) {
// we can't even read the sizes with sz[]! That's a failure. // we can't even read the sizes with sz[]! That's a failure.
@ -232,21 +229,21 @@ static VP8StatusCode ParsePartitions(VP8Decoder* const dec,
// Paragraph 9.4 // Paragraph 9.4
static int ParseFilterHeader(VP8BitReader* br, VP8Decoder* const dec) { static int ParseFilterHeader(VP8BitReader* br, VP8Decoder* const dec) {
VP8FilterHeader* const hdr = &dec->filter_hdr_; VP8FilterHeader* const hdr = &dec->filter_hdr_;
hdr->simple_ = VP8Get(br, "global-header"); hdr->simple_ = VP8Get(br);
hdr->level_ = VP8GetValue(br, 6, "global-header"); hdr->level_ = VP8GetValue(br, 6);
hdr->sharpness_ = VP8GetValue(br, 3, "global-header"); hdr->sharpness_ = VP8GetValue(br, 3);
hdr->use_lf_delta_ = VP8Get(br, "global-header"); hdr->use_lf_delta_ = VP8Get(br);
if (hdr->use_lf_delta_) { if (hdr->use_lf_delta_) {
if (VP8Get(br, "global-header")) { // update lf-delta? if (VP8Get(br)) { // update lf-delta?
int i; int i;
for (i = 0; i < NUM_REF_LF_DELTAS; ++i) { for (i = 0; i < NUM_REF_LF_DELTAS; ++i) {
if (VP8Get(br, "global-header")) { if (VP8Get(br)) {
hdr->ref_lf_delta_[i] = VP8GetSignedValue(br, 6, "global-header"); hdr->ref_lf_delta_[i] = VP8GetSignedValue(br, 6);
} }
} }
for (i = 0; i < NUM_MODE_LF_DELTAS; ++i) { for (i = 0; i < NUM_MODE_LF_DELTAS; ++i) {
if (VP8Get(br, "global-header")) { if (VP8Get(br)) {
hdr->mode_lf_delta_[i] = VP8GetSignedValue(br, 6, "global-header"); hdr->mode_lf_delta_[i] = VP8GetSignedValue(br, 6);
} }
} }
} }
@ -355,8 +352,8 @@ int VP8GetHeaders(VP8Decoder* const dec, VP8Io* const io) {
buf_size -= frm_hdr->partition_length_; buf_size -= frm_hdr->partition_length_;
if (frm_hdr->key_frame_) { if (frm_hdr->key_frame_) {
pic_hdr->colorspace_ = VP8Get(br, "global-header"); pic_hdr->colorspace_ = VP8Get(br);
pic_hdr->clamp_type_ = VP8Get(br, "global-header"); pic_hdr->clamp_type_ = VP8Get(br);
} }
if (!ParseSegmentHeader(br, &dec->segment_hdr_, &dec->proba_)) { if (!ParseSegmentHeader(br, &dec->segment_hdr_, &dec->proba_)) {
return VP8SetError(dec, VP8_STATUS_BITSTREAM_ERROR, return VP8SetError(dec, VP8_STATUS_BITSTREAM_ERROR,
@ -381,7 +378,7 @@ int VP8GetHeaders(VP8Decoder* const dec, VP8Io* const io) {
"Not a key frame."); "Not a key frame.");
} }
VP8Get(br, "global-header"); // ignore the value of update_proba_ VP8Get(br); // ignore the value of update_proba_
VP8ParseProba(br, dec); VP8ParseProba(br, dec);
@ -406,28 +403,28 @@ static const uint8_t kZigzag[16] = {
// See section 13-2: http://tools.ietf.org/html/rfc6386#section-13.2 // See section 13-2: http://tools.ietf.org/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])) {
if (!VP8GetBit(br, p[4], "coeffs")) { if (!VP8GetBit(br, p[4])) {
v = 2; v = 2;
} else { } else {
v = 3 + VP8GetBit(br, p[5], "coeffs"); v = 3 + VP8GetBit(br, p[5]);
} }
} else { } else {
if (!VP8GetBit(br, p[6], "coeffs")) { if (!VP8GetBit(br, p[6])) {
if (!VP8GetBit(br, p[7], "coeffs")) { if (!VP8GetBit(br, p[7])) {
v = 5 + VP8GetBit(br, 159, "coeffs"); v = 5 + VP8GetBit(br, 159);
} else { } else {
v = 7 + 2 * VP8GetBit(br, 165, "coeffs"); v = 7 + 2 * VP8GetBit(br, 165);
v += VP8GetBit(br, 145, "coeffs"); v += VP8GetBit(br, 145);
} }
} else { } else {
const uint8_t* tab; const uint8_t* tab;
const int bit1 = VP8GetBit(br, p[8], "coeffs"); const int bit1 = VP8GetBit(br, p[8]);
const int bit0 = VP8GetBit(br, p[9 + bit1], "coeffs"); const int bit0 = VP8GetBit(br, p[9 + bit1]);
const int cat = 2 * bit1 + bit0; const int cat = 2 * bit1 + bit0;
v = 0; v = 0;
for (tab = kCat3456[cat]; *tab; ++tab) { for (tab = kCat3456[cat]; *tab; ++tab) {
v += v + VP8GetBit(br, *tab, "coeffs"); v += v + VP8GetBit(br, *tab);
} }
v += 3 + (8 << cat); v += 3 + (8 << cat);
} }
@ -441,24 +438,24 @@ static int GetCoeffsFast(VP8BitReader* const br,
int ctx, const quant_t dq, int n, int16_t* out) { int ctx, const quant_t dq, int n, int16_t* out) {
const uint8_t* p = prob[n]->probas_[ctx]; const uint8_t* p = prob[n]->probas_[ctx];
for (; n < 16; ++n) { for (; n < 16; ++n) {
if (!VP8GetBit(br, p[0], "coeffs")) { if (!VP8GetBit(br, p[0])) {
return n; // previous coeff was last non-zero coeff return n; // previous coeff was last non-zero coeff
} }
while (!VP8GetBit(br, p[1], "coeffs")) { // sequence of zero coeffs while (!VP8GetBit(br, p[1])) { // sequence of zero coeffs
p = prob[++n]->probas_[0]; p = prob[++n]->probas_[0];
if (n == 16) return 16; if (n == 16) return 16;
} }
{ // non zero coeff { // non zero coeff
const VP8ProbaArray* const p_ctx = &prob[n + 1]->probas_[0]; const VP8ProbaArray* const p_ctx = &prob[n + 1]->probas_[0];
int v; int v;
if (!VP8GetBit(br, p[2], "coeffs")) { if (!VP8GetBit(br, p[2])) {
v = 1; v = 1;
p = p_ctx[1]; p = p_ctx[1];
} else { } else {
v = GetLargeValue(br, p); v = GetLargeValue(br, p);
p = p_ctx[2]; p = p_ctx[2];
} }
out[kZigzag[n]] = VP8GetSigned(br, v, "coeffs") * dq[n > 0]; out[kZigzag[n]] = VP8GetSigned(br, v) * dq[n > 0];
} }
} }
return 16; return 16;
@ -471,24 +468,24 @@ static int GetCoeffsAlt(VP8BitReader* const br,
int ctx, const quant_t dq, int n, int16_t* out) { int ctx, const quant_t dq, int n, int16_t* out) {
const uint8_t* p = prob[n]->probas_[ctx]; const uint8_t* p = prob[n]->probas_[ctx];
for (; n < 16; ++n) { for (; n < 16; ++n) {
if (!VP8GetBitAlt(br, p[0], "coeffs")) { if (!VP8GetBitAlt(br, p[0])) {
return n; // previous coeff was last non-zero coeff return n; // previous coeff was last non-zero coeff
} }
while (!VP8GetBitAlt(br, p[1], "coeffs")) { // sequence of zero coeffs while (!VP8GetBitAlt(br, p[1])) { // sequence of zero coeffs
p = prob[++n]->probas_[0]; p = prob[++n]->probas_[0];
if (n == 16) return 16; if (n == 16) return 16;
} }
{ // non zero coeff { // non zero coeff
const VP8ProbaArray* const p_ctx = &prob[n + 1]->probas_[0]; const VP8ProbaArray* const p_ctx = &prob[n + 1]->probas_[0];
int v; int v;
if (!VP8GetBitAlt(br, p[2], "coeffs")) { if (!VP8GetBitAlt(br, p[2])) {
v = 1; v = 1;
p = p_ctx[1]; p = p_ctx[1];
} else { } else {
v = GetLargeValue(br, p); v = GetLargeValue(br, p);
p = p_ctx[2]; p = p_ctx[2];
} }
out[kZigzag[n]] = VP8GetSigned(br, v, "coeffs") * dq[n > 0]; out[kZigzag[n]] = VP8GetSigned(br, v) * dq[n > 0];
} }
} }
return 16; return 16;

View File

@ -32,7 +32,7 @@ extern "C" {
// version numbers // version numbers
#define DEC_MAJ_VERSION 1 #define DEC_MAJ_VERSION 1
#define DEC_MIN_VERSION 0 #define DEC_MIN_VERSION 0
#define DEC_REV_VERSION 3 #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),

View File

@ -362,8 +362,12 @@ 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;
// When reading htrees, some might be unused, as the format allows it.
// We will still read them but put them in this htree_group_bogus.
HTreeGroup htree_group_bogus;
HuffmanCode* huffman_tables = NULL; HuffmanCode* huffman_tables = NULL;
HuffmanCode* huffman_table = NULL; HuffmanCode* huffman_tables_bogus = NULL;
HuffmanCode* next = 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;
@ -414,6 +418,12 @@ static int ReadHuffmanCodes(VP8LDecoder* const dec, int xsize, int ysize,
if (*mapped_group == -1) *mapped_group = num_htree_groups++; if (*mapped_group == -1) *mapped_group = num_htree_groups++;
huffman_image[i] = *mapped_group; huffman_image[i] = *mapped_group;
} }
huffman_tables_bogus = (HuffmanCode*)WebPSafeMalloc(
table_size, sizeof(*huffman_tables_bogus));
if (huffman_tables_bogus == NULL) {
dec->status_ = VP8_STATUS_OUT_OF_MEMORY;
goto Error;
}
} else { } else {
num_htree_groups = num_htree_groups_max; num_htree_groups = num_htree_groups_max;
} }
@ -443,71 +453,63 @@ static int ReadHuffmanCodes(VP8LDecoder* const dec, int xsize, int ysize,
goto Error; goto Error;
} }
huffman_table = huffman_tables; next = 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, read the coefficients
// coefficients are valid but do not store them. // but store them to a bogus htree_group.
if (mapping != NULL && mapping[i] == -1) { const int is_bogus = (mapping != NULL && mapping[i] == -1);
for (j = 0; j < HUFFMAN_CODES_PER_META_CODE; ++j) { HTreeGroup* const htree_group =
int alphabet_size = kAlphabetSize[j]; is_bogus ? &htree_group_bogus :
if (j == 0 && color_cache_bits > 0) { &htree_groups[(mapping == NULL) ? i : mapping[i]];
alphabet_size += (1 << color_cache_bits); HuffmanCode** const htrees = htree_group->htrees;
} HuffmanCode* huffman_tables_i = is_bogus ? huffman_tables_bogus : next;
// Passing in NULL so that nothing gets filled. int size;
if (!ReadHuffmanCode(alphabet_size, dec, code_lengths, NULL)) { int total_size = 0;
goto Error; int is_trivial_literal = 1;
} int max_bits = 0;
for (j = 0; j < HUFFMAN_CODES_PER_META_CODE; ++j) {
int alphabet_size = kAlphabetSize[j];
htrees[j] = huffman_tables_i;
if (j == 0 && color_cache_bits > 0) {
alphabet_size += 1 << color_cache_bits;
} }
} else { size =
HTreeGroup* const htree_group = ReadHuffmanCode(alphabet_size, dec, code_lengths, huffman_tables_i);
&htree_groups[(mapping == NULL) ? i : mapping[i]]; if (size == 0) {
HuffmanCode** const htrees = htree_group->htrees; goto Error;
int size; }
int total_size = 0; if (is_trivial_literal && kLiteralMap[j] == 1) {
int is_trivial_literal = 1; is_trivial_literal = (huffman_tables_i->bits == 0);
int max_bits = 0; }
for (j = 0; j < HUFFMAN_CODES_PER_META_CODE; ++j) { total_size += huffman_tables_i->bits;
int alphabet_size = kAlphabetSize[j]; huffman_tables_i += size;
htrees[j] = huffman_table; if (j <= ALPHA) {
if (j == 0 && color_cache_bits > 0) { int local_max_bits = code_lengths[0];
alphabet_size += (1 << color_cache_bits); int k;
} for (k = 1; k < alphabet_size; ++k) {
size = ReadHuffmanCode(alphabet_size, dec, code_lengths, huffman_table); if (code_lengths[k] > local_max_bits) {
if (size == 0) { local_max_bits = code_lengths[k];
goto Error;
}
if (is_trivial_literal && kLiteralMap[j] == 1) {
is_trivial_literal = (huffman_table->bits == 0);
}
total_size += huffman_table->bits;
huffman_table += size;
if (j <= ALPHA) {
int local_max_bits = code_lengths[0];
int k;
for (k = 1; k < alphabet_size; ++k) {
if (code_lengths[k] > local_max_bits) {
local_max_bits = code_lengths[k];
}
} }
max_bits += local_max_bits;
} }
max_bits += local_max_bits;
} }
htree_group->is_trivial_literal = is_trivial_literal;
htree_group->is_trivial_code = 0;
if (is_trivial_literal) {
const int red = htrees[RED][0].value;
const int blue = htrees[BLUE][0].value;
const int alpha = htrees[ALPHA][0].value;
htree_group->literal_arb = ((uint32_t)alpha << 24) | (red << 16) | blue;
if (total_size == 0 && htrees[GREEN][0].value < NUM_LITERAL_CODES) {
htree_group->is_trivial_code = 1;
htree_group->literal_arb |= htrees[GREEN][0].value << 8;
}
}
htree_group->use_packed_table =
!htree_group->is_trivial_code && (max_bits < HUFFMAN_PACKED_BITS);
if (htree_group->use_packed_table) BuildPackedTable(htree_group);
} }
if (!is_bogus) next = huffman_tables_i;
htree_group->is_trivial_literal = is_trivial_literal;
htree_group->is_trivial_code = 0;
if (is_trivial_literal) {
const int red = htrees[RED][0].value;
const int blue = htrees[BLUE][0].value;
const int alpha = htrees[ALPHA][0].value;
htree_group->literal_arb = ((uint32_t)alpha << 24) | (red << 16) | blue;
if (total_size == 0 && htrees[GREEN][0].value < NUM_LITERAL_CODES) {
htree_group->is_trivial_code = 1;
htree_group->literal_arb |= htrees[GREEN][0].value << 8;
}
}
htree_group->use_packed_table =
!htree_group->is_trivial_code && (max_bits < HUFFMAN_PACKED_BITS);
if (htree_group->use_packed_table) BuildPackedTable(htree_group);
} }
ok = 1; ok = 1;
@ -519,6 +521,7 @@ static int ReadHuffmanCodes(VP8LDecoder* const dec, int xsize, int ysize,
Error: Error:
WebPSafeFree(code_lengths); WebPSafeFree(code_lengths);
WebPSafeFree(huffman_tables_bogus);
WebPSafeFree(mapping); WebPSafeFree(mapping);
if (!ok) { if (!ok) {
WebPSafeFree(huffman_image); WebPSafeFree(huffman_image);

View File

@ -25,7 +25,7 @@
#define DMUX_MAJ_VERSION 1 #define DMUX_MAJ_VERSION 1
#define DMUX_MIN_VERSION 0 #define DMUX_MIN_VERSION 0
#define DMUX_REV_VERSION 3 #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

View File

@ -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,0,3 FILEVERSION 1,0,0,2
PRODUCTVERSION 1,0,0,3 PRODUCTVERSION 1,0,0,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.0.3" VALUE "FileVersion", "1.0.2"
VALUE "InternalName", "libwebpdemux.dll" VALUE "InternalName", "libwebpdemux.dll"
VALUE "LegalCopyright", "Copyright (C) 2019" VALUE "LegalCopyright", "Copyright (C) 2019"
VALUE "OriginalFilename", "libwebpdemux.dll" VALUE "OriginalFilename", "libwebpdemux.dll"
VALUE "ProductName", "WebP Image Demuxer" VALUE "ProductName", "WebP Image Demuxer"
VALUE "ProductVersion", "1.0.3" VALUE "ProductVersion", "1.0.2"
END END
END END
BLOCK "VarFileInfo" BLOCK "VarFileInfo"

View File

@ -83,7 +83,7 @@ static void ApplyAlphaMultiply_NEON(uint8_t* rgba, int alpha_first,
static int DispatchAlpha_NEON(const uint8_t* alpha, int alpha_stride, static int DispatchAlpha_NEON(const uint8_t* alpha, int alpha_stride,
int width, int height, int width, int height,
uint8_t* dst, int dst_stride) { uint8_t* 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* alpha, int alpha_stride,
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);
@ -134,7 +135,7 @@ static void DispatchAlphaToGreen_NEON(const uint8_t* alpha, int alpha_stride,
static int ExtractAlpha_NEON(const uint8_t* argb, int argb_stride, static int ExtractAlpha_NEON(const uint8_t* argb, int argb_stride,
int width, int height, int width, int height,
uint8_t* alpha, int alpha_stride) { uint8_t* 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;
@ -156,6 +157,7 @@ static int ExtractAlpha_NEON(const uint8_t* 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);

View File

@ -214,7 +214,7 @@ static void ApplyAlphaMultiply_SSE2(uint8_t* rgba, int alpha_first,
// Alpha detection // Alpha detection
static int HasAlpha8b_SSE2(const uint8_t* src, int length) { static int HasAlpha8b_SSE2(const uint8_t* src, int length) {
const __m128i all_0xff = _mm_set1_epi8((char)0xff); const __m128i all_0xff = _mm_set1_epi8(0xff);
int i = 0; int i = 0;
for (; i + 16 <= length; i += 16) { for (; i + 16 <= length; i += 16) {
const __m128i v = _mm_loadu_si128((const __m128i*)(src + i)); const __m128i v = _mm_loadu_si128((const __m128i*)(src + i));
@ -228,7 +228,7 @@ static int HasAlpha8b_SSE2(const uint8_t* src, int length) {
static int HasAlpha32b_SSE2(const uint8_t* src, int length) { static int HasAlpha32b_SSE2(const uint8_t* src, int length) {
const __m128i alpha_mask = _mm_set1_epi32(0xff); const __m128i alpha_mask = _mm_set1_epi32(0xff);
const __m128i all_0xff = _mm_set1_epi8((char)0xff); const __m128i all_0xff = _mm_set1_epi8(0xff);
int i = 0; int i = 0;
// We don't know if we can access the last 3 bytes after the last alpha // We don't know if we can access the last 3 bytes after the last alpha
// value 'src[4 * length - 4]' (because we don't know if alpha is the first // value 'src[4 * length - 4]' (because we don't know if alpha is the first

View File

@ -173,8 +173,8 @@ static int AndroidCPUInfo(CPUFeature feature) {
const AndroidCpuFamily cpu_family = android_getCpuFamily(); const AndroidCpuFamily cpu_family = android_getCpuFamily();
const uint64_t cpu_features = android_getCpuFeatures(); const uint64_t cpu_features = android_getCpuFeatures();
if (feature == kNEON) { if (feature == kNEON) {
return cpu_family == ANDROID_CPU_FAMILY_ARM && return (cpu_family == ANDROID_CPU_FAMILY_ARM &&
(cpu_features & ANDROID_CPU_ARM_FEATURE_NEON) != 0; 0 != (cpu_features & ANDROID_CPU_ARM_FEATURE_NEON));
} }
return 0; return 0;
} }

View File

@ -326,7 +326,7 @@ static WEBP_INLINE void Update2Pixels_SSE2(__m128i* const pi, __m128i* const qi,
const __m128i a1_lo = _mm_srai_epi16(*a0_lo, 7); const __m128i a1_lo = _mm_srai_epi16(*a0_lo, 7);
const __m128i a1_hi = _mm_srai_epi16(*a0_hi, 7); const __m128i a1_hi = _mm_srai_epi16(*a0_hi, 7);
const __m128i delta = _mm_packs_epi16(a1_lo, a1_hi); const __m128i delta = _mm_packs_epi16(a1_lo, a1_hi);
const __m128i sign_bit = _mm_set1_epi8((char)0x80); const __m128i sign_bit = _mm_set1_epi8(0x80);
*pi = _mm_adds_epi8(*pi, delta); *pi = _mm_adds_epi8(*pi, delta);
*qi = _mm_subs_epi8(*qi, delta); *qi = _mm_subs_epi8(*qi, delta);
FLIP_SIGN_BIT2(*pi, *qi); FLIP_SIGN_BIT2(*pi, *qi);
@ -338,9 +338,9 @@ static WEBP_INLINE void NeedsFilter_SSE2(const __m128i* const p1,
const __m128i* const q0, const __m128i* const q0,
const __m128i* const q1, const __m128i* const q1,
int thresh, __m128i* const mask) { int thresh, __m128i* const mask) {
const __m128i m_thresh = _mm_set1_epi8((char)thresh); const __m128i m_thresh = _mm_set1_epi8(thresh);
const __m128i t1 = MM_ABS(*p1, *q1); // abs(p1 - q1) const __m128i t1 = MM_ABS(*p1, *q1); // abs(p1 - q1)
const __m128i kFE = _mm_set1_epi8((char)0xFE); const __m128i kFE = _mm_set1_epi8(0xFE);
const __m128i t2 = _mm_and_si128(t1, kFE); // set lsb of each byte to zero const __m128i t2 = _mm_and_si128(t1, kFE); // set lsb of each byte to zero
const __m128i t3 = _mm_srli_epi16(t2, 1); // abs(p1 - q1) / 2 const __m128i t3 = _mm_srli_epi16(t2, 1); // abs(p1 - q1) / 2
@ -360,7 +360,7 @@ static WEBP_INLINE void DoFilter2_SSE2(__m128i* const p1, __m128i* const p0,
__m128i* const q0, __m128i* const q1, __m128i* const q0, __m128i* const q1,
int thresh) { int thresh) {
__m128i a, mask; __m128i a, mask;
const __m128i sign_bit = _mm_set1_epi8((char)0x80); const __m128i sign_bit = _mm_set1_epi8(0x80);
// convert p1/q1 to int8_t (for GetBaseDelta_SSE2) // convert p1/q1 to int8_t (for GetBaseDelta_SSE2)
const __m128i p1s = _mm_xor_si128(*p1, sign_bit); const __m128i p1s = _mm_xor_si128(*p1, sign_bit);
const __m128i q1s = _mm_xor_si128(*q1, sign_bit); const __m128i q1s = _mm_xor_si128(*q1, sign_bit);
@ -380,7 +380,7 @@ static WEBP_INLINE void DoFilter4_SSE2(__m128i* const p1, __m128i* const p0,
const __m128i* const mask, const __m128i* const mask,
int hev_thresh) { int hev_thresh) {
const __m128i zero = _mm_setzero_si128(); const __m128i zero = _mm_setzero_si128();
const __m128i sign_bit = _mm_set1_epi8((char)0x80); const __m128i sign_bit = _mm_set1_epi8(0x80);
const __m128i k64 = _mm_set1_epi8(64); const __m128i k64 = _mm_set1_epi8(64);
const __m128i k3 = _mm_set1_epi8(3); const __m128i k3 = _mm_set1_epi8(3);
const __m128i k4 = _mm_set1_epi8(4); const __m128i k4 = _mm_set1_epi8(4);
@ -427,7 +427,7 @@ static WEBP_INLINE void DoFilter6_SSE2(__m128i* const p2, __m128i* const p1,
const __m128i* const mask, const __m128i* const mask,
int hev_thresh) { int hev_thresh) {
const __m128i zero = _mm_setzero_si128(); const __m128i zero = _mm_setzero_si128();
const __m128i sign_bit = _mm_set1_epi8((char)0x80); const __m128i sign_bit = _mm_set1_epi8(0x80);
__m128i a, not_hev; __m128i a, not_hev;
// compute hev mask // compute hev mask
@ -941,7 +941,7 @@ static void VR4_SSE2(uint8_t* dst) { // Vertical-Right
const __m128i ABCD0 = _mm_srli_si128(XABCD, 1); const __m128i ABCD0 = _mm_srli_si128(XABCD, 1);
const __m128i abcd = _mm_avg_epu8(XABCD, ABCD0); const __m128i abcd = _mm_avg_epu8(XABCD, ABCD0);
const __m128i _XABCD = _mm_slli_si128(XABCD, 1); const __m128i _XABCD = _mm_slli_si128(XABCD, 1);
const __m128i IXABCD = _mm_insert_epi16(_XABCD, (short)(I | (X << 8)), 0); const __m128i IXABCD = _mm_insert_epi16(_XABCD, I | (X << 8), 0);
const __m128i avg1 = _mm_avg_epu8(IXABCD, ABCD0); const __m128i avg1 = _mm_avg_epu8(IXABCD, ABCD0);
const __m128i lsb = _mm_and_si128(_mm_xor_si128(IXABCD, ABCD0), one); const __m128i lsb = _mm_and_si128(_mm_xor_si128(IXABCD, ABCD0), one);
const __m128i avg2 = _mm_subs_epu8(avg1, lsb); const __m128i avg2 = _mm_subs_epu8(avg1, lsb);

View File

@ -777,7 +777,7 @@ static WEBP_INLINE void VR4_SSE2(uint8_t* dst,
const __m128i ABCD0 = _mm_srli_si128(XABCD, 1); const __m128i ABCD0 = _mm_srli_si128(XABCD, 1);
const __m128i abcd = _mm_avg_epu8(XABCD, ABCD0); const __m128i abcd = _mm_avg_epu8(XABCD, ABCD0);
const __m128i _XABCD = _mm_slli_si128(XABCD, 1); const __m128i _XABCD = _mm_slli_si128(XABCD, 1);
const __m128i IXABCD = _mm_insert_epi16(_XABCD, (short)(I | (X << 8)), 0); const __m128i IXABCD = _mm_insert_epi16(_XABCD, I | (X << 8), 0);
const __m128i avg1 = _mm_avg_epu8(IXABCD, ABCD0); const __m128i avg1 = _mm_avg_epu8(IXABCD, ABCD0);
const __m128i lsb = _mm_and_si128(_mm_xor_si128(IXABCD, ABCD0), one); const __m128i lsb = _mm_and_si128(_mm_xor_si128(IXABCD, ABCD0), one);
const __m128i avg2 = _mm_subs_epu8(avg1, lsb); const __m128i avg2 = _mm_subs_epu8(avg1, lsb);

View File

@ -33,9 +33,9 @@ static WEBP_INLINE void PredictLine_C(const uint8_t* src, const uint8_t* pred,
uint8_t* dst, int length, int inverse) { uint8_t* dst, int length, int inverse) {
int i; int i;
if (inverse) { if (inverse) {
for (i = 0; i < length; ++i) dst[i] = (uint8_t)(src[i] + pred[i]); for (i = 0; i < length; ++i) dst[i] = src[i] + pred[i];
} else { } else {
for (i = 0; i < length; ++i) dst[i] = (uint8_t)(src[i] - pred[i]); for (i = 0; i < length; ++i) dst[i] = src[i] - pred[i];
} }
} }
@ -155,7 +155,7 @@ static WEBP_INLINE void DoGradientFilter_C(const uint8_t* in,
const int pred = GradientPredictor_C(preds[w - 1], const int pred = GradientPredictor_C(preds[w - 1],
preds[w - stride], preds[w - stride],
preds[w - stride - 1]); preds[w - stride - 1]);
out[w] = (uint8_t)(in[w] + (inverse ? pred : -pred)); out[w] = in[w] + (inverse ? pred : -pred);
} }
++row; ++row;
preds += stride; preds += stride;
@ -194,7 +194,7 @@ static void HorizontalUnfilter_C(const uint8_t* prev, const uint8_t* in,
uint8_t pred = (prev == NULL) ? 0 : prev[0]; uint8_t pred = (prev == NULL) ? 0 : prev[0];
int i; int i;
for (i = 0; i < width; ++i) { for (i = 0; i < width; ++i) {
out[i] = (uint8_t)(pred + in[i]); out[i] = pred + in[i];
pred = out[i]; pred = out[i];
} }
} }
@ -206,7 +206,7 @@ static void VerticalUnfilter_C(const uint8_t* prev, const uint8_t* in,
HorizontalUnfilter_C(NULL, in, out, width); HorizontalUnfilter_C(NULL, in, out, width);
} else { } else {
int i; int i;
for (i = 0; i < width; ++i) out[i] = (uint8_t)(prev[i] + in[i]); for (i = 0; i < width; ++i) out[i] = prev[i] + in[i];
} }
} }
#endif // !WEBP_NEON_OMIT_C_CODE #endif // !WEBP_NEON_OMIT_C_CODE
@ -220,7 +220,7 @@ static void GradientUnfilter_C(const uint8_t* prev, const uint8_t* in,
int i; int i;
for (i = 0; i < width; ++i) { for (i = 0; i < width; ++i) {
top = prev[i]; // need to read this first, in case prev==out top = prev[i]; // need to read this first, in case prev==out
left = (uint8_t)(in[i] + GradientPredictor_C(left, top, top_left)); left = in[i] + GradientPredictor_C(left, top, top_left);
top_left = top; top_left = top;
out[i] = left; out[i] = left;
} }

View File

@ -163,8 +163,7 @@ static void GradientPredictDirect_SSE2(const uint8_t* const row,
_mm_storel_epi64((__m128i*)(out + i), H); _mm_storel_epi64((__m128i*)(out + i), H);
} }
for (; i < length; ++i) { for (; i < length; ++i) {
const int delta = GradientPredictor_SSE2(row[i - 1], top[i], top[i - 1]); out[i] = row[i] - GradientPredictor_SSE2(row[i - 1], top[i], top[i - 1]);
out[i] = (uint8_t)(row[i] - delta);
} }
} }
@ -189,7 +188,7 @@ static WEBP_INLINE void DoGradientFilter_SSE2(const uint8_t* in,
// Filter line-by-line. // Filter line-by-line.
while (row < last_row) { while (row < last_row) {
out[0] = (uint8_t)(in[0] - in[-stride]); out[0] = in[0] - in[-stride];
GradientPredictDirect_SSE2(in + 1, in + 1 - stride, out + 1, width - 1); GradientPredictDirect_SSE2(in + 1, in + 1 - stride, out + 1, width - 1);
++row; ++row;
in += stride; in += stride;
@ -224,7 +223,7 @@ static void HorizontalUnfilter_SSE2(const uint8_t* prev, const uint8_t* in,
uint8_t* out, int width) { uint8_t* out, int width) {
int i; int i;
__m128i last; __m128i last;
out[0] = (uint8_t)(in[0] + (prev == NULL ? 0 : prev[0])); out[0] = in[0] + (prev == NULL ? 0 : prev[0]);
if (width <= 1) return; if (width <= 1) return;
last = _mm_set_epi32(0, 0, 0, out[0]); last = _mm_set_epi32(0, 0, 0, out[0]);
for (i = 1; i + 8 <= width; i += 8) { for (i = 1; i + 8 <= width; i += 8) {
@ -239,7 +238,7 @@ static void HorizontalUnfilter_SSE2(const uint8_t* prev, const uint8_t* in,
_mm_storel_epi64((__m128i*)(out + i), A7); _mm_storel_epi64((__m128i*)(out + i), A7);
last = _mm_srli_epi64(A7, 56); last = _mm_srli_epi64(A7, 56);
} }
for (; i < width; ++i) out[i] = (uint8_t)(in[i] + out[i - 1]); for (; i < width; ++i) out[i] = in[i] + out[i - 1];
} }
static void VerticalUnfilter_SSE2(const uint8_t* prev, const uint8_t* in, static void VerticalUnfilter_SSE2(const uint8_t* prev, const uint8_t* in,
@ -260,7 +259,7 @@ static void VerticalUnfilter_SSE2(const uint8_t* prev, const uint8_t* in,
_mm_storeu_si128((__m128i*)&out[i + 0], C0); _mm_storeu_si128((__m128i*)&out[i + 0], C0);
_mm_storeu_si128((__m128i*)&out[i + 16], C1); _mm_storeu_si128((__m128i*)&out[i + 16], C1);
} }
for (; i < width; ++i) out[i] = (uint8_t)(in[i] + prev[i]); for (; i < width; ++i) out[i] = in[i] + prev[i];
} }
} }
@ -297,8 +296,7 @@ static void GradientPredictInverse_SSE2(const uint8_t* const in,
_mm_storel_epi64((__m128i*)&row[i], out); _mm_storel_epi64((__m128i*)&row[i], out);
} }
for (; i < length; ++i) { for (; i < length; ++i) {
const int delta = GradientPredictor_SSE2(row[i - 1], top[i], top[i - 1]); row[i] = in[i] + GradientPredictor_SSE2(row[i - 1], top[i], top[i - 1]);
row[i] = (uint8_t)(in[i] + delta);
} }
} }
} }
@ -308,7 +306,7 @@ static void GradientUnfilter_SSE2(const uint8_t* prev, const uint8_t* in,
if (prev == NULL) { if (prev == NULL) {
HorizontalUnfilter_SSE2(NULL, in, out, width); HorizontalUnfilter_SSE2(NULL, in, out, width);
} else { } else {
out[0] = (uint8_t)(in[0] + prev[0]); // predict from above out[0] = in[0] + prev[0]; // predict from above
GradientPredictInverse_SSE2(in + 1, prev + 1, out + 1, width - 1); GradientPredictInverse_SSE2(in + 1, prev + 1, out + 1, width - 1);
} }
} }

View File

@ -270,14 +270,14 @@ void VP8LTransformColorInverse_C(const VP8LMultipliers* const m,
int i; int i;
for (i = 0; i < num_pixels; ++i) { for (i = 0; i < num_pixels; ++i) {
const uint32_t argb = src[i]; const uint32_t argb = src[i];
const int8_t green = (int8_t)(argb >> 8); const uint32_t green = argb >> 8;
const uint32_t red = argb >> 16; const uint32_t red = argb >> 16;
int new_red = red & 0xff; int new_red = red & 0xff;
int new_blue = argb & 0xff; int new_blue = argb & 0xff;
new_red += ColorTransformDelta(m->green_to_red_, green); new_red += ColorTransformDelta(m->green_to_red_, green);
new_red &= 0xff; new_red &= 0xff;
new_blue += ColorTransformDelta(m->green_to_blue_, green); new_blue += ColorTransformDelta(m->green_to_blue_, green);
new_blue += ColorTransformDelta(m->red_to_blue_, (int8_t)new_red); new_blue += ColorTransformDelta(m->red_to_blue_, new_red);
new_blue &= 0xff; new_blue &= 0xff;
dst[i] = (argb & 0xff00ff00u) | (new_red << 16) | (new_blue); dst[i] = (argb & 0xff00ff00u) | (new_red << 16) | (new_blue);
} }

View File

@ -515,17 +515,13 @@ static WEBP_INLINE int ColorTransformDelta(int8_t color_pred, int8_t color) {
return ((int)color_pred * color) >> 5; return ((int)color_pred * color) >> 5;
} }
static WEBP_INLINE int8_t U32ToS8(uint32_t v) {
return (int8_t)(v & 0xff);
}
void VP8LTransformColor_C(const VP8LMultipliers* const m, uint32_t* data, void VP8LTransformColor_C(const VP8LMultipliers* const m, uint32_t* data,
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 uint32_t argb = data[i]; const uint32_t argb = data[i];
const int8_t green = U32ToS8(argb >> 8); const uint32_t green = argb >> 8;
const int8_t red = U32ToS8(argb >> 16); const uint32_t red = argb >> 16;
int new_red = red & 0xff; int new_red = red & 0xff;
int new_blue = argb & 0xff; int new_blue = argb & 0xff;
new_red -= ColorTransformDelta(m->green_to_red_, green); new_red -= ColorTransformDelta(m->green_to_red_, green);
@ -539,7 +535,7 @@ void VP8LTransformColor_C(const VP8LMultipliers* const m, uint32_t* data,
static WEBP_INLINE uint8_t TransformColorRed(uint8_t green_to_red, static WEBP_INLINE uint8_t TransformColorRed(uint8_t green_to_red,
uint32_t argb) { uint32_t argb) {
const int8_t green = U32ToS8(argb >> 8); const uint32_t green = argb >> 8;
int new_red = argb >> 16; int new_red = argb >> 16;
new_red -= ColorTransformDelta(green_to_red, green); new_red -= ColorTransformDelta(green_to_red, green);
return (new_red & 0xff); return (new_red & 0xff);
@ -548,9 +544,9 @@ static WEBP_INLINE uint8_t TransformColorRed(uint8_t green_to_red,
static WEBP_INLINE uint8_t TransformColorBlue(uint8_t green_to_blue, static WEBP_INLINE uint8_t TransformColorBlue(uint8_t green_to_blue,
uint8_t red_to_blue, uint8_t red_to_blue,
uint32_t argb) { uint32_t argb) {
const int8_t green = U32ToS8(argb >> 8); const uint32_t green = argb >> 8;
const int8_t red = U32ToS8(argb >> 16); const uint32_t red = argb >> 16;
uint8_t new_blue = argb & 0xff; uint8_t new_blue = argb;
new_blue -= ColorTransformDelta(green_to_blue, green); new_blue -= ColorTransformDelta(green_to_blue, green);
new_blue -= ColorTransformDelta(red_to_blue, red); new_blue -= ColorTransformDelta(red_to_blue, red);
return (new_blue & 0xff); return (new_blue & 0xff);
@ -562,7 +558,7 @@ void VP8LCollectColorRedTransforms_C(const uint32_t* argb, int stride,
while (tile_height-- > 0) { while (tile_height-- > 0) {
int x; int x;
for (x = 0; x < tile_width; ++x) { for (x = 0; x < tile_width; ++x) {
++histo[TransformColorRed((uint8_t)green_to_red, argb[x])]; ++histo[TransformColorRed(green_to_red, argb[x])];
} }
argb += stride; argb += stride;
} }
@ -575,8 +571,7 @@ void VP8LCollectColorBlueTransforms_C(const uint32_t* argb, int stride,
while (tile_height-- > 0) { while (tile_height-- > 0) {
int x; int x;
for (x = 0; x < tile_width; ++x) { for (x = 0; x < tile_width; ++x) {
++histo[TransformColorBlue((uint8_t)green_to_blue, (uint8_t)red_to_blue, ++histo[TransformColorBlue(green_to_blue, red_to_blue, argb[x])];
argb[x])];
} }
argb += stride; argb += stride;
} }

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

View File

@ -363,7 +363,7 @@ static void BundleColorMap_SSE2(const uint8_t* const row, int width, int xbits,
assert(xbits <= 3); assert(xbits <= 3);
switch (xbits) { switch (xbits) {
case 0: { case 0: {
const __m128i ff = _mm_set1_epi16((short)0xff00); const __m128i ff = _mm_set1_epi16(0xff00);
const __m128i zero = _mm_setzero_si128(); const __m128i zero = _mm_setzero_si128();
// Store 0xff000000 | (row[x] << 8). // Store 0xff000000 | (row[x] << 8).
for (x = 0; x + 16 <= width; x += 16, dst += 16) { for (x = 0; x + 16 <= width; x += 16, dst += 16) {
@ -382,7 +382,7 @@ static void BundleColorMap_SSE2(const uint8_t* const row, int width, int xbits,
break; break;
} }
case 1: { case 1: {
const __m128i ff = _mm_set1_epi16((short)0xff00); const __m128i ff = _mm_set1_epi16(0xff00);
const __m128i mul = _mm_set1_epi16(0x110); const __m128i mul = _mm_set1_epi16(0x110);
for (x = 0; x + 16 <= width; x += 16, dst += 8) { for (x = 0; x + 16 <= width; x += 16, dst += 8) {
// 0a0b | (where a/b are 4 bits). // 0a0b | (where a/b are 4 bits).

View File

@ -51,9 +51,9 @@ static void CollectColorBlueTransforms_SSE41(const uint32_t* argb, int stride,
int histo[]) { int histo[]) {
const __m128i mults_r = _mm_set1_epi16(CST_5b(red_to_blue)); const __m128i mults_r = _mm_set1_epi16(CST_5b(red_to_blue));
const __m128i mults_g = _mm_set1_epi16(CST_5b(green_to_blue)); const __m128i mults_g = _mm_set1_epi16(CST_5b(green_to_blue));
const __m128i mask_g = _mm_set1_epi16((short)0xff00); // green mask const __m128i mask_g = _mm_set1_epi16(0xff00); // green mask
const __m128i mask_gb = _mm_set1_epi32(0xffff); // green/blue mask const __m128i mask_gb = _mm_set1_epi32(0xffff); // green/blue mask
const __m128i mask_b = _mm_set1_epi16(0x00ff); // blue mask const __m128i mask_b = _mm_set1_epi16(0x00ff); // blue mask
const __m128i shuffler_lo = _mm_setr_epi8(-1, 2, -1, 6, -1, 10, -1, 14, -1, const __m128i shuffler_lo = _mm_setr_epi8(-1, 2, -1, 6, -1, 10, -1, 14, -1,
-1, -1, -1, -1, -1, -1, -1); -1, -1, -1, -1, -1, -1, -1);
const __m128i shuffler_hi = _mm_setr_epi8(-1, -1, -1, -1, -1, -1, -1, -1, -1, const __m128i shuffler_hi = _mm_setr_epi8(-1, -1, -1, -1, -1, -1, -1, -1, -1,

View File

@ -10,8 +10,6 @@
#ifndef WEBP_DSP_QUANT_H_ #ifndef WEBP_DSP_QUANT_H_
#define WEBP_DSP_QUANT_H_ #define WEBP_DSP_QUANT_H_
#include <string.h>
#include "src/dsp/dsp.h" #include "src/dsp/dsp.h"
#include "src/webp/types.h" #include "src/webp/types.h"
@ -69,17 +67,4 @@ static WEBP_INLINE int IsFlat(const int16_t* levels, int num_blocks,
#endif // defined(WEBP_USE_NEON) && !defined(WEBP_ANDROID_NEON) && #endif // defined(WEBP_USE_NEON) && !defined(WEBP_ANDROID_NEON) &&
// !defined(WEBP_HAVE_NEON_RTCD) // !defined(WEBP_HAVE_NEON_RTCD)
static WEBP_INLINE int IsFlatSource16(const uint8_t* src) {
const uint32_t v = src[0] * 0x01010101u;
int i;
for (i = 0; i < 16; ++i) {
if (memcmp(src + 0, &v, 4) || memcmp(src + 4, &v, 4) ||
memcmp(src + 8, &v, 4) || memcmp(src + 12, &v, 4)) {
return 0;
}
src += BPS;
}
return 1;
}
#endif // WEBP_DSP_QUANT_H_ #endif // WEBP_DSP_QUANT_H_

View File

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

View File

@ -191,14 +191,13 @@ void VP8LHashChainClear(VP8LHashChain* const p) {
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
static const uint32_t kHashMultiplierHi = 0xc6a4a793u; #define HASH_MULTIPLIER_HI (0xc6a4a793ULL)
static const uint32_t kHashMultiplierLo = 0x5bd1e996u; #define HASH_MULTIPLIER_LO (0x5bd1e996ULL)
static WEBP_UBSAN_IGNORE_UNSIGNED_OVERFLOW WEBP_INLINE static WEBP_INLINE uint32_t GetPixPairHash64(const uint32_t* const argb) {
uint32_t GetPixPairHash64(const uint32_t* const argb) {
uint32_t key; uint32_t key;
key = argb[1] * kHashMultiplierHi; key = (argb[1] * HASH_MULTIPLIER_HI) & 0xffffffffu;
key += argb[0] * kHashMultiplierLo; key += (argb[0] * HASH_MULTIPLIER_LO) & 0xffffffffu;
key = key >> (32 - HASH_BITS); key = key >> (32 - HASH_BITS);
return key; return key;
} }
@ -912,13 +911,14 @@ static VP8LBackwardRefs* GetBackwardReferences(
quality >= 25) { quality >= 25) {
const VP8LHashChain* const hash_chain_tmp = const VP8LHashChain* const hash_chain_tmp =
(lz77_type_best == kLZ77Standard) ? hash_chain : &hash_chain_box; (lz77_type_best == kLZ77Standard) ? hash_chain : &hash_chain_box;
if (VP8LBackwardReferencesTraceBackwards(width, height, argb, *cache_bits, double bit_cost_trace;
hash_chain_tmp, best, worst)) { if (!VP8LBackwardReferencesTraceBackwards(width, height, argb, *cache_bits,
double bit_cost_trace; hash_chain_tmp, best, worst)) {
VP8LHistogramCreate(histo, worst, *cache_bits); goto Error;
bit_cost_trace = VP8LHistogramEstimateBits(histo);
if (bit_cost_trace < bit_cost_best) best = worst;
} }
VP8LHistogramCreate(histo, worst, *cache_bits);
bit_cost_trace = VP8LHistogramEstimateBits(histo);
if (bit_cost_trace < bit_cost_best) best = worst;
} }
BackwardReferences2DLocality(width, best); BackwardReferences2DLocality(width, best);

View File

@ -202,7 +202,7 @@ static uint32_t NearLossless(uint32_t value, uint32_t predict,
} }
if ((value >> 24) == 0 || (value >> 24) == 0xff) { if ((value >> 24) == 0 || (value >> 24) == 0xff) {
// Preserve transparency of fully transparent or fully opaque pixels. // Preserve transparency of fully transparent or fully opaque pixels.
a = NearLosslessDiff((value >> 24) & 0xff, (predict >> 24) & 0xff); a = NearLosslessDiff(value >> 24, predict >> 24);
} else { } else {
a = NearLosslessComponent(value >> 24, predict >> 24, 0xff, quantization); a = NearLosslessComponent(value >> 24, predict >> 24, 0xff, quantization);
} }
@ -215,12 +215,12 @@ static uint32_t NearLossless(uint32_t value, uint32_t predict,
// The amount by which green has been adjusted during quantization. It is // The amount by which green has been adjusted during quantization. It is
// subtracted from red and blue for compensation, to avoid accumulating two // subtracted from red and blue for compensation, to avoid accumulating two
// quantization errors in them. // quantization errors in them.
green_diff = NearLosslessDiff(new_green, (value >> 8) & 0xff); green_diff = NearLosslessDiff(new_green, value >> 8);
} }
r = NearLosslessComponent(NearLosslessDiff((value >> 16) & 0xff, green_diff), r = NearLosslessComponent(NearLosslessDiff(value >> 16, green_diff),
(predict >> 16) & 0xff, 0xff - new_green, (predict >> 16) & 0xff, 0xff - new_green,
quantization); quantization);
b = NearLosslessComponent(NearLosslessDiff(value & 0xff, green_diff), b = NearLosslessComponent(NearLosslessDiff(value, green_diff),
predict & 0xff, 0xff - new_green, quantization); predict & 0xff, 0xff - new_green, quantization);
return ((uint32_t)a << 24) | ((uint32_t)r << 16) | ((uint32_t)g << 8) | b; return ((uint32_t)a << 24) | ((uint32_t)r << 16) | ((uint32_t)g << 8) | b;
} }
@ -587,7 +587,7 @@ static void GetBestGreenToRed(
} }
} }
} }
best_tx->green_to_red_ = (green_to_red_best & 0xff); best_tx->green_to_red_ = green_to_red_best;
} }
static float GetPredictionCostCrossColorBlue( static float GetPredictionCostCrossColorBlue(
@ -666,8 +666,8 @@ static void GetBestGreenRedToBlue(
break; // out of iter-loop. break; // out of iter-loop.
} }
} }
best_tx->green_to_blue_ = green_to_blue_best & 0xff; best_tx->green_to_blue_ = green_to_blue_best;
best_tx->red_to_blue_ = red_to_blue_best & 0xff; best_tx->red_to_blue_ = red_to_blue_best;
} }
#undef kGreenRedToBlueMaxIters #undef kGreenRedToBlueMaxIters
#undef kGreenRedToBlueNumAxis #undef kGreenRedToBlueNumAxis

View File

@ -33,7 +33,7 @@
// number of non-zero coeffs below which we consider the block very flat // number of non-zero coeffs below which we consider the block very flat
// (and apply a penalty to complex predictions) // (and apply a penalty to complex predictions)
#define FLATNESS_LIMIT_I16 0 // I16 mode (special case) #define FLATNESS_LIMIT_I16 10 // I16 mode
#define FLATNESS_LIMIT_I4 3 // I4 mode #define FLATNESS_LIMIT_I4 3 // I4 mode
#define FLATNESS_LIMIT_UV 2 // UV mode #define FLATNESS_LIMIT_UV 2 // UV mode
#define FLATNESS_PENALTY 140 // roughly ~1bit per block #define FLATNESS_PENALTY 140 // roughly ~1bit per block
@ -988,7 +988,6 @@ static void PickBestIntra16(VP8EncIterator* const it, VP8ModeScore* rd) {
VP8ModeScore* rd_cur = &rd_tmp; VP8ModeScore* rd_cur = &rd_tmp;
VP8ModeScore* rd_best = rd; VP8ModeScore* rd_best = rd;
int mode; int mode;
int is_flat = IsFlatSource16(it->yuv_in_ + Y_OFF_ENC);
rd->mode_i16 = -1; rd->mode_i16 = -1;
for (mode = 0; mode < NUM_PRED_MODES; ++mode) { for (mode = 0; mode < NUM_PRED_MODES; ++mode) {
@ -1004,14 +1003,10 @@ static void PickBestIntra16(VP8EncIterator* const it, VP8ModeScore* rd) {
tlambda ? MULT_8B(tlambda, VP8TDisto16x16(src, tmp_dst, kWeightY)) : 0; tlambda ? MULT_8B(tlambda, VP8TDisto16x16(src, tmp_dst, kWeightY)) : 0;
rd_cur->H = VP8FixedCostsI16[mode]; rd_cur->H = VP8FixedCostsI16[mode];
rd_cur->R = VP8GetCostLuma16(it, rd_cur); rd_cur->R = VP8GetCostLuma16(it, rd_cur);
if (is_flat) { if (mode > 0 &&
// refine the first impression (which was in pixel space) IsFlat(rd_cur->y_ac_levels[0], kNumBlocks, FLATNESS_LIMIT_I16)) {
is_flat = IsFlat(rd_cur->y_ac_levels[0], kNumBlocks, FLATNESS_LIMIT_I16); // penalty to avoid flat area to be mispredicted by complex mode
if (is_flat) { rd_cur->R += FLATNESS_PENALTY * kNumBlocks;
// Block is very flat. We put emphasis on the distortion being very low!
rd_cur->D *= 2;
rd_cur->SD *= 2;
}
} }
// Since we always examine Intra16 first, we can overwrite *rd directly. // Since we always examine Intra16 first, we can overwrite *rd directly.
@ -1092,8 +1087,7 @@ static int PickBestIntra4(VP8EncIterator* const it, VP8ModeScore* const rd) {
: 0; : 0;
rd_tmp.H = mode_costs[mode]; rd_tmp.H = mode_costs[mode];
// Add flatness penalty, to avoid flat area to be mispredicted // Add flatness penalty
// by a complex mode.
if (mode > 0 && IsFlat(tmp_levels, kNumBlocks, FLATNESS_LIMIT_I4)) { if (mode > 0 && IsFlat(tmp_levels, kNumBlocks, FLATNESS_LIMIT_I4)) {
rd_tmp.R = FLATNESS_PENALTY * kNumBlocks; rd_tmp.R = FLATNESS_PENALTY * kNumBlocks;
} else { } else {
@ -1248,19 +1242,11 @@ static void RefineUsingDistortion(VP8EncIterator* const it,
if (mode > 0 && VP8FixedCostsI16[mode] > bit_limit) { if (mode > 0 && VP8FixedCostsI16[mode] > bit_limit) {
continue; continue;
} }
if (score < best_score) { if (score < best_score) {
best_mode = mode; best_mode = mode;
best_score = score; best_score = score;
} }
} }
if (it->x_ == 0 || it->y_ == 0) {
// avoid starting a checkerboard resonance from the border. See bug #432.
if (IsFlatSource16(src)) {
best_mode = (it->x_ == 0) ? 0 : 2;
try_both_modes = 0; // stick to i16
}
}
VP8SetIntra16Mode(it, best_mode); VP8SetIntra16Mode(it, best_mode);
// we'll reconstruct later, if i16 mode actually gets selected // we'll reconstruct later, if i16 mode actually gets selected
} }

View File

@ -32,7 +32,7 @@ extern "C" {
// version numbers // version numbers
#define ENC_MAJ_VERSION 1 #define ENC_MAJ_VERSION 1
#define ENC_MIN_VERSION 0 #define ENC_MIN_VERSION 0
#define ENC_REV_VERSION 3 #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

View File

@ -1693,11 +1693,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;
} }

View File

@ -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,0,3 FILEVERSION 1,0,0,2
PRODUCTVERSION 1,0,0,3 PRODUCTVERSION 1,0,0,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.0.3" VALUE "FileVersion", "1.0.2"
VALUE "InternalName", "libwebp.dll" VALUE "InternalName", "libwebp.dll"
VALUE "LegalCopyright", "Copyright (C) 2019" VALUE "LegalCopyright", "Copyright (C) 2019"
VALUE "OriginalFilename", "libwebp.dll" VALUE "OriginalFilename", "libwebp.dll"
VALUE "ProductName", "WebP Image Codec" VALUE "ProductName", "WebP Image Codec"
VALUE "ProductVersion", "1.0.3" VALUE "ProductVersion", "1.0.2"
END END
END END
BLOCK "VarFileInfo" BLOCK "VarFileInfo"

View File

@ -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,0,3 FILEVERSION 1,0,0,2
PRODUCTVERSION 1,0,0,3 PRODUCTVERSION 1,0,0,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.0.3" VALUE "FileVersion", "1.0.2"
VALUE "InternalName", "libwebpdecoder.dll" VALUE "InternalName", "libwebpdecoder.dll"
VALUE "LegalCopyright", "Copyright (C) 2019" VALUE "LegalCopyright", "Copyright (C) 2019"
VALUE "OriginalFilename", "libwebpdecoder.dll" VALUE "OriginalFilename", "libwebpdecoder.dll"
VALUE "ProductName", "WebP Image Decoder" VALUE "ProductName", "WebP Image Decoder"
VALUE "ProductVersion", "1.0.3" VALUE "ProductVersion", "1.0.2"
END END
END END
BLOCK "VarFileInfo" BLOCK "VarFileInfo"

View File

@ -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,0,3 FILEVERSION 1,0,0,2
PRODUCTVERSION 1,0,0,3 PRODUCTVERSION 1,0,0,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.0.3" VALUE "FileVersion", "1.0.2"
VALUE "InternalName", "libwebpmux.dll" VALUE "InternalName", "libwebpmux.dll"
VALUE "LegalCopyright", "Copyright (C) 2019" VALUE "LegalCopyright", "Copyright (C) 2019"
VALUE "OriginalFilename", "libwebpmux.dll" VALUE "OriginalFilename", "libwebpmux.dll"
VALUE "ProductName", "WebP Image Muxer" VALUE "ProductName", "WebP Image Muxer"
VALUE "ProductVersion", "1.0.3" VALUE "ProductVersion", "1.0.2"
END END
END END
BLOCK "VarFileInfo" BLOCK "VarFileInfo"

View File

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

View File

@ -104,8 +104,7 @@ void VP8LoadNewBytes(VP8BitReader* const br) {
} }
// Read a bit with proba 'prob'. Speed-critical function! // Read a bit with proba 'prob'. Speed-critical function!
static WEBP_INLINE int VP8GetBit(VP8BitReader* const br, static WEBP_INLINE int VP8GetBit(VP8BitReader* const br, int prob) {
int prob, const char label[]) {
// Don't move this declaration! It makes a big speed difference to store // Don't move this declaration! It makes a big speed difference to store
// 'range' *before* calling VP8LoadNewBytes(), even if this function doesn't // 'range' *before* calling VP8LoadNewBytes(), even if this function doesn't
// alter br->range_ value. // alter br->range_ value.
@ -130,14 +129,13 @@ static WEBP_INLINE int VP8GetBit(VP8BitReader* const br,
br->bits_ -= shift; br->bits_ -= shift;
} }
br->range_ = range - 1; br->range_ = range - 1;
BT_TRACK(br);
return bit; return bit;
} }
} }
// simplified version of VP8GetBit() for prob=0x80 (note shift is always 1 here) // simplified version of VP8GetBit() for prob=0x80 (note shift is always 1 here)
static WEBP_UBSAN_IGNORE_UNSIGNED_OVERFLOW WEBP_INLINE static WEBP_UBSAN_IGNORE_UNSIGNED_OVERFLOW WEBP_INLINE
int VP8GetSigned(VP8BitReader* const br, int v, const char label[]) { int VP8GetSigned(VP8BitReader* const br, int v) {
if (br->bits_ < 0) { if (br->bits_ < 0) {
VP8LoadNewBytes(br); VP8LoadNewBytes(br);
} }
@ -150,13 +148,11 @@ int VP8GetSigned(VP8BitReader* const br, int v, const char label[]) {
br->range_ += mask; br->range_ += mask;
br->range_ |= 1; br->range_ |= 1;
br->value_ -= (bit_t)((split + 1) & mask) << pos; br->value_ -= (bit_t)((split + 1) & mask) << pos;
BT_TRACK(br);
return (v ^ mask) - mask; return (v ^ mask) - mask;
} }
} }
static WEBP_INLINE int VP8GetBitAlt(VP8BitReader* const br, static WEBP_INLINE int VP8GetBitAlt(VP8BitReader* const br, int prob) {
int prob, const char label[]) {
// Don't move this declaration! It makes a big speed difference to store // Don't move this declaration! It makes a big speed difference to store
// 'range' *before* calling VP8LoadNewBytes(), even if this function doesn't // 'range' *before* calling VP8LoadNewBytes(), even if this function doesn't
// alter br->range_ value. // alter br->range_ value.
@ -183,7 +179,6 @@ static WEBP_INLINE int VP8GetBitAlt(VP8BitReader* const br,
br->bits_ -= shift; br->bits_ -= shift;
} }
br->range_ = range; br->range_ = range;
BT_TRACK(br);
return bit; return bit;
} }
} }

View File

@ -102,18 +102,17 @@ void VP8LoadFinalBytes(VP8BitReader* const br) {
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// Higher-level calls // Higher-level calls
uint32_t VP8GetValue(VP8BitReader* const br, int bits, const char label[]) { uint32_t VP8GetValue(VP8BitReader* const br, int bits) {
uint32_t v = 0; uint32_t v = 0;
while (bits-- > 0) { while (bits-- > 0) {
v |= VP8GetBit(br, 0x80, label) << bits; v |= VP8GetBit(br, 0x80) << bits;
} }
return v; return v;
} }
int32_t VP8GetSignedValue(VP8BitReader* const br, int bits, int32_t VP8GetSignedValue(VP8BitReader* const br, int bits) {
const char label[]) { const int value = VP8GetValue(br, bits);
const int value = VP8GetValue(br, bits, label); return VP8Get(br) ? -value : value;
return VP8Get(br, label) ? -value : value;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@ -221,78 +220,3 @@ uint32_t VP8LReadBits(VP8LBitReader* const br, int n_bits) {
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// Bit-tracing tool
#if (BITTRACE > 0)
#include <stdlib.h> // for atexit()
#include <stdio.h>
#include <string.h>
#define MAX_NUM_LABELS 32
static struct {
const char* label;
int size;
int count;
} kLabels[MAX_NUM_LABELS];
static int last_label = 0;
static int last_pos = 0;
static const uint8_t* buf_start = NULL;
static int init_done = 0;
static void PrintBitTraces(void) {
int i;
int scale = 1;
int total = 0;
const char* units = "bits";
#if (BITTRACE == 2)
scale = 8;
units = "bytes";
#endif
for (i = 0; i < last_label; ++i) total += kLabels[i].size;
if (total < 1) total = 1; // avoid rounding errors
printf("=== Bit traces ===\n");
for (i = 0; i < last_label; ++i) {
const int skip = 16 - (int)strlen(kLabels[i].label);
const int value = (kLabels[i].size + scale - 1) / scale;
assert(skip > 0);
printf("%s \%*s: %6d %s \t[%5.2f%%] [count: %7d]\n",
kLabels[i].label, skip, "", value, units,
100.f * kLabels[i].size / total,
kLabels[i].count);
}
total = (total + scale - 1) / scale;
printf("Total: %d %s\n", total, units);
}
void BitTrace(const struct VP8BitReader* const br, const char label[]) {
int i, pos;
if (!init_done) {
memset(kLabels, 0, sizeof(kLabels));
atexit(PrintBitTraces);
buf_start = br->buf_;
init_done = 1;
}
pos = (int)(br->buf_ - buf_start) * 8 - br->bits_;
// if there's a too large jump, we've changed partition -> reset counter
if (abs(pos - last_pos) > 32) {
buf_start = br->buf_;
pos = 0;
last_pos = 0;
}
if (br->range_ >= 0x7f) pos += kVP8Log2Range[br->range_ - 0x7f];
for (i = 0; i < last_label; ++i) {
if (!strcmp(label, kLabels[i].label)) break;
}
if (i == MAX_NUM_LABELS) abort(); // overflow!
kLabels[i].label = label;
kLabels[i].size += pos - last_pos;
kLabels[i].count += 1;
if (i == last_label) ++last_label;
last_pos = pos;
}
#endif // BITTRACE > 0
//------------------------------------------------------------------------------

View File

@ -21,27 +21,6 @@
#endif #endif
#include "src/webp/types.h" #include "src/webp/types.h"
// Warning! This macro triggers quite some MACRO wizardry around func signature!
#if !defined(BITTRACE)
#define BITTRACE 0 // 0 = off, 1 = print bits, 2 = print bytes
#endif
#if (BITTRACE > 0)
struct VP8BitReader;
extern void BitTrace(const struct VP8BitReader* const br, const char label[]);
#define BT_TRACK(br) BitTrace(br, label)
#define VP8Get(BR, L) VP8GetValue(BR, 1, L)
#else
#define BT_TRACK(br)
// We'll REMOVE the 'const char label[]' from all signatures and calls (!!):
#define VP8GetValue(BR, N, L) VP8GetValue(BR, N)
#define VP8Get(BR, L) VP8GetValue(BR, 1, L)
#define VP8GetSignedValue(BR, N, L) VP8GetSignedValue(BR, N)
#define VP8GetBit(BR, P, L) VP8GetBit(BR, P)
#define VP8GetBitAlt(BR, P, L) VP8GetBitAlt(BR, P)
#define VP8GetSigned(BR, V, L) VP8GetSigned(BR, V)
#endif
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
@ -113,15 +92,17 @@ void VP8BitReaderSetBuffer(VP8BitReader* const br,
void VP8RemapBitReader(VP8BitReader* const br, ptrdiff_t offset); void VP8RemapBitReader(VP8BitReader* const br, ptrdiff_t offset);
// return the next value made of 'num_bits' bits // return the next value made of 'num_bits' bits
uint32_t VP8GetValue(VP8BitReader* const br, int num_bits, const char label[]); uint32_t VP8GetValue(VP8BitReader* const br, int num_bits);
static WEBP_INLINE uint32_t VP8Get(VP8BitReader* const br) {
return VP8GetValue(br, 1);
}
// return the next value with sign-extension. // return the next value with sign-extension.
int32_t VP8GetSignedValue(VP8BitReader* const br, int num_bits, int32_t VP8GetSignedValue(VP8BitReader* const br, int num_bits);
const char label[]);
// bit_reader_inl.h will implement the following methods: // bit_reader_inl.h will implement the following methods:
// static WEBP_INLINE int VP8GetBit(VP8BitReader* const br, int prob, ...) // static WEBP_INLINE int VP8GetBit(VP8BitReader* const br, int prob)
// static WEBP_INLINE int VP8GetSigned(VP8BitReader* const br, int v, ...) // static WEBP_INLINE int VP8GetSigned(VP8BitReader* const br, int v)
// and should be included by the .c files that actually need them. // and should be included by the .c files that actually need them.
// This is to avoid recompiling the whole library whenever this file is touched, // This is to avoid recompiling the whole library whenever this file is touched,
// and also allowing platform-specific ad-hoc hacks. // and also allowing platform-specific ad-hoc hacks.

View File

@ -70,7 +70,7 @@ static void Flush(VP8BitWriter* const bw) {
const int value = (bits & 0x100) ? 0x00 : 0xff; const int value = (bits & 0x100) ? 0x00 : 0xff;
for (; bw->run_ > 0; --bw->run_) bw->buf_[pos++] = value; for (; bw->run_ > 0; --bw->run_) bw->buf_[pos++] = value;
} }
bw->buf_[pos++] = bits & 0xff; bw->buf_[pos++] = bits;
bw->pos_ = pos; bw->pos_ = pos;
} else { } else {
bw->run_++; // delay writing of bytes 0xff, pending eventual carry. bw->run_++; // delay writing of bytes 0xff, pending eventual carry.

View File

@ -17,7 +17,6 @@
#include <assert.h> #include <assert.h>
#include "src/dsp/dsp.h"
#include "src/webp/types.h" #include "src/webp/types.h"
#ifdef __cplusplus #ifdef __cplusplus
@ -31,11 +30,10 @@ typedef struct {
int hash_bits_; int hash_bits_;
} VP8LColorCache; } VP8LColorCache;
static const uint32_t kHashMul = 0x1e35a7bdu; static const uint64_t kHashMul = 0x1e35a7bdull;
static WEBP_UBSAN_IGNORE_UNSIGNED_OVERFLOW WEBP_INLINE static WEBP_INLINE int VP8LHashPix(uint32_t argb, int shift) {
int VP8LHashPix(uint32_t argb, int shift) { return (int)(((argb * kHashMul) & 0xffffffffu) >> shift);
return (int)((argb * kHashMul) >> shift);
} }
static WEBP_INLINE uint32_t VP8LColorCacheLookup( static WEBP_INLINE uint32_t VP8LColorCacheLookup(

View File

@ -91,8 +91,7 @@ static int BuildHuffmanTable(HuffmanCode* const root_table, int root_bits,
assert(code_lengths_size != 0); assert(code_lengths_size != 0);
assert(code_lengths != NULL); assert(code_lengths != NULL);
assert((root_table != NULL && sorted != NULL) || assert(root_table != NULL);
(root_table == NULL && sorted == NULL));
assert(root_bits > 0); assert(root_bits > 0);
// Build histogram of code lengths. // Build histogram of code lengths.
@ -121,22 +120,16 @@ static int BuildHuffmanTable(HuffmanCode* const root_table, int root_bits,
for (symbol = 0; symbol < code_lengths_size; ++symbol) { for (symbol = 0; symbol < code_lengths_size; ++symbol) {
const int symbol_code_length = code_lengths[symbol]; const int symbol_code_length = code_lengths[symbol];
if (code_lengths[symbol] > 0) { if (code_lengths[symbol] > 0) {
if (sorted != NULL) { sorted[offset[symbol_code_length]++] = symbol;
sorted[offset[symbol_code_length]++] = symbol;
} else {
offset[symbol_code_length]++;
}
} }
} }
// Special case code with only one value. // Special case code with only one value.
if (offset[MAX_ALLOWED_CODE_LENGTH] == 1) { if (offset[MAX_ALLOWED_CODE_LENGTH] == 1) {
if (sorted != NULL) { HuffmanCode code;
HuffmanCode code; code.bits = 0;
code.bits = 0; code.value = (uint16_t)sorted[0];
code.value = (uint16_t)sorted[0]; ReplicateValue(table, 1, total_size, code);
ReplicateValue(table, 1, total_size, code);
}
return total_size; return total_size;
} }
@ -158,7 +151,6 @@ 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;
code.bits = (uint8_t)len; code.bits = (uint8_t)len;
@ -177,7 +169,6 @@ 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) {
@ -215,10 +206,7 @@ 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) {
int total_size; int total_size;
assert(code_lengths_size <= MAX_CODE_LENGTHS_SIZE); assert(code_lengths_size <= MAX_CODE_LENGTHS_SIZE);
if (root_table == NULL) { if (code_lengths_size <= SORTED_SIZE_CUTOFF) {
total_size = BuildHuffmanTable(NULL, root_bits,
code_lengths, code_lengths_size, NULL);
} else 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, total_size = BuildHuffmanTable(root_table, root_bits,

View File

@ -78,8 +78,6 @@ 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
// > 0 otherwise (but not the table size).
int VP8LBuildHuffmanTable(HuffmanCode* const root_table, int root_bits, 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);

View File

@ -84,14 +84,14 @@ int WebPRescalerGetScaledDimensions(int src_width, int src_height,
int height = *scaled_height; int height = *scaled_height;
// if width is unspecified, scale original proportionally to height ratio. // if width is unspecified, scale original proportionally to height ratio.
if (width == 0 && src_height > 0) { if (width == 0) {
width = width =
(int)(((uint64_t)src_width * height + src_height - 1) / src_height); (int)(((uint64_t)src_width * height + src_height / 2) / src_height);
} }
// if height is unspecified, scale original proportionally to width ratio. // if height is unspecified, scale original proportionally to width ratio.
if (height == 0 && src_width > 0) { if (height == 0) {
height = height =
(int)(((uint64_t)src_height * width + src_width - 1) / src_width); (int)(((uint64_t)src_height * width + src_width / 2) / src_width);
} }
// Check if the overall dimensions still make sense. // Check if the overall dimensions still make sense.
if (width <= 0 || height <= 0) { if (width <= 0 || height <= 0) {

View File

@ -217,12 +217,8 @@ static THREADFN ThreadLoop(void* ptr) {
done = 1; done = 1;
} }
// signal to the main thread that we're done (for Sync()) // signal to the main thread that we're done (for Sync())
// Note the associated mutex does not need to be held when signaling the
// condition. Unlocking the mutex first may improve performance in some
// implementations, avoiding the case where the waiting thread can't
// reacquire the mutex when woken.
pthread_mutex_unlock(&impl->mutex_);
pthread_cond_signal(&impl->condition_); pthread_cond_signal(&impl->condition_);
pthread_mutex_unlock(&impl->mutex_);
} }
return THREAD_RETURN(NULL); // Thread is finished return THREAD_RETURN(NULL); // Thread is finished
} }
@ -244,13 +240,7 @@ static void ChangeState(WebPWorker* const worker, WebPWorkerStatus new_status) {
// assign new status and release the working thread if needed // assign new status and release the working thread if needed
if (new_status != OK) { if (new_status != OK) {
worker->status_ = new_status; worker->status_ = new_status;
// Note the associated mutex does not need to be held when signaling the
// condition. Unlocking the mutex first may improve performance in some
// implementations, avoiding the case where the waiting thread can't
// reacquire the mutex when woken.
pthread_mutex_unlock(&impl->mutex_);
pthread_cond_signal(&impl->condition_); pthread_cond_signal(&impl->condition_);
return;
} }
} }
pthread_mutex_unlock(&impl->mutex_); pthread_mutex_unlock(&impl->mutex_);

View File

@ -92,14 +92,14 @@ static WEBP_INLINE uint32_t GetLE32(const uint8_t* const data) {
// Store 16, 24 or 32 bits in little-endian order. // Store 16, 24 or 32 bits in little-endian order.
static WEBP_INLINE void PutLE16(uint8_t* const data, int val) { static WEBP_INLINE void PutLE16(uint8_t* const data, int val) {
assert(val < (1 << 16)); assert(val < (1 << 16));
data[0] = (val >> 0) & 0xff; data[0] = (val >> 0);
data[1] = (val >> 8) & 0xff; data[1] = (val >> 8);
} }
static WEBP_INLINE void PutLE24(uint8_t* const data, int val) { static WEBP_INLINE void PutLE24(uint8_t* const data, int val) {
assert(val < (1 << 24)); assert(val < (1 << 24));
PutLE16(data, val & 0xffff); PutLE16(data, val & 0xffff);
data[2] = (val >> 16) & 0xff; data[2] = (val >> 16);
} }
static WEBP_INLINE void PutLE32(uint8_t* const data, uint32_t val) { static WEBP_INLINE void PutLE32(uint8_t* const data, uint32_t val) {

View File

@ -62,10 +62,6 @@ WEBP_EXTERN size_t WebPEncodeBGRA(const uint8_t* bgra,
// These functions are the equivalent of the above, but compressing in a // These functions are the equivalent of the above, but compressing in a
// lossless manner. Files are usually larger than lossy format, but will // lossless manner. Files are usually larger than lossy format, but will
// not suffer any compression loss. // not suffer any compression loss.
// Note these functions, like the lossy versions, use the library's default
// settings. For lossless this means 'exact' is disabled. RGB values in
// transparent areas will be modified to improve compression. To avoid this,
// use WebPEncode() and set WebPConfig::exact to 1.
WEBP_EXTERN size_t WebPEncodeLosslessRGB(const uint8_t* rgb, WEBP_EXTERN size_t WebPEncodeLosslessRGB(const uint8_t* rgb,
int width, int height, int stride, int width, int height, int stride,
uint8_t** output); uint8_t** output);

View File

@ -1,27 +1,13 @@
# Lint as: python2, python3
# This file was automatically generated by SWIG (http://www.swig.org). # This file was automatically generated by SWIG (http://www.swig.org).
# Version 3.0.10 # Version 2.0.4
# #
# Do not make changes to this file unless you know what you are doing--modify # Do not make changes to this file unless you know what you are doing--modify
# the SWIG interface file instead. # the SWIG interface file instead.
from sys import version_info
if version_info >= (2,6,0):
from sys import version_info as _swig_python_version_info
if _swig_python_version_info >= (2, 7, 0):
def swig_import_helper():
import importlib
pkg = __name__.rpartition('.')[0]
mname = '.'.join((pkg, '_libwebp')).lstrip('.')
try:
return importlib.import_module(mname)
except ImportError:
return importlib.import_module('_libwebp')
_libwebp = swig_import_helper()
del swig_import_helper
elif _swig_python_version_info >= (2, 6, 0):
def swig_import_helper(): def swig_import_helper():
from os.path import dirname from os.path import dirname
import imp import imp
@ -41,132 +27,112 @@ elif _swig_python_version_info >= (2, 6, 0):
del swig_import_helper del swig_import_helper
else: else:
import _libwebp import _libwebp
del _swig_python_version_info del version_info
try: try:
_swig_property = property _swig_property = property
except NameError: except NameError:
pass # Python < 2.2 doesn't have 'property'. pass # Python < 2.2 doesn't have 'property'.
def _swig_setattr_nondynamic(self,class_type,name,value,static=1):
try: if (name == "thisown"): return self.this.own(value)
import builtins as __builtin__
except ImportError:
import __builtin__
def _swig_setattr_nondynamic(self, class_type, name, value, static=1):
if (name == "thisown"):
return self.this.own(value)
if (name == "this"): if (name == "this"):
if type(value).__name__ == 'SwigPyObject': if type(value).__name__ == 'SwigPyObject':
self.__dict__[name] = value self.__dict__[name] = value
return return
method = class_type.__swig_setmethods__.get(name, None) method = class_type.__swig_setmethods__.get(name,None)
if method: if method: return method(self,value)
return method(self, value)
if (not static): if (not static):
if _newclass: self.__dict__[name] = value
object.__setattr__(self, name, value)
else:
self.__dict__[name] = value
else: else:
raise AttributeError("You cannot add attributes to %s" % self) raise AttributeError("You cannot add attributes to %s" % self)
def _swig_setattr(self,class_type,name,value):
return _swig_setattr_nondynamic(self,class_type,name,value,0)
def _swig_setattr(self, class_type, name, value): def _swig_getattr(self,class_type,name):
return _swig_setattr_nondynamic(self, class_type, name, value, 0) if (name == "thisown"): return self.this.own()
method = class_type.__swig_getmethods__.get(name,None)
if method: return method(self)
def _swig_getattr(self, class_type, name): raise AttributeError(name)
if (name == "thisown"):
return self.this.own()
method = class_type.__swig_getmethods__.get(name, None)
if method:
return method(self)
raise AttributeError("'%s' object has no attribute '%s'" % (class_type.__name__, name))
def _swig_repr(self): def _swig_repr(self):
try: try: strthis = "proxy of " + self.this.__repr__()
strthis = "proxy of " + self.this.__repr__() except: strthis = ""
except __builtin__.Exception:
strthis = ""
return "<%s.%s; %s >" % (self.__class__.__module__, self.__class__.__name__, strthis,) return "<%s.%s; %s >" % (self.__class__.__module__, self.__class__.__name__, strthis,)
try: try:
_object = object _object = object
_newclass = 1 _newclass = 1
except __builtin__.Exception: except AttributeError:
class _object: class _object : pass
pass
_newclass = 0 _newclass = 0
def WebPGetDecoderVersion(): def WebPGetDecoderVersion():
"""WebPGetDecoderVersion() -> int""" """WebPGetDecoderVersion() -> int"""
return _libwebp.WebPGetDecoderVersion() return _libwebp.WebPGetDecoderVersion()
def WebPGetInfo(data): def WebPGetInfo(*args):
"""WebPGetInfo(uint8_t data) -> (width, height)""" """WebPGetInfo(uint8_t data) -> (width, height)"""
return _libwebp.WebPGetInfo(data) return _libwebp.WebPGetInfo(*args)
def WebPDecodeRGB(data): def WebPDecodeRGB(*args):
"""WebPDecodeRGB(uint8_t data) -> (rgb, width, height)""" """WebPDecodeRGB(uint8_t data) -> (rgb, width, height)"""
return _libwebp.WebPDecodeRGB(data) return _libwebp.WebPDecodeRGB(*args)
def WebPDecodeRGBA(data): def WebPDecodeRGBA(*args):
"""WebPDecodeRGBA(uint8_t data) -> (rgb, width, height)""" """WebPDecodeRGBA(uint8_t data) -> (rgb, width, height)"""
return _libwebp.WebPDecodeRGBA(data) return _libwebp.WebPDecodeRGBA(*args)
def WebPDecodeARGB(data): def WebPDecodeARGB(*args):
"""WebPDecodeARGB(uint8_t data) -> (rgb, width, height)""" """WebPDecodeARGB(uint8_t data) -> (rgb, width, height)"""
return _libwebp.WebPDecodeARGB(data) return _libwebp.WebPDecodeARGB(*args)
def WebPDecodeBGR(data): def WebPDecodeBGR(*args):
"""WebPDecodeBGR(uint8_t data) -> (rgb, width, height)""" """WebPDecodeBGR(uint8_t data) -> (rgb, width, height)"""
return _libwebp.WebPDecodeBGR(data) return _libwebp.WebPDecodeBGR(*args)
def WebPDecodeBGRA(data): def WebPDecodeBGRA(*args):
"""WebPDecodeBGRA(uint8_t data) -> (rgb, width, height)""" """WebPDecodeBGRA(uint8_t data) -> (rgb, width, height)"""
return _libwebp.WebPDecodeBGRA(data) return _libwebp.WebPDecodeBGRA(*args)
def WebPGetEncoderVersion(): def WebPGetEncoderVersion():
"""WebPGetEncoderVersion() -> int""" """WebPGetEncoderVersion() -> int"""
return _libwebp.WebPGetEncoderVersion() return _libwebp.WebPGetEncoderVersion()
def wrap_WebPEncodeRGB(rgb, unused1, unused2, width, height, stride, quality_factor): def wrap_WebPEncodeRGB(*args):
"""private, do not call directly.""" """private, do not call directly."""
return _libwebp.wrap_WebPEncodeRGB(rgb, unused1, unused2, width, height, stride, quality_factor) return _libwebp.wrap_WebPEncodeRGB(*args)
def wrap_WebPEncodeBGR(rgb, unused1, unused2, width, height, stride, quality_factor): def wrap_WebPEncodeBGR(*args):
"""private, do not call directly.""" """private, do not call directly."""
return _libwebp.wrap_WebPEncodeBGR(rgb, unused1, unused2, width, height, stride, quality_factor) return _libwebp.wrap_WebPEncodeBGR(*args)
def wrap_WebPEncodeRGBA(rgb, unused1, unused2, width, height, stride, quality_factor): def wrap_WebPEncodeRGBA(*args):
"""private, do not call directly.""" """private, do not call directly."""
return _libwebp.wrap_WebPEncodeRGBA(rgb, unused1, unused2, width, height, stride, quality_factor) return _libwebp.wrap_WebPEncodeRGBA(*args)
def wrap_WebPEncodeBGRA(rgb, unused1, unused2, width, height, stride, quality_factor): def wrap_WebPEncodeBGRA(*args):
"""private, do not call directly.""" """private, do not call directly."""
return _libwebp.wrap_WebPEncodeBGRA(rgb, unused1, unused2, width, height, stride, quality_factor) return _libwebp.wrap_WebPEncodeBGRA(*args)
def wrap_WebPEncodeLosslessRGB(rgb, unused1, unused2, width, height, stride): def wrap_WebPEncodeLosslessRGB(*args):
"""private, do not call directly.""" """private, do not call directly."""
return _libwebp.wrap_WebPEncodeLosslessRGB(rgb, unused1, unused2, width, height, stride) return _libwebp.wrap_WebPEncodeLosslessRGB(*args)
def wrap_WebPEncodeLosslessBGR(rgb, unused1, unused2, width, height, stride): def wrap_WebPEncodeLosslessBGR(*args):
"""private, do not call directly.""" """private, do not call directly."""
return _libwebp.wrap_WebPEncodeLosslessBGR(rgb, unused1, unused2, width, height, stride) return _libwebp.wrap_WebPEncodeLosslessBGR(*args)
def wrap_WebPEncodeLosslessRGBA(rgb, unused1, unused2, width, height, stride): def wrap_WebPEncodeLosslessRGBA(*args):
"""private, do not call directly.""" """private, do not call directly."""
return _libwebp.wrap_WebPEncodeLosslessRGBA(rgb, unused1, unused2, width, height, stride) return _libwebp.wrap_WebPEncodeLosslessRGBA(*args)
def wrap_WebPEncodeLosslessBGRA(rgb, unused1, unused2, width, height, stride):
"""private, do not call directly."""
return _libwebp.wrap_WebPEncodeLosslessBGRA(rgb, unused1, unused2, width, height, stride)
def wrap_WebPEncodeLosslessBGRA(*args):
"""private, do not call directly."""
return _libwebp.wrap_WebPEncodeLosslessBGRA(*args)
_UNUSED = 1 _UNUSED = 1
def WebPEncodeRGB(rgb, width, height, stride, quality_factor): def WebPEncodeRGB(rgb, width, height, stride, quality_factor):
"""WebPEncodeRGB(uint8_t rgb, int width, int height, int stride, float quality_factor) -> lossy_webp""" """WebPEncodeRGB(uint8_t rgb, int width, int height, int stride, float quality_factor) -> lossy_webp"""
webp = wrap_WebPEncodeRGB( webp = wrap_WebPEncodeRGB(
@ -175,7 +141,6 @@ def WebPEncodeRGB(rgb, width, height, stride, quality_factor):
return None return None
return webp[0] return webp[0]
def WebPEncodeRGBA(rgb, width, height, stride, quality_factor): def WebPEncodeRGBA(rgb, width, height, stride, quality_factor):
"""WebPEncodeRGBA(uint8_t rgb, int width, int height, int stride, float quality_factor) -> lossy_webp""" """WebPEncodeRGBA(uint8_t rgb, int width, int height, int stride, float quality_factor) -> lossy_webp"""
webp = wrap_WebPEncodeRGBA( webp = wrap_WebPEncodeRGBA(
@ -184,7 +149,6 @@ def WebPEncodeRGBA(rgb, width, height, stride, quality_factor):
return None return None
return webp[0] return webp[0]
def WebPEncodeBGR(rgb, width, height, stride, quality_factor): def WebPEncodeBGR(rgb, width, height, stride, quality_factor):
"""WebPEncodeBGR(uint8_t rgb, int width, int height, int stride, float quality_factor) -> lossy_webp""" """WebPEncodeBGR(uint8_t rgb, int width, int height, int stride, float quality_factor) -> lossy_webp"""
webp = wrap_WebPEncodeBGR( webp = wrap_WebPEncodeBGR(
@ -193,7 +157,6 @@ def WebPEncodeBGR(rgb, width, height, stride, quality_factor):
return None return None
return webp[0] return webp[0]
def WebPEncodeBGRA(rgb, width, height, stride, quality_factor): def WebPEncodeBGRA(rgb, width, height, stride, quality_factor):
"""WebPEncodeBGRA(uint8_t rgb, int width, int height, int stride, float quality_factor) -> lossy_webp""" """WebPEncodeBGRA(uint8_t rgb, int width, int height, int stride, float quality_factor) -> lossy_webp"""
webp = wrap_WebPEncodeBGRA( webp = wrap_WebPEncodeBGRA(
@ -202,7 +165,6 @@ def WebPEncodeBGRA(rgb, width, height, stride, quality_factor):
return None return None
return webp[0] return webp[0]
def WebPEncodeLosslessRGB(rgb, width, height, stride): def WebPEncodeLosslessRGB(rgb, width, height, stride):
"""WebPEncodeLosslessRGB(uint8_t rgb, int width, int height, int stride) -> lossless_webp""" """WebPEncodeLosslessRGB(uint8_t rgb, int width, int height, int stride) -> lossless_webp"""
webp = wrap_WebPEncodeLosslessRGB(rgb, _UNUSED, _UNUSED, width, height, stride) webp = wrap_WebPEncodeLosslessRGB(rgb, _UNUSED, _UNUSED, width, height, stride)
@ -210,7 +172,6 @@ def WebPEncodeLosslessRGB(rgb, width, height, stride):
return None return None
return webp[0] return webp[0]
def WebPEncodeLosslessRGBA(rgb, width, height, stride): def WebPEncodeLosslessRGBA(rgb, width, height, stride):
"""WebPEncodeLosslessRGBA(uint8_t rgb, int width, int height, int stride) -> lossless_webp""" """WebPEncodeLosslessRGBA(uint8_t rgb, int width, int height, int stride) -> lossless_webp"""
webp = wrap_WebPEncodeLosslessRGBA(rgb, _UNUSED, _UNUSED, width, height, stride) webp = wrap_WebPEncodeLosslessRGBA(rgb, _UNUSED, _UNUSED, width, height, stride)
@ -218,7 +179,6 @@ def WebPEncodeLosslessRGBA(rgb, width, height, stride):
return None return None
return webp[0] return webp[0]
def WebPEncodeLosslessBGR(rgb, width, height, stride): def WebPEncodeLosslessBGR(rgb, width, height, stride):
"""WebPEncodeLosslessBGR(uint8_t rgb, int width, int height, int stride) -> lossless_webp""" """WebPEncodeLosslessBGR(uint8_t rgb, int width, int height, int stride) -> lossless_webp"""
webp = wrap_WebPEncodeLosslessBGR(rgb, _UNUSED, _UNUSED, width, height, stride) webp = wrap_WebPEncodeLosslessBGR(rgb, _UNUSED, _UNUSED, width, height, stride)
@ -226,7 +186,6 @@ def WebPEncodeLosslessBGR(rgb, width, height, stride):
return None return None
return webp[0] return webp[0]
def WebPEncodeLosslessBGRA(rgb, width, height, stride): def WebPEncodeLosslessBGRA(rgb, width, height, stride):
"""WebPEncodeLosslessBGRA(uint8_t rgb, int width, int height, int stride) -> lossless_webp""" """WebPEncodeLosslessBGRA(uint8_t rgb, int width, int height, int stride) -> lossless_webp"""
webp = wrap_WebPEncodeLosslessBGRA(rgb, _UNUSED, _UNUSED, width, height, stride) webp = wrap_WebPEncodeLosslessBGRA(rgb, _UNUSED, _UNUSED, width, height, stride)

File diff suppressed because it is too large Load Diff