mirror of
https://github.com/webmproject/libwebp.git
synced 2025-07-17 22:39:52 +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)
|
- Urvang Joshi (urvang at google dot com)
|
||||||
- Vikas Arora (vikasa at google dot com)
|
- Vikas Arora (vikasa at google dot com)
|
||||||
- Vincent Rabaud (vrabaud 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)
|
- 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_neon.$(NEON) \
|
||||||
src/dsp/alpha_processing_sse2.c \
|
src/dsp/alpha_processing_sse2.c \
|
||||||
src/dsp/alpha_processing_sse41.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/cpu.c \
|
||||||
src/dsp/dec.c \
|
src/dsp/dec.c \
|
||||||
src/dsp/dec_clip_tables.c \
|
src/dsp/dec_clip_tables.c \
|
||||||
@ -85,13 +88,11 @@ dsp_dec_srcs := \
|
|||||||
src/dsp/upsampling_msa.c \
|
src/dsp/upsampling_msa.c \
|
||||||
src/dsp/upsampling_neon.$(NEON) \
|
src/dsp/upsampling_neon.$(NEON) \
|
||||||
src/dsp/upsampling_sse2.c \
|
src/dsp/upsampling_sse2.c \
|
||||||
src/dsp/upsampling_sse41.c \
|
|
||||||
src/dsp/yuv.c \
|
src/dsp/yuv.c \
|
||||||
src/dsp/yuv_mips32.c \
|
src/dsp/yuv_mips32.c \
|
||||||
src/dsp/yuv_mips_dsp_r2.c \
|
src/dsp/yuv_mips_dsp_r2.c \
|
||||||
src/dsp/yuv_neon.$(NEON) \
|
src/dsp/yuv_neon.$(NEON) \
|
||||||
src/dsp/yuv_sse2.c \
|
src/dsp/yuv_sse2.c \
|
||||||
src/dsp/yuv_sse41.c \
|
|
||||||
|
|
||||||
dsp_enc_srcs := \
|
dsp_enc_srcs := \
|
||||||
src/dsp/cost.c \
|
src/dsp/cost.c \
|
||||||
@ -123,6 +124,7 @@ enc_srcs := \
|
|||||||
src/enc/backward_references_enc.c \
|
src/enc/backward_references_enc.c \
|
||||||
src/enc/config_enc.c \
|
src/enc/config_enc.c \
|
||||||
src/enc/cost_enc.c \
|
src/enc/cost_enc.c \
|
||||||
|
src/enc/delta_palettization_enc.c \
|
||||||
src/enc/filter_enc.c \
|
src/enc/filter_enc.c \
|
||||||
src/enc/frame_enc.c \
|
src/enc/frame_enc.c \
|
||||||
src/enc/histogram_enc.c \
|
src/enc/histogram_enc.c \
|
||||||
|
@ -4,16 +4,17 @@ project(libwebp C)
|
|||||||
|
|
||||||
# Options for coder / decoder executables.
|
# Options for coder / decoder executables.
|
||||||
option(WEBP_ENABLE_SIMD "Enable any SIMD optimization." ON)
|
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_CWEBP "Build the cwebp command line tool." OFF)
|
||||||
option(WEBP_BUILD_DWEBP "Build the dwebp 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_GIF2WEBP "Build the gif2webp conversion tool." OFF)
|
||||||
option(WEBP_BUILD_IMG2WEBP "Build the img2webp animation 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_WEBPINFO "Build the webpinfo command line tool." OFF)
|
||||||
option(WEBP_BUILD_WEBP_JS "Emscripten build of webp.js." 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)
|
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)
|
set(WEBP_ENABLE_SIMD OFF)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
@ -26,13 +27,19 @@ if(NOT CMAKE_BUILD_TYPE)
|
|||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Include dependencies.
|
include(cmake/config.h.cmake)
|
||||||
include(cmake/deps.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.
|
# Options.
|
||||||
if(WEBP_ENABLE_SWAP_16BIT_CSP)
|
if(WEBP_ENABLE_SWAP_16BIT_CSP)
|
||||||
add_definitions(-DWEBP_SWAP_16BIT_CSP=1)
|
add_definitions(-DWEBP_SWAP_16BIT_CSP)
|
||||||
|
endif()
|
||||||
|
if(WEBP_ENABLE_WASM)
|
||||||
|
add_definitions(-DWEBP_USE_WASM)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
@ -47,10 +54,7 @@ if(ANDROID)
|
|||||||
set(WEBP_DEP_INCLUDE_DIRS ${WEBP_DEP_INCLUDE_DIRS}
|
set(WEBP_DEP_INCLUDE_DIRS ${WEBP_DEP_INCLUDE_DIRS}
|
||||||
${ANDROID_NDK}/sources/android/cpufeatures
|
${ANDROID_NDK}/sources/android/cpufeatures
|
||||||
)
|
)
|
||||||
add_definitions(-DHAVE_CPU_FEATURES_H=1)
|
add_definitions(-DHAVE_CPU_FEATURES_H)
|
||||||
set(HAVE_CPU_FEATURES_H 1)
|
|
||||||
else()
|
|
||||||
set(HAVE_CPU_FEATURES_H 0)
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
@ -102,13 +106,8 @@ endforeach()
|
|||||||
|
|
||||||
### Define the mandatory libraries.
|
### Define the mandatory libraries.
|
||||||
# Build the webpdecoder library.
|
# Build the webpdecoder library.
|
||||||
if(MSVC)
|
add_definitions(-Wall)
|
||||||
# avoid security warnings for e.g., fopen() used in the examples.
|
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/src/ ${WEBP_DEP_INCLUDE_DIRS})
|
||||||
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
|
|
||||||
else()
|
|
||||||
add_definitions(-Wall)
|
|
||||||
endif()
|
|
||||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${WEBP_DEP_INCLUDE_DIRS})
|
|
||||||
add_library(webpdecode OBJECT ${WEBP_DEC_SRCS})
|
add_library(webpdecode OBJECT ${WEBP_DEC_SRCS})
|
||||||
add_library(webpdspdecode OBJECT ${WEBP_DSP_COMMON_SRCS} ${WEBP_DSP_DEC_SRCS})
|
add_library(webpdspdecode OBJECT ${WEBP_DSP_COMMON_SRCS} ${WEBP_DSP_DEC_SRCS})
|
||||||
add_library(webputilsdecode OBJECT ${WEBP_UTILS_COMMON_SRCS}
|
add_library(webputilsdecode OBJECT ${WEBP_UTILS_COMMON_SRCS}
|
||||||
@ -146,13 +145,13 @@ function(parse_version FILE NAME VAR)
|
|||||||
set(${VAR} "${VERSION}" PARENT_SCOPE)
|
set(${VAR} "${VERSION}" PARENT_SCOPE)
|
||||||
endfunction()
|
endfunction()
|
||||||
parse_version(Makefile.am webp WEBP_WEBP_SOVERSION)
|
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})
|
SOVERSION ${WEBP_WEBP_SOVERSION})
|
||||||
parse_version(Makefile.am webpdecoder WEBP_DECODER_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})
|
SOVERSION ${WEBP_DECODER_SOVERSION})
|
||||||
parse_version(demux/Makefile.am webpdemux WEBP_DEMUX_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})
|
SOVERSION ${WEBP_DEMUX_SOVERSION})
|
||||||
|
|
||||||
# Define the libraries to install.
|
# 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})
|
foreach(I_FILE RANGE ${WEBP_SIMD_FILES_TO_INCLUDE_RANGE})
|
||||||
list(GET WEBP_SIMD_FILES_TO_INCLUDE ${I_FILE} FILE)
|
list(GET WEBP_SIMD_FILES_TO_INCLUDE ${I_FILE} FILE)
|
||||||
list(GET WEBP_SIMD_FLAGS_TO_INCLUDE ${I_FILE} SIMD_COMPILE_FLAG)
|
list(GET WEBP_SIMD_FLAGS_TO_INCLUDE ${I_FILE} SIMD_COMPILE_FLAG)
|
||||||
set_source_files_properties(${FILE} PROPERTIES
|
if(NOT ${SIMD_COMPILE_FLAG} STREQUAL "NOTFOUND")
|
||||||
COMPILE_FLAGS ${SIMD_COMPILE_FLAG}
|
set_source_files_properties(${FILE} PROPERTIES
|
||||||
)
|
COMPILE_FLAGS ${SIMD_COMPILE_FLAG}
|
||||||
|
)
|
||||||
|
endif()
|
||||||
endforeach()
|
endforeach()
|
||||||
|
|
||||||
# Build the executables if asked for.
|
# 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"
|
parse_Makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/imageio "IMAGEDEC_SRCS"
|
||||||
"imagedec_[^ ]*")
|
"imagedec_[^ ]*")
|
||||||
add_library(imagedec ${IMAGEDEC_SRCS})
|
add_library(imagedec ${IMAGEDEC_SRCS})
|
||||||
target_link_libraries(imagedec imageioutil webpdemux webp
|
target_link_libraries(imagedec imageioutil webp ${WEBP_DEP_IMG_LIBRARIES})
|
||||||
${WEBP_DEP_IMG_LIBRARIES})
|
|
||||||
|
|
||||||
# Image-encoding utility library.
|
# Image-encoding utility library.
|
||||||
parse_Makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/imageio "IMAGEENC_SRCS"
|
parse_Makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/imageio "IMAGEENC_SRCS"
|
||||||
"imageenc_[^ ]*")
|
"imageenc_[^ ]*")
|
||||||
add_library(imageenc ${IMAGEENC_SRCS})
|
add_library(imageenc ${IMAGEENC_SRCS})
|
||||||
target_link_libraries(imageenc webp)
|
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()
|
endif()
|
||||||
|
|
||||||
if(WEBP_BUILD_DWEBP)
|
if(WEBP_BUILD_DWEBP)
|
||||||
@ -214,8 +210,6 @@ if(WEBP_BUILD_DWEBP)
|
|||||||
add_executable(dwebp ${DWEBP_SRCS})
|
add_executable(dwebp ${DWEBP_SRCS})
|
||||||
target_link_libraries(dwebp exampleutil imagedec imageenc webpdecoder)
|
target_link_libraries(dwebp exampleutil imagedec imageenc webpdecoder)
|
||||||
install(TARGETS dwebp RUNTIME DESTINATION bin)
|
install(TARGETS dwebp RUNTIME DESTINATION bin)
|
||||||
set_property(TARGET dwebp PROPERTY INCLUDE_DIRECTORIES
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/src ${CMAKE_CURRENT_BINARY_DIR}/src)
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(WEBP_BUILD_CWEBP)
|
if(WEBP_BUILD_CWEBP)
|
||||||
@ -226,12 +220,6 @@ if(WEBP_BUILD_CWEBP)
|
|||||||
add_executable(cwebp ${CWEBP_SRCS})
|
add_executable(cwebp ${CWEBP_SRCS})
|
||||||
target_link_libraries(cwebp exampleutil imagedec webp)
|
target_link_libraries(cwebp exampleutil imagedec webp)
|
||||||
install(TARGETS cwebp RUNTIME DESTINATION bin)
|
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()
|
endif()
|
||||||
|
|
||||||
if(WEBP_BUILD_GIF2WEBP OR WEBP_BUILD_IMG2WEBP)
|
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})
|
add_library(webpmux ${WEBP_MUX_SRCS})
|
||||||
target_link_libraries(webpmux webp)
|
target_link_libraries(webpmux webp)
|
||||||
parse_version(mux/Makefile.am webpmux WEBP_MUX_SOVERSION)
|
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})
|
SOVERSION ${WEBP_MUX_SOVERSION})
|
||||||
list(APPEND INSTALLED_LIBRARIES webpmux)
|
list(APPEND INSTALLED_LIBRARIES webpmux)
|
||||||
endif()
|
endif()
|
||||||
@ -254,8 +242,6 @@ if(WEBP_BUILD_GIF2WEBP)
|
|||||||
target_link_libraries(gif2webp exampleutil imageioutil webp webpmux
|
target_link_libraries(gif2webp exampleutil imageioutil webp webpmux
|
||||||
${WEBP_DEP_GIF_LIBRARIES})
|
${WEBP_DEP_GIF_LIBRARIES})
|
||||||
install(TARGETS gif2webp RUNTIME DESTINATION bin)
|
install(TARGETS gif2webp RUNTIME DESTINATION bin)
|
||||||
set_property(TARGET gif2webp PROPERTY INCLUDE_DIRECTORIES
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/src ${CMAKE_CURRENT_BINARY_DIR}/src)
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(WEBP_BUILD_IMG2WEBP)
|
if(WEBP_BUILD_IMG2WEBP)
|
||||||
@ -266,8 +252,6 @@ if(WEBP_BUILD_IMG2WEBP)
|
|||||||
add_executable(img2webp ${IMG2WEBP_SRCS})
|
add_executable(img2webp ${IMG2WEBP_SRCS})
|
||||||
target_link_libraries(img2webp exampleutil imagedec imageioutil webp webpmux)
|
target_link_libraries(img2webp exampleutil imagedec imageioutil webp webpmux)
|
||||||
install(TARGETS img2webp RUNTIME DESTINATION bin)
|
install(TARGETS img2webp RUNTIME DESTINATION bin)
|
||||||
set_property(TARGET img2webp PROPERTY INCLUDE_DIRECTORIES
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/src ${CMAKE_CURRENT_BINARY_DIR}/src)
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (WEBP_BUILD_WEBPINFO)
|
if (WEBP_BUILD_WEBPINFO)
|
||||||
@ -278,8 +262,6 @@ if (WEBP_BUILD_WEBPINFO)
|
|||||||
add_executable(webpinfo ${WEBPINFO_SRCS})
|
add_executable(webpinfo ${WEBPINFO_SRCS})
|
||||||
target_link_libraries(webpinfo exampleutil imageioutil)
|
target_link_libraries(webpinfo exampleutil imageioutil)
|
||||||
install(TARGETS webpinfo RUNTIME DESTINATION bin)
|
install(TARGETS webpinfo RUNTIME DESTINATION bin)
|
||||||
set_property(TARGET webpinfo PROPERTY INCLUDE_DIRECTORIES
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/src ${CMAKE_CURRENT_BINARY_DIR}/src)
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(WEBP_BUILD_WEBP_JS)
|
if(WEBP_BUILD_WEBP_JS)
|
||||||
@ -287,10 +269,8 @@ if(WEBP_BUILD_WEBP_JS)
|
|||||||
add_executable(webp_js
|
add_executable(webp_js
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/extras/webp_to_sdl.c)
|
${CMAKE_CURRENT_SOURCE_DIR}/extras/webp_to_sdl.c)
|
||||||
target_link_libraries(webp_js webpdecoder SDL)
|
target_link_libraries(webp_js webpdecoder SDL)
|
||||||
set(WEBP_HAVE_SDL 1)
|
|
||||||
set_target_properties(webp_js PROPERTIES LINK_FLAGS
|
set_target_properties(webp_js PROPERTIES LINK_FLAGS
|
||||||
"-s EXPORTED_FUNCTIONS='[\"_WebpToSDL\"]' -s INVOKE_RUN=0 \
|
"-s EXPORTED_FUNCTIONS='[\"_WebpToSDL\"]' -s INVOKE_RUN=0")
|
||||||
-s EXTRA_EXPORTED_RUNTIME_METHODS='[\"cwrap\"]'")
|
|
||||||
set_target_properties(webp_js PROPERTIES OUTPUT_NAME webp)
|
set_target_properties(webp_js PROPERTIES OUTPUT_NAME webp)
|
||||||
target_compile_definitions(webp_js PUBLIC EMSCRIPTEN WEBP_HAVE_SDL)
|
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)
|
target_link_libraries(webp_wasm webpdecoder SDL)
|
||||||
set_target_properties(webp_wasm PROPERTIES LINK_FLAGS
|
set_target_properties(webp_wasm PROPERTIES LINK_FLAGS
|
||||||
"-s WASM=1 -s 'BINARYEN_METHOD=\"native-wasm\"' \
|
"-s WASM=1 -s 'BINARYEN_METHOD=\"native-wasm\"' \
|
||||||
-s EXPORTED_FUNCTIONS='[\"_WebpToSDL\"]' -s INVOKE_RUN=0 \
|
-s EXPORTED_FUNCTIONS='[\"_WebpToSDL\"]' -s INVOKE_RUN=0")
|
||||||
-s EXTRA_EXPORTED_RUNTIME_METHODS='[\"cwrap\"]'")
|
|
||||||
target_compile_definitions(webp_wasm PUBLIC EMSCRIPTEN WEBP_HAVE_SDL)
|
target_compile_definitions(webp_wasm PUBLIC EMSCRIPTEN WEBP_HAVE_SDL)
|
||||||
|
|
||||||
target_compile_definitions(webpdecoder PUBLIC EMSCRIPTEN)
|
target_compile_definitions(webpdecoder PUBLIC EMSCRIPTEN)
|
||||||
endif()
|
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 the different headers and libraries.
|
||||||
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/webp/decode.h
|
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/webp/decode.h
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/src/webp/demux.h
|
${CMAKE_CURRENT_SOURCE_DIR}/src/webp/demux.h
|
||||||
@ -331,7 +302,7 @@ install(TARGETS ${INSTALLED_LIBRARIES}
|
|||||||
include(CMakePackageConfigHelpers)
|
include(CMakePackageConfigHelpers)
|
||||||
write_basic_package_version_file(
|
write_basic_package_version_file(
|
||||||
"${CMAKE_CURRENT_BINARY_DIR}/WebPConfigVersion.cmake"
|
"${CMAKE_CURRENT_BINARY_DIR}/WebPConfigVersion.cmake"
|
||||||
VERSION ${PACKAGE_VERSION}
|
VERSION ${WEBP_VERSION}
|
||||||
COMPATIBILITY AnyNewerVersion
|
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
|
20a7fea0 extras/Makefile.am: fix libwebpextras.la reference
|
||||||
415f3ffe update ChangeLog (tag: v0.6.0-rc3)
|
415f3ffe update ChangeLog (tag: v0.6.0-rc3)
|
||||||
3c6d1224 update NEWS
|
3c6d1224 update NEWS
|
||||||
ee4a4141 update AUTHORS
|
ee4a4141 update AUTHORS
|
||||||
32ed856f Fix "all|no frames are keyframes" settings.
|
32ed856f Fix "all|no frames are keyframes" settings.
|
||||||
1c3190b6 Merge "Fix "all|no frames are keyframes" settings."
|
|
||||||
f4dc56fd disable GradientUnfilter_NEON
|
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
|
0d8e0588 img2webp: treat -loop as a no-op w/single images
|
||||||
b0450139 ReadImage(): restore size reporting
|
b0450139 ReadImage(): restore size reporting
|
||||||
0ad3b4ef update ChangeLog (tag: v0.6.0-rc2)
|
0ad3b4ef update ChangeLog (tag: v0.6.0-rc2)
|
||||||
|
35
Makefile.vc
35
Makefile.vc
@ -29,7 +29,7 @@ PLATFORM_LDFLAGS = /SAFESEH
|
|||||||
NOLOGO = /nologo
|
NOLOGO = /nologo
|
||||||
CCNODBG = cl.exe $(NOLOGO) /O2 /DNDEBUG
|
CCNODBG = cl.exe $(NOLOGO) /O2 /DNDEBUG
|
||||||
CCDEBUG = cl.exe $(NOLOGO) /Od /Gm /Zi /D_DEBUG /RTC1
|
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
|
CFLAGS = $(CFLAGS) /DWIN32 /D_CRT_SECURE_NO_WARNINGS /DWIN32_LEAN_AND_MEAN
|
||||||
LDFLAGS = /LARGEADDRESSAWARE /MANIFEST /NXCOMPAT /DYNAMICBASE
|
LDFLAGS = /LARGEADDRESSAWARE /MANIFEST /NXCOMPAT /DYNAMICBASE
|
||||||
LDFLAGS = $(LDFLAGS) $(PLATFORM_LDFLAGS)
|
LDFLAGS = $(LDFLAGS) $(PLATFORM_LDFLAGS)
|
||||||
@ -155,7 +155,6 @@ CFGSET = TRUE
|
|||||||
!MESSAGE - all - build (de)mux-based targets for CFG
|
!MESSAGE - all - build (de)mux-based targets for CFG
|
||||||
!MESSAGE - gif2webp - requires libgif & >= VS2013
|
!MESSAGE - gif2webp - requires libgif & >= VS2013
|
||||||
!MESSAGE - anim_diff - requires libgif & >= VS2013
|
!MESSAGE - anim_diff - requires libgif & >= VS2013
|
||||||
!MESSAGE - anim_dump
|
|
||||||
!MESSAGE
|
!MESSAGE
|
||||||
!MESSAGE RTLIBCFG controls the runtime library linkage - 'static' or 'dynamic'.
|
!MESSAGE RTLIBCFG controls the runtime library linkage - 'static' or 'dynamic'.
|
||||||
!MESSAGE 'legacy' will produce a Windows 2000 compatible library.
|
!MESSAGE 'legacy' will produce a Windows 2000 compatible library.
|
||||||
@ -227,15 +226,16 @@ DSP_DEC_OBJS = \
|
|||||||
$(DIROBJ)\dsp\upsampling_msa.obj \
|
$(DIROBJ)\dsp\upsampling_msa.obj \
|
||||||
$(DIROBJ)\dsp\upsampling_neon.obj \
|
$(DIROBJ)\dsp\upsampling_neon.obj \
|
||||||
$(DIROBJ)\dsp\upsampling_sse2.obj \
|
$(DIROBJ)\dsp\upsampling_sse2.obj \
|
||||||
$(DIROBJ)\dsp\upsampling_sse41.obj \
|
|
||||||
$(DIROBJ)\dsp\yuv.obj \
|
$(DIROBJ)\dsp\yuv.obj \
|
||||||
$(DIROBJ)\dsp\yuv_mips32.obj \
|
$(DIROBJ)\dsp\yuv_mips32.obj \
|
||||||
$(DIROBJ)\dsp\yuv_mips_dsp_r2.obj \
|
$(DIROBJ)\dsp\yuv_mips_dsp_r2.obj \
|
||||||
$(DIROBJ)\dsp\yuv_neon.obj \
|
$(DIROBJ)\dsp\yuv_neon.obj \
|
||||||
$(DIROBJ)\dsp\yuv_sse2.obj \
|
$(DIROBJ)\dsp\yuv_sse2.obj \
|
||||||
$(DIROBJ)\dsp\yuv_sse41.obj \
|
|
||||||
|
|
||||||
DSP_ENC_OBJS = \
|
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.obj \
|
||||||
$(DIROBJ)\dsp\cost_mips32.obj \
|
$(DIROBJ)\dsp\cost_mips32.obj \
|
||||||
$(DIROBJ)\dsp\cost_mips_dsp_r2.obj \
|
$(DIROBJ)\dsp\cost_mips_dsp_r2.obj \
|
||||||
@ -287,6 +287,7 @@ ENC_OBJS = \
|
|||||||
$(DIROBJ)\enc\backward_references_enc.obj \
|
$(DIROBJ)\enc\backward_references_enc.obj \
|
||||||
$(DIROBJ)\enc\config_enc.obj \
|
$(DIROBJ)\enc\config_enc.obj \
|
||||||
$(DIROBJ)\enc\cost_enc.obj \
|
$(DIROBJ)\enc\cost_enc.obj \
|
||||||
|
$(DIROBJ)\enc\delta_palettization_enc.obj \
|
||||||
$(DIROBJ)\enc\filter_enc.obj \
|
$(DIROBJ)\enc\filter_enc.obj \
|
||||||
$(DIROBJ)\enc\frame_enc.obj \
|
$(DIROBJ)\enc\frame_enc.obj \
|
||||||
$(DIROBJ)\enc\histogram_enc.obj \
|
$(DIROBJ)\enc\histogram_enc.obj \
|
||||||
@ -357,22 +358,15 @@ all: ex $(EXTRA_EXAMPLES)
|
|||||||
# C99 support which is only available from VS2013 onward.
|
# C99 support which is only available from VS2013 onward.
|
||||||
gif2webp: $(DIRBIN)\gif2webp.exe
|
gif2webp: $(DIRBIN)\gif2webp.exe
|
||||||
anim_diff: $(DIRBIN)\anim_diff.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: $(DIROBJ)\examples\anim_diff.obj $(EX_ANIM_UTIL_OBJS)
|
||||||
$(DIRBIN)\anim_diff.exe: $(EX_UTIL_OBJS) $(IMAGEIO_UTIL_OBJS)
|
$(DIRBIN)\anim_diff.exe: $(EX_UTIL_OBJS) $(IMAGEIO_UTIL_OBJS)
|
||||||
$(DIRBIN)\anim_diff.exe: $(EX_GIF_DEC_OBJS) $(LIBWEBPDEMUX) $(LIBWEBP)
|
$(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: $(DIROBJ)\examples\cwebp.obj $(IMAGEIO_DEC_OBJS)
|
||||||
$(DIRBIN)\cwebp.exe: $(IMAGEIO_UTIL_OBJS)
|
$(DIRBIN)\cwebp.exe: $(IMAGEIO_UTIL_OBJS)
|
||||||
$(DIRBIN)\cwebp.exe: $(LIBWEBPDEMUX)
|
|
||||||
$(DIRBIN)\dwebp.exe: $(DIROBJ)\examples\dwebp.obj $(IMAGEIO_DEC_OBJS)
|
$(DIRBIN)\dwebp.exe: $(DIROBJ)\examples\dwebp.obj $(IMAGEIO_DEC_OBJS)
|
||||||
$(DIRBIN)\dwebp.exe: $(IMAGEIO_ENC_OBJS)
|
$(DIRBIN)\dwebp.exe: $(IMAGEIO_ENC_OBJS)
|
||||||
$(DIRBIN)\dwebp.exe: $(IMAGEIO_UTIL_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: $(DIROBJ)\examples\gif2webp.obj $(EX_GIF_DEC_OBJS)
|
||||||
$(DIRBIN)\gif2webp.exe: $(EX_UTIL_OBJS) $(IMAGEIO_UTIL_OBJS) $(LIBWEBPMUX)
|
$(DIRBIN)\gif2webp.exe: $(EX_UTIL_OBJS) $(IMAGEIO_UTIL_OBJS) $(LIBWEBPMUX)
|
||||||
$(DIRBIN)\gif2webp.exe: $(LIBWEBP)
|
$(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)\webpmux.exe: $(EX_UTIL_OBJS) $(IMAGEIO_UTIL_OBJS) $(LIBWEBP)
|
||||||
$(DIRBIN)\img2webp.exe: $(DIROBJ)\examples\img2webp.obj $(LIBWEBPMUX)
|
$(DIRBIN)\img2webp.exe: $(DIROBJ)\examples\img2webp.obj $(LIBWEBPMUX)
|
||||||
$(DIRBIN)\img2webp.exe: $(IMAGEIO_DEC_OBJS)
|
$(DIRBIN)\img2webp.exe: $(IMAGEIO_DEC_OBJS)
|
||||||
$(DIRBIN)\img2webp.exe: $(EX_UTIL_OBJS) $(IMAGEIO_UTIL_OBJS)
|
$(DIRBIN)\img2webp.exe: $(EX_UTIL_OBJS) $(IMAGEIO_UTIL_OBJS) $(LIBWEBP)
|
||||||
$(DIRBIN)\img2webp.exe: $(LIBWEBPDEMUX) $(LIBWEBP)
|
|
||||||
$(DIRBIN)\get_disto.exe: $(DIROBJ)\extras\get_disto.obj
|
$(DIRBIN)\get_disto.exe: $(DIROBJ)\extras\get_disto.obj
|
||||||
$(DIRBIN)\get_disto.exe: $(IMAGEIO_DEC_OBJS) $(IMAGEIO_UTIL_OBJS)
|
$(DIRBIN)\get_disto.exe: $(IMAGEIO_DEC_OBJS) $(IMAGEIO_UTIL_OBJS) $(LIBWEBP)
|
||||||
$(DIRBIN)\get_disto.exe: $(LIBWEBPDEMUX) $(LIBWEBP)
|
|
||||||
$(DIRBIN)\webp_quality.exe: $(DIROBJ)\extras\webp_quality.obj
|
$(DIRBIN)\webp_quality.exe: $(DIROBJ)\extras\webp_quality.obj
|
||||||
$(DIRBIN)\webp_quality.exe: $(IMAGEIO_UTIL_OBJS)
|
$(DIRBIN)\webp_quality.exe: $(IMAGEIO_UTIL_OBJS)
|
||||||
$(DIRBIN)\webp_quality.exe: $(EXTRAS_OBJS) $(LIBWEBP)
|
$(DIRBIN)\webp_quality.exe: $(EXTRAS_OBJS) $(LIBWEBP)
|
||||||
$(DIRBIN)\webpinfo.exe: $(DIROBJ)\examples\webpinfo.obj
|
$(DIRBIN)\webpinfo.exe: $(DIROBJ)\examples\webpinfo.obj
|
||||||
$(DIRBIN)\webpinfo.exe: $(IMAGEIO_DEC_OBJS)
|
$(DIRBIN)\webpinfo.exe: $(IMAGEIO_DEC_OBJS)
|
||||||
$(DIRBIN)\webpinfo.exe: $(EX_UTIL_OBJS) $(IMAGEIO_UTIL_OBJS)
|
$(DIRBIN)\webpinfo.exe: $(EX_UTIL_OBJS) $(IMAGEIO_UTIL_OBJS) $(LIBWEBP)
|
||||||
$(DIRBIN)\webpinfo.exe: $(LIBWEBPDEMUX) $(LIBWEBP)
|
|
||||||
|
|
||||||
$(OUT_EXAMPLES): $(EX_UTIL_OBJS) $(LIBWEBP)
|
$(OUT_EXAMPLES): $(EX_UTIL_OBJS) $(LIBWEBP)
|
||||||
$(EX_UTIL_OBJS) $(IMAGEIO_UTIL_OBJS): $(OUTPUT_DIRS)
|
$(EX_UTIL_OBJS) $(IMAGEIO_UTIL_OBJS): $(OUTPUT_DIRS)
|
||||||
$(IMAGEIO_DEC_OBJS) $(IMAGEIO_ENC_OBJS) $(EXTRAS_OBJS): $(OUTPUT_DIRS)
|
$(IMAGEIO_DEC_OBJS) $(IMAGEIO_ENC_OBJS) $(EXTRAS_OBJS): $(OUTPUT_DIRS)
|
||||||
!ENDIF # ARCH == ARM
|
!ENDIF # ARCH == ARM
|
||||||
|
|
||||||
|
experimental:
|
||||||
|
$(MAKE) /f Makefile.vc \
|
||||||
|
CFG=$(CFG) \
|
||||||
|
CFLAGS="$(CFLAGS) /DWEBP_EXPERIMENTAL_FEATURES" /$(MAKEFLAGS)
|
||||||
|
|
||||||
$(LIBWEBPDECODER): $(LIBWEBPDECODER_OBJS)
|
$(LIBWEBPDECODER): $(LIBWEBPDECODER_OBJS)
|
||||||
$(LIBWEBP): $(LIBWEBP_OBJS)
|
$(LIBWEBP): $(LIBWEBP_OBJS)
|
||||||
$(LIBWEBPMUX): $(LIBWEBPMUX_OBJS)
|
$(LIBWEBPMUX): $(LIBWEBPMUX_OBJS)
|
||||||
@ -448,7 +444,7 @@ $(OUTPUT_DIRS):
|
|||||||
$(DIROBJ)\$(DLLINC):
|
$(DIROBJ)\$(DLLINC):
|
||||||
@echo #ifndef WEBP_DLL_H_ > $@
|
@echo #ifndef WEBP_DLL_H_ > $@
|
||||||
@echo #define 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_ */ >> $@
|
@echo #endif /* WEBP_DLL_H_ */ >> $@
|
||||||
|
|
||||||
.SUFFIXES: .c .obj .res .exe
|
.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
|
$(DIROBJ)\examples\anim_diff.obj: examples\anim_diff.c
|
||||||
$(CC) $(CFLAGS) /DWEBP_HAVE_GIF /Fd$(LIBWEBP_PDBNAME) \
|
$(CC) $(CFLAGS) /DWEBP_HAVE_GIF /Fd$(LIBWEBP_PDBNAME) \
|
||||||
/Fo$(DIROBJ)\examples\ examples\$(@B).c
|
/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
|
$(DIROBJ)\examples\anim_util.obj: examples\anim_util.c
|
||||||
$(CC) $(CFLAGS) /DWEBP_HAVE_GIF /Fd$(LIBWEBP_PDBNAME) \
|
$(CC) $(CFLAGS) /DWEBP_HAVE_GIF /Fd$(LIBWEBP_PDBNAME) \
|
||||||
/Fo$(DIROBJ)\examples\ examples\$(@B).c
|
/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
|
- 1/26/2017: version 0.6.0
|
||||||
* lossless performance and compression improvements
|
* lossless performance and compression improvements
|
||||||
* miscellaneous performance improvements (SSE2, NEON, MSA)
|
* miscellaneous performance improvements (SSE2, NEON, MSA)
|
||||||
|
31
README
31
README
@ -4,7 +4,7 @@
|
|||||||
\__\__/\____/\_____/__/ ____ ___
|
\__\__/\____/\_____/__/ ____ ___
|
||||||
/ _/ / \ \ / _ \/ _/
|
/ _/ / \ \ / _ \/ _/
|
||||||
/ \_/ / / \ \ __/ \__
|
/ \_/ / / \ \ __/ \__
|
||||||
\____/____/\_____/_____/____/v1.0.0
|
\____/____/\_____/_____/____/v0.6.0
|
||||||
|
|
||||||
Description:
|
Description:
|
||||||
============
|
============
|
||||||
@ -113,8 +113,8 @@ make install
|
|||||||
|
|
||||||
CMake:
|
CMake:
|
||||||
------
|
------
|
||||||
With CMake, you can compile libwebp, cwebp, dwebp, gif2web, img2webp, webpinfo
|
With CMake, you can compile libwebp, cwebp, dwebp, gif2web, img2webp and the
|
||||||
and the JS bindings.
|
JS bindings.
|
||||||
|
|
||||||
Prerequisites:
|
Prerequisites:
|
||||||
A compiler (e.g., gcc with autotools) and CMake.
|
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
|
-quiet ....... quiet mode, don't print anything
|
||||||
-noasm ....... disable all assembly optimizations
|
-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:
|
Visualization tool:
|
||||||
===================
|
===================
|
||||||
|
|
||||||
@ -458,7 +441,6 @@ File-level options (only used at the start of compression):
|
|||||||
-mixed ............... use mixed lossy/lossless automatic mode
|
-mixed ............... use mixed lossy/lossless automatic mode
|
||||||
-v ................... verbose mode
|
-v ................... verbose mode
|
||||||
-h ................... this help
|
-h ................... this help
|
||||||
-version ............. print version number and exit
|
|
||||||
|
|
||||||
Per-frame options (only used for subsequent images input):
|
Per-frame options (only used for subsequent images input):
|
||||||
-d <int> ............. frame duration in ms (default: 100)
|
-d <int> ............. frame duration in ms (default: 100)
|
||||||
@ -495,8 +477,6 @@ Options:
|
|||||||
-metadata <string> ..... comma separated list of metadata to
|
-metadata <string> ..... comma separated list of metadata to
|
||||||
copy from the input to the output if present
|
copy from the input to the output if present
|
||||||
Valid values: all, none, icc, xmp (default)
|
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
|
-mt .................... use multi-threading if available
|
||||||
|
|
||||||
-version ............... print version number and exit
|
-version ............... print version number and exit
|
||||||
@ -525,11 +505,6 @@ Options:
|
|||||||
-min_psnr <float> ... minimum per-frame PSNR
|
-min_psnr <float> ... minimum per-frame PSNR
|
||||||
-raw_comparison ..... if this flag is not used, RGB is
|
-raw_comparison ..... if this flag is not used, RGB is
|
||||||
premultiplied before comparison
|
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:
|
Building:
|
||||||
---------
|
---------
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
__ __ ____ ____ ____ __ __ _ __ __
|
__ __ ____ ____ ____ __ __ _ __ __
|
||||||
/ \\/ \/ _ \/ _ \/ _ \/ \ \/ \___/_ / _\
|
/ \\/ \/ _ \/ _ \/ _ \/ \ \/ \___/_ / _\
|
||||||
\ / __/ _ \ __/ / / (_/ /__
|
\ / __/ _ \ __/ / / (_/ /__
|
||||||
\__\__/\_____/_____/__/ \__//_/\_____/__/___/v1.0.0
|
\__\__/\_____/_____/__/ \__//_/\_____/__/___/v0.4.0
|
||||||
|
|
||||||
|
|
||||||
Description:
|
Description:
|
||||||
@ -33,7 +33,6 @@ Usage: webpmux -get GET_OPTIONS INPUT -o OUTPUT
|
|||||||
webpmux -info INPUT
|
webpmux -info INPUT
|
||||||
webpmux [-h|-help]
|
webpmux [-h|-help]
|
||||||
webpmux -version
|
webpmux -version
|
||||||
webpmux argument_file_name
|
|
||||||
|
|
||||||
GET_OPTIONS:
|
GET_OPTIONS:
|
||||||
Extract relevant data:
|
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
|
Note: The nature of EXIF, XMP and ICC data is not checked and is assumed to be
|
||||||
valid.
|
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:
|
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
|
- that's it! Upon completion, you should have the webp.js and
|
||||||
webp.js.mem files generated.
|
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
|
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
|
bitstream into a canvas. See webp_js/index.html for a simple usage sample.
|
||||||
(see below for instructions).
|
|
||||||
|
|
||||||
Demo HTML page:
|
Demo HTML page:
|
||||||
===============
|
===============
|
||||||
|
14
build.gradle
14
build.gradle
@ -82,14 +82,12 @@ model {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Check for NEON usage.
|
// Check for NEON usage.
|
||||||
if (getTargetPlatform() == "arm") {
|
if (getTargetPlatform() == "arm" || getTargetPlatform() == "arm64") {
|
||||||
NEON = "c.neon"
|
NEON = "c.neon"
|
||||||
cCompiler.define "HAVE_CPU_FEATURES_H"
|
cCompiler.define "HAVE_CPU_FEATURES_H"
|
||||||
} else {
|
} else {
|
||||||
NEON = "c"
|
NEON = "c"
|
||||||
}
|
}
|
||||||
|
|
||||||
cCompiler.args "-I" + file(".").absolutePath
|
|
||||||
}
|
}
|
||||||
// Link to pthread for shared libraries.
|
// Link to pthread for shared libraries.
|
||||||
withType(SharedLibraryBinarySpec) {
|
withType(SharedLibraryBinarySpec) {
|
||||||
@ -122,6 +120,9 @@ model {
|
|||||||
include "alpha_processing_neon.$NEON"
|
include "alpha_processing_neon.$NEON"
|
||||||
include "alpha_processing_sse2.c"
|
include "alpha_processing_sse2.c"
|
||||||
include "alpha_processing_sse41.c"
|
include "alpha_processing_sse41.c"
|
||||||
|
include "argb.c"
|
||||||
|
include "argb_mips_dsp_r2.c"
|
||||||
|
include "argb_sse2.c"
|
||||||
include "cpu.c"
|
include "cpu.c"
|
||||||
include "dec.c"
|
include "dec.c"
|
||||||
include "dec_clip_tables.c"
|
include "dec_clip_tables.c"
|
||||||
@ -152,13 +153,11 @@ model {
|
|||||||
include "upsampling_msa.c"
|
include "upsampling_msa.c"
|
||||||
include "upsampling_neon.$NEON"
|
include "upsampling_neon.$NEON"
|
||||||
include "upsampling_sse2.c"
|
include "upsampling_sse2.c"
|
||||||
include "upsampling_sse41.c"
|
|
||||||
include "yuv.c"
|
include "yuv.c"
|
||||||
include "yuv_mips32.c"
|
include "yuv_mips32.c"
|
||||||
include "yuv_mips_dsp_r2.c"
|
include "yuv_mips_dsp_r2.c"
|
||||||
include "yuv_neon.$NEON"
|
include "yuv_neon.$NEON"
|
||||||
include "yuv_sse2.c"
|
include "yuv_sse2.c"
|
||||||
include "yuv_sse41.c"
|
|
||||||
srcDir "src/utils"
|
srcDir "src/utils"
|
||||||
include "bit_reader_utils.c"
|
include "bit_reader_utils.c"
|
||||||
include "color_cache_utils.c"
|
include "color_cache_utils.c"
|
||||||
@ -198,6 +197,7 @@ model {
|
|||||||
include "backward_references_enc.c"
|
include "backward_references_enc.c"
|
||||||
include "config_enc.c"
|
include "config_enc.c"
|
||||||
include "cost_enc.c"
|
include "cost_enc.c"
|
||||||
|
include "delta_palettization_enc.c"
|
||||||
include "filter_enc.c"
|
include "filter_enc.c"
|
||||||
include "frame_enc.c"
|
include "frame_enc.c"
|
||||||
include "histogram_enc.c"
|
include "histogram_enc.c"
|
||||||
@ -289,7 +289,6 @@ model {
|
|||||||
imagedec(NativeLibrarySpec) {
|
imagedec(NativeLibrarySpec) {
|
||||||
binaries {
|
binaries {
|
||||||
all {
|
all {
|
||||||
lib library: "webpdemux", linkage: "static"
|
|
||||||
lib library: "webp", linkage: "static"
|
lib library: "webp", linkage: "static"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -332,7 +331,6 @@ model {
|
|||||||
lib library: "example_util", linkage: "static"
|
lib library: "example_util", linkage: "static"
|
||||||
lib library: "imagedec", linkage: "static"
|
lib library: "imagedec", linkage: "static"
|
||||||
lib library: "imageio_util", linkage: "static"
|
lib library: "imageio_util", linkage: "static"
|
||||||
lib library: "webpdemux", linkage: "static"
|
|
||||||
lib library: "webp", linkage: "static"
|
lib library: "webp", linkage: "static"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -353,7 +351,6 @@ model {
|
|||||||
lib library: "imagedec", linkage: "static"
|
lib library: "imagedec", linkage: "static"
|
||||||
lib library: "imageenc", linkage: "static"
|
lib library: "imageenc", linkage: "static"
|
||||||
lib library: "imageio_util", linkage: "static"
|
lib library: "imageio_util", linkage: "static"
|
||||||
lib library: "webpdemux", linkage: "static"
|
|
||||||
lib library: "webp"
|
lib library: "webp"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -393,7 +390,6 @@ model {
|
|||||||
lib library: "imagedec", linkage: "static"
|
lib library: "imagedec", linkage: "static"
|
||||||
lib library: "imageio_util", linkage: "static"
|
lib library: "imageio_util", linkage: "static"
|
||||||
lib library: "webpmux", linkage: "static"
|
lib library: "webpmux", linkage: "static"
|
||||||
lib library: "webpdemux", linkage: "static"
|
|
||||||
lib library: "webp"
|
lib library: "webp"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -70,43 +70,18 @@ foreach(I_LIB PNG JPEG TIFF)
|
|||||||
set(WEBP_HAVE_${I_LIB} ${${I_LIB}_FOUND})
|
set(WEBP_HAVE_${I_LIB} ${${I_LIB}_FOUND})
|
||||||
if(${I_LIB}_FOUND)
|
if(${I_LIB}_FOUND)
|
||||||
list(APPEND WEBP_DEP_IMG_LIBRARIES ${${I_LIB}_LIBRARIES})
|
list(APPEND WEBP_DEP_IMG_LIBRARIES ${${I_LIB}_LIBRARIES})
|
||||||
list(APPEND WEBP_DEP_IMG_INCLUDE_DIRS
|
list(APPEND WEBP_DEP_IMG_INCLUDE_DIRS ${${I_LIB}_INCLUDE_DIRS})
|
||||||
${${I_LIB}_INCLUDE_DIR} ${${I_LIB}_INCLUDE_DIRS})
|
|
||||||
endif()
|
endif()
|
||||||
endforeach()
|
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.
|
# GIF detection, gifdec isn't part of the imageio lib.
|
||||||
include(CMakePushCheckState)
|
|
||||||
set(WEBP_DEP_GIF_LIBRARIES)
|
set(WEBP_DEP_GIF_LIBRARIES)
|
||||||
set(WEBP_DEP_GIF_INCLUDE_DIRS)
|
set(WEBP_DEP_GIF_INCLUDE_DIRS)
|
||||||
find_package(GIF)
|
find_package(GIF)
|
||||||
set(WEBP_HAVE_GIF ${GIF_FOUND})
|
set(WEBP_HAVE_GIF ${GIF_FOUND})
|
||||||
if(GIF_FOUND)
|
if(GIF_FOUND)
|
||||||
# GIF find_package only locates the header and library, it doesn't fail
|
list(APPEND WEBP_DEP_GIF_LIBRARIES ${GIF_LIBRARIES})
|
||||||
# compile tests when detecting the version, but falls back to 3 (as of at
|
list(APPEND WEBP_DEP_GIF_INCLUDE_DIRS ${GIF_INCLUDE_DIR})
|
||||||
# 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()
|
endif()
|
||||||
|
|
||||||
## Check for specific headers.
|
## Check for specific headers.
|
||||||
@ -164,3 +139,13 @@ strip_bracket(PACKAGE_URL)
|
|||||||
set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}")
|
set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}")
|
||||||
set(PACKAGE_TARNAME ${PACKAGE_NAME})
|
set(PACKAGE_TARNAME ${PACKAGE_NAME})
|
||||||
set(VERSION ${PACKAGE_VERSION})
|
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 */
|
/* Set to 1 if __builtin_bswap64 is available */
|
||||||
#cmakedefine HAVE_BUILTIN_BSWAP64 1
|
#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. */
|
/* Define to 1 if you have the <dlfcn.h> header file. */
|
||||||
#cmakedefine HAVE_DLFCN_H 1
|
#cmakedefine HAVE_DLFCN_H 1
|
||||||
|
|
||||||
@ -103,6 +100,9 @@
|
|||||||
/* Version number of package */
|
/* Version number of package */
|
||||||
#cmakedefine VERSION "@VERSION@"
|
#cmakedefine VERSION "@VERSION@"
|
||||||
|
|
||||||
|
/* Enable experimental code */
|
||||||
|
#cmakedefine WEBP_EXPERIMENTAL_FEATURES 1
|
||||||
|
|
||||||
/* Set to 1 if AVX2 is supported */
|
/* Set to 1 if AVX2 is supported */
|
||||||
#cmakedefine WEBP_HAVE_AVX2 1
|
#cmakedefine WEBP_HAVE_AVX2 1
|
||||||
|
|
||||||
@ -115,19 +115,9 @@
|
|||||||
/* Set to 1 if JPEG library is installed */
|
/* Set to 1 if JPEG library is installed */
|
||||||
#cmakedefine WEBP_HAVE_JPEG 1
|
#cmakedefine WEBP_HAVE_JPEG 1
|
||||||
|
|
||||||
/* Set to 1 if 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 */
|
/* Set to 1 if PNG library is installed */
|
||||||
#cmakedefine WEBP_HAVE_PNG 1
|
#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 */
|
/* Set to 1 if SSE2 is supported */
|
||||||
#cmakedefine WEBP_HAVE_SSE2 1
|
#cmakedefine WEBP_HAVE_SSE2 1
|
||||||
|
|
||||||
@ -137,9 +127,6 @@
|
|||||||
/* Set to 1 if TIFF library is installed */
|
/* Set to 1 if TIFF library is installed */
|
||||||
#cmakedefine WEBP_HAVE_TIFF 1
|
#cmakedefine WEBP_HAVE_TIFF 1
|
||||||
|
|
||||||
/* Enable near lossless encoding */
|
|
||||||
#cmakedefine WEBP_NEAR_LOSSLESS 1
|
|
||||||
|
|
||||||
/* Undefine this to disable thread support. */
|
/* Undefine this to disable thread support. */
|
||||||
#cmakedefine WEBP_USE_THREAD 1
|
#cmakedefine WEBP_USE_THREAD 1
|
||||||
|
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
## Check for SIMD extensions.
|
## Check for SIMD extensions.
|
||||||
include(CMakePushCheckState)
|
|
||||||
|
|
||||||
function(webp_check_compiler_flag WEBP_SIMD_FLAG ENABLE_SIMD)
|
function(webp_check_compiler_flag WEBP_SIMD_FLAG ENABLE_SIMD)
|
||||||
if(NOT ENABLE_SIMD)
|
if(NOT ENABLE_SIMD)
|
||||||
@ -8,8 +7,6 @@ function(webp_check_compiler_flag WEBP_SIMD_FLAG ENABLE_SIMD)
|
|||||||
return()
|
return()
|
||||||
endif()
|
endif()
|
||||||
unset(WEBP_HAVE_FLAG_${WEBP_SIMD_FLAG} CACHE)
|
unset(WEBP_HAVE_FLAG_${WEBP_SIMD_FLAG} CACHE)
|
||||||
cmake_push_check_state()
|
|
||||||
set(CMAKE_REQUIRED_INCLUDES ${CMAKE_CURRENT_SOURCE_DIR})
|
|
||||||
check_c_source_compiles("
|
check_c_source_compiles("
|
||||||
#include \"${CMAKE_CURRENT_LIST_DIR}/../src/dsp/dsp.h\"
|
#include \"${CMAKE_CURRENT_LIST_DIR}/../src/dsp/dsp.h\"
|
||||||
int main(void) {
|
int main(void) {
|
||||||
@ -20,7 +17,6 @@ function(webp_check_compiler_flag WEBP_SIMD_FLAG ENABLE_SIMD)
|
|||||||
}
|
}
|
||||||
" WEBP_HAVE_FLAG_${WEBP_SIMD_FLAG}
|
" WEBP_HAVE_FLAG_${WEBP_SIMD_FLAG}
|
||||||
)
|
)
|
||||||
cmake_pop_check_state()
|
|
||||||
if(WEBP_HAVE_FLAG_${WEBP_SIMD_FLAG})
|
if(WEBP_HAVE_FLAG_${WEBP_SIMD_FLAG})
|
||||||
set(WEBP_HAVE_${WEBP_SIMD_FLAG} 1 PARENT_SCOPE)
|
set(WEBP_HAVE_${WEBP_SIMD_FLAG} 1 PARENT_SCOPE)
|
||||||
else()
|
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
|
# First try with no extra flag added as the compiler might have default flags
|
||||||
# (especially on Android).
|
# (especially on Android).
|
||||||
unset(WEBP_HAVE_${WEBP_SIMD_FLAG} CACHE)
|
unset(WEBP_HAVE_${WEBP_SIMD_FLAG} CACHE)
|
||||||
cmake_push_check_state()
|
|
||||||
set(CMAKE_REQUIRED_FLAGS)
|
set(CMAKE_REQUIRED_FLAGS)
|
||||||
webp_check_compiler_flag(${WEBP_SIMD_FLAG} ${WEBP_ENABLE_SIMD})
|
webp_check_compiler_flag(${WEBP_SIMD_FLAG} ${WEBP_ENABLE_SIMD})
|
||||||
if(NOT WEBP_HAVE_${WEBP_SIMD_FLAG})
|
if(NOT WEBP_HAVE_${WEBP_SIMD_FLAG})
|
||||||
@ -90,8 +85,11 @@ foreach(I_SIMD RANGE ${WEBP_SIMD_FLAGS_RANGE})
|
|||||||
foreach(FILE ${SIMD_FILES})
|
foreach(FILE ${SIMD_FILES})
|
||||||
list(APPEND WEBP_SIMD_FILES_NOT_TO_INCLUDE ${FILE})
|
list(APPEND WEBP_SIMD_FILES_NOT_TO_INCLUDE ${FILE})
|
||||||
endforeach()
|
endforeach()
|
||||||
# Explicitly disable SIMD.
|
# Explicitly disable SIMD. Avoid this with WASM to avoid an ICE with clang:
|
||||||
if(SIMD_DISABLE_FLAGS)
|
# 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)
|
list(GET SIMD_DISABLE_FLAGS ${I_SIMD} SIMD_COMPILE_FLAG)
|
||||||
include(CheckCCompilerFlag)
|
include(CheckCCompilerFlag)
|
||||||
if(SIMD_COMPILE_FLAG)
|
if(SIMD_COMPILE_FLAG)
|
||||||
@ -106,12 +104,11 @@ foreach(I_SIMD RANGE ${WEBP_SIMD_FLAGS_RANGE})
|
|||||||
set(COMMON_PATTERNS)
|
set(COMMON_PATTERNS)
|
||||||
endif()
|
endif()
|
||||||
set(CMAKE_REQUIRED_DEFINITIONS ${SIMD_COMPILE_FLAG})
|
set(CMAKE_REQUIRED_DEFINITIONS ${SIMD_COMPILE_FLAG})
|
||||||
check_c_source_compiles("int main(void) {return 0;}"
|
check_c_source_compiles("int main(void) {return 0;}" FLAG2
|
||||||
FLAG_${SIMD_COMPILE_FLAG}
|
|
||||||
FAIL_REGEX "warning: argument unused during compilation:"
|
FAIL_REGEX "warning: argument unused during compilation:"
|
||||||
${COMMON_PATTERNS}
|
${COMMON_PATTERNS}
|
||||||
)
|
)
|
||||||
if(NOT FLAG_${SIMD_COMPILE_FLAG})
|
if(NOT FLAG2)
|
||||||
unset(HAS_COMPILE_FLAG CACHE)
|
unset(HAS_COMPILE_FLAG CACHE)
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
@ -121,5 +118,14 @@ foreach(I_SIMD RANGE ${WEBP_SIMD_FLAGS_RANGE})
|
|||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
cmake_pop_check_state()
|
|
||||||
endforeach()
|
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()
|
||||||
|
99
configure.ac
99
configure.ac
@ -1,4 +1,4 @@
|
|||||||
AC_INIT([libwebp], [1.0.0],
|
AC_INIT([libwebp], [0.6.0],
|
||||||
[https://bugs.chromium.org/p/webp],,
|
[https://bugs.chromium.org/p/webp],,
|
||||||
[http://developers.google.com/speed/webp])
|
[http://developers.google.com/speed/webp])
|
||||||
AC_CANONICAL_HOST
|
AC_CANONICAL_HOST
|
||||||
@ -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], [-Wparentheses-equality])
|
||||||
TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wshadow])
|
TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wshadow])
|
||||||
TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wshorten-64-to-32])
|
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], [-Wunreachable-code])
|
||||||
TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wunused-but-set-variable])
|
TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wunused-but-set-variable])
|
||||||
TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wunused])
|
TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wunused])
|
||||||
@ -347,8 +346,6 @@ AS_IF([test "x$enable_gl" != "xno"], [
|
|||||||
# override with --with-gl*
|
# override with --with-gl*
|
||||||
glut_cflags="$glut_cflags|-framework GLUT -framework OpenGL"
|
glut_cflags="$glut_cflags|-framework GLUT -framework OpenGL"
|
||||||
glut_ldflags="$glut_ldflags|-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
|
esac
|
||||||
|
|
||||||
@ -445,54 +442,31 @@ AC_ARG_ENABLE([sdl],
|
|||||||
@<:@default=auto@:>@]))
|
@<:@default=auto@:>@]))
|
||||||
AS_IF([test "x$enable_sdl" != "xno"], [
|
AS_IF([test "x$enable_sdl" != "xno"], [
|
||||||
CLEAR_LIBVARS([SDL])
|
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])
|
WITHLIB_OPTION([sdl], [SDL])
|
||||||
|
|
||||||
sdl_header="no"
|
$sdl_header = "no";
|
||||||
LIBCHECK_PROLOGUE([SDL])
|
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_CHECK_HEADER([SDL.h], [sdl_header="SDL.h"],
|
||||||
[AC_MSG_WARN(SDL library not available - no sdl.h)])])
|
[AC_MSG_WARN(SDL library not available - no sdl.h)])])
|
||||||
if test x"$sdl_header" != "xno"; then
|
if test x"$sdl_header" != "xno" ; then
|
||||||
AC_LANG_PUSH(C)
|
AC_CHECK_LIB(SDL, SDL_Init,
|
||||||
SDL_SAVED_LIBS="$LIBS"
|
[SDL_LIBS="-lSDL"
|
||||||
for lib in "" "-lSDL" "-lSDLmain -lSDL"; do
|
SDL_INCLUDES="-DWEBP_HAVE_SDL"
|
||||||
LIBS="$SDL_SAVED_LIBS $lib"
|
AC_DEFINE(WEBP_HAVE_SDL, [1],
|
||||||
# Perform a full link to ensure SDL_main is resolved if needed.
|
[Set to 1 if SDL library is installed])
|
||||||
AC_LINK_IFELSE(
|
sdl_support=yes
|
||||||
[AC_LANG_SOURCE([
|
],
|
||||||
#include <$sdl_header>
|
AC_MSG_WARN(Optional SDL library not found),
|
||||||
int main(int argc, char** argv) {
|
[$MATH_LIBS]),
|
||||||
SDL_Init(0);
|
if test x"$sdl_header" == "xSDL.h" ; then
|
||||||
return 0;
|
|
||||||
}])],
|
|
||||||
[SDL_LIBS="$LDFLAGS $LIBS"
|
|
||||||
SDL_INCLUDES="$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_INCLUDES="$SDL_INCLUDES -DWEBP_HAVE_JUST_SDL_H"
|
SDL_INCLUDES="$SDL_INCLUDES -DWEBP_HAVE_JUST_SDL_H"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
LIBCHECK_EPILOGUE([SDL])
|
LIBCHECK_EPILOGUE([SDL])
|
||||||
|
|
||||||
if test x"$sdl_support" = "xyes"; then
|
if test "$sdl_support" = "yes" ; then
|
||||||
build_vwebp_sdl=yes
|
build_vwebp_sdl=yes
|
||||||
else
|
|
||||||
AC_MSG_WARN(Optional SDL library not found)
|
|
||||||
fi
|
fi
|
||||||
])
|
])
|
||||||
|
|
||||||
@ -615,7 +589,7 @@ AS_IF([test "x$enable_gif" != "xno"], [
|
|||||||
|
|
||||||
if test "$gif_support" = "yes" -a \
|
if test "$gif_support" = "yes" -a \
|
||||||
"$enable_libwebpdemux" = "yes"; then
|
"$enable_libwebpdemux" = "yes"; then
|
||||||
build_anim_diff=yes
|
build_animdiff=yes
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if test "$gif_support" = "yes" -a \
|
if test "$gif_support" = "yes" -a \
|
||||||
@ -623,10 +597,10 @@ AS_IF([test "x$enable_gif" != "xno"], [
|
|||||||
build_gif2webp=yes
|
build_gif2webp=yes
|
||||||
fi
|
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"])
|
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
|
build_img2webp=yes
|
||||||
fi
|
fi
|
||||||
AM_CONDITIONAL([BUILD_IMG2WEBP], [test "${build_img2webp}" = "yes"])
|
AM_CONDITIONAL([BUILD_IMG2WEBP], [test "${build_img2webp}" = "yes"])
|
||||||
@ -688,7 +662,7 @@ if test "$enable_wic" = "yes"; then
|
|||||||
fi
|
fi
|
||||||
esac
|
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=""
|
USE_SWAP_16BIT_CSP=""
|
||||||
AC_MSG_CHECKING(if --enable-swap-16bit-csp option is specified)
|
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],
|
AS_HELP_STRING([--enable-swap-16bit-csp],
|
||||||
[Enable byte swap for 16 bit colorspaces]))
|
[Enable byte swap for 16 bit colorspaces]))
|
||||||
if test "$enable_swap_16bit_csp" = "yes"; then
|
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
|
fi
|
||||||
AC_MSG_RESULT(${enable_swap_16bit_csp-no})
|
AC_MSG_RESULT(${enable_swap_16bit_csp-no})
|
||||||
AC_SUBST(USE_SWAP_16BIT_CSP)
|
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])
|
USE_EXPERIMENTAL_CODE=""
|
||||||
AC_MSG_CHECKING(if --disable-near-lossless option is specified)
|
AC_MSG_CHECKING(if --enable-experimental option is specified)
|
||||||
AC_ARG_ENABLE([near_lossless],
|
AC_ARG_ENABLE([experimental], AS_HELP_STRING([--enable-experimental],
|
||||||
AS_HELP_STRING([--disable-near-lossless],
|
[Activate experimental features]))
|
||||||
[Disable near lossless encoding]),
|
if test "$enable_experimental" = "yes"; then
|
||||||
[], [enable_near_lossless=yes])
|
AC_DEFINE(WEBP_EXPERIMENTAL_FEATURES, [1], [Enable experimental code])
|
||||||
if test "$enable_near_lossless" = "no"; then
|
USE_EXPERIMENTAL_CODE="-DWEBP_EXPERIMENTAL_FEATURES"
|
||||||
AC_DEFINE(WEBP_NEAR_LOSSLESS, [0], [Enable near lossless encoding])
|
|
||||||
AC_MSG_RESULT([yes])
|
|
||||||
else
|
|
||||||
AC_MSG_RESULT([no])
|
|
||||||
fi
|
fi
|
||||||
|
AC_MSG_RESULT(${enable_experimental-no})
|
||||||
|
AC_SUBST(USE_EXPERIMENTAL_CODE)
|
||||||
|
|
||||||
dnl === Check whether libwebpmux should be built
|
dnl === Check whether libwebpmux should be built
|
||||||
AC_MSG_CHECKING(whether libwebpmux is to 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
|
dnl === Check whether libwebpdemux should be built
|
||||||
AC_MSG_CHECKING(whether libwebpdemux is to be built)
|
AC_MSG_CHECKING(whether libwebpdemux is to be built)
|
||||||
AC_ARG_ENABLE([libwebpdemux],
|
AC_ARG_ENABLE([libwebpdemux],
|
||||||
AS_HELP_STRING([--disable-libwebpdemux],
|
AS_HELP_STRING([--enable-libwebpdemux],
|
||||||
[Disable libwebpdemux @<:@default=no@:>@]),
|
[Build libwebpdemux @<:@default=no@:>@]))
|
||||||
[], [enable_libwebpdemux=yes])
|
|
||||||
AC_MSG_RESULT(${enable_libwebpdemux-no})
|
AC_MSG_RESULT(${enable_libwebpdemux-no})
|
||||||
AM_CONDITIONAL([WANT_DEMUX], [test "$enable_libwebpdemux" = "yes"])
|
AM_CONDITIONAL([WANT_DEMUX], [test "$enable_libwebpdemux" = "yes"])
|
||||||
|
|
||||||
@ -778,20 +749,20 @@ libwebpmux: ${enable_libwebpmux-no}
|
|||||||
libwebpextras: ${enable_libwebpextras-no}
|
libwebpextras: ${enable_libwebpextras-no}
|
||||||
|
|
||||||
Tools:
|
Tools:
|
||||||
cwebp : ${enable_libwebpdemux-no}
|
cwebp : yes
|
||||||
Input format support
|
Input format support
|
||||||
====================
|
====================
|
||||||
JPEG : ${jpeg_support-no}
|
JPEG : ${jpeg_support-no}
|
||||||
PNG : ${png_support-no}
|
PNG : ${png_support-no}
|
||||||
TIFF : ${tiff_support-no}
|
TIFF : ${tiff_support-no}
|
||||||
WIC : ${wic_support-no}
|
WIC : ${wic_support-no}
|
||||||
dwebp : ${enable_libwebpdemux-no}
|
dwebp : yes
|
||||||
Output format support
|
Output format support
|
||||||
=====================
|
=====================
|
||||||
PNG : ${png_support-no}
|
PNG : ${png_support-no}
|
||||||
WIC : ${wic_support-no}
|
WIC : ${wic_support-no}
|
||||||
GIF support : ${gif_support-no}
|
GIF support : ${gif_support-no}
|
||||||
anim_diff : ${build_anim_diff-no}
|
anim_diff : ${build_animdiff-no}
|
||||||
gif2webp : ${build_gif2webp-no}
|
gif2webp : ${build_gif2webp-no}
|
||||||
img2webp : ${build_img2webp-no}
|
img2webp : ${build_img2webp-no}
|
||||||
webpmux : ${enable_libwebpmux-no}
|
webpmux : ${enable_libwebpmux-no}
|
||||||
|
@ -446,9 +446,8 @@ Frame Height Minus One: 24 bits (_uint24_)
|
|||||||
Frame Duration: 24 bits (_uint24_)
|
Frame Duration: 24 bits (_uint24_)
|
||||||
|
|
||||||
: The time to wait before displaying the next frame, in 1 millisecond units.
|
: 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
|
In particular, frame duration of 0 is useful when one wants to update
|
||||||
implementation defined. Many tools and browsers assign a minimum duration
|
multiple areas of the canvas at once during the animation.
|
||||||
similar to GIF.
|
|
||||||
|
|
||||||
Reserved: 6 bits
|
Reserved: 6 bits
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@ LOCAL_SRC_FILES := \
|
|||||||
|
|
||||||
LOCAL_CFLAGS := $(WEBP_CFLAGS)
|
LOCAL_CFLAGS := $(WEBP_CFLAGS)
|
||||||
LOCAL_C_INCLUDES := $(LOCAL_PATH)/../src
|
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
|
LOCAL_MODULE := cwebp
|
||||||
|
|
||||||
@ -43,7 +43,8 @@ LOCAL_SRC_FILES := \
|
|||||||
|
|
||||||
LOCAL_CFLAGS := $(WEBP_CFLAGS)
|
LOCAL_CFLAGS := $(WEBP_CFLAGS)
|
||||||
LOCAL_C_INCLUDES := $(LOCAL_PATH)/../src
|
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
|
LOCAL_MODULE := dwebp
|
||||||
|
|
||||||
include $(BUILD_EXECUTABLE)
|
include $(BUILD_EXECUTABLE)
|
||||||
@ -74,8 +75,7 @@ LOCAL_SRC_FILES := \
|
|||||||
|
|
||||||
LOCAL_CFLAGS := $(WEBP_CFLAGS)
|
LOCAL_CFLAGS := $(WEBP_CFLAGS)
|
||||||
LOCAL_C_INCLUDES := $(LOCAL_PATH)/../src
|
LOCAL_C_INCLUDES := $(LOCAL_PATH)/../src
|
||||||
LOCAL_STATIC_LIBRARIES := example_util imageio_util imagedec webpmux webpdemux \
|
LOCAL_STATIC_LIBRARIES := example_util imageio_util imagedec webpmux webp
|
||||||
webp
|
|
||||||
|
|
||||||
LOCAL_MODULE := img2webp_example
|
LOCAL_MODULE := img2webp_example
|
||||||
|
|
||||||
|
@ -1,11 +1,8 @@
|
|||||||
AM_CPPFLAGS += -I$(top_builddir)/src -I$(top_srcdir)/src
|
AM_CPPFLAGS += -I$(top_builddir)/src -I$(top_srcdir)/src
|
||||||
|
|
||||||
bin_PROGRAMS =
|
bin_PROGRAMS = dwebp cwebp
|
||||||
if WANT_DEMUX
|
|
||||||
bin_PROGRAMS += dwebp cwebp
|
|
||||||
endif
|
|
||||||
if BUILD_ANIMDIFF
|
if BUILD_ANIMDIFF
|
||||||
noinst_PROGRAMS = anim_diff anim_dump
|
noinst_PROGRAMS = anim_diff
|
||||||
endif
|
endif
|
||||||
if BUILD_GIF2WEBP
|
if BUILD_GIF2WEBP
|
||||||
bin_PROGRAMS += 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
|
libexample_util_la_LIBADD = ../src/libwebp.la
|
||||||
|
|
||||||
anim_diff_SOURCES = anim_diff.c anim_util.c anim_util.h
|
anim_diff_SOURCES = anim_diff.c anim_util.c anim_util.h
|
||||||
anim_diff_CPPFLAGS = $(AM_CPPFLAGS) $(GIF_INCLUDES)
|
anim_diff_CPPFLAGS = $(AM_CPPFLAGS) $(USE_EXPERIMENTAL_CODE) $(GIF_INCLUDES)
|
||||||
anim_diff_LDADD =
|
anim_diff_LDADD = ../src/demux/libwebpdemux.la
|
||||||
anim_diff_LDADD += ../src/demux/libwebpdemux.la
|
anim_diff_LDADD += libexample_util.la ../imageio/libimageio_util.la
|
||||||
anim_diff_LDADD += libexample_util.la
|
|
||||||
anim_diff_LDADD += ../imageio/libimageio_util.la
|
|
||||||
anim_diff_LDADD += $(GIF_LIBS) -lm
|
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_SOURCES = cwebp.c stopwatch.h
|
||||||
cwebp_CPPFLAGS = $(AM_CPPFLAGS)
|
cwebp_CPPFLAGS = $(AM_CPPFLAGS) $(USE_EXPERIMENTAL_CODE)
|
||||||
cwebp_LDADD =
|
cwebp_LDADD = libexample_util.la ../imageio/libimageio_util.la
|
||||||
cwebp_LDADD += libexample_util.la
|
cwebp_LDADD += ../imageio/libimagedec.la ../src/libwebp.la
|
||||||
cwebp_LDADD += ../imageio/libimageio_util.la
|
|
||||||
cwebp_LDADD += ../imageio/libimagedec.la
|
|
||||||
cwebp_LDADD += ../src/libwebp.la
|
|
||||||
cwebp_LDADD += $(JPEG_LIBS) $(PNG_LIBS) $(TIFF_LIBS)
|
cwebp_LDADD += $(JPEG_LIBS) $(PNG_LIBS) $(TIFF_LIBS)
|
||||||
|
|
||||||
dwebp_SOURCES = dwebp.c stopwatch.h
|
dwebp_SOURCES = dwebp.c stopwatch.h
|
||||||
dwebp_CPPFLAGS = $(AM_CPPFLAGS)
|
dwebp_CPPFLAGS = $(AM_CPPFLAGS) $(USE_EXPERIMENTAL_CODE)
|
||||||
dwebp_CPPFLAGS += $(JPEG_INCLUDES) $(PNG_INCLUDES)
|
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/libimagedec.la
|
||||||
dwebp_LDADD += ../imageio/libimageenc.la
|
dwebp_LDADD += ../imageio/libimageenc.la
|
||||||
dwebp_LDADD += ../imageio/libimageio_util.la
|
dwebp_LDADD += ../imageio/libimageio_util.la
|
||||||
@ -67,53 +48,36 @@ dwebp_LDADD += ../src/libwebp.la
|
|||||||
dwebp_LDADD +=$(PNG_LIBS) $(JPEG_LIBS)
|
dwebp_LDADD +=$(PNG_LIBS) $(JPEG_LIBS)
|
||||||
|
|
||||||
gif2webp_SOURCES = gif2webp.c gifdec.c gifdec.h
|
gif2webp_SOURCES = gif2webp.c gifdec.c gifdec.h
|
||||||
gif2webp_CPPFLAGS = $(AM_CPPFLAGS) $(GIF_INCLUDES)
|
gif2webp_CPPFLAGS = $(AM_CPPFLAGS) $(USE_EXPERIMENTAL_CODE) $(GIF_INCLUDES)
|
||||||
gif2webp_LDADD =
|
gif2webp_LDADD = libexample_util.la ../imageio/libimageio_util.la
|
||||||
gif2webp_LDADD += libexample_util.la
|
gif2webp_LDADD += ../src/mux/libwebpmux.la ../src/libwebp.la $(GIF_LIBS)
|
||||||
gif2webp_LDADD += ../imageio/libimageio_util.la
|
|
||||||
gif2webp_LDADD += ../src/mux/libwebpmux.la
|
|
||||||
gif2webp_LDADD += ../src/libwebp.la
|
|
||||||
gif2webp_LDADD += $(GIF_LIBS)
|
|
||||||
|
|
||||||
vwebp_SOURCES = vwebp.c
|
vwebp_SOURCES = vwebp.c
|
||||||
vwebp_CPPFLAGS = $(AM_CPPFLAGS) $(GL_INCLUDES)
|
vwebp_CPPFLAGS = $(AM_CPPFLAGS) $(USE_EXPERIMENTAL_CODE) $(GL_INCLUDES)
|
||||||
vwebp_LDADD =
|
vwebp_LDADD = libexample_util.la ../imageio/libimageio_util.la
|
||||||
vwebp_LDADD += libexample_util.la
|
vwebp_LDADD += ../src/demux/libwebpdemux.la $(GL_LIBS)
|
||||||
vwebp_LDADD += ../imageio/libimageio_util.la
|
|
||||||
vwebp_LDADD += ../src/demux/libwebpdemux.la
|
|
||||||
vwebp_LDADD += $(GL_LIBS)
|
|
||||||
|
|
||||||
webpmux_SOURCES = webpmux.c
|
webpmux_SOURCES = webpmux.c
|
||||||
webpmux_CPPFLAGS = $(AM_CPPFLAGS)
|
webpmux_CPPFLAGS = $(AM_CPPFLAGS) $(USE_EXPERIMENTAL_CODE)
|
||||||
webpmux_LDADD =
|
webpmux_LDADD = libexample_util.la ../imageio/libimageio_util.la
|
||||||
webpmux_LDADD += libexample_util.la
|
webpmux_LDADD += ../src/mux/libwebpmux.la ../src/libwebp.la
|
||||||
webpmux_LDADD += ../imageio/libimageio_util.la
|
|
||||||
webpmux_LDADD += ../src/mux/libwebpmux.la
|
|
||||||
webpmux_LDADD += ../src/libwebp.la
|
|
||||||
|
|
||||||
img2webp_SOURCES = img2webp.c
|
img2webp_SOURCES = img2webp.c
|
||||||
img2webp_CPPFLAGS = $(AM_CPPFLAGS)
|
img2webp_CPPFLAGS = $(AM_CPPFLAGS) $(USE_EXPERIMENTAL_CODE)
|
||||||
img2webp_LDADD =
|
img2webp_LDADD = libexample_util.la ../imageio/libimageio_util.la
|
||||||
img2webp_LDADD += libexample_util.la
|
|
||||||
img2webp_LDADD += ../imageio/libimageio_util.la
|
|
||||||
img2webp_LDADD += ../imageio/libimagedec.la
|
img2webp_LDADD += ../imageio/libimagedec.la
|
||||||
img2webp_LDADD += ../src/mux/libwebpmux.la
|
img2webp_LDADD += ../src/mux/libwebpmux.la ../src/libwebp.la
|
||||||
img2webp_LDADD += ../src/libwebp.la
|
|
||||||
img2webp_LDADD += $(PNG_LIBS) $(JPEG_LIBS) $(TIFF_LIBS)
|
img2webp_LDADD += $(PNG_LIBS) $(JPEG_LIBS) $(TIFF_LIBS)
|
||||||
|
|
||||||
webpinfo_SOURCES = webpinfo.c
|
webpinfo_SOURCES = webpinfo.c
|
||||||
webpinfo_CPPFLAGS = $(AM_CPPFLAGS)
|
webpinfo_CPPFLAGS = $(AM_CPPFLAGS) $(USE_EXPERIMENTAL_CODE)
|
||||||
webpinfo_LDADD =
|
webpinfo_LDADD = libexample_util.la ../imageio/libimageio_util.la
|
||||||
webpinfo_LDADD += libexample_util.la
|
|
||||||
webpinfo_LDADD += ../imageio/libimageio_util.la
|
|
||||||
webpinfo_LDADD += ../src/libwebp.la
|
webpinfo_LDADD += ../src/libwebp.la
|
||||||
|
|
||||||
if BUILD_LIBWEBPDECODER
|
if BUILD_LIBWEBPDECODER
|
||||||
anim_diff_LDADD += ../src/libwebpdecoder.la
|
anim_diff_LDADD += ../src/libwebpdecoder.la
|
||||||
anim_dump_LDADD += ../src/libwebpdecoder.la
|
|
||||||
vwebp_LDADD += ../src/libwebpdecoder.la
|
vwebp_LDADD += ../src/libwebpdecoder.la
|
||||||
else
|
else
|
||||||
anim_diff_LDADD += ../src/libwebp.la
|
anim_diff_LDADD += ../src/libwebp.la
|
||||||
anim_dump_LDADD += ../src/libwebp.la
|
|
||||||
vwebp_LDADD += ../src/libwebp.la
|
vwebp_LDADD += ../src/libwebp.la
|
||||||
endif
|
endif
|
||||||
|
@ -187,11 +187,11 @@ static void Help(void) {
|
|||||||
printf(" -min_psnr <float> ... minimum per-frame PSNR\n");
|
printf(" -min_psnr <float> ... minimum per-frame PSNR\n");
|
||||||
printf(" -raw_comparison ..... if this flag is not used, RGB is\n");
|
printf(" -raw_comparison ..... if this flag is not used, RGB is\n");
|
||||||
printf(" premultiplied before comparison\n");
|
printf(" premultiplied before comparison\n");
|
||||||
printf(" -max_diff <int> ..... maximum allowed difference per channel\n"
|
#ifdef WEBP_EXPERIMENTAL_FEATURES
|
||||||
" between corresponding pixels in subsequent\n"
|
printf(" -max_diff <int> ..... maximum allowed difference per channel "
|
||||||
|
" between corresponding pixels in subsequent"
|
||||||
" frames\n");
|
" frames\n");
|
||||||
printf(" -h .................. this help\n");
|
#endif
|
||||||
printf(" -version ............ print version number and exit\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, const char* argv[]) {
|
int main(int argc, const char* argv[]) {
|
||||||
@ -207,6 +207,11 @@ int main(int argc, const char* argv[]) {
|
|||||||
const char* files[2] = { NULL, NULL };
|
const char* files[2] = { NULL, NULL };
|
||||||
AnimatedImage images[2];
|
AnimatedImage images[2];
|
||||||
|
|
||||||
|
if (argc < 3) {
|
||||||
|
Help();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
for (c = 1; c < argc; ++c) {
|
for (c = 1; c < argc; ++c) {
|
||||||
int parse_error = 0;
|
int parse_error = 0;
|
||||||
if (!strcmp(argv[c], "-dump_frames")) {
|
if (!strcmp(argv[c], "-dump_frames")) {
|
||||||
@ -231,6 +236,7 @@ int main(int argc, const char* argv[]) {
|
|||||||
}
|
}
|
||||||
} else if (!strcmp(argv[c], "-raw_comparison")) {
|
} else if (!strcmp(argv[c], "-raw_comparison")) {
|
||||||
premultiply = 0;
|
premultiply = 0;
|
||||||
|
#ifdef WEBP_EXPERIMENTAL_FEATURES
|
||||||
} else if (!strcmp(argv[c], "-max_diff")) {
|
} else if (!strcmp(argv[c], "-max_diff")) {
|
||||||
if (c < argc - 1) {
|
if (c < argc - 1) {
|
||||||
const char* const v = argv[++c];
|
const char* const v = argv[++c];
|
||||||
@ -244,18 +250,7 @@ int main(int argc, const char* argv[]) {
|
|||||||
} else {
|
} else {
|
||||||
parse_error = 1;
|
parse_error = 1;
|
||||||
}
|
}
|
||||||
} else if (!strcmp(argv[c], "-h") || !strcmp(argv[c], "-help")) {
|
#endif
|
||||||
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 {
|
} else {
|
||||||
if (!got_input1) {
|
if (!got_input1) {
|
||||||
files[0] = argv[c];
|
files[0] = argv[c];
|
||||||
@ -272,12 +267,6 @@ int main(int argc, const char* argv[]) {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (argc < 3) {
|
|
||||||
Help();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (!got_input2) {
|
if (!got_input2) {
|
||||||
Help();
|
Help();
|
||||||
return -1;
|
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 <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#if defined(WEBP_HAVE_GIF)
|
#ifdef WEBP_HAVE_GIF
|
||||||
#include <gif_lib.h>
|
#include <gif_lib.h>
|
||||||
#endif
|
#endif
|
||||||
#include "webp/format_constants.h"
|
#include "webp/format_constants.h"
|
||||||
@ -33,13 +33,11 @@ static const int kNumChannels = 4;
|
|||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// Common utilities.
|
// Common utilities.
|
||||||
|
|
||||||
#if defined(WEBP_HAVE_GIF)
|
|
||||||
// Returns true if the frame covers the full canvas.
|
// Returns true if the frame covers the full canvas.
|
||||||
static int IsFullFrame(int width, int height,
|
static int IsFullFrame(int width, int height,
|
||||||
int canvas_width, int canvas_height) {
|
int canvas_width, int canvas_height) {
|
||||||
return (width == canvas_width && height == canvas_height);
|
return (width == canvas_width && height == canvas_height);
|
||||||
}
|
}
|
||||||
#endif // WEBP_HAVE_GIF
|
|
||||||
|
|
||||||
static int CheckSizeForOverflow(uint64_t size) {
|
static int CheckSizeForOverflow(uint64_t size) {
|
||||||
return (size == (size_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.
|
// Clear the canvas to transparent.
|
||||||
static void ZeroFillCanvas(uint8_t* rgba,
|
static void ZeroFillCanvas(uint8_t* rgba,
|
||||||
uint32_t canvas_width, uint32_t canvas_height) {
|
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;
|
dst += stride;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif // WEBP_HAVE_GIF
|
|
||||||
|
|
||||||
// Canonicalize all transparent pixels to transparent black to aid comparison.
|
// Canonicalize all transparent pixels to transparent black to aid comparison.
|
||||||
static void CleanupTransparentPixels(uint32_t* rgba,
|
static void CleanupTransparentPixels(uint32_t* rgba,
|
||||||
@ -156,8 +152,6 @@ static int DumpFrame(const char filename[], const char dump_folder[],
|
|||||||
FILE* f = NULL;
|
FILE* f = NULL;
|
||||||
const char* row;
|
const char* row;
|
||||||
|
|
||||||
if (dump_folder == NULL) dump_folder = ".";
|
|
||||||
|
|
||||||
base_name = strrchr(filename, '/');
|
base_name = strrchr(filename, '/');
|
||||||
base_name = (base_name == NULL) ? filename : base_name + 1;
|
base_name = (base_name == NULL) ? filename : base_name + 1;
|
||||||
max_len = strlen(dump_folder) + 1 + strlen(base_name)
|
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);
|
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[],
|
static int ReadAnimatedWebP(const char filename[],
|
||||||
const WebPData* const webp_data,
|
const WebPData* const webp_data,
|
||||||
AnimatedImage* const image, int dump_frames,
|
AnimatedImage* const image, int dump_frames,
|
||||||
@ -284,7 +278,7 @@ static int ReadAnimatedWebP(const char filename[],
|
|||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// GIF Decoding.
|
// GIF Decoding.
|
||||||
|
|
||||||
#if defined(WEBP_HAVE_GIF)
|
#ifdef WEBP_HAVE_GIF
|
||||||
|
|
||||||
// Returns true if this is a valid GIF bitstream.
|
// Returns true if this is a valid GIF bitstream.
|
||||||
static int IsGIF(const WebPData* const data) {
|
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.
|
// 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) {
|
static uint32_t GetLoopCountGIF(const GifFileType* const gif) {
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < gif->ImageCount; ++i) {
|
for (i = 0; i < gif->ImageCount; ++i) {
|
||||||
@ -451,13 +440,12 @@ static uint32_t GetLoopCountGIF(const GifFileType* const gif) {
|
|||||||
if (signature_is_ok &&
|
if (signature_is_ok &&
|
||||||
eb2->Function == CONTINUE_EXT_FUNC_CODE && eb2->ByteCount >= 3 &&
|
eb2->Function == CONTINUE_EXT_FUNC_CODE && eb2->ByteCount >= 3 &&
|
||||||
eb2->Bytes[0] == 1) {
|
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);
|
((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.
|
// 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_frame = &image->frames[i];
|
||||||
curr_rgba = curr_frame->rgba;
|
curr_rgba = curr_frame->rgba;
|
||||||
curr_frame->duration = GetFrameDurationGIF(gif, i);
|
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.
|
if (i == 0) { // Initialize as transparent.
|
||||||
curr_frame->is_key_frame = 1;
|
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);
|
*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,
|
uint32_t width, uint32_t height, int premultiply,
|
||||||
int* const max_diff, double* const psnr);
|
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
|
#ifdef __cplusplus
|
||||||
} // extern "C"
|
} // extern "C"
|
||||||
#endif
|
#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);
|
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;
|
int s;
|
||||||
const int total = counts[0] + counts[1] + counts[2] + counts[3];
|
|
||||||
for (s = 0; s < 4; ++s) {
|
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);
|
fprintf(stderr, "| %7d\n", total);
|
||||||
}
|
}
|
||||||
@ -187,8 +186,7 @@ static void PrintExtraInfoLossless(const WebPPicture* const pic,
|
|||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "File: %s\n", file_name);
|
fprintf(stderr, "File: %s\n", file_name);
|
||||||
fprintf(stderr, "Dimension: %d x %d\n", pic->width, pic->height);
|
fprintf(stderr, "Dimension: %d x %d\n", pic->width, pic->height);
|
||||||
fprintf(stderr, "Output: %d bytes (%.2f bpp)\n", stats->coded_size,
|
fprintf(stderr, "Output: %d bytes\n", stats->coded_size);
|
||||||
8.f * stats->coded_size / pic->width / pic->height);
|
|
||||||
PrintFullLosslessInfo(stats, "ARGB");
|
PrintFullLosslessInfo(stats, "ARGB");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -209,18 +207,15 @@ static void PrintExtraInfoLossy(const WebPPicture* const pic, int short_output,
|
|||||||
pic->width, pic->height,
|
pic->width, pic->height,
|
||||||
stats->alpha_data_size ? " (with alpha)" : "");
|
stats->alpha_data_size ? " (with alpha)" : "");
|
||||||
fprintf(stderr, "Output: "
|
fprintf(stderr, "Output: "
|
||||||
"%d bytes Y-U-V-All-PSNR %2.2f %2.2f %2.2f %2.2f dB\n"
|
"%d bytes Y-U-V-All-PSNR %2.2f %2.2f %2.2f %2.2f dB\n",
|
||||||
" (%.2f bpp)\n",
|
|
||||||
stats->coded_size,
|
stats->coded_size,
|
||||||
stats->PSNR[0], stats->PSNR[1], stats->PSNR[2], stats->PSNR[3],
|
stats->PSNR[0], stats->PSNR[1], stats->PSNR[2], stats->PSNR[3]);
|
||||||
8.f * stats->coded_size / pic->width / pic->height);
|
|
||||||
if (total > 0) {
|
if (total > 0) {
|
||||||
int totals[4] = { 0, 0, 0, 0 };
|
int totals[4] = { 0, 0, 0, 0 };
|
||||||
fprintf(stderr, "block count: intra4: %6d (%.2f%%)\n"
|
fprintf(stderr, "block count: intra4: %d\n"
|
||||||
" intra16: %6d (%.2f%%)\n"
|
" intra16: %d (-> %.2f%%)\n",
|
||||||
" skipped: %6d (%.2f%%)\n",
|
num_i4, num_i16, 100.f * num_i16 / total);
|
||||||
num_i4, 100.f * num_i4 / total,
|
fprintf(stderr, " skipped block: %d (%.2f%%)\n",
|
||||||
num_i16, 100.f * num_i16 / total,
|
|
||||||
num_skip, 100.f * num_skip / total);
|
num_skip, 100.f * num_skip / total);
|
||||||
fprintf(stderr, "bytes used: header: %6d (%.1f%%)\n"
|
fprintf(stderr, "bytes used: header: %6d (%.1f%%)\n"
|
||||||
" mode-partition: %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);
|
PrintByteCount(stats->residual_bytes[2], stats->coded_size, totals);
|
||||||
}
|
}
|
||||||
fprintf(stderr, " macroblocks: ");
|
fprintf(stderr, " macroblocks: ");
|
||||||
PrintPercents(stats->segment_size);
|
PrintPercents(stats->segment_size, total);
|
||||||
fprintf(stderr, " quantizer: ");
|
fprintf(stderr, " quantizer: ");
|
||||||
PrintValues(stats->segment_quant);
|
PrintValues(stats->segment_quant);
|
||||||
fprintf(stderr, " filter level: ");
|
fprintf(stderr, " filter level: ");
|
||||||
@ -468,9 +463,8 @@ static int WriteWebPWithMetadata(FILE* const out,
|
|||||||
} else {
|
} else {
|
||||||
const int is_lossless = !memcmp(webp, "VP8L", kTagSize);
|
const int is_lossless = !memcmp(webp, "VP8L", kTagSize);
|
||||||
if (is_lossless) {
|
if (is_lossless) {
|
||||||
// Presence of alpha is stored in the 37th bit (29th after the
|
// Presence of alpha is stored in the 29th bit of VP8L data.
|
||||||
// signature) of VP8L data.
|
if (webp[kChunkHeaderSize + 3] & (1 << 5)) flags |= kAlphaFlag;
|
||||||
if (webp[kChunkHeaderSize + 4] & (1 << 4)) flags |= kAlphaFlag;
|
|
||||||
}
|
}
|
||||||
ok = ok && (fwrite(kVP8XHeader, kChunkHeaderSize, 1, out) == 1);
|
ok = ok && (fwrite(kVP8XHeader, kChunkHeaderSize, 1, out) == 1);
|
||||||
ok = ok && WriteLE32(out, flags);
|
ok = ok && WriteLE32(out, flags);
|
||||||
@ -492,10 +486,10 @@ static int WriteWebPWithMetadata(FILE* const out,
|
|||||||
*metadata_written |= METADATA_XMP;
|
*metadata_written |= METADATA_XMP;
|
||||||
}
|
}
|
||||||
return ok;
|
return ok;
|
||||||
|
} else {
|
||||||
|
// No metadata, just write the original image file.
|
||||||
|
return (fwrite(webp, webp_size, 1, out) == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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"
|
printf(" -near_lossless <int> ... use near-lossless image\n"
|
||||||
" preprocessing (0..100=off), "
|
" preprocessing (0..100=off), "
|
||||||
"default=100\n");
|
"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(" -hint <string> ......... specify image characteristics hint,\n");
|
||||||
printf(" one of: photo, picture or graph\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) {
|
} else if (!strcmp(argv[c], "-near_lossless") && c < argc - 1) {
|
||||||
config.near_lossless = ExUtilGetInt(argv[++c], 0, &parse_error);
|
config.near_lossless = ExUtilGetInt(argv[++c], 0, &parse_error);
|
||||||
config.lossless = 1; // use near-lossless only with lossless
|
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) {
|
} else if (!strcmp(argv[c], "-hint") && c < argc - 1) {
|
||||||
++c;
|
++c;
|
||||||
if (!strcmp(argv[c], "photo")) {
|
if (!strcmp(argv[c], "photo")) {
|
||||||
|
@ -12,14 +12,10 @@
|
|||||||
|
|
||||||
#include "./example_util.h"
|
#include "./example_util.h"
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "webp/mux_types.h"
|
|
||||||
#include "../imageio/imageio_util.h"
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// String parsing
|
// String parsing
|
||||||
|
|
||||||
@ -60,68 +56,3 @@ float ExUtilGetFloat(const char* const v, int* const error) {
|
|||||||
}
|
}
|
||||||
return f;
|
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_
|
#define WEBP_EXAMPLES_EXAMPLE_UTIL_H_
|
||||||
|
|
||||||
#include "webp/types.h"
|
#include "webp/types.h"
|
||||||
#include "webp/mux_types.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
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.
|
// actually parsed is returned, or -1 if an error occurred.
|
||||||
int ExUtilGetInts(const char* v, int base, int max_output, int output[]);
|
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
|
#ifdef __cplusplus
|
||||||
} // extern "C"
|
} // extern "C"
|
||||||
#endif
|
#endif
|
||||||
|
@ -23,10 +23,6 @@
|
|||||||
|
|
||||||
#ifdef WEBP_HAVE_GIF
|
#ifdef WEBP_HAVE_GIF
|
||||||
|
|
||||||
#if defined(HAVE_UNISTD_H) && HAVE_UNISTD_H
|
|
||||||
#include <unistd.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <gif_lib.h>
|
#include <gif_lib.h>
|
||||||
#include "webp/encode.h"
|
#include "webp/encode.h"
|
||||||
#include "webp/mux.h"
|
#include "webp/mux.h"
|
||||||
@ -34,10 +30,6 @@
|
|||||||
#include "../imageio/imageio_util.h"
|
#include "../imageio/imageio_util.h"
|
||||||
#include "./gifdec.h"
|
#include "./gifdec.h"
|
||||||
|
|
||||||
#if !defined(STDIN_FILENO)
|
|
||||||
#define STDIN_FILENO 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
static int transparent_index = GIF_INDEX_INVALID; // Opaque by default.
|
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(" -metadata <string> ..... comma separated list of metadata to\n");
|
||||||
printf(" ");
|
printf(" ");
|
||||||
printf("copy from the input to the output if present\n");
|
printf("copy from the input to the output if present\n");
|
||||||
printf(" ");
|
printf(" "
|
||||||
printf("Valid values: all, none, icc, xmp (default)\n");
|
"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(" -mt .................... use multi-threading if available\n");
|
printf(" -mt .................... use multi-threading if available\n");
|
||||||
printf("\n");
|
printf("\n");
|
||||||
printf(" -version ............... print version number and exit\n");
|
printf(" -version ............... print version number and exit\n");
|
||||||
@ -114,7 +104,7 @@ int main(int argc, const char *argv[]) {
|
|||||||
WebPAnimEncoderOptions enc_options;
|
WebPAnimEncoderOptions enc_options;
|
||||||
WebPConfig config;
|
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 done;
|
||||||
int c;
|
int c;
|
||||||
int quiet = 0;
|
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.
|
int stored_icc = 0; // Whether we have already stored an ICC profile.
|
||||||
WebPData xmp_data;
|
WebPData xmp_data;
|
||||||
int stored_xmp = 0; // Whether we have already stored an XMP profile.
|
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 stored_loop_count = 0; // Whether we have found an explicit loop count.
|
||||||
int loop_compatibility = 0;
|
|
||||||
WebPMux* mux = NULL;
|
WebPMux* mux = NULL;
|
||||||
|
|
||||||
int default_kmin = 1; // Whether to use default kmin value.
|
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")) {
|
} else if (!strcmp(argv[c], "-mixed")) {
|
||||||
enc_options.allow_mixed = 1;
|
enc_options.allow_mixed = 1;
|
||||||
config.lossless = 0;
|
config.lossless = 0;
|
||||||
} else if (!strcmp(argv[c], "-loop_compatibility")) {
|
|
||||||
loop_compatibility = 1;
|
|
||||||
} else if (!strcmp(argv[c], "-q") && c < argc - 1) {
|
} else if (!strcmp(argv[c], "-q") && c < argc - 1) {
|
||||||
config.quality = ExUtilGetFloat(argv[++c], &parse_error);
|
config.quality = ExUtilGetFloat(argv[++c], &parse_error);
|
||||||
} else if (!strcmp(argv[c], "-m") && c < argc - 1) {
|
} else if (!strcmp(argv[c], "-m") && c < argc - 1) {
|
||||||
@ -271,11 +258,9 @@ int main(int argc, const char *argv[]) {
|
|||||||
|
|
||||||
// Start the decoder object
|
// Start the decoder object
|
||||||
#if LOCAL_GIF_PREREQ(5,0)
|
#if LOCAL_GIF_PREREQ(5,0)
|
||||||
gif = !strcmp(in_file, "-") ? DGifOpenFileHandle(STDIN_FILENO, &gif_error)
|
gif = DGifOpenFileName(in_file, &gif_error);
|
||||||
: DGifOpenFileName(in_file, &gif_error);
|
|
||||||
#else
|
#else
|
||||||
gif = !strcmp(in_file, "-") ? DGifOpenFileHandle(STDIN_FILENO)
|
gif = DGifOpenFileName(in_file);
|
||||||
: DGifOpenFileName(in_file);
|
|
||||||
#endif
|
#endif
|
||||||
if (gif == NULL) goto End;
|
if (gif == NULL) goto End;
|
||||||
|
|
||||||
@ -292,7 +277,7 @@ int main(int argc, const char *argv[]) {
|
|||||||
|
|
||||||
if (!DGifGetImageDesc(gif)) goto End;
|
if (!DGifGetImageDesc(gif)) goto End;
|
||||||
|
|
||||||
if (frame_number == 0) {
|
if (is_first_frame) {
|
||||||
if (verbose) {
|
if (verbose) {
|
||||||
printf("Canvas screen: %d x %d\n", gif->SWidth, gif->SHeight);
|
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");
|
"a memory error.\n");
|
||||||
goto End;
|
goto End;
|
||||||
}
|
}
|
||||||
|
is_first_frame = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Some even more broken GIF can have sub-rect with zero width/height.
|
// 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);
|
GIFBlendFrames(&frame, &gif_rect, &curr_canvas);
|
||||||
|
|
||||||
if (!WebPAnimEncoderAdd(enc, &curr_canvas, frame_timestamp, &config)) {
|
if (!WebPAnimEncoderAdd(enc, &curr_canvas, frame_timestamp, &config)) {
|
||||||
fprintf(stderr, "Error while adding frame #%d: %s\n", frame_number,
|
fprintf(stderr, "%s\n", WebPAnimEncoderGetError(enc));
|
||||||
WebPAnimEncoderGetError(enc));
|
|
||||||
goto End;
|
|
||||||
} else {
|
|
||||||
++frame_number;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update canvases.
|
// Update canvases.
|
||||||
GIFDisposeFrame(orig_dispose, &gif_rect, &prev_canvas, &curr_canvas);
|
GIFDisposeFrame(orig_dispose, &gif_rect, &prev_canvas, &curr_canvas);
|
||||||
GIFCopyPixels(&curr_canvas, &prev_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).
|
// Update timestamp (for next frame).
|
||||||
frame_timestamp += frame_duration;
|
frame_timestamp += frame_duration;
|
||||||
|
|
||||||
@ -412,7 +386,7 @@ int main(int argc, const char *argv[]) {
|
|||||||
if (verbose) {
|
if (verbose) {
|
||||||
fprintf(stderr, "Loop count: %d\n", loop_count);
|
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.
|
} else { // An extension containing metadata.
|
||||||
// We only store the first encountered chunk of each type, and
|
// We only store the first encountered chunk of each type, and
|
||||||
// only if requested by the user.
|
// only if requested by the user.
|
||||||
@ -469,23 +443,6 @@ int main(int argc, const char *argv[]) {
|
|||||||
goto End;
|
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) {
|
if (stored_loop_count || stored_icc || stored_xmp) {
|
||||||
// Re-mux to add loop count and/or metadata as needed.
|
// Re-mux to add loop count and/or metadata as needed.
|
||||||
mux = WebPMuxCreate(&webp_data, 1);
|
mux = WebPMuxCreate(&webp_data, 1);
|
||||||
@ -550,13 +507,8 @@ int main(int argc, const char *argv[]) {
|
|||||||
goto End;
|
goto End;
|
||||||
}
|
}
|
||||||
if (!quiet) {
|
if (!quiet) {
|
||||||
if (!strcmp(out_file, "-")) {
|
fprintf(stderr, "Saved output file (%d bytes): %s\n",
|
||||||
fprintf(stderr, "Saved %d bytes to STDIO\n",
|
(int)webp_data.size, out_file);
|
||||||
(int)webp_data.size);
|
|
||||||
} else {
|
|
||||||
fprintf(stderr, "Saved output file (%d bytes): %s\n",
|
|
||||||
(int)webp_data.size, out_file);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!quiet) {
|
if (!quiet) {
|
||||||
|
@ -48,7 +48,6 @@ static void Help(void) {
|
|||||||
printf(" -mixed ............... use mixed lossy/lossless automatic mode\n");
|
printf(" -mixed ............... use mixed lossy/lossless automatic mode\n");
|
||||||
printf(" -v ................... verbose mode\n");
|
printf(" -v ................... verbose mode\n");
|
||||||
printf(" -h ................... this help\n");
|
printf(" -h ................... this help\n");
|
||||||
printf(" -version ............. print version number and exit\n");
|
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
|
||||||
printf("Per-frame options (only used for subsequent images input):\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;
|
const char* output = NULL;
|
||||||
WebPAnimEncoder* enc = NULL;
|
WebPAnimEncoder* enc = NULL;
|
||||||
int verbose = 0;
|
int verbose = 0;
|
||||||
int pic_num = 0;
|
int pic_num = 0;
|
||||||
int duration = 100;
|
int duration = 100;
|
||||||
int timestamp_ms = 0;
|
int timestamp_ms = 0;
|
||||||
|
int ok = 1;
|
||||||
int loop_count = 0;
|
int loop_count = 0;
|
||||||
int width = 0, height = 0;
|
int width = 0, height = 0;
|
||||||
WebPAnimEncoderOptions anim_config;
|
WebPAnimEncoderOptions anim_config;
|
||||||
@ -133,23 +133,17 @@ int main(int argc, const char* argv[]) {
|
|||||||
WebPData webp_data;
|
WebPData webp_data;
|
||||||
int c;
|
int c;
|
||||||
int have_input = 0;
|
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);
|
WebPDataInit(&webp_data);
|
||||||
if (!WebPAnimEncoderOptionsInit(&anim_config) ||
|
if (!WebPAnimEncoderOptionsInit(&anim_config) ||
|
||||||
!WebPConfigInit(&config) ||
|
!WebPConfigInit(&config) ||
|
||||||
!WebPPictureInit(&pic)) {
|
!WebPPictureInit(&pic)) {
|
||||||
fprintf(stderr, "Library version mismatch!\n");
|
fprintf(stderr, "Library version mismatch!\n");
|
||||||
ok = 0;
|
return 1;
|
||||||
goto End;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 1st pass of option parsing
|
// 1st pass of option parsing
|
||||||
for (c = 0; ok && c < argc; ++c) {
|
for (c = 1; ok && c < argc; ++c) {
|
||||||
if (argv[c][0] == '-') {
|
if (argv[c][0] == '-') {
|
||||||
int parse_error = 0;
|
int parse_error = 0;
|
||||||
if (!strcmp(argv[c], "-o") && c + 1 < argc) {
|
if (!strcmp(argv[c], "-o") && c + 1 < argc) {
|
||||||
@ -177,15 +171,7 @@ int main(int argc, const char* argv[]) {
|
|||||||
verbose = 1;
|
verbose = 1;
|
||||||
} else if (!strcmp(argv[c], "-h") || !strcmp(argv[c], "-help")) {
|
} else if (!strcmp(argv[c], "-h") || !strcmp(argv[c], "-help")) {
|
||||||
Help();
|
Help();
|
||||||
goto End;
|
return 0;
|
||||||
} 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;
|
|
||||||
} else {
|
} else {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -198,13 +184,13 @@ int main(int argc, const char* argv[]) {
|
|||||||
}
|
}
|
||||||
if (!have_input) {
|
if (!have_input) {
|
||||||
fprintf(stderr, "No input file(s) for generating animation!\n");
|
fprintf(stderr, "No input file(s) for generating animation!\n");
|
||||||
goto End;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// image-reading pass
|
// image-reading pass
|
||||||
pic_num = 0;
|
pic_num = 0;
|
||||||
config.lossless = 1;
|
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] == NULL) continue;
|
||||||
if (argv[c][0] == '-') { // parse local options
|
if (argv[c][0] == '-') { // parse local options
|
||||||
int parse_error = 0;
|
int parse_error = 0;
|
||||||
@ -308,7 +294,7 @@ int main(int argc, const char* argv[]) {
|
|||||||
fprintf(stderr, "[%d frames, %u bytes].\n",
|
fprintf(stderr, "[%d frames, %u bytes].\n",
|
||||||
pic_num, (unsigned int)webp_data.size);
|
pic_num, (unsigned int)webp_data.size);
|
||||||
}
|
}
|
||||||
|
|
||||||
WebPDataClear(&webp_data);
|
WebPDataClear(&webp_data);
|
||||||
ExUtilDeleteCommandLineArguments(&cmd_args);
|
|
||||||
return ok ? 0 : 1;
|
return ok ? 0 : 1;
|
||||||
}
|
}
|
||||||
|
@ -205,11 +205,6 @@ static void decode_callback(int what) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
duration = curr->duration;
|
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()) {
|
if (!Decode()) {
|
||||||
kParams.decoding_error = 1;
|
kParams.decoding_error = 1;
|
||||||
@ -253,9 +248,9 @@ static void HandleKey(unsigned char key, int pos_x, int pos_y) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (key == 'i') {
|
} 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;
|
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();
|
if (!kParams.has_animation) ClearPreviousFrame();
|
||||||
glutPostRedisplay();
|
glutPostRedisplay();
|
||||||
} else if (key == 'd') {
|
} 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) {
|
static void HandleReshape(int width, int height) {
|
||||||
// Note: reshape doesn't preserve aspect ratio, and might
|
// TODO(skal): should we preserve aspect ratio?
|
||||||
// be handling larger-than-screen pictures incorrectly.
|
// Also: handle larger-than-screen pictures correctly.
|
||||||
glViewport(0, 0, width, height);
|
glViewport(0, 0, width, height);
|
||||||
glMatrixMode(GL_PROJECTION);
|
glMatrixMode(GL_PROJECTION);
|
||||||
glLoadIdentity();
|
glLoadIdentity();
|
||||||
@ -383,23 +378,13 @@ static void HandleDisplay(void) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
glPopMatrix();
|
glPopMatrix();
|
||||||
#if defined(__APPLE__) || defined(_WIN32)
|
|
||||||
glFlush();
|
|
||||||
#else
|
|
||||||
glutSwapBuffers();
|
glutSwapBuffers();
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void StartDisplay(void) {
|
static void StartDisplay(void) {
|
||||||
const int width = kParams.canvas_width;
|
const int width = kParams.canvas_width;
|
||||||
const int height = kParams.canvas_height;
|
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);
|
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);
|
||||||
#endif
|
|
||||||
glutInitWindowSize(width, height);
|
glutInitWindowSize(width, height);
|
||||||
glutCreateWindow("WebP viewer");
|
glutCreateWindow("WebP viewer");
|
||||||
glutDisplayFunc(HandleDisplay);
|
glutDisplayFunc(HandleDisplay);
|
||||||
|
@ -233,20 +233,20 @@ static int GetSignedBits(const uint8_t* const data, size_t data_size, size_t nb,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define GET_BITS(v, n) \
|
#define GET_BITS(v, n) \
|
||||||
do { \
|
do { \
|
||||||
if (!GetBits(data, data_size, n, &(v), bit_pos)) { \
|
if (!GetBits(data, data_size, n, &v, bit_pos)) { \
|
||||||
LOG_ERROR("Truncated lossy bitstream."); \
|
LOG_ERROR("Truncated lossy bitstream."); \
|
||||||
return WEBP_INFO_TRUNCATED_DATA; \
|
return WEBP_INFO_TRUNCATED_DATA; \
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define GET_SIGNED_BITS(v, n) \
|
#define GET_SIGNED_BITS(v, n) \
|
||||||
do { \
|
do { \
|
||||||
if (!GetSignedBits(data, data_size, n, &(v), bit_pos)) { \
|
if (!GetSignedBits(data, data_size, n, &v, bit_pos)) { \
|
||||||
LOG_ERROR("Truncated lossy bitstream."); \
|
LOG_ERROR("Truncated lossy bitstream."); \
|
||||||
return WEBP_INFO_TRUNCATED_DATA; \
|
return WEBP_INFO_TRUNCATED_DATA; \
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
static WebPInfoStatus ParseLossySegmentHeader(const WebPInfo* const webp_info,
|
static WebPInfoStatus ParseLossySegmentHeader(const WebPInfo* const webp_info,
|
||||||
@ -340,7 +340,7 @@ static WebPInfoStatus ParseLossyHeader(const ChunkData* const chunk_data,
|
|||||||
WebPInfoStatus status = WEBP_INFO_OK;
|
WebPInfoStatus status = WEBP_INFO_OK;
|
||||||
uint64_t bit_position = 0;
|
uint64_t bit_position = 0;
|
||||||
uint64_t* const bit_pos = &bit_position;
|
uint64_t* const bit_pos = &bit_position;
|
||||||
int colorspace, clamp_type;
|
int color_space, clamp_type;
|
||||||
printf(" Parsing lossy bitstream...\n");
|
printf(" Parsing lossy bitstream...\n");
|
||||||
// Calling WebPGetFeatures() in ProcessImageChunk() should ensure this.
|
// Calling WebPGetFeatures() in ProcessImageChunk() should ensure this.
|
||||||
assert(chunk_data->size_ >= CHUNK_HEADER_SIZE + 10);
|
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.");
|
LOG_ERROR("Bad partition length.");
|
||||||
return WEBP_INFO_BITSTREAM_ERROR;
|
return WEBP_INFO_BITSTREAM_ERROR;
|
||||||
}
|
}
|
||||||
GET_BITS(colorspace, 1);
|
GET_BITS(color_space, 1);
|
||||||
GET_BITS(clamp_type, 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);
|
printf(" Clamp type: %d\n", clamp_type);
|
||||||
status = ParseLossySegmentHeader(webp_info, data, data_size, bit_pos);
|
status = ParseLossySegmentHeader(webp_info, data, data_size, bit_pos);
|
||||||
if (status != WEBP_INFO_OK) return status;
|
if (status != WEBP_INFO_OK) return status;
|
||||||
@ -462,12 +462,12 @@ static int LLGetBits(const uint8_t* const data, size_t data_size, size_t nb,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define LL_GET_BITS(v, n) \
|
#define LL_GET_BITS(v, n) \
|
||||||
do { \
|
do { \
|
||||||
if (!LLGetBits(data, data_size, n, &(v), bit_pos)) { \
|
if (!LLGetBits(data, data_size, n, &v, bit_pos)) { \
|
||||||
LOG_ERROR("Truncated lossless bitstream."); \
|
LOG_ERROR("Truncated lossless bitstream."); \
|
||||||
return WEBP_INFO_TRUNCATED_DATA; \
|
return WEBP_INFO_TRUNCATED_DATA; \
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
static WebPInfoStatus ParseLosslessTransform(WebPInfo* const webp_info,
|
static WebPInfoStatus ParseLosslessTransform(WebPInfo* const webp_info,
|
||||||
@ -817,8 +817,9 @@ static WebPInfoStatus ProcessImageChunk(const ChunkData* const chunk_data,
|
|||||||
if (webp_info->seen_image_subchunk_) {
|
if (webp_info->seen_image_subchunk_) {
|
||||||
LOG_ERROR("Consecutive VP8/VP8L sub-chunks in an ANMF chunk.");
|
LOG_ERROR("Consecutive VP8/VP8L sub-chunks in an ANMF chunk.");
|
||||||
return WEBP_INFO_PARSE_ERROR;
|
return WEBP_INFO_PARSE_ERROR;
|
||||||
|
} else {
|
||||||
|
webp_info->seen_image_subchunk_ = 1;
|
||||||
}
|
}
|
||||||
webp_info->seen_image_subchunk_ = 1;
|
|
||||||
} else {
|
} else {
|
||||||
if (webp_info->chunk_counts_[CHUNK_VP8] ||
|
if (webp_info->chunk_counts_[CHUNK_VP8] ||
|
||||||
webp_info->chunk_counts_[CHUNK_VP8L]) {
|
webp_info->chunk_counts_[CHUNK_VP8L]) {
|
||||||
@ -872,9 +873,9 @@ static WebPInfoStatus ProcessALPHChunk(const ChunkData* const chunk_data,
|
|||||||
if (webp_info->seen_alpha_subchunk_) {
|
if (webp_info->seen_alpha_subchunk_) {
|
||||||
LOG_ERROR("Consecutive ALPH sub-chunks in an ANMF chunk.");
|
LOG_ERROR("Consecutive ALPH sub-chunks in an ANMF chunk.");
|
||||||
return WEBP_INFO_PARSE_ERROR;
|
return WEBP_INFO_PARSE_ERROR;
|
||||||
|
} else {
|
||||||
|
webp_info->seen_alpha_subchunk_ = 1;
|
||||||
}
|
}
|
||||||
webp_info->seen_alpha_subchunk_ = 1;
|
|
||||||
|
|
||||||
if (webp_info->seen_image_subchunk_) {
|
if (webp_info->seen_image_subchunk_) {
|
||||||
LOG_ERROR("ALPHA sub-chunk detected after VP8 sub-chunk "
|
LOG_ERROR("ALPHA sub-chunk detected after VP8 sub-chunk "
|
||||||
"in an ANMF chunk.");
|
"in an ANMF chunk.");
|
||||||
@ -1106,7 +1107,6 @@ static void HelpLong(void) {
|
|||||||
"Note: there could be multiple input files;\n"
|
"Note: there could be multiple input files;\n"
|
||||||
" options must come before input files.\n"
|
" options must come before input files.\n"
|
||||||
"Options:\n"
|
"Options:\n"
|
||||||
" -version ........... Print version number and exit.\n"
|
|
||||||
" -quiet ............. Do not show chunk parsing information.\n"
|
" -quiet ............. Do not show chunk parsing information.\n"
|
||||||
" -diag .............. Show parsing error diagnosis.\n"
|
" -diag .............. Show parsing error diagnosis.\n"
|
||||||
" -summary ........... Show chunk stats summary.\n"
|
" -summary ........... Show chunk stats summary.\n"
|
||||||
@ -1140,11 +1140,6 @@ int main(int argc, const char* argv[]) {
|
|||||||
show_summary = 1;
|
show_summary = 1;
|
||||||
} else if (!strcmp(argv[c], "-bitstream_info")) {
|
} else if (!strcmp(argv[c], "-bitstream_info")) {
|
||||||
parse_bitstream = 1;
|
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.
|
} else { // Assume the remaining are all input files.
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -47,7 +47,6 @@
|
|||||||
webpmux -info in.webp
|
webpmux -info in.webp
|
||||||
webpmux [ -h | -help ]
|
webpmux [ -h | -help ]
|
||||||
webpmux -version
|
webpmux -version
|
||||||
webpmux argument_file_name
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
@ -109,26 +108,28 @@ static const char* const kDescriptions[LAST_FEATURE] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
CommandLineArguments cmd_args_;
|
|
||||||
|
|
||||||
ActionType action_type_;
|
|
||||||
const char* input_;
|
|
||||||
const char* output_;
|
|
||||||
FeatureType type_;
|
FeatureType type_;
|
||||||
FeatureArg* args_;
|
FeatureArg* args_;
|
||||||
int arg_count_;
|
int arg_count_;
|
||||||
} Config;
|
} Feature;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
ActionType action_type_;
|
||||||
|
const char* input_;
|
||||||
|
const char* output_;
|
||||||
|
Feature feature_;
|
||||||
|
} WebPMuxConfig;
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Helper functions.
|
// Helper functions.
|
||||||
|
|
||||||
static int CountOccurrences(const CommandLineArguments* const args,
|
static int CountOccurrences(const char* arglist[], int list_length,
|
||||||
const char* const arg) {
|
const char* arg) {
|
||||||
int i;
|
int i;
|
||||||
int num_occurences = 0;
|
int num_occurences = 0;
|
||||||
|
|
||||||
for (i = 0; i < args->argc_; ++i) {
|
for (i = 0; i < list_length; ++i) {
|
||||||
if (!strcmp(args->argv_[i], arg)) {
|
if (!strcmp(arglist[i], arg)) {
|
||||||
++num_occurences;
|
++num_occurences;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -300,7 +301,6 @@ static void PrintHelp(void) {
|
|||||||
printf(" webpmux -info INPUT\n");
|
printf(" webpmux -info INPUT\n");
|
||||||
printf(" webpmux [-h|-help]\n");
|
printf(" webpmux [-h|-help]\n");
|
||||||
printf(" webpmux -version\n");
|
printf(" webpmux -version\n");
|
||||||
printf(" webpmux argument_file_name\n");
|
|
||||||
|
|
||||||
printf("\n");
|
printf("\n");
|
||||||
printf("GET_OPTIONS:\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("\nNote: The nature of EXIF, XMP and ICC data is not checked");
|
||||||
printf(" and is assumed to be\nvalid.\n");
|
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) {
|
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) {
|
static int CreateMux(const char* const filename, WebPMux** mux) {
|
||||||
WebPData bitstream;
|
WebPData bitstream;
|
||||||
assert(mux != NULL);
|
assert(mux != NULL);
|
||||||
if (!ExUtilReadFileToWebPData(filename, &bitstream)) return 0;
|
if (!ReadFileToWebPData(filename, &bitstream)) return 0;
|
||||||
*mux = WebPMuxCreate(&bitstream, 1);
|
*mux = WebPMuxCreate(&bitstream, 1);
|
||||||
WebPDataClear(&bitstream);
|
free((void*)bitstream.bytes);
|
||||||
if (*mux != NULL) return 1;
|
if (*mux != NULL) return 1;
|
||||||
fprintf(stderr, "Failed to create mux object from file %s.\n", filename);
|
fprintf(stderr, "Failed to create mux object from file %s.\n", filename);
|
||||||
return 0;
|
return 0;
|
||||||
@ -511,10 +517,9 @@ static int ParseBgcolorArgs(const char* args, uint32_t* const bgcolor) {
|
|||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Clean-up.
|
// Clean-up.
|
||||||
|
|
||||||
static void DeleteConfig(Config* const config) {
|
static void DeleteConfig(WebPMuxConfig* config) {
|
||||||
if (config != NULL) {
|
if (config != NULL) {
|
||||||
free(config->args_);
|
free(config->feature_.args_);
|
||||||
ExUtilDeleteCommandLineArguments(&config->cmd_args_);
|
|
||||||
memset(config, 0, sizeof(*config));
|
memset(config, 0, sizeof(*config));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -526,7 +531,7 @@ static void DeleteConfig(Config* const config) {
|
|||||||
// Returns 1 on valid, 0 otherwise.
|
// Returns 1 on valid, 0 otherwise.
|
||||||
// Also fills up num_feature_args to be number of feature arguments given.
|
// 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).
|
// (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_feature_args) {
|
||||||
int num_frame_args;
|
int num_frame_args;
|
||||||
int num_loop_args;
|
int num_loop_args;
|
||||||
@ -538,27 +543,27 @@ static int ValidateCommandLine(const CommandLineArguments* const cmd_args,
|
|||||||
*num_feature_args = 0;
|
*num_feature_args = 0;
|
||||||
|
|
||||||
// Simple checks.
|
// Simple checks.
|
||||||
if (CountOccurrences(cmd_args, "-get") > 1) {
|
if (CountOccurrences(argv, argc, "-get") > 1) {
|
||||||
ERROR_GOTO1("ERROR: Multiple '-get' arguments specified.\n", ErrValidate);
|
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);
|
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);
|
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);
|
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);
|
ERROR_GOTO1("ERROR: Multiple output files specified.\n", ErrValidate);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compound checks.
|
// Compound checks.
|
||||||
num_frame_args = CountOccurrences(cmd_args, "-frame");
|
num_frame_args = CountOccurrences(argv, argc, "-frame");
|
||||||
num_loop_args = CountOccurrences(cmd_args, "-loop");
|
num_loop_args = CountOccurrences(argv, argc, "-loop");
|
||||||
num_bgcolor_args = CountOccurrences(cmd_args, "-bgcolor");
|
num_bgcolor_args = CountOccurrences(argv, argc, "-bgcolor");
|
||||||
num_durations_args = CountOccurrences(cmd_args, "-duration");
|
num_durations_args = CountOccurrences(argv, argc, "-duration");
|
||||||
|
|
||||||
if (num_loop_args > 1) {
|
if (num_loop_args > 1) {
|
||||||
ERROR_GOTO1("ERROR: Multiple loop counts specified.\n", ErrValidate);
|
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 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) \
|
#define CHECK_NUM_ARGS_LESS(NUM, LABEL) \
|
||||||
if (argc < i + (NUM)) { \
|
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
|
// Parses command-line arguments to fill up config object. Also performs some
|
||||||
// semantic checks.
|
// semantic checks.
|
||||||
static int ParseCommandLine(Config* config) {
|
static int ParseCommandLine(int argc, const char* argv[],
|
||||||
|
WebPMuxConfig* config) {
|
||||||
int i = 0;
|
int i = 0;
|
||||||
int feature_arg_index = 0;
|
int feature_arg_index = 0;
|
||||||
int ok = 1;
|
int ok = 1;
|
||||||
int argc = config->cmd_args_.argc_;
|
|
||||||
const char* const* argv = config->cmd_args_.argv_;
|
|
||||||
|
|
||||||
while (i < argc) {
|
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 (argv[i][0] == '-') { // One of the action types or output.
|
||||||
if (!strcmp(argv[i], "-set")) {
|
if (!strcmp(argv[i], "-set")) {
|
||||||
if (ACTION_IS_NIL) {
|
if (ACTION_IS_NIL) {
|
||||||
@ -633,8 +638,8 @@ static int ParseCommandLine(Config* config) {
|
|||||||
} else {
|
} else {
|
||||||
ERROR_GOTO1("ERROR: Multiple actions specified.\n", ErrParse);
|
ERROR_GOTO1("ERROR: Multiple actions specified.\n", ErrParse);
|
||||||
}
|
}
|
||||||
if (FEATURETYPE_IS_NIL || config->type_ == FEATURE_DURATION) {
|
if (FEATURETYPE_IS_NIL || feature->type_ == FEATURE_DURATION) {
|
||||||
config->type_ = FEATURE_DURATION;
|
feature->type_ = FEATURE_DURATION;
|
||||||
} else {
|
} else {
|
||||||
ERROR_GOTO1("ERROR: Multiple features specified.\n", ErrParse);
|
ERROR_GOTO1("ERROR: Multiple features specified.\n", ErrParse);
|
||||||
}
|
}
|
||||||
@ -651,7 +656,7 @@ static int ParseCommandLine(Config* config) {
|
|||||||
} else if (!strcmp(argv[i], "-strip")) {
|
} else if (!strcmp(argv[i], "-strip")) {
|
||||||
if (ACTION_IS_NIL) {
|
if (ACTION_IS_NIL) {
|
||||||
config->action_type_ = ACTION_STRIP;
|
config->action_type_ = ACTION_STRIP;
|
||||||
config->arg_count_ = 0;
|
feature->arg_count_ = 0;
|
||||||
} else {
|
} else {
|
||||||
ERROR_GOTO1("ERROR: Multiple actions specified.\n", ErrParse);
|
ERROR_GOTO1("ERROR: Multiple actions specified.\n", ErrParse);
|
||||||
}
|
}
|
||||||
@ -663,8 +668,8 @@ static int ParseCommandLine(Config* config) {
|
|||||||
} else {
|
} else {
|
||||||
ERROR_GOTO1("ERROR: Multiple actions specified.\n", ErrParse);
|
ERROR_GOTO1("ERROR: Multiple actions specified.\n", ErrParse);
|
||||||
}
|
}
|
||||||
if (FEATURETYPE_IS_NIL || config->type_ == FEATURE_ANMF) {
|
if (FEATURETYPE_IS_NIL || feature->type_ == FEATURE_ANMF) {
|
||||||
config->type_ = FEATURE_ANMF;
|
feature->type_ = FEATURE_ANMF;
|
||||||
} else {
|
} else {
|
||||||
ERROR_GOTO1("ERROR: Multiple features specified.\n", ErrParse);
|
ERROR_GOTO1("ERROR: Multiple features specified.\n", ErrParse);
|
||||||
}
|
}
|
||||||
@ -680,8 +685,8 @@ static int ParseCommandLine(Config* config) {
|
|||||||
} else {
|
} else {
|
||||||
ERROR_GOTO1("ERROR: Multiple actions specified.\n", ErrParse);
|
ERROR_GOTO1("ERROR: Multiple actions specified.\n", ErrParse);
|
||||||
}
|
}
|
||||||
if (FEATURETYPE_IS_NIL || config->type_ == FEATURE_ANMF) {
|
if (FEATURETYPE_IS_NIL || feature->type_ == FEATURE_ANMF) {
|
||||||
config->type_ = FEATURE_ANMF;
|
feature->type_ = FEATURE_ANMF;
|
||||||
} else {
|
} else {
|
||||||
ERROR_GOTO1("ERROR: Multiple features specified.\n", ErrParse);
|
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);
|
ERROR_GOTO1("ERROR: Multiple actions specified.\n", ErrParse);
|
||||||
} else {
|
} else {
|
||||||
config->action_type_ = ACTION_INFO;
|
config->action_type_ = ACTION_INFO;
|
||||||
config->arg_count_ = 0;
|
feature->arg_count_ = 0;
|
||||||
config->input_ = argv[i + 1];
|
config->input_ = argv[i + 1];
|
||||||
}
|
}
|
||||||
i += 2;
|
i += 2;
|
||||||
@ -736,7 +741,7 @@ static int ParseCommandLine(Config* config) {
|
|||||||
if (!strcmp(argv[i], "icc") || !strcmp(argv[i], "exif") ||
|
if (!strcmp(argv[i], "icc") || !strcmp(argv[i], "exif") ||
|
||||||
!strcmp(argv[i], "xmp")) {
|
!strcmp(argv[i], "xmp")) {
|
||||||
if (FEATURETYPE_IS_NIL) {
|
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;
|
(!strcmp(argv[i], "exif")) ? FEATURE_EXIF : FEATURE_XMP;
|
||||||
} else {
|
} else {
|
||||||
ERROR_GOTO1("ERROR: Multiple features specified.\n", ErrParse);
|
ERROR_GOTO1("ERROR: Multiple features specified.\n", ErrParse);
|
||||||
@ -752,7 +757,7 @@ static int ParseCommandLine(Config* config) {
|
|||||||
} else if (!strcmp(argv[i], "frame") &&
|
} else if (!strcmp(argv[i], "frame") &&
|
||||||
(config->action_type_ == ACTION_GET)) {
|
(config->action_type_ == ACTION_GET)) {
|
||||||
CHECK_NUM_ARGS_LESS(2, ErrParse);
|
CHECK_NUM_ARGS_LESS(2, ErrParse);
|
||||||
config->type_ = FEATURE_ANMF;
|
feature->type_ = FEATURE_ANMF;
|
||||||
arg->params_ = argv[i + 1];
|
arg->params_ = argv[i + 1];
|
||||||
++feature_arg_index;
|
++feature_arg_index;
|
||||||
i += 2;
|
i += 2;
|
||||||
@ -772,8 +777,9 @@ static int ParseCommandLine(Config* config) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Additional checks after config is filled.
|
// Additional checks after config is filled.
|
||||||
static int ValidateConfig(Config* const config) {
|
static int ValidateConfig(WebPMuxConfig* config) {
|
||||||
int ok = 1;
|
int ok = 1;
|
||||||
|
Feature* const feature = &config->feature_;
|
||||||
|
|
||||||
// Action.
|
// Action.
|
||||||
if (ACTION_IS_NIL) {
|
if (ACTION_IS_NIL) {
|
||||||
@ -789,7 +795,7 @@ static int ValidateConfig(Config* const config) {
|
|||||||
if (config->input_ == NULL) {
|
if (config->input_ == NULL) {
|
||||||
if (config->action_type_ != ACTION_SET) {
|
if (config->action_type_ != ACTION_SET) {
|
||||||
ERROR_GOTO1("ERROR: No input file specified.\n", ErrValidate2);
|
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);
|
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.
|
// Create config object from command-line arguments.
|
||||||
static int InitializeConfig(int argc, const char* argv[],
|
static int InitializeConfig(int argc, const char* argv[],
|
||||||
Config* const config) {
|
WebPMuxConfig* config) {
|
||||||
int num_feature_args = 0;
|
int num_feature_args = 0;
|
||||||
int ok;
|
int ok = 1;
|
||||||
|
|
||||||
|
assert(config != NULL);
|
||||||
memset(config, 0, sizeof(*config));
|
memset(config, 0, sizeof(*config));
|
||||||
|
|
||||||
ok = ExUtilInitCommandLineArguments(argc, argv, &config->cmd_args_);
|
|
||||||
if (!ok) return 0;
|
|
||||||
|
|
||||||
// Validate command-line arguments.
|
// 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);
|
ERROR_GOTO1("Exiting due to command-line parsing error.\n", Err1);
|
||||||
}
|
}
|
||||||
|
|
||||||
config->arg_count_ = num_feature_args;
|
config->feature_.arg_count_ = num_feature_args;
|
||||||
config->args_ = (FeatureArg*)calloc(num_feature_args, sizeof(*config->args_));
|
config->feature_.args_ =
|
||||||
if (config->args_ == NULL) {
|
(FeatureArg*)calloc(num_feature_args, sizeof(*config->feature_.args_));
|
||||||
|
if (config->feature_.args_ == NULL) {
|
||||||
ERROR_GOTO1("ERROR: Memory allocation error.\n", Err1);
|
ERROR_GOTO1("ERROR: Memory allocation error.\n", Err1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse command-line.
|
// 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);
|
ERROR_GOTO1("Exiting due to command-line parsing error.\n", Err1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -842,7 +847,7 @@ static int InitializeConfig(int argc, const char* argv[],
|
|||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Processing.
|
// Processing.
|
||||||
|
|
||||||
static int GetFrame(const WebPMux* mux, const Config* config) {
|
static int GetFrame(const WebPMux* mux, const WebPMuxConfig* config) {
|
||||||
WebPMuxError err = WEBP_MUX_OK;
|
WebPMuxError err = WEBP_MUX_OK;
|
||||||
WebPMux* mux_single = NULL;
|
WebPMux* mux_single = NULL;
|
||||||
int num = 0;
|
int num = 0;
|
||||||
@ -852,7 +857,7 @@ static int GetFrame(const WebPMux* mux, const Config* config) {
|
|||||||
WebPMuxFrameInfo info;
|
WebPMuxFrameInfo info;
|
||||||
WebPDataInit(&info.bitstream);
|
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) {
|
if (num < 0) {
|
||||||
ERROR_GOTO1("ERROR: Frame/Fragment index must be non-negative.\n", ErrGet);
|
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.
|
// Read and process config.
|
||||||
static int Process(const Config* config) {
|
static int Process(const WebPMuxConfig* config) {
|
||||||
WebPMux* mux = NULL;
|
WebPMux* mux = NULL;
|
||||||
WebPData chunk;
|
WebPData chunk;
|
||||||
WebPMuxError err = WEBP_MUX_OK;
|
WebPMuxError err = WEBP_MUX_OK;
|
||||||
int ok = 1;
|
int ok = 1;
|
||||||
|
const Feature* const feature = &config->feature_;
|
||||||
|
|
||||||
switch (config->action_type_) {
|
switch (config->action_type_) {
|
||||||
case ACTION_GET: {
|
case ACTION_GET: {
|
||||||
ok = CreateMux(config->input_, &mux);
|
ok = CreateMux(config->input_, &mux);
|
||||||
if (!ok) goto Err2;
|
if (!ok) goto Err2;
|
||||||
switch (config->type_) {
|
switch (feature->type_) {
|
||||||
case FEATURE_ANMF:
|
case FEATURE_ANMF:
|
||||||
ok = GetFrame(mux, config);
|
ok = GetFrame(mux, config);
|
||||||
break;
|
break;
|
||||||
@ -904,10 +910,10 @@ static int Process(const Config* config) {
|
|||||||
case FEATURE_ICCP:
|
case FEATURE_ICCP:
|
||||||
case FEATURE_EXIF:
|
case FEATURE_EXIF:
|
||||||
case FEATURE_XMP:
|
case FEATURE_XMP:
|
||||||
err = WebPMuxGetChunk(mux, kFourccList[config->type_], &chunk);
|
err = WebPMuxGetChunk(mux, kFourccList[feature->type_], &chunk);
|
||||||
if (err != WEBP_MUX_OK) {
|
if (err != WEBP_MUX_OK) {
|
||||||
ERROR_GOTO3("ERROR (%s): Could not get the %s.\n",
|
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);
|
ok = WriteData(config->output_, &chunk);
|
||||||
break;
|
break;
|
||||||
@ -919,7 +925,7 @@ static int Process(const Config* config) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ACTION_SET: {
|
case ACTION_SET: {
|
||||||
switch (config->type_) {
|
switch (feature->type_) {
|
||||||
case FEATURE_ANMF: {
|
case FEATURE_ANMF: {
|
||||||
int i;
|
int i;
|
||||||
WebPMuxAnimParams params = { 0xFFFFFFFF, 0 };
|
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",
|
ERROR_GOTO2("ERROR (%s): Could not allocate a mux object.\n",
|
||||||
ErrorString(WEBP_MUX_MEMORY_ERROR), Err2);
|
ErrorString(WEBP_MUX_MEMORY_ERROR), Err2);
|
||||||
}
|
}
|
||||||
for (i = 0; i < config->arg_count_; ++i) {
|
for (i = 0; i < feature->arg_count_; ++i) {
|
||||||
switch (config->args_[i].subtype_) {
|
switch (feature->args_[i].subtype_) {
|
||||||
case SUBTYPE_BGCOLOR: {
|
case SUBTYPE_BGCOLOR: {
|
||||||
uint32_t bgcolor;
|
uint32_t bgcolor;
|
||||||
ok = ParseBgcolorArgs(config->args_[i].params_, &bgcolor);
|
ok = ParseBgcolorArgs(feature->args_[i].params_, &bgcolor);
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
ERROR_GOTO1("ERROR: Could not parse the background color \n",
|
ERROR_GOTO1("ERROR: Could not parse the background color \n",
|
||||||
Err2);
|
Err2);
|
||||||
@ -943,7 +949,7 @@ static int Process(const Config* config) {
|
|||||||
case SUBTYPE_LOOP: {
|
case SUBTYPE_LOOP: {
|
||||||
int parse_error = 0;
|
int parse_error = 0;
|
||||||
const int loop_count =
|
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) {
|
if (loop_count < 0 || loop_count > 65535) {
|
||||||
// Note: This is only a 'necessary' condition for loop_count
|
// Note: This is only a 'necessary' condition for loop_count
|
||||||
// to be valid. The 'sufficient' conditioned in checked in
|
// to be valid. The 'sufficient' conditioned in checked in
|
||||||
@ -959,10 +965,10 @@ static int Process(const Config* config) {
|
|||||||
case SUBTYPE_ANMF: {
|
case SUBTYPE_ANMF: {
|
||||||
WebPMuxFrameInfo frame;
|
WebPMuxFrameInfo frame;
|
||||||
frame.id = WEBP_CHUNK_ANMF;
|
frame.id = WEBP_CHUNK_ANMF;
|
||||||
ok = ExUtilReadFileToWebPData(config->args_[i].filename_,
|
ok = ReadFileToWebPData(feature->args_[i].filename_,
|
||||||
&frame.bitstream);
|
&frame.bitstream);
|
||||||
if (!ok) goto Err2;
|
if (!ok) goto Err2;
|
||||||
ok = ParseFrameArgs(config->args_[i].params_, &frame);
|
ok = ParseFrameArgs(feature->args_[i].params_, &frame);
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
WebPDataClear(&frame.bitstream);
|
WebPDataClear(&frame.bitstream);
|
||||||
ERROR_GOTO1("ERROR: Could not parse frame properties.\n",
|
ERROR_GOTO1("ERROR: Could not parse frame properties.\n",
|
||||||
@ -995,13 +1001,13 @@ static int Process(const Config* config) {
|
|||||||
case FEATURE_XMP: {
|
case FEATURE_XMP: {
|
||||||
ok = CreateMux(config->input_, &mux);
|
ok = CreateMux(config->input_, &mux);
|
||||||
if (!ok) goto Err2;
|
if (!ok) goto Err2;
|
||||||
ok = ExUtilReadFileToWebPData(config->args_[0].filename_, &chunk);
|
ok = ReadFileToWebPData(feature->args_[0].filename_, &chunk);
|
||||||
if (!ok) goto Err2;
|
if (!ok) goto Err2;
|
||||||
err = WebPMuxSetChunk(mux, kFourccList[config->type_], &chunk, 1);
|
err = WebPMuxSetChunk(mux, kFourccList[feature->type_], &chunk, 1);
|
||||||
free((void*)chunk.bytes);
|
free((void*)chunk.bytes);
|
||||||
if (err != WEBP_MUX_OK) {
|
if (err != WEBP_MUX_OK) {
|
||||||
ERROR_GOTO3("ERROR (%s): Could not set the %s.\n",
|
ERROR_GOTO3("ERROR (%s): Could not set the %s.\n",
|
||||||
ErrorString(err), kDescriptions[config->type_], Err2);
|
ErrorString(err), kDescriptions[feature->type_], Err2);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1037,11 +1043,11 @@ static int Process(const Config* config) {
|
|||||||
for (i = 0; i < num_frames; ++i) durations[i] = -1;
|
for (i = 0; i < num_frames; ++i) durations[i] = -1;
|
||||||
|
|
||||||
// Parse intervals to process.
|
// Parse intervals to process.
|
||||||
for (i = 0; i < config->arg_count_; ++i) {
|
for (i = 0; i < feature->arg_count_; ++i) {
|
||||||
int k;
|
int k;
|
||||||
int args[3];
|
int args[3];
|
||||||
int duration, start, end;
|
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);
|
10, 3, args);
|
||||||
ok = (nb_args >= 1);
|
ok = (nb_args >= 1);
|
||||||
if (!ok) goto Err3;
|
if (!ok) goto Err3;
|
||||||
@ -1099,12 +1105,12 @@ static int Process(const Config* config) {
|
|||||||
case ACTION_STRIP: {
|
case ACTION_STRIP: {
|
||||||
ok = CreateMux(config->input_, &mux);
|
ok = CreateMux(config->input_, &mux);
|
||||||
if (!ok) goto Err2;
|
if (!ok) goto Err2;
|
||||||
if (config->type_ == FEATURE_ICCP || config->type_ == FEATURE_EXIF ||
|
if (feature->type_ == FEATURE_ICCP || feature->type_ == FEATURE_EXIF ||
|
||||||
config->type_ == FEATURE_XMP) {
|
feature->type_ == FEATURE_XMP) {
|
||||||
err = WebPMuxDeleteChunk(mux, kFourccList[config->type_]);
|
err = WebPMuxDeleteChunk(mux, kFourccList[feature->type_]);
|
||||||
if (err != WEBP_MUX_OK) {
|
if (err != WEBP_MUX_OK) {
|
||||||
ERROR_GOTO3("ERROR (%s): Could not strip the %s.\n",
|
ERROR_GOTO3("ERROR (%s): Could not strip the %s.\n",
|
||||||
ErrorString(err), kDescriptions[config->type_], Err2);
|
ErrorString(err), kDescriptions[feature->type_], Err2);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ERROR_GOTO1("ERROR: Invalid feature for action 'strip'.\n", Err2);
|
ERROR_GOTO1("ERROR: Invalid feature for action 'strip'.\n", Err2);
|
||||||
@ -1134,7 +1140,7 @@ static int Process(const Config* config) {
|
|||||||
// Main.
|
// Main.
|
||||||
|
|
||||||
int main(int argc, const char* argv[]) {
|
int main(int argc, const char* argv[]) {
|
||||||
Config config;
|
WebPMuxConfig config;
|
||||||
int ok = InitializeConfig(argc - 1, argv + 1, &config);
|
int ok = InitializeConfig(argc - 1, argv + 1, &config);
|
||||||
if (ok) {
|
if (ok) {
|
||||||
ok = Process(&config);
|
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
|
AM_CPPFLAGS += -I$(top_builddir)/src -I$(top_srcdir)/src
|
||||||
noinst_LTLIBRARIES = libwebpextras.la
|
noinst_LTLIBRARIES = libwebpextras.la
|
||||||
|
|
||||||
@ -13,32 +12,25 @@ libwebpextras_la_LDFLAGS = -lm
|
|||||||
libwebpextras_la_LIBADD = ../src/libwebp.la
|
libwebpextras_la_LIBADD = ../src/libwebp.la
|
||||||
|
|
||||||
noinst_PROGRAMS =
|
noinst_PROGRAMS =
|
||||||
noinst_PROGRAMS += webp_quality
|
noinst_PROGRAMS += get_disto webp_quality
|
||||||
if WANT_DEMUX
|
|
||||||
noinst_PROGRAMS += get_disto
|
|
||||||
endif
|
|
||||||
if BUILD_VWEBP_SDL
|
if BUILD_VWEBP_SDL
|
||||||
noinst_PROGRAMS += vwebp_sdl
|
noinst_PROGRAMS += vwebp_sdl
|
||||||
endif
|
endif
|
||||||
|
|
||||||
get_disto_SOURCES = get_disto.c
|
get_disto_SOURCES = get_disto.c
|
||||||
get_disto_CPPFLAGS = $(AM_CPPFLAGS)
|
get_disto_CPPFLAGS = $(AM_CPPFLAGS)
|
||||||
get_disto_LDADD =
|
get_disto_LDADD = ../imageio/libimageio_util.la ../imageio/libimagedec.la
|
||||||
get_disto_LDADD += ../imageio/libimageio_util.la
|
|
||||||
get_disto_LDADD += ../imageio/libimagedec.la
|
|
||||||
get_disto_LDADD += ../src/libwebp.la
|
get_disto_LDADD += ../src/libwebp.la
|
||||||
get_disto_LDADD += $(PNG_LIBS) $(JPEG_LIBS) $(TIFF_LIBS)
|
get_disto_LDADD += $(PNG_LIBS) $(JPEG_LIBS) $(TIFF_LIBS)
|
||||||
|
|
||||||
webp_quality_SOURCES = webp_quality.c
|
webp_quality_SOURCES = webp_quality.c
|
||||||
webp_quality_CPPFLAGS = $(AM_CPPFLAGS)
|
webp_quality_CPPFLAGS = $(AM_CPPFLAGS) $(USE_EXPERIMENTAL_CODE)
|
||||||
webp_quality_LDADD =
|
webp_quality_LDADD = ../imageio/libimageio_util.la
|
||||||
webp_quality_LDADD += ../imageio/libimageio_util.la
|
|
||||||
webp_quality_LDADD += libwebpextras.la
|
webp_quality_LDADD += libwebpextras.la
|
||||||
webp_quality_LDADD += ../src/libwebp.la
|
webp_quality_LDADD += ../src/libwebp.la
|
||||||
|
|
||||||
vwebp_sdl_SOURCES = vwebp_sdl.c webp_to_sdl.c webp_to_sdl.h
|
vwebp_sdl_SOURCES = vwebp_sdl.c webp_to_sdl.c webp_to_sdl.h
|
||||||
vwebp_sdl_CPPFLAGS = $(AM_CPPFLAGS) $(SDL_INCLUDES)
|
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 += ../src/libwebp.la
|
||||||
vwebp_sdl_LDADD += $(SDL_LIBS)
|
vwebp_sdl_LDADD += $(SDL_LIBS)
|
||||||
|
@ -10,14 +10,14 @@
|
|||||||
// Additional WebP utilities.
|
// Additional WebP utilities.
|
||||||
//
|
//
|
||||||
|
|
||||||
#include "extras/extras.h"
|
#include "./extras.h"
|
||||||
#include "webp/format_constants.h"
|
#include "webp/format_constants.h"
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#define XTRA_MAJ_VERSION 1
|
#define XTRA_MAJ_VERSION 0
|
||||||
#define XTRA_MIN_VERSION 0
|
#define XTRA_MIN_VERSION 1
|
||||||
#define XTRA_REV_VERSION 0
|
#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 WebPImportRGB565(const uint8_t* rgb565, WebPPicture* pic) {
|
||||||
int x, y;
|
int x, y;
|
||||||
uint32_t* dst;
|
|
||||||
if (pic == NULL || rgb565 == NULL) return 0;
|
if (pic == NULL || rgb565 == NULL) return 0;
|
||||||
pic->colorspace = WEBP_YUV420;
|
pic->colorspace = WEBP_YUV420;
|
||||||
pic->use_argb = 1;
|
pic->use_argb = 1;
|
||||||
if (!WebPPictureAlloc(pic)) return 0;
|
if (!WebPPictureAlloc(pic)) return 0;
|
||||||
dst = pic->argb;
|
|
||||||
for (y = 0; y < pic->height; ++y) {
|
for (y = 0; y < pic->height; ++y) {
|
||||||
const int width = pic->width;
|
const int width = pic->width;
|
||||||
|
uint32_t* dst = pic->argb + y * pic->argb_stride;
|
||||||
for (x = 0; x < width; ++x) {
|
for (x = 0; x < width; ++x) {
|
||||||
#ifdef WEBP_SWAP_16BIT_CSP
|
#ifdef WEBP_SWAP_16BIT_CSP
|
||||||
const uint32_t rg = rgb565[2 * x + 1];
|
const uint32_t rg = rgb565[2 * x + 1];
|
||||||
@ -71,24 +70,22 @@ int WebPImportRGB565(const uint8_t* rgb565, WebPPicture* pic) {
|
|||||||
r = r | (r >> 5);
|
r = r | (r >> 5);
|
||||||
g = g | (g >> 6);
|
g = g | (g >> 6);
|
||||||
b = b | (b >> 5);
|
b = b | (b >> 5);
|
||||||
dst[x] = (0xffu << 24) | (r << 16) | (g << 8) | b;
|
dst[x] = (r << 16) | (g << 8) | b;
|
||||||
}
|
}
|
||||||
rgb565 += 2 * width;
|
rgb565 += 2 * width;
|
||||||
dst += pic->argb_stride;
|
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int WebPImportRGB4444(const uint8_t* rgb4444, WebPPicture* pic) {
|
int WebPImportRGB4444(const uint8_t* rgb4444, WebPPicture* pic) {
|
||||||
int x, y;
|
int x, y;
|
||||||
uint32_t* dst;
|
|
||||||
if (pic == NULL || rgb4444 == NULL) return 0;
|
if (pic == NULL || rgb4444 == NULL) return 0;
|
||||||
pic->colorspace = WEBP_YUV420;
|
pic->colorspace = WEBP_YUV420;
|
||||||
pic->use_argb = 1;
|
pic->use_argb = 1;
|
||||||
if (!WebPPictureAlloc(pic)) return 0;
|
if (!WebPPictureAlloc(pic)) return 0;
|
||||||
dst = pic->argb;
|
|
||||||
for (y = 0; y < pic->height; ++y) {
|
for (y = 0; y < pic->height; ++y) {
|
||||||
const int width = pic->width;
|
const int width = pic->width;
|
||||||
|
uint32_t* dst = pic->argb + y * pic->argb_stride;
|
||||||
for (x = 0; x < width; ++x) {
|
for (x = 0; x < width; ++x) {
|
||||||
#ifdef WEBP_SWAP_16BIT_CSP
|
#ifdef WEBP_SWAP_16BIT_CSP
|
||||||
const uint32_t rg = rgb4444[2 * x + 1];
|
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;
|
dst[x] = (a << 24) | (r << 16) | (g << 8) | b;
|
||||||
}
|
}
|
||||||
rgb4444 += 2 * width;
|
rgb4444 += 2 * width;
|
||||||
dst += pic->argb_stride;
|
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -25,28 +25,28 @@ extern "C" {
|
|||||||
|
|
||||||
// Returns the version number of the extras library, packed in hexadecimal using
|
// 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.
|
// 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.
|
// Ad-hoc colorspace importers.
|
||||||
|
|
||||||
// Import luma sample (gray scale image) into 'picture'. The 'picture'
|
// Import luma sample (gray scale image) into 'picture'. The 'picture'
|
||||||
// width and height must be set prior to calling this function.
|
// 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'
|
// Import rgb sample in RGB565 packed format into 'picture'. The 'picture'
|
||||||
// width and height must be set prior to calling this function.
|
// 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'
|
// Import rgb sample in RGB4444 packed format into 'picture'. The 'picture'
|
||||||
// width and height must be set prior to calling this function.
|
// 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
|
// 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,
|
// 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
|
// will be discarded. Returns 'false' in case of error, or if indexed[] contains
|
||||||
// invalid indices.
|
// invalid indices.
|
||||||
WEBP_EXTERN int
|
WEBP_EXTERN(int)
|
||||||
WebPImportColorMappedARGB(const uint8_t* indexed, int indexed_stride,
|
WebPImportColorMappedARGB(const uint8_t* indexed, int indexed_stride,
|
||||||
const uint32_t palette[], int palette_size,
|
const uint32_t palette[], int palette_size,
|
||||||
WebPPicture* pic);
|
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].
|
// Otherwise (lossy bitstream), the returned value is in the range [0..100].
|
||||||
// Any error (invalid bitstream, animated WebP, incomplete header, etc.)
|
// Any error (invalid bitstream, animated WebP, incomplete header, etc.)
|
||||||
// will return a value of -1.
|
// 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 <string.h>
|
||||||
|
|
||||||
#include "webp/encode.h"
|
#include "webp/encode.h"
|
||||||
#include "imageio/image_dec.h"
|
#include "../imageio/image_dec.h"
|
||||||
#include "imageio/imageio_util.h"
|
#include "../imageio/imageio_util.h"
|
||||||
|
|
||||||
static size_t ReadPicture(const char* const filename, WebPPicture* const pic,
|
static size_t ReadPicture(const char* const filename, WebPPicture* const pic,
|
||||||
int keep_alpha) {
|
int keep_alpha) {
|
||||||
@ -290,10 +290,9 @@ int main(int argc, const char *argv[]) {
|
|||||||
fprintf(stderr, "Error while computing the distortion.\n");
|
fprintf(stderr, "Error while computing the distortion.\n");
|
||||||
goto End;
|
goto End;
|
||||||
}
|
}
|
||||||
printf("%u %.2f %.2f %.2f %.2f %.2f [ %.2f bpp ]\n",
|
printf("%u %.2f %.2f %.2f %.2f %.2f\n",
|
||||||
(unsigned int)size1,
|
(unsigned int)size1,
|
||||||
disto[4], disto[0], disto[1], disto[2], disto[3],
|
disto[4], disto[0], disto[1], disto[2], disto[3]);
|
||||||
8.f * size1 / pic1.width / pic1.height);
|
|
||||||
|
|
||||||
if (output != NULL) {
|
if (output != NULL) {
|
||||||
uint8_t* data = 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");
|
fprintf(stderr, "Can only compute the difference map in ARGB format.\n");
|
||||||
goto End;
|
goto End;
|
||||||
}
|
}
|
||||||
#if !defined(WEBP_REDUCE_CSP)
|
|
||||||
data_size = WebPEncodeLosslessBGRA((const uint8_t*)pic1.argb,
|
data_size = WebPEncodeLosslessBGRA((const uint8_t*)pic1.argb,
|
||||||
pic1.width, pic1.height,
|
pic1.width, pic1.height,
|
||||||
pic1.argb_stride * 4,
|
pic1.argb_stride * 4,
|
||||||
@ -335,12 +333,6 @@ int main(int argc, const char *argv[]) {
|
|||||||
ret = ImgIoUtilWriteFile(output, data, data_size) ? 0 : 1;
|
ret = ImgIoUtilWriteFile(output, data, data_size) ? 0 : 1;
|
||||||
WebPFree(data);
|
WebPFree(data);
|
||||||
if (ret) goto End;
|
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;
|
ret = 0;
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
//
|
//
|
||||||
// Author: Skal (pascal.massimino@gmail.com)
|
// Author: Skal (pascal.massimino@gmail.com)
|
||||||
|
|
||||||
#include "extras/extras.h"
|
#include "./extras.h"
|
||||||
#include "webp/decode.h"
|
#include "webp/decode.h"
|
||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
@ -73,7 +73,7 @@ int VP8EstimateQuality(const uint8_t* const data, size_t size) {
|
|||||||
pos += 4;
|
pos += 4;
|
||||||
bit_pos = pos * 8;
|
bit_pos = pos * 8;
|
||||||
|
|
||||||
GET_BIT(2); // colorspace + clamp type
|
GET_BIT(2); // color_space + clamp type
|
||||||
|
|
||||||
// Segment header
|
// Segment header
|
||||||
if (GET_BIT(1)) { // use_segment_
|
if (GET_BIT(1)) { // use_segment_
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
|
|
||||||
#include "webp_to_sdl.h"
|
#include "webp_to_sdl.h"
|
||||||
#include "webp/decode.h"
|
#include "webp/decode.h"
|
||||||
#include "imageio/imageio_util.h"
|
#include "../imageio/imageio_util.h"
|
||||||
|
|
||||||
#if defined(WEBP_HAVE_JUST_SDL_H)
|
#if defined(WEBP_HAVE_JUST_SDL_H)
|
||||||
#include <SDL.h>
|
#include <SDL.h>
|
||||||
|
@ -11,8 +11,8 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "extras/extras.h"
|
#include "./extras.h"
|
||||||
#include "imageio/imageio_util.h"
|
#include "../imageio/imageio_util.h"
|
||||||
|
|
||||||
int main(int argc, const char *argv[]) {
|
int main(int argc, const char *argv[]) {
|
||||||
int c;
|
int c;
|
||||||
|
11
extras/webp_to_sdl.c
Normal file → Executable file
11
extras/webp_to_sdl.c
Normal file → Executable file
@ -12,7 +12,7 @@
|
|||||||
// Author: James Zern (jzern@google.com)
|
// Author: James Zern (jzern@google.com)
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
#include "src/webp/config.h"
|
#include "webp/config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(WEBP_HAVE_SDL)
|
#if defined(WEBP_HAVE_SDL)
|
||||||
@ -20,7 +20,7 @@
|
|||||||
#include "webp_to_sdl.h"
|
#include "webp_to_sdl.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "src/webp/decode.h"
|
#include "webp/decode.h"
|
||||||
|
|
||||||
#if defined(WEBP_HAVE_JUST_SDL_H)
|
#if defined(WEBP_HAVE_JUST_SDL_H)
|
||||||
#include <SDL.h>
|
#include <SDL.h>
|
||||||
@ -28,7 +28,6 @@
|
|||||||
#include <SDL/SDL.h>
|
#include <SDL/SDL.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int init_ok = 0;
|
|
||||||
int WebpToSDL(const char* data, unsigned int data_size) {
|
int WebpToSDL(const char* data, unsigned int data_size) {
|
||||||
int ok = 0;
|
int ok = 0;
|
||||||
VP8StatusCode status;
|
VP8StatusCode status;
|
||||||
@ -43,10 +42,7 @@ int WebpToSDL(const char* data, unsigned int data_size) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!init_ok) {
|
SDL_Init(SDL_INIT_VIDEO);
|
||||||
SDL_Init(SDL_INIT_VIDEO);
|
|
||||||
init_ok = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
status = WebPGetFeatures((uint8_t*)data, (size_t)data_size, &config.input);
|
status = WebPGetFeatures((uint8_t*)data, (size_t)data_size, &config.input);
|
||||||
if (status != VP8_STATUS_OK) goto Error;
|
if (status != VP8_STATUS_OK) goto Error;
|
||||||
@ -101,7 +97,6 @@ int WebpToSDL(const char* data, unsigned int data_size) {
|
|||||||
Error:
|
Error:
|
||||||
SDL_FreeSurface(surface);
|
SDL_FreeSurface(surface);
|
||||||
SDL_FreeSurface(screen);
|
SDL_FreeSurface(screen);
|
||||||
WebPFreeDecBuffer(output);
|
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,20 +1,13 @@
|
|||||||
AM_CPPFLAGS += -I$(top_builddir)/src -I$(top_srcdir)/src
|
AM_CPPFLAGS += -I$(top_builddir)/src -I$(top_srcdir)/src
|
||||||
noinst_LTLIBRARIES =
|
noinst_LTLIBRARIES = libimageio_util.la libimagedec.la libimageenc.la
|
||||||
noinst_LTLIBRARIES += libimageio_util.la
|
|
||||||
if WANT_DEMUX
|
|
||||||
noinst_LTLIBRARIES += libimagedec.la
|
|
||||||
endif
|
|
||||||
noinst_LTLIBRARIES += libimageenc.la
|
|
||||||
|
|
||||||
noinst_HEADERS =
|
noinst_HEADERS =
|
||||||
noinst_HEADERS += ../src/webp/decode.h
|
noinst_HEADERS += ../src/webp/decode.h
|
||||||
noinst_HEADERS += ../src/webp/types.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 += jpegdec.c jpegdec.h
|
||||||
libimagedec_la_SOURCES += metadata.c metadata.h
|
libimagedec_la_SOURCES += metadata.c metadata.h
|
||||||
libimagedec_la_SOURCES += pngdec.c pngdec.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 += webpdec.c webpdec.h
|
||||||
libimagedec_la_SOURCES += wicdec.c wicdec.h
|
libimagedec_la_SOURCES += wicdec.c wicdec.h
|
||||||
libimagedec_la_CPPFLAGS = $(JPEG_INCLUDES) $(PNG_INCLUDES) $(TIFF_INCLUDES)
|
libimagedec_la_CPPFLAGS = $(JPEG_INCLUDES) $(PNG_INCLUDES) $(TIFF_INCLUDES)
|
||||||
libimagedec_la_CPPFLAGS += $(AM_CPPFLAGS)
|
libimagedec_la_CPPFLAGS += $(AM_CPPFLAGS) $(USE_EXPERIMENTAL_CODE)
|
||||||
libimagedec_la_LIBADD = ../src/demux/libwebpdemux.la
|
|
||||||
|
|
||||||
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 = $(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) {
|
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_structp png;
|
||||||
volatile png_infop info;
|
volatile png_infop info;
|
||||||
|
png_uint_32 y;
|
||||||
|
|
||||||
if (out_file == NULL || buffer == NULL) return 0;
|
if (out_file == NULL || buffer == NULL) return 0;
|
||||||
|
|
||||||
@ -178,23 +184,14 @@ int WebPWritePNG(FILE* out_file, const WebPDecBuffer* const buffer) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
png_init_io(png, out_file);
|
png_init_io(png, out_file);
|
||||||
{
|
png_set_IHDR(png, info, width, height, 8,
|
||||||
const uint32_t width = buffer->width;
|
has_alpha ? PNG_COLOR_TYPE_RGBA : PNG_COLOR_TYPE_RGB,
|
||||||
const uint32_t height = buffer->height;
|
PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT,
|
||||||
png_bytep row = buffer->u.RGBA.rgba;
|
PNG_FILTER_TYPE_DEFAULT);
|
||||||
const int stride = buffer->u.RGBA.stride;
|
png_write_info(png, info);
|
||||||
const int has_alpha = WebPIsAlphaMode(buffer->colorspace);
|
for (y = 0; y < height; ++y) {
|
||||||
uint32_t y;
|
png_write_rows(png, &row, 1);
|
||||||
|
row += stride;
|
||||||
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,
|
|
||||||
PNG_FILTER_TYPE_DEFAULT);
|
|
||||||
png_write_info(png, info);
|
|
||||||
for (y = 0; y < height; ++y) {
|
|
||||||
png_write_rows(png, &row, 1);
|
|
||||||
row += stride;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
png_write_end(png, info);
|
png_write_end(png, info);
|
||||||
png_destroy_write_struct((png_structpp)&png, (png_infopp)&info);
|
png_destroy_write_struct((png_structpp)&png, (png_infopp)&info);
|
||||||
@ -545,24 +542,22 @@ int WebPWriteYUV(FILE* fout, const WebPDecBuffer* const buffer) {
|
|||||||
// Generic top-level call
|
// Generic top-level call
|
||||||
|
|
||||||
int WebPSaveImage(const WebPDecBuffer* const buffer,
|
int WebPSaveImage(const WebPDecBuffer* const buffer,
|
||||||
WebPOutputFileFormat format,
|
WebPOutputFileFormat format, const char* const out_file) {
|
||||||
const char* const out_file_name) {
|
|
||||||
FILE* fout = NULL;
|
FILE* fout = NULL;
|
||||||
int needs_open_file = 1;
|
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;
|
int ok = 1;
|
||||||
|
|
||||||
if (buffer == NULL || out_file_name == NULL) return 0;
|
if (buffer == NULL || out_file == NULL) return 0;
|
||||||
|
|
||||||
#ifdef HAVE_WINCODEC_H
|
#ifdef HAVE_WINCODEC_H
|
||||||
needs_open_file = (format != PNG);
|
needs_open_file = (format != PNG);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (needs_open_file) {
|
if (needs_open_file) {
|
||||||
fout = use_stdout ? ImgIoUtilSetBinaryMode(stdout)
|
fout = use_stdout ? ImgIoUtilSetBinaryMode(stdout) : fopen(out_file, "wb");
|
||||||
: fopen(out_file_name, "wb");
|
|
||||||
if (fout == NULL) {
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -571,7 +566,7 @@ int WebPSaveImage(const WebPDecBuffer* const buffer,
|
|||||||
format == RGBA || format == BGRA || format == ARGB ||
|
format == RGBA || format == BGRA || format == ARGB ||
|
||||||
format == rgbA || format == bgrA || format == Argb) {
|
format == rgbA || format == bgrA || format == Argb) {
|
||||||
#ifdef HAVE_WINCODEC_H
|
#ifdef HAVE_WINCODEC_H
|
||||||
ok &= WebPWritePNG(out_file_name, use_stdout, buffer);
|
ok &= WebPWritePNG(out_file, use_stdout, buffer);
|
||||||
#else
|
#else
|
||||||
ok &= WebPWritePNG(fout, buffer);
|
ok &= WebPWritePNG(fout, buffer);
|
||||||
#endif
|
#endif
|
||||||
|
@ -47,8 +47,7 @@ int ImgIoUtilReadFromStdin(const uint8_t** data, size_t* data_size) {
|
|||||||
while (!feof(stdin)) {
|
while (!feof(stdin)) {
|
||||||
// We double the buffer size each time and read as much as possible.
|
// We double the buffer size each time and read as much as possible.
|
||||||
const size_t extra_size = (max_size == 0) ? kBlockSize : max_size;
|
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);
|
||||||
void* const new_data = realloc(input, max_size + extra_size + 1);
|
|
||||||
if (new_data == NULL) goto Error;
|
if (new_data == NULL) goto Error;
|
||||||
input = (uint8_t*)new_data;
|
input = (uint8_t*)new_data;
|
||||||
max_size += extra_size;
|
max_size += extra_size;
|
||||||
@ -56,7 +55,6 @@ int ImgIoUtilReadFromStdin(const uint8_t** data, size_t* data_size) {
|
|||||||
if (size < max_size) break;
|
if (size < max_size) break;
|
||||||
}
|
}
|
||||||
if (ferror(stdin)) goto Error;
|
if (ferror(stdin)) goto Error;
|
||||||
if (input != NULL) input[size] = '\0'; // convenient 0-terminator
|
|
||||||
*data = input;
|
*data = input;
|
||||||
*data_size = size;
|
*data_size = size;
|
||||||
return 1;
|
return 1;
|
||||||
@ -70,7 +68,7 @@ int ImgIoUtilReadFromStdin(const uint8_t** data, size_t* data_size) {
|
|||||||
int ImgIoUtilReadFile(const char* const file_name,
|
int ImgIoUtilReadFile(const char* const file_name,
|
||||||
const uint8_t** data, size_t* data_size) {
|
const uint8_t** data, size_t* data_size) {
|
||||||
int ok;
|
int ok;
|
||||||
uint8_t* file_data;
|
void* file_data;
|
||||||
size_t file_size;
|
size_t file_size;
|
||||||
FILE* in;
|
FILE* in;
|
||||||
const int from_stdin = (file_name == NULL) || !strcmp(file_name, "-");
|
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);
|
fseek(in, 0, SEEK_END);
|
||||||
file_size = ftell(in);
|
file_size = ftell(in);
|
||||||
fseek(in, 0, SEEK_SET);
|
fseek(in, 0, SEEK_SET);
|
||||||
// we allocate one extra byte for the \0 terminator
|
file_data = malloc(file_size);
|
||||||
file_data = (uint8_t*)malloc(file_size + 1);
|
if (file_data == NULL) return 0;
|
||||||
if (file_data == NULL) {
|
|
||||||
fclose(in);
|
|
||||||
fprintf(stderr, "memory allocation failure when reading file %s\n",
|
|
||||||
file_name);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
ok = (fread(file_data, file_size, 1, in) == 1);
|
ok = (fread(file_data, file_size, 1, in) == 1);
|
||||||
fclose(in);
|
fclose(in);
|
||||||
|
|
||||||
@ -106,14 +98,11 @@ int ImgIoUtilReadFile(const char* const file_name,
|
|||||||
free(file_data);
|
free(file_data);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
file_data[file_size] = '\0'; // convenient 0-terminator
|
*data = (uint8_t*)file_data;
|
||||||
*data = file_data;
|
|
||||||
*data_size = file_size;
|
*data_size = file_size;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
int ImgIoUtilWriteFile(const char* const file_name,
|
int ImgIoUtilWriteFile(const char* const file_name,
|
||||||
const uint8_t* data, size_t data_size) {
|
const uint8_t* data, size_t data_size) {
|
||||||
int ok;
|
int ok;
|
||||||
@ -148,11 +137,7 @@ void ImgIoUtilCopyPlane(const uint8_t* src, int src_stride,
|
|||||||
|
|
||||||
int ImgIoUtilCheckSizeArgumentsOverflow(uint64_t nmemb, size_t size) {
|
int ImgIoUtilCheckSizeArgumentsOverflow(uint64_t nmemb, size_t size) {
|
||||||
const uint64_t total_size = nmemb * size;
|
const uint64_t total_size = nmemb * size;
|
||||||
int ok = (total_size == (size_t)total_size);
|
return (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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
@ -30,9 +30,6 @@ FILE* ImgIoUtilSetBinaryMode(FILE* file);
|
|||||||
// Allocates storage for entire file 'file_name' and returns contents and size
|
// 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
|
// in 'data' and 'data_size'. Returns 1 on success, 0 otherwise. '*data' should
|
||||||
// be deleted using free().
|
// 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
|
// If 'file_name' is NULL or equal to "-", input is read from stdin by calling
|
||||||
// the function ImgIoUtilReadFromStdin().
|
// the function ImgIoUtilReadFromStdin().
|
||||||
int ImgIoUtilReadFile(const char* const file_name,
|
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 ||
|
if (stride != (int)stride ||
|
||||||
!ImgIoUtilCheckSizeArgumentsOverflow(stride, height)) {
|
!ImgIoUtilCheckSizeArgumentsOverflow(stride, height)) {
|
||||||
goto Error;
|
goto End;
|
||||||
}
|
}
|
||||||
|
|
||||||
rgb = (uint8_t*)malloc((size_t)stride * height);
|
rgb = (uint8_t*)malloc((size_t)stride * height);
|
||||||
if (rgb == NULL) {
|
if (rgb == NULL) {
|
||||||
goto Error;
|
goto End;
|
||||||
}
|
}
|
||||||
buffer[0] = (JSAMPLE*)rgb;
|
buffer[0] = (JSAMPLE*)rgb;
|
||||||
|
|
||||||
while (dinfo.output_scanline < dinfo.output_height) {
|
while (dinfo.output_scanline < dinfo.output_height) {
|
||||||
if (jpeg_read_scanlines((j_decompress_ptr)&dinfo, buffer, 1) != 1) {
|
if (jpeg_read_scanlines((j_decompress_ptr)&dinfo, buffer, 1) != 1) {
|
||||||
goto Error;
|
goto End;
|
||||||
}
|
}
|
||||||
buffer[0] += stride;
|
buffer[0] += stride;
|
||||||
}
|
}
|
||||||
|
@ -185,6 +185,7 @@ static int ExtractMetadataFromPNG(png_structp png,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
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);
|
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) {
|
if (!keep_alpha) {
|
||||||
png_set_strip_alpha(png);
|
png_set_strip_alpha(png);
|
||||||
has_alpha = 0;
|
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->seen_flags & TUPLE_FLAG)) {
|
||||||
if (info->depth > 0 && info->depth <= 4 && info->depth != 2) {
|
info->seen_flags |= TUPLE_FLAG;
|
||||||
info->seen_flags |= TUPLE_FLAG;
|
info->bytes_per_px = info->depth * (info->max_value > 255 ? 2 : 1);
|
||||||
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) {
|
if (info->seen_flags != ALL_NEEDED_FLAGS) {
|
||||||
fprintf(stderr, "PAM: incomplete header.\n");
|
fprintf(stderr, "PAM: incomplete header.\n");
|
||||||
@ -165,7 +160,7 @@ static size_t ReadHeader(PNMInfo* const info) {
|
|||||||
// perform some basic numerical validation
|
// perform some basic numerical validation
|
||||||
if (info->width <= 0 || info->height <= 0 ||
|
if (info->width <= 0 || info->height <= 0 ||
|
||||||
info->type <= 0 || info->type >= 9 ||
|
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->bytes_per_px < info->depth ||
|
||||||
info->max_value <= 0 || info->max_value >= 65536) {
|
info->max_value <= 0 || info->max_value >= 65536) {
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -9,18 +9,12 @@
|
|||||||
//
|
//
|
||||||
// WebP decode.
|
// WebP decode.
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "webp/config.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "./webpdec.h"
|
#include "./webpdec.h"
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "webp/decode.h"
|
#include "webp/decode.h"
|
||||||
#include "webp/demux.h"
|
|
||||||
#include "webp/encode.h"
|
#include "webp/encode.h"
|
||||||
#include "./imageio_util.h"
|
#include "./imageio_util.h"
|
||||||
#include "./metadata.h"
|
#include "./metadata.h"
|
||||||
@ -97,47 +91,25 @@ VP8StatusCode DecodeWebPIncremental(
|
|||||||
fprintf(stderr, "Failed during WebPINewDecoder().\n");
|
fprintf(stderr, "Failed during WebPINewDecoder().\n");
|
||||||
return VP8_STATUS_OUT_OF_MEMORY;
|
return VP8_STATUS_OUT_OF_MEMORY;
|
||||||
} else {
|
} 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);
|
status = WebPIUpdate(idec, data, data_size);
|
||||||
|
#endif
|
||||||
WebPIDelete(idec);
|
WebPIDelete(idec);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return status;
|
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,
|
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;
|
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)) {
|
if (!WebPInitDecoderConfig(&config)) {
|
||||||
fprintf(stderr, "Library version mismatch!\n");
|
fprintf(stderr, "Library version mismatch!\n");
|
||||||
return 0;
|
return 0;
|
||||||
@ -164,32 +141,17 @@ int ReadWebP(const uint8_t* const data, size_t data_size,
|
|||||||
|
|
||||||
do {
|
do {
|
||||||
const int has_alpha = keep_alpha && bitstream->has_alpha;
|
const int has_alpha = keep_alpha && bitstream->has_alpha;
|
||||||
uint64_t stride;
|
|
||||||
pic->width = bitstream->width;
|
pic->width = bitstream->width;
|
||||||
pic->height = bitstream->height;
|
pic->height = bitstream->height;
|
||||||
if (pic->use_argb) {
|
if (!pic->use_argb) pic->colorspace = has_alpha ? WEBP_YUV420A
|
||||||
stride = (uint64_t)bitstream->width * 4;
|
: WEBP_YUV420;
|
||||||
} 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
ok = WebPPictureAlloc(pic);
|
ok = WebPPictureAlloc(pic);
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
status = VP8_STATUS_OUT_OF_MEMORY;
|
status = VP8_STATUS_OUT_OF_MEMORY;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (pic->use_argb) {
|
if (pic->use_argb) {
|
||||||
#ifdef WORDS_BIGENDIAN
|
|
||||||
output_buffer->colorspace = MODE_ARGB;
|
|
||||||
#else
|
|
||||||
output_buffer->colorspace = MODE_BGRA;
|
output_buffer->colorspace = MODE_BGRA;
|
||||||
#endif
|
|
||||||
output_buffer->u.RGBA.rgba = (uint8_t*)pic->argb;
|
output_buffer->u.RGBA.rgba = (uint8_t*)pic->argb;
|
||||||
output_buffer->u.RGBA.stride = pic->argb_stride * sizeof(uint32_t);
|
output_buffer->u.RGBA.stride = pic->argb_stride * sizeof(uint32_t);
|
||||||
output_buffer->u.RGBA.size = output_buffer->u.RGBA.stride * pic->height;
|
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);
|
status = DecodeWebP(data, data_size, &config);
|
||||||
ok = (status == VP8_STATUS_OK);
|
ok = (status == VP8_STATUS_OK);
|
||||||
|
if (!ok) WebPPictureFree(pic);
|
||||||
if (ok && !keep_alpha && pic->use_argb) {
|
if (ok && !keep_alpha && pic->use_argb) {
|
||||||
// Need to wipe out the alpha value, as requested.
|
// Need to wipe out the alpha value, as requested.
|
||||||
int x, y;
|
int x, y;
|
||||||
@ -225,18 +188,9 @@ int ReadWebP(const uint8_t* const data, size_t data_size,
|
|||||||
|
|
||||||
if (status != VP8_STATUS_OK) {
|
if (status != VP8_STATUS_OK) {
|
||||||
PrintWebPError("input data", status);
|
PrintWebPError("input data", status);
|
||||||
ok = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
WebPFreeDecBuffer(output_buffer);
|
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;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,7 +25,6 @@ ifeq ($(strip $(shell uname)), Darwin)
|
|||||||
# Failure observed with: gcc 4.2.1 and 4.0.1.
|
# Failure observed with: gcc 4.2.1 and 4.0.1.
|
||||||
EXTRA_FLAGS += -fno-common
|
EXTRA_FLAGS += -fno-common
|
||||||
EXTRA_FLAGS += -DHAVE_GLUT_GLUT_H
|
EXTRA_FLAGS += -DHAVE_GLUT_GLUT_H
|
||||||
EXTRA_FLAGS += -Wno-deprecated-declarations
|
|
||||||
EXTRA_FLAGS += -I/opt/local/include
|
EXTRA_FLAGS += -I/opt/local/include
|
||||||
EXTRA_LIBS += -L/opt/local/lib
|
EXTRA_LIBS += -L/opt/local/lib
|
||||||
GL_LIBS = -framework GLUT -framework OpenGL
|
GL_LIBS = -framework GLUT -framework OpenGL
|
||||||
@ -35,16 +34,6 @@ else
|
|||||||
GL_LIBS = -lglut -lGL
|
GL_LIBS = -lglut -lGL
|
||||||
endif
|
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:
|
# To install libraries on Mac OS X:
|
||||||
# 1. Install MacPorts (http://www.macports.org/install.php)
|
# 1. Install MacPorts (http://www.macports.org/install.php)
|
||||||
@ -64,8 +53,11 @@ endif
|
|||||||
# 'make -f makefile.unix EXTRA_FLAGS=-m32' to that effect.
|
# 'make -f makefile.unix EXTRA_FLAGS=-m32' to that effect.
|
||||||
# EXTRA_FLAGS += -m32
|
# 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 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 to enable multi-threading
|
||||||
EXTRA_FLAGS += -DWEBP_USE_THREAD
|
EXTRA_FLAGS += -DWEBP_USE_THREAD
|
||||||
@ -111,13 +103,8 @@ endif
|
|||||||
|
|
||||||
AR = ar
|
AR = ar
|
||||||
ARFLAGS = r
|
ARFLAGS = r
|
||||||
CPPFLAGS = -I. -Isrc/ -Wall
|
CPPFLAGS = -Isrc/ -Wall
|
||||||
ifeq ($(DEBUG), 1)
|
CFLAGS = -O3 -DNDEBUG $(EXTRA_FLAGS)
|
||||||
CFLAGS = -g
|
|
||||||
else
|
|
||||||
CFLAGS = -O3 -DNDEBUG
|
|
||||||
endif
|
|
||||||
CFLAGS += $(EXTRA_FLAGS)
|
|
||||||
CC = gcc
|
CC = gcc
|
||||||
INSTALL = install
|
INSTALL = install
|
||||||
GROFF = /usr/bin/groff
|
GROFF = /usr/bin/groff
|
||||||
@ -179,15 +166,16 @@ DSP_DEC_OBJS = \
|
|||||||
src/dsp/upsampling_msa.o \
|
src/dsp/upsampling_msa.o \
|
||||||
src/dsp/upsampling_neon.o \
|
src/dsp/upsampling_neon.o \
|
||||||
src/dsp/upsampling_sse2.o \
|
src/dsp/upsampling_sse2.o \
|
||||||
src/dsp/upsampling_sse41.o \
|
|
||||||
src/dsp/yuv.o \
|
src/dsp/yuv.o \
|
||||||
src/dsp/yuv_mips32.o \
|
src/dsp/yuv_mips32.o \
|
||||||
src/dsp/yuv_mips_dsp_r2.o \
|
src/dsp/yuv_mips_dsp_r2.o \
|
||||||
src/dsp/yuv_neon.o \
|
src/dsp/yuv_neon.o \
|
||||||
src/dsp/yuv_sse2.o \
|
src/dsp/yuv_sse2.o \
|
||||||
src/dsp/yuv_sse41.o \
|
|
||||||
|
|
||||||
DSP_ENC_OBJS = \
|
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.o \
|
||||||
src/dsp/cost_mips32.o \
|
src/dsp/cost_mips32.o \
|
||||||
src/dsp/cost_mips_dsp_r2.o \
|
src/dsp/cost_mips_dsp_r2.o \
|
||||||
@ -217,6 +205,7 @@ ENC_OBJS = \
|
|||||||
src/enc/backward_references_enc.o \
|
src/enc/backward_references_enc.o \
|
||||||
src/enc/config_enc.o \
|
src/enc/config_enc.o \
|
||||||
src/enc/cost_enc.o \
|
src/enc/cost_enc.o \
|
||||||
|
src/enc/delta_palettization_enc.o \
|
||||||
src/enc/filter_enc.o \
|
src/enc/filter_enc.o \
|
||||||
src/enc/frame_enc.o \
|
src/enc/frame_enc.o \
|
||||||
src/enc/histogram_enc.o \
|
src/enc/histogram_enc.o \
|
||||||
@ -314,6 +303,7 @@ HDRS = \
|
|||||||
src/dsp/yuv.h \
|
src/dsp/yuv.h \
|
||||||
src/enc/backward_references_enc.h \
|
src/enc/backward_references_enc.h \
|
||||||
src/enc/cost_enc.h \
|
src/enc/cost_enc.h \
|
||||||
|
src/enc/delta_palettization_enc.h \
|
||||||
src/enc/histogram_enc.h \
|
src/enc/histogram_enc.h \
|
||||||
src/enc/vp8i_enc.h \
|
src/enc/vp8i_enc.h \
|
||||||
src/enc/vp8li_enc.h \
|
src/enc/vp8li_enc.h \
|
||||||
@ -345,8 +335,7 @@ OUT_LIBS += src/libwebp.a
|
|||||||
EXTRA_LIB = extras/libwebpextras.a
|
EXTRA_LIB = extras/libwebpextras.a
|
||||||
OUT_EXAMPLES = examples/cwebp examples/dwebp
|
OUT_EXAMPLES = examples/cwebp examples/dwebp
|
||||||
EXTRA_EXAMPLES = examples/gif2webp examples/vwebp examples/webpmux \
|
EXTRA_EXAMPLES = examples/gif2webp examples/vwebp examples/webpmux \
|
||||||
examples/anim_diff examples/anim_dump \
|
examples/anim_diff examples/img2webp examples/webpinfo
|
||||||
examples/img2webp examples/webpinfo
|
|
||||||
OTHER_EXAMPLES = extras/get_disto extras/webp_quality extras/vwebp_sdl
|
OTHER_EXAMPLES = extras/get_disto extras/webp_quality extras/vwebp_sdl
|
||||||
|
|
||||||
OUTPUT = $(OUT_LIBS) $(OUT_EXAMPLES)
|
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
|
src/utils/bit_writer_utils.o: src/utils/endian_inl_utils.h
|
||||||
|
|
||||||
%.o: %.c $(HDRS)
|
%.o: %.c $(HDRS)
|
||||||
$(CC) $(CPPFLAGS) $(CFLAGS) -c $< -o $@
|
$(CC) $(CFLAGS) $(CPPFLAGS) -c $< -o $@
|
||||||
|
|
||||||
examples/libanim_util.a: $(ANIM_UTIL_OBJS)
|
examples/libanim_util.a: $(ANIM_UTIL_OBJS)
|
||||||
examples/libexample_util.a: $(EX_UTIL_OBJS)
|
examples/libexample_util.a: $(EX_UTIL_OBJS)
|
||||||
@ -392,7 +381,6 @@ src/demux/libwebpdemux.a: $(LIBWEBPDEMUX_OBJS)
|
|||||||
$(AR) $(ARFLAGS) $@ $^
|
$(AR) $(ARFLAGS) $@ $^
|
||||||
|
|
||||||
examples/anim_diff: examples/anim_diff.o $(ANIM_UTIL_OBJS) $(GIFDEC_OBJS)
|
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/cwebp: examples/cwebp.o
|
||||||
examples/dwebp: examples/dwebp.o
|
examples/dwebp: examples/dwebp.o
|
||||||
examples/gif2webp: examples/gif2webp.o $(GIFDEC_OBJS)
|
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: imageio/libimageio_util.a src/libwebp.a
|
||||||
examples/anim_diff: EXTRA_LIBS += $(GIF_LIBS)
|
examples/anim_diff: EXTRA_LIBS += $(GIF_LIBS)
|
||||||
examples/anim_diff: EXTRA_FLAGS += -DWEBP_HAVE_GIF
|
examples/anim_diff: EXTRA_FLAGS += -DWEBP_HAVE_GIF
|
||||||
examples/anim_dump: examples/libanim_util.a
|
|
||||||
examples/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: examples/libexample_util.a
|
||||||
examples/cwebp: imageio/libimagedec.a
|
examples/cwebp: imageio/libimagedec.a
|
||||||
examples/cwebp: src/demux/libwebpdemux.a
|
|
||||||
examples/cwebp: imageio/libimageio_util.a
|
examples/cwebp: imageio/libimageio_util.a
|
||||||
examples/cwebp: src/libwebp.a
|
examples/cwebp: src/libwebp.a
|
||||||
examples/cwebp: EXTRA_LIBS += $(CWEBP_LIBS)
|
examples/cwebp: EXTRA_LIBS += $(CWEBP_LIBS)
|
||||||
examples/dwebp: examples/libexample_util.a
|
examples/dwebp: examples/libexample_util.a
|
||||||
examples/dwebp: imageio/libimagedec.a
|
examples/dwebp: imageio/libimagedec.a
|
||||||
examples/dwebp: src/demux/libwebpdemux.a
|
|
||||||
examples/dwebp: imageio/libimageenc.a
|
examples/dwebp: imageio/libimageenc.a
|
||||||
examples/dwebp: imageio/libimageio_util.a
|
examples/dwebp: imageio/libimageio_util.a
|
||||||
examples/dwebp: src/libwebp.a
|
examples/dwebp: src/libwebp.a
|
||||||
@ -438,17 +417,13 @@ examples/webpmux: examples/libexample_util.a imageio/libimageio_util.a
|
|||||||
examples/webpmux: src/mux/libwebpmux.a src/libwebpdecoder.a
|
examples/webpmux: src/mux/libwebpmux.a src/libwebpdecoder.a
|
||||||
examples/img2webp: examples/libexample_util.a imageio/libimageio_util.a
|
examples/img2webp: examples/libexample_util.a imageio/libimageio_util.a
|
||||||
examples/img2webp: imageio/libimagedec.a
|
examples/img2webp: imageio/libimagedec.a
|
||||||
examples/img2webp: src/demux/libwebpdemux.a
|
|
||||||
examples/img2webp: src/mux/libwebpmux.a src/libwebp.a
|
examples/img2webp: src/mux/libwebpmux.a src/libwebp.a
|
||||||
examples/img2webp: EXTRA_LIBS += $(CWEBP_LIBS)
|
examples/img2webp: EXTRA_LIBS += $(CWEBP_LIBS)
|
||||||
examples/webpinfo: examples/libexample_util.a imageio/libimageio_util.a
|
examples/webpinfo: examples/libexample_util.a imageio/libimageio_util.a
|
||||||
examples/webpinfo: src/libwebpdecoder.a
|
examples/webpinfo: src/libwebpdecoder.a
|
||||||
|
|
||||||
extras/get_disto: extras/get_disto.o
|
extras/get_disto: extras/get_disto.o
|
||||||
extras/get_disto: imageio/libimagedec.a
|
extras/get_disto: imageio/libimagedec.a imageio/libimageio_util.a src/libwebp.a
|
||||||
extras/get_disto: src/demux/libwebpdemux.a
|
|
||||||
extras/get_disto: imageio/libimageio_util.a
|
|
||||||
extras/get_disto: src/libwebp.a
|
|
||||||
extras/get_disto: EXTRA_LIBS += $(CWEBP_LIBS)
|
extras/get_disto: EXTRA_LIBS += $(CWEBP_LIBS)
|
||||||
|
|
||||||
extras/webp_quality: extras/webp_quality.o
|
extras/webp_quality: extras/webp_quality.o
|
||||||
@ -459,8 +434,8 @@ extras/vwebp_sdl: extras/vwebp_sdl.o
|
|||||||
extras/vwebp_sdl: extras/webp_to_sdl.o
|
extras/vwebp_sdl: extras/webp_to_sdl.o
|
||||||
extras/vwebp_sdl: imageio/libimageio_util.a
|
extras/vwebp_sdl: imageio/libimageio_util.a
|
||||||
extras/vwebp_sdl: src/libwebp.a
|
extras/vwebp_sdl: src/libwebp.a
|
||||||
extras/vwebp_sdl: EXTRA_FLAGS += -DWEBP_HAVE_SDL $(SDL_FLAGS)
|
extras/vwebp_sdl: EXTRA_FLAGS += -DWEBP_HAVE_SDL
|
||||||
extras/vwebp_sdl: EXTRA_LIBS += $(SDL_LIBS)
|
extras/vwebp_sdl: EXTRA_LIBS += -lSDL
|
||||||
|
|
||||||
$(OUT_EXAMPLES) $(EXTRA_EXAMPLES) $(OTHER_EXAMPLES):
|
$(OUT_EXAMPLES) $(EXTRA_EXAMPLES) $(OTHER_EXAMPLES):
|
||||||
$(CC) -o $@ $^ $(LDFLAGS)
|
$(CC) -o $@ $^ $(LDFLAGS)
|
||||||
@ -479,7 +454,7 @@ dist: all
|
|||||||
for m in man/[cdv]webp.1 man/gif2webp.1 man/webpmux.1 \
|
for m in man/[cdv]webp.1 man/gif2webp.1 man/webpmux.1 \
|
||||||
man/img2webp.1 man/webpinfo.1; do \
|
man/img2webp.1 man/webpinfo.1; do \
|
||||||
basenam=$$(basename $$m .1); \
|
basenam=$$(basename $$m .1); \
|
||||||
$(GROFF) -t -e -man -T ascii $$m \
|
$(GROFF) -t -e -man -T utf8 $$m \
|
||||||
| $(COL) -bx >$(DESTDIR)/doc/$${basenam}.txt; \
|
| $(COL) -bx >$(DESTDIR)/doc/$${basenam}.txt; \
|
||||||
$(GROFF) -t -e -man -T html $$m \
|
$(GROFF) -t -e -man -T html $$m \
|
||||||
| $(COL) -bx >$(DESTDIR)/doc/$${basenam}.html; \
|
| $(COL) -bx >$(DESTDIR)/doc/$${basenam}.html; \
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
.\" Hey, EMACS: -*- nroff -*-
|
.\" Hey, EMACS: -*- nroff -*-
|
||||||
.TH GIF2WEBP 1 "January 25, 2018"
|
.TH GIF2WEBP 1 "January 25, 2017"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
gif2webp \- Convert a GIF image to WebP
|
gif2webp \- Convert a GIF image to WebP
|
||||||
.SH SYNOPSIS
|
.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.
|
perform conversion but only report statistics.
|
||||||
Using "\-" as output name will direct output to 'stdout'.
|
Using "\-" as output name will direct output to 'stdout'.
|
||||||
.TP
|
.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
|
.B \-h, \-help
|
||||||
Usage information.
|
Usage information.
|
||||||
.TP
|
.TP
|
||||||
@ -116,10 +110,6 @@ the range of 20 to 50.
|
|||||||
.B \-mt
|
.B \-mt
|
||||||
Use multi-threading for encoding, if possible.
|
Use multi-threading for encoding, if possible.
|
||||||
.TP
|
.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
|
.B \-v
|
||||||
Print extra information.
|
Print extra information.
|
||||||
.TP
|
.TP
|
||||||
@ -143,8 +133,6 @@ gif2webp \-lossy \-m 3 picture.gif \-o picture_lossy.webp
|
|||||||
gif2webp \-lossy \-f 50 picture.gif \-o picture.webp
|
gif2webp \-lossy \-f 50 picture.gif \-o picture.webp
|
||||||
.br
|
.br
|
||||||
gif2webp \-q 70 \-o picture.webp \-\- \-\-\-picture.gif
|
gif2webp \-q 70 \-o picture.webp \-\- \-\-\-picture.gif
|
||||||
.br
|
|
||||||
cat picture.gif | gif2webp \-o \- \-\- \- > output.webp
|
|
||||||
|
|
||||||
.SH AUTHORS
|
.SH AUTHORS
|
||||||
\fBgif2webp\fP is a part of libwebp and was written by the WebP team.
|
\fBgif2webp\fP is a part of libwebp and was written by the WebP team.
|
||||||
|
@ -1,13 +1,11 @@
|
|||||||
.\" Hey, EMACS: -*- nroff -*-
|
.\" Hey, EMACS: -*- nroff -*-
|
||||||
.TH IMG2WEBP 1 "April 3, 2018"
|
.TH IMG2WEBP 1 "January 23, 2017"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
img2webp \- create animated WebP file from a sequence of input images.
|
img2webp \- create animated WebP file from a sequence of input images.
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
.B img2webp
|
.B img2webp
|
||||||
[file_level_options] [files] [per_frame_options...]
|
[file_level_options] [files] [per_frame_options...]
|
||||||
.br
|
.br
|
||||||
.B img2webp argument_file_name
|
|
||||||
.br
|
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
This manual page documents the
|
This manual page documents the
|
||||||
.B img2webp
|
.B img2webp
|
||||||
@ -15,9 +13,6 @@ command.
|
|||||||
.PP
|
.PP
|
||||||
\fBimg2webp\fP compresses a sequence of images using the animated WebP format.
|
\fBimg2webp\fP compresses a sequence of images using the animated WebP format.
|
||||||
Input images can either be PNG, JPEG, TIFF or WebP.
|
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
|
.SH FILE-LEVEL OPTIONS
|
||||||
The file-level options are applied at the beginning of the compression process,
|
The file-level options are applied at the beginning of the compression process,
|
||||||
before the input frames are read.
|
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 .
|
option disables the local option \fB-lossy\fP and \fB-lossless\fP .
|
||||||
.TP
|
.TP
|
||||||
.BI \-loop " int
|
.BI \-loop " int
|
||||||
Specifies the number of times the animation should loop. Using '0'
|
Specifies the number of times the animation should loop. Using '0' means
|
||||||
means 'loop indefinitely'.
|
'loop indefinitely'.
|
||||||
.TP
|
.TP
|
||||||
.BI \-v
|
.BI \-v
|
||||||
Be more verbose.
|
Be more verbose.
|
||||||
.TP
|
.TP
|
||||||
.B \-h, \-help
|
.B \-h, \-help
|
||||||
A short usage summary.
|
A short usage summary.
|
||||||
.TP
|
|
||||||
.B \-version
|
|
||||||
Print the version numbers of the relevant libraries used.
|
|
||||||
|
|
||||||
.SH PER-FRAME OPTIONS
|
.SH PER-FRAME OPTIONS
|
||||||
The per-frame options are applied for the images following as arguments in the
|
The per-frame options are applied for the images following as arguments in the
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
.\" Hey, EMACS: -*- nroff -*-
|
.\" Hey, EMACS: -*- nroff -*-
|
||||||
.TH WEBPINFO 1 "November 24, 2017"
|
.TH WEBPINFO 1 "May 08, 2017"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
webpinfo \- print out the chunk level structure of WebP files
|
webpinfo \- print out the chunk level structure of WebP files
|
||||||
along with basic integrity checks.
|
along with basic integrity checks.
|
||||||
@ -22,19 +22,16 @@ WebP format.
|
|||||||
|
|
||||||
.SH OPTIONS
|
.SH OPTIONS
|
||||||
.TP
|
.TP
|
||||||
.B \-version
|
.B -quiet
|
||||||
Print the version number (as major.minor.revision) and exit.
|
|
||||||
.TP
|
|
||||||
.B \-quiet
|
|
||||||
Do not show chunk parsing information.
|
Do not show chunk parsing information.
|
||||||
.TP
|
.TP
|
||||||
.B \-diag
|
.B -diag
|
||||||
Show parsing error diagnosis.
|
Show parsing error diagnosis.
|
||||||
.TP
|
.TP
|
||||||
.B \-summary
|
.B -summary
|
||||||
Show chunk stats summary.
|
Show chunk stats summary.
|
||||||
.TP
|
.TP
|
||||||
.BI \-bitstream_info
|
.BI -bitstream_info
|
||||||
Parse bitstream header.
|
Parse bitstream header.
|
||||||
.TP
|
.TP
|
||||||
.B \-h, \-help
|
.B \-h, \-help
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
.\" Hey, EMACS: -*- nroff -*-
|
.\" Hey, EMACS: -*- nroff -*-
|
||||||
.TH WEBPMUX 1 "December 1, 2017"
|
.TH WEBPMUX 1 "November 10, 2016"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
webpmux \- create animated WebP files from non\-animated WebP images, extract
|
webpmux \- create animated WebP files from non\-animated WebP images, extract
|
||||||
frames from animated WebP images, and manage XMP/EXIF metadata and ICC profile.
|
frames from animated WebP images, and manage XMP/EXIF metadata and ICC profile.
|
||||||
@ -48,8 +48,6 @@ frames from animated WebP images, and manage XMP/EXIF metadata and ICC profile.
|
|||||||
.B webpmux [\-h|\-help]
|
.B webpmux [\-h|\-help]
|
||||||
.br
|
.br
|
||||||
.B webpmux \-version
|
.B webpmux \-version
|
||||||
.br
|
|
||||||
.B webpmux argument_file_name
|
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
This manual page documents the
|
This manual page documents the
|
||||||
.B webpmux
|
.B webpmux
|
||||||
@ -57,9 +55,6 @@ command.
|
|||||||
.PP
|
.PP
|
||||||
\fBwebpmux\fP can be used to create/extract from animated WebP files, as well as
|
\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.
|
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
|
.SH OPTIONS
|
||||||
.SS GET_OPTIONS (\-get):
|
.SS GET_OPTIONS (\-get):
|
||||||
.TP
|
.TP
|
||||||
|
@ -22,7 +22,6 @@ commondir = $(includedir)/webp
|
|||||||
libwebp_la_SOURCES =
|
libwebp_la_SOURCES =
|
||||||
libwebpinclude_HEADERS =
|
libwebpinclude_HEADERS =
|
||||||
libwebpinclude_HEADERS += webp/encode.h
|
libwebpinclude_HEADERS += webp/encode.h
|
||||||
|
|
||||||
noinst_HEADERS =
|
noinst_HEADERS =
|
||||||
noinst_HEADERS += webp/format_constants.h
|
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
|
# other than the ones listed on the command line, i.e., after linking, it will
|
||||||
# not have unresolved symbols. Some platforms (Windows among them) require all
|
# not have unresolved symbols. Some platforms (Windows among them) require all
|
||||||
# symbols in shared libraries to be resolved at library creation.
|
# symbols in shared libraries to be resolved at library creation.
|
||||||
libwebp_la_LDFLAGS = -no-undefined -version-info 7:2:0
|
libwebp_la_LDFLAGS = -no-undefined -version-info 7:0:0
|
||||||
libwebpincludedir = $(includedir)/webp
|
libwebpincludedir = $(includedir)/webp
|
||||||
pkgconfig_DATA = libwebp.pc
|
pkgconfig_DATA = libwebp.pc
|
||||||
|
|
||||||
@ -48,7 +47,7 @@ if BUILD_LIBWEBPDECODER
|
|||||||
libwebpdecoder_la_LIBADD += dsp/libwebpdspdecode.la
|
libwebpdecoder_la_LIBADD += dsp/libwebpdspdecode.la
|
||||||
libwebpdecoder_la_LIBADD += utils/libwebputilsdecode.la
|
libwebpdecoder_la_LIBADD += utils/libwebputilsdecode.la
|
||||||
|
|
||||||
libwebpdecoder_la_LDFLAGS = -no-undefined -version-info 3:2:0
|
libwebpdecoder_la_LDFLAGS = -no-undefined -version-info 3:0:0
|
||||||
pkgconfig_DATA += libwebpdecoder.pc
|
pkgconfig_DATA += libwebpdecoder.pc
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
AM_CPPFLAGS += -I$(top_builddir) -I$(top_srcdir)
|
|
||||||
noinst_LTLIBRARIES = libwebpdecode.la
|
noinst_LTLIBRARIES = libwebpdecode.la
|
||||||
|
|
||||||
libwebpdecode_la_SOURCES =
|
libwebpdecode_la_SOURCES =
|
||||||
@ -25,5 +24,5 @@ libwebpdecodeinclude_HEADERS += ../webp/types.h
|
|||||||
noinst_HEADERS =
|
noinst_HEADERS =
|
||||||
noinst_HEADERS += ../webp/format_constants.h
|
noinst_HEADERS += ../webp/format_constants.h
|
||||||
|
|
||||||
libwebpdecode_la_CPPFLAGS = $(AM_CPPFLAGS)
|
libwebpdecode_la_CPPFLAGS = $(AM_CPPFLAGS) $(USE_EXPERIMENTAL_CODE)
|
||||||
libwebpdecodeincludedir = $(includedir)/webp
|
libwebpdecodeincludedir = $(includedir)/webp
|
||||||
|
@ -12,13 +12,13 @@
|
|||||||
// Author: Skal (pascal.massimino@gmail.com)
|
// Author: Skal (pascal.massimino@gmail.com)
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include "src/dec/alphai_dec.h"
|
#include "./alphai_dec.h"
|
||||||
#include "src/dec/vp8i_dec.h"
|
#include "./vp8i_dec.h"
|
||||||
#include "src/dec/vp8li_dec.h"
|
#include "./vp8li_dec.h"
|
||||||
#include "src/dsp/dsp.h"
|
#include "../dsp/dsp.h"
|
||||||
#include "src/utils/quant_levels_dec_utils.h"
|
#include "../utils/quant_levels_dec_utils.h"
|
||||||
#include "src/utils/utils.h"
|
#include "../utils/utils.h"
|
||||||
#include "src/webp/format_constants.h"
|
#include "../webp/format_constants.h"
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// ALPHDecoder object.
|
// ALPHDecoder object.
|
||||||
|
@ -11,11 +11,11 @@
|
|||||||
//
|
//
|
||||||
// Author: Urvang (urvang@google.com)
|
// Author: Urvang (urvang@google.com)
|
||||||
|
|
||||||
#ifndef WEBP_DEC_ALPHAI_DEC_H_
|
#ifndef WEBP_DEC_ALPHAI_H_
|
||||||
#define WEBP_DEC_ALPHAI_DEC_H_
|
#define WEBP_DEC_ALPHAI_H_
|
||||||
|
|
||||||
#include "src/dec/webpi_dec.h"
|
#include "./webpi_dec.h"
|
||||||
#include "src/utils/filters_utils.h"
|
#include "../utils/filters_utils.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@ -51,4 +51,4 @@ void WebPDeallocateAlphaMemory(VP8Decoder* const dec);
|
|||||||
} // extern "C"
|
} // extern "C"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* WEBP_DEC_ALPHAI_DEC_H_ */
|
#endif /* WEBP_DEC_ALPHAI_H_ */
|
||||||
|
@ -13,15 +13,15 @@
|
|||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "src/dec/vp8i_dec.h"
|
#include "./vp8i_dec.h"
|
||||||
#include "src/dec/webpi_dec.h"
|
#include "./webpi_dec.h"
|
||||||
#include "src/utils/utils.h"
|
#include "../utils/utils.h"
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// WebPDecBuffer
|
// WebPDecBuffer
|
||||||
|
|
||||||
// Number of bytes per pixel for the different color-spaces.
|
// 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,
|
3, 4, 3, 4, 4, 2, 2,
|
||||||
4, 4, 4, 2, // pre-multiplied modes
|
4, 4, 4, 2, // pre-multiplied modes
|
||||||
1, 1 };
|
1, 1 };
|
||||||
@ -36,7 +36,7 @@ static int IsValidColorspace(int webp_csp_mode) {
|
|||||||
// strictly speaking, the very last (or first, if flipped) row
|
// strictly speaking, the very last (or first, if flipped) row
|
||||||
// doesn't require padding.
|
// doesn't require padding.
|
||||||
#define MIN_BUFFER_SIZE(WIDTH, HEIGHT, STRIDE) \
|
#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) {
|
static VP8StatusCode CheckDecBuffer(const WebPDecBuffer* const buffer) {
|
||||||
int ok = 1;
|
int ok = 1;
|
||||||
@ -98,14 +98,9 @@ static VP8StatusCode AllocateBuffer(WebPDecBuffer* const buffer) {
|
|||||||
uint64_t uv_size = 0, a_size = 0, total_size;
|
uint64_t uv_size = 0, a_size = 0, total_size;
|
||||||
// We need memory and it hasn't been allocated yet.
|
// We need memory and it hasn't been allocated yet.
|
||||||
// => initialize output buffer, now that dimensions are known.
|
// => initialize output buffer, now that dimensions are known.
|
||||||
int stride;
|
const int stride = w * kModeBpp[mode];
|
||||||
uint64_t size;
|
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)) {
|
if (!WebPIsRGBMode(mode)) {
|
||||||
uv_stride = (w + 1) / 2;
|
uv_stride = (w + 1) / 2;
|
||||||
uv_size = (uint64_t)uv_stride * ((h + 1) / 2);
|
uv_size = (uint64_t)uv_stride * ((h + 1) / 2);
|
||||||
@ -174,11 +169,11 @@ VP8StatusCode WebPFlipBuffer(WebPDecBuffer* const buffer) {
|
|||||||
return VP8_STATUS_OK;
|
return VP8_STATUS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
VP8StatusCode WebPAllocateDecBuffer(int width, int height,
|
VP8StatusCode WebPAllocateDecBuffer(int w, int h,
|
||||||
const WebPDecoderOptions* const options,
|
const WebPDecoderOptions* const options,
|
||||||
WebPDecBuffer* const buffer) {
|
WebPDecBuffer* const out) {
|
||||||
VP8StatusCode status;
|
VP8StatusCode status;
|
||||||
if (buffer == NULL || width <= 0 || height <= 0) {
|
if (out == NULL || w <= 0 || h <= 0) {
|
||||||
return VP8_STATUS_INVALID_PARAM;
|
return VP8_STATUS_INVALID_PARAM;
|
||||||
}
|
}
|
||||||
if (options != NULL) { // First, apply options if there is any.
|
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 ch = options->crop_height;
|
||||||
const int x = options->crop_left & ~1;
|
const int x = options->crop_left & ~1;
|
||||||
const int y = options->crop_top & ~1;
|
const int y = options->crop_top & ~1;
|
||||||
if (x < 0 || y < 0 || cw <= 0 || ch <= 0 ||
|
if (x < 0 || y < 0 || cw <= 0 || ch <= 0 || x + cw > w || y + ch > h) {
|
||||||
x + cw > width || y + ch > height) {
|
|
||||||
return VP8_STATUS_INVALID_PARAM; // out of frame boundary.
|
return VP8_STATUS_INVALID_PARAM; // out of frame boundary.
|
||||||
}
|
}
|
||||||
width = cw;
|
w = cw;
|
||||||
height = ch;
|
h = ch;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options->use_scaling) {
|
if (options->use_scaling) {
|
||||||
#if !defined(WEBP_REDUCE_SIZE)
|
|
||||||
int scaled_width = options->scaled_width;
|
int scaled_width = options->scaled_width;
|
||||||
int scaled_height = options->scaled_height;
|
int scaled_height = options->scaled_height;
|
||||||
if (!WebPRescalerGetScaledDimensions(
|
if (!WebPRescalerGetScaledDimensions(
|
||||||
width, height, &scaled_width, &scaled_height)) {
|
w, h, &scaled_width, &scaled_height)) {
|
||||||
return VP8_STATUS_INVALID_PARAM;
|
return VP8_STATUS_INVALID_PARAM;
|
||||||
}
|
}
|
||||||
width = scaled_width;
|
w = scaled_width;
|
||||||
height = scaled_height;
|
h = scaled_height;
|
||||||
#else
|
|
||||||
return VP8_STATUS_INVALID_PARAM; // rescaling not supported
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
buffer->width = width;
|
out->width = w;
|
||||||
buffer->height = height;
|
out->height = h;
|
||||||
|
|
||||||
// Then, allocate buffer for real.
|
// Then, allocate buffer for real.
|
||||||
status = AllocateBuffer(buffer);
|
status = AllocateBuffer(out);
|
||||||
if (status != VP8_STATUS_OK) return status;
|
if (status != VP8_STATUS_OK) return status;
|
||||||
|
|
||||||
// Use the stride trick if vertical flip is needed.
|
// Use the stride trick if vertical flip is needed.
|
||||||
if (options != NULL && options->flip) {
|
if (options != NULL && options->flip) {
|
||||||
status = WebPFlipBuffer(buffer);
|
status = WebPFlipBuffer(out);
|
||||||
}
|
}
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
@ -11,8 +11,8 @@
|
|||||||
//
|
//
|
||||||
// Author: Skal (pascal.massimino@gmail.com)
|
// Author: Skal (pascal.massimino@gmail.com)
|
||||||
|
|
||||||
#ifndef WEBP_DEC_COMMON_DEC_H_
|
#ifndef WEBP_DEC_COMMON_H_
|
||||||
#define WEBP_DEC_COMMON_DEC_H_
|
#define WEBP_DEC_COMMON_H_
|
||||||
|
|
||||||
// intra prediction modes
|
// intra prediction modes
|
||||||
enum { B_DC_PRED = 0, // 4x4 modes
|
enum { B_DC_PRED = 0, // 4x4 modes
|
||||||
@ -51,4 +51,4 @@ enum { MB_FEATURE_TREE_PROBS = 3,
|
|||||||
NUM_PROBAS = 11
|
NUM_PROBAS = 11
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // WEBP_DEC_COMMON_DEC_H_
|
#endif // WEBP_DEC_COMMON_H_
|
||||||
|
@ -12,13 +12,13 @@
|
|||||||
// Author: Skal (pascal.massimino@gmail.com)
|
// Author: Skal (pascal.massimino@gmail.com)
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include "src/dec/vp8i_dec.h"
|
#include "./vp8i_dec.h"
|
||||||
#include "src/utils/utils.h"
|
#include "../utils/utils.h"
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Main reconstruction function.
|
// 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 + 0 * BPS, 4 + 0 * BPS, 8 + 0 * BPS, 12 + 0 * BPS,
|
||||||
0 + 4 * BPS, 4 + 4 * BPS, 8 + 4 * BPS, 12 + 4 * 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,
|
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 MIN_DITHER_AMP 4
|
||||||
|
|
||||||
#define DITHER_AMP_TAB_SIZE 12
|
#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]
|
// roughly, it's dqm->uv_mat_[1]
|
||||||
8, 7, 6, 4, 4, 2, 2, 2, 1, 1, 1, 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
|
#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.
|
// Finalize and transmit a complete row. Return false in case of user-abort.
|
||||||
static int FinishRow(void* arg1, void* arg2) {
|
static int FinishRow(VP8Decoder* const dec, VP8Io* const io) {
|
||||||
VP8Decoder* const dec = (VP8Decoder*)arg1;
|
|
||||||
VP8Io* const io = (VP8Io*)arg2;
|
|
||||||
int ok = 1;
|
int ok = 1;
|
||||||
const VP8ThreadContext* const ctx = &dec->thread_ctx_;
|
const VP8ThreadContext* const ctx = &dec->thread_ctx_;
|
||||||
const int cache_id = ctx->id_;
|
const int cache_id = ctx->id_;
|
||||||
@ -450,9 +448,10 @@ static int FinishRow(void* arg1, void* arg2) {
|
|||||||
if (y_end > io->crop_bottom) {
|
if (y_end > io->crop_bottom) {
|
||||||
y_end = io->crop_bottom; // make sure we don't overflow on last row.
|
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;
|
io->a = NULL;
|
||||||
if (dec->alpha_data_ != NULL && y_start < y_end) {
|
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);
|
io->a = VP8DecompressAlphaRows(dec, io, y_start, y_end - y_start);
|
||||||
if (io->a == NULL) {
|
if (io->a == NULL) {
|
||||||
return VP8SetError(dec, VP8_STATUS_BITSTREAM_ERROR,
|
return VP8SetError(dec, VP8_STATUS_BITSTREAM_ERROR,
|
||||||
@ -559,6 +558,7 @@ VP8StatusCode VP8EnterCritical(VP8Decoder* const dec, VP8Io* const io) {
|
|||||||
if (io->bypass_filtering) {
|
if (io->bypass_filtering) {
|
||||||
dec->filter_type_ = 0;
|
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.
|
// 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
|
// 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
|
// top-left corner of the picture (MB #0). We must filter all the previous
|
||||||
// macroblocks.
|
// 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_];
|
const int extra_pixels = kFilterExtraRows[dec->filter_type_];
|
||||||
if (dec->filter_type_ == 2) {
|
if (dec->filter_type_ == 2) {
|
||||||
@ -649,7 +651,7 @@ static int InitThreadContext(VP8Decoder* const dec) {
|
|||||||
}
|
}
|
||||||
worker->data1 = dec;
|
worker->data1 = dec;
|
||||||
worker->data2 = (void*)&dec->thread_ctx_.io_;
|
worker->data2 = (void*)&dec->thread_ctx_.io_;
|
||||||
worker->hook = FinishRow;
|
worker->hook = (WebPWorkerHook)FinishRow;
|
||||||
dec->num_caches_ =
|
dec->num_caches_ =
|
||||||
(dec->filter_type_ > 0) ? MT_CACHE_LINES : MT_CACHE_LINES - 1;
|
(dec->filter_type_ > 0) ? MT_CACHE_LINES : MT_CACHE_LINES - 1;
|
||||||
} else {
|
} else {
|
||||||
@ -726,7 +728,7 @@ static int AllocateMemory(VP8Decoder* const dec) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mem = (uint8_t*)dec->mem_;
|
mem = (uint8_t*)dec->mem_;
|
||||||
dec->intra_t_ = mem;
|
dec->intra_t_ = (uint8_t*)mem;
|
||||||
mem += intra_pred_mode_size;
|
mem += intra_pred_mode_size;
|
||||||
|
|
||||||
dec->yuv_t_ = (VP8TopSamples*)mem;
|
dec->yuv_t_ = (VP8TopSamples*)mem;
|
||||||
@ -748,7 +750,7 @@ static int AllocateMemory(VP8Decoder* const dec) {
|
|||||||
|
|
||||||
mem = (uint8_t*)WEBP_ALIGN(mem);
|
mem = (uint8_t*)WEBP_ALIGN(mem);
|
||||||
assert((yuv_size & WEBP_ALIGN_CST) == 0);
|
assert((yuv_size & WEBP_ALIGN_CST) == 0);
|
||||||
dec->yuv_b_ = mem;
|
dec->yuv_b_ = (uint8_t*)mem;
|
||||||
mem += yuv_size;
|
mem += yuv_size;
|
||||||
|
|
||||||
dec->mb_data_ = (VP8MBData*)mem;
|
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_rows = kFilterExtraRows[dec->filter_type_];
|
||||||
const int extra_y = extra_rows * dec->cache_y_stride_;
|
const int extra_y = extra_rows * dec->cache_y_stride_;
|
||||||
const int extra_uv = (extra_rows / 2) * dec->cache_uv_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_
|
dec->cache_u_ = dec->cache_y_
|
||||||
+ 16 * num_caches * dec->cache_y_stride_ + extra_uv;
|
+ 16 * num_caches * dec->cache_y_stride_ + extra_uv;
|
||||||
dec->cache_v_ = dec->cache_u_
|
dec->cache_v_ = dec->cache_u_
|
||||||
@ -774,7 +776,7 @@ static int AllocateMemory(VP8Decoder* const dec) {
|
|||||||
mem += cache_size;
|
mem += cache_size;
|
||||||
|
|
||||||
// alpha plane
|
// alpha plane
|
||||||
dec->alpha_plane_ = alpha_size ? mem : NULL;
|
dec->alpha_plane_ = alpha_size ? (uint8_t*)mem : NULL;
|
||||||
mem += alpha_size;
|
mem += alpha_size;
|
||||||
assert(mem <= (uint8_t*)dec->mem_ + dec->mem_size_);
|
assert(mem <= (uint8_t*)dec->mem_ + dec->mem_size_);
|
||||||
|
|
||||||
|
@ -15,10 +15,10 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "src/dec/alphai_dec.h"
|
#include "./alphai_dec.h"
|
||||||
#include "src/dec/webpi_dec.h"
|
#include "./webpi_dec.h"
|
||||||
#include "src/dec/vp8i_dec.h"
|
#include "./vp8i_dec.h"
|
||||||
#include "src/utils/utils.h"
|
#include "../utils/utils.h"
|
||||||
|
|
||||||
// In append mode, buffer allocations increase as multiples of this value.
|
// In append mode, buffer allocations increase as multiples of this value.
|
||||||
// Needs to be a power of 2.
|
// Needs to be a power of 2.
|
||||||
@ -673,12 +673,12 @@ void WebPIDelete(WebPIDecoder* idec) {
|
|||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Wrapper toward WebPINewDecoder
|
// 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) {
|
size_t output_buffer_size, int output_stride) {
|
||||||
const int is_external_memory = (output_buffer != NULL) ? 1 : 0;
|
const int is_external_memory = (output_buffer != NULL) ? 1 : 0;
|
||||||
WebPIDecoder* idec;
|
WebPIDecoder* idec;
|
||||||
|
|
||||||
if (csp >= MODE_YUV) return NULL;
|
if (mode >= MODE_YUV) return NULL;
|
||||||
if (is_external_memory == 0) { // Overwrite parameters to sane values.
|
if (is_external_memory == 0) { // Overwrite parameters to sane values.
|
||||||
output_buffer_size = 0;
|
output_buffer_size = 0;
|
||||||
output_stride = 0;
|
output_stride = 0;
|
||||||
@ -689,7 +689,7 @@ WebPIDecoder* WebPINewRGB(WEBP_CSP_MODE csp, uint8_t* output_buffer,
|
|||||||
}
|
}
|
||||||
idec = WebPINewDecoder(NULL);
|
idec = WebPINewDecoder(NULL);
|
||||||
if (idec == NULL) return NULL;
|
if (idec == NULL) return NULL;
|
||||||
idec->output_.colorspace = csp;
|
idec->output_.colorspace = mode;
|
||||||
idec->output_.is_external_memory = is_external_memory;
|
idec->output_.is_external_memory = is_external_memory;
|
||||||
idec->output_.u.RGBA.rgba = output_buffer;
|
idec->output_.u.RGBA.rgba = output_buffer;
|
||||||
idec->output_.u.RGBA.stride = output_stride;
|
idec->output_.u.RGBA.stride = output_stride;
|
||||||
|
@ -13,11 +13,11 @@
|
|||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include "src/dec/vp8i_dec.h"
|
#include "../dec/vp8i_dec.h"
|
||||||
#include "src/dec/webpi_dec.h"
|
#include "./webpi_dec.h"
|
||||||
#include "src/dsp/dsp.h"
|
#include "../dsp/dsp.h"
|
||||||
#include "src/dsp/yuv.h"
|
#include "../dsp/yuv.h"
|
||||||
#include "src/utils/utils.h"
|
#include "../utils/utils.h"
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Main YUV<->RGB conversion functions
|
// Main YUV<->RGB conversion functions
|
||||||
@ -212,7 +212,7 @@ static int EmitAlphaRGBA4444(const VP8Io* const io, WebPDecParams* const p,
|
|||||||
int num_rows;
|
int num_rows;
|
||||||
const int start_y = GetAlphaSourceRow(io, &alpha, &num_rows);
|
const int start_y = GetAlphaSourceRow(io, &alpha, &num_rows);
|
||||||
uint8_t* const base_rgba = buf->rgba + start_y * buf->stride;
|
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;
|
uint8_t* alpha_dst = base_rgba;
|
||||||
#else
|
#else
|
||||||
uint8_t* alpha_dst = base_rgba + 1;
|
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)
|
// YUV rescaling (no final RGB conversion needed)
|
||||||
|
|
||||||
#if !defined(WEBP_REDUCE_SIZE)
|
|
||||||
static int Rescale(const uint8_t* src, int src_stride,
|
static int Rescale(const uint8_t* src, int src_stride,
|
||||||
int new_lines, WebPRescaler* const wrk) {
|
int new_lines, WebPRescaler* const wrk) {
|
||||||
int num_lines_out = 0;
|
int num_lines_out = 0;
|
||||||
@ -432,7 +431,7 @@ static int ExportAlphaRGBA4444(WebPDecParams* const p, int y_pos,
|
|||||||
int max_lines_out) {
|
int max_lines_out) {
|
||||||
const WebPRGBABuffer* const buf = &p->output->u.RGBA;
|
const WebPRGBABuffer* const buf = &p->output->u.RGBA;
|
||||||
uint8_t* const base_rgba = buf->rgba + y_pos * buf->stride;
|
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;
|
uint8_t* alpha_dst = base_rgba;
|
||||||
#else
|
#else
|
||||||
uint8_t* alpha_dst = base_rgba + 1;
|
uint8_t* alpha_dst = base_rgba + 1;
|
||||||
@ -542,8 +541,6 @@ static int InitRGBRescaler(const VP8Io* const io, WebPDecParams* const p) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // WEBP_REDUCE_SIZE
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Default custom functions
|
// Default custom functions
|
||||||
|
|
||||||
@ -564,14 +561,10 @@ static int CustomSetup(VP8Io* io) {
|
|||||||
WebPInitUpsamplers();
|
WebPInitUpsamplers();
|
||||||
}
|
}
|
||||||
if (io->use_scaling) {
|
if (io->use_scaling) {
|
||||||
#if !defined(WEBP_REDUCE_SIZE)
|
|
||||||
const int ok = is_rgb ? InitRGBRescaler(io, p) : InitYUVRescaler(io, p);
|
const int ok = is_rgb ? InitRGBRescaler(io, p) : InitYUVRescaler(io, p);
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
return 0; // memory error
|
return 0; // memory error
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
return 0; // rescaling support not compiled
|
|
||||||
#endif
|
|
||||||
} else {
|
} else {
|
||||||
if (is_rgb) {
|
if (is_rgb) {
|
||||||
WebPInitSamplers();
|
WebPInitSamplers();
|
||||||
@ -605,6 +598,9 @@ static int CustomSetup(VP8Io* io) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (is_rgb) {
|
||||||
|
VP8YUVInit();
|
||||||
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
//
|
//
|
||||||
// Author: Skal (pascal.massimino@gmail.com)
|
// 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) {
|
static WEBP_INLINE int clip(int v, int M) {
|
||||||
return v < 0 ? 0 : v > M ? M : v;
|
return v < 0 ? 0 : v > M ? M : v;
|
||||||
|
@ -11,19 +11,15 @@
|
|||||||
//
|
//
|
||||||
// Author: Skal (pascal.massimino@gmail.com)
|
// Author: Skal (pascal.massimino@gmail.com)
|
||||||
|
|
||||||
#include "src/dec/vp8i_dec.h"
|
#include "./vp8i_dec.h"
|
||||||
#include "src/utils/bit_reader_inl_utils.h"
|
#include "../utils/bit_reader_inl_utils.h"
|
||||||
|
|
||||||
#if !defined(USE_GENERIC_TREE)
|
|
||||||
#if !defined(__arm__) && !defined(_M_ARM) && !defined(__aarch64__)
|
#if !defined(__arm__) && !defined(_M_ARM) && !defined(__aarch64__)
|
||||||
// using a table is ~1-2% slower on ARM. Prefer the coded-tree approach then.
|
// using a table is ~1-2% slower on ARM. Prefer the coded-tree approach then.
|
||||||
#define USE_GENERIC_TREE 1 // ALTERNATE_CODE
|
#define USE_GENERIC_TREE
|
||||||
#else
|
|
||||||
#define USE_GENERIC_TREE 0
|
|
||||||
#endif
|
#endif
|
||||||
#endif // USE_GENERIC_TREE
|
|
||||||
|
|
||||||
#if (USE_GENERIC_TREE == 1)
|
#ifdef USE_GENERIC_TREE
|
||||||
static const int8_t kYModesIntra4[18] = {
|
static const int8_t kYModesIntra4[18] = {
|
||||||
-B_DC_PRED, 1,
|
-B_DC_PRED, 1,
|
||||||
-B_TM_PRED, 2,
|
-B_TM_PRED, 2,
|
||||||
@ -321,7 +317,7 @@ static void ParseIntraMode(VP8BitReader* const br,
|
|||||||
int x;
|
int x;
|
||||||
for (x = 0; x < 4; ++x) {
|
for (x = 0; x < 4; ++x) {
|
||||||
const uint8_t* const prob = kBModesProba[top[x]][ymode];
|
const uint8_t* const prob = kBModesProba[top[x]][ymode];
|
||||||
#if (USE_GENERIC_TREE == 1)
|
#ifdef USE_GENERIC_TREE
|
||||||
// Generic tree-parsing
|
// Generic tree-parsing
|
||||||
int i = kYModesIntra4[VP8GetBit(br, prob[0])];
|
int i = kYModesIntra4[VP8GetBit(br, prob[0])];
|
||||||
while (i > 0) {
|
while (i > 0) {
|
||||||
@ -339,7 +335,7 @@ static void ParseIntraMode(VP8BitReader* const br,
|
|||||||
(!VP8GetBit(br, prob[6]) ? B_LD_PRED :
|
(!VP8GetBit(br, prob[6]) ? B_LD_PRED :
|
||||||
(!VP8GetBit(br, prob[7]) ? B_VL_PRED :
|
(!VP8GetBit(br, prob[7]) ? B_VL_PRED :
|
||||||
(!VP8GetBit(br, prob[8]) ? B_HD_PRED : B_HU_PRED)));
|
(!VP8GetBit(br, prob[8]) ? B_HD_PRED : B_HU_PRED)));
|
||||||
#endif // USE_GENERIC_TREE
|
#endif // USE_GENERIC_TREE
|
||||||
top[x] = ymode;
|
top[x] = ymode;
|
||||||
}
|
}
|
||||||
memcpy(modes, top, 4 * sizeof(*top));
|
memcpy(modes, top, 4 * sizeof(*top));
|
||||||
@ -502,7 +498,7 @@ static const uint8_t
|
|||||||
|
|
||||||
// Paragraph 9.9
|
// 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, 1, 2, 3, 6, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6, 7,
|
||||||
0 // extra entry as sentinel
|
0 // extra entry as sentinel
|
||||||
};
|
};
|
||||||
|
@ -13,12 +13,12 @@
|
|||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "src/dec/alphai_dec.h"
|
#include "./alphai_dec.h"
|
||||||
#include "src/dec/vp8i_dec.h"
|
#include "./vp8i_dec.h"
|
||||||
#include "src/dec/vp8li_dec.h"
|
#include "./vp8li_dec.h"
|
||||||
#include "src/dec/webpi_dec.h"
|
#include "./webpi_dec.h"
|
||||||
#include "src/utils/bit_reader_inl_utils.h"
|
#include "../utils/bit_reader_inl_utils.h"
|
||||||
#include "src/utils/utils.h"
|
#include "../utils/utils.h"
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
@ -491,7 +491,7 @@ static int GetCoeffsAlt(VP8BitReader* const br,
|
|||||||
return 16;
|
return 16;
|
||||||
}
|
}
|
||||||
|
|
||||||
static WEBP_TSAN_IGNORE_FUNCTION void InitGetCoeffs(void) {
|
WEBP_TSAN_IGNORE_FUNCTION static void InitGetCoeffs(void) {
|
||||||
if (GetCoeffs == NULL) {
|
if (GetCoeffs == NULL) {
|
||||||
if (VP8GetCPUInfo != NULL && VP8GetCPUInfo(kSlowSSSE3)) {
|
if (VP8GetCPUInfo != NULL && VP8GetCPUInfo(kSlowSSSE3)) {
|
||||||
GetCoeffs = GetCoeffsAlt;
|
GetCoeffs = GetCoeffsAlt;
|
||||||
|
@ -11,10 +11,10 @@
|
|||||||
//
|
//
|
||||||
// Author: Skal (pascal.massimino@gmail.com)
|
// Author: Skal (pascal.massimino@gmail.com)
|
||||||
|
|
||||||
#ifndef WEBP_DEC_VP8_DEC_H_
|
#ifndef WEBP_WEBP_DECODE_VP8_H_
|
||||||
#define WEBP_DEC_VP8_DEC_H_
|
#define WEBP_WEBP_DECODE_VP8_H_
|
||||||
|
|
||||||
#include "src/webp/decode.h"
|
#include "../webp/decode.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@ -157,24 +157,24 @@ void VP8Delete(VP8Decoder* const dec);
|
|||||||
// Miscellaneous VP8/VP8L bitstream probing functions.
|
// Miscellaneous VP8/VP8L bitstream probing functions.
|
||||||
|
|
||||||
// Returns true if the next 3 bytes in data contain the VP8 signature.
|
// 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
|
// Validates the VP8 data-header and retrieves basic header information viz
|
||||||
// width and height. Returns 0 in case of formatting error. *width/*height
|
// width and height. Returns 0 in case of formatting error. *width/*height
|
||||||
// can be passed NULL.
|
// can be passed NULL.
|
||||||
WEBP_EXTERN int VP8GetInfo(
|
WEBP_EXTERN(int) VP8GetInfo(
|
||||||
const uint8_t* data,
|
const uint8_t* data,
|
||||||
size_t data_size, // data available so far
|
size_t data_size, // data available so far
|
||||||
size_t chunk_size, // total data size expected in the chunk
|
size_t chunk_size, // total data size expected in the chunk
|
||||||
int* const width, int* const height);
|
int* const width, int* const height);
|
||||||
|
|
||||||
// Returns true if the next byte(s) in data is a VP8L signature.
|
// 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
|
// Validates the VP8L data-header and retrieves basic header information viz
|
||||||
// width, height and alpha. Returns 0 in case of formatting error.
|
// width, height and alpha. Returns 0 in case of formatting error.
|
||||||
// width/height/has_alpha can be passed NULL.
|
// 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
|
const uint8_t* data, size_t data_size, // data available so far
|
||||||
int* const width, int* const height, int* const has_alpha);
|
int* const width, int* const height, int* const has_alpha);
|
||||||
|
|
||||||
@ -182,4 +182,4 @@ WEBP_EXTERN int VP8LGetInfo(
|
|||||||
} // extern "C"
|
} // extern "C"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* WEBP_DEC_VP8_DEC_H_ */
|
#endif /* WEBP_WEBP_DECODE_VP8_H_ */
|
||||||
|
@ -11,16 +11,16 @@
|
|||||||
//
|
//
|
||||||
// Author: Skal (pascal.massimino@gmail.com)
|
// Author: Skal (pascal.massimino@gmail.com)
|
||||||
|
|
||||||
#ifndef WEBP_DEC_VP8I_DEC_H_
|
#ifndef WEBP_DEC_VP8I_H_
|
||||||
#define WEBP_DEC_VP8I_DEC_H_
|
#define WEBP_DEC_VP8I_H_
|
||||||
|
|
||||||
#include <string.h> // for memcpy()
|
#include <string.h> // for memcpy()
|
||||||
#include "src/dec/common_dec.h"
|
#include "./common_dec.h"
|
||||||
#include "src/dec/vp8li_dec.h"
|
#include "./vp8li_dec.h"
|
||||||
#include "src/utils/bit_reader_utils.h"
|
#include "../utils/bit_reader_utils.h"
|
||||||
#include "src/utils/random_utils.h"
|
#include "../utils/random_utils.h"
|
||||||
#include "src/utils/thread_utils.h"
|
#include "../utils/thread_utils.h"
|
||||||
#include "src/dsp/dsp.h"
|
#include "../dsp/dsp.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@ -30,8 +30,8 @@ extern "C" {
|
|||||||
// Various defines and enums
|
// Various defines and enums
|
||||||
|
|
||||||
// version numbers
|
// version numbers
|
||||||
#define DEC_MAJ_VERSION 1
|
#define DEC_MAJ_VERSION 0
|
||||||
#define DEC_MIN_VERSION 0
|
#define DEC_MIN_VERSION 6
|
||||||
#define DEC_REV_VERSION 0
|
#define DEC_REV_VERSION 0
|
||||||
|
|
||||||
// YUV-cache parameters. Cache is 32-bytes wide (= one cacheline).
|
// YUV-cache parameters. Cache is 32-bytes wide (= one cacheline).
|
||||||
@ -57,6 +57,7 @@ extern "C" {
|
|||||||
// '|' = left sample, '-' = top sample, '+' = top-left sample
|
// '|' = left sample, '-' = top sample, '+' = top-left sample
|
||||||
// 't' = extra top-right sample for 4x4 modes
|
// 't' = extra top-right sample for 4x4 modes
|
||||||
#define YUV_SIZE (BPS * 17 + BPS * 9)
|
#define YUV_SIZE (BPS * 17 + BPS * 9)
|
||||||
|
#define Y_SIZE (BPS * 17)
|
||||||
#define Y_OFF (BPS * 1 + 8)
|
#define Y_OFF (BPS * 1 + 8)
|
||||||
#define U_OFF (Y_OFF + BPS * 16 + BPS)
|
#define U_OFF (Y_OFF + BPS * 16 + BPS)
|
||||||
#define V_OFF (U_OFF + 16)
|
#define V_OFF (U_OFF + 16)
|
||||||
@ -316,4 +317,4 @@ const uint8_t* VP8DecompressAlphaRows(VP8Decoder* const dec,
|
|||||||
} // extern "C"
|
} // extern "C"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* WEBP_DEC_VP8I_DEC_H_ */
|
#endif /* WEBP_DEC_VP8I_H_ */
|
||||||
|
@ -14,22 +14,22 @@
|
|||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "src/dec/alphai_dec.h"
|
#include "./alphai_dec.h"
|
||||||
#include "src/dec/vp8li_dec.h"
|
#include "./vp8li_dec.h"
|
||||||
#include "src/dsp/dsp.h"
|
#include "../dsp/dsp.h"
|
||||||
#include "src/dsp/lossless.h"
|
#include "../dsp/lossless.h"
|
||||||
#include "src/dsp/lossless_common.h"
|
#include "../dsp/lossless_common.h"
|
||||||
#include "src/dsp/yuv.h"
|
#include "../dsp/yuv.h"
|
||||||
#include "src/utils/endian_inl_utils.h"
|
#include "../utils/endian_inl_utils.h"
|
||||||
#include "src/utils/huffman_utils.h"
|
#include "../utils/huffman_utils.h"
|
||||||
#include "src/utils/utils.h"
|
#include "../utils/utils.h"
|
||||||
|
|
||||||
#define NUM_ARGB_CACHE_ROWS 16
|
#define NUM_ARGB_CACHE_ROWS 16
|
||||||
|
|
||||||
static const int kCodeLengthLiterals = 16;
|
static const int kCodeLengthLiterals = 16;
|
||||||
static const int kCodeLengthRepeatCode = 16;
|
static const int kCodeLengthRepeatCode = 16;
|
||||||
static const uint8_t kCodeLengthExtraBits[3] = { 2, 3, 7 };
|
static const int kCodeLengthExtraBits[3] = { 2, 3, 7 };
|
||||||
static const uint8_t kCodeLengthRepeatOffsets[3] = { 3, 3, 11 };
|
static const int kCodeLengthRepeatOffsets[3] = { 3, 3, 11 };
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// Five Huffman codes are used at each meta code:
|
// 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:
|
// 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
|
// http://www.hdfgroup.org/ftp/lib-external/zlib/zlib-1.2.5/examples/enough.c
|
||||||
#define FIXED_TABLE_SIZE (630 * 3 + 410)
|
#define FIXED_TABLE_SIZE (630 * 3 + 410)
|
||||||
static const uint16_t kTableSize[12] = {
|
static const int kTableSize[12] = {
|
||||||
FIXED_TABLE_SIZE + 654,
|
FIXED_TABLE_SIZE + 654,
|
||||||
FIXED_TABLE_SIZE + 656,
|
FIXED_TABLE_SIZE + 656,
|
||||||
FIXED_TABLE_SIZE + 658,
|
FIXED_TABLE_SIZE + 658,
|
||||||
@ -485,7 +485,6 @@ static int ReadHuffmanCodes(VP8LDecoder* const dec, int xsize, int ysize,
|
|||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Scaling.
|
// Scaling.
|
||||||
|
|
||||||
#if !defined(WEBP_REDUCE_SIZE)
|
|
||||||
static int AllocateAndInitRescaler(VP8LDecoder* const dec, VP8Io* const io) {
|
static int AllocateAndInitRescaler(VP8LDecoder* const dec, VP8Io* const io) {
|
||||||
const int num_channels = 4;
|
const int num_channels = 4;
|
||||||
const int in_width = io->mb_w;
|
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);
|
out_width, out_height, 0, num_channels, work);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
#endif // WEBP_REDUCE_SIZE
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Export to ARGB
|
// Export to ARGB
|
||||||
|
|
||||||
#if !defined(WEBP_REDUCE_SIZE)
|
|
||||||
|
|
||||||
// We have special "export" function since we need to convert from BGRA
|
// We have special "export" function since we need to convert from BGRA
|
||||||
static int Export(WebPRescaler* const rescaler, WEBP_CSP_MODE colorspace,
|
static int Export(WebPRescaler* const rescaler, WEBP_CSP_MODE colorspace,
|
||||||
int rgba_stride, uint8_t* const rgba) {
|
int rgba_stride, uint8_t* const rgba) {
|
||||||
@ -565,8 +561,6 @@ static int EmitRescaledRowsRGBA(const VP8LDecoder* const dec,
|
|||||||
return num_lines_out;
|
return num_lines_out;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // WEBP_REDUCE_SIZE
|
|
||||||
|
|
||||||
// Emit rows without any scaling.
|
// Emit rows without any scaling.
|
||||||
static int EmitRows(WEBP_CSP_MODE colorspace,
|
static int EmitRows(WEBP_CSP_MODE colorspace,
|
||||||
const uint8_t* row_in, int in_stride,
|
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
|
if (WebPIsRGBMode(output->colorspace)) { // convert to RGBA
|
||||||
const WebPRGBABuffer* const buf = &output->u.RGBA;
|
const WebPRGBABuffer* const buf = &output->u.RGBA;
|
||||||
uint8_t* const rgba = buf->rgba + dec->last_out_row_ * buf->stride;
|
uint8_t* const rgba = buf->rgba + dec->last_out_row_ * buf->stride;
|
||||||
const int num_rows_out =
|
const int num_rows_out = io->use_scaling ?
|
||||||
#if !defined(WEBP_REDUCE_SIZE)
|
|
||||||
io->use_scaling ?
|
|
||||||
EmitRescaledRowsRGBA(dec, rows_data, in_stride, io->mb_h,
|
EmitRescaledRowsRGBA(dec, rows_data, in_stride, io->mb_h,
|
||||||
rgba, buf->stride) :
|
rgba, buf->stride) :
|
||||||
#endif // WEBP_REDUCE_SIZE
|
|
||||||
EmitRows(output->colorspace, rows_data, in_stride,
|
EmitRows(output->colorspace, rows_data, in_stride,
|
||||||
io->mb_w, io->mb_h, rgba, buf->stride);
|
io->mb_w, io->mb_h, rgba, buf->stride);
|
||||||
// Update 'last_out_row_'.
|
// Update 'last_out_row_'.
|
||||||
@ -1641,19 +1632,12 @@ int VP8LDecodeImage(VP8LDecoder* const dec) {
|
|||||||
|
|
||||||
if (!AllocateInternalBuffers32b(dec, io->width)) goto Err;
|
if (!AllocateInternalBuffers32b(dec, io->width)) goto Err;
|
||||||
|
|
||||||
#if !defined(WEBP_REDUCE_SIZE)
|
|
||||||
if (io->use_scaling && !AllocateAndInitRescaler(dec, io)) goto Err;
|
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)) {
|
if (io->use_scaling || WebPIsPremultipliedMode(dec->output_->colorspace)) {
|
||||||
// need the alpha-multiply functions for premultiplied output or rescaling
|
// need the alpha-multiply functions for premultiplied output or rescaling
|
||||||
WebPInitAlphaProcessing();
|
WebPInitAlphaProcessing();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!WebPIsRGBMode(dec->output_->colorspace)) {
|
if (!WebPIsRGBMode(dec->output_->colorspace)) {
|
||||||
WebPInitConvertARGBToYUV();
|
WebPInitConvertARGBToYUV();
|
||||||
if (dec->output_->u.YUVA.a != NULL) WebPInitAlphaProcessing();
|
if (dec->output_->u.YUVA.a != NULL) WebPInitAlphaProcessing();
|
||||||
|
@ -12,14 +12,14 @@
|
|||||||
// Author: Skal (pascal.massimino@gmail.com)
|
// Author: Skal (pascal.massimino@gmail.com)
|
||||||
// Vikas Arora(vikaas.arora@gmail.com)
|
// Vikas Arora(vikaas.arora@gmail.com)
|
||||||
|
|
||||||
#ifndef WEBP_DEC_VP8LI_DEC_H_
|
#ifndef WEBP_DEC_VP8LI_H_
|
||||||
#define WEBP_DEC_VP8LI_DEC_H_
|
#define WEBP_DEC_VP8LI_H_
|
||||||
|
|
||||||
#include <string.h> // for memcpy()
|
#include <string.h> // for memcpy()
|
||||||
#include "src/dec/webpi_dec.h"
|
#include "./webpi_dec.h"
|
||||||
#include "src/utils/bit_reader_utils.h"
|
#include "../utils/bit_reader_utils.h"
|
||||||
#include "src/utils/color_cache_utils.h"
|
#include "../utils/color_cache_utils.h"
|
||||||
#include "src/utils/huffman_utils.h"
|
#include "../utils/huffman_utils.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@ -132,4 +132,4 @@ void VP8LDelete(VP8LDecoder* const dec);
|
|||||||
} // extern "C"
|
} // extern "C"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* WEBP_DEC_VP8LI_DEC_H_ */
|
#endif /* WEBP_DEC_VP8LI_H_ */
|
||||||
|
@ -13,11 +13,11 @@
|
|||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "src/dec/vp8i_dec.h"
|
#include "./vp8i_dec.h"
|
||||||
#include "src/dec/vp8li_dec.h"
|
#include "./vp8li_dec.h"
|
||||||
#include "src/dec/webpi_dec.h"
|
#include "./webpi_dec.h"
|
||||||
#include "src/utils/utils.h"
|
#include "../utils/utils.h"
|
||||||
#include "src/webp/mux_types.h" // ALPHA_FLAG
|
#include "../webp/mux_types.h" // ALPHA_FLAG
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// RIFF layout is:
|
// RIFF layout is:
|
||||||
@ -421,9 +421,7 @@ VP8StatusCode WebPParseHeaders(WebPHeaderStructure* const headers) {
|
|||||||
NULL, NULL, NULL, &has_animation,
|
NULL, NULL, NULL, &has_animation,
|
||||||
NULL, headers);
|
NULL, headers);
|
||||||
if (status == VP8_STATUS_OK || status == VP8_STATUS_NOT_ENOUGH_DATA) {
|
if (status == VP8_STATUS_OK || status == VP8_STATUS_NOT_ENOUGH_DATA) {
|
||||||
// The WebPDemux API + libwebp can be used to decode individual
|
// TODO(jzern): full support of animation frames will require API additions.
|
||||||
// uncomposited frames or the WebPAnimDecoder can be used to fully
|
|
||||||
// reconstruct them (see webp/demux.h).
|
|
||||||
if (has_animation) {
|
if (has_animation) {
|
||||||
status = VP8_STATUS_UNSUPPORTED_FEATURE;
|
status = VP8_STATUS_UNSUPPORTED_FEATURE;
|
||||||
}
|
}
|
||||||
|
@ -11,15 +11,15 @@
|
|||||||
//
|
//
|
||||||
// Author: somnath@google.com (Somnath Banerjee)
|
// Author: somnath@google.com (Somnath Banerjee)
|
||||||
|
|
||||||
#ifndef WEBP_DEC_WEBPI_DEC_H_
|
#ifndef WEBP_DEC_WEBPI_H_
|
||||||
#define WEBP_DEC_WEBPI_DEC_H_
|
#define WEBP_DEC_WEBPI_H_
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "src/utils/rescaler_utils.h"
|
#include "../utils/rescaler_utils.h"
|
||||||
#include "src/dec/vp8_dec.h"
|
#include "./vp8_dec.h"
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// WebPDecParams: Decoding output parameters. Transient internal object.
|
// WebPDecParams: Decoding output parameters. Transient internal object.
|
||||||
@ -130,4 +130,4 @@ int WebPAvoidSlowMemory(const WebPDecBuffer* const output,
|
|||||||
} // extern "C"
|
} // extern "C"
|
||||||
#endif
|
#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
|
lib_LTLIBRARIES = libwebpdemux.la
|
||||||
|
|
||||||
libwebpdemux_la_SOURCES =
|
libwebpdemux_la_SOURCES =
|
||||||
libwebpdemux_la_SOURCES += anim_decode.c demux.c
|
libwebpdemux_la_SOURCES += anim_decode.c demux.c
|
||||||
|
|
||||||
libwebpdemuxinclude_HEADERS =
|
libwebpdemuxinclude_HEADERS =
|
||||||
libwebpdemuxinclude_HEADERS += ../webp/decode.h
|
|
||||||
libwebpdemuxinclude_HEADERS += ../webp/demux.h
|
libwebpdemuxinclude_HEADERS += ../webp/demux.h
|
||||||
libwebpdemuxinclude_HEADERS += ../webp/mux_types.h
|
libwebpdemuxinclude_HEADERS += ../webp/mux_types.h
|
||||||
libwebpdemuxinclude_HEADERS += ../webp/types.h
|
libwebpdemuxinclude_HEADERS += ../webp/types.h
|
||||||
noinst_HEADERS =
|
|
||||||
noinst_HEADERS += ../webp/format_constants.h
|
|
||||||
|
|
||||||
libwebpdemux_la_LIBADD = ../libwebp.la
|
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
|
libwebpdemuxincludedir = $(includedir)/webp
|
||||||
pkgconfig_DATA = libwebpdemux.pc
|
pkgconfig_DATA = libwebpdemux.pc
|
||||||
|
@ -11,15 +11,15 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
#include "src/webp/config.h"
|
#include "../webp/config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "src/utils/utils.h"
|
#include "../utils/utils.h"
|
||||||
#include "src/webp/decode.h"
|
#include "../webp/decode.h"
|
||||||
#include "src/webp/demux.h"
|
#include "../webp/demux.h"
|
||||||
|
|
||||||
#define NUM_CHANNELS 4
|
#define NUM_CHANNELS 4
|
||||||
|
|
||||||
|
@ -11,21 +11,21 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
#include "src/webp/config.h"
|
#include "../webp/config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "src/utils/utils.h"
|
#include "../utils/utils.h"
|
||||||
#include "src/webp/decode.h" // WebPGetFeatures
|
#include "../webp/decode.h" // WebPGetFeatures
|
||||||
#include "src/webp/demux.h"
|
#include "../webp/demux.h"
|
||||||
#include "src/webp/format_constants.h"
|
#include "../webp/format_constants.h"
|
||||||
|
|
||||||
#define DMUX_MAJ_VERSION 1
|
#define DMUX_MAJ_VERSION 0
|
||||||
#define DMUX_MIN_VERSION 0
|
#define DMUX_MIN_VERSION 3
|
||||||
#define DMUX_REV_VERSION 0
|
#define DMUX_REV_VERSION 2
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
size_t start_; // start location of the data
|
size_t start_; // start location of the data
|
||||||
@ -205,14 +205,12 @@ static void SetFrameInfo(size_t start_offset, size_t size,
|
|||||||
frame->complete_ = complete;
|
frame->complete_ = complete;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Store image bearing chunks to 'frame'. 'min_size' is an optional size
|
// Store image bearing chunks to 'frame'.
|
||||||
// requirement, it may be zero.
|
|
||||||
static ParseStatus StoreFrame(int frame_num, uint32_t min_size,
|
static ParseStatus StoreFrame(int frame_num, uint32_t min_size,
|
||||||
MemBuffer* const mem, Frame* const frame) {
|
MemBuffer* const mem, Frame* const frame) {
|
||||||
int alpha_chunks = 0;
|
int alpha_chunks = 0;
|
||||||
int image_chunks = 0;
|
int image_chunks = 0;
|
||||||
int done = (MemDataSize(mem) < CHUNK_HEADER_SIZE ||
|
int done = (MemDataSize(mem) < min_size);
|
||||||
MemDataSize(mem) < min_size);
|
|
||||||
ParseStatus status = PARSE_OK;
|
ParseStatus status = PARSE_OK;
|
||||||
|
|
||||||
if (done) return PARSE_NEED_MORE_DATA;
|
if (done) return PARSE_NEED_MORE_DATA;
|
||||||
@ -403,9 +401,9 @@ static ParseStatus ParseSingleImage(WebPDemuxer* const dmux) {
|
|||||||
frame = (Frame*)WebPSafeCalloc(1ULL, sizeof(*frame));
|
frame = (Frame*)WebPSafeCalloc(1ULL, sizeof(*frame));
|
||||||
if (frame == NULL) return PARSE_ERROR;
|
if (frame == NULL) return PARSE_ERROR;
|
||||||
|
|
||||||
// For the single image case we allow parsing of a partial frame, so no
|
// For the single image case we allow parsing of a partial frame, but we need
|
||||||
// minimum size is imposed here.
|
// at least CHUNK_HEADER_SIZE for parsing.
|
||||||
status = StoreFrame(1, 0, &dmux->mem_, frame);
|
status = StoreFrame(1, CHUNK_HEADER_SIZE, &dmux->mem_, frame);
|
||||||
if (status != PARSE_ERROR) {
|
if (status != PARSE_ERROR) {
|
||||||
const int has_alpha = !!(dmux->feature_flags_ & ALPHA_FLAG);
|
const int has_alpha = !!(dmux->feature_flags_ & ALPHA_FLAG);
|
||||||
// Clear any alpha when the alpha flag is missing.
|
// Clear any alpha when the alpha flag is missing.
|
||||||
|
@ -6,8 +6,8 @@
|
|||||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||||
|
|
||||||
VS_VERSION_INFO VERSIONINFO
|
VS_VERSION_INFO VERSIONINFO
|
||||||
FILEVERSION 1,0,0,0
|
FILEVERSION 0,3,0,2
|
||||||
PRODUCTVERSION 1,0,0,0
|
PRODUCTVERSION 0,3,0,2
|
||||||
FILEFLAGSMASK 0x3fL
|
FILEFLAGSMASK 0x3fL
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
FILEFLAGS 0x1L
|
FILEFLAGS 0x1L
|
||||||
@ -24,12 +24,12 @@ BEGIN
|
|||||||
BEGIN
|
BEGIN
|
||||||
VALUE "CompanyName", "Google, Inc."
|
VALUE "CompanyName", "Google, Inc."
|
||||||
VALUE "FileDescription", "libwebpdemux DLL"
|
VALUE "FileDescription", "libwebpdemux DLL"
|
||||||
VALUE "FileVersion", "1.0.0"
|
VALUE "FileVersion", "0.3.2"
|
||||||
VALUE "InternalName", "libwebpdemux.dll"
|
VALUE "InternalName", "libwebpdemux.dll"
|
||||||
VALUE "LegalCopyright", "Copyright (C) 2018"
|
VALUE "LegalCopyright", "Copyright (C) 2017"
|
||||||
VALUE "OriginalFilename", "libwebpdemux.dll"
|
VALUE "OriginalFilename", "libwebpdemux.dll"
|
||||||
VALUE "ProductName", "WebP Image Demuxer"
|
VALUE "ProductName", "WebP Image Demuxer"
|
||||||
VALUE "ProductVersion", "1.0.0"
|
VALUE "ProductVersion", "0.3.2"
|
||||||
END
|
END
|
||||||
END
|
END
|
||||||
BLOCK "VarFileInfo"
|
BLOCK "VarFileInfo"
|
||||||
|
@ -1,15 +1,9 @@
|
|||||||
AM_CPPFLAGS += -I$(top_builddir) -I$(top_srcdir)
|
noinst_LTLIBRARIES = libwebpdsp.la libwebpdsp_avx2.la
|
||||||
noinst_LTLIBRARIES =
|
noinst_LTLIBRARIES += libwebpdsp_sse2.la libwebpdspdecode_sse2.la
|
||||||
noinst_LTLIBRARIES += libwebpdsp.la
|
noinst_LTLIBRARIES += libwebpdsp_sse41.la libwebpdspdecode_sse41.la
|
||||||
noinst_LTLIBRARIES += libwebpdsp_avx2.la
|
noinst_LTLIBRARIES += libwebpdsp_neon.la libwebpdspdecode_neon.la
|
||||||
noinst_LTLIBRARIES += libwebpdsp_sse2.la
|
noinst_LTLIBRARIES += libwebpdsp_msa.la libwebpdspdecode_msa.la
|
||||||
noinst_LTLIBRARIES += libwebpdspdecode_sse2.la
|
noinst_LTLIBRARIES += libwebpdspdecode_wasm.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
|
|
||||||
|
|
||||||
if BUILD_LIBWEBPDECODER
|
if BUILD_LIBWEBPDECODER
|
||||||
noinst_LTLIBRARIES += libwebpdspdecode.la
|
noinst_LTLIBRARIES += libwebpdspdecode.la
|
||||||
@ -46,6 +40,8 @@ COMMON_SOURCES += yuv_mips32.c
|
|||||||
COMMON_SOURCES += yuv_mips_dsp_r2.c
|
COMMON_SOURCES += yuv_mips_dsp_r2.c
|
||||||
|
|
||||||
ENC_SOURCES =
|
ENC_SOURCES =
|
||||||
|
ENC_SOURCES += argb.c
|
||||||
|
ENC_SOURCES += argb_mips_dsp_r2.c
|
||||||
ENC_SOURCES += cost.c
|
ENC_SOURCES += cost.c
|
||||||
ENC_SOURCES += cost_mips32.c
|
ENC_SOURCES += cost_mips32.c
|
||||||
ENC_SOURCES += cost_mips_dsp_r2.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 =
|
||||||
libwebpdspdecode_sse41_la_SOURCES += alpha_processing_sse41.c
|
libwebpdspdecode_sse41_la_SOURCES += alpha_processing_sse41.c
|
||||||
libwebpdspdecode_sse41_la_SOURCES += dec_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_CPPFLAGS = $(libwebpdsp_la_CPPFLAGS)
|
||||||
libwebpdspdecode_sse41_la_CFLAGS = $(AM_CFLAGS) $(SSE41_FLAGS)
|
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_CPPFLAGS = $(libwebpdsp_msa_la_CPPFLAGS)
|
||||||
libwebpdspdecode_msa_la_CFLAGS = $(libwebpdsp_msa_la_CFLAGS)
|
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 =
|
||||||
|
libwebpdsp_sse2_la_SOURCES += argb_sse2.c
|
||||||
libwebpdsp_sse2_la_SOURCES += cost_sse2.c
|
libwebpdsp_sse2_la_SOURCES += cost_sse2.c
|
||||||
libwebpdsp_sse2_la_SOURCES += enc_sse2.c
|
libwebpdsp_sse2_la_SOURCES += enc_sse2.c
|
||||||
libwebpdsp_sse2_la_SOURCES += lossless_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 =
|
||||||
libwebpdsp_la_CPPFLAGS += $(AM_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_LDFLAGS = -lm
|
||||||
libwebpdsp_la_LIBADD =
|
libwebpdsp_la_LIBADD =
|
||||||
libwebpdsp_la_LIBADD += libwebpdsp_avx2.la
|
libwebpdsp_la_LIBADD += libwebpdsp_avx2.la libwebpdsp_sse2.la
|
||||||
libwebpdsp_la_LIBADD += libwebpdsp_sse2.la
|
|
||||||
libwebpdsp_la_LIBADD += libwebpdsp_sse41.la
|
libwebpdsp_la_LIBADD += libwebpdsp_sse41.la
|
||||||
libwebpdsp_la_LIBADD += libwebpdsp_neon.la
|
libwebpdsp_la_LIBADD += libwebpdsp_neon.la
|
||||||
libwebpdsp_la_LIBADD += libwebpdsp_msa.la
|
libwebpdsp_la_LIBADD += libwebpdsp_msa.la
|
||||||
|
@ -12,13 +12,10 @@
|
|||||||
// Author: Skal (pascal.massimino@gmail.com)
|
// Author: Skal (pascal.massimino@gmail.com)
|
||||||
|
|
||||||
#include <assert.h>
|
#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).
|
// 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
|
||||||
#define USE_TABLES_FOR_ALPHA_MULT 0 // ALTERNATE_CODE
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
@ -32,7 +29,7 @@ static uint32_t Mult(uint8_t x, uint32_t mult) {
|
|||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if (USE_TABLES_FOR_ALPHA_MULT == 1)
|
#ifdef USE_TABLES_FOR_ALPHA_MULT
|
||||||
|
|
||||||
static const uint32_t kMultTables[2][256] = {
|
static const uint32_t kMultTables[2][256] = {
|
||||||
{ // (255u << MFIX) / alpha
|
{ // (255u << MFIX) / alpha
|
||||||
@ -135,9 +132,9 @@ static WEBP_INLINE uint32_t GetScale(uint32_t a, int inverse) {
|
|||||||
return inverse ? (255u << MFIX) / a : a * KINV_255;
|
return inverse ? (255u << MFIX) / a : a * KINV_255;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // USE_TABLES_FOR_ALPHA_MULT
|
#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;
|
int x;
|
||||||
for (x = 0; x < width; ++x) {
|
for (x = 0; x < width; ++x) {
|
||||||
const uint32_t argb = ptr[x];
|
const uint32_t argb = ptr[x];
|
||||||
@ -157,8 +154,8 @@ 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 width, int inverse) {
|
||||||
int x;
|
int x;
|
||||||
for (x = 0; x < width; ++x) {
|
for (x = 0; x < width; ++x) {
|
||||||
const uint32_t a = alpha[x];
|
const uint32_t a = alpha[x];
|
||||||
@ -220,9 +217,8 @@ void WebPMultRows(uint8_t* ptr, int stride,
|
|||||||
#define PREMULTIPLY(x, m) (((x) * (m) + (1U << 23)) >> 24)
|
#define PREMULTIPLY(x, m) (((x) * (m) + (1U << 23)) >> 24)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !WEBP_NEON_OMIT_C_CODE
|
static void ApplyAlphaMultiply(uint8_t* rgba, int alpha_first,
|
||||||
static void ApplyAlphaMultiply_C(uint8_t* rgba, int alpha_first,
|
int w, int h, int stride) {
|
||||||
int w, int h, int stride) {
|
|
||||||
while (h-- > 0) {
|
while (h-- > 0) {
|
||||||
uint8_t* const rgb = rgba + (alpha_first ? 1 : 0);
|
uint8_t* const rgb = rgba + (alpha_first ? 1 : 0);
|
||||||
const uint8_t* const alpha = rgba + (alpha_first ? 0 : 3);
|
const uint8_t* const alpha = rgba + (alpha_first ? 0 : 3);
|
||||||
@ -239,7 +235,6 @@ static void ApplyAlphaMultiply_C(uint8_t* rgba, int alpha_first,
|
|||||||
rgba += stride;
|
rgba += stride;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif // !WEBP_NEON_OMIT_C_CODE
|
|
||||||
#undef MULTIPLIER
|
#undef MULTIPLIER
|
||||||
#undef PREMULTIPLY
|
#undef PREMULTIPLY
|
||||||
|
|
||||||
@ -259,9 +254,9 @@ static WEBP_INLINE uint8_t multiply(uint8_t x, uint32_t m) {
|
|||||||
return (x * m) >> 16;
|
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 w, int h, int stride,
|
||||||
int rg_byte_pos /* 0 or 1 */) {
|
int rg_byte_pos /* 0 or 1 */) {
|
||||||
while (h-- > 0) {
|
while (h-- > 0) {
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < w; ++i) {
|
for (i = 0; i < w; ++i) {
|
||||||
@ -280,16 +275,15 @@ static WEBP_INLINE void ApplyAlphaMultiply4444_C(uint8_t* rgba4444,
|
|||||||
}
|
}
|
||||||
#undef MULTIPLIER
|
#undef MULTIPLIER
|
||||||
|
|
||||||
static void ApplyAlphaMultiply_16b_C(uint8_t* rgba4444,
|
static void ApplyAlphaMultiply_16b(uint8_t* rgba4444,
|
||||||
int w, int h, int stride) {
|
int w, int h, int stride) {
|
||||||
#if (WEBP_SWAP_16BIT_CSP == 1)
|
#ifdef WEBP_SWAP_16BIT_CSP
|
||||||
ApplyAlphaMultiply4444_C(rgba4444, w, h, stride, 1);
|
ApplyAlphaMultiply4444(rgba4444, w, h, stride, 1);
|
||||||
#else
|
#else
|
||||||
ApplyAlphaMultiply4444_C(rgba4444, w, h, stride, 0);
|
ApplyAlphaMultiply4444(rgba4444, w, h, stride, 0);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !WEBP_NEON_OMIT_C_CODE
|
|
||||||
static int DispatchAlpha_C(const uint8_t* alpha, int alpha_stride,
|
static int DispatchAlpha_C(const uint8_t* alpha, int alpha_stride,
|
||||||
int width, int height,
|
int width, int height,
|
||||||
uint8_t* dst, int dst_stride) {
|
uint8_t* dst, int dst_stride) {
|
||||||
@ -344,46 +338,6 @@ static void ExtractGreen_C(const uint32_t* argb, uint8_t* alpha, int size) {
|
|||||||
int i;
|
int i;
|
||||||
for (i = 0; i < size; ++i) alpha[i] = argb[i] >> 8;
|
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 (*WebPApplyAlphaMultiply)(uint8_t*, int, int, int, int);
|
||||||
void (*WebPApplyAlphaMultiply4444)(uint8_t*, 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);
|
void (*WebPDispatchAlphaToGreen)(const uint8_t*, int, int, int, uint32_t*, int);
|
||||||
int (*WebPExtractAlpha)(const uint8_t*, int, int, int, uint8_t*, int);
|
int (*WebPExtractAlpha)(const uint8_t*, int, int, int, uint8_t*, int);
|
||||||
void (*WebPExtractGreen)(const uint32_t* argb, uint8_t* alpha, int size);
|
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
|
// Init function
|
||||||
@ -409,25 +354,21 @@ extern void WebPInitAlphaProcessingSSE2(void);
|
|||||||
extern void WebPInitAlphaProcessingSSE41(void);
|
extern void WebPInitAlphaProcessingSSE41(void);
|
||||||
extern void WebPInitAlphaProcessingNEON(void);
|
extern void WebPInitAlphaProcessingNEON(void);
|
||||||
|
|
||||||
WEBP_DSP_INIT_FUNC(WebPInitAlphaProcessing) {
|
static volatile VP8CPUInfo alpha_processing_last_cpuinfo_used =
|
||||||
WebPMultARGBRow = WebPMultARGBRow_C;
|
(VP8CPUInfo)&alpha_processing_last_cpuinfo_used;
|
||||||
WebPMultRow = WebPMultRow_C;
|
|
||||||
WebPApplyAlphaMultiply4444 = ApplyAlphaMultiply_16b_C;
|
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;
|
WebPDispatchAlpha = DispatchAlpha_C;
|
||||||
WebPDispatchAlphaToGreen = DispatchAlphaToGreen_C;
|
WebPDispatchAlphaToGreen = DispatchAlphaToGreen_C;
|
||||||
WebPExtractAlpha = ExtractAlpha_C;
|
WebPExtractAlpha = ExtractAlpha_C;
|
||||||
WebPExtractGreen = ExtractGreen_C;
|
WebPExtractGreen = ExtractGreen_C;
|
||||||
#endif
|
|
||||||
|
|
||||||
WebPHasAlpha8b = HasAlpha8b_C;
|
|
||||||
WebPHasAlpha32b = HasAlpha32b_C;
|
|
||||||
|
|
||||||
// If defined, use CPUInfo() to overwrite some pointers with faster versions.
|
// If defined, use CPUInfo() to overwrite some pointers with faster versions.
|
||||||
if (VP8GetCPUInfo != NULL) {
|
if (VP8GetCPUInfo != NULL) {
|
||||||
@ -441,32 +382,16 @@ WEBP_DSP_INIT_FUNC(WebPInitAlphaProcessing) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#if defined(WEBP_USE_NEON)
|
||||||
|
if (VP8GetCPUInfo(kNEON)) {
|
||||||
|
WebPInitAlphaProcessingNEON();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
#if defined(WEBP_USE_MIPS_DSP_R2)
|
#if defined(WEBP_USE_MIPS_DSP_R2)
|
||||||
if (VP8GetCPUInfo(kMIPSdspR2)) {
|
if (VP8GetCPUInfo(kMIPSdspR2)) {
|
||||||
WebPInitAlphaProcessingMIPSdspR2();
|
WebPInitAlphaProcessingMIPSdspR2();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
alpha_processing_last_cpuinfo_used = VP8GetCPUInfo;
|
||||||
#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);
|
|
||||||
}
|
}
|
||||||
|
@ -12,13 +12,13 @@
|
|||||||
// Author(s): Branimir Vasic (branimir.vasic@imgtec.com)
|
// Author(s): Branimir Vasic (branimir.vasic@imgtec.com)
|
||||||
// Djordje Pesut (djordje.pesut@imgtec.com)
|
// Djordje Pesut (djordje.pesut@imgtec.com)
|
||||||
|
|
||||||
#include "src/dsp/dsp.h"
|
#include "./dsp.h"
|
||||||
|
|
||||||
#if defined(WEBP_USE_MIPS_DSP_R2)
|
#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,
|
int width, int height,
|
||||||
uint8_t* dst, int dst_stride) {
|
uint8_t* dst, int dst_stride) {
|
||||||
uint32_t alpha_mask = 0xffffffff;
|
uint32_t alpha_mask = 0xffffffff;
|
||||||
int i, j, temp0;
|
int i, j, temp0;
|
||||||
|
|
||||||
@ -79,8 +79,7 @@ static int DispatchAlpha_MIPSdspR2(const uint8_t* alpha, int alpha_stride,
|
|||||||
return (alpha_mask != 0xff);
|
return (alpha_mask != 0xff);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void MultARGBRow_MIPSdspR2(uint32_t* const ptr, int width,
|
static void MultARGBRow(uint32_t* const ptr, int width, int inverse) {
|
||||||
int inverse) {
|
|
||||||
int x;
|
int x;
|
||||||
const uint32_t c_00ffffff = 0x00ffffffu;
|
const uint32_t c_00ffffff = 0x00ffffffu;
|
||||||
const uint32_t c_ff000000 = 0xff000000u;
|
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
|
// Entry point
|
||||||
|
|
||||||
extern void WebPInitAlphaProcessingMIPSdspR2(void);
|
extern void WebPInitAlphaProcessingMIPSdspR2(void);
|
||||||
|
|
||||||
WEBP_TSAN_IGNORE_FUNCTION void WebPInitAlphaProcessingMIPSdspR2(void) {
|
WEBP_TSAN_IGNORE_FUNCTION void WebPInitAlphaProcessingMIPSdspR2(void) {
|
||||||
WebPDispatchAlpha = DispatchAlpha_MIPSdspR2;
|
WebPDispatchAlpha = DispatchAlpha;
|
||||||
WebPMultARGBRow = MultARGBRow_MIPSdspR2;
|
WebPMultARGBRow = MultARGBRow;
|
||||||
#ifdef WORDS_BIGENDIAN
|
|
||||||
WebPPackARGB = PackARGB_MIPSdspR2;
|
|
||||||
#endif
|
|
||||||
WebPPackRGB = PackRGB_MIPSdspR2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#else // !WEBP_USE_MIPS_DSP_R2
|
#else // !WEBP_USE_MIPS_DSP_R2
|
||||||
|
@ -11,11 +11,11 @@
|
|||||||
//
|
//
|
||||||
// Author: Skal (pascal.massimino@gmail.com)
|
// Author: Skal (pascal.massimino@gmail.com)
|
||||||
|
|
||||||
#include "src/dsp/dsp.h"
|
#include "./dsp.h"
|
||||||
|
|
||||||
#if defined(WEBP_USE_NEON)
|
#if defined(WEBP_USE_NEON)
|
||||||
|
|
||||||
#include "src/dsp/neon.h"
|
#include "./neon.h"
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -11,16 +11,16 @@
|
|||||||
//
|
//
|
||||||
// Author: Skal (pascal.massimino@gmail.com)
|
// Author: Skal (pascal.massimino@gmail.com)
|
||||||
|
|
||||||
#include "src/dsp/dsp.h"
|
#include "./dsp.h"
|
||||||
|
|
||||||
#if defined(WEBP_USE_SSE2)
|
#if defined(WEBP_USE_SSE2)
|
||||||
#include <emmintrin.h>
|
#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,
|
int width, int height,
|
||||||
uint8_t* dst, int dst_stride) {
|
uint8_t* dst, int dst_stride) {
|
||||||
// alpha_and stores an 'and' operation of all the alpha[] values. The final
|
// alpha_and stores an 'and' operation of all the alpha[] values. The final
|
||||||
// value is not 0xff if any of the alpha[] is not equal to 0xff.
|
// value is not 0xff if any of the alpha[] is not equal to 0xff.
|
||||||
uint32_t alpha_and = 0xff;
|
uint32_t alpha_and = 0xff;
|
||||||
@ -72,9 +72,9 @@ static int DispatchAlpha_SSE2(const uint8_t* alpha, int alpha_stride,
|
|||||||
return (alpha_and != 0xff);
|
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,
|
int width, int height,
|
||||||
uint32_t* dst, int dst_stride) {
|
uint32_t* dst, int dst_stride) {
|
||||||
int i, j;
|
int i, j;
|
||||||
const __m128i zero = _mm_setzero_si128();
|
const __m128i zero = _mm_setzero_si128();
|
||||||
const int limit = width & ~15;
|
const int limit = width & ~15;
|
||||||
@ -98,9 +98,9 @@ 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,
|
int width, int height,
|
||||||
uint8_t* alpha, int alpha_stride) {
|
uint8_t* alpha, int alpha_stride) {
|
||||||
// alpha_and stores an 'and' operation of all the alpha[] values. The final
|
// alpha_and stores an 'and' operation of all the alpha[] values. The final
|
||||||
// value is not 0xff if any of the alpha[] is not equal to 0xff.
|
// value is not 0xff if any of the alpha[] is not equal to 0xff.
|
||||||
uint32_t alpha_and = 0xff;
|
uint32_t alpha_and = 0xff;
|
||||||
@ -210,61 +210,6 @@ static void ApplyAlphaMultiply_SSE2(uint8_t* rgba, int alpha_first,
|
|||||||
#undef MULTIPLIER
|
#undef MULTIPLIER
|
||||||
#undef PREMULTIPLY
|
#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
|
// Apply alpha value to rows
|
||||||
|
|
||||||
@ -293,7 +238,7 @@ static void MultARGBRow_SSE2(uint32_t* const ptr, int width, int inverse) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
width -= x;
|
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,
|
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;
|
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;
|
WebPMultARGBRow = MultARGBRow_SSE2;
|
||||||
WebPMultRow = MultRow_SSE2;
|
WebPMultRow = MultRow_SSE2;
|
||||||
WebPApplyAlphaMultiply = ApplyAlphaMultiply_SSE2;
|
WebPApplyAlphaMultiply = ApplyAlphaMultiply_SSE2;
|
||||||
WebPDispatchAlpha = DispatchAlpha_SSE2;
|
WebPDispatchAlpha = DispatchAlpha;
|
||||||
WebPDispatchAlphaToGreen = DispatchAlphaToGreen_SSE2;
|
WebPDispatchAlphaToGreen = DispatchAlphaToGreen;
|
||||||
WebPExtractAlpha = ExtractAlpha_SSE2;
|
WebPExtractAlpha = ExtractAlpha;
|
||||||
|
|
||||||
WebPHasAlpha8b = HasAlpha8b_SSE2;
|
|
||||||
WebPHasAlpha32b = HasAlpha32b_SSE2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#else // !WEBP_USE_SSE2
|
#else // !WEBP_USE_SSE2
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
//
|
//
|
||||||
// Author: Skal (pascal.massimino@gmail.com)
|
// Author: Skal (pascal.massimino@gmail.com)
|
||||||
|
|
||||||
#include "src/dsp/dsp.h"
|
#include "./dsp.h"
|
||||||
|
|
||||||
#if defined(WEBP_USE_SSE41)
|
#if defined(WEBP_USE_SSE41)
|
||||||
|
|
||||||
@ -19,9 +19,9 @@
|
|||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
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,
|
int width, int height,
|
||||||
uint8_t* alpha, int alpha_stride) {
|
uint8_t* alpha, int alpha_stride) {
|
||||||
// alpha_and stores an 'and' operation of all the alpha[] values. The final
|
// alpha_and stores an 'and' operation of all the alpha[] values. The final
|
||||||
// value is not 0xff if any of the alpha[] is not equal to 0xff.
|
// value is not 0xff if any of the alpha[] is not equal to 0xff.
|
||||||
uint32_t alpha_and = 0xff;
|
uint32_t alpha_and = 0xff;
|
||||||
@ -82,7 +82,7 @@ static int ExtractAlpha_SSE41(const uint8_t* argb, int argb_stride,
|
|||||||
extern void WebPInitAlphaProcessingSSE41(void);
|
extern void WebPInitAlphaProcessingSSE41(void);
|
||||||
|
|
||||||
WEBP_TSAN_IGNORE_FUNCTION void WebPInitAlphaProcessingSSE41(void) {
|
WEBP_TSAN_IGNORE_FUNCTION void WebPInitAlphaProcessingSSE41(void) {
|
||||||
WebPExtractAlpha = ExtractAlpha_SSE41;
|
WebPExtractAlpha = ExtractAlpha;
|
||||||
}
|
}
|
||||||
|
|
||||||
#else // !WEBP_USE_SSE41
|
#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
|
// Pack the planar buffers
|
||||||
// rrrr... rrrr... gggg... gggg... bbbb... bbbb....
|
// rrrr... rrrr... gggg... gggg... bbbb... bbbb....
|
||||||
// triplet by triplet in the output buffer rgb as rgbrgbrgbrgb ...
|
// triplet by triplet in the output buffer rgb as rgbrgbrgbrgb ...
|
||||||
static WEBP_INLINE void VP8PlanarTo24b_SSE2(
|
static WEBP_INLINE void VP8PlanarTo24b(__m128i* const in0, __m128i* const in1,
|
||||||
__m128i* const in0, __m128i* const in1, __m128i* const in2,
|
__m128i* const in2, __m128i* const in3,
|
||||||
__m128i* const in3, __m128i* const in4, __m128i* const in5) {
|
__m128i* const in4, __m128i* const in5) {
|
||||||
// The input is 6 registers of sixteen 8b but for the sake of explanation,
|
// The input is 6 registers of sixteen 8b but for the sake of explanation,
|
||||||
// let's take 6 registers of four 8b values.
|
// let's take 6 registers of four 8b values.
|
||||||
// To pack, we will keep taking one every two 8b integer and move it
|
// To pack, we will keep taking one every two 8b integer and move it
|
||||||
@ -159,10 +159,10 @@ static WEBP_INLINE void VP8PlanarTo24b_SSE2(
|
|||||||
|
|
||||||
// Convert four packed four-channel buffers like argbargbargbargb... into the
|
// Convert four packed four-channel buffers like argbargbargbargb... into the
|
||||||
// split channels aaaaa ... rrrr ... gggg .... bbbbb ......
|
// 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 in1,
|
||||||
__m128i* const in2,
|
__m128i* const in2,
|
||||||
__m128i* const in3) {
|
__m128i* const in3) {
|
||||||
// Column-wise transpose.
|
// Column-wise transpose.
|
||||||
const __m128i A0 = _mm_unpacklo_epi8(*in0, *in1);
|
const __m128i A0 = _mm_unpacklo_epi8(*in0, *in1);
|
||||||
const __m128i A1 = _mm_unpackhi_epi8(*in0, *in1);
|
const __m128i A1 = _mm_unpackhi_epi8(*in0, *in1);
|
||||||
|
@ -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)
|
// Author: Skal (pascal.massimino@gmail.com)
|
||||||
|
|
||||||
#include "src/dsp/dsp.h"
|
#include "./dsp.h"
|
||||||
#include "src/enc/cost_enc.h"
|
#include "../enc/cost_enc.h"
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Boolean-cost cost table
|
// Boolean-cost cost table
|
||||||
@ -319,7 +319,7 @@ const uint8_t VP8EncBands[16 + 1] = {
|
|||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Mode costs
|
// 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;
|
int n = res->first;
|
||||||
// should be prob[VP8EncBands[n]], but it's equivalent for n=0 or 1
|
// should be prob[VP8EncBands[n]], but it's equivalent for n=0 or 1
|
||||||
const int p0 = res->prob[n][ctx0][0];
|
const int p0 = res->prob[n][ctx0][0];
|
||||||
@ -354,8 +354,8 @@ static int GetResidualCost_C(int ctx0, const VP8Residual* const res) {
|
|||||||
return cost;
|
return cost;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SetResidualCoeffs_C(const int16_t* const coeffs,
|
static void SetResidualCoeffs(const int16_t* const coeffs,
|
||||||
VP8Residual* const res) {
|
VP8Residual* const res) {
|
||||||
int n;
|
int n;
|
||||||
res->last = -1;
|
res->last = -1;
|
||||||
assert(res->first == 0 || coeffs[0] == 0);
|
assert(res->first == 0 || coeffs[0] == 0);
|
||||||
@ -378,9 +378,14 @@ extern void VP8EncDspCostInitMIPS32(void);
|
|||||||
extern void VP8EncDspCostInitMIPSdspR2(void);
|
extern void VP8EncDspCostInitMIPSdspR2(void);
|
||||||
extern void VP8EncDspCostInitSSE2(void);
|
extern void VP8EncDspCostInitSSE2(void);
|
||||||
|
|
||||||
WEBP_DSP_INIT_FUNC(VP8EncDspCostInit) {
|
static volatile VP8CPUInfo cost_last_cpuinfo_used =
|
||||||
VP8GetResidualCost = GetResidualCost_C;
|
(VP8CPUInfo)&cost_last_cpuinfo_used;
|
||||||
VP8SetResidualCoeffs = SetResidualCoeffs_C;
|
|
||||||
|
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 defined, use CPUInfo() to overwrite some pointers with faster versions.
|
||||||
if (VP8GetCPUInfo != NULL) {
|
if (VP8GetCPUInfo != NULL) {
|
||||||
@ -400,6 +405,8 @@ WEBP_DSP_INIT_FUNC(VP8EncDspCostInit) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cost_last_cpuinfo_used = VP8GetCPUInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
@ -9,13 +9,13 @@
|
|||||||
//
|
//
|
||||||
// Author: Djordje Pesut (djordje.pesut@imgtec.com)
|
// Author: Djordje Pesut (djordje.pesut@imgtec.com)
|
||||||
|
|
||||||
#include "src/dsp/dsp.h"
|
#include "./dsp.h"
|
||||||
|
|
||||||
#if defined(WEBP_USE_MIPS32)
|
#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 temp0, temp1;
|
||||||
int v_reg, ctx_reg;
|
int v_reg, ctx_reg;
|
||||||
int n = res->first;
|
int n = res->first;
|
||||||
@ -96,8 +96,8 @@ static int GetResidualCost_MIPS32(int ctx0, const VP8Residual* const res) {
|
|||||||
return cost;
|
return cost;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SetResidualCoeffs_MIPS32(const int16_t* const coeffs,
|
static void SetResidualCoeffs(const int16_t* const coeffs,
|
||||||
VP8Residual* const res) {
|
VP8Residual* const res) {
|
||||||
const int16_t* p_coeffs = (int16_t*)coeffs;
|
const int16_t* p_coeffs = (int16_t*)coeffs;
|
||||||
int temp0, temp1, temp2, n, n1;
|
int temp0, temp1, temp2, n, n1;
|
||||||
assert(res->first == 0 || coeffs[0] == 0);
|
assert(res->first == 0 || coeffs[0] == 0);
|
||||||
@ -143,8 +143,8 @@ static void SetResidualCoeffs_MIPS32(const int16_t* const coeffs,
|
|||||||
extern void VP8EncDspCostInitMIPS32(void);
|
extern void VP8EncDspCostInitMIPS32(void);
|
||||||
|
|
||||||
WEBP_TSAN_IGNORE_FUNCTION void VP8EncDspCostInitMIPS32(void) {
|
WEBP_TSAN_IGNORE_FUNCTION void VP8EncDspCostInitMIPS32(void) {
|
||||||
VP8GetResidualCost = GetResidualCost_MIPS32;
|
VP8GetResidualCost = GetResidualCost;
|
||||||
VP8SetResidualCoeffs = SetResidualCoeffs_MIPS32;
|
VP8SetResidualCoeffs = SetResidualCoeffs;
|
||||||
}
|
}
|
||||||
|
|
||||||
#else // !WEBP_USE_MIPS32
|
#else // !WEBP_USE_MIPS32
|
||||||
|
@ -9,13 +9,13 @@
|
|||||||
//
|
//
|
||||||
// Author: Djordje Pesut (djordje.pesut@imgtec.com)
|
// Author: Djordje Pesut (djordje.pesut@imgtec.com)
|
||||||
|
|
||||||
#include "src/dsp/dsp.h"
|
#include "./dsp.h"
|
||||||
|
|
||||||
#if defined(WEBP_USE_MIPS_DSP_R2)
|
#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 temp0, temp1;
|
||||||
int v_reg, ctx_reg;
|
int v_reg, ctx_reg;
|
||||||
int n = res->first;
|
int n = res->first;
|
||||||
@ -97,7 +97,7 @@ static int GetResidualCost_MIPSdspR2(int ctx0, const VP8Residual* const res) {
|
|||||||
extern void VP8EncDspCostInitMIPSdspR2(void);
|
extern void VP8EncDspCostInitMIPSdspR2(void);
|
||||||
|
|
||||||
WEBP_TSAN_IGNORE_FUNCTION void VP8EncDspCostInitMIPSdspR2(void) {
|
WEBP_TSAN_IGNORE_FUNCTION void VP8EncDspCostInitMIPSdspR2(void) {
|
||||||
VP8GetResidualCost = GetResidualCost_MIPSdspR2;
|
VP8GetResidualCost = GetResidualCost;
|
||||||
}
|
}
|
||||||
|
|
||||||
#else // !WEBP_USE_MIPS_DSP_R2
|
#else // !WEBP_USE_MIPS_DSP_R2
|
||||||
|
@ -11,19 +11,19 @@
|
|||||||
//
|
//
|
||||||
// Author: Skal (pascal.massimino@gmail.com)
|
// Author: Skal (pascal.massimino@gmail.com)
|
||||||
|
|
||||||
#include "src/dsp/dsp.h"
|
#include "./dsp.h"
|
||||||
|
|
||||||
#if defined(WEBP_USE_SSE2)
|
#if defined(WEBP_USE_SSE2)
|
||||||
#include <emmintrin.h>
|
#include <emmintrin.h>
|
||||||
|
|
||||||
#include "src/enc/cost_enc.h"
|
#include "../enc/cost_enc.h"
|
||||||
#include "src/enc/vp8i_enc.h"
|
#include "../enc/vp8i_enc.h"
|
||||||
#include "src/utils/utils.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) {
|
VP8Residual* const res) {
|
||||||
const __m128i c0 = _mm_loadu_si128((const __m128i*)(coeffs + 0));
|
const __m128i c0 = _mm_loadu_si128((const __m128i*)(coeffs + 0));
|
||||||
const __m128i c1 = _mm_loadu_si128((const __m128i*)(coeffs + 8));
|
const __m128i c1 = _mm_loadu_si128((const __m128i*)(coeffs + 8));
|
||||||
// Use SSE2 to compare 16 values with a single instruction.
|
// Use SSE2 to compare 16 values with a single instruction.
|
||||||
@ -42,7 +42,7 @@ static void SetResidualCoeffs_SSE2(const int16_t* const coeffs,
|
|||||||
res->coeffs = 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];
|
uint8_t levels[16], ctxs[16];
|
||||||
uint16_t abs_levels[16];
|
uint16_t abs_levels[16];
|
||||||
int n = res->first;
|
int n = res->first;
|
||||||
@ -108,8 +108,8 @@ static int GetResidualCost_SSE2(int ctx0, const VP8Residual* const res) {
|
|||||||
extern void VP8EncDspCostInitSSE2(void);
|
extern void VP8EncDspCostInitSSE2(void);
|
||||||
|
|
||||||
WEBP_TSAN_IGNORE_FUNCTION void VP8EncDspCostInitSSE2(void) {
|
WEBP_TSAN_IGNORE_FUNCTION void VP8EncDspCostInitSSE2(void) {
|
||||||
VP8SetResidualCoeffs = SetResidualCoeffs_SSE2;
|
VP8SetResidualCoeffs = SetResidualCoeffsSSE2;
|
||||||
VP8GetResidualCost = GetResidualCost_SSE2;
|
VP8GetResidualCost = GetResidualCostSSE2;
|
||||||
}
|
}
|
||||||
|
|
||||||
#else // !WEBP_USE_SSE2
|
#else // !WEBP_USE_SSE2
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
//
|
//
|
||||||
// Author: Christian Duvivier (cduvivier@google.com)
|
// Author: Christian Duvivier (cduvivier@google.com)
|
||||||
|
|
||||||
#include "src/dsp/dsp.h"
|
#include "./dsp.h"
|
||||||
|
|
||||||
#if defined(WEBP_HAVE_NEON_RTCD)
|
#if defined(WEBP_HAVE_NEON_RTCD)
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -23,11 +23,13 @@
|
|||||||
#endif
|
#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.
|
// 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) {
|
static WEBP_INLINE void GetCPUInfo(int cpu_info[4], int info_type) {
|
||||||
__asm__ volatile (
|
__asm__ volatile (
|
||||||
"mov %%ebx, %%edi\n"
|
"mov %%ebx, %%edi\n"
|
||||||
@ -63,8 +65,10 @@ static WEBP_INLINE void GetCPUInfo(int cpu_info[4], int info_type) {
|
|||||||
#define GetCPUInfo __cpuid
|
#define GetCPUInfo __cpuid
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// skip xgetbv definition for WASM builds
|
||||||
|
#if defined(WEBP_USE_WASM)
|
||||||
// NaCl has no support for xgetbv or the raw opcode.
|
// 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) {
|
static WEBP_INLINE uint64_t xgetbv(void) {
|
||||||
const uint32_t ecx = 0;
|
const uint32_t ecx = 0;
|
||||||
uint32_t eax, edx;
|
uint32_t eax, edx;
|
||||||
@ -94,7 +98,19 @@ static WEBP_INLINE uint64_t xgetbv(void) {
|
|||||||
#define xgetbv() 0U // no AVX for older x64 or unrecognized toolchains.
|
#define xgetbv() 0U // no AVX for older x64 or unrecognized toolchains.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(__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
|
// helper function for run-time detection of slow SSSE3 platforms
|
||||||
static int CheckSlowModel(int info) {
|
static int CheckSlowModel(int info) {
|
||||||
@ -143,7 +159,7 @@ static int x86CPUInfo(CPUFeature feature) {
|
|||||||
return !!(cpu_info[2] & (1 << 0));
|
return !!(cpu_info[2] & (1 << 0));
|
||||||
}
|
}
|
||||||
if (feature == kSlowSSSE3) {
|
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 CheckSlowModel(cpu_info[0]);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
404
src/dsp/dec.c
404
src/dsp/dec.c
@ -11,11 +11,9 @@
|
|||||||
//
|
//
|
||||||
// Author: Skal (pascal.massimino@gmail.com)
|
// Author: Skal (pascal.massimino@gmail.com)
|
||||||
|
|
||||||
#include <assert.h>
|
#include "./dsp.h"
|
||||||
|
#include "../dec/vp8i_dec.h"
|
||||||
#include "src/dsp/dsp.h"
|
#include "../utils/utils.h"
|
||||||
#include "src/dec/vp8i_dec.h"
|
|
||||||
#include "src/utils/utils.h"
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
@ -27,7 +25,7 @@ static WEBP_INLINE uint8_t clip_8b(int v) {
|
|||||||
// Transforms (Paragraph 14.4)
|
// Transforms (Paragraph 14.4)
|
||||||
|
|
||||||
#define STORE(x, y, v) \
|
#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 { \
|
#define STORE2(y, dc, d, c) do { \
|
||||||
const int DC = (dc); \
|
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 MUL1(a) ((((a) * 20091) >> 16) + (a))
|
||||||
#define MUL2(a) (((a) * 35468) >> 16)
|
#define MUL2(a) (((a) * 35468) >> 16)
|
||||||
|
|
||||||
#if !WEBP_NEON_OMIT_C_CODE
|
static void TransformOne(const int16_t* in, uint8_t* dst) {
|
||||||
static void TransformOne_C(const int16_t* in, uint8_t* dst) {
|
|
||||||
int C[4 * 4], *tmp;
|
int C[4 * 4], *tmp;
|
||||||
int i;
|
int i;
|
||||||
tmp = C;
|
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
|
// 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 a = in[0] + 4;
|
||||||
const int c4 = MUL2(in[4]);
|
const int c4 = MUL2(in[4]);
|
||||||
const int d4 = MUL1(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 MUL2
|
||||||
#undef STORE2
|
#undef STORE2
|
||||||
|
|
||||||
static void TransformTwo_C(const int16_t* in, uint8_t* dst, int do_two) {
|
static void TransformTwo(const int16_t* in, uint8_t* dst, int do_two) {
|
||||||
TransformOne_C(in, dst);
|
TransformOne(in, dst);
|
||||||
if (do_two) {
|
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 + 0 * 16, dst, 1);
|
||||||
VP8Transform(in + 2 * 16, dst + 4 * BPS, 1);
|
VP8Transform(in + 2 * 16, dst + 4 * BPS, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !WEBP_NEON_OMIT_C_CODE
|
static void TransformDC(const int16_t* in, uint8_t* dst) {
|
||||||
static void TransformDC_C(const int16_t* in, uint8_t* dst) {
|
|
||||||
const int DC = in[0] + 4;
|
const int DC = in[0] + 4;
|
||||||
int i, j;
|
int i, j;
|
||||||
for (j = 0; j < 4; ++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[0 * 16]) VP8TransformDC(in + 0 * 16, dst);
|
||||||
if (in[1 * 16]) VP8TransformDC(in + 1 * 16, dst + 4);
|
if (in[1 * 16]) VP8TransformDC(in + 1 * 16, dst + 4);
|
||||||
if (in[2 * 16]) VP8TransformDC(in + 2 * 16, dst + 4 * BPS);
|
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
|
// Paragraph 14.3
|
||||||
|
|
||||||
#if !WEBP_NEON_OMIT_C_CODE
|
static void TransformWHT(const int16_t* in, int16_t* out) {
|
||||||
static void TransformWHT_C(const int16_t* in, int16_t* out) {
|
|
||||||
int tmp[16];
|
int tmp[16];
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < 4; ++i) {
|
for (i = 0; i < 4; ++i) {
|
||||||
@ -160,7 +153,6 @@ static void TransformWHT_C(const int16_t* in, int16_t* out) {
|
|||||||
out += 64;
|
out += 64;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif // !WEBP_NEON_OMIT_C_CODE
|
|
||||||
|
|
||||||
void (*VP8TransformWHT)(const int16_t* in, int16_t* out);
|
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]
|
#define DST(x, y) dst[(x) + (y) * BPS]
|
||||||
|
|
||||||
#if !WEBP_NEON_OMIT_C_CODE
|
|
||||||
static WEBP_INLINE void TrueMotion(uint8_t* dst, int size) {
|
static WEBP_INLINE void TrueMotion(uint8_t* dst, int size) {
|
||||||
const uint8_t* top = dst - BPS;
|
const uint8_t* top = dst - BPS;
|
||||||
const uint8_t* const clip0 = VP8kclip1 - top[-1];
|
const uint8_t* const clip0 = VP8kclip1 - top[-1];
|
||||||
@ -183,21 +174,21 @@ static WEBP_INLINE void TrueMotion(uint8_t* dst, int size) {
|
|||||||
dst += BPS;
|
dst += BPS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static void TM4_C(uint8_t* dst) { TrueMotion(dst, 4); }
|
static void TM4(uint8_t* dst) { TrueMotion(dst, 4); }
|
||||||
static void TM8uv_C(uint8_t* dst) { TrueMotion(dst, 8); }
|
static void TM8uv(uint8_t* dst) { TrueMotion(dst, 8); }
|
||||||
static void TM16_C(uint8_t* dst) { TrueMotion(dst, 16); }
|
static void TM16(uint8_t* dst) { TrueMotion(dst, 16); }
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// 16x16
|
// 16x16
|
||||||
|
|
||||||
static void VE16_C(uint8_t* dst) { // vertical
|
static void VE16(uint8_t* dst) { // vertical
|
||||||
int j;
|
int j;
|
||||||
for (j = 0; j < 16; ++j) {
|
for (j = 0; j < 16; ++j) {
|
||||||
memcpy(dst + j * BPS, dst - BPS, 16);
|
memcpy(dst + j * BPS, dst - BPS, 16);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void HE16_C(uint8_t* dst) { // horizontal
|
static void HE16(uint8_t* dst) { // horizontal
|
||||||
int j;
|
int j;
|
||||||
for (j = 16; j > 0; --j) {
|
for (j = 16; j > 0; --j) {
|
||||||
memset(dst, dst[-1], 16);
|
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 DC = 16;
|
||||||
int j;
|
int j;
|
||||||
for (j = 0; j < 16; ++j) {
|
for (j = 0; j < 16; ++j) {
|
||||||
@ -221,7 +212,7 @@ static void DC16_C(uint8_t* dst) { // DC
|
|||||||
Put16(DC >> 5, dst);
|
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 DC = 8;
|
||||||
int j;
|
int j;
|
||||||
for (j = 0; j < 16; ++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);
|
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 DC = 8;
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < 16; ++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);
|
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);
|
Put16(0x80, dst);
|
||||||
}
|
}
|
||||||
#endif // !WEBP_NEON_OMIT_C_CODE
|
|
||||||
|
|
||||||
VP8PredFunc VP8PredLuma16[NUM_B_DC_MODES];
|
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 AVG3(a, b, c) ((uint8_t)(((a) + 2 * (b) + (c) + 2) >> 2))
|
||||||
#define AVG2(a, b) (((a) + (b) + 1) >> 1)
|
#define AVG2(a, b) (((a) + (b) + 1) >> 1)
|
||||||
|
|
||||||
#if !WEBP_NEON_OMIT_C_CODE
|
static void VE4(uint8_t* dst) { // vertical
|
||||||
static void VE4_C(uint8_t* dst) { // vertical
|
|
||||||
const uint8_t* top = dst - BPS;
|
const uint8_t* top = dst - BPS;
|
||||||
const uint8_t vals[4] = {
|
const uint8_t vals[4] = {
|
||||||
AVG3(top[-1], top[0], top[1]),
|
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));
|
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 A = dst[-1 - BPS];
|
||||||
const int B = dst[-1];
|
const int B = dst[-1];
|
||||||
const int C = dst[-1 + BPS];
|
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));
|
WebPUint32ToMem(dst + 3 * BPS, 0x01010101U * AVG3(D, E, E));
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !WEBP_NEON_OMIT_C_CODE
|
static void DC4(uint8_t* dst) { // DC
|
||||||
static void DC4_C(uint8_t* dst) { // DC
|
|
||||||
uint32_t dc = 4;
|
uint32_t dc = 4;
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < 4; ++i) dc += dst[i - BPS] + dst[-1 + i * BPS];
|
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);
|
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 I = dst[-1 + 0 * BPS];
|
||||||
const int J = dst[-1 + 1 * BPS];
|
const int J = dst[-1 + 1 * BPS];
|
||||||
const int K = dst[-1 + 2 * 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);
|
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 A = dst[0 - BPS];
|
||||||
const int B = dst[1 - BPS];
|
const int B = dst[1 - BPS];
|
||||||
const int C = dst[2 - 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, 2) = DST(2, 3) = AVG3(F, G, H);
|
||||||
DST(3, 3) = AVG3(G, H, 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 I = dst[-1 + 0 * BPS];
|
||||||
const int J = dst[-1 + 1 * BPS];
|
const int J = dst[-1 + 1 * BPS];
|
||||||
const int K = dst[-1 + 2 * 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);
|
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 A = dst[0 - BPS];
|
||||||
const int B = dst[1 - BPS];
|
const int B = dst[1 - BPS];
|
||||||
const int C = dst[2 - 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);
|
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 I = dst[-1 + 0 * BPS];
|
||||||
const int J = dst[-1 + 1 * BPS];
|
const int J = dst[-1 + 1 * BPS];
|
||||||
const int K = dst[-1 + 2 * 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;
|
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 I = dst[-1 + 0 * BPS];
|
||||||
const int J = dst[-1 + 1 * BPS];
|
const int J = dst[-1 + 1 * BPS];
|
||||||
const int K = dst[-1 + 2 * BPS];
|
const int K = dst[-1 + 2 * BPS];
|
||||||
@ -418,15 +404,14 @@ VP8PredFunc VP8PredLuma4[NUM_BMODES];
|
|||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Chroma
|
// Chroma
|
||||||
|
|
||||||
#if !WEBP_NEON_OMIT_C_CODE
|
static void VE8uv(uint8_t* dst) { // vertical
|
||||||
static void VE8uv_C(uint8_t* dst) { // vertical
|
|
||||||
int j;
|
int j;
|
||||||
for (j = 0; j < 8; ++j) {
|
for (j = 0; j < 8; ++j) {
|
||||||
memcpy(dst + j * BPS, dst - BPS, 8);
|
memcpy(dst + j * BPS, dst - BPS, 8);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void HE8uv_C(uint8_t* dst) { // horizontal
|
static void HE8uv(uint8_t* dst) { // horizontal
|
||||||
int j;
|
int j;
|
||||||
for (j = 0; j < 8; ++j) {
|
for (j = 0; j < 8; ++j) {
|
||||||
memset(dst, dst[-1], 8);
|
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 dc0 = 8;
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < 8; ++i) {
|
for (i = 0; i < 8; ++i) {
|
||||||
@ -451,7 +436,7 @@ static void DC8uv_C(uint8_t* dst) { // DC
|
|||||||
Put8x8uv(dc0 >> 4, dst);
|
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 dc0 = 4;
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < 8; ++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);
|
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 dc0 = 4;
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < 8; ++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);
|
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);
|
Put8x8uv(0x80, dst);
|
||||||
}
|
}
|
||||||
#endif // !WEBP_NEON_OMIT_C_CODE
|
|
||||||
|
|
||||||
VP8PredFunc VP8PredChroma8[NUM_B_DC_MODES];
|
VP8PredFunc VP8PredChroma8[NUM_B_DC_MODES];
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Edge filtering functions
|
// Edge filtering functions
|
||||||
|
|
||||||
#if !WEBP_NEON_OMIT_C_CODE || WEBP_NEON_WORK_AROUND_GCC
|
|
||||||
// 4 pixels in, 2 pixels out
|
// 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 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 a = 3 * (q0 - p0) + VP8ksclip1[p1 - q1]; // in [-893,892]
|
||||||
const int a1 = VP8ksclip2[(a + 4) >> 3]; // in [-16,15]
|
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
|
// 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 p1 = p[-2*step], p0 = p[-step], q0 = p[0], q1 = p[step];
|
||||||
const int a = 3 * (q0 - p0);
|
const int a = 3 * (q0 - p0);
|
||||||
const int a1 = VP8ksclip2[(a + 4) >> 3];
|
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
|
// 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 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 q0 = p[0], q1 = p[step], q2 = p[2*step];
|
||||||
const int a = VP8ksclip1[3 * (q0 - p0) + VP8ksclip1[p1 - q1]];
|
const int a = VP8ksclip1[3 * (q0 - p0) + VP8ksclip1[p1 - q1]];
|
||||||
@ -520,22 +503,18 @@ static WEBP_INLINE void DoFilter6_C(uint8_t* p, int step) {
|
|||||||
p[ 2*step] = VP8kclip1[q2 - a3];
|
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];
|
const int p1 = p[-2*step], p0 = p[-step], q0 = p[0], q1 = p[step];
|
||||||
return (VP8kabs0[p1 - p0] > thresh) || (VP8kabs0[q1 - q0] > thresh);
|
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 needs_filter(const uint8_t* p, int step, int t) {
|
||||||
static WEBP_INLINE int NeedsFilter_C(const uint8_t* p, int step, int t) {
|
|
||||||
const int p1 = p[-2 * step], p0 = p[-step], q0 = p[0], q1 = p[step];
|
const int p1 = p[-2 * step], p0 = p[-step], q0 = p[0], q1 = p[step];
|
||||||
return ((4 * VP8kabs0[p0 - q0] + VP8kabs0[p1 - q1]) <= t);
|
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 needs_filter2(const uint8_t* p,
|
||||||
static WEBP_INLINE int NeedsFilter2_C(const uint8_t* p,
|
int step, int t, int it) {
|
||||||
int step, int t, int it) {
|
|
||||||
const int p3 = p[-4 * step], p2 = p[-3 * step], p1 = p[-2 * step];
|
const int p3 = p[-4 * step], p2 = p[-3 * step], p1 = p[-2 * step];
|
||||||
const int p0 = p[-step], q0 = p[0];
|
const int p0 = p[-step], q0 = p[0];
|
||||||
const int q1 = p[step], q2 = p[2 * step], q3 = p[3 * step];
|
const int q1 = p[step], q2 = p[2 * step], q3 = p[3 * step];
|
||||||
@ -544,159 +523,140 @@ static WEBP_INLINE int NeedsFilter2_C(const uint8_t* p,
|
|||||||
VP8kabs0[p1 - p0] <= it && VP8kabs0[q3 - q2] <= it &&
|
VP8kabs0[p1 - p0] <= it && VP8kabs0[q3 - q2] <= it &&
|
||||||
VP8kabs0[q2 - q1] <= it && VP8kabs0[q1 - q0] <= 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)
|
// Simple In-loop filtering (Paragraph 15.2)
|
||||||
|
|
||||||
#if !WEBP_NEON_OMIT_C_CODE
|
static void SimpleVFilter16(uint8_t* p, int stride, int thresh) {
|
||||||
static void SimpleVFilter16_C(uint8_t* p, int stride, int thresh) {
|
|
||||||
int i;
|
int i;
|
||||||
const int thresh2 = 2 * thresh + 1;
|
const int thresh2 = 2 * thresh + 1;
|
||||||
for (i = 0; i < 16; ++i) {
|
for (i = 0; i < 16; ++i) {
|
||||||
if (NeedsFilter_C(p + i, stride, thresh2)) {
|
if (needs_filter(p + i, stride, thresh2)) {
|
||||||
DoFilter2_C(p + i, stride);
|
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;
|
int i;
|
||||||
const int thresh2 = 2 * thresh + 1;
|
const int thresh2 = 2 * thresh + 1;
|
||||||
for (i = 0; i < 16; ++i) {
|
for (i = 0; i < 16; ++i) {
|
||||||
if (NeedsFilter_C(p + i * stride, 1, thresh2)) {
|
if (needs_filter(p + i * stride, 1, thresh2)) {
|
||||||
DoFilter2_C(p + i * stride, 1);
|
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;
|
int k;
|
||||||
for (k = 3; k > 0; --k) {
|
for (k = 3; k > 0; --k) {
|
||||||
p += 4 * stride;
|
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;
|
int k;
|
||||||
for (k = 3; k > 0; --k) {
|
for (k = 3; k > 0; --k) {
|
||||||
p += 4;
|
p += 4;
|
||||||
SimpleHFilter16_C(p, stride, thresh);
|
SimpleHFilter16(p, stride, thresh);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif // !WEBP_NEON_OMIT_C_CODE
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Complex In-loop filtering (Paragraph 15.3)
|
// Complex In-loop filtering (Paragraph 15.3)
|
||||||
|
|
||||||
#if !WEBP_NEON_OMIT_C_CODE || WEBP_NEON_WORK_AROUND_GCC
|
static WEBP_INLINE void FilterLoop26(uint8_t* p,
|
||||||
static WEBP_INLINE void FilterLoop26_C(uint8_t* p,
|
int hstride, int vstride, int size,
|
||||||
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;
|
const int thresh2 = 2 * thresh + 1;
|
||||||
while (size-- > 0) {
|
while (size-- > 0) {
|
||||||
if (NeedsFilter2_C(p, hstride, thresh2, ithresh)) {
|
if (needs_filter2(p, hstride, thresh2, ithresh)) {
|
||||||
if (Hev(p, hstride, hev_thresh)) {
|
if (hev(p, hstride, hev_thresh)) {
|
||||||
DoFilter2_C(p, hstride);
|
do_filter2(p, hstride);
|
||||||
} else {
|
} else {
|
||||||
DoFilter6_C(p, hstride);
|
do_filter6(p, hstride);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
p += vstride;
|
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 hstride, int vstride, int size,
|
||||||
int thresh, int ithresh,
|
int thresh, int ithresh, int hev_thresh) {
|
||||||
int hev_thresh) {
|
|
||||||
const int thresh2 = 2 * thresh + 1;
|
const int thresh2 = 2 * thresh + 1;
|
||||||
while (size-- > 0) {
|
while (size-- > 0) {
|
||||||
if (NeedsFilter2_C(p, hstride, thresh2, ithresh)) {
|
if (needs_filter2(p, hstride, thresh2, ithresh)) {
|
||||||
if (Hev(p, hstride, hev_thresh)) {
|
if (hev(p, hstride, hev_thresh)) {
|
||||||
DoFilter2_C(p, hstride);
|
do_filter2(p, hstride);
|
||||||
} else {
|
} else {
|
||||||
DoFilter4_C(p, hstride);
|
do_filter4(p, hstride);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
p += vstride;
|
p += vstride;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif // !WEBP_NEON_OMIT_C_CODE || WEBP_NEON_WORK_AROUND_GCC
|
|
||||||
|
|
||||||
#if !WEBP_NEON_OMIT_C_CODE
|
|
||||||
// on macroblock edges
|
// 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) {
|
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) {
|
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
|
// 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 thresh, int ithresh, int hev_thresh) {
|
||||||
int k;
|
int k;
|
||||||
for (k = 3; k > 0; --k) {
|
for (k = 3; k > 0; --k) {
|
||||||
p += 4 * stride;
|
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(uint8_t* p, int stride,
|
||||||
static void HFilter16i_C(uint8_t* p, int stride,
|
int thresh, int ithresh, int hev_thresh) {
|
||||||
int thresh, int ithresh, int hev_thresh) {
|
|
||||||
int k;
|
int k;
|
||||||
for (k = 3; k > 0; --k) {
|
for (k = 3; k > 0; --k) {
|
||||||
p += 4;
|
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
|
// 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) {
|
int thresh, int ithresh, int hev_thresh) {
|
||||||
FilterLoop26_C(u, stride, 1, 8, thresh, ithresh, hev_thresh);
|
FilterLoop26(u, stride, 1, 8, thresh, ithresh, hev_thresh);
|
||||||
FilterLoop26_C(v, 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(uint8_t* u, uint8_t* v, int stride,
|
||||||
static void HFilter8_C(uint8_t* u, uint8_t* v, int stride,
|
int thresh, int ithresh, int hev_thresh) {
|
||||||
int thresh, int ithresh, int hev_thresh) {
|
FilterLoop26(u, 1, stride, 8, thresh, ithresh, hev_thresh);
|
||||||
FilterLoop26_C(u, 1, stride, 8, thresh, ithresh, hev_thresh);
|
FilterLoop26(v, 1, stride, 8, thresh, ithresh, hev_thresh);
|
||||||
FilterLoop26_C(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(uint8_t* u, uint8_t* v, int stride,
|
||||||
static void VFilter8i_C(uint8_t* u, uint8_t* v, int stride,
|
int thresh, int ithresh, int hev_thresh) {
|
||||||
int thresh, int ithresh, int hev_thresh) {
|
FilterLoop24(u + 4 * stride, stride, 1, 8, thresh, ithresh, hev_thresh);
|
||||||
FilterLoop24_C(u + 4 * stride, stride, 1, 8, thresh, ithresh, hev_thresh);
|
FilterLoop24(v + 4 * stride, stride, 1, 8, thresh, ithresh, hev_thresh);
|
||||||
FilterLoop24_C(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(uint8_t* u, uint8_t* v, int stride,
|
||||||
static void HFilter8i_C(uint8_t* u, uint8_t* v, int stride,
|
int thresh, int ithresh, int hev_thresh) {
|
||||||
int thresh, int ithresh, int hev_thresh) {
|
FilterLoop24(u + 4, 1, stride, 8, thresh, ithresh, hev_thresh);
|
||||||
FilterLoop24_C(u + 4, 1, stride, 8, thresh, ithresh, hev_thresh);
|
FilterLoop24(v + 4, 1, stride, 8, thresh, ithresh, hev_thresh);
|
||||||
FilterLoop24_C(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 dst_stride) {
|
||||||
int i, j;
|
int i, j;
|
||||||
for (j = 0; j < 8; ++j) {
|
for (j = 0; j < 8; ++j) {
|
||||||
for (i = 0; i < 8; ++i) {
|
for (i = 0; i < 8; ++i) {
|
||||||
@ -740,70 +700,64 @@ extern void VP8DspInitNEON(void);
|
|||||||
extern void VP8DspInitMIPS32(void);
|
extern void VP8DspInitMIPS32(void);
|
||||||
extern void VP8DspInitMIPSdspR2(void);
|
extern void VP8DspInitMIPSdspR2(void);
|
||||||
extern void VP8DspInitMSA(void);
|
extern void VP8DspInitMSA(void);
|
||||||
|
extern void 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();
|
VP8InitClipTables();
|
||||||
|
|
||||||
#if !WEBP_NEON_OMIT_C_CODE
|
VP8TransformWHT = TransformWHT;
|
||||||
VP8TransformWHT = TransformWHT_C;
|
VP8Transform = TransformTwo;
|
||||||
VP8Transform = TransformTwo_C;
|
VP8TransformUV = TransformUV;
|
||||||
VP8TransformDC = TransformDC_C;
|
VP8TransformDC = TransformDC;
|
||||||
VP8TransformAC3 = TransformAC3_C;
|
VP8TransformDCUV = TransformDCUV;
|
||||||
#endif
|
VP8TransformAC3 = TransformAC3;
|
||||||
VP8TransformUV = TransformUV_C;
|
|
||||||
VP8TransformDCUV = TransformDCUV_C;
|
|
||||||
|
|
||||||
#if !WEBP_NEON_OMIT_C_CODE
|
VP8VFilter16 = VFilter16;
|
||||||
VP8VFilter16 = VFilter16_C;
|
VP8HFilter16 = HFilter16;
|
||||||
VP8VFilter16i = VFilter16i_C;
|
VP8VFilter8 = VFilter8;
|
||||||
VP8HFilter16 = HFilter16_C;
|
VP8HFilter8 = HFilter8;
|
||||||
VP8VFilter8 = VFilter8_C;
|
VP8VFilter16i = VFilter16i;
|
||||||
VP8VFilter8i = VFilter8i_C;
|
VP8HFilter16i = HFilter16i;
|
||||||
VP8SimpleVFilter16 = SimpleVFilter16_C;
|
VP8VFilter8i = VFilter8i;
|
||||||
VP8SimpleHFilter16 = SimpleHFilter16_C;
|
VP8HFilter8i = HFilter8i;
|
||||||
VP8SimpleVFilter16i = SimpleVFilter16i_C;
|
VP8SimpleVFilter16 = SimpleVFilter16;
|
||||||
VP8SimpleHFilter16i = SimpleHFilter16i_C;
|
VP8SimpleHFilter16 = SimpleHFilter16;
|
||||||
#endif
|
VP8SimpleVFilter16i = SimpleVFilter16i;
|
||||||
|
VP8SimpleHFilter16i = SimpleHFilter16i;
|
||||||
|
|
||||||
#if !WEBP_NEON_OMIT_C_CODE || WEBP_NEON_WORK_AROUND_GCC
|
VP8PredLuma4[0] = DC4;
|
||||||
VP8HFilter16i = HFilter16i_C;
|
VP8PredLuma4[1] = TM4;
|
||||||
VP8HFilter8 = HFilter8_C;
|
VP8PredLuma4[2] = VE4;
|
||||||
VP8HFilter8i = HFilter8i_C;
|
VP8PredLuma4[3] = HE4;
|
||||||
#endif
|
VP8PredLuma4[4] = RD4;
|
||||||
|
VP8PredLuma4[5] = VR4;
|
||||||
|
VP8PredLuma4[6] = LD4;
|
||||||
|
VP8PredLuma4[7] = VL4;
|
||||||
|
VP8PredLuma4[8] = HD4;
|
||||||
|
VP8PredLuma4[9] = HU4;
|
||||||
|
|
||||||
#if !WEBP_NEON_OMIT_C_CODE
|
VP8PredLuma16[0] = DC16;
|
||||||
VP8PredLuma4[0] = DC4_C;
|
VP8PredLuma16[1] = TM16;
|
||||||
VP8PredLuma4[1] = TM4_C;
|
VP8PredLuma16[2] = VE16;
|
||||||
VP8PredLuma4[2] = VE4_C;
|
VP8PredLuma16[3] = HE16;
|
||||||
VP8PredLuma4[4] = RD4_C;
|
VP8PredLuma16[4] = DC16NoTop;
|
||||||
VP8PredLuma4[6] = LD4_C;
|
VP8PredLuma16[5] = DC16NoLeft;
|
||||||
#endif
|
VP8PredLuma16[6] = DC16NoTopLeft;
|
||||||
|
|
||||||
VP8PredLuma4[3] = HE4_C;
|
VP8PredChroma8[0] = DC8uv;
|
||||||
VP8PredLuma4[5] = VR4_C;
|
VP8PredChroma8[1] = TM8uv;
|
||||||
VP8PredLuma4[7] = VL4_C;
|
VP8PredChroma8[2] = VE8uv;
|
||||||
VP8PredLuma4[8] = HD4_C;
|
VP8PredChroma8[3] = HE8uv;
|
||||||
VP8PredLuma4[9] = HU4_C;
|
VP8PredChroma8[4] = DC8uvNoTop;
|
||||||
|
VP8PredChroma8[5] = DC8uvNoLeft;
|
||||||
|
VP8PredChroma8[6] = DC8uvNoTopLeft;
|
||||||
|
|
||||||
#if !WEBP_NEON_OMIT_C_CODE
|
VP8DitherCombine8x8 = DitherCombine8x8;
|
||||||
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;
|
|
||||||
|
|
||||||
// If defined, use CPUInfo() to overwrite some pointers with faster versions.
|
// If defined, use CPUInfo() to overwrite some pointers with faster versions.
|
||||||
if (VP8GetCPUInfo != NULL) {
|
if (VP8GetCPUInfo != NULL) {
|
||||||
@ -817,6 +771,11 @@ WEBP_DSP_INIT_FUNC(VP8DspInit) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#if defined(WEBP_USE_NEON)
|
||||||
|
if (VP8GetCPUInfo(kNEON)) {
|
||||||
|
VP8DspInitNEON();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
#if defined(WEBP_USE_MIPS32)
|
#if defined(WEBP_USE_MIPS32)
|
||||||
if (VP8GetCPUInfo(kMIPS32)) {
|
if (VP8GetCPUInfo(kMIPS32)) {
|
||||||
VP8DspInitMIPS32();
|
VP8DspInitMIPS32();
|
||||||
@ -832,56 +791,11 @@ WEBP_DSP_INIT_FUNC(VP8DspInit) {
|
|||||||
VP8DspInitMSA();
|
VP8DspInitMSA();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
#if defined(WEBP_USE_WASM)
|
||||||
|
if (VP8GetCPUInfo(kWASM)) {
|
||||||
#if defined(WEBP_USE_NEON)
|
VP8DspInitWASM();
|
||||||
if (WEBP_NEON_OMIT_C_CODE ||
|
}
|
||||||
(VP8GetCPUInfo != NULL && VP8GetCPUInfo(kNEON))) {
|
|
||||||
VP8DspInitNEON();
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
assert(VP8TransformWHT != NULL);
|
dec_last_cpuinfo_used = VP8GetCPUInfo;
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
@ -11,14 +11,11 @@
|
|||||||
//
|
//
|
||||||
// Author: Skal (pascal.massimino@gmail.com)
|
// Author: Skal (pascal.massimino@gmail.com)
|
||||||
|
|
||||||
#include "src/dsp/dsp.h"
|
#include "./dsp.h"
|
||||||
|
|
||||||
// define to 0 to have run-time table initialization
|
#define USE_STATIC_TABLES // undefine to have run-time table initialization
|
||||||
#if !defined(USE_STATIC_TABLES)
|
|
||||||
#define USE_STATIC_TABLES 1 // ALTERNATE_CODE
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if (USE_STATIC_TABLES == 1)
|
#ifdef USE_STATIC_TABLES
|
||||||
|
|
||||||
static const uint8_t abs0[255 + 255 + 1] = {
|
static const uint8_t abs0[255 + 255 + 1] = {
|
||||||
0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8, 0xf7, 0xf6, 0xf5, 0xf4,
|
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)
|
// and make sure it's set to true _last_ (so as to be thread-safe)
|
||||||
static volatile int tables_ok = 0;
|
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 VP8ksclip1 = (const int8_t*)&sclip1[1020];
|
||||||
const int8_t* const VP8ksclip2 = (const int8_t*)&sclip2[112];
|
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];
|
const uint8_t* const VP8kabs0 = &abs0[255];
|
||||||
|
|
||||||
WEBP_TSAN_IGNORE_FUNCTION void VP8InitClipTables(void) {
|
WEBP_TSAN_IGNORE_FUNCTION void VP8InitClipTables(void) {
|
||||||
#if (USE_STATIC_TABLES == 0)
|
#if !defined(USE_STATIC_TABLES)
|
||||||
int i;
|
int i;
|
||||||
if (!tables_ok) {
|
if (!tables_ok) {
|
||||||
for (i = -255; i <= 255; ++i) {
|
for (i = -255; i <= 255; ++i) {
|
||||||
|
@ -12,11 +12,11 @@
|
|||||||
// Author(s): Djordje Pesut (djordje.pesut@imgtec.com)
|
// Author(s): Djordje Pesut (djordje.pesut@imgtec.com)
|
||||||
// Jovan Zelincevic (jovan.zelincevic@imgtec.com)
|
// Jovan Zelincevic (jovan.zelincevic@imgtec.com)
|
||||||
|
|
||||||
#include "src/dsp/dsp.h"
|
#include "./dsp.h"
|
||||||
|
|
||||||
#if defined(WEBP_USE_MIPS32)
|
#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 kC1 = 20091 + (1 << 16);
|
||||||
static const int kC2 = 35468;
|
static const int kC2 = 35468;
|
||||||
|
@ -12,11 +12,11 @@
|
|||||||
// Author(s): Djordje Pesut (djordje.pesut@imgtec.com)
|
// Author(s): Djordje Pesut (djordje.pesut@imgtec.com)
|
||||||
// Jovan Zelincevic (jovan.zelincevic@imgtec.com)
|
// Jovan Zelincevic (jovan.zelincevic@imgtec.com)
|
||||||
|
|
||||||
#include "src/dsp/dsp.h"
|
#include "./dsp.h"
|
||||||
|
|
||||||
#if defined(WEBP_USE_MIPS_DSP_R2)
|
#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 kC1 = 20091 + (1 << 16);
|
||||||
static const int kC2 = 35468;
|
static const int kC2 = 35468;
|
||||||
|
@ -12,11 +12,11 @@
|
|||||||
// Author(s): Prashant Patil (prashant.patil@imgtec.com)
|
// Author(s): Prashant Patil (prashant.patil@imgtec.com)
|
||||||
|
|
||||||
|
|
||||||
#include "src/dsp/dsp.h"
|
#include "./dsp.h"
|
||||||
|
|
||||||
#if defined(WEBP_USE_MSA)
|
#if defined(WEBP_USE_MSA)
|
||||||
|
|
||||||
#include "src/dsp/msa_macro.h"
|
#include "./msa_macro.h"
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Transforms
|
// Transforms
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -12,25 +12,23 @@
|
|||||||
// Author: somnath@google.com (Somnath Banerjee)
|
// Author: somnath@google.com (Somnath Banerjee)
|
||||||
// cduvivier@google.com (Christian Duvivier)
|
// cduvivier@google.com (Christian Duvivier)
|
||||||
|
|
||||||
#include "src/dsp/dsp.h"
|
#include "./dsp.h"
|
||||||
|
|
||||||
#if defined(WEBP_USE_SSE2)
|
#if defined(WEBP_USE_SSE2)
|
||||||
|
|
||||||
// The 3-coeff sparse transform in SSE2 is not really faster than the plain-C
|
// 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:
|
// one it seems => disable it by default. Uncomment the following to enable:
|
||||||
#if !defined(USE_TRANSFORM_AC3)
|
// #define USE_TRANSFORM_AC3
|
||||||
#define USE_TRANSFORM_AC3 0 // ALTERNATE_CODE
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <emmintrin.h>
|
#include <emmintrin.h>
|
||||||
#include "src/dsp/common_sse2.h"
|
#include "./common_sse2.h"
|
||||||
#include "src/dec/vp8i_dec.h"
|
#include "../dec/vp8i_dec.h"
|
||||||
#include "src/utils/utils.h"
|
#include "../utils/utils.h"
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Transforms (Paragraph 14.4)
|
// 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
|
// This implementation makes use of 16-bit fixed point versions of two
|
||||||
// multiply constants:
|
// multiply constants:
|
||||||
// K1 = sqrt(2) * cos (pi/8) ~= 85627 / 2^16
|
// 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)
|
#define MUL(a, b) (((a) * (b)) >> 16)
|
||||||
static void TransformAC3(const int16_t* in, uint8_t* dst) {
|
static void TransformAC3(const int16_t* in, uint8_t* dst) {
|
||||||
static const int kC1 = 20091 + (1 << 16);
|
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)))
|
_mm_subs_epu8((p), (q)))
|
||||||
|
|
||||||
// Shift each byte of "x" by 3 bits while preserving by the sign bit.
|
// 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 zero = _mm_setzero_si128();
|
||||||
const __m128i lo_0 = _mm_unpacklo_epi8(zero, *x);
|
const __m128i lo_0 = _mm_unpacklo_epi8(zero, *x);
|
||||||
const __m128i hi_0 = _mm_unpackhi_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) { \
|
#define FLIP_SIGN_BIT2(a, b) { \
|
||||||
(a) = _mm_xor_si128(a, sign_bit); \
|
a = _mm_xor_si128(a, sign_bit); \
|
||||||
(b) = _mm_xor_si128(b, sign_bit); \
|
b = _mm_xor_si128(b, sign_bit); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define FLIP_SIGN_BIT4(a, b, c, d) { \
|
#define FLIP_SIGN_BIT4(a, b, c, d) { \
|
||||||
@ -270,11 +268,11 @@ static WEBP_INLINE void SignedShift8b_SSE2(__m128i* const x) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// input/output is uint8_t
|
// 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 p0,
|
||||||
const __m128i* const q0,
|
const __m128i* const q0,
|
||||||
const __m128i* const q1,
|
const __m128i* const q1,
|
||||||
int hev_thresh, __m128i* const not_hev) {
|
int hev_thresh, __m128i* const not_hev) {
|
||||||
const __m128i zero = _mm_setzero_si128();
|
const __m128i zero = _mm_setzero_si128();
|
||||||
const __m128i t_1 = MM_ABS(*p1, *p0);
|
const __m128i t_1 = MM_ABS(*p1, *p0);
|
||||||
const __m128i t_2 = MM_ABS(*q1, *q0);
|
const __m128i t_2 = MM_ABS(*q1, *q0);
|
||||||
@ -287,11 +285,11 @@ static WEBP_INLINE void GetNotHEV_SSE2(const __m128i* const p1,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// input pixels are int8_t
|
// 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 p0,
|
||||||
const __m128i* const q0,
|
const __m128i* const q0,
|
||||||
const __m128i* const q1,
|
const __m128i* const q1,
|
||||||
__m128i* const delta) {
|
__m128i* const delta) {
|
||||||
// beware of addition order, for saturation!
|
// beware of addition order, for saturation!
|
||||||
const __m128i p1_q1 = _mm_subs_epi8(*p1, *q1); // p1 - q1
|
const __m128i p1_q1 = _mm_subs_epi8(*p1, *q1); // p1 - q1
|
||||||
const __m128i q0_p0 = _mm_subs_epi8(*q0, *p0); // q0 - p0
|
const __m128i q0_p0 = _mm_subs_epi8(*q0, *p0); // q0 - p0
|
||||||
@ -302,16 +300,15 @@ static WEBP_INLINE void GetBaseDelta_SSE2(const __m128i* const p1,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// input and output are int8_t
|
// input and output are int8_t
|
||||||
static WEBP_INLINE void DoSimpleFilter_SSE2(__m128i* const p0,
|
static WEBP_INLINE void DoSimpleFilter(__m128i* const p0, __m128i* const q0,
|
||||||
__m128i* const q0,
|
const __m128i* const fl) {
|
||||||
const __m128i* const fl) {
|
|
||||||
const __m128i k3 = _mm_set1_epi8(3);
|
const __m128i k3 = _mm_set1_epi8(3);
|
||||||
const __m128i k4 = _mm_set1_epi8(4);
|
const __m128i k4 = _mm_set1_epi8(4);
|
||||||
__m128i v3 = _mm_adds_epi8(*fl, k3);
|
__m128i v3 = _mm_adds_epi8(*fl, k3);
|
||||||
__m128i v4 = _mm_adds_epi8(*fl, k4);
|
__m128i v4 = _mm_adds_epi8(*fl, k4);
|
||||||
|
|
||||||
SignedShift8b_SSE2(&v4); // v4 >> 3
|
SignedShift8b(&v4); // v4 >> 3
|
||||||
SignedShift8b_SSE2(&v3); // v3 >> 3
|
SignedShift8b(&v3); // v3 >> 3
|
||||||
*q0 = _mm_subs_epi8(*q0, v4); // q0 -= v4
|
*q0 = _mm_subs_epi8(*q0, v4); // q0 -= v4
|
||||||
*p0 = _mm_adds_epi8(*p0, v3); // p0 += v3
|
*p0 = _mm_adds_epi8(*p0, v3); // p0 += v3
|
||||||
}
|
}
|
||||||
@ -320,9 +317,9 @@ static WEBP_INLINE void DoSimpleFilter_SSE2(__m128i* const p0,
|
|||||||
// Update operations:
|
// Update operations:
|
||||||
// q = q - delta and p = p + delta; where delta = [(a_hi >> 7), (a_lo >> 7)]
|
// 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).
|
// 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_lo,
|
||||||
const __m128i* const a0_hi) {
|
const __m128i* const a0_hi) {
|
||||||
const __m128i a1_lo = _mm_srai_epi16(*a0_lo, 7);
|
const __m128i a1_lo = _mm_srai_epi16(*a0_lo, 7);
|
||||||
const __m128i a1_hi = _mm_srai_epi16(*a0_hi, 7);
|
const __m128i a1_hi = _mm_srai_epi16(*a0_hi, 7);
|
||||||
const __m128i delta = _mm_packs_epi16(a1_lo, a1_hi);
|
const __m128i delta = _mm_packs_epi16(a1_lo, a1_hi);
|
||||||
@ -333,11 +330,11 @@ static WEBP_INLINE void Update2Pixels_SSE2(__m128i* const pi, __m128i* const qi,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// input pixels are uint8_t
|
// 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 p0,
|
||||||
const __m128i* const q0,
|
const __m128i* const q0,
|
||||||
const __m128i* const q1,
|
const __m128i* const q1,
|
||||||
int thresh, __m128i* const mask) {
|
int thresh, __m128i* const mask) {
|
||||||
const __m128i m_thresh = _mm_set1_epi8(thresh);
|
const __m128i m_thresh = _mm_set1_epi8(thresh);
|
||||||
const __m128i t1 = MM_ABS(*p1, *q1); // abs(p1 - q1)
|
const __m128i t1 = MM_ABS(*p1, *q1); // abs(p1 - q1)
|
||||||
const __m128i kFE = _mm_set1_epi8(0xFE);
|
const __m128i kFE = _mm_set1_epi8(0xFE);
|
||||||
@ -356,29 +353,28 @@ static WEBP_INLINE void NeedsFilter_SSE2(const __m128i* const p1,
|
|||||||
// Edge filtering functions
|
// Edge filtering functions
|
||||||
|
|
||||||
// Applies filter on 2 pixels (p0 and q0)
|
// 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,
|
__m128i* const q0, __m128i* const q1,
|
||||||
int thresh) {
|
int thresh) {
|
||||||
__m128i a, mask;
|
__m128i a, mask;
|
||||||
const __m128i sign_bit = _mm_set1_epi8(0x80);
|
const __m128i sign_bit = _mm_set1_epi8(0x80);
|
||||||
// convert p1/q1 to int8_t (for GetBaseDelta_SSE2)
|
// convert p1/q1 to int8_t (for GetBaseDelta)
|
||||||
const __m128i p1s = _mm_xor_si128(*p1, sign_bit);
|
const __m128i p1s = _mm_xor_si128(*p1, sign_bit);
|
||||||
const __m128i q1s = _mm_xor_si128(*q1, sign_bit);
|
const __m128i q1s = _mm_xor_si128(*q1, sign_bit);
|
||||||
|
|
||||||
NeedsFilter_SSE2(p1, p0, q0, q1, thresh, &mask);
|
NeedsFilter(p1, p0, q0, q1, thresh, &mask);
|
||||||
|
|
||||||
FLIP_SIGN_BIT2(*p0, *q0);
|
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
|
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);
|
FLIP_SIGN_BIT2(*p0, *q0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Applies filter on 4 pixels (p1, p0, q0 and q1)
|
// 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,
|
__m128i* const q0, __m128i* const q1,
|
||||||
const __m128i* const mask,
|
const __m128i* const mask, int hev_thresh) {
|
||||||
int hev_thresh) {
|
|
||||||
const __m128i zero = _mm_setzero_si128();
|
const __m128i zero = _mm_setzero_si128();
|
||||||
const __m128i sign_bit = _mm_set1_epi8(0x80);
|
const __m128i sign_bit = _mm_set1_epi8(0x80);
|
||||||
const __m128i k64 = _mm_set1_epi8(64);
|
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;
|
__m128i t1, t2, t3;
|
||||||
|
|
||||||
// compute hev mask
|
// compute hev mask
|
||||||
GetNotHEV_SSE2(p1, p0, q0, q1, hev_thresh, ¬_hev);
|
GetNotHEV(p1, p0, q0, q1, hev_thresh, ¬_hev);
|
||||||
|
|
||||||
// convert to signed values
|
// convert to signed values
|
||||||
FLIP_SIGN_BIT4(*p1, *p0, *q0, *q1);
|
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
|
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
|
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(&t2); // (3 * (q0 - p0) + hev(p1 - q1) + 3) >> 3
|
||||||
SignedShift8b_SSE2(&t3); // (3 * (q0 - p0) + hev(p1 - q1) + 4) >> 3
|
SignedShift8b(&t3); // (3 * (q0 - p0) + hev(p1 - q1) + 4) >> 3
|
||||||
*p0 = _mm_adds_epi8(*p0, t2); // p0 += t2
|
*p0 = _mm_adds_epi8(*p0, t2); // p0 += t2
|
||||||
*q0 = _mm_subs_epi8(*q0, t3); // q0 -= t3
|
*q0 = _mm_subs_epi8(*q0, t3); // q0 -= t3
|
||||||
FLIP_SIGN_BIT2(*p0, *q0);
|
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)
|
// 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 p0, __m128i* const q0,
|
||||||
__m128i* const q1, __m128i* const q2,
|
__m128i* const q1, __m128i* const q2,
|
||||||
const __m128i* const mask,
|
const __m128i* const mask, int hev_thresh) {
|
||||||
int hev_thresh) {
|
|
||||||
const __m128i zero = _mm_setzero_si128();
|
const __m128i zero = _mm_setzero_si128();
|
||||||
const __m128i sign_bit = _mm_set1_epi8(0x80);
|
const __m128i sign_bit = _mm_set1_epi8(0x80);
|
||||||
__m128i a, not_hev;
|
__m128i a, not_hev;
|
||||||
|
|
||||||
// compute hev mask
|
// 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_BIT4(*p1, *p0, *q0, *q1);
|
||||||
FLIP_SIGN_BIT2(*p2, *q2);
|
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
|
{ // do simple filter on pixels with hev
|
||||||
const __m128i m = _mm_andnot_si128(not_hev, *mask);
|
const __m128i m = _mm_andnot_si128(not_hev, *mask);
|
||||||
const __m128i f = _mm_and_si128(a, m);
|
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
|
{ // do strong filter on pixels with not hev
|
||||||
@ -465,15 +460,15 @@ 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_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
|
const __m128i a0_hi = _mm_add_epi16(a1_hi, f9_hi); // Filter * 27 + 63
|
||||||
|
|
||||||
Update2Pixels_SSE2(p2, q2, &a2_lo, &a2_hi);
|
Update2Pixels(p2, q2, &a2_lo, &a2_hi);
|
||||||
Update2Pixels_SSE2(p1, q1, &a1_lo, &a1_hi);
|
Update2Pixels(p1, q1, &a1_lo, &a1_hi);
|
||||||
Update2Pixels_SSE2(p0, q0, &a0_lo, &a0_hi);
|
Update2Pixels(p0, q0, &a0_lo, &a0_hi);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// reads 8 rows across a vertical edge.
|
// 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) {
|
__m128i* const p, __m128i* const q) {
|
||||||
// A0 = 63 62 61 60 23 22 21 20 43 42 41 40 03 02 01 00
|
// 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
|
// A1 = 73 72 71 70 33 32 31 30 53 52 51 50 13 12 11 10
|
||||||
const __m128i A0 = _mm_set_epi32(
|
const __m128i A0 = _mm_set_epi32(
|
||||||
@ -499,11 +494,11 @@ static WEBP_INLINE void Load8x4_SSE2(const uint8_t* const b, int stride,
|
|||||||
*q = _mm_unpackhi_epi32(C0, C1);
|
*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,
|
const uint8_t* const r8,
|
||||||
int stride,
|
int stride,
|
||||||
__m128i* const p1, __m128i* const p0,
|
__m128i* const p1, __m128i* const p0,
|
||||||
__m128i* const q0, __m128i* const q1) {
|
__m128i* const q0, __m128i* const q1) {
|
||||||
// Assume the pixels around the edge (|) are numbered as follows
|
// Assume the pixels around the edge (|) are numbered as follows
|
||||||
// 00 01 | 02 03
|
// 00 01 | 02 03
|
||||||
// 10 11 | 12 13
|
// 10 11 | 12 13
|
||||||
@ -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
|
// 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
|
// 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
|
// q1 = f3 e3 d3 c3 b3 a3 93 83 f2 e2 d2 c2 b2 a2 92 82
|
||||||
Load8x4_SSE2(r0, stride, p1, q0);
|
Load8x4(r0, stride, p1, q0);
|
||||||
Load8x4_SSE2(r8, stride, p0, q1);
|
Load8x4(r8, stride, p0, q1);
|
||||||
|
|
||||||
{
|
{
|
||||||
// p1 = f0 e0 d0 c0 b0 a0 90 80 70 60 50 40 30 20 10 00
|
// 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,
|
static WEBP_INLINE void Store4x4(__m128i* const x, uint8_t* dst, int stride) {
|
||||||
uint8_t* dst, int stride) {
|
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < 4; ++i, dst += stride) {
|
for (i = 0; i < 4; ++i, dst += stride) {
|
||||||
WebPUint32ToMem(dst, _mm_cvtsi128_si32(*x));
|
WebPUint32ToMem(dst, _mm_cvtsi128_si32(*x));
|
||||||
@ -546,12 +540,12 @@ static WEBP_INLINE void Store4x4_SSE2(__m128i* const x,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Transpose back and store
|
// 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 p0,
|
||||||
const __m128i* const q0,
|
const __m128i* const q0,
|
||||||
const __m128i* const q1,
|
const __m128i* const q1,
|
||||||
uint8_t* r0, uint8_t* r8,
|
uint8_t* r0, uint8_t* r8,
|
||||||
int stride) {
|
int stride) {
|
||||||
__m128i t1, p1_s, p0_s, q0_s, q1_s;
|
__m128i t1, p1_s, p0_s, q0_s, q1_s;
|
||||||
|
|
||||||
// p0 = 71 70 61 60 51 50 41 40 31 30 21 20 11 10 01 00
|
// p0 = 71 70 61 60 51 50 41 40 31 30 21 20 11 10 01 00
|
||||||
@ -578,55 +572,55 @@ static WEBP_INLINE void Store16x4_SSE2(const __m128i* const p1,
|
|||||||
p1_s = _mm_unpacklo_epi16(t1, q1_s);
|
p1_s = _mm_unpacklo_epi16(t1, q1_s);
|
||||||
q1_s = _mm_unpackhi_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;
|
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;
|
r8 += 4 * stride;
|
||||||
Store4x4_SSE2(&q1_s, r8, stride);
|
Store4x4(&q1_s, r8, stride);
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Simple In-loop filtering (Paragraph 15.2)
|
// 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
|
// Load
|
||||||
__m128i p1 = _mm_loadu_si128((__m128i*)&p[-2 * stride]);
|
__m128i p1 = _mm_loadu_si128((__m128i*)&p[-2 * stride]);
|
||||||
__m128i p0 = _mm_loadu_si128((__m128i*)&p[-stride]);
|
__m128i p0 = _mm_loadu_si128((__m128i*)&p[-stride]);
|
||||||
__m128i q0 = _mm_loadu_si128((__m128i*)&p[0]);
|
__m128i q0 = _mm_loadu_si128((__m128i*)&p[0]);
|
||||||
__m128i q1 = _mm_loadu_si128((__m128i*)&p[stride]);
|
__m128i q1 = _mm_loadu_si128((__m128i*)&p[stride]);
|
||||||
|
|
||||||
DoFilter2_SSE2(&p1, &p0, &q0, &q1, thresh);
|
DoFilter2(&p1, &p0, &q0, &q1, thresh);
|
||||||
|
|
||||||
// Store
|
// Store
|
||||||
_mm_storeu_si128((__m128i*)&p[-stride], p0);
|
_mm_storeu_si128((__m128i*)&p[-stride], p0);
|
||||||
_mm_storeu_si128((__m128i*)&p[0], q0);
|
_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;
|
__m128i p1, p0, q0, q1;
|
||||||
|
|
||||||
p -= 2; // beginning of p1
|
p -= 2; // beginning of p1
|
||||||
|
|
||||||
Load16x4_SSE2(p, p + 8 * stride, stride, &p1, &p0, &q0, &q1);
|
Load16x4(p, p + 8 * stride, stride, &p1, &p0, &q0, &q1);
|
||||||
DoFilter2_SSE2(&p1, &p0, &q0, &q1, thresh);
|
DoFilter2(&p1, &p0, &q0, &q1, thresh);
|
||||||
Store16x4_SSE2(&p1, &p0, &q0, &q1, p, p + 8 * stride, stride);
|
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;
|
int k;
|
||||||
for (k = 3; k > 0; --k) {
|
for (k = 3; k > 0; --k) {
|
||||||
p += 4 * stride;
|
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;
|
int k;
|
||||||
for (k = 3; k > 0; --k) {
|
for (k = 3; k > 0; --k) {
|
||||||
p += 4;
|
p += 4;
|
||||||
SimpleHFilter16_SSE2(p, stride, thresh);
|
SimpleHFilter16(p, stride, thresh);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -634,60 +628,60 @@ static void SimpleHFilter16i_SSE2(uint8_t* p, int stride, int thresh) {
|
|||||||
// Complex In-loop filtering (Paragraph 15.3)
|
// Complex In-loop filtering (Paragraph 15.3)
|
||||||
|
|
||||||
#define MAX_DIFF1(p3, p2, p1, p0, m) do { \
|
#define MAX_DIFF1(p3, p2, p1, p0, m) do { \
|
||||||
(m) = MM_ABS(p1, p0); \
|
m = MM_ABS(p1, p0); \
|
||||||
(m) = _mm_max_epu8(m, MM_ABS(p3, p2)); \
|
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(p2, p1)); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define MAX_DIFF2(p3, p2, p1, p0, m) do { \
|
#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(p1, p0)); \
|
||||||
(m) = _mm_max_epu8(m, MM_ABS(p3, p2)); \
|
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(p2, p1)); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define LOAD_H_EDGES4(p, stride, e1, e2, e3, e4) { \
|
#define LOAD_H_EDGES4(p, stride, e1, e2, e3, e4) { \
|
||||||
(e1) = _mm_loadu_si128((__m128i*)&(p)[0 * (stride)]); \
|
e1 = _mm_loadu_si128((__m128i*)&(p)[0 * stride]); \
|
||||||
(e2) = _mm_loadu_si128((__m128i*)&(p)[1 * (stride)]); \
|
e2 = _mm_loadu_si128((__m128i*)&(p)[1 * stride]); \
|
||||||
(e3) = _mm_loadu_si128((__m128i*)&(p)[2 * (stride)]); \
|
e3 = _mm_loadu_si128((__m128i*)&(p)[2 * stride]); \
|
||||||
(e4) = _mm_loadu_si128((__m128i*)&(p)[3 * (stride)]); \
|
e4 = _mm_loadu_si128((__m128i*)&(p)[3 * stride]); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define LOADUV_H_EDGE(p, u, v, stride) do { \
|
#define LOADUV_H_EDGE(p, u, v, stride) do { \
|
||||||
const __m128i U = _mm_loadl_epi64((__m128i*)&(u)[(stride)]); \
|
const __m128i U = _mm_loadl_epi64((__m128i*)&(u)[(stride)]); \
|
||||||
const __m128i V = _mm_loadl_epi64((__m128i*)&(v)[(stride)]); \
|
const __m128i V = _mm_loadl_epi64((__m128i*)&(v)[(stride)]); \
|
||||||
(p) = _mm_unpacklo_epi64(U, V); \
|
p = _mm_unpacklo_epi64(U, V); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define LOADUV_H_EDGES4(u, v, stride, e1, e2, e3, e4) { \
|
#define LOADUV_H_EDGES4(u, v, stride, e1, e2, e3, e4) { \
|
||||||
LOADUV_H_EDGE(e1, u, v, 0 * (stride)); \
|
LOADUV_H_EDGE(e1, u, v, 0 * stride); \
|
||||||
LOADUV_H_EDGE(e2, u, v, 1 * (stride)); \
|
LOADUV_H_EDGE(e2, u, v, 1 * stride); \
|
||||||
LOADUV_H_EDGE(e3, u, v, 2 * (stride)); \
|
LOADUV_H_EDGE(e3, u, v, 2 * stride); \
|
||||||
LOADUV_H_EDGE(e4, u, v, 3 * (stride)); \
|
LOADUV_H_EDGE(e4, u, v, 3 * stride); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define STOREUV(p, u, v, stride) { \
|
#define STOREUV(p, u, v, stride) { \
|
||||||
_mm_storel_epi64((__m128i*)&(u)[(stride)], p); \
|
_mm_storel_epi64((__m128i*)&u[(stride)], p); \
|
||||||
(p) = _mm_srli_si128(p, 8); \
|
p = _mm_srli_si128(p, 8); \
|
||||||
_mm_storel_epi64((__m128i*)&(v)[(stride)], p); \
|
_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 p0,
|
||||||
const __m128i* const q0,
|
const __m128i* const q0,
|
||||||
const __m128i* const q1,
|
const __m128i* const q1,
|
||||||
int thresh, int ithresh,
|
int thresh, int ithresh,
|
||||||
__m128i* const mask) {
|
__m128i* const mask) {
|
||||||
const __m128i it = _mm_set1_epi8(ithresh);
|
const __m128i it = _mm_set1_epi8(ithresh);
|
||||||
const __m128i diff = _mm_subs_epu8(*mask, it);
|
const __m128i diff = _mm_subs_epu8(*mask, it);
|
||||||
const __m128i thresh_mask = _mm_cmpeq_epi8(diff, _mm_setzero_si128());
|
const __m128i thresh_mask = _mm_cmpeq_epi8(diff, _mm_setzero_si128());
|
||||||
__m128i filter_mask;
|
__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);
|
*mask = _mm_and_si128(thresh_mask, filter_mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
// on macroblock edges
|
// 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) {
|
int thresh, int ithresh, int hev_thresh) {
|
||||||
__m128i t1;
|
__m128i t1;
|
||||||
__m128i mask;
|
__m128i mask;
|
||||||
__m128i p2, p1, p0, q0, q1, q2;
|
__m128i p2, p1, p0, q0, q1, q2;
|
||||||
@ -700,8 +694,8 @@ static void VFilter16_SSE2(uint8_t* p, int stride,
|
|||||||
LOAD_H_EDGES4(p, stride, q0, q1, q2, t1);
|
LOAD_H_EDGES4(p, stride, q0, q1, q2, t1);
|
||||||
MAX_DIFF2(t1, q2, q1, q0, mask);
|
MAX_DIFF2(t1, q2, q1, q0, mask);
|
||||||
|
|
||||||
ComplexMask_SSE2(&p1, &p0, &q0, &q1, thresh, ithresh, &mask);
|
ComplexMask(&p1, &p0, &q0, &q1, thresh, ithresh, &mask);
|
||||||
DoFilter6_SSE2(&p2, &p1, &p0, &q0, &q1, &q2, &mask, hev_thresh);
|
DoFilter6(&p2, &p1, &p0, &q0, &q1, &q2, &mask, hev_thresh);
|
||||||
|
|
||||||
// Store
|
// Store
|
||||||
_mm_storeu_si128((__m128i*)&p[-3 * stride], p2);
|
_mm_storeu_si128((__m128i*)&p[-3 * stride], p2);
|
||||||
@ -712,28 +706,28 @@ static void VFilter16_SSE2(uint8_t* p, int stride,
|
|||||||
_mm_storeu_si128((__m128i*)&p[+2 * stride], q2);
|
_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) {
|
int thresh, int ithresh, int hev_thresh) {
|
||||||
__m128i mask;
|
__m128i mask;
|
||||||
__m128i p3, p2, p1, p0, q0, q1, q2, q3;
|
__m128i p3, p2, p1, p0, q0, q1, q2, q3;
|
||||||
|
|
||||||
uint8_t* const b = p - 4;
|
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);
|
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);
|
MAX_DIFF2(q3, q2, q1, q0, mask);
|
||||||
|
|
||||||
ComplexMask_SSE2(&p1, &p0, &q0, &q1, thresh, ithresh, &mask);
|
ComplexMask(&p1, &p0, &q0, &q1, thresh, ithresh, &mask);
|
||||||
DoFilter6_SSE2(&p2, &p1, &p0, &q0, &q1, &q2, &mask, hev_thresh);
|
DoFilter6(&p2, &p1, &p0, &q0, &q1, &q2, &mask, hev_thresh);
|
||||||
|
|
||||||
Store16x4_SSE2(&p3, &p2, &p1, &p0, b, b + 8 * stride, stride);
|
Store16x4(&p3, &p2, &p1, &p0, b, b + 8 * stride, stride);
|
||||||
Store16x4_SSE2(&q0, &q1, &q2, &q3, p, p + 8 * stride, stride);
|
Store16x4(&q0, &q1, &q2, &q3, p, p + 8 * stride, stride);
|
||||||
}
|
}
|
||||||
|
|
||||||
// on three inner edges
|
// 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 thresh, int ithresh, int hev_thresh) {
|
||||||
int k;
|
int k;
|
||||||
__m128i p3, p2, p1, p0; // loop invariants
|
__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
|
// 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.
|
// re-used for next span. And q2/q3 will become p1/p0 accordingly.
|
||||||
ComplexMask_SSE2(&p1, &p0, &p3, &p2, thresh, ithresh, &mask);
|
ComplexMask(&p1, &p0, &p3, &p2, thresh, ithresh, &mask);
|
||||||
DoFilter4_SSE2(&p1, &p0, &p3, &p2, &mask, hev_thresh);
|
DoFilter4(&p1, &p0, &p3, &p2, &mask, hev_thresh);
|
||||||
|
|
||||||
// Store
|
// Store
|
||||||
_mm_storeu_si128((__m128i*)&b[0 * stride], p1);
|
_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 thresh, int ithresh, int hev_thresh) {
|
||||||
int k;
|
int k;
|
||||||
__m128i p3, p2, p1, p0; // loop invariants
|
__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) {
|
for (k = 3; k > 0; --k) {
|
||||||
__m128i mask, tmp1, tmp2;
|
__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)
|
p += 4; // beginning of q0 (and next span)
|
||||||
|
|
||||||
MAX_DIFF1(p3, p2, p1, p0, mask); // compute partial mask
|
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);
|
MAX_DIFF2(p3, p2, tmp1, tmp2, mask);
|
||||||
|
|
||||||
ComplexMask_SSE2(&p1, &p0, &p3, &p2, thresh, ithresh, &mask);
|
ComplexMask(&p1, &p0, &p3, &p2, thresh, ithresh, &mask);
|
||||||
DoFilter4_SSE2(&p1, &p0, &p3, &p2, &mask, hev_thresh);
|
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
|
// rotate samples
|
||||||
p1 = tmp1;
|
p1 = tmp1;
|
||||||
@ -794,8 +788,8 @@ static void HFilter16i_SSE2(uint8_t* p, int stride,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 8-pixels wide variant, for chroma filtering
|
// 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) {
|
int thresh, int ithresh, int hev_thresh) {
|
||||||
__m128i mask;
|
__m128i mask;
|
||||||
__m128i t1, p2, p1, p0, q0, q1, q2;
|
__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);
|
LOADUV_H_EDGES4(u, v, stride, q0, q1, q2, t1);
|
||||||
MAX_DIFF2(t1, q2, q1, q0, mask);
|
MAX_DIFF2(t1, q2, q1, q0, mask);
|
||||||
|
|
||||||
ComplexMask_SSE2(&p1, &p0, &q0, &q1, thresh, ithresh, &mask);
|
ComplexMask(&p1, &p0, &q0, &q1, thresh, ithresh, &mask);
|
||||||
DoFilter6_SSE2(&p2, &p1, &p0, &q0, &q1, &q2, &mask, hev_thresh);
|
DoFilter6(&p2, &p1, &p0, &q0, &q1, &q2, &mask, hev_thresh);
|
||||||
|
|
||||||
// Store
|
// Store
|
||||||
STOREUV(p2, u, v, -3 * stride);
|
STOREUV(p2, u, v, -3 * stride);
|
||||||
@ -819,28 +813,28 @@ static void VFilter8_SSE2(uint8_t* u, uint8_t* v, int stride,
|
|||||||
STOREUV(q2, u, v, 2 * 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) {
|
int thresh, int ithresh, int hev_thresh) {
|
||||||
__m128i mask;
|
__m128i mask;
|
||||||
__m128i p3, p2, p1, p0, q0, q1, q2, q3;
|
__m128i p3, p2, p1, p0, q0, q1, q2, q3;
|
||||||
|
|
||||||
uint8_t* const tu = u - 4;
|
uint8_t* const tu = u - 4;
|
||||||
uint8_t* const tv = v - 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);
|
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);
|
MAX_DIFF2(q3, q2, q1, q0, mask);
|
||||||
|
|
||||||
ComplexMask_SSE2(&p1, &p0, &q0, &q1, thresh, ithresh, &mask);
|
ComplexMask(&p1, &p0, &q0, &q1, thresh, ithresh, &mask);
|
||||||
DoFilter6_SSE2(&p2, &p1, &p0, &q0, &q1, &q2, &mask, hev_thresh);
|
DoFilter6(&p2, &p1, &p0, &q0, &q1, &q2, &mask, hev_thresh);
|
||||||
|
|
||||||
Store16x4_SSE2(&p3, &p2, &p1, &p0, tu, tv, stride);
|
Store16x4(&p3, &p2, &p1, &p0, tu, tv, stride);
|
||||||
Store16x4_SSE2(&q0, &q1, &q2, &q3, u, v, 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) {
|
int thresh, int ithresh, int hev_thresh) {
|
||||||
__m128i mask;
|
__m128i mask;
|
||||||
__m128i t1, t2, p1, p0, q0, q1;
|
__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);
|
LOADUV_H_EDGES4(u, v, stride, q0, q1, t1, t2);
|
||||||
MAX_DIFF2(t2, t1, q1, q0, mask);
|
MAX_DIFF2(t2, t1, q1, q0, mask);
|
||||||
|
|
||||||
ComplexMask_SSE2(&p1, &p0, &q0, &q1, thresh, ithresh, &mask);
|
ComplexMask(&p1, &p0, &q0, &q1, thresh, ithresh, &mask);
|
||||||
DoFilter4_SSE2(&p1, &p0, &q0, &q1, &mask, hev_thresh);
|
DoFilter4(&p1, &p0, &q0, &q1, &mask, hev_thresh);
|
||||||
|
|
||||||
// Store
|
// Store
|
||||||
STOREUV(p1, u, v, -2 * stride);
|
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);
|
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) {
|
int thresh, int ithresh, int hev_thresh) {
|
||||||
__m128i mask;
|
__m128i mask;
|
||||||
__m128i t1, t2, p1, p0, q0, q1;
|
__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);
|
MAX_DIFF1(t2, t1, p1, p0, mask);
|
||||||
|
|
||||||
u += 4; // beginning of q0
|
u += 4; // beginning of q0
|
||||||
v += 4;
|
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);
|
MAX_DIFF2(t2, t1, q1, q0, mask);
|
||||||
|
|
||||||
ComplexMask_SSE2(&p1, &p0, &q0, &q1, thresh, ithresh, &mask);
|
ComplexMask(&p1, &p0, &q0, &q1, thresh, ithresh, &mask);
|
||||||
DoFilter4_SSE2(&p1, &p0, &q0, &q1, &mask, hev_thresh);
|
DoFilter4(&p1, &p0, &q0, &q1, &mask, hev_thresh);
|
||||||
|
|
||||||
u -= 2; // beginning of p1
|
u -= 2; // beginning of p1
|
||||||
v -= 2;
|
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
|
// where: AC = (a + b + 1) >> 1, BC = (b + c + 1) >> 1
|
||||||
// and ab = a ^ b, bc = b ^ c, lsb = (AC^BC)&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 one = _mm_set1_epi8(1);
|
||||||
const __m128i ABCDEFGH = _mm_loadl_epi64((__m128i*)(dst - BPS - 1));
|
const __m128i ABCDEFGH = _mm_loadl_epi64((__m128i*)(dst - BPS - 1));
|
||||||
const __m128i BCDEFGH0 = _mm_srli_si128(ABCDEFGH, 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 one = _mm_set1_epi8(1);
|
||||||
const __m128i ABCDEFGH = _mm_loadl_epi64((__m128i*)(dst - BPS));
|
const __m128i ABCDEFGH = _mm_loadl_epi64((__m128i*)(dst - BPS));
|
||||||
const __m128i BCDEFGH0 = _mm_srli_si128(ABCDEFGH, 1);
|
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)));
|
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 __m128i one = _mm_set1_epi8(1);
|
||||||
const int I = dst[-1 + 0 * BPS];
|
const int I = dst[-1 + 0 * BPS];
|
||||||
const int J = dst[-1 + 1 * 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);
|
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 one = _mm_set1_epi8(1);
|
||||||
const __m128i ABCDEFGH = _mm_loadl_epi64((__m128i*)(dst - BPS));
|
const __m128i ABCDEFGH = _mm_loadl_epi64((__m128i*)(dst - BPS));
|
||||||
const __m128i BCDEFGH_ = _mm_srli_si128(ABCDEFGH, 1);
|
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;
|
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 one = _mm_set1_epi8(1);
|
||||||
const __m128i XABCD = _mm_loadl_epi64((__m128i*)(dst - BPS - 1));
|
const __m128i XABCD = _mm_loadl_epi64((__m128i*)(dst - BPS - 1));
|
||||||
const __m128i ____XABCD = _mm_slli_si128(XABCD, 4);
|
const __m128i ____XABCD = _mm_slli_si128(XABCD, 4);
|
||||||
@ -1010,7 +1004,7 @@ static void RD4_SSE2(uint8_t* dst) { // Down-right
|
|||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Luma 16x16
|
// 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 uint8_t* top = dst - BPS;
|
||||||
const __m128i zero = _mm_setzero_si128();
|
const __m128i zero = _mm_setzero_si128();
|
||||||
int y;
|
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 TM4(uint8_t* dst) { TrueMotion(dst, 4); }
|
||||||
static void TM8uv_SSE2(uint8_t* dst) { TrueMotion_SSE2(dst, 8); }
|
static void TM8uv(uint8_t* dst) { TrueMotion(dst, 8); }
|
||||||
static void TM16_SSE2(uint8_t* dst) { TrueMotion_SSE2(dst, 16); }
|
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));
|
const __m128i top = _mm_loadu_si128((const __m128i*)(dst - BPS));
|
||||||
int j;
|
int j;
|
||||||
for (j = 0; j < 16; ++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;
|
int j;
|
||||||
for (j = 16; j > 0; --j) {
|
for (j = 16; j > 0; --j) {
|
||||||
const __m128i values = _mm_set1_epi8(dst[-1]);
|
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;
|
int j;
|
||||||
const __m128i values = _mm_set1_epi8(v);
|
const __m128i values = _mm_set1_epi8(v);
|
||||||
for (j = 0; j < 16; ++j) {
|
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 zero = _mm_setzero_si128();
|
||||||
const __m128i top = _mm_loadu_si128((const __m128i*)(dst - BPS));
|
const __m128i top = _mm_loadu_si128((const __m128i*)(dst - BPS));
|
||||||
const __m128i sad8x2 = _mm_sad_epu8(top, zero);
|
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;
|
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 DC = 8;
|
||||||
int j;
|
int j;
|
||||||
for (j = 0; j < 16; ++j) {
|
for (j = 0; j < 16; ++j) {
|
||||||
DC += dst[-1 + j * BPS];
|
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 zero = _mm_setzero_si128();
|
||||||
const __m128i top = _mm_loadu_si128((const __m128i*)(dst - BPS));
|
const __m128i top = _mm_loadu_si128((const __m128i*)(dst - BPS));
|
||||||
const __m128i sad8x2 = _mm_sad_epu8(top, zero);
|
const __m128i sad8x2 = _mm_sad_epu8(top, zero);
|
||||||
// sum the two sads: sad8x2[0:1] + sad8x2[8:9]
|
// sum the two sads: sad8x2[0:1] + sad8x2[8:9]
|
||||||
const __m128i sum = _mm_add_epi16(sad8x2, _mm_shuffle_epi32(sad8x2, 2));
|
const __m128i sum = _mm_add_epi16(sad8x2, _mm_shuffle_epi32(sad8x2, 2));
|
||||||
const int DC = _mm_cvtsi128_si32(sum) + 8;
|
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
|
static void DC16NoTopLeft(uint8_t* dst) { // DC with no top and left samples
|
||||||
Put16_SSE2(0x80, dst);
|
Put16(0x80, dst);
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Chroma
|
// Chroma
|
||||||
|
|
||||||
static void VE8uv_SSE2(uint8_t* dst) { // vertical
|
static void VE8uv(uint8_t* dst) { // vertical
|
||||||
int j;
|
int j;
|
||||||
const __m128i top = _mm_loadl_epi64((const __m128i*)(dst - BPS));
|
const __m128i top = _mm_loadl_epi64((const __m128i*)(dst - BPS));
|
||||||
for (j = 0; j < 8; ++j) {
|
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
|
// 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;
|
int j;
|
||||||
const __m128i values = _mm_set1_epi8(v);
|
const __m128i values = _mm_set1_epi8(v);
|
||||||
for (j = 0; j < 8; ++j) {
|
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 zero = _mm_setzero_si128();
|
||||||
const __m128i top = _mm_loadl_epi64((const __m128i*)(dst - BPS));
|
const __m128i top = _mm_loadl_epi64((const __m128i*)(dst - BPS));
|
||||||
const __m128i sum = _mm_sad_epu8(top, zero);
|
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;
|
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 zero = _mm_setzero_si128();
|
||||||
const __m128i top = _mm_loadl_epi64((const __m128i*)(dst - BPS));
|
const __m128i top = _mm_loadl_epi64((const __m128i*)(dst - BPS));
|
||||||
const __m128i sum = _mm_sad_epu8(top, zero);
|
const __m128i sum = _mm_sad_epu8(top, zero);
|
||||||
const int DC = _mm_cvtsi128_si32(sum) + 4;
|
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 dc0 = 4;
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < 8; ++i) {
|
for (i = 0; i < 8; ++i) {
|
||||||
dc0 += dst[-1 + i * BPS];
|
dc0 += dst[-1 + i * BPS];
|
||||||
}
|
}
|
||||||
Put8x8uv_SSE2(dc0 >> 3, dst);
|
Put8x8uv(dc0 >> 3, dst);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void DC8uvNoTopLeft_SSE2(uint8_t* dst) { // DC with nothing
|
static void DC8uvNoTopLeft(uint8_t* dst) { // DC with nothing
|
||||||
Put8x8uv_SSE2(0x80, dst);
|
Put8x8uv(0x80, dst);
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
@ -1178,46 +1181,47 @@ static void DC8uvNoTopLeft_SSE2(uint8_t* dst) { // DC with nothing
|
|||||||
extern void VP8DspInitSSE2(void);
|
extern void VP8DspInitSSE2(void);
|
||||||
|
|
||||||
WEBP_TSAN_IGNORE_FUNCTION void VP8DspInitSSE2(void) {
|
WEBP_TSAN_IGNORE_FUNCTION void VP8DspInitSSE2(void) {
|
||||||
VP8Transform = Transform_SSE2;
|
VP8Transform = Transform;
|
||||||
#if (USE_TRANSFORM_AC3 == 1)
|
#if defined(USE_TRANSFORM_AC3)
|
||||||
VP8TransformAC3 = TransformAC3_SSE2;
|
VP8TransformAC3 = TransformAC3;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
VP8VFilter16 = VFilter16_SSE2;
|
VP8VFilter16 = VFilter16;
|
||||||
VP8HFilter16 = HFilter16_SSE2;
|
VP8HFilter16 = HFilter16;
|
||||||
VP8VFilter8 = VFilter8_SSE2;
|
VP8VFilter8 = VFilter8;
|
||||||
VP8HFilter8 = HFilter8_SSE2;
|
VP8HFilter8 = HFilter8;
|
||||||
VP8VFilter16i = VFilter16i_SSE2;
|
VP8VFilter16i = VFilter16i;
|
||||||
VP8HFilter16i = HFilter16i_SSE2;
|
VP8HFilter16i = HFilter16i;
|
||||||
VP8VFilter8i = VFilter8i_SSE2;
|
VP8VFilter8i = VFilter8i;
|
||||||
VP8HFilter8i = HFilter8i_SSE2;
|
VP8HFilter8i = HFilter8i;
|
||||||
|
|
||||||
VP8SimpleVFilter16 = SimpleVFilter16_SSE2;
|
VP8SimpleVFilter16 = SimpleVFilter16;
|
||||||
VP8SimpleHFilter16 = SimpleHFilter16_SSE2;
|
VP8SimpleHFilter16 = SimpleHFilter16;
|
||||||
VP8SimpleVFilter16i = SimpleVFilter16i_SSE2;
|
VP8SimpleVFilter16i = SimpleVFilter16i;
|
||||||
VP8SimpleHFilter16i = SimpleHFilter16i_SSE2;
|
VP8SimpleHFilter16i = SimpleHFilter16i;
|
||||||
|
|
||||||
VP8PredLuma4[1] = TM4_SSE2;
|
VP8PredLuma4[1] = TM4;
|
||||||
VP8PredLuma4[2] = VE4_SSE2;
|
VP8PredLuma4[2] = VE4;
|
||||||
VP8PredLuma4[4] = RD4_SSE2;
|
VP8PredLuma4[4] = RD4;
|
||||||
VP8PredLuma4[5] = VR4_SSE2;
|
VP8PredLuma4[5] = VR4;
|
||||||
VP8PredLuma4[6] = LD4_SSE2;
|
VP8PredLuma4[6] = LD4;
|
||||||
VP8PredLuma4[7] = VL4_SSE2;
|
VP8PredLuma4[7] = VL4;
|
||||||
|
|
||||||
VP8PredLuma16[0] = DC16_SSE2;
|
VP8PredLuma16[0] = DC16;
|
||||||
VP8PredLuma16[1] = TM16_SSE2;
|
VP8PredLuma16[1] = TM16;
|
||||||
VP8PredLuma16[2] = VE16_SSE2;
|
VP8PredLuma16[2] = VE16;
|
||||||
VP8PredLuma16[3] = HE16_SSE2;
|
VP8PredLuma16[3] = HE16;
|
||||||
VP8PredLuma16[4] = DC16NoTop_SSE2;
|
VP8PredLuma16[4] = DC16NoTop;
|
||||||
VP8PredLuma16[5] = DC16NoLeft_SSE2;
|
VP8PredLuma16[5] = DC16NoLeft;
|
||||||
VP8PredLuma16[6] = DC16NoTopLeft_SSE2;
|
VP8PredLuma16[6] = DC16NoTopLeft;
|
||||||
|
|
||||||
VP8PredChroma8[0] = DC8uv_SSE2;
|
VP8PredChroma8[0] = DC8uv;
|
||||||
VP8PredChroma8[1] = TM8uv_SSE2;
|
VP8PredChroma8[1] = TM8uv;
|
||||||
VP8PredChroma8[2] = VE8uv_SSE2;
|
VP8PredChroma8[2] = VE8uv;
|
||||||
VP8PredChroma8[4] = DC8uvNoTop_SSE2;
|
VP8PredChroma8[3] = HE8uv;
|
||||||
VP8PredChroma8[5] = DC8uvNoLeft_SSE2;
|
VP8PredChroma8[4] = DC8uvNoTop;
|
||||||
VP8PredChroma8[6] = DC8uvNoTopLeft_SSE2;
|
VP8PredChroma8[5] = DC8uvNoLeft;
|
||||||
|
VP8PredChroma8[6] = DC8uvNoTopLeft;
|
||||||
}
|
}
|
||||||
|
|
||||||
#else // !WEBP_USE_SSE2
|
#else // !WEBP_USE_SSE2
|
||||||
|
@ -11,15 +11,15 @@
|
|||||||
//
|
//
|
||||||
// Author: Skal (pascal.massimino@gmail.com)
|
// Author: Skal (pascal.massimino@gmail.com)
|
||||||
|
|
||||||
#include "src/dsp/dsp.h"
|
#include "./dsp.h"
|
||||||
|
|
||||||
#if defined(WEBP_USE_SSE41)
|
#if defined(WEBP_USE_SSE41)
|
||||||
|
|
||||||
#include <smmintrin.h>
|
#include <smmintrin.h>
|
||||||
#include "src/dec/vp8i_dec.h"
|
#include "../dec/vp8i_dec.h"
|
||||||
#include "src/utils/utils.h"
|
#include "../utils/utils.h"
|
||||||
|
|
||||||
static void HE16_SSE41(uint8_t* dst) { // horizontal
|
static void HE16(uint8_t* dst) { // horizontal
|
||||||
int j;
|
int j;
|
||||||
const __m128i kShuffle3 = _mm_set1_epi8(3);
|
const __m128i kShuffle3 = _mm_set1_epi8(3);
|
||||||
for (j = 16; j > 0; --j) {
|
for (j = 16; j > 0; --j) {
|
||||||
@ -36,7 +36,7 @@ static void HE16_SSE41(uint8_t* dst) { // horizontal
|
|||||||
extern void VP8DspInitSSE41(void);
|
extern void VP8DspInitSSE41(void);
|
||||||
|
|
||||||
WEBP_TSAN_IGNORE_FUNCTION void VP8DspInitSSE41(void) {
|
WEBP_TSAN_IGNORE_FUNCTION void VP8DspInitSSE41(void) {
|
||||||
VP8PredLuma16[3] = HE16_SSE41;
|
VP8PredLuma16[3] = HE16;
|
||||||
}
|
}
|
||||||
|
|
||||||
#else // !WEBP_USE_SSE41
|
#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
132
src/dsp/dsp.h
132
src/dsp/dsp.h
@ -15,10 +15,10 @@
|
|||||||
#define WEBP_DSP_DSP_H_
|
#define WEBP_DSP_DSP_H_
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
#include "src/webp/config.h"
|
#include "../webp/config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "src/webp/types.h"
|
#include "../webp/types.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@ -51,8 +51,9 @@ extern "C" {
|
|||||||
# define __has_builtin(x) 0
|
# define __has_builtin(x) 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// for now, none of the optimizations below are available in emscripten
|
// For now, none of the optimizations below are available in emscripten.
|
||||||
#if !defined(EMSCRIPTEN)
|
// WebAssembly overrides native optimizations.
|
||||||
|
#if !(defined(EMSCRIPTEN) || defined(WEBP_USE_WASM))
|
||||||
|
|
||||||
#if defined(_MSC_VER) && _MSC_VER > 1310 && \
|
#if defined(_MSC_VER) && _MSC_VER > 1310 && \
|
||||||
(defined(_M_X64) || defined(_M_IX86))
|
(defined(_M_X64) || defined(_M_IX86))
|
||||||
@ -104,7 +105,7 @@ extern "C" {
|
|||||||
#define WEBP_USE_MIPS32
|
#define WEBP_USE_MIPS32
|
||||||
#if (__mips_isa_rev >= 2)
|
#if (__mips_isa_rev >= 2)
|
||||||
#define WEBP_USE_MIPS32_R2
|
#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
|
#define WEBP_USE_MIPS_DSP_R2
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
@ -116,22 +117,6 @@ extern "C" {
|
|||||||
|
|
||||||
#endif /* EMSCRIPTEN */
|
#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.
|
// This macro prevents thread_sanitizer from reporting known concurrent writes.
|
||||||
#define WEBP_TSAN_IGNORE_FUNCTION
|
#define WEBP_TSAN_IGNORE_FUNCTION
|
||||||
#if defined(__has_feature)
|
#if defined(__has_feature)
|
||||||
@ -141,42 +126,6 @@ extern "C" {
|
|||||||
#endif
|
#endif
|
||||||
#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_UNDEF
|
||||||
#define WEBP_UBSAN_IGNORE_UNSIGNED_OVERFLOW
|
#define WEBP_UBSAN_IGNORE_UNSIGNED_OVERFLOW
|
||||||
#if defined(__clang__) && defined(__has_attribute)
|
#if defined(__clang__) && defined(__has_attribute)
|
||||||
@ -197,18 +146,6 @@ extern "C" {
|
|||||||
#endif
|
#endif
|
||||||
#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 {
|
typedef enum {
|
||||||
kSSE2,
|
kSSE2,
|
||||||
kSSE3,
|
kSSE3,
|
||||||
@ -219,11 +156,12 @@ typedef enum {
|
|||||||
kNEON,
|
kNEON,
|
||||||
kMIPS32,
|
kMIPS32,
|
||||||
kMIPSdspR2,
|
kMIPSdspR2,
|
||||||
kMSA
|
kMSA,
|
||||||
|
kWASM
|
||||||
} CPUFeature;
|
} CPUFeature;
|
||||||
// returns true if the CPU supports the feature.
|
// returns true if the CPU supports the feature.
|
||||||
typedef int (*VP8CPUInfo)(CPUFeature feature);
|
typedef int (*VP8CPUInfo)(CPUFeature feature);
|
||||||
WEBP_EXTERN VP8CPUInfo VP8GetCPUInfo;
|
WEBP_EXTERN(VP8CPUInfo) VP8GetCPUInfo;
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Init stub generator
|
// Init stub generator
|
||||||
@ -232,7 +170,7 @@ WEBP_EXTERN VP8CPUInfo VP8GetCPUInfo;
|
|||||||
// avoiding a compiler warning.
|
// avoiding a compiler warning.
|
||||||
#define WEBP_DSP_INIT_STUB(func) \
|
#define WEBP_DSP_INIT_STUB(func) \
|
||||||
extern void func(void); \
|
extern void func(void); \
|
||||||
void func(void) {}
|
WEBP_TSAN_IGNORE_FUNCTION void func(void) {}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Encoding
|
// Encoding
|
||||||
@ -351,7 +289,6 @@ typedef double (*VP8SSIMGetClippedFunc)(const uint8_t* src1, int stride1,
|
|||||||
int xo, int yo, // center position
|
int xo, int yo, // center position
|
||||||
int W, int H); // plane dimension
|
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
|
// This version is called with the guarantee that you can load 8 bytes and
|
||||||
// 8 rows at offset src1 and src2
|
// 8 rows at offset src1 and src2
|
||||||
typedef double (*VP8SSIMGetFunc)(const uint8_t* src1, int stride1,
|
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 VP8SSIMGetFunc VP8SSIMGet; // unclipped / unchecked
|
||||||
extern VP8SSIMGetClippedFunc VP8SSIMGetClipped; // with clipping
|
extern VP8SSIMGetClippedFunc VP8SSIMGetClipped; // with clipping
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined(WEBP_DISABLE_STATS)
|
|
||||||
typedef uint32_t (*VP8AccumulateSSEFunc)(const uint8_t* src1,
|
typedef uint32_t (*VP8AccumulateSSEFunc)(const uint8_t* src1,
|
||||||
const uint8_t* src2, int len);
|
const uint8_t* src2, int len);
|
||||||
extern VP8AccumulateSSEFunc VP8AccumulateSSE;
|
extern VP8AccumulateSSEFunc VP8AccumulateSSE;
|
||||||
#endif
|
|
||||||
|
|
||||||
// must be called before using any of the above directly
|
// must be called before using any of the above directly
|
||||||
void VP8SSIMDspInit(void);
|
void VP8SSIMDspInit(void);
|
||||||
@ -546,12 +480,12 @@ extern WebPRescalerExportRowFunc WebPRescalerExportRowExpand;
|
|||||||
extern WebPRescalerExportRowFunc WebPRescalerExportRowShrink;
|
extern WebPRescalerExportRowFunc WebPRescalerExportRowShrink;
|
||||||
|
|
||||||
// Plain-C implementation, as fall-back.
|
// 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);
|
const uint8_t* src);
|
||||||
extern void WebPRescalerImportRowShrink_C(struct WebPRescaler* const wrk,
|
extern void WebPRescalerImportRowShrinkC(struct WebPRescaler* const wrk,
|
||||||
const uint8_t* src);
|
const uint8_t* src);
|
||||||
extern void WebPRescalerExportRowExpand_C(struct WebPRescaler* const wrk);
|
extern void WebPRescalerExportRowExpandC(struct WebPRescaler* const wrk);
|
||||||
extern void WebPRescalerExportRowShrink_C(struct WebPRescaler* const wrk);
|
extern void WebPRescalerExportRowShrinkC(struct WebPRescaler* const wrk);
|
||||||
|
|
||||||
// Main entry calls:
|
// Main entry calls:
|
||||||
extern void WebPRescalerImportRow(struct WebPRescaler* const wrk,
|
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);
|
int width, int num_rows, int inverse);
|
||||||
|
|
||||||
// Plain-C versions, used as fallback by some implementations.
|
// 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);
|
int width, int inverse);
|
||||||
void WebPMultARGBRow_C(uint32_t* const ptr, int width, int inverse);
|
void WebPMultARGBRowC(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);
|
|
||||||
|
|
||||||
// To be called first before using the above.
|
// To be called first before using the above.
|
||||||
void WebPInitAlphaProcessing(void);
|
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
|
// Filter functions
|
||||||
|
|
||||||
|
165
src/dsp/enc.c
165
src/dsp/enc.c
@ -14,18 +14,16 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stdlib.h> // for abs()
|
#include <stdlib.h> // for abs()
|
||||||
|
|
||||||
#include "src/dsp/dsp.h"
|
#include "./dsp.h"
|
||||||
#include "src/enc/vp8i_enc.h"
|
#include "../enc/vp8i_enc.h"
|
||||||
|
|
||||||
static WEBP_INLINE uint8_t clip_8b(int v) {
|
static WEBP_INLINE uint8_t clip_8b(int v) {
|
||||||
return (!(v & ~0xff)) ? v : (v < 0) ? 0 : 255;
|
return (!(v & ~0xff)) ? v : (v < 0) ? 0 : 255;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !WEBP_NEON_OMIT_C_CODE
|
|
||||||
static WEBP_INLINE int clip_max(int v, int max) {
|
static WEBP_INLINE int clip_max(int v, int max) {
|
||||||
return (v > max) ? max : v;
|
return (v > max) ? max : v;
|
||||||
}
|
}
|
||||||
#endif // !WEBP_NEON_OMIT_C_CODE
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Compute susceptibility based on DCT-coeff histograms:
|
// Compute susceptibility based on DCT-coeff histograms:
|
||||||
@ -58,10 +56,9 @@ void VP8SetHistogramData(const int distribution[MAX_COEFF_THRESH + 1],
|
|||||||
histo->last_non_zero = last_non_zero;
|
histo->last_non_zero = last_non_zero;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !WEBP_NEON_OMIT_C_CODE
|
static void CollectHistogram(const uint8_t* ref, const uint8_t* pred,
|
||||||
static void CollectHistogram_C(const uint8_t* ref, const uint8_t* pred,
|
int start_block, int end_block,
|
||||||
int start_block, int end_block,
|
VP8Histogram* const histo) {
|
||||||
VP8Histogram* const histo) {
|
|
||||||
int j;
|
int j;
|
||||||
int distribution[MAX_COEFF_THRESH + 1] = { 0 };
|
int distribution[MAX_COEFF_THRESH + 1] = { 0 };
|
||||||
for (j = start_block; j < end_block; ++j) {
|
for (j = start_block; j < end_block; ++j) {
|
||||||
@ -79,7 +76,6 @@ static void CollectHistogram_C(const uint8_t* ref, const uint8_t* pred,
|
|||||||
}
|
}
|
||||||
VP8SetHistogramData(distribution, histo);
|
VP8SetHistogramData(distribution, histo);
|
||||||
}
|
}
|
||||||
#endif // !WEBP_NEON_OMIT_C_CODE
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// run-time tables (~4k)
|
// run-time tables (~4k)
|
||||||
@ -104,8 +100,6 @@ static WEBP_TSAN_IGNORE_FUNCTION void InitTables(void) {
|
|||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Transforms (Paragraph 14.4)
|
// Transforms (Paragraph 14.4)
|
||||||
|
|
||||||
#if !WEBP_NEON_OMIT_C_CODE
|
|
||||||
|
|
||||||
#define STORE(x, y, v) \
|
#define STORE(x, y, v) \
|
||||||
dst[(x) + (y) * BPS] = clip_8b(ref[(x) + (y) * BPS] + ((v) >> 3))
|
dst[(x) + (y) * BPS] = clip_8b(ref[(x) + (y) * BPS] + ((v) >> 3))
|
||||||
|
|
||||||
@ -146,15 +140,15 @@ 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) {
|
int do_two) {
|
||||||
ITransformOne(ref, in, dst);
|
ITransformOne(ref, in, dst);
|
||||||
if (do_two) {
|
if (do_two) {
|
||||||
ITransformOne(ref + 4, in + 16, dst + 4);
|
ITransformOne(ref + 4, in + 16, dst + 4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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 i;
|
||||||
int tmp[16];
|
int tmp[16];
|
||||||
for (i = 0; i < 4; ++i, src += BPS, ref += BPS) {
|
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);
|
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,
|
static void FTransform2(const uint8_t* src, const uint8_t* ref, int16_t* out) {
|
||||||
int16_t* out) {
|
|
||||||
VP8FTransform(src, ref, out);
|
VP8FTransform(src, ref, out);
|
||||||
VP8FTransform(src + 4, ref + 4, out + 16);
|
VP8FTransform(src + 4, ref + 4, out + 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !WEBP_NEON_OMIT_C_CODE
|
static void FTransformWHT(const int16_t* in, int16_t* out) {
|
||||||
static void FTransformWHT_C(const int16_t* in, int16_t* out) {
|
|
||||||
// input is 12b signed
|
// input is 12b signed
|
||||||
int32_t tmp[16];
|
int32_t tmp[16];
|
||||||
int i;
|
int i;
|
||||||
@ -220,7 +211,6 @@ static void FTransformWHT_C(const int16_t* in, int16_t* out) {
|
|||||||
out[12 + i] = b3 >> 1;
|
out[12 + i] = b3 >> 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif // !WEBP_NEON_OMIT_C_CODE
|
|
||||||
|
|
||||||
#undef MUL
|
#undef MUL
|
||||||
#undef STORE
|
#undef STORE
|
||||||
@ -313,8 +303,8 @@ static WEBP_INLINE void DCMode(uint8_t* dst, const uint8_t* left,
|
|||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Chroma 8x8 prediction (paragraph 12.2)
|
// 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) {
|
const uint8_t* top) {
|
||||||
// U block
|
// U block
|
||||||
DCMode(C8DC8 + dst, left, top, 8, 8, 4);
|
DCMode(C8DC8 + dst, left, top, 8, 8, 4);
|
||||||
VerticalPred(C8VE8 + dst, top, 8);
|
VerticalPred(C8VE8 + dst, top, 8);
|
||||||
@ -333,8 +323,8 @@ static void IntraChromaPreds_C(uint8_t* dst, const uint8_t* left,
|
|||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// luma 16x16 prediction (paragraph 12.3)
|
// 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) {
|
const uint8_t* left, const uint8_t* top) {
|
||||||
DCMode(I16DC16 + dst, left, top, 16, 16, 5);
|
DCMode(I16DC16 + dst, left, top, 16, 16, 5);
|
||||||
VerticalPred(I16VE16 + dst, top, 16);
|
VerticalPred(I16VE16 + dst, top, 16);
|
||||||
HorizontalPred(I16HE16 + dst, left, 16);
|
HorizontalPred(I16HE16 + dst, left, 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
|
// 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]
|
// 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);
|
DC4(I4DC4 + dst, top);
|
||||||
TM4(I4TM4 + dst, top);
|
TM4(I4TM4 + dst, top);
|
||||||
VE4(I4VE4 + dst, top);
|
VE4(I4VE4 + dst, top);
|
||||||
@ -533,7 +523,6 @@ static void Intra4Preds_C(uint8_t* dst, const uint8_t* top) {
|
|||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Metric
|
// Metric
|
||||||
|
|
||||||
#if !WEBP_NEON_OMIT_C_CODE
|
|
||||||
static WEBP_INLINE int GetSSE(const uint8_t* a, const uint8_t* b,
|
static WEBP_INLINE int GetSSE(const uint8_t* a, const uint8_t* b,
|
||||||
int w, int h) {
|
int w, int h) {
|
||||||
int count = 0;
|
int count = 0;
|
||||||
@ -549,21 +538,20 @@ static WEBP_INLINE int GetSSE(const uint8_t* a, const uint8_t* b,
|
|||||||
return count;
|
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);
|
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);
|
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);
|
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);
|
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;
|
int k, x, y;
|
||||||
for (k = 0; k < 4; ++k) {
|
for (k = 0; k < 4; ++k) {
|
||||||
uint32_t avg = 0;
|
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
|
// We try to match the spectral content (weighted) between source and
|
||||||
// reconstructed samples.
|
// reconstructed samples.
|
||||||
|
|
||||||
#if !WEBP_NEON_OMIT_C_CODE
|
|
||||||
// Hadamard transform
|
// Hadamard transform
|
||||||
// Returns the weighted sum of the absolute value of transformed coefficients.
|
// Returns the weighted sum of the absolute value of transformed coefficients.
|
||||||
// w[] contains a row-major 4 by 4 symmetric matrix.
|
// 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;
|
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 uint16_t* const w) {
|
||||||
const int sum1 = TTransform(a, w);
|
const int sum1 = TTransform(a, w);
|
||||||
const int sum2 = TTransform(b, w);
|
const int sum2 = TTransform(b, w);
|
||||||
return abs(sum2 - sum1) >> 5;
|
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) {
|
const uint16_t* const w) {
|
||||||
int D = 0;
|
int D = 0;
|
||||||
int x, y;
|
int x, y;
|
||||||
for (y = 0; y < 16 * BPS; y += 4 * BPS) {
|
for (y = 0; y < 16 * BPS; y += 4 * BPS) {
|
||||||
for (x = 0; x < 16; x += 4) {
|
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;
|
return D;
|
||||||
}
|
}
|
||||||
#endif // !WEBP_NEON_OMIT_C_CODE
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Quantization
|
// Quantization
|
||||||
@ -650,8 +636,8 @@ static const uint8_t kZigzag[16] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Simple quantization
|
// 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) {
|
const VP8Matrix* const mtx) {
|
||||||
int last = -1;
|
int last = -1;
|
||||||
int n;
|
int n;
|
||||||
for (n = 0; n < 16; ++n) {
|
for (n = 0; n < 16; ++n) {
|
||||||
@ -676,15 +662,13 @@ static int QuantizeBlock_C(int16_t in[16], int16_t out[16],
|
|||||||
return (last >= 0);
|
return (last >= 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !WEBP_NEON_OMIT_C_CODE || WEBP_NEON_WORK_AROUND_GCC
|
static int Quantize2Blocks(int16_t in[32], int16_t out[32],
|
||||||
static int Quantize2Blocks_C(int16_t in[32], int16_t out[32],
|
const VP8Matrix* const mtx) {
|
||||||
const VP8Matrix* const mtx) {
|
|
||||||
int nz;
|
int nz;
|
||||||
nz = VP8EncQuantizeBlock(in + 0 * 16, out + 0 * 16, mtx) << 0;
|
nz = VP8EncQuantizeBlock(in + 0 * 16, out + 0 * 16, mtx) << 0;
|
||||||
nz |= VP8EncQuantizeBlock(in + 1 * 16, out + 1 * 16, mtx) << 1;
|
nz |= VP8EncQuantizeBlock(in + 1 * 16, out + 1 * 16, mtx) << 1;
|
||||||
return nz;
|
return nz;
|
||||||
}
|
}
|
||||||
#endif // !WEBP_NEON_OMIT_C_CODE || WEBP_NEON_WORK_AROUND_GCC
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Block copy
|
// 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);
|
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);
|
Copy(src, dst, 16, 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -740,37 +724,36 @@ extern void VP8EncDspInitMIPS32(void);
|
|||||||
extern void VP8EncDspInitMIPSdspR2(void);
|
extern void VP8EncDspInitMIPSdspR2(void);
|
||||||
extern void VP8EncDspInitMSA(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
|
VP8DspInit(); // common inverse transforms
|
||||||
InitTables();
|
InitTables();
|
||||||
|
|
||||||
// default C implementations
|
// default C implementations
|
||||||
#if !WEBP_NEON_OMIT_C_CODE
|
VP8CollectHistogram = CollectHistogram;
|
||||||
VP8ITransform = ITransform_C;
|
VP8ITransform = ITransform;
|
||||||
VP8FTransform = FTransform_C;
|
VP8FTransform = FTransform;
|
||||||
VP8FTransformWHT = FTransformWHT_C;
|
VP8FTransform2 = FTransform2;
|
||||||
VP8TDisto4x4 = Disto4x4_C;
|
VP8FTransformWHT = FTransformWHT;
|
||||||
VP8TDisto16x16 = Disto16x16_C;
|
VP8EncPredLuma4 = Intra4Preds;
|
||||||
VP8CollectHistogram = CollectHistogram_C;
|
VP8EncPredLuma16 = Intra16Preds;
|
||||||
VP8SSE16x16 = SSE16x16_C;
|
VP8EncPredChroma8 = IntraChromaPreds;
|
||||||
VP8SSE16x8 = SSE16x8_C;
|
VP8SSE16x16 = SSE16x16;
|
||||||
VP8SSE8x8 = SSE8x8_C;
|
VP8SSE8x8 = SSE8x8;
|
||||||
VP8SSE4x4 = SSE4x4_C;
|
VP8SSE16x8 = SSE16x8;
|
||||||
#endif
|
VP8SSE4x4 = SSE4x4;
|
||||||
|
VP8TDisto4x4 = Disto4x4;
|
||||||
#if !WEBP_NEON_OMIT_C_CODE || WEBP_NEON_WORK_AROUND_GCC
|
VP8TDisto16x16 = Disto16x16;
|
||||||
VP8EncQuantizeBlock = QuantizeBlock_C;
|
VP8Mean16x4 = Mean16x4;
|
||||||
VP8EncQuantize2Blocks = Quantize2Blocks_C;
|
VP8EncQuantizeBlock = QuantizeBlock;
|
||||||
#endif
|
VP8EncQuantize2Blocks = Quantize2Blocks;
|
||||||
|
VP8EncQuantizeBlockWHT = QuantizeBlock;
|
||||||
VP8FTransform2 = FTransform2_C;
|
VP8Copy4x4 = Copy4x4;
|
||||||
VP8EncPredLuma4 = Intra4Preds_C;
|
VP8Copy16x8 = Copy16x8;
|
||||||
VP8EncPredLuma16 = Intra16Preds_C;
|
|
||||||
VP8EncPredChroma8 = IntraChromaPreds_C;
|
|
||||||
VP8Mean16x4 = Mean16x4_C;
|
|
||||||
VP8EncQuantizeBlockWHT = QuantizeBlock_C;
|
|
||||||
VP8Copy4x4 = Copy4x4_C;
|
|
||||||
VP8Copy16x8 = Copy16x8_C;
|
|
||||||
|
|
||||||
// If defined, use CPUInfo() to overwrite some pointers with faster versions.
|
// If defined, use CPUInfo() to overwrite some pointers with faster versions.
|
||||||
if (VP8GetCPUInfo != NULL) {
|
if (VP8GetCPUInfo != NULL) {
|
||||||
@ -789,6 +772,11 @@ WEBP_DSP_INIT_FUNC(VP8EncDspInit) {
|
|||||||
VP8EncDspInitAVX2();
|
VP8EncDspInitAVX2();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#if defined(WEBP_USE_NEON)
|
||||||
|
if (VP8GetCPUInfo(kNEON)) {
|
||||||
|
VP8EncDspInitNEON();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
#if defined(WEBP_USE_MIPS32)
|
#if defined(WEBP_USE_MIPS32)
|
||||||
if (VP8GetCPUInfo(kMIPS32)) {
|
if (VP8GetCPUInfo(kMIPS32)) {
|
||||||
VP8EncDspInitMIPS32();
|
VP8EncDspInitMIPS32();
|
||||||
@ -805,32 +793,5 @@ WEBP_DSP_INIT_FUNC(VP8EncDspInit) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
enc_last_cpuinfo_used = VP8GetCPUInfo;
|
||||||
#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);
|
|
||||||
}
|
}
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user