Compare commits

..

1 Commits

Author SHA1 Message Date
James Zern
86c756929c rescaler_mips32: disable ImportRowShrink
this function is failing the 'accum == 0' assert on skia bots for
rescaling to 13x13

BUG=skia:6682

Change-Id: I9f9f3adf28cec63ad6e38ed3128f18825d5b70cc
2017-06-02 19:58:33 -07:00
233 changed files with 6738 additions and 12267 deletions

View File

@ -11,24 +11,12 @@ ifeq ($(APP_OPTIM),release)
endif endif
endif endif
# mips32 fails to build with clang from r14b
# https://bugs.chromium.org/p/webp/issues/detail?id=343
ifeq ($(findstring clang,$(NDK_TOOLCHAIN_VERSION)),clang)
ifeq ($(TARGET_ARCH),mips)
clang_version := $(shell $(TARGET_CC) --version)
ifneq ($(findstring clang version 3,$(clang_version)),)
WEBP_CFLAGS += -no-integrated-as
endif
endif
endif
ifneq ($(findstring armeabi-v7a, $(TARGET_ARCH_ABI)),) ifneq ($(findstring armeabi-v7a, $(TARGET_ARCH_ABI)),)
# Setting LOCAL_ARM_NEON will enable -mfpu=neon which may cause illegal # Setting LOCAL_ARM_NEON will enable -mfpu=neon which may cause illegal
# instructions to be generated for armv7a code. Instead target the neon code # instructions to be generated for armv7a code. Instead target the neon code
# specifically. # specifically.
NEON := c.neon NEON := c.neon
USE_CPUFEATURES := yes USE_CPUFEATURES := yes
WEBP_CFLAGS += -DHAVE_CPU_FEATURES_H
else else
NEON := c NEON := c
endif endif
@ -55,6 +43,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 +76,10 @@ 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_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 \
@ -113,16 +101,14 @@ dsp_enc_srcs := \
src/dsp/lossless_enc_neon.$(NEON) \ src/dsp/lossless_enc_neon.$(NEON) \
src/dsp/lossless_enc_sse2.c \ src/dsp/lossless_enc_sse2.c \
src/dsp/lossless_enc_sse41.c \ src/dsp/lossless_enc_sse41.c \
src/dsp/ssim.c \
src/dsp/ssim_sse2.c \
enc_srcs := \ enc_srcs := \
src/enc/alpha_enc.c \ src/enc/alpha_enc.c \
src/enc/analysis_enc.c \ src/enc/analysis_enc.c \
src/enc/backward_references_cost_enc.c \
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 \

View File

