mirror of
https://github.com/webmproject/libwebp.git
synced 2025-07-15 13:29:54 +02:00
Compare commits
46 Commits
v1.0.0
...
portable-i
Author | SHA1 | Date | |
---|---|---|---|
0d7614fddf | |||
88692490a5 | |||
0af22e17d6 | |||
08af967025 | |||
a26996116f | |||
5505a5b107 | |||
8ed24a564c | |||
0e8c3004be | |||
6fcc3a720d | |||
2371724d79 | |||
9d1e151bf5 | |||
a1ab868427 | |||
0b8ecc8cfa | |||
c646241391 | |||
cfaebe3e95 | |||
c0eb3ff7d4 | |||
415b98ffad | |||
09bcd9a397 | |||
e83df9d208 | |||
3387fb6fa6 | |||
599bddb658 | |||
28fbe808b9 | |||
c396e6701b | |||
96ef09107c | |||
bc01db116f | |||
d2adc08095 | |||
d6f90a3d83 | |||
cd01fc3944 | |||
9a1a3aa827 | |||
9eceff25c0 | |||
fe6184d706 | |||
cb6c3a2a36 | |||
ec666c7526 | |||
bafa90ccd8 | |||
e6e3ec335c | |||
168a3a9e28 | |||
ad4ca27449 | |||
3a5528713b | |||
b4cefba731 | |||
440945ca57 | |||
a37a7b00d5 | |||
a604ab5600 | |||
b005d916f8 | |||
586eda373d | |||
4026e34e3f | |||
4b21971337 |
1
AUTHORS
1
AUTHORS
@ -35,5 +35,4 @@ Contributors:
|
||||
- Urvang Joshi (urvang at google dot com)
|
||||
- Vikas Arora (vikasa at google dot com)
|
||||
- Vincent Rabaud (vrabaud at google dot com)
|
||||
- Vlad Tsyrklevich (vtsyrklevich at chromium dot org)
|
||||
- Yang Zhang (yang dot zhang at arm dot com)
|
||||
|
@ -55,6 +55,9 @@ dsp_dec_srcs := \
|
||||
src/dsp/alpha_processing_neon.$(NEON) \
|
||||
src/dsp/alpha_processing_sse2.c \
|
||||
src/dsp/alpha_processing_sse41.c \
|
||||
src/dsp/argb.c \
|
||||
src/dsp/argb_mips_dsp_r2.c \
|
||||
src/dsp/argb_sse2.c \
|
||||
src/dsp/cpu.c \
|
||||
src/dsp/dec.c \
|
||||
src/dsp/dec_clip_tables.c \
|
||||
@ -85,13 +88,11 @@ dsp_dec_srcs := \
|
||||
src/dsp/upsampling_msa.c \
|
||||
src/dsp/upsampling_neon.$(NEON) \
|
||||
src/dsp/upsampling_sse2.c \
|
||||
src/dsp/upsampling_sse41.c \
|
||||
src/dsp/yuv.c \
|
||||
src/dsp/yuv_mips32.c \
|
||||
src/dsp/yuv_mips_dsp_r2.c \
|
||||
src/dsp/yuv_neon.$(NEON) \
|
||||
src/dsp/yuv_sse2.c \
|
||||
src/dsp/yuv_sse41.c \
|
||||
|
||||
dsp_enc_srcs := \
|
||||
src/dsp/cost.c \
|
||||
@ -123,6 +124,7 @@ enc_srcs := \
|
||||
src/enc/backward_references_enc.c \
|
||||
src/enc/config_enc.c \
|
||||
src/enc/cost_enc.c \
|
||||
src/enc/delta_palettization_enc.c \
|
||||
src/enc/filter_enc.c \
|
||||
src/enc/frame_enc.c \
|
||||
src/enc/histogram_enc.c \
|
||||
|
@ -4,16 +4,17 @@ project(libwebp C)
|
||||
|
||||
# Options for coder / decoder executables.
|
||||
option(WEBP_ENABLE_SIMD "Enable any SIMD optimization." ON)
|
||||
option(WEBP_ENABLE_WASM "Enable WebAssembly optimizations." OFF)
|
||||
option(WEBP_BUILD_CWEBP "Build the cwebp command line tool." OFF)
|
||||
option(WEBP_BUILD_DWEBP "Build the dwebp command line tool." OFF)
|
||||
option(WEBP_BUILD_GIF2WEBP "Build the gif2webp conversion tool." OFF)
|
||||
option(WEBP_BUILD_IMG2WEBP "Build the img2webp animation tool." OFF)
|
||||
option(WEBP_BUILD_WEBPINFO "Build the webpinfo command line tool." OFF)
|
||||
option(WEBP_BUILD_WEBP_JS "Emscripten build of webp.js." OFF)
|
||||
option(WEBP_NEAR_LOSSLESS "Enable near-lossless encoding" ON)
|
||||
option(WEBP_EXPERIMENTAL_FEATURES "Build with experimental features." OFF)
|
||||
option(WEBP_ENABLE_SWAP_16BIT_CSP "Enable byte swap for 16 bit colorspaces." OFF)
|
||||
|
||||
if(WEBP_BUILD_WEBP_JS)
|
||||
if(WEBP_BUILD_WEBP_JS OR WEBP_ENABLE_WASM)
|
||||
set(WEBP_ENABLE_SIMD OFF)
|
||||
endif()
|
||||
|
||||
@ -26,13 +27,19 @@ if(NOT CMAKE_BUILD_TYPE)
|
||||
)
|
||||
endif()
|
||||
|
||||
# Include dependencies.
|
||||
include(cmake/deps.cmake)
|
||||
include(cmake/config.h.cmake)
|
||||
|
||||
# Extract the version of the library.
|
||||
file(READ ${CMAKE_CURRENT_SOURCE_DIR}/configure.ac SOURCE_FILE)
|
||||
string(REGEX MATCH "[0-9.]+" WEBP_VERSION ${SOURCE_FILE})
|
||||
|
||||
################################################################################
|
||||
# Options.
|
||||
if(WEBP_ENABLE_SWAP_16BIT_CSP)
|
||||
add_definitions(-DWEBP_SWAP_16BIT_CSP=1)
|
||||
add_definitions(-DWEBP_SWAP_16BIT_CSP)
|
||||
endif()
|
||||
if(WEBP_ENABLE_WASM)
|
||||
add_definitions(-DWEBP_USE_WASM)
|
||||
endif()
|
||||
|
||||
################################################################################
|
||||
@ -47,10 +54,7 @@ if(ANDROID)
|
||||
set(WEBP_DEP_INCLUDE_DIRS ${WEBP_DEP_INCLUDE_DIRS}
|
||||
${ANDROID_NDK}/sources/android/cpufeatures
|
||||
)
|
||||
add_definitions(-DHAVE_CPU_FEATURES_H=1)
|
||||
set(HAVE_CPU_FEATURES_H 1)
|
||||
else()
|
||||
set(HAVE_CPU_FEATURES_H 0)
|
||||
add_definitions(-DHAVE_CPU_FEATURES_H)
|
||||
endif()
|
||||
|
||||
################################################################################
|
||||
@ -102,13 +106,8 @@ endforeach()
|
||||
|
||||
### Define the mandatory libraries.
|
||||
# Build the webpdecoder library.
|
||||
if(MSVC)
|
||||
# avoid security warnings for e.g., fopen() used in the examples.
|
||||
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
|
||||
else()
|
||||
add_definitions(-Wall)
|
||||
endif()
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${WEBP_DEP_INCLUDE_DIRS})
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/src/ ${WEBP_DEP_INCLUDE_DIRS})
|
||||
add_library(webpdecode OBJECT ${WEBP_DEC_SRCS})
|
||||
add_library(webpdspdecode OBJECT ${WEBP_DSP_COMMON_SRCS} ${WEBP_DSP_DEC_SRCS})
|
||||
add_library(webputilsdecode OBJECT ${WEBP_UTILS_COMMON_SRCS}
|
||||
@ -146,13 +145,13 @@ function(parse_version FILE NAME VAR)
|
||||
set(${VAR} "${VERSION}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
parse_version(Makefile.am webp WEBP_WEBP_SOVERSION)
|
||||
set_target_properties(webp PROPERTIES VERSION ${PACKAGE_VERSION}
|
||||
set_target_properties(webp PROPERTIES VERSION ${WEBP_VERSION}
|
||||
SOVERSION ${WEBP_WEBP_SOVERSION})
|
||||
parse_version(Makefile.am webpdecoder WEBP_DECODER_SOVERSION)
|
||||
set_target_properties(webpdecoder PROPERTIES VERSION ${PACKAGE_VERSION}
|
||||
set_target_properties(webpdecoder PROPERTIES VERSION ${WEBP_VERSION}
|
||||
SOVERSION ${WEBP_DECODER_SOVERSION})
|
||||
parse_version(demux/Makefile.am webpdemux WEBP_DEMUX_SOVERSION)
|
||||
set_target_properties(webpdemux PROPERTIES VERSION ${PACKAGE_VERSION}
|
||||
set_target_properties(webpdemux PROPERTIES VERSION ${WEBP_VERSION}
|
||||
SOVERSION ${WEBP_DEMUX_SOVERSION})
|
||||
|
||||
# Define the libraries to install.
|
||||
@ -168,9 +167,11 @@ math(EXPR WEBP_SIMD_FILES_TO_INCLUDE_RANGE
|
||||
foreach(I_FILE RANGE ${WEBP_SIMD_FILES_TO_INCLUDE_RANGE})
|
||||
list(GET WEBP_SIMD_FILES_TO_INCLUDE ${I_FILE} FILE)
|
||||
list(GET WEBP_SIMD_FLAGS_TO_INCLUDE ${I_FILE} SIMD_COMPILE_FLAG)
|
||||
if(NOT ${SIMD_COMPILE_FLAG} STREQUAL "NOTFOUND")
|
||||
set_source_files_properties(${FILE} PROPERTIES
|
||||
COMPILE_FLAGS ${SIMD_COMPILE_FLAG}
|
||||
)
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
# Build the executables if asked for.
|
||||
@ -192,18 +193,13 @@ if(WEBP_BUILD_CWEBP OR WEBP_BUILD_DWEBP OR
|
||||
parse_Makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/imageio "IMAGEDEC_SRCS"
|
||||
"imagedec_[^ ]*")
|
||||
add_library(imagedec ${IMAGEDEC_SRCS})
|
||||
target_link_libraries(imagedec imageioutil webpdemux webp
|
||||
${WEBP_DEP_IMG_LIBRARIES})
|
||||
target_link_libraries(imagedec imageioutil webp ${WEBP_DEP_IMG_LIBRARIES})
|
||||
|
||||
# Image-encoding utility library.
|
||||
parse_Makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/imageio "IMAGEENC_SRCS"
|
||||
"imageenc_[^ ]*")
|
||||
add_library(imageenc ${IMAGEENC_SRCS})
|
||||
target_link_libraries(imageenc webp)
|
||||
|
||||
set_property(TARGET exampleutil imageioutil imagedec imageenc
|
||||
PROPERTY INCLUDE_DIRECTORIES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src ${CMAKE_CURRENT_BINARY_DIR}/src)
|
||||
endif()
|
||||
|
||||
if(WEBP_BUILD_DWEBP)
|
||||
@ -214,8 +210,6 @@ if(WEBP_BUILD_DWEBP)
|
||||
add_executable(dwebp ${DWEBP_SRCS})
|
||||
target_link_libraries(dwebp exampleutil imagedec imageenc webpdecoder)
|
||||
install(TARGETS dwebp RUNTIME DESTINATION bin)
|
||||
set_property(TARGET dwebp PROPERTY INCLUDE_DIRECTORIES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src ${CMAKE_CURRENT_BINARY_DIR}/src)
|
||||
endif()
|
||||
|
||||
if(WEBP_BUILD_CWEBP)
|
||||
@ -226,12 +220,6 @@ if(WEBP_BUILD_CWEBP)
|
||||
add_executable(cwebp ${CWEBP_SRCS})
|
||||
target_link_libraries(cwebp exampleutil imagedec webp)
|
||||
install(TARGETS cwebp RUNTIME DESTINATION bin)
|
||||
set_property(TARGET cwebp PROPERTY INCLUDE_DIRECTORIES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src ${CMAKE_CURRENT_BINARY_DIR}/src)
|
||||
endif()
|
||||
|
||||
if(WEBP_BUILD_GIF2WEBP AND NOT GIF_FOUND)
|
||||
unset(WEBP_BUILD_GIF2WEBP CACHE)
|
||||
endif()
|
||||
|
||||
if(WEBP_BUILD_GIF2WEBP OR WEBP_BUILD_IMG2WEBP)
|
||||
@ -240,7 +228,7 @@ if(WEBP_BUILD_GIF2WEBP OR WEBP_BUILD_IMG2WEBP)
|
||||
add_library(webpmux ${WEBP_MUX_SRCS})
|
||||
target_link_libraries(webpmux webp)
|
||||
parse_version(mux/Makefile.am webpmux WEBP_MUX_SOVERSION)
|
||||
set_target_properties(webpmux PROPERTIES VERSION ${PACKAGE_VERSION}
|
||||
set_target_properties(webpmux PROPERTIES VERSION ${WEBP_VERSION}
|
||||
SOVERSION ${WEBP_MUX_SOVERSION})
|
||||
list(APPEND INSTALLED_LIBRARIES webpmux)
|
||||
endif()
|
||||
@ -254,8 +242,6 @@ if(WEBP_BUILD_GIF2WEBP)
|
||||
target_link_libraries(gif2webp exampleutil imageioutil webp webpmux
|
||||
${WEBP_DEP_GIF_LIBRARIES})
|
||||
install(TARGETS gif2webp RUNTIME DESTINATION bin)
|
||||
set_property(TARGET gif2webp PROPERTY INCLUDE_DIRECTORIES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src ${CMAKE_CURRENT_BINARY_DIR}/src)
|
||||
endif()
|
||||
|
||||
if(WEBP_BUILD_IMG2WEBP)
|
||||
@ -266,8 +252,6 @@ if(WEBP_BUILD_IMG2WEBP)
|
||||
add_executable(img2webp ${IMG2WEBP_SRCS})
|
||||
target_link_libraries(img2webp exampleutil imagedec imageioutil webp webpmux)
|
||||
install(TARGETS img2webp RUNTIME DESTINATION bin)
|
||||
set_property(TARGET img2webp PROPERTY INCLUDE_DIRECTORIES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src ${CMAKE_CURRENT_BINARY_DIR}/src)
|
||||
endif()
|
||||
|
||||
if (WEBP_BUILD_WEBPINFO)
|
||||
@ -278,8 +262,6 @@ if (WEBP_BUILD_WEBPINFO)
|
||||
add_executable(webpinfo ${WEBPINFO_SRCS})
|
||||
target_link_libraries(webpinfo exampleutil imageioutil)
|
||||
install(TARGETS webpinfo RUNTIME DESTINATION bin)
|
||||
set_property(TARGET webpinfo PROPERTY INCLUDE_DIRECTORIES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src ${CMAKE_CURRENT_BINARY_DIR}/src)
|
||||
endif()
|
||||
|
||||
if(WEBP_BUILD_WEBP_JS)
|
||||
@ -287,10 +269,8 @@ if(WEBP_BUILD_WEBP_JS)
|
||||
add_executable(webp_js
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/extras/webp_to_sdl.c)
|
||||
target_link_libraries(webp_js webpdecoder SDL)
|
||||
set(WEBP_HAVE_SDL 1)
|
||||
set_target_properties(webp_js PROPERTIES LINK_FLAGS
|
||||
"-s EXPORTED_FUNCTIONS='[\"_WebpToSDL\"]' -s INVOKE_RUN=0 \
|
||||
-s EXTRA_EXPORTED_RUNTIME_METHODS='[\"cwrap\"]'")
|
||||
"-s EXPORTED_FUNCTIONS='[\"_WebpToSDL\"]' -s INVOKE_RUN=0")
|
||||
set_target_properties(webp_js PROPERTIES OUTPUT_NAME webp)
|
||||
target_compile_definitions(webp_js PUBLIC EMSCRIPTEN WEBP_HAVE_SDL)
|
||||
|
||||
@ -300,21 +280,12 @@ if(WEBP_BUILD_WEBP_JS)
|
||||
target_link_libraries(webp_wasm webpdecoder SDL)
|
||||
set_target_properties(webp_wasm PROPERTIES LINK_FLAGS
|
||||
"-s WASM=1 -s 'BINARYEN_METHOD=\"native-wasm\"' \
|
||||
-s EXPORTED_FUNCTIONS='[\"_WebpToSDL\"]' -s INVOKE_RUN=0 \
|
||||
-s EXTRA_EXPORTED_RUNTIME_METHODS='[\"cwrap\"]'")
|
||||
-s EXPORTED_FUNCTIONS='[\"_WebpToSDL\"]' -s INVOKE_RUN=0")
|
||||
target_compile_definitions(webp_wasm PUBLIC EMSCRIPTEN WEBP_HAVE_SDL)
|
||||
|
||||
target_compile_definitions(webpdecoder PUBLIC EMSCRIPTEN)
|
||||
endif()
|
||||
|
||||
# Generate the config.h file.
|
||||
configure_file(${CMAKE_CURRENT_LIST_DIR}/cmake/config.h.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/src/webp/config.h)
|
||||
add_definitions(-DHAVE_CONFIG_H)
|
||||
# The webp folder is included as we reference config.h as
|
||||
# ../webp/config.h or webp/config.h
|
||||
include_directories(${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
# Install the different headers and libraries.
|
||||
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/webp/decode.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/webp/demux.h
|
||||
@ -331,7 +302,7 @@ install(TARGETS ${INSTALLED_LIBRARIES}
|
||||
include(CMakePackageConfigHelpers)
|
||||
write_basic_package_version_file(
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/WebPConfigVersion.cmake"
|
||||
VERSION ${PACKAGE_VERSION}
|
||||
VERSION ${WEBP_VERSION}
|
||||
COMPATIBILITY AnyNewerVersion
|
||||
)
|
||||
|
||||
|
368
ChangeLog
368
ChangeLog
@ -1,377 +1,9 @@
|
||||
8d510751 webp-container-spec: correct frame duration=0 note
|
||||
e6b2164e vwebp: Copy Chrome's behavior w/frame duration == 0
|
||||
d20b7707 update ChangeLog (tag: v1.0.0-rc3)
|
||||
0d5fad46 add WEBP_DSP_INIT / WEBP_DSP_INIT_FUNC
|
||||
c1cb86af fix 16b overflow in SSE2
|
||||
e577feb7 makefile.unix: add DEBUG flag for compiling w/ debug-symbol
|
||||
99be34b3 cwebp,get_disto: fix bpp output
|
||||
f5565ca8 cmake: Make sure we use near-lossless by default.
|
||||
d898dc14 fix bug in WebPImport565: alpha value was not set
|
||||
882784b0 update ChangeLog (tag: v1.0.0-rc2)
|
||||
2f930e08 Revert "Use proper targets for CMake."
|
||||
8165e8fb Use proper targets for CMake.
|
||||
3f157dd5 Remove some very hard TODOs.
|
||||
cd758a17 {de,}mux/Makefile.am: add missing headers
|
||||
b892b8ba makefile.unix,dist: use ascii for text output
|
||||
64a57d05 add -version option to anim_dump,anim_diff and img2webp
|
||||
fc1b8e3a webp_js: fix webp_js demo html
|
||||
15aa48d9 update ChangeLog (tag: v1.0.0-rc1)
|
||||
e607dabc update AUTHORS
|
||||
38410c08 [CFI] Remove function pointer casts
|
||||
c57b2736 bump version to 1.0.0
|
||||
cba28853 update NEWS
|
||||
c909d531 Merge "remove some deprecation warning on MacOSX"
|
||||
217443c7 remove some deprecation warning on MacOSX
|
||||
b672bdfa configure: quiet glut deprecation warnings on OS X
|
||||
daa9fcaf configure: use sdl-config if available
|
||||
dd174cae Merge "imagedec: support metadata reading for WebP image decoding"
|
||||
641cedcc imagedec: support metadata reading for WebP image decoding
|
||||
065b2ce1 anim_diff: add a couple missing newlines in Help()
|
||||
c4cc1147 Merge "gif2webp: force low duration frames to 100ms"
|
||||
09333097 gif2webp: force low duration frames to 100ms
|
||||
e03f0ec3 sharp_yuv: use 14b fixed-point precision for gamma
|
||||
b2db361c image_enc,WebPWritePNG: move locals after setjmp
|
||||
74e82ec6 Merge "WebPPictureDistortion: fix big-endian results order"
|
||||
645d04ca Merge "cwebp,get_disto: report bpp"
|
||||
120f58c3 Merge "lossless*sse2: improve non-const 16-bit vector creation"
|
||||
a7fe9412 WebPPictureDistortion: fix big-endian results order
|
||||
e26fe066 cwebp,get_disto: report bpp
|
||||
9df64e28 Merge changes Id5b4a1a4,Ia20ce844
|
||||
8043504f lossless*sse2: improve non-const 16-bit vector creation
|
||||
1e3dfc48 Import: extract condition from loop
|
||||
3b07d327 Import,RGBA: fix for BigEndian import
|
||||
551948e4 Remove unused argument in VP8LBitsEntropy.
|
||||
3005237a ReadWebP: fix for big-endian
|
||||
499c395a Merge "anim_diff: expose the -max_diff option"
|
||||
f69dcd69 Merge "remove WEBP_EXPERIMENTAL_FEATURES"
|
||||
07d884d5 anim_diff: expose the -max_diff option
|
||||
f4dd9256 remove WEBP_EXPERIMENTAL_FEATURES
|
||||
94a8377b extract the command-line parsing helpers to example_util
|
||||
fc09e6e2 PNM decoder: prevent unsupported depth=2 PAM case.
|
||||
6de58603 MIPS64: Fix defined-but-not-used errors with WEBP_REDUCE_CSP
|
||||
cbde5728 gif2webp: add support for reading from stdin
|
||||
cf1c5054 Add an SSE4 version of some lossless color transforms.
|
||||
45a8b5eb Fix lint error with man page.
|
||||
cff38e8f Merge "PNG decoder: handle gAMA chunk"
|
||||
59cb1a48 Merge "enable dc error-diffusion always"
|
||||
78318b30 PNG decoder: handle gAMA chunk
|
||||
664c21dd Merge "remove some TODOs"
|
||||
815652de enable dc error-diffusion always
|
||||
aec45cec remove some TODOs
|
||||
5715dfce fix block-count[] increment in case of large image
|
||||
c2d04f3e enable DC error-diffusion always for multi-pass
|
||||
96bf07c5 use DC error diffusion for U/V at low-quality
|
||||
1c59020b fix missing sse41 targets in makefile.unix
|
||||
7a8e814b cosmetics: s/color_space/colorspace/
|
||||
05f6fe24 upsampling: rm asserts w/REDUCE_CSP+OMIT_C_CODE
|
||||
b4cf5597 Merge "Upsampling SSE2/SSE4 speedup."
|
||||
ccbeb32c Makefile.vc: add missing sse41 files
|
||||
55403a9a Upsampling SSE2/SSE4 speedup.
|
||||
807b53c4 Implement the upsampling/yuv functions in SSE41
|
||||
84101a81 Fix wasm WebP compilation
|
||||
8bebd2a3 fix warning on MSVC
|
||||
a7f93fe3 webpmux: allow reading argument from a file
|
||||
b69f18a7 gif2webp.1: fix -loop_compatibility layout
|
||||
72d530c0 Merge "fix lossless decoding w/WEBP_REDUCE_SIZE"
|
||||
296c7dc4 fix lossless decoding w/WEBP_REDUCE_SIZE
|
||||
0d5d029c Merge "ImgIoUtilReadFile: fix file leak upon error"
|
||||
ae568ce7 ImgIoUtilReadFile: fix file leak upon error
|
||||
796b5a8a Merge tag 'v0.6.1'
|
||||
6b7a95fd update ChangeLog (tag: v0.6.1)
|
||||
f66955de WEBP_REDUCE_CSP: restrict colorspace support
|
||||
1af0df76 Merge "WEBP_REDUCE_CSP: restrict colorspace support"
|
||||
6de20df0 WEBP_REDUCE_CSP: restrict colorspace support
|
||||
a289d8e7 update ChangeLog (tag: v0.6.1-rc2)
|
||||
c10a493c vwebp: disable double buffering on windows & mac
|
||||
0d4466c2 webp_to_sdl.c: fix file mode
|
||||
1b27bf8b WEBP_REDUCE_SIZE: disable all rescaler code
|
||||
126be109 webpinfo: add -version option
|
||||
0df22b9e WEBP_REDUCE_SIZE: disable all rescaler code
|
||||
9add62b5 bump version to 0.6.1
|
||||
d3e26144 update NEWS
|
||||
2edda639 README: add webpinfo section
|
||||
9ca568ef Merge "right-size some tables"
|
||||
31f1995c Merge "SSE2 implementation of HasAlphaXXX"
|
||||
a80c46bd SSE2 implementation of HasAlphaXXX
|
||||
083507f2 right-size some tables
|
||||
2e5785b2 anim_utils.c: remove warning when !defined(WEBP_HAVE_GIF)
|
||||
b299c47e add WEBP_REDUCE_SIZE
|
||||
f593d71a enc: disable pic->stats/extra_info w/WEBP_DISABLE_STATS
|
||||
541179a9 Merge "predictor_enc: fix build w/--disable-near-lossless"
|
||||
5755a7ec predictor_enc: fix build w/--disable-near-lossless
|
||||
eab5bab7 add WEBP_DISABLE_STATS
|
||||
8052c585 remove some petty TODOs from vwebp.
|
||||
c245343d move LOAD8x4 and STORE8x2 closer to their use location
|
||||
b9e734fd dec,cosmetics: normalize function naming style
|
||||
c188d546 dec: harmonize function suffixes
|
||||
28c5ac81 dec_sse41: harmonize function suffixes
|
||||
e65b72a3 Merge "introduce WebPHasAlpha8b and WebPHasAlpha32b"
|
||||
b94cee98 dec_sse2: remove HE8uv_SSE2
|
||||
44a0ee3f introduce WebPHasAlpha8b and WebPHasAlpha32b
|
||||
aebf59ac Merge "WebPPictureAllocARGB: align argb allocation"
|
||||
c184665e WebPPictureAllocARGB: align argb allocation
|
||||
3daf7509 WebPParseHeaders: remove obsolete animation TODO
|
||||
80285d97 cmake: avoid security warnings under msvc
|
||||
650eac55 cmake: don't set -Wall with MSVC
|
||||
c462cd00 Remove useless code.
|
||||
01a98217 Merge "remove WebPWorkerImpl declaration from the header"
|
||||
3c49fc47 Merge "thread_utils: fix potentially bad call to Execute"
|
||||
fde2782e thread_utils: fix potentially bad call to Execute
|
||||
2a270c1d remove WebPWorkerImpl declaration from the header
|
||||
f1f437cc remove mention of 'lossy-only parameters' from the doc
|
||||
3879074d Merge "WebPMemToUint32: remove ptr cast to int"
|
||||
04b029d2 WebPMemToUint32: remove ptr cast to int
|
||||
b7971d0e dsp: avoid defining _C functions w/NEON builds
|
||||
6ba98764 webpdec: correct alloc size check w/use_argb
|
||||
5cfb3b0f normalize include guards
|
||||
f433205e Merge changes Ia17c7dfc,I75423abb,Ia2f716b4,I161caa14,I4210081a, ...
|
||||
8d033b14 {dec,enc}_neon: harmonize function suffixes x2
|
||||
0295e981 upsampling_neon: harmonize function suffixes
|
||||
d572c4e5 yuv_neon: harmonize function suffixes
|
||||
ab9c2500 rescaler_neon: harmonize function suffixes
|
||||
93e0ce27 lossless_neon: harmonize function suffixes
|
||||
22fbc50e lossless_enc_neon: harmonize function suffixes
|
||||
447875b4 filters_neon,cosmetics: fix indent
|
||||
e51bdd43 remove unused VP8TokenToStats() function
|
||||
785da7ea enc_neon: harmonize function suffixes
|
||||
bc1a251f dec_neon: harmonize function suffixes
|
||||
61e535f1 dsp/lossless: workaround gcc-4.8 bug on arm
|
||||
68b2eab7 cwebp: fix alpha reporting w/lossless & metadata
|
||||
30042faa WebPDemuxGetI: add doc details around WebPFormatFeature
|
||||
0a17f471 Merge "WIP: list includes as descendants of the project dir"
|
||||
a4399721 WIP: list includes as descendants of the project dir
|
||||
08275708 Merge "Make sure we reach the full range for alpha blending."
|
||||
d361a6a7 yuv_sse2: harmonize function suffixes
|
||||
6921aa6f upsampling_sse2: harmonize function suffixes
|
||||
08c67d3e ssim_sse2: harmonize function suffixes
|
||||
582a1b57 rescaler_sse2: harmonize function suffixes
|
||||
2c1b18ba lossless_sse2: harmonize function suffixes
|
||||
0ac46e81 lossless_enc_sse2: harmonize function suffixes
|
||||
bc634d57 enc_sse2: harmonize function suffixes
|
||||
bcb7347c dec_sse2: harmonize function suffixes
|
||||
e14ad93c Make sure we reach the full range for alpha blending.
|
||||
7038ca8d demux,StoreFrame: restore hdr size check to min req
|
||||
fb3daad6 cpu: fix ssse3 check
|
||||
be590e06 Merge "Fix CMake redefinition for HAVE_CPU_FEATURES_H"
|
||||
35f736e1 Fix CMake redefinition for HAVE_CPU_FEATURES_H
|
||||
a5216efc Fix integer overflow warning.
|
||||
a9c8916b decode.h,WebPIDecGetRGB: clarify output ptr validity
|
||||
3c74c645 gif2webp: handle 1-frame case properly + fix anim_diff
|
||||
c7f295d3 Merge "gif2webp: introduce -loop_compatibility option"
|
||||
b4e04677 gif2webp: introduce -loop_compatibility option
|
||||
f78da3de add LOCAL_CLANG_PREREQ and avoid WORK_AROUND_GCC w/3.8+
|
||||
01c426f1 define WEBP_USE_INTRINSICS w/gcc-4.9+
|
||||
8635973d use sdl-config (if available) to determine the link flags
|
||||
e9459382 use CPPFLAGS before CFLAGS
|
||||
4a9d788e Merge "Android.mk,mips: fix clang build with r15"
|
||||
4fbdc9fb Android.mk,mips: fix clang build with r15
|
||||
a80fcc4a ifdef code not used by Chrome/Android.
|
||||
3993af12 Fix signed integer overflows.
|
||||
f66f94ef anim_dump: small tool to dump frames from animated WebP
|
||||
6eba857b Merge "rationalize the Makefile.am"
|
||||
c5e34fba function definition cleanup
|
||||
3822762a rationalize the Makefile.am
|
||||
501ef6e4 configure style fix: animdiff -> anim_diff
|
||||
f8bdc268 Merge "protect against NULL dump_folder[] value in ReadAnimatedImage()"
|
||||
23bfc652 protect against NULL dump_folder[] value in ReadAnimatedImage()
|
||||
8dc3d71b cosmetics,ReadAnimatedWebP: correct function comment
|
||||
5bd40066 Merge changes I66a64a0a,I4d2e520f
|
||||
7945575c cosmetics,webpinfo: remove an else after a return
|
||||
8729fa11 cosmetics,cwebp: remove an else after a return
|
||||
f324b7f9 cosmetics: normalize fn proto & decl param names
|
||||
869eb369 CMake cleanups.
|
||||
289e62a3 Remove declaration of unimplemented VP8ApplyNearLosslessPredict
|
||||
20a94186 pnmdec,PAM: validate depth before calculating bytes_per_px
|
||||
34130afe anim_encode: fix integer overflow
|
||||
42c79aa6 Merge "Encoder: harmonize function suffixes"
|
||||
b09307dc Encoder: harmonize function suffixes
|
||||
bed0456d Merge "SSIM: harmonize the function suffix"
|
||||
54f6a3cf lossless_sse2.c: fix some missed suffix changes
|
||||
088f1dcc SSIM: harmonize the function suffix
|
||||
86fc4dd9 webpdec: use ImgIoUtilCheckSizeArgumentsOverflow
|
||||
08ea9ecd imageio: add ability restrict max image size
|
||||
6f9daa4a jpegdec,ReadError: fix leaks on error
|
||||
a0f72a4f VP8LTransformColorFunc: drop an non-respected 'const' from the signature.
|
||||
8c934902 Merge "Lossess dec: harmonize the function suffixes"
|
||||
622242aa Lossess dec: harmonize the function suffixes
|
||||
1411f027 Lossless Enc: harmonize the function suffixes
|
||||
24ad2e3c add const to two variables
|
||||
46efe062 Merge "Allow the lossless cruncher to work for alpha."
|
||||
8c3f9a47 Speed-up LZ77.
|
||||
1aef4c71 Allow the lossless cruncher to work for alpha.
|
||||
b8821dbd Improve the box LZ77 speed.
|
||||
7beed280 add missing ()s to macro parameters
|
||||
6473d20b Merge "fix Android standalone toolchain build"
|
||||
dcefed95 Merge "build.gradle: fix arm64 build"
|
||||
0c83a8bc Merge "yuv: harmonize suffix naming"
|
||||
c6d1db4b fix Android standalone toolchain build
|
||||
663a6d9d unify the ALTERNATE_CODE flag usage
|
||||
73ea9f27 yuv: harmonize suffix naming
|
||||
c71b68ac build.gradle: fix arm64 build
|
||||
c4568b47 Rescaler: harmonize the suffix naming
|
||||
6cb13b05 Merge "alpha_processing: harmonize the naming suffixes to be _C()"
|
||||
83a3e69a Merge "simplify WEBP_EXTERN macro"
|
||||
7295fde2 Merge "filters: harmonize the suffixes naming to _SSE2(), _C(), etc."
|
||||
8e42ba4c simplify WEBP_EXTERN macro
|
||||
331ab34b cost*.c: harmonize the suffix namings
|
||||
b161f670 filters: harmonize the suffixes naming to _SSE2(), _C(), etc.
|
||||
dec5e4d3 alpha_processing: harmonize the naming suffixes to be _C()
|
||||
6878d427 fix memory leak in SDL_Init()
|
||||
461ae555 Merge "configure: fix warnings in sdl check"
|
||||
62486a22 configure: test for -Wundef
|
||||
92982609 dsp.h: fix -Wundef w/__mips_dsp_rev
|
||||
0265cede configure: fix warnings in sdl check
|
||||
88c73d8a backward_references_enc.h: fix WINDOW_SIZE_BITS check
|
||||
4ea49f6b rescaler_sse2.c: fix WEBP_RESCALER_FIX -> _RFIX typo
|
||||
1b526638 Clean-up some CMake
|
||||
87f57a4b Merge "cmake: fix gif lib detection when cross compiling"
|
||||
b34a9db1 cosmetics,dec_sse2: remove some redundant comments
|
||||
471c5755 cmake: fix gif lib detection when cross compiling
|
||||
c793417a cmake: disable gif2webp if gif lib isn't found
|
||||
dcbc1c88 cmake: split gif detection from IMG deps
|
||||
66ad84f0 Merge "muxread: remove unreachable code"
|
||||
50ec3ab7 muxread: remove unreachable code
|
||||
7d67a164 Lossy encoding: smoothen transparent areas to improve compression
|
||||
e50650c7 Merge "fix signature for DISABLE_TOKEN_BUFFER compilation"
|
||||
671d2567 fix signature for DISABLE_TOKEN_BUFFER compilation
|
||||
d6755580 cpu.cmake: use unique flag to test simd disable flags
|
||||
28914528 Merge "Remove the argb* files."
|
||||
8acb4942 Remove the argb* files.
|
||||
3b62347b README: correct cmake invocation note
|
||||
7ca0df13 Have the SSE2 version of PackARGB use common code.
|
||||
7b250459 Merge "Re-use the transformed image when trying several LZ77 in lossless."
|
||||
e132072f Re-use the transformed image when trying several LZ77 in lossless.
|
||||
5d7a50ef Get code to compile in C++.
|
||||
7b012987 configure: test for -Wparentheses-equality
|
||||
f0569adb Fix man pages for multi-threading.
|
||||
f1d5a397 multithread cruncher: only copy stats when picture->stats != NULL
|
||||
f8c2ac15 Multi-thread the lossless cruncher.
|
||||
a88c6522 Merge "Integrate a new LZ77 looking for matches in the neighborhood of a pixel only."
|
||||
8f6df1d0 Unroll Predictors 10, 11 and 12.
|
||||
355c3d1b Integrate a new LZ77 looking for matches in the neighborhood of a pixel only.
|
||||
a1779a01 Refactor LZ77 handling in preparation for a new method.
|
||||
67de68b5 Android.mk/build.gradle: fix mips build with clang from r14b
|
||||
f209a548 Use the plane code and not the distance when computing statistics.
|
||||
b903b80c Split cost-based backward references in its own file.
|
||||
498cad34 Cosmetic changes in backward reference.
|
||||
e4eb4587 lossless, VP8LTransformColor_C: make sure no overflow happens with colors.
|
||||
af6deaff webpinfo: handle alpha flag mismatch
|
||||
7caef29b Fix typo that creeped in.
|
||||
39e19f92 Merge "near lossless: fix unsigned int overflow warnings."
|
||||
9bbc0891 near lossless: fix unsigned int overflow warnings.
|
||||
e1118d62 Merge "cosmetics,FindClosestDiscretized: use uint in mask creation"
|
||||
186bc9b7 Merge "webpinfo: tolerate ALPH+VP8L"
|
||||
b5887297 cosmetics,FindClosestDiscretized: use uint in mask creation
|
||||
f1784aee near_lossless,FindClosestDiscretized: use unsigned ops
|
||||
0d20abb3 webpinfo: tolerate ALPH+VP8L
|
||||
972104b3 webpmux: tolerate false positive Alpha flag
|
||||
dd7e83cc tiffdec,ReadTIFF: ensure data_size is < tsize_t max
|
||||
d988eb7b tiffdec,MyRead: quiet -Wshorten-64-to-32 warning
|
||||
dabda707 webpinfo: add support to parse Alpha bitstream
|
||||
4c117643 webpinfo: correct background color output, BGRA->ARGB
|
||||
defc98d7 Doc: clarify the role of quality in WebPConfig.
|
||||
d78ff780 Merge "Fix code to compile with C++."
|
||||
c8f14093 Fix code to compile with C++.
|
||||
497dc6a7 pnmdec: sanitize invalid header output
|
||||
d78e5867 Merge "configure: test for -Wconstant-conversion"
|
||||
481e91eb Merge "pnmdec,PAM: set bytes_per_px based on depth when missing"
|
||||
93b12753 configure: test for -Wconstant-conversion
|
||||
645f0c53 pnmdec,PAM: set bytes_per_px based on depth when missing
|
||||
e9154605 Merge "vwebp: activate GLUT double-buffering"
|
||||
818d795b vwebp: activate GLUT double-buffering
|
||||
d63e6f4b Add a man page for webpinfo
|
||||
4d708435 Merge "NEON: implement ConvertRGB24ToY/BGR24/ARGB/RGBA32ToUV/ARGBToUV"
|
||||
faf42213 NEON: implement ConvertRGB24ToY/BGR24/ARGB/RGBA32ToUV/ARGBToUV
|
||||
b4d576fa Install man pages with CMake.
|
||||
cbc1b921 webpinfo: add features to parse bitstream header
|
||||
e644c556 Fix bad bit writer initialization.
|
||||
b62cdad2 Merge "Implement a cruncher for lossless at method 6."
|
||||
da3e4dfb use the exact constant for the gamma transfer function
|
||||
a9c701e0 Merge "tiffdec: fix EXTRASAMPLES check"
|
||||
adab8ce0 Implement a cruncher for lossless at method 6.
|
||||
1b92b237 Merge "Fix VP8ApplyNearLossless to respect const and stride."
|
||||
1923ff02 tiffdec: fix EXTRASAMPLES check
|
||||
97cce5ba tiffdec: only request EXTRASAMPLES w/> 3 samples/px
|
||||
0dcd85b6 Fix VP8ApplyNearLossless to respect const and stride.
|
||||
f7682189 yuv: rationalize the C/SSE2 function naming
|
||||
52245424 NEON implementation of some Sharp-YUV420 functions
|
||||
690efd82 Avoid several backward reference copies.
|
||||
4bb1f607 src/dec/vp8_dec.h, cosmetics: fix comments
|
||||
285748be cmake: build/install webpinfo
|
||||
78fd199c backward_references_enc.c: clear -Wshadow warnings
|
||||
ae836410 WebPLog2FloorC: clear -Wshadow warning
|
||||
d0b7404e Merge "WASM support"
|
||||
134e314f WASM support
|
||||
c08adb6f Merge "VP8LEnc: remove use of BitsLog2Ceiling()"
|
||||
28c37ebd VP8LEnc: remove use of BitsLog2Ceiling()
|
||||
2cb58ab2 webpinfo: output format as a human readable string
|
||||
bb175a93 Merge "rename some symbols clashing with MSVC headers"
|
||||
39eda658 Remove a duplicated pixel hash implementation.
|
||||
36b8274d rename some symbols clashing with MSVC headers
|
||||
274daf54 Add webpinfo tool.
|
||||
ec5036e4 add explicit reference to /usr/local/{lib,inc}
|
||||
18f0dfac Merge "fix TIFF encoder regarding rgbA/RGBA"
|
||||
4e2b0b50 Merge "webpdec.h: fix a doc typo"
|
||||
e2eeabff Merge "Install binaries, libraries and headers in CMake."
|
||||
836607e6 webpdec.h: fix a doc typo
|
||||
9273e441 fix TIFF encoder regarding rgbA/RGBA
|
||||
17e3c11f Add limited PAM decoding support
|
||||
5f624871 Install binaries, libraries and headers in CMake.
|
||||
976adac1 Merge "lossless incremental decoding: fix missing eos_ test"
|
||||
f8fad4fa lossless incremental decoding: fix missing eos_ test
|
||||
27415d41 Merge "vwebp_sdl: fix the makefile.unix"
|
||||
49566182 Merge "ImgIoUtilWriteFile(): use ImgIoUtilSetBinaryMode"
|
||||
6f75a51b Analyze the transform entropy on the whole image.
|
||||
a5e4e3af Use palette only if we can in entropy analysis.
|
||||
75a9c3c4 Improve compression by better entropy analysis.
|
||||
39cf6f4f vwebp_sdl: fix the makefile.unix
|
||||
699b0416 ImgIoUtilWriteFile(): use ImgIoUtilSetBinaryMode
|
||||
7d985bd1 Fix small entropy analysis bug.
|
||||
6e7caf06 Optimize the color cache size.
|
||||
833c9219 More efficient stochastic histogram merge.
|
||||
5183326b Refactor the greedy histogram merge.
|
||||
99f6f462 Merge "histogram_enc.c,MyRand: s/ul/u/ for unsigned constants"
|
||||
80a22186 ssim.c: remove dead include
|
||||
a128dfff histogram_enc.c,MyRand: s/ul/u/ for unsigned constants
|
||||
693bf74e move the SSIM calculation code in ssim.c / ssim_sse2.c
|
||||
10d791ca Merge "Fix the random generator in HistogramCombineStochastic."
|
||||
fa63a966 Fix the random generator in HistogramCombineStochastic.
|
||||
16be192f VP8LSetBitPos: remove the eos_ setting
|
||||
027151ca don't erase the surface before blitting.
|
||||
4105d565 disable WEBP_USE_XXX optimisations when EMSCRIPTEN is defined
|
||||
9ee32a75 Merge "WebP-JS: emscripten-based Javascript decoder"
|
||||
ca9f7b7d WebP-JS: emscripten-based Javascript decoder
|
||||
868aa690 Perform greedy histogram merge in a unified way.
|
||||
5b393f2d Merge "fix path typo for vwebp_sdl in Makefile.vc"
|
||||
e0012bea CMake: only use libwebpdecoder for building dwebp
|
||||
84c2a7b0 fix path typo for vwebp_sdl in Makefile.vc
|
||||
1b0e4abf Merge "Add a flag to disable SIMD optimizations."
|
||||
32263250 Add a flag to disable SIMD optimizations.
|
||||
b494fdec optimize the ARGB->ARGB Import to use memcpy
|
||||
f1536039 Merge "ReadWebP: decode directly into a pre-allocated buffer"
|
||||
e69ed291 ReadWebP: decode directly into a pre-allocated buffer
|
||||
57d8de8a Merge "vwebp_sdl: simple viewer based on SDL"
|
||||
5cfd4ebc LZ77 interval speedups. Faster, smaller, simpler.
|
||||
1e7ad88b PNM header decoder: add some basic numerical validation
|
||||
17c7890c Merge "Add a decoder only library for WebP in CMake."
|
||||
be733786 Merge "Add clang build fix for MSA"
|
||||
03cda0e4 Add a decoder only library for WebP in CMake.
|
||||
aa893914 Add clang build fix for MSA
|
||||
31a92e97 Merge "imageio: add limited PNM support for reading"
|
||||
dcf9d82a imageio: add limited PNM support for reading
|
||||
6524fcd6 vwebp_sdl: simple viewer based on SDL
|
||||
6cf24a24 get_disto: fix reference file read
|
||||
43d472aa Merge tag 'v0.6.0'
|
||||
50d1a848 update ChangeLog (tag: v0.6.0, origin/0.6.0, 0.6.0)
|
||||
20a7fea0 extras/Makefile.am: fix libwebpextras.la reference
|
||||
415f3ffe update ChangeLog (tag: v0.6.0-rc3)
|
||||
3c6d1224 update NEWS
|
||||
ee4a4141 update AUTHORS
|
||||
32ed856f Fix "all|no frames are keyframes" settings.
|
||||
1c3190b6 Merge "Fix "all|no frames are keyframes" settings."
|
||||
f4dc56fd disable GradientUnfilter_NEON
|
||||
4f3e3bbd disable GradientUnfilter_NEON
|
||||
2dc0bdca Fix "all|no frames are keyframes" settings.
|
||||
0d8e0588 img2webp: treat -loop as a no-op w/single images
|
||||
b0450139 ReadImage(): restore size reporting
|
||||
0ad3b4ef update ChangeLog (tag: v0.6.0-rc2)
|
||||
|
35
Makefile.vc
35
Makefile.vc
@ -29,7 +29,7 @@ PLATFORM_LDFLAGS = /SAFESEH
|
||||
NOLOGO = /nologo
|
||||
CCNODBG = cl.exe $(NOLOGO) /O2 /DNDEBUG
|
||||
CCDEBUG = cl.exe $(NOLOGO) /Od /Gm /Zi /D_DEBUG /RTC1
|
||||
CFLAGS = /I. /Isrc $(NOLOGO) /W3 /EHsc /c
|
||||
CFLAGS = /Isrc $(NOLOGO) /W3 /EHsc /c
|
||||
CFLAGS = $(CFLAGS) /DWIN32 /D_CRT_SECURE_NO_WARNINGS /DWIN32_LEAN_AND_MEAN
|
||||
LDFLAGS = /LARGEADDRESSAWARE /MANIFEST /NXCOMPAT /DYNAMICBASE
|
||||
LDFLAGS = $(LDFLAGS) $(PLATFORM_LDFLAGS)
|
||||
@ -155,7 +155,6 @@ CFGSET = TRUE
|
||||
!MESSAGE - all - build (de)mux-based targets for CFG
|
||||
!MESSAGE - gif2webp - requires libgif & >= VS2013
|
||||
!MESSAGE - anim_diff - requires libgif & >= VS2013
|
||||
!MESSAGE - anim_dump
|
||||
!MESSAGE
|
||||
!MESSAGE RTLIBCFG controls the runtime library linkage - 'static' or 'dynamic'.
|
||||
!MESSAGE 'legacy' will produce a Windows 2000 compatible library.
|
||||
@ -227,15 +226,16 @@ DSP_DEC_OBJS = \
|
||||
$(DIROBJ)\dsp\upsampling_msa.obj \
|
||||
$(DIROBJ)\dsp\upsampling_neon.obj \
|
||||
$(DIROBJ)\dsp\upsampling_sse2.obj \
|
||||
$(DIROBJ)\dsp\upsampling_sse41.obj \
|
||||
$(DIROBJ)\dsp\yuv.obj \
|
||||
$(DIROBJ)\dsp\yuv_mips32.obj \
|
||||
$(DIROBJ)\dsp\yuv_mips_dsp_r2.obj \
|
||||
$(DIROBJ)\dsp\yuv_neon.obj \
|
||||
$(DIROBJ)\dsp\yuv_sse2.obj \
|
||||
$(DIROBJ)\dsp\yuv_sse41.obj \
|
||||
|
||||
DSP_ENC_OBJS = \
|
||||
$(DIROBJ)\dsp\argb.obj \
|
||||
$(DIROBJ)\dsp\argb_mips_dsp_r2.obj \
|
||||
$(DIROBJ)\dsp\argb_sse2.obj \
|
||||
$(DIROBJ)\dsp\cost.obj \
|
||||
$(DIROBJ)\dsp\cost_mips32.obj \
|
||||
$(DIROBJ)\dsp\cost_mips_dsp_r2.obj \
|
||||
@ -287,6 +287,7 @@ ENC_OBJS = \
|
||||
$(DIROBJ)\enc\backward_references_enc.obj \
|
||||
$(DIROBJ)\enc\config_enc.obj \
|
||||
$(DIROBJ)\enc\cost_enc.obj \
|
||||
$(DIROBJ)\enc\delta_palettization_enc.obj \
|
||||
$(DIROBJ)\enc\filter_enc.obj \
|
||||
$(DIROBJ)\enc\frame_enc.obj \
|
||||
$(DIROBJ)\enc\histogram_enc.obj \
|
||||
@ -357,22 +358,15 @@ all: ex $(EXTRA_EXAMPLES)
|
||||
# C99 support which is only available from VS2013 onward.
|
||||
gif2webp: $(DIRBIN)\gif2webp.exe
|
||||
anim_diff: $(DIRBIN)\anim_diff.exe
|
||||
anim_dump: $(DIRBIN)\anim_dump.exe
|
||||
|
||||
$(DIRBIN)\anim_diff.exe: $(DIROBJ)\examples\anim_diff.obj $(EX_ANIM_UTIL_OBJS)
|
||||
$(DIRBIN)\anim_diff.exe: $(EX_UTIL_OBJS) $(IMAGEIO_UTIL_OBJS)
|
||||
$(DIRBIN)\anim_diff.exe: $(EX_GIF_DEC_OBJS) $(LIBWEBPDEMUX) $(LIBWEBP)
|
||||
$(DIRBIN)\anim_dump.exe: $(DIROBJ)\examples\anim_dump.obj $(EX_ANIM_UTIL_OBJS)
|
||||
$(DIRBIN)\anim_dump.exe: $(EX_UTIL_OBJS) $(IMAGEIO_UTIL_OBJS)
|
||||
$(DIRBIN)\anim_dump.exe: $(EX_GIF_DEC_OBJS) $(LIBWEBPDEMUX) $(LIBWEBP)
|
||||
$(DIRBIN)\anim_dump.exe: $(IMAGEIO_ENC_OBJS)
|
||||
$(DIRBIN)\cwebp.exe: $(DIROBJ)\examples\cwebp.obj $(IMAGEIO_DEC_OBJS)
|
||||
$(DIRBIN)\cwebp.exe: $(IMAGEIO_UTIL_OBJS)
|
||||
$(DIRBIN)\cwebp.exe: $(LIBWEBPDEMUX)
|
||||
$(DIRBIN)\dwebp.exe: $(DIROBJ)\examples\dwebp.obj $(IMAGEIO_DEC_OBJS)
|
||||
$(DIRBIN)\dwebp.exe: $(IMAGEIO_ENC_OBJS)
|
||||
$(DIRBIN)\dwebp.exe: $(IMAGEIO_UTIL_OBJS)
|
||||
$(DIRBIN)\dwebp.exe: $(LIBWEBPDEMUX)
|
||||
$(DIRBIN)\gif2webp.exe: $(DIROBJ)\examples\gif2webp.obj $(EX_GIF_DEC_OBJS)
|
||||
$(DIRBIN)\gif2webp.exe: $(EX_UTIL_OBJS) $(IMAGEIO_UTIL_OBJS) $(LIBWEBPMUX)
|
||||
$(DIRBIN)\gif2webp.exe: $(LIBWEBP)
|
||||
@ -385,24 +379,26 @@ $(DIRBIN)\webpmux.exe: $(DIROBJ)\examples\webpmux.obj $(LIBWEBPMUX)
|
||||
$(DIRBIN)\webpmux.exe: $(EX_UTIL_OBJS) $(IMAGEIO_UTIL_OBJS) $(LIBWEBP)
|
||||
$(DIRBIN)\img2webp.exe: $(DIROBJ)\examples\img2webp.obj $(LIBWEBPMUX)
|
||||
$(DIRBIN)\img2webp.exe: $(IMAGEIO_DEC_OBJS)
|
||||
$(DIRBIN)\img2webp.exe: $(EX_UTIL_OBJS) $(IMAGEIO_UTIL_OBJS)
|
||||
$(DIRBIN)\img2webp.exe: $(LIBWEBPDEMUX) $(LIBWEBP)
|
||||
$(DIRBIN)\img2webp.exe: $(EX_UTIL_OBJS) $(IMAGEIO_UTIL_OBJS) $(LIBWEBP)
|
||||
$(DIRBIN)\get_disto.exe: $(DIROBJ)\extras\get_disto.obj
|
||||
$(DIRBIN)\get_disto.exe: $(IMAGEIO_DEC_OBJS) $(IMAGEIO_UTIL_OBJS)
|
||||
$(DIRBIN)\get_disto.exe: $(LIBWEBPDEMUX) $(LIBWEBP)
|
||||
$(DIRBIN)\get_disto.exe: $(IMAGEIO_DEC_OBJS) $(IMAGEIO_UTIL_OBJS) $(LIBWEBP)
|
||||
$(DIRBIN)\webp_quality.exe: $(DIROBJ)\extras\webp_quality.obj
|
||||
$(DIRBIN)\webp_quality.exe: $(IMAGEIO_UTIL_OBJS)
|
||||
$(DIRBIN)\webp_quality.exe: $(EXTRAS_OBJS) $(LIBWEBP)
|
||||
$(DIRBIN)\webpinfo.exe: $(DIROBJ)\examples\webpinfo.obj
|
||||
$(DIRBIN)\webpinfo.exe: $(IMAGEIO_DEC_OBJS)
|
||||
$(DIRBIN)\webpinfo.exe: $(EX_UTIL_OBJS) $(IMAGEIO_UTIL_OBJS)
|
||||
$(DIRBIN)\webpinfo.exe: $(LIBWEBPDEMUX) $(LIBWEBP)
|
||||
$(DIRBIN)\webpinfo.exe: $(EX_UTIL_OBJS) $(IMAGEIO_UTIL_OBJS) $(LIBWEBP)
|
||||
|
||||
$(OUT_EXAMPLES): $(EX_UTIL_OBJS) $(LIBWEBP)
|
||||
$(EX_UTIL_OBJS) $(IMAGEIO_UTIL_OBJS): $(OUTPUT_DIRS)
|
||||
$(IMAGEIO_DEC_OBJS) $(IMAGEIO_ENC_OBJS) $(EXTRAS_OBJS): $(OUTPUT_DIRS)
|
||||
!ENDIF # ARCH == ARM
|
||||
|
||||
experimental:
|
||||
$(MAKE) /f Makefile.vc \
|
||||
CFG=$(CFG) \
|
||||
CFLAGS="$(CFLAGS) /DWEBP_EXPERIMENTAL_FEATURES" /$(MAKEFLAGS)
|
||||
|
||||
$(LIBWEBPDECODER): $(LIBWEBPDECODER_OBJS)
|
||||
$(LIBWEBP): $(LIBWEBP_OBJS)
|
||||
$(LIBWEBPMUX): $(LIBWEBPMUX_OBJS)
|
||||
@ -448,7 +444,7 @@ $(OUTPUT_DIRS):
|
||||
$(DIROBJ)\$(DLLINC):
|
||||
@echo #ifndef WEBP_DLL_H_ > $@
|
||||
@echo #define WEBP_DLL_H_ >> $@
|
||||
@echo #define WEBP_EXTERN __declspec(dllexport) >> $@
|
||||
@echo #define WEBP_EXTERN(type) __declspec(dllexport) type >> $@
|
||||
@echo #endif /* WEBP_DLL_H_ */ >> $@
|
||||
|
||||
.SUFFIXES: .c .obj .res .exe
|
||||
@ -460,9 +456,6 @@ $(DIROBJ)\dsp\enc_avx2.obj: src\dsp\enc_avx2.c
|
||||
$(DIROBJ)\examples\anim_diff.obj: examples\anim_diff.c
|
||||
$(CC) $(CFLAGS) /DWEBP_HAVE_GIF /Fd$(LIBWEBP_PDBNAME) \
|
||||
/Fo$(DIROBJ)\examples\ examples\$(@B).c
|
||||
$(DIROBJ)\examples\anim_dump.obj: examples\anim_dump.c
|
||||
$(CC) $(CFLAGS) /DWEBP_HAVE_GIF /Fd$(LIBWEBP_PDBNAME) \
|
||||
/Fo$(DIROBJ)\examples\ examples\$(@B).c
|
||||
$(DIROBJ)\examples\anim_util.obj: examples\anim_util.c
|
||||
$(CC) $(CFLAGS) /DWEBP_HAVE_GIF /Fd$(LIBWEBP_PDBNAME) \
|
||||
/Fo$(DIROBJ)\examples\ examples\$(@B).c
|
||||
|
23
NEWS
23
NEWS
@ -1,26 +1,3 @@
|
||||
- 4/2/2018: version 1.0.0
|
||||
This is a binary compatible release.
|
||||
* lossy encoder improvements to avoid chroma shifts in various circumstances
|
||||
(issues #308, #340)
|
||||
* big-endian fixes for decode, RGBA import and WebPPictureDistortion
|
||||
Tool updates:
|
||||
gifwebp, anim_diff - default duration behavior (<= 10ms) changed to match
|
||||
web browsers, transcoding tools (issue #379)
|
||||
img2webp, webpmux - allow options to be passed in via a file (issue #355)
|
||||
|
||||
- 11/24/2017: version 0.6.1
|
||||
This is a binary compatible release.
|
||||
* lossless performance and compression improvements + a new 'cruncher' mode
|
||||
(-m 6 -q 100)
|
||||
* ARM performance improvements with clang (15-20% w/ndk r15c, issue #339)
|
||||
* webp-js: emscripten/webassembly based javascript decoder
|
||||
* miscellaneous bug & build fixes (issue #329, #332, #343, #353, #360, #361,
|
||||
#363)
|
||||
Tool updates / additions:
|
||||
added webpinfo - prints file format information (issue #330)
|
||||
gif2webp - loop behavior modified to match Chrome M63+ (crbug.com/649264);
|
||||
'-loop_compatibility' can be used for the old behavior
|
||||
|
||||
- 1/26/2017: version 0.6.0
|
||||
* lossless performance and compression improvements
|
||||
* miscellaneous performance improvements (SSE2, NEON, MSA)
|
||||
|
31
README
31
README
@ -4,7 +4,7 @@
|
||||
\__\__/\____/\_____/__/ ____ ___
|
||||
/ _/ / \ \ / _ \/ _/
|
||||
/ \_/ / / \ \ __/ \__
|
||||
\____/____/\_____/_____/____/v1.0.0
|
||||
\____/____/\_____/_____/____/v0.6.0
|
||||
|
||||
Description:
|
||||
============
|
||||
@ -113,8 +113,8 @@ make install
|
||||
|
||||
CMake:
|
||||
------
|
||||
With CMake, you can compile libwebp, cwebp, dwebp, gif2web, img2webp, webpinfo
|
||||
and the JS bindings.
|
||||
With CMake, you can compile libwebp, cwebp, dwebp, gif2web, img2webp and the
|
||||
JS bindings.
|
||||
|
||||
Prerequisites:
|
||||
A compiler (e.g., gcc with autotools) and CMake.
|
||||
@ -367,23 +367,6 @@ Use following options to convert into alternate image formats:
|
||||
-quiet ....... quiet mode, don't print anything
|
||||
-noasm ....... disable all assembly optimizations
|
||||
|
||||
WebP file analysis tool:
|
||||
========================
|
||||
|
||||
'webpinfo' can be used to print out the chunk level structure and bitstream
|
||||
header information of WebP files. It can also check if the files are of valid
|
||||
WebP format.
|
||||
|
||||
Usage: webpinfo [options] in_files
|
||||
Note: there could be multiple input files;
|
||||
options must come before input files.
|
||||
Options:
|
||||
-version ........... Print version number and exit.
|
||||
-quiet ............. Do not show chunk parsing information.
|
||||
-diag .............. Show parsing error diagnosis.
|
||||
-summary ........... Show chunk stats summary.
|
||||
-bitstream_info .... Parse bitstream header.
|
||||
|
||||
Visualization tool:
|
||||
===================
|
||||
|
||||
@ -458,7 +441,6 @@ File-level options (only used at the start of compression):
|
||||
-mixed ............... use mixed lossy/lossless automatic mode
|
||||
-v ................... verbose mode
|
||||
-h ................... this help
|
||||
-version ............. print version number and exit
|
||||
|
||||
Per-frame options (only used for subsequent images input):
|
||||
-d <int> ............. frame duration in ms (default: 100)
|
||||
@ -495,8 +477,6 @@ Options:
|
||||
-metadata <string> ..... comma separated list of metadata to
|
||||
copy from the input to the output if present
|
||||
Valid values: all, none, icc, xmp (default)
|
||||
-loop_compatibility .... use compatibility mode for Chrome
|
||||
version prior to M62 (inclusive)
|
||||
-mt .................... use multi-threading if available
|
||||
|
||||
-version ............... print version number and exit
|
||||
@ -525,11 +505,6 @@ Options:
|
||||
-min_psnr <float> ... minimum per-frame PSNR
|
||||
-raw_comparison ..... if this flag is not used, RGB is
|
||||
premultiplied before comparison
|
||||
-max_diff <int> ..... maximum allowed difference per channel
|
||||
between corresponding pixels in subsequent
|
||||
frames
|
||||
-h .................. this help
|
||||
-version ............ print version number and exit
|
||||
|
||||
Building:
|
||||
---------
|
||||
|
@ -1,7 +1,7 @@
|
||||
__ __ ____ ____ ____ __ __ _ __ __
|
||||
/ \\/ \/ _ \/ _ \/ _ \/ \ \/ \___/_ / _\
|
||||
\ / __/ _ \ __/ / / (_/ /__
|
||||
\__\__/\_____/_____/__/ \__//_/\_____/__/___/v1.0.0
|
||||
\__\__/\_____/_____/__/ \__//_/\_____/__/___/v0.4.0
|
||||
|
||||
|
||||
Description:
|
||||
@ -33,7 +33,6 @@ Usage: webpmux -get GET_OPTIONS INPUT -o OUTPUT
|
||||
webpmux -info INPUT
|
||||
webpmux [-h|-help]
|
||||
webpmux -version
|
||||
webpmux argument_file_name
|
||||
|
||||
GET_OPTIONS:
|
||||
Extract relevant data:
|
||||
@ -93,9 +92,6 @@ INPUT & OUTPUT are in WebP format.
|
||||
Note: The nature of EXIF, XMP and ICC data is not checked and is assumed to be
|
||||
valid.
|
||||
|
||||
Note: if a single file name is passed as the argument, the arguments will be
|
||||
tokenized from this file. The file name must not start with the character '-'.
|
||||
|
||||
Visualization tool:
|
||||
===================
|
||||
|
||||
|
91
README.wasm
Normal file
91
README.wasm
Normal file
@ -0,0 +1,91 @@
|
||||
Description:
|
||||
============
|
||||
|
||||
This file describes the compilation of libwebp using portable intrinsics /
|
||||
WebAssembly (wasm) to native targets using clang and CMake.
|
||||
|
||||
Prerequisites:
|
||||
==============
|
||||
|
||||
- cmake 2.8+
|
||||
|
||||
- clang 3.9+ for portable intrinsics support; as wasm progresses a tip of tree
|
||||
build may be necessary.
|
||||
|
||||
Building:
|
||||
=========
|
||||
|
||||
- configure the project with CMake using:
|
||||
|
||||
$ mkdir -p build && \
|
||||
cd build && \
|
||||
cmake -DWEBP_BUILD_DWEBP=1 -DCMAKE_C_COMPILER=clang -DWEBP_ENABLE_WASM=1 ../
|
||||
|
||||
- compile dwebp using 'make'.
|
||||
|
||||
- Note this currently generates native executables only and is incompatible
|
||||
with -DWEBP_BUILD_WEBP_JS.
|
||||
|
||||
Build options:
|
||||
==============
|
||||
|
||||
- platform specific multiply high (mulhi) implementation, disabled by default.
|
||||
arm: -DCMAKE_C_FLAGS='-DENABLE_NEON_BUILTIN_MULHI_INT16X8 ...'
|
||||
x86: -DCMAKE_C_FLAGS='-DENABLE_X86_BUILTIN_MULHI_INT16X8 ...'
|
||||
|
||||
Cross compilation:
|
||||
==================
|
||||
|
||||
- arm toolchains can be obtained from:
|
||||
http://www.linaro.org/downloads/
|
||||
|
||||
- the android ndk can be obtained from:
|
||||
https://developer.android.com/ndk/downloads/index.html
|
||||
|
||||
armv7:
|
||||
------
|
||||
|
||||
Android:
|
||||
$ ./android-ndk-r15b/build/tools/make_standalone_toolchain.py \
|
||||
--arch arm --api 24 --stl gnustl --install-dir /opt/android-arm-24
|
||||
$ mkdir -p build && cd build
|
||||
$ cmake ../libwebp \
|
||||
-DWEBP_BUILD_DWEBP=1 \
|
||||
-DCMAKE_C_COMPILER=/opt/android-arm-24/bin/clang \
|
||||
-DCMAKE_PREFIX_PATH=/opt/android-arm-24/sysroot/usr/lib \
|
||||
-DCMAKE_C_FLAGS=-fPIE \
|
||||
-DCMAKE_EXE_LINKER_FLAGS=-Wl,-pie \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DWEBP_ENABLE_WASM=1
|
||||
|
||||
Linux:
|
||||
$ gcc_arm=/opt/gcc-arm; target=arm-linux-gnueabihf
|
||||
$ mkdir -p build && cd build
|
||||
$ cmake ../libwebp -DWEBP_BUILD_DWEBP=1 -DWEBP_ENABLE_WASM=1 \
|
||||
-DCMAKE_C_COMPILER=clang \
|
||||
-DCMAKE_C_FLAGS="--target=$target --gcc-toolchain=$gcc_arm --sysroot=$gcc_arm/$target/libc -march=armv7-a -mfpu=neon" \
|
||||
-DCMAKE_PREFIX_PATH=$gcc_arm/$target/libc/usr
|
||||
|
||||
aarch64 / arm64:
|
||||
----------------
|
||||
|
||||
Android:
|
||||
$ ./android-ndk-r15b/build/tools/make_standalone_toolchain.py \
|
||||
--arch arm64 --api 24 --stl gnustl --install-dir /opt/android-arm64-24
|
||||
$ mkdir -p build && cd build
|
||||
$ cmake ../libwebp \
|
||||
-DWEBP_BUILD_DWEBP=1 \
|
||||
-DCMAKE_C_COMPILER=/opt/android-arm64-24/bin/clang \
|
||||
-DCMAKE_PREFIX_PATH=/opt/android-arm64-24/sysroot/usr/lib \
|
||||
-DCMAKE_C_FLAGS=-fPIE \
|
||||
-DCMAKE_EXE_LINKER_FLAGS=-Wl,-pie \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DWEBP_ENABLE_WASM=1
|
||||
|
||||
Linux:
|
||||
$ gcc_arm=/opt/gcc-aarch64; target=aarch64-linux-gnu
|
||||
$ mkdir -p build && cd build
|
||||
$ cmake ../libwebp -DWEBP_BUILD_DWEBP=1 -DWEBP_ENABLE_WASM=1 \
|
||||
-DCMAKE_C_COMPILER=clang \
|
||||
-DCMAKE_C_FLAGS="--target=$target --gcc-toolchain=$gcc_arm --sysroot=$gcc_arm/$target/libc" \
|
||||
-DCMAKE_PREFIX_PATH=$gcc_arm/$target/libc/usr
|
@ -31,9 +31,13 @@ using Emscripten and CMake.
|
||||
- that's it! Upon completion, you should have the webp.js and
|
||||
webp.js.mem files generated.
|
||||
|
||||
- Note this generates both webp_js and webp_wasm without any SIMD enabled due
|
||||
to bugs with this toolchain associated with the SSE2 code.
|
||||
-DWEBP_ENABLE_WASM is currently meant to generate native (x86, arm)
|
||||
executables (dwebp, cwebp) and is incompatible with -DWEBP_BUILD_WEBP_JS.
|
||||
|
||||
The callable JavaScript function is WebPToSDL(), which decodes a raw WebP
|
||||
bitstream into a canvas. See webp_js/index.html for a simple usage sample
|
||||
(see below for instructions).
|
||||
bitstream into a canvas. See webp_js/index.html for a simple usage sample.
|
||||
|
||||
Demo HTML page:
|
||||
===============
|
||||
|
14
build.gradle
14
build.gradle
@ -82,14 +82,12 @@ model {
|
||||
}
|
||||
}
|
||||
// Check for NEON usage.
|
||||
if (getTargetPlatform() == "arm") {
|
||||
if (getTargetPlatform() == "arm" || getTargetPlatform() == "arm64") {
|
||||
NEON = "c.neon"
|
||||
cCompiler.define "HAVE_CPU_FEATURES_H"
|
||||
} else {
|
||||
NEON = "c"
|
||||
}
|
||||
|
||||
cCompiler.args "-I" + file(".").absolutePath
|
||||
}
|
||||
// Link to pthread for shared libraries.
|
||||
withType(SharedLibraryBinarySpec) {
|
||||
@ -122,6 +120,9 @@ model {
|
||||
include "alpha_processing_neon.$NEON"
|
||||
include "alpha_processing_sse2.c"
|
||||
include "alpha_processing_sse41.c"
|
||||
include "argb.c"
|
||||
include "argb_mips_dsp_r2.c"
|
||||
include "argb_sse2.c"
|
||||
include "cpu.c"
|
||||
include "dec.c"
|
||||
include "dec_clip_tables.c"
|
||||
@ -152,13 +153,11 @@ model {
|
||||
include "upsampling_msa.c"
|
||||
include "upsampling_neon.$NEON"
|
||||
include "upsampling_sse2.c"
|
||||
include "upsampling_sse41.c"
|
||||
include "yuv.c"
|
||||
include "yuv_mips32.c"
|
||||
include "yuv_mips_dsp_r2.c"
|
||||
include "yuv_neon.$NEON"
|
||||
include "yuv_sse2.c"
|
||||
include "yuv_sse41.c"
|
||||
srcDir "src/utils"
|
||||
include "bit_reader_utils.c"
|
||||
include "color_cache_utils.c"
|
||||
@ -198,6 +197,7 @@ model {
|
||||
include "backward_references_enc.c"
|
||||
include "config_enc.c"
|
||||
include "cost_enc.c"
|
||||
include "delta_palettization_enc.c"
|
||||
include "filter_enc.c"
|
||||
include "frame_enc.c"
|
||||
include "histogram_enc.c"
|
||||
@ -289,7 +289,6 @@ model {
|
||||
imagedec(NativeLibrarySpec) {
|
||||
binaries {
|
||||
all {
|
||||
lib library: "webpdemux", linkage: "static"
|
||||
lib library: "webp", linkage: "static"
|
||||
}
|
||||
}
|
||||
@ -332,7 +331,6 @@ model {
|
||||
lib library: "example_util", linkage: "static"
|
||||
lib library: "imagedec", linkage: "static"
|
||||
lib library: "imageio_util", linkage: "static"
|
||||
lib library: "webpdemux", linkage: "static"
|
||||
lib library: "webp", linkage: "static"
|
||||
}
|
||||
}
|
||||
@ -353,7 +351,6 @@ model {
|
||||
lib library: "imagedec", linkage: "static"
|
||||
lib library: "imageenc", linkage: "static"
|
||||
lib library: "imageio_util", linkage: "static"
|
||||
lib library: "webpdemux", linkage: "static"
|
||||
lib library: "webp"
|
||||
}
|
||||
}
|
||||
@ -393,7 +390,6 @@ model {
|
||||
lib library: "imagedec", linkage: "static"
|
||||
lib library: "imageio_util", linkage: "static"
|
||||
lib library: "webpmux", linkage: "static"
|
||||
lib library: "webpdemux", linkage: "static"
|
||||
lib library: "webp"
|
||||
}
|
||||
}
|
||||
|
@ -70,43 +70,18 @@ foreach(I_LIB PNG JPEG TIFF)
|
||||
set(WEBP_HAVE_${I_LIB} ${${I_LIB}_FOUND})
|
||||
if(${I_LIB}_FOUND)
|
||||
list(APPEND WEBP_DEP_IMG_LIBRARIES ${${I_LIB}_LIBRARIES})
|
||||
list(APPEND WEBP_DEP_IMG_INCLUDE_DIRS
|
||||
${${I_LIB}_INCLUDE_DIR} ${${I_LIB}_INCLUDE_DIRS})
|
||||
list(APPEND WEBP_DEP_IMG_INCLUDE_DIRS ${${I_LIB}_INCLUDE_DIRS})
|
||||
endif()
|
||||
endforeach()
|
||||
if(WEBP_DEP_IMG_INCLUDE_DIRS)
|
||||
list(REMOVE_DUPLICATES WEBP_DEP_IMG_INCLUDE_DIRS)
|
||||
endif()
|
||||
|
||||
# GIF detection, gifdec isn't part of the imageio lib.
|
||||
include(CMakePushCheckState)
|
||||
set(WEBP_DEP_GIF_LIBRARIES)
|
||||
set(WEBP_DEP_GIF_INCLUDE_DIRS)
|
||||
find_package(GIF)
|
||||
set(WEBP_HAVE_GIF ${GIF_FOUND})
|
||||
if(GIF_FOUND)
|
||||
# GIF find_package only locates the header and library, it doesn't fail
|
||||
# compile tests when detecting the version, but falls back to 3 (as of at
|
||||
# least cmake 3.7.2). Make sure the library links to avoid incorrect
|
||||
# detection when cross compiling.
|
||||
cmake_push_check_state()
|
||||
set(CMAKE_REQUIRED_LIBRARIES ${GIF_LIBRARIES})
|
||||
set(CMAKE_REQUIRED_INCLUDES ${GIF_INCLUDE_DIR})
|
||||
check_c_source_compiles("
|
||||
#include <gif_lib.h>
|
||||
int main(void) {
|
||||
(void)DGifOpenFileHandle;
|
||||
return 0;
|
||||
}
|
||||
" GIF_COMPILES
|
||||
)
|
||||
cmake_pop_check_state()
|
||||
if(GIF_COMPILES)
|
||||
list(APPEND WEBP_DEP_GIF_LIBRARIES ${GIF_LIBRARIES})
|
||||
list(APPEND WEBP_DEP_GIF_INCLUDE_DIRS ${GIF_INCLUDE_DIR})
|
||||
else()
|
||||
unset(GIF_FOUND)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
## Check for specific headers.
|
||||
@ -164,3 +139,13 @@ strip_bracket(PACKAGE_URL)
|
||||
set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}")
|
||||
set(PACKAGE_TARNAME ${PACKAGE_NAME})
|
||||
set(VERSION ${PACKAGE_VERSION})
|
||||
|
||||
## Generate the config.h header.
|
||||
configure_file(${CMAKE_CURRENT_LIST_DIR}/config.h.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/include/webp/config.h)
|
||||
add_definitions(-DHAVE_CONFIG_H)
|
||||
# The webp folder is included as we reference config.h as
|
||||
# ../webp/config.h or webp/config.h
|
||||
include_directories(${CMAKE_CURRENT_BINARY_DIR}/include
|
||||
${CMAKE_CURRENT_BINARY_DIR}/include/webp
|
||||
)
|
@ -13,9 +13,6 @@
|
||||
/* Set to 1 if __builtin_bswap64 is available */
|
||||
#cmakedefine HAVE_BUILTIN_BSWAP64 1
|
||||
|
||||
/* Define to 1 if you have the <cpu-features.h> header file. */
|
||||
#cmakedefine HAVE_CPU_FEATURES_H 1
|
||||
|
||||
/* Define to 1 if you have the <dlfcn.h> header file. */
|
||||
#cmakedefine HAVE_DLFCN_H 1
|
||||
|
||||
@ -103,6 +100,9 @@
|
||||
/* Version number of package */
|
||||
#cmakedefine VERSION "@VERSION@"
|
||||
|
||||
/* Enable experimental code */
|
||||
#cmakedefine WEBP_EXPERIMENTAL_FEATURES 1
|
||||
|
||||
/* Set to 1 if AVX2 is supported */
|
||||
#cmakedefine WEBP_HAVE_AVX2 1
|
||||
|
||||
@ -115,19 +115,9 @@
|
||||
/* Set to 1 if JPEG library is installed */
|
||||
#cmakedefine WEBP_HAVE_JPEG 1
|
||||
|
||||
/* Set to 1 if NEON is supported */
|
||||
#cmakedefine WEBP_HAVE_NEON
|
||||
|
||||
/* Set to 1 if runtime detection of NEON is enabled */
|
||||
/* TODO: handle properly in CMake */
|
||||
#cmakedefine WEBP_HAVE_NEON_RTCD
|
||||
|
||||
/* Set to 1 if PNG library is installed */
|
||||
#cmakedefine WEBP_HAVE_PNG 1
|
||||
|
||||
/* Set to 1 if SDL library is installed */
|
||||
#cmakedefine WEBP_HAVE_SDL 1
|
||||
|
||||
/* Set to 1 if SSE2 is supported */
|
||||
#cmakedefine WEBP_HAVE_SSE2 1
|
||||
|
||||
@ -137,9 +127,6 @@
|
||||
/* Set to 1 if TIFF library is installed */
|
||||
#cmakedefine WEBP_HAVE_TIFF 1
|
||||
|
||||
/* Enable near lossless encoding */
|
||||
#cmakedefine WEBP_NEAR_LOSSLESS 1
|
||||
|
||||
/* Undefine this to disable thread support. */
|
||||
#cmakedefine WEBP_USE_THREAD 1
|
||||
|
||||
|
@ -1,5 +1,4 @@
|
||||
## Check for SIMD extensions.
|
||||
include(CMakePushCheckState)
|
||||
|
||||
function(webp_check_compiler_flag WEBP_SIMD_FLAG ENABLE_SIMD)
|
||||
if(NOT ENABLE_SIMD)
|
||||
@ -8,8 +7,6 @@ function(webp_check_compiler_flag WEBP_SIMD_FLAG ENABLE_SIMD)
|
||||
return()
|
||||
endif()
|
||||
unset(WEBP_HAVE_FLAG_${WEBP_SIMD_FLAG} CACHE)
|
||||
cmake_push_check_state()
|
||||
set(CMAKE_REQUIRED_INCLUDES ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
check_c_source_compiles("
|
||||
#include \"${CMAKE_CURRENT_LIST_DIR}/../src/dsp/dsp.h\"
|
||||
int main(void) {
|
||||
@ -20,7 +17,6 @@ function(webp_check_compiler_flag WEBP_SIMD_FLAG ENABLE_SIMD)
|
||||
}
|
||||
" WEBP_HAVE_FLAG_${WEBP_SIMD_FLAG}
|
||||
)
|
||||
cmake_pop_check_state()
|
||||
if(WEBP_HAVE_FLAG_${WEBP_SIMD_FLAG})
|
||||
set(WEBP_HAVE_${WEBP_SIMD_FLAG} 1 PARENT_SCOPE)
|
||||
else()
|
||||
@ -64,7 +60,6 @@ foreach(I_SIMD RANGE ${WEBP_SIMD_FLAGS_RANGE})
|
||||
# First try with no extra flag added as the compiler might have default flags
|
||||
# (especially on Android).
|
||||
unset(WEBP_HAVE_${WEBP_SIMD_FLAG} CACHE)
|
||||
cmake_push_check_state()
|
||||
set(CMAKE_REQUIRED_FLAGS)
|
||||
webp_check_compiler_flag(${WEBP_SIMD_FLAG} ${WEBP_ENABLE_SIMD})
|
||||
if(NOT WEBP_HAVE_${WEBP_SIMD_FLAG})
|
||||
@ -90,8 +85,11 @@ foreach(I_SIMD RANGE ${WEBP_SIMD_FLAGS_RANGE})
|
||||
foreach(FILE ${SIMD_FILES})
|
||||
list(APPEND WEBP_SIMD_FILES_NOT_TO_INCLUDE ${FILE})
|
||||
endforeach()
|
||||
# Explicitly disable SIMD.
|
||||
if(SIMD_DISABLE_FLAGS)
|
||||
# Explicitly disable SIMD. Avoid this with WASM to avoid an ICE with clang:
|
||||
# https://bugs.chromium.org/p/webp/issues/detail?id=350
|
||||
# WASM overrides the native SIMD so building it in is harmless aside from
|
||||
# binary size.
|
||||
if(NOT WEBP_ENABLE_WASM AND SIMD_DISABLE_FLAGS)
|
||||
list(GET SIMD_DISABLE_FLAGS ${I_SIMD} SIMD_COMPILE_FLAG)
|
||||
include(CheckCCompilerFlag)
|
||||
if(SIMD_COMPILE_FLAG)
|
||||
@ -106,12 +104,11 @@ foreach(I_SIMD RANGE ${WEBP_SIMD_FLAGS_RANGE})
|
||||
set(COMMON_PATTERNS)
|
||||
endif()
|
||||
set(CMAKE_REQUIRED_DEFINITIONS ${SIMD_COMPILE_FLAG})
|
||||
check_c_source_compiles("int main(void) {return 0;}"
|
||||
FLAG_${SIMD_COMPILE_FLAG}
|
||||
check_c_source_compiles("int main(void) {return 0;}" FLAG2
|
||||
FAIL_REGEX "warning: argument unused during compilation:"
|
||||
${COMMON_PATTERNS}
|
||||
)
|
||||
if(NOT FLAG_${SIMD_COMPILE_FLAG})
|
||||
if(NOT FLAG2)
|
||||
unset(HAS_COMPILE_FLAG CACHE)
|
||||
endif()
|
||||
endif()
|
||||
@ -121,5 +118,14 @@ foreach(I_SIMD RANGE ${WEBP_SIMD_FLAGS_RANGE})
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
cmake_pop_check_state()
|
||||
endforeach()
|
||||
|
||||
## Add *_wasm.c files if enabled.
|
||||
if(WEBP_ENABLE_WASM)
|
||||
file(GLOB SIMD_FILES "${CMAKE_CURRENT_LIST_DIR}/../"
|
||||
"src/dsp/*_wasm.c"
|
||||
)
|
||||
foreach(FILE ${SIMD_FILES})
|
||||
list(APPEND WEBP_SIMD_FILES_TO_INCLUDE ${FILE})
|
||||
endforeach()
|
||||
endif()
|
||||
|
93
configure.ac
93
configure.ac
@ -1,4 +1,4 @@
|
||||
AC_INIT([libwebp], [1.0.0],
|
||||
AC_INIT([libwebp], [0.6.0],
|
||||
[https://bugs.chromium.org/p/webp],,
|
||||
[http://developers.google.com/speed/webp])
|
||||
AC_CANONICAL_HOST
|
||||
@ -79,7 +79,6 @@ TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wold-style-definition])
|
||||
TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wparentheses-equality])
|
||||
TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wshadow])
|
||||
TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wshorten-64-to-32])
|
||||
TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wundef])
|
||||
TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wunreachable-code])
|
||||
TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wunused-but-set-variable])
|
||||
TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wunused])
|
||||
@ -347,8 +346,6 @@ AS_IF([test "x$enable_gl" != "xno"], [
|
||||
# override with --with-gl*
|
||||
glut_cflags="$glut_cflags|-framework GLUT -framework OpenGL"
|
||||
glut_ldflags="$glut_ldflags|-framework GLUT -framework OpenGL"
|
||||
# quiet deprecation warnings for glut
|
||||
TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wno-deprecated-declarations])
|
||||
;;
|
||||
esac
|
||||
|
||||
@ -445,54 +442,31 @@ AC_ARG_ENABLE([sdl],
|
||||
@<:@default=auto@:>@]))
|
||||
AS_IF([test "x$enable_sdl" != "xno"], [
|
||||
CLEAR_LIBVARS([SDL])
|
||||
AC_PATH_PROGS([LIBSDL_CONFIG], [sdl-config])
|
||||
if test -n "$LIBSDL_CONFIG"; then
|
||||
SDL_INCLUDES=`$LIBSDL_CONFIG --cflags`
|
||||
SDL_LIBS="`$LIBSDL_CONFIG --libs`"
|
||||
fi
|
||||
|
||||
WITHLIB_OPTION([sdl], [SDL])
|
||||
|
||||
sdl_header="no"
|
||||
$sdl_header = "no";
|
||||
LIBCHECK_PROLOGUE([SDL])
|
||||
AC_CHECK_HEADER([SDL/SDL.h], [sdl_header="SDL/SDL.h"],
|
||||
AC_CHECK_HEADER([SDL/SDL.h], [sdl_header="SDL_SDL.h"],
|
||||
[AC_CHECK_HEADER([SDL.h], [sdl_header="SDL.h"],
|
||||
[AC_MSG_WARN(SDL library not available - no sdl.h)])])
|
||||
if test x"$sdl_header" != "xno" ; then
|
||||
AC_LANG_PUSH(C)
|
||||
SDL_SAVED_LIBS="$LIBS"
|
||||
for lib in "" "-lSDL" "-lSDLmain -lSDL"; do
|
||||
LIBS="$SDL_SAVED_LIBS $lib"
|
||||
# Perform a full link to ensure SDL_main is resolved if needed.
|
||||
AC_LINK_IFELSE(
|
||||
[AC_LANG_SOURCE([
|
||||
#include <$sdl_header>
|
||||
int main(int argc, char** argv) {
|
||||
SDL_Init(0);
|
||||
return 0;
|
||||
}])],
|
||||
[SDL_LIBS="$LDFLAGS $LIBS"
|
||||
SDL_INCLUDES="$SDL_INCLUDES -DWEBP_HAVE_SDL"
|
||||
AC_CHECK_LIB(SDL, SDL_Init,
|
||||
[SDL_LIBS="-lSDL"
|
||||
SDL_INCLUDES="-DWEBP_HAVE_SDL"
|
||||
AC_DEFINE(WEBP_HAVE_SDL, [1],
|
||||
[Set to 1 if SDL library is installed])
|
||||
sdl_support=yes]
|
||||
)
|
||||
if test x"$sdl_support" = "xyes"; then
|
||||
break
|
||||
fi
|
||||
done
|
||||
# LIBS is restored by LIBCHECK_EPILOGUE
|
||||
AC_LANG_POP
|
||||
if test x"$sdl_header" = "xSDL.h"; then
|
||||
sdl_support=yes
|
||||
],
|
||||
AC_MSG_WARN(Optional SDL library not found),
|
||||
[$MATH_LIBS]),
|
||||
if test x"$sdl_header" == "xSDL.h" ; then
|
||||
SDL_INCLUDES="$SDL_INCLUDES -DWEBP_HAVE_JUST_SDL_H"
|
||||
fi
|
||||
fi
|
||||
LIBCHECK_EPILOGUE([SDL])
|
||||
|
||||
if test x"$sdl_support" = "xyes"; then
|
||||
if test "$sdl_support" = "yes" ; then
|
||||
build_vwebp_sdl=yes
|
||||
else
|
||||
AC_MSG_WARN(Optional SDL library not found)
|
||||
fi
|
||||
])
|
||||
|
||||
@ -615,7 +589,7 @@ AS_IF([test "x$enable_gif" != "xno"], [
|
||||
|
||||
if test "$gif_support" = "yes" -a \
|
||||
"$enable_libwebpdemux" = "yes"; then
|
||||
build_anim_diff=yes
|
||||
build_animdiff=yes
|
||||
fi
|
||||
|
||||
if test "$gif_support" = "yes" -a \
|
||||
@ -623,10 +597,10 @@ AS_IF([test "x$enable_gif" != "xno"], [
|
||||
build_gif2webp=yes
|
||||
fi
|
||||
])
|
||||
AM_CONDITIONAL([BUILD_ANIMDIFF], [test "${build_anim_diff}" = "yes"])
|
||||
AM_CONDITIONAL([BUILD_ANIMDIFF], [test "${build_animdiff}" = "yes"])
|
||||
AM_CONDITIONAL([BUILD_GIF2WEBP], [test "${build_gif2webp}" = "yes"])
|
||||
|
||||
if test "$enable_libwebpdemux" = "yes" -a "$enable_libwebpmux" = "yes"; then
|
||||
if test "$enable_libwebpmux" = "yes"; then
|
||||
build_img2webp=yes
|
||||
fi
|
||||
AM_CONDITIONAL([BUILD_IMG2WEBP], [test "${build_img2webp}" = "yes"])
|
||||
@ -688,7 +662,7 @@ if test "$enable_wic" = "yes"; then
|
||||
fi
|
||||
esac
|
||||
|
||||
dnl === If --enable-swap-16bit-csp is defined, add -DWEBP_SWAP_16BIT_CSP=1
|
||||
dnl === If --enable-swap-16bit-csp is defined, add -DWEBP_SWAP_16BIT_CSP
|
||||
|
||||
USE_SWAP_16BIT_CSP=""
|
||||
AC_MSG_CHECKING(if --enable-swap-16bit-csp option is specified)
|
||||
@ -696,25 +670,23 @@ AC_ARG_ENABLE([swap-16bit-csp],
|
||||
AS_HELP_STRING([--enable-swap-16bit-csp],
|
||||
[Enable byte swap for 16 bit colorspaces]))
|
||||
if test "$enable_swap_16bit_csp" = "yes"; then
|
||||
USE_SWAP_16BIT_CSP="-DWEBP_SWAP_16BIT_CSP=1"
|
||||
USE_SWAP_16BIT_CSP="-DWEBP_SWAP_16BIT_CSP"
|
||||
fi
|
||||
AC_MSG_RESULT(${enable_swap_16bit_csp-no})
|
||||
AC_SUBST(USE_SWAP_16BIT_CSP)
|
||||
|
||||
dnl === If --disable-near-lossless is defined, add -DWEBP_NEAR_LOSSLESS=0
|
||||
dnl === If --enable-experimental is defined, add -DWEBP_EXPERIMENTAL_FEATURES
|
||||
|
||||
AC_DEFINE(WEBP_NEAR_LOSSLESS, [1], [Enable near lossless encoding])
|
||||
AC_MSG_CHECKING(if --disable-near-lossless option is specified)
|
||||
AC_ARG_ENABLE([near_lossless],
|
||||
AS_HELP_STRING([--disable-near-lossless],
|
||||
[Disable near lossless encoding]),
|
||||
[], [enable_near_lossless=yes])
|
||||
if test "$enable_near_lossless" = "no"; then
|
||||
AC_DEFINE(WEBP_NEAR_LOSSLESS, [0], [Enable near lossless encoding])
|
||||
AC_MSG_RESULT([yes])
|
||||
else
|
||||
AC_MSG_RESULT([no])
|
||||
USE_EXPERIMENTAL_CODE=""
|
||||
AC_MSG_CHECKING(if --enable-experimental option is specified)
|
||||
AC_ARG_ENABLE([experimental], AS_HELP_STRING([--enable-experimental],
|
||||
[Activate experimental features]))
|
||||
if test "$enable_experimental" = "yes"; then
|
||||
AC_DEFINE(WEBP_EXPERIMENTAL_FEATURES, [1], [Enable experimental code])
|
||||
USE_EXPERIMENTAL_CODE="-DWEBP_EXPERIMENTAL_FEATURES"
|
||||
fi
|
||||
AC_MSG_RESULT(${enable_experimental-no})
|
||||
AC_SUBST(USE_EXPERIMENTAL_CODE)
|
||||
|
||||
dnl === Check whether libwebpmux should be built
|
||||
AC_MSG_CHECKING(whether libwebpmux is to be built)
|
||||
@ -727,9 +699,8 @@ AM_CONDITIONAL([WANT_MUX], [test "$enable_libwebpmux" = "yes"])
|
||||
dnl === Check whether libwebpdemux should be built
|
||||
AC_MSG_CHECKING(whether libwebpdemux is to be built)
|
||||
AC_ARG_ENABLE([libwebpdemux],
|
||||
AS_HELP_STRING([--disable-libwebpdemux],
|
||||
[Disable libwebpdemux @<:@default=no@:>@]),
|
||||
[], [enable_libwebpdemux=yes])
|
||||
AS_HELP_STRING([--enable-libwebpdemux],
|
||||
[Build libwebpdemux @<:@default=no@:>@]))
|
||||
AC_MSG_RESULT(${enable_libwebpdemux-no})
|
||||
AM_CONDITIONAL([WANT_DEMUX], [test "$enable_libwebpdemux" = "yes"])
|
||||
|
||||
@ -778,20 +749,20 @@ libwebpmux: ${enable_libwebpmux-no}
|
||||
libwebpextras: ${enable_libwebpextras-no}
|
||||
|
||||
Tools:
|
||||
cwebp : ${enable_libwebpdemux-no}
|
||||
cwebp : yes
|
||||
Input format support
|
||||
====================
|
||||
JPEG : ${jpeg_support-no}
|
||||
PNG : ${png_support-no}
|
||||
TIFF : ${tiff_support-no}
|
||||
WIC : ${wic_support-no}
|
||||
dwebp : ${enable_libwebpdemux-no}
|
||||
dwebp : yes
|
||||
Output format support
|
||||
=====================
|
||||
PNG : ${png_support-no}
|
||||
WIC : ${wic_support-no}
|
||||
GIF support : ${gif_support-no}
|
||||
anim_diff : ${build_anim_diff-no}
|
||||
anim_diff : ${build_animdiff-no}
|
||||
gif2webp : ${build_gif2webp-no}
|
||||
img2webp : ${build_img2webp-no}
|
||||
webpmux : ${enable_libwebpmux-no}
|
||||
|
@ -446,9 +446,8 @@ Frame Height Minus One: 24 bits (_uint24_)
|
||||
Frame Duration: 24 bits (_uint24_)
|
||||
|
||||
: The time to wait before displaying the next frame, in 1 millisecond units.
|
||||
Note the interpretation of frame duration of 0 (and often <= 10) is
|
||||
implementation defined. Many tools and browsers assign a minimum duration
|
||||
similar to GIF.
|
||||
In particular, frame duration of 0 is useful when one wants to update
|
||||
multiple areas of the canvas at once during the animation.
|
||||
|
||||
Reserved: 6 bits
|
||||
|
||||
|
@ -27,7 +27,7 @@ LOCAL_SRC_FILES := \
|
||||
|
||||
LOCAL_CFLAGS := $(WEBP_CFLAGS)
|
||||
LOCAL_C_INCLUDES := $(LOCAL_PATH)/../src
|
||||
LOCAL_STATIC_LIBRARIES := example_util imageio_util imagedec webpdemux webp
|
||||
LOCAL_STATIC_LIBRARIES := example_util imageio_util imagedec webp
|
||||
|
||||
LOCAL_MODULE := cwebp
|
||||
|
||||
@ -43,7 +43,8 @@ LOCAL_SRC_FILES := \
|
||||
|
||||
LOCAL_CFLAGS := $(WEBP_CFLAGS)
|
||||
LOCAL_C_INCLUDES := $(LOCAL_PATH)/../src
|
||||
LOCAL_STATIC_LIBRARIES := example_util imagedec imageenc webpdemux webp
|
||||
LOCAL_STATIC_LIBRARIES := example_util imagedec imageenc webp
|
||||
|
||||
LOCAL_MODULE := dwebp
|
||||
|
||||
include $(BUILD_EXECUTABLE)
|
||||
@ -74,8 +75,7 @@ LOCAL_SRC_FILES := \
|
||||
|
||||
LOCAL_CFLAGS := $(WEBP_CFLAGS)
|
||||
LOCAL_C_INCLUDES := $(LOCAL_PATH)/../src
|
||||
LOCAL_STATIC_LIBRARIES := example_util imageio_util imagedec webpmux webpdemux \
|
||||
webp
|
||||
LOCAL_STATIC_LIBRARIES := example_util imageio_util imagedec webpmux webp
|
||||
|
||||
LOCAL_MODULE := img2webp_example
|
||||
|
||||
|
@ -1,11 +1,8 @@
|
||||
AM_CPPFLAGS += -I$(top_builddir)/src -I$(top_srcdir)/src
|
||||
|
||||
bin_PROGRAMS =
|
||||
if WANT_DEMUX
|
||||
bin_PROGRAMS += dwebp cwebp
|
||||
endif
|
||||
bin_PROGRAMS = dwebp cwebp
|
||||
if BUILD_ANIMDIFF
|
||||
noinst_PROGRAMS = anim_diff anim_dump
|
||||
noinst_PROGRAMS = anim_diff
|
||||
endif
|
||||
if BUILD_GIF2WEBP
|
||||
bin_PROGRAMS += gif2webp
|
||||
@ -29,37 +26,21 @@ libexample_util_la_SOURCES = example_util.c example_util.h
|
||||
libexample_util_la_LIBADD = ../src/libwebp.la
|
||||
|
||||
anim_diff_SOURCES = anim_diff.c anim_util.c anim_util.h
|
||||
anim_diff_CPPFLAGS = $(AM_CPPFLAGS) $(GIF_INCLUDES)
|
||||
anim_diff_LDADD =
|
||||
anim_diff_LDADD += ../src/demux/libwebpdemux.la
|
||||
anim_diff_LDADD += libexample_util.la
|
||||
anim_diff_LDADD += ../imageio/libimageio_util.la
|
||||
anim_diff_CPPFLAGS = $(AM_CPPFLAGS) $(USE_EXPERIMENTAL_CODE) $(GIF_INCLUDES)
|
||||
anim_diff_LDADD = ../src/demux/libwebpdemux.la
|
||||
anim_diff_LDADD += libexample_util.la ../imageio/libimageio_util.la
|
||||
anim_diff_LDADD += $(GIF_LIBS) -lm
|
||||
|
||||
anim_dump_SOURCES = anim_dump.c anim_util.c anim_util.h
|
||||
anim_dump_CPPFLAGS = $(AM_CPPFLAGS) $(PNG_INCLUDES)
|
||||
anim_dump_CPPFLAGS += $(GIF_INCLUDES)
|
||||
anim_dump_LDADD =
|
||||
anim_dump_LDADD += ../src/demux/libwebpdemux.la
|
||||
anim_dump_LDADD += libexample_util.la
|
||||
anim_dump_LDADD += ../imageio/libimageio_util.la
|
||||
anim_dump_LDADD += ../imageio/libimageenc.la
|
||||
anim_dump_LDADD += $(PNG_LIBS) $(GIF_LIBS) $(TIFF_LIBS) -lm
|
||||
|
||||
cwebp_SOURCES = cwebp.c stopwatch.h
|
||||
cwebp_CPPFLAGS = $(AM_CPPFLAGS)
|
||||
cwebp_LDADD =
|
||||
cwebp_LDADD += libexample_util.la
|
||||
cwebp_LDADD += ../imageio/libimageio_util.la
|
||||
cwebp_LDADD += ../imageio/libimagedec.la
|
||||
cwebp_LDADD += ../src/libwebp.la
|
||||
cwebp_CPPFLAGS = $(AM_CPPFLAGS) $(USE_EXPERIMENTAL_CODE)
|
||||
cwebp_LDADD = libexample_util.la ../imageio/libimageio_util.la
|
||||
cwebp_LDADD += ../imageio/libimagedec.la ../src/libwebp.la
|
||||
cwebp_LDADD += $(JPEG_LIBS) $(PNG_LIBS) $(TIFF_LIBS)
|
||||
|
||||
dwebp_SOURCES = dwebp.c stopwatch.h
|
||||
dwebp_CPPFLAGS = $(AM_CPPFLAGS)
|
||||
dwebp_CPPFLAGS = $(AM_CPPFLAGS) $(USE_EXPERIMENTAL_CODE)
|
||||
dwebp_CPPFLAGS += $(JPEG_INCLUDES) $(PNG_INCLUDES)
|
||||
dwebp_LDADD =
|
||||
dwebp_LDADD += libexample_util.la
|
||||
dwebp_LDADD = libexample_util.la
|
||||
dwebp_LDADD += ../imageio/libimagedec.la
|
||||
dwebp_LDADD += ../imageio/libimageenc.la
|
||||
dwebp_LDADD += ../imageio/libimageio_util.la
|
||||
@ -67,53 +48,36 @@ dwebp_LDADD += ../src/libwebp.la
|
||||
dwebp_LDADD +=$(PNG_LIBS) $(JPEG_LIBS)
|
||||
|
||||
gif2webp_SOURCES = gif2webp.c gifdec.c gifdec.h
|
||||
gif2webp_CPPFLAGS = $(AM_CPPFLAGS) $(GIF_INCLUDES)
|
||||
gif2webp_LDADD =
|
||||
gif2webp_LDADD += libexample_util.la
|
||||
gif2webp_LDADD += ../imageio/libimageio_util.la
|
||||
gif2webp_LDADD += ../src/mux/libwebpmux.la
|
||||
gif2webp_LDADD += ../src/libwebp.la
|
||||
gif2webp_LDADD += $(GIF_LIBS)
|
||||
gif2webp_CPPFLAGS = $(AM_CPPFLAGS) $(USE_EXPERIMENTAL_CODE) $(GIF_INCLUDES)
|
||||
gif2webp_LDADD = libexample_util.la ../imageio/libimageio_util.la
|
||||
gif2webp_LDADD += ../src/mux/libwebpmux.la ../src/libwebp.la $(GIF_LIBS)
|
||||
|
||||
vwebp_SOURCES = vwebp.c
|
||||
vwebp_CPPFLAGS = $(AM_CPPFLAGS) $(GL_INCLUDES)
|
||||
vwebp_LDADD =
|
||||
vwebp_LDADD += libexample_util.la
|
||||
vwebp_LDADD += ../imageio/libimageio_util.la
|
||||
vwebp_LDADD += ../src/demux/libwebpdemux.la
|
||||
vwebp_LDADD += $(GL_LIBS)
|
||||
vwebp_CPPFLAGS = $(AM_CPPFLAGS) $(USE_EXPERIMENTAL_CODE) $(GL_INCLUDES)
|
||||
vwebp_LDADD = libexample_util.la ../imageio/libimageio_util.la
|
||||
vwebp_LDADD += ../src/demux/libwebpdemux.la $(GL_LIBS)
|
||||
|
||||
webpmux_SOURCES = webpmux.c
|
||||
webpmux_CPPFLAGS = $(AM_CPPFLAGS)
|
||||
webpmux_LDADD =
|
||||
webpmux_LDADD += libexample_util.la
|
||||
webpmux_LDADD += ../imageio/libimageio_util.la
|
||||
webpmux_LDADD += ../src/mux/libwebpmux.la
|
||||
webpmux_LDADD += ../src/libwebp.la
|
||||
webpmux_CPPFLAGS = $(AM_CPPFLAGS) $(USE_EXPERIMENTAL_CODE)
|
||||
webpmux_LDADD = libexample_util.la ../imageio/libimageio_util.la
|
||||
webpmux_LDADD += ../src/mux/libwebpmux.la ../src/libwebp.la
|
||||
|
||||
img2webp_SOURCES = img2webp.c
|
||||
img2webp_CPPFLAGS = $(AM_CPPFLAGS)
|
||||
img2webp_LDADD =
|
||||
img2webp_LDADD += libexample_util.la
|
||||
img2webp_LDADD += ../imageio/libimageio_util.la
|
||||
img2webp_CPPFLAGS = $(AM_CPPFLAGS) $(USE_EXPERIMENTAL_CODE)
|
||||
img2webp_LDADD = libexample_util.la ../imageio/libimageio_util.la
|
||||
img2webp_LDADD += ../imageio/libimagedec.la
|
||||
img2webp_LDADD += ../src/mux/libwebpmux.la
|
||||
img2webp_LDADD += ../src/libwebp.la
|
||||
img2webp_LDADD += ../src/mux/libwebpmux.la ../src/libwebp.la
|
||||
img2webp_LDADD += $(PNG_LIBS) $(JPEG_LIBS) $(TIFF_LIBS)
|
||||
|
||||
webpinfo_SOURCES = webpinfo.c
|
||||
webpinfo_CPPFLAGS = $(AM_CPPFLAGS)
|
||||
webpinfo_LDADD =
|
||||
webpinfo_LDADD += libexample_util.la
|
||||
webpinfo_LDADD += ../imageio/libimageio_util.la
|
||||
webpinfo_CPPFLAGS = $(AM_CPPFLAGS) $(USE_EXPERIMENTAL_CODE)
|
||||
webpinfo_LDADD = libexample_util.la ../imageio/libimageio_util.la
|
||||
webpinfo_LDADD += ../src/libwebp.la
|
||||
|
||||
if BUILD_LIBWEBPDECODER
|
||||
anim_diff_LDADD += ../src/libwebpdecoder.la
|
||||
anim_dump_LDADD += ../src/libwebpdecoder.la
|
||||
vwebp_LDADD += ../src/libwebpdecoder.la
|
||||
else
|
||||
anim_diff_LDADD += ../src/libwebp.la
|
||||
anim_dump_LDADD += ../src/libwebp.la
|
||||
vwebp_LDADD += ../src/libwebp.la
|
||||
endif
|
||||
|
@ -187,11 +187,11 @@ static void Help(void) {
|
||||
printf(" -min_psnr <float> ... minimum per-frame PSNR\n");
|
||||
printf(" -raw_comparison ..... if this flag is not used, RGB is\n");
|
||||
printf(" premultiplied before comparison\n");
|
||||
printf(" -max_diff <int> ..... maximum allowed difference per channel\n"
|
||||
" between corresponding pixels in subsequent\n"
|
||||
#ifdef WEBP_EXPERIMENTAL_FEATURES
|
||||
printf(" -max_diff <int> ..... maximum allowed difference per channel "
|
||||
" between corresponding pixels in subsequent"
|
||||
" frames\n");
|
||||
printf(" -h .................. this help\n");
|
||||
printf(" -version ............ print version number and exit\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
int main(int argc, const char* argv[]) {
|
||||
@ -207,6 +207,11 @@ int main(int argc, const char* argv[]) {
|
||||
const char* files[2] = { NULL, NULL };
|
||||
AnimatedImage images[2];
|
||||
|
||||
if (argc < 3) {
|
||||
Help();
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (c = 1; c < argc; ++c) {
|
||||
int parse_error = 0;
|
||||
if (!strcmp(argv[c], "-dump_frames")) {
|
||||
@ -231,6 +236,7 @@ int main(int argc, const char* argv[]) {
|
||||
}
|
||||
} else if (!strcmp(argv[c], "-raw_comparison")) {
|
||||
premultiply = 0;
|
||||
#ifdef WEBP_EXPERIMENTAL_FEATURES
|
||||
} else if (!strcmp(argv[c], "-max_diff")) {
|
||||
if (c < argc - 1) {
|
||||
const char* const v = argv[++c];
|
||||
@ -244,18 +250,7 @@ int main(int argc, const char* argv[]) {
|
||||
} else {
|
||||
parse_error = 1;
|
||||
}
|
||||
} else if (!strcmp(argv[c], "-h") || !strcmp(argv[c], "-help")) {
|
||||
Help();
|
||||
return 0;
|
||||
} else if (!strcmp(argv[c], "-version")) {
|
||||
int dec_version, demux_version;
|
||||
GetAnimatedImageVersions(&dec_version, &demux_version);
|
||||
printf("WebP Decoder version: %d.%d.%d\nWebP Demux version: %d.%d.%d\n",
|
||||
(dec_version >> 16) & 0xff, (dec_version >> 8) & 0xff,
|
||||
(dec_version >> 0) & 0xff,
|
||||
(demux_version >> 16) & 0xff, (demux_version >> 8) & 0xff,
|
||||
(demux_version >> 0) & 0xff);
|
||||
return 0;
|
||||
#endif
|
||||
} else {
|
||||
if (!got_input1) {
|
||||
files[0] = argv[c];
|
||||
@ -272,12 +267,6 @@ int main(int argc, const char* argv[]) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (argc < 3) {
|
||||
Help();
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
if (!got_input2) {
|
||||
Help();
|
||||
return -1;
|
||||
|
@ -1,118 +0,0 @@
|
||||
// Copyright 2017 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// Use of this source code is governed by a BSD-style license
|
||||
// that can be found in the COPYING file in the root of the source
|
||||
// tree. An additional intellectual property rights grant can be found
|
||||
// in the file PATENTS. All contributing project authors may
|
||||
// be found in the AUTHORS file in the root of the source tree.
|
||||
// -----------------------------------------------------------------------------
|
||||
//
|
||||
// Decodes an animated WebP file and dumps the decoded frames as PNG or TIFF.
|
||||
//
|
||||
// Author: Skal (pascal.massimino@gmail.com)
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h> // for 'strcmp'.
|
||||
|
||||
#include "./anim_util.h"
|
||||
#include "webp/decode.h"
|
||||
#include "../imageio/image_enc.h"
|
||||
|
||||
#if defined(_MSC_VER) && _MSC_VER < 1900
|
||||
#define snprintf _snprintf
|
||||
#endif
|
||||
|
||||
static void Help(void) {
|
||||
printf("Usage: anim_dump [options] files...\n");
|
||||
printf("\nOptions:\n");
|
||||
printf(" -folder <string> .... dump folder (default: '.')\n");
|
||||
printf(" -prefix <string> .... prefix for dumped frames "
|
||||
"(default: 'dump_')\n");
|
||||
printf(" -tiff ............... save frames as TIFF\n");
|
||||
printf(" -pam ................ save frames as PAM\n");
|
||||
printf(" -h .................. this help\n");
|
||||
printf(" -version ............ print version number and exit\n");
|
||||
}
|
||||
|
||||
int main(int argc, const char* argv[]) {
|
||||
int error = 0;
|
||||
const char* dump_folder = ".";
|
||||
const char* prefix = "dump_";
|
||||
const char* suffix = "png";
|
||||
WebPOutputFileFormat format = PNG;
|
||||
int c;
|
||||
|
||||
if (argc < 2) {
|
||||
Help();
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (c = 1; !error && c < argc; ++c) {
|
||||
if (!strcmp(argv[c], "-folder")) {
|
||||
if (c + 1 == argc) {
|
||||
fprintf(stderr, "missing argument after option '%s'\n", argv[c]);
|
||||
error = 1;
|
||||
break;
|
||||
}
|
||||
dump_folder = argv[++c];
|
||||
} else if (!strcmp(argv[c], "-prefix")) {
|
||||
if (c + 1 == argc) {
|
||||
fprintf(stderr, "missing argument after option '%s'\n", argv[c]);
|
||||
error = 1;
|
||||
break;
|
||||
}
|
||||
prefix = argv[++c];
|
||||
} else if (!strcmp(argv[c], "-tiff")) {
|
||||
format = TIFF;
|
||||
suffix = "tiff";
|
||||
} else if (!strcmp(argv[c], "-pam")) {
|
||||
format = PAM;
|
||||
suffix = "pam";
|
||||
} else if (!strcmp(argv[c], "-h") || !strcmp(argv[c], "-help")) {
|
||||
Help();
|
||||
return 0;
|
||||
} else if (!strcmp(argv[c], "-version")) {
|
||||
int dec_version, demux_version;
|
||||
GetAnimatedImageVersions(&dec_version, &demux_version);
|
||||
printf("WebP Decoder version: %d.%d.%d\nWebP Demux version: %d.%d.%d\n",
|
||||
(dec_version >> 16) & 0xff, (dec_version >> 8) & 0xff,
|
||||
(dec_version >> 0) & 0xff,
|
||||
(demux_version >> 16) & 0xff, (demux_version >> 8) & 0xff,
|
||||
(demux_version >> 0) & 0xff);
|
||||
return 0;
|
||||
} else {
|
||||
uint32_t i;
|
||||
AnimatedImage image;
|
||||
const char* const file = argv[c];
|
||||
memset(&image, 0, sizeof(image));
|
||||
printf("Decoding file: %s as %s/%sxxxx.%s\n",
|
||||
file, dump_folder, prefix, suffix);
|
||||
if (!ReadAnimatedImage(file, &image, 0, NULL)) {
|
||||
fprintf(stderr, "Error decoding file: %s\n Aborting.\n", file);
|
||||
error = 1;
|
||||
break;
|
||||
}
|
||||
for (i = 0; !error && i < image.num_frames; ++i) {
|
||||
char out_file[1024];
|
||||
WebPDecBuffer buffer;
|
||||
WebPInitDecBuffer(&buffer);
|
||||
buffer.colorspace = MODE_RGBA;
|
||||
buffer.is_external_memory = 1;
|
||||
buffer.width = image.canvas_width;
|
||||
buffer.height = image.canvas_height;
|
||||
buffer.u.RGBA.rgba = image.frames[i].rgba;
|
||||
buffer.u.RGBA.stride = buffer.width * sizeof(uint32_t);
|
||||
buffer.u.RGBA.size = buffer.u.RGBA.stride * buffer.height;
|
||||
snprintf(out_file, sizeof(out_file), "%s/%s%.4d.%s",
|
||||
dump_folder, prefix, i, suffix);
|
||||
if (!WebPSaveImage(&buffer, format, out_file)) {
|
||||
fprintf(stderr, "Error while saving image '%s'\n", out_file);
|
||||
error = 1;
|
||||
}
|
||||
WebPFreeDecBuffer(&buffer);
|
||||
}
|
||||
ClearAnimatedImage(&image);
|
||||
}
|
||||
}
|
||||
return error ? 1 : 0;
|
||||
}
|
@ -16,7 +16,7 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#if defined(WEBP_HAVE_GIF)
|
||||
#ifdef WEBP_HAVE_GIF
|
||||
#include <gif_lib.h>
|
||||
#endif
|
||||
#include "webp/format_constants.h"
|
||||
@ -33,13 +33,11 @@ static const int kNumChannels = 4;
|
||||
// -----------------------------------------------------------------------------
|
||||
// Common utilities.
|
||||
|
||||
#if defined(WEBP_HAVE_GIF)
|
||||
// Returns true if the frame covers the full canvas.
|
||||
static int IsFullFrame(int width, int height,
|
||||
int canvas_width, int canvas_height) {
|
||||
return (width == canvas_width && height == canvas_height);
|
||||
}
|
||||
#endif // WEBP_HAVE_GIF
|
||||
|
||||
static int CheckSizeForOverflow(uint64_t size) {
|
||||
return (size == (size_t)size);
|
||||
@ -87,7 +85,6 @@ void ClearAnimatedImage(AnimatedImage* const image) {
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(WEBP_HAVE_GIF)
|
||||
// Clear the canvas to transparent.
|
||||
static void ZeroFillCanvas(uint8_t* rgba,
|
||||
uint32_t canvas_width, uint32_t canvas_height) {
|
||||
@ -129,7 +126,6 @@ static void CopyFrameRectangle(const uint8_t* src, uint8_t* dst, int stride,
|
||||
dst += stride;
|
||||
}
|
||||
}
|
||||
#endif // WEBP_HAVE_GIF
|
||||
|
||||
// Canonicalize all transparent pixels to transparent black to aid comparison.
|
||||
static void CleanupTransparentPixels(uint32_t* rgba,
|
||||
@ -156,8 +152,6 @@ static int DumpFrame(const char filename[], const char dump_folder[],
|
||||
FILE* f = NULL;
|
||||
const char* row;
|
||||
|
||||
if (dump_folder == NULL) dump_folder = ".";
|
||||
|
||||
base_name = strrchr(filename, '/');
|
||||
base_name = (base_name == NULL) ? filename : base_name + 1;
|
||||
max_len = strlen(dump_folder) + 1 + strlen(base_name)
|
||||
@ -206,7 +200,7 @@ static int IsWebP(const WebPData* const webp_data) {
|
||||
return (WebPGetInfo(webp_data->bytes, webp_data->size, NULL, NULL) != 0);
|
||||
}
|
||||
|
||||
// Read animated WebP bitstream 'webp_data' into 'AnimatedImage' struct.
|
||||
// Read animated WebP bitstream 'file_str' into 'AnimatedImage' struct.
|
||||
static int ReadAnimatedWebP(const char filename[],
|
||||
const WebPData* const webp_data,
|
||||
AnimatedImage* const image, int dump_frames,
|
||||
@ -284,7 +278,7 @@ static int ReadAnimatedWebP(const char filename[],
|
||||
// -----------------------------------------------------------------------------
|
||||
// GIF Decoding.
|
||||
|
||||
#if defined(WEBP_HAVE_GIF)
|
||||
#ifdef WEBP_HAVE_GIF
|
||||
|
||||
// Returns true if this is a valid GIF bitstream.
|
||||
static int IsGIF(const WebPData* const data) {
|
||||
@ -429,11 +423,6 @@ static uint32_t GetBackgroundColorGIF(GifFileType* gif) {
|
||||
}
|
||||
|
||||
// Find appropriate app extension and get loop count from the next extension.
|
||||
// We use Chrome's interpretation of the 'loop_count' semantics:
|
||||
// if not present -> loop once
|
||||
// if present and loop_count == 0, return 0 ('infinite').
|
||||
// if present and loop_count != 0, it's the number of *extra* loops
|
||||
// so we need to return loop_count + 1 as total loop number.
|
||||
static uint32_t GetLoopCountGIF(const GifFileType* const gif) {
|
||||
int i;
|
||||
for (i = 0; i < gif->ImageCount; ++i) {
|
||||
@ -451,13 +440,12 @@ static uint32_t GetLoopCountGIF(const GifFileType* const gif) {
|
||||
if (signature_is_ok &&
|
||||
eb2->Function == CONTINUE_EXT_FUNC_CODE && eb2->ByteCount >= 3 &&
|
||||
eb2->Bytes[0] == 1) {
|
||||
const uint32_t extra_loop = ((uint32_t)(eb2->Bytes[2]) << 8) +
|
||||
return ((uint32_t)(eb2->Bytes[2]) << 8) +
|
||||
((uint32_t)(eb2->Bytes[1]) << 0);
|
||||
return (extra_loop > 0) ? extra_loop + 1 : 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 1; // Default.
|
||||
return 0; // Default.
|
||||
}
|
||||
|
||||
// Get duration of 'n'th frame in milliseconds.
|
||||
@ -593,9 +581,6 @@ static int ReadAnimatedGIF(const char filename[], AnimatedImage* const image,
|
||||
curr_frame = &image->frames[i];
|
||||
curr_rgba = curr_frame->rgba;
|
||||
curr_frame->duration = GetFrameDurationGIF(gif, i);
|
||||
// Force frames with a small or no duration to 100ms to be consistent
|
||||
// with web browsers and other transcoding tools (like gif2webp itself).
|
||||
if (curr_frame->duration <= 10) curr_frame->duration = 100;
|
||||
|
||||
if (i == 0) { // Initialize as transparent.
|
||||
curr_frame->is_key_frame = 1;
|
||||
@ -786,9 +771,3 @@ void GetDiffAndPSNR(const uint8_t rgba1[], const uint8_t rgba2[],
|
||||
*psnr = 4.3429448 * log(255. * 255. / sse);
|
||||
}
|
||||
}
|
||||
|
||||
void GetAnimatedImageVersions(int* const decoder_version,
|
||||
int* const demux_version) {
|
||||
*decoder_version = WebPGetDecoderVersion();
|
||||
*demux_version = WebPGetDemuxVersion();
|
||||
}
|
||||
|
@ -56,10 +56,6 @@ void GetDiffAndPSNR(const uint8_t rgba1[], const uint8_t rgba2[],
|
||||
uint32_t width, uint32_t height, int premultiply,
|
||||
int* const max_diff, double* const psnr);
|
||||
|
||||
// Return library versions used by anim_util.
|
||||
void GetAnimatedImageVersions(int* const decoder_version,
|
||||
int* const demux_version);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
@ -140,11 +140,10 @@ static void PrintByteCount(const int bytes[4], int total_size,
|
||||
fprintf(stderr, "| %7d (%.1f%%)\n", total, 100.f * total / total_size);
|
||||
}
|
||||
|
||||
static void PrintPercents(const int counts[4]) {
|
||||
static void PrintPercents(const int counts[4], int total) {
|
||||
int s;
|
||||
const int total = counts[0] + counts[1] + counts[2] + counts[3];
|
||||
for (s = 0; s < 4; ++s) {
|
||||
fprintf(stderr, "| %2d%%", (int)(100. * counts[s] / total + .5));
|
||||
fprintf(stderr, "| %2d%%", 100 * counts[s] / total);
|
||||
}
|
||||
fprintf(stderr, "| %7d\n", total);
|
||||
}
|
||||
@ -187,8 +186,7 @@ static void PrintExtraInfoLossless(const WebPPicture* const pic,
|
||||
} else {
|
||||
fprintf(stderr, "File: %s\n", file_name);
|
||||
fprintf(stderr, "Dimension: %d x %d\n", pic->width, pic->height);
|
||||
fprintf(stderr, "Output: %d bytes (%.2f bpp)\n", stats->coded_size,
|
||||
8.f * stats->coded_size / pic->width / pic->height);
|
||||
fprintf(stderr, "Output: %d bytes\n", stats->coded_size);
|
||||
PrintFullLosslessInfo(stats, "ARGB");
|
||||
}
|
||||
}
|
||||
@ -209,18 +207,15 @@ static void PrintExtraInfoLossy(const WebPPicture* const pic, int short_output,
|
||||
pic->width, pic->height,
|
||||
stats->alpha_data_size ? " (with alpha)" : "");
|
||||
fprintf(stderr, "Output: "
|
||||
"%d bytes Y-U-V-All-PSNR %2.2f %2.2f %2.2f %2.2f dB\n"
|
||||
" (%.2f bpp)\n",
|
||||
"%d bytes Y-U-V-All-PSNR %2.2f %2.2f %2.2f %2.2f dB\n",
|
||||
stats->coded_size,
|
||||
stats->PSNR[0], stats->PSNR[1], stats->PSNR[2], stats->PSNR[3],
|
||||
8.f * stats->coded_size / pic->width / pic->height);
|
||||
stats->PSNR[0], stats->PSNR[1], stats->PSNR[2], stats->PSNR[3]);
|
||||
if (total > 0) {
|
||||
int totals[4] = { 0, 0, 0, 0 };
|
||||
fprintf(stderr, "block count: intra4: %6d (%.2f%%)\n"
|
||||
" intra16: %6d (%.2f%%)\n"
|
||||
" skipped: %6d (%.2f%%)\n",
|
||||
num_i4, 100.f * num_i4 / total,
|
||||
num_i16, 100.f * num_i16 / total,
|
||||
fprintf(stderr, "block count: intra4: %d\n"
|
||||
" intra16: %d (-> %.2f%%)\n",
|
||||
num_i4, num_i16, 100.f * num_i16 / total);
|
||||
fprintf(stderr, " skipped block: %d (%.2f%%)\n",
|
||||
num_skip, 100.f * num_skip / total);
|
||||
fprintf(stderr, "bytes used: header: %6d (%.1f%%)\n"
|
||||
" mode-partition: %6d (%.1f%%)\n",
|
||||
@ -244,7 +239,7 @@ static void PrintExtraInfoLossy(const WebPPicture* const pic, int short_output,
|
||||
PrintByteCount(stats->residual_bytes[2], stats->coded_size, totals);
|
||||
}
|
||||
fprintf(stderr, " macroblocks: ");
|
||||
PrintPercents(stats->segment_size);
|
||||
PrintPercents(stats->segment_size, total);
|
||||
fprintf(stderr, " quantizer: ");
|
||||
PrintValues(stats->segment_quant);
|
||||
fprintf(stderr, " filter level: ");
|
||||
@ -468,9 +463,8 @@ static int WriteWebPWithMetadata(FILE* const out,
|
||||
} else {
|
||||
const int is_lossless = !memcmp(webp, "VP8L", kTagSize);
|
||||
if (is_lossless) {
|
||||
// Presence of alpha is stored in the 37th bit (29th after the
|
||||
// signature) of VP8L data.
|
||||
if (webp[kChunkHeaderSize + 4] & (1 << 4)) flags |= kAlphaFlag;
|
||||
// Presence of alpha is stored in the 29th bit of VP8L data.
|
||||
if (webp[kChunkHeaderSize + 3] & (1 << 5)) flags |= kAlphaFlag;
|
||||
}
|
||||
ok = ok && (fwrite(kVP8XHeader, kChunkHeaderSize, 1, out) == 1);
|
||||
ok = ok && WriteLE32(out, flags);
|
||||
@ -492,11 +486,11 @@ static int WriteWebPWithMetadata(FILE* const out,
|
||||
*metadata_written |= METADATA_XMP;
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
} else {
|
||||
// No metadata, just write the original image file.
|
||||
return (fwrite(webp, webp_size, 1, out) == 1);
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@ -585,6 +579,9 @@ static void HelpLong(void) {
|
||||
printf(" -near_lossless <int> ... use near-lossless image\n"
|
||||
" preprocessing (0..100=off), "
|
||||
"default=100\n");
|
||||
#ifdef WEBP_EXPERIMENTAL_FEATURES /* not documented yet */
|
||||
printf(" -delta_palette ......... use delta palettization\n");
|
||||
#endif // WEBP_EXPERIMENTAL_FEATURES
|
||||
printf(" -hint <string> ......... specify image characteristics hint,\n");
|
||||
printf(" one of: photo, picture or graph\n");
|
||||
|
||||
@ -753,6 +750,11 @@ int main(int argc, const char *argv[]) {
|
||||
} else if (!strcmp(argv[c], "-near_lossless") && c < argc - 1) {
|
||||
config.near_lossless = ExUtilGetInt(argv[++c], 0, &parse_error);
|
||||
config.lossless = 1; // use near-lossless only with lossless
|
||||
#ifdef WEBP_EXPERIMENTAL_FEATURES
|
||||
} else if (!strcmp(argv[c], "-delta_palette")) {
|
||||
config.use_delta_palette = 1;
|
||||
config.lossless = 1; // delta-palette is for lossless only
|
||||
#endif // WEBP_EXPERIMENTAL_FEATURES
|
||||
} else if (!strcmp(argv[c], "-hint") && c < argc - 1) {
|
||||
++c;
|
||||
if (!strcmp(argv[c], "photo")) {
|
||||
|
@ -12,14 +12,10 @@
|
||||
|
||||
#include "./example_util.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "webp/mux_types.h"
|
||||
#include "../imageio/imageio_util.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// String parsing
|
||||
|
||||
@ -60,68 +56,3 @@ float ExUtilGetFloat(const char* const v, int* const error) {
|
||||
}
|
||||
return f;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
static void ResetCommandLineArguments(int argc, const char* argv[],
|
||||
CommandLineArguments* const args) {
|
||||
assert(args != NULL);
|
||||
args->argc_ = argc;
|
||||
args->argv_ = argv;
|
||||
args->own_argv_ = 0;
|
||||
WebPDataInit(&args->argv_data_);
|
||||
}
|
||||
|
||||
void ExUtilDeleteCommandLineArguments(CommandLineArguments* const args) {
|
||||
if (args != NULL) {
|
||||
if (args->own_argv_) {
|
||||
free((void*)args->argv_);
|
||||
WebPDataClear(&args->argv_data_);
|
||||
}
|
||||
ResetCommandLineArguments(0, NULL, args);
|
||||
}
|
||||
}
|
||||
|
||||
#define MAX_ARGC 16384
|
||||
int ExUtilInitCommandLineArguments(int argc, const char* argv[],
|
||||
CommandLineArguments* const args) {
|
||||
if (args == NULL || argv == NULL) return 0;
|
||||
ResetCommandLineArguments(argc, argv, args);
|
||||
if (argc == 1 && argv[0][0] != '-') {
|
||||
char* cur;
|
||||
const char sep[] = " \t\r\n\f\v";
|
||||
if (!ExUtilReadFileToWebPData(argv[0], &args->argv_data_)) {
|
||||
return 0;
|
||||
}
|
||||
args->own_argv_ = 1;
|
||||
args->argv_ = (const char**)malloc(MAX_ARGC * sizeof(*args->argv_));
|
||||
if (args->argv_ == NULL) return 0;
|
||||
|
||||
argc = 0;
|
||||
for (cur = strtok((char*)args->argv_data_.bytes, sep);
|
||||
cur != NULL;
|
||||
cur = strtok(NULL, sep)) {
|
||||
if (argc == MAX_ARGC) {
|
||||
fprintf(stderr, "ERROR: Arguments limit %d reached\n", MAX_ARGC);
|
||||
return 0;
|
||||
}
|
||||
assert(strlen(cur) != 0);
|
||||
args->argv_[argc++] = cur;
|
||||
}
|
||||
args->argc_ = argc;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
int ExUtilReadFileToWebPData(const char* const filename,
|
||||
WebPData* const webp_data) {
|
||||
const uint8_t* data;
|
||||
size_t size;
|
||||
if (webp_data == NULL) return 0;
|
||||
if (!ImgIoUtilReadFile(filename, &data, &size)) return 0;
|
||||
webp_data->bytes = data;
|
||||
webp_data->size = size;
|
||||
return 1;
|
||||
}
|
||||
|
@ -14,7 +14,6 @@
|
||||
#define WEBP_EXAMPLES_EXAMPLE_UTIL_H_
|
||||
|
||||
#include "webp/types.h"
|
||||
#include "webp/mux_types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -36,33 +35,6 @@ float ExUtilGetFloat(const char* const v, int* const error);
|
||||
// actually parsed is returned, or -1 if an error occurred.
|
||||
int ExUtilGetInts(const char* v, int base, int max_output, int output[]);
|
||||
|
||||
// Reads a file named 'filename' into a WebPData structure. The content of
|
||||
// webp_data is overwritten. Returns false in case of error.
|
||||
int ExUtilReadFileToWebPData(const char* const filename,
|
||||
WebPData* const webp_data);
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Command-line arguments
|
||||
|
||||
typedef struct {
|
||||
int argc_;
|
||||
const char** argv_;
|
||||
WebPData argv_data_;
|
||||
int own_argv_;
|
||||
} CommandLineArguments;
|
||||
|
||||
// Initializes the structure from the command-line parameters. If there is
|
||||
// only one parameter and it does not start with a '-', then it is assumed to
|
||||
// be a file name. This file will be read and tokenized into command-line
|
||||
// arguments. The content of 'args' is overwritten.
|
||||
// Returns false in case of error (memory allocation failure, non
|
||||
// existing file, too many arguments, ...).
|
||||
int ExUtilInitCommandLineArguments(int argc, const char* argv[],
|
||||
CommandLineArguments* const args);
|
||||
|
||||
// Deallocate all memory and reset 'args'.
|
||||
void ExUtilDeleteCommandLineArguments(CommandLineArguments* const args);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
@ -23,10 +23,6 @@
|
||||
|
||||
#ifdef WEBP_HAVE_GIF
|
||||
|
||||
#if defined(HAVE_UNISTD_H) && HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <gif_lib.h>
|
||||
#include "webp/encode.h"
|
||||
#include "webp/mux.h"
|
||||
@ -34,10 +30,6 @@
|
||||
#include "../imageio/imageio_util.h"
|
||||
#include "./gifdec.h"
|
||||
|
||||
#if !defined(STDIN_FILENO)
|
||||
#define STDIN_FILENO 0
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
static int transparent_index = GIF_INDEX_INVALID; // Opaque by default.
|
||||
@ -80,10 +72,8 @@ static void Help(void) {
|
||||
printf(" -metadata <string> ..... comma separated list of metadata to\n");
|
||||
printf(" ");
|
||||
printf("copy from the input to the output if present\n");
|
||||
printf(" ");
|
||||
printf("Valid values: all, none, icc, xmp (default)\n");
|
||||
printf(" -loop_compatibility .... use compatibility mode for Chrome\n");
|
||||
printf(" version prior to M62 (inclusive)\n");
|
||||
printf(" "
|
||||
"Valid values: all, none, icc, xmp (default)\n");
|
||||
printf(" -mt .................... use multi-threading if available\n");
|
||||
printf("\n");
|
||||
printf(" -version ............... print version number and exit\n");
|
||||
@ -114,7 +104,7 @@ int main(int argc, const char *argv[]) {
|
||||
WebPAnimEncoderOptions enc_options;
|
||||
WebPConfig config;
|
||||
|
||||
int frame_number = 0; // Whether we are processing the first frame.
|
||||
int is_first_frame = 1; // Whether we are processing the first frame.
|
||||
int done;
|
||||
int c;
|
||||
int quiet = 0;
|
||||
@ -125,9 +115,8 @@ int main(int argc, const char *argv[]) {
|
||||
int stored_icc = 0; // Whether we have already stored an ICC profile.
|
||||
WebPData xmp_data;
|
||||
int stored_xmp = 0; // Whether we have already stored an XMP profile.
|
||||
int loop_count = 0; // default: infinite
|
||||
int loop_count = 0;
|
||||
int stored_loop_count = 0; // Whether we have found an explicit loop count.
|
||||
int loop_compatibility = 0;
|
||||
WebPMux* mux = NULL;
|
||||
|
||||
int default_kmin = 1; // Whether to use default kmin value.
|
||||
@ -162,8 +151,6 @@ int main(int argc, const char *argv[]) {
|
||||
} else if (!strcmp(argv[c], "-mixed")) {
|
||||
enc_options.allow_mixed = 1;
|
||||
config.lossless = 0;
|
||||
} else if (!strcmp(argv[c], "-loop_compatibility")) {
|
||||
loop_compatibility = 1;
|
||||
} else if (!strcmp(argv[c], "-q") && c < argc - 1) {
|
||||
config.quality = ExUtilGetFloat(argv[++c], &parse_error);
|
||||
} else if (!strcmp(argv[c], "-m") && c < argc - 1) {
|
||||
@ -271,11 +258,9 @@ int main(int argc, const char *argv[]) {
|
||||
|
||||
// Start the decoder object
|
||||
#if LOCAL_GIF_PREREQ(5,0)
|
||||
gif = !strcmp(in_file, "-") ? DGifOpenFileHandle(STDIN_FILENO, &gif_error)
|
||||
: DGifOpenFileName(in_file, &gif_error);
|
||||
gif = DGifOpenFileName(in_file, &gif_error);
|
||||
#else
|
||||
gif = !strcmp(in_file, "-") ? DGifOpenFileHandle(STDIN_FILENO)
|
||||
: DGifOpenFileName(in_file);
|
||||
gif = DGifOpenFileName(in_file);
|
||||
#endif
|
||||
if (gif == NULL) goto End;
|
||||
|
||||
@ -292,7 +277,7 @@ int main(int argc, const char *argv[]) {
|
||||
|
||||
if (!DGifGetImageDesc(gif)) goto End;
|
||||
|
||||
if (frame_number == 0) {
|
||||
if (is_first_frame) {
|
||||
if (verbose) {
|
||||
printf("Canvas screen: %d x %d\n", gif->SWidth, gif->SHeight);
|
||||
}
|
||||
@ -334,6 +319,7 @@ int main(int argc, const char *argv[]) {
|
||||
"a memory error.\n");
|
||||
goto End;
|
||||
}
|
||||
is_first_frame = 0;
|
||||
}
|
||||
|
||||
// Some even more broken GIF can have sub-rect with zero width/height.
|
||||
@ -350,25 +336,13 @@ int main(int argc, const char *argv[]) {
|
||||
GIFBlendFrames(&frame, &gif_rect, &curr_canvas);
|
||||
|
||||
if (!WebPAnimEncoderAdd(enc, &curr_canvas, frame_timestamp, &config)) {
|
||||
fprintf(stderr, "Error while adding frame #%d: %s\n", frame_number,
|
||||
WebPAnimEncoderGetError(enc));
|
||||
goto End;
|
||||
} else {
|
||||
++frame_number;
|
||||
fprintf(stderr, "%s\n", WebPAnimEncoderGetError(enc));
|
||||
}
|
||||
|
||||
// Update canvases.
|
||||
GIFDisposeFrame(orig_dispose, &gif_rect, &prev_canvas, &curr_canvas);
|
||||
GIFCopyPixels(&curr_canvas, &prev_canvas);
|
||||
|
||||
// Force frames with a small or no duration to 100ms to be consistent
|
||||
// with web browsers and other transcoding tools. This also avoids
|
||||
// incorrect durations between frames when padding frames are
|
||||
// discarded.
|
||||
if (frame_duration <= 10) {
|
||||
frame_duration = 100;
|
||||
}
|
||||
|
||||
// Update timestamp (for next frame).
|
||||
frame_timestamp += frame_duration;
|
||||
|
||||
@ -412,7 +386,7 @@ int main(int argc, const char *argv[]) {
|
||||
if (verbose) {
|
||||
fprintf(stderr, "Loop count: %d\n", loop_count);
|
||||
}
|
||||
stored_loop_count = loop_compatibility ? (loop_count != 0) : 1;
|
||||
stored_loop_count = (loop_count != 0);
|
||||
} else { // An extension containing metadata.
|
||||
// We only store the first encountered chunk of each type, and
|
||||
// only if requested by the user.
|
||||
@ -469,23 +443,6 @@ int main(int argc, const char *argv[]) {
|
||||
goto End;
|
||||
}
|
||||
|
||||
if (!loop_compatibility) {
|
||||
if (!stored_loop_count) {
|
||||
// if no loop-count element is seen, the default is '1' (loop-once)
|
||||
// and we need to signal it explicitly in WebP. Note however that
|
||||
// in case there's a single frame, we still don't need to store it.
|
||||
if (frame_number > 1) {
|
||||
stored_loop_count = 1;
|
||||
loop_count = 1;
|
||||
}
|
||||
} else if (loop_count > 0) {
|
||||
// adapt GIF's semantic to WebP's (except in the infinite-loop case)
|
||||
loop_count += 1;
|
||||
}
|
||||
}
|
||||
// loop_count of 0 is the default (infinite), so no need to signal it
|
||||
if (loop_count == 0) stored_loop_count = 0;
|
||||
|
||||
if (stored_loop_count || stored_icc || stored_xmp) {
|
||||
// Re-mux to add loop count and/or metadata as needed.
|
||||
mux = WebPMuxCreate(&webp_data, 1);
|
||||
@ -550,14 +507,9 @@ int main(int argc, const char *argv[]) {
|
||||
goto End;
|
||||
}
|
||||
if (!quiet) {
|
||||
if (!strcmp(out_file, "-")) {
|
||||
fprintf(stderr, "Saved %d bytes to STDIO\n",
|
||||
(int)webp_data.size);
|
||||
} else {
|
||||
fprintf(stderr, "Saved output file (%d bytes): %s\n",
|
||||
(int)webp_data.size, out_file);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!quiet) {
|
||||
fprintf(stderr, "Nothing written; use -o flag to save the result "
|
||||
|
@ -48,7 +48,6 @@ static void Help(void) {
|
||||
printf(" -mixed ............... use mixed lossy/lossless automatic mode\n");
|
||||
printf(" -v ................... verbose mode\n");
|
||||
printf(" -h ................... this help\n");
|
||||
printf(" -version ............. print version number and exit\n");
|
||||
printf("\n");
|
||||
|
||||
printf("Per-frame options (only used for subsequent images input):\n");
|
||||
@ -118,13 +117,14 @@ static int SetLoopCount(int loop_count, WebPData* const webp_data) {
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
int main(int argc, const char* argv[]) {
|
||||
int main(int argc, char* argv[]) {
|
||||
const char* output = NULL;
|
||||
WebPAnimEncoder* enc = NULL;
|
||||
int verbose = 0;
|
||||
int pic_num = 0;
|
||||
int duration = 100;
|
||||
int timestamp_ms = 0;
|
||||
int ok = 1;
|
||||
int loop_count = 0;
|
||||
int width = 0, height = 0;
|
||||
WebPAnimEncoderOptions anim_config;
|
||||
@ -133,23 +133,17 @@ int main(int argc, const char* argv[]) {
|
||||
WebPData webp_data;
|
||||
int c;
|
||||
int have_input = 0;
|
||||
CommandLineArguments cmd_args;
|
||||
int ok = ExUtilInitCommandLineArguments(argc - 1, argv + 1, &cmd_args);
|
||||
if (!ok) return 1;
|
||||
argc = cmd_args.argc_;
|
||||
argv = cmd_args.argv_;
|
||||
|
||||
WebPDataInit(&webp_data);
|
||||
if (!WebPAnimEncoderOptionsInit(&anim_config) ||
|
||||
!WebPConfigInit(&config) ||
|
||||
!WebPPictureInit(&pic)) {
|
||||
fprintf(stderr, "Library version mismatch!\n");
|
||||
ok = 0;
|
||||
goto End;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// 1st pass of option parsing
|
||||
for (c = 0; ok && c < argc; ++c) {
|
||||
for (c = 1; ok && c < argc; ++c) {
|
||||
if (argv[c][0] == '-') {
|
||||
int parse_error = 0;
|
||||
if (!strcmp(argv[c], "-o") && c + 1 < argc) {
|
||||
@ -177,15 +171,7 @@ int main(int argc, const char* argv[]) {
|
||||
verbose = 1;
|
||||
} else if (!strcmp(argv[c], "-h") || !strcmp(argv[c], "-help")) {
|
||||
Help();
|
||||
goto End;
|
||||
} else if (!strcmp(argv[c], "-version")) {
|
||||
const int enc_version = WebPGetEncoderVersion();
|
||||
const int mux_version = WebPGetMuxVersion();
|
||||
printf("WebP Encoder version: %d.%d.%d\nWebP Mux version: %d.%d.%d\n",
|
||||
(enc_version >> 16) & 0xff, (enc_version >> 8) & 0xff,
|
||||
enc_version & 0xff, (mux_version >> 16) & 0xff,
|
||||
(mux_version >> 8) & 0xff, mux_version & 0xff);
|
||||
goto End;
|
||||
return 0;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
@ -198,13 +184,13 @@ int main(int argc, const char* argv[]) {
|
||||
}
|
||||
if (!have_input) {
|
||||
fprintf(stderr, "No input file(s) for generating animation!\n");
|
||||
goto End;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// image-reading pass
|
||||
pic_num = 0;
|
||||
config.lossless = 1;
|
||||
for (c = 0; ok && c < argc; ++c) {
|
||||
for (c = 1; ok && c < argc; ++c) {
|
||||
if (argv[c] == NULL) continue;
|
||||
if (argv[c][0] == '-') { // parse local options
|
||||
int parse_error = 0;
|
||||
@ -308,7 +294,7 @@ int main(int argc, const char* argv[]) {
|
||||
fprintf(stderr, "[%d frames, %u bytes].\n",
|
||||
pic_num, (unsigned int)webp_data.size);
|
||||
}
|
||||
|
||||
WebPDataClear(&webp_data);
|
||||
ExUtilDeleteCommandLineArguments(&cmd_args);
|
||||
return ok ? 0 : 1;
|
||||
}
|
||||
|
@ -205,11 +205,6 @@ static void decode_callback(int what) {
|
||||
}
|
||||
}
|
||||
duration = curr->duration;
|
||||
// Behavior copied from Chrome, cf:
|
||||
// https://cs.chromium.org/chromium/src/third_party/WebKit/Source/
|
||||
// platform/graphics/DeferredImageDecoder.cpp?
|
||||
// rcl=b4c33049f096cd283f32be9a58b9a9e768227c26&l=246
|
||||
if (duration <= 10) duration = 100;
|
||||
}
|
||||
if (!Decode()) {
|
||||
kParams.decoding_error = 1;
|
||||
@ -253,9 +248,9 @@ static void HandleKey(unsigned char key, int pos_x, int pos_y) {
|
||||
}
|
||||
}
|
||||
} else if (key == 'i') {
|
||||
// Note: doesn't handle refresh of animation's last-frame (it's quite
|
||||
// more involved to do, since you need to save the previous frame).
|
||||
kParams.print_info = 1 - kParams.print_info;
|
||||
// TODO(skal): handle refresh of animation's last-frame too. It's quite
|
||||
// more involved though (need to save the previous frame).
|
||||
if (!kParams.has_animation) ClearPreviousFrame();
|
||||
glutPostRedisplay();
|
||||
} else if (key == 'd') {
|
||||
@ -265,8 +260,8 @@ static void HandleKey(unsigned char key, int pos_x, int pos_y) {
|
||||
}
|
||||
|
||||
static void HandleReshape(int width, int height) {
|
||||
// Note: reshape doesn't preserve aspect ratio, and might
|
||||
// be handling larger-than-screen pictures incorrectly.
|
||||
// TODO(skal): should we preserve aspect ratio?
|
||||
// Also: handle larger-than-screen pictures correctly.
|
||||
glViewport(0, 0, width, height);
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
@ -383,23 +378,13 @@ static void HandleDisplay(void) {
|
||||
}
|
||||
}
|
||||
glPopMatrix();
|
||||
#if defined(__APPLE__) || defined(_WIN32)
|
||||
glFlush();
|
||||
#else
|
||||
glutSwapBuffers();
|
||||
#endif
|
||||
}
|
||||
|
||||
static void StartDisplay(void) {
|
||||
const int width = kParams.canvas_width;
|
||||
const int height = kParams.canvas_height;
|
||||
// TODO(webp:365) GLUT_DOUBLE results in flickering / old frames to be
|
||||
// partially displayed with animated webp + alpha.
|
||||
#if defined(__APPLE__) || defined(_WIN32)
|
||||
glutInitDisplayMode(GLUT_RGBA);
|
||||
#else
|
||||
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);
|
||||
#endif
|
||||
glutInitWindowSize(width, height);
|
||||
glutCreateWindow("WebP viewer");
|
||||
glutDisplayFunc(HandleDisplay);
|
||||
|
@ -235,7 +235,7 @@ static int GetSignedBits(const uint8_t* const data, size_t data_size, size_t nb,
|
||||
|
||||
#define GET_BITS(v, n) \
|
||||
do { \
|
||||
if (!GetBits(data, data_size, n, &(v), bit_pos)) { \
|
||||
if (!GetBits(data, data_size, n, &v, bit_pos)) { \
|
||||
LOG_ERROR("Truncated lossy bitstream."); \
|
||||
return WEBP_INFO_TRUNCATED_DATA; \
|
||||
} \
|
||||
@ -243,7 +243,7 @@ static int GetSignedBits(const uint8_t* const data, size_t data_size, size_t nb,
|
||||
|
||||
#define GET_SIGNED_BITS(v, n) \
|
||||
do { \
|
||||
if (!GetSignedBits(data, data_size, n, &(v), bit_pos)) { \
|
||||
if (!GetSignedBits(data, data_size, n, &v, bit_pos)) { \
|
||||
LOG_ERROR("Truncated lossy bitstream."); \
|
||||
return WEBP_INFO_TRUNCATED_DATA; \
|
||||
} \
|
||||
@ -340,7 +340,7 @@ static WebPInfoStatus ParseLossyHeader(const ChunkData* const chunk_data,
|
||||
WebPInfoStatus status = WEBP_INFO_OK;
|
||||
uint64_t bit_position = 0;
|
||||
uint64_t* const bit_pos = &bit_position;
|
||||
int colorspace, clamp_type;
|
||||
int color_space, clamp_type;
|
||||
printf(" Parsing lossy bitstream...\n");
|
||||
// Calling WebPGetFeatures() in ProcessImageChunk() should ensure this.
|
||||
assert(chunk_data->size_ >= CHUNK_HEADER_SIZE + 10);
|
||||
@ -381,9 +381,9 @@ static WebPInfoStatus ParseLossyHeader(const ChunkData* const chunk_data,
|
||||
LOG_ERROR("Bad partition length.");
|
||||
return WEBP_INFO_BITSTREAM_ERROR;
|
||||
}
|
||||
GET_BITS(colorspace, 1);
|
||||
GET_BITS(color_space, 1);
|
||||
GET_BITS(clamp_type, 1);
|
||||
printf(" Color space: %d\n", colorspace);
|
||||
printf(" Color space: %d\n", color_space);
|
||||
printf(" Clamp type: %d\n", clamp_type);
|
||||
status = ParseLossySegmentHeader(webp_info, data, data_size, bit_pos);
|
||||
if (status != WEBP_INFO_OK) return status;
|
||||
@ -464,7 +464,7 @@ static int LLGetBits(const uint8_t* const data, size_t data_size, size_t nb,
|
||||
|
||||
#define LL_GET_BITS(v, n) \
|
||||
do { \
|
||||
if (!LLGetBits(data, data_size, n, &(v), bit_pos)) { \
|
||||
if (!LLGetBits(data, data_size, n, &v, bit_pos)) { \
|
||||
LOG_ERROR("Truncated lossless bitstream."); \
|
||||
return WEBP_INFO_TRUNCATED_DATA; \
|
||||
} \
|
||||
@ -817,8 +817,9 @@ static WebPInfoStatus ProcessImageChunk(const ChunkData* const chunk_data,
|
||||
if (webp_info->seen_image_subchunk_) {
|
||||
LOG_ERROR("Consecutive VP8/VP8L sub-chunks in an ANMF chunk.");
|
||||
return WEBP_INFO_PARSE_ERROR;
|
||||
}
|
||||
} else {
|
||||
webp_info->seen_image_subchunk_ = 1;
|
||||
}
|
||||
} else {
|
||||
if (webp_info->chunk_counts_[CHUNK_VP8] ||
|
||||
webp_info->chunk_counts_[CHUNK_VP8L]) {
|
||||
@ -872,9 +873,9 @@ static WebPInfoStatus ProcessALPHChunk(const ChunkData* const chunk_data,
|
||||
if (webp_info->seen_alpha_subchunk_) {
|
||||
LOG_ERROR("Consecutive ALPH sub-chunks in an ANMF chunk.");
|
||||
return WEBP_INFO_PARSE_ERROR;
|
||||
}
|
||||
} else {
|
||||
webp_info->seen_alpha_subchunk_ = 1;
|
||||
|
||||
}
|
||||
if (webp_info->seen_image_subchunk_) {
|
||||
LOG_ERROR("ALPHA sub-chunk detected after VP8 sub-chunk "
|
||||
"in an ANMF chunk.");
|
||||
@ -1106,7 +1107,6 @@ static void HelpLong(void) {
|
||||
"Note: there could be multiple input files;\n"
|
||||
" options must come before input files.\n"
|
||||
"Options:\n"
|
||||
" -version ........... Print version number and exit.\n"
|
||||
" -quiet ............. Do not show chunk parsing information.\n"
|
||||
" -diag .............. Show parsing error diagnosis.\n"
|
||||
" -summary ........... Show chunk stats summary.\n"
|
||||
@ -1140,11 +1140,6 @@ int main(int argc, const char* argv[]) {
|
||||
show_summary = 1;
|
||||
} else if (!strcmp(argv[c], "-bitstream_info")) {
|
||||
parse_bitstream = 1;
|
||||
} else if (!strcmp(argv[c], "-version")) {
|
||||
const int version = WebPGetDecoderVersion();
|
||||
printf("WebP Decoder version: %d.%d.%d\n",
|
||||
(version >> 16) & 0xff, (version >> 8) & 0xff, version & 0xff);
|
||||
return 0;
|
||||
} else { // Assume the remaining are all input files.
|
||||
break;
|
||||
}
|
||||
|
@ -47,7 +47,6 @@
|
||||
webpmux -info in.webp
|
||||
webpmux [ -h | -help ]
|
||||
webpmux -version
|
||||
webpmux argument_file_name
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
@ -109,26 +108,28 @@ static const char* const kDescriptions[LAST_FEATURE] = {
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
CommandLineArguments cmd_args_;
|
||||
|
||||
ActionType action_type_;
|
||||
const char* input_;
|
||||
const char* output_;
|
||||
FeatureType type_;
|
||||
FeatureArg* args_;
|
||||
int arg_count_;
|
||||
} Config;
|
||||
} Feature;
|
||||
|
||||
typedef struct {
|
||||
ActionType action_type_;
|
||||
const char* input_;
|
||||
const char* output_;
|
||||
Feature feature_;
|
||||
} WebPMuxConfig;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Helper functions.
|
||||
|
||||
static int CountOccurrences(const CommandLineArguments* const args,
|
||||
const char* const arg) {
|
||||
static int CountOccurrences(const char* arglist[], int list_length,
|
||||
const char* arg) {
|
||||
int i;
|
||||
int num_occurences = 0;
|
||||
|
||||
for (i = 0; i < args->argc_; ++i) {
|
||||
if (!strcmp(args->argv_[i], arg)) {
|
||||
for (i = 0; i < list_length; ++i) {
|
||||
if (!strcmp(arglist[i], arg)) {
|
||||
++num_occurences;
|
||||
}
|
||||
}
|
||||
@ -300,7 +301,6 @@ static void PrintHelp(void) {
|
||||
printf(" webpmux -info INPUT\n");
|
||||
printf(" webpmux [-h|-help]\n");
|
||||
printf(" webpmux -version\n");
|
||||
printf(" webpmux argument_file_name\n");
|
||||
|
||||
printf("\n");
|
||||
printf("GET_OPTIONS:\n");
|
||||
@ -369,10 +369,6 @@ static void PrintHelp(void) {
|
||||
|
||||
printf("\nNote: The nature of EXIF, XMP and ICC data is not checked");
|
||||
printf(" and is assumed to be\nvalid.\n");
|
||||
printf("\nNote: if a single file name is passed as the argument, the "
|
||||
"arguments will be\n");
|
||||
printf("tokenized from this file. The file name must not start with "
|
||||
"the character '-'.\n");
|
||||
}
|
||||
|
||||
static void WarnAboutOddOffset(const WebPMuxFrameInfo* const info) {
|
||||
@ -383,12 +379,22 @@ static void WarnAboutOddOffset(const WebPMuxFrameInfo* const info) {
|
||||
}
|
||||
}
|
||||
|
||||
static int ReadFileToWebPData(const char* const filename,
|
||||
WebPData* const webp_data) {
|
||||
const uint8_t* data;
|
||||
size_t size;
|
||||
if (!ImgIoUtilReadFile(filename, &data, &size)) return 0;
|
||||
webp_data->bytes = data;
|
||||
webp_data->size = size;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int CreateMux(const char* const filename, WebPMux** mux) {
|
||||
WebPData bitstream;
|
||||
assert(mux != NULL);
|
||||
if (!ExUtilReadFileToWebPData(filename, &bitstream)) return 0;
|
||||
if (!ReadFileToWebPData(filename, &bitstream)) return 0;
|
||||
*mux = WebPMuxCreate(&bitstream, 1);
|
||||
WebPDataClear(&bitstream);
|
||||
free((void*)bitstream.bytes);
|
||||
if (*mux != NULL) return 1;
|
||||
fprintf(stderr, "Failed to create mux object from file %s.\n", filename);
|
||||
return 0;
|
||||
@ -511,10 +517,9 @@ static int ParseBgcolorArgs(const char* args, uint32_t* const bgcolor) {
|
||||
//------------------------------------------------------------------------------
|
||||
// Clean-up.
|
||||
|
||||
static void DeleteConfig(Config* const config) {
|
||||
static void DeleteConfig(WebPMuxConfig* config) {
|
||||
if (config != NULL) {
|
||||
free(config->args_);
|
||||
ExUtilDeleteCommandLineArguments(&config->cmd_args_);
|
||||
free(config->feature_.args_);
|
||||
memset(config, 0, sizeof(*config));
|
||||
}
|
||||
}
|
||||
@ -526,7 +531,7 @@ static void DeleteConfig(Config* const config) {
|
||||
// Returns 1 on valid, 0 otherwise.
|
||||
// Also fills up num_feature_args to be number of feature arguments given.
|
||||
// (e.g. if there are 4 '-frame's and 1 '-loop', then num_feature_args = 5).
|
||||
static int ValidateCommandLine(const CommandLineArguments* const cmd_args,
|
||||
static int ValidateCommandLine(int argc, const char* argv[],
|
||||
int* num_feature_args) {
|
||||
int num_frame_args;
|
||||
int num_loop_args;
|
||||
@ -538,27 +543,27 @@ static int ValidateCommandLine(const CommandLineArguments* const cmd_args,
|
||||
*num_feature_args = 0;
|
||||
|
||||
// Simple checks.
|
||||
if (CountOccurrences(cmd_args, "-get") > 1) {
|
||||
if (CountOccurrences(argv, argc, "-get") > 1) {
|
||||
ERROR_GOTO1("ERROR: Multiple '-get' arguments specified.\n", ErrValidate);
|
||||
}
|
||||
if (CountOccurrences(cmd_args, "-set") > 1) {
|
||||
if (CountOccurrences(argv, argc, "-set") > 1) {
|
||||
ERROR_GOTO1("ERROR: Multiple '-set' arguments specified.\n", ErrValidate);
|
||||
}
|
||||
if (CountOccurrences(cmd_args, "-strip") > 1) {
|
||||
if (CountOccurrences(argv, argc, "-strip") > 1) {
|
||||
ERROR_GOTO1("ERROR: Multiple '-strip' arguments specified.\n", ErrValidate);
|
||||
}
|
||||
if (CountOccurrences(cmd_args, "-info") > 1) {
|
||||
if (CountOccurrences(argv, argc, "-info") > 1) {
|
||||
ERROR_GOTO1("ERROR: Multiple '-info' arguments specified.\n", ErrValidate);
|
||||
}
|
||||
if (CountOccurrences(cmd_args, "-o") > 1) {
|
||||
if (CountOccurrences(argv, argc, "-o") > 1) {
|
||||
ERROR_GOTO1("ERROR: Multiple output files specified.\n", ErrValidate);
|
||||
}
|
||||
|
||||
// Compound checks.
|
||||
num_frame_args = CountOccurrences(cmd_args, "-frame");
|
||||
num_loop_args = CountOccurrences(cmd_args, "-loop");
|
||||
num_bgcolor_args = CountOccurrences(cmd_args, "-bgcolor");
|
||||
num_durations_args = CountOccurrences(cmd_args, "-duration");
|
||||
num_frame_args = CountOccurrences(argv, argc, "-frame");
|
||||
num_loop_args = CountOccurrences(argv, argc, "-loop");
|
||||
num_bgcolor_args = CountOccurrences(argv, argc, "-bgcolor");
|
||||
num_durations_args = CountOccurrences(argv, argc, "-duration");
|
||||
|
||||
if (num_loop_args > 1) {
|
||||
ERROR_GOTO1("ERROR: Multiple loop counts specified.\n", ErrValidate);
|
||||
@ -593,7 +598,7 @@ static int ValidateCommandLine(const CommandLineArguments* const cmd_args,
|
||||
|
||||
#define ACTION_IS_NIL (config->action_type_ == NIL_ACTION)
|
||||
|
||||
#define FEATURETYPE_IS_NIL (config->type_ == NIL_FEATURE)
|
||||
#define FEATURETYPE_IS_NIL (feature->type_ == NIL_FEATURE)
|
||||
|
||||
#define CHECK_NUM_ARGS_LESS(NUM, LABEL) \
|
||||
if (argc < i + (NUM)) { \
|
||||
@ -609,15 +614,15 @@ static int ValidateCommandLine(const CommandLineArguments* const cmd_args,
|
||||
|
||||
// Parses command-line arguments to fill up config object. Also performs some
|
||||
// semantic checks.
|
||||
static int ParseCommandLine(Config* config) {
|
||||
static int ParseCommandLine(int argc, const char* argv[],
|
||||
WebPMuxConfig* config) {
|
||||
int i = 0;
|
||||
int feature_arg_index = 0;
|
||||
int ok = 1;
|
||||
int argc = config->cmd_args_.argc_;
|
||||
const char* const* argv = config->cmd_args_.argv_;
|
||||
|
||||
while (i < argc) {
|
||||
FeatureArg* const arg = &config->args_[feature_arg_index];
|
||||
Feature* const feature = &config->feature_;
|
||||
FeatureArg* const arg = &feature->args_[feature_arg_index];
|
||||
if (argv[i][0] == '-') { // One of the action types or output.
|
||||
if (!strcmp(argv[i], "-set")) {
|
||||
if (ACTION_IS_NIL) {
|
||||
@ -633,8 +638,8 @@ static int ParseCommandLine(Config* config) {
|
||||
} else {
|
||||
ERROR_GOTO1("ERROR: Multiple actions specified.\n", ErrParse);
|
||||
}
|
||||
if (FEATURETYPE_IS_NIL || config->type_ == FEATURE_DURATION) {
|
||||
config->type_ = FEATURE_DURATION;
|
||||
if (FEATURETYPE_IS_NIL || feature->type_ == FEATURE_DURATION) {
|
||||
feature->type_ = FEATURE_DURATION;
|
||||
} else {
|
||||
ERROR_GOTO1("ERROR: Multiple features specified.\n", ErrParse);
|
||||
}
|
||||
@ -651,7 +656,7 @@ static int ParseCommandLine(Config* config) {
|
||||
} else if (!strcmp(argv[i], "-strip")) {
|
||||
if (ACTION_IS_NIL) {
|
||||
config->action_type_ = ACTION_STRIP;
|
||||
config->arg_count_ = 0;
|
||||
feature->arg_count_ = 0;
|
||||
} else {
|
||||
ERROR_GOTO1("ERROR: Multiple actions specified.\n", ErrParse);
|
||||
}
|
||||
@ -663,8 +668,8 @@ static int ParseCommandLine(Config* config) {
|
||||
} else {
|
||||
ERROR_GOTO1("ERROR: Multiple actions specified.\n", ErrParse);
|
||||
}
|
||||
if (FEATURETYPE_IS_NIL || config->type_ == FEATURE_ANMF) {
|
||||
config->type_ = FEATURE_ANMF;
|
||||
if (FEATURETYPE_IS_NIL || feature->type_ == FEATURE_ANMF) {
|
||||
feature->type_ = FEATURE_ANMF;
|
||||
} else {
|
||||
ERROR_GOTO1("ERROR: Multiple features specified.\n", ErrParse);
|
||||
}
|
||||
@ -680,8 +685,8 @@ static int ParseCommandLine(Config* config) {
|
||||
} else {
|
||||
ERROR_GOTO1("ERROR: Multiple actions specified.\n", ErrParse);
|
||||
}
|
||||
if (FEATURETYPE_IS_NIL || config->type_ == FEATURE_ANMF) {
|
||||
config->type_ = FEATURE_ANMF;
|
||||
if (FEATURETYPE_IS_NIL || feature->type_ == FEATURE_ANMF) {
|
||||
feature->type_ = FEATURE_ANMF;
|
||||
} else {
|
||||
ERROR_GOTO1("ERROR: Multiple features specified.\n", ErrParse);
|
||||
}
|
||||
@ -700,7 +705,7 @@ static int ParseCommandLine(Config* config) {
|
||||
ERROR_GOTO1("ERROR: Multiple actions specified.\n", ErrParse);
|
||||
} else {
|
||||
config->action_type_ = ACTION_INFO;
|
||||
config->arg_count_ = 0;
|
||||
feature->arg_count_ = 0;
|
||||
config->input_ = argv[i + 1];
|
||||
}
|
||||
i += 2;
|
||||
@ -736,7 +741,7 @@ static int ParseCommandLine(Config* config) {
|
||||
if (!strcmp(argv[i], "icc") || !strcmp(argv[i], "exif") ||
|
||||
!strcmp(argv[i], "xmp")) {
|
||||
if (FEATURETYPE_IS_NIL) {
|
||||
config->type_ = (!strcmp(argv[i], "icc")) ? FEATURE_ICCP :
|
||||
feature->type_ = (!strcmp(argv[i], "icc")) ? FEATURE_ICCP :
|
||||
(!strcmp(argv[i], "exif")) ? FEATURE_EXIF : FEATURE_XMP;
|
||||
} else {
|
||||
ERROR_GOTO1("ERROR: Multiple features specified.\n", ErrParse);
|
||||
@ -752,7 +757,7 @@ static int ParseCommandLine(Config* config) {
|
||||
} else if (!strcmp(argv[i], "frame") &&
|
||||
(config->action_type_ == ACTION_GET)) {
|
||||
CHECK_NUM_ARGS_LESS(2, ErrParse);
|
||||
config->type_ = FEATURE_ANMF;
|
||||
feature->type_ = FEATURE_ANMF;
|
||||
arg->params_ = argv[i + 1];
|
||||
++feature_arg_index;
|
||||
i += 2;
|
||||
@ -772,8 +777,9 @@ static int ParseCommandLine(Config* config) {
|
||||
}
|
||||
|
||||
// Additional checks after config is filled.
|
||||
static int ValidateConfig(Config* const config) {
|
||||
static int ValidateConfig(WebPMuxConfig* config) {
|
||||
int ok = 1;
|
||||
Feature* const feature = &config->feature_;
|
||||
|
||||
// Action.
|
||||
if (ACTION_IS_NIL) {
|
||||
@ -789,7 +795,7 @@ static int ValidateConfig(Config* const config) {
|
||||
if (config->input_ == NULL) {
|
||||
if (config->action_type_ != ACTION_SET) {
|
||||
ERROR_GOTO1("ERROR: No input file specified.\n", ErrValidate2);
|
||||
} else if (config->type_ != FEATURE_ANMF) {
|
||||
} else if (feature->type_ != FEATURE_ANMF) {
|
||||
ERROR_GOTO1("ERROR: No input file specified.\n", ErrValidate2);
|
||||
}
|
||||
}
|
||||
@ -805,28 +811,27 @@ static int ValidateConfig(Config* const config) {
|
||||
|
||||
// Create config object from command-line arguments.
|
||||
static int InitializeConfig(int argc, const char* argv[],
|
||||
Config* const config) {
|
||||
WebPMuxConfig* config) {
|
||||
int num_feature_args = 0;
|
||||
int ok;
|
||||
int ok = 1;
|
||||
|
||||
assert(config != NULL);
|
||||
memset(config, 0, sizeof(*config));
|
||||
|
||||
ok = ExUtilInitCommandLineArguments(argc, argv, &config->cmd_args_);
|
||||
if (!ok) return 0;
|
||||
|
||||
// Validate command-line arguments.
|
||||
if (!ValidateCommandLine(&config->cmd_args_, &num_feature_args)) {
|
||||
if (!ValidateCommandLine(argc, argv, &num_feature_args)) {
|
||||
ERROR_GOTO1("Exiting due to command-line parsing error.\n", Err1);
|
||||
}
|
||||
|
||||
config->arg_count_ = num_feature_args;
|
||||
config->args_ = (FeatureArg*)calloc(num_feature_args, sizeof(*config->args_));
|
||||
if (config->args_ == NULL) {
|
||||
config->feature_.arg_count_ = num_feature_args;
|
||||
config->feature_.args_ =
|
||||
(FeatureArg*)calloc(num_feature_args, sizeof(*config->feature_.args_));
|
||||
if (config->feature_.args_ == NULL) {
|
||||
ERROR_GOTO1("ERROR: Memory allocation error.\n", Err1);
|
||||
}
|
||||
|
||||
// Parse command-line.
|
||||
if (!ParseCommandLine(config) || !ValidateConfig(config)) {
|
||||
if (!ParseCommandLine(argc, argv, config) || !ValidateConfig(config)) {
|
||||
ERROR_GOTO1("Exiting due to command-line parsing error.\n", Err1);
|
||||
}
|
||||
|
||||
@ -842,7 +847,7 @@ static int InitializeConfig(int argc, const char* argv[],
|
||||
//------------------------------------------------------------------------------
|
||||
// Processing.
|
||||
|
||||
static int GetFrame(const WebPMux* mux, const Config* config) {
|
||||
static int GetFrame(const WebPMux* mux, const WebPMuxConfig* config) {
|
||||
WebPMuxError err = WEBP_MUX_OK;
|
||||
WebPMux* mux_single = NULL;
|
||||
int num = 0;
|
||||
@ -852,7 +857,7 @@ static int GetFrame(const WebPMux* mux, const Config* config) {
|
||||
WebPMuxFrameInfo info;
|
||||
WebPDataInit(&info.bitstream);
|
||||
|
||||
num = ExUtilGetInt(config->args_[0].params_, 10, &parse_error);
|
||||
num = ExUtilGetInt(config->feature_.args_[0].params_, 10, &parse_error);
|
||||
if (num < 0) {
|
||||
ERROR_GOTO1("ERROR: Frame/Fragment index must be non-negative.\n", ErrGet);
|
||||
}
|
||||
@ -886,17 +891,18 @@ static int GetFrame(const WebPMux* mux, const Config* config) {
|
||||
}
|
||||
|
||||
// Read and process config.
|
||||
static int Process(const Config* config) {
|
||||
static int Process(const WebPMuxConfig* config) {
|
||||
WebPMux* mux = NULL;
|
||||
WebPData chunk;
|
||||
WebPMuxError err = WEBP_MUX_OK;
|
||||
int ok = 1;
|
||||
const Feature* const feature = &config->feature_;
|
||||
|
||||
switch (config->action_type_) {
|
||||
case ACTION_GET: {
|
||||
ok = CreateMux(config->input_, &mux);
|
||||
if (!ok) goto Err2;
|
||||
switch (config->type_) {
|
||||
switch (feature->type_) {
|
||||
case FEATURE_ANMF:
|
||||
ok = GetFrame(mux, config);
|
||||
break;
|
||||
@ -904,10 +910,10 @@ static int Process(const Config* config) {
|
||||
case FEATURE_ICCP:
|
||||
case FEATURE_EXIF:
|
||||
case FEATURE_XMP:
|
||||
err = WebPMuxGetChunk(mux, kFourccList[config->type_], &chunk);
|
||||
err = WebPMuxGetChunk(mux, kFourccList[feature->type_], &chunk);
|
||||
if (err != WEBP_MUX_OK) {
|
||||
ERROR_GOTO3("ERROR (%s): Could not get the %s.\n",
|
||||
ErrorString(err), kDescriptions[config->type_], Err2);
|
||||
ErrorString(err), kDescriptions[feature->type_], Err2);
|
||||
}
|
||||
ok = WriteData(config->output_, &chunk);
|
||||
break;
|
||||
@ -919,7 +925,7 @@ static int Process(const Config* config) {
|
||||
break;
|
||||
}
|
||||
case ACTION_SET: {
|
||||
switch (config->type_) {
|
||||
switch (feature->type_) {
|
||||
case FEATURE_ANMF: {
|
||||
int i;
|
||||
WebPMuxAnimParams params = { 0xFFFFFFFF, 0 };
|
||||
@ -928,11 +934,11 @@ static int Process(const Config* config) {
|
||||
ERROR_GOTO2("ERROR (%s): Could not allocate a mux object.\n",
|
||||
ErrorString(WEBP_MUX_MEMORY_ERROR), Err2);
|
||||
}
|
||||
for (i = 0; i < config->arg_count_; ++i) {
|
||||
switch (config->args_[i].subtype_) {
|
||||
for (i = 0; i < feature->arg_count_; ++i) {
|
||||
switch (feature->args_[i].subtype_) {
|
||||
case SUBTYPE_BGCOLOR: {
|
||||
uint32_t bgcolor;
|
||||
ok = ParseBgcolorArgs(config->args_[i].params_, &bgcolor);
|
||||
ok = ParseBgcolorArgs(feature->args_[i].params_, &bgcolor);
|
||||
if (!ok) {
|
||||
ERROR_GOTO1("ERROR: Could not parse the background color \n",
|
||||
Err2);
|
||||
@ -943,7 +949,7 @@ static int Process(const Config* config) {
|
||||
case SUBTYPE_LOOP: {
|
||||
int parse_error = 0;
|
||||
const int loop_count =
|
||||
ExUtilGetInt(config->args_[i].params_, 10, &parse_error);
|
||||
ExUtilGetInt(feature->args_[i].params_, 10, &parse_error);
|
||||
if (loop_count < 0 || loop_count > 65535) {
|
||||
// Note: This is only a 'necessary' condition for loop_count
|
||||
// to be valid. The 'sufficient' conditioned in checked in
|
||||
@ -959,10 +965,10 @@ static int Process(const Config* config) {
|
||||
case SUBTYPE_ANMF: {
|
||||
WebPMuxFrameInfo frame;
|
||||
frame.id = WEBP_CHUNK_ANMF;
|
||||
ok = ExUtilReadFileToWebPData(config->args_[i].filename_,
|
||||
ok = ReadFileToWebPData(feature->args_[i].filename_,
|
||||
&frame.bitstream);
|
||||
if (!ok) goto Err2;
|
||||
ok = ParseFrameArgs(config->args_[i].params_, &frame);
|
||||
ok = ParseFrameArgs(feature->args_[i].params_, &frame);
|
||||
if (!ok) {
|
||||
WebPDataClear(&frame.bitstream);
|
||||
ERROR_GOTO1("ERROR: Could not parse frame properties.\n",
|
||||
@ -995,13 +1001,13 @@ static int Process(const Config* config) {
|
||||
case FEATURE_XMP: {
|
||||
ok = CreateMux(config->input_, &mux);
|
||||
if (!ok) goto Err2;
|
||||
ok = ExUtilReadFileToWebPData(config->args_[0].filename_, &chunk);
|
||||
ok = ReadFileToWebPData(feature->args_[0].filename_, &chunk);
|
||||
if (!ok) goto Err2;
|
||||
err = WebPMuxSetChunk(mux, kFourccList[config->type_], &chunk, 1);
|
||||
err = WebPMuxSetChunk(mux, kFourccList[feature->type_], &chunk, 1);
|
||||
free((void*)chunk.bytes);
|
||||
if (err != WEBP_MUX_OK) {
|
||||
ERROR_GOTO3("ERROR (%s): Could not set the %s.\n",
|
||||
ErrorString(err), kDescriptions[config->type_], Err2);
|
||||
ErrorString(err), kDescriptions[feature->type_], Err2);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -1037,11 +1043,11 @@ static int Process(const Config* config) {
|
||||
for (i = 0; i < num_frames; ++i) durations[i] = -1;
|
||||
|
||||
// Parse intervals to process.
|
||||
for (i = 0; i < config->arg_count_; ++i) {
|
||||
for (i = 0; i < feature->arg_count_; ++i) {
|
||||
int k;
|
||||
int args[3];
|
||||
int duration, start, end;
|
||||
const int nb_args = ExUtilGetInts(config->args_[i].params_,
|
||||
const int nb_args = ExUtilGetInts(feature->args_[i].params_,
|
||||
10, 3, args);
|
||||
ok = (nb_args >= 1);
|
||||
if (!ok) goto Err3;
|
||||
@ -1099,12 +1105,12 @@ static int Process(const Config* config) {
|
||||
case ACTION_STRIP: {
|
||||
ok = CreateMux(config->input_, &mux);
|
||||
if (!ok) goto Err2;
|
||||
if (config->type_ == FEATURE_ICCP || config->type_ == FEATURE_EXIF ||
|
||||
config->type_ == FEATURE_XMP) {
|
||||
err = WebPMuxDeleteChunk(mux, kFourccList[config->type_]);
|
||||
if (feature->type_ == FEATURE_ICCP || feature->type_ == FEATURE_EXIF ||
|
||||
feature->type_ == FEATURE_XMP) {
|
||||
err = WebPMuxDeleteChunk(mux, kFourccList[feature->type_]);
|
||||
if (err != WEBP_MUX_OK) {
|
||||
ERROR_GOTO3("ERROR (%s): Could not strip the %s.\n",
|
||||
ErrorString(err), kDescriptions[config->type_], Err2);
|
||||
ErrorString(err), kDescriptions[feature->type_], Err2);
|
||||
}
|
||||
} else {
|
||||
ERROR_GOTO1("ERROR: Invalid feature for action 'strip'.\n", Err2);
|
||||
@ -1134,7 +1140,7 @@ static int Process(const Config* config) {
|
||||
// Main.
|
||||
|
||||
int main(int argc, const char* argv[]) {
|
||||
Config config;
|
||||
WebPMuxConfig config;
|
||||
int ok = InitializeConfig(argc - 1, argv + 1, &config);
|
||||
if (ok) {
|
||||
ok = Process(&config);
|
||||
|
@ -1,4 +1,3 @@
|
||||
AM_CPPFLAGS += -I$(top_builddir) -I$(top_srcdir)
|
||||
AM_CPPFLAGS += -I$(top_builddir)/src -I$(top_srcdir)/src
|
||||
noinst_LTLIBRARIES = libwebpextras.la
|
||||
|
||||
@ -13,32 +12,25 @@ libwebpextras_la_LDFLAGS = -lm
|
||||
libwebpextras_la_LIBADD = ../src/libwebp.la
|
||||
|
||||
noinst_PROGRAMS =
|
||||
noinst_PROGRAMS += webp_quality
|
||||
if WANT_DEMUX
|
||||
noinst_PROGRAMS += get_disto
|
||||
endif
|
||||
noinst_PROGRAMS += get_disto webp_quality
|
||||
if BUILD_VWEBP_SDL
|
||||
noinst_PROGRAMS += vwebp_sdl
|
||||
endif
|
||||
|
||||
get_disto_SOURCES = get_disto.c
|
||||
get_disto_CPPFLAGS = $(AM_CPPFLAGS)
|
||||
get_disto_LDADD =
|
||||
get_disto_LDADD += ../imageio/libimageio_util.la
|
||||
get_disto_LDADD += ../imageio/libimagedec.la
|
||||
get_disto_LDADD = ../imageio/libimageio_util.la ../imageio/libimagedec.la
|
||||
get_disto_LDADD += ../src/libwebp.la
|
||||
get_disto_LDADD += $(PNG_LIBS) $(JPEG_LIBS) $(TIFF_LIBS)
|
||||
|
||||
webp_quality_SOURCES = webp_quality.c
|
||||
webp_quality_CPPFLAGS = $(AM_CPPFLAGS)
|
||||
webp_quality_LDADD =
|
||||
webp_quality_LDADD += ../imageio/libimageio_util.la
|
||||
webp_quality_CPPFLAGS = $(AM_CPPFLAGS) $(USE_EXPERIMENTAL_CODE)
|
||||
webp_quality_LDADD = ../imageio/libimageio_util.la
|
||||
webp_quality_LDADD += libwebpextras.la
|
||||
webp_quality_LDADD += ../src/libwebp.la
|
||||
|
||||
vwebp_sdl_SOURCES = vwebp_sdl.c webp_to_sdl.c webp_to_sdl.h
|
||||
vwebp_sdl_CPPFLAGS = $(AM_CPPFLAGS) $(SDL_INCLUDES)
|
||||
vwebp_sdl_LDADD =
|
||||
vwebp_sdl_LDADD += ../imageio/libimageio_util.la
|
||||
vwebp_sdl_LDADD = ../imageio/libimageio_util.la
|
||||
vwebp_sdl_LDADD += ../src/libwebp.la
|
||||
vwebp_sdl_LDADD += $(SDL_LIBS)
|
||||
|
@ -10,14 +10,14 @@
|
||||
// Additional WebP utilities.
|
||||
//
|
||||
|
||||
#include "extras/extras.h"
|
||||
#include "./extras.h"
|
||||
#include "webp/format_constants.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#define XTRA_MAJ_VERSION 1
|
||||
#define XTRA_MIN_VERSION 0
|
||||
#define XTRA_MAJ_VERSION 0
|
||||
#define XTRA_MIN_VERSION 1
|
||||
#define XTRA_REV_VERSION 0
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@ -48,14 +48,13 @@ int WebPImportGray(const uint8_t* gray_data, WebPPicture* pic) {
|
||||
|
||||
int WebPImportRGB565(const uint8_t* rgb565, WebPPicture* pic) {
|
||||
int x, y;
|
||||
uint32_t* dst;
|
||||
if (pic == NULL || rgb565 == NULL) return 0;
|
||||
pic->colorspace = WEBP_YUV420;
|
||||
pic->use_argb = 1;
|
||||
if (!WebPPictureAlloc(pic)) return 0;
|
||||
dst = pic->argb;
|
||||
for (y = 0; y < pic->height; ++y) {
|
||||
const int width = pic->width;
|
||||
uint32_t* dst = pic->argb + y * pic->argb_stride;
|
||||
for (x = 0; x < width; ++x) {
|
||||
#ifdef WEBP_SWAP_16BIT_CSP
|
||||
const uint32_t rg = rgb565[2 * x + 1];
|
||||
@ -71,24 +70,22 @@ int WebPImportRGB565(const uint8_t* rgb565, WebPPicture* pic) {
|
||||
r = r | (r >> 5);
|
||||
g = g | (g >> 6);
|
||||
b = b | (b >> 5);
|
||||
dst[x] = (0xffu << 24) | (r << 16) | (g << 8) | b;
|
||||
dst[x] = (r << 16) | (g << 8) | b;
|
||||
}
|
||||
rgb565 += 2 * width;
|
||||
dst += pic->argb_stride;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int WebPImportRGB4444(const uint8_t* rgb4444, WebPPicture* pic) {
|
||||
int x, y;
|
||||
uint32_t* dst;
|
||||
if (pic == NULL || rgb4444 == NULL) return 0;
|
||||
pic->colorspace = WEBP_YUV420;
|
||||
pic->use_argb = 1;
|
||||
if (!WebPPictureAlloc(pic)) return 0;
|
||||
dst = pic->argb;
|
||||
for (y = 0; y < pic->height; ++y) {
|
||||
const int width = pic->width;
|
||||
uint32_t* dst = pic->argb + y * pic->argb_stride;
|
||||
for (x = 0; x < width; ++x) {
|
||||
#ifdef WEBP_SWAP_16BIT_CSP
|
||||
const uint32_t rg = rgb4444[2 * x + 1];
|
||||
@ -109,7 +106,6 @@ int WebPImportRGB4444(const uint8_t* rgb4444, WebPPicture* pic) {
|
||||
dst[x] = (a << 24) | (r << 16) | (g << 8) | b;
|
||||
}
|
||||
rgb4444 += 2 * width;
|
||||
dst += pic->argb_stride;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
@ -25,28 +25,28 @@ extern "C" {
|
||||
|
||||
// Returns the version number of the extras library, packed in hexadecimal using
|
||||
// 8bits for each of major/minor/revision. E.g: v2.5.7 is 0x020507.
|
||||
WEBP_EXTERN int WebPGetExtrasVersion(void);
|
||||
WEBP_EXTERN(int) WebPGetExtrasVersion(void);
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Ad-hoc colorspace importers.
|
||||
|
||||
// Import luma sample (gray scale image) into 'picture'. The 'picture'
|
||||
// width and height must be set prior to calling this function.
|
||||
WEBP_EXTERN int WebPImportGray(const uint8_t* gray, WebPPicture* picture);
|
||||
WEBP_EXTERN(int) WebPImportGray(const uint8_t* gray, WebPPicture* picture);
|
||||
|
||||
// Import rgb sample in RGB565 packed format into 'picture'. The 'picture'
|
||||
// width and height must be set prior to calling this function.
|
||||
WEBP_EXTERN int WebPImportRGB565(const uint8_t* rgb565, WebPPicture* pic);
|
||||
WEBP_EXTERN(int) WebPImportRGB565(const uint8_t* rgb565, WebPPicture* pic);
|
||||
|
||||
// Import rgb sample in RGB4444 packed format into 'picture'. The 'picture'
|
||||
// width and height must be set prior to calling this function.
|
||||
WEBP_EXTERN int WebPImportRGB4444(const uint8_t* rgb4444, WebPPicture* pic);
|
||||
WEBP_EXTERN(int) WebPImportRGB4444(const uint8_t* rgb4444, WebPPicture* pic);
|
||||
|
||||
// Import a color mapped image. The number of colors is less or equal to
|
||||
// MAX_PALETTE_SIZE. 'pic' must have been initialized. Its content, if any,
|
||||
// will be discarded. Returns 'false' in case of error, or if indexed[] contains
|
||||
// invalid indices.
|
||||
WEBP_EXTERN int
|
||||
WEBP_EXTERN(int)
|
||||
WebPImportColorMappedARGB(const uint8_t* indexed, int indexed_stride,
|
||||
const uint32_t palette[], int palette_size,
|
||||
WebPPicture* pic);
|
||||
@ -59,7 +59,7 @@ WebPImportColorMappedARGB(const uint8_t* indexed, int indexed_stride,
|
||||
// Otherwise (lossy bitstream), the returned value is in the range [0..100].
|
||||
// Any error (invalid bitstream, animated WebP, incomplete header, etc.)
|
||||
// will return a value of -1.
|
||||
WEBP_EXTERN int VP8EstimateQuality(const uint8_t* const data, size_t size);
|
||||
WEBP_EXTERN(int) VP8EstimateQuality(const uint8_t* const data, size_t size);
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
|
@ -24,8 +24,8 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "webp/encode.h"
|
||||
#include "imageio/image_dec.h"
|
||||
#include "imageio/imageio_util.h"
|
||||
#include "../imageio/image_dec.h"
|
||||
#include "../imageio/imageio_util.h"
|
||||
|
||||
static size_t ReadPicture(const char* const filename, WebPPicture* const pic,
|
||||
int keep_alpha) {
|
||||
@ -290,10 +290,9 @@ int main(int argc, const char *argv[]) {
|
||||
fprintf(stderr, "Error while computing the distortion.\n");
|
||||
goto End;
|
||||
}
|
||||
printf("%u %.2f %.2f %.2f %.2f %.2f [ %.2f bpp ]\n",
|
||||
printf("%u %.2f %.2f %.2f %.2f %.2f\n",
|
||||
(unsigned int)size1,
|
||||
disto[4], disto[0], disto[1], disto[2], disto[3],
|
||||
8.f * size1 / pic1.width / pic1.height);
|
||||
disto[4], disto[0], disto[1], disto[2], disto[3]);
|
||||
|
||||
if (output != NULL) {
|
||||
uint8_t* data = NULL;
|
||||
@ -323,7 +322,6 @@ int main(int argc, const char *argv[]) {
|
||||
fprintf(stderr, "Can only compute the difference map in ARGB format.\n");
|
||||
goto End;
|
||||
}
|
||||
#if !defined(WEBP_REDUCE_CSP)
|
||||
data_size = WebPEncodeLosslessBGRA((const uint8_t*)pic1.argb,
|
||||
pic1.width, pic1.height,
|
||||
pic1.argb_stride * 4,
|
||||
@ -335,12 +333,6 @@ int main(int argc, const char *argv[]) {
|
||||
ret = ImgIoUtilWriteFile(output, data, data_size) ? 0 : 1;
|
||||
WebPFree(data);
|
||||
if (ret) goto End;
|
||||
#else
|
||||
(void)data;
|
||||
(void)data_size;
|
||||
fprintf(stderr, "Cannot save the difference map. Please recompile "
|
||||
"without the WEBP_REDUCE_CSP flag.\n");
|
||||
#endif // WEBP_REDUCE_CSP
|
||||
}
|
||||
ret = 0;
|
||||
|
||||
|
@ -11,7 +11,7 @@
|
||||
//
|
||||
// Author: Skal (pascal.massimino@gmail.com)
|
||||
|
||||
#include "extras/extras.h"
|
||||
#include "./extras.h"
|
||||
#include "webp/decode.h"
|
||||
|
||||
#include <math.h>
|
||||
@ -73,7 +73,7 @@ int VP8EstimateQuality(const uint8_t* const data, size_t size) {
|
||||
pos += 4;
|
||||
bit_pos = pos * 8;
|
||||
|
||||
GET_BIT(2); // colorspace + clamp type
|
||||
GET_BIT(2); // color_space + clamp type
|
||||
|
||||
// Segment header
|
||||
if (GET_BIT(1)) { // use_segment_
|
||||
|
@ -24,7 +24,7 @@
|
||||
|
||||
#include "webp_to_sdl.h"
|
||||
#include "webp/decode.h"
|
||||
#include "imageio/imageio_util.h"
|
||||
#include "../imageio/imageio_util.h"
|
||||
|
||||
#if defined(WEBP_HAVE_JUST_SDL_H)
|
||||
#include <SDL.h>
|
||||
|
@ -11,8 +11,8 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "extras/extras.h"
|
||||
#include "imageio/imageio_util.h"
|
||||
#include "./extras.h"
|
||||
#include "../imageio/imageio_util.h"
|
||||
|
||||
int main(int argc, const char *argv[]) {
|
||||
int c;
|
||||
|
9
extras/webp_to_sdl.c
Normal file → Executable file
9
extras/webp_to_sdl.c
Normal file → Executable file
@ -12,7 +12,7 @@
|
||||
// Author: James Zern (jzern@google.com)
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "src/webp/config.h"
|
||||
#include "webp/config.h"
|
||||
#endif
|
||||
|
||||
#if defined(WEBP_HAVE_SDL)
|
||||
@ -20,7 +20,7 @@
|
||||
#include "webp_to_sdl.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include "src/webp/decode.h"
|
||||
#include "webp/decode.h"
|
||||
|
||||
#if defined(WEBP_HAVE_JUST_SDL_H)
|
||||
#include <SDL.h>
|
||||
@ -28,7 +28,6 @@
|
||||
#include <SDL/SDL.h>
|
||||
#endif
|
||||
|
||||
static int init_ok = 0;
|
||||
int WebpToSDL(const char* data, unsigned int data_size) {
|
||||
int ok = 0;
|
||||
VP8StatusCode status;
|
||||
@ -43,10 +42,7 @@ int WebpToSDL(const char* data, unsigned int data_size) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!init_ok) {
|
||||
SDL_Init(SDL_INIT_VIDEO);
|
||||
init_ok = 1;
|
||||
}
|
||||
|
||||
status = WebPGetFeatures((uint8_t*)data, (size_t)data_size, &config.input);
|
||||
if (status != VP8_STATUS_OK) goto Error;
|
||||
@ -101,7 +97,6 @@ int WebpToSDL(const char* data, unsigned int data_size) {
|
||||
Error:
|
||||
SDL_FreeSurface(surface);
|
||||
SDL_FreeSurface(screen);
|
||||
WebPFreeDecBuffer(output);
|
||||
return ok;
|
||||
}
|
||||
|
||||
|
@ -1,20 +1,13 @@
|
||||
AM_CPPFLAGS += -I$(top_builddir)/src -I$(top_srcdir)/src
|
||||
noinst_LTLIBRARIES =
|
||||
noinst_LTLIBRARIES += libimageio_util.la
|
||||
if WANT_DEMUX
|
||||
noinst_LTLIBRARIES += libimagedec.la
|
||||
endif
|
||||
noinst_LTLIBRARIES += libimageenc.la
|
||||
noinst_LTLIBRARIES = libimageio_util.la libimagedec.la libimageenc.la
|
||||
|
||||
noinst_HEADERS =
|
||||
noinst_HEADERS += ../src/webp/decode.h
|
||||
noinst_HEADERS += ../src/webp/types.h
|
||||
|
||||
libimageio_util_la_SOURCES =
|
||||
libimageio_util_la_SOURCES += imageio_util.c imageio_util.h
|
||||
libimageio_util_la_SOURCES = imageio_util.c imageio_util.h
|
||||
|
||||
libimagedec_la_SOURCES =
|
||||
libimagedec_la_SOURCES += image_dec.c image_dec.h
|
||||
libimagedec_la_SOURCES = image_dec.c image_dec.h
|
||||
libimagedec_la_SOURCES += jpegdec.c jpegdec.h
|
||||
libimagedec_la_SOURCES += metadata.c metadata.h
|
||||
libimagedec_la_SOURCES += pngdec.c pngdec.h
|
||||
@ -23,10 +16,8 @@ libimagedec_la_SOURCES += tiffdec.c tiffdec.h
|
||||
libimagedec_la_SOURCES += webpdec.c webpdec.h
|
||||
libimagedec_la_SOURCES += wicdec.c wicdec.h
|
||||
libimagedec_la_CPPFLAGS = $(JPEG_INCLUDES) $(PNG_INCLUDES) $(TIFF_INCLUDES)
|
||||
libimagedec_la_CPPFLAGS += $(AM_CPPFLAGS)
|
||||
libimagedec_la_LIBADD = ../src/demux/libwebpdemux.la
|
||||
libimagedec_la_CPPFLAGS += $(AM_CPPFLAGS) $(USE_EXPERIMENTAL_CODE)
|
||||
|
||||
libimageenc_la_SOURCES =
|
||||
libimageenc_la_SOURCES += image_enc.c image_enc.h
|
||||
libimageenc_la_SOURCES = image_enc.c image_enc.h
|
||||
libimageenc_la_CPPFLAGS = $(JPEG_INCLUDES) $(PNG_INCLUDES) $(TIFF_INCLUDES)
|
||||
libimageenc_la_CPPFLAGS += $(AM_CPPFLAGS)
|
||||
libimageenc_la_CPPFLAGS += $(AM_CPPFLAGS) $(USE_EXPERIMENTAL_CODE)
|
||||
|
@ -158,8 +158,14 @@ static void PNGAPI PNGErrorFunction(png_structp png, png_const_charp dummy) {
|
||||
}
|
||||
|
||||
int WebPWritePNG(FILE* out_file, const WebPDecBuffer* const buffer) {
|
||||
const uint32_t width = buffer->width;
|
||||
const uint32_t height = buffer->height;
|
||||
png_bytep row = buffer->u.RGBA.rgba;
|
||||
const int stride = buffer->u.RGBA.stride;
|
||||
const int has_alpha = WebPIsAlphaMode(buffer->colorspace);
|
||||
volatile png_structp png;
|
||||
volatile png_infop info;
|
||||
png_uint_32 y;
|
||||
|
||||
if (out_file == NULL || buffer == NULL) return 0;
|
||||
|
||||
@ -178,14 +184,6 @@ int WebPWritePNG(FILE* out_file, const WebPDecBuffer* const buffer) {
|
||||
return 0;
|
||||
}
|
||||
png_init_io(png, out_file);
|
||||
{
|
||||
const uint32_t width = buffer->width;
|
||||
const uint32_t height = buffer->height;
|
||||
png_bytep row = buffer->u.RGBA.rgba;
|
||||
const int stride = buffer->u.RGBA.stride;
|
||||
const int has_alpha = WebPIsAlphaMode(buffer->colorspace);
|
||||
uint32_t y;
|
||||
|
||||
png_set_IHDR(png, info, width, height, 8,
|
||||
has_alpha ? PNG_COLOR_TYPE_RGBA : PNG_COLOR_TYPE_RGB,
|
||||
PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT,
|
||||
@ -195,7 +193,6 @@ int WebPWritePNG(FILE* out_file, const WebPDecBuffer* const buffer) {
|
||||
png_write_rows(png, &row, 1);
|
||||
row += stride;
|
||||
}
|
||||
}
|
||||
png_write_end(png, info);
|
||||
png_destroy_write_struct((png_structpp)&png, (png_infopp)&info);
|
||||
return 1;
|
||||
@ -545,24 +542,22 @@ int WebPWriteYUV(FILE* fout, const WebPDecBuffer* const buffer) {
|
||||
// Generic top-level call
|
||||
|
||||
int WebPSaveImage(const WebPDecBuffer* const buffer,
|
||||
WebPOutputFileFormat format,
|
||||
const char* const out_file_name) {
|
||||
WebPOutputFileFormat format, const char* const out_file) {
|
||||
FILE* fout = NULL;
|
||||
int needs_open_file = 1;
|
||||
const int use_stdout = (out_file_name != NULL) && !strcmp(out_file_name, "-");
|
||||
const int use_stdout = (out_file != NULL) && !strcmp(out_file, "-");
|
||||
int ok = 1;
|
||||
|
||||
if (buffer == NULL || out_file_name == NULL) return 0;
|
||||
if (buffer == NULL || out_file == NULL) return 0;
|
||||
|
||||
#ifdef HAVE_WINCODEC_H
|
||||
needs_open_file = (format != PNG);
|
||||
#endif
|
||||
|
||||
if (needs_open_file) {
|
||||
fout = use_stdout ? ImgIoUtilSetBinaryMode(stdout)
|
||||
: fopen(out_file_name, "wb");
|
||||
fout = use_stdout ? ImgIoUtilSetBinaryMode(stdout) : fopen(out_file, "wb");
|
||||
if (fout == NULL) {
|
||||
fprintf(stderr, "Error opening output file %s\n", out_file_name);
|
||||
fprintf(stderr, "Error opening output file %s\n", out_file);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -571,7 +566,7 @@ int WebPSaveImage(const WebPDecBuffer* const buffer,
|
||||
format == RGBA || format == BGRA || format == ARGB ||
|
||||
format == rgbA || format == bgrA || format == Argb) {
|
||||
#ifdef HAVE_WINCODEC_H
|
||||
ok &= WebPWritePNG(out_file_name, use_stdout, buffer);
|
||||
ok &= WebPWritePNG(out_file, use_stdout, buffer);
|
||||
#else
|
||||
ok &= WebPWritePNG(fout, buffer);
|
||||
#endif
|
||||
|
@ -47,8 +47,7 @@ int ImgIoUtilReadFromStdin(const uint8_t** data, size_t* data_size) {
|
||||
while (!feof(stdin)) {
|
||||
// We double the buffer size each time and read as much as possible.
|
||||
const size_t extra_size = (max_size == 0) ? kBlockSize : max_size;
|
||||
// we allocate one extra byte for the \0 terminator
|
||||
void* const new_data = realloc(input, max_size + extra_size + 1);
|
||||
void* const new_data = realloc(input, max_size + extra_size);
|
||||
if (new_data == NULL) goto Error;
|
||||
input = (uint8_t*)new_data;
|
||||
max_size += extra_size;
|
||||
@ -56,7 +55,6 @@ int ImgIoUtilReadFromStdin(const uint8_t** data, size_t* data_size) {
|
||||
if (size < max_size) break;
|
||||
}
|
||||
if (ferror(stdin)) goto Error;
|
||||
if (input != NULL) input[size] = '\0'; // convenient 0-terminator
|
||||
*data = input;
|
||||
*data_size = size;
|
||||
return 1;
|
||||
@ -70,7 +68,7 @@ int ImgIoUtilReadFromStdin(const uint8_t** data, size_t* data_size) {
|
||||
int ImgIoUtilReadFile(const char* const file_name,
|
||||
const uint8_t** data, size_t* data_size) {
|
||||
int ok;
|
||||
uint8_t* file_data;
|
||||
void* file_data;
|
||||
size_t file_size;
|
||||
FILE* in;
|
||||
const int from_stdin = (file_name == NULL) || !strcmp(file_name, "-");
|
||||
@ -89,14 +87,8 @@ int ImgIoUtilReadFile(const char* const file_name,
|
||||
fseek(in, 0, SEEK_END);
|
||||
file_size = ftell(in);
|
||||
fseek(in, 0, SEEK_SET);
|
||||
// we allocate one extra byte for the \0 terminator
|
||||
file_data = (uint8_t*)malloc(file_size + 1);
|
||||
if (file_data == NULL) {
|
||||
fclose(in);
|
||||
fprintf(stderr, "memory allocation failure when reading file %s\n",
|
||||
file_name);
|
||||
return 0;
|
||||
}
|
||||
file_data = malloc(file_size);
|
||||
if (file_data == NULL) return 0;
|
||||
ok = (fread(file_data, file_size, 1, in) == 1);
|
||||
fclose(in);
|
||||
|
||||
@ -106,14 +98,11 @@ int ImgIoUtilReadFile(const char* const file_name,
|
||||
free(file_data);
|
||||
return 0;
|
||||
}
|
||||
file_data[file_size] = '\0'; // convenient 0-terminator
|
||||
*data = file_data;
|
||||
*data = (uint8_t*)file_data;
|
||||
*data_size = file_size;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
int ImgIoUtilWriteFile(const char* const file_name,
|
||||
const uint8_t* data, size_t data_size) {
|
||||
int ok;
|
||||
@ -148,11 +137,7 @@ void ImgIoUtilCopyPlane(const uint8_t* src, int src_stride,
|
||||
|
||||
int ImgIoUtilCheckSizeArgumentsOverflow(uint64_t nmemb, size_t size) {
|
||||
const uint64_t total_size = nmemb * size;
|
||||
int ok = (total_size == (size_t)total_size);
|
||||
#if defined(WEBP_MAX_IMAGE_SIZE)
|
||||
ok = ok && (total_size <= (uint64_t)WEBP_MAX_IMAGE_SIZE);
|
||||
#endif
|
||||
return ok;
|
||||
return (total_size == (size_t)total_size);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
@ -30,9 +30,6 @@ FILE* ImgIoUtilSetBinaryMode(FILE* file);
|
||||
// Allocates storage for entire file 'file_name' and returns contents and size
|
||||
// in 'data' and 'data_size'. Returns 1 on success, 0 otherwise. '*data' should
|
||||
// be deleted using free().
|
||||
// Note: for convenience, the data will be null-terminated with an extra byte
|
||||
// (not accounted for in *data_size), in case the file is text and intended
|
||||
// to be used as a C-string.
|
||||
// If 'file_name' is NULL or equal to "-", input is read from stdin by calling
|
||||
// the function ImgIoUtilReadFromStdin().
|
||||
int ImgIoUtilReadFile(const char* const file_name,
|
||||
|
@ -304,18 +304,18 @@ int ReadJPEG(const uint8_t* const data, size_t data_size,
|
||||
|
||||
if (stride != (int)stride ||
|
||||
!ImgIoUtilCheckSizeArgumentsOverflow(stride, height)) {
|
||||
goto Error;
|
||||
goto End;
|
||||
}
|
||||
|
||||
rgb = (uint8_t*)malloc((size_t)stride * height);
|
||||
if (rgb == NULL) {
|
||||
goto Error;
|
||||
goto End;
|
||||
}
|
||||
buffer[0] = (JSAMPLE*)rgb;
|
||||
|
||||
while (dinfo.output_scanline < dinfo.output_height) {
|
||||
if (jpeg_read_scanlines((j_decompress_ptr)&dinfo, buffer, 1) != 1) {
|
||||
goto Error;
|
||||
goto End;
|
||||
}
|
||||
buffer[0] += stride;
|
||||
}
|
||||
|
@ -185,6 +185,7 @@ static int ExtractMetadataFromPNG(png_structp png,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -264,16 +265,6 @@ int ReadPNG(const uint8_t* const data, size_t data_size,
|
||||
has_alpha = !!(color_type & PNG_COLOR_MASK_ALPHA);
|
||||
}
|
||||
|
||||
// Apply gamma correction if needed.
|
||||
{
|
||||
double image_gamma = 1 / 2.2, screen_gamma = 2.2;
|
||||
int srgb_intent;
|
||||
if (png_get_sRGB(png, info, &srgb_intent) ||
|
||||
png_get_gAMA(png, info, &image_gamma)) {
|
||||
png_set_gamma(png, screen_gamma, image_gamma);
|
||||
}
|
||||
}
|
||||
|
||||
if (!keep_alpha) {
|
||||
png_set_strip_alpha(png);
|
||||
has_alpha = 0;
|
||||
|
@ -117,13 +117,8 @@ static size_t ReadPAMFields(PNMInfo* const info, size_t off) {
|
||||
}
|
||||
}
|
||||
if (!(info->seen_flags & TUPLE_FLAG)) {
|
||||
if (info->depth > 0 && info->depth <= 4 && info->depth != 2) {
|
||||
info->seen_flags |= TUPLE_FLAG;
|
||||
info->bytes_per_px = info->depth * (info->max_value > 255 ? 2 : 1);
|
||||
} else {
|
||||
fprintf(stderr, "PAM: invalid bitdepth (%d).\n", info->depth);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if (info->seen_flags != ALL_NEEDED_FLAGS) {
|
||||
fprintf(stderr, "PAM: incomplete header.\n");
|
||||
@ -165,7 +160,7 @@ static size_t ReadHeader(PNMInfo* const info) {
|
||||
// perform some basic numerical validation
|
||||
if (info->width <= 0 || info->height <= 0 ||
|
||||
info->type <= 0 || info->type >= 9 ||
|
||||
info->depth <= 0 || info->depth == 2 || info->depth > 4 ||
|
||||
info->depth <= 0 || info->depth > 4 ||
|
||||
info->bytes_per_px < info->depth ||
|
||||
info->max_value <= 0 || info->max_value >= 65536) {
|
||||
return 0;
|
||||
|
@ -9,18 +9,12 @@
|
||||
//
|
||||
// WebP decode.
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "webp/config.h"
|
||||
#endif
|
||||
|
||||
#include "./webpdec.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "webp/decode.h"
|
||||
#include "webp/demux.h"
|
||||
#include "webp/encode.h"
|
||||
#include "./imageio_util.h"
|
||||
#include "./metadata.h"
|
||||
@ -97,47 +91,25 @@ VP8StatusCode DecodeWebPIncremental(
|
||||
fprintf(stderr, "Failed during WebPINewDecoder().\n");
|
||||
return VP8_STATUS_OUT_OF_MEMORY;
|
||||
} else {
|
||||
#ifdef WEBP_EXPERIMENTAL_FEATURES
|
||||
size_t size = 0;
|
||||
const size_t incr = 2 + (data_size / 20);
|
||||
while (size < data_size) {
|
||||
size_t next_size = size + (rand() % incr);
|
||||
if (next_size > data_size) next_size = data_size;
|
||||
status = WebPIUpdate(idec, data, next_size);
|
||||
if (status != VP8_STATUS_OK && status != VP8_STATUS_SUSPENDED) break;
|
||||
size = next_size;
|
||||
}
|
||||
#else
|
||||
status = WebPIUpdate(idec, data, data_size);
|
||||
#endif
|
||||
WebPIDelete(idec);
|
||||
}
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Metadata
|
||||
|
||||
static int ExtractMetadata(const uint8_t* const data, size_t data_size,
|
||||
Metadata* const metadata) {
|
||||
WebPData webp_data = { data, data_size };
|
||||
WebPDemuxer* const demux = WebPDemux(&webp_data);
|
||||
WebPChunkIterator chunk_iter;
|
||||
uint32_t flags;
|
||||
|
||||
if (demux == NULL) return 0;
|
||||
assert(metadata != NULL);
|
||||
|
||||
flags = WebPDemuxGetI(demux, WEBP_FF_FORMAT_FLAGS);
|
||||
|
||||
if ((flags & ICCP_FLAG) && WebPDemuxGetChunk(demux, "ICCP", 1, &chunk_iter)) {
|
||||
MetadataCopy((const char*)chunk_iter.chunk.bytes, chunk_iter.chunk.size,
|
||||
&metadata->iccp);
|
||||
WebPDemuxReleaseChunkIterator(&chunk_iter);
|
||||
}
|
||||
if ((flags & EXIF_FLAG) && WebPDemuxGetChunk(demux, "EXIF", 1, &chunk_iter)) {
|
||||
MetadataCopy((const char*)chunk_iter.chunk.bytes, chunk_iter.chunk.size,
|
||||
&metadata->exif);
|
||||
WebPDemuxReleaseChunkIterator(&chunk_iter);
|
||||
}
|
||||
if ((flags & XMP_FLAG) && WebPDemuxGetChunk(demux, "XMP ", 1, &chunk_iter)) {
|
||||
MetadataCopy((const char*)chunk_iter.chunk.bytes, chunk_iter.chunk.size,
|
||||
&metadata->xmp);
|
||||
WebPDemuxReleaseChunkIterator(&chunk_iter);
|
||||
}
|
||||
WebPDemuxDelete(demux);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
int ReadWebP(const uint8_t* const data, size_t data_size,
|
||||
@ -151,6 +123,11 @@ int ReadWebP(const uint8_t* const data, size_t data_size,
|
||||
|
||||
if (data == NULL || data_size == 0 || pic == NULL) return 0;
|
||||
|
||||
// TODO(jzern): add Exif/XMP/ICC extraction.
|
||||
if (metadata != NULL) {
|
||||
fprintf(stderr, "Warning: metadata extraction from WebP is unsupported.\n");
|
||||
}
|
||||
|
||||
if (!WebPInitDecoderConfig(&config)) {
|
||||
fprintf(stderr, "Library version mismatch!\n");
|
||||
return 0;
|
||||
@ -164,32 +141,17 @@ int ReadWebP(const uint8_t* const data, size_t data_size,
|
||||
|
||||
do {
|
||||
const int has_alpha = keep_alpha && bitstream->has_alpha;
|
||||
uint64_t stride;
|
||||
pic->width = bitstream->width;
|
||||
pic->height = bitstream->height;
|
||||
if (pic->use_argb) {
|
||||
stride = (uint64_t)bitstream->width * 4;
|
||||
} else {
|
||||
stride = (uint64_t)bitstream->width * (has_alpha ? 5 : 3) / 2;
|
||||
pic->colorspace = has_alpha ? WEBP_YUV420A : WEBP_YUV420;
|
||||
}
|
||||
|
||||
if (!ImgIoUtilCheckSizeArgumentsOverflow(stride, bitstream->height)) {
|
||||
status = VP8_STATUS_OUT_OF_MEMORY;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!pic->use_argb) pic->colorspace = has_alpha ? WEBP_YUV420A
|
||||
: WEBP_YUV420;
|
||||
ok = WebPPictureAlloc(pic);
|
||||
if (!ok) {
|
||||
status = VP8_STATUS_OUT_OF_MEMORY;
|
||||
break;
|
||||
}
|
||||
if (pic->use_argb) {
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
output_buffer->colorspace = MODE_ARGB;
|
||||
#else
|
||||
output_buffer->colorspace = MODE_BGRA;
|
||||
#endif
|
||||
output_buffer->u.RGBA.rgba = (uint8_t*)pic->argb;
|
||||
output_buffer->u.RGBA.stride = pic->argb_stride * sizeof(uint32_t);
|
||||
output_buffer->u.RGBA.size = output_buffer->u.RGBA.stride * pic->height;
|
||||
@ -212,6 +174,7 @@ int ReadWebP(const uint8_t* const data, size_t data_size,
|
||||
|
||||
status = DecodeWebP(data, data_size, &config);
|
||||
ok = (status == VP8_STATUS_OK);
|
||||
if (!ok) WebPPictureFree(pic);
|
||||
if (ok && !keep_alpha && pic->use_argb) {
|
||||
// Need to wipe out the alpha value, as requested.
|
||||
int x, y;
|
||||
@ -225,18 +188,9 @@ int ReadWebP(const uint8_t* const data, size_t data_size,
|
||||
|
||||
if (status != VP8_STATUS_OK) {
|
||||
PrintWebPError("input data", status);
|
||||
ok = 0;
|
||||
}
|
||||
|
||||
WebPFreeDecBuffer(output_buffer);
|
||||
|
||||
if (ok && metadata != NULL) {
|
||||
ok = ExtractMetadata(data, data_size, metadata);
|
||||
if (!ok) {
|
||||
PrintWebPError("metadata", VP8_STATUS_BITSTREAM_ERROR);
|
||||
}
|
||||
}
|
||||
if (!ok) WebPPictureFree(pic);
|
||||
return ok;
|
||||
}
|
||||
|
||||
|
@ -25,7 +25,6 @@ ifeq ($(strip $(shell uname)), Darwin)
|
||||
# Failure observed with: gcc 4.2.1 and 4.0.1.
|
||||
EXTRA_FLAGS += -fno-common
|
||||
EXTRA_FLAGS += -DHAVE_GLUT_GLUT_H
|
||||
EXTRA_FLAGS += -Wno-deprecated-declarations
|
||||
EXTRA_FLAGS += -I/opt/local/include
|
||||
EXTRA_LIBS += -L/opt/local/lib
|
||||
GL_LIBS = -framework GLUT -framework OpenGL
|
||||
@ -35,16 +34,6 @@ else
|
||||
GL_LIBS = -lglut -lGL
|
||||
endif
|
||||
|
||||
# SDL flags: use sdl-config if it exists
|
||||
SDL_CONFIG = $(shell sdl-config --version 2> /dev/null)
|
||||
ifneq ($(SDL_CONFIG),)
|
||||
SDL_LIBS = $(shell sdl-config --libs)
|
||||
SDL_FLAGS = $(shell sdl-config --cflags)
|
||||
else
|
||||
# use best-guess
|
||||
SDL_LIBS = -lSDL
|
||||
SDL_FLAGS =
|
||||
endif
|
||||
|
||||
# To install libraries on Mac OS X:
|
||||
# 1. Install MacPorts (http://www.macports.org/install.php)
|
||||
@ -64,8 +53,11 @@ endif
|
||||
# 'make -f makefile.unix EXTRA_FLAGS=-m32' to that effect.
|
||||
# EXTRA_FLAGS += -m32
|
||||
|
||||
# Extra flags to enable experimental features and code
|
||||
# EXTRA_FLAGS += -DWEBP_EXPERIMENTAL_FEATURES
|
||||
|
||||
# Extra flags to enable byte swap for 16 bit colorspaces.
|
||||
# EXTRA_FLAGS += -DWEBP_SWAP_16BIT_CSP=1
|
||||
# EXTRA_FLAGS += -DWEBP_SWAP_16BIT_CSP
|
||||
|
||||
# Extra flags to enable multi-threading
|
||||
EXTRA_FLAGS += -DWEBP_USE_THREAD
|
||||
@ -111,13 +103,8 @@ endif
|
||||
|
||||
AR = ar
|
||||
ARFLAGS = r
|
||||
CPPFLAGS = -I. -Isrc/ -Wall
|
||||
ifeq ($(DEBUG), 1)
|
||||
CFLAGS = -g
|
||||
else
|
||||
CFLAGS = -O3 -DNDEBUG
|
||||
endif
|
||||
CFLAGS += $(EXTRA_FLAGS)
|
||||
CPPFLAGS = -Isrc/ -Wall
|
||||
CFLAGS = -O3 -DNDEBUG $(EXTRA_FLAGS)
|
||||
CC = gcc
|
||||
INSTALL = install
|
||||
GROFF = /usr/bin/groff
|
||||
@ -179,15 +166,16 @@ DSP_DEC_OBJS = \
|
||||
src/dsp/upsampling_msa.o \
|
||||
src/dsp/upsampling_neon.o \
|
||||
src/dsp/upsampling_sse2.o \
|
||||
src/dsp/upsampling_sse41.o \
|
||||
src/dsp/yuv.o \
|
||||
src/dsp/yuv_mips32.o \
|
||||
src/dsp/yuv_mips_dsp_r2.o \
|
||||
src/dsp/yuv_neon.o \
|
||||
src/dsp/yuv_sse2.o \
|
||||
src/dsp/yuv_sse41.o \
|
||||
|
||||
DSP_ENC_OBJS = \
|
||||
src/dsp/argb.o \
|
||||
src/dsp/argb_mips_dsp_r2.o \
|
||||
src/dsp/argb_sse2.o \
|
||||
src/dsp/cost.o \
|
||||
src/dsp/cost_mips32.o \
|
||||
src/dsp/cost_mips_dsp_r2.o \
|
||||
@ -217,6 +205,7 @@ ENC_OBJS = \
|
||||
src/enc/backward_references_enc.o \
|
||||
src/enc/config_enc.o \
|
||||
src/enc/cost_enc.o \
|
||||
src/enc/delta_palettization_enc.o \
|
||||
src/enc/filter_enc.o \
|
||||
src/enc/frame_enc.o \
|
||||
src/enc/histogram_enc.o \
|
||||
@ -314,6 +303,7 @@ HDRS = \
|
||||
src/dsp/yuv.h \
|
||||
src/enc/backward_references_enc.h \
|
||||
src/enc/cost_enc.h \
|
||||
src/enc/delta_palettization_enc.h \
|
||||
src/enc/histogram_enc.h \
|
||||
src/enc/vp8i_enc.h \
|
||||
src/enc/vp8li_enc.h \
|
||||
@ -345,8 +335,7 @@ OUT_LIBS += src/libwebp.a
|
||||
EXTRA_LIB = extras/libwebpextras.a
|
||||
OUT_EXAMPLES = examples/cwebp examples/dwebp
|
||||
EXTRA_EXAMPLES = examples/gif2webp examples/vwebp examples/webpmux \
|
||||
examples/anim_diff examples/anim_dump \
|
||||
examples/img2webp examples/webpinfo
|
||||
examples/anim_diff examples/img2webp examples/webpinfo
|
||||
OTHER_EXAMPLES = extras/get_disto extras/webp_quality extras/vwebp_sdl
|
||||
|
||||
OUTPUT = $(OUT_LIBS) $(OUT_EXAMPLES)
|
||||
@ -374,7 +363,7 @@ src/utils/bit_reader_utils.o: src/utils/endian_inl_utils.h
|
||||
src/utils/bit_writer_utils.o: src/utils/endian_inl_utils.h
|
||||
|
||||
%.o: %.c $(HDRS)
|
||||
$(CC) $(CPPFLAGS) $(CFLAGS) -c $< -o $@
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) -c $< -o $@
|
||||
|
||||
examples/libanim_util.a: $(ANIM_UTIL_OBJS)
|
||||
examples/libexample_util.a: $(EX_UTIL_OBJS)
|
||||
@ -392,7 +381,6 @@ src/demux/libwebpdemux.a: $(LIBWEBPDEMUX_OBJS)
|
||||
$(AR) $(ARFLAGS) $@ $^
|
||||
|
||||
examples/anim_diff: examples/anim_diff.o $(ANIM_UTIL_OBJS) $(GIFDEC_OBJS)
|
||||
examples/anim_dump: examples/anim_dump.o $(ANIM_UTIL_OBJS)
|
||||
examples/cwebp: examples/cwebp.o
|
||||
examples/dwebp: examples/dwebp.o
|
||||
examples/gif2webp: examples/gif2webp.o $(GIFDEC_OBJS)
|
||||
@ -406,22 +394,13 @@ examples/anim_diff: src/demux/libwebpdemux.a examples/libexample_util.a
|
||||
examples/anim_diff: imageio/libimageio_util.a src/libwebp.a
|
||||
examples/anim_diff: EXTRA_LIBS += $(GIF_LIBS)
|
||||
examples/anim_diff: EXTRA_FLAGS += -DWEBP_HAVE_GIF
|
||||
examples/anim_dump: examples/libanim_util.a
|
||||
examples/anim_dump: src/demux/libwebpdemux.a
|
||||
examples/anim_dump: examples/libexample_util.a
|
||||
examples/anim_dump: imageio/libimageio_util.a
|
||||
examples/anim_dump: imageio/libimageenc.a
|
||||
examples/anim_dump: src/libwebp.a
|
||||
examples/anim_dump: EXTRA_LIBS += $(GIF_LIBS) $(DWEBP_LIBS)
|
||||
examples/cwebp: examples/libexample_util.a
|
||||
examples/cwebp: imageio/libimagedec.a
|
||||
examples/cwebp: src/demux/libwebpdemux.a
|
||||
examples/cwebp: imageio/libimageio_util.a
|
||||
examples/cwebp: src/libwebp.a
|
||||
examples/cwebp: EXTRA_LIBS += $(CWEBP_LIBS)
|
||||
examples/dwebp: examples/libexample_util.a
|
||||
examples/dwebp: imageio/libimagedec.a
|
||||
examples/dwebp: src/demux/libwebpdemux.a
|
||||
examples/dwebp: imageio/libimageenc.a
|
||||
examples/dwebp: imageio/libimageio_util.a
|
||||
examples/dwebp: src/libwebp.a
|
||||
@ -438,17 +417,13 @@ examples/webpmux: examples/libexample_util.a imageio/libimageio_util.a
|
||||
examples/webpmux: src/mux/libwebpmux.a src/libwebpdecoder.a
|
||||
examples/img2webp: examples/libexample_util.a imageio/libimageio_util.a
|
||||
examples/img2webp: imageio/libimagedec.a
|
||||
examples/img2webp: src/demux/libwebpdemux.a
|
||||
examples/img2webp: src/mux/libwebpmux.a src/libwebp.a
|
||||
examples/img2webp: EXTRA_LIBS += $(CWEBP_LIBS)
|
||||
examples/webpinfo: examples/libexample_util.a imageio/libimageio_util.a
|
||||
examples/webpinfo: src/libwebpdecoder.a
|
||||
|
||||
extras/get_disto: extras/get_disto.o
|
||||
extras/get_disto: imageio/libimagedec.a
|
||||
extras/get_disto: src/demux/libwebpdemux.a
|
||||
extras/get_disto: imageio/libimageio_util.a
|
||||
extras/get_disto: src/libwebp.a
|
||||
extras/get_disto: imageio/libimagedec.a imageio/libimageio_util.a src/libwebp.a
|
||||
extras/get_disto: EXTRA_LIBS += $(CWEBP_LIBS)
|
||||
|
||||
extras/webp_quality: extras/webp_quality.o
|
||||
@ -459,8 +434,8 @@ extras/vwebp_sdl: extras/vwebp_sdl.o
|
||||
extras/vwebp_sdl: extras/webp_to_sdl.o
|
||||
extras/vwebp_sdl: imageio/libimageio_util.a
|
||||
extras/vwebp_sdl: src/libwebp.a
|
||||
extras/vwebp_sdl: EXTRA_FLAGS += -DWEBP_HAVE_SDL $(SDL_FLAGS)
|
||||
extras/vwebp_sdl: EXTRA_LIBS += $(SDL_LIBS)
|
||||
extras/vwebp_sdl: EXTRA_FLAGS += -DWEBP_HAVE_SDL
|
||||
extras/vwebp_sdl: EXTRA_LIBS += -lSDL
|
||||
|
||||
$(OUT_EXAMPLES) $(EXTRA_EXAMPLES) $(OTHER_EXAMPLES):
|
||||
$(CC) -o $@ $^ $(LDFLAGS)
|
||||
@ -479,7 +454,7 @@ dist: all
|
||||
for m in man/[cdv]webp.1 man/gif2webp.1 man/webpmux.1 \
|
||||
man/img2webp.1 man/webpinfo.1; do \
|
||||
basenam=$$(basename $$m .1); \
|
||||
$(GROFF) -t -e -man -T ascii $$m \
|
||||
$(GROFF) -t -e -man -T utf8 $$m \
|
||||
| $(COL) -bx >$(DESTDIR)/doc/$${basenam}.txt; \
|
||||
$(GROFF) -t -e -man -T html $$m \
|
||||
| $(COL) -bx >$(DESTDIR)/doc/$${basenam}.html; \
|
||||
|
@ -1,5 +1,5 @@
|
||||
.\" Hey, EMACS: -*- nroff -*-
|
||||
.TH GIF2WEBP 1 "January 25, 2018"
|
||||
.TH GIF2WEBP 1 "January 25, 2017"
|
||||
.SH NAME
|
||||
gif2webp \- Convert a GIF image to WebP
|
||||
.SH SYNOPSIS
|
||||
@ -20,12 +20,6 @@ Specify the name of the output WebP file. If omitted, \fBgif2webp\fP will
|
||||
perform conversion but only report statistics.
|
||||
Using "\-" as output name will direct output to 'stdout'.
|
||||
.TP
|
||||
.BI \-\- " string
|
||||
Explicitly specify the input file. This option is useful if the input
|
||||
file starts with an '\-' for instance. This option must appear \fBlast\fP.
|
||||
Any other options afterward will be ignored. If the input file is "\-",
|
||||
the data will be read from \fIstdin\fP instead of a file.
|
||||
.TP
|
||||
.B \-h, \-help
|
||||
Usage information.
|
||||
.TP
|
||||
@ -116,10 +110,6 @@ the range of 20 to 50.
|
||||
.B \-mt
|
||||
Use multi-threading for encoding, if possible.
|
||||
.TP
|
||||
.B \-loop_compatibility
|
||||
If enabled, handle the loop information in a compatible fashion for Chrome
|
||||
version prior to M62 (inclusive) and Firefox.
|
||||
.TP
|
||||
.B \-v
|
||||
Print extra information.
|
||||
.TP
|
||||
@ -143,8 +133,6 @@ gif2webp \-lossy \-m 3 picture.gif \-o picture_lossy.webp
|
||||
gif2webp \-lossy \-f 50 picture.gif \-o picture.webp
|
||||
.br
|
||||
gif2webp \-q 70 \-o picture.webp \-\- \-\-\-picture.gif
|
||||
.br
|
||||
cat picture.gif | gif2webp \-o \- \-\- \- > output.webp
|
||||
|
||||
.SH AUTHORS
|
||||
\fBgif2webp\fP is a part of libwebp and was written by the WebP team.
|
||||
|
@ -1,13 +1,11 @@
|
||||
.\" Hey, EMACS: -*- nroff -*-
|
||||
.TH IMG2WEBP 1 "April 3, 2018"
|
||||
.TH IMG2WEBP 1 "January 23, 2017"
|
||||
.SH NAME
|
||||
img2webp \- create animated WebP file from a sequence of input images.
|
||||
.SH SYNOPSIS
|
||||
.B img2webp
|
||||
[file_level_options] [files] [per_frame_options...]
|
||||
.br
|
||||
.B img2webp argument_file_name
|
||||
.br
|
||||
.SH DESCRIPTION
|
||||
This manual page documents the
|
||||
.B img2webp
|
||||
@ -15,9 +13,6 @@ command.
|
||||
.PP
|
||||
\fBimg2webp\fP compresses a sequence of images using the animated WebP format.
|
||||
Input images can either be PNG, JPEG, TIFF or WebP.
|
||||
If a single file name (not starting with the character '\-') is supplied as
|
||||
the argument, the command line argument are actually tokenized from this file.
|
||||
This allows for easy scripting or using large number of arguments.
|
||||
.SH FILE-LEVEL OPTIONS
|
||||
The file-level options are applied at the beginning of the compression process,
|
||||
before the input frames are read.
|
||||
@ -45,17 +40,14 @@ lossy or lossless compression for each frame heuristically. This global
|
||||
option disables the local option \fB-lossy\fP and \fB-lossless\fP .
|
||||
.TP
|
||||
.BI \-loop " int
|
||||
Specifies the number of times the animation should loop. Using '0'
|
||||
means 'loop indefinitely'.
|
||||
Specifies the number of times the animation should loop. Using '0' means
|
||||
'loop indefinitely'.
|
||||
.TP
|
||||
.BI \-v
|
||||
Be more verbose.
|
||||
.TP
|
||||
.B \-h, \-help
|
||||
A short usage summary.
|
||||
.TP
|
||||
.B \-version
|
||||
Print the version numbers of the relevant libraries used.
|
||||
|
||||
.SH PER-FRAME OPTIONS
|
||||
The per-frame options are applied for the images following as arguments in the
|
||||
|
@ -1,5 +1,5 @@
|
||||
.\" Hey, EMACS: -*- nroff -*-
|
||||
.TH WEBPINFO 1 "November 24, 2017"
|
||||
.TH WEBPINFO 1 "May 08, 2017"
|
||||
.SH NAME
|
||||
webpinfo \- print out the chunk level structure of WebP files
|
||||
along with basic integrity checks.
|
||||
@ -22,19 +22,16 @@ WebP format.
|
||||
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.B \-version
|
||||
Print the version number (as major.minor.revision) and exit.
|
||||
.TP
|
||||
.B \-quiet
|
||||
.B -quiet
|
||||
Do not show chunk parsing information.
|
||||
.TP
|
||||
.B \-diag
|
||||
.B -diag
|
||||
Show parsing error diagnosis.
|
||||
.TP
|
||||
.B \-summary
|
||||
.B -summary
|
||||
Show chunk stats summary.
|
||||
.TP
|
||||
.BI \-bitstream_info
|
||||
.BI -bitstream_info
|
||||
Parse bitstream header.
|
||||
.TP
|
||||
.B \-h, \-help
|
||||
|
@ -1,5 +1,5 @@
|
||||
.\" Hey, EMACS: -*- nroff -*-
|
||||
.TH WEBPMUX 1 "December 1, 2017"
|
||||
.TH WEBPMUX 1 "November 10, 2016"
|
||||
.SH NAME
|
||||
webpmux \- create animated WebP files from non\-animated WebP images, extract
|
||||
frames from animated WebP images, and manage XMP/EXIF metadata and ICC profile.
|
||||
@ -48,8 +48,6 @@ frames from animated WebP images, and manage XMP/EXIF metadata and ICC profile.
|
||||
.B webpmux [\-h|\-help]
|
||||
.br
|
||||
.B webpmux \-version
|
||||
.br
|
||||
.B webpmux argument_file_name
|
||||
.SH DESCRIPTION
|
||||
This manual page documents the
|
||||
.B webpmux
|
||||
@ -57,9 +55,6 @@ command.
|
||||
.PP
|
||||
\fBwebpmux\fP can be used to create/extract from animated WebP files, as well as
|
||||
to add/extract/strip XMP/EXIF metadata and ICC profile.
|
||||
If a single file name (not starting with the character '\-') is supplied as
|
||||
the argument, the command line argument are actually tokenized from this file.
|
||||
This allows for easy scripting or using large number of arguments.
|
||||
.SH OPTIONS
|
||||
.SS GET_OPTIONS (\-get):
|
||||
.TP
|
||||
|
@ -22,7 +22,6 @@ commondir = $(includedir)/webp
|
||||
libwebp_la_SOURCES =
|
||||
libwebpinclude_HEADERS =
|
||||
libwebpinclude_HEADERS += webp/encode.h
|
||||
|
||||
noinst_HEADERS =
|
||||
noinst_HEADERS += webp/format_constants.h
|
||||
|
||||
@ -36,7 +35,7 @@ libwebp_la_LIBADD += utils/libwebputils.la
|
||||
# other than the ones listed on the command line, i.e., after linking, it will
|
||||
# not have unresolved symbols. Some platforms (Windows among them) require all
|
||||
# symbols in shared libraries to be resolved at library creation.
|
||||
libwebp_la_LDFLAGS = -no-undefined -version-info 7:2:0
|
||||
libwebp_la_LDFLAGS = -no-undefined -version-info 7:0:0
|
||||
libwebpincludedir = $(includedir)/webp
|
||||
pkgconfig_DATA = libwebp.pc
|
||||
|
||||
@ -48,7 +47,7 @@ if BUILD_LIBWEBPDECODER
|
||||
libwebpdecoder_la_LIBADD += dsp/libwebpdspdecode.la
|
||||
libwebpdecoder_la_LIBADD += utils/libwebputilsdecode.la
|
||||
|
||||
libwebpdecoder_la_LDFLAGS = -no-undefined -version-info 3:2:0
|
||||
libwebpdecoder_la_LDFLAGS = -no-undefined -version-info 3:0:0
|
||||
pkgconfig_DATA += libwebpdecoder.pc
|
||||
endif
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
AM_CPPFLAGS += -I$(top_builddir) -I$(top_srcdir)
|
||||
noinst_LTLIBRARIES = libwebpdecode.la
|
||||
|
||||
libwebpdecode_la_SOURCES =
|
||||
@ -25,5 +24,5 @@ libwebpdecodeinclude_HEADERS += ../webp/types.h
|
||||
noinst_HEADERS =
|
||||
noinst_HEADERS += ../webp/format_constants.h
|
||||
|
||||
libwebpdecode_la_CPPFLAGS = $(AM_CPPFLAGS)
|
||||
libwebpdecode_la_CPPFLAGS = $(AM_CPPFLAGS) $(USE_EXPERIMENTAL_CODE)
|
||||
libwebpdecodeincludedir = $(includedir)/webp
|
||||
|
@ -12,13 +12,13 @@
|
||||
// Author: Skal (pascal.massimino@gmail.com)
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "src/dec/alphai_dec.h"
|
||||
#include "src/dec/vp8i_dec.h"
|
||||
#include "src/dec/vp8li_dec.h"
|
||||
#include "src/dsp/dsp.h"
|
||||
#include "src/utils/quant_levels_dec_utils.h"
|
||||
#include "src/utils/utils.h"
|
||||
#include "src/webp/format_constants.h"
|
||||
#include "./alphai_dec.h"
|
||||
#include "./vp8i_dec.h"
|
||||
#include "./vp8li_dec.h"
|
||||
#include "../dsp/dsp.h"
|
||||
#include "../utils/quant_levels_dec_utils.h"
|
||||
#include "../utils/utils.h"
|
||||
#include "../webp/format_constants.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// ALPHDecoder object.
|
||||
|
@ -11,11 +11,11 @@
|
||||
//
|
||||
// Author: Urvang (urvang@google.com)
|
||||
|
||||
#ifndef WEBP_DEC_ALPHAI_DEC_H_
|
||||
#define WEBP_DEC_ALPHAI_DEC_H_
|
||||
#ifndef WEBP_DEC_ALPHAI_H_
|
||||
#define WEBP_DEC_ALPHAI_H_
|
||||
|
||||
#include "src/dec/webpi_dec.h"
|
||||
#include "src/utils/filters_utils.h"
|
||||
#include "./webpi_dec.h"
|
||||
#include "../utils/filters_utils.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -51,4 +51,4 @@ void WebPDeallocateAlphaMemory(VP8Decoder* const dec);
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif /* WEBP_DEC_ALPHAI_DEC_H_ */
|
||||
#endif /* WEBP_DEC_ALPHAI_H_ */
|
||||
|
@ -13,15 +13,15 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "src/dec/vp8i_dec.h"
|
||||
#include "src/dec/webpi_dec.h"
|
||||
#include "src/utils/utils.h"
|
||||
#include "./vp8i_dec.h"
|
||||
#include "./webpi_dec.h"
|
||||
#include "../utils/utils.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// WebPDecBuffer
|
||||
|
||||
// Number of bytes per pixel for the different color-spaces.
|
||||
static const uint8_t kModeBpp[MODE_LAST] = {
|
||||
static const int kModeBpp[MODE_LAST] = {
|
||||
3, 4, 3, 4, 4, 2, 2,
|
||||
4, 4, 4, 2, // pre-multiplied modes
|
||||
1, 1 };
|
||||
@ -36,7 +36,7 @@ static int IsValidColorspace(int webp_csp_mode) {
|
||||
// strictly speaking, the very last (or first, if flipped) row
|
||||
// doesn't require padding.
|
||||
#define MIN_BUFFER_SIZE(WIDTH, HEIGHT, STRIDE) \
|
||||
((uint64_t)(STRIDE) * ((HEIGHT) - 1) + (WIDTH))
|
||||
(uint64_t)(STRIDE) * ((HEIGHT) - 1) + (WIDTH)
|
||||
|
||||
static VP8StatusCode CheckDecBuffer(const WebPDecBuffer* const buffer) {
|
||||
int ok = 1;
|
||||
@ -98,14 +98,9 @@ static VP8StatusCode AllocateBuffer(WebPDecBuffer* const buffer) {
|
||||
uint64_t uv_size = 0, a_size = 0, total_size;
|
||||
// We need memory and it hasn't been allocated yet.
|
||||
// => initialize output buffer, now that dimensions are known.
|
||||
int stride;
|
||||
uint64_t size;
|
||||
const int stride = w * kModeBpp[mode];
|
||||
const uint64_t size = (uint64_t)stride * h;
|
||||
|
||||
if ((uint64_t)w * kModeBpp[mode] >= (1ull << 32)) {
|
||||
return VP8_STATUS_INVALID_PARAM;
|
||||
}
|
||||
stride = w * kModeBpp[mode];
|
||||
size = (uint64_t)stride * h;
|
||||
if (!WebPIsRGBMode(mode)) {
|
||||
uv_stride = (w + 1) / 2;
|
||||
uv_size = (uint64_t)uv_stride * ((h + 1) / 2);
|
||||
@ -174,11 +169,11 @@ VP8StatusCode WebPFlipBuffer(WebPDecBuffer* const buffer) {
|
||||
return VP8_STATUS_OK;
|
||||
}
|
||||
|
||||
VP8StatusCode WebPAllocateDecBuffer(int width, int height,
|
||||
VP8StatusCode WebPAllocateDecBuffer(int w, int h,
|
||||
const WebPDecoderOptions* const options,
|
||||
WebPDecBuffer* const buffer) {
|
||||
WebPDecBuffer* const out) {
|
||||
VP8StatusCode status;
|
||||
if (buffer == NULL || width <= 0 || height <= 0) {
|
||||
if (out == NULL || w <= 0 || h <= 0) {
|
||||
return VP8_STATUS_INVALID_PARAM;
|
||||
}
|
||||
if (options != NULL) { // First, apply options if there is any.
|
||||
@ -187,39 +182,33 @@ VP8StatusCode WebPAllocateDecBuffer(int width, int height,
|
||||
const int ch = options->crop_height;
|
||||
const int x = options->crop_left & ~1;
|
||||
const int y = options->crop_top & ~1;
|
||||
if (x < 0 || y < 0 || cw <= 0 || ch <= 0 ||
|
||||
x + cw > width || y + ch > height) {
|
||||
if (x < 0 || y < 0 || cw <= 0 || ch <= 0 || x + cw > w || y + ch > h) {
|
||||
return VP8_STATUS_INVALID_PARAM; // out of frame boundary.
|
||||
}
|
||||
width = cw;
|
||||
height = ch;
|
||||
w = cw;
|
||||
h = ch;
|
||||
}
|
||||
|
||||
if (options->use_scaling) {
|
||||
#if !defined(WEBP_REDUCE_SIZE)
|
||||
int scaled_width = options->scaled_width;
|
||||
int scaled_height = options->scaled_height;
|
||||
if (!WebPRescalerGetScaledDimensions(
|
||||
width, height, &scaled_width, &scaled_height)) {
|
||||
w, h, &scaled_width, &scaled_height)) {
|
||||
return VP8_STATUS_INVALID_PARAM;
|
||||
}
|
||||
width = scaled_width;
|
||||
height = scaled_height;
|
||||
#else
|
||||
return VP8_STATUS_INVALID_PARAM; // rescaling not supported
|
||||
#endif
|
||||
w = scaled_width;
|
||||
h = scaled_height;
|
||||
}
|
||||
}
|
||||
buffer->width = width;
|
||||
buffer->height = height;
|
||||
out->width = w;
|
||||
out->height = h;
|
||||
|
||||
// Then, allocate buffer for real.
|
||||
status = AllocateBuffer(buffer);
|
||||
status = AllocateBuffer(out);
|
||||
if (status != VP8_STATUS_OK) return status;
|
||||
|
||||
// Use the stride trick if vertical flip is needed.
|
||||
if (options != NULL && options->flip) {
|
||||
status = WebPFlipBuffer(buffer);
|
||||
status = WebPFlipBuffer(out);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
@ -11,8 +11,8 @@
|
||||
//
|
||||
// Author: Skal (pascal.massimino@gmail.com)
|
||||
|
||||
#ifndef WEBP_DEC_COMMON_DEC_H_
|
||||
#define WEBP_DEC_COMMON_DEC_H_
|
||||
#ifndef WEBP_DEC_COMMON_H_
|
||||
#define WEBP_DEC_COMMON_H_
|
||||
|
||||
// intra prediction modes
|
||||
enum { B_DC_PRED = 0, // 4x4 modes
|
||||
@ -51,4 +51,4 @@ enum { MB_FEATURE_TREE_PROBS = 3,
|
||||
NUM_PROBAS = 11
|
||||
};
|
||||
|
||||
#endif // WEBP_DEC_COMMON_DEC_H_
|
||||
#endif // WEBP_DEC_COMMON_H_
|
||||
|
@ -12,13 +12,13 @@
|
||||
// Author: Skal (pascal.massimino@gmail.com)
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "src/dec/vp8i_dec.h"
|
||||
#include "src/utils/utils.h"
|
||||
#include "./vp8i_dec.h"
|
||||
#include "../utils/utils.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Main reconstruction function.
|
||||
|
||||
static const uint16_t kScan[16] = {
|
||||
static const int kScan[16] = {
|
||||
0 + 0 * BPS, 4 + 0 * BPS, 8 + 0 * BPS, 12 + 0 * BPS,
|
||||
0 + 4 * BPS, 4 + 4 * BPS, 8 + 4 * BPS, 12 + 4 * BPS,
|
||||
0 + 8 * BPS, 4 + 8 * BPS, 8 + 8 * BPS, 12 + 8 * BPS,
|
||||
@ -320,7 +320,7 @@ static void PrecomputeFilterStrengths(VP8Decoder* const dec) {
|
||||
#define MIN_DITHER_AMP 4
|
||||
|
||||
#define DITHER_AMP_TAB_SIZE 12
|
||||
static const uint8_t kQuantToDitherAmp[DITHER_AMP_TAB_SIZE] = {
|
||||
static const int kQuantToDitherAmp[DITHER_AMP_TAB_SIZE] = {
|
||||
// roughly, it's dqm->uv_mat_[1]
|
||||
8, 7, 6, 4, 4, 2, 2, 2, 1, 1, 1, 1
|
||||
};
|
||||
@ -400,9 +400,7 @@ static void DitherRow(VP8Decoder* const dec) {
|
||||
#define MACROBLOCK_VPOS(mb_y) ((mb_y) * 16) // vertical position of a MB
|
||||
|
||||
// Finalize and transmit a complete row. Return false in case of user-abort.
|
||||
static int FinishRow(void* arg1, void* arg2) {
|
||||
VP8Decoder* const dec = (VP8Decoder*)arg1;
|
||||
VP8Io* const io = (VP8Io*)arg2;
|
||||
static int FinishRow(VP8Decoder* const dec, VP8Io* const io) {
|
||||
int ok = 1;
|
||||
const VP8ThreadContext* const ctx = &dec->thread_ctx_;
|
||||
const int cache_id = ctx->id_;
|
||||
@ -450,9 +448,10 @@ static int FinishRow(void* arg1, void* arg2) {
|
||||
if (y_end > io->crop_bottom) {
|
||||
y_end = io->crop_bottom; // make sure we don't overflow on last row.
|
||||
}
|
||||
// If dec->alpha_data_ is not NULL, we have some alpha plane present.
|
||||
io->a = NULL;
|
||||
if (dec->alpha_data_ != NULL && y_start < y_end) {
|
||||
// TODO(skal): testing presence of alpha with dec->alpha_data_ is not a
|
||||
// good idea.
|
||||
io->a = VP8DecompressAlphaRows(dec, io, y_start, y_end - y_start);
|
||||
if (io->a == NULL) {
|
||||
return VP8SetError(dec, VP8_STATUS_BITSTREAM_ERROR,
|
||||
@ -559,6 +558,7 @@ VP8StatusCode VP8EnterCritical(VP8Decoder* const dec, VP8Io* const io) {
|
||||
if (io->bypass_filtering) {
|
||||
dec->filter_type_ = 0;
|
||||
}
|
||||
// TODO(skal): filter type / strength / sharpness forcing
|
||||
|
||||
// Define the area where we can skip in-loop filtering, in case of cropping.
|
||||
//
|
||||
@ -569,6 +569,8 @@ VP8StatusCode VP8EnterCritical(VP8Decoder* const dec, VP8Io* const io) {
|
||||
// Means: there's a dependency chain that goes all the way up to the
|
||||
// top-left corner of the picture (MB #0). We must filter all the previous
|
||||
// macroblocks.
|
||||
// TODO(skal): add an 'approximate_decoding' option, that won't produce
|
||||
// a 1:1 bit-exactness for complex filtering?
|
||||
{
|
||||
const int extra_pixels = kFilterExtraRows[dec->filter_type_];
|
||||
if (dec->filter_type_ == 2) {
|
||||
@ -649,7 +651,7 @@ static int InitThreadContext(VP8Decoder* const dec) {
|
||||
}
|
||||
worker->data1 = dec;
|
||||
worker->data2 = (void*)&dec->thread_ctx_.io_;
|
||||
worker->hook = FinishRow;
|
||||
worker->hook = (WebPWorkerHook)FinishRow;
|
||||
dec->num_caches_ =
|
||||
(dec->filter_type_ > 0) ? MT_CACHE_LINES : MT_CACHE_LINES - 1;
|
||||
} else {
|
||||
@ -726,7 +728,7 @@ static int AllocateMemory(VP8Decoder* const dec) {
|
||||
}
|
||||
|
||||
mem = (uint8_t*)dec->mem_;
|
||||
dec->intra_t_ = mem;
|
||||
dec->intra_t_ = (uint8_t*)mem;
|
||||
mem += intra_pred_mode_size;
|
||||
|
||||
dec->yuv_t_ = (VP8TopSamples*)mem;
|
||||
@ -748,7 +750,7 @@ static int AllocateMemory(VP8Decoder* const dec) {
|
||||
|
||||
mem = (uint8_t*)WEBP_ALIGN(mem);
|
||||
assert((yuv_size & WEBP_ALIGN_CST) == 0);
|
||||
dec->yuv_b_ = mem;
|
||||
dec->yuv_b_ = (uint8_t*)mem;
|
||||
mem += yuv_size;
|
||||
|
||||
dec->mb_data_ = (VP8MBData*)mem;
|
||||
@ -764,7 +766,7 @@ static int AllocateMemory(VP8Decoder* const dec) {
|
||||
const int extra_rows = kFilterExtraRows[dec->filter_type_];
|
||||
const int extra_y = extra_rows * dec->cache_y_stride_;
|
||||
const int extra_uv = (extra_rows / 2) * dec->cache_uv_stride_;
|
||||
dec->cache_y_ = mem + extra_y;
|
||||
dec->cache_y_ = ((uint8_t*)mem) + extra_y;
|
||||
dec->cache_u_ = dec->cache_y_
|
||||
+ 16 * num_caches * dec->cache_y_stride_ + extra_uv;
|
||||
dec->cache_v_ = dec->cache_u_
|
||||
@ -774,7 +776,7 @@ static int AllocateMemory(VP8Decoder* const dec) {
|
||||
mem += cache_size;
|
||||
|
||||
// alpha plane
|
||||
dec->alpha_plane_ = alpha_size ? mem : NULL;
|
||||
dec->alpha_plane_ = alpha_size ? (uint8_t*)mem : NULL;
|
||||
mem += alpha_size;
|
||||
assert(mem <= (uint8_t*)dec->mem_ + dec->mem_size_);
|
||||
|
||||
|
@ -15,10 +15,10 @@
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "src/dec/alphai_dec.h"
|
||||
#include "src/dec/webpi_dec.h"
|
||||
#include "src/dec/vp8i_dec.h"
|
||||
#include "src/utils/utils.h"
|
||||
#include "./alphai_dec.h"
|
||||
#include "./webpi_dec.h"
|
||||
#include "./vp8i_dec.h"
|
||||
#include "../utils/utils.h"
|
||||
|
||||
// In append mode, buffer allocations increase as multiples of this value.
|
||||
// Needs to be a power of 2.
|
||||
@ -673,12 +673,12 @@ void WebPIDelete(WebPIDecoder* idec) {
|
||||
//------------------------------------------------------------------------------
|
||||
// Wrapper toward WebPINewDecoder
|
||||
|
||||
WebPIDecoder* WebPINewRGB(WEBP_CSP_MODE csp, uint8_t* output_buffer,
|
||||
WebPIDecoder* WebPINewRGB(WEBP_CSP_MODE mode, uint8_t* output_buffer,
|
||||
size_t output_buffer_size, int output_stride) {
|
||||
const int is_external_memory = (output_buffer != NULL) ? 1 : 0;
|
||||
WebPIDecoder* idec;
|
||||
|
||||
if (csp >= MODE_YUV) return NULL;
|
||||
if (mode >= MODE_YUV) return NULL;
|
||||
if (is_external_memory == 0) { // Overwrite parameters to sane values.
|
||||
output_buffer_size = 0;
|
||||
output_stride = 0;
|
||||
@ -689,7 +689,7 @@ WebPIDecoder* WebPINewRGB(WEBP_CSP_MODE csp, uint8_t* output_buffer,
|
||||
}
|
||||
idec = WebPINewDecoder(NULL);
|
||||
if (idec == NULL) return NULL;
|
||||
idec->output_.colorspace = csp;
|
||||
idec->output_.colorspace = mode;
|
||||
idec->output_.is_external_memory = is_external_memory;
|
||||
idec->output_.u.RGBA.rgba = output_buffer;
|
||||
idec->output_.u.RGBA.stride = output_stride;
|
||||
|
@ -13,11 +13,11 @@
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include "src/dec/vp8i_dec.h"
|
||||
#include "src/dec/webpi_dec.h"
|
||||
#include "src/dsp/dsp.h"
|
||||
#include "src/dsp/yuv.h"
|
||||
#include "src/utils/utils.h"
|
||||
#include "../dec/vp8i_dec.h"
|
||||
#include "./webpi_dec.h"
|
||||
#include "../dsp/dsp.h"
|
||||
#include "../dsp/yuv.h"
|
||||
#include "../utils/utils.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Main YUV<->RGB conversion functions
|
||||
@ -212,7 +212,7 @@ static int EmitAlphaRGBA4444(const VP8Io* const io, WebPDecParams* const p,
|
||||
int num_rows;
|
||||
const int start_y = GetAlphaSourceRow(io, &alpha, &num_rows);
|
||||
uint8_t* const base_rgba = buf->rgba + start_y * buf->stride;
|
||||
#if (WEBP_SWAP_16BIT_CSP == 1)
|
||||
#ifdef WEBP_SWAP_16BIT_CSP
|
||||
uint8_t* alpha_dst = base_rgba;
|
||||
#else
|
||||
uint8_t* alpha_dst = base_rgba + 1;
|
||||
@ -241,7 +241,6 @@ static int EmitAlphaRGBA4444(const VP8Io* const io, WebPDecParams* const p,
|
||||
//------------------------------------------------------------------------------
|
||||
// YUV rescaling (no final RGB conversion needed)
|
||||
|
||||
#if !defined(WEBP_REDUCE_SIZE)
|
||||
static int Rescale(const uint8_t* src, int src_stride,
|
||||
int new_lines, WebPRescaler* const wrk) {
|
||||
int num_lines_out = 0;
|
||||
@ -432,7 +431,7 @@ static int ExportAlphaRGBA4444(WebPDecParams* const p, int y_pos,
|
||||
int max_lines_out) {
|
||||
const WebPRGBABuffer* const buf = &p->output->u.RGBA;
|
||||
uint8_t* const base_rgba = buf->rgba + y_pos * buf->stride;
|
||||
#if (WEBP_SWAP_16BIT_CSP == 1)
|
||||
#ifdef WEBP_SWAP_16BIT_CSP
|
||||
uint8_t* alpha_dst = base_rgba;
|
||||
#else
|
||||
uint8_t* alpha_dst = base_rgba + 1;
|
||||
@ -542,8 +541,6 @@ static int InitRGBRescaler(const VP8Io* const io, WebPDecParams* const p) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif // WEBP_REDUCE_SIZE
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Default custom functions
|
||||
|
||||
@ -564,14 +561,10 @@ static int CustomSetup(VP8Io* io) {
|
||||
WebPInitUpsamplers();
|
||||
}
|
||||
if (io->use_scaling) {
|
||||
#if !defined(WEBP_REDUCE_SIZE)
|
||||
const int ok = is_rgb ? InitRGBRescaler(io, p) : InitYUVRescaler(io, p);
|
||||
if (!ok) {
|
||||
return 0; // memory error
|
||||
}
|
||||
#else
|
||||
return 0; // rescaling support not compiled
|
||||
#endif
|
||||
} else {
|
||||
if (is_rgb) {
|
||||
WebPInitSamplers();
|
||||
@ -605,6 +598,9 @@ static int CustomSetup(VP8Io* io) {
|
||||
}
|
||||
}
|
||||
|
||||
if (is_rgb) {
|
||||
VP8YUVInit();
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -11,7 +11,7 @@
|
||||
//
|
||||
// Author: Skal (pascal.massimino@gmail.com)
|
||||
|
||||
#include "src/dec/vp8i_dec.h"
|
||||
#include "./vp8i_dec.h"
|
||||
|
||||
static WEBP_INLINE int clip(int v, int M) {
|
||||
return v < 0 ? 0 : v > M ? M : v;
|
||||
|
@ -11,19 +11,15 @@
|
||||
//
|
||||
// Author: Skal (pascal.massimino@gmail.com)
|
||||
|
||||
#include "src/dec/vp8i_dec.h"
|
||||
#include "src/utils/bit_reader_inl_utils.h"
|
||||
#include "./vp8i_dec.h"
|
||||
#include "../utils/bit_reader_inl_utils.h"
|
||||
|
||||
#if !defined(USE_GENERIC_TREE)
|
||||
#if !defined(__arm__) && !defined(_M_ARM) && !defined(__aarch64__)
|
||||
// using a table is ~1-2% slower on ARM. Prefer the coded-tree approach then.
|
||||
#define USE_GENERIC_TREE 1 // ALTERNATE_CODE
|
||||
#else
|
||||
#define USE_GENERIC_TREE 0
|
||||
#define USE_GENERIC_TREE
|
||||
#endif
|
||||
#endif // USE_GENERIC_TREE
|
||||
|
||||
#if (USE_GENERIC_TREE == 1)
|
||||
#ifdef USE_GENERIC_TREE
|
||||
static const int8_t kYModesIntra4[18] = {
|
||||
-B_DC_PRED, 1,
|
||||
-B_TM_PRED, 2,
|
||||
@ -321,7 +317,7 @@ static void ParseIntraMode(VP8BitReader* const br,
|
||||
int x;
|
||||
for (x = 0; x < 4; ++x) {
|
||||
const uint8_t* const prob = kBModesProba[top[x]][ymode];
|
||||
#if (USE_GENERIC_TREE == 1)
|
||||
#ifdef USE_GENERIC_TREE
|
||||
// Generic tree-parsing
|
||||
int i = kYModesIntra4[VP8GetBit(br, prob[0])];
|
||||
while (i > 0) {
|
||||
@ -502,7 +498,7 @@ static const uint8_t
|
||||
|
||||
// Paragraph 9.9
|
||||
|
||||
static const uint8_t kBands[16 + 1] = {
|
||||
static const int kBands[16 + 1] = {
|
||||
0, 1, 2, 3, 6, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6, 7,
|
||||
0 // extra entry as sentinel
|
||||
};
|
||||
|
@ -13,12 +13,12 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "src/dec/alphai_dec.h"
|
||||
#include "src/dec/vp8i_dec.h"
|
||||
#include "src/dec/vp8li_dec.h"
|
||||
#include "src/dec/webpi_dec.h"
|
||||
#include "src/utils/bit_reader_inl_utils.h"
|
||||
#include "src/utils/utils.h"
|
||||
#include "./alphai_dec.h"
|
||||
#include "./vp8i_dec.h"
|
||||
#include "./vp8li_dec.h"
|
||||
#include "./webpi_dec.h"
|
||||
#include "../utils/bit_reader_inl_utils.h"
|
||||
#include "../utils/utils.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@ -491,7 +491,7 @@ static int GetCoeffsAlt(VP8BitReader* const br,
|
||||
return 16;
|
||||
}
|
||||
|
||||
static WEBP_TSAN_IGNORE_FUNCTION void InitGetCoeffs(void) {
|
||||
WEBP_TSAN_IGNORE_FUNCTION static void InitGetCoeffs(void) {
|
||||
if (GetCoeffs == NULL) {
|
||||
if (VP8GetCPUInfo != NULL && VP8GetCPUInfo(kSlowSSSE3)) {
|
||||
GetCoeffs = GetCoeffsAlt;
|
||||
|
@ -11,10 +11,10 @@
|
||||
//
|
||||
// Author: Skal (pascal.massimino@gmail.com)
|
||||
|
||||
#ifndef WEBP_DEC_VP8_DEC_H_
|
||||
#define WEBP_DEC_VP8_DEC_H_
|
||||
#ifndef WEBP_WEBP_DECODE_VP8_H_
|
||||
#define WEBP_WEBP_DECODE_VP8_H_
|
||||
|
||||
#include "src/webp/decode.h"
|
||||
#include "../webp/decode.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -157,24 +157,24 @@ void VP8Delete(VP8Decoder* const dec);
|
||||
// Miscellaneous VP8/VP8L bitstream probing functions.
|
||||
|
||||
// Returns true if the next 3 bytes in data contain the VP8 signature.
|
||||
WEBP_EXTERN int VP8CheckSignature(const uint8_t* const data, size_t data_size);
|
||||
WEBP_EXTERN(int) VP8CheckSignature(const uint8_t* const data, size_t data_size);
|
||||
|
||||
// Validates the VP8 data-header and retrieves basic header information viz
|
||||
// width and height. Returns 0 in case of formatting error. *width/*height
|
||||
// can be passed NULL.
|
||||
WEBP_EXTERN int VP8GetInfo(
|
||||
WEBP_EXTERN(int) VP8GetInfo(
|
||||
const uint8_t* data,
|
||||
size_t data_size, // data available so far
|
||||
size_t chunk_size, // total data size expected in the chunk
|
||||
int* const width, int* const height);
|
||||
|
||||
// Returns true if the next byte(s) in data is a VP8L signature.
|
||||
WEBP_EXTERN int VP8LCheckSignature(const uint8_t* const data, size_t size);
|
||||
WEBP_EXTERN(int) VP8LCheckSignature(const uint8_t* const data, size_t size);
|
||||
|
||||
// Validates the VP8L data-header and retrieves basic header information viz
|
||||
// width, height and alpha. Returns 0 in case of formatting error.
|
||||
// width/height/has_alpha can be passed NULL.
|
||||
WEBP_EXTERN int VP8LGetInfo(
|
||||
WEBP_EXTERN(int) VP8LGetInfo(
|
||||
const uint8_t* data, size_t data_size, // data available so far
|
||||
int* const width, int* const height, int* const has_alpha);
|
||||
|
||||
@ -182,4 +182,4 @@ WEBP_EXTERN int VP8LGetInfo(
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif /* WEBP_DEC_VP8_DEC_H_ */
|
||||
#endif /* WEBP_WEBP_DECODE_VP8_H_ */
|
||||
|
@ -11,16 +11,16 @@
|
||||
//
|
||||
// Author: Skal (pascal.massimino@gmail.com)
|
||||
|
||||
#ifndef WEBP_DEC_VP8I_DEC_H_
|
||||
#define WEBP_DEC_VP8I_DEC_H_
|
||||
#ifndef WEBP_DEC_VP8I_H_
|
||||
#define WEBP_DEC_VP8I_H_
|
||||
|
||||
#include <string.h> // for memcpy()
|
||||
#include "src/dec/common_dec.h"
|
||||
#include "src/dec/vp8li_dec.h"
|
||||
#include "src/utils/bit_reader_utils.h"
|
||||
#include "src/utils/random_utils.h"
|
||||
#include "src/utils/thread_utils.h"
|
||||
#include "src/dsp/dsp.h"
|
||||
#include "./common_dec.h"
|
||||
#include "./vp8li_dec.h"
|
||||
#include "../utils/bit_reader_utils.h"
|
||||
#include "../utils/random_utils.h"
|
||||
#include "../utils/thread_utils.h"
|
||||
#include "../dsp/dsp.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -30,8 +30,8 @@ extern "C" {
|
||||
// Various defines and enums
|
||||
|
||||
// version numbers
|
||||
#define DEC_MAJ_VERSION 1
|
||||
#define DEC_MIN_VERSION 0
|
||||
#define DEC_MAJ_VERSION 0
|
||||
#define DEC_MIN_VERSION 6
|
||||
#define DEC_REV_VERSION 0
|
||||
|
||||
// YUV-cache parameters. Cache is 32-bytes wide (= one cacheline).
|
||||
@ -57,6 +57,7 @@ extern "C" {
|
||||
// '|' = left sample, '-' = top sample, '+' = top-left sample
|
||||
// 't' = extra top-right sample for 4x4 modes
|
||||
#define YUV_SIZE (BPS * 17 + BPS * 9)
|
||||
#define Y_SIZE (BPS * 17)
|
||||
#define Y_OFF (BPS * 1 + 8)
|
||||
#define U_OFF (Y_OFF + BPS * 16 + BPS)
|
||||
#define V_OFF (U_OFF + 16)
|
||||
@ -316,4 +317,4 @@ const uint8_t* VP8DecompressAlphaRows(VP8Decoder* const dec,
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif /* WEBP_DEC_VP8I_DEC_H_ */
|
||||
#endif /* WEBP_DEC_VP8I_H_ */
|
||||
|
@ -14,22 +14,22 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "src/dec/alphai_dec.h"
|
||||
#include "src/dec/vp8li_dec.h"
|
||||
#include "src/dsp/dsp.h"
|
||||
#include "src/dsp/lossless.h"
|
||||
#include "src/dsp/lossless_common.h"
|
||||
#include "src/dsp/yuv.h"
|
||||
#include "src/utils/endian_inl_utils.h"
|
||||
#include "src/utils/huffman_utils.h"
|
||||
#include "src/utils/utils.h"
|
||||
#include "./alphai_dec.h"
|
||||
#include "./vp8li_dec.h"
|
||||
#include "../dsp/dsp.h"
|
||||
#include "../dsp/lossless.h"
|
||||
#include "../dsp/lossless_common.h"
|
||||
#include "../dsp/yuv.h"
|
||||
#include "../utils/endian_inl_utils.h"
|
||||
#include "../utils/huffman_utils.h"
|
||||
#include "../utils/utils.h"
|
||||
|
||||
#define NUM_ARGB_CACHE_ROWS 16
|
||||
|
||||
static const int kCodeLengthLiterals = 16;
|
||||
static const int kCodeLengthRepeatCode = 16;
|
||||
static const uint8_t kCodeLengthExtraBits[3] = { 2, 3, 7 };
|
||||
static const uint8_t kCodeLengthRepeatOffsets[3] = { 3, 3, 11 };
|
||||
static const int kCodeLengthExtraBits[3] = { 2, 3, 7 };
|
||||
static const int kCodeLengthRepeatOffsets[3] = { 3, 3, 11 };
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Five Huffman codes are used at each meta code:
|
||||
@ -86,7 +86,7 @@ static const uint8_t kCodeToPlane[CODE_TO_PLANE_CODES] = {
|
||||
// All values computed for 8-bit first level lookup with Mark Adler's tool:
|
||||
// http://www.hdfgroup.org/ftp/lib-external/zlib/zlib-1.2.5/examples/enough.c
|
||||
#define FIXED_TABLE_SIZE (630 * 3 + 410)
|
||||
static const uint16_t kTableSize[12] = {
|
||||
static const int kTableSize[12] = {
|
||||
FIXED_TABLE_SIZE + 654,
|
||||
FIXED_TABLE_SIZE + 656,
|
||||
FIXED_TABLE_SIZE + 658,
|
||||
@ -485,7 +485,6 @@ static int ReadHuffmanCodes(VP8LDecoder* const dec, int xsize, int ysize,
|
||||
//------------------------------------------------------------------------------
|
||||
// Scaling.
|
||||
|
||||
#if !defined(WEBP_REDUCE_SIZE)
|
||||
static int AllocateAndInitRescaler(VP8LDecoder* const dec, VP8Io* const io) {
|
||||
const int num_channels = 4;
|
||||
const int in_width = io->mb_w;
|
||||
@ -517,13 +516,10 @@ static int AllocateAndInitRescaler(VP8LDecoder* const dec, VP8Io* const io) {
|
||||
out_width, out_height, 0, num_channels, work);
|
||||
return 1;
|
||||
}
|
||||
#endif // WEBP_REDUCE_SIZE
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Export to ARGB
|
||||
|
||||
#if !defined(WEBP_REDUCE_SIZE)
|
||||
|
||||
// We have special "export" function since we need to convert from BGRA
|
||||
static int Export(WebPRescaler* const rescaler, WEBP_CSP_MODE colorspace,
|
||||
int rgba_stride, uint8_t* const rgba) {
|
||||
@ -565,8 +561,6 @@ static int EmitRescaledRowsRGBA(const VP8LDecoder* const dec,
|
||||
return num_lines_out;
|
||||
}
|
||||
|
||||
#endif // WEBP_REDUCE_SIZE
|
||||
|
||||
// Emit rows without any scaling.
|
||||
static int EmitRows(WEBP_CSP_MODE colorspace,
|
||||
const uint8_t* row_in, int in_stride,
|
||||
@ -752,12 +746,9 @@ static void ProcessRows(VP8LDecoder* const dec, int row) {
|
||||
if (WebPIsRGBMode(output->colorspace)) { // convert to RGBA
|
||||
const WebPRGBABuffer* const buf = &output->u.RGBA;
|
||||
uint8_t* const rgba = buf->rgba + dec->last_out_row_ * buf->stride;
|
||||
const int num_rows_out =
|
||||
#if !defined(WEBP_REDUCE_SIZE)
|
||||
io->use_scaling ?
|
||||
const int num_rows_out = io->use_scaling ?
|
||||
EmitRescaledRowsRGBA(dec, rows_data, in_stride, io->mb_h,
|
||||
rgba, buf->stride) :
|
||||
#endif // WEBP_REDUCE_SIZE
|
||||
EmitRows(output->colorspace, rows_data, in_stride,
|
||||
io->mb_w, io->mb_h, rgba, buf->stride);
|
||||
// Update 'last_out_row_'.
|
||||
@ -1641,19 +1632,12 @@ int VP8LDecodeImage(VP8LDecoder* const dec) {
|
||||
|
||||
if (!AllocateInternalBuffers32b(dec, io->width)) goto Err;
|
||||
|
||||
#if !defined(WEBP_REDUCE_SIZE)
|
||||
if (io->use_scaling && !AllocateAndInitRescaler(dec, io)) goto Err;
|
||||
#else
|
||||
if (io->use_scaling) {
|
||||
dec->status_ = VP8_STATUS_INVALID_PARAM;
|
||||
goto Err;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (io->use_scaling || WebPIsPremultipliedMode(dec->output_->colorspace)) {
|
||||
// need the alpha-multiply functions for premultiplied output or rescaling
|
||||
WebPInitAlphaProcessing();
|
||||
}
|
||||
|
||||
if (!WebPIsRGBMode(dec->output_->colorspace)) {
|
||||
WebPInitConvertARGBToYUV();
|
||||
if (dec->output_->u.YUVA.a != NULL) WebPInitAlphaProcessing();
|
||||
|
@ -12,14 +12,14 @@
|
||||
// Author: Skal (pascal.massimino@gmail.com)
|
||||
// Vikas Arora(vikaas.arora@gmail.com)
|
||||
|
||||
#ifndef WEBP_DEC_VP8LI_DEC_H_
|
||||
#define WEBP_DEC_VP8LI_DEC_H_
|
||||
#ifndef WEBP_DEC_VP8LI_H_
|
||||
#define WEBP_DEC_VP8LI_H_
|
||||
|
||||
#include <string.h> // for memcpy()
|
||||
#include "src/dec/webpi_dec.h"
|
||||
#include "src/utils/bit_reader_utils.h"
|
||||
#include "src/utils/color_cache_utils.h"
|
||||
#include "src/utils/huffman_utils.h"
|
||||
#include "./webpi_dec.h"
|
||||
#include "../utils/bit_reader_utils.h"
|
||||
#include "../utils/color_cache_utils.h"
|
||||
#include "../utils/huffman_utils.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -132,4 +132,4 @@ void VP8LDelete(VP8LDecoder* const dec);
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif /* WEBP_DEC_VP8LI_DEC_H_ */
|
||||
#endif /* WEBP_DEC_VP8LI_H_ */
|
||||
|
@ -13,11 +13,11 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "src/dec/vp8i_dec.h"
|
||||
#include "src/dec/vp8li_dec.h"
|
||||
#include "src/dec/webpi_dec.h"
|
||||
#include "src/utils/utils.h"
|
||||
#include "src/webp/mux_types.h" // ALPHA_FLAG
|
||||
#include "./vp8i_dec.h"
|
||||
#include "./vp8li_dec.h"
|
||||
#include "./webpi_dec.h"
|
||||
#include "../utils/utils.h"
|
||||
#include "../webp/mux_types.h" // ALPHA_FLAG
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// RIFF layout is:
|
||||
@ -421,9 +421,7 @@ VP8StatusCode WebPParseHeaders(WebPHeaderStructure* const headers) {
|
||||
NULL, NULL, NULL, &has_animation,
|
||||
NULL, headers);
|
||||
if (status == VP8_STATUS_OK || status == VP8_STATUS_NOT_ENOUGH_DATA) {
|
||||
// The WebPDemux API + libwebp can be used to decode individual
|
||||
// uncomposited frames or the WebPAnimDecoder can be used to fully
|
||||
// reconstruct them (see webp/demux.h).
|
||||
// TODO(jzern): full support of animation frames will require API additions.
|
||||
if (has_animation) {
|
||||
status = VP8_STATUS_UNSUPPORTED_FEATURE;
|
||||
}
|
||||
|
@ -11,15 +11,15 @@
|
||||
//
|
||||
// Author: somnath@google.com (Somnath Banerjee)
|
||||
|
||||
#ifndef WEBP_DEC_WEBPI_DEC_H_
|
||||
#define WEBP_DEC_WEBPI_DEC_H_
|
||||
#ifndef WEBP_DEC_WEBPI_H_
|
||||
#define WEBP_DEC_WEBPI_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "src/utils/rescaler_utils.h"
|
||||
#include "src/dec/vp8_dec.h"
|
||||
#include "../utils/rescaler_utils.h"
|
||||
#include "./vp8_dec.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// WebPDecParams: Decoding output parameters. Transient internal object.
|
||||
@ -130,4 +130,4 @@ int WebPAvoidSlowMemory(const WebPDecBuffer* const output,
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif /* WEBP_DEC_WEBPI_DEC_H_ */
|
||||
#endif /* WEBP_DEC_WEBPI_H_ */
|
||||
|
@ -1,18 +1,14 @@
|
||||
AM_CPPFLAGS += -I$(top_builddir) -I$(top_srcdir)
|
||||
lib_LTLIBRARIES = libwebpdemux.la
|
||||
|
||||
libwebpdemux_la_SOURCES =
|
||||
libwebpdemux_la_SOURCES += anim_decode.c demux.c
|
||||
|
||||
libwebpdemuxinclude_HEADERS =
|
||||
libwebpdemuxinclude_HEADERS += ../webp/decode.h
|
||||
libwebpdemuxinclude_HEADERS += ../webp/demux.h
|
||||
libwebpdemuxinclude_HEADERS += ../webp/mux_types.h
|
||||
libwebpdemuxinclude_HEADERS += ../webp/types.h
|
||||
noinst_HEADERS =
|
||||
noinst_HEADERS += ../webp/format_constants.h
|
||||
|
||||
libwebpdemux_la_LIBADD = ../libwebp.la
|
||||
libwebpdemux_la_LDFLAGS = -no-undefined -version-info 2:4:0
|
||||
libwebpdemux_la_LDFLAGS = -no-undefined -version-info 2:2:0
|
||||
libwebpdemuxincludedir = $(includedir)/webp
|
||||
pkgconfig_DATA = libwebpdemux.pc
|
||||
|
@ -11,15 +11,15 @@
|
||||
//
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "src/webp/config.h"
|
||||
#include "../webp/config.h"
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "src/utils/utils.h"
|
||||
#include "src/webp/decode.h"
|
||||
#include "src/webp/demux.h"
|
||||
#include "../utils/utils.h"
|
||||
#include "../webp/decode.h"
|
||||
#include "../webp/demux.h"
|
||||
|
||||
#define NUM_CHANNELS 4
|
||||
|
||||
|
@ -11,21 +11,21 @@
|
||||
//
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "src/webp/config.h"
|
||||
#include "../webp/config.h"
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "src/utils/utils.h"
|
||||
#include "src/webp/decode.h" // WebPGetFeatures
|
||||
#include "src/webp/demux.h"
|
||||
#include "src/webp/format_constants.h"
|
||||
#include "../utils/utils.h"
|
||||
#include "../webp/decode.h" // WebPGetFeatures
|
||||
#include "../webp/demux.h"
|
||||
#include "../webp/format_constants.h"
|
||||
|
||||
#define DMUX_MAJ_VERSION 1
|
||||
#define DMUX_MIN_VERSION 0
|
||||
#define DMUX_REV_VERSION 0
|
||||
#define DMUX_MAJ_VERSION 0
|
||||
#define DMUX_MIN_VERSION 3
|
||||
#define DMUX_REV_VERSION 2
|
||||
|
||||
typedef struct {
|
||||
size_t start_; // start location of the data
|
||||
@ -205,14 +205,12 @@ static void SetFrameInfo(size_t start_offset, size_t size,
|
||||
frame->complete_ = complete;
|
||||
}
|
||||
|
||||
// Store image bearing chunks to 'frame'. 'min_size' is an optional size
|
||||
// requirement, it may be zero.
|
||||
// Store image bearing chunks to 'frame'.
|
||||
static ParseStatus StoreFrame(int frame_num, uint32_t min_size,
|
||||
MemBuffer* const mem, Frame* const frame) {
|
||||
int alpha_chunks = 0;
|
||||
int image_chunks = 0;
|
||||
int done = (MemDataSize(mem) < CHUNK_HEADER_SIZE ||
|
||||
MemDataSize(mem) < min_size);
|
||||
int done = (MemDataSize(mem) < min_size);
|
||||
ParseStatus status = PARSE_OK;
|
||||
|
||||
if (done) return PARSE_NEED_MORE_DATA;
|
||||
@ -403,9 +401,9 @@ static ParseStatus ParseSingleImage(WebPDemuxer* const dmux) {
|
||||
frame = (Frame*)WebPSafeCalloc(1ULL, sizeof(*frame));
|
||||
if (frame == NULL) return PARSE_ERROR;
|
||||
|
||||
// For the single image case we allow parsing of a partial frame, so no
|
||||
// minimum size is imposed here.
|
||||
status = StoreFrame(1, 0, &dmux->mem_, frame);
|
||||
// For the single image case we allow parsing of a partial frame, but we need
|
||||
// at least CHUNK_HEADER_SIZE for parsing.
|
||||
status = StoreFrame(1, CHUNK_HEADER_SIZE, &dmux->mem_, frame);
|
||||
if (status != PARSE_ERROR) {
|
||||
const int has_alpha = !!(dmux->feature_flags_ & ALPHA_FLAG);
|
||||
// Clear any alpha when the alpha flag is missing.
|
||||
|
@ -6,8 +6,8 @@
|
||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 1,0,0,0
|
||||
PRODUCTVERSION 1,0,0,0
|
||||
FILEVERSION 0,3,0,2
|
||||
PRODUCTVERSION 0,3,0,2
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
@ -24,12 +24,12 @@ BEGIN
|
||||
BEGIN
|
||||
VALUE "CompanyName", "Google, Inc."
|
||||
VALUE "FileDescription", "libwebpdemux DLL"
|
||||
VALUE "FileVersion", "1.0.0"
|
||||
VALUE "FileVersion", "0.3.2"
|
||||
VALUE "InternalName", "libwebpdemux.dll"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2018"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2017"
|
||||
VALUE "OriginalFilename", "libwebpdemux.dll"
|
||||
VALUE "ProductName", "WebP Image Demuxer"
|
||||
VALUE "ProductVersion", "1.0.0"
|
||||
VALUE "ProductVersion", "0.3.2"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
|
@ -1,15 +1,9 @@
|
||||
AM_CPPFLAGS += -I$(top_builddir) -I$(top_srcdir)
|
||||
noinst_LTLIBRARIES =
|
||||
noinst_LTLIBRARIES += libwebpdsp.la
|
||||
noinst_LTLIBRARIES += libwebpdsp_avx2.la
|
||||
noinst_LTLIBRARIES += libwebpdsp_sse2.la
|
||||
noinst_LTLIBRARIES += libwebpdspdecode_sse2.la
|
||||
noinst_LTLIBRARIES += libwebpdsp_sse41.la
|
||||
noinst_LTLIBRARIES += libwebpdspdecode_sse41.la
|
||||
noinst_LTLIBRARIES += libwebpdsp_neon.la
|
||||
noinst_LTLIBRARIES += libwebpdspdecode_neon.la
|
||||
noinst_LTLIBRARIES += libwebpdsp_msa.la
|
||||
noinst_LTLIBRARIES += libwebpdspdecode_msa.la
|
||||
noinst_LTLIBRARIES = libwebpdsp.la libwebpdsp_avx2.la
|
||||
noinst_LTLIBRARIES += libwebpdsp_sse2.la libwebpdspdecode_sse2.la
|
||||
noinst_LTLIBRARIES += libwebpdsp_sse41.la libwebpdspdecode_sse41.la
|
||||
noinst_LTLIBRARIES += libwebpdsp_neon.la libwebpdspdecode_neon.la
|
||||
noinst_LTLIBRARIES += libwebpdsp_msa.la libwebpdspdecode_msa.la
|
||||
noinst_LTLIBRARIES += libwebpdspdecode_wasm.la
|
||||
|
||||
if BUILD_LIBWEBPDECODER
|
||||
noinst_LTLIBRARIES += libwebpdspdecode.la
|
||||
@ -46,6 +40,8 @@ COMMON_SOURCES += yuv_mips32.c
|
||||
COMMON_SOURCES += yuv_mips_dsp_r2.c
|
||||
|
||||
ENC_SOURCES =
|
||||
ENC_SOURCES += argb.c
|
||||
ENC_SOURCES += argb_mips_dsp_r2.c
|
||||
ENC_SOURCES += cost.c
|
||||
ENC_SOURCES += cost_mips32.c
|
||||
ENC_SOURCES += cost_mips_dsp_r2.c
|
||||
@ -65,8 +61,6 @@ libwebpdsp_avx2_la_CFLAGS = $(AM_CFLAGS) $(AVX2_FLAGS)
|
||||
libwebpdspdecode_sse41_la_SOURCES =
|
||||
libwebpdspdecode_sse41_la_SOURCES += alpha_processing_sse41.c
|
||||
libwebpdspdecode_sse41_la_SOURCES += dec_sse41.c
|
||||
libwebpdspdecode_sse41_la_SOURCES += upsampling_sse41.c
|
||||
libwebpdspdecode_sse41_la_SOURCES += yuv_sse41.c
|
||||
libwebpdspdecode_sse41_la_CPPFLAGS = $(libwebpdsp_la_CPPFLAGS)
|
||||
libwebpdspdecode_sse41_la_CFLAGS = $(AM_CFLAGS) $(SSE41_FLAGS)
|
||||
|
||||
@ -103,7 +97,12 @@ libwebpdspdecode_msa_la_SOURCES += upsampling_msa.c
|
||||
libwebpdspdecode_msa_la_CPPFLAGS = $(libwebpdsp_msa_la_CPPFLAGS)
|
||||
libwebpdspdecode_msa_la_CFLAGS = $(libwebpdsp_msa_la_CFLAGS)
|
||||
|
||||
# WASM is not fully integrated into configure; the addition here keeps source
|
||||
# extraction by cmake simple.
|
||||
libwebpdspdecode_wasm_la_SOURCES = dec_wasm.c
|
||||
|
||||
libwebpdsp_sse2_la_SOURCES =
|
||||
libwebpdsp_sse2_la_SOURCES += argb_sse2.c
|
||||
libwebpdsp_sse2_la_SOURCES += cost_sse2.c
|
||||
libwebpdsp_sse2_la_SOURCES += enc_sse2.c
|
||||
libwebpdsp_sse2_la_SOURCES += lossless_enc_sse2.c
|
||||
@ -141,11 +140,10 @@ noinst_HEADERS += ../webp/decode.h
|
||||
|
||||
libwebpdsp_la_CPPFLAGS =
|
||||
libwebpdsp_la_CPPFLAGS += $(AM_CPPFLAGS)
|
||||
libwebpdsp_la_CPPFLAGS += $(USE_SWAP_16BIT_CSP)
|
||||
libwebpdsp_la_CPPFLAGS += $(USE_EXPERIMENTAL_CODE) $(USE_SWAP_16BIT_CSP)
|
||||
libwebpdsp_la_LDFLAGS = -lm
|
||||
libwebpdsp_la_LIBADD =
|
||||
libwebpdsp_la_LIBADD += libwebpdsp_avx2.la
|
||||
libwebpdsp_la_LIBADD += libwebpdsp_sse2.la
|
||||
libwebpdsp_la_LIBADD += libwebpdsp_avx2.la libwebpdsp_sse2.la
|
||||
libwebpdsp_la_LIBADD += libwebpdsp_sse41.la
|
||||
libwebpdsp_la_LIBADD += libwebpdsp_neon.la
|
||||
libwebpdsp_la_LIBADD += libwebpdsp_msa.la
|
||||
|
@ -12,13 +12,10 @@
|
||||
// Author: Skal (pascal.massimino@gmail.com)
|
||||
|
||||
#include <assert.h>
|
||||
#include "src/dsp/dsp.h"
|
||||
#include "./dsp.h"
|
||||
|
||||
// Tables can be faster on some platform but incur some extra binary size (~2k).
|
||||
#if !defined(USE_TABLES_FOR_ALPHA_MULT)
|
||||
#define USE_TABLES_FOR_ALPHA_MULT 0 // ALTERNATE_CODE
|
||||
#endif
|
||||
|
||||
// #define USE_TABLES_FOR_ALPHA_MULT
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
@ -32,7 +29,7 @@ static uint32_t Mult(uint8_t x, uint32_t mult) {
|
||||
return v;
|
||||
}
|
||||
|
||||
#if (USE_TABLES_FOR_ALPHA_MULT == 1)
|
||||
#ifdef USE_TABLES_FOR_ALPHA_MULT
|
||||
|
||||
static const uint32_t kMultTables[2][256] = {
|
||||
{ // (255u << MFIX) / alpha
|
||||
@ -137,7 +134,7 @@ static WEBP_INLINE uint32_t GetScale(uint32_t a, int inverse) {
|
||||
|
||||
#endif // USE_TABLES_FOR_ALPHA_MULT
|
||||
|
||||
void WebPMultARGBRow_C(uint32_t* const ptr, int width, int inverse) {
|
||||
void WebPMultARGBRowC(uint32_t* const ptr, int width, int inverse) {
|
||||
int x;
|
||||
for (x = 0; x < width; ++x) {
|
||||
const uint32_t argb = ptr[x];
|
||||
@ -157,7 +154,7 @@ void WebPMultARGBRow_C(uint32_t* const ptr, int width, int inverse) {
|
||||
}
|
||||
}
|
||||
|
||||
void WebPMultRow_C(uint8_t* const ptr, const uint8_t* const alpha,
|
||||
void WebPMultRowC(uint8_t* const ptr, const uint8_t* const alpha,
|
||||
int width, int inverse) {
|
||||
int x;
|
||||
for (x = 0; x < width; ++x) {
|
||||
@ -220,8 +217,7 @@ void WebPMultRows(uint8_t* ptr, int stride,
|
||||
#define PREMULTIPLY(x, m) (((x) * (m) + (1U << 23)) >> 24)
|
||||
#endif
|
||||
|
||||
#if !WEBP_NEON_OMIT_C_CODE
|
||||
static void ApplyAlphaMultiply_C(uint8_t* rgba, int alpha_first,
|
||||
static void ApplyAlphaMultiply(uint8_t* rgba, int alpha_first,
|
||||
int w, int h, int stride) {
|
||||
while (h-- > 0) {
|
||||
uint8_t* const rgb = rgba + (alpha_first ? 1 : 0);
|
||||
@ -239,7 +235,6 @@ static void ApplyAlphaMultiply_C(uint8_t* rgba, int alpha_first,
|
||||
rgba += stride;
|
||||
}
|
||||
}
|
||||
#endif // !WEBP_NEON_OMIT_C_CODE
|
||||
#undef MULTIPLIER
|
||||
#undef PREMULTIPLY
|
||||
|
||||
@ -259,7 +254,7 @@ static WEBP_INLINE uint8_t multiply(uint8_t x, uint32_t m) {
|
||||
return (x * m) >> 16;
|
||||
}
|
||||
|
||||
static WEBP_INLINE void ApplyAlphaMultiply4444_C(uint8_t* rgba4444,
|
||||
static WEBP_INLINE void ApplyAlphaMultiply4444(uint8_t* rgba4444,
|
||||
int w, int h, int stride,
|
||||
int rg_byte_pos /* 0 or 1 */) {
|
||||
while (h-- > 0) {
|
||||
@ -280,16 +275,15 @@ static WEBP_INLINE void ApplyAlphaMultiply4444_C(uint8_t* rgba4444,
|
||||
}
|
||||
#undef MULTIPLIER
|
||||
|
||||
static void ApplyAlphaMultiply_16b_C(uint8_t* rgba4444,
|
||||
static void ApplyAlphaMultiply_16b(uint8_t* rgba4444,
|
||||
int w, int h, int stride) {
|
||||
#if (WEBP_SWAP_16BIT_CSP == 1)
|
||||
ApplyAlphaMultiply4444_C(rgba4444, w, h, stride, 1);
|
||||
#ifdef WEBP_SWAP_16BIT_CSP
|
||||
ApplyAlphaMultiply4444(rgba4444, w, h, stride, 1);
|
||||
#else
|
||||
ApplyAlphaMultiply4444_C(rgba4444, w, h, stride, 0);
|
||||
ApplyAlphaMultiply4444(rgba4444, w, h, stride, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if !WEBP_NEON_OMIT_C_CODE
|
||||
static int DispatchAlpha_C(const uint8_t* alpha, int alpha_stride,
|
||||
int width, int height,
|
||||
uint8_t* dst, int dst_stride) {
|
||||
@ -344,46 +338,6 @@ static void ExtractGreen_C(const uint32_t* argb, uint8_t* alpha, int size) {
|
||||
int i;
|
||||
for (i = 0; i < size; ++i) alpha[i] = argb[i] >> 8;
|
||||
}
|
||||
#endif // !WEBP_NEON_OMIT_C_CODE
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
static int HasAlpha8b_C(const uint8_t* src, int length) {
|
||||
while (length-- > 0) if (*src++ != 0xff) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int HasAlpha32b_C(const uint8_t* src, int length) {
|
||||
int x;
|
||||
for (x = 0; length-- > 0; x += 4) if (src[x] != 0xff) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Simple channel manipulations.
|
||||
|
||||
static WEBP_INLINE uint32_t MakeARGB32(int a, int r, int g, int b) {
|
||||
return (((uint32_t)a << 24) | (r << 16) | (g << 8) | b);
|
||||
}
|
||||
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
static void PackARGB_C(const uint8_t* a, const uint8_t* r, const uint8_t* g,
|
||||
const uint8_t* b, int len, uint32_t* out) {
|
||||
int i;
|
||||
for (i = 0; i < len; ++i) {
|
||||
out[i] = MakeARGB32(a[4 * i], r[4 * i], g[4 * i], b[4 * i]);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void PackRGB_C(const uint8_t* r, const uint8_t* g, const uint8_t* b,
|
||||
int len, int step, uint32_t* out) {
|
||||
int i, offset = 0;
|
||||
for (i = 0; i < len; ++i) {
|
||||
out[i] = MakeARGB32(0xff, r[offset], g[offset], b[offset]);
|
||||
offset += step;
|
||||
}
|
||||
}
|
||||
|
||||
void (*WebPApplyAlphaMultiply)(uint8_t*, int, int, int, int);
|
||||
void (*WebPApplyAlphaMultiply4444)(uint8_t*, int, int, int);
|
||||
@ -391,15 +345,6 @@ int (*WebPDispatchAlpha)(const uint8_t*, int, int, int, uint8_t*, int);
|
||||
void (*WebPDispatchAlphaToGreen)(const uint8_t*, int, int, int, uint32_t*, int);
|
||||
int (*WebPExtractAlpha)(const uint8_t*, int, int, int, uint8_t*, int);
|
||||
void (*WebPExtractGreen)(const uint32_t* argb, uint8_t* alpha, int size);
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
void (*WebPPackARGB)(const uint8_t* a, const uint8_t* r, const uint8_t* g,
|
||||
const uint8_t* b, int, uint32_t*);
|
||||
#endif
|
||||
void (*WebPPackRGB)(const uint8_t* r, const uint8_t* g, const uint8_t* b,
|
||||
int len, int step, uint32_t* out);
|
||||
|
||||
int (*WebPHasAlpha8b)(const uint8_t* src, int length);
|
||||
int (*WebPHasAlpha32b)(const uint8_t* src, int length);
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Init function
|
||||
@ -409,25 +354,21 @@ extern void WebPInitAlphaProcessingSSE2(void);
|
||||
extern void WebPInitAlphaProcessingSSE41(void);
|
||||
extern void WebPInitAlphaProcessingNEON(void);
|
||||
|
||||
WEBP_DSP_INIT_FUNC(WebPInitAlphaProcessing) {
|
||||
WebPMultARGBRow = WebPMultARGBRow_C;
|
||||
WebPMultRow = WebPMultRow_C;
|
||||
WebPApplyAlphaMultiply4444 = ApplyAlphaMultiply_16b_C;
|
||||
static volatile VP8CPUInfo alpha_processing_last_cpuinfo_used =
|
||||
(VP8CPUInfo)&alpha_processing_last_cpuinfo_used;
|
||||
|
||||
WEBP_TSAN_IGNORE_FUNCTION void WebPInitAlphaProcessing(void) {
|
||||
if (alpha_processing_last_cpuinfo_used == VP8GetCPUInfo) return;
|
||||
|
||||
WebPMultARGBRow = WebPMultARGBRowC;
|
||||
WebPMultRow = WebPMultRowC;
|
||||
WebPApplyAlphaMultiply = ApplyAlphaMultiply;
|
||||
WebPApplyAlphaMultiply4444 = ApplyAlphaMultiply_16b;
|
||||
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
WebPPackARGB = PackARGB_C;
|
||||
#endif
|
||||
WebPPackRGB = PackRGB_C;
|
||||
#if !WEBP_NEON_OMIT_C_CODE
|
||||
WebPApplyAlphaMultiply = ApplyAlphaMultiply_C;
|
||||
WebPDispatchAlpha = DispatchAlpha_C;
|
||||
WebPDispatchAlphaToGreen = DispatchAlphaToGreen_C;
|
||||
WebPExtractAlpha = ExtractAlpha_C;
|
||||
WebPExtractGreen = ExtractGreen_C;
|
||||
#endif
|
||||
|
||||
WebPHasAlpha8b = HasAlpha8b_C;
|
||||
WebPHasAlpha32b = HasAlpha32b_C;
|
||||
|
||||
// If defined, use CPUInfo() to overwrite some pointers with faster versions.
|
||||
if (VP8GetCPUInfo != NULL) {
|
||||
@ -441,32 +382,16 @@ WEBP_DSP_INIT_FUNC(WebPInitAlphaProcessing) {
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
#if defined(WEBP_USE_NEON)
|
||||
if (VP8GetCPUInfo(kNEON)) {
|
||||
WebPInitAlphaProcessingNEON();
|
||||
}
|
||||
#endif
|
||||
#if defined(WEBP_USE_MIPS_DSP_R2)
|
||||
if (VP8GetCPUInfo(kMIPSdspR2)) {
|
||||
WebPInitAlphaProcessingMIPSdspR2();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(WEBP_USE_NEON)
|
||||
if (WEBP_NEON_OMIT_C_CODE ||
|
||||
(VP8GetCPUInfo != NULL && VP8GetCPUInfo(kNEON))) {
|
||||
WebPInitAlphaProcessingNEON();
|
||||
}
|
||||
#endif
|
||||
|
||||
assert(WebPMultARGBRow != NULL);
|
||||
assert(WebPMultRow != NULL);
|
||||
assert(WebPApplyAlphaMultiply != NULL);
|
||||
assert(WebPApplyAlphaMultiply4444 != NULL);
|
||||
assert(WebPDispatchAlpha != NULL);
|
||||
assert(WebPDispatchAlphaToGreen != NULL);
|
||||
assert(WebPExtractAlpha != NULL);
|
||||
assert(WebPExtractGreen != NULL);
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
assert(WebPPackARGB != NULL);
|
||||
#endif
|
||||
assert(WebPPackRGB != NULL);
|
||||
assert(WebPHasAlpha8b != NULL);
|
||||
assert(WebPHasAlpha32b != NULL);
|
||||
alpha_processing_last_cpuinfo_used = VP8GetCPUInfo;
|
||||
}
|
||||
|
@ -12,11 +12,11 @@
|
||||
// Author(s): Branimir Vasic (branimir.vasic@imgtec.com)
|
||||
// Djordje Pesut (djordje.pesut@imgtec.com)
|
||||
|
||||
#include "src/dsp/dsp.h"
|
||||
#include "./dsp.h"
|
||||
|
||||
#if defined(WEBP_USE_MIPS_DSP_R2)
|
||||
|
||||
static int DispatchAlpha_MIPSdspR2(const uint8_t* alpha, int alpha_stride,
|
||||
static int DispatchAlpha(const uint8_t* alpha, int alpha_stride,
|
||||
int width, int height,
|
||||
uint8_t* dst, int dst_stride) {
|
||||
uint32_t alpha_mask = 0xffffffff;
|
||||
@ -79,8 +79,7 @@ static int DispatchAlpha_MIPSdspR2(const uint8_t* alpha, int alpha_stride,
|
||||
return (alpha_mask != 0xff);
|
||||
}
|
||||
|
||||
static void MultARGBRow_MIPSdspR2(uint32_t* const ptr, int width,
|
||||
int inverse) {
|
||||
static void MultARGBRow(uint32_t* const ptr, int width, int inverse) {
|
||||
int x;
|
||||
const uint32_t c_00ffffff = 0x00ffffffu;
|
||||
const uint32_t c_ff000000 = 0xff000000u;
|
||||
@ -125,100 +124,14 @@ static void MultARGBRow_MIPSdspR2(uint32_t* const ptr, int width,
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
static void PackARGB_MIPSdspR2(const uint8_t* a, const uint8_t* r,
|
||||
const uint8_t* g, const uint8_t* b, int len,
|
||||
uint32_t* out) {
|
||||
int temp0, temp1, temp2, temp3, offset;
|
||||
const int rest = len & 1;
|
||||
const uint32_t* const loop_end = out + len - rest;
|
||||
const int step = 4;
|
||||
__asm__ volatile (
|
||||
"xor %[offset], %[offset], %[offset] \n\t"
|
||||
"beq %[loop_end], %[out], 0f \n\t"
|
||||
"2: \n\t"
|
||||
"lbux %[temp0], %[offset](%[a]) \n\t"
|
||||
"lbux %[temp1], %[offset](%[r]) \n\t"
|
||||
"lbux %[temp2], %[offset](%[g]) \n\t"
|
||||
"lbux %[temp3], %[offset](%[b]) \n\t"
|
||||
"ins %[temp1], %[temp0], 16, 16 \n\t"
|
||||
"ins %[temp3], %[temp2], 16, 16 \n\t"
|
||||
"addiu %[out], %[out], 4 \n\t"
|
||||
"precr.qb.ph %[temp0], %[temp1], %[temp3] \n\t"
|
||||
"sw %[temp0], -4(%[out]) \n\t"
|
||||
"addu %[offset], %[offset], %[step] \n\t"
|
||||
"bne %[loop_end], %[out], 2b \n\t"
|
||||
"0: \n\t"
|
||||
"beq %[rest], $zero, 1f \n\t"
|
||||
"lbux %[temp0], %[offset](%[a]) \n\t"
|
||||
"lbux %[temp1], %[offset](%[r]) \n\t"
|
||||
"lbux %[temp2], %[offset](%[g]) \n\t"
|
||||
"lbux %[temp3], %[offset](%[b]) \n\t"
|
||||
"ins %[temp1], %[temp0], 16, 16 \n\t"
|
||||
"ins %[temp3], %[temp2], 16, 16 \n\t"
|
||||
"precr.qb.ph %[temp0], %[temp1], %[temp3] \n\t"
|
||||
"sw %[temp0], 0(%[out]) \n\t"
|
||||
"1: \n\t"
|
||||
: [temp0]"=&r"(temp0), [temp1]"=&r"(temp1), [temp2]"=&r"(temp2),
|
||||
[temp3]"=&r"(temp3), [offset]"=&r"(offset), [out]"+&r"(out)
|
||||
: [a]"r"(a), [r]"r"(r), [g]"r"(g), [b]"r"(b), [step]"r"(step),
|
||||
[loop_end]"r"(loop_end), [rest]"r"(rest)
|
||||
: "memory"
|
||||
);
|
||||
}
|
||||
#endif // WORDS_BIGENDIAN
|
||||
|
||||
static void PackRGB_MIPSdspR2(const uint8_t* r, const uint8_t* g,
|
||||
const uint8_t* b, int len, int step,
|
||||
uint32_t* out) {
|
||||
int temp0, temp1, temp2, offset;
|
||||
const int rest = len & 1;
|
||||
const int a = 0xff;
|
||||
const uint32_t* const loop_end = out + len - rest;
|
||||
__asm__ volatile (
|
||||
"xor %[offset], %[offset], %[offset] \n\t"
|
||||
"beq %[loop_end], %[out], 0f \n\t"
|
||||
"2: \n\t"
|
||||
"lbux %[temp0], %[offset](%[r]) \n\t"
|
||||
"lbux %[temp1], %[offset](%[g]) \n\t"
|
||||
"lbux %[temp2], %[offset](%[b]) \n\t"
|
||||
"ins %[temp0], %[a], 16, 16 \n\t"
|
||||
"ins %[temp2], %[temp1], 16, 16 \n\t"
|
||||
"addiu %[out], %[out], 4 \n\t"
|
||||
"precr.qb.ph %[temp0], %[temp0], %[temp2] \n\t"
|
||||
"sw %[temp0], -4(%[out]) \n\t"
|
||||
"addu %[offset], %[offset], %[step] \n\t"
|
||||
"bne %[loop_end], %[out], 2b \n\t"
|
||||
"0: \n\t"
|
||||
"beq %[rest], $zero, 1f \n\t"
|
||||
"lbux %[temp0], %[offset](%[r]) \n\t"
|
||||
"lbux %[temp1], %[offset](%[g]) \n\t"
|
||||
"lbux %[temp2], %[offset](%[b]) \n\t"
|
||||
"ins %[temp0], %[a], 16, 16 \n\t"
|
||||
"ins %[temp2], %[temp1], 16, 16 \n\t"
|
||||
"precr.qb.ph %[temp0], %[temp0], %[temp2] \n\t"
|
||||
"sw %[temp0], 0(%[out]) \n\t"
|
||||
"1: \n\t"
|
||||
: [temp0]"=&r"(temp0), [temp1]"=&r"(temp1), [temp2]"=&r"(temp2),
|
||||
[offset]"=&r"(offset), [out]"+&r"(out)
|
||||
: [a]"r"(a), [r]"r"(r), [g]"r"(g), [b]"r"(b), [step]"r"(step),
|
||||
[loop_end]"r"(loop_end), [rest]"r"(rest)
|
||||
: "memory"
|
||||
);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Entry point
|
||||
|
||||
extern void WebPInitAlphaProcessingMIPSdspR2(void);
|
||||
|
||||
WEBP_TSAN_IGNORE_FUNCTION void WebPInitAlphaProcessingMIPSdspR2(void) {
|
||||
WebPDispatchAlpha = DispatchAlpha_MIPSdspR2;
|
||||
WebPMultARGBRow = MultARGBRow_MIPSdspR2;
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
WebPPackARGB = PackARGB_MIPSdspR2;
|
||||
#endif
|
||||
WebPPackRGB = PackRGB_MIPSdspR2;
|
||||
WebPDispatchAlpha = DispatchAlpha;
|
||||
WebPMultARGBRow = MultARGBRow;
|
||||
}
|
||||
|
||||
#else // !WEBP_USE_MIPS_DSP_R2
|
||||
|
@ -11,11 +11,11 @@
|
||||
//
|
||||
// Author: Skal (pascal.massimino@gmail.com)
|
||||
|
||||
#include "src/dsp/dsp.h"
|
||||
#include "./dsp.h"
|
||||
|
||||
#if defined(WEBP_USE_NEON)
|
||||
|
||||
#include "src/dsp/neon.h"
|
||||
#include "./neon.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
|
@ -11,14 +11,14 @@
|
||||
//
|
||||
// Author: Skal (pascal.massimino@gmail.com)
|
||||
|
||||
#include "src/dsp/dsp.h"
|
||||
#include "./dsp.h"
|
||||
|
||||
#if defined(WEBP_USE_SSE2)
|
||||
#include <emmintrin.h>
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
static int DispatchAlpha_SSE2(const uint8_t* alpha, int alpha_stride,
|
||||
static int DispatchAlpha(const uint8_t* alpha, int alpha_stride,
|
||||
int width, int height,
|
||||
uint8_t* dst, int dst_stride) {
|
||||
// alpha_and stores an 'and' operation of all the alpha[] values. The final
|
||||
@ -72,7 +72,7 @@ static int DispatchAlpha_SSE2(const uint8_t* alpha, int alpha_stride,
|
||||
return (alpha_and != 0xff);
|
||||
}
|
||||
|
||||
static void DispatchAlphaToGreen_SSE2(const uint8_t* alpha, int alpha_stride,
|
||||
static void DispatchAlphaToGreen(const uint8_t* alpha, int alpha_stride,
|
||||
int width, int height,
|
||||
uint32_t* dst, int dst_stride) {
|
||||
int i, j;
|
||||
@ -98,7 +98,7 @@ static void DispatchAlphaToGreen_SSE2(const uint8_t* alpha, int alpha_stride,
|
||||
}
|
||||
}
|
||||
|
||||
static int ExtractAlpha_SSE2(const uint8_t* argb, int argb_stride,
|
||||
static int ExtractAlpha(const uint8_t* argb, int argb_stride,
|
||||
int width, int height,
|
||||
uint8_t* alpha, int alpha_stride) {
|
||||
// alpha_and stores an 'and' operation of all the alpha[] values. The final
|
||||
@ -210,61 +210,6 @@ static void ApplyAlphaMultiply_SSE2(uint8_t* rgba, int alpha_first,
|
||||
#undef MULTIPLIER
|
||||
#undef PREMULTIPLY
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Alpha detection
|
||||
|
||||
static int HasAlpha8b_SSE2(const uint8_t* src, int length) {
|
||||
const __m128i all_0xff = _mm_set1_epi8(0xff);
|
||||
int i = 0;
|
||||
for (; i + 16 <= length; i += 16) {
|
||||
const __m128i v = _mm_loadu_si128((const __m128i*)(src + i));
|
||||
const __m128i bits = _mm_cmpeq_epi8(v, all_0xff);
|
||||
const int mask = _mm_movemask_epi8(bits);
|
||||
if (mask != 0xffff) return 1;
|
||||
}
|
||||
for (; i < length; ++i) if (src[i] != 0xff) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int HasAlpha32b_SSE2(const uint8_t* src, int length) {
|
||||
const __m128i alpha_mask = _mm_set1_epi32(0xff);
|
||||
const __m128i all_0xff = _mm_set1_epi8(0xff);
|
||||
int i = 0;
|
||||
// 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
|
||||
// or the last byte of the quadruplet). Hence the '-3' protection below.
|
||||
length = length * 4 - 3; // size in bytes
|
||||
for (; i + 64 <= length; i += 64) {
|
||||
const __m128i a0 = _mm_loadu_si128((const __m128i*)(src + i + 0));
|
||||
const __m128i a1 = _mm_loadu_si128((const __m128i*)(src + i + 16));
|
||||
const __m128i a2 = _mm_loadu_si128((const __m128i*)(src + i + 32));
|
||||
const __m128i a3 = _mm_loadu_si128((const __m128i*)(src + i + 48));
|
||||
const __m128i b0 = _mm_and_si128(a0, alpha_mask);
|
||||
const __m128i b1 = _mm_and_si128(a1, alpha_mask);
|
||||
const __m128i b2 = _mm_and_si128(a2, alpha_mask);
|
||||
const __m128i b3 = _mm_and_si128(a3, alpha_mask);
|
||||
const __m128i c0 = _mm_packs_epi32(b0, b1);
|
||||
const __m128i c1 = _mm_packs_epi32(b2, b3);
|
||||
const __m128i d = _mm_packus_epi16(c0, c1);
|
||||
const __m128i bits = _mm_cmpeq_epi8(d, all_0xff);
|
||||
const int mask = _mm_movemask_epi8(bits);
|
||||
if (mask != 0xffff) return 1;
|
||||
}
|
||||
for (; i + 32 <= length; i += 32) {
|
||||
const __m128i a0 = _mm_loadu_si128((const __m128i*)(src + i + 0));
|
||||
const __m128i a1 = _mm_loadu_si128((const __m128i*)(src + i + 16));
|
||||
const __m128i b0 = _mm_and_si128(a0, alpha_mask);
|
||||
const __m128i b1 = _mm_and_si128(a1, alpha_mask);
|
||||
const __m128i c = _mm_packs_epi32(b0, b1);
|
||||
const __m128i d = _mm_packus_epi16(c, c);
|
||||
const __m128i bits = _mm_cmpeq_epi8(d, all_0xff);
|
||||
const int mask = _mm_movemask_epi8(bits);
|
||||
if (mask != 0xffff) return 1;
|
||||
}
|
||||
for (; i <= length; i += 4) if (src[i] != 0xff) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Apply alpha value to rows
|
||||
|
||||
@ -293,7 +238,7 @@ static void MultARGBRow_SSE2(uint32_t* const ptr, int width, int inverse) {
|
||||
}
|
||||
}
|
||||
width -= x;
|
||||
if (width > 0) WebPMultARGBRow_C(ptr + x, width, inverse);
|
||||
if (width > 0) WebPMultARGBRowC(ptr + x, width, inverse);
|
||||
}
|
||||
|
||||
static void MultRow_SSE2(uint8_t* const ptr, const uint8_t* const alpha,
|
||||
@ -316,7 +261,7 @@ static void MultRow_SSE2(uint8_t* const ptr, const uint8_t* const alpha,
|
||||
}
|
||||
}
|
||||
width -= x;
|
||||
if (width > 0) WebPMultRow_C(ptr + x, alpha + x, width, inverse);
|
||||
if (width > 0) WebPMultRowC(ptr + x, alpha + x, width, inverse);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@ -328,12 +273,9 @@ WEBP_TSAN_IGNORE_FUNCTION void WebPInitAlphaProcessingSSE2(void) {
|
||||
WebPMultARGBRow = MultARGBRow_SSE2;
|
||||
WebPMultRow = MultRow_SSE2;
|
||||
WebPApplyAlphaMultiply = ApplyAlphaMultiply_SSE2;
|
||||
WebPDispatchAlpha = DispatchAlpha_SSE2;
|
||||
WebPDispatchAlphaToGreen = DispatchAlphaToGreen_SSE2;
|
||||
WebPExtractAlpha = ExtractAlpha_SSE2;
|
||||
|
||||
WebPHasAlpha8b = HasAlpha8b_SSE2;
|
||||
WebPHasAlpha32b = HasAlpha32b_SSE2;
|
||||
WebPDispatchAlpha = DispatchAlpha;
|
||||
WebPDispatchAlphaToGreen = DispatchAlphaToGreen;
|
||||
WebPExtractAlpha = ExtractAlpha;
|
||||
}
|
||||
|
||||
#else // !WEBP_USE_SSE2
|
||||
|
@ -11,7 +11,7 @@
|
||||
//
|
||||
// Author: Skal (pascal.massimino@gmail.com)
|
||||
|
||||
#include "src/dsp/dsp.h"
|
||||
#include "./dsp.h"
|
||||
|
||||
#if defined(WEBP_USE_SSE41)
|
||||
|
||||
@ -19,7 +19,7 @@
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
static int ExtractAlpha_SSE41(const uint8_t* argb, int argb_stride,
|
||||
static int ExtractAlpha(const uint8_t* argb, int argb_stride,
|
||||
int width, int height,
|
||||
uint8_t* alpha, int alpha_stride) {
|
||||
// alpha_and stores an 'and' operation of all the alpha[] values. The final
|
||||
@ -82,7 +82,7 @@ static int ExtractAlpha_SSE41(const uint8_t* argb, int argb_stride,
|
||||
extern void WebPInitAlphaProcessingSSE41(void);
|
||||
|
||||
WEBP_TSAN_IGNORE_FUNCTION void WebPInitAlphaProcessingSSE41(void) {
|
||||
WebPExtractAlpha = ExtractAlpha_SSE41;
|
||||
WebPExtractAlpha = ExtractAlpha;
|
||||
}
|
||||
|
||||
#else // !WEBP_USE_SSE41
|
||||
|
68
src/dsp/argb.c
Normal file
68
src/dsp/argb.c
Normal file
@ -0,0 +1,68 @@
|
||||
// Copyright 2014 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// Use of this source code is governed by a BSD-style license
|
||||
// that can be found in the COPYING file in the root of the source
|
||||
// tree. An additional intellectual property rights grant can be found
|
||||
// in the file PATENTS. All contributing project authors may
|
||||
// be found in the AUTHORS file in the root of the source tree.
|
||||
// -----------------------------------------------------------------------------
|
||||
//
|
||||
// ARGB making functions.
|
||||
//
|
||||
// Author: Djordje Pesut (djordje.pesut@imgtec.com)
|
||||
|
||||
#include "./dsp.h"
|
||||
|
||||
static WEBP_INLINE uint32_t MakeARGB32(int a, int r, int g, int b) {
|
||||
return (((uint32_t)a << 24) | (r << 16) | (g << 8) | b);
|
||||
}
|
||||
|
||||
static void PackARGB(const uint8_t* a, const uint8_t* r, const uint8_t* g,
|
||||
const uint8_t* b, int len, uint32_t* out) {
|
||||
int i;
|
||||
for (i = 0; i < len; ++i) {
|
||||
out[i] = MakeARGB32(a[4 * i], r[4 * i], g[4 * i], b[4 * i]);
|
||||
}
|
||||
}
|
||||
|
||||
static void PackRGB(const uint8_t* r, const uint8_t* g, const uint8_t* b,
|
||||
int len, int step, uint32_t* out) {
|
||||
int i, offset = 0;
|
||||
for (i = 0; i < len; ++i) {
|
||||
out[i] = MakeARGB32(0xff, r[offset], g[offset], b[offset]);
|
||||
offset += step;
|
||||
}
|
||||
}
|
||||
|
||||
void (*VP8PackARGB)(const uint8_t*, const uint8_t*, const uint8_t*,
|
||||
const uint8_t*, int, uint32_t*);
|
||||
void (*VP8PackRGB)(const uint8_t*, const uint8_t*, const uint8_t*,
|
||||
int, int, uint32_t*);
|
||||
|
||||
extern void VP8EncDspARGBInitMIPSdspR2(void);
|
||||
extern void VP8EncDspARGBInitSSE2(void);
|
||||
|
||||
static volatile VP8CPUInfo argb_last_cpuinfo_used =
|
||||
(VP8CPUInfo)&argb_last_cpuinfo_used;
|
||||
|
||||
WEBP_TSAN_IGNORE_FUNCTION void VP8EncDspARGBInit(void) {
|
||||
if (argb_last_cpuinfo_used == VP8GetCPUInfo) return;
|
||||
|
||||
VP8PackARGB = PackARGB;
|
||||
VP8PackRGB = PackRGB;
|
||||
|
||||
// If defined, use CPUInfo() to overwrite some pointers with faster versions.
|
||||
if (VP8GetCPUInfo != NULL) {
|
||||
#if defined(WEBP_USE_SSE2)
|
||||
if (VP8GetCPUInfo(kSSE2)) {
|
||||
VP8EncDspARGBInitSSE2();
|
||||
}
|
||||
#endif
|
||||
#if defined(WEBP_USE_MIPS_DSP_R2)
|
||||
if (VP8GetCPUInfo(kMIPSdspR2)) {
|
||||
VP8EncDspARGBInitMIPSdspR2();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
argb_last_cpuinfo_used = VP8GetCPUInfo;
|
||||
}
|
110
src/dsp/argb_mips_dsp_r2.c
Normal file
110
src/dsp/argb_mips_dsp_r2.c
Normal file
@ -0,0 +1,110 @@
|
||||
// Copyright 2014 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// Use of this source code is governed by a BSD-style license
|
||||
// that can be found in the COPYING file in the root of the source
|
||||
// tree. An additional intellectual property rights grant can be found
|
||||
// in the file PATENTS. All contributing project authors may
|
||||
// be found in the AUTHORS file in the root of the source tree.
|
||||
// -----------------------------------------------------------------------------
|
||||
//
|
||||
// ARGB making functions (mips version).
|
||||
//
|
||||
// Author: Djordje Pesut (djordje.pesut@imgtec.com)
|
||||
|
||||
#include "./dsp.h"
|
||||
|
||||
#if defined(WEBP_USE_MIPS_DSP_R2)
|
||||
|
||||
static void PackARGB(const uint8_t* a, const uint8_t* r, const uint8_t* g,
|
||||
const uint8_t* b, int len, uint32_t* out) {
|
||||
int temp0, temp1, temp2, temp3, offset;
|
||||
const int rest = len & 1;
|
||||
const uint32_t* const loop_end = out + len - rest;
|
||||
const int step = 4;
|
||||
__asm__ volatile (
|
||||
"xor %[offset], %[offset], %[offset] \n\t"
|
||||
"beq %[loop_end], %[out], 0f \n\t"
|
||||
"2: \n\t"
|
||||
"lbux %[temp0], %[offset](%[a]) \n\t"
|
||||
"lbux %[temp1], %[offset](%[r]) \n\t"
|
||||
"lbux %[temp2], %[offset](%[g]) \n\t"
|
||||
"lbux %[temp3], %[offset](%[b]) \n\t"
|
||||
"ins %[temp1], %[temp0], 16, 16 \n\t"
|
||||
"ins %[temp3], %[temp2], 16, 16 \n\t"
|
||||
"addiu %[out], %[out], 4 \n\t"
|
||||
"precr.qb.ph %[temp0], %[temp1], %[temp3] \n\t"
|
||||
"sw %[temp0], -4(%[out]) \n\t"
|
||||
"addu %[offset], %[offset], %[step] \n\t"
|
||||
"bne %[loop_end], %[out], 2b \n\t"
|
||||
"0: \n\t"
|
||||
"beq %[rest], $zero, 1f \n\t"
|
||||
"lbux %[temp0], %[offset](%[a]) \n\t"
|
||||
"lbux %[temp1], %[offset](%[r]) \n\t"
|
||||
"lbux %[temp2], %[offset](%[g]) \n\t"
|
||||
"lbux %[temp3], %[offset](%[b]) \n\t"
|
||||
"ins %[temp1], %[temp0], 16, 16 \n\t"
|
||||
"ins %[temp3], %[temp2], 16, 16 \n\t"
|
||||
"precr.qb.ph %[temp0], %[temp1], %[temp3] \n\t"
|
||||
"sw %[temp0], 0(%[out]) \n\t"
|
||||
"1: \n\t"
|
||||
: [temp0]"=&r"(temp0), [temp1]"=&r"(temp1), [temp2]"=&r"(temp2),
|
||||
[temp3]"=&r"(temp3), [offset]"=&r"(offset), [out]"+&r"(out)
|
||||
: [a]"r"(a), [r]"r"(r), [g]"r"(g), [b]"r"(b), [step]"r"(step),
|
||||
[loop_end]"r"(loop_end), [rest]"r"(rest)
|
||||
: "memory"
|
||||
);
|
||||
}
|
||||
|
||||
static void PackRGB(const uint8_t* r, const uint8_t* g, const uint8_t* b,
|
||||
int len, int step, uint32_t* out) {
|
||||
int temp0, temp1, temp2, offset;
|
||||
const int rest = len & 1;
|
||||
const int a = 0xff;
|
||||
const uint32_t* const loop_end = out + len - rest;
|
||||
__asm__ volatile (
|
||||
"xor %[offset], %[offset], %[offset] \n\t"
|
||||
"beq %[loop_end], %[out], 0f \n\t"
|
||||
"2: \n\t"
|
||||
"lbux %[temp0], %[offset](%[r]) \n\t"
|
||||
"lbux %[temp1], %[offset](%[g]) \n\t"
|
||||
"lbux %[temp2], %[offset](%[b]) \n\t"
|
||||
"ins %[temp0], %[a], 16, 16 \n\t"
|
||||
"ins %[temp2], %[temp1], 16, 16 \n\t"
|
||||
"addiu %[out], %[out], 4 \n\t"
|
||||
"precr.qb.ph %[temp0], %[temp0], %[temp2] \n\t"
|
||||
"sw %[temp0], -4(%[out]) \n\t"
|
||||
"addu %[offset], %[offset], %[step] \n\t"
|
||||
"bne %[loop_end], %[out], 2b \n\t"
|
||||
"0: \n\t"
|
||||
"beq %[rest], $zero, 1f \n\t"
|
||||
"lbux %[temp0], %[offset](%[r]) \n\t"
|
||||
"lbux %[temp1], %[offset](%[g]) \n\t"
|
||||
"lbux %[temp2], %[offset](%[b]) \n\t"
|
||||
"ins %[temp0], %[a], 16, 16 \n\t"
|
||||
"ins %[temp2], %[temp1], 16, 16 \n\t"
|
||||
"precr.qb.ph %[temp0], %[temp0], %[temp2] \n\t"
|
||||
"sw %[temp0], 0(%[out]) \n\t"
|
||||
"1: \n\t"
|
||||
: [temp0]"=&r"(temp0), [temp1]"=&r"(temp1), [temp2]"=&r"(temp2),
|
||||
[offset]"=&r"(offset), [out]"+&r"(out)
|
||||
: [a]"r"(a), [r]"r"(r), [g]"r"(g), [b]"r"(b), [step]"r"(step),
|
||||
[loop_end]"r"(loop_end), [rest]"r"(rest)
|
||||
: "memory"
|
||||
);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Entry point
|
||||
|
||||
extern void VP8EncDspARGBInitMIPSdspR2(void);
|
||||
|
||||
WEBP_TSAN_IGNORE_FUNCTION void VP8EncDspARGBInitMIPSdspR2(void) {
|
||||
VP8PackARGB = PackARGB;
|
||||
VP8PackRGB = PackRGB;
|
||||
}
|
||||
|
||||
#else // !WEBP_USE_MIPS_DSP_R2
|
||||
|
||||
WEBP_DSP_INIT_STUB(VP8EncDspARGBInitMIPSdspR2)
|
||||
|
||||
#endif // WEBP_USE_MIPS_DSP_R2
|
53
src/dsp/argb_sse2.c
Normal file
53
src/dsp/argb_sse2.c
Normal file
@ -0,0 +1,53 @@
|
||||
// Copyright 2014 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// Use of this source code is governed by a BSD-style license
|
||||
// that can be found in the COPYING file in the root of the source
|
||||
// tree. An additional intellectual property rights grant can be found
|
||||
// in the file PATENTS. All contributing project authors may
|
||||
// be found in the AUTHORS file in the root of the source tree.
|
||||
// -----------------------------------------------------------------------------
|
||||
//
|
||||
// ARGB making functions (SSE2 version).
|
||||
//
|
||||
// Author: Skal (pascal.massimino@gmail.com)
|
||||
|
||||
#include "./dsp.h"
|
||||
#include "./lossless.h"
|
||||
|
||||
#if defined(WEBP_USE_SSE2)
|
||||
|
||||
#include <assert.h>
|
||||
#include <emmintrin.h>
|
||||
#include <string.h>
|
||||
|
||||
static void PackARGB(const uint8_t* a, const uint8_t* r, const uint8_t* g,
|
||||
const uint8_t* b, int len, uint32_t* out) {
|
||||
(void)a;
|
||||
if (g == r + 1) { // RGBA input order. Need to swap R and B.
|
||||
assert(b == r + 2);
|
||||
assert(a == r + 3);
|
||||
VP8LConvertBGRAToRGBA((const uint32_t*)r, len, (uint8_t*)out);
|
||||
} else {
|
||||
assert(g == b + 1);
|
||||
assert(r == b + 2);
|
||||
assert(a == b + 3);
|
||||
memcpy(out, b, len * 4);
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Entry point
|
||||
|
||||
extern void VP8EncDspARGBInitSSE2(void);
|
||||
extern void VP8LDspInitSSE2(void);
|
||||
|
||||
WEBP_TSAN_IGNORE_FUNCTION void VP8EncDspARGBInitSSE2(void) {
|
||||
VP8LDspInitSSE2();
|
||||
VP8PackARGB = PackARGB;
|
||||
}
|
||||
|
||||
#else // !WEBP_USE_SSE2
|
||||
|
||||
WEBP_DSP_INIT_STUB(VP8EncDspARGBInitSSE2)
|
||||
|
||||
#endif // WEBP_USE_SSE2
|
@ -128,9 +128,9 @@ static WEBP_INLINE void VP8Transpose_2_4x4_16b(
|
||||
// Pack the planar buffers
|
||||
// rrrr... rrrr... gggg... gggg... bbbb... bbbb....
|
||||
// triplet by triplet in the output buffer rgb as rgbrgbrgbrgb ...
|
||||
static WEBP_INLINE void VP8PlanarTo24b_SSE2(
|
||||
__m128i* const in0, __m128i* const in1, __m128i* const in2,
|
||||
__m128i* const in3, __m128i* const in4, __m128i* const in5) {
|
||||
static WEBP_INLINE void VP8PlanarTo24b(__m128i* const in0, __m128i* const in1,
|
||||
__m128i* const in2, __m128i* const in3,
|
||||
__m128i* const in4, __m128i* const in5) {
|
||||
// The input is 6 registers of sixteen 8b but for the sake of explanation,
|
||||
// let's take 6 registers of four 8b values.
|
||||
// To pack, we will keep taking one every two 8b integer and move it
|
||||
@ -159,7 +159,7 @@ static WEBP_INLINE void VP8PlanarTo24b_SSE2(
|
||||
|
||||
// Convert four packed four-channel buffers like argbargbargbargb... into the
|
||||
// split channels aaaaa ... rrrr ... gggg .... bbbbb ......
|
||||
static WEBP_INLINE void VP8L32bToPlanar_SSE2(__m128i* const in0,
|
||||
static WEBP_INLINE void VP8L32bToPlanar(__m128i* const in0,
|
||||
__m128i* const in1,
|
||||
__m128i* const in2,
|
||||
__m128i* const in3) {
|
||||
|
@ -1,132 +0,0 @@
|
||||
// Copyright 2016 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// Use of this source code is governed by a BSD-style license
|
||||
// that can be found in the COPYING file in the root of the source
|
||||
// tree. An additional intellectual property rights grant can be found
|
||||
// in the file PATENTS. All contributing project authors may
|
||||
// be found in the AUTHORS file in the root of the source tree.
|
||||
// -----------------------------------------------------------------------------
|
||||
//
|
||||
// SSE4 code common to several files.
|
||||
//
|
||||
// Author: Vincent Rabaud (vrabaud@google.com)
|
||||
|
||||
#ifndef WEBP_DSP_COMMON_SSE41_H_
|
||||
#define WEBP_DSP_COMMON_SSE41_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined(WEBP_USE_SSE41)
|
||||
#include <smmintrin.h>
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Channel mixing.
|
||||
// Shuffles the input buffer as A0 0 0 A1 0 0 A2 ...
|
||||
#define WEBP_SSE41_SHUFF(OUT, IN0, IN1) \
|
||||
OUT##0 = _mm_shuffle_epi8(*IN0, shuff0); \
|
||||
OUT##1 = _mm_shuffle_epi8(*IN0, shuff1); \
|
||||
OUT##2 = _mm_shuffle_epi8(*IN0, shuff2); \
|
||||
OUT##3 = _mm_shuffle_epi8(*IN1, shuff0); \
|
||||
OUT##4 = _mm_shuffle_epi8(*IN1, shuff1); \
|
||||
OUT##5 = _mm_shuffle_epi8(*IN1, shuff2);
|
||||
|
||||
// Pack the planar buffers
|
||||
// rrrr... rrrr... gggg... gggg... bbbb... bbbb....
|
||||
// triplet by triplet in the output buffer rgb as rgbrgbrgbrgb ...
|
||||
static WEBP_INLINE void VP8PlanarTo24b_SSE41(
|
||||
__m128i* const in0, __m128i* const in1, __m128i* const in2,
|
||||
__m128i* const in3, __m128i* const in4, __m128i* const in5) {
|
||||
__m128i R0, R1, R2, R3, R4, R5;
|
||||
__m128i G0, G1, G2, G3, G4, G5;
|
||||
__m128i B0, B1, B2, B3, B4, B5;
|
||||
|
||||
// Process R.
|
||||
{
|
||||
const __m128i shuff0 = _mm_set_epi8(
|
||||
5, -1, -1, 4, -1, -1, 3, -1, -1, 2, -1, -1, 1, -1, -1, 0);
|
||||
const __m128i shuff1 = _mm_set_epi8(
|
||||
-1, 10, -1, -1, 9, -1, -1, 8, -1, -1, 7, -1, -1, 6, -1, -1);
|
||||
const __m128i shuff2 = _mm_set_epi8(
|
||||
-1, -1, 15, -1, -1, 14, -1, -1, 13, -1, -1, 12, -1, -1, 11, -1);
|
||||
WEBP_SSE41_SHUFF(R, in0, in1)
|
||||
}
|
||||
|
||||
// Process G.
|
||||
{
|
||||
// Same as before, just shifted to the left by one and including the right
|
||||
// padding.
|
||||
const __m128i shuff0 = _mm_set_epi8(
|
||||
-1, -1, 4, -1, -1, 3, -1, -1, 2, -1, -1, 1, -1, -1, 0, -1);
|
||||
const __m128i shuff1 = _mm_set_epi8(
|
||||
10, -1, -1, 9, -1, -1, 8, -1, -1, 7, -1, -1, 6, -1, -1, 5);
|
||||
const __m128i shuff2 = _mm_set_epi8(
|
||||
-1, 15, -1, -1, 14, -1, -1, 13, -1, -1, 12, -1, -1, 11, -1, -1);
|
||||
WEBP_SSE41_SHUFF(G, in2, in3)
|
||||
}
|
||||
|
||||
// Process B.
|
||||
{
|
||||
const __m128i shuff0 = _mm_set_epi8(
|
||||
-1, 4, -1, -1, 3, -1, -1, 2, -1, -1, 1, -1, -1, 0, -1, -1);
|
||||
const __m128i shuff1 = _mm_set_epi8(
|
||||
-1, -1, 9, -1, -1, 8, -1, -1, 7, -1, -1, 6, -1, -1, 5, -1);
|
||||
const __m128i shuff2 = _mm_set_epi8(
|
||||
15, -1, -1, 14, -1, -1, 13, -1, -1, 12, -1, -1, 11, -1, -1, 10);
|
||||
WEBP_SSE41_SHUFF(B, in4, in5)
|
||||
}
|
||||
|
||||
// OR the different channels.
|
||||
{
|
||||
const __m128i RG0 = _mm_or_si128(R0, G0);
|
||||
const __m128i RG1 = _mm_or_si128(R1, G1);
|
||||
const __m128i RG2 = _mm_or_si128(R2, G2);
|
||||
const __m128i RG3 = _mm_or_si128(R3, G3);
|
||||
const __m128i RG4 = _mm_or_si128(R4, G4);
|
||||
const __m128i RG5 = _mm_or_si128(R5, G5);
|
||||
*in0 = _mm_or_si128(RG0, B0);
|
||||
*in1 = _mm_or_si128(RG1, B1);
|
||||
*in2 = _mm_or_si128(RG2, B2);
|
||||
*in3 = _mm_or_si128(RG3, B3);
|
||||
*in4 = _mm_or_si128(RG4, B4);
|
||||
*in5 = _mm_or_si128(RG5, B5);
|
||||
}
|
||||
}
|
||||
|
||||
#undef WEBP_SSE41_SHUFF
|
||||
|
||||
// Convert four packed four-channel buffers like argbargbargbargb... into the
|
||||
// split channels aaaaa ... rrrr ... gggg .... bbbbb ......
|
||||
static WEBP_INLINE void VP8L32bToPlanar_SSE41(__m128i* const in0,
|
||||
__m128i* const in1,
|
||||
__m128i* const in2,
|
||||
__m128i* const in3) {
|
||||
// aaaarrrrggggbbbb
|
||||
const __m128i shuff0 =
|
||||
_mm_set_epi8(15, 11, 7, 3, 14, 10, 6, 2, 13, 9, 5, 1, 12, 8, 4, 0);
|
||||
const __m128i A0 = _mm_shuffle_epi8(*in0, shuff0);
|
||||
const __m128i A1 = _mm_shuffle_epi8(*in1, shuff0);
|
||||
const __m128i A2 = _mm_shuffle_epi8(*in2, shuff0);
|
||||
const __m128i A3 = _mm_shuffle_epi8(*in3, shuff0);
|
||||
// A0A1R0R1
|
||||
// G0G1B0B1
|
||||
// A2A3R2R3
|
||||
// G0G1B0B1
|
||||
const __m128i B0 = _mm_unpacklo_epi32(A0, A1);
|
||||
const __m128i B1 = _mm_unpackhi_epi32(A0, A1);
|
||||
const __m128i B2 = _mm_unpacklo_epi32(A2, A3);
|
||||
const __m128i B3 = _mm_unpackhi_epi32(A2, A3);
|
||||
*in3 = _mm_unpacklo_epi64(B0, B2);
|
||||
*in2 = _mm_unpackhi_epi64(B0, B2);
|
||||
*in1 = _mm_unpacklo_epi64(B1, B3);
|
||||
*in0 = _mm_unpackhi_epi64(B1, B3);
|
||||
}
|
||||
|
||||
#endif // WEBP_USE_SSE41
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // WEBP_DSP_COMMON_SSE41_H_
|
@ -9,8 +9,8 @@
|
||||
//
|
||||
// Author: Skal (pascal.massimino@gmail.com)
|
||||
|
||||
#include "src/dsp/dsp.h"
|
||||
#include "src/enc/cost_enc.h"
|
||||
#include "./dsp.h"
|
||||
#include "../enc/cost_enc.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Boolean-cost cost table
|
||||
@ -319,7 +319,7 @@ const uint8_t VP8EncBands[16 + 1] = {
|
||||
//------------------------------------------------------------------------------
|
||||
// Mode costs
|
||||
|
||||
static int GetResidualCost_C(int ctx0, const VP8Residual* const res) {
|
||||
static int GetResidualCost(int ctx0, const VP8Residual* const res) {
|
||||
int n = res->first;
|
||||
// should be prob[VP8EncBands[n]], but it's equivalent for n=0 or 1
|
||||
const int p0 = res->prob[n][ctx0][0];
|
||||
@ -354,7 +354,7 @@ static int GetResidualCost_C(int ctx0, const VP8Residual* const res) {
|
||||
return cost;
|
||||
}
|
||||
|
||||
static void SetResidualCoeffs_C(const int16_t* const coeffs,
|
||||
static void SetResidualCoeffs(const int16_t* const coeffs,
|
||||
VP8Residual* const res) {
|
||||
int n;
|
||||
res->last = -1;
|
||||
@ -378,9 +378,14 @@ extern void VP8EncDspCostInitMIPS32(void);
|
||||
extern void VP8EncDspCostInitMIPSdspR2(void);
|
||||
extern void VP8EncDspCostInitSSE2(void);
|
||||
|
||||
WEBP_DSP_INIT_FUNC(VP8EncDspCostInit) {
|
||||
VP8GetResidualCost = GetResidualCost_C;
|
||||
VP8SetResidualCoeffs = SetResidualCoeffs_C;
|
||||
static volatile VP8CPUInfo cost_last_cpuinfo_used =
|
||||
(VP8CPUInfo)&cost_last_cpuinfo_used;
|
||||
|
||||
WEBP_TSAN_IGNORE_FUNCTION void VP8EncDspCostInit(void) {
|
||||
if (cost_last_cpuinfo_used == VP8GetCPUInfo) return;
|
||||
|
||||
VP8GetResidualCost = GetResidualCost;
|
||||
VP8SetResidualCoeffs = SetResidualCoeffs;
|
||||
|
||||
// If defined, use CPUInfo() to overwrite some pointers with faster versions.
|
||||
if (VP8GetCPUInfo != NULL) {
|
||||
@ -400,6 +405,8 @@ WEBP_DSP_INIT_FUNC(VP8EncDspCostInit) {
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
cost_last_cpuinfo_used = VP8GetCPUInfo;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
@ -9,13 +9,13 @@
|
||||
//
|
||||
// Author: Djordje Pesut (djordje.pesut@imgtec.com)
|
||||
|
||||
#include "src/dsp/dsp.h"
|
||||
#include "./dsp.h"
|
||||
|
||||
#if defined(WEBP_USE_MIPS32)
|
||||
|
||||
#include "src/enc/cost_enc.h"
|
||||
#include "../enc/cost_enc.h"
|
||||
|
||||
static int GetResidualCost_MIPS32(int ctx0, const VP8Residual* const res) {
|
||||
static int GetResidualCost(int ctx0, const VP8Residual* const res) {
|
||||
int temp0, temp1;
|
||||
int v_reg, ctx_reg;
|
||||
int n = res->first;
|
||||
@ -96,7 +96,7 @@ static int GetResidualCost_MIPS32(int ctx0, const VP8Residual* const res) {
|
||||
return cost;
|
||||
}
|
||||
|
||||
static void SetResidualCoeffs_MIPS32(const int16_t* const coeffs,
|
||||
static void SetResidualCoeffs(const int16_t* const coeffs,
|
||||
VP8Residual* const res) {
|
||||
const int16_t* p_coeffs = (int16_t*)coeffs;
|
||||
int temp0, temp1, temp2, n, n1;
|
||||
@ -143,8 +143,8 @@ static void SetResidualCoeffs_MIPS32(const int16_t* const coeffs,
|
||||
extern void VP8EncDspCostInitMIPS32(void);
|
||||
|
||||
WEBP_TSAN_IGNORE_FUNCTION void VP8EncDspCostInitMIPS32(void) {
|
||||
VP8GetResidualCost = GetResidualCost_MIPS32;
|
||||
VP8SetResidualCoeffs = SetResidualCoeffs_MIPS32;
|
||||
VP8GetResidualCost = GetResidualCost;
|
||||
VP8SetResidualCoeffs = SetResidualCoeffs;
|
||||
}
|
||||
|
||||
#else // !WEBP_USE_MIPS32
|
||||
|
@ -9,13 +9,13 @@
|
||||
//
|
||||
// Author: Djordje Pesut (djordje.pesut@imgtec.com)
|
||||
|
||||
#include "src/dsp/dsp.h"
|
||||
#include "./dsp.h"
|
||||
|
||||
#if defined(WEBP_USE_MIPS_DSP_R2)
|
||||
|
||||
#include "src/enc/cost_enc.h"
|
||||
#include "../enc/cost_enc.h"
|
||||
|
||||
static int GetResidualCost_MIPSdspR2(int ctx0, const VP8Residual* const res) {
|
||||
static int GetResidualCost(int ctx0, const VP8Residual* const res) {
|
||||
int temp0, temp1;
|
||||
int v_reg, ctx_reg;
|
||||
int n = res->first;
|
||||
@ -97,7 +97,7 @@ static int GetResidualCost_MIPSdspR2(int ctx0, const VP8Residual* const res) {
|
||||
extern void VP8EncDspCostInitMIPSdspR2(void);
|
||||
|
||||
WEBP_TSAN_IGNORE_FUNCTION void VP8EncDspCostInitMIPSdspR2(void) {
|
||||
VP8GetResidualCost = GetResidualCost_MIPSdspR2;
|
||||
VP8GetResidualCost = GetResidualCost;
|
||||
}
|
||||
|
||||
#else // !WEBP_USE_MIPS_DSP_R2
|
||||
|
@ -11,18 +11,18 @@
|
||||
//
|
||||
// Author: Skal (pascal.massimino@gmail.com)
|
||||
|
||||
#include "src/dsp/dsp.h"
|
||||
#include "./dsp.h"
|
||||
|
||||
#if defined(WEBP_USE_SSE2)
|
||||
#include <emmintrin.h>
|
||||
|
||||
#include "src/enc/cost_enc.h"
|
||||
#include "src/enc/vp8i_enc.h"
|
||||
#include "src/utils/utils.h"
|
||||
#include "../enc/cost_enc.h"
|
||||
#include "../enc/vp8i_enc.h"
|
||||
#include "../utils/utils.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
static void SetResidualCoeffs_SSE2(const int16_t* const coeffs,
|
||||
static void SetResidualCoeffsSSE2(const int16_t* const coeffs,
|
||||
VP8Residual* const res) {
|
||||
const __m128i c0 = _mm_loadu_si128((const __m128i*)(coeffs + 0));
|
||||
const __m128i c1 = _mm_loadu_si128((const __m128i*)(coeffs + 8));
|
||||
@ -42,7 +42,7 @@ static void SetResidualCoeffs_SSE2(const int16_t* const coeffs,
|
||||
res->coeffs = coeffs;
|
||||
}
|
||||
|
||||
static int GetResidualCost_SSE2(int ctx0, const VP8Residual* const res) {
|
||||
static int GetResidualCostSSE2(int ctx0, const VP8Residual* const res) {
|
||||
uint8_t levels[16], ctxs[16];
|
||||
uint16_t abs_levels[16];
|
||||
int n = res->first;
|
||||
@ -108,8 +108,8 @@ static int GetResidualCost_SSE2(int ctx0, const VP8Residual* const res) {
|
||||
extern void VP8EncDspCostInitSSE2(void);
|
||||
|
||||
WEBP_TSAN_IGNORE_FUNCTION void VP8EncDspCostInitSSE2(void) {
|
||||
VP8SetResidualCoeffs = SetResidualCoeffs_SSE2;
|
||||
VP8GetResidualCost = GetResidualCost_SSE2;
|
||||
VP8SetResidualCoeffs = SetResidualCoeffsSSE2;
|
||||
VP8GetResidualCost = GetResidualCostSSE2;
|
||||
}
|
||||
|
||||
#else // !WEBP_USE_SSE2
|
||||
|
@ -11,7 +11,7 @@
|
||||
//
|
||||
// Author: Christian Duvivier (cduvivier@google.com)
|
||||
|
||||
#include "src/dsp/dsp.h"
|
||||
#include "./dsp.h"
|
||||
|
||||
#if defined(WEBP_HAVE_NEON_RTCD)
|
||||
#include <stdio.h>
|
||||
@ -23,11 +23,13 @@
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// SSE2 detection.
|
||||
// x86/x86-64 micro-arch detection.
|
||||
//
|
||||
|
||||
// skip x86 specific code for WASM builds
|
||||
#if defined(WEBP_USE_WASM)
|
||||
// apple/darwin gcc-4.0.1 defines __PIC__, but not __pic__ with -fPIC.
|
||||
#if (defined(__pic__) || defined(__PIC__)) && defined(__i386__)
|
||||
#elif (defined(__pic__) || defined(__PIC__)) && defined(__i386__)
|
||||
static WEBP_INLINE void GetCPUInfo(int cpu_info[4], int info_type) {
|
||||
__asm__ volatile (
|
||||
"mov %%ebx, %%edi\n"
|
||||
@ -63,8 +65,10 @@ static WEBP_INLINE void GetCPUInfo(int cpu_info[4], int info_type) {
|
||||
#define GetCPUInfo __cpuid
|
||||
#endif
|
||||
|
||||
// skip xgetbv definition for WASM builds
|
||||
#if defined(WEBP_USE_WASM)
|
||||
// NaCl has no support for xgetbv or the raw opcode.
|
||||
#if !defined(__native_client__) && (defined(__i386__) || defined(__x86_64__))
|
||||
#elif !defined(__native_client__) && (defined(__i386__) || defined(__x86_64__))
|
||||
static WEBP_INLINE uint64_t xgetbv(void) {
|
||||
const uint32_t ecx = 0;
|
||||
uint32_t eax, edx;
|
||||
@ -94,7 +98,19 @@ static WEBP_INLINE uint64_t xgetbv(void) {
|
||||
#define xgetbv() 0U // no AVX for older x64 or unrecognized toolchains.
|
||||
#endif
|
||||
|
||||
#if defined(__i386__) || defined(__x86_64__) || defined(WEBP_MSC_SSE2)
|
||||
//------------------------------------------------------------------------------
|
||||
// Platform specific VP8CPUInfo functions.
|
||||
//
|
||||
|
||||
// WASM needs to precede platform specific architecture checks as the defines
|
||||
// will still be present when building this target.
|
||||
#if defined(WEBP_USE_WASM)
|
||||
static int wasmCPUInfo(CPUFeature feature) {
|
||||
if (feature != kWASM) return 0;
|
||||
return 1;
|
||||
}
|
||||
VP8CPUInfo VP8GetCPUInfo = wasmCPUInfo;
|
||||
#elif defined(__i386__) || defined(__x86_64__) || defined(WEBP_MSC_SSE2)
|
||||
|
||||
// helper function for run-time detection of slow SSSE3 platforms
|
||||
static int CheckSlowModel(int info) {
|
||||
@ -143,7 +159,7 @@ static int x86CPUInfo(CPUFeature feature) {
|
||||
return !!(cpu_info[2] & (1 << 0));
|
||||
}
|
||||
if (feature == kSlowSSSE3) {
|
||||
if (is_intel && (cpu_info[2] & (1 << 9))) { // SSSE3?
|
||||
if (is_intel && (cpu_info[2] & (1 << 0))) { // SSSE3?
|
||||
return CheckSlowModel(cpu_info[0]);
|
||||
}
|
||||
return 0;
|
||||
|
378
src/dsp/dec.c
378
src/dsp/dec.c
@ -11,11 +11,9 @@
|
||||
//
|
||||
// Author: Skal (pascal.massimino@gmail.com)
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "src/dsp/dsp.h"
|
||||
#include "src/dec/vp8i_dec.h"
|
||||
#include "src/utils/utils.h"
|
||||
#include "./dsp.h"
|
||||
#include "../dec/vp8i_dec.h"
|
||||
#include "../utils/utils.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@ -27,7 +25,7 @@ static WEBP_INLINE uint8_t clip_8b(int v) {
|
||||
// Transforms (Paragraph 14.4)
|
||||
|
||||
#define STORE(x, y, v) \
|
||||
dst[(x) + (y) * BPS] = clip_8b(dst[(x) + (y) * BPS] + ((v) >> 3))
|
||||
dst[x + y * BPS] = clip_8b(dst[x + y * BPS] + ((v) >> 3))
|
||||
|
||||
#define STORE2(y, dc, d, c) do { \
|
||||
const int DC = (dc); \
|
||||
@ -40,8 +38,7 @@ static WEBP_INLINE uint8_t clip_8b(int v) {
|
||||
#define MUL1(a) ((((a) * 20091) >> 16) + (a))
|
||||
#define MUL2(a) (((a) * 35468) >> 16)
|
||||
|
||||
#if !WEBP_NEON_OMIT_C_CODE
|
||||
static void TransformOne_C(const int16_t* in, uint8_t* dst) {
|
||||
static void TransformOne(const int16_t* in, uint8_t* dst) {
|
||||
int C[4 * 4], *tmp;
|
||||
int i;
|
||||
tmp = C;
|
||||
@ -81,7 +78,7 @@ static void TransformOne_C(const int16_t* in, uint8_t* dst) {
|
||||
}
|
||||
|
||||
// Simplified transform when only in[0], in[1] and in[4] are non-zero
|
||||
static void TransformAC3_C(const int16_t* in, uint8_t* dst) {
|
||||
static void TransformAC3(const int16_t* in, uint8_t* dst) {
|
||||
const int a = in[0] + 4;
|
||||
const int c4 = MUL2(in[4]);
|
||||
const int d4 = MUL1(in[4]);
|
||||
@ -96,21 +93,19 @@ static void TransformAC3_C(const int16_t* in, uint8_t* dst) {
|
||||
#undef MUL2
|
||||
#undef STORE2
|
||||
|
||||
static void TransformTwo_C(const int16_t* in, uint8_t* dst, int do_two) {
|
||||
TransformOne_C(in, dst);
|
||||
static void TransformTwo(const int16_t* in, uint8_t* dst, int do_two) {
|
||||
TransformOne(in, dst);
|
||||
if (do_two) {
|
||||
TransformOne_C(in + 16, dst + 4);
|
||||
TransformOne(in + 16, dst + 4);
|
||||
}
|
||||
}
|
||||
#endif // !WEBP_NEON_OMIT_C_CODE
|
||||
|
||||
static void TransformUV_C(const int16_t* in, uint8_t* dst) {
|
||||
static void TransformUV(const int16_t* in, uint8_t* dst) {
|
||||
VP8Transform(in + 0 * 16, dst, 1);
|
||||
VP8Transform(in + 2 * 16, dst + 4 * BPS, 1);
|
||||
}
|
||||
|
||||
#if !WEBP_NEON_OMIT_C_CODE
|
||||
static void TransformDC_C(const int16_t* in, uint8_t* dst) {
|
||||
static void TransformDC(const int16_t* in, uint8_t* dst) {
|
||||
const int DC = in[0] + 4;
|
||||
int i, j;
|
||||
for (j = 0; j < 4; ++j) {
|
||||
@ -119,9 +114,8 @@ static void TransformDC_C(const int16_t* in, uint8_t* dst) {
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // !WEBP_NEON_OMIT_C_CODE
|
||||
|
||||
static void TransformDCUV_C(const int16_t* in, uint8_t* dst) {
|
||||
static void TransformDCUV(const int16_t* in, uint8_t* dst) {
|
||||
if (in[0 * 16]) VP8TransformDC(in + 0 * 16, dst);
|
||||
if (in[1 * 16]) VP8TransformDC(in + 1 * 16, dst + 4);
|
||||
if (in[2 * 16]) VP8TransformDC(in + 2 * 16, dst + 4 * BPS);
|
||||
@ -133,8 +127,7 @@ static void TransformDCUV_C(const int16_t* in, uint8_t* dst) {
|
||||
//------------------------------------------------------------------------------
|
||||
// Paragraph 14.3
|
||||
|
||||
#if !WEBP_NEON_OMIT_C_CODE
|
||||
static void TransformWHT_C(const int16_t* in, int16_t* out) {
|
||||
static void TransformWHT(const int16_t* in, int16_t* out) {
|
||||
int tmp[16];
|
||||
int i;
|
||||
for (i = 0; i < 4; ++i) {
|
||||
@ -160,7 +153,6 @@ static void TransformWHT_C(const int16_t* in, int16_t* out) {
|
||||
out += 64;
|
||||
}
|
||||
}
|
||||
#endif // !WEBP_NEON_OMIT_C_CODE
|
||||
|
||||
void (*VP8TransformWHT)(const int16_t* in, int16_t* out);
|
||||
|
||||
@ -169,7 +161,6 @@ void (*VP8TransformWHT)(const int16_t* in, int16_t* out);
|
||||
|
||||
#define DST(x, y) dst[(x) + (y) * BPS]
|
||||
|
||||
#if !WEBP_NEON_OMIT_C_CODE
|
||||
static WEBP_INLINE void TrueMotion(uint8_t* dst, int size) {
|
||||
const uint8_t* top = dst - BPS;
|
||||
const uint8_t* const clip0 = VP8kclip1 - top[-1];
|
||||
@ -183,21 +174,21 @@ static WEBP_INLINE void TrueMotion(uint8_t* dst, int size) {
|
||||
dst += BPS;
|
||||
}
|
||||
}
|
||||
static void TM4_C(uint8_t* dst) { TrueMotion(dst, 4); }
|
||||
static void TM8uv_C(uint8_t* dst) { TrueMotion(dst, 8); }
|
||||
static void TM16_C(uint8_t* dst) { TrueMotion(dst, 16); }
|
||||
static void TM4(uint8_t* dst) { TrueMotion(dst, 4); }
|
||||
static void TM8uv(uint8_t* dst) { TrueMotion(dst, 8); }
|
||||
static void TM16(uint8_t* dst) { TrueMotion(dst, 16); }
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// 16x16
|
||||
|
||||
static void VE16_C(uint8_t* dst) { // vertical
|
||||
static void VE16(uint8_t* dst) { // vertical
|
||||
int j;
|
||||
for (j = 0; j < 16; ++j) {
|
||||
memcpy(dst + j * BPS, dst - BPS, 16);
|
||||
}
|
||||
}
|
||||
|
||||
static void HE16_C(uint8_t* dst) { // horizontal
|
||||
static void HE16(uint8_t* dst) { // horizontal
|
||||
int j;
|
||||
for (j = 16; j > 0; --j) {
|
||||
memset(dst, dst[-1], 16);
|
||||
@ -212,7 +203,7 @@ static WEBP_INLINE void Put16(int v, uint8_t* dst) {
|
||||
}
|
||||
}
|
||||
|
||||
static void DC16_C(uint8_t* dst) { // DC
|
||||
static void DC16(uint8_t* dst) { // DC
|
||||
int DC = 16;
|
||||
int j;
|
||||
for (j = 0; j < 16; ++j) {
|
||||
@ -221,7 +212,7 @@ static void DC16_C(uint8_t* dst) { // DC
|
||||
Put16(DC >> 5, dst);
|
||||
}
|
||||
|
||||
static void DC16NoTop_C(uint8_t* dst) { // DC with top samples not available
|
||||
static void DC16NoTop(uint8_t* dst) { // DC with top samples not available
|
||||
int DC = 8;
|
||||
int j;
|
||||
for (j = 0; j < 16; ++j) {
|
||||
@ -230,7 +221,7 @@ static void DC16NoTop_C(uint8_t* dst) { // DC with top samples not available
|
||||
Put16(DC >> 4, dst);
|
||||
}
|
||||
|
||||
static void DC16NoLeft_C(uint8_t* dst) { // DC with left samples not available
|
||||
static void DC16NoLeft(uint8_t* dst) { // DC with left samples not available
|
||||
int DC = 8;
|
||||
int i;
|
||||
for (i = 0; i < 16; ++i) {
|
||||
@ -239,10 +230,9 @@ static void DC16NoLeft_C(uint8_t* dst) { // DC with left samples not available
|
||||
Put16(DC >> 4, dst);
|
||||
}
|
||||
|
||||
static void DC16NoTopLeft_C(uint8_t* dst) { // DC with no top and left samples
|
||||
static void DC16NoTopLeft(uint8_t* dst) { // DC with no top and left samples
|
||||
Put16(0x80, dst);
|
||||
}
|
||||
#endif // !WEBP_NEON_OMIT_C_CODE
|
||||
|
||||
VP8PredFunc VP8PredLuma16[NUM_B_DC_MODES];
|
||||
|
||||
@ -252,8 +242,7 @@ VP8PredFunc VP8PredLuma16[NUM_B_DC_MODES];
|
||||
#define AVG3(a, b, c) ((uint8_t)(((a) + 2 * (b) + (c) + 2) >> 2))
|
||||
#define AVG2(a, b) (((a) + (b) + 1) >> 1)
|
||||
|
||||
#if !WEBP_NEON_OMIT_C_CODE
|
||||
static void VE4_C(uint8_t* dst) { // vertical
|
||||
static void VE4(uint8_t* dst) { // vertical
|
||||
const uint8_t* top = dst - BPS;
|
||||
const uint8_t vals[4] = {
|
||||
AVG3(top[-1], top[0], top[1]),
|
||||
@ -266,9 +255,8 @@ static void VE4_C(uint8_t* dst) { // vertical
|
||||
memcpy(dst + i * BPS, vals, sizeof(vals));
|
||||
}
|
||||
}
|
||||
#endif // !WEBP_NEON_OMIT_C_CODE
|
||||
|
||||
static void HE4_C(uint8_t* dst) { // horizontal
|
||||
static void HE4(uint8_t* dst) { // horizontal
|
||||
const int A = dst[-1 - BPS];
|
||||
const int B = dst[-1];
|
||||
const int C = dst[-1 + BPS];
|
||||
@ -280,8 +268,7 @@ static void HE4_C(uint8_t* dst) { // horizontal
|
||||
WebPUint32ToMem(dst + 3 * BPS, 0x01010101U * AVG3(D, E, E));
|
||||
}
|
||||
|
||||
#if !WEBP_NEON_OMIT_C_CODE
|
||||
static void DC4_C(uint8_t* dst) { // DC
|
||||
static void DC4(uint8_t* dst) { // DC
|
||||
uint32_t dc = 4;
|
||||
int i;
|
||||
for (i = 0; i < 4; ++i) dc += dst[i - BPS] + dst[-1 + i * BPS];
|
||||
@ -289,7 +276,7 @@ static void DC4_C(uint8_t* dst) { // DC
|
||||
for (i = 0; i < 4; ++i) memset(dst + i * BPS, dc, 4);
|
||||
}
|
||||
|
||||
static void RD4_C(uint8_t* dst) { // Down-right
|
||||
static void RD4(uint8_t* dst) { // Down-right
|
||||
const int I = dst[-1 + 0 * BPS];
|
||||
const int J = dst[-1 + 1 * BPS];
|
||||
const int K = dst[-1 + 2 * BPS];
|
||||
@ -308,7 +295,7 @@ static void RD4_C(uint8_t* dst) { // Down-right
|
||||
DST(3, 0) = AVG3(D, C, B);
|
||||
}
|
||||
|
||||
static void LD4_C(uint8_t* dst) { // Down-Left
|
||||
static void LD4(uint8_t* dst) { // Down-Left
|
||||
const int A = dst[0 - BPS];
|
||||
const int B = dst[1 - BPS];
|
||||
const int C = dst[2 - BPS];
|
||||
@ -325,9 +312,8 @@ static void LD4_C(uint8_t* dst) { // Down-Left
|
||||
DST(3, 2) = DST(2, 3) = AVG3(F, G, H);
|
||||
DST(3, 3) = AVG3(G, H, H);
|
||||
}
|
||||
#endif // !WEBP_NEON_OMIT_C_CODE
|
||||
|
||||
static void VR4_C(uint8_t* dst) { // Vertical-Right
|
||||
static void VR4(uint8_t* dst) { // Vertical-Right
|
||||
const int I = dst[-1 + 0 * BPS];
|
||||
const int J = dst[-1 + 1 * BPS];
|
||||
const int K = dst[-1 + 2 * BPS];
|
||||
@ -349,7 +335,7 @@ static void VR4_C(uint8_t* dst) { // Vertical-Right
|
||||
DST(3, 1) = AVG3(B, C, D);
|
||||
}
|
||||
|
||||
static void VL4_C(uint8_t* dst) { // Vertical-Left
|
||||
static void VL4(uint8_t* dst) { // Vertical-Left
|
||||
const int A = dst[0 - BPS];
|
||||
const int B = dst[1 - BPS];
|
||||
const int C = dst[2 - BPS];
|
||||
@ -371,7 +357,7 @@ static void VL4_C(uint8_t* dst) { // Vertical-Left
|
||||
DST(3, 3) = AVG3(F, G, H);
|
||||
}
|
||||
|
||||
static void HU4_C(uint8_t* dst) { // Horizontal-Up
|
||||
static void HU4(uint8_t* dst) { // Horizontal-Up
|
||||
const int I = dst[-1 + 0 * BPS];
|
||||
const int J = dst[-1 + 1 * BPS];
|
||||
const int K = dst[-1 + 2 * BPS];
|
||||
@ -386,7 +372,7 @@ static void HU4_C(uint8_t* dst) { // Horizontal-Up
|
||||
DST(0, 3) = DST(1, 3) = DST(2, 3) = DST(3, 3) = L;
|
||||
}
|
||||
|
||||
static void HD4_C(uint8_t* dst) { // Horizontal-Down
|
||||
static void HD4(uint8_t* dst) { // Horizontal-Down
|
||||
const int I = dst[-1 + 0 * BPS];
|
||||
const int J = dst[-1 + 1 * BPS];
|
||||
const int K = dst[-1 + 2 * BPS];
|
||||
@ -418,15 +404,14 @@ VP8PredFunc VP8PredLuma4[NUM_BMODES];
|
||||
//------------------------------------------------------------------------------
|
||||
// Chroma
|
||||
|
||||
#if !WEBP_NEON_OMIT_C_CODE
|
||||
static void VE8uv_C(uint8_t* dst) { // vertical
|
||||
static void VE8uv(uint8_t* dst) { // vertical
|
||||
int j;
|
||||
for (j = 0; j < 8; ++j) {
|
||||
memcpy(dst + j * BPS, dst - BPS, 8);
|
||||
}
|
||||
}
|
||||
|
||||
static void HE8uv_C(uint8_t* dst) { // horizontal
|
||||
static void HE8uv(uint8_t* dst) { // horizontal
|
||||
int j;
|
||||
for (j = 0; j < 8; ++j) {
|
||||
memset(dst, dst[-1], 8);
|
||||
@ -442,7 +427,7 @@ static WEBP_INLINE void Put8x8uv(uint8_t value, uint8_t* dst) {
|
||||
}
|
||||
}
|
||||
|
||||
static void DC8uv_C(uint8_t* dst) { // DC
|
||||
static void DC8uv(uint8_t* dst) { // DC
|
||||
int dc0 = 8;
|
||||
int i;
|
||||
for (i = 0; i < 8; ++i) {
|
||||
@ -451,7 +436,7 @@ static void DC8uv_C(uint8_t* dst) { // DC
|
||||
Put8x8uv(dc0 >> 4, dst);
|
||||
}
|
||||
|
||||
static void DC8uvNoLeft_C(uint8_t* dst) { // DC with no left samples
|
||||
static void DC8uvNoLeft(uint8_t* dst) { // DC with no left samples
|
||||
int dc0 = 4;
|
||||
int i;
|
||||
for (i = 0; i < 8; ++i) {
|
||||
@ -460,7 +445,7 @@ static void DC8uvNoLeft_C(uint8_t* dst) { // DC with no left samples
|
||||
Put8x8uv(dc0 >> 3, dst);
|
||||
}
|
||||
|
||||
static void DC8uvNoTop_C(uint8_t* dst) { // DC with no top samples
|
||||
static void DC8uvNoTop(uint8_t* dst) { // DC with no top samples
|
||||
int dc0 = 4;
|
||||
int i;
|
||||
for (i = 0; i < 8; ++i) {
|
||||
@ -469,19 +454,17 @@ static void DC8uvNoTop_C(uint8_t* dst) { // DC with no top samples
|
||||
Put8x8uv(dc0 >> 3, dst);
|
||||
}
|
||||
|
||||
static void DC8uvNoTopLeft_C(uint8_t* dst) { // DC with nothing
|
||||
static void DC8uvNoTopLeft(uint8_t* dst) { // DC with nothing
|
||||
Put8x8uv(0x80, dst);
|
||||
}
|
||||
#endif // !WEBP_NEON_OMIT_C_CODE
|
||||
|
||||
VP8PredFunc VP8PredChroma8[NUM_B_DC_MODES];
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Edge filtering functions
|
||||
|
||||
#if !WEBP_NEON_OMIT_C_CODE || WEBP_NEON_WORK_AROUND_GCC
|
||||
// 4 pixels in, 2 pixels out
|
||||
static WEBP_INLINE void DoFilter2_C(uint8_t* p, int step) {
|
||||
static WEBP_INLINE void do_filter2(uint8_t* p, int step) {
|
||||
const int p1 = p[-2*step], p0 = p[-step], q0 = p[0], q1 = p[step];
|
||||
const int a = 3 * (q0 - p0) + VP8ksclip1[p1 - q1]; // in [-893,892]
|
||||
const int a1 = VP8ksclip2[(a + 4) >> 3]; // in [-16,15]
|
||||
@ -491,7 +474,7 @@ static WEBP_INLINE void DoFilter2_C(uint8_t* p, int step) {
|
||||
}
|
||||
|
||||
// 4 pixels in, 4 pixels out
|
||||
static WEBP_INLINE void DoFilter4_C(uint8_t* p, int step) {
|
||||
static WEBP_INLINE void do_filter4(uint8_t* p, int step) {
|
||||
const int p1 = p[-2*step], p0 = p[-step], q0 = p[0], q1 = p[step];
|
||||
const int a = 3 * (q0 - p0);
|
||||
const int a1 = VP8ksclip2[(a + 4) >> 3];
|
||||
@ -504,7 +487,7 @@ static WEBP_INLINE void DoFilter4_C(uint8_t* p, int step) {
|
||||
}
|
||||
|
||||
// 6 pixels in, 6 pixels out
|
||||
static WEBP_INLINE void DoFilter6_C(uint8_t* p, int step) {
|
||||
static WEBP_INLINE void do_filter6(uint8_t* p, int step) {
|
||||
const int p2 = p[-3*step], p1 = p[-2*step], p0 = p[-step];
|
||||
const int q0 = p[0], q1 = p[step], q2 = p[2*step];
|
||||
const int a = VP8ksclip1[3 * (q0 - p0) + VP8ksclip1[p1 - q1]];
|
||||
@ -520,21 +503,17 @@ static WEBP_INLINE void DoFilter6_C(uint8_t* p, int step) {
|
||||
p[ 2*step] = VP8kclip1[q2 - a3];
|
||||
}
|
||||
|
||||
static WEBP_INLINE int Hev(const uint8_t* p, int step, int thresh) {
|
||||
static WEBP_INLINE int hev(const uint8_t* p, int step, int thresh) {
|
||||
const int p1 = p[-2*step], p0 = p[-step], q0 = p[0], q1 = p[step];
|
||||
return (VP8kabs0[p1 - p0] > thresh) || (VP8kabs0[q1 - q0] > thresh);
|
||||
}
|
||||
#endif // !WEBP_NEON_OMIT_C_CODE || WEBP_NEON_WORK_AROUND_GCC
|
||||
|
||||
#if !WEBP_NEON_OMIT_C_CODE
|
||||
static WEBP_INLINE int NeedsFilter_C(const uint8_t* p, int step, int t) {
|
||||
static WEBP_INLINE int needs_filter(const uint8_t* p, int step, int t) {
|
||||
const int p1 = p[-2 * step], p0 = p[-step], q0 = p[0], q1 = p[step];
|
||||
return ((4 * VP8kabs0[p0 - q0] + VP8kabs0[p1 - q1]) <= t);
|
||||
}
|
||||
#endif // !WEBP_NEON_OMIT_C_CODE
|
||||
|
||||
#if !WEBP_NEON_OMIT_C_CODE || WEBP_NEON_WORK_AROUND_GCC
|
||||
static WEBP_INLINE int NeedsFilter2_C(const uint8_t* p,
|
||||
static WEBP_INLINE int needs_filter2(const uint8_t* p,
|
||||
int step, int t, int it) {
|
||||
const int p3 = p[-4 * step], p2 = p[-3 * step], p1 = p[-2 * step];
|
||||
const int p0 = p[-step], q0 = p[0];
|
||||
@ -544,158 +523,139 @@ static WEBP_INLINE int NeedsFilter2_C(const uint8_t* p,
|
||||
VP8kabs0[p1 - p0] <= it && VP8kabs0[q3 - q2] <= it &&
|
||||
VP8kabs0[q2 - q1] <= it && VP8kabs0[q1 - q0] <= it;
|
||||
}
|
||||
#endif // !WEBP_NEON_OMIT_C_CODE || WEBP_NEON_WORK_AROUND_GCC
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Simple In-loop filtering (Paragraph 15.2)
|
||||
|
||||
#if !WEBP_NEON_OMIT_C_CODE
|
||||
static void SimpleVFilter16_C(uint8_t* p, int stride, int thresh) {
|
||||
static void SimpleVFilter16(uint8_t* p, int stride, int thresh) {
|
||||
int i;
|
||||
const int thresh2 = 2 * thresh + 1;
|
||||
for (i = 0; i < 16; ++i) {
|
||||
if (NeedsFilter_C(p + i, stride, thresh2)) {
|
||||
DoFilter2_C(p + i, stride);
|
||||
if (needs_filter(p + i, stride, thresh2)) {
|
||||
do_filter2(p + i, stride);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void SimpleHFilter16_C(uint8_t* p, int stride, int thresh) {
|
||||
static void SimpleHFilter16(uint8_t* p, int stride, int thresh) {
|
||||
int i;
|
||||
const int thresh2 = 2 * thresh + 1;
|
||||
for (i = 0; i < 16; ++i) {
|
||||
if (NeedsFilter_C(p + i * stride, 1, thresh2)) {
|
||||
DoFilter2_C(p + i * stride, 1);
|
||||
if (needs_filter(p + i * stride, 1, thresh2)) {
|
||||
do_filter2(p + i * stride, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void SimpleVFilter16i_C(uint8_t* p, int stride, int thresh) {
|
||||
static void SimpleVFilter16i(uint8_t* p, int stride, int thresh) {
|
||||
int k;
|
||||
for (k = 3; k > 0; --k) {
|
||||
p += 4 * stride;
|
||||
SimpleVFilter16_C(p, stride, thresh);
|
||||
SimpleVFilter16(p, stride, thresh);
|
||||
}
|
||||
}
|
||||
|
||||
static void SimpleHFilter16i_C(uint8_t* p, int stride, int thresh) {
|
||||
static void SimpleHFilter16i(uint8_t* p, int stride, int thresh) {
|
||||
int k;
|
||||
for (k = 3; k > 0; --k) {
|
||||
p += 4;
|
||||
SimpleHFilter16_C(p, stride, thresh);
|
||||
SimpleHFilter16(p, stride, thresh);
|
||||
}
|
||||
}
|
||||
#endif // !WEBP_NEON_OMIT_C_CODE
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Complex In-loop filtering (Paragraph 15.3)
|
||||
|
||||
#if !WEBP_NEON_OMIT_C_CODE || WEBP_NEON_WORK_AROUND_GCC
|
||||
static WEBP_INLINE void FilterLoop26_C(uint8_t* p,
|
||||
static WEBP_INLINE void FilterLoop26(uint8_t* p,
|
||||
int hstride, int vstride, int size,
|
||||
int thresh, int ithresh,
|
||||
int hev_thresh) {
|
||||
int thresh, int ithresh, int hev_thresh) {
|
||||
const int thresh2 = 2 * thresh + 1;
|
||||
while (size-- > 0) {
|
||||
if (NeedsFilter2_C(p, hstride, thresh2, ithresh)) {
|
||||
if (Hev(p, hstride, hev_thresh)) {
|
||||
DoFilter2_C(p, hstride);
|
||||
if (needs_filter2(p, hstride, thresh2, ithresh)) {
|
||||
if (hev(p, hstride, hev_thresh)) {
|
||||
do_filter2(p, hstride);
|
||||
} else {
|
||||
DoFilter6_C(p, hstride);
|
||||
do_filter6(p, hstride);
|
||||
}
|
||||
}
|
||||
p += vstride;
|
||||
}
|
||||
}
|
||||
|
||||
static WEBP_INLINE void FilterLoop24_C(uint8_t* p,
|
||||
static WEBP_INLINE void FilterLoop24(uint8_t* p,
|
||||
int hstride, int vstride, int size,
|
||||
int thresh, int ithresh,
|
||||
int hev_thresh) {
|
||||
int thresh, int ithresh, int hev_thresh) {
|
||||
const int thresh2 = 2 * thresh + 1;
|
||||
while (size-- > 0) {
|
||||
if (NeedsFilter2_C(p, hstride, thresh2, ithresh)) {
|
||||
if (Hev(p, hstride, hev_thresh)) {
|
||||
DoFilter2_C(p, hstride);
|
||||
if (needs_filter2(p, hstride, thresh2, ithresh)) {
|
||||
if (hev(p, hstride, hev_thresh)) {
|
||||
do_filter2(p, hstride);
|
||||
} else {
|
||||
DoFilter4_C(p, hstride);
|
||||
do_filter4(p, hstride);
|
||||
}
|
||||
}
|
||||
p += vstride;
|
||||
}
|
||||
}
|
||||
#endif // !WEBP_NEON_OMIT_C_CODE || WEBP_NEON_WORK_AROUND_GCC
|
||||
|
||||
#if !WEBP_NEON_OMIT_C_CODE
|
||||
// on macroblock edges
|
||||
static void VFilter16_C(uint8_t* p, int stride,
|
||||
static void VFilter16(uint8_t* p, int stride,
|
||||
int thresh, int ithresh, int hev_thresh) {
|
||||
FilterLoop26_C(p, stride, 1, 16, thresh, ithresh, hev_thresh);
|
||||
FilterLoop26(p, stride, 1, 16, thresh, ithresh, hev_thresh);
|
||||
}
|
||||
|
||||
static void HFilter16_C(uint8_t* p, int stride,
|
||||
static void HFilter16(uint8_t* p, int stride,
|
||||
int thresh, int ithresh, int hev_thresh) {
|
||||
FilterLoop26_C(p, 1, stride, 16, thresh, ithresh, hev_thresh);
|
||||
FilterLoop26(p, 1, stride, 16, thresh, ithresh, hev_thresh);
|
||||
}
|
||||
|
||||
// on three inner edges
|
||||
static void VFilter16i_C(uint8_t* p, int stride,
|
||||
static void VFilter16i(uint8_t* p, int stride,
|
||||
int thresh, int ithresh, int hev_thresh) {
|
||||
int k;
|
||||
for (k = 3; k > 0; --k) {
|
||||
p += 4 * stride;
|
||||
FilterLoop24_C(p, stride, 1, 16, thresh, ithresh, hev_thresh);
|
||||
FilterLoop24(p, stride, 1, 16, thresh, ithresh, hev_thresh);
|
||||
}
|
||||
}
|
||||
#endif // !WEBP_NEON_OMIT_C_CODE
|
||||
|
||||
#if !WEBP_NEON_OMIT_C_CODE || WEBP_NEON_WORK_AROUND_GCC
|
||||
static void HFilter16i_C(uint8_t* p, int stride,
|
||||
static void HFilter16i(uint8_t* p, int stride,
|
||||
int thresh, int ithresh, int hev_thresh) {
|
||||
int k;
|
||||
for (k = 3; k > 0; --k) {
|
||||
p += 4;
|
||||
FilterLoop24_C(p, 1, stride, 16, thresh, ithresh, hev_thresh);
|
||||
FilterLoop24(p, 1, stride, 16, thresh, ithresh, hev_thresh);
|
||||
}
|
||||
}
|
||||
#endif // !WEBP_NEON_OMIT_C_CODE || WEBP_NEON_WORK_AROUND_GCC
|
||||
|
||||
#if !WEBP_NEON_OMIT_C_CODE
|
||||
// 8-pixels wide variant, for chroma filtering
|
||||
static void VFilter8_C(uint8_t* u, uint8_t* v, int stride,
|
||||
static void VFilter8(uint8_t* u, uint8_t* v, int stride,
|
||||
int thresh, int ithresh, int hev_thresh) {
|
||||
FilterLoop26_C(u, stride, 1, 8, thresh, ithresh, hev_thresh);
|
||||
FilterLoop26_C(v, stride, 1, 8, thresh, ithresh, hev_thresh);
|
||||
FilterLoop26(u, stride, 1, 8, thresh, ithresh, hev_thresh);
|
||||
FilterLoop26(v, stride, 1, 8, thresh, ithresh, hev_thresh);
|
||||
}
|
||||
#endif // !WEBP_NEON_OMIT_C_CODE
|
||||
|
||||
#if !WEBP_NEON_OMIT_C_CODE || WEBP_NEON_WORK_AROUND_GCC
|
||||
static void HFilter8_C(uint8_t* u, uint8_t* v, int stride,
|
||||
static void HFilter8(uint8_t* u, uint8_t* v, int stride,
|
||||
int thresh, int ithresh, int hev_thresh) {
|
||||
FilterLoop26_C(u, 1, stride, 8, thresh, ithresh, hev_thresh);
|
||||
FilterLoop26_C(v, 1, stride, 8, thresh, ithresh, hev_thresh);
|
||||
FilterLoop26(u, 1, stride, 8, thresh, ithresh, hev_thresh);
|
||||
FilterLoop26(v, 1, stride, 8, thresh, ithresh, hev_thresh);
|
||||
}
|
||||
#endif // !WEBP_NEON_OMIT_C_CODE || WEBP_NEON_WORK_AROUND_GCC
|
||||
|
||||
#if !WEBP_NEON_OMIT_C_CODE
|
||||
static void VFilter8i_C(uint8_t* u, uint8_t* v, int stride,
|
||||
static void VFilter8i(uint8_t* u, uint8_t* v, int stride,
|
||||
int thresh, int ithresh, int hev_thresh) {
|
||||
FilterLoop24_C(u + 4 * stride, stride, 1, 8, thresh, ithresh, hev_thresh);
|
||||
FilterLoop24_C(v + 4 * stride, stride, 1, 8, thresh, ithresh, hev_thresh);
|
||||
FilterLoop24(u + 4 * stride, stride, 1, 8, thresh, ithresh, hev_thresh);
|
||||
FilterLoop24(v + 4 * stride, stride, 1, 8, thresh, ithresh, hev_thresh);
|
||||
}
|
||||
#endif // !WEBP_NEON_OMIT_C_CODE
|
||||
|
||||
#if !WEBP_NEON_OMIT_C_CODE || WEBP_NEON_WORK_AROUND_GCC
|
||||
static void HFilter8i_C(uint8_t* u, uint8_t* v, int stride,
|
||||
static void HFilter8i(uint8_t* u, uint8_t* v, int stride,
|
||||
int thresh, int ithresh, int hev_thresh) {
|
||||
FilterLoop24_C(u + 4, 1, stride, 8, thresh, ithresh, hev_thresh);
|
||||
FilterLoop24_C(v + 4, 1, stride, 8, thresh, ithresh, hev_thresh);
|
||||
FilterLoop24(u + 4, 1, stride, 8, thresh, ithresh, hev_thresh);
|
||||
FilterLoop24(v + 4, 1, stride, 8, thresh, ithresh, hev_thresh);
|
||||
}
|
||||
#endif // !WEBP_NEON_OMIT_C_CODE || WEBP_NEON_WORK_AROUND_GCC
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
static void DitherCombine8x8_C(const uint8_t* dither, uint8_t* dst,
|
||||
static void DitherCombine8x8(const uint8_t* dither, uint8_t* dst,
|
||||
int dst_stride) {
|
||||
int i, j;
|
||||
for (j = 0; j < 8; ++j) {
|
||||
@ -740,70 +700,64 @@ extern void VP8DspInitNEON(void);
|
||||
extern void VP8DspInitMIPS32(void);
|
||||
extern void VP8DspInitMIPSdspR2(void);
|
||||
extern void VP8DspInitMSA(void);
|
||||
extern void VP8DspInitWASM(void);
|
||||
|
||||
static volatile VP8CPUInfo dec_last_cpuinfo_used =
|
||||
(VP8CPUInfo)&dec_last_cpuinfo_used;
|
||||
|
||||
WEBP_TSAN_IGNORE_FUNCTION void VP8DspInit(void) {
|
||||
if (dec_last_cpuinfo_used == VP8GetCPUInfo) return;
|
||||
|
||||
WEBP_DSP_INIT_FUNC(VP8DspInit) {
|
||||
VP8InitClipTables();
|
||||
|
||||
#if !WEBP_NEON_OMIT_C_CODE
|
||||
VP8TransformWHT = TransformWHT_C;
|
||||
VP8Transform = TransformTwo_C;
|
||||
VP8TransformDC = TransformDC_C;
|
||||
VP8TransformAC3 = TransformAC3_C;
|
||||
#endif
|
||||
VP8TransformUV = TransformUV_C;
|
||||
VP8TransformDCUV = TransformDCUV_C;
|
||||
VP8TransformWHT = TransformWHT;
|
||||
VP8Transform = TransformTwo;
|
||||
VP8TransformUV = TransformUV;
|
||||
VP8TransformDC = TransformDC;
|
||||
VP8TransformDCUV = TransformDCUV;
|
||||
VP8TransformAC3 = TransformAC3;
|
||||
|
||||
#if !WEBP_NEON_OMIT_C_CODE
|
||||
VP8VFilter16 = VFilter16_C;
|
||||
VP8VFilter16i = VFilter16i_C;
|
||||
VP8HFilter16 = HFilter16_C;
|
||||
VP8VFilter8 = VFilter8_C;
|
||||
VP8VFilter8i = VFilter8i_C;
|
||||
VP8SimpleVFilter16 = SimpleVFilter16_C;
|
||||
VP8SimpleHFilter16 = SimpleHFilter16_C;
|
||||
VP8SimpleVFilter16i = SimpleVFilter16i_C;
|
||||
VP8SimpleHFilter16i = SimpleHFilter16i_C;
|
||||
#endif
|
||||
VP8VFilter16 = VFilter16;
|
||||
VP8HFilter16 = HFilter16;
|
||||
VP8VFilter8 = VFilter8;
|
||||
VP8HFilter8 = HFilter8;
|
||||
VP8VFilter16i = VFilter16i;
|
||||
VP8HFilter16i = HFilter16i;
|
||||
VP8VFilter8i = VFilter8i;
|
||||
VP8HFilter8i = HFilter8i;
|
||||
VP8SimpleVFilter16 = SimpleVFilter16;
|
||||
VP8SimpleHFilter16 = SimpleHFilter16;
|
||||
VP8SimpleVFilter16i = SimpleVFilter16i;
|
||||
VP8SimpleHFilter16i = SimpleHFilter16i;
|
||||
|
||||
#if !WEBP_NEON_OMIT_C_CODE || WEBP_NEON_WORK_AROUND_GCC
|
||||
VP8HFilter16i = HFilter16i_C;
|
||||
VP8HFilter8 = HFilter8_C;
|
||||
VP8HFilter8i = HFilter8i_C;
|
||||
#endif
|
||||
VP8PredLuma4[0] = DC4;
|
||||
VP8PredLuma4[1] = TM4;
|
||||
VP8PredLuma4[2] = VE4;
|
||||
VP8PredLuma4[3] = HE4;
|
||||
VP8PredLuma4[4] = RD4;
|
||||
VP8PredLuma4[5] = VR4;
|
||||
VP8PredLuma4[6] = LD4;
|
||||
VP8PredLuma4[7] = VL4;
|
||||
VP8PredLuma4[8] = HD4;
|
||||
VP8PredLuma4[9] = HU4;
|
||||
|
||||
#if !WEBP_NEON_OMIT_C_CODE
|
||||
VP8PredLuma4[0] = DC4_C;
|
||||
VP8PredLuma4[1] = TM4_C;
|
||||
VP8PredLuma4[2] = VE4_C;
|
||||
VP8PredLuma4[4] = RD4_C;
|
||||
VP8PredLuma4[6] = LD4_C;
|
||||
#endif
|
||||
VP8PredLuma16[0] = DC16;
|
||||
VP8PredLuma16[1] = TM16;
|
||||
VP8PredLuma16[2] = VE16;
|
||||
VP8PredLuma16[3] = HE16;
|
||||
VP8PredLuma16[4] = DC16NoTop;
|
||||
VP8PredLuma16[5] = DC16NoLeft;
|
||||
VP8PredLuma16[6] = DC16NoTopLeft;
|
||||
|
||||
VP8PredLuma4[3] = HE4_C;
|
||||
VP8PredLuma4[5] = VR4_C;
|
||||
VP8PredLuma4[7] = VL4_C;
|
||||
VP8PredLuma4[8] = HD4_C;
|
||||
VP8PredLuma4[9] = HU4_C;
|
||||
VP8PredChroma8[0] = DC8uv;
|
||||
VP8PredChroma8[1] = TM8uv;
|
||||
VP8PredChroma8[2] = VE8uv;
|
||||
VP8PredChroma8[3] = HE8uv;
|
||||
VP8PredChroma8[4] = DC8uvNoTop;
|
||||
VP8PredChroma8[5] = DC8uvNoLeft;
|
||||
VP8PredChroma8[6] = DC8uvNoTopLeft;
|
||||
|
||||
#if !WEBP_NEON_OMIT_C_CODE
|
||||
VP8PredLuma16[0] = DC16_C;
|
||||
VP8PredLuma16[1] = TM16_C;
|
||||
VP8PredLuma16[2] = VE16_C;
|
||||
VP8PredLuma16[3] = HE16_C;
|
||||
VP8PredLuma16[4] = DC16NoTop_C;
|
||||
VP8PredLuma16[5] = DC16NoLeft_C;
|
||||
VP8PredLuma16[6] = DC16NoTopLeft_C;
|
||||
|
||||
VP8PredChroma8[0] = DC8uv_C;
|
||||
VP8PredChroma8[1] = TM8uv_C;
|
||||
VP8PredChroma8[2] = VE8uv_C;
|
||||
VP8PredChroma8[3] = HE8uv_C;
|
||||
VP8PredChroma8[4] = DC8uvNoTop_C;
|
||||
VP8PredChroma8[5] = DC8uvNoLeft_C;
|
||||
VP8PredChroma8[6] = DC8uvNoTopLeft_C;
|
||||
#endif
|
||||
|
||||
VP8DitherCombine8x8 = DitherCombine8x8_C;
|
||||
VP8DitherCombine8x8 = DitherCombine8x8;
|
||||
|
||||
// If defined, use CPUInfo() to overwrite some pointers with faster versions.
|
||||
if (VP8GetCPUInfo != NULL) {
|
||||
@ -817,6 +771,11 @@ WEBP_DSP_INIT_FUNC(VP8DspInit) {
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
#if defined(WEBP_USE_NEON)
|
||||
if (VP8GetCPUInfo(kNEON)) {
|
||||
VP8DspInitNEON();
|
||||
}
|
||||
#endif
|
||||
#if defined(WEBP_USE_MIPS32)
|
||||
if (VP8GetCPUInfo(kMIPS32)) {
|
||||
VP8DspInitMIPS32();
|
||||
@ -832,56 +791,11 @@ WEBP_DSP_INIT_FUNC(VP8DspInit) {
|
||||
VP8DspInitMSA();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(WEBP_USE_NEON)
|
||||
if (WEBP_NEON_OMIT_C_CODE ||
|
||||
(VP8GetCPUInfo != NULL && VP8GetCPUInfo(kNEON))) {
|
||||
VP8DspInitNEON();
|
||||
#if defined(WEBP_USE_WASM)
|
||||
if (VP8GetCPUInfo(kWASM)) {
|
||||
VP8DspInitWASM();
|
||||
}
|
||||
#endif
|
||||
|
||||
assert(VP8TransformWHT != NULL);
|
||||
assert(VP8Transform != NULL);
|
||||
assert(VP8TransformDC != NULL);
|
||||
assert(VP8TransformAC3 != NULL);
|
||||
assert(VP8TransformUV != NULL);
|
||||
assert(VP8TransformDCUV != NULL);
|
||||
assert(VP8VFilter16 != NULL);
|
||||
assert(VP8HFilter16 != NULL);
|
||||
assert(VP8VFilter8 != NULL);
|
||||
assert(VP8HFilter8 != NULL);
|
||||
assert(VP8VFilter16i != NULL);
|
||||
assert(VP8HFilter16i != NULL);
|
||||
assert(VP8VFilter8i != NULL);
|
||||
assert(VP8HFilter8i != NULL);
|
||||
assert(VP8SimpleVFilter16 != NULL);
|
||||
assert(VP8SimpleHFilter16 != NULL);
|
||||
assert(VP8SimpleVFilter16i != NULL);
|
||||
assert(VP8SimpleHFilter16i != NULL);
|
||||
assert(VP8PredLuma4[0] != NULL);
|
||||
assert(VP8PredLuma4[1] != NULL);
|
||||
assert(VP8PredLuma4[2] != NULL);
|
||||
assert(VP8PredLuma4[3] != NULL);
|
||||
assert(VP8PredLuma4[4] != NULL);
|
||||
assert(VP8PredLuma4[5] != NULL);
|
||||
assert(VP8PredLuma4[6] != NULL);
|
||||
assert(VP8PredLuma4[7] != NULL);
|
||||
assert(VP8PredLuma4[8] != NULL);
|
||||
assert(VP8PredLuma4[9] != NULL);
|
||||
assert(VP8PredLuma16[0] != NULL);
|
||||
assert(VP8PredLuma16[1] != NULL);
|
||||
assert(VP8PredLuma16[2] != NULL);
|
||||
assert(VP8PredLuma16[3] != NULL);
|
||||
assert(VP8PredLuma16[4] != NULL);
|
||||
assert(VP8PredLuma16[5] != NULL);
|
||||
assert(VP8PredLuma16[6] != NULL);
|
||||
assert(VP8PredChroma8[0] != NULL);
|
||||
assert(VP8PredChroma8[1] != NULL);
|
||||
assert(VP8PredChroma8[2] != NULL);
|
||||
assert(VP8PredChroma8[3] != NULL);
|
||||
assert(VP8PredChroma8[4] != NULL);
|
||||
assert(VP8PredChroma8[5] != NULL);
|
||||
assert(VP8PredChroma8[6] != NULL);
|
||||
assert(VP8DitherCombine8x8 != NULL);
|
||||
}
|
||||
dec_last_cpuinfo_used = VP8GetCPUInfo;
|
||||
}
|
||||
|
@ -11,14 +11,11 @@
|
||||
//
|
||||
// Author: Skal (pascal.massimino@gmail.com)
|
||||
|
||||
#include "src/dsp/dsp.h"
|
||||
#include "./dsp.h"
|
||||
|
||||
// define to 0 to have run-time table initialization
|
||||
#if !defined(USE_STATIC_TABLES)
|
||||
#define USE_STATIC_TABLES 1 // ALTERNATE_CODE
|
||||
#endif
|
||||
#define USE_STATIC_TABLES // undefine to have run-time table initialization
|
||||
|
||||
#if (USE_STATIC_TABLES == 1)
|
||||
#ifdef USE_STATIC_TABLES
|
||||
|
||||
static const uint8_t abs0[255 + 255 + 1] = {
|
||||
0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8, 0xf7, 0xf6, 0xf5, 0xf4,
|
||||
@ -340,7 +337,7 @@ static uint8_t clip1[255 + 511 + 1];
|
||||
// and make sure it's set to true _last_ (so as to be thread-safe)
|
||||
static volatile int tables_ok = 0;
|
||||
|
||||
#endif // USE_STATIC_TABLES
|
||||
#endif
|
||||
|
||||
const int8_t* const VP8ksclip1 = (const int8_t*)&sclip1[1020];
|
||||
const int8_t* const VP8ksclip2 = (const int8_t*)&sclip2[112];
|
||||
@ -348,7 +345,7 @@ const uint8_t* const VP8kclip1 = &clip1[255];
|
||||
const uint8_t* const VP8kabs0 = &abs0[255];
|
||||
|
||||
WEBP_TSAN_IGNORE_FUNCTION void VP8InitClipTables(void) {
|
||||
#if (USE_STATIC_TABLES == 0)
|
||||
#if !defined(USE_STATIC_TABLES)
|
||||
int i;
|
||||
if (!tables_ok) {
|
||||
for (i = -255; i <= 255; ++i) {
|
||||
|
@ -12,11 +12,11 @@
|
||||
// Author(s): Djordje Pesut (djordje.pesut@imgtec.com)
|
||||
// Jovan Zelincevic (jovan.zelincevic@imgtec.com)
|
||||
|
||||
#include "src/dsp/dsp.h"
|
||||
#include "./dsp.h"
|
||||
|
||||
#if defined(WEBP_USE_MIPS32)
|
||||
|
||||
#include "src/dsp/mips_macro.h"
|
||||
#include "./mips_macro.h"
|
||||
|
||||
static const int kC1 = 20091 + (1 << 16);
|
||||
static const int kC2 = 35468;
|
||||
|
@ -12,11 +12,11 @@
|
||||
// Author(s): Djordje Pesut (djordje.pesut@imgtec.com)
|
||||
// Jovan Zelincevic (jovan.zelincevic@imgtec.com)
|
||||
|
||||
#include "src/dsp/dsp.h"
|
||||
#include "./dsp.h"
|
||||
|
||||
#if defined(WEBP_USE_MIPS_DSP_R2)
|
||||
|
||||
#include "src/dsp/mips_macro.h"
|
||||
#include "./mips_macro.h"
|
||||
|
||||
static const int kC1 = 20091 + (1 << 16);
|
||||
static const int kC2 = 35468;
|
||||
|
@ -12,11 +12,11 @@
|
||||
// Author(s): Prashant Patil (prashant.patil@imgtec.com)
|
||||
|
||||
|
||||
#include "src/dsp/dsp.h"
|
||||
#include "./dsp.h"
|
||||
|
||||
#if defined(WEBP_USE_MSA)
|
||||
|
||||
#include "src/dsp/msa_macro.h"
|
||||
#include "./msa_macro.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Transforms
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -12,25 +12,23 @@
|
||||
// Author: somnath@google.com (Somnath Banerjee)
|
||||
// cduvivier@google.com (Christian Duvivier)
|
||||
|
||||
#include "src/dsp/dsp.h"
|
||||
#include "./dsp.h"
|
||||
|
||||
#if defined(WEBP_USE_SSE2)
|
||||
|
||||
// The 3-coeff sparse transform in SSE2 is not really faster than the plain-C
|
||||
// one it seems => disable it by default. Uncomment the following to enable:
|
||||
#if !defined(USE_TRANSFORM_AC3)
|
||||
#define USE_TRANSFORM_AC3 0 // ALTERNATE_CODE
|
||||
#endif
|
||||
// #define USE_TRANSFORM_AC3
|
||||
|
||||
#include <emmintrin.h>
|
||||
#include "src/dsp/common_sse2.h"
|
||||
#include "src/dec/vp8i_dec.h"
|
||||
#include "src/utils/utils.h"
|
||||
#include "./common_sse2.h"
|
||||
#include "../dec/vp8i_dec.h"
|
||||
#include "../utils/utils.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Transforms (Paragraph 14.4)
|
||||
|
||||
static void Transform_SSE2(const int16_t* in, uint8_t* dst, int do_two) {
|
||||
static void Transform(const int16_t* in, uint8_t* dst, int do_two) {
|
||||
// This implementation makes use of 16-bit fixed point versions of two
|
||||
// multiply constants:
|
||||
// K1 = sqrt(2) * cos (pi/8) ~= 85627 / 2^16
|
||||
@ -195,7 +193,7 @@ static void Transform_SSE2(const int16_t* in, uint8_t* dst, int do_two) {
|
||||
}
|
||||
}
|
||||
|
||||
#if (USE_TRANSFORM_AC3 == 1)
|
||||
#if defined(USE_TRANSFORM_AC3)
|
||||
#define MUL(a, b) (((a) * (b)) >> 16)
|
||||
static void TransformAC3(const int16_t* in, uint8_t* dst) {
|
||||
static const int kC1 = 20091 + (1 << 16);
|
||||
@ -250,7 +248,7 @@ static void TransformAC3(const int16_t* in, uint8_t* dst) {
|
||||
_mm_subs_epu8((p), (q)))
|
||||
|
||||
// Shift each byte of "x" by 3 bits while preserving by the sign bit.
|
||||
static WEBP_INLINE void SignedShift8b_SSE2(__m128i* const x) {
|
||||
static WEBP_INLINE void SignedShift8b(__m128i* const x) {
|
||||
const __m128i zero = _mm_setzero_si128();
|
||||
const __m128i lo_0 = _mm_unpacklo_epi8(zero, *x);
|
||||
const __m128i hi_0 = _mm_unpackhi_epi8(zero, *x);
|
||||
@ -260,8 +258,8 @@ static WEBP_INLINE void SignedShift8b_SSE2(__m128i* const x) {
|
||||
}
|
||||
|
||||
#define FLIP_SIGN_BIT2(a, b) { \
|
||||
(a) = _mm_xor_si128(a, sign_bit); \
|
||||
(b) = _mm_xor_si128(b, sign_bit); \
|
||||
a = _mm_xor_si128(a, sign_bit); \
|
||||
b = _mm_xor_si128(b, sign_bit); \
|
||||
}
|
||||
|
||||
#define FLIP_SIGN_BIT4(a, b, c, d) { \
|
||||
@ -270,7 +268,7 @@ static WEBP_INLINE void SignedShift8b_SSE2(__m128i* const x) {
|
||||
}
|
||||
|
||||
// input/output is uint8_t
|
||||
static WEBP_INLINE void GetNotHEV_SSE2(const __m128i* const p1,
|
||||
static WEBP_INLINE void GetNotHEV(const __m128i* const p1,
|
||||
const __m128i* const p0,
|
||||
const __m128i* const q0,
|
||||
const __m128i* const q1,
|
||||
@ -287,7 +285,7 @@ static WEBP_INLINE void GetNotHEV_SSE2(const __m128i* const p1,
|
||||
}
|
||||
|
||||
// input pixels are int8_t
|
||||
static WEBP_INLINE void GetBaseDelta_SSE2(const __m128i* const p1,
|
||||
static WEBP_INLINE void GetBaseDelta(const __m128i* const p1,
|
||||
const __m128i* const p0,
|
||||
const __m128i* const q0,
|
||||
const __m128i* const q1,
|
||||
@ -302,16 +300,15 @@ static WEBP_INLINE void GetBaseDelta_SSE2(const __m128i* const p1,
|
||||
}
|
||||
|
||||
// input and output are int8_t
|
||||
static WEBP_INLINE void DoSimpleFilter_SSE2(__m128i* const p0,
|
||||
__m128i* const q0,
|
||||
static WEBP_INLINE void DoSimpleFilter(__m128i* const p0, __m128i* const q0,
|
||||
const __m128i* const fl) {
|
||||
const __m128i k3 = _mm_set1_epi8(3);
|
||||
const __m128i k4 = _mm_set1_epi8(4);
|
||||
__m128i v3 = _mm_adds_epi8(*fl, k3);
|
||||
__m128i v4 = _mm_adds_epi8(*fl, k4);
|
||||
|
||||
SignedShift8b_SSE2(&v4); // v4 >> 3
|
||||
SignedShift8b_SSE2(&v3); // v3 >> 3
|
||||
SignedShift8b(&v4); // v4 >> 3
|
||||
SignedShift8b(&v3); // v3 >> 3
|
||||
*q0 = _mm_subs_epi8(*q0, v4); // q0 -= v4
|
||||
*p0 = _mm_adds_epi8(*p0, v3); // p0 += v3
|
||||
}
|
||||
@ -320,7 +317,7 @@ static WEBP_INLINE void DoSimpleFilter_SSE2(__m128i* const p0,
|
||||
// Update operations:
|
||||
// q = q - delta and p = p + delta; where delta = [(a_hi >> 7), (a_lo >> 7)]
|
||||
// Pixels 'pi' and 'qi' are int8_t on input, uint8_t on output (sign flip).
|
||||
static WEBP_INLINE void Update2Pixels_SSE2(__m128i* const pi, __m128i* const qi,
|
||||
static WEBP_INLINE void Update2Pixels(__m128i* const pi, __m128i* const qi,
|
||||
const __m128i* const a0_lo,
|
||||
const __m128i* const a0_hi) {
|
||||
const __m128i a1_lo = _mm_srai_epi16(*a0_lo, 7);
|
||||
@ -333,7 +330,7 @@ static WEBP_INLINE void Update2Pixels_SSE2(__m128i* const pi, __m128i* const qi,
|
||||
}
|
||||
|
||||
// input pixels are uint8_t
|
||||
static WEBP_INLINE void NeedsFilter_SSE2(const __m128i* const p1,
|
||||
static WEBP_INLINE void NeedsFilter(const __m128i* const p1,
|
||||
const __m128i* const p0,
|
||||
const __m128i* const q0,
|
||||
const __m128i* const q1,
|
||||
@ -356,29 +353,28 @@ static WEBP_INLINE void NeedsFilter_SSE2(const __m128i* const p1,
|
||||
// Edge filtering functions
|
||||
|
||||
// Applies filter on 2 pixels (p0 and q0)
|
||||
static WEBP_INLINE void DoFilter2_SSE2(__m128i* const p1, __m128i* const p0,
|
||||
static WEBP_INLINE void DoFilter2(__m128i* const p1, __m128i* const p0,
|
||||
__m128i* const q0, __m128i* const q1,
|
||||
int thresh) {
|
||||
__m128i a, mask;
|
||||
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)
|
||||
const __m128i p1s = _mm_xor_si128(*p1, sign_bit);
|
||||
const __m128i q1s = _mm_xor_si128(*q1, sign_bit);
|
||||
|
||||
NeedsFilter_SSE2(p1, p0, q0, q1, thresh, &mask);
|
||||
NeedsFilter(p1, p0, q0, q1, thresh, &mask);
|
||||
|
||||
FLIP_SIGN_BIT2(*p0, *q0);
|
||||
GetBaseDelta_SSE2(&p1s, p0, q0, &q1s, &a);
|
||||
GetBaseDelta(&p1s, p0, q0, &q1s, &a);
|
||||
a = _mm_and_si128(a, mask); // mask filter values we don't care about
|
||||
DoSimpleFilter_SSE2(p0, q0, &a);
|
||||
DoSimpleFilter(p0, q0, &a);
|
||||
FLIP_SIGN_BIT2(*p0, *q0);
|
||||
}
|
||||
|
||||
// Applies filter on 4 pixels (p1, p0, q0 and q1)
|
||||
static WEBP_INLINE void DoFilter4_SSE2(__m128i* const p1, __m128i* const p0,
|
||||
static WEBP_INLINE void DoFilter4(__m128i* const p1, __m128i* const p0,
|
||||
__m128i* const q0, __m128i* const q1,
|
||||
const __m128i* const mask,
|
||||
int hev_thresh) {
|
||||
const __m128i* const mask, int hev_thresh) {
|
||||
const __m128i zero = _mm_setzero_si128();
|
||||
const __m128i sign_bit = _mm_set1_epi8(0x80);
|
||||
const __m128i k64 = _mm_set1_epi8(64);
|
||||
@ -388,7 +384,7 @@ static WEBP_INLINE void DoFilter4_SSE2(__m128i* const p1, __m128i* const p0,
|
||||
__m128i t1, t2, t3;
|
||||
|
||||
// compute hev mask
|
||||
GetNotHEV_SSE2(p1, p0, q0, q1, hev_thresh, ¬_hev);
|
||||
GetNotHEV(p1, p0, q0, q1, hev_thresh, ¬_hev);
|
||||
|
||||
// convert to signed values
|
||||
FLIP_SIGN_BIT4(*p1, *p0, *q0, *q1);
|
||||
@ -403,8 +399,8 @@ static WEBP_INLINE void DoFilter4_SSE2(__m128i* const p1, __m128i* const p0,
|
||||
|
||||
t2 = _mm_adds_epi8(t1, k3); // 3 * (q0 - p0) + hev(p1 - q1) + 3
|
||||
t3 = _mm_adds_epi8(t1, k4); // 3 * (q0 - p0) + hev(p1 - q1) + 4
|
||||
SignedShift8b_SSE2(&t2); // (3 * (q0 - p0) + hev(p1 - q1) + 3) >> 3
|
||||
SignedShift8b_SSE2(&t3); // (3 * (q0 - p0) + hev(p1 - q1) + 4) >> 3
|
||||
SignedShift8b(&t2); // (3 * (q0 - p0) + hev(p1 - q1) + 3) >> 3
|
||||
SignedShift8b(&t3); // (3 * (q0 - p0) + hev(p1 - q1) + 4) >> 3
|
||||
*p0 = _mm_adds_epi8(*p0, t2); // p0 += t2
|
||||
*q0 = _mm_subs_epi8(*q0, t3); // q0 -= t3
|
||||
FLIP_SIGN_BIT2(*p0, *q0);
|
||||
@ -421,26 +417,25 @@ static WEBP_INLINE void DoFilter4_SSE2(__m128i* const p1, __m128i* const p0,
|
||||
}
|
||||
|
||||
// Applies filter on 6 pixels (p2, p1, p0, q0, q1 and q2)
|
||||
static WEBP_INLINE void DoFilter6_SSE2(__m128i* const p2, __m128i* const p1,
|
||||
static WEBP_INLINE void DoFilter6(__m128i* const p2, __m128i* const p1,
|
||||
__m128i* const p0, __m128i* const q0,
|
||||
__m128i* const q1, __m128i* const q2,
|
||||
const __m128i* const mask,
|
||||
int hev_thresh) {
|
||||
const __m128i* const mask, int hev_thresh) {
|
||||
const __m128i zero = _mm_setzero_si128();
|
||||
const __m128i sign_bit = _mm_set1_epi8(0x80);
|
||||
__m128i a, not_hev;
|
||||
|
||||
// compute hev mask
|
||||
GetNotHEV_SSE2(p1, p0, q0, q1, hev_thresh, ¬_hev);
|
||||
GetNotHEV(p1, p0, q0, q1, hev_thresh, ¬_hev);
|
||||
|
||||
FLIP_SIGN_BIT4(*p1, *p0, *q0, *q1);
|
||||
FLIP_SIGN_BIT2(*p2, *q2);
|
||||
GetBaseDelta_SSE2(p1, p0, q0, q1, &a);
|
||||
GetBaseDelta(p1, p0, q0, q1, &a);
|
||||
|
||||
{ // do simple filter on pixels with hev
|
||||
const __m128i m = _mm_andnot_si128(not_hev, *mask);
|
||||
const __m128i f = _mm_and_si128(a, m);
|
||||
DoSimpleFilter_SSE2(p0, q0, &f);
|
||||
DoSimpleFilter(p0, q0, &f);
|
||||
}
|
||||
|
||||
{ // do strong filter on pixels with not hev
|
||||
@ -465,14 +460,14 @@ static WEBP_INLINE void DoFilter6_SSE2(__m128i* const p2, __m128i* const p1,
|
||||
const __m128i a0_lo = _mm_add_epi16(a1_lo, f9_lo); // Filter * 27 + 63
|
||||
const __m128i a0_hi = _mm_add_epi16(a1_hi, f9_hi); // Filter * 27 + 63
|
||||
|
||||
Update2Pixels_SSE2(p2, q2, &a2_lo, &a2_hi);
|
||||
Update2Pixels_SSE2(p1, q1, &a1_lo, &a1_hi);
|
||||
Update2Pixels_SSE2(p0, q0, &a0_lo, &a0_hi);
|
||||
Update2Pixels(p2, q2, &a2_lo, &a2_hi);
|
||||
Update2Pixels(p1, q1, &a1_lo, &a1_hi);
|
||||
Update2Pixels(p0, q0, &a0_lo, &a0_hi);
|
||||
}
|
||||
}
|
||||
|
||||
// reads 8 rows across a vertical edge.
|
||||
static WEBP_INLINE void Load8x4_SSE2(const uint8_t* const b, int stride,
|
||||
static WEBP_INLINE void Load8x4(const uint8_t* const b, int stride,
|
||||
__m128i* const p, __m128i* const q) {
|
||||
// A0 = 63 62 61 60 23 22 21 20 43 42 41 40 03 02 01 00
|
||||
// A1 = 73 72 71 70 33 32 31 30 53 52 51 50 13 12 11 10
|
||||
@ -499,7 +494,7 @@ static WEBP_INLINE void Load8x4_SSE2(const uint8_t* const b, int stride,
|
||||
*q = _mm_unpackhi_epi32(C0, C1);
|
||||
}
|
||||
|
||||
static WEBP_INLINE void Load16x4_SSE2(const uint8_t* const r0,
|
||||
static WEBP_INLINE void Load16x4(const uint8_t* const r0,
|
||||
const uint8_t* const r8,
|
||||
int stride,
|
||||
__m128i* const p1, __m128i* const p0,
|
||||
@ -519,8 +514,8 @@ static WEBP_INLINE void Load16x4_SSE2(const uint8_t* const r0,
|
||||
// q0 = 73 63 53 43 33 23 13 03 72 62 52 42 32 22 12 02
|
||||
// p0 = f1 e1 d1 c1 b1 a1 91 81 f0 e0 d0 c0 b0 a0 90 80
|
||||
// q1 = f3 e3 d3 c3 b3 a3 93 83 f2 e2 d2 c2 b2 a2 92 82
|
||||
Load8x4_SSE2(r0, stride, p1, q0);
|
||||
Load8x4_SSE2(r8, stride, p0, q1);
|
||||
Load8x4(r0, stride, p1, q0);
|
||||
Load8x4(r8, stride, p0, q1);
|
||||
|
||||
{
|
||||
// p1 = f0 e0 d0 c0 b0 a0 90 80 70 60 50 40 30 20 10 00
|
||||
@ -536,8 +531,7 @@ static WEBP_INLINE void Load16x4_SSE2(const uint8_t* const r0,
|
||||
}
|
||||
}
|
||||
|
||||
static WEBP_INLINE void Store4x4_SSE2(__m128i* const x,
|
||||
uint8_t* dst, int stride) {
|
||||
static WEBP_INLINE void Store4x4(__m128i* const x, uint8_t* dst, int stride) {
|
||||
int i;
|
||||
for (i = 0; i < 4; ++i, dst += stride) {
|
||||
WebPUint32ToMem(dst, _mm_cvtsi128_si32(*x));
|
||||
@ -546,7 +540,7 @@ static WEBP_INLINE void Store4x4_SSE2(__m128i* const x,
|
||||
}
|
||||
|
||||
// Transpose back and store
|
||||
static WEBP_INLINE void Store16x4_SSE2(const __m128i* const p1,
|
||||
static WEBP_INLINE void Store16x4(const __m128i* const p1,
|
||||
const __m128i* const p0,
|
||||
const __m128i* const q0,
|
||||
const __m128i* const q1,
|
||||
@ -578,55 +572,55 @@ static WEBP_INLINE void Store16x4_SSE2(const __m128i* const p1,
|
||||
p1_s = _mm_unpacklo_epi16(t1, q1_s);
|
||||
q1_s = _mm_unpackhi_epi16(t1, q1_s);
|
||||
|
||||
Store4x4_SSE2(&p0_s, r0, stride);
|
||||
Store4x4(&p0_s, r0, stride);
|
||||
r0 += 4 * stride;
|
||||
Store4x4_SSE2(&q0_s, r0, stride);
|
||||
Store4x4(&q0_s, r0, stride);
|
||||
|
||||
Store4x4_SSE2(&p1_s, r8, stride);
|
||||
Store4x4(&p1_s, r8, stride);
|
||||
r8 += 4 * stride;
|
||||
Store4x4_SSE2(&q1_s, r8, stride);
|
||||
Store4x4(&q1_s, r8, stride);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Simple In-loop filtering (Paragraph 15.2)
|
||||
|
||||
static void SimpleVFilter16_SSE2(uint8_t* p, int stride, int thresh) {
|
||||
static void SimpleVFilter16(uint8_t* p, int stride, int thresh) {
|
||||
// Load
|
||||
__m128i p1 = _mm_loadu_si128((__m128i*)&p[-2 * stride]);
|
||||
__m128i p0 = _mm_loadu_si128((__m128i*)&p[-stride]);
|
||||
__m128i q0 = _mm_loadu_si128((__m128i*)&p[0]);
|
||||
__m128i q1 = _mm_loadu_si128((__m128i*)&p[stride]);
|
||||
|
||||
DoFilter2_SSE2(&p1, &p0, &q0, &q1, thresh);
|
||||
DoFilter2(&p1, &p0, &q0, &q1, thresh);
|
||||
|
||||
// Store
|
||||
_mm_storeu_si128((__m128i*)&p[-stride], p0);
|
||||
_mm_storeu_si128((__m128i*)&p[0], q0);
|
||||
}
|
||||
|
||||
static void SimpleHFilter16_SSE2(uint8_t* p, int stride, int thresh) {
|
||||
static void SimpleHFilter16(uint8_t* p, int stride, int thresh) {
|
||||
__m128i p1, p0, q0, q1;
|
||||
|
||||
p -= 2; // beginning of p1
|
||||
|
||||
Load16x4_SSE2(p, p + 8 * stride, stride, &p1, &p0, &q0, &q1);
|
||||
DoFilter2_SSE2(&p1, &p0, &q0, &q1, thresh);
|
||||
Store16x4_SSE2(&p1, &p0, &q0, &q1, p, p + 8 * stride, stride);
|
||||
Load16x4(p, p + 8 * stride, stride, &p1, &p0, &q0, &q1);
|
||||
DoFilter2(&p1, &p0, &q0, &q1, thresh);
|
||||
Store16x4(&p1, &p0, &q0, &q1, p, p + 8 * stride, stride);
|
||||
}
|
||||
|
||||
static void SimpleVFilter16i_SSE2(uint8_t* p, int stride, int thresh) {
|
||||
static void SimpleVFilter16i(uint8_t* p, int stride, int thresh) {
|
||||
int k;
|
||||
for (k = 3; k > 0; --k) {
|
||||
p += 4 * stride;
|
||||
SimpleVFilter16_SSE2(p, stride, thresh);
|
||||
SimpleVFilter16(p, stride, thresh);
|
||||
}
|
||||
}
|
||||
|
||||
static void SimpleHFilter16i_SSE2(uint8_t* p, int stride, int thresh) {
|
||||
static void SimpleHFilter16i(uint8_t* p, int stride, int thresh) {
|
||||
int k;
|
||||
for (k = 3; k > 0; --k) {
|
||||
p += 4;
|
||||
SimpleHFilter16_SSE2(p, stride, thresh);
|
||||
SimpleHFilter16(p, stride, thresh);
|
||||
}
|
||||
}
|
||||
|
||||
@ -634,44 +628,44 @@ static void SimpleHFilter16i_SSE2(uint8_t* p, int stride, int thresh) {
|
||||
// Complex In-loop filtering (Paragraph 15.3)
|
||||
|
||||
#define MAX_DIFF1(p3, p2, p1, p0, m) do { \
|
||||
(m) = MM_ABS(p1, p0); \
|
||||
(m) = _mm_max_epu8(m, MM_ABS(p3, p2)); \
|
||||
(m) = _mm_max_epu8(m, MM_ABS(p2, p1)); \
|
||||
m = MM_ABS(p1, p0); \
|
||||
m = _mm_max_epu8(m, MM_ABS(p3, p2)); \
|
||||
m = _mm_max_epu8(m, MM_ABS(p2, p1)); \
|
||||
} while (0)
|
||||
|
||||
#define MAX_DIFF2(p3, p2, p1, p0, m) do { \
|
||||
(m) = _mm_max_epu8(m, MM_ABS(p1, p0)); \
|
||||
(m) = _mm_max_epu8(m, MM_ABS(p3, p2)); \
|
||||
(m) = _mm_max_epu8(m, MM_ABS(p2, p1)); \
|
||||
m = _mm_max_epu8(m, MM_ABS(p1, p0)); \
|
||||
m = _mm_max_epu8(m, MM_ABS(p3, p2)); \
|
||||
m = _mm_max_epu8(m, MM_ABS(p2, p1)); \
|
||||
} while (0)
|
||||
|
||||
#define LOAD_H_EDGES4(p, stride, e1, e2, e3, e4) { \
|
||||
(e1) = _mm_loadu_si128((__m128i*)&(p)[0 * (stride)]); \
|
||||
(e2) = _mm_loadu_si128((__m128i*)&(p)[1 * (stride)]); \
|
||||
(e3) = _mm_loadu_si128((__m128i*)&(p)[2 * (stride)]); \
|
||||
(e4) = _mm_loadu_si128((__m128i*)&(p)[3 * (stride)]); \
|
||||
e1 = _mm_loadu_si128((__m128i*)&(p)[0 * stride]); \
|
||||
e2 = _mm_loadu_si128((__m128i*)&(p)[1 * stride]); \
|
||||
e3 = _mm_loadu_si128((__m128i*)&(p)[2 * stride]); \
|
||||
e4 = _mm_loadu_si128((__m128i*)&(p)[3 * stride]); \
|
||||
}
|
||||
|
||||
#define LOADUV_H_EDGE(p, u, v, stride) do { \
|
||||
const __m128i U = _mm_loadl_epi64((__m128i*)&(u)[(stride)]); \
|
||||
const __m128i V = _mm_loadl_epi64((__m128i*)&(v)[(stride)]); \
|
||||
(p) = _mm_unpacklo_epi64(U, V); \
|
||||
p = _mm_unpacklo_epi64(U, V); \
|
||||
} while (0)
|
||||
|
||||
#define LOADUV_H_EDGES4(u, v, stride, e1, e2, e3, e4) { \
|
||||
LOADUV_H_EDGE(e1, u, v, 0 * (stride)); \
|
||||
LOADUV_H_EDGE(e2, u, v, 1 * (stride)); \
|
||||
LOADUV_H_EDGE(e3, u, v, 2 * (stride)); \
|
||||
LOADUV_H_EDGE(e4, u, v, 3 * (stride)); \
|
||||
LOADUV_H_EDGE(e1, u, v, 0 * stride); \
|
||||
LOADUV_H_EDGE(e2, u, v, 1 * stride); \
|
||||
LOADUV_H_EDGE(e3, u, v, 2 * stride); \
|
||||
LOADUV_H_EDGE(e4, u, v, 3 * stride); \
|
||||
}
|
||||
|
||||
#define STOREUV(p, u, v, stride) { \
|
||||
_mm_storel_epi64((__m128i*)&(u)[(stride)], p); \
|
||||
(p) = _mm_srli_si128(p, 8); \
|
||||
_mm_storel_epi64((__m128i*)&(v)[(stride)], p); \
|
||||
_mm_storel_epi64((__m128i*)&u[(stride)], p); \
|
||||
p = _mm_srli_si128(p, 8); \
|
||||
_mm_storel_epi64((__m128i*)&v[(stride)], p); \
|
||||
}
|
||||
|
||||
static WEBP_INLINE void ComplexMask_SSE2(const __m128i* const p1,
|
||||
static WEBP_INLINE void ComplexMask(const __m128i* const p1,
|
||||
const __m128i* const p0,
|
||||
const __m128i* const q0,
|
||||
const __m128i* const q1,
|
||||
@ -681,12 +675,12 @@ static WEBP_INLINE void ComplexMask_SSE2(const __m128i* const p1,
|
||||
const __m128i diff = _mm_subs_epu8(*mask, it);
|
||||
const __m128i thresh_mask = _mm_cmpeq_epi8(diff, _mm_setzero_si128());
|
||||
__m128i filter_mask;
|
||||
NeedsFilter_SSE2(p1, p0, q0, q1, thresh, &filter_mask);
|
||||
NeedsFilter(p1, p0, q0, q1, thresh, &filter_mask);
|
||||
*mask = _mm_and_si128(thresh_mask, filter_mask);
|
||||
}
|
||||
|
||||
// on macroblock edges
|
||||
static void VFilter16_SSE2(uint8_t* p, int stride,
|
||||
static void VFilter16(uint8_t* p, int stride,
|
||||
int thresh, int ithresh, int hev_thresh) {
|
||||
__m128i t1;
|
||||
__m128i mask;
|
||||
@ -700,8 +694,8 @@ static void VFilter16_SSE2(uint8_t* p, int stride,
|
||||
LOAD_H_EDGES4(p, stride, q0, q1, q2, t1);
|
||||
MAX_DIFF2(t1, q2, q1, q0, mask);
|
||||
|
||||
ComplexMask_SSE2(&p1, &p0, &q0, &q1, thresh, ithresh, &mask);
|
||||
DoFilter6_SSE2(&p2, &p1, &p0, &q0, &q1, &q2, &mask, hev_thresh);
|
||||
ComplexMask(&p1, &p0, &q0, &q1, thresh, ithresh, &mask);
|
||||
DoFilter6(&p2, &p1, &p0, &q0, &q1, &q2, &mask, hev_thresh);
|
||||
|
||||
// Store
|
||||
_mm_storeu_si128((__m128i*)&p[-3 * stride], p2);
|
||||
@ -712,27 +706,27 @@ static void VFilter16_SSE2(uint8_t* p, int stride,
|
||||
_mm_storeu_si128((__m128i*)&p[+2 * stride], q2);
|
||||
}
|
||||
|
||||
static void HFilter16_SSE2(uint8_t* p, int stride,
|
||||
static void HFilter16(uint8_t* p, int stride,
|
||||
int thresh, int ithresh, int hev_thresh) {
|
||||
__m128i mask;
|
||||
__m128i p3, p2, p1, p0, q0, q1, q2, q3;
|
||||
|
||||
uint8_t* const b = p - 4;
|
||||
Load16x4_SSE2(b, b + 8 * stride, stride, &p3, &p2, &p1, &p0);
|
||||
Load16x4(b, b + 8 * stride, stride, &p3, &p2, &p1, &p0); // p3, p2, p1, p0
|
||||
MAX_DIFF1(p3, p2, p1, p0, mask);
|
||||
|
||||
Load16x4_SSE2(p, p + 8 * stride, stride, &q0, &q1, &q2, &q3);
|
||||
Load16x4(p, p + 8 * stride, stride, &q0, &q1, &q2, &q3); // q0, q1, q2, q3
|
||||
MAX_DIFF2(q3, q2, q1, q0, mask);
|
||||
|
||||
ComplexMask_SSE2(&p1, &p0, &q0, &q1, thresh, ithresh, &mask);
|
||||
DoFilter6_SSE2(&p2, &p1, &p0, &q0, &q1, &q2, &mask, hev_thresh);
|
||||
ComplexMask(&p1, &p0, &q0, &q1, thresh, ithresh, &mask);
|
||||
DoFilter6(&p2, &p1, &p0, &q0, &q1, &q2, &mask, hev_thresh);
|
||||
|
||||
Store16x4_SSE2(&p3, &p2, &p1, &p0, b, b + 8 * stride, stride);
|
||||
Store16x4_SSE2(&q0, &q1, &q2, &q3, p, p + 8 * stride, stride);
|
||||
Store16x4(&p3, &p2, &p1, &p0, b, b + 8 * stride, stride);
|
||||
Store16x4(&q0, &q1, &q2, &q3, p, p + 8 * stride, stride);
|
||||
}
|
||||
|
||||
// on three inner edges
|
||||
static void VFilter16i_SSE2(uint8_t* p, int stride,
|
||||
static void VFilter16i(uint8_t* p, int stride,
|
||||
int thresh, int ithresh, int hev_thresh) {
|
||||
int k;
|
||||
__m128i p3, p2, p1, p0; // loop invariants
|
||||
@ -750,8 +744,8 @@ static void VFilter16i_SSE2(uint8_t* p, int stride,
|
||||
|
||||
// p3 and p2 are not just temporary variables here: they will be
|
||||
// re-used for next span. And q2/q3 will become p1/p0 accordingly.
|
||||
ComplexMask_SSE2(&p1, &p0, &p3, &p2, thresh, ithresh, &mask);
|
||||
DoFilter4_SSE2(&p1, &p0, &p3, &p2, &mask, hev_thresh);
|
||||
ComplexMask(&p1, &p0, &p3, &p2, thresh, ithresh, &mask);
|
||||
DoFilter4(&p1, &p0, &p3, &p2, &mask, hev_thresh);
|
||||
|
||||
// Store
|
||||
_mm_storeu_si128((__m128i*)&b[0 * stride], p1);
|
||||
@ -765,12 +759,12 @@ static void VFilter16i_SSE2(uint8_t* p, int stride,
|
||||
}
|
||||
}
|
||||
|
||||
static void HFilter16i_SSE2(uint8_t* p, int stride,
|
||||
static void HFilter16i(uint8_t* p, int stride,
|
||||
int thresh, int ithresh, int hev_thresh) {
|
||||
int k;
|
||||
__m128i p3, p2, p1, p0; // loop invariants
|
||||
|
||||
Load16x4_SSE2(p, p + 8 * stride, stride, &p3, &p2, &p1, &p0); // prologue
|
||||
Load16x4(p, p + 8 * stride, stride, &p3, &p2, &p1, &p0); // prologue
|
||||
|
||||
for (k = 3; k > 0; --k) {
|
||||
__m128i mask, tmp1, tmp2;
|
||||
@ -779,13 +773,13 @@ static void HFilter16i_SSE2(uint8_t* p, int stride,
|
||||
p += 4; // beginning of q0 (and next span)
|
||||
|
||||
MAX_DIFF1(p3, p2, p1, p0, mask); // compute partial mask
|
||||
Load16x4_SSE2(p, p + 8 * stride, stride, &p3, &p2, &tmp1, &tmp2);
|
||||
Load16x4(p, p + 8 * stride, stride, &p3, &p2, &tmp1, &tmp2);
|
||||
MAX_DIFF2(p3, p2, tmp1, tmp2, mask);
|
||||
|
||||
ComplexMask_SSE2(&p1, &p0, &p3, &p2, thresh, ithresh, &mask);
|
||||
DoFilter4_SSE2(&p1, &p0, &p3, &p2, &mask, hev_thresh);
|
||||
ComplexMask(&p1, &p0, &p3, &p2, thresh, ithresh, &mask);
|
||||
DoFilter4(&p1, &p0, &p3, &p2, &mask, hev_thresh);
|
||||
|
||||
Store16x4_SSE2(&p1, &p0, &p3, &p2, b, b + 8 * stride, stride);
|
||||
Store16x4(&p1, &p0, &p3, &p2, b, b + 8 * stride, stride);
|
||||
|
||||
// rotate samples
|
||||
p1 = tmp1;
|
||||
@ -794,7 +788,7 @@ static void HFilter16i_SSE2(uint8_t* p, int stride,
|
||||
}
|
||||
|
||||
// 8-pixels wide variant, for chroma filtering
|
||||
static void VFilter8_SSE2(uint8_t* u, uint8_t* v, int stride,
|
||||
static void VFilter8(uint8_t* u, uint8_t* v, int stride,
|
||||
int thresh, int ithresh, int hev_thresh) {
|
||||
__m128i mask;
|
||||
__m128i t1, p2, p1, p0, q0, q1, q2;
|
||||
@ -807,8 +801,8 @@ static void VFilter8_SSE2(uint8_t* u, uint8_t* v, int stride,
|
||||
LOADUV_H_EDGES4(u, v, stride, q0, q1, q2, t1);
|
||||
MAX_DIFF2(t1, q2, q1, q0, mask);
|
||||
|
||||
ComplexMask_SSE2(&p1, &p0, &q0, &q1, thresh, ithresh, &mask);
|
||||
DoFilter6_SSE2(&p2, &p1, &p0, &q0, &q1, &q2, &mask, hev_thresh);
|
||||
ComplexMask(&p1, &p0, &q0, &q1, thresh, ithresh, &mask);
|
||||
DoFilter6(&p2, &p1, &p0, &q0, &q1, &q2, &mask, hev_thresh);
|
||||
|
||||
// Store
|
||||
STOREUV(p2, u, v, -3 * stride);
|
||||
@ -819,27 +813,27 @@ static void VFilter8_SSE2(uint8_t* u, uint8_t* v, int stride,
|
||||
STOREUV(q2, u, v, 2 * stride);
|
||||
}
|
||||
|
||||
static void HFilter8_SSE2(uint8_t* u, uint8_t* v, int stride,
|
||||
static void HFilter8(uint8_t* u, uint8_t* v, int stride,
|
||||
int thresh, int ithresh, int hev_thresh) {
|
||||
__m128i mask;
|
||||
__m128i p3, p2, p1, p0, q0, q1, q2, q3;
|
||||
|
||||
uint8_t* const tu = u - 4;
|
||||
uint8_t* const tv = v - 4;
|
||||
Load16x4_SSE2(tu, tv, stride, &p3, &p2, &p1, &p0);
|
||||
Load16x4(tu, tv, stride, &p3, &p2, &p1, &p0); // p3, p2, p1, p0
|
||||
MAX_DIFF1(p3, p2, p1, p0, mask);
|
||||
|
||||
Load16x4_SSE2(u, v, stride, &q0, &q1, &q2, &q3);
|
||||
Load16x4(u, v, stride, &q0, &q1, &q2, &q3); // q0, q1, q2, q3
|
||||
MAX_DIFF2(q3, q2, q1, q0, mask);
|
||||
|
||||
ComplexMask_SSE2(&p1, &p0, &q0, &q1, thresh, ithresh, &mask);
|
||||
DoFilter6_SSE2(&p2, &p1, &p0, &q0, &q1, &q2, &mask, hev_thresh);
|
||||
ComplexMask(&p1, &p0, &q0, &q1, thresh, ithresh, &mask);
|
||||
DoFilter6(&p2, &p1, &p0, &q0, &q1, &q2, &mask, hev_thresh);
|
||||
|
||||
Store16x4_SSE2(&p3, &p2, &p1, &p0, tu, tv, stride);
|
||||
Store16x4_SSE2(&q0, &q1, &q2, &q3, u, v, stride);
|
||||
Store16x4(&p3, &p2, &p1, &p0, tu, tv, stride);
|
||||
Store16x4(&q0, &q1, &q2, &q3, u, v, stride);
|
||||
}
|
||||
|
||||
static void VFilter8i_SSE2(uint8_t* u, uint8_t* v, int stride,
|
||||
static void VFilter8i(uint8_t* u, uint8_t* v, int stride,
|
||||
int thresh, int ithresh, int hev_thresh) {
|
||||
__m128i mask;
|
||||
__m128i t1, t2, p1, p0, q0, q1;
|
||||
@ -855,8 +849,8 @@ static void VFilter8i_SSE2(uint8_t* u, uint8_t* v, int stride,
|
||||
LOADUV_H_EDGES4(u, v, stride, q0, q1, t1, t2);
|
||||
MAX_DIFF2(t2, t1, q1, q0, mask);
|
||||
|
||||
ComplexMask_SSE2(&p1, &p0, &q0, &q1, thresh, ithresh, &mask);
|
||||
DoFilter4_SSE2(&p1, &p0, &q0, &q1, &mask, hev_thresh);
|
||||
ComplexMask(&p1, &p0, &q0, &q1, thresh, ithresh, &mask);
|
||||
DoFilter4(&p1, &p0, &q0, &q1, &mask, hev_thresh);
|
||||
|
||||
// Store
|
||||
STOREUV(p1, u, v, -2 * stride);
|
||||
@ -865,24 +859,24 @@ static void VFilter8i_SSE2(uint8_t* u, uint8_t* v, int stride,
|
||||
STOREUV(q1, u, v, 1 * stride);
|
||||
}
|
||||
|
||||
static void HFilter8i_SSE2(uint8_t* u, uint8_t* v, int stride,
|
||||
static void HFilter8i(uint8_t* u, uint8_t* v, int stride,
|
||||
int thresh, int ithresh, int hev_thresh) {
|
||||
__m128i mask;
|
||||
__m128i t1, t2, p1, p0, q0, q1;
|
||||
Load16x4_SSE2(u, v, stride, &t2, &t1, &p1, &p0); // p3, p2, p1, p0
|
||||
Load16x4(u, v, stride, &t2, &t1, &p1, &p0); // p3, p2, p1, p0
|
||||
MAX_DIFF1(t2, t1, p1, p0, mask);
|
||||
|
||||
u += 4; // beginning of q0
|
||||
v += 4;
|
||||
Load16x4_SSE2(u, v, stride, &q0, &q1, &t1, &t2); // q0, q1, q2, q3
|
||||
Load16x4(u, v, stride, &q0, &q1, &t1, &t2); // q0, q1, q2, q3
|
||||
MAX_DIFF2(t2, t1, q1, q0, mask);
|
||||
|
||||
ComplexMask_SSE2(&p1, &p0, &q0, &q1, thresh, ithresh, &mask);
|
||||
DoFilter4_SSE2(&p1, &p0, &q0, &q1, &mask, hev_thresh);
|
||||
ComplexMask(&p1, &p0, &q0, &q1, thresh, ithresh, &mask);
|
||||
DoFilter4(&p1, &p0, &q0, &q1, &mask, hev_thresh);
|
||||
|
||||
u -= 2; // beginning of p1
|
||||
v -= 2;
|
||||
Store16x4_SSE2(&p1, &p0, &q0, &q1, u, v, stride);
|
||||
Store16x4(&p1, &p0, &q0, &q1, u, v, stride);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@ -899,7 +893,7 @@ static void HFilter8i_SSE2(uint8_t* u, uint8_t* v, int stride,
|
||||
// where: AC = (a + b + 1) >> 1, BC = (b + c + 1) >> 1
|
||||
// and ab = a ^ b, bc = b ^ c, lsb = (AC^BC)&1
|
||||
|
||||
static void VE4_SSE2(uint8_t* dst) { // vertical
|
||||
static void VE4(uint8_t* dst) { // vertical
|
||||
const __m128i one = _mm_set1_epi8(1);
|
||||
const __m128i ABCDEFGH = _mm_loadl_epi64((__m128i*)(dst - BPS - 1));
|
||||
const __m128i BCDEFGH0 = _mm_srli_si128(ABCDEFGH, 1);
|
||||
@ -915,7 +909,7 @@ static void VE4_SSE2(uint8_t* dst) { // vertical
|
||||
}
|
||||
}
|
||||
|
||||
static void LD4_SSE2(uint8_t* dst) { // Down-Left
|
||||
static void LD4(uint8_t* dst) { // Down-Left
|
||||
const __m128i one = _mm_set1_epi8(1);
|
||||
const __m128i ABCDEFGH = _mm_loadl_epi64((__m128i*)(dst - BPS));
|
||||
const __m128i BCDEFGH0 = _mm_srli_si128(ABCDEFGH, 1);
|
||||
@ -931,7 +925,7 @@ static void LD4_SSE2(uint8_t* dst) { // Down-Left
|
||||
WebPUint32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 3)));
|
||||
}
|
||||
|
||||
static void VR4_SSE2(uint8_t* dst) { // Vertical-Right
|
||||
static void VR4(uint8_t* dst) { // Vertical-Right
|
||||
const __m128i one = _mm_set1_epi8(1);
|
||||
const int I = dst[-1 + 0 * BPS];
|
||||
const int J = dst[-1 + 1 * BPS];
|
||||
@ -956,7 +950,7 @@ static void VR4_SSE2(uint8_t* dst) { // Vertical-Right
|
||||
DST(0, 3) = AVG3(K, J, I);
|
||||
}
|
||||
|
||||
static void VL4_SSE2(uint8_t* dst) { // Vertical-Left
|
||||
static void VL4(uint8_t* dst) { // Vertical-Left
|
||||
const __m128i one = _mm_set1_epi8(1);
|
||||
const __m128i ABCDEFGH = _mm_loadl_epi64((__m128i*)(dst - BPS));
|
||||
const __m128i BCDEFGH_ = _mm_srli_si128(ABCDEFGH, 1);
|
||||
@ -981,7 +975,7 @@ static void VL4_SSE2(uint8_t* dst) { // Vertical-Left
|
||||
DST(3, 3) = (extra_out >> 8) & 0xff;
|
||||
}
|
||||
|
||||
static void RD4_SSE2(uint8_t* dst) { // Down-right
|
||||
static void RD4(uint8_t* dst) { // Down-right
|
||||
const __m128i one = _mm_set1_epi8(1);
|
||||
const __m128i XABCD = _mm_loadl_epi64((__m128i*)(dst - BPS - 1));
|
||||
const __m128i ____XABCD = _mm_slli_si128(XABCD, 4);
|
||||
@ -1010,7 +1004,7 @@ static void RD4_SSE2(uint8_t* dst) { // Down-right
|
||||
//------------------------------------------------------------------------------
|
||||
// Luma 16x16
|
||||
|
||||
static WEBP_INLINE void TrueMotion_SSE2(uint8_t* dst, int size) {
|
||||
static WEBP_INLINE void TrueMotion(uint8_t* dst, int size) {
|
||||
const uint8_t* top = dst - BPS;
|
||||
const __m128i zero = _mm_setzero_si128();
|
||||
int y;
|
||||
@ -1047,11 +1041,11 @@ static WEBP_INLINE void TrueMotion_SSE2(uint8_t* dst, int size) {
|
||||
}
|
||||
}
|
||||
|
||||
static void TM4_SSE2(uint8_t* dst) { TrueMotion_SSE2(dst, 4); }
|
||||
static void TM8uv_SSE2(uint8_t* dst) { TrueMotion_SSE2(dst, 8); }
|
||||
static void TM16_SSE2(uint8_t* dst) { TrueMotion_SSE2(dst, 16); }
|
||||
static void TM4(uint8_t* dst) { TrueMotion(dst, 4); }
|
||||
static void TM8uv(uint8_t* dst) { TrueMotion(dst, 8); }
|
||||
static void TM16(uint8_t* dst) { TrueMotion(dst, 16); }
|
||||
|
||||
static void VE16_SSE2(uint8_t* dst) {
|
||||
static void VE16(uint8_t* dst) {
|
||||
const __m128i top = _mm_loadu_si128((const __m128i*)(dst - BPS));
|
||||
int j;
|
||||
for (j = 0; j < 16; ++j) {
|
||||
@ -1059,7 +1053,7 @@ static void VE16_SSE2(uint8_t* dst) {
|
||||
}
|
||||
}
|
||||
|
||||
static void HE16_SSE2(uint8_t* dst) { // horizontal
|
||||
static void HE16(uint8_t* dst) { // horizontal
|
||||
int j;
|
||||
for (j = 16; j > 0; --j) {
|
||||
const __m128i values = _mm_set1_epi8(dst[-1]);
|
||||
@ -1068,7 +1062,7 @@ static void HE16_SSE2(uint8_t* dst) { // horizontal
|
||||
}
|
||||
}
|
||||
|
||||
static WEBP_INLINE void Put16_SSE2(uint8_t v, uint8_t* dst) {
|
||||
static WEBP_INLINE void Put16(uint8_t v, uint8_t* dst) {
|
||||
int j;
|
||||
const __m128i values = _mm_set1_epi8(v);
|
||||
for (j = 0; j < 16; ++j) {
|
||||
@ -1076,7 +1070,7 @@ static WEBP_INLINE void Put16_SSE2(uint8_t v, uint8_t* dst) {
|
||||
}
|
||||
}
|
||||
|
||||
static void DC16_SSE2(uint8_t* dst) { // DC
|
||||
static void DC16(uint8_t* dst) { // DC
|
||||
const __m128i zero = _mm_setzero_si128();
|
||||
const __m128i top = _mm_loadu_si128((const __m128i*)(dst - BPS));
|
||||
const __m128i sad8x2 = _mm_sad_epu8(top, zero);
|
||||
@ -1089,37 +1083,37 @@ static void DC16_SSE2(uint8_t* dst) { // DC
|
||||
}
|
||||
{
|
||||
const int DC = _mm_cvtsi128_si32(sum) + left + 16;
|
||||
Put16_SSE2(DC >> 5, dst);
|
||||
Put16(DC >> 5, dst);
|
||||
}
|
||||
}
|
||||
|
||||
static void DC16NoTop_SSE2(uint8_t* dst) { // DC with top samples unavailable
|
||||
static void DC16NoTop(uint8_t* dst) { // DC with top samples not available
|
||||
int DC = 8;
|
||||
int j;
|
||||
for (j = 0; j < 16; ++j) {
|
||||
DC += dst[-1 + j * BPS];
|
||||
}
|
||||
Put16_SSE2(DC >> 4, dst);
|
||||
Put16(DC >> 4, dst);
|
||||
}
|
||||
|
||||
static void DC16NoLeft_SSE2(uint8_t* dst) { // DC with left samples unavailable
|
||||
static void DC16NoLeft(uint8_t* dst) { // DC with left samples not available
|
||||
const __m128i zero = _mm_setzero_si128();
|
||||
const __m128i top = _mm_loadu_si128((const __m128i*)(dst - BPS));
|
||||
const __m128i sad8x2 = _mm_sad_epu8(top, zero);
|
||||
// sum the two sads: sad8x2[0:1] + sad8x2[8:9]
|
||||
const __m128i sum = _mm_add_epi16(sad8x2, _mm_shuffle_epi32(sad8x2, 2));
|
||||
const int DC = _mm_cvtsi128_si32(sum) + 8;
|
||||
Put16_SSE2(DC >> 4, dst);
|
||||
Put16(DC >> 4, dst);
|
||||
}
|
||||
|
||||
static void DC16NoTopLeft_SSE2(uint8_t* dst) { // DC with no top & left samples
|
||||
Put16_SSE2(0x80, dst);
|
||||
static void DC16NoTopLeft(uint8_t* dst) { // DC with no top and left samples
|
||||
Put16(0x80, dst);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Chroma
|
||||
|
||||
static void VE8uv_SSE2(uint8_t* dst) { // vertical
|
||||
static void VE8uv(uint8_t* dst) { // vertical
|
||||
int j;
|
||||
const __m128i top = _mm_loadl_epi64((const __m128i*)(dst - BPS));
|
||||
for (j = 0; j < 8; ++j) {
|
||||
@ -1127,8 +1121,17 @@ static void VE8uv_SSE2(uint8_t* dst) { // vertical
|
||||
}
|
||||
}
|
||||
|
||||
static void HE8uv(uint8_t* dst) { // horizontal
|
||||
int j;
|
||||
for (j = 0; j < 8; ++j) {
|
||||
const __m128i values = _mm_set1_epi8(dst[-1]);
|
||||
_mm_storel_epi64((__m128i*)dst, values);
|
||||
dst += BPS;
|
||||
}
|
||||
}
|
||||
|
||||
// helper for chroma-DC predictions
|
||||
static WEBP_INLINE void Put8x8uv_SSE2(uint8_t v, uint8_t* dst) {
|
||||
static WEBP_INLINE void Put8x8uv(uint8_t v, uint8_t* dst) {
|
||||
int j;
|
||||
const __m128i values = _mm_set1_epi8(v);
|
||||
for (j = 0; j < 8; ++j) {
|
||||
@ -1136,7 +1139,7 @@ static WEBP_INLINE void Put8x8uv_SSE2(uint8_t v, uint8_t* dst) {
|
||||
}
|
||||
}
|
||||
|
||||
static void DC8uv_SSE2(uint8_t* dst) { // DC
|
||||
static void DC8uv(uint8_t* dst) { // DC
|
||||
const __m128i zero = _mm_setzero_si128();
|
||||
const __m128i top = _mm_loadl_epi64((const __m128i*)(dst - BPS));
|
||||
const __m128i sum = _mm_sad_epu8(top, zero);
|
||||
@ -1147,29 +1150,29 @@ static void DC8uv_SSE2(uint8_t* dst) { // DC
|
||||
}
|
||||
{
|
||||
const int DC = _mm_cvtsi128_si32(sum) + left + 8;
|
||||
Put8x8uv_SSE2(DC >> 4, dst);
|
||||
Put8x8uv(DC >> 4, dst);
|
||||
}
|
||||
}
|
||||
|
||||
static void DC8uvNoLeft_SSE2(uint8_t* dst) { // DC with no left samples
|
||||
static void DC8uvNoLeft(uint8_t* dst) { // DC with no left samples
|
||||
const __m128i zero = _mm_setzero_si128();
|
||||
const __m128i top = _mm_loadl_epi64((const __m128i*)(dst - BPS));
|
||||
const __m128i sum = _mm_sad_epu8(top, zero);
|
||||
const int DC = _mm_cvtsi128_si32(sum) + 4;
|
||||
Put8x8uv_SSE2(DC >> 3, dst);
|
||||
Put8x8uv(DC >> 3, dst);
|
||||
}
|
||||
|
||||
static void DC8uvNoTop_SSE2(uint8_t* dst) { // DC with no top samples
|
||||
static void DC8uvNoTop(uint8_t* dst) { // DC with no top samples
|
||||
int dc0 = 4;
|
||||
int i;
|
||||
for (i = 0; i < 8; ++i) {
|
||||
dc0 += dst[-1 + i * BPS];
|
||||
}
|
||||
Put8x8uv_SSE2(dc0 >> 3, dst);
|
||||
Put8x8uv(dc0 >> 3, dst);
|
||||
}
|
||||
|
||||
static void DC8uvNoTopLeft_SSE2(uint8_t* dst) { // DC with nothing
|
||||
Put8x8uv_SSE2(0x80, dst);
|
||||
static void DC8uvNoTopLeft(uint8_t* dst) { // DC with nothing
|
||||
Put8x8uv(0x80, dst);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@ -1178,46 +1181,47 @@ static void DC8uvNoTopLeft_SSE2(uint8_t* dst) { // DC with nothing
|
||||
extern void VP8DspInitSSE2(void);
|
||||
|
||||
WEBP_TSAN_IGNORE_FUNCTION void VP8DspInitSSE2(void) {
|
||||
VP8Transform = Transform_SSE2;
|
||||
#if (USE_TRANSFORM_AC3 == 1)
|
||||
VP8TransformAC3 = TransformAC3_SSE2;
|
||||
VP8Transform = Transform;
|
||||
#if defined(USE_TRANSFORM_AC3)
|
||||
VP8TransformAC3 = TransformAC3;
|
||||
#endif
|
||||
|
||||
VP8VFilter16 = VFilter16_SSE2;
|
||||
VP8HFilter16 = HFilter16_SSE2;
|
||||
VP8VFilter8 = VFilter8_SSE2;
|
||||
VP8HFilter8 = HFilter8_SSE2;
|
||||
VP8VFilter16i = VFilter16i_SSE2;
|
||||
VP8HFilter16i = HFilter16i_SSE2;
|
||||
VP8VFilter8i = VFilter8i_SSE2;
|
||||
VP8HFilter8i = HFilter8i_SSE2;
|
||||
VP8VFilter16 = VFilter16;
|
||||
VP8HFilter16 = HFilter16;
|
||||
VP8VFilter8 = VFilter8;
|
||||
VP8HFilter8 = HFilter8;
|
||||
VP8VFilter16i = VFilter16i;
|
||||
VP8HFilter16i = HFilter16i;
|
||||
VP8VFilter8i = VFilter8i;
|
||||
VP8HFilter8i = HFilter8i;
|
||||
|
||||
VP8SimpleVFilter16 = SimpleVFilter16_SSE2;
|
||||
VP8SimpleHFilter16 = SimpleHFilter16_SSE2;
|
||||
VP8SimpleVFilter16i = SimpleVFilter16i_SSE2;
|
||||
VP8SimpleHFilter16i = SimpleHFilter16i_SSE2;
|
||||
VP8SimpleVFilter16 = SimpleVFilter16;
|
||||
VP8SimpleHFilter16 = SimpleHFilter16;
|
||||
VP8SimpleVFilter16i = SimpleVFilter16i;
|
||||
VP8SimpleHFilter16i = SimpleHFilter16i;
|
||||
|
||||
VP8PredLuma4[1] = TM4_SSE2;
|
||||
VP8PredLuma4[2] = VE4_SSE2;
|
||||
VP8PredLuma4[4] = RD4_SSE2;
|
||||
VP8PredLuma4[5] = VR4_SSE2;
|
||||
VP8PredLuma4[6] = LD4_SSE2;
|
||||
VP8PredLuma4[7] = VL4_SSE2;
|
||||
VP8PredLuma4[1] = TM4;
|
||||
VP8PredLuma4[2] = VE4;
|
||||
VP8PredLuma4[4] = RD4;
|
||||
VP8PredLuma4[5] = VR4;
|
||||
VP8PredLuma4[6] = LD4;
|
||||
VP8PredLuma4[7] = VL4;
|
||||
|
||||
VP8PredLuma16[0] = DC16_SSE2;
|
||||
VP8PredLuma16[1] = TM16_SSE2;
|
||||
VP8PredLuma16[2] = VE16_SSE2;
|
||||
VP8PredLuma16[3] = HE16_SSE2;
|
||||
VP8PredLuma16[4] = DC16NoTop_SSE2;
|
||||
VP8PredLuma16[5] = DC16NoLeft_SSE2;
|
||||
VP8PredLuma16[6] = DC16NoTopLeft_SSE2;
|
||||
VP8PredLuma16[0] = DC16;
|
||||
VP8PredLuma16[1] = TM16;
|
||||
VP8PredLuma16[2] = VE16;
|
||||
VP8PredLuma16[3] = HE16;
|
||||
VP8PredLuma16[4] = DC16NoTop;
|
||||
VP8PredLuma16[5] = DC16NoLeft;
|
||||
VP8PredLuma16[6] = DC16NoTopLeft;
|
||||
|
||||
VP8PredChroma8[0] = DC8uv_SSE2;
|
||||
VP8PredChroma8[1] = TM8uv_SSE2;
|
||||
VP8PredChroma8[2] = VE8uv_SSE2;
|
||||
VP8PredChroma8[4] = DC8uvNoTop_SSE2;
|
||||
VP8PredChroma8[5] = DC8uvNoLeft_SSE2;
|
||||
VP8PredChroma8[6] = DC8uvNoTopLeft_SSE2;
|
||||
VP8PredChroma8[0] = DC8uv;
|
||||
VP8PredChroma8[1] = TM8uv;
|
||||
VP8PredChroma8[2] = VE8uv;
|
||||
VP8PredChroma8[3] = HE8uv;
|
||||
VP8PredChroma8[4] = DC8uvNoTop;
|
||||
VP8PredChroma8[5] = DC8uvNoLeft;
|
||||
VP8PredChroma8[6] = DC8uvNoTopLeft;
|
||||
}
|
||||
|
||||
#else // !WEBP_USE_SSE2
|
||||
|
@ -11,15 +11,15 @@
|
||||
//
|
||||
// Author: Skal (pascal.massimino@gmail.com)
|
||||
|
||||
#include "src/dsp/dsp.h"
|
||||
#include "./dsp.h"
|
||||
|
||||
#if defined(WEBP_USE_SSE41)
|
||||
|
||||
#include <smmintrin.h>
|
||||
#include "src/dec/vp8i_dec.h"
|
||||
#include "src/utils/utils.h"
|
||||
#include "../dec/vp8i_dec.h"
|
||||
#include "../utils/utils.h"
|
||||
|
||||
static void HE16_SSE41(uint8_t* dst) { // horizontal
|
||||
static void HE16(uint8_t* dst) { // horizontal
|
||||
int j;
|
||||
const __m128i kShuffle3 = _mm_set1_epi8(3);
|
||||
for (j = 16; j > 0; --j) {
|
||||
@ -36,7 +36,7 @@ static void HE16_SSE41(uint8_t* dst) { // horizontal
|
||||
extern void VP8DspInitSSE41(void);
|
||||
|
||||
WEBP_TSAN_IGNORE_FUNCTION void VP8DspInitSSE41(void) {
|
||||
VP8PredLuma16[3] = HE16_SSE41;
|
||||
VP8PredLuma16[3] = HE16;
|
||||
}
|
||||
|
||||
#else // !WEBP_USE_SSE41
|
||||
|
1618
src/dsp/dec_wasm.c
Normal file
1618
src/dsp/dec_wasm.c
Normal file
File diff suppressed because it is too large
Load Diff
126
src/dsp/dsp.h
126
src/dsp/dsp.h
@ -15,10 +15,10 @@
|
||||
#define WEBP_DSP_DSP_H_
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "src/webp/config.h"
|
||||
#include "../webp/config.h"
|
||||
#endif
|
||||
|
||||
#include "src/webp/types.h"
|
||||
#include "../webp/types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -51,8 +51,9 @@ extern "C" {
|
||||
# define __has_builtin(x) 0
|
||||
#endif
|
||||
|
||||
// for now, none of the optimizations below are available in emscripten
|
||||
#if !defined(EMSCRIPTEN)
|
||||
// For now, none of the optimizations below are available in emscripten.
|
||||
// WebAssembly overrides native optimizations.
|
||||
#if !(defined(EMSCRIPTEN) || defined(WEBP_USE_WASM))
|
||||
|
||||
#if defined(_MSC_VER) && _MSC_VER > 1310 && \
|
||||
(defined(_M_X64) || defined(_M_IX86))
|
||||
@ -104,7 +105,7 @@ extern "C" {
|
||||
#define WEBP_USE_MIPS32
|
||||
#if (__mips_isa_rev >= 2)
|
||||
#define WEBP_USE_MIPS32_R2
|
||||
#if defined(__mips_dspr2) || (defined(__mips_dsp_rev) && __mips_dsp_rev >= 2)
|
||||
#if defined(__mips_dspr2) || (__mips_dsp_rev >= 2)
|
||||
#define WEBP_USE_MIPS_DSP_R2
|
||||
#endif
|
||||
#endif
|
||||
@ -116,22 +117,6 @@ extern "C" {
|
||||
|
||||
#endif /* EMSCRIPTEN */
|
||||
|
||||
#ifndef WEBP_DSP_OMIT_C_CODE
|
||||
#define WEBP_DSP_OMIT_C_CODE 1
|
||||
#endif
|
||||
|
||||
#if (defined(__aarch64__) || defined(__ARM_NEON__)) && WEBP_DSP_OMIT_C_CODE
|
||||
#define WEBP_NEON_OMIT_C_CODE 1
|
||||
#else
|
||||
#define WEBP_NEON_OMIT_C_CODE 0
|
||||
#endif
|
||||
|
||||
#if !(LOCAL_CLANG_PREREQ(3,8) || LOCAL_GCC_PREREQ(4,8) || defined(__aarch64__))
|
||||
#define WEBP_NEON_WORK_AROUND_GCC 1
|
||||
#else
|
||||
#define WEBP_NEON_WORK_AROUND_GCC 0
|
||||
#endif
|
||||
|
||||
// This macro prevents thread_sanitizer from reporting known concurrent writes.
|
||||
#define WEBP_TSAN_IGNORE_FUNCTION
|
||||
#if defined(__has_feature)
|
||||
@ -141,42 +126,6 @@ extern "C" {
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(WEBP_USE_THREAD) && !defined(_WIN32)
|
||||
#include <pthread.h> // NOLINT
|
||||
|
||||
#define WEBP_DSP_INIT(func) do { \
|
||||
static volatile VP8CPUInfo func ## _last_cpuinfo_used = \
|
||||
(VP8CPUInfo)&func ## _last_cpuinfo_used; \
|
||||
static pthread_mutex_t func ## _lock = PTHREAD_MUTEX_INITIALIZER; \
|
||||
if (pthread_mutex_lock(&func ## _lock)) break; \
|
||||
if (func ## _last_cpuinfo_used != VP8GetCPUInfo) func(); \
|
||||
func ## _last_cpuinfo_used = VP8GetCPUInfo; \
|
||||
(void)pthread_mutex_unlock(&func ## _lock); \
|
||||
} while (0)
|
||||
#else // !(defined(WEBP_USE_THREAD) && !defined(_WIN32))
|
||||
#define WEBP_DSP_INIT(func) do { \
|
||||
static volatile VP8CPUInfo func ## _last_cpuinfo_used = \
|
||||
(VP8CPUInfo)&func ## _last_cpuinfo_used; \
|
||||
if (func ## _last_cpuinfo_used == VP8GetCPUInfo) break; \
|
||||
func(); \
|
||||
func ## _last_cpuinfo_used = VP8GetCPUInfo; \
|
||||
} while (0)
|
||||
#endif // defined(WEBP_USE_THREAD) && !defined(_WIN32)
|
||||
|
||||
// Defines an Init + helper function that control multiple initialization of
|
||||
// function pointers / tables.
|
||||
/* Usage:
|
||||
WEBP_DSP_INIT_FUNC(InitFunc) {
|
||||
...function body
|
||||
}
|
||||
*/
|
||||
#define WEBP_DSP_INIT_FUNC(name) \
|
||||
static WEBP_TSAN_IGNORE_FUNCTION void name ## _body(void); \
|
||||
WEBP_TSAN_IGNORE_FUNCTION void name(void) { \
|
||||
WEBP_DSP_INIT(name ## _body); \
|
||||
} \
|
||||
static WEBP_TSAN_IGNORE_FUNCTION void name ## _body(void)
|
||||
|
||||
#define WEBP_UBSAN_IGNORE_UNDEF
|
||||
#define WEBP_UBSAN_IGNORE_UNSIGNED_OVERFLOW
|
||||
#if defined(__clang__) && defined(__has_attribute)
|
||||
@ -197,18 +146,6 @@ extern "C" {
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Regularize the definition of WEBP_SWAP_16BIT_CSP (backward compatibility)
|
||||
#if !defined(WEBP_SWAP_16BIT_CSP)
|
||||
#define WEBP_SWAP_16BIT_CSP 0
|
||||
#endif
|
||||
|
||||
// some endian fix (e.g.: mips-gcc doesn't define __BIG_ENDIAN__)
|
||||
#if !defined(WORDS_BIGENDIAN) && \
|
||||
(defined(__BIG_ENDIAN__) || defined(_M_PPC) || \
|
||||
(defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)))
|
||||
#define WORDS_BIGENDIAN
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
kSSE2,
|
||||
kSSE3,
|
||||
@ -219,11 +156,12 @@ typedef enum {
|
||||
kNEON,
|
||||
kMIPS32,
|
||||
kMIPSdspR2,
|
||||
kMSA
|
||||
kMSA,
|
||||
kWASM
|
||||
} CPUFeature;
|
||||
// returns true if the CPU supports the feature.
|
||||
typedef int (*VP8CPUInfo)(CPUFeature feature);
|
||||
WEBP_EXTERN VP8CPUInfo VP8GetCPUInfo;
|
||||
WEBP_EXTERN(VP8CPUInfo) VP8GetCPUInfo;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Init stub generator
|
||||
@ -232,7 +170,7 @@ WEBP_EXTERN VP8CPUInfo VP8GetCPUInfo;
|
||||
// avoiding a compiler warning.
|
||||
#define WEBP_DSP_INIT_STUB(func) \
|
||||
extern void func(void); \
|
||||
void func(void) {}
|
||||
WEBP_TSAN_IGNORE_FUNCTION void func(void) {}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Encoding
|
||||
@ -351,7 +289,6 @@ typedef double (*VP8SSIMGetClippedFunc)(const uint8_t* src1, int stride1,
|
||||
int xo, int yo, // center position
|
||||
int W, int H); // plane dimension
|
||||
|
||||
#if !defined(WEBP_REDUCE_SIZE)
|
||||
// This version is called with the guarantee that you can load 8 bytes and
|
||||
// 8 rows at offset src1 and src2
|
||||
typedef double (*VP8SSIMGetFunc)(const uint8_t* src1, int stride1,
|
||||
@ -359,13 +296,10 @@ typedef double (*VP8SSIMGetFunc)(const uint8_t* src1, int stride1,
|
||||
|
||||
extern VP8SSIMGetFunc VP8SSIMGet; // unclipped / unchecked
|
||||
extern VP8SSIMGetClippedFunc VP8SSIMGetClipped; // with clipping
|
||||
#endif
|
||||
|
||||
#if !defined(WEBP_DISABLE_STATS)
|
||||
typedef uint32_t (*VP8AccumulateSSEFunc)(const uint8_t* src1,
|
||||
const uint8_t* src2, int len);
|
||||
extern VP8AccumulateSSEFunc VP8AccumulateSSE;
|
||||
#endif
|
||||
|
||||
// must be called before using any of the above directly
|
||||
void VP8SSIMDspInit(void);
|
||||
@ -546,12 +480,12 @@ extern WebPRescalerExportRowFunc WebPRescalerExportRowExpand;
|
||||
extern WebPRescalerExportRowFunc WebPRescalerExportRowShrink;
|
||||
|
||||
// Plain-C implementation, as fall-back.
|
||||
extern void WebPRescalerImportRowExpand_C(struct WebPRescaler* const wrk,
|
||||
extern void WebPRescalerImportRowExpandC(struct WebPRescaler* const wrk,
|
||||
const uint8_t* src);
|
||||
extern void WebPRescalerImportRowShrink_C(struct WebPRescaler* const wrk,
|
||||
extern void WebPRescalerImportRowShrinkC(struct WebPRescaler* const wrk,
|
||||
const uint8_t* src);
|
||||
extern void WebPRescalerExportRowExpand_C(struct WebPRescaler* const wrk);
|
||||
extern void WebPRescalerExportRowShrink_C(struct WebPRescaler* const wrk);
|
||||
extern void WebPRescalerExportRowExpandC(struct WebPRescaler* const wrk);
|
||||
extern void WebPRescalerExportRowShrinkC(struct WebPRescaler* const wrk);
|
||||
|
||||
// Main entry calls:
|
||||
extern void WebPRescalerImportRow(struct WebPRescaler* const wrk,
|
||||
@ -617,29 +551,25 @@ void WebPMultRows(uint8_t* ptr, int stride,
|
||||
int width, int num_rows, int inverse);
|
||||
|
||||
// Plain-C versions, used as fallback by some implementations.
|
||||
void WebPMultRow_C(uint8_t* const ptr, const uint8_t* const alpha,
|
||||
void WebPMultRowC(uint8_t* const ptr, const uint8_t* const alpha,
|
||||
int width, int inverse);
|
||||
void WebPMultARGBRow_C(uint32_t* const ptr, int width, int inverse);
|
||||
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
// ARGB packing function: a/r/g/b input is rgba or bgra order.
|
||||
extern void (*WebPPackARGB)(const uint8_t* a, const uint8_t* r,
|
||||
const uint8_t* g, const uint8_t* b, int len,
|
||||
uint32_t* out);
|
||||
#endif
|
||||
|
||||
// RGB packing function. 'step' can be 3 or 4. r/g/b input is rgb or bgr order.
|
||||
extern void (*WebPPackRGB)(const uint8_t* r, const uint8_t* g, const uint8_t* b,
|
||||
int len, int step, uint32_t* out);
|
||||
|
||||
// This function returns true if src[i] contains a value different from 0xff.
|
||||
extern int (*WebPHasAlpha8b)(const uint8_t* src, int length);
|
||||
// This function returns true if src[4*i] contains a value different from 0xff.
|
||||
extern int (*WebPHasAlpha32b)(const uint8_t* src, int length);
|
||||
void WebPMultARGBRowC(uint32_t* const ptr, int width, int inverse);
|
||||
|
||||
// To be called first before using the above.
|
||||
void WebPInitAlphaProcessing(void);
|
||||
|
||||
// ARGB packing function: a/r/g/b input is rgba or bgra order.
|
||||
extern void (*VP8PackARGB)(const uint8_t* a, const uint8_t* r,
|
||||
const uint8_t* g, const uint8_t* b, int len,
|
||||
uint32_t* out);
|
||||
|
||||
// RGB packing function. 'step' can be 3 or 4. r/g/b input is rgb or bgr order.
|
||||
extern void (*VP8PackRGB)(const uint8_t* r, const uint8_t* g, const uint8_t* b,
|
||||
int len, int step, uint32_t* out);
|
||||
|
||||
// To be called first before using the above.
|
||||
void VP8EncDspARGBInit(void);
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Filter functions
|
||||
|
||||
|
147
src/dsp/enc.c
147
src/dsp/enc.c
@ -14,18 +14,16 @@
|
||||
#include <assert.h>
|
||||
#include <stdlib.h> // for abs()
|
||||
|
||||
#include "src/dsp/dsp.h"
|
||||
#include "src/enc/vp8i_enc.h"
|
||||
#include "./dsp.h"
|
||||
#include "../enc/vp8i_enc.h"
|
||||
|
||||
static WEBP_INLINE uint8_t clip_8b(int v) {
|
||||
return (!(v & ~0xff)) ? v : (v < 0) ? 0 : 255;
|
||||
}
|
||||
|
||||
#if !WEBP_NEON_OMIT_C_CODE
|
||||
static WEBP_INLINE int clip_max(int v, int max) {
|
||||
return (v > max) ? max : v;
|
||||
}
|
||||
#endif // !WEBP_NEON_OMIT_C_CODE
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Compute susceptibility based on DCT-coeff histograms:
|
||||
@ -58,8 +56,7 @@ void VP8SetHistogramData(const int distribution[MAX_COEFF_THRESH + 1],
|
||||
histo->last_non_zero = last_non_zero;
|
||||
}
|
||||
|
||||
#if !WEBP_NEON_OMIT_C_CODE
|
||||
static void CollectHistogram_C(const uint8_t* ref, const uint8_t* pred,
|
||||
static void CollectHistogram(const uint8_t* ref, const uint8_t* pred,
|
||||
int start_block, int end_block,
|
||||
VP8Histogram* const histo) {
|
||||
int j;
|
||||
@ -79,7 +76,6 @@ static void CollectHistogram_C(const uint8_t* ref, const uint8_t* pred,
|
||||
}
|
||||
VP8SetHistogramData(distribution, histo);
|
||||
}
|
||||
#endif // !WEBP_NEON_OMIT_C_CODE
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// run-time tables (~4k)
|
||||
@ -104,8 +100,6 @@ static WEBP_TSAN_IGNORE_FUNCTION void InitTables(void) {
|
||||
//------------------------------------------------------------------------------
|
||||
// Transforms (Paragraph 14.4)
|
||||
|
||||
#if !WEBP_NEON_OMIT_C_CODE
|
||||
|
||||
#define STORE(x, y, v) \
|
||||
dst[(x) + (y) * BPS] = clip_8b(ref[(x) + (y) * BPS] + ((v) >> 3))
|
||||
|
||||
@ -146,7 +140,7 @@ static WEBP_INLINE void ITransformOne(const uint8_t* ref, const int16_t* in,
|
||||
}
|
||||
}
|
||||
|
||||
static void ITransform_C(const uint8_t* ref, const int16_t* in, uint8_t* dst,
|
||||
static void ITransform(const uint8_t* ref, const int16_t* in, uint8_t* dst,
|
||||
int do_two) {
|
||||
ITransformOne(ref, in, dst);
|
||||
if (do_two) {
|
||||
@ -154,7 +148,7 @@ static void ITransform_C(const uint8_t* ref, const int16_t* in, uint8_t* dst,
|
||||
}
|
||||
}
|
||||
|
||||
static void FTransform_C(const uint8_t* src, const uint8_t* ref, int16_t* out) {
|
||||
static void FTransform(const uint8_t* src, const uint8_t* ref, int16_t* out) {
|
||||
int i;
|
||||
int tmp[16];
|
||||
for (i = 0; i < 4; ++i, src += BPS, ref += BPS) {
|
||||
@ -182,16 +176,13 @@ static void FTransform_C(const uint8_t* src, const uint8_t* ref, int16_t* out) {
|
||||
out[12+ i] = ((a3 * 2217 - a2 * 5352 + 51000) >> 16);
|
||||
}
|
||||
}
|
||||
#endif // !WEBP_NEON_OMIT_C_CODE
|
||||
|
||||
static void FTransform2_C(const uint8_t* src, const uint8_t* ref,
|
||||
int16_t* out) {
|
||||
static void FTransform2(const uint8_t* src, const uint8_t* ref, int16_t* out) {
|
||||
VP8FTransform(src, ref, out);
|
||||
VP8FTransform(src + 4, ref + 4, out + 16);
|
||||
}
|
||||
|
||||
#if !WEBP_NEON_OMIT_C_CODE
|
||||
static void FTransformWHT_C(const int16_t* in, int16_t* out) {
|
||||
static void FTransformWHT(const int16_t* in, int16_t* out) {
|
||||
// input is 12b signed
|
||||
int32_t tmp[16];
|
||||
int i;
|
||||
@ -220,7 +211,6 @@ static void FTransformWHT_C(const int16_t* in, int16_t* out) {
|
||||
out[12 + i] = b3 >> 1;
|
||||
}
|
||||
}
|
||||
#endif // !WEBP_NEON_OMIT_C_CODE
|
||||
|
||||
#undef MUL
|
||||
#undef STORE
|
||||
@ -313,7 +303,7 @@ static WEBP_INLINE void DCMode(uint8_t* dst, const uint8_t* left,
|
||||
//------------------------------------------------------------------------------
|
||||
// Chroma 8x8 prediction (paragraph 12.2)
|
||||
|
||||
static void IntraChromaPreds_C(uint8_t* dst, const uint8_t* left,
|
||||
static void IntraChromaPreds(uint8_t* dst, const uint8_t* left,
|
||||
const uint8_t* top) {
|
||||
// U block
|
||||
DCMode(C8DC8 + dst, left, top, 8, 8, 4);
|
||||
@ -333,7 +323,7 @@ static void IntraChromaPreds_C(uint8_t* dst, const uint8_t* left,
|
||||
//------------------------------------------------------------------------------
|
||||
// luma 16x16 prediction (paragraph 12.3)
|
||||
|
||||
static void Intra16Preds_C(uint8_t* dst,
|
||||
static void Intra16Preds(uint8_t* dst,
|
||||
const uint8_t* left, const uint8_t* top) {
|
||||
DCMode(I16DC16 + dst, left, top, 16, 16, 5);
|
||||
VerticalPred(I16VE16 + dst, top, 16);
|
||||
@ -517,7 +507,7 @@ static void TM4(uint8_t* dst, const uint8_t* top) {
|
||||
|
||||
// Left samples are top[-5 .. -2], top_left is top[-1], top are
|
||||
// located at top[0..3], and top right is top[4..7]
|
||||
static void Intra4Preds_C(uint8_t* dst, const uint8_t* top) {
|
||||
static void Intra4Preds(uint8_t* dst, const uint8_t* top) {
|
||||
DC4(I4DC4 + dst, top);
|
||||
TM4(I4TM4 + dst, top);
|
||||
VE4(I4VE4 + dst, top);
|
||||
@ -533,7 +523,6 @@ static void Intra4Preds_C(uint8_t* dst, const uint8_t* top) {
|
||||
//------------------------------------------------------------------------------
|
||||
// Metric
|
||||
|
||||
#if !WEBP_NEON_OMIT_C_CODE
|
||||
static WEBP_INLINE int GetSSE(const uint8_t* a, const uint8_t* b,
|
||||
int w, int h) {
|
||||
int count = 0;
|
||||
@ -549,21 +538,20 @@ static WEBP_INLINE int GetSSE(const uint8_t* a, const uint8_t* b,
|
||||
return count;
|
||||
}
|
||||
|
||||
static int SSE16x16_C(const uint8_t* a, const uint8_t* b) {
|
||||
static int SSE16x16(const uint8_t* a, const uint8_t* b) {
|
||||
return GetSSE(a, b, 16, 16);
|
||||
}
|
||||
static int SSE16x8_C(const uint8_t* a, const uint8_t* b) {
|
||||
static int SSE16x8(const uint8_t* a, const uint8_t* b) {
|
||||
return GetSSE(a, b, 16, 8);
|
||||
}
|
||||
static int SSE8x8_C(const uint8_t* a, const uint8_t* b) {
|
||||
static int SSE8x8(const uint8_t* a, const uint8_t* b) {
|
||||
return GetSSE(a, b, 8, 8);
|
||||
}
|
||||
static int SSE4x4_C(const uint8_t* a, const uint8_t* b) {
|
||||
static int SSE4x4(const uint8_t* a, const uint8_t* b) {
|
||||
return GetSSE(a, b, 4, 4);
|
||||
}
|
||||
#endif // !WEBP_NEON_OMIT_C_CODE
|
||||
|
||||
static void Mean16x4_C(const uint8_t* ref, uint32_t dc[4]) {
|
||||
static void Mean16x4(const uint8_t* ref, uint32_t dc[4]) {
|
||||
int k, x, y;
|
||||
for (k = 0; k < 4; ++k) {
|
||||
uint32_t avg = 0;
|
||||
@ -583,7 +571,6 @@ static void Mean16x4_C(const uint8_t* ref, uint32_t dc[4]) {
|
||||
// We try to match the spectral content (weighted) between source and
|
||||
// reconstructed samples.
|
||||
|
||||
#if !WEBP_NEON_OMIT_C_CODE
|
||||
// Hadamard transform
|
||||
// Returns the weighted sum of the absolute value of transformed coefficients.
|
||||
// w[] contains a row-major 4 by 4 symmetric matrix.
|
||||
@ -621,25 +608,24 @@ static int TTransform(const uint8_t* in, const uint16_t* w) {
|
||||
return sum;
|
||||
}
|
||||
|
||||
static int Disto4x4_C(const uint8_t* const a, const uint8_t* const b,
|
||||
static int Disto4x4(const uint8_t* const a, const uint8_t* const b,
|
||||
const uint16_t* const w) {
|
||||
const int sum1 = TTransform(a, w);
|
||||
const int sum2 = TTransform(b, w);
|
||||
return abs(sum2 - sum1) >> 5;
|
||||
}
|
||||
|
||||
static int Disto16x16_C(const uint8_t* const a, const uint8_t* const b,
|
||||
static int Disto16x16(const uint8_t* const a, const uint8_t* const b,
|
||||
const uint16_t* const w) {
|
||||
int D = 0;
|
||||
int x, y;
|
||||
for (y = 0; y < 16 * BPS; y += 4 * BPS) {
|
||||
for (x = 0; x < 16; x += 4) {
|
||||
D += Disto4x4_C(a + x + y, b + x + y, w);
|
||||
D += Disto4x4(a + x + y, b + x + y, w);
|
||||
}
|
||||
}
|
||||
return D;
|
||||
}
|
||||
#endif // !WEBP_NEON_OMIT_C_CODE
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Quantization
|
||||
@ -650,7 +636,7 @@ static const uint8_t kZigzag[16] = {
|
||||
};
|
||||
|
||||
// Simple quantization
|
||||
static int QuantizeBlock_C(int16_t in[16], int16_t out[16],
|
||||
static int QuantizeBlock(int16_t in[16], int16_t out[16],
|
||||
const VP8Matrix* const mtx) {
|
||||
int last = -1;
|
||||
int n;
|
||||
@ -676,15 +662,13 @@ static int QuantizeBlock_C(int16_t in[16], int16_t out[16],
|
||||
return (last >= 0);
|
||||
}
|
||||
|
||||
#if !WEBP_NEON_OMIT_C_CODE || WEBP_NEON_WORK_AROUND_GCC
|
||||
static int Quantize2Blocks_C(int16_t in[32], int16_t out[32],
|
||||
static int Quantize2Blocks(int16_t in[32], int16_t out[32],
|
||||
const VP8Matrix* const mtx) {
|
||||
int nz;
|
||||
nz = VP8EncQuantizeBlock(in + 0 * 16, out + 0 * 16, mtx) << 0;
|
||||
nz |= VP8EncQuantizeBlock(in + 1 * 16, out + 1 * 16, mtx) << 1;
|
||||
return nz;
|
||||
}
|
||||
#endif // !WEBP_NEON_OMIT_C_CODE || WEBP_NEON_WORK_AROUND_GCC
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Block copy
|
||||
@ -698,11 +682,11 @@ static WEBP_INLINE void Copy(const uint8_t* src, uint8_t* dst, int w, int h) {
|
||||
}
|
||||
}
|
||||
|
||||
static void Copy4x4_C(const uint8_t* src, uint8_t* dst) {
|
||||
static void Copy4x4(const uint8_t* src, uint8_t* dst) {
|
||||
Copy(src, dst, 4, 4);
|
||||
}
|
||||
|
||||
static void Copy16x8_C(const uint8_t* src, uint8_t* dst) {
|
||||
static void Copy16x8(const uint8_t* src, uint8_t* dst) {
|
||||
Copy(src, dst, 16, 8);
|
||||
}
|
||||
|
||||
@ -740,37 +724,36 @@ extern void VP8EncDspInitMIPS32(void);
|
||||
extern void VP8EncDspInitMIPSdspR2(void);
|
||||
extern void VP8EncDspInitMSA(void);
|
||||
|
||||
WEBP_DSP_INIT_FUNC(VP8EncDspInit) {
|
||||
static volatile VP8CPUInfo enc_last_cpuinfo_used =
|
||||
(VP8CPUInfo)&enc_last_cpuinfo_used;
|
||||
|
||||
WEBP_TSAN_IGNORE_FUNCTION void VP8EncDspInit(void) {
|
||||
if (enc_last_cpuinfo_used == VP8GetCPUInfo) return;
|
||||
|
||||
VP8DspInit(); // common inverse transforms
|
||||
InitTables();
|
||||
|
||||
// default C implementations
|
||||
#if !WEBP_NEON_OMIT_C_CODE
|
||||
VP8ITransform = ITransform_C;
|
||||
VP8FTransform = FTransform_C;
|
||||
VP8FTransformWHT = FTransformWHT_C;
|
||||
VP8TDisto4x4 = Disto4x4_C;
|
||||
VP8TDisto16x16 = Disto16x16_C;
|
||||
VP8CollectHistogram = CollectHistogram_C;
|
||||
VP8SSE16x16 = SSE16x16_C;
|
||||
VP8SSE16x8 = SSE16x8_C;
|
||||
VP8SSE8x8 = SSE8x8_C;
|
||||
VP8SSE4x4 = SSE4x4_C;
|
||||
#endif
|
||||
|
||||
#if !WEBP_NEON_OMIT_C_CODE || WEBP_NEON_WORK_AROUND_GCC
|
||||
VP8EncQuantizeBlock = QuantizeBlock_C;
|
||||
VP8EncQuantize2Blocks = Quantize2Blocks_C;
|
||||
#endif
|
||||
|
||||
VP8FTransform2 = FTransform2_C;
|
||||
VP8EncPredLuma4 = Intra4Preds_C;
|
||||
VP8EncPredLuma16 = Intra16Preds_C;
|
||||
VP8EncPredChroma8 = IntraChromaPreds_C;
|
||||
VP8Mean16x4 = Mean16x4_C;
|
||||
VP8EncQuantizeBlockWHT = QuantizeBlock_C;
|
||||
VP8Copy4x4 = Copy4x4_C;
|
||||
VP8Copy16x8 = Copy16x8_C;
|
||||
VP8CollectHistogram = CollectHistogram;
|
||||
VP8ITransform = ITransform;
|
||||
VP8FTransform = FTransform;
|
||||
VP8FTransform2 = FTransform2;
|
||||
VP8FTransformWHT = FTransformWHT;
|
||||
VP8EncPredLuma4 = Intra4Preds;
|
||||
VP8EncPredLuma16 = Intra16Preds;
|
||||
VP8EncPredChroma8 = IntraChromaPreds;
|
||||
VP8SSE16x16 = SSE16x16;
|
||||
VP8SSE8x8 = SSE8x8;
|
||||
VP8SSE16x8 = SSE16x8;
|
||||
VP8SSE4x4 = SSE4x4;
|
||||
VP8TDisto4x4 = Disto4x4;
|
||||
VP8TDisto16x16 = Disto16x16;
|
||||
VP8Mean16x4 = Mean16x4;
|
||||
VP8EncQuantizeBlock = QuantizeBlock;
|
||||
VP8EncQuantize2Blocks = Quantize2Blocks;
|
||||
VP8EncQuantizeBlockWHT = QuantizeBlock;
|
||||
VP8Copy4x4 = Copy4x4;
|
||||
VP8Copy16x8 = Copy16x8;
|
||||
|
||||
// If defined, use CPUInfo() to overwrite some pointers with faster versions.
|
||||
if (VP8GetCPUInfo != NULL) {
|
||||
@ -789,6 +772,11 @@ WEBP_DSP_INIT_FUNC(VP8EncDspInit) {
|
||||
VP8EncDspInitAVX2();
|
||||
}
|
||||
#endif
|
||||
#if defined(WEBP_USE_NEON)
|
||||
if (VP8GetCPUInfo(kNEON)) {
|
||||
VP8EncDspInitNEON();
|
||||
}
|
||||
#endif
|
||||
#if defined(WEBP_USE_MIPS32)
|
||||
if (VP8GetCPUInfo(kMIPS32)) {
|
||||
VP8EncDspInitMIPS32();
|
||||
@ -805,32 +793,5 @@ WEBP_DSP_INIT_FUNC(VP8EncDspInit) {
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(WEBP_USE_NEON)
|
||||
if (WEBP_NEON_OMIT_C_CODE ||
|
||||
(VP8GetCPUInfo != NULL && VP8GetCPUInfo(kNEON))) {
|
||||
VP8EncDspInitNEON();
|
||||
}
|
||||
#endif
|
||||
|
||||
assert(VP8ITransform != NULL);
|
||||
assert(VP8FTransform != NULL);
|
||||
assert(VP8FTransformWHT != NULL);
|
||||
assert(VP8TDisto4x4 != NULL);
|
||||
assert(VP8TDisto16x16 != NULL);
|
||||
assert(VP8CollectHistogram != NULL);
|
||||
assert(VP8SSE16x16 != NULL);
|
||||
assert(VP8SSE16x8 != NULL);
|
||||
assert(VP8SSE8x8 != NULL);
|
||||
assert(VP8SSE4x4 != NULL);
|
||||
assert(VP8EncQuantizeBlock != NULL);
|
||||
assert(VP8EncQuantize2Blocks != NULL);
|
||||
assert(VP8FTransform2 != NULL);
|
||||
assert(VP8EncPredLuma4 != NULL);
|
||||
assert(VP8EncPredLuma16 != NULL);
|
||||
assert(VP8EncPredChroma8 != NULL);
|
||||
assert(VP8Mean16x4 != NULL);
|
||||
assert(VP8EncQuantizeBlockWHT != NULL);
|
||||
assert(VP8Copy4x4 != NULL);
|
||||
assert(VP8Copy16x8 != NULL);
|
||||
enc_last_cpuinfo_used = VP8GetCPUInfo;
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user