@ -1,39 +1,30 @@
cmake_minimum_required(VERSION 3.5) cmake_minimum_required(VERSION 2.8.7)
project(WebP C) project(libwebp C)
# Options for coder / decoder executables. # Options for coder / decoder executables.
option(WEBP_ENABLE_SIMD "Enable any SIMD optimization." ON) option(WEBP_BUILD_CWEBP "Build the cwebp command line tool." OFF)
option(WEBP_BUILD_CWEBP "Build the cwebp command line tool." ON) option(WEBP_BUILD_DWEBP "Build the dwebp command line tool." OFF)
option(WEBP_BUILD_DWEBP "Build the dwebp command line tool." ON) option(WEBP_BUILD_GIF2WEBP "Build the gif2webp conversion tool." OFF)
option(WEBP_BUILD_GIF2WEBP "Build the gif2webp conversion tool." ON) option(WEBP_BUILD_IMG2WEBP "Build the img2webp animation tool." OFF)
option(WEBP_BUILD_IMG2WEBP "Build the img2webp animation tool." ON) option(WEBP_EXPERIMENTAL_FEATURES "Build with experimental features." OFF)
option(WEBP_BUILD_WEBPINFO "Build the webpinfo command line tool." ON)
option(WEBP_BUILD_WEBP_JS "Emscripten build of webp.js." OFF)
option(WEBP_NEAR_LOSSLESS "Enable near-lossless encoding" ON)
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)
set(WEBP_ENABLE_SIMD OFF)
endif()
set(WEBP_DEP_LIBRARIES) set(WEBP_DEP_LIBRARIES)
set(WEBP_DEP_INCLUDE_DIRS) set(WEBP_DEP_INCLUDE_DIRS)
if(NOT CMAKE_BUILD_TYPE) if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "Release" CACHE set(CMAKE_BUILD_TYPE "Release" CACHE
"Build type: Release, Debug, MinSizeRel or RelWithDebInfo" STRING FORCE "Build type: Release, Debug or RelWithDebInfo" STRING FORCE
) )
endif() endif()
# Include dependencies. include(cmake/config.h.cmake)
include(cmake/deps.cmake)
include(GNUInstallDirs)
################################################################################ ################################################################################
# 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() endif()
################################################################################ ################################################################################
@ -48,173 +39,48 @@ 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)
set(HAVE_CPU_FEATURES_H 1)
else()
set(HAVE_CPU_FEATURES_H 0)
endif() endif()
################################################################################ ################################################################################
# WebP source files. # WebP source files.
# Read the Makefile.am to get the source files. # Read the Makefile.am to get the source files.
# We expect the Makefiles to define the sources as defined in function(parse_Makefile_am FOLDER VAR)
# the first regex. E.g.:
# libimagedec_la_SOURCES = image_dec.c image_dec.h
function(parse_Makefile_am FOLDER VAR SRC_REGEX)
file(READ ${FOLDER}/Makefile.am MAKEFILE_AM) file(READ ${FOLDER}/Makefile.am MAKEFILE_AM)
string(REGEX MATCHALL "${SRC_REGEX}_SOURCES[ ]*\\+?=[ ]+[0-9a-z\\._ ]*" string(REGEX MATCHALL "_SOURCES \\+= [^\n]*"
FILES_PER_LINE ${MAKEFILE_AM} FILES_PER_LINE ${MAKEFILE_AM}
) )
set(SRCS ${${VAR}}) set(SRCS ${${VAR}})
foreach(FILES ${FILES_PER_LINE}) foreach(FILES ${FILES_PER_LINE})
string(FIND ${FILES} "=" OFFSET) string(SUBSTRING ${FILES} 12 -1 FILES)
math(EXPR OFFSET "${OFFSET} + 2")
string(SUBSTRING ${FILES} ${OFFSET} -1 FILES)
if(FILES)
string(REGEX MATCHALL "[0-9a-z\\._]+" string(REGEX MATCHALL "[0-9a-z\\._]+"
FILES ${FILES} FILES ${FILES}
) )
foreach(FILE ${FILES}) foreach(FILE ${FILES})
list(APPEND SRCS ${FOLDER}/${FILE}) list(APPEND SRCS ${FOLDER}/${FILE})
endforeach() endforeach()
endif()
endforeach() endforeach()
set(${VAR} ${SRCS} PARENT_SCOPE) set(${VAR} ${SRCS} PARENT_SCOPE)
endfunction() endfunction()
set(WEBP_SRC_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src) set(WEBP_SRCS)
parse_Makefile_am(${WEBP_SRC_DIR}/dec "WEBP_DEC_SRCS" "") parse_Makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/src/dec "WEBP_SRCS")
parse_Makefile_am(${WEBP_SRC_DIR}/demux "WEBP_DEMUX_SRCS" "") parse_Makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/src/demux "WEBP_SRCS")
parse_Makefile_am(${WEBP_SRC_DIR}/dsp "WEBP_DSP_COMMON_SRCS" "COMMON") parse_Makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/src/dsp "WEBP_SRCS")
parse_Makefile_am(${WEBP_SRC_DIR}/dsp "WEBP_DSP_ENC_SRCS" "ENC") parse_Makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/src/enc "WEBP_SRCS")
parse_Makefile_am(${WEBP_SRC_DIR}/dsp "WEBP_DSP_ENC_SRCS" "dsp_[^ ]*") parse_Makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/src/utils "WEBP_SRCS")
parse_Makefile_am(${WEBP_SRC_DIR}/dsp "WEBP_DSP_DEC_SRCS" "decode_[^ ]*")
parse_Makefile_am(${WEBP_SRC_DIR}/enc "WEBP_ENC_SRCS" "")
parse_Makefile_am(${WEBP_SRC_DIR}/utils "WEBP_UTILS_COMMON_SRCS" "COMMON")
parse_Makefile_am(${WEBP_SRC_DIR}/utils "WEBP_UTILS_ENC_SRCS" "ENC")
parse_Makefile_am(${WEBP_SRC_DIR}/utils "WEBP_UTILS_DEC_SRCS" "decode_[^ ]*")
# Remove the files specific to SIMD we don't use. # Remove the files specific to SIMD we don't use.
foreach(FILE ${WEBP_SIMD_FILES_NOT_TO_INCLUDE}) foreach(FILE ${WEBP_SIMD_FILES_NOT_TO_INCLUDE})
list(REMOVE_ITEM WEBP_DSP_ENC_SRCS ${FILE}) list(REMOVE_ITEM WEBP_SRCS ${FILE})
list(REMOVE_ITEM WEBP_DSP_DEC_SRCS ${FILE})
endforeach() endforeach()
# Generate the config.h file. # Build the library.
configure_file(${CMAKE_CURRENT_LIST_DIR}/cmake/config.h.in
${CMAKE_CURRENT_BINARY_DIR}/src/webp/config.h)
add_definitions(-DHAVE_CONFIG_H)
### Define the mandatory libraries.
# Build the webpdecoder library.
if(MSVC)
# avoid security warnings for e.g., fopen() used in the examples.
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
else()
add_definitions(-Wall) add_definitions(-Wall)
endif() include_directories(${CMAKE_CURRENT_SOURCE_DIR}/src/ ${WEBP_DEP_INCLUDE_DIRS})
include_directories(${WEBP_DEP_INCLUDE_DIRS}) add_library(webp ${WEBP_SRCS})
add_library(webpdecode OBJECT ${WEBP_DEC_SRCS})
target_include_directories(webpdecode PRIVATE ${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_CURRENT_SOURCE_DIR}
)
add_library(webpdspdecode OBJECT ${WEBP_DSP_COMMON_SRCS} ${WEBP_DSP_DEC_SRCS})
target_include_directories(webpdspdecode PRIVATE ${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_CURRENT_SOURCE_DIR}
)
add_library(webputilsdecode OBJECT ${WEBP_UTILS_COMMON_SRCS}
${WEBP_UTILS_DEC_SRCS}
)
target_include_directories(webputilsdecode PRIVATE ${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_CURRENT_SOURCE_DIR}
)
add_library(webpdecoder $<TARGET_OBJECTS:webpdecode>
$<TARGET_OBJECTS:webpdspdecode> $<TARGET_OBJECTS:webputilsdecode>)
target_link_libraries(webpdecoder ${WEBP_DEP_LIBRARIES})
target_include_directories(webpdecoder
PRIVATE ${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_CURRENT_SOURCE_DIR}
INTERFACE $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
)
set_target_properties(webpdecoder PROPERTIES PUBLIC_HEADER
"${CMAKE_CURRENT_SOURCE_DIR}/src/webp/decode.h;\
${CMAKE_CURRENT_SOURCE_DIR}/src/webp/types.h"
)
# Build the webp library.
add_library(webpencode OBJECT ${WEBP_ENC_SRCS})
target_include_directories(webpencode PRIVATE ${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_CURRENT_SOURCE_DIR}
)
add_library(webpdsp OBJECT ${WEBP_DSP_COMMON_SRCS} ${WEBP_DSP_DEC_SRCS}
${WEBP_DSP_ENC_SRCS})
target_include_directories(webpdsp PRIVATE ${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_CURRENT_SOURCE_DIR}
)
add_library(webputils OBJECT ${WEBP_UTILS_COMMON_SRCS} ${WEBP_UTILS_DEC_SRCS}
${WEBP_UTILS_ENC_SRCS})
target_include_directories(webputils PRIVATE ${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_CURRENT_SOURCE_DIR}
)
add_library(webp $<TARGET_OBJECTS:webpdecode> $<TARGET_OBJECTS:webpdsp>
$<TARGET_OBJECTS:webpencode> $<TARGET_OBJECTS:webputils>)
target_link_libraries(webp ${WEBP_DEP_LIBRARIES}) target_link_libraries(webp ${WEBP_DEP_LIBRARIES})
target_include_directories(webp
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_BINARY_DIR}
PUBLIC $<INSTALL_INTERFACE:include>
)
set_target_properties(webp PROPERTIES PUBLIC_HEADER
"${CMAKE_CURRENT_SOURCE_DIR}/src/webp/decode.h;\
${CMAKE_CURRENT_SOURCE_DIR}/src/webp/encode.h;\
${CMAKE_CURRENT_SOURCE_DIR}/src/webp/types.h"
)
# Make sure the OBJECT libraries are built with position independent code
# (it is not ON by default).
set_target_properties(webpdecode webpdspdecode webputilsdecode
webpencode webpdsp webputils PROPERTIES POSITION_INDEPENDENT_CODE ON)
# Build the webp demux library.
add_library(webpdemux ${WEBP_DEMUX_SRCS})
target_link_libraries(webpdemux webp)
target_include_directories(webpdemux
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_BINARY_DIR}
PUBLIC $<INSTALL_INTERFACE:include>
)
set_target_properties(webpdemux PROPERTIES PUBLIC_HEADER
"${CMAKE_CURRENT_SOURCE_DIR}/src/webp/decode.h;\
${CMAKE_CURRENT_SOURCE_DIR}/src/webp/demux.h;\
${CMAKE_CURRENT_SOURCE_DIR}/src/webp/mux_types.h;\
${CMAKE_CURRENT_SOURCE_DIR}/src/webp/types.h"
)
# Set the version numbers.
function(parse_version FILE NAME VAR)
file(READ ${CMAKE_CURRENT_SOURCE_DIR}/src/${FILE} SOURCE_FILE)
string(REGEX MATCH "${NAME}_la_LDFLAGS[^\n]* -version-info [0-9:]+" TMP
${SOURCE_FILE})
string(REGEX MATCH "[0-9:]+" TMP ${TMP})
string(REGEX REPLACE ":" "." VERSION ${TMP})
set(${VAR} "${VERSION}" PARENT_SCOPE)
endfunction()
parse_version(Makefile.am webp WEBP_WEBP_SOVERSION)
set_target_properties(webp PROPERTIES VERSION ${PACKAGE_VERSION}
SOVERSION ${WEBP_WEBP_SOVERSION})
parse_version(Makefile.am webpdecoder WEBP_DECODER_SOVERSION)
set_target_properties(webpdecoder PROPERTIES VERSION ${PACKAGE_VERSION}
SOVERSION ${WEBP_DECODER_SOVERSION})
parse_version(demux/Makefile.am webpdemux WEBP_DEMUX_SOVERSION)
set_target_properties(webpdemux PROPERTIES VERSION ${PACKAGE_VERSION}
SOVERSION ${WEBP_DEMUX_SOVERSION})
# Define the libraries to install.
set(INSTALLED_LIBRARIES webpdecoder webp webpdemux)
### Deal with SIMD.
# Change the compile flags for SIMD files we use. # Change the compile flags for SIMD files we use.
list(LENGTH WEBP_SIMD_FILES_TO_INCLUDE WEBP_SIMD_FILES_TO_INCLUDE_LENGTH) list(LENGTH WEBP_SIMD_FILES_TO_INCLUDE WEBP_SIMD_FILES_TO_INCLUDE_LENGTH)
math(EXPR WEBP_SIMD_FILES_TO_INCLUDE_RANGE math(EXPR WEBP_SIMD_FILES_TO_INCLUDE_RANGE
@ -231,195 +97,93 @@ endforeach()
# Build the executables if asked for. # Build the executables if asked for.
if(WEBP_BUILD_CWEBP OR WEBP_BUILD_DWEBP OR if(WEBP_BUILD_CWEBP OR WEBP_BUILD_DWEBP OR
WEBP_BUILD_GIF2WEBP OR WEBP_BUILD_IMG2WEBP OR WEBP_BUILD_WEBP_JS) WEBP_BUILD_GIF2WEBP OR WEBP_BUILD_IMG2WEBP)
# Example utility library. # Example utility library.
parse_Makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/examples "EXAMPLEUTIL_SRCS" set(exampleutil_SRCS
"example_util_[^ ]*") ${CMAKE_CURRENT_SOURCE_DIR}/examples/stopwatch.h
list(APPEND EXAMPLEUTIL_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/examples/example_util.c
${CMAKE_CURRENT_SOURCE_DIR}/examples/stopwatch.h) ${CMAKE_CURRENT_SOURCE_DIR}/examples/example_util.h)
add_library(exampleutil ${EXAMPLEUTIL_SRCS}) add_library(exampleutil ${exampleutil_SRCS})
target_include_directories(exampleutil target_link_libraries(exampleutil webp ${WEBP_DEP_LIBRARIES})
PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>)
parse_Makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/imageio "IMAGEIOUTILS_SRCS" set(imageioutil_SRCS
"imageio_util_[^ ]*") ${CMAKE_CURRENT_SOURCE_DIR}/imageio/imageio_util.c
add_library(imageioutil ${IMAGEIOUTILS_SRCS}) ${CMAKE_CURRENT_SOURCE_DIR}/imageio/imageio_util.h)
target_link_libraries(imageioutil webp) add_library(imageioutil ${imageioutil_SRCS})
target_link_libraries(imageioutil ${WEBP_DEP_LIBRARIES})
# Image-decoding utility library. # Image-decoding utility library.
parse_Makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/imageio "IMAGEDEC_SRCS" set(imagedec_SRCS
"imagedec_[^ ]*") ${CMAKE_CURRENT_SOURCE_DIR}/examples/gifdec.c
add_library(imagedec ${IMAGEDEC_SRCS}) ${CMAKE_CURRENT_SOURCE_DIR}/examples/gifdec.h
target_link_libraries(imagedec imageioutil webpdemux webp ${CMAKE_CURRENT_SOURCE_DIR}/imageio/image_dec.c
${CMAKE_CURRENT_SOURCE_DIR}/imageio/image_dec.h
${CMAKE_CURRENT_SOURCE_DIR}/imageio/jpegdec.c
${CMAKE_CURRENT_SOURCE_DIR}/imageio/jpegdec.h
${CMAKE_CURRENT_SOURCE_DIR}/imageio/metadata.c
${CMAKE_CURRENT_SOURCE_DIR}/imageio/metadata.h
${CMAKE_CURRENT_SOURCE_DIR}/imageio/pngdec.c
${CMAKE_CURRENT_SOURCE_DIR}/imageio/pngdec.h
${CMAKE_CURRENT_SOURCE_DIR}/imageio/tiffdec.c
${CMAKE_CURRENT_SOURCE_DIR}/imageio/tiffdec.h
${CMAKE_CURRENT_SOURCE_DIR}/imageio/webpdec.c
${CMAKE_CURRENT_SOURCE_DIR}/imageio/webpdec.h
${CMAKE_CURRENT_SOURCE_DIR}/imageio/wicdec.c
${CMAKE_CURRENT_SOURCE_DIR}/imageio/wicdec.h)
add_library(imagedec ${imagedec_SRCS})
target_link_libraries(imagedec webp ${WEBP_DEP_LIBRARIES}
${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" set(imageenc_SRCS
"imageenc_[^ ]*") ${CMAKE_CURRENT_SOURCE_DIR}/imageio/image_enc.c
add_library(imageenc ${IMAGEENC_SRCS}) ${CMAKE_CURRENT_SOURCE_DIR}/imageio/image_enc.h)
target_link_libraries(imageenc webp) add_library(imageenc ${imageenc_SRCS})
target_link_libraries(imageenc webp imageioutil
set_property(TARGET exampleutil imageioutil imagedec imageenc ${WEBP_DEP_LIBRARIES} ${WEBP_DEP_IMG_LIBRARIES})
PROPERTY INCLUDE_DIRECTORIES
${CMAKE_CURRENT_SOURCE_DIR}/src ${CMAKE_CURRENT_BINARY_DIR}/src)
endif() endif()
if(WEBP_BUILD_DWEBP) if(WEBP_BUILD_DWEBP)
# dwebp # dwebp
parse_Makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/examples "DWEBP_SRCS" include_directories(${WEBP_DEP_IMG_INCLUDE_DIRS})
"dwebp") add_executable(dwebp
add_executable(dwebp ${DWEBP_SRCS}) ${CMAKE_CURRENT_SOURCE_DIR}/examples/dwebp.c
target_link_libraries(dwebp exampleutil imagedec imageenc) ${CMAKE_CURRENT_SOURCE_DIR}/examples/stopwatch.h)
target_include_directories(dwebp PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/src) target_link_libraries(dwebp imagedec imageenc webp
install(TARGETS dwebp RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) exampleutil imageioutil
${WEBP_DEP_LIBRARIES} ${WEBP_DEP_IMG_LIBRARIES}
)
endif() endif()
if(WEBP_BUILD_CWEBP) if(WEBP_BUILD_CWEBP)
# cwebp # cwebp
parse_Makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/examples "CWEBP_SRCS" include_directories(${WEBP_DEP_IMG_INCLUDE_DIRS})
"cwebp") add_executable(cwebp
add_executable(cwebp ${CWEBP_SRCS}) ${CMAKE_CURRENT_SOURCE_DIR}/examples/cwebp.c
target_link_libraries(cwebp exampleutil imagedec webp) ${CMAKE_CURRENT_SOURCE_DIR}/examples/stopwatch.h)
target_include_directories(cwebp PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/src) target_link_libraries(cwebp imagedec webp exampleutil imageioutil
install(TARGETS cwebp RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) ${WEBP_DEP_LIBRARIES} ${WEBP_DEP_IMG_LIBRARIES}
endif()
if(WEBP_BUILD_GIF2WEBP AND NOT GIF_FOUND)
unset(WEBP_BUILD_GIF2WEBP CACHE)
endif()
if(WEBP_BUILD_GIF2WEBP OR WEBP_BUILD_IMG2WEBP)
parse_Makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/src/mux "WEBP_MUX_SRCS"
"")
add_library(webpmux ${WEBP_MUX_SRCS})
target_link_libraries(webpmux webp)
target_include_directories(webpmux
PRIVATE ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR})
parse_version(mux/Makefile.am webpmux WEBP_MUX_SOVERSION)
set_target_properties(webpmux PROPERTIES VERSION ${PACKAGE_VERSION}
SOVERSION ${WEBP_MUX_SOVERSION})
set_target_properties(webpmux PROPERTIES PUBLIC_HEADER
"${CMAKE_CURRENT_SOURCE_DIR}/src/webp/mux.h;\
${CMAKE_CURRENT_SOURCE_DIR}/src/webp/mux_types.h;\
${CMAKE_CURRENT_SOURCE_DIR}/src/webp/types.h;"
) )
list(APPEND INSTALLED_LIBRARIES webpmux)
endif() endif()
if(WEBP_BUILD_GIF2WEBP) if(WEBP_BUILD_GIF2WEBP)
# gif2webp # gif2webp
include_directories(${WEBP_DEP_GIF_INCLUDE_DIRS}) include_directories(${WEBP_DEP_IMG_INCLUDE_DIRS})
parse_Makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/examples "GIF2WEBP_SRCS" set(GIF2WEBP_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/examples/gif2webp.c)
"gif2webp") parse_Makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/src/mux "GIF2WEBP_SRCS")
add_executable(gif2webp ${GIF2WEBP_SRCS}) add_executable(gif2webp ${GIF2WEBP_SRCS})
target_link_libraries(gif2webp exampleutil imageioutil webp webpmux target_link_libraries(gif2webp imagedec webp exampleutil imageioutil
${WEBP_DEP_GIF_LIBRARIES}) ${WEBP_DEP_LIBRARIES} ${WEBP_DEP_IMG_LIBRARIES}
target_include_directories(gif2webp PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/src) )
install(TARGETS gif2webp RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
endif() endif()
if(WEBP_BUILD_IMG2WEBP) if(WEBP_BUILD_IMG2WEBP)
# img2webp # img2webp
include_directories(${WEBP_DEP_IMG_INCLUDE_DIRS}) include_directories(${WEBP_DEP_IMG_INCLUDE_DIRS})
parse_Makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/examples "IMG2WEBP_SRCS" set(IMG2WEBP_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/examples/img2webp.c)
"img2webp") parse_Makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/src/mux "IMG2WEBP_SRCS")
add_executable(img2webp ${IMG2WEBP_SRCS}) add_executable(img2webp ${IMG2WEBP_SRCS})
target_link_libraries(img2webp exampleutil imagedec imageioutil webp webpmux) target_link_libraries(img2webp imagedec webp exampleutil imageioutil
target_include_directories(img2webp PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/src) ${WEBP_DEP_LIBRARIES} ${WEBP_DEP_IMG_LIBRARIES}
install(TARGETS img2webp RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
endif()
if (WEBP_BUILD_WEBPINFO)
# webpinfo
include_directories(${WEBP_DEP_IMG_INCLUDE_DIRS})
parse_Makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/examples "WEBPINFO_SRCS"
"webpinfo")
add_executable(webpinfo ${WEBPINFO_SRCS})
target_link_libraries(webpinfo exampleutil imageioutil)
target_include_directories(webpinfo PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/src)
install(TARGETS webpinfo RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
endif()
if(WEBP_BUILD_WEBP_JS)
# JavaScript version
add_executable(webp_js ${CMAKE_CURRENT_SOURCE_DIR}/extras/webp_to_sdl.c)
target_link_libraries(webp_js webpdecoder SDL)
target_include_directories(webp_js PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
set(WEBP_HAVE_SDL 1)
set_target_properties(webp_js PROPERTIES LINK_FLAGS
"-s EXPORTED_FUNCTIONS='[\"_WebpToSDL\"]' -s INVOKE_RUN=0 \
-s EXTRA_EXPORTED_RUNTIME_METHODS='[\"cwrap\"]'")
set_target_properties(webp_js PROPERTIES OUTPUT_NAME webp)
target_compile_definitions(webp_js PUBLIC EMSCRIPTEN WEBP_HAVE_SDL)
# WASM version
add_executable(webp_wasm ${CMAKE_CURRENT_SOURCE_DIR}/extras/webp_to_sdl.c)
target_link_libraries(webp_wasm webpdecoder SDL)
target_include_directories(webp_wasm PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
set_target_properties(webp_wasm PROPERTIES LINK_FLAGS
"-s WASM=1 -s 'BINARYEN_METHOD=\"native-wasm\"' \
-s EXPORTED_FUNCTIONS='[\"_WebpToSDL\"]' -s INVOKE_RUN=0 \
-s EXTRA_EXPORTED_RUNTIME_METHODS='[\"cwrap\"]'")
target_compile_definitions(webp_wasm PUBLIC EMSCRIPTEN WEBP_HAVE_SDL)
target_compile_definitions(webpdspdecode PUBLIC EMSCRIPTEN)
endif()
# Install the different headers and libraries.
include(GNUInstallDirs)
install(
TARGETS ${INSTALLED_LIBRARIES}
EXPORT ${PROJECT_NAME}Targets
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/webp
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)
set(ConfigPackageLocation ${CMAKE_INSTALL_DATADIR}/${PROJECT_NAME}/cmake/)
install(EXPORT ${PROJECT_NAME}Targets
NAMESPACE ${PROJECT_NAME}::
DESTINATION ${ConfigPackageLocation}
)
# Create the CMake version file.
include(CMakePackageConfigHelpers)
write_basic_package_version_file(
"${CMAKE_CURRENT_BINARY_DIR}/WebPConfigVersion.cmake"
VERSION ${PACKAGE_VERSION}
COMPATIBILITY AnyNewerVersion
)
# Create the Config file.
include(CMakePackageConfigHelpers)
configure_package_config_file(
${CMAKE_CURRENT_SOURCE_DIR}/cmake/WebPConfig.cmake.in
${CMAKE_CURRENT_BINARY_DIR}/WebPConfig.cmake
INSTALL_DESTINATION ${ConfigPackageLocation}
)
# Install the generated CMake files.
install(
FILES "${CMAKE_CURRENT_BINARY_DIR}/WebPConfigVersion.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/WebPConfig.cmake"
DESTINATION ${ConfigPackageLocation}
)
# Install the man pages.
set(MAN_PAGES cwebp.1 dwebp.1 gif2webp.1 img2webp.1 vwebp.1 webpmux.1
webpinfo.1)
set(EXEC_BUILDS "CWEBP" "DWEBP" "GIF2WEBP" "IMG2WEBP" "VWEBP" "WEBPMUX"
"WEBPINFO")
list(LENGTH MAN_PAGES MAN_PAGES_LENGTH)
math(EXPR MAN_PAGES_RANGE "${MAN_PAGES_LENGTH} - 1")
foreach(I_MAN RANGE ${MAN_PAGES_RANGE})
list(GET EXEC_BUILDS ${I_MAN} EXEC_BUILD)
if(WEBP_BUILD_${EXEC_BUILD})
list(GET MAN_PAGES ${I_MAN} MAN_PAGE)
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/man/${MAN_PAGE}
DESTINATION ${CMAKE_INSTALL_MANDIR}/man1
COMPONENT doc
) )
endif() endif()
endforeach()

285
ChangeLog
View File

@ -1,294 +1,9 @@
f66955de 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
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)

View File

@ -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,15 @@ 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_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 \
@ -255,8 +254,6 @@ DSP_ENC_OBJS = \
$(DIROBJ)\dsp\lossless_enc_neon.obj \ $(DIROBJ)\dsp\lossless_enc_neon.obj \
$(DIROBJ)\dsp\lossless_enc_sse2.obj \ $(DIROBJ)\dsp\lossless_enc_sse2.obj \
$(DIROBJ)\dsp\lossless_enc_sse41.obj \ $(DIROBJ)\dsp\lossless_enc_sse41.obj \
$(DIROBJ)\dsp\ssim.obj \
$(DIROBJ)\dsp\ssim_sse2.obj \
EX_ANIM_UTIL_OBJS = \ EX_ANIM_UTIL_OBJS = \
$(DIROBJ)\examples\anim_util.obj \ $(DIROBJ)\examples\anim_util.obj \
@ -266,7 +263,6 @@ IMAGEIO_DEC_OBJS = \
$(DIROBJ)\imageio\jpegdec.obj \ $(DIROBJ)\imageio\jpegdec.obj \
$(DIROBJ)\imageio\metadata.obj \ $(DIROBJ)\imageio\metadata.obj \
$(DIROBJ)\imageio\pngdec.obj \ $(DIROBJ)\imageio\pngdec.obj \
$(DIROBJ)\imageio\pnmdec.obj \
$(DIROBJ)\imageio\tiffdec.obj \ $(DIROBJ)\imageio\tiffdec.obj \
$(DIROBJ)\imageio\webpdec.obj \ $(DIROBJ)\imageio\webpdec.obj \
$(DIROBJ)\imageio\wicdec.obj \ $(DIROBJ)\imageio\wicdec.obj \
@ -283,10 +279,10 @@ EX_UTIL_OBJS = \
ENC_OBJS = \ ENC_OBJS = \
$(DIROBJ)\enc\alpha_enc.obj \ $(DIROBJ)\enc\alpha_enc.obj \
$(DIROBJ)\enc\analysis_enc.obj \ $(DIROBJ)\enc\analysis_enc.obj \
$(DIROBJ)\enc\backward_references_cost_enc.obj \
$(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 \
@ -348,8 +344,7 @@ all: ex
OUT_EXAMPLES = $(DIRBIN)\cwebp.exe $(DIRBIN)\dwebp.exe OUT_EXAMPLES = $(DIRBIN)\cwebp.exe $(DIRBIN)\dwebp.exe
EXTRA_EXAMPLES = $(DIRBIN)\vwebp.exe $(DIRBIN)\webpmux.exe \ EXTRA_EXAMPLES = $(DIRBIN)\vwebp.exe $(DIRBIN)\webpmux.exe \
$(DIRBIN)\img2webp.exe $(DIRBIN)\get_disto.exe \ $(DIRBIN)\img2webp.exe $(DIRBIN)\get_disto.exe \
$(DIRBIN)\webp_quality.exe $(DIRBIN)\vwebp_sdl.exe \ $(DIRBIN)\webp_quality.exe
$(DIRBIN)\webpinfo.exe
ex: $(OUT_LIBS) $(OUT_EXAMPLES) ex: $(OUT_LIBS) $(OUT_EXAMPLES)
all: ex $(EXTRA_EXAMPLES) all: ex $(EXTRA_EXAMPLES)
@ -357,52 +352,42 @@ 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)
$(DIRBIN)\vwebp.exe: $(DIROBJ)\examples\vwebp.obj $(EX_UTIL_OBJS) $(DIRBIN)\vwebp.exe: $(DIROBJ)\examples\vwebp.obj $(EX_UTIL_OBJS)
$(DIRBIN)\vwebp.exe: $(IMAGEIO_UTIL_OBJS) $(LIBWEBPDEMUX) $(LIBWEBP) $(DIRBIN)\vwebp.exe: $(IMAGEIO_UTIL_OBJS) $(LIBWEBPDEMUX) $(LIBWEBP)
$(DIRBIN)\vwebp_sdl.exe: $(DIROBJ)\extras\vwebp_sdl.obj
$(DIRBIN)\vwebp_sdl.exe: $(DIROBJ)\extras\webp_to_sdl.obj
$(DIRBIN)\vwebp_sdl.exe: $(IMAGEIO_UTIL_OBJS) $(LIBWEBP)
$(DIRBIN)\webpmux.exe: $(DIROBJ)\examples\webpmux.obj $(LIBWEBPMUX) $(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: $(IMAGEIO_DEC_OBJS)
$(DIRBIN)\webpinfo.exe: $(EX_UTIL_OBJS) $(IMAGEIO_UTIL_OBJS)
$(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 +433,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 +445,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

13
NEWS
View File

@ -1,16 +1,3 @@
- 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)

36
README
View File

@ -4,7 +4,7 @@
\__\__/\____/\_____/__/ ____ ___ \__\__/\____/\_____/__/ ____ ___
/ _/ / \ \ / _ \/ _/ / _/ / \ \ / _ \/ _/
/ \_/ / / \ \ __/ \__ / \_/ / / \ \ __/ \__
\____/____/\_____/_____/____/v0.6.1 \____/____/\_____/_____/____/v0.6.0
Description: Description:
============ ============
@ -113,8 +113,8 @@ make install
CMake: CMake:
------ ------
With CMake, you can compile libwebp, cwebp, dwebp, gif2web, img2webp, webpinfo The support for CMake is minimal: it only helps you compile libwebp, cwebp and
and the JS bindings. dwebp.
Prerequisites: Prerequisites:
A compiler (e.g., gcc with autotools) and CMake. A compiler (e.g., gcc with autotools) and CMake.
@ -123,25 +123,18 @@ minimal build:
$ sudo apt-get install build-essential cmake $ sudo apt-get install build-essential cmake
When building from git sources, you will need to run cmake to generate the When building from git sources, you will need to run cmake to generate the
makefiles. configure script.
mkdir build && cd build && cmake ../ mkdir build && cd build && cmake ../
make make
make install make install
If you also want any of the executables, you will need to enable them through If you also want cwebp or dwebp, you will need to enable them through CMake:
CMake, e.g.:
cmake -DWEBP_BUILD_CWEBP=ON -DWEBP_BUILD_DWEBP=ON ../ cmake -DWEBP_BUILD_CWEBP=ON -DWEBP_BUILD_DWEBP=ON ../
or through your favorite interface (like ccmake or cmake-qt-gui). or through your favorite interface (like ccmake or cmake-qt-gui).
Finally, once installed, you can also use WebP in your CMake project by doing:
find_package(WebP)
which will define the CMake variables WebP_INCLUDE_DIRS and WebP_LIBRARIES.
Gradle: Gradle:
------- -------
The support for Gradle is minimal: it only helps you compile libwebp, cwebp and The support for Gradle is minimal: it only helps you compile libwebp, cwebp and
@ -367,23 +360,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:
=================== ===================
@ -494,8 +470,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

View File

@ -1,7 +1,7 @@
 __ __ ____ ____ ____ __ __ _ __ __  __ __ ____ ____ ____ __ __ _ __ __
/ \\/ \/ _ \/ _ \/ _ \/ \ \/ \___/_ / _\ / \\/ \/ _ \/ _ \/ _ \/ \ \/ \___/_ / _\
\ / __/ _ \ __/ / / (_/ /__ \ / __/ _ \ __/ / / (_/ /__
\__\__/\_____/_____/__/ \__//_/\_____/__/___/v0.4.1 \__\__/\_____/_____/__/ \__//_/\_____/__/___/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:
=================== ===================

View File

@ -1,76 +0,0 @@
__ __ ____ ____ ____ __ ____
/ \\/ \ _ \ _ \ _ \ (__)/ __\
\ / __/ _ \ __/ _) \_ \
\__\__/_____/____/_/ /____/____/
Description:
============
This file describes the compilation of libwebp into a JavaScript decoder
using Emscripten and CMake.
- install the Emscripten SDK following the procedure described at:
https://kripken.github.io/emscripten-site/docs/getting_started/downloads.html
After installation, you should have some global variable positioned to the
location of the SDK. In particular, $EMSCRIPTEN should point to the
top-level directory containing Emscripten tools.
- make sure the file $EMSCRIPTEN/cmake/Modules/Platform/Emscripten.cmake is
accessible. This is the toolchain file used by CMake to invoke Emscripten.
- configure the project 'WEBP_JS' with CMake using:
cd webp_js && \
cmake -DWEBP_BUILD_WEBP_JS=ON \
-DEMSCRIPTEN_GENERATE_BITCODE_STATIC_LIBRARIES=1 \
-DCMAKE_TOOLCHAIN_FILE=$EMSCRIPTEN/cmake/Modules/Platform/Emscripten.cmake \
../
- compile webp.js using 'make'.
- that's it! Upon completion, you should have the webp.js and
webp.js.mem files generated.
The callable JavaScript function is WebPToSDL(), which decodes a raw WebP
bitstream into a canvas. See webp_js/index.html for a simple usage sample
(see below for instructions).
Demo HTML page:
===============
The HTML page webp_js/index.html requires an HTTP server to serve the WebP
image example. It's easy to just use Python for that.
cd webp_js && python -m SimpleHTTPServer 8080
and then navigate to http://localhost:8080 in your favorite browser.
Web-Assembly (WASM) version:
============================
CMakeLists.txt is configured to build the WASM version when using
the option WEBP_BUILD_WEBP_JS=ON. The compilation step will assemble
the files 'webp_wasm.js', 'webp_wasm.wasm' in the webp_js/ directory.
See webp_js/index_wasm.html for a simple demo page using the WASM version
of the library.
You will need a fairly recent version of Emscripten (at least 1.37.8) and of
your WASM-enabled browser to run this version. Consider it very experimental!
Caveat:
=======
- First decoding using the library is usually slower, due to just-in-time
compilation.
- Some versions of llvm produce the following compile error when SSE2 is
enabled.
"Unsupported: %516 = bitcast <8 x i16> %481 to i128
LLVM ERROR: BitCast Instruction not yet supported for integer types larger than 64 bits"
The corresponding Emscripten bug is at:
https://github.com/kripken/emscripten/issues/3788
Therefore, SSE2 optimization is currently disabled in CMakeLists.txt.

View File

@ -74,22 +74,12 @@ model {
cCompiler.args "-frename-registers -s" cCompiler.args "-frename-registers -s"
} }
} }
// mips32 fails to build with clang from r14b
// https://bugs.chromium.org/p/webp/issues/detail?id=343
if (toolChain in Clang) {
if (getTargetPlatform() == "mips") {
cCompiler.args "-no-integrated-as"
}
}
// 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"
} 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 +112,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 +145,10 @@ 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_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"
@ -189,15 +179,13 @@ model {
include "lossless_enc_neon.$NEON" include "lossless_enc_neon.$NEON"
include "lossless_enc_sse2.c" include "lossless_enc_sse2.c"
include "lossless_enc_sse41.c" include "lossless_enc_sse41.c"
include "ssim.c"
include "ssim_sse2.c"
srcDir "src/enc" srcDir "src/enc"
include "alpha_enc.c" include "alpha_enc.c"
include "analysis_enc.c" include "analysis_enc.c"
include "backward_references_cost_enc.c"
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 +277,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"
} }
} }
@ -301,7 +288,6 @@ model {
include "jpegdec.c" include "jpegdec.c"
include "metadata.c" include "metadata.c"
include "pngdec.c" include "pngdec.c"
include "pnmdec.c"
include "tiffdec.c" include "tiffdec.c"
include "webpdec.c" include "webpdec.c"
} }
@ -332,7 +318,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 +338,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 +377,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"
} }
} }
@ -406,24 +389,6 @@ model {
} }
} }
} }
webpinfo_example(NativeExecutableSpec) {
binaries {
all {
lib library: "example_util", linkage: "static"
lib library: "imageio_util", linkage: "static"
lib library: "webp"
}
}
sources {
c {
source {
srcDir "./examples"
include "webpinfo.c"
}
}
}
}
} }
tasks { tasks {
// Task to test all possible configurations. // Task to test all possible configurations.

View File

@ -1,6 +0,0 @@
@PACKAGE_INIT@
set(WebP_INCLUDE_DIRS "webp")
set(WEBP_INCLUDE_DIRS ${WebP_INCLUDE_DIRS})
set(WebP_LIBRARIES "@INSTALLED_LIBRARIES@")
set(WEBP_LIBRARIES "${WebP_LIBRARIES}")

View File

@ -65,49 +65,14 @@ endif()
# Find the standard image libraries. # Find the standard image libraries.
set(WEBP_DEP_IMG_LIBRARIES) set(WEBP_DEP_IMG_LIBRARIES)
set(WEBP_DEP_IMG_INCLUDE_DIRS) set(WEBP_DEP_IMG_INCLUDE_DIRS)
foreach(I_LIB PNG JPEG TIFF) foreach(I_LIB PNG JPEG TIFF GIF)
find_package(${I_LIB}) find_package(${I_LIB})
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.
include(CMakePushCheckState)
set(WEBP_DEP_GIF_LIBRARIES)
set(WEBP_DEP_GIF_INCLUDE_DIRS)
find_package(GIF)
set(WEBP_HAVE_GIF ${GIF_FOUND})
if(GIF_FOUND)
# GIF find_package only locates the header and library, it doesn't fail
# compile tests when detecting the version, but falls back to 3 (as of at
# least cmake 3.7.2). Make sure the library links to avoid incorrect
# detection when cross compiling.
cmake_push_check_state()
set(CMAKE_REQUIRED_LIBRARIES ${GIF_LIBRARIES})
set(CMAKE_REQUIRED_INCLUDES ${GIF_INCLUDE_DIR})
check_c_source_compiles("
#include <gif_lib.h>
int main(void) {
(void)DGifOpenFileHandle;
return 0;
}
" GIF_COMPILES
)
cmake_pop_check_state()
if(GIF_COMPILES)
list(APPEND WEBP_DEP_GIF_LIBRARIES ${GIF_LIBRARIES})
list(APPEND WEBP_DEP_GIF_INCLUDE_DIRS ${GIF_INCLUDE_DIR})
else()
unset(GIF_FOUND)
endif()
endif()
## Check for specific headers. ## Check for specific headers.
include(CheckIncludeFiles) include(CheckIncludeFiles)
@ -164,3 +129,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
)

View File

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

View File

@ -1,15 +1,7 @@
## 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)
if(NOT ENABLE_SIMD)
message(STATUS "Disabling ${WEBP_SIMD_FLAG} optimization.")
set(WEBP_HAVE_${WEBP_SIMD_FLAG} 0 PARENT_SCOPE)
return()
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 +12,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,13 +55,12 @@ 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})
if(NOT WEBP_HAVE_${WEBP_SIMD_FLAG}) if(NOT WEBP_HAVE_${WEBP_SIMD_FLAG})
list(GET SIMD_ENABLE_FLAGS ${I_SIMD} SIMD_COMPILE_FLAG) list(GET SIMD_ENABLE_FLAGS ${I_SIMD} SIMD_COMPILE_FLAG)
set(CMAKE_REQUIRED_FLAGS ${SIMD_COMPILE_FLAG}) set(CMAKE_REQUIRED_FLAGS ${SIMD_COMPILE_FLAG})
webp_check_compiler_flag(${WEBP_SIMD_FLAG} ${WEBP_ENABLE_SIMD}) webp_check_compiler_flag(${WEBP_SIMD_FLAG})
else() else()
set(SIMD_COMPILE_FLAG " ") set(SIMD_COMPILE_FLAG " ")
endif() endif()
@ -106,12 +96,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 +110,4 @@ foreach(I_SIMD RANGE ${WEBP_SIMD_FLAGS_RANGE})
endif() endif()
endif() endif()
endif() endif()
cmake_pop_check_state()
endforeach() endforeach()

View File

@ -1,4 +1,4 @@
AC_INIT([libwebp], [0.6.1], 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
@ -67,7 +67,6 @@ AC_DEFUN([TEST_AND_ADD_CFLAGS],
CFLAGS="$SAVED_CFLAGS"]) CFLAGS="$SAVED_CFLAGS"])
TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-fvisibility=hidden]) TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-fvisibility=hidden])
TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wall]) TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wall])
TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wconstant-conversion])
TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wdeclaration-after-statement]) TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wdeclaration-after-statement])
TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wextra]) TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wextra])
TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wfloat-conversion]) TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wfloat-conversion])
@ -76,10 +75,8 @@ TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wformat -Wformat-security])
TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wmissing-declarations]) TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wmissing-declarations])
TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wmissing-prototypes]) TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wmissing-prototypes])
TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wold-style-definition]) TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wold-style-definition])
TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wparentheses-equality])
TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wshadow]) TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-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])
@ -244,10 +241,6 @@ AS_IF([test "x$enable_neon" != "xno"], [
NEON_FLAGS=""], NEON_FLAGS=""],
[AC_DEFINE(WEBP_HAVE_NEON_RTCD, [1], [AC_DEFINE(WEBP_HAVE_NEON_RTCD, [1],
[Set to 1 if runtime detection of NEON is enabled])])]) [Set to 1 if runtime detection of NEON is enabled])])])
case "$host_os" in
*android*) AC_CHECK_HEADERS([cpu-features.h]) ;;
esac
;; ;;
esac esac
AC_SUBST([NEON_FLAGS])]) AC_SUBST([NEON_FLAGS])])
@ -347,8 +340,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
@ -437,67 +428,6 @@ AS_IF([test "x$enable_gl" != "xno"], [
]) ])
AM_CONDITIONAL([BUILD_VWEBP], [test "$build_vwebp" = "yes"]) AM_CONDITIONAL([BUILD_VWEBP], [test "$build_vwebp" = "yes"])
dnl === check for SDL support ===
AC_ARG_ENABLE([sdl],
AS_HELP_STRING([--disable-sdl],
[Disable detection of SDL support
@<:@default=auto@:>@]))
AS_IF([test "x$enable_sdl" != "xno"], [
CLEAR_LIBVARS([SDL])
AC_PATH_PROGS([LIBSDL_CONFIG], [sdl-config])
if test -n "$LIBSDL_CONFIG"; then
SDL_INCLUDES=`$LIBSDL_CONFIG --cflags`
SDL_LIBS="`$LIBSDL_CONFIG --libs`"
fi
WITHLIB_OPTION([sdl], [SDL])
sdl_header="no"
LIBCHECK_PROLOGUE([SDL])
AC_CHECK_HEADER([SDL/SDL.h], [sdl_header="SDL/SDL.h"],
[AC_CHECK_HEADER([SDL.h], [sdl_header="SDL.h"],
[AC_MSG_WARN(SDL library not available - no sdl.h)])])
if test x"$sdl_header" != "xno"; then
AC_LANG_PUSH(C)
SDL_SAVED_LIBS="$LIBS"
for lib in "" "-lSDL" "-lSDLmain -lSDL"; do
LIBS="$SDL_SAVED_LIBS $lib"
# Perform a full link to ensure SDL_main is resolved if needed.
AC_LINK_IFELSE(
[AC_LANG_SOURCE([
#include <$sdl_header>
int main(int argc, char** argv) {
SDL_Init(0);
return 0;
}])],
[SDL_LIBS="$LDFLAGS $LIBS"
SDL_INCLUDES="$SDL_INCLUDES -DWEBP_HAVE_SDL"
AC_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"
fi
fi
LIBCHECK_EPILOGUE([SDL])
if test x"$sdl_support" = "xyes"; then
build_vwebp_sdl=yes
else
AC_MSG_WARN(Optional SDL library not found)
fi
])
AM_CONDITIONAL([BUILD_VWEBP_SDL], [test "$build_vwebp_sdl" = "yes"])
dnl === check for PNG support === dnl === check for PNG support ===
AC_ARG_ENABLE([png], AS_HELP_STRING([--disable-png], AC_ARG_ENABLE([png], AS_HELP_STRING([--disable-png],
@ -615,7 +545,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,19 +553,14 @@ 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"])
if test "$enable_libwebpmux" = "yes"; then
build_webpinfo=yes
fi
AM_CONDITIONAL([BUILD_WEBPINFO], [test "${build_webpinfo}" = "yes"])
dnl === check for WIC support === dnl === check for WIC support ===
AC_ARG_ENABLE([wic], AC_ARG_ENABLE([wic],
@ -688,7 +613,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 +621,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 +650,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,25 +700,22 @@ 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}
vwebp : ${build_vwebp-no} vwebp : ${build_vwebp-no}
webpinfo : ${build_webpinfo-no}
SDL support : ${sdl_support-no}
vwebp_sdl : ${build_vwebp_sdl-no}
]) ])

View File

@ -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,25 +75,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 imageio_util imagedec webpmux webpdemux \ LOCAL_STATIC_LIBRARIES := example_util imageio_util imagedec webpmux webp
webp
LOCAL_MODULE := img2webp_example LOCAL_MODULE := img2webp_example
include $(BUILD_EXECUTABLE) include $(BUILD_EXECUTABLE)
################################################################################
# webpinfo
include $(CLEAR_VARS)
LOCAL_SRC_FILES := \
webpinfo.c \
LOCAL_CFLAGS := $(WEBP_CFLAGS)
LOCAL_C_INCLUDES := $(LOCAL_PATH)/../src
LOCAL_STATIC_LIBRARIES := example_util imageio_util webp
LOCAL_MODULE := webpinfo_example
include $(BUILD_EXECUTABLE)

View File

@ -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
@ -19,9 +16,6 @@ endif
if BUILD_VWEBP if BUILD_VWEBP
bin_PROGRAMS += vwebp bin_PROGRAMS += vwebp
endif endif
if BUILD_WEBPINFO
bin_PROGRAMS += webpinfo
endif
noinst_LTLIBRARIES = libexample_util.la noinst_LTLIBRARIES = libexample_util.la
@ -29,37 +23,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 +45,31 @@ 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_CPPFLAGS = $(AM_CPPFLAGS)
webpinfo_LDADD =
webpinfo_LDADD += libexample_util.la
webpinfo_LDADD += ../imageio/libimageio_util.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

View File

@ -187,9 +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");
#endif
} }
int main(int argc, const char* argv[]) { int main(int argc, const char* argv[]) {
@ -234,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];
@ -247,6 +250,7 @@ int main(int argc, const char* argv[]) {
} else { } else {
parse_error = 1; parse_error = 1;
} }
#endif
} else { } else {
if (!got_input1) { if (!got_input1) {
files[0] = argv[c]; files[0] = argv[c];

View File

@ -1,104 +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");
}
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 {
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;
}

View File

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

View File

@ -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,11 +486,11 @@ 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. // No metadata, just write the original image file.
return (fwrite(webp, webp_size, 1, out) == 1); 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")) {

View File

@ -332,8 +332,9 @@ int main(int argc, const char *argv[]) {
case BMP: case BMP:
output_buffer->colorspace = bitstream->has_alpha ? MODE_BGRA : MODE_BGR; output_buffer->colorspace = bitstream->has_alpha ? MODE_BGRA : MODE_BGR;
break; break;
case TIFF: case TIFF: // note: force pre-multiplied alpha
output_buffer->colorspace = bitstream->has_alpha ? MODE_RGBA : MODE_RGB; output_buffer->colorspace =
bitstream->has_alpha ? MODE_rgbA : MODE_RGB;
break; break;
case PGM: case PGM:
case RAW_YUV: case RAW_YUV:

View File

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

View File

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

View File

@ -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,14 +507,9 @@ int main(int argc, const char *argv[]) {
goto End; goto End;
} }
if (!quiet) { if (!quiet) {
if (!strcmp(out_file, "-")) {
fprintf(stderr, "Saved %d bytes to STDIO\n",
(int)webp_data.size);
} else {
fprintf(stderr, "Saved output file (%d bytes): %s\n", fprintf(stderr, "Saved output file (%d bytes): %s\n",
(int)webp_data.size, out_file); (int)webp_data.size, out_file);
} }
}
} else { } else {
if (!quiet) { if (!quiet) {
fprintf(stderr, "Nothing written; use -o flag to save the result " fprintf(stderr, "Nothing written; use -o flag to save the result "

View File

@ -28,17 +28,11 @@
#define GIF_DISPOSE_SHIFT 2 #define GIF_DISPOSE_SHIFT 2
// from utils/utils.h // from utils/utils.h
#ifdef __cplusplus
extern "C" {
#endif
extern void WebPCopyPlane(const uint8_t* src, int src_stride, extern void WebPCopyPlane(const uint8_t* src, int src_stride,
uint8_t* dst, int dst_stride, uint8_t* dst, int dst_stride,
int width, int height); int width, int height);
extern void WebPCopyPixels(const WebPPicture* const src, extern void WebPCopyPixels(const WebPPicture* const src,
WebPPicture* const dst); WebPPicture* const dst);
#ifdef __cplusplus
}
#endif
void GIFGetBackgroundColor(const ColorMapObject* const color_map, void GIFGetBackgroundColor(const ColorMapObject* const color_map,
int bgcolor_index, int transparent_index, int bgcolor_index, int transparent_index,

View File

@ -117,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;
@ -132,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) {
@ -176,7 +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 { } else {
continue; continue;
} }
@ -189,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;
@ -299,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;
} }

View File

@ -248,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') {
@ -260,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();
@ -378,23 +378,13 @@ static void HandleDisplay(void) {
} }
} }
glPopMatrix(); glPopMatrix();
#if defined(__APPLE__) || defined(_WIN32)
glFlush(); glFlush();
#else
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); glutInitDisplayMode(GLUT_RGBA);
#else
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);
#endif
glutInitWindowSize(width, height); glutInitWindowSize(width, height);
glutCreateWindow("WebP viewer"); glutCreateWindow("WebP viewer");
glutDisplayFunc(HandleDisplay); glutDisplayFunc(HandleDisplay);

File diff suppressed because it is too large Load Diff

View File

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

View File

@ -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
@ -12,33 +11,16 @@ libwebpextras_la_CPPFLAGS = $(AM_CPPFLAGS)
libwebpextras_la_LDFLAGS = -lm libwebpextras_la_LDFLAGS = -lm
libwebpextras_la_LIBADD = ../src/libwebp.la libwebpextras_la_LIBADD = ../src/libwebp.la
noinst_PROGRAMS = noinst_PROGRAMS = get_disto webp_quality
noinst_PROGRAMS += webp_quality
if WANT_DEMUX
noinst_PROGRAMS += get_disto
endif
if BUILD_VWEBP_SDL
noinst_PROGRAMS += vwebp_sdl
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_CPPFLAGS = $(AM_CPPFLAGS) $(SDL_INCLUDES)
vwebp_sdl_LDADD =
vwebp_sdl_LDADD += ../imageio/libimageio_util.la
vwebp_sdl_LDADD += ../src/libwebp.la
vwebp_sdl_LDADD += $(SDL_LIBS)

View File

@ -10,7 +10,7 @@
// 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>
@ -18,7 +18,7 @@
#define XTRA_MAJ_VERSION 0 #define XTRA_MAJ_VERSION 0
#define XTRA_MIN_VERSION 1 #define XTRA_MIN_VERSION 1
#define XTRA_REV_VERSION 1 #define XTRA_REV_VERSION 0
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------

View File

@ -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);
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------

View File

@ -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) {
@ -278,7 +278,7 @@ int main(int argc, const char *argv[]) {
goto End; goto End;
} }
size1 = ReadPicture(name1, &pic1, 1); size1 = ReadPicture(name1, &pic1, 1);
size2 = ReadPicture(name2, &pic2, 1); size2 = ReadPicture(name1, &pic2, 1);
if (size1 == 0 || size2 == 0) goto End; if (size1 == 0 || size2 == 0) goto End;
if (!keep_alpha) { if (!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;

View File

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

View File

@ -1,96 +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.
// -----------------------------------------------------------------------------
//
// Simple SDL-based WebP file viewer.
// Does not support animation, just static images.
//
// Press 'q' to exit.
//
// Author: James Zern (jzern@google.com)
#include <stdio.h>
#ifdef HAVE_CONFIG_H
#include "webp/config.h"
#endif
#if defined(WEBP_HAVE_SDL)
#include "webp_to_sdl.h"
#include "webp/decode.h"
#include "imageio/imageio_util.h"
#if defined(WEBP_HAVE_JUST_SDL_H)
#include <SDL.h>
#else
#include <SDL/SDL.h>
#endif
static void ProcessEvents(void) {
int done = 0;
SDL_Event event;
while (!done && SDL_WaitEvent(&event)) {
switch (event.type) {
case SDL_KEYUP:
switch (event.key.keysym.sym) {
case SDLK_q: done = 1; break;
default: break;
}
break;
default: break;
}
}
}
int main(int argc, char* argv[]) {
int c;
int ok = 0;
for (c = 1; c < argc; ++c) {
const char* file = NULL;
const uint8_t* webp = NULL;
size_t webp_size = 0;
if (!strcmp(argv[c], "-h")) {
printf("Usage: %s [-h] image.webp [more_files.webp...]\n", argv[0]);
return 0;
} else {
file = argv[c];
}
if (file == NULL) continue;
if (!ImgIoUtilReadFile(file, &webp, &webp_size)) {
fprintf(stderr, "Error opening file: %s\n", file);
goto Error;
}
if (webp_size != (size_t)(int)webp_size) {
fprintf(stderr, "File too large.\n");
goto Error;
}
ok = WebpToSDL((const char*)webp, (int)webp_size);
free((void*)webp);
if (!ok) {
fprintf(stderr, "Error decoding file %s\n", file);
goto Error;
}
ProcessEvents();
}
ok = 1;
Error:
SDL_Quit();
return ok ? 0 : 1;
}
#else // !WEBP_HAVE_SDL
int main(int argc, const char *argv[]) {
fprintf(stderr, "SDL support not enabled in %s.\n", argv[0]);
(void)argc;
return 0;
}
#endif

View File

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

View File

@ -1,110 +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.
// -----------------------------------------------------------------------------
//
// Simple WebP-to-SDL wrapper. Useful for emscripten.
//
// Author: James Zern (jzern@google.com)
#ifdef HAVE_CONFIG_H
#include "src/webp/config.h"
#endif
#if defined(WEBP_HAVE_SDL)
#include "webp_to_sdl.h"
#include <stdio.h>
#include "src/webp/decode.h"
#if defined(WEBP_HAVE_JUST_SDL_H)
#include <SDL.h>
#else
#include <SDL/SDL.h>
#endif
static int init_ok = 0;
int WebpToSDL(const char* data, unsigned int data_size) {
int ok = 0;
VP8StatusCode status;
WebPDecoderConfig config;
WebPBitstreamFeatures* const input = &config.input;
WebPDecBuffer* const output = &config.output;
SDL_Surface* screen = NULL;
SDL_Surface* surface = NULL;
if (!WebPInitDecoderConfig(&config)) {
fprintf(stderr, "Library version mismatch!\n");
return 1;
}
if (!init_ok) {
SDL_Init(SDL_INIT_VIDEO);
init_ok = 1;
}
status = WebPGetFeatures((uint8_t*)data, (size_t)data_size, &config.input);
if (status != VP8_STATUS_OK) goto Error;
screen = SDL_SetVideoMode(input->width, input->height, 32, SDL_SWSURFACE);
if (screen == NULL) {
fprintf(stderr, "Unable to set video mode (32bpp %dx%d)!\n",
input->width, input->height);
goto Error;
}
surface = SDL_CreateRGBSurface(SDL_SWSURFACE,
input->width, input->height, 32,
0x000000ffu, // R mask
0x0000ff00u, // G mask
0x00ff0000u, // B mask
0xff000000u); // A mask
if (surface == NULL) {
fprintf(stderr, "Unable to create %dx%d RGBA surface!\n",
input->width, input->height);
goto Error;
}
if (SDL_MUSTLOCK(surface)) SDL_LockSurface(surface);
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
output->colorspace = MODE_BGRA;
#else
output->colorspace = MODE_RGBA;
#endif
output->width = surface->w;
output->height = surface->h;
output->u.RGBA.rgba = surface->pixels;
output->u.RGBA.stride = surface->pitch;
output->u.RGBA.size = surface->pitch * surface->h;
output->is_external_memory = 1;
status = WebPDecode((const uint8_t*)data, (size_t)data_size, &config);
if (status != VP8_STATUS_OK) {
fprintf(stderr, "Error decoding image (%d)\n", status);
goto Error;
}
if (SDL_MUSTLOCK(surface)) SDL_UnlockSurface(surface);
if (SDL_BlitSurface(surface, NULL, screen, NULL) ||
SDL_Flip(screen)) {
goto Error;
}
ok = 1;
Error:
SDL_FreeSurface(surface);
SDL_FreeSurface(screen);
WebPFreeDecBuffer(output);
return ok;
}
//------------------------------------------------------------------------------
#endif // WEBP_HAVE_SDL

View File

@ -1,22 +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.
// -----------------------------------------------------------------------------
//
// Simple WebP-to-SDL wrapper. Useful for emscripten.
//
// Author: James Zern (jzern@google.com)
#ifndef WEBP_EXTRAS_WEBP_TO_SDL_H_
#define WEBP_EXTRAS_WEBP_TO_SDL_H_
// Exports the method WebpToSDL(const char* data, int data_size) which decodes
// a WebP bitstream into an RGBA SDL surface.
// Return false on failure.
extern int WebpToSDL(const char* data, unsigned int data_size);
#endif // WEBP_EXTRAS_WEBP_TO_SDL_H_

View File

@ -25,7 +25,6 @@ LOCAL_SRC_FILES := \
jpegdec.c \ jpegdec.c \
metadata.c \ metadata.c \
pngdec.c \ pngdec.c \
pnmdec.c \
tiffdec.c \ tiffdec.c \
webpdec.c \ webpdec.c \

View File

@ -1,32 +1,22 @@
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
libimagedec_la_SOURCES += pnmdec.c pnmdec.h
libimagedec_la_SOURCES += tiffdec.c tiffdec.h 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)

View File

@ -29,10 +29,6 @@ WebPInputFileFormat WebPGuessImageType(const uint8_t* const data,
format = WEBP_TIFF_FORMAT; format = WEBP_TIFF_FORMAT;
} else if (magic1 == 0x52494646 && magic2 == 0x57454250) { } else if (magic1 == 0x52494646 && magic2 == 0x57454250) {
format = WEBP_WEBP_FORMAT; format = WEBP_WEBP_FORMAT;
} else if (((magic1 >> 24) & 0xff) == 'P') {
const int type = (magic1 >> 16) & 0xff;
// we only support 'P5 -> P7' for now.
if (type >= '5' && type <= '7') format = WEBP_PNM_FORMAT;
} }
} }
return format; return format;
@ -55,7 +51,6 @@ WebPImageReader WebPGetImageReader(WebPInputFileFormat format) {
case WEBP_JPEG_FORMAT: return ReadJPEG; case WEBP_JPEG_FORMAT: return ReadJPEG;
case WEBP_TIFF_FORMAT: return ReadTIFF; case WEBP_TIFF_FORMAT: return ReadTIFF;
case WEBP_WEBP_FORMAT: return ReadWebP; case WEBP_WEBP_FORMAT: return ReadWebP;
case WEBP_PNM_FORMAT: return ReadPNM;
default: return FailReader; default: return FailReader;
} }
} }

View File

@ -23,7 +23,6 @@
#include "./metadata.h" #include "./metadata.h"
#include "./jpegdec.h" #include "./jpegdec.h"
#include "./pngdec.h" #include "./pngdec.h"
#include "./pnmdec.h"
#include "./tiffdec.h" #include "./tiffdec.h"
#include "./webpdec.h" #include "./webpdec.h"
#include "./wicdec.h" #include "./wicdec.h"
@ -37,7 +36,6 @@ typedef enum {
WEBP_JPEG_FORMAT, WEBP_JPEG_FORMAT,
WEBP_TIFF_FORMAT, WEBP_TIFF_FORMAT,
WEBP_WEBP_FORMAT, WEBP_WEBP_FORMAT,
WEBP_PNM_FORMAT,
WEBP_UNSUPPORTED_FORMAT WEBP_UNSUPPORTED_FORMAT
} WebPInputFileFormat; } WebPInputFileFormat;

View File

@ -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,14 +184,6 @@ 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);
{
const uint32_t width = buffer->width;
const uint32_t height = buffer->height;
png_bytep row = buffer->u.RGBA.rgba;
const int stride = buffer->u.RGBA.stride;
const int has_alpha = WebPIsAlphaMode(buffer->colorspace);
uint32_t y;
png_set_IHDR(png, info, width, height, 8, png_set_IHDR(png, info, width, height, 8,
has_alpha ? PNG_COLOR_TYPE_RGBA : PNG_COLOR_TYPE_RGB, has_alpha ? PNG_COLOR_TYPE_RGBA : PNG_COLOR_TYPE_RGB,
PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT,
@ -195,7 +193,6 @@ int WebPWritePNG(FILE* out_file, const WebPDecBuffer* const buffer) {
png_write_rows(png, &row, 1); png_write_rows(png, &row, 1);
row += stride; 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);
return 1; return 1;
@ -364,8 +361,6 @@ int WebPWriteTIFF(FILE* fout, const WebPDecBuffer* const buffer) {
const uint8_t* rgba = buffer->u.RGBA.rgba; const uint8_t* rgba = buffer->u.RGBA.rgba;
const int stride = buffer->u.RGBA.stride; const int stride = buffer->u.RGBA.stride;
const uint8_t bytes_per_px = has_alpha ? 4 : 3; const uint8_t bytes_per_px = has_alpha ? 4 : 3;
const uint8_t assoc_alpha =
WebPIsPremultipliedMode(buffer->colorspace) ? 1 : 2;
// For non-alpha case, we omit tag 0x152 (ExtraSamples). // For non-alpha case, we omit tag 0x152 (ExtraSamples).
const uint8_t num_ifd_entries = has_alpha ? NUM_IFD_ENTRIES const uint8_t num_ifd_entries = has_alpha ? NUM_IFD_ENTRIES
: NUM_IFD_ENTRIES - 1; : NUM_IFD_ENTRIES - 1;
@ -393,8 +388,7 @@ int WebPWriteTIFF(FILE* fout, const WebPDecBuffer* const buffer) {
EXTRA_DATA_OFFSET + 8, 0, 0, 0, EXTRA_DATA_OFFSET + 8, 0, 0, 0,
0x1c, 0x01, 3, 0, 1, 0, 0, 0, 1, 0, 0, 0, // 154: PlanarConfiguration 0x1c, 0x01, 3, 0, 1, 0, 0, 0, 1, 0, 0, 0, // 154: PlanarConfiguration
0x28, 0x01, 3, 0, 1, 0, 0, 0, 2, 0, 0, 0, // 166: ResolutionUnit (inch) 0x28, 0x01, 3, 0, 1, 0, 0, 0, 2, 0, 0, 0, // 166: ResolutionUnit (inch)
0x52, 0x01, 3, 0, 1, 0, 0, 0, 0x52, 0x01, 3, 0, 1, 0, 0, 0, 1, 0, 0, 0, // 178: ExtraSamples: rgbA
assoc_alpha, 0, 0, 0, // 178: ExtraSamples: rgbA/RGBA
0, 0, 0, 0, // 190: IFD terminator 0, 0, 0, 0, // 190: IFD terminator
// EXTRA_DATA_OFFSET: // EXTRA_DATA_OFFSET:
8, 0, 8, 0, 8, 0, 8, 0, // BitsPerSample 8, 0, 8, 0, 8, 0, 8, 0, // BitsPerSample
@ -545,24 +539,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 +563,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

View File

@ -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;
@ -123,7 +112,7 @@ int ImgIoUtilWriteFile(const char* const file_name,
if (data == NULL) { if (data == NULL) {
return 0; return 0;
} }
out = to_stdout ? ImgIoUtilSetBinaryMode(stdout) : fopen(file_name, "wb"); out = to_stdout ? stdout : fopen(file_name, "wb");
if (out == NULL) { if (out == NULL) {
fprintf(stderr, "Error! Cannot open output file '%s'\n", file_name); fprintf(stderr, "Error! Cannot open output file '%s'\n", file_name);
return 0; return 0;
@ -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;
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------

View File

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

View File

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

View File

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

View File

@ -1,257 +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.
// -----------------------------------------------------------------------------
//
// (limited) PNM decoder
#include "./pnmdec.h"
#include <assert.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "webp/encode.h"
#include "./imageio_util.h"
typedef enum {
WIDTH_FLAG = 1 << 0,
HEIGHT_FLAG = 1 << 1,
DEPTH_FLAG = 1 << 2,
MAXVAL_FLAG = 1 << 3,
TUPLE_FLAG = 1 << 4,
ALL_NEEDED_FLAGS = 0x1f
} PNMFlags;
typedef struct {
const uint8_t* data;
size_t data_size;
int width, height;
int bytes_per_px; // 1, 3, 4
int depth;
int max_value;
int type; // 5, 6 or 7
int seen_flags;
} PNMInfo;
// -----------------------------------------------------------------------------
// PNM decoding
#define MAX_LINE_SIZE 1024
static const size_t kMinPNMHeaderSize = 3;
static size_t ReadLine(const uint8_t* const data, size_t off, size_t data_size,
char out[MAX_LINE_SIZE + 1], size_t* const out_size) {
size_t i = 0;
*out_size = 0;
redo:
for (i = 0; i < MAX_LINE_SIZE && off < data_size; ++i) {
out[i] = data[off++];
if (out[i] == '\n') break;
}
if (off < data_size) {
if (i == 0) goto redo; // empty line
if (out[0] == '#') goto redo; // skip comment
}
out[i] = 0; // safety sentinel
*out_size = i;
return off;
}
static size_t FlagError(const char flag[]) {
fprintf(stderr, "PAM header error: flags '%s' already seen.\n", flag);
return 0;
}
// inspired from http://netpbm.sourceforge.net/doc/pam.html
static size_t ReadPAMFields(PNMInfo* const info, size_t off) {
char out[MAX_LINE_SIZE + 1];
size_t out_size;
int tmp;
assert(info != NULL);
while (1) {
off = ReadLine(info->data, off, info->data_size, out, &out_size);
if (off == 0) return 0;
if (sscanf(out, "WIDTH %d", &tmp) == 1) {
if (info->seen_flags & WIDTH_FLAG) return FlagError("WIDTH");
info->seen_flags |= WIDTH_FLAG;
info->width = tmp;
} else if (sscanf(out, "HEIGHT %d", &tmp) == 1) {
if (info->seen_flags & HEIGHT_FLAG) return FlagError("HEIGHT");
info->seen_flags |= HEIGHT_FLAG;
info->height = tmp;
} else if (sscanf(out, "DEPTH %d", &tmp) == 1) {
if (info->seen_flags & DEPTH_FLAG) return FlagError("DEPTH");
info->seen_flags |= DEPTH_FLAG;
info->depth = tmp;
} else if (sscanf(out, "MAXVAL %d", &tmp) == 1) {
if (info->seen_flags & MAXVAL_FLAG) return FlagError("MAXVAL");
info->seen_flags |= MAXVAL_FLAG;
info->max_value = tmp;
} else if (!strcmp(out, "TUPLTYPE RGB_ALPHA")) {
info->bytes_per_px = 4;
info->seen_flags |= TUPLE_FLAG;
} else if (!strcmp(out, "TUPLTYPE RGB")) {
info->bytes_per_px = 3;
info->seen_flags |= TUPLE_FLAG;
} else if (!strcmp(out, "TUPLTYPE GRAYSCALE")) {
info->bytes_per_px = 1;
info->seen_flags |= TUPLE_FLAG;
} else if (!strcmp(out, "ENDHDR")) {
break;
} else {
static const char kEllipsis[] = " ...";
int i;
if (out_size > 20) sprintf(out + 20 - strlen(kEllipsis), kEllipsis);
for (i = 0; i < (int)strlen(out); ++i) {
if (!isprint(out[i])) out[i] = ' ';
}
fprintf(stderr, "PAM header error: unrecognized entry [%s]\n", out);
return 0;
}
}
if (!(info->seen_flags & TUPLE_FLAG)) {
if (info->depth > 0 && info->depth <= 4 && info->depth != 2) {
info->seen_flags |= TUPLE_FLAG;
info->bytes_per_px = info->depth * (info->max_value > 255 ? 2 : 1);
} else {
fprintf(stderr, "PAM: invalid bitdepth (%d).\n", info->depth);
return 0;
}
}
if (info->seen_flags != ALL_NEEDED_FLAGS) {
fprintf(stderr, "PAM: incomplete header.\n");
return 0;
}
return off;
}
static size_t ReadHeader(PNMInfo* const info) {
size_t off = 0;
char out[MAX_LINE_SIZE + 1];
size_t out_size;
if (info == NULL) return 0;
if (info->data == NULL || info->data_size < kMinPNMHeaderSize) return 0;
info->width = info->height = 0;
info->type = -1;
info->seen_flags = 0;
info->bytes_per_px = 0;
info->depth = 0;
info->max_value = 0;
off = ReadLine(info->data, off, info->data_size, out, &out_size);
if (off == 0 || sscanf(out, "P%d", &info->type) != 1) return 0;
if (info->type == 7) {
off = ReadPAMFields(info, off);
} else {
off = ReadLine(info->data, off, info->data_size, out, &out_size);
if (off == 0 || sscanf(out, "%d %d", &info->width, &info->height) != 2) {
return 0;
}
off = ReadLine(info->data, off, info->data_size, out, &out_size);
if (off == 0 || sscanf(out, "%d", &info->max_value) != 1) return 0;
// finish initializing missing fields
info->depth = (info->type == 5) ? 1 : 3;
info->bytes_per_px = info->depth * (info->max_value > 255 ? 2 : 1);
}
// perform some basic numerical validation
if (info->width <= 0 || info->height <= 0 ||
info->type <= 0 || info->type >= 9 ||
info->depth <= 0 || info->depth == 2 || info->depth > 4 ||
info->bytes_per_px < info->depth ||
info->max_value <= 0 || info->max_value >= 65536) {
return 0;
}
return off;
}
int ReadPNM(const uint8_t* const data, size_t data_size,
WebPPicture* const pic, int keep_alpha,
struct Metadata* const metadata) {
int ok = 0;
int i, j;
uint64_t stride, pixel_bytes;
uint8_t* rgb = NULL, *tmp_rgb;
size_t offset;
PNMInfo info;
info.data = data;
info.data_size = data_size;
offset = ReadHeader(&info);
if (offset == 0) {
fprintf(stderr, "Error parsing PNM header.\n");
goto End;
}
if (info.type < 5 || info.type > 7) {
fprintf(stderr, "Unsupported P%d PNM format.\n", info.type);
goto End;
}
// Some basic validations.
if (pic == NULL) goto End;
if (info.width > WEBP_MAX_DIMENSION || info.height > WEBP_MAX_DIMENSION) {
fprintf(stderr, "Invalid %dx%d dimension for PNM\n",
info.width, info.height);
goto End;
}
pixel_bytes = (uint64_t)info.width * info.height * info.bytes_per_px;
if (data_size < offset + pixel_bytes) {
fprintf(stderr, "Truncated PNM file (P%d).\n", info.type);
goto End;
}
stride =
(uint64_t)(info.bytes_per_px < 3 ? 3 : info.bytes_per_px) * info.width;
if (stride != (size_t)stride ||
!ImgIoUtilCheckSizeArgumentsOverflow(stride, info.height)) {
goto End;
}
rgb = (uint8_t*)malloc((size_t)stride * info.height);
if (rgb == NULL) goto End;
// Convert input
tmp_rgb = rgb;
for (j = 0; j < info.height; ++j) {
assert(offset + info.bytes_per_px * info.width <= data_size);
if (info.depth == 1) {
// convert grayscale -> RGB
for (i = 0; i < info.width; ++i) {
const uint8_t v = data[offset + i];
tmp_rgb[3 * i + 0] = tmp_rgb[3 * i + 1] = tmp_rgb[3 * i + 2] = v;
}
} else if (info.depth == 3) { // RGB
memcpy(tmp_rgb, data + offset, 3 * info.width * sizeof(*data));
} else if (info.depth == 4) { // RGBA
memcpy(tmp_rgb, data + offset, 4 * info.width * sizeof(*data));
}
offset += info.bytes_per_px * info.width;
tmp_rgb += stride;
}
// WebP conversion.
pic->width = info.width;
pic->height = info.height;
ok = (info.depth == 4) ? WebPPictureImportRGBA(pic, rgb, (int)stride)
: WebPPictureImportRGB(pic, rgb, (int)stride);
if (!ok) goto End;
ok = 1;
End:
free((void*)rgb);
(void)metadata;
(void)keep_alpha;
return ok;
}
// -----------------------------------------------------------------------------

View File

@ -1,37 +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.
// -----------------------------------------------------------------------------
//
// partial PNM format decoder (ppm/pgm)
#ifndef WEBP_IMAGEIO_PNMDEC_H_
#define WEBP_IMAGEIO_PNMDEC_H_
#include "webp/types.h"
#ifdef __cplusplus
extern "C" {
#endif
struct Metadata;
struct WebPPicture;
// Reads a PNM file from 'data', returning the decoded output in 'pic'.
// The output is RGB or YUV depending on pic->use_argb value.
// Returns true on success.
// 'metadata' has no effect, but is kept for coherence with other signatures
// for image readers.
int ReadPNM(const uint8_t* const data, size_t data_size,
struct WebPPicture* const pic, int keep_alpha,
struct Metadata* const metadata);
#ifdef __cplusplus
} // extern "C"
#endif
#endif // WEBP_IMAGEIO_PNMDEC_H_

View File

@ -15,7 +15,6 @@
#include "webp/config.h" #include "webp/config.h"
#endif #endif
#include <limits.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
@ -108,7 +107,7 @@ static void MyUnmapFile(thandle_t opaque, void* base, toff_t size) {
static tsize_t MyRead(thandle_t opaque, void* dst, tsize_t size) { static tsize_t MyRead(thandle_t opaque, void* dst, tsize_t size) {
MyData* const my_data = (MyData*)opaque; MyData* const my_data = (MyData*)opaque;
if (my_data->pos + size > my_data->size) { if (my_data->pos + size > my_data->size) {
size = (tsize_t)(my_data->size - my_data->pos); size = my_data->size - my_data->pos;
} }
if (size > 0) { if (size > 0) {
memcpy(dst, my_data->data + my_data->pos, size); memcpy(dst, my_data->data + my_data->pos, size);
@ -117,55 +116,18 @@ static tsize_t MyRead(thandle_t opaque, void* dst, tsize_t size) {
return size; return size;
} }
// Unmultiply Argb data. Taken from dsp/alpha_processing
// (we don't want to force a dependency to a libdspdec library).
#define MFIX 24 // 24bit fixed-point arithmetic
#define HALF ((1u << MFIX) >> 1)
#define KINV_255 ((1u << MFIX) / 255u)
static uint32_t Unmult(uint8_t x, uint32_t mult) {
const uint32_t v = (x * mult + HALF) >> MFIX;
return (v > 255u) ? 255u : v;
}
static WEBP_INLINE uint32_t GetScale(uint32_t a) {
return (255u << MFIX) / a;
}
static void MultARGBRow(uint8_t* ptr, int width) {
int x;
for (x = 0; x < width; ++x, ptr += 4) {
const uint32_t alpha = ptr[3];
if (alpha < 255) {
if (alpha == 0) { // alpha == 0
ptr[0] = ptr[1] = ptr[2] = 0;
} else {
const uint32_t scale = GetScale(alpha);
ptr[0] = Unmult(ptr[0], scale);
ptr[1] = Unmult(ptr[1], scale);
ptr[2] = Unmult(ptr[2], scale);
}
}
}
}
int ReadTIFF(const uint8_t* const data, size_t data_size, int ReadTIFF(const uint8_t* const data, size_t data_size,
WebPPicture* const pic, int keep_alpha, WebPPicture* const pic, int keep_alpha,
Metadata* const metadata) { Metadata* const metadata) {
MyData my_data = { data, (toff_t)data_size, 0 }; MyData my_data = { data, (toff_t)data_size, 0 };
TIFF* tif; TIFF* tif;
uint32_t width, height; uint32 width, height;
uint16_t samples_per_px = 0; uint32* raster;
uint16_t extra_samples = 0;
uint16_t* extra_samples_ptr = NULL;
uint32_t* raster;
int64_t alloc_size; int64_t alloc_size;
int ok = 0; int ok = 0;
tdir_t dircount; tdir_t dircount;
if (data == NULL || data_size == 0 || data_size > INT_MAX || pic == NULL) { if (data == NULL || data_size == 0 || pic == NULL) return 0;
return 0;
}
tif = TIFFClientOpen("Memory", "r", &my_data, tif = TIFFClientOpen("Memory", "r", &my_data,
MyRead, MyRead, MySeek, MyClose, MyRead, MyRead, MySeek, MyClose,
@ -181,27 +143,17 @@ int ReadTIFF(const uint8_t* const data, size_t data_size,
"Only the first will be used, %d will be ignored.\n", "Only the first will be used, %d will be ignored.\n",
dircount - 1); dircount - 1);
} }
if (!TIFFGetFieldDefaulted(tif, TIFFTAG_SAMPLESPERPIXEL, &samples_per_px)) {
fprintf(stderr, "Error! Cannot retrieve TIFF samples-per-pixel info.\n");
goto End;
}
if (samples_per_px < 3 || samples_per_px > 4) goto End; // not supported
if (!(TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &width) && if (!(TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &width) &&
TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &height))) { TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &height))) {
fprintf(stderr, "Error! Cannot retrieve TIFF image dimensions.\n"); fprintf(stderr, "Error! Cannot retrieve TIFF image dimensions.\n");
goto End; goto End;
} }
if (!ImgIoUtilCheckSizeArgumentsOverflow((uint64_t)width * height, if (!ImgIoUtilCheckSizeArgumentsOverflow((uint64_t)width * height,
sizeof(*raster))) { sizeof(*raster))) {
goto End; goto End;
} }
if (samples_per_px > 3 && !TIFFGetField(tif, TIFFTAG_EXTRASAMPLES,
&extra_samples, &extra_samples_ptr)) {
fprintf(stderr, "Error! Cannot retrieve TIFF ExtraSamples info.\n");
goto End;
}
// _Tiffmalloc uses a signed type for size. // _Tiffmalloc uses a signed type for size.
alloc_size = (int64_t)((uint64_t)width * height * sizeof(*raster)); alloc_size = (int64_t)((uint64_t)width * height * sizeof(*raster));
if (alloc_size < 0 || alloc_size != (tsize_t)alloc_size) goto End; if (alloc_size < 0 || alloc_size != (tsize_t)alloc_size) goto End;
@ -217,16 +169,6 @@ int ReadTIFF(const uint8_t* const data, size_t data_size,
#ifdef WORDS_BIGENDIAN #ifdef WORDS_BIGENDIAN
TIFFSwabArrayOfLong(raster, width * height); TIFFSwabArrayOfLong(raster, width * height);
#endif #endif
// if we have an alpha channel, we must un-multiply from rgbA to RGBA
if (extra_samples == 1 && extra_samples_ptr != NULL &&
extra_samples_ptr[0] == EXTRASAMPLE_ASSOCALPHA) {
uint32_t y;
uint8_t* tmp = (uint8_t*)raster;
for (y = 0; y < height; ++y) {
MultARGBRow(tmp, width);
tmp += stride;
}
}
ok = keep_alpha ok = keep_alpha
? WebPPictureImportRGBA(pic, (const uint8_t*)raster, stride) ? WebPPictureImportRGBA(pic, (const uint8_t*)raster, stride)
: WebPPictureImportRGBX(pic, (const uint8_t*)raster, stride); : WebPPictureImportRGBX(pic, (const uint8_t*)raster, stride);

View File

@ -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;
@ -161,82 +138,52 @@ int ReadWebP(const uint8_t* const data, size_t data_size,
PrintWebPError("input data", status); PrintWebPError("input data", status);
return 0; return 0;
} }
{
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->height = bitstream->height;
if (pic->use_argb) { if (pic->use_argb) {
stride = (uint64_t)bitstream->width * 4; output_buffer->colorspace = has_alpha ? MODE_RGBA : MODE_RGB;
} else {
output_buffer->colorspace = has_alpha ? MODE_YUVA : MODE_YUV;
}
status = DecodeWebP(data, data_size, &config);
if (status == VP8_STATUS_OK) {
pic->width = output_buffer->width;
pic->height = output_buffer->height;
if (pic->use_argb) {
const uint8_t* const rgba = output_buffer->u.RGBA.rgba;
const int stride = output_buffer->u.RGBA.stride;
ok = has_alpha ? WebPPictureImportRGBA(pic, rgba, stride)
: WebPPictureImportRGB(pic, rgba, stride);
} else { } else {
stride = (uint64_t)bitstream->width * (has_alpha ? 5 : 3) / 2;
pic->colorspace = has_alpha ? WEBP_YUV420A : WEBP_YUV420; 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;
}
if (pic->use_argb) {
#ifdef WORDS_BIGENDIAN
output_buffer->colorspace = MODE_ARGB;
#else
output_buffer->colorspace = MODE_BGRA;
#endif
output_buffer->u.RGBA.rgba = (uint8_t*)pic->argb;
output_buffer->u.RGBA.stride = pic->argb_stride * sizeof(uint32_t);
output_buffer->u.RGBA.size = output_buffer->u.RGBA.stride * pic->height;
} else { } else {
output_buffer->colorspace = has_alpha ? MODE_YUVA : MODE_YUV; const WebPYUVABuffer* const yuva = &output_buffer->u.YUVA;
output_buffer->u.YUVA.y = pic->y; const int uv_width = (pic->width + 1) >> 1;
output_buffer->u.YUVA.u = pic->u; const int uv_height = (pic->height + 1) >> 1;
output_buffer->u.YUVA.v = pic->v; ImgIoUtilCopyPlane(yuva->y, yuva->y_stride,
output_buffer->u.YUVA.a = has_alpha ? pic->a : NULL; pic->y, pic->y_stride, pic->width, pic->height);
output_buffer->u.YUVA.y_stride = pic->y_stride; ImgIoUtilCopyPlane(yuva->u, yuva->u_stride,
output_buffer->u.YUVA.u_stride = pic->uv_stride; pic->u, pic->uv_stride, uv_width, uv_height);
output_buffer->u.YUVA.v_stride = pic->uv_stride; ImgIoUtilCopyPlane(yuva->v, yuva->v_stride,
output_buffer->u.YUVA.a_stride = has_alpha ? pic->a_stride : 0; pic->v, pic->uv_stride, uv_width, uv_height);
output_buffer->u.YUVA.y_size = pic->height * pic->y_stride; if (has_alpha) {
output_buffer->u.YUVA.u_size = (pic->height + 1) / 2 * pic->uv_stride; ImgIoUtilCopyPlane(yuva->a, yuva->a_stride,
output_buffer->u.YUVA.v_size = (pic->height + 1) / 2 * pic->uv_stride; pic->a, pic->a_stride, pic->width, pic->height);
output_buffer->u.YUVA.a_size = pic->height * pic->a_stride; }
} }
output_buffer->is_external_memory = 1; }
status = DecodeWebP(data, data_size, &config);
ok = (status == VP8_STATUS_OK);
if (ok && !keep_alpha && pic->use_argb) {
// Need to wipe out the alpha value, as requested.
int x, y;
uint32_t* argb = pic->argb;
for (y = 0; y < pic->height; ++y) {
for (x = 0; x < pic->width; ++x) argb[x] |= 0xff000000u;
argb += pic->argb_stride;
} }
} }
} while (0); // <- so we can 'break' out of the loop
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;
} }

View File

@ -51,7 +51,7 @@ VP8StatusCode DecodeWebPIncremental(
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// Decodes a WebP contained in 'data', returning the decoded output in 'pic'. // Reads a WebP from 'in_file', returning the decoded output in 'pic'.
// Output is RGBA or YUVA, depending on pic->use_argb value. // Output is RGBA or YUVA, depending on pic->use_argb value.
// If 'keep_alpha' is true and the WebP has an alpha channel, the output is RGBA // If 'keep_alpha' is true and the WebP has an alpha channel, the output is RGBA
// or YUVA. Otherwise, alpha channel is dropped and output is RGB or YUV. // or YUVA. Otherwise, alpha channel is dropped and output is RGB or YUV.

View File

@ -25,26 +25,13 @@ 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
else else
EXTRA_FLAGS += -I/usr/local/include
EXTRA_LIBS += -L/usr/local/lib
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 +51,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,7 +101,7 @@ endif
AR = ar AR = ar
ARFLAGS = r ARFLAGS = r
CPPFLAGS = -I. -Isrc/ -Wall CPPFLAGS = -Isrc/ -Wall
CFLAGS = -O3 -DNDEBUG $(EXTRA_FLAGS) CFLAGS = -O3 -DNDEBUG $(EXTRA_FLAGS)
CC = gcc CC = gcc
INSTALL = install INSTALL = install
@ -174,15 +164,15 @@ 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_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 \
@ -202,16 +192,14 @@ DSP_ENC_OBJS = \
src/dsp/lossless_enc_neon.o \ src/dsp/lossless_enc_neon.o \
src/dsp/lossless_enc_sse2.o \ src/dsp/lossless_enc_sse2.o \
src/dsp/lossless_enc_sse41.o \ src/dsp/lossless_enc_sse41.o \
src/dsp/ssim.o \
src/dsp/ssim_sse2.o \
ENC_OBJS = \ ENC_OBJS = \
src/enc/alpha_enc.o \ src/enc/alpha_enc.o \
src/enc/analysis_enc.o \ src/enc/analysis_enc.o \
src/enc/backward_references_cost_enc.o \
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 \
@ -235,7 +223,6 @@ EX_FORMAT_DEC_OBJS = \
imageio/jpegdec.o \ imageio/jpegdec.o \
imageio/metadata.o \ imageio/metadata.o \
imageio/pngdec.o \ imageio/pngdec.o \
imageio/pnmdec.o \
imageio/tiffdec.o \ imageio/tiffdec.o \
imageio/webpdec.o \ imageio/webpdec.o \
@ -309,6 +296,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 \
@ -340,9 +328,8 @@ 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/img2webp examples/webpinfo OTHER_EXAMPLES = extras/get_disto extras/webp_quality
OTHER_EXAMPLES = extras/get_disto extras/webp_quality extras/vwebp_sdl
OUTPUT = $(OUT_LIBS) $(OUT_EXAMPLES) OUTPUT = $(OUT_LIBS) $(OUT_EXAMPLES)
ifeq ($(MAKECMDGOALS),clean) ifeq ($(MAKECMDGOALS),clean)
@ -369,7 +356,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)
@ -387,36 +374,25 @@ 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)
examples/vwebp: examples/vwebp.o examples/vwebp: examples/vwebp.o
examples/webpmux: examples/webpmux.o examples/webpmux: examples/webpmux.o
examples/img2webp: examples/img2webp.o examples/img2webp: examples/img2webp.o
examples/webpinfo: examples/webpinfo.o
examples/anim_diff: examples/libanim_util.a examples/libgifdec.a examples/anim_diff: examples/libanim_util.a examples/libgifdec.a
examples/anim_diff: src/demux/libwebpdemux.a examples/libexample_util.a examples/anim_diff: src/demux/libwebpdemux.a examples/libexample_util.a
examples/anim_diff: imageio/libimageio_util.a src/libwebp.a examples/anim_diff: imageio/libimageio_util.a src/libwebp.a
examples/anim_diff: 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
@ -433,30 +409,17 @@ 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: 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
extras/webp_quality: imageio/libimageio_util.a extras/webp_quality: imageio/libimageio_util.a
extras/webp_quality: $(EXTRA_LIB) src/libwebp.a extras/webp_quality: $(EXTRA_LIB) src/libwebp.a
extras/vwebp_sdl: extras/vwebp_sdl.o
extras/vwebp_sdl: extras/webp_to_sdl.o
extras/vwebp_sdl: imageio/libimageio_util.a
extras/vwebp_sdl: src/libwebp.a
extras/vwebp_sdl: EXTRA_FLAGS += -DWEBP_HAVE_SDL $(SDL_FLAGS)
extras/vwebp_sdl: EXTRA_LIBS += $(SDL_LIBS)
$(OUT_EXAMPLES) $(EXTRA_EXAMPLES) $(OTHER_EXAMPLES): $(OUT_EXAMPLES) $(EXTRA_EXAMPLES) $(OTHER_EXAMPLES):
$(CC) -o $@ $^ $(LDFLAGS) $(CC) -o $@ $^ $(LDFLAGS)
@ -472,7 +435,7 @@ dist: all
$(INSTALL) -m644 src/mux/libwebpmux.a $(DESTDIR)/lib $(INSTALL) -m644 src/mux/libwebpmux.a $(DESTDIR)/lib
umask 022; \ umask 022; \
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; do \
basenam=$$(basename $$m .1); \ basenam=$$(basename $$m .1); \
$(GROFF) -t -e -man -T utf8 $$m \ $(GROFF) -t -e -man -T utf8 $$m \
| $(COL) -bx >$(DESTDIR)/doc/$${basenam}.txt; \ | $(COL) -bx >$(DESTDIR)/doc/$${basenam}.txt; \

View File

@ -8,7 +8,4 @@ endif
if BUILD_VWEBP if BUILD_VWEBP
man_MANS += vwebp.1 man_MANS += vwebp.1
endif endif
if BUILD_WEBPINFO
man_MANS += webpinfo.1
endif
EXTRA_DIST = $(man_MANS) EXTRA_DIST = $(man_MANS)

View File

@ -98,7 +98,8 @@ Crop the source to a rectangle with top\-left corner at coordinates
This cropping area must be fully contained within the source rectangle. This cropping area must be fully contained within the source rectangle.
.TP .TP
.B \-mt .B \-mt
Use multi\-threading for encoding, if possible. Use multi\-threading for encoding, if possible. This option is only effective
when using lossy compression on a source with a transparency channel.
.TP .TP
.B \-low_memory .B \-low_memory
Reduce memory usage of lossy encoding by saving four times the compressed Reduce memory usage of lossy encoding by saving four times the compressed

View File

@ -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
@ -114,11 +108,8 @@ the value the smoother the picture will appear. Typical values are usually in
the range of 20 to 50. the range of 20 to 50.
.TP .TP
.B \-mt .B \-mt
Use multi-threading for encoding, if possible. Use multi-threading for encoding, if possible. This option is only effective
.TP when using lossy compression.
.B \-loop_compatibility
If enabled, handle the loop information in a compatible fashion for Chrome
version prior to M62 (inclusive) and Firefox.
.TP .TP
.B \-v .B \-v
Print extra information. Print extra information.
@ -143,8 +134,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.

View File

@ -1,13 +1,11 @@
.\" Hey, EMACS: -*- nroff -*- .\" Hey, EMACS: -*- nroff -*-
.TH IMG2WEBP 1 "February 7, 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,8 +40,8 @@ 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.

View File

@ -1,80 +0,0 @@
.\" Hey, EMACS: -*- nroff -*-
.TH WEBPINFO 1 "November 24, 2017"
.SH NAME
webpinfo \- print out the chunk level structure of WebP files
along with basic integrity checks.
.SH SYNOPSIS
.B webpinfo
.I OPTIONS
.I INPUT
.br
.B webpinfo [\-h|\-help|\-H|\-longhelp]
.br
.SH DESCRIPTION
This manual page documents the
.B webpinfo
command.
.PP
\fBwebpinfo\fP 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.
.SH OPTIONS
.TP
.B \-version
Print the version number (as major.minor.revision) and exit.
.TP
.B \-quiet
Do not show chunk parsing information.
.TP
.B \-diag
Show parsing error diagnosis.
.TP
.B \-summary
Show chunk stats summary.
.TP
.BI \-bitstream_info
Parse bitstream header.
.TP
.B \-h, \-help
A short usage summary.
.TP
.B \-H, \-longhelp
Detailed usage instructions.
.SH INPUT
Input files in WebP format. Input files must come last, following
options (if any). There can be multiple input files.
.SH BUGS
Please report all bugs to the issue tracker:
https://bugs.chromium.org/p/webp
.br
Patches welcome! See this page to get started:
http://www.webmproject.org/code/contribute/submitting\-patches/
.SH EXAMPLES
.br
webpinfo \-h
.br
webpinfo \-diag \-summary input_file.webp
.br
webpinfo \-bitstream_info input_file_1.webp input_file_2.webp
.br
webpinfo *.webp
.SH AUTHORS
\fBwebpinfo\fP is a part of libwebp and was written by the WebP team.
.br
The latest source tree is available at
https://chromium.googlesource.com/webm/libwebp
.PP
This manual page was written by Hui Su <huisu@google.com>,
for the Debian project (and may be used by others).
.SH SEE ALSO
.BR webpmux (1)
.br
Please refer to http://developers.google.com/speed/webp/ for additional
information.

View File

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

View File

@ -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:1: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:1:0 libwebpdecoder_la_LDFLAGS = -no-undefined -version-info 3:0:0
pkgconfig_DATA += libwebpdecoder.pc pkgconfig_DATA += libwebpdecoder.pc
endif endif

View File

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

View File

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

View File

@ -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_ */

View File

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

View File

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

View File

@ -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_);

View File

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

View File

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

View File

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

View File

@ -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) {
@ -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
}; };

View File

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

View File

@ -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" {
@ -33,7 +33,7 @@ extern "C" {
// /* customize io's functions (setup()/put()/teardown()) if needed. */ // /* customize io's functions (setup()/put()/teardown()) if needed. */
// //
// VP8Decoder* dec = VP8New(); // VP8Decoder* dec = VP8New();
// int ok = VP8Decode(dec, &io); // bool ok = VP8Decode(dec);
// if (!ok) printf("Error: %s\n", VP8StatusMessage(dec)); // if (!ok) printf("Error: %s\n", VP8StatusMessage(dec));
// VP8Delete(dec); // VP8Delete(dec);
// return ok; // return ok;
@ -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_ */

View File

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

View File

@ -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_'.
@ -1021,13 +1012,12 @@ static int DecodeAlphaData(VP8LDecoder* const dec, uint8_t* const data,
ok = 0; ok = 0;
goto End; goto End;
} }
br->eos_ = VP8LIsEndOfStream(br); assert(br->eos_ == VP8LIsEndOfStream(br));
} }
// Process the remaining rows corresponding to last row-block. // Process the remaining rows corresponding to last row-block.
ExtractPalettedAlphaRows(dec, row > last_row ? last_row : row); ExtractPalettedAlphaRows(dec, row > last_row ? last_row : row);
End: End:
br->eos_ = VP8LIsEndOfStream(br);
if (!ok || (br->eos_ && pos < end)) { if (!ok || (br->eos_ && pos < end)) {
ok = 0; ok = 0;
dec->status_ = br->eos_ ? VP8_STATUS_SUSPENDED dec->status_ = br->eos_ ? VP8_STATUS_SUSPENDED
@ -1100,12 +1090,11 @@ static int DecodeImageData(VP8LDecoder* const dec, uint32_t* const data,
VP8LFillBitWindow(br); VP8LFillBitWindow(br);
if (htree_group->use_packed_table) { if (htree_group->use_packed_table) {
code = ReadPackedSymbols(htree_group, br, src); code = ReadPackedSymbols(htree_group, br, src);
if (VP8LIsEndOfStream(br)) break;
if (code == PACKED_NON_LITERAL_CODE) goto AdvanceByOne; if (code == PACKED_NON_LITERAL_CODE) goto AdvanceByOne;
} else { } else {
code = ReadSymbol(htree_group->htrees[GREEN], br); code = ReadSymbol(htree_group->htrees[GREEN], br);
} }
if (VP8LIsEndOfStream(br)) break; if (br->eos_) break; // early out
if (code < NUM_LITERAL_CODES) { // Literal if (code < NUM_LITERAL_CODES) { // Literal
if (htree_group->is_trivial_literal) { if (htree_group->is_trivial_literal) {
*src = htree_group->literal_arb | (code << 8); *src = htree_group->literal_arb | (code << 8);
@ -1115,7 +1104,7 @@ static int DecodeImageData(VP8LDecoder* const dec, uint32_t* const data,
VP8LFillBitWindow(br); VP8LFillBitWindow(br);
blue = ReadSymbol(htree_group->htrees[BLUE], br); blue = ReadSymbol(htree_group->htrees[BLUE], br);
alpha = ReadSymbol(htree_group->htrees[ALPHA], br); alpha = ReadSymbol(htree_group->htrees[ALPHA], br);
if (VP8LIsEndOfStream(br)) break; if (br->eos_) break;
*src = ((uint32_t)alpha << 24) | (red << 16) | (code << 8) | blue; *src = ((uint32_t)alpha << 24) | (red << 16) | (code << 8) | blue;
} }
AdvanceByOne: AdvanceByOne:
@ -1143,7 +1132,7 @@ static int DecodeImageData(VP8LDecoder* const dec, uint32_t* const data,
VP8LFillBitWindow(br); VP8LFillBitWindow(br);
dist_code = GetCopyDistance(dist_symbol, br); dist_code = GetCopyDistance(dist_symbol, br);
dist = PlaneCodeToDistance(width, dist_code); dist = PlaneCodeToDistance(width, dist_code);
if (VP8LIsEndOfStream(br)) break; if (br->eos_) break;
if (src - data < (ptrdiff_t)dist || src_end - src < (ptrdiff_t)length) { if (src - data < (ptrdiff_t)dist || src_end - src < (ptrdiff_t)length) {
goto Error; goto Error;
} else { } else {
@ -1180,9 +1169,9 @@ static int DecodeImageData(VP8LDecoder* const dec, uint32_t* const data,
} else { // Not reached } else { // Not reached
goto Error; goto Error;
} }
assert(br->eos_ == VP8LIsEndOfStream(br));
} }
br->eos_ = VP8LIsEndOfStream(br);
if (dec->incremental_ && br->eos_ && src < src_end) { if (dec->incremental_ && br->eos_ && src < src_end) {
RestoreState(dec); RestoreState(dec);
} else if (!br->eos_) { } else if (!br->eos_) {
@ -1641,19 +1630,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();

View File

@ -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_ */

View File

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

View File

@ -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_ */

View File

@ -1,4 +1,3 @@
AM_CPPFLAGS += -I$(top_builddir) -I$(top_srcdir)
lib_LTLIBRARIES = libwebpdemux.la lib_LTLIBRARIES = libwebpdemux.la
libwebpdemux_la_SOURCES = libwebpdemux_la_SOURCES =
@ -10,6 +9,6 @@ libwebpdemuxinclude_HEADERS += ../webp/mux_types.h
libwebpdemuxinclude_HEADERS += ../webp/types.h libwebpdemuxinclude_HEADERS += ../webp/types.h
libwebpdemux_la_LIBADD = ../libwebp.la libwebpdemux_la_LIBADD = ../libwebp.la
libwebpdemux_la_LDFLAGS = -no-undefined -version-info 2:3: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

View File

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

View File

@ -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 0 #define DMUX_MAJ_VERSION 0
#define DMUX_MIN_VERSION 3 #define DMUX_MIN_VERSION 3
#define DMUX_REV_VERSION 3 #define DMUX_REV_VERSION 2
typedef struct { typedef struct {
size_t start_; // start location of the data size_t start_; // start location of the data
@ -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.

View File

@ -6,8 +6,8 @@
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
VS_VERSION_INFO VERSIONINFO VS_VERSION_INFO VERSIONINFO
FILEVERSION 0,3,0,3 FILEVERSION 0,3,0,2
PRODUCTVERSION 0,3,0,3 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", "0.3.3" VALUE "FileVersion", "0.3.2"
VALUE "InternalName", "libwebpdemux.dll" VALUE "InternalName", "libwebpdemux.dll"
VALUE "LegalCopyright", "Copyright (C) 2017" 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", "0.3.3" VALUE "ProductVersion", "0.3.2"
END END
END END
BLOCK "VarFileInfo" BLOCK "VarFileInfo"

View File

@ -1,15 +1,8 @@
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 += 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 +39,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
@ -55,7 +50,6 @@ ENC_SOURCES += enc_mips_dsp_r2.c
ENC_SOURCES += lossless_enc.c ENC_SOURCES += lossless_enc.c
ENC_SOURCES += lossless_enc_mips32.c ENC_SOURCES += lossless_enc_mips32.c
ENC_SOURCES += lossless_enc_mips_dsp_r2.c ENC_SOURCES += lossless_enc_mips_dsp_r2.c
ENC_SOURCES += ssim.c
libwebpdsp_avx2_la_SOURCES = libwebpdsp_avx2_la_SOURCES =
libwebpdsp_avx2_la_SOURCES += enc_avx2.c libwebpdsp_avx2_la_SOURCES += enc_avx2.c
@ -65,8 +59,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)
@ -89,7 +81,6 @@ libwebpdspdecode_neon_la_SOURCES += lossless_neon.c
libwebpdspdecode_neon_la_SOURCES += neon.h libwebpdspdecode_neon_la_SOURCES += neon.h
libwebpdspdecode_neon_la_SOURCES += rescaler_neon.c libwebpdspdecode_neon_la_SOURCES += rescaler_neon.c
libwebpdspdecode_neon_la_SOURCES += upsampling_neon.c libwebpdspdecode_neon_la_SOURCES += upsampling_neon.c
libwebpdspdecode_neon_la_SOURCES += yuv_neon.c
libwebpdspdecode_neon_la_CPPFLAGS = $(libwebpdsp_neon_la_CPPFLAGS) libwebpdspdecode_neon_la_CPPFLAGS = $(libwebpdsp_neon_la_CPPFLAGS)
libwebpdspdecode_neon_la_CFLAGS = $(libwebpdsp_neon_la_CFLAGS) libwebpdspdecode_neon_la_CFLAGS = $(libwebpdsp_neon_la_CFLAGS)
@ -104,10 +95,10 @@ libwebpdspdecode_msa_la_CPPFLAGS = $(libwebpdsp_msa_la_CPPFLAGS)
libwebpdspdecode_msa_la_CFLAGS = $(libwebpdsp_msa_la_CFLAGS) libwebpdspdecode_msa_la_CFLAGS = $(libwebpdsp_msa_la_CFLAGS)
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
libwebpdsp_sse2_la_SOURCES += ssim_sse2.c
libwebpdsp_sse2_la_CPPFLAGS = $(libwebpdsp_la_CPPFLAGS) libwebpdsp_sse2_la_CPPFLAGS = $(libwebpdsp_la_CPPFLAGS)
libwebpdsp_sse2_la_CFLAGS = $(AM_CFLAGS) $(SSE2_FLAGS) libwebpdsp_sse2_la_CFLAGS = $(AM_CFLAGS) $(SSE2_FLAGS)
libwebpdsp_sse2_la_LIBADD = libwebpdspdecode_sse2.la libwebpdsp_sse2_la_LIBADD = libwebpdspdecode_sse2.la
@ -141,11 +132,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

View File

@ -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
@ -137,7 +134,7 @@ static WEBP_INLINE uint32_t GetScale(uint32_t a, int inverse) {
#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,7 +154,7 @@ void WebPMultARGBRow_C(uint32_t* const ptr, int width, int inverse) {
} }
} }
void WebPMultRow_C(uint8_t* const ptr, const uint8_t* const alpha, void WebPMultRowC(uint8_t* const ptr, const uint8_t* const alpha,
int width, int inverse) { int width, int inverse) {
int x; int x;
for (x = 0; x < width; ++x) { for (x = 0; x < width; ++x) {
@ -220,8 +217,7 @@ void WebPMultRows(uint8_t* ptr, int stride,
#define PREMULTIPLY(x, m) (((x) * (m) + (1U << 23)) >> 24) #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);
@ -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,7 +254,7 @@ 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) {
@ -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
@ -415,24 +360,15 @@ static volatile VP8CPUInfo alpha_processing_last_cpuinfo_used =
WEBP_TSAN_IGNORE_FUNCTION void WebPInitAlphaProcessing(void) { WEBP_TSAN_IGNORE_FUNCTION void WebPInitAlphaProcessing(void) {
if (alpha_processing_last_cpuinfo_used == VP8GetCPUInfo) return; if (alpha_processing_last_cpuinfo_used == VP8GetCPUInfo) return;
WebPMultARGBRow = WebPMultARGBRow_C; WebPMultARGBRow = WebPMultARGBRowC;
WebPMultRow = WebPMultRow_C; WebPMultRow = WebPMultRowC;
WebPApplyAlphaMultiply4444 = ApplyAlphaMultiply_16b_C; 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) {
@ -446,34 +382,16 @@ WEBP_TSAN_IGNORE_FUNCTION void WebPInitAlphaProcessing(void) {
#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
} }
#if defined(WEBP_USE_NEON)
if (WEBP_NEON_OMIT_C_CODE ||
(VP8GetCPUInfo != NULL && VP8GetCPUInfo(kNEON))) {
WebPInitAlphaProcessingNEON();
}
#endif
assert(WebPMultARGBRow != NULL);
assert(WebPMultRow != NULL);
assert(WebPApplyAlphaMultiply != NULL);
assert(WebPApplyAlphaMultiply4444 != NULL);
assert(WebPDispatchAlpha != NULL);
assert(WebPDispatchAlphaToGreen != NULL);
assert(WebPExtractAlpha != NULL);
assert(WebPExtractGreen != NULL);
#ifdef WORDS_BIGENDIAN
assert(WebPPackARGB != NULL);
#endif
assert(WebPPackRGB != NULL);
assert(WebPHasAlpha8b != NULL);
assert(WebPHasAlpha32b != NULL);
alpha_processing_last_cpuinfo_used = VP8GetCPUInfo; alpha_processing_last_cpuinfo_used = VP8GetCPUInfo;
} }

View File

@ -12,11 +12,11 @@
// 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;
@ -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

View File

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

View File

@ -11,14 +11,14 @@
// //
// 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
@ -72,7 +72,7 @@ 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;
@ -98,7 +98,7 @@ static void DispatchAlphaToGreen_SSE2(const uint8_t* alpha, int alpha_stride,
} }
} }
static int ExtractAlpha_SSE2(const uint8_t* argb, int argb_stride, static int ExtractAlpha(const uint8_t* argb, int argb_stride,
int width, int height, 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
@ -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

View File

@ -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,7 +19,7 @@
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
static int ExtractAlpha_SSE41(const uint8_t* argb, int argb_stride, static int ExtractAlpha(const uint8_t* argb, int argb_stride,
int width, int height, 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
@ -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
View 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
View 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

67
src/dsp/argb_sse2.c Normal file
View File

@ -0,0 +1,67 @@
// 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"
#if defined(WEBP_USE_SSE2)
#include <assert.h>
#include <emmintrin.h>
#include <string.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) {
if (g == r + 1) { // RGBA input order. Need to swap R and B.
int i = 0;
const int len_max = len & ~3; // max length processed in main loop
const __m128i red_blue_mask = _mm_set1_epi32(0x00ff00ffu);
assert(b == r + 2);
assert(a == r + 3);
for (; i < len_max; i += 4) {
const __m128i A = _mm_loadu_si128((const __m128i*)(r + 4 * i));
const __m128i B = _mm_and_si128(A, red_blue_mask); // R 0 B 0
const __m128i C = _mm_andnot_si128(red_blue_mask, A); // 0 G 0 A
const __m128i D = _mm_shufflelo_epi16(B, _MM_SHUFFLE(2, 3, 0, 1));
const __m128i E = _mm_shufflehi_epi16(D, _MM_SHUFFLE(2, 3, 0, 1));
const __m128i F = _mm_or_si128(E, C);
_mm_storeu_si128((__m128i*)(out + i), F);
}
for (; i < len; ++i) {
out[i] = MakeARGB32(a[4 * i], r[4 * i], g[4 * i], b[4 * i]);
}
} else {
assert(g == b + 1);
assert(r == b + 2);
assert(a == b + 3);
memcpy(out, b, len * 4);
}
}
//------------------------------------------------------------------------------
// Entry point
extern void VP8EncDspARGBInitSSE2(void);
WEBP_TSAN_IGNORE_FUNCTION void VP8EncDspARGBInitSSE2(void) {
VP8PackARGB = PackARGB;
}
#else // !WEBP_USE_SSE2
WEBP_DSP_INIT_STUB(VP8EncDspARGBInitSSE2)
#endif // WEBP_USE_SSE2

View File

@ -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,7 +159,7 @@ 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) {

View File

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

View File

@ -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,7 +354,7 @@ 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;
@ -384,8 +384,8 @@ static volatile VP8CPUInfo cost_last_cpuinfo_used =
WEBP_TSAN_IGNORE_FUNCTION void VP8EncDspCostInit(void) { WEBP_TSAN_IGNORE_FUNCTION void VP8EncDspCostInit(void) {
if (cost_last_cpuinfo_used == VP8GetCPUInfo) return; if (cost_last_cpuinfo_used == VP8GetCPUInfo) return;
VP8GetResidualCost = GetResidualCost_C; VP8GetResidualCost = GetResidualCost;
VP8SetResidualCoeffs = SetResidualCoeffs_C; 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) {

View File

@ -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,7 +96,7 @@ 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;
@ -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

View File

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

View File

@ -11,18 +11,18 @@
// //
// 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));
@ -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

View File

@ -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>
@ -143,7 +143,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;

View File

@ -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,21 +503,17 @@ 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];
@ -544,158 +523,139 @@ 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 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 {
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_C(u, 1, stride, 8, thresh, ithresh, hev_thresh); FilterLoop26(u, 1, stride, 8, thresh, ithresh, hev_thresh);
FilterLoop26_C(v, 1, stride, 8, thresh, ithresh, hev_thresh); FilterLoop26(v, 1, stride, 8, thresh, ithresh, hev_thresh);
} }
#endif // !WEBP_NEON_OMIT_C_CODE || WEBP_NEON_WORK_AROUND_GCC
#if !WEBP_NEON_OMIT_C_CODE static void VFilter8i(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_C(u + 4 * stride, stride, 1, 8, thresh, ithresh, hev_thresh); FilterLoop24(u + 4 * stride, stride, 1, 8, thresh, ithresh, hev_thresh);
FilterLoop24_C(v + 4 * stride, stride, 1, 8, thresh, ithresh, hev_thresh); FilterLoop24(v + 4 * stride, stride, 1, 8, thresh, ithresh, hev_thresh);
} }
#endif // !WEBP_NEON_OMIT_C_CODE
#if !WEBP_NEON_OMIT_C_CODE || WEBP_NEON_WORK_AROUND_GCC static void HFilter8i(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_C(u + 4, 1, stride, 8, thresh, ithresh, hev_thresh); FilterLoop24(u + 4, 1, stride, 8, thresh, ithresh, hev_thresh);
FilterLoop24_C(v + 4, 1, stride, 8, thresh, ithresh, hev_thresh); FilterLoop24(v + 4, 1, stride, 8, thresh, ithresh, hev_thresh);
} }
#endif // !WEBP_NEON_OMIT_C_CODE || WEBP_NEON_WORK_AROUND_GCC
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
static void DitherCombine8x8_C(const uint8_t* dither, uint8_t* dst, static void DitherCombine8x8(const uint8_t* dither, uint8_t* dst,
int dst_stride) { int dst_stride) {
int i, j; int i, j;
for (j = 0; j < 8; ++j) { for (j = 0; j < 8; ++j) {
@ -749,66 +709,54 @@ WEBP_TSAN_IGNORE_FUNCTION void VP8DspInit(void) {
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) {
@ -822,6 +770,11 @@ WEBP_TSAN_IGNORE_FUNCTION void VP8DspInit(void) {
#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();
@ -838,57 +791,5 @@ WEBP_TSAN_IGNORE_FUNCTION void VP8DspInit(void) {
} }
#endif #endif
} }
#if defined(WEBP_USE_NEON)
if (WEBP_NEON_OMIT_C_CODE ||
(VP8GetCPUInfo != NULL && VP8GetCPUInfo(kNEON))) {
VP8DspInitNEON();
}
#endif
assert(VP8TransformWHT != NULL);
assert(VP8Transform != NULL);
assert(VP8TransformDC != NULL);
assert(VP8TransformAC3 != NULL);
assert(VP8TransformUV != NULL);
assert(VP8TransformDCUV != NULL);
assert(VP8VFilter16 != NULL);
assert(VP8HFilter16 != NULL);
assert(VP8VFilter8 != NULL);
assert(VP8HFilter8 != NULL);
assert(VP8VFilter16i != NULL);
assert(VP8HFilter16i != NULL);
assert(VP8VFilter8i != NULL);
assert(VP8HFilter8i != NULL);
assert(VP8SimpleVFilter16 != NULL);
assert(VP8SimpleHFilter16 != NULL);
assert(VP8SimpleVFilter16i != NULL);
assert(VP8SimpleHFilter16i != NULL);
assert(VP8PredLuma4[0] != NULL);
assert(VP8PredLuma4[1] != NULL);
assert(VP8PredLuma4[2] != NULL);
assert(VP8PredLuma4[3] != NULL);
assert(VP8PredLuma4[4] != NULL);
assert(VP8PredLuma4[5] != NULL);
assert(VP8PredLuma4[6] != NULL);
assert(VP8PredLuma4[7] != NULL);
assert(VP8PredLuma4[8] != NULL);
assert(VP8PredLuma4[9] != NULL);
assert(VP8PredLuma16[0] != NULL);
assert(VP8PredLuma16[1] != NULL);
assert(VP8PredLuma16[2] != NULL);
assert(VP8PredLuma16[3] != NULL);
assert(VP8PredLuma16[4] != NULL);
assert(VP8PredLuma16[5] != NULL);
assert(VP8PredLuma16[6] != NULL);
assert(VP8PredChroma8[0] != NULL);
assert(VP8PredChroma8[1] != NULL);
assert(VP8PredChroma8[2] != NULL);
assert(VP8PredChroma8[3] != NULL);
assert(VP8PredChroma8[4] != NULL);
assert(VP8PredChroma8[5] != NULL);
assert(VP8PredChroma8[6] != NULL);
assert(VP8DitherCombine8x8 != NULL);
dec_last_cpuinfo_used = VP8GetCPUInfo; dec_last_cpuinfo_used = VP8GetCPUInfo;
} }

View File

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

View File

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

Some files were not shown because too many files have changed in this diff Show More