aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2023-01-19 04:22:13 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2023-01-19 04:22:13 +0000
commitba397c49b64685e0b1f6fa462fdb1cd228b5889b (patch)
treee32852e48e7a969f8f46e0116c165bd92a5ec3ac
parentc0b7cc8510409b808239fb4c9cc9c5d1e08fc250 (diff)
parent11fa439dd43046c24dcae92f16f1e18312c481e3 (diff)
downloadwebp-ba397c49b64685e0b1f6fa462fdb1cd228b5889b.tar.gz
Snap for 9505375 from 11fa439dd43046c24dcae92f16f1e18312c481e3 to udc-release
Change-Id: I6cffad183760d67daad95974949b5c38991ec316
-rw-r--r--AUTHORS2
-rw-r--r--Android.bp1
-rw-r--r--Android.mk12
-rw-r--r--CMakeLists.txt531
-rw-r--r--ChangeLog147
-rw-r--r--METADATA8
-rw-r--r--Makefile.vc44
-rw-r--r--NEWS14
-rw-r--r--README.android8
-rw-r--r--README.md2
-rw-r--r--README.version4
-rw-r--r--build.gradle1
-rw-r--r--cmake/WebPConfig.cmake.in5
-rw-r--r--cmake/cpu.cmake27
-rw-r--r--cmake/deps.cmake53
-rw-r--r--configure.ac6
-rw-r--r--doc/api.md2
-rw-r--r--doc/webp-container-spec.txt223
-rw-r--r--doc/webp-lossless-bitstream-spec.txt789
-rw-r--r--examples/Android.mk3
-rw-r--r--examples/Makefile.am2
-rw-r--r--examples/cwebp.c12
-rw-r--r--extras/extras.c4
-rw-r--r--extras/vwebp_sdl.c2
-rw-r--r--extras/webp_to_sdl.c2
-rw-r--r--extras/webp_to_sdl.h4
-rw-r--r--imageio/Android.mk3
-rw-r--r--imageio/pnmdec.c7
-rw-r--r--makefile.unix33
-rw-r--r--sharpyuv/Makefile.am17
-rw-r--r--sharpyuv/libsharpyuv.pc.in11
-rw-r--r--sharpyuv/libsharpyuv.rc41
-rw-r--r--sharpyuv/sharpyuv.c58
-rw-r--r--sharpyuv/sharpyuv.h38
-rw-r--r--sharpyuv/sharpyuv_cpu.c14
-rw-r--r--sharpyuv/sharpyuv_cpu.h22
-rw-r--r--sharpyuv/sharpyuv_csp.c2
-rw-r--r--sharpyuv/sharpyuv_csp.h7
-rw-r--r--sharpyuv/sharpyuv_dsp.c17
-rw-r--r--sharpyuv/sharpyuv_dsp.h7
-rw-r--r--sharpyuv/sharpyuv_gamma.c1
-rw-r--r--sharpyuv/sharpyuv_gamma.h2
-rw-r--r--sharpyuv/sharpyuv_neon.c9
-rw-r--r--sharpyuv/sharpyuv_sse2.c7
-rw-r--r--src/Makefile.am4
-rw-r--r--src/dec/vp8i_dec.h4
-rw-r--r--src/dec/vp8l_dec.c2
-rw-r--r--src/dec/webp_dec.c2
-rw-r--r--src/demux/Makefile.am2
-rw-r--r--src/demux/demux.c4
-rw-r--r--src/demux/libwebpdemux.pc.in2
-rw-r--r--src/demux/libwebpdemux.rc8
-rw-r--r--src/dsp/alpha_processing_sse2.c12
-rw-r--r--src/dsp/alpha_processing_sse41.c2
-rw-r--r--src/dsp/cpu.c2
-rw-r--r--src/dsp/cpu.h2
-rw-r--r--src/dsp/dec_sse2.c93
-rw-r--r--src/dsp/dec_sse41.c2
-rw-r--r--src/dsp/enc_neon.c9
-rw-r--r--src/dsp/enc_sse2.c67
-rw-r--r--src/dsp/lossless.c12
-rw-r--r--src/dsp/lossless_enc.c18
-rw-r--r--src/dsp/lossless_enc_sse2.c8
-rw-r--r--src/dsp/lossless_sse2.c88
-rw-r--r--src/dsp/lossless_sse41.c7
-rw-r--r--src/dsp/quant.h13
-rw-r--r--src/dsp/rescaler_sse2.c6
-rw-r--r--src/dsp/upsampling_sse2.c2
-rw-r--r--src/dsp/yuv_sse2.c13
-rw-r--r--src/dsp/yuv_sse41.c6
-rw-r--r--src/enc/analysis_enc.c8
-rw-r--r--src/enc/picture_csp_enc.c29
-rw-r--r--src/enc/picture_rescale_enc.c25
-rw-r--r--src/enc/vp8i_enc.h4
-rw-r--r--src/enc/vp8l_enc.c11
-rw-r--r--src/libwebp.pc.in3
-rw-r--r--src/libwebp.rc8
-rw-r--r--src/libwebpdecoder.pc.in2
-rw-r--r--src/libwebpdecoder.rc8
-rw-r--r--src/mux/Makefile.am2
-rw-r--r--src/mux/libwebpmux.pc.in2
-rw-r--r--src/mux/libwebpmux.rc8
-rw-r--r--src/mux/muxi.h4
-rw-r--r--src/utils/bit_reader_inl_utils.h4
-rw-r--r--src/utils/huffman_utils.c2
-rw-r--r--src/utils/utils.h12
-rw-r--r--src/webp/format_constants.h2
-rw-r--r--src/webp/types.h6
-rw-r--r--tests/fuzzer/makefile.unix1
-rw-r--r--webp_js/README.md19
-rw-r--r--webp_js/index.html2
-rw-r--r--webp_js/index_wasm.html2
-rwxr-xr-xxcframeworkbuild.sh2
93 files changed, 1584 insertions, 1176 deletions
diff --git a/AUTHORS b/AUTHORS
index 3efcbe25..2f0c537d 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -11,11 +11,13 @@ Contributors:
- Djordje Pesut (djordje dot pesut at imgtec dot com)
- Frank Barchard (fbarchard at google dot com)
- Hui Su (huisu at google dot com)
+- H. Vetinari (h dot vetinari at gmx dot com)
- Ilya Kurdyukov (jpegqs at gmail dot com)
- Ingvar Stepanyan (rreverser at google dot com)
- James Zern (jzern at google dot com)
- Jan Engelhardt (jengelh at medozas dot de)
- Jehan (jehan at girinstud dot io)
+- Jeremy Maitin-Shepard (jbms at google dot com)
- Johann Koenig (johann dot koenig at duck dot com)
- Jovan Zelincevic (jovan dot zelincevic at imgtec dot com)
- Jyrki Alakuijala (jyrki at google dot com)
diff --git a/Android.bp b/Android.bp
index 9c950aae..ace6a9e9 100644
--- a/Android.bp
+++ b/Android.bp
@@ -61,6 +61,7 @@ cc_library_static {
host_supported: true,
srcs: [
"sharpyuv/sharpyuv.c",
+ "sharpyuv/sharpyuv_cpu.c",
"sharpyuv/sharpyuv_csp.c",
"sharpyuv/sharpyuv_dsp.c",
"sharpyuv/sharpyuv_gamma.c",
diff --git a/Android.mk b/Android.mk
index ff036834..c7bcb0f5 100644
--- a/Android.mk
+++ b/Android.mk
@@ -1,9 +1,5 @@
-# Note that the platform modules are defined in the Android.bp. This file is
-# used for the NDK.
-
-# If we're being invoked from ndk-build, we'll have NDK_ROOT defined.
+# Ignore this file during non-NDK builds.
ifdef NDK_ROOT
-
LOCAL_PATH := $(call my-dir)
WEBP_CFLAGS := -Wall -DANDROID -DHAVE_MALLOC_H -DHAVE_PTHREAD -DWEBP_USE_THREAD
@@ -41,6 +37,7 @@ endif
sharpyuv_srcs := \
sharpyuv/sharpyuv.c \
+ sharpyuv/sharpyuv_cpu.c \
sharpyuv/sharpyuv_csp.c \
sharpyuv/sharpyuv_dsp.c \
sharpyuv/sharpyuv_gamma.c \
@@ -230,7 +227,7 @@ LOCAL_SRC_FILES := \
$(utils_enc_srcs) \
LOCAL_CFLAGS := $(WEBP_CFLAGS)
-LOCAL_EXPORT_C_INCLUDES += $(LOCAL_PATH)/src
+LOCAL_EXPORT_C_INCLUDES += $(LOCAL_PATH)/src $(LOCAL_PATH)
# prefer arm over thumb mode for performance gains
LOCAL_ARM_MODE := arm
@@ -309,5 +306,4 @@ include $(WEBP_SRC_PATH)/examples/Android.mk
ifeq ($(USE_CPUFEATURES),yes)
$(call import-module,android/cpufeatures)
endif
-
-endif
+endif # NDK_ROOT
diff --git a/CMakeLists.txt b/CMakeLists.txt
index d1b120bd..0a5af428 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -6,7 +6,11 @@
# in the file PATENTS. All contributing project authors may
# be found in the AUTHORS file in the root of the source tree.
-cmake_minimum_required(VERSION 3.7)
+if(APPLE)
+ cmake_minimum_required(VERSION 3.17)
+else()
+ cmake_minimum_required(VERSION 3.7)
+endif()
if(POLICY CMP0072)
cmake_policy(SET CMP0072 NEW)
@@ -50,9 +54,9 @@ set_property(CACHE WEBP_BITTRACE PROPERTY STRINGS 0 1 2)
if(WEBP_LINK_STATIC)
if(WIN32)
- SET(CMAKE_FIND_LIBRARY_SUFFIXES .lib .a ${CMAKE_FIND_LIBRARY_SUFFIXES})
+ set(CMAKE_FIND_LIBRARY_SUFFIXES .lib .a ${CMAKE_FIND_LIBRARY_SUFFIXES})
else()
- SET(CMAKE_FIND_LIBRARY_SUFFIXES .a ${CMAKE_FIND_LIBRARY_SUFFIXES})
+ set(CMAKE_FIND_LIBRARY_SUFFIXES .a ${CMAKE_FIND_LIBRARY_SUFFIXES})
endif()
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
# vwebp does not compile on Ubuntu with static libraries so disabling it for
@@ -82,19 +86,27 @@ if(WEBP_BUILD_WEBP_JS)
endif()
endif()
+set(SHARPYUV_DEP_LIBRARIES)
+set(SHARPYUV_DEP_INCLUDE_DIRS)
set(WEBP_DEP_LIBRARIES)
set(WEBP_DEP_INCLUDE_DIRS)
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "Release"
CACHE STRING "Build type: Release, Debug, MinSizeRel or RelWithDebInfo"
- FORCE)
+ FORCE)
endif()
# Include dependencies.
include(cmake/deps.cmake)
include(GNUInstallDirs)
+if(BUILD_SHARED_LIBS AND NOT CMAKE_INSTALL_RPATH)
+ # Set the rpath to match autoconf/libtool behavior. Note this must be set
+ # before target creation.
+ set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}")
+endif()
+
# ##############################################################################
# Options.
if(WEBP_ENABLE_SWAP_16BIT_CSP)
@@ -110,26 +122,50 @@ if(WEBP_UNICODE)
add_definitions(-DUNICODE -D_UNICODE)
endif()
+if(MSVC AND BUILD_SHARED_LIBS)
+ add_definitions(-DWEBP_DLL)
+endif()
+
+# pkg-config variables used by *.pc.in.
set(prefix ${CMAKE_INSTALL_PREFIX})
-set(exec_prefix "\$\{prefix\}")
-set(libdir "\$\{prefix\}/lib")
-set(includedir "\$\{prefix\}/include")
+set(exec_prefix "\${prefix}")
+if(IS_ABSOLUTE "${CMAKE_INSTALL_LIBDIR}")
+ set(libdir "${CMAKE_INSTALL_LIBDIR}")
+else()
+ set(libdir "\${exec_prefix}/${CMAKE_INSTALL_LIBDIR}")
+endif()
+if(IS_ABSOLUTE "${CMAKE_INSTALL_INCLUDEDIR}")
+ set(includedir "${CMAKE_INSTALL_INCLUDEDIR}")
+else()
+ set(includedir "\${prefix}/${CMAKE_INSTALL_INCLUDEDIR}")
+endif()
set(PTHREAD_LIBS ${CMAKE_THREAD_LIBS_INIT})
set(INSTALLED_LIBRARIES)
+if(MSVC)
+ # match the naming convention used by nmake
+ set(webp_libname_prefix "lib")
+ set(CMAKE_SHARED_LIBRARY_PREFIX "${webp_libname_prefix}")
+ set(CMAKE_IMPORT_LIBRARY_PREFIX "${webp_libname_prefix}")
+ set(CMAKE_STATIC_LIBRARY_PREFIX "${webp_libname_prefix}")
+endif()
+
set(CMAKE_C_VISIBILITY_PRESET hidden)
# ##############################################################################
# Android only.
if(ANDROID)
include_directories(${ANDROID_NDK}/sources/android/cpufeatures)
- add_library(cpufeatures STATIC
+ add_library(cpufeatures-webp STATIC
${ANDROID_NDK}/sources/android/cpufeatures/cpu-features.c)
- list(APPEND INSTALLED_LIBRARIES cpufeatures)
- target_link_libraries(cpufeatures dl)
- set(WEBP_DEP_LIBRARIES ${WEBP_DEP_LIBRARIES} cpufeatures)
- set(WEBP_DEP_INCLUDE_DIRS ${WEBP_DEP_INCLUDE_DIRS}
- ${ANDROID_NDK}/sources/android/cpufeatures)
+ list(APPEND INSTALLED_LIBRARIES cpufeatures-webp)
+ target_link_libraries(cpufeatures-webp dl)
+ set(SHARPYUV_DEP_LIBRARIES ${SHARPYUV_DEP_LIBRARIES} cpufeatures-webp)
+ set(WEBP_DEP_LIBRARIES ${WEBP_DEP_LIBRARIES} cpufeatures-webp)
+ set(cpufeatures_include_dir ${ANDROID_NDK}/sources/android/cpufeatures)
+ set(SHARPYUV_DEP_INCLUDE_DIRS ${SHARPYUV_DEP_INCLUDE_DIRS}
+ ${cpufeatures_include_dir})
+ set(WEBP_DEP_INCLUDE_DIRS ${WEBP_DEP_INCLUDE_DIRS} ${cpufeatures_include_dir})
add_definitions(-DHAVE_CPU_FEATURES_H=1)
set(HAVE_CPU_FEATURES_H 1)
else()
@@ -138,7 +174,7 @@ endif()
function(configure_pkg_config FILE)
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/${FILE}.in"
- "${CMAKE_CURRENT_BINARY_DIR}/${FILE}")
+ "${CMAKE_CURRENT_BINARY_DIR}/${FILE}" @ONLY)
if(HAVE_MATH_LIBRARY)
# MSVC doesn't have libm
@@ -147,10 +183,8 @@ function(configure_pkg_config FILE)
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/${FILE} ${data})
endif()
- install(
- FILES "${CMAKE_CURRENT_BINARY_DIR}/${FILE}"
- DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig
- )
+ install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${FILE}"
+ DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
endfunction()
# ##############################################################################
@@ -160,23 +194,15 @@ endfunction()
# 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)
- string(REGEX MATCHALL
- "${SRC_REGEX}_SOURCES[ ]*\\+?=[ ]+[0-9a-z\\._ ]*"
- FILES_PER_LINE
- ${MAKEFILE_AM})
+ string(REGEX MATCHALL "${SRC_REGEX}_SOURCES[ ]*\\+?=[ ]+[0-9a-z\\._ ]*"
+ FILES_PER_LINE ${MAKEFILE_AM})
set(SRCS ${${VAR}})
foreach(FILES ${FILES_PER_LINE})
string(FIND ${FILES} "=" OFFSET)
math(EXPR OFFSET "${OFFSET} + 2")
- string(SUBSTRING ${FILES}
- ${OFFSET}
- -1
- FILES)
+ string(SUBSTRING ${FILES} ${OFFSET} -1 FILES)
if(FILES)
- string(REGEX MATCHALL
- "[0-9a-z\\._]+"
- FILES
- ${FILES})
+ string(REGEX MATCHALL "[0-9a-z\\._]+" FILES ${FILES})
foreach(FILE ${FILES})
list(APPEND SRCS ${FOLDER}/${FILE})
endforeach()
@@ -205,9 +231,52 @@ endforeach()
# Generate the config.h file.
configure_file(${CMAKE_CURRENT_LIST_DIR}/cmake/config.h.in
- ${CMAKE_CURRENT_BINARY_DIR}/src/webp/config.h)
+ ${CMAKE_CURRENT_BINARY_DIR}/src/webp/config.h @ONLY)
add_definitions(-DHAVE_CONFIG_H)
+# Set the version numbers.
+macro(set_version FILE TARGET_NAME NAME_IN_MAKEFILE)
+ file(READ ${CMAKE_CURRENT_SOURCE_DIR}/${FILE} SOURCE_FILE)
+ string(REGEX MATCH
+ "${NAME_IN_MAKEFILE}_la_LDFLAGS[^\n]* -version-info [0-9:]+" TMP
+ ${SOURCE_FILE})
+ string(REGEX MATCH "[0-9:]+" TMP ${TMP})
+ string(REGEX REPLACE ":" " " LT_VERSION ${TMP})
+
+ # See the libtool docs for more information:
+ # https://www.gnu.org/software/libtool/manual/libtool.html#Updating-version-info
+ #
+ # c=<current>, a=<age>, r=<revision>
+ #
+ # libtool generates a .so file as .so.[c-a].a.r, while -version-info c:r:a is
+ # passed to libtool.
+ #
+ # We set FULL = [c-a].a.r and MAJOR = [c-a].
+ separate_arguments(LT_VERSION)
+ list(GET LT_VERSION 0 LT_CURRENT)
+ list(GET LT_VERSION 1 LT_REVISION)
+ list(GET LT_VERSION 2 LT_AGE)
+ math(EXPR LT_CURRENT_MINUS_AGE "${LT_CURRENT} - ${LT_AGE}")
+
+ set_target_properties(
+ ${TARGET_NAME}
+ PROPERTIES VERSION ${LT_CURRENT_MINUS_AGE}.${LT_AGE}.${LT_REVISION}
+ SOVERSION ${LT_CURRENT_MINUS_AGE})
+ if(APPLE)
+ # For compatibility, set MACHO_COMPATIBILITY_VERSION and
+ # MACHO_CURRENT_VERSION to match libtool. These properties were introduced
+ # in 3.17:
+ # https://cmake.org/cmake/help/latest/prop_tgt/MACHO_COMPATIBILITY_VERSION.html
+ math(EXPR LIBWEBP_MACHO_COMPATIBILITY_VERSION "${LT_CURRENT} + 1")
+ set_target_properties(
+ ${TARGET_NAME}
+ PROPERTIES MACHO_COMPATIBILITY_VERSION
+ ${LIBWEBP_MACHO_COMPATIBILITY_VERSION}
+ MACHO_CURRENT_VERSION
+ ${LIBWEBP_MACHO_COMPATIBILITY_VERSION}.${LT_REVISION})
+ endif()
+endmacro()
+
# ##############################################################################
# Build the webpdecoder library.
@@ -216,13 +285,12 @@ add_definitions(-DHAVE_CONFIG_H)
#
# See also:
# https://cmake.org/cmake/help/v3.18/command/add_library.html#object-libraries
-# "Some native build systems (such as Xcode) may not like targets that have
-# only object files, so consider adding at least one real source file to any
-# target that references $<TARGET_OBJECTS:objlib>."
+# "Some native build systems (such as Xcode) may not like targets that have only
+# object files, so consider adding at least one real source file to any target
+# that references $<TARGET_OBJECTS:objlib>."
function(libwebp_add_stub_file TARGET)
set(stub_source_dir "${CMAKE_BINARY_DIR}")
- set(stub_source_file
- "${stub_source_dir}/libwebp_${TARGET}_stub.c")
+ set(stub_source_file "${stub_source_dir}/libwebp_${TARGET}_stub.c")
set(stub_source_code
"// Generated file. DO NOT EDIT!\n"
"// C source file created for target ${TARGET}.\n"
@@ -233,51 +301,55 @@ function(libwebp_add_stub_file TARGET)
target_sources(${TARGET} PRIVATE ${stub_source_file})
endfunction()
-parse_makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/sharpyuv "WEBP_SHARPYUV_SRCS"
- "")
-add_library(sharpyuv OBJECT ${WEBP_SHARPYUV_SRCS})
-target_include_directories(sharpyuv
- PRIVATE ${CMAKE_CURRENT_BINARY_DIR}
- ${CMAKE_CURRENT_SOURCE_DIR})
+parse_makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/sharpyuv "WEBP_SHARPYUV_SRCS" "")
+add_library(sharpyuv ${WEBP_SHARPYUV_SRCS})
+target_link_libraries(sharpyuv ${SHARPYUV_DEP_LIBRARIES})
+set_version(sharpyuv/Makefile.am sharpyuv sharpyuv)
+target_include_directories(
+ sharpyuv PRIVATE ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}/src)
set_target_properties(
sharpyuv
PROPERTIES PUBLIC_HEADER "${CMAKE_CURRENT_SOURCE_DIR}/sharpyuv/sharpyuv.h;\
-${CMAKE_CURRENT_SOURCE_DIR}/sharpyuv/sharpyuv_csp.h;\
-${CMAKE_CURRENT_SOURCE_DIR}/src/webp/types.h")
+${CMAKE_CURRENT_SOURCE_DIR}/sharpyuv/sharpyuv_csp.h")
+configure_pkg_config("sharpyuv/libsharpyuv.pc")
+install(
+ TARGETS sharpyuv
+ EXPORT ${PROJECT_NAME}Targets
+ PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/webp/sharpyuv
+ INCLUDES
+ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
+ ${CMAKE_INSTALL_INCLUDEDIR}/webp
+ ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
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_compile_options(-Wall)
endif()
include_directories(${WEBP_DEP_INCLUDE_DIRS})
add_library(webpdecode OBJECT ${WEBP_DEC_SRCS})
-target_include_directories(webpdecode
- PRIVATE ${CMAKE_CURRENT_BINARY_DIR}
- ${CMAKE_CURRENT_SOURCE_DIR})
+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_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>)
if(XCODE)
libwebp_add_stub_file(webpdecoder)
endif()
target_link_libraries(webpdecoder ${WEBP_DEP_LIBRARIES})
target_include_directories(
- webpdecoder
- PRIVATE ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}
+ 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(
@@ -289,39 +361,26 @@ configure_pkg_config("src/libwebpdecoder.pc")
# 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:sharpyuv>
- $<TARGET_OBJECTS:webpdecode>
- $<TARGET_OBJECTS:webpdsp>
- $<TARGET_OBJECTS:webpencode>
- $<TARGET_OBJECTS:webputils>)
+target_include_directories(
+ webpencode PRIVATE ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}/src)
+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 sharpyuv)
if(XCODE)
libwebp_add_stub_file(webp)
endif()
target_link_libraries(webp ${WEBP_DEP_LIBRARIES})
target_include_directories(
- webp
- PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
- ${CMAKE_CURRENT_BINARY_DIR}
+ webp PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}
PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>
$<INSTALL_INTERFACE:include>)
set_target_properties(
@@ -332,83 +391,33 @@ ${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(sharpyuv
- webpdecode
- webpdspdecode
- webputilsdecode
- webpencode
- webpdsp
- webputils
- PROPERTIES POSITION_INDEPENDENT_CODE ON)
+set_target_properties(webpdecode webpdspdecode webputilsdecode webpencode
+ webpdsp webputils PROPERTIES POSITION_INDEPENDENT_CODE ON)
configure_pkg_config("src/libwebp.pc")
# 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>)
+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;\
+ 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")
configure_pkg_config("src/demux/libwebpdemux.pc")
-# Set the version numbers.
-macro(set_version FILE TARGET_NAME NAME_IN_MAKEFILE)
- file(READ ${CMAKE_CURRENT_SOURCE_DIR}/src/${FILE} SOURCE_FILE)
- string(REGEX MATCH
- "${NAME_IN_MAKEFILE}_la_LDFLAGS[^\n]* -version-info [0-9:]+"
- TMP
- ${SOURCE_FILE})
- string(REGEX MATCH
- "[0-9:]+"
- TMP
- ${TMP})
- string(REGEX
- REPLACE ":"
- " "
- LT_VERSION
- ${TMP})
-
- # See the libtool docs for more information:
- # https://www.gnu.org/software/libtool/manual/libtool.html#Updating-version-info
- #
- # c=<current>, a=<age>, r=<revision>
- #
- # libtool generates a .so file as .so.[c-a].a.r, while -version-info c:r:a is
- # passed to libtool.
- #
- # We set FULL = [c-a].a.r and MAJOR = [c-a].
- separate_arguments(LT_VERSION)
- list(GET LT_VERSION 0 LT_CURRENT)
- list(GET LT_VERSION 1 LT_REVISION)
- list(GET LT_VERSION 2 LT_AGE)
- math(EXPR LT_CURRENT_MINUS_AGE "${LT_CURRENT} - ${LT_AGE}")
-
- set_target_properties(
- ${TARGET_NAME}
- PROPERTIES VERSION
- ${LT_CURRENT_MINUS_AGE}.${LT_AGE}.${LT_REVISION}
- SOVERSION
- ${LT_CURRENT_MINUS_AGE})
-endmacro()
-set_version(Makefile.am webp webp)
-set_version(Makefile.am webpdecoder webpdecoder)
-set_version(demux/Makefile.am webpdemux webpdemux)
+set_version(src/Makefile.am webp webp)
+set_version(src/Makefile.am webpdecoder webpdecoder)
+set_version(src/demux/Makefile.am webpdemux webpdemux)
file(READ ${CMAKE_CURRENT_SOURCE_DIR}/configure.ac CONFIGURE_FILE)
-string(REGEX MATCH
- "AC_INIT\\([^\n]*\\[[0-9\\.]+\\]"
- TMP
- ${CONFIGURE_FILE})
-string(REGEX MATCH
- "[0-9\\.]+"
- PROJECT_VERSION
- ${TMP})
+string(REGEX MATCH "AC_INIT\\([^\n]*\\[[0-9\\.]+\\]" TMP ${CONFIGURE_FILE})
+string(REGEX MATCH "[0-9\\.]+" PROJECT_VERSION ${TMP})
# Define the libraries to install.
list(APPEND INSTALLED_LIBRARIES webpdecoder webp webpdemux)
@@ -421,10 +430,8 @@ math(EXPR WEBP_SIMD_FILES_TO_INCLUDE_RANGE
foreach(I_FILE RANGE ${WEBP_SIMD_FILES_TO_INCLUDE_RANGE})
list(GET WEBP_SIMD_FILES_TO_INCLUDE ${I_FILE} FILE)
list(GET WEBP_SIMD_FLAGS_TO_INCLUDE ${I_FILE} SIMD_COMPILE_FLAG)
- set_source_files_properties(${FILE}
- PROPERTIES
- COMPILE_FLAGS
- ${SIMD_COMPILE_FLAG})
+ set_source_files_properties(${FILE} PROPERTIES COMPILE_FLAGS
+ ${SIMD_COMPILE_FLAG})
endforeach()
if(NOT WEBP_BUILD_LIBWEBPMUX)
@@ -456,8 +463,7 @@ if(WEBP_BUILD_ANIM_UTILS
list(APPEND EXAMPLEUTIL_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/examples/stopwatch.h)
add_library(exampleutil STATIC ${EXAMPLEUTIL_SRCS})
target_include_directories(
- exampleutil
- PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>)
+ exampleutil PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>)
parse_makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/imageio "IMAGEIOUTILS_SRCS"
"imageio_util_[^ ]*")
@@ -469,10 +475,7 @@ if(WEBP_BUILD_ANIM_UTILS
parse_makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/imageio "IMAGEDEC_SRCS"
"imagedec_[^ ]*")
add_library(imagedec STATIC ${IMAGEDEC_SRCS})
- target_link_libraries(imagedec
- imageioutil
- webpdemux
- webp
+ target_link_libraries(imagedec imageioutil webpdemux webp
${WEBP_DEP_IMG_LIBRARIES})
# Image-encoding utility library.
@@ -481,12 +484,10 @@ if(WEBP_BUILD_ANIM_UTILS
add_library(imageenc STATIC ${IMAGEENC_SRCS})
target_link_libraries(imageenc imageioutil webp)
- set_property(TARGET exampleutil
- imageioutil
- imagedec
- imageenc
- PROPERTY INCLUDE_DIRECTORIES ${CMAKE_CURRENT_SOURCE_DIR}/src
- ${CMAKE_CURRENT_BINARY_DIR}/src)
+ set_property(
+ TARGET exampleutil imageioutil imagedec imageenc
+ PROPERTY INCLUDE_DIRECTORIES ${CMAKE_CURRENT_SOURCE_DIR}/src
+ ${CMAKE_CURRENT_BINARY_DIR}/src)
endif()
if(WEBP_BUILD_DWEBP)
@@ -503,24 +504,25 @@ if(WEBP_BUILD_CWEBP)
parse_makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/examples "CWEBP_SRCS" "cwebp")
add_executable(cwebp ${CWEBP_SRCS})
target_link_libraries(cwebp exampleutil imagedec webp)
- target_include_directories(cwebp PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/src)
+ target_include_directories(cwebp PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/src
+ ${CMAKE_CURRENT_SOURCE_DIR})
install(TARGETS cwebp RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
endif()
if(WEBP_BUILD_LIBWEBPMUX)
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})
- set_version(mux/Makefile.am webpmux webpmux)
- set_target_properties(webpmux
- PROPERTIES PUBLIC_HEADER
- "${CMAKE_CURRENT_SOURCE_DIR}/src/webp/mux.h;\
+ add_library(libwebpmux ${WEBP_MUX_SRCS})
+ target_link_libraries(libwebpmux webp)
+ target_include_directories(libwebpmux PRIVATE ${CMAKE_CURRENT_BINARY_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR})
+ set_version(src/mux/Makefile.am libwebpmux webpmux)
+ set_target_properties(
+ libwebpmux
+ 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)
+ set_target_properties(libwebpmux PROPERTIES OUTPUT_NAME webpmux)
+ list(APPEND INSTALLED_LIBRARIES libwebpmux)
configure_pkg_config("src/mux/libwebpmux.pc")
endif()
@@ -530,11 +532,7 @@ if(WEBP_BUILD_GIF2WEBP)
parse_makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/examples "GIF2WEBP_SRCS"
"gif2webp")
add_executable(gif2webp ${GIF2WEBP_SRCS})
- target_link_libraries(gif2webp
- exampleutil
- imageioutil
- webp
- webpmux
+ target_link_libraries(gif2webp exampleutil imageioutil webp libwebpmux
${WEBP_DEP_GIF_LIBRARIES})
target_include_directories(gif2webp PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/src)
install(TARGETS gif2webp RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
@@ -546,12 +544,8 @@ if(WEBP_BUILD_IMG2WEBP)
parse_makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/examples "IMG2WEBP_SRCS"
"img2webp")
add_executable(img2webp ${IMG2WEBP_SRCS})
- target_link_libraries(img2webp
- exampleutil
- imagedec
- imageioutil
- webp
- webpmux)
+ target_link_libraries(img2webp exampleutil imagedec imageioutil webp
+ libwebpmux)
target_include_directories(img2webp PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/src)
install(TARGETS img2webp RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
endif()
@@ -563,17 +557,17 @@ if(WEBP_BUILD_VWEBP)
include_directories(${WEBP_DEP_IMG_INCLUDE_DIRS})
parse_makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/examples "VWEBP_SRCS" "vwebp")
add_executable(vwebp ${VWEBP_SRCS})
- target_link_libraries(vwebp
- ${OPENGL_LIBRARIES}
- exampleutil
- ${GLUT_glut_LIBRARY}
- imageioutil
- webp
- webpdemux)
- target_include_directories(vwebp
- PRIVATE ${GLUT_INCLUDE_DIR}
- ${CMAKE_CURRENT_BINARY_DIR}/src
- ${OPENGL_INCLUDE_DIR})
+ target_link_libraries(
+ vwebp
+ ${OPENGL_LIBRARIES}
+ exampleutil
+ GLUT::GLUT
+ imageioutil
+ webp
+ webpdemux)
+ target_include_directories(
+ vwebp PRIVATE ${GLUT_INCLUDE_DIR} ${CMAKE_CURRENT_BINARY_DIR}/src
+ ${OPENGL_INCLUDE_DIR})
install(TARGETS vwebp RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
if(${CMAKE_SYSTEM_NAME} STREQUAL "Darwin")
check_c_compiler_flag("-Wno-deprecated-declarations" HAS_NO_DEPRECATED)
@@ -591,9 +585,8 @@ if(WEBP_BUILD_WEBPINFO)
"webpinfo")
add_executable(webpinfo ${WEBPINFO_SRCS})
target_link_libraries(webpinfo exampleutil imageioutil)
- target_include_directories(webpinfo
- PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/src
- ${CMAKE_CURRENT_SOURCE_DIR}/src)
+ target_include_directories(webpinfo PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/src
+ ${CMAKE_CURRENT_SOURCE_DIR}/src)
install(TARGETS webpinfo RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
endif()
@@ -601,12 +594,10 @@ if(WEBP_BUILD_WEBPMUX)
# webpmux
parse_makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/examples "WEBPMUX_SRCS"
"webpmux")
- add_executable(webpmux_app ${WEBPMUX_SRCS})
- set_target_properties(webpmux_app PROPERTIES OUTPUT_NAME webpmux)
- target_link_libraries(webpmux_app exampleutil imageioutil webpmux webp)
- target_include_directories(webpmux_app
- PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/src)
- install(TARGETS webpmux_app RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
+ add_executable(webpmux ${WEBPMUX_SRCS})
+ target_link_libraries(webpmux exampleutil imageioutil libwebpmux webp)
+ target_include_directories(webpmux PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/src)
+ install(TARGETS webpmux RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
endif()
if(WEBP_BUILD_EXTRAS)
@@ -618,35 +609,30 @@ if(WEBP_BUILD_EXTRAS)
# libextras
add_library(extras STATIC ${WEBP_EXTRAS_SRCS})
- target_include_directories(extras
- PRIVATE ${CMAKE_CURRENT_BINARY_DIR}
- ${CMAKE_CURRENT_SOURCE_DIR}
- ${CMAKE_CURRENT_SOURCE_DIR}/src)
+ target_include_directories(
+ extras PRIVATE ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}/src)
# get_disto
add_executable(get_disto ${GET_DISTO_SRCS})
target_link_libraries(get_disto imagedec)
- target_include_directories(get_disto
- PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
- ${CMAKE_CURRENT_BINARY_DIR}/src)
+ target_include_directories(get_disto PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+ ${CMAKE_CURRENT_BINARY_DIR}/src)
# webp_quality
add_executable(webp_quality ${WEBP_QUALITY_SRCS})
target_link_libraries(webp_quality exampleutil imagedec extras)
- target_include_directories(webp_quality
- PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
- ${CMAKE_CURRENT_BINARY_DIR})
+ target_include_directories(webp_quality PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+ ${CMAKE_CURRENT_BINARY_DIR})
# vwebp_sdl
find_package(SDL)
if(WEBP_BUILD_VWEBP AND SDL_FOUND)
add_executable(vwebp_sdl ${VWEBP_SDL_SRCS})
target_link_libraries(vwebp_sdl ${SDL_LIBRARY} imageioutil webp)
- target_include_directories(vwebp_sdl
- PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
- ${CMAKE_CURRENT_BINARY_DIR}
- ${CMAKE_CURRENT_BINARY_DIR}/src
- ${SDL_INCLUDE_DIR})
+ target_include_directories(
+ vwebp_sdl PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}
+ ${CMAKE_CURRENT_BINARY_DIR}/src ${SDL_INCLUDE_DIR})
set(WEBP_HAVE_SDL 1)
target_compile_definitions(vwebp_sdl PUBLIC WEBP_HAVE_SDL)
endif()
@@ -662,9 +648,9 @@ if(WEBP_BUILD_WEBP_JS)
set(WEBP_HAVE_SDL 1)
set_target_properties(
webp_js
- PROPERTIES LINK_FLAGS "-s WASM=0 \
- -s EXPORTED_FUNCTIONS='[\"_WebpToSDL\"]' -s INVOKE_RUN=0 \
- -s EXPORTED_RUNTIME_METHODS='[\"cwrap\"]'")
+ PROPERTIES LINK_FLAGS "-sWASM=0 \
+ -sEXPORTED_FUNCTIONS=_WebPToSDL -sINVOKE_RUN=0 \
+ -sEXPORTED_RUNTIME_METHODS=cwrap")
set_target_properties(webp_js PROPERTIES OUTPUT_NAME webp)
target_compile_definitions(webp_js PUBLIC EMSCRIPTEN WEBP_HAVE_SDL)
endif()
@@ -675,9 +661,9 @@ if(WEBP_BUILD_WEBP_JS)
target_include_directories(webp_wasm PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
set_target_properties(
webp_wasm
- PROPERTIES LINK_FLAGS "-s WASM=1 \
- -s EXPORTED_FUNCTIONS='[\"_WebpToSDL\"]' -s INVOKE_RUN=0 \
- -s EXPORTED_RUNTIME_METHODS='[\"cwrap\"]'")
+ PROPERTIES LINK_FLAGS "-sWASM=1 \
+ -sEXPORTED_FUNCTIONS=_WebPToSDL -sINVOKE_RUN=0 \
+ -sEXPORTED_RUNTIME_METHODS=cwrap")
target_compile_definitions(webp_wasm PUBLIC EMSCRIPTEN WEBP_HAVE_SDL)
target_compile_definitions(webpdspdecode PUBLIC EMSCRIPTEN)
@@ -689,14 +675,15 @@ if(WEBP_BUILD_ANIM_UTILS)
parse_makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/examples "ANIM_DIFF_SRCS"
"anim_diff")
add_executable(anim_diff ${ANIM_DIFF_SRCS})
- target_link_libraries(anim_diff
- exampleutil
- imagedec
- imageenc
- imageioutil
- webp
- webpdemux
- ${WEBP_DEP_GIF_LIBRARIES})
+ target_link_libraries(
+ anim_diff
+ exampleutil
+ imagedec
+ imageenc
+ imageioutil
+ webp
+ webpdemux
+ ${WEBP_DEP_GIF_LIBRARIES})
target_include_directories(anim_diff PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/src)
# anim_dump
@@ -704,45 +691,58 @@ if(WEBP_BUILD_ANIM_UTILS)
parse_makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/examples "ANIM_DUMP_SRCS"
"anim_dump")
add_executable(anim_dump ${ANIM_DUMP_SRCS})
- target_link_libraries(anim_dump
- exampleutil
- imagedec
- imageenc
- imageioutil
- webp
- webpdemux
- ${WEBP_DEP_GIF_LIBRARIES})
+ target_link_libraries(
+ anim_dump
+ exampleutil
+ imagedec
+ imageenc
+ imageioutil
+ webp
+ webpdemux
+ ${WEBP_DEP_GIF_LIBRARIES})
target_include_directories(anim_dump PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/src)
endif()
# Install the different headers and libraries.
-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})
+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}::
+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)
+ VERSION ${PACKAGE_VERSION} COMPATIBILITY AnyNewerVersion)
# Create the Config file.
include(CMakePackageConfigHelpers)
+# Fix libwebpmux reference. The target name libwebpmux is used for compatibility
+# purposes, but the library mentioned in WebPConfig.cmake should be the
+# unprefixed version. Note string(...) can be replaced with list(TRANSFORM ...)
+# if cmake_minimum_required is >= 3.12.
+string(REGEX REPLACE "libwebpmux" "webpmux" INSTALLED_LIBRARIES
+ "${INSTALLED_LIBRARIES}")
+
+if(MSVC)
+ # For compatibility with nmake, MSVC builds use a custom prefix (lib) that
+ # needs to be included in the library name.
+ string(REGEX REPLACE "[A-Za-z0-9_]+" "${CMAKE_STATIC_LIBRARY_PREFIX}\\0"
+ INSTALLED_LIBRARIES "${INSTALLED_LIBRARIES}")
+endif()
+
configure_package_config_file(
${CMAKE_CURRENT_SOURCE_DIR}/cmake/WebPConfig.cmake.in
${CMAKE_CURRENT_BINARY_DIR}/WebPConfig.cmake
- INSTALL_DESTINATION
- ${ConfigPackageLocation})
+ INSTALL_DESTINATION ${ConfigPackageLocation})
# Install the generated CMake files.
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/WebPConfigVersion.cmake"
@@ -774,7 +774,6 @@ foreach(I_MAN RANGE ${MAN_PAGES_RANGE})
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)
+ DESTINATION ${CMAKE_INSTALL_MANDIR}/man1 COMPONENT doc)
endif()
endforeach()
diff --git a/ChangeLog b/ChangeLog
index 88739148..00ef6175 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,150 @@
+0ba77244 update NEWS
+e763eb1e bump version to 1.3.0
+2a8686fc update AUTHORS
+106a57c1 Merge "*/Android.mk: add a check for NDK_ROOT" into main
+c5e841c4 Merge "extras: WebpToSDL -> WebPToSDL" into main
+dbc30715 Merge "xcframeworkbuild.sh: bump MACOSX_CATALYST_MIN_VERSION" into main
+6fc1a9f9 */Android.mk: add a check for NDK_ROOT
+d3e151fc doc/api.md,webp_js/README.md: Webp -> WebP
+ed92a626 extras: WebpToSDL -> WebPToSDL
+6eb0189b xcframeworkbuild.sh: bump MACOSX_CATALYST_MIN_VERSION
+1d58575b CMake: align .pc variables with autoconf
+e5fe2cfc webp-lossless-bitstream-spec,cosmetics: reflow paragraphs
+0ceeeab9 webp-lossless-bitstream-spec: add amendment note
+607611cd Merge "webp-container-spec: normalize section title case" into main
+f853685e lossless: SUBTRACT_GREEN -> SUBTRACT_GREEN_TRANSFORM
+786497e4 webp-lossless-bitstream-spec: fix inv color txfm description
+c6ac672d webp-lossless-bitstream-spec: fix num_code_lengths check
+b5700efb webp-lossless-bitstream-spec,cosmetics: grammar/capitalization
+d8ed8c11 webp-container-spec: normalize section title case
+52ec0b8f Merge changes Ie975dbb5,Ifc8c93af,I6ca7c5d6,I2e8d66f5,I152477b8 into main
+5097ef62 webp-container-spec,cosmetics: grammar/capitalization
+e3ba2b1f webp-lossless-bitstream-spec,cosmetics: reflow abstract
+1e8e3ded webp-lossless-bitstream-spec: reword abstract re alpha
+017cb6fa webp-container-spec,cosmetics: normalize range syntax
+f6a4684b webp-lossless-bitstream-spec,cosmetics: normalize range syntax
+54ebd5a3 webp-lossless-bitstream-spec: limit dist map lut to 69 cols
+44741f9c webp-lossless-bitstream-spec: fix dist mapping example
+fad0ece7 pnmdec.c: use snprintf instead of sprintf
+3f73e8f7 sharpyuv: add SharpYuvGetVersion()
+ce2f2d66 SharpYuvConvert: fix a race on SharpYuvGetCPUInfo
+a458e308 sharpyuv_dsp.h: restore sharpyuv_cpu.h include
+9ba800a7 Merge changes Id72fbf3b,Ic59d23a2 into main
+979c0ebb sharpyuv: add SharpYuvGetCPUInfo
+8bab09a4 Merge "*.pc.in: rename lib_prefix to webp_libname_prefix" into main
+769387c5 cpu.c,cosmetics: fix a typo
+a02978c2 sharpyuv/Makefile.am+cmake: add missing -lm
+28aedcb9 *.pc.in: rename lib_prefix to webp_libname_prefix
+c42e6d5a configure.ac: export an empty lib_prefix variable
+dfc843aa Merge "*.pc.in: add lib prefix to lib names w/MSVC" into main
+2498209b *.pc.in: add lib prefix to lib names w/MSVC
+ac252b61 Merge "analysis_enc.c: fix a dead store warning" into main
+56944762 analysis_enc.c: fix a dead store warning
+d34f9b99 Merge "webp-lossless-bitstream-spec: convert BNF to ABNF" into main
+dc05b4db Merge changes I96bc063c,I45880467,If9e18e5a,I6ee938e4,I0a410b28, ... into main
+83270c7f webp-container-spec: add prose for rendering process
+73b19b64 webp-container-spec: note reserved fields MUST be ignored
+57101d3f webp-lossless-bitstream-spec: improve 'small' color table stmt
+dfd32e45 webp-container-spec: remove redundant sentence
+8a6185dd doc/webp-*: fix some punctuation, grammar
+72776530 webp-lossless-bitstream-spec: convert BNF to ABNF
+d992bb08 cmake: rename cpufeatures target to cpufeatures-webp
+3ed2b275 webp-container-spec: clarify background color note
+951c292d webp-container-spec: come too late -> out of order
+902dd787 webp-container-spec: prefer hex literals
+a8f6b5ee webp-container-spec: change SHOULD to MUST w/ANIM chunk
+1dc59435 webp-container-spec: add unknown fields MUST be ignored
+280a810f webp-container-spec: make padding byte=0 a MUST
+41f0bf68 webp-container-spec: update note on trailing data
+6bdd36db webp-container-spec: clarify Chunk Size is in bytes
+87e36c48 Merge "webp_js/README.md,cosmetics: reflow some lines" into main
+5b01f321 Merge "Update Windows makefile to build libsharpyuv library." into main
+19b1a71c webp_js/README.md,cosmetics: reflow some lines
+780db756 Update Windows makefile to build libsharpyuv library.
+e407d4b3 CMakeLists.txt: replace GLUT_glut_LIBRARY w/GLUT::GLUT
+abf73d62 Merge "WebPConfig.cmake.in: add find_dependency(Threads)" into main
+25807fb4 Merge "cmake: restore compatibility with cmake < 3.12" into main
+5dbc4bfa WebPConfig.cmake.in: add find_dependency(Threads)
+b2a175dd Merge "Update wasm instructions." into main
+cb90f76b Update wasm instructions.
+02d15258 cmake: restore compatibility with cmake < 3.12
+5ba046e2 CMake: add_definitions -> add_compile_options
+e68765af dsp,neon: use vaddv in a few more places
+e8f83de2 Set libsharpyuv include dir to 'webp' subdirectory.
+15a91ab1 cmake,cosmetics: apply cmake-format
+0dd49d1a CMakeLists.txt: set @ONLY in configure_file() calls
+62b1bfe8 Merge changes I2877e7bb,I777cad70,I15af7d1a,I686e6740,If10538a9, ... into main
+95c8fe5f Merge changes Iecea3603,I9dc228ab into main
+e7c805cf picture_csp_enc.c: remove SafeInitSharpYuv
+6af8845a sharpyuv: prefer webp/types.h
+639619ce cmake: fix dll exports
+782ed48c sharpyuv,SharpYuvInit: add mutex protection when available
+cad0d5ad sharyuv_{neon,sse2}.c: merge WEBP_USE_* sections
+ef70ee06 add a few missing <stddef.h> includes for NULL
+f0f9eda4 sharpyuv.h: remove <inttypes.h>
+9b902cba Merge "picture_csp_enc.c,CheckNonOpaque: rm unneeded local" into main
+9c1d457c cmake/cpu.cmake: remove unused variable
+9ac25bcb CMakeLists.txt,win32: match naming convention used by nmake
+76c353ba picture_csp_enc.c,CheckNonOpaque: rm unneeded local
+5000de54 Merge "cwebp: fix WebPPictureHasTransparency call" into main
+e1729309 Merge "WebPPictureHasTransparency: add missing pointer check" into main
+00ff988a vp8l_enc,AddSingleSubGreen: clear int sanitizer warnings
+e2fecc22 dsp/lossless_enc.c: clear int sanitizer warnings
+129cf9e9 dsp/lossless.c: clear int sanitizer warnings
+ad7d1753 dsp/lossless_enc.c: clear int sanitizer warnings
+5037220e VP8LSubtractGreenFromBlueAndRed_C: clear int sanitizer warnings
+2ee786c7 upsampling_sse2.c: clear int sanitizer warnings
+4cc157d4 ParseOptionalChunks: clear int sanitizer warning
+892cf033 BuildHuffmanTable: clear int sanitizer warning
+3a9a4d45 VP8GetSigned: clear int sanitizer warnings
+704a3d0a dsp/lossless.c: quiet int sanitizer warnings
+1a6c109c WebPPictureHasTransparency: add missing pointer check
+c626e7d5 cwebp: fix WebPPictureHasTransparency call
+866e349c Merge tag 'v1.2.4'
+c170df38 Merge "Create libsharpyuv.a in makefile.unix." into main
+9d7ff74a Create libsharpyuv.a in makefile.unix.
+0d1f1254 update ChangeLog (tag: v1.2.4, origin/1.2.4)
+fcbc2d78 Merge "doc/*.txt: restrict code to 69 columns" into main
+4ad0e189 Merge "webp-container-spec.txt: normalize fourcc spelling" into main
+980d2488 update NEWS
+9fde8127 bump version to 1.2.4
+7a0a9935 doc/*.txt: restrict code to 69 columns
+c040a615 webp-container-spec.txt: normalize fourcc spelling
+aff1c546 dsp,x86: normalize types w/_mm_cvtsi128_si32 calls
+ab540ae0 dsp,x86: normalize types w/_mm_cvtsi32_si128 calls
+8980362e dsp,x86: normalize types w/_mm_set* calls (2)
+e626925c lossless: fix crunch mode w/WEBP_REDUCE_SIZE
+83539239 dsp,x86: normalize types w/_mm_set* calls
+8a4576ce webp-container-spec.txt: replace &amp; with &
+db870881 Merge "webp-container-spec.txt: make reserved 0 values a MUST" into main
+01d7d378 webp-lossless-bitstream-spec: number all sections
+337cf69f webp-lossless-bitstream-spec: mv Nomenclature after Intro
+79be856e Merge changes I7111d1f7,I872cd62c into main
+5b87983a webp-container-spec.txt: make reserved 0 values a MUST
+bd939123 Merge changes I7a25b1a6,I51b2c2a0,I87d0cbcf,I6ec60af6,I0a3fe9dc into main
+04764b56 libwebp.pc: add libsharpyuv to requires
+7deee810 libsharpyuv: add pkg-config file
+1a64a7e6 webp-container-spec.txt: clarify some SHOULDs
+bec2c88a webp-container-spec.txt: move ChunkHeader to terminology
+c9359332 webp-container-spec.txt: clarify 'VP8 '/'XMP ' fourccs
+70fe3063 webp-container-spec.txt: rightsize table entries
+ddbf3f3f webp-container-spec.txt: update 'key words' text
+c151e95b utils.h,WEBP_ALIGN: make bitmask unsigned
+748e92bb add WebPInt32ToMem
+3fe15b67 Merge "Build libsharpyuv as a full installable library." into main
+4f402f34 add WebPMemToInt32
+a3b68c19 Build libsharpyuv as a full installable library.
+b4994eaa CMake: set rpath for shared objects
+94cd7117 Merge "CMake: fix dylib versioning" into main
+e91451b6 Fix the lossless specs a bit more.
+231bdfb7 CMake: fix dylib versioning
+bfad7ab5 CMakeLists.txt: correct libwebpmux name in WebPConfig.cmake
+c2e3fd30 Revert "cmake: fix webpmux lib name for cmake linking"
+7366f7f3 Merge "lossless: fix crunch mode w/WEBP_REDUCE_SIZE" into main
+84163d9d lossless: fix crunch mode w/WEBP_REDUCE_SIZE
+d01c1eb3 webp-lossless-bitstream-spec,cosmetics: normalize capitalization
+8813ca8e Merge tag 'v1.2.3'
+3c4a0fbf update ChangeLog (tag: v1.2.3)
56a480e8 dsp/cpu.h: add missing extern "C"
62b45bdd update ChangeLog (tag: v1.2.3-rc1)
8764ec7a Merge changes Idb037953,Id582e395 into 1.2.3
diff --git a/METADATA b/METADATA
index 558dc6a3..def00a92 100644
--- a/METADATA
+++ b/METADATA
@@ -5,11 +5,11 @@ third_party {
type: GIT
value: "https://chromium.googlesource.com/webm/libwebp"
}
- version: "v1.2.3"
+ version: "v1.3.0"
license_type: NOTICE
last_upgrade_date {
- year: 2022
- month: 11
- day: 16
+ year: 2023
+ month: 01
+ day: 13
}
}
diff --git a/Makefile.vc b/Makefile.vc
index f2541097..00d899e7 100644
--- a/Makefile.vc
+++ b/Makefile.vc
@@ -5,6 +5,7 @@ LIBWEBPDECODER_BASENAME = libwebpdecoder
LIBWEBP_BASENAME = libwebp
LIBWEBPMUX_BASENAME = libwebpmux
LIBWEBPDEMUX_BASENAME = libwebpdemux
+LIBSHARPYUV_BASENAME = libsharpyuv
!IFNDEF ARCH
!IF ! [ cl 2>&1 | find "x86" > NUL ]
@@ -96,6 +97,7 @@ LIBWEBPDECODER_BASENAME = $(LIBWEBPDECODER_BASENAME)_debug
LIBWEBP_BASENAME = $(LIBWEBP_BASENAME)_debug
LIBWEBPMUX_BASENAME = $(LIBWEBPMUX_BASENAME)_debug
LIBWEBPDEMUX_BASENAME = $(LIBWEBPDEMUX_BASENAME)_debug
+LIBSHARPYUV_BASENAME = $(LIBSHARPYUV_BASENAME)_debug
!ELSE IF "$(CFG)" == "release-dynamic"
CC = $(CCNODBG)
RC = $(RCNODBG)
@@ -109,6 +111,7 @@ LIBWEBPDECODER_BASENAME = $(LIBWEBPDECODER_BASENAME)_debug
LIBWEBP_BASENAME = $(LIBWEBP_BASENAME)_debug
LIBWEBPMUX_BASENAME = $(LIBWEBPMUX_BASENAME)_debug
LIBWEBPDEMUX_BASENAME = $(LIBWEBPDEMUX_BASENAME)_debug
+LIBSHARPYUV_BASENAME = $(LIBSHARPYUV_BASENAME)_debug
!ENDIF
!IF "$(STATICLIBBUILD)" == "TRUE"
@@ -118,13 +121,14 @@ LIBWEBPDECODER = $(DIRLIB)\$(LIBWEBPDECODER_BASENAME).lib
LIBWEBP = $(DIRLIB)\$(LIBWEBP_BASENAME).lib
LIBWEBPMUX = $(DIRLIB)\$(LIBWEBPMUX_BASENAME).lib
LIBWEBPDEMUX = $(DIRLIB)\$(LIBWEBPDEMUX_BASENAME).lib
+LIBSHARPYUV = $(DIRLIB)\$(LIBSHARPYUV_BASENAME).lib
!ELSE IF "$(DLLBUILD)" == "TRUE"
-DLLINC = webp_dll.h
-CC = $(CC) /I$(DIROBJ) /FI$(DLLINC) $(RTLIB) /DWEBP_DLL
+CC = $(CC) /I$(DIROBJ) $(RTLIB) /DWEBP_DLL
LIBWEBPDECODER = $(DIRLIB)\$(LIBWEBPDECODER_BASENAME)_dll.lib
LIBWEBP = $(DIRLIB)\$(LIBWEBP_BASENAME)_dll.lib
LIBWEBPMUX = $(DIRLIB)\$(LIBWEBPMUX_BASENAME)_dll.lib
LIBWEBPDEMUX = $(DIRLIB)\$(LIBWEBPDEMUX_BASENAME)_dll.lib
+LIBSHARPYUV = $(DIRLIB)\$(LIBSHARPYUV_BASENAME)_dll.lib
LIBWEBP_PDBNAME = $(DIROBJ)\$(LIBWEBP_BASENAME)_dll.pdb
CFGSET = TRUE
!ENDIF
@@ -176,6 +180,7 @@ CFLAGS = $(CFLAGS) /D_UNICODE /DUNICODE
SHARPYUV_OBJS = \
$(DIROBJ)\sharpyuv\sharpyuv.obj \
+ $(DIROBJ)\sharpyuv\sharpyuv_cpu.obj \
$(DIROBJ)\sharpyuv\sharpyuv_csp.obj \
$(DIROBJ)\sharpyuv\sharpyuv_dsp.obj \
$(DIROBJ)\sharpyuv\sharpyuv_gamma.obj \
@@ -343,12 +348,13 @@ UTILS_ENC_OBJS = \
$(DIROBJ)\utils\quant_levels_utils.obj \
LIBWEBPDECODER_OBJS = $(DEC_OBJS) $(DSP_DEC_OBJS) $(UTILS_DEC_OBJS)
-LIBWEBP_OBJS = $(LIBWEBPDECODER_OBJS) $(SHARPYUV_OBJS) $(ENC_OBJS) \
+LIBWEBP_OBJS = $(LIBWEBPDECODER_OBJS) $(ENC_OBJS) \
$(DSP_ENC_OBJS) $(UTILS_ENC_OBJS) $(DLL_OBJS)
LIBWEBPMUX_OBJS = $(MUX_OBJS) $(LIBWEBPMUX_OBJS)
LIBWEBPDEMUX_OBJS = $(DEMUX_OBJS) $(LIBWEBPDEMUX_OBJS)
+LIBSHARPYUV_OBJS = $(SHARPYUV_OBJS)
-OUT_LIBS = $(LIBWEBPDECODER) $(LIBWEBP)
+OUT_LIBS = $(LIBWEBPDECODER) $(LIBWEBP) $(LIBSHARPYUV)
!IF "$(ARCH)" == "ARM"
ex: $(OUT_LIBS)
all: ex
@@ -376,7 +382,7 @@ $(DIRBIN)\anim_dump.exe: $(EX_GIF_DEC_OBJS) $(LIBWEBPDEMUX) $(LIBWEBP)
$(DIRBIN)\anim_dump.exe: $(IMAGEIO_ENC_OBJS)
$(DIRBIN)\cwebp.exe: $(DIROBJ)\examples\cwebp.obj $(IMAGEIO_DEC_OBJS)
$(DIRBIN)\cwebp.exe: $(IMAGEIO_UTIL_OBJS)
-$(DIRBIN)\cwebp.exe: $(LIBWEBPDEMUX)
+$(DIRBIN)\cwebp.exe: $(LIBWEBPDEMUX) $(LIBSHARPYUV)
$(DIRBIN)\dwebp.exe: $(DIROBJ)\examples\dwebp.obj $(IMAGEIO_DEC_OBJS)
$(DIRBIN)\dwebp.exe: $(IMAGEIO_ENC_OBJS)
$(DIRBIN)\dwebp.exe: $(IMAGEIO_UTIL_OBJS)
@@ -417,17 +423,16 @@ $(EX_UTIL_OBJS) $(IMAGEIO_UTIL_OBJS): $(OUTPUT_DIRS)
$(IMAGEIO_DEC_OBJS) $(IMAGEIO_ENC_OBJS) $(EXTRAS_OBJS): $(OUTPUT_DIRS)
!ENDIF # ARCH == ARM
+$(LIBSHARPYUV): $(LIBSHARPYUV_OBJS)
$(LIBWEBPDECODER): $(LIBWEBPDECODER_OBJS)
-$(LIBWEBP): $(LIBWEBP_OBJS)
+$(LIBWEBP): $(LIBWEBP_OBJS) $(LIBSHARPYUV)
$(LIBWEBPMUX): $(LIBWEBPMUX_OBJS)
$(LIBWEBPDEMUX): $(LIBWEBPDEMUX_OBJS)
-$(LIBWEBP_OBJS) $(LIBWEBPMUX_OBJS) $(LIBWEBPDEMUX_OBJS): $(OUTPUT_DIRS)
+$(LIBWEBP_OBJS) $(LIBWEBPMUX_OBJS) $(LIBWEBPDEMUX_OBJS) $(LIBSHARPYUV_OBJS): \
+ $(OUTPUT_DIRS)
!IF "$(DLLBUILD)" == "TRUE"
-$(LIBWEBP_OBJS) $(LIBWEBPMUX_OBJS) $(LIBWEBPDEMUX_OBJS): \
- $(DIROBJ)\$(DLLINC)
-
{$(DIROBJ)}.c{$(DIROBJ)}.obj:
$(CC) $(CFLAGS) /Fd$(LIBWEBP_PDBNAME) /Fo$@ $<
@@ -437,20 +442,20 @@ $(LIBWEBP_OBJS) $(LIBWEBPMUX_OBJS) $(LIBWEBPDEMUX_OBJS): \
$(RC) /fo$@ $<
{src\mux}.rc{$(DIROBJ)\mux}.res:
$(RC) /fo$@ $<
+{sharpyuv}.rc{$(DIROBJ)\sharpyuv}.res:
+ $(RC) /fo$@ $<
-$(LIBWEBP): $(DIROBJ)\$(LIBWEBP_BASENAME:_debug=).res
+$(LIBSHARPYUV): $(DIROBJ)\sharpyuv\$(LIBSHARPYUV_BASENAME:_debug=).res
+$(LIBWEBP): $(LIBSHARPYUV) $(DIROBJ)\$(LIBWEBP_BASENAME:_debug=).res
$(LIBWEBPDECODER): $(DIROBJ)\$(LIBWEBPDECODER_BASENAME:_debug=).res
$(LIBWEBPMUX): $(LIBWEBP) $(DIROBJ)\mux\$(LIBWEBPMUX_BASENAME:_debug=).res
$(LIBWEBPDEMUX): $(LIBWEBP) $(DIROBJ)\demux\$(LIBWEBPDEMUX_BASENAME:_debug=).res
-$(LIBWEBPDECODER) $(LIBWEBP) $(LIBWEBPMUX) $(LIBWEBPDEMUX):
+$(LIBWEBPDECODER) $(LIBWEBP) $(LIBWEBPMUX) $(LIBWEBPDEMUX) $(LIBSHARPYUV):
$(LNKDLL) /out:$(DIRBIN)\$(@B:_dll=.dll) /implib:$@ $(LFLAGS) $**
-xcopy $(DIROBJ)\*.pdb $(DIRLIB) /y
-
-clean::
- @-erase /s $(DIROBJ)\$(DLLINC) 2> NUL
!ELSE
-$(LIBWEBPDECODER) $(LIBWEBP) $(LIBWEBPMUX) $(LIBWEBPDEMUX):
+$(LIBWEBPDECODER) $(LIBWEBP) $(LIBWEBPMUX) $(LIBWEBPDEMUX) $(LIBSHARPYUV):
$(LNKLIB) /out:$@ $**
-xcopy $(DIROBJ)\*.pdb $(DIRLIB) /y
!ENDIF
@@ -458,13 +463,6 @@ $(LIBWEBPDECODER) $(LIBWEBP) $(LIBWEBPMUX) $(LIBWEBPDEMUX):
$(OUTPUT_DIRS):
@if not exist "$(@)" mkdir "$(@)"
-# generate a helper include to define WEBP_EXTERN suitable for the DLL build
-$(DIROBJ)\$(DLLINC):
- @echo #ifndef WEBP_DLL_H_ > $@
- @echo #define WEBP_DLL_H_ >> $@
- @echo #define WEBP_EXTERN __declspec(dllexport) >> $@
- @echo #endif /* WEBP_DLL_H_ */ >> $@
-
.SUFFIXES: .c .obj .res .exe
# File-specific flag builds. Note batch rules take precedence over wildcards,
# so for now name each file individually.
diff --git a/NEWS b/NEWS
index be3b47aa..c4f8ef79 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,17 @@
+- 12/16/2022: version 1.3.0
+ This is a binary compatible release.
+ * add libsharpyuv, which exposes -sharp_yuv/config.use_sharp_yuv
+ functionality to other libraries; libwebp now depends on this library
+ * major updates to the container and lossless bitstream docs (#448, #546,
+ #551)
+ * miscellaneous warning, bug & build fixes (#576, #583, #584)
+
+- 8/4/2022: version 1.2.4
+ This is a binary compatible release.
+ * restore CMake libwebpmux target name for compatibility with 1.2.2 (#575)
+ * fix lossless crunch mode encoding with WEBP_REDUCE_SIZE
+ (chromium: #1345547, #1345595, #1345772, #1345804)
+
- 6/30/2022: version 1.2.3
This is a binary compatible release.
* security fix for lossless encoder (#565, chromium:1313709)
diff --git a/README.android b/README.android
index 13637e9a..8e5fca29 100644
--- a/README.android
+++ b/README.android
@@ -1,13 +1,9 @@
URL: https://chromium.googlesource.com/webm/libwebp
-Version: 1.2.3
+Version: 1.3.0
License: Google BSD like
Local modifications:
-- Copy public headers from src/webp to include/webp, so path to headers
- may be appended into CFLAGS without risk for other private headers
- (e.g. bits.h) to leak into
-- Removed build files necessary for building via autoconf/automake tools
- These files are not required to build via Android.bp
+- LOCAL_LICENSE_KINDS and related variables added to **/Android.mk
The Android.bp file creates WebP decoder and encoder static libraries which
can be added to any application by adding libwebp-decode and libwebp-encode to
diff --git a/README.md b/README.md
index e0efbe34..4e201d33 100644
--- a/README.md
+++ b/README.md
@@ -7,7 +7,7 @@
\__\__/\____/\_____/__/ ____ ___
/ _/ / \ \ / _ \/ _/
/ \_/ / / \ \ __/ \__
- \____/____/\_____/_____/____/v1.2.3
+ \____/____/\_____/_____/____/v1.3.0
```
WebP codec is a library to encode and decode images in WebP format. This package
diff --git a/README.version b/README.version
index bbea80c8..9189f436 100644
--- a/README.version
+++ b/README.version
@@ -1,3 +1,3 @@
-URL: https://chromium.googlesource.com/webm/libwebp/+archive/a8e366166ab57bb1b4aaf6739fc775515bc71b51.tar.gz
-Version: 1.2.3
+URL: https://chromium.googlesource.com/webm/libwebp
+Version: v1.3.0
BugComponent: 20174
diff --git a/build.gradle b/build.gradle
index 13202a85..c25314c0 100644
--- a/build.gradle
+++ b/build.gradle
@@ -107,6 +107,7 @@ model {
source {
srcDir "sharpyuv"
include "sharpyuv.c"
+ include "sharpyuv_cpu.c"
include "sharpyuv_csp.c"
include "sharpyuv_dsp.c"
include "sharpyuv_gamma.c"
diff --git a/cmake/WebPConfig.cmake.in b/cmake/WebPConfig.cmake.in
index 822fc592..f3347394 100644
--- a/cmake/WebPConfig.cmake.in
+++ b/cmake/WebPConfig.cmake.in
@@ -3,6 +3,11 @@ set(WEBP_VERSION ${WebP_VERSION})
@PACKAGE_INIT@
+if(@WEBP_USE_THREAD@)
+ include(CMakeFindDependencyMacro)
+ find_dependency(Threads REQUIRED)
+endif()
+
include ("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Targets.cmake")
set(WebP_INCLUDE_DIRS "@CMAKE_INSTALL_FULL_INCLUDEDIR@")
diff --git a/cmake/cpu.cmake b/cmake/cpu.cmake
index bc0dbc98..7513ca8a 100644
--- a/cmake/cpu.cmake
+++ b/cmake/cpu.cmake
@@ -18,7 +18,8 @@ function(webp_check_compiler_flag WEBP_SIMD_FLAG ENABLE_SIMD)
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\"
int main(void) {
#if !defined(WEBP_USE_${WEBP_SIMD_FLAG})
@@ -26,7 +27,8 @@ function(webp_check_compiler_flag WEBP_SIMD_FLAG ENABLE_SIMD)
#endif
return 0;
}
- " WEBP_HAVE_FLAG_${WEBP_SIMD_FLAG})
+ "
+ WEBP_HAVE_FLAG_${WEBP_SIMD_FLAG})
cmake_pop_check_state()
if(WEBP_HAVE_FLAG_${WEBP_SIMD_FLAG})
set(WEBP_HAVE_${WEBP_SIMD_FLAG} 1 PARENT_SCOPE)
@@ -52,13 +54,10 @@ if(MSVC AND CMAKE_C_COMPILER_ID STREQUAL "MSVC")
endif()
set(SIMD_DISABLE_FLAGS)
else()
- set(SIMD_ENABLE_FLAGS
- "-msse4.1;-msse2;-mips32;-mdspr2;-mfpu=neon;-mmsa")
- set(SIMD_DISABLE_FLAGS
- "-mno-sse4.1;-mno-sse2;;-mno-dspr2;;-mno-msa")
+ set(SIMD_ENABLE_FLAGS "-msse4.1;-msse2;-mips32;-mdspr2;-mfpu=neon;-mmsa")
+ set(SIMD_DISABLE_FLAGS "-mno-sse4.1;-mno-sse2;;-mno-dspr2;;-mno-msa")
endif()
-set(WEBP_SIMD_FILES_TO_NOT_INCLUDE)
set(WEBP_SIMD_FILES_TO_INCLUDE)
set(WEBP_SIMD_FLAGS_TO_INCLUDE)
@@ -75,8 +74,8 @@ list(LENGTH WEBP_SIMD_FLAGS WEBP_SIMD_FLAGS_LENGTH)
math(EXPR WEBP_SIMD_FLAGS_RANGE "${WEBP_SIMD_FLAGS_LENGTH} - 1")
foreach(I_SIMD RANGE ${WEBP_SIMD_FLAGS_RANGE})
- # With Emscripten 2.0.9 -msimd128 -mfpu=neon will enable NEON, but the
- # source will fail to compile.
+ # With Emscripten 2.0.9 -msimd128 -mfpu=neon will enable NEON, but the source
+ # will fail to compile.
if(EMSCRIPTEN AND ${I_SIMD} GREATER_EQUAL 2)
break()
endif()
@@ -108,7 +107,7 @@ foreach(I_SIMD RANGE ${WEBP_SIMD_FLAGS_RANGE})
# Check which files we should include or not.
list(GET WEBP_SIMD_FILE_EXTENSIONS ${I_SIMD} WEBP_SIMD_FILE_EXTENSION)
file(GLOB SIMD_FILES "${CMAKE_CURRENT_LIST_DIR}/../"
- "src/dsp/*${WEBP_SIMD_FILE_EXTENSION}")
+ "src/dsp/*${WEBP_SIMD_FILE_EXTENSION}")
if(WEBP_HAVE_${WEBP_SIMD_FLAG})
# Memorize the file and flags.
foreach(FILE ${SIMD_FILES})
@@ -142,11 +141,9 @@ foreach(I_SIMD RANGE ${WEBP_SIMD_FLAGS_RANGE})
set(COMMON_PATTERNS)
endif()
set(CMAKE_REQUIRED_DEFINITIONS ${SIMD_COMPILE_FLAG})
- check_c_source_compiles("int main(void) {return 0;}"
- FLAG_${SIMD_COMPILE_FLAG}
- FAIL_REGEX
- "warning: argument unused during compilation:"
- ${COMMON_PATTERNS})
+ check_c_source_compiles(
+ "int main(void) {return 0;}" FLAG_${SIMD_COMPILE_FLAG} FAIL_REGEX
+ "warning: argument unused during compilation:" ${COMMON_PATTERNS})
if(NOT FLAG_${SIMD_COMPILE_FLAG})
unset(HAS_COMPILE_FLAG)
unset(HAS_COMPILE_FLAG CACHE)
diff --git a/cmake/deps.cmake b/cmake/deps.cmake
index f79cdbb8..48c821e6 100644
--- a/cmake/deps.cmake
+++ b/cmake/deps.cmake
@@ -10,24 +10,30 @@
# Check for compiler options.
include(CheckCSourceCompiles)
-check_c_source_compiles("
+check_c_source_compiles(
+ "
int main(void) {
(void)__builtin_bswap16(0);
return 0;
}
- " HAVE_BUILTIN_BSWAP16)
-check_c_source_compiles("
+ "
+ HAVE_BUILTIN_BSWAP16)
+check_c_source_compiles(
+ "
int main(void) {
(void)__builtin_bswap32(0);
return 0;
}
- " HAVE_BUILTIN_BSWAP32)
-check_c_source_compiles("
+ "
+ HAVE_BUILTIN_BSWAP32)
+check_c_source_compiles(
+ "
int main(void) {
(void)__builtin_bswap64(0);
return 0;
}
- " HAVE_BUILTIN_BSWAP64)
+ "
+ HAVE_BUILTIN_BSWAP64)
# Check for libraries.
if(WEBP_USE_THREAD)
@@ -37,13 +43,15 @@ if(WEBP_USE_THREAD)
if(CMAKE_USE_PTHREADS_INIT AND NOT CMAKE_SYSTEM_NAME STREQUAL "QNX")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pthread")
endif()
- check_c_source_compiles("
+ check_c_source_compiles(
+ "
#include <pthread.h>
int main (void) {
int attr = PTHREAD_PRIO_INHERIT;
return attr;
}
- " FLAG_HAVE_PTHREAD_PRIO_INHERIT)
+ "
+ FLAG_HAVE_PTHREAD_PRIO_INHERIT)
set(HAVE_PTHREAD_PRIO_INHERIT ${FLAG_HAVE_PTHREAD_PRIO_INHERIT})
list(APPEND WEBP_DEP_LIBRARIES Threads::Threads)
endif()
@@ -59,14 +67,17 @@ set(WEBP_HAVE_GL ${OPENGL_FOUND})
# Check if we need to link to the C math library. We do not look for it as it is
# not found when cross-compiling, while it is here.
-check_c_source_compiles("
+check_c_source_compiles(
+ "
#include <math.h>
int main(int argc, char** argv) {
return (int)pow(argc, 2.5);
}
- " HAVE_MATH_LIBRARY)
+ "
+ HAVE_MATH_LIBRARY)
if(NOT HAVE_MATH_LIBRARY)
message(STATUS "Adding -lm flag.")
+ list(APPEND SHARPYUV_DEP_LIBRARIES m)
list(APPEND WEBP_DEP_LIBRARIES m)
endif()
@@ -84,7 +95,7 @@ foreach(I_LIB PNG JPEG TIFF)
if(${I_LIB}_FOUND)
list(APPEND WEBP_DEP_IMG_LIBRARIES ${${I_LIB}_LIBRARIES})
list(APPEND WEBP_DEP_IMG_INCLUDE_DIRS ${${I_LIB}_INCLUDE_DIR}
- ${${I_LIB}_INCLUDE_DIRS})
+ ${${I_LIB}_INCLUDE_DIRS})
endif()
endforeach()
if(WEBP_DEP_IMG_INCLUDE_DIRS)
@@ -105,13 +116,15 @@ if(GIF_FOUND)
cmake_push_check_state()
set(CMAKE_REQUIRED_LIBRARIES ${GIF_LIBRARIES})
set(CMAKE_REQUIRED_INCLUDES ${GIF_INCLUDE_DIR})
- check_c_source_compiles("
+ check_c_source_compiles(
+ "
#include <gif_lib.h>
int main(void) {
(void)DGifOpenFileHandle;
return 0;
}
- " GIF_COMPILES)
+ "
+ GIF_COMPILES)
cmake_pop_check_state()
if(GIF_COMPILES)
list(APPEND WEBP_DEP_GIF_LIBRARIES ${GIF_LIBRARIES})
@@ -143,10 +156,7 @@ check_include_files(windows.h HAVE_WINDOWS_H)
# Windows specifics
if(HAVE_WINCODEC_H)
- list(APPEND WEBP_DEP_LIBRARIES
- shlwapi
- ole32
- windowscodecs)
+ list(APPEND WEBP_DEP_LIBRARIES shlwapi ole32 windowscodecs)
endif()
# Check for SIMD extensions.
@@ -158,17 +168,12 @@ set(PACKAGE_NAME ${PROJECT_NAME})
# Read from configure.ac.
file(READ ${CMAKE_CURRENT_SOURCE_DIR}/configure.ac CONFIGURE_AC)
-string(REGEX MATCHALL
- "\\[([0-9a-z\\.:/]*)\\]"
- CONFIGURE_AC_PACKAGE_INFO
+string(REGEX MATCHALL "\\[([0-9a-z\\.:/]*)\\]" CONFIGURE_AC_PACKAGE_INFO
${CONFIGURE_AC})
function(strip_bracket VAR)
string(LENGTH ${${VAR}} TMP_LEN)
math(EXPR TMP_LEN ${TMP_LEN}-2)
- string(SUBSTRING ${${VAR}}
- 1
- ${TMP_LEN}
- TMP_SUB)
+ string(SUBSTRING ${${VAR}} 1 ${TMP_LEN} TMP_SUB)
set(${VAR} ${TMP_SUB} PARENT_SCOPE)
endfunction()
diff --git a/configure.ac b/configure.ac
index 5baaca52..de5dfe7a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,4 +1,4 @@
-AC_INIT([libwebp], [1.2.3],
+AC_INIT([libwebp], [1.3.0],
[https://bugs.chromium.org/p/webp],,
[https://developers.google.com/speed/webp])
AC_CANONICAL_HOST
@@ -749,11 +749,13 @@ fi
dnl =========================
+dnl Add an empty webp_libname_prefix variable for use in *.pc.in.
+AC_SUBST([webp_libname_prefix])
AC_CONFIG_MACRO_DIR([m4])
AC_CONFIG_HEADERS([src/webp/config.h])
AC_CONFIG_FILES([Makefile src/Makefile man/Makefile \
examples/Makefile extras/Makefile imageio/Makefile \
- sharpyuv/Makefile \
+ sharpyuv/Makefile sharpyuv/libsharpyuv.pc \
src/dec/Makefile src/enc/Makefile src/dsp/Makefile \
src/demux/Makefile src/mux/Makefile \
src/utils/Makefile \
diff --git a/doc/api.md b/doc/api.md
index d0adafbd..c613ed34 100644
--- a/doc/api.md
+++ b/doc/api.md
@@ -233,7 +233,7 @@ WebPIDelete(idec);
WebPFreeDecBuffer(&config.output);
```
-## Webp Mux
+## WebP Mux
WebPMux is a set of two libraries 'Mux' and 'Demux' for creation, extraction and
manipulation of an extended format WebP file, which can have features like color
diff --git a/doc/webp-container-spec.txt b/doc/webp-container-spec.txt
index e421dc6c..ffa919eb 100644
--- a/doc/webp-container-spec.txt
+++ b/doc/webp-container-spec.txt
@@ -25,7 +25,7 @@ to compress image data in a lossy way, or (ii) the WebP lossless encoding
(and possibly other encodings in the future). These encoding schemes should
make it more efficient than currently used formats. It is optimized for fast
image transfer over the network (e.g., for websites). The WebP format has
-feature parity (color profile, metadata, animation etc) with other formats as
+feature parity (color profile, metadata, animation, etc.) with other formats as
well. This document describes the structure of a WebP file.
The WebP container (i.e., RIFF container for WebP) allows feature support over
@@ -46,15 +46,16 @@ for:
* **Animation.** An image may have multiple frames with pauses between them,
making it an animation.
-The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
-"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
-document are to be interpreted as described in [RFC 2119][].
+The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD",
+"SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this
+document are to be interpreted as described in BCP 14 [RFC 2119][] [RFC 8174][]
+when, and only when, they appear in all capitals, as shown here.
Bit numbering in chunk diagrams starts at `0` for the most significant bit
('MSB 0') as described in [RFC 1166][].
-Terminology &amp; Basics
-------------------------
+Terminology & Basics
+--------------------
A WebP file contains either a still image (i.e., an encoded matrix of pixels)
or an [animation](#animation). Optionally, it can also contain transparency
@@ -83,13 +84,20 @@ _uint32_
_FourCC_
: A _FourCC_ (four-character code) is a _uint32_ created by concatenating four
- ASCII characters in little-endian order.
+ ASCII characters in little-endian order. This means 'aaaa' (0x61616161) and
+ 'AAAA' (0x41414141) are treated as different _FourCCs_.
_1-based_
: An unsigned integer field storing values offset by `-1`. e.g., Such a field
would store value _25_ as _24_.
+_ChunkHeader('ABCD')_
+
+: This is used to describe the _FourCC_ and _Chunk Size_ header of individual
+ chunks, where 'ABCD' is the FourCC for the chunk. This element's size is 8
+ bytes.
+
RIFF File Format
----------------
@@ -106,7 +114,7 @@ The basic element of a RIFF file is a _chunk_. It consists of:
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Chunk Size |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | Chunk Payload |
+ : Chunk Payload :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Chunk FourCC: 32 bits
@@ -115,19 +123,13 @@ Chunk FourCC: 32 bits
Chunk Size: 32 bits (_uint32_)
-: The size of the chunk not including this field, the chunk identifier or
- padding.
+: The size of the chunk in bytes, not including this field, the chunk
+ identifier or padding.
Chunk Payload: _Chunk Size_ bytes
-: The data payload. If _Chunk Size_ is odd, a single padding byte -- that
- SHOULD be `0` -- is added.
-
-_ChunkHeader('ABCD')_
-
-: This is used to describe the _FourCC_ and _Chunk Size_ header of individual
- chunks, where 'ABCD' is the FourCC for the chunk. This element's
- size is 8 bytes.
+: The data payload. If _Chunk Size_ is odd, a single padding byte -- that MUST
+ be `0` to conform with RIFF -- is added.
**Note:** RIFF has a convention that all-uppercase chunk FourCCs are standard
chunks that apply to any RIFF file format, while FourCCs specific to a file
@@ -163,9 +165,11 @@ File Size: 32 bits (_uint32_)
A WebP file MUST begin with a RIFF header with the FourCC 'WEBP'. The file size
in the header is the total size of the chunks that follow plus `4` bytes for
-the 'WEBP' FourCC. The file SHOULD NOT contain anything after it. As the size
-of any chunk is even, the size given by the RIFF header is also even. The
-contents of individual chunks will be described in the following sections.
+the 'WEBP' FourCC. The file SHOULD NOT contain any data after the data
+specified by _File Size_. Readers MAY parse such files, ignoring the trailing
+data. As the size of any chunk is even, the size given by the RIFF header is
+also even. The contents of individual chunks will be described in the following
+sections.
Simple File Format (Lossy)
@@ -180,9 +184,11 @@ Simple WebP (lossy) file format:
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | |
| WebP file header (12 bytes) |
+ | |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | VP8 chunk |
+ : VP8 chunk :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
VP8 chunk:
@@ -191,20 +197,24 @@ VP8 chunk:
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| ChunkHeader('VP8 ') |
+ | |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | VP8 data |
+ : VP8 data :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
VP8 data: _Chunk Size_ bytes
: VP8 bitstream data.
+Note the fourth character in the 'VP8 ' FourCC is an ASCII space (0x20).
+
The VP8 bitstream format specification can be found at [VP8 Data Format and
Decoding Guide][vp8spec]. Note that the VP8 frame header contains the VP8 frame
width and height. That is assumed to be the width and height of the canvas.
-The VP8 specification describes how to decode the image into Y'CbCr
-format. To convert to RGB, Rec. 601 SHOULD be used.
+The VP8 specification describes how to decode the image into Y'CbCr format. To
+convert to RGB, Rec. 601 SHOULD be used. Applications MAY use another
+conversion method, but visual results may differ among decoders.
Simple File Format (Lossless)
@@ -221,9 +231,11 @@ Simple WebP (lossless) file format:
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | |
| WebP file header (12 bytes) |
+ | |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | VP8L chunk |
+ : VP8L chunk :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
VP8L chunk:
@@ -232,8 +244,9 @@ VP8L chunk:
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| ChunkHeader('VP8L') |
+ | |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | VP8L data |
+ : VP8L data :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
VP8L data: _Chunk Size_ bytes
@@ -279,7 +292,7 @@ details about frames can be found in the [Animation](#animation) section.
All chunks SHOULD be placed in the same order as listed above. If a chunk
appears in the wrong place, the file is invalid, but readers MAY parse the
-file, ignoring the chunks that come too late.
+file, ignoring the chunks that are out of order.
**Rationale:** Setting the order of chunks should allow quicker file
parsing. For example, if an 'ALPH' chunk does not appear in its required
@@ -293,9 +306,12 @@ Extended WebP file header:
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | |
| WebP file header (12 bytes) |
+ | |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| ChunkHeader('VP8X') |
+ | |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|Rsv|I|L|E|X|A|R| Reserved |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
@@ -306,7 +322,7 @@ Extended WebP file header:
Reserved (Rsv): 2 bits
-: SHOULD be `0`.
+: MUST be `0`. Readers MUST ignore this field.
ICC profile (I): 1 bit
@@ -332,11 +348,11 @@ Animation (A): 1 bit
Reserved (R): 1 bit
-: SHOULD be `0`.
+: MUST be `0`. Readers MUST ignore this field.
Reserved: 24 bits
-: SHOULD be `0`.
+: MUST be `0`. Readers MUST ignore this field.
Canvas Width Minus One: 24 bits
@@ -350,7 +366,7 @@ Canvas Height Minus One: 24 bits
The product of _Canvas Width_ and _Canvas Height_ MUST be at most `2^32 - 1`.
-Future specifications MAY add more fields.
+Future specifications may add more fields. Unknown fields MUST be ignored.
### Chunks
@@ -368,6 +384,7 @@ animation.
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| ChunkHeader('ANIM') |
+ | |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Background Color |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
@@ -383,8 +400,8 @@ Background Color: 32 bits (_uint32_)
**Note**:
- * Background color MAY contain a transparency value (alpha), even if the
- _Alpha_ flag in [VP8X chunk](#extended_header) is unset.
+ * Background color MAY contain a non-opaque alpha value, even if the _Alpha_
+ flag in [VP8X chunk](#extended_header) is unset.
* Viewer applications SHOULD treat the background color value as a hint, and
are not required to use it.
@@ -397,8 +414,8 @@ Loop Count: 16 bits (_uint16_)
: The number of times to loop the animation. `0` means infinitely.
This chunk MUST appear if the _Animation_ flag in the VP8X chunk is set.
-If the _Animation_ flag is not set and this chunk is present, it
-SHOULD be ignored.
+If the _Animation_ flag is not set and this chunk is present, it MUST be
+ignored.
ANMF chunk:
@@ -409,6 +426,7 @@ If the _Animation flag_ is not set, then this chunk SHOULD NOT be present.
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| ChunkHeader('ANMF') |
+ | |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Frame X | ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
@@ -418,7 +436,7 @@ If the _Animation flag_ is not set, then this chunk SHOULD NOT be present.
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Frame Duration | Reserved |B|D|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | Frame Data |
+ : Frame Data :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Frame X: 24 bits (_uint24_)
@@ -448,7 +466,7 @@ Frame Duration: 24 bits (_uint24_)
Reserved: 6 bits
-: SHOULD be 0.
+: MUST be `0`. Readers MUST ignore this field.
Blending method (B): 1 bit
@@ -493,8 +511,9 @@ Disposal method (D): 1 bit
if blend.A = 0 then
blend.RGB = 0
else
- blend.RGB = (src.RGB * src.A +
- dst.RGB * dst.A * (1 - src.A / 255)) / blend.A
+ blend.RGB =
+ (src.RGB * src.A +
+ dst.RGB * dst.A * (1 - src.A / 255)) / blend.A
~~~~~
* Alpha-blending SHOULD be done in linear color space, by taking into account
@@ -521,22 +540,23 @@ _padded_ chunks as described by the [RIFF file format](#riff-file-format).
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| ChunkHeader('ALPH') |
+ | |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|Rsv| P | F | C | Alpha Bitstream... |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Reserved (Rsv): 2 bits
-: SHOULD be `0`.
+: MUST be `0`. Readers MUST ignore this field.
Pre-processing (P): 2 bits
-: These INFORMATIVE bits are used to signal the pre-processing that has
+: These _informative_ bits are used to signal the pre-processing that has
been performed during compression. The decoder can use this information to
e.g. dither the values or smooth the gradients prior to display.
- * `0`: no pre-processing
- * `1`: level reduction
+ * `0`: No pre-processing.
+ * `1`: Level reduction.
Filtering method (F): 2 bits
@@ -569,14 +589,14 @@ where `clip(v)` is equal to:
* v otherwise
The final value is derived by adding the decompressed value `X` to the
-predictor and using modulo-256 arithmetic to wrap the \[256-511\] range
-into the \[0-255\] one:
+predictor and using modulo-256 arithmetic to wrap the \[256..511\] range
+into the \[0..255\] one:
`alpha = (predictor + X) % 256`
-There are special cases for left-most and top-most pixel positions:
+There are special cases for the left-most and top-most pixel positions:
- * Top-left value at location (0,0) uses 0 as predictor value. Otherwise,
+ * The top-left value at location (0, 0) uses 0 as predictor value. Otherwise,
* For horizontal or gradient filtering methods, the left-most pixels at
location (0, y) are predicted using the location (0, y-1) just above.
* For vertical or gradient filtering methods, the top-most pixels at
@@ -638,14 +658,15 @@ The formats of VP8 and VP8L chunks are as described in sections
[Simple File Format (Lossy)](#simple-file-format-lossy)
and [Simple File Format (Lossless)](#simple-file-format-lossless) respectively.
-#### Color profile
+#### Color Profile
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| ChunkHeader('ICCP') |
+ | |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | Color Profile |
+ : Color Profile :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Color Profile: _Chunk Size_ bytes
@@ -665,8 +686,7 @@ If this chunk is not present, sRGB SHOULD be assumed.
Metadata can be stored in 'EXIF' or 'XMP ' chunks.
There SHOULD be at most one chunk of each type ('EXIF' and 'XMP '). If there
-are more such chunks, readers MAY ignore all except the first one. Also, a file
-may possibly contain both 'EXIF' and 'XMP ' chunks.
+are more such chunks, readers MAY ignore all except the first one.
The chunks are defined as follows:
@@ -676,13 +696,14 @@ EXIF chunk:
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| ChunkHeader('EXIF') |
+ | |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | Exif Metadata |
+ : Exif Metadata :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Exif Metadata: _Chunk Size_ bytes
-: image metadata in Exif format.
+: Image metadata in Exif format.
XMP chunk:
@@ -690,13 +711,16 @@ XMP chunk:
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| ChunkHeader('XMP ') |
+ | |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | XMP Metadata |
+ : XMP Metadata :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
XMP Metadata: _Chunk Size_ bytes
-: image metadata in XMP format.
+: Image metadata in XMP format.
+
+Note the fourth character in the 'XMP ' FourCC is an ASCII space (0x20).
Additional guidance about handling metadata can be found in the
Metadata Working Group's [Guidelines for Handling Metadata][metadata].
@@ -720,49 +744,73 @@ A file MAY contain unknown chunks:
Readers SHOULD ignore these chunks. Writers SHOULD preserve them in their
original order (unless they specifically intend to modify these chunks).
-### Assembling the Canvas from frames
+### Assembling the Canvas From Frames
+
+Here we provide an overview of how a reader MUST assemble a canvas in the case
+of an animated image.
+
+The process begins with creating a canvas using the dimensions given in the
+'VP8X' chunk, `Canvas Width Minus One + 1` pixels wide by `Canvas Height Minus
+One + 1` pixels high. The `Loop Count` field from the 'ANIM' chunk controls how
+many times the animation process is repeated. This is `Loop Count - 1` for
+non-zero `Loop Count` values or infinitely if `Loop Count` is zero.
+
+At the beginning of each loop iteration the canvas is filled using the
+background color from the 'ANIM' chunk or an application defined color.
+
+'ANMF' chunks contain individual frames given in display order. Before rendering
+each frame, the previous frame's `Disposal method` is applied.
+
+The rendering of the decoded frame begins at the Cartesian coordinates (`2 *
+Frame X`, `2 * Frame Y`) using the top-left corner of the canvas as the origin.
+`Frame Width Minus One + 1` pixels wide by `Frame Height Minus One + 1` pixels
+high are rendered onto the canvas using the `Blending method`.
-Here we provide an overview of how a reader should assemble a canvas in the
-case of an animated image. The notation _VP8X.field_ means the field in the
-'VP8X' chunk with the same description.
+The canvas is displayed for `Frame Duration` milliseconds. This continues until
+all frames given by 'ANMF' chunks have been displayed. A new loop iteration is
+then begun or the canvas is left in its final state if all iterations have been
+completed.
-Displaying an _animated image_ canvas MUST be equivalent to the following
-pseudocode:
+The following pseudocode illustrates the rendering process. The notation
+_VP8X.field_ means the field in the 'VP8X' chunk with the same description.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
assert VP8X.flags.hasAnimation
canvas ← new image of size VP8X.canvasWidth x VP8X.canvasHeight with
background color ANIM.background_color.
loop_count ← ANIM.loopCount
-dispose_method ← ANIM.disposeMethod
+dispose_method ← Dispose to background color
if loop_count == 0:
- loop_count = ∞
+ loop_count = ∞
frame_params ← nil
assert next chunk in image_data is ANMF
for loop = 0..loop_count - 1
- clear canvas to ANIM.background_color or application defined color
- until eof or non-ANMF chunk
- frame_params.frameX = Frame X
- frame_params.frameY = Frame Y
- frame_params.frameWidth = Frame Width Minus One + 1
- frame_params.frameHeight = Frame Height Minus One + 1
- frame_params.frameDuration = Frame Duration
- frame_right = frame_params.frameX + frame_params.frameWidth
- frame_bottom = frame_params.frameY + frame_params.frameHeight
- assert VP8X.canvasWidth >= frame_right
- assert VP8X.canvasHeight >= frame_bottom
- for subchunk in 'Frame Data':
- if subchunk.tag == "ALPH":
- assert alpha subchunks not found in 'Frame Data' earlier
- frame_params.alpha = alpha_data
- else if subchunk.tag == "VP8 " OR subchunk.tag == "VP8L":
- assert bitstream subchunks not found in 'Frame Data' earlier
- frame_params.bitstream = bitstream_data
- render frame with frame_params.alpha and frame_params.bitstream on
- canvas with top-left corner at (frame_params.frameX,
- frame_params.frameY), using dispose method dispose_method.
- canvas contains the decoded image.
- Show the contents of the canvas for frame_params.frameDuration * 1ms.
+ clear canvas to ANIM.background_color or application defined color
+ until eof or non-ANMF chunk
+ frame_params.frameX = Frame X
+ frame_params.frameY = Frame Y
+ frame_params.frameWidth = Frame Width Minus One + 1
+ frame_params.frameHeight = Frame Height Minus One + 1
+ frame_params.frameDuration = Frame Duration
+ frame_right = frame_params.frameX + frame_params.frameWidth
+ frame_bottom = frame_params.frameY + frame_params.frameHeight
+ assert VP8X.canvasWidth >= frame_right
+ assert VP8X.canvasHeight >= frame_bottom
+ for subchunk in 'Frame Data':
+ if subchunk.tag == "ALPH":
+ assert alpha subchunks not found in 'Frame Data' earlier
+ frame_params.alpha = alpha_data
+ else if subchunk.tag == "VP8 " OR subchunk.tag == "VP8L":
+ assert bitstream subchunks not found in 'Frame Data' earlier
+ frame_params.bitstream = bitstream_data
+ render frame with frame_params.alpha and frame_params.bitstream
+ on canvas with top-left corner at (frame_params.frameX,
+ frame_params.frameY), using blending method
+ frame_params.blendingMethod.
+ canvas contains the decoded image.
+ Show the contents of the canvas for
+ frame_params.frameDuration * 1ms.
+ dispose_method = frame_params.disposeMethod
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -817,3 +865,4 @@ RIFF/WEBP
[metadata]: https://web.archive.org/web/20180919181934/http://www.metadataworkinggroup.org/pdf/mwg_guidance.pdf
[rfc 1166]: https://datatracker.ietf.org/doc/html/rfc1166
[rfc 2119]: https://datatracker.ietf.org/doc/html/rfc2119
+[rfc 8174]: https://datatracker.ietf.org/doc/html/rfc8174
diff --git a/doc/webp-lossless-bitstream-spec.txt b/doc/webp-lossless-bitstream-spec.txt
index d38481ea..563426d4 100644
--- a/doc/webp-lossless-bitstream-spec.txt
+++ b/doc/webp-lossless-bitstream-spec.txt
@@ -1,8 +1,8 @@
<!--
-Although you may be viewing an alternate representation, this document
-is sourced in Markdown, a light-duty markup scheme, and is optimized for
-the [kramdown](https://kramdown.gettalong.org/) transformer.
+Although you may be viewing an alternate representation, this document is
+sourced in Markdown, a light-duty markup scheme, and is optimized for the
+[kramdown](https://kramdown.gettalong.org/) transformer.
See the accompanying specs_generation.md. External link targets are referenced
at the end of this file.
@@ -18,128 +18,126 @@ Paragraphs marked as \[AMENDED\] were amended on 2014-09-16.
Paragraphs marked as \[AMENDED2\] were amended on 2022-05-13.
+Paragraphs marked as \[AMENDED3\] were amended on 2022-11-21.
+
Abstract
--------
-WebP lossless is an image format for lossless compression of ARGB
-images. The lossless format stores and restores the pixel values
-exactly, including the color values for zero alpha pixels. The
-format uses subresolution images, recursively embedded into the format
-itself, for storing statistical data about the images, such as the used
-entropy codes, spatial predictors, color space conversion, and color
-table. LZ77, prefix coding, and a color cache are used for compression
-of the bulk data. Decoding speeds faster than PNG have been
-demonstrated, as well as 25% denser compression than can be achieved
-using today's PNG format.
+WebP lossless is an image format for lossless compression of ARGB images. The
+lossless format stores and restores the pixel values exactly, including the
+color values for pixels whose alpha value is 0. The format uses subresolution
+images, recursively embedded into the format itself, for storing statistical
+data about the images, such as the used entropy codes, spatial predictors, color
+space conversion, and color table. LZ77, prefix coding, and a color cache are
+used for compression of the bulk data. Decoding speeds faster than PNG have been
+demonstrated, as well as 25% denser compression than can be achieved using
+today's PNG format.
* TOC placeholder
{:toc}
-Nomenclature
-------------
+1 Introduction
+--------------
+
+This document describes the compressed data representation of a WebP lossless
+image. It is intended as a detailed reference for the WebP lossless encoder and
+decoder implementation.
+
+In this document, we extensively use C programming language syntax to describe
+the bitstream, and assume the existence of a function for reading bits,
+`ReadBits(n)`. The bytes are read in the natural order of the stream containing
+them, and bits of each byte are read in least-significant-bit-first order. When
+multiple bits are read at the same time, the integer is constructed from the
+original data in the original order. The most significant bits of the returned
+integer are also the most significant bits of the original data. Thus, the
+statement
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+b = ReadBits(2);
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+is equivalent with the two statements below:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+b = ReadBits(1);
+b |= ReadBits(1) << 1;
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+We assume that each color component (e.g. alpha, red, blue and green) is
+represented using an 8-bit byte. We define the corresponding type as uint8. A
+whole ARGB pixel is represented by a type called uint32, an unsigned integer
+consisting of 32 bits. In the code showing the behavior of the transformations,
+alpha value is codified in bits 31..24, red in bits 23..16, green in bits 15..8
+and blue in bits 7..0, but implementations of the format are free to use another
+representation internally.
+
+Broadly, a WebP lossless image contains header data, transform information and
+actual image data. Headers contain width and height of the image. A WebP
+lossless image can go through four different types of transformation before
+being entropy encoded. The transform information in the bitstream contains the
+data required to apply the respective inverse transforms.
+
+
+2 Nomenclature
+--------------
ARGB
-: A pixel value consisting of alpha, red, green, and blue values.
+: A pixel value consisting of alpha, red, green, and blue values.
ARGB image
-: A two-dimensional array containing ARGB pixels.
+: A two-dimensional array containing ARGB pixels.
color cache
-: A small hash-addressed array to store recently used colors, to be able
- to recall them with shorter codes.
+: A small hash-addressed array to store recently used colors, to be able to
+ recall them with shorter codes.
color indexing image
-: A one-dimensional image of colors that can be indexed using a small
- integer (up to 256 within WebP lossless).
+: A one-dimensional image of colors that can be indexed using a small integer
+ (up to 256 within WebP lossless).
color transform image
-: A two-dimensional subresolution image containing data about
- correlations of color components.
+: A two-dimensional subresolution image containing data about correlations of
+ color components.
distance mapping
-: Changes LZ77 distances to have the smallest values for pixels in 2D
- proximity.
+: Changes LZ77 distances to have the smallest values for pixels in 2D
+ proximity.
entropy image
-: A two-dimensional subresolution image indicating which entropy coding
- should be used in a respective square in the image, i.e., each pixel
- is a meta prefix code.
+: A two-dimensional subresolution image indicating which entropy coding should
+ be used in a respective square in the image, i.e., each pixel is a meta
+ prefix code.
prefix code
-: A classic way to do entropy coding where a smaller number of bits are
- used for more frequent codes.
+: A classic way to do entropy coding where a smaller number of bits are used
+ for more frequent codes.
LZ77
-: Dictionary-based sliding window compression algorithm that either
- emits symbols or describes them as sequences of past symbols.
+: Dictionary-based sliding window compression algorithm that either emits
+ symbols or describes them as sequences of past symbols.
meta prefix code
-: A small integer (up to 16 bits) that indexes an element in the meta
- prefix table.
+: A small integer (up to 16 bits) that indexes an element in the meta prefix
+ table.
predictor image
-: A two-dimensional subresolution image indicating which spatial
- predictor is used for a particular square in the image.
+: A two-dimensional subresolution image indicating which spatial predictor is
+ used for a particular square in the image.
prefix coding
-: A way to entropy code larger integers that codes a few bits of the
- integer using an entropy code and codifies the remaining bits raw.
- This allows for the descriptions of the entropy codes to remain
- relatively small even when the range of symbols is large.
+: A way to entropy code larger integers that codes a few bits of the integer
+ using an entropy code and codifies the remaining bits raw. This allows for
+ the descriptions of the entropy codes to remain relatively small even when
+ the range of symbols is large.
scan-line order
-: A processing order of pixels, left-to-right, top-to-bottom, starting
- from the left-hand-top pixel, proceeding to the right. Once a row is
- completed, continue from the left-hand column of the next row.
-
-
-1 Introduction
---------------
-
-This document describes the compressed data representation of a WebP
-lossless image. It is intended as a detailed reference for WebP lossless
-encoder and decoder implementation.
-
-In this document, we extensively use C programming language syntax to
-describe the bitstream, and assume the existence of a function for
-reading bits, `ReadBits(n)`. The bytes are read in the natural order of
-the stream containing them, and bits of each byte are read in
-least-significant-bit-first order. When multiple bits are read at the
-same time, the integer is constructed from the original data in the
-original order. The most significant bits of the returned integer are
-also the most significant bits of the original data. Thus the statement
-
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-b = ReadBits(2);
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-is equivalent with the two statements below:
-
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-b = ReadBits(1);
-b |= ReadBits(1) << 1;
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+: A processing order of pixels, left-to-right, top-to-bottom, starting from
+ the left-hand-top pixel, proceeding to the right. Once a row is completed,
+ continue from the left-hand column of the next row.
-We assume that each color component (e.g. alpha, red, blue and green) is
-represented using an 8-bit byte. We define the corresponding type as
-uint8. A whole ARGB pixel is represented by a type called uint32, an
-unsigned integer consisting of 32 bits. In the code showing the behavior
-of the transformations, alpha value is codified in bits 31..24, red in
-bits 23..16, green in bits 15..8 and blue in bits 7..0, but
-implementations of the format are free to use another representation
-internally.
-
-Broadly, a WebP lossless image contains header data, transform
-information and actual image data. Headers contain width and height of
-the image. A WebP lossless image can go through four different types of
-transformation before being entropy encoded. The transform information
-in the bitstream contains the data required to apply the respective
-inverse transforms.
-
-
-2 RIFF Header
+3 RIFF Header
-------------
The beginning of the header has the RIFF container. This consists of the
@@ -156,49 +154,47 @@ following 21 bytes:
lossless stream.
6. One byte signature 0x2f.
-The first 28 bits of the bitstream specify the width and height of the
-image. Width and height are decoded as 14-bit integers as follows:
+The first 28 bits of the bitstream specify the width and height of the image.
+Width and height are decoded as 14-bit integers as follows:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
int image_width = ReadBits(14) + 1;
int image_height = ReadBits(14) + 1;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-The 14-bit dynamics for image size limit the maximum size of a WebP
-lossless image to 16384✕16384 pixels.
+The 14-bit dynamics for image size limit the maximum size of a WebP lossless
+image to 16384✕16384 pixels.
-The alpha_is_used bit is a hint only, and should not impact decoding.
-It should be set to 0 when all alpha values are 255 in the picture, and
-1 otherwise.
+The alpha_is_used bit is a hint only, and should not impact decoding. It should
+be set to 0 when all alpha values are 255 in the picture, and 1 otherwise.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
int alpha_is_used = ReadBits(1);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-The version_number is a 3 bit code that must be set to 0. Any other value
-should be treated as an error. \[AMENDED\]
+The version_number is a 3 bit code that must be set to 0. Any other value should
+be treated as an error. \[AMENDED\]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
int version_number = ReadBits(3);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-3 Transformations
+4 Transformations
-----------------
-Transformations are reversible manipulations of the image data that can
-reduce the remaining symbolic entropy by modeling spatial and color
-correlations. Transformations can make the final compression more dense.
+Transformations are reversible manipulations of the image data that can reduce
+the remaining symbolic entropy by modeling spatial and color correlations.
+Transformations can make the final compression more dense.
-An image can go through four types of transformation. A 1 bit indicates
-the presence of a transform. Each transform is allowed to be used only
-once. The transformations are used only for the main level ARGB image:
-the subresolution images have no transforms, not even the 0 bit
-indicating the end-of-transforms.
+An image can go through four types of transformation. A 1 bit indicates the
+presence of a transform. Each transform is allowed to be used only once. The
+transformations are used only for the main level ARGB image: the subresolution
+images have no transforms, not even the 0 bit indicating the end-of-transforms.
-Typically an encoder would use these transforms to reduce the Shannon
-entropy in the residual image. Also, the transform data can be decided
-based on entropy minimization.
+Typically, an encoder would use these transforms to reduce the Shannon entropy
+in the residual image. Also, the transform data can be decided based on entropy
+minimization.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
while (ReadBits(1)) { // Transform present.
@@ -211,37 +207,35 @@ while (ReadBits(1)) { // Transform present.
// Decode actual image data (Section 4).
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-If a transform is present then the next two bits specify the transform
-type. There are four types of transforms.
+If a transform is present then the next two bits specify the transform type.
+There are four types of transforms.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
enum TransformType {
PREDICTOR_TRANSFORM = 0,
COLOR_TRANSFORM = 1,
- SUBTRACT_GREEN = 2,
+ SUBTRACT_GREEN_TRANSFORM = 2,
COLOR_INDEXING_TRANSFORM = 3,
};
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-The transform type is followed by the transform data. Transform data
-contains the information required to apply the inverse transform and
-depends on the transform type. Next we describe the transform data for
-different types.
+The transform type is followed by the transform data. Transform data contains
+the information required to apply the inverse transform and depends on the
+transform type. Next we describe the transform data for different types.
-### Predictor Transform
+### 4.1 Predictor Transform
-The predictor transform can be used to reduce entropy by exploiting the
-fact that neighboring pixels are often correlated. In the predictor
-transform, the current pixel value is predicted from the pixels already
-decoded (in scan-line order) and only the residual value (actual -
-predicted) is encoded. The _prediction mode_ determines the type of
-prediction to use. We divide the image into squares and all the pixels
-in a square use the same prediction mode.
+The predictor transform can be used to reduce entropy by exploiting the fact
+that neighboring pixels are often correlated. In the predictor transform, the
+current pixel value is predicted from the pixels already decoded (in scan-line
+order) and only the residual value (actual - predicted) is encoded. The
+_prediction mode_ determines the type of prediction to use. We divide the image
+into squares and all the pixels in a square use the same prediction mode.
-The first 3 bits of prediction data define the block width and height in
-number of bits. The number of block columns, `block_xsize`, is used in
-indexing two-dimensionally.
+The first 3 bits of prediction data define the block width and height in number
+of bits. The number of block columns, `block_xsize`, is used in indexing
+two-dimensionally.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
int size_bits = ReadBits(3) + 2;
@@ -251,26 +245,24 @@ int block_height = (1 << size_bits);
int block_xsize = DIV_ROUND_UP(image_width, 1 << size_bits);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-The transform data contains the prediction mode for each block of the
-image. All the `block_width * block_height` pixels of a block use same
-prediction mode. The prediction modes are treated as pixels of an image
-and encoded using the same techniques described in
-[Chapter 4](#image-data).
+The transform data contains the prediction mode for each block of the image. All
+the `block_width * block_height` pixels of a block use same prediction mode. The
+prediction modes are treated as pixels of an image and encoded using the same
+techniques described in [Chapter 5](#image-data).
-For a pixel _x, y_, one can compute the respective filter block address
-by:
+For a pixel _x, y_, one can compute the respective filter block address by:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
int block_index = (y >> size_bits) * block_xsize +
(x >> size_bits);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-There are 14 different prediction modes. In each prediction mode, the
-current pixel value is predicted from one or more neighboring pixels
-whose values are already known.
+There are 14 different prediction modes. In each prediction mode, the current
+pixel value is predicted from one or more neighboring pixels whose values are
+already known.
-We choose the neighboring pixels (TL, T, TR, and L) of the current pixel
-(P) as follows:
+We choose the neighboring pixels (TL, T, TR, and L) of the current pixel (P) as
+follows:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
O O O O O O O O O O O
@@ -281,12 +273,12 @@ X X X X X X X X X X X
X X X X X X X X X X X
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-where TL means top-left, T top, TR top-right, L left pixel.
-At the time of predicting a value for P, all pixels O, TL, T, TR and L
-have been already processed, and pixel P and all pixels X are unknown.
+where TL means top-left, T top, TR top-right, L left pixel. At the time of
+predicting a value for P, all pixels O, TL, T, TR and L have already been
+processed, and pixel P and all pixels X are unknown.
-Given the above neighboring pixels, the different prediction modes are
-defined as follows.
+Given the above neighboring pixels, the different prediction modes are defined
+as follows.
| Mode | Predicted value of each channel of the current pixel |
| ------ | ------------------------------------------------------- |
@@ -341,8 +333,8 @@ uint32 Select(uint32 L, uint32 T, uint32 TL) {
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-The functions `ClampAddSubtractFull` and `ClampAddSubtractHalf` are
-performed for each ARGB component as follows:
+The functions `ClampAddSubtractFull` and `ClampAddSubtractHalf` are performed
+for each ARGB component as follows:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Clamp the input value between 0 and 255.
@@ -364,30 +356,28 @@ int ClampAddSubtractHalf(int a, int b) {
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
There are special handling rules for some border pixels. If there is a
-prediction transform, regardless of the mode \[0..13\] for these pixels,
-the predicted value for the left-topmost pixel of the image is
-0xff000000, L-pixel for all pixels on the top row, and T-pixel for all
-pixels on the leftmost column.
+prediction transform, regardless of the mode \[0..13\] for these pixels, the
+predicted value for the left-topmost pixel of the image is 0xff000000, L-pixel
+for all pixels on the top row, and T-pixel for all pixels on the leftmost
+column.
-\[AMENDED2\]
-Addressing the TR-pixel for pixels on the rightmost column is
-exceptional. The pixels on the rightmost column are predicted by using
-the modes \[0..13\] just like pixels not on the border, but the leftmost pixel
-on the same row as the current pixel is instead used as the TR-pixel.
+\[AMENDED2\] Addressing the TR-pixel for pixels on the rightmost column is
+exceptional. The pixels on the rightmost column are predicted by using the modes
+\[0..13\] just like pixels not on the border, but the leftmost pixel on the same
+row as the current pixel is instead used as the TR-pixel.
-### Color Transform
+### 4.2 Color Transform
\[AMENDED2\]
-The goal of the color transform is to decorrelate the R, G and B values
-of each pixel. Color transform keeps the green (G) value as it is,
-transforms red (R) based on green and transforms blue (B) based on green
-and then based on red.
+The goal of the color transform is to decorrelate the R, G and B values of each
+pixel. The color transform keeps the green (G) value as it is, transforms red
+(R) based on green and transforms blue (B) based on green and then based on red.
-As is the case for the predictor transform, first the image is divided
-into blocks and the same transform mode is used for all the pixels in a
-block. For each block there are three types of color transform elements.
+As is the case for the predictor transform, first the image is divided into
+blocks and the same transform mode is used for all the pixels in a block. For
+each block there are three types of color transform elements.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
typedef struct {
@@ -397,11 +387,10 @@ typedef struct {
} ColorTransformElement;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-The actual color transformation is done by defining a color transform
-delta. The color transform delta depends on the `ColorTransformElement`,
-which is the same for all the pixels in a particular block. The delta is
-subtracted during color transform. The inverse color transform then is just
-adding those deltas.
+The actual color transformation is done by defining a color transform delta. The
+color transform delta depends on the `ColorTransformElement`, which is the same
+for all the pixels in a particular block. The delta is subtracted during the
+color transform. The inverse color transform then is just adding those deltas.
The color transform function is defined as follows:
@@ -414,18 +403,18 @@ void ColorTransform(uint8 red, uint8 blue, uint8 green,
int tmp_blue = blue;
// Applying the transform is just subtracting the transform deltas
- tmp_red -= ColorTransformDelta(p->green_to_red_, green);
- tmp_blue -= ColorTransformDelta(p->green_to_blue_, green);
- tmp_blue -= ColorTransformDelta(p->red_to_blue_, red);
+ tmp_red -= ColorTransformDelta(trans->green_to_red_, green);
+ tmp_blue -= ColorTransformDelta(trans->green_to_blue_, green);
+ tmp_blue -= ColorTransformDelta(trans->red_to_blue_, red);
*new_red = tmp_red & 0xff;
*new_blue = tmp_blue & 0xff;
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-`ColorTransformDelta` is computed using a signed 8-bit integer
-representing a 3.5-fixed-point number, and a signed 8-bit RGB color
-channel (c) \[-128..127\] and is defined as follows:
+`ColorTransformDelta` is computed using a signed 8-bit integer representing a
+3.5-fixed-point number, and a signed 8-bit RGB color channel (c) \[-128..127\]
+and is defined as follows:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
int8 ColorTransformDelta(int8 t, int8 c) {
@@ -433,22 +422,20 @@ int8 ColorTransformDelta(int8 t, int8 c) {
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-A conversion from the 8-bit unsigned representation (uint8) to the 8-bit
-signed one (int8) is required before calling `ColorTransformDelta()`.
-It should be performed using 8-bit two's complement (that is: uint8 range
-\[128-255\] is mapped to the \[-128, -1\] range of its converted int8 value).
+A conversion from the 8-bit unsigned representation (uint8) to the 8-bit signed
+one (int8) is required before calling `ColorTransformDelta()`. It should be
+performed using 8-bit two's complement (that is: uint8 range \[128..255\] is
+mapped to the \[-128..-1\] range of its converted int8 value).
-The multiplication is to be done using more precision (with at least
-16-bit dynamics). The sign extension property of the shift operation
-does not matter here: only the lowest 8 bits are used from the result,
-and there the sign extension shifting and unsigned shifting are
-consistent with each other.
+The multiplication is to be done using more precision (with at least 16-bit
+dynamics). The sign extension property of the shift operation does not matter
+here: only the lowest 8 bits are used from the result, and there the sign
+extension shifting and unsigned shifting are consistent with each other.
-Now we describe the contents of color transform data so that decoding
-can apply the inverse color transform and recover the original red and
-blue values. The first 3 bits of the color transform data contain the
-width and height of the image block in number of bits, just like the
-predictor transform:
+Now we describe the contents of color transform data so that decoding can apply
+the inverse color transform and recover the original red and blue values. The
+first 3 bits of the color transform data contain the width and height of the
+image block in number of bits, just like the predictor transform:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
int size_bits = ReadBits(3) + 2;
@@ -456,31 +443,30 @@ int block_width = 1 << size_bits;
int block_height = 1 << size_bits;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-The remaining part of the color transform data contains
-`ColorTransformElement` instances corresponding to each block of the
-image. `ColorTransformElement` instances are treated as pixels of an
-image and encoded using the methods described in
-[Chapter 4](#image-data).
+The remaining part of the color transform data contains `ColorTransformElement`
+instances corresponding to each block of the image. `ColorTransformElement`
+instances are treated as pixels of an image and encoded using the methods
+described in [Chapter 5](#image-data).
-During decoding, `ColorTransformElement` instances of the blocks are
-decoded and the inverse color transform is applied on the ARGB values of
-the pixels. As mentioned earlier, that inverse color transform is just
-subtracting `ColorTransformElement` values from the red and blue
-channels.
+During decoding, `ColorTransformElement` instances of the blocks are decoded and
+the inverse color transform is applied on the ARGB values of the pixels. As
+mentioned earlier, that inverse color transform is just adding
+`ColorTransformElement` values to the red and blue channels. \[AMENDED3\]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void InverseTransform(uint8 red, uint8 green, uint8 blue,
- ColorTransformElement *p,
+ ColorTransformElement *trans,
uint8 *new_red, uint8 *new_blue) {
// Transformed values of red and blue components
int tmp_red = red;
int tmp_blue = blue;
- // Applying inverse transform is just adding the
+ // Applying the inverse transform is just adding the
// color transform deltas
tmp_red += ColorTransformDelta(trans->green_to_red, green);
tmp_blue += ColorTransformDelta(trans->green_to_blue, green);
- tmp_blue += ColorTransformDelta(trans->red_to_blue, tmp_red & 0xff);
+ tmp_blue +=
+ ColorTransformDelta(trans->red_to_blue, tmp_red & 0xff);
*new_red = tmp_red & 0xff;
*new_blue = tmp_blue & 0xff;
@@ -488,13 +474,12 @@ void InverseTransform(uint8 red, uint8 green, uint8 blue,
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-### Subtract Green Transform
+### 4.3 Subtract Green Transform
-The subtract green transform subtracts green values from red and blue
-values of each pixel. When this transform is present, the decoder needs
-to add the green value to both red and blue. There is no data associated
-with this transform. The decoder applies the inverse transform as
-follows:
+The subtract green transform subtracts green values from red and blue values of
+each pixel. When this transform is present, the decoder needs to add the green
+value to both red and blue. There is no data associated with this transform. The
+decoder applies the inverse transform as follows:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void AddGreenToBlueAndRed(uint8 green, uint8 *red, uint8 *blue) {
@@ -503,71 +488,64 @@ void AddGreenToBlueAndRed(uint8 green, uint8 *red, uint8 *blue) {
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-This transform is redundant as it can be modeled using the color
-transform, but it is still often useful. Since it can extend the
-dynamics of the color transform and there is no additional data here,
-the subtract green transform can be coded using fewer bits than a
-full-blown color transform.
+This transform is redundant as it can be modeled using the color transform, but
+it is still often useful. Since it can extend the dynamics of the color
+transform and there is no additional data here, the subtract green transform can
+be coded using fewer bits than a full-blown color transform.
-### Color Indexing Transform
+### 4.4 Color Indexing Transform
-If there are not many unique pixel values, it may be more efficient to
-create a color index array and replace the pixel values by the array's
-indices. The color indexing transform achieves this. (In the context of
-WebP lossless, we specifically do not call this a palette transform
-because a similar but more dynamic concept exists in WebP lossless
-encoding: color cache.)
+If there are not many unique pixel values, it may be more efficient to create a
+color index array and replace the pixel values by the array's indices. The color
+indexing transform achieves this. (In the context of WebP lossless, we
+specifically do not call this a palette transform because a similar but more
+dynamic concept exists in WebP lossless encoding: color cache).
-The color indexing transform checks for the number of unique ARGB values
-in the image. If that number is below a threshold (256), it creates an
-array of those ARGB values, which is then used to replace the pixel
-values with the corresponding index: the green channel of the pixels are
-replaced with the index; all alpha values are set to 255; all red and
-blue values to 0.
+The color indexing transform checks for the number of unique ARGB values in the
+image. If that number is below a threshold (256), it creates an array of those
+ARGB values, which is then used to replace the pixel values with the
+corresponding index: the green channel of the pixels are replaced with the
+index; all alpha values are set to 255; all red and blue values to 0.
-The transform data contains color table size and the entries in the
-color table. The decoder reads the color indexing transform data as
-follows:
+The transform data contains color table size and the entries in the color table.
+The decoder reads the color indexing transform data as follows:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 8 bit value for color table size
int color_table_size = ReadBits(8) + 1;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-The color table is stored using the image storage format itself. The
-color table can be obtained by reading an image, without the RIFF
-header, image size, and transforms, assuming a height of one pixel and
-a width of `color_table_size`. The color table is always
-subtraction-coded to reduce image entropy. The deltas of palette colors
-contain typically much less entropy than the colors themselves, leading
-to significant savings for smaller images. In decoding, every final
-color in the color table can be obtained by adding the previous color
-component values by each ARGB component separately, and storing the
-least significant 8 bits of the result.
+The color table is stored using the image storage format itself. The color table
+can be obtained by reading an image, without the RIFF header, image size, and
+transforms, assuming a height of one pixel and a width of `color_table_size`.
+The color table is always subtraction-coded to reduce image entropy. The deltas
+of palette colors contain typically much less entropy than the colors
+themselves, leading to significant savings for smaller images. In decoding,
+every final color in the color table can be obtained by adding the previous
+color component values by each ARGB component separately, and storing the least
+significant 8 bits of the result.
-The inverse transform for the image is simply replacing the pixel values
-(which are indices to the color table) with the actual color table
-values. The indexing is done based on the green component of the ARGB
-color.
+The inverse transform for the image is simply replacing the pixel values (which
+are indices to the color table) with the actual color table values. The indexing
+is done based on the green component of the ARGB color.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Inverse transform
argb = color_table[GREEN(argb)];
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-If the index is equal or larger than color_table_size, the argb color value
-should be set to 0x00000000 (transparent black). \[AMENDED\]
+If the index is equal or larger than `color_table_size`, the argb color value
+should be set to 0x00000000 (transparent black). \[AMENDED\]
-When the color table is small (equal to or less than 16 colors), several
-pixels are bundled into a single pixel. The pixel bundling packs several
-(2, 4, or 8) pixels into a single pixel, reducing the image width
-respectively. Pixel bundling allows for a more efficient joint
-distribution entropy coding of neighboring pixels, and gives some
-arithmetic coding-like benefits to the entropy code, but it can only be
-used when there are a small number of unique values.
+When the color table is small (equal to or less than 16 colors), several pixels
+are bundled into a single pixel. The pixel bundling packs several (2, 4, or 8)
+pixels into a single pixel, reducing the image width respectively. Pixel
+bundling allows for a more efficient joint distribution entropy coding of
+neighboring pixels, and gives some arithmetic coding-like benefits to the
+entropy code, but it can only be used when there are 16 or fewer unique values.
-`color_table_size` specifies how many pixels are combined together:
+`color_table_size` specifies how many pixels are combined:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
int width_bits;
@@ -582,13 +560,12 @@ if (color_table_size <= 2) {
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-`width_bits` has a value of 0, 1, 2 or 3. A value of 0 indicates no
-pixel bundling to be done for the image. A value of 1 indicates that two
-pixels are combined together, and each pixel has a range of \[0..15\]. A
-value of 2 indicates that four pixels are combined together, and each
-pixel has a range of \[0..3\]. A value of 3 indicates that eight pixels
-are combined together and each pixel has a range of \[0..1\], i.e., a
-binary value.
+`width_bits` has a value of 0, 1, 2 or 3. A value of 0 indicates no pixel
+bundling is to be done for the image. A value of 1 indicates that two pixels are
+combined, and each pixel has a range of \[0..15\]. A value of 2 indicates that
+four pixels are combined, and each pixel has a range of \[0..3\]. A value of 3
+indicates that eight pixels are combined and each pixel has a range of \[0..1\],
+i.e., a binary value.
The values are packed into the green component as follows:
@@ -606,12 +583,12 @@ The values are packed into the green component as follows:
the more significant bits of the green value at x / 8.
-4 Image Data
+5 Image Data
------------
Image data is an array of pixel values in scan-line order.
-### 4.1 Roles of Image Data
+### 5.1 Roles of Image Data
We use image data in five different roles:
@@ -620,9 +597,9 @@ We use image data in five different roles:
[meta prefix codes](#decoding-of-meta-prefix-codes). The red and green
components of a pixel define the meta prefix code used in a particular
block of the ARGB image.
- 1. Predictor image: Stores the metadata for [Predictor
- Transform](#predictor-transform). The green component of a pixel defines
- which of the 14 predictors is used within a particular block of the
+ 1. Predictor image: Stores the metadata for
+ [Predictor Transform](#predictor-transform). The green component of a pixel
+ defines which of the 14 predictors is used within a particular block of the
ARGB image.
1. Color transform image. It is created by `ColorTransformElement` values
(defined in [Color Transform](#color-transform)) for different blocks of
@@ -634,7 +611,7 @@ We use image data in five different roles:
[Color Indexing Transform](#color-indexing-transform). This is stored as an
image of width `color_table_size` and height `1`.
-### 4.2 Encoding of Image data
+### 5.2 Encoding of Image Data
The encoding of image data is independent of its role.
@@ -651,21 +628,21 @@ the image.
Each pixel is encoded using one of the three possible methods:
- 1. prefix coded literal: each channel (green, red, blue and alpha) is
+ 1. Prefix coded literal: each channel (green, red, blue and alpha) is
entropy-coded independently;
2. LZ77 backward reference: a sequence of pixels are copied from elsewhere
in the image; or
3. Color cache code: using a short multiplicative hash code (color cache
index) of a recently seen color.
-The following sub-sections describe each of these in detail.
+The following subsections describe each of these in detail.
-#### 4.2.1 Prefix Coded Literals
+#### 5.2.1 Prefix Coded Literals
The pixel is stored as prefix coded values of green, red, blue and alpha (in
that order). See [this section](#decoding-entropy-coded-image-data) for details.
-#### 4.2.2 LZ77 Backward Reference
+#### 5.2.2 LZ77 Backward Reference
Backward references are tuples of _length_ and _distance code_:
@@ -682,8 +659,8 @@ while the extra bits are stored as they are (without an entropy code).
**Rationale**: This approach reduces the storage requirement for the entropy
code. Also, large values are usually rare, and so extra bits would be used for
-very few values in the image. Thus, this approach results in a better
-compression overall.
+very few values in the image. Thus, this approach results in better compression
+overall.
The following table denotes the prefix codes and extra bits used for storing
different ranges of values.
@@ -708,8 +685,8 @@ values. For distance values, however, all the 40 prefix codes are valid.
| 524289..786432 | 38 | 18 |
| 786433..1048576 | 39 | 18 |
-The pseudocode to obtain a (length or distance) value from the prefix code is
-as follows:
+The pseudocode to obtain a (length or distance) value from the prefix code is as
+follows:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
if (prefix_code < 4) {
@@ -723,13 +700,13 @@ return offset + ReadBits(extra_bits) + 1;
**Distance Mapping:**
{:#distance-mapping}
-As noted previously, distance code is a number indicating the position of a
-previously seen pixel, from which the pixels are to be copied. This sub-section
+As noted previously, a distance code is a number indicating the position of a
+previously seen pixel, from which the pixels are to be copied. This subsection
defines the mapping between a distance code and the position of a previous
pixel.
-The distance codes larger than 120 denote the pixel-distance in scan-line
-order, offset by 120.
+Distance codes larger than 120 denote the pixel-distance in scan-line order,
+offset by 120.
The smallest distance codes \[1..120\] are special, and are reserved for a close
neighborhood of the current pixel. This neighborhood consists of 120 pixels:
@@ -744,51 +721,56 @@ The mapping between distance code `i` and the neighboring pixel offset
`(xi, yi)` is as follows:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-(0, 1), (1, 0), (1, 1), (-1, 1), (0, 2), (2, 0), (1, 2), (-1, 2),
-(2, 1), (-2, 1), (2, 2), (-2, 2), (0, 3), (3, 0), (1, 3), (-1, 3),
-(3, 1), (-3, 1), (2, 3), (-2, 3), (3, 2), (-3, 2), (0, 4), (4, 0),
-(1, 4), (-1, 4), (4, 1), (-4, 1), (3, 3), (-3, 3), (2, 4), (-2, 4),
-(4, 2), (-4, 2), (0, 5), (3, 4), (-3, 4), (4, 3), (-4, 3), (5, 0),
-(1, 5), (-1, 5), (5, 1), (-5, 1), (2, 5), (-2, 5), (5, 2), (-5, 2),
-(4, 4), (-4, 4), (3, 5), (-3, 5), (5, 3), (-5, 3), (0, 6), (6, 0),
-(1, 6), (-1, 6), (6, 1), (-6, 1), (2, 6), (-2, 6), (6, 2), (-6, 2),
-(4, 5), (-4, 5), (5, 4), (-5, 4), (3, 6), (-3, 6), (6, 3), (-6, 3),
-(0, 7), (7, 0), (1, 7), (-1, 7), (5, 5), (-5, 5), (7, 1), (-7, 1),
-(4, 6), (-4, 6), (6, 4), (-6, 4), (2, 7), (-2, 7), (7, 2), (-7, 2),
-(3, 7), (-3, 7), (7, 3), (-7, 3), (5, 6), (-5, 6), (6, 5), (-6, 5),
-(8, 0), (4, 7), (-4, 7), (7, 4), (-7, 4), (8, 1), (8, 2), (6, 6),
-(-6, 6), (8, 3), (5, 7), (-5, 7), (7, 5), (-7, 5), (8, 4), (6, 7),
-(-6, 7), (7, 6), (-7, 6), (8, 5), (7, 7), (-7, 7), (8, 6), (8, 7)
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-For example, distance code `1` indicates an offset of `(0, 1)` for the
+(0, 1), (1, 0), (1, 1), (-1, 1), (0, 2), (2, 0), (1, 2),
+(-1, 2), (2, 1), (-2, 1), (2, 2), (-2, 2), (0, 3), (3, 0),
+(1, 3), (-1, 3), (3, 1), (-3, 1), (2, 3), (-2, 3), (3, 2),
+(-3, 2), (0, 4), (4, 0), (1, 4), (-1, 4), (4, 1), (-4, 1),
+(3, 3), (-3, 3), (2, 4), (-2, 4), (4, 2), (-4, 2), (0, 5),
+(3, 4), (-3, 4), (4, 3), (-4, 3), (5, 0), (1, 5), (-1, 5),
+(5, 1), (-5, 1), (2, 5), (-2, 5), (5, 2), (-5, 2), (4, 4),
+(-4, 4), (3, 5), (-3, 5), (5, 3), (-5, 3), (0, 6), (6, 0),
+(1, 6), (-1, 6), (6, 1), (-6, 1), (2, 6), (-2, 6), (6, 2),
+(-6, 2), (4, 5), (-4, 5), (5, 4), (-5, 4), (3, 6), (-3, 6),
+(6, 3), (-6, 3), (0, 7), (7, 0), (1, 7), (-1, 7), (5, 5),
+(-5, 5), (7, 1), (-7, 1), (4, 6), (-4, 6), (6, 4), (-6, 4),
+(2, 7), (-2, 7), (7, 2), (-7, 2), (3, 7), (-3, 7), (7, 3),
+(-7, 3), (5, 6), (-5, 6), (6, 5), (-6, 5), (8, 0), (4, 7),
+(-4, 7), (7, 4), (-7, 4), (8, 1), (8, 2), (6, 6), (-6, 6),
+(8, 3), (5, 7), (-5, 7), (7, 5), (-7, 5), (8, 4), (6, 7),
+(-6, 7), (7, 6), (-7, 6), (8, 5), (7, 7), (-7, 7), (8, 6),
+(8, 7)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+For example, the distance code `1` indicates an offset of `(0, 1)` for the
neighboring pixel, that is, the pixel above the current pixel (0 pixel
-difference in X-direction and 1 pixel difference in Y-direction). Similarly,
-distance code `3` indicates left-top pixel.
+difference in the X-direction and 1 pixel difference in the Y-direction).
+Similarly, the distance code `3` indicates the left-top pixel.
-The decoder can convert a distance code `i` to a scan-line order distance
-`dist` as follows:
+The decoder can convert a distance code `i` to a scan-line order distance `dist`
+as follows:
+
+\[AMENDED3\]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-(xi, yi) = distance_map[i]
-dist = x + y * xsize
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+(xi, yi) = distance_map[i - 1]
+dist = xi + yi * xsize
if (dist < 1) {
dist = 1
}
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
where `distance_map` is the mapping noted above and `xsize` is the width of the
image in pixels.
-#### 4.2.3 Color Cache Coding
+#### 5.2.3 Color Cache Coding
{:#color-cache-code}
Color cache stores a set of colors that have been recently used in the image.
**Rationale:** This way, the recently used colors can sometimes be referred to
more efficiently than emitting them using the other two methods (described in
-[4.2.1](#prefix-coded-literals) and [4.2.2](#lz77-backward-reference)).
+[5.2.1](#prefix-coded-literals) and [5.2.2](#lz77-backward-reference)).
Color cache codes are stored as follows. First, there is a 1-bit value that
indicates if the color cache is used. If this bit is 0, no color cache codes
@@ -806,22 +788,22 @@ int color_cache_size = 1 << color_cache_code_bits;
`color_cache_code_bits` is \[1..11\]. Compliant decoders must indicate a
corrupted bitstream for other values.
-A color cache is an array of size `color_cache_size`. Each entry
-stores one ARGB color. Colors are looked up by indexing them by
-(0x1e35a7bd * `color`) >> (32 - `color_cache_code_bits`). Only one
-lookup is done in a color cache; there is no conflict resolution.
+A color cache is an array of size `color_cache_size`. Each entry stores one ARGB
+color. Colors are looked up by indexing them by (0x1e35a7bd * `color`) >> (32 -
+`color_cache_code_bits`). Only one lookup is done in a color cache; there is no
+conflict resolution.
-In the beginning of decoding or encoding of an image, all entries in all
-color cache values are set to zero. The color cache code is converted to
-this color at decoding time. The state of the color cache is maintained
-by inserting every pixel, be it produced by backward referencing or as
-literals, into the cache in the order they appear in the stream.
+In the beginning of decoding or encoding of an image, all entries in all color
+cache values are set to zero. The color cache code is converted to this color at
+decoding time. The state of the color cache is maintained by inserting every
+pixel, be it produced by backward referencing or as literals, into the cache in
+the order they appear in the stream.
-5 Entropy Code
+6 Entropy Code
--------------
-### 5.1 Overview
+### 6.1 Overview
Most of the data is coded using a [canonical prefix code][canonical_huff].
Hence, the codes are transmitted by sending the _prefix code lengths_, as
@@ -835,7 +817,7 @@ codes.
So, allowing them to use different entropy codes provides more flexibility and
potentially better compression.
-### 5.2 Details
+### 6.2 Details
The encoded image data consists of several parts:
@@ -843,7 +825,7 @@ The encoded image data consists of several parts:
1. Meta prefix codes
1. Entropy-coded image data
-#### 5.2.1 Decoding and Building the Prefix Codes
+#### 6.2.1 Decoding and Building the Prefix Codes
There are several steps in decoding the prefix codes.
@@ -865,9 +847,9 @@ stream. This may be inefficient, but it is allowed by the format.
\[AMENDED2\]
-This variant is used in the special case when only 1 or 2 prefix symbols are
-in the range \[0..255\] with code length `1`. All other prefix code lengths
-are implicitly zeros.
+This variant is used in the special case when only 1 or 2 prefix symbols are in
+the range \[0..255\] with code length `1`. All other prefix code lengths are
+implicitly zeros.
The first bit indicates the number of symbols:
@@ -876,10 +858,11 @@ int num_symbols = ReadBits(1) + 1;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Following are the symbol values.
+
This first symbol is coded using 1 or 8 bits depending on the value of
-`is_first_8bits`. The range is \[0..1\] or \[0..255\], respectively.
-The second symbol, if present, is always assumed to be in the range \[0..255\]
-and coded using 8 bits.
+`is_first_8bits`. The range is \[0..1\] or \[0..255\], respectively. The second
+symbol, if present, is always assumed to be in the range \[0..255\] and coded
+using 8 bits.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
int is_first_8bits = ReadBits(1);
@@ -891,13 +874,12 @@ if (num_symbols == 2) {
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**Note:** Another special case is when _all_ prefix code lengths are _zeros_
-(an empty prefix code). For example, a prefix code for distance can be empty
-if there are no backward references. Similarly, prefix codes for alpha, red,
-and blue can be empty if all pixels within the same meta prefix code are
-produced using the color cache. However, this case doesn't need a special
-handling, as empty prefix codes can be coded as those containing a single
-symbol `0`.
+**Note:** Another special case is when _all_ prefix code lengths are _zeros_ (an
+empty prefix code). For example, a prefix code for distance can be empty if
+there are no backward references. Similarly, prefix codes for alpha, red, and
+blue can be empty if all pixels within the same meta prefix code are produced
+using the color cache. However, this case doesn't need special handling, as
+empty prefix codes can be coded as those containing a single symbol `0`.
**(ii) Normal Code Length Code:**
@@ -908,10 +890,10 @@ First, `num_code_lengths` specifies the number of code lengths.
int num_code_lengths = 4 + ReadBits(4);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-If `num_code_lengths` is > 18, the bitstream is invalid.
+If `num_code_lengths` is > 19, the bitstream is invalid. \[AMENDED3\]
The code lengths are themselves encoded using prefix codes: lower level code
-lengths `code_length_code_lengths` first have to be read. The rest of those
+lengths, `code_length_code_lengths`, first have to be read. The rest of those
`code_length_code_lengths` (according to the order in `kCodeLengthCodeOrder`)
are zeros.
@@ -920,7 +902,7 @@ int kCodeLengthCodes = 19;
int kCodeLengthCodeOrder[kCodeLengthCodes] = {
17, 18, 0, 1, 2, 3, 4, 5, 16, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
};
-int code_length_code_lengths[kCodeLengthCodes] = { 0 }; // All zeros.
+int code_length_code_lengths[kCodeLengthCodes] = { 0 }; // All zeros
for (i = 0; i < num_code_lengths; ++i) {
code_length_code_lengths[kCodeLengthCodeOrder[i]] = ReadBits(3);
}
@@ -934,8 +916,8 @@ int length_nbits = 2 + 2 * ReadBits(3);
int max_symbol = 2 + ReadBits(length_nbits);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-A prefix table is then built from `code_length_code_lengths` and used to read
-up to `max_symbol` code lengths.
+A prefix table is then built from `code_length_code_lengths` and used to read up
+to `max_symbol` code lengths.
* Code \[0..15\] indicates literal code lengths.
* Value 0 means no symbols have been coded.
@@ -955,11 +937,11 @@ distance) is formed using their respective alphabet sizes:
* other literals (A,R,B): 256
* distance code: 40
-#### 5.2.2 Decoding of Meta Prefix Codes
+#### 6.2.2 Decoding of Meta Prefix Codes
As noted earlier, the format allows the use of different prefix codes for
-different blocks of the image. _Meta prefix codes_ are indexes identifying
-which prefix codes to use in different parts of the image.
+different blocks of the image. _Meta prefix codes_ are indexes identifying which
+prefix codes to use in different parts of the image.
Meta prefix codes may be used _only_ when the image is being used in the
[role](#roles-of-image-data) of an _ARGB image_.
@@ -978,7 +960,7 @@ The entropy image defines which prefix codes are used in different parts of the
image, as described below.
The first 3-bits contain the `prefix_bits` value. The dimensions of the entropy
-image are derived from 'prefix_bits'.
+image are derived from `prefix_bits`.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
int prefix_bits = ReadBits(3) + 2;
@@ -996,11 +978,11 @@ The next bits contain an entropy image of width `prefix_xsize` and height
For any given pixel (x, y), there is a set of five prefix codes associated with
it. These codes are (in bitstream order):
- * **prefix code #1**: used for green channel, backward-reference length and
- color cache
- * **prefix code #2, #3 and #4**: used for red, blue and alpha channels
+ * **Prefix code #1**: used for green channel, backward-reference length and
+ color cache.
+ * **Prefix code #2, #3 and #4**: used for red, blue and alpha channels
respectively.
- * **prefix code #5**: used for backward-reference distance.
+ * **Prefix code #5**: used for backward-reference distance.
From here on, we refer to this set as a **prefix code group**.
@@ -1013,8 +995,8 @@ int num_prefix_groups = max(entropy image) + 1;
where `max(entropy image)` indicates the largest prefix code stored in the
entropy image.
-As each prefix code group contains five prefix codes, the total number of
-prefix codes is:
+As each prefix code group contains five prefix codes, the total number of prefix
+codes is:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
int num_prefix_codes = 5 * num_prefix_groups;
@@ -1024,19 +1006,20 @@ Given a pixel (x, y) in the ARGB image, we can obtain the corresponding prefix
codes to be used as follows:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-int position = (y >> prefix_bits) * prefix_xsize + (x >> prefix_bits);
+int position =
+ (y >> prefix_bits) * prefix_xsize + (x >> prefix_bits);
int meta_prefix_code = (entropy_image[pos] >> 8) & 0xffff;
PrefixCodeGroup prefix_group = prefix_code_groups[meta_prefix_code];
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
where, we have assumed the existence of `PrefixCodeGroup` structure, which
-represents a set of five prefix codes. Also, `prefix_code_groups` is an array
-of `PrefixCodeGroup` (of size `num_prefix_groups`).
+represents a set of five prefix codes. Also, `prefix_code_groups` is an array of
+`PrefixCodeGroup` (of size `num_prefix_groups`).
The decoder then uses prefix code group `prefix_group` to decode the pixel
(x, y) as explained in the [next section](#decoding-entropy-coded-image-data).
-#### 5.2.3 Decoding Entropy-coded Image Data
+#### 6.2.3 Decoding Entropy-coded Image Data
\[AMENDED2\]
@@ -1044,8 +1027,8 @@ For the current position (x, y) in the image, the decoder first identifies the
corresponding prefix code group (as explained in the last section). Given the
prefix code group, the pixel is read and decoded as follows:
-Read next symbol S from the bitstream using prefix code #1. Note that S is any
-integer in the range `0` to
+Read the next symbol S from the bitstream using prefix code #1. Note that S is
+any integer in the range `0` to
`(256 + 24 + ` [`color_cache_size`](#color-cache-code)` - 1)`.
The interpretation of S depends on its value:
@@ -1071,72 +1054,86 @@ The interpretation of S depends on its value:
1. Get ARGB color from the color cache at that index.
-6 Overall Structure of the Format
+7 Overall Structure of the Format
---------------------------------
-Below is a view into the format in Backus-Naur form. It does not cover
-all details. End-of-image (EOI) is only implicitly coded into the number
-of pixels (xsize * ysize).
+Below is a view into the format in Augmented Backus-Naur Form ([ABNF]). It does
+not cover all details. End-of-image (EOI) is only implicitly coded into the
+number of pixels (xsize * ysize).
-#### Basic Structure
+#### 7.1 Basic Structure
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-<format> ::= <RIFF header><image size><image stream>
-<image stream> ::= <optional-transform><spatially-coded image>
+format = RIFF-header image-size image-stream
+RIFF-header = "RIFF" 4OCTET "WEBP" "VP8L" 4OCTET %x2F
+image-size = 14BIT 14BIT ; width - 1, height - 1
+image-stream = optional-transform spatially-coded-image
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-#### Structure of Transforms
+#### 7.2 Structure of Transforms
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-<optional-transform> ::= (1-bit value 1; <transform> <optional-transform>) |
- 1-bit value 0
-<transform> ::= <predictor-tx> | <color-tx> | <subtract-green-tx> |
- <color-indexing-tx>
-<predictor-tx> ::= 2-bit value 0; <predictor image>
-<predictor image> ::= 3-bit sub-pixel code ; <entropy-coded image>
-<color-tx> ::= 2-bit value 1; <color image>
-<color image> ::= 3-bit sub-pixel code ; <entropy-coded image>
-<subtract-green-tx> ::= 2-bit value 2
-<color-indexing-tx> ::= 2-bit value 3; <color-indexing image>
-<color-indexing image> ::= 8-bit color count; <entropy-coded image>
+optional-transform = (%b1 transform optional-transform) / %b0
+transform = predictor-tx / color-tx / subtract-green-tx
+transform =/ color-indexing-tx
+
+predictor-tx = %b00 predictor-image
+predictor-image = 3BIT ; sub-pixel code
+ entropy-coded-image
+
+color-tx = %b01 color-image
+color-image = 3BIT ; sub-pixel code
+ entropy-coded-image
+
+subtract-green-tx = %b10
+
+color-indexing-tx = %b11 color-indexing-image
+color-indexing-image = 8BIT ; color count
+ entropy-coded-image
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-#### Structure of the Image Data
+#### 7.3 Structure of the Image Data
\[AMENDED2\]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-<spatially-coded image> ::= <color cache info><meta prefix><data>
-<entropy-coded image> ::= <color cache info><data>
-<color cache info> ::= 1 bit value 0 |
- (1-bit value 1; 4-bit value for color cache size)
-<meta prefix> ::= 1-bit value 0 |
- (1-bit value 1; <entropy image>)
-<data> ::= <prefix codes><lz77-coded image>
-<entropy image> ::= 3-bit subsample value; <entropy-coded image>
-<prefix codes> ::= <prefix code group> | <prefix code group><prefix codes>
-<prefix code group> ::= <prefix code><prefix code><prefix code>
- <prefix code><prefix code>
- See "Interpretation of Meta Prefix Codes" to
- understand what each of these five prefix codes are
- for.
-<prefix code> ::= <simple prefix code> | <normal prefix code>
-<simple prefix code> ::= see "Simple code length code" for details
-<normal prefix code> ::= <code length code>; encoded code lengths
-<code length code> ::= see section "Normal code length code"
-<lz77-coded image> ::= ((<argb-pixel> | <lz77-copy> | <color-cache-code>)
- <lz77-coded image>) | ""
+spatially-coded-image = color-cache-info meta-prefix data
+entropy-coded-image = color-cache-info data
+
+color-cache-info = %b0
+color-cache-info =/ (%b1 4BIT) ; 1 followed by color cache size
+
+meta-prefix = %b0 / (%b1 entropy-image)
+
+data = prefix-codes lz77-coded-image
+entropy-image = 3BIT ; subsample value
+ entropy-coded-image
+
+prefix-codes = prefix-code-group *prefix-codes
+prefix-code-group =
+ 5prefix-code ; See "Interpretation of Meta Prefix Codes" to
+ ; understand what each of these five prefix
+ ; codes are for.
+
+prefix-code = simple-prefix-code / normal-prefix-code
+simple-prefix-code = ; see "Simple Code Length Code" for details
+normal-prefix-code = code-length-code encoded-code-lengths
+code-length-code = ; see section "Normal Code Length Code"
+
+lz77-coded-image =
+ *((argb-pixel / lz77-copy / color-cache-code) lz77-coded-image)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
A possible example sequence:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-<RIFF header><image size>1-bit value 1<subtract-green-tx>
-1-bit value 1<predictor-tx>1-bit value 0<color cache info>1-bit value 0
-<prefix codes><lz77-coded image>
+RIFF-header image-size %b1 subtract-green-tx
+%b1 predictor-tx %b0 color-cache-info
+%b0 prefix-codes lz77-coded-image
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+[ABNF]: https://www.rfc-editor.org/rfc/rfc5234
[canonical_huff]: https://en.wikipedia.org/wiki/Canonical_Huffman_code
diff --git a/examples/Android.mk b/examples/Android.mk
index ad0f84e0..ba3c458c 100644
--- a/examples/Android.mk
+++ b/examples/Android.mk
@@ -1,3 +1,5 @@
+# Ignore this file during non-NDK builds.
+ifdef NDK_ROOT
LOCAL_PATH := $(call my-dir)
################################################################################
@@ -109,3 +111,4 @@ LOCAL_LICENSE_KINDS := SPDX-license-identifier-BSD
LOCAL_LICENSE_CONDITIONS := notice
LOCAL_NOTICE_FILE := $(LOCAL_PATH)/../COPYING $(LOCAL_PATH)/../NOTICE $(LOCAL_PATH)/../PATENTS
include $(BUILD_EXECUTABLE)
+endif # NDK_ROOT
diff --git a/examples/Makefile.am b/examples/Makefile.am
index 8d52589f..72aa9f91 100644
--- a/examples/Makefile.am
+++ b/examples/Makefile.am
@@ -47,7 +47,7 @@ anim_dump_LDADD += ../imageio/libimageenc.la
anim_dump_LDADD += $(PNG_LIBS) $(GIF_LIBS) $(TIFF_LIBS) -lm
cwebp_SOURCES = cwebp.c stopwatch.h
-cwebp_CPPFLAGS = $(AM_CPPFLAGS)
+cwebp_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_srcdir)
cwebp_LDADD =
cwebp_LDADD += libexample_util.la
cwebp_LDADD += ../imageio/libimageio_util.la
diff --git a/examples/cwebp.c b/examples/cwebp.c
index a9f93be0..9adb31ec 100644
--- a/examples/cwebp.c
+++ b/examples/cwebp.c
@@ -27,6 +27,7 @@
#include "../imageio/webpdec.h"
#include "./stopwatch.h"
#include "./unicode.h"
+#include "sharpyuv/sharpyuv.h"
#include "webp/encode.h"
#ifndef WEBP_DLL
@@ -832,8 +833,12 @@ int main(int argc, const char* argv[]) {
#endif
} else if (!strcmp(argv[c], "-version")) {
const int version = WebPGetEncoderVersion();
+ const int sharpyuv_version = SharpYuvGetVersion();
printf("%d.%d.%d\n",
(version >> 16) & 0xff, (version >> 8) & 0xff, version & 0xff);
+ printf("libsharpyuv: %d.%d.%d\n",
+ (sharpyuv_version >> 24) & 0xff, (sharpyuv_version >> 16) & 0xffff,
+ sharpyuv_version & 0xff);
FREE_WARGV_AND_RETURN(0);
} else if (!strcmp(argv[c], "-progress")) {
show_progress = 1;
@@ -1140,9 +1145,10 @@ int main(int argc, const char* argv[]) {
}
picture.use_argb = 1;
- if (!ReadWebP(memory_writer.mem, memory_writer.size, &picture,
- /*keep_alpha=*/WebPPictureHasTransparency(&picture),
- /*metadata=*/NULL)) {
+ if (!ReadWebP(
+ memory_writer.mem, memory_writer.size, &picture,
+ /*keep_alpha=*/WebPPictureHasTransparency(&original_picture),
+ /*metadata=*/NULL)) {
fprintf(stderr, "Error! Cannot decode encoded WebP bitstream\n");
fprintf(stderr, "Error code: %d (%s)\n", picture.error_code,
kErrorMessages[picture.error_code]);
diff --git a/extras/extras.c b/extras/extras.c
index 06f0ecc6..b170ee23 100644
--- a/extras/extras.c
+++ b/extras/extras.c
@@ -18,8 +18,8 @@
#include <string.h>
#define XTRA_MAJ_VERSION 1
-#define XTRA_MIN_VERSION 2
-#define XTRA_REV_VERSION 3
+#define XTRA_MIN_VERSION 3
+#define XTRA_REV_VERSION 0
//------------------------------------------------------------------------------
diff --git a/extras/vwebp_sdl.c b/extras/vwebp_sdl.c
index 3cf44666..e9554eb1 100644
--- a/extras/vwebp_sdl.c
+++ b/extras/vwebp_sdl.c
@@ -75,7 +75,7 @@ int main(int argc, char* argv[]) {
fprintf(stderr, "File too large.\n");
goto Error;
}
- ok = WebpToSDL((const char*)webp, (int)webp_size);
+ ok = WebPToSDL((const char*)webp, (int)webp_size);
free((void*)webp);
if (!ok) {
WFPRINTF(stderr, "Error decoding file %s\n", (const W_CHAR*)file);
diff --git a/extras/webp_to_sdl.c b/extras/webp_to_sdl.c
index b13fc928..1e526811 100644
--- a/extras/webp_to_sdl.c
+++ b/extras/webp_to_sdl.c
@@ -29,7 +29,7 @@
#endif
static int init_ok = 0;
-int WebpToSDL(const char* data, unsigned int data_size) {
+int WebPToSDL(const char* data, unsigned int data_size) {
int ok = 0;
VP8StatusCode status;
WebPDecoderConfig config;
diff --git a/extras/webp_to_sdl.h b/extras/webp_to_sdl.h
index 1b5ea980..1534f2b4 100644
--- a/extras/webp_to_sdl.h
+++ b/extras/webp_to_sdl.h
@@ -14,9 +14,9 @@
#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
+// 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);
+extern int WebPToSDL(const char* data, unsigned int data_size);
#endif // WEBP_EXTRAS_WEBP_TO_SDL_H_
diff --git a/imageio/Android.mk b/imageio/Android.mk
index e410454a..aa877ce9 100644
--- a/imageio/Android.mk
+++ b/imageio/Android.mk
@@ -1,3 +1,5 @@
+# Ignore this file during non-NDK builds.
+ifdef NDK_ROOT
LOCAL_PATH := $(call my-dir)
################################################################################
@@ -61,3 +63,4 @@ LOCAL_LICENSE_KINDS := SPDX-license-identifier-BSD
LOCAL_LICENSE_CONDITIONS := notice
LOCAL_NOTICE_FILE := $(LOCAL_PATH)/../COPYING $(LOCAL_PATH)/../NOTICE $(LOCAL_PATH)/../PATENTS
include $(BUILD_STATIC_LIBRARY)
+endif # NDK_ROOT
diff --git a/imageio/pnmdec.c b/imageio/pnmdec.c
index 2db007d7..0d592c32 100644
--- a/imageio/pnmdec.c
+++ b/imageio/pnmdec.c
@@ -20,6 +20,10 @@
#include "webp/encode.h"
#include "./imageio_util.h"
+#if defined(_MSC_VER) && _MSC_VER < 1900
+#define snprintf _snprintf
+#endif
+
typedef enum {
WIDTH_FLAG = 1 << 0,
HEIGHT_FLAG = 1 << 1,
@@ -111,8 +115,9 @@ static size_t ReadPAMFields(PNMInfo* const info, size_t off) {
break;
} else {
static const char kEllipsis[] = " ...";
+ const size_t kLen = strlen(kEllipsis) + 1; // +1 = trailing \0
int i;
- if (out_size > 20) sprintf(out + 20 - strlen(kEllipsis), kEllipsis);
+ if (out_size > 20) snprintf(out + 20 - kLen, kLen, kEllipsis);
for (i = 0; i < (int)strlen(out); ++i) {
// isprint() might trigger a "char-subscripts" warning if given a char.
if (!isprint((int)out[i])) out[i] = ' ';
diff --git a/makefile.unix b/makefile.unix
index 90397cac..8348d108 100644
--- a/makefile.unix
+++ b/makefile.unix
@@ -3,7 +3,8 @@
# It will not install the libraries system-wide, but just create the 'cwebp'
# and 'dwebp' tools in the examples/ directory, along with the static
# libraries 'src/libwebp.a', 'src/libwebpdecoder.a', 'src/mux/libwebpmux.a',
-# 'src/demux/libwebpdemux.a' and 'extras/libwebpextras.a'.
+# 'src/demux/libwebpdemux.a', 'extras/libwebpextras.a' and
+# 'sharpyuv/libsharpyuv.a'.
#
# To build the library and examples, use:
# make -f makefile.unix
@@ -127,6 +128,7 @@ ANIM_UTIL_OBJS = \
SHARPYUV_OBJS = \
sharpyuv/sharpyuv.o \
+ sharpyuv/sharpyuv_cpu.o \
sharpyuv/sharpyuv_csp.o \
sharpyuv/sharpyuv_dsp.o \
sharpyuv/sharpyuv_gamma.o \
@@ -290,11 +292,12 @@ EXTRA_OBJS = \
extras/quality_estimate.o \
LIBWEBPDECODER_OBJS = $(DEC_OBJS) $(DSP_DEC_OBJS) $(UTILS_DEC_OBJS)
-LIBWEBP_OBJS = $(SHARPYUV_OBJS) $(LIBWEBPDECODER_OBJS) $(ENC_OBJS) \
+LIBWEBP_OBJS = $(LIBWEBPDECODER_OBJS) $(ENC_OBJS) \
$(DSP_ENC_OBJS) $(UTILS_ENC_OBJS)
LIBWEBPMUX_OBJS = $(MUX_OBJS)
LIBWEBPDEMUX_OBJS = $(DEMUX_OBJS)
LIBWEBPEXTRA_OBJS = $(EXTRA_OBJS)
+LIBSHARPYUV_OBJS = $(SHARPYUV_OBJS)
HDRS_INSTALLED = \
src/webp/decode.h \
@@ -304,6 +307,11 @@ HDRS_INSTALLED = \
src/webp/mux_types.h \
src/webp/types.h \
+SHARPYUV_HDRS_INSTALLED = \
+ sharpyuv/sharpyuv.h \
+ sharpyuv/sharpyuv_cpu.h \
+ sharpyuv/sharpyuv_csp.h \
+
HDRS = \
src/dec/alphai_dec.h \
src/dec/common_dec.h \
@@ -343,6 +351,7 @@ HDRS = \
src/utils/utils.h \
src/webp/format_constants.h \
$(HDRS_INSTALLED) \
+ $(SHARPYUV_HDRS_INSTALLED) \
OUT_LIBS = examples/libexample_util.a
OUT_LIBS += imageio/libimageio_util.a
@@ -350,6 +359,7 @@ OUT_LIBS += imageio/libimagedec.a
OUT_LIBS += imageio/libimageenc.a
OUT_LIBS += src/libwebpdecoder.a
OUT_LIBS += src/libwebp.a
+OUT_LIBS += sharpyuv/libsharpyuv.a
EXTRA_LIB = extras/libwebpextras.a
OUT_EXAMPLES = examples/cwebp examples/dwebp
EXTRA_EXAMPLES = examples/gif2webp examples/vwebp examples/webpmux \
@@ -395,6 +405,7 @@ src/libwebpdecoder.a: $(LIBWEBPDECODER_OBJS)
src/libwebp.a: $(LIBWEBP_OBJS)
src/mux/libwebpmux.a: $(LIBWEBPMUX_OBJS)
src/demux/libwebpdemux.a: $(LIBWEBPDEMUX_OBJS)
+sharpyuv/libsharpyuv.a: $(LIBSHARPYUV_OBJS)
%.a:
$(AR) $(ARFLAGS) $@ $^
@@ -412,6 +423,7 @@ examples/webpinfo: examples/webpinfo.o
examples/anim_diff: examples/libanim_util.a examples/libgifdec.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: sharpyuv/libsharpyuv.a
examples/anim_diff: override EXTRA_LIBS += $(GIF_LIBS)
examples/anim_diff: EXTRA_FLAGS += -DWEBP_HAVE_GIF
examples/anim_dump: examples/libanim_util.a examples/libgifdec.a
@@ -420,12 +432,14 @@ 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: sharpyuv/libsharpyuv.a
examples/anim_dump: override EXTRA_LIBS += $(GIF_LIBS) $(DWEBP_LIBS)
examples/cwebp: examples/libexample_util.a
examples/cwebp: imageio/libimagedec.a
examples/cwebp: src/demux/libwebpdemux.a
examples/cwebp: imageio/libimageio_util.a
examples/cwebp: src/libwebp.a
+examples/cwebp: sharpyuv/libsharpyuv.a
examples/cwebp: override EXTRA_LIBS += $(CWEBP_LIBS)
examples/dwebp: examples/libexample_util.a
examples/dwebp: imageio/libimagedec.a
@@ -433,13 +447,16 @@ examples/dwebp: src/demux/libwebpdemux.a
examples/dwebp: imageio/libimageenc.a
examples/dwebp: imageio/libimageio_util.a
examples/dwebp: src/libwebp.a
+examples/dwebp: sharpyuv/libsharpyuv.a
examples/dwebp: override EXTRA_LIBS += $(DWEBP_LIBS)
examples/gif2webp: examples/libexample_util.a imageio/libimageio_util.a
examples/gif2webp: examples/libgifdec.a src/mux/libwebpmux.a src/libwebp.a
+examples/gif2webp: sharpyuv/libsharpyuv.a
examples/gif2webp: override EXTRA_LIBS += $(GIF_LIBS)
examples/gif2webp: EXTRA_FLAGS += -DWEBP_HAVE_GIF
examples/vwebp: examples/libexample_util.a src/demux/libwebpdemux.a
examples/vwebp: imageio/libimageio_util.a src/libwebp.a
+examples/vwebp: sharpyuv/libsharpyuv.a
examples/vwebp: override EXTRA_LIBS += $(GL_LIBS)
examples/vwebp: EXTRA_FLAGS += -DWEBP_HAVE_GL
examples/webpmux: examples/libexample_util.a imageio/libimageio_util.a
@@ -447,7 +464,9 @@ examples/webpmux: src/mux/libwebpmux.a src/libwebpdecoder.a
examples/img2webp: examples/libexample_util.a imageio/libimageio_util.a
examples/img2webp: imageio/libimagedec.a
examples/img2webp: src/demux/libwebpdemux.a
-examples/img2webp: src/mux/libwebpmux.a src/libwebp.a
+examples/img2webp: src/mux/libwebpmux.a
+examples/img2webp: src/libwebp.a
+examples/img2webp: sharpyuv/libsharpyuv.a
examples/img2webp: override EXTRA_LIBS += $(CWEBP_LIBS)
examples/webpinfo: examples/libexample_util.a imageio/libimageio_util.a
examples/webpinfo: src/libwebpdecoder.a
@@ -457,16 +476,19 @@ extras/get_disto: imageio/libimagedec.a
extras/get_disto: src/demux/libwebpdemux.a
extras/get_disto: imageio/libimageio_util.a
extras/get_disto: src/libwebp.a
+extras/get_disto: sharpyuv/libsharpyuv.a
extras/get_disto: override EXTRA_LIBS += $(CWEBP_LIBS)
extras/webp_quality: extras/webp_quality.o
extras/webp_quality: imageio/libimageio_util.a
extras/webp_quality: $(EXTRA_LIB) src/libwebp.a
+extras/webp_quality: sharpyuv/libsharpyuv.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: sharpyuv/libsharpyuv.a
extras/vwebp_sdl: EXTRA_FLAGS += -DWEBP_HAVE_SDL $(SDL_FLAGS)
extras/vwebp_sdl: override EXTRA_LIBS += $(SDL_LIBS)
@@ -477,12 +499,15 @@ dist: DESTDIR := dist
dist: OUT_EXAMPLES += $(EXTRA_EXAMPLES)
dist: all
$(INSTALL) -m755 -d $(DESTDIR)/include/webp \
- $(DESTDIR)/bin $(DESTDIR)/doc $(DESTDIR)/lib
+ $(DESTDIR)/include/webp/sharpyuv \
+ $(DESTDIR)/bin $(DESTDIR)/doc $(DESTDIR)/lib
$(INSTALL) -m755 -s $(OUT_EXAMPLES) $(DESTDIR)/bin
$(INSTALL) -m644 $(HDRS_INSTALLED) $(DESTDIR)/include/webp
+ $(INSTALL) -m644 $(SHARPYUV_HDRS_INSTALLED) $(DESTDIR)/include/webp/sharpyuv
$(INSTALL) -m644 src/libwebp.a $(DESTDIR)/lib
$(INSTALL) -m644 src/demux/libwebpdemux.a $(DESTDIR)/lib
$(INSTALL) -m644 src/mux/libwebpmux.a $(DESTDIR)/lib
+ $(INSTALL) -m644 sharpyuv/libsharpyuv.a $(DESTDIR)/lib
umask 022; \
for m in man/[cdv]webp.1 man/gif2webp.1 man/webpmux.1 \
man/img2webp.1 man/webpinfo.1; do \
diff --git a/sharpyuv/Makefile.am b/sharpyuv/Makefile.am
index a2297a76..b6b46758 100644
--- a/sharpyuv/Makefile.am
+++ b/sharpyuv/Makefile.am
@@ -1,13 +1,19 @@
AM_CPPFLAGS += -I$(top_builddir) -I$(top_srcdir)
AM_CPPFLAGS += -I$(top_builddir)/src -I$(top_srcdir)/src
+
+lib_LTLIBRARIES = libsharpyuv.la
+
noinst_LTLIBRARIES =
-noinst_LTLIBRARIES += libsharpyuv.la
noinst_LTLIBRARIES += libsharpyuv_sse2.la
noinst_LTLIBRARIES += libsharpyuv_neon.la
+libsharpyuvinclude_HEADERS =
+libsharpyuvinclude_HEADERS += sharpyuv.h
+libsharpyuvinclude_HEADERS += sharpyuv_csp.h
noinst_HEADERS =
-noinst_HEADERS += ../src/webp/types.h
+noinst_HEADERS += ../src/dsp/cpu.c
noinst_HEADERS += ../src/dsp/cpu.h
+noinst_HEADERS += ../src/webp/types.h
libsharpyuv_sse2_la_SOURCES =
libsharpyuv_sse2_la_SOURCES += sharpyuv_sse2.c
@@ -20,15 +26,16 @@ libsharpyuv_neon_la_CPPFLAGS = $(libsharpyuv_la_CPPFLAGS)
libsharpyuv_neon_la_CFLAGS = $(AM_CFLAGS) $(NEON_FLAGS)
libsharpyuv_la_SOURCES =
+libsharpyuv_la_SOURCES += sharpyuv_cpu.c sharpyuv_cpu.h
libsharpyuv_la_SOURCES += sharpyuv_csp.c sharpyuv_csp.h
libsharpyuv_la_SOURCES += sharpyuv_dsp.c sharpyuv_dsp.h
libsharpyuv_la_SOURCES += sharpyuv_gamma.c sharpyuv_gamma.h
libsharpyuv_la_SOURCES += sharpyuv.c sharpyuv.h
libsharpyuv_la_CPPFLAGS = $(AM_CPPFLAGS)
-libsharpyuv_la_LDFLAGS =
+libsharpyuv_la_LDFLAGS = -no-undefined -version-info 0:0:0 -lm
libsharpyuv_la_LIBADD =
libsharpyuv_la_LIBADD += libsharpyuv_sse2.la
libsharpyuv_la_LIBADD += libsharpyuv_neon.la
-
-noinst_PROGRAMS =
+libsharpyuvincludedir = $(includedir)/webp/sharpyuv
+pkgconfig_DATA = libsharpyuv.pc
diff --git a/sharpyuv/libsharpyuv.pc.in b/sharpyuv/libsharpyuv.pc.in
new file mode 100644
index 00000000..0fb565a6
--- /dev/null
+++ b/sharpyuv/libsharpyuv.pc.in
@@ -0,0 +1,11 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@/webp
+
+Name: libsharpyuv
+Description: Library for sharp RGB to YUV conversion
+Version: @PACKAGE_VERSION@
+Cflags: -I${includedir}
+Libs: -L${libdir} -l@webp_libname_prefix@sharpyuv
+Libs.private: -lm @PTHREAD_CFLAGS@ @PTHREAD_LIBS@
diff --git a/sharpyuv/libsharpyuv.rc b/sharpyuv/libsharpyuv.rc
new file mode 100644
index 00000000..7f1df723
--- /dev/null
+++ b/sharpyuv/libsharpyuv.rc
@@ -0,0 +1,41 @@
+#define APSTUDIO_READONLY_SYMBOLS
+#include "winres.h"
+#undef APSTUDIO_READONLY_SYMBOLS
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 0,0,2,0
+ PRODUCTVERSION 0,0,2,0
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x40004L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "CompanyName", "Google, Inc."
+ VALUE "FileDescription", "libsharpyuv DLL"
+ VALUE "FileVersion", "0.2.0"
+ VALUE "InternalName", "libsharpyuv.dll"
+ VALUE "LegalCopyright", "Copyright (C) 2022"
+ VALUE "OriginalFilename", "libsharpyuv.dll"
+ VALUE "ProductName", "SharpYuv Library"
+ VALUE "ProductVersion", "0.2.0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
+#endif // English (United States) resources
diff --git a/sharpyuv/sharpyuv.c b/sharpyuv/sharpyuv.c
index 8b3ab721..7de34fb0 100644
--- a/sharpyuv/sharpyuv.c
+++ b/sharpyuv/sharpyuv.c
@@ -15,16 +15,22 @@
#include <assert.h>
#include <limits.h>
-#include <math.h>
+#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include "src/webp/types.h"
-#include "src/dsp/cpu.h"
+#include "sharpyuv/sharpyuv_cpu.h"
#include "sharpyuv/sharpyuv_dsp.h"
#include "sharpyuv/sharpyuv_gamma.h"
//------------------------------------------------------------------------------
+
+int SharpYuvGetVersion(void) {
+ return SHARPYUV_VERSION;
+}
+
+//------------------------------------------------------------------------------
// Sharp RGB->YUV conversion
static const int kNumIterations = 4;
@@ -414,24 +420,45 @@ static int DoSharpArgbToYuv(const uint8_t* r_ptr, const uint8_t* g_ptr,
}
#undef SAFE_ALLOC
+#if defined(WEBP_USE_THREAD) && !defined(_WIN32)
+#include <pthread.h> // NOLINT
+
+#define LOCK_ACCESS \
+ static pthread_mutex_t sharpyuv_lock = PTHREAD_MUTEX_INITIALIZER; \
+ if (pthread_mutex_lock(&sharpyuv_lock)) return
+#define UNLOCK_ACCESS_AND_RETURN \
+ do { \
+ (void)pthread_mutex_unlock(&sharpyuv_lock); \
+ return; \
+ } while (0)
+#else // !(defined(WEBP_USE_THREAD) && !defined(_WIN32))
+#define LOCK_ACCESS do {} while (0)
+#define UNLOCK_ACCESS_AND_RETURN return
+#endif // defined(WEBP_USE_THREAD) && !defined(_WIN32)
+
// Hidden exported init function.
-// By default SharpYuvConvert calls it with NULL. If needed, users can declare
-// it as extern and call it with a VP8CPUInfo function.
-extern void SharpYuvInit(VP8CPUInfo cpu_info_func);
+// By default SharpYuvConvert calls it with SharpYuvGetCPUInfo. If needed,
+// users can declare it as extern and call it with an alternate VP8CPUInfo
+// function.
+SHARPYUV_EXTERN void SharpYuvInit(VP8CPUInfo cpu_info_func);
void SharpYuvInit(VP8CPUInfo cpu_info_func) {
static volatile VP8CPUInfo sharpyuv_last_cpuinfo_used =
(VP8CPUInfo)&sharpyuv_last_cpuinfo_used;
- const int initialized =
- (sharpyuv_last_cpuinfo_used != (VP8CPUInfo)&sharpyuv_last_cpuinfo_used);
- if (cpu_info_func == NULL && initialized) return;
- if (sharpyuv_last_cpuinfo_used == cpu_info_func) return;
-
- SharpYuvInitDsp(cpu_info_func);
- if (!initialized) {
- SharpYuvInitGammaTables();
+ LOCK_ACCESS;
+ // Only update SharpYuvGetCPUInfo when called from external code to avoid a
+ // race on reading the value in SharpYuvConvert().
+ if (cpu_info_func != (VP8CPUInfo)&SharpYuvGetCPUInfo) {
+ SharpYuvGetCPUInfo = cpu_info_func;
+ }
+ if (sharpyuv_last_cpuinfo_used == SharpYuvGetCPUInfo) {
+ UNLOCK_ACCESS_AND_RETURN;
}
- sharpyuv_last_cpuinfo_used = cpu_info_func;
+ SharpYuvInitDsp();
+ SharpYuvInitGammaTables();
+
+ sharpyuv_last_cpuinfo_used = SharpYuvGetCPUInfo;
+ UNLOCK_ACCESS_AND_RETURN;
}
int SharpYuvConvert(const void* r_ptr, const void* g_ptr,
@@ -467,7 +494,8 @@ int SharpYuvConvert(const void* r_ptr, const void* g_ptr,
// Stride should be even for uint16_t buffers.
return 0;
}
- SharpYuvInit(NULL);
+ // The address of the function pointer is used to avoid a read race.
+ SharpYuvInit((VP8CPUInfo)&SharpYuvGetCPUInfo);
// Add scaling factor to go from rgb_bit_depth to yuv_bit_depth, to the
// rgb->yuv conversion matrix.
diff --git a/sharpyuv/sharpyuv.h b/sharpyuv/sharpyuv.h
index 9386ea21..181b20a0 100644
--- a/sharpyuv/sharpyuv.h
+++ b/sharpyuv/sharpyuv.h
@@ -12,15 +12,31 @@
#ifndef WEBP_SHARPYUV_SHARPYUV_H_
#define WEBP_SHARPYUV_SHARPYUV_H_
-#include <inttypes.h>
-
#ifdef __cplusplus
extern "C" {
#endif
+#ifndef SHARPYUV_EXTERN
+#ifdef WEBP_EXTERN
+#define SHARPYUV_EXTERN WEBP_EXTERN
+#else
+// This explicitly marks library functions and allows for changing the
+// signature for e.g., Windows DLL builds.
+#if defined(__GNUC__) && __GNUC__ >= 4
+#define SHARPYUV_EXTERN extern __attribute__((visibility("default")))
+#else
+#if defined(_MSC_VER) && defined(WEBP_DLL)
+#define SHARPYUV_EXTERN __declspec(dllexport)
+#else
+#define SHARPYUV_EXTERN extern
+#endif /* _MSC_VER && WEBP_DLL */
+#endif /* __GNUC__ >= 4 */
+#endif /* WEBP_EXTERN */
+#endif /* SHARPYUV_EXTERN */
+
// SharpYUV API version following the convention from semver.org
#define SHARPYUV_VERSION_MAJOR 0
-#define SHARPYUV_VERSION_MINOR 1
+#define SHARPYUV_VERSION_MINOR 2
#define SHARPYUV_VERSION_PATCH 0
// Version as a uint32_t. The major number is the high 8 bits.
// The minor number is the middle 8 bits. The patch number is the low 16 bits.
@@ -30,6 +46,10 @@ extern "C" {
SHARPYUV_MAKE_VERSION(SHARPYUV_VERSION_MAJOR, SHARPYUV_VERSION_MINOR, \
SHARPYUV_VERSION_PATCH)
+// Returns the library's version number, packed in hexadecimal. See
+// SHARPYUV_VERSION.
+SHARPYUV_EXTERN int SharpYuvGetVersion(void);
+
// RGB to YUV conversion matrix, in 16 bit fixed point.
// y = rgb_to_y[0] * r + rgb_to_y[1] * g + rgb_to_y[2] * b + rgb_to_y[3]
// u = rgb_to_u[0] * r + rgb_to_u[1] * g + rgb_to_u[2] * b + rgb_to_u[3]
@@ -65,11 +85,13 @@ typedef struct {
// adjacent pixels on the y, u and v channels. If yuv_bit_depth > 8, they
// should be multiples of 2.
// width, height: width and height of the image in pixels
-int SharpYuvConvert(const void* r_ptr, const void* g_ptr, const void* b_ptr,
- int rgb_step, int rgb_stride, int rgb_bit_depth,
- void* y_ptr, int y_stride, void* u_ptr, int u_stride,
- void* v_ptr, int v_stride, int yuv_bit_depth, int width,
- int height, const SharpYuvConversionMatrix* yuv_matrix);
+SHARPYUV_EXTERN int SharpYuvConvert(const void* r_ptr, const void* g_ptr,
+ const void* b_ptr, int rgb_step,
+ int rgb_stride, int rgb_bit_depth,
+ void* y_ptr, int y_stride, void* u_ptr,
+ int u_stride, void* v_ptr, int v_stride,
+ int yuv_bit_depth, int width, int height,
+ const SharpYuvConversionMatrix* yuv_matrix);
// TODO(b/194336375): Add YUV444 to YUV420 conversion. Maybe also add 422
// support (it's rarely used in practice, especially for images).
diff --git a/sharpyuv/sharpyuv_cpu.c b/sharpyuv/sharpyuv_cpu.c
new file mode 100644
index 00000000..29425a0c
--- /dev/null
+++ b/sharpyuv/sharpyuv_cpu.c
@@ -0,0 +1,14 @@
+// Copyright 2022 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.
+// -----------------------------------------------------------------------------
+//
+#include "sharpyuv/sharpyuv_cpu.h"
+
+// Include src/dsp/cpu.c to create SharpYuvGetCPUInfo from VP8GetCPUInfo. The
+// function pointer is renamed in sharpyuv_cpu.h.
+#include "src/dsp/cpu.c"
diff --git a/sharpyuv/sharpyuv_cpu.h b/sharpyuv/sharpyuv_cpu.h
new file mode 100644
index 00000000..176ca3eb
--- /dev/null
+++ b/sharpyuv/sharpyuv_cpu.h
@@ -0,0 +1,22 @@
+// Copyright 2022 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.
+// -----------------------------------------------------------------------------
+//
+#ifndef WEBP_SHARPYUV_SHARPYUV_CPU_H_
+#define WEBP_SHARPYUV_SHARPYUV_CPU_H_
+
+#include "sharpyuv/sharpyuv.h"
+
+// Avoid exporting SharpYuvGetCPUInfo in shared object / DLL builds.
+// SharpYuvInit() replaces the use of the function pointer.
+#undef WEBP_EXTERN
+#define WEBP_EXTERN extern
+#define VP8GetCPUInfo SharpYuvGetCPUInfo
+#include "src/dsp/cpu.h"
+
+#endif // WEBP_SHARPYUV_SHARPYUV_CPU_H_
diff --git a/sharpyuv/sharpyuv_csp.c b/sharpyuv/sharpyuv_csp.c
index 5334fa64..0ad22be9 100644
--- a/sharpyuv/sharpyuv_csp.c
+++ b/sharpyuv/sharpyuv_csp.c
@@ -13,7 +13,7 @@
#include <assert.h>
#include <math.h>
-#include <string.h>
+#include <stddef.h>
static int ToFixed16(float f) { return (int)floor(f * (1 << 16) + 0.5f); }
diff --git a/sharpyuv/sharpyuv_csp.h b/sharpyuv/sharpyuv_csp.h
index 63c99ef5..3214e3ac 100644
--- a/sharpyuv/sharpyuv_csp.h
+++ b/sharpyuv/sharpyuv_csp.h
@@ -35,8 +35,9 @@ typedef struct {
} SharpYuvColorSpace;
// Fills in 'matrix' for the given YUVColorSpace.
-void SharpYuvComputeConversionMatrix(const SharpYuvColorSpace* yuv_color_space,
- SharpYuvConversionMatrix* matrix);
+SHARPYUV_EXTERN void SharpYuvComputeConversionMatrix(
+ const SharpYuvColorSpace* yuv_color_space,
+ SharpYuvConversionMatrix* matrix);
// Enums for precomputed conversion matrices.
typedef enum {
@@ -49,7 +50,7 @@ typedef enum {
} SharpYuvMatrixType;
// Returns a pointer to a matrix for one of the predefined colorspaces.
-const SharpYuvConversionMatrix* SharpYuvGetConversionMatrix(
+SHARPYUV_EXTERN const SharpYuvConversionMatrix* SharpYuvGetConversionMatrix(
SharpYuvMatrixType matrix_type);
#ifdef __cplusplus
diff --git a/sharpyuv/sharpyuv_dsp.c b/sharpyuv/sharpyuv_dsp.c
index 956fa7ce..31c272c4 100644
--- a/sharpyuv/sharpyuv_dsp.c
+++ b/sharpyuv/sharpyuv_dsp.c
@@ -16,7 +16,7 @@
#include <assert.h>
#include <stdlib.h>
-#include "src/dsp/cpu.h"
+#include "sharpyuv/sharpyuv_cpu.h"
//-----------------------------------------------------------------------------
@@ -75,23 +75,24 @@ void (*SharpYuvFilterRow)(const int16_t* A, const int16_t* B, int len,
extern void InitSharpYuvSSE2(void);
extern void InitSharpYuvNEON(void);
-void SharpYuvInitDsp(VP8CPUInfo cpu_info_func) {
- (void)cpu_info_func;
-
+void SharpYuvInitDsp(void) {
#if !WEBP_NEON_OMIT_C_CODE
SharpYuvUpdateY = SharpYuvUpdateY_C;
SharpYuvUpdateRGB = SharpYuvUpdateRGB_C;
SharpYuvFilterRow = SharpYuvFilterRow_C;
#endif
+ if (SharpYuvGetCPUInfo != NULL) {
#if defined(WEBP_HAVE_SSE2)
- if (cpu_info_func == NULL || cpu_info_func(kSSE2)) {
- InitSharpYuvSSE2();
- }
+ if (SharpYuvGetCPUInfo(kSSE2)) {
+ InitSharpYuvSSE2();
+ }
#endif // WEBP_HAVE_SSE2
+ }
#if defined(WEBP_HAVE_NEON)
- if (WEBP_NEON_OMIT_C_CODE || cpu_info_func == NULL || cpu_info_func(kNEON)) {
+ if (WEBP_NEON_OMIT_C_CODE ||
+ (SharpYuvGetCPUInfo != NULL && SharpYuvGetCPUInfo(kNEON))) {
InitSharpYuvNEON();
}
#endif // WEBP_HAVE_NEON
diff --git a/sharpyuv/sharpyuv_dsp.h b/sharpyuv/sharpyuv_dsp.h
index e561d8d3..805fbadb 100644
--- a/sharpyuv/sharpyuv_dsp.h
+++ b/sharpyuv/sharpyuv_dsp.h
@@ -12,9 +12,8 @@
#ifndef WEBP_SHARPYUV_SHARPYUV_DSP_H_
#define WEBP_SHARPYUV_SHARPYUV_DSP_H_
-#include <stdint.h>
-
-#include "src/dsp/cpu.h"
+#include "sharpyuv/sharpyuv_cpu.h"
+#include "src/webp/types.h"
extern uint64_t (*SharpYuvUpdateY)(const uint16_t* src, const uint16_t* ref,
uint16_t* dst, int len, int bit_depth);
@@ -24,6 +23,6 @@ extern void (*SharpYuvFilterRow)(const int16_t* A, const int16_t* B, int len,
const uint16_t* best_y, uint16_t* out,
int bit_depth);
-void SharpYuvInitDsp(VP8CPUInfo cpu_info_func);
+void SharpYuvInitDsp(void);
#endif // WEBP_SHARPYUV_SHARPYUV_DSP_H_
diff --git a/sharpyuv/sharpyuv_gamma.c b/sharpyuv/sharpyuv_gamma.c
index 05b5436f..20ab2da6 100644
--- a/sharpyuv/sharpyuv_gamma.c
+++ b/sharpyuv/sharpyuv_gamma.c
@@ -13,7 +13,6 @@
#include <assert.h>
#include <math.h>
-#include <stdint.h>
#include "src/webp/types.h"
diff --git a/sharpyuv/sharpyuv_gamma.h b/sharpyuv/sharpyuv_gamma.h
index 2f1a3ff4..d13aff59 100644
--- a/sharpyuv/sharpyuv_gamma.h
+++ b/sharpyuv/sharpyuv_gamma.h
@@ -12,7 +12,7 @@
#ifndef WEBP_SHARPYUV_SHARPYUV_GAMMA_H_
#define WEBP_SHARPYUV_SHARPYUV_GAMMA_H_
-#include <stdint.h>
+#include "src/webp/types.h"
#ifdef __cplusplus
extern "C" {
diff --git a/sharpyuv/sharpyuv_neon.c b/sharpyuv/sharpyuv_neon.c
index 5cf6aaff..58409148 100644
--- a/sharpyuv/sharpyuv_neon.c
+++ b/sharpyuv/sharpyuv_neon.c
@@ -17,11 +17,6 @@
#include <assert.h>
#include <stdlib.h>
#include <arm_neon.h>
-#endif
-
-extern void InitSharpYuvNEON(void);
-
-#if defined(WEBP_USE_NEON)
static uint16_t clip_NEON(int v, int max) {
return (v < 0) ? 0 : (v > max) ? max : (uint16_t)v;
@@ -169,6 +164,8 @@ static void SharpYuvFilterRow_NEON(const int16_t* A, const int16_t* B, int len,
//------------------------------------------------------------------------------
+extern void InitSharpYuvNEON(void);
+
WEBP_TSAN_IGNORE_FUNCTION void InitSharpYuvNEON(void) {
SharpYuvUpdateY = SharpYuvUpdateY_NEON;
SharpYuvUpdateRGB = SharpYuvUpdateRGB_NEON;
@@ -177,6 +174,8 @@ WEBP_TSAN_IGNORE_FUNCTION void InitSharpYuvNEON(void) {
#else // !WEBP_USE_NEON
+extern void InitSharpYuvNEON(void);
+
void InitSharpYuvNEON(void) {}
#endif // WEBP_USE_NEON
diff --git a/sharpyuv/sharpyuv_sse2.c b/sharpyuv/sharpyuv_sse2.c
index 19438737..9744d1bb 100644
--- a/sharpyuv/sharpyuv_sse2.c
+++ b/sharpyuv/sharpyuv_sse2.c
@@ -16,11 +16,6 @@
#if defined(WEBP_USE_SSE2)
#include <stdlib.h>
#include <emmintrin.h>
-#endif
-
-extern void InitSharpYuvSSE2(void);
-
-#if defined(WEBP_USE_SSE2)
static uint16_t clip_SSE2(int v, int max) {
return (v < 0) ? 0 : (v > max) ? max : (uint16_t)v;
@@ -199,6 +194,8 @@ WEBP_TSAN_IGNORE_FUNCTION void InitSharpYuvSSE2(void) {
}
#else // !WEBP_USE_SSE2
+extern void InitSharpYuvSSE2(void);
+
void InitSharpYuvSSE2(void) {}
#endif // WEBP_USE_SSE2
diff --git a/src/Makefile.am b/src/Makefile.am
index b3f024f1..b2979fbf 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -36,7 +36,7 @@ libwebp_la_LIBADD += utils/libwebputils.la
# other than the ones listed on the command line, i.e., after linking, it will
# not have unresolved symbols. Some platforms (Windows among them) require all
# symbols in shared libraries to be resolved at library creation.
-libwebp_la_LDFLAGS = -no-undefined -version-info 8:4:1
+libwebp_la_LDFLAGS = -no-undefined -version-info 8:6:1
libwebpincludedir = $(includedir)/webp
pkgconfig_DATA = libwebp.pc
@@ -48,7 +48,7 @@ if BUILD_LIBWEBPDECODER
libwebpdecoder_la_LIBADD += dsp/libwebpdspdecode.la
libwebpdecoder_la_LIBADD += utils/libwebputilsdecode.la
- libwebpdecoder_la_LDFLAGS = -no-undefined -version-info 4:4:1
+ libwebpdecoder_la_LDFLAGS = -no-undefined -version-info 4:6:1
pkgconfig_DATA += libwebpdecoder.pc
endif
diff --git a/src/dec/vp8i_dec.h b/src/dec/vp8i_dec.h
index a68ece30..83791ecd 100644
--- a/src/dec/vp8i_dec.h
+++ b/src/dec/vp8i_dec.h
@@ -31,8 +31,8 @@ extern "C" {
// version numbers
#define DEC_MAJ_VERSION 1
-#define DEC_MIN_VERSION 2
-#define DEC_REV_VERSION 3
+#define DEC_MIN_VERSION 3
+#define DEC_REV_VERSION 0
// YUV-cache parameters. Cache is 32-bytes wide (= one cacheline).
// Constraints are: We need to store one 16x16 block of luma samples (y),
diff --git a/src/dec/vp8l_dec.c b/src/dec/vp8l_dec.c
index 13480551..c0ea0181 100644
--- a/src/dec/vp8l_dec.c
+++ b/src/dec/vp8l_dec.c
@@ -1336,7 +1336,7 @@ static int ReadTransform(int* const xsize, int const* ysize,
ok = ok && ExpandColorMap(num_colors, transform);
break;
}
- case SUBTRACT_GREEN:
+ case SUBTRACT_GREEN_TRANSFORM:
break;
default:
assert(0); // can't happen
diff --git a/src/dec/webp_dec.c b/src/dec/webp_dec.c
index 77a54c55..3f4f7bb6 100644
--- a/src/dec/webp_dec.c
+++ b/src/dec/webp_dec.c
@@ -179,7 +179,7 @@ static VP8StatusCode ParseOptionalChunks(const uint8_t** const data,
return VP8_STATUS_BITSTREAM_ERROR; // Not a valid chunk size.
}
// For odd-sized chunk-payload, there's one byte padding at the end.
- disk_chunk_size = (CHUNK_HEADER_SIZE + chunk_size + 1) & ~1;
+ disk_chunk_size = (CHUNK_HEADER_SIZE + chunk_size + 1) & ~1u;
total_size += disk_chunk_size;
// Check that total bytes skipped so far does not exceed riff_size.
diff --git a/src/demux/Makefile.am b/src/demux/Makefile.am
index 3bf7a609..d7392b3e 100644
--- a/src/demux/Makefile.am
+++ b/src/demux/Makefile.am
@@ -13,6 +13,6 @@ noinst_HEADERS =
noinst_HEADERS += ../webp/format_constants.h
libwebpdemux_la_LIBADD = ../libwebp.la
-libwebpdemux_la_LDFLAGS = -no-undefined -version-info 2:10:0
+libwebpdemux_la_LDFLAGS = -no-undefined -version-info 2:12:0
libwebpdemuxincludedir = $(includedir)/webp
pkgconfig_DATA = libwebpdemux.pc
diff --git a/src/demux/demux.c b/src/demux/demux.c
index 80773027..324e5eb9 100644
--- a/src/demux/demux.c
+++ b/src/demux/demux.c
@@ -24,8 +24,8 @@
#include "src/webp/format_constants.h"
#define DMUX_MAJ_VERSION 1
-#define DMUX_MIN_VERSION 2
-#define DMUX_REV_VERSION 3
+#define DMUX_MIN_VERSION 3
+#define DMUX_REV_VERSION 0
typedef struct {
size_t start_; // start location of the data
diff --git a/src/demux/libwebpdemux.pc.in b/src/demux/libwebpdemux.pc.in
index 6dfbbbde..15ed1763 100644
--- a/src/demux/libwebpdemux.pc.in
+++ b/src/demux/libwebpdemux.pc.in
@@ -8,4 +8,4 @@ Description: Library for parsing the WebP graphics format container
Version: @PACKAGE_VERSION@
Requires: libwebp >= 0.2.0
Cflags: -I${includedir}
-Libs: -L${libdir} -lwebpdemux
+Libs: -L${libdir} -l@webp_libname_prefix@webpdemux
diff --git a/src/demux/libwebpdemux.rc b/src/demux/libwebpdemux.rc
index bee513e8..18353e59 100644
--- a/src/demux/libwebpdemux.rc
+++ b/src/demux/libwebpdemux.rc
@@ -6,8 +6,8 @@
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
VS_VERSION_INFO VERSIONINFO
- FILEVERSION 1,0,2,3
- PRODUCTVERSION 1,0,2,3
+ FILEVERSION 1,0,3,0
+ PRODUCTVERSION 1,0,3,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@@ -24,12 +24,12 @@ BEGIN
BEGIN
VALUE "CompanyName", "Google, Inc."
VALUE "FileDescription", "libwebpdemux DLL"
- VALUE "FileVersion", "1.2.3"
+ VALUE "FileVersion", "1.3.0"
VALUE "InternalName", "libwebpdemux.dll"
VALUE "LegalCopyright", "Copyright (C) 2022"
VALUE "OriginalFilename", "libwebpdemux.dll"
VALUE "ProductName", "WebP Image Demuxer"
- VALUE "ProductVersion", "1.2.3"
+ VALUE "ProductVersion", "1.3.0"
END
END
BLOCK "VarFileInfo"
diff --git a/src/dsp/alpha_processing_sse2.c b/src/dsp/alpha_processing_sse2.c
index a5f8c9f7..f0843d0f 100644
--- a/src/dsp/alpha_processing_sse2.c
+++ b/src/dsp/alpha_processing_sse2.c
@@ -26,8 +26,8 @@ static int DispatchAlpha_SSE2(const uint8_t* WEBP_RESTRICT alpha,
uint32_t alpha_and = 0xff;
int i, j;
const __m128i zero = _mm_setzero_si128();
- const __m128i rgb_mask = _mm_set1_epi32(0xffffff00u); // to preserve RGB
- const __m128i all_0xff = _mm_set_epi32(0, 0, ~0u, ~0u);
+ const __m128i rgb_mask = _mm_set1_epi32((int)0xffffff00); // to preserve RGB
+ const __m128i all_0xff = _mm_set_epi32(0, 0, ~0, ~0);
__m128i all_alphas = all_0xff;
// We must be able to access 3 extra bytes after the last written byte
@@ -106,8 +106,8 @@ static int ExtractAlpha_SSE2(const uint8_t* WEBP_RESTRICT argb, int argb_stride,
// value is not 0xff if any of the alpha[] is not equal to 0xff.
uint32_t alpha_and = 0xff;
int i, j;
- const __m128i a_mask = _mm_set1_epi32(0xffu); // to preserve alpha
- const __m128i all_0xff = _mm_set_epi32(0, 0, ~0u, ~0u);
+ const __m128i a_mask = _mm_set1_epi32(0xff); // to preserve alpha
+ const __m128i all_0xff = _mm_set_epi32(0, 0, ~0, ~0);
__m128i all_alphas = all_0xff;
// We must be able to access 3 extra bytes after the last written byte
@@ -178,7 +178,7 @@ static int ExtractAlpha_SSE2(const uint8_t* WEBP_RESTRICT argb, int argb_stride,
static void ApplyAlphaMultiply_SSE2(uint8_t* rgba, int alpha_first,
int w, int h, int stride) {
const __m128i zero = _mm_setzero_si128();
- const __m128i kMult = _mm_set1_epi16(0x8081u);
+ const __m128i kMult = _mm_set1_epi16((short)0x8081);
const __m128i kMask = _mm_set_epi16(0, 0xff, 0xff, 0, 0, 0xff, 0xff, 0);
const int kSpan = 4;
while (h-- > 0) {
@@ -267,7 +267,7 @@ static int HasAlpha32b_SSE2(const uint8_t* src, int length) {
}
static void AlphaReplace_SSE2(uint32_t* src, int length, uint32_t color) {
- const __m128i m_color = _mm_set1_epi32(color);
+ const __m128i m_color = _mm_set1_epi32((int)color);
const __m128i zero = _mm_setzero_si128();
int i = 0;
for (; i + 8 <= length; i += 8) {
diff --git a/src/dsp/alpha_processing_sse41.c b/src/dsp/alpha_processing_sse41.c
index cdf877ce..1156ac34 100644
--- a/src/dsp/alpha_processing_sse41.c
+++ b/src/dsp/alpha_processing_sse41.c
@@ -26,7 +26,7 @@ static int ExtractAlpha_SSE41(const uint8_t* WEBP_RESTRICT argb,
// value is not 0xff if any of the alpha[] is not equal to 0xff.
uint32_t alpha_and = 0xff;
int i, j;
- const __m128i all_0xff = _mm_set1_epi32(~0u);
+ const __m128i all_0xff = _mm_set1_epi32(~0);
__m128i all_alphas = all_0xff;
// We must be able to access 3 extra bytes after the last written byte
diff --git a/src/dsp/cpu.c b/src/dsp/cpu.c
index a4ba7f2c..62de73f7 100644
--- a/src/dsp/cpu.c
+++ b/src/dsp/cpu.c
@@ -212,7 +212,7 @@ VP8CPUInfo VP8GetCPUInfo = wasmCPUInfo;
#elif defined(WEBP_HAVE_NEON)
// In most cases this function doesn't check for NEON support (it's assumed by
// the configuration), but enables turning off NEON at runtime, for testing
-// purposes, by setting VP8DecGetCPUInfo = NULL.
+// purposes, by setting VP8GetCPUInfo = NULL.
static int armCPUInfo(CPUFeature feature) {
if (feature != kNEON) return 0;
#if defined(__linux__) && defined(WEBP_HAVE_NEON_RTCD)
diff --git a/src/dsp/cpu.h b/src/dsp/cpu.h
index 57a40d87..be80727c 100644
--- a/src/dsp/cpu.h
+++ b/src/dsp/cpu.h
@@ -14,6 +14,8 @@
#ifndef WEBP_DSP_CPU_H_
#define WEBP_DSP_CPU_H_
+#include <stddef.h>
+
#ifdef HAVE_CONFIG_H
#include "src/webp/config.h"
#endif
diff --git a/src/dsp/dec_sse2.c b/src/dsp/dec_sse2.c
index 873aa59e..01e6bcb6 100644
--- a/src/dsp/dec_sse2.c
+++ b/src/dsp/dec_sse2.c
@@ -158,10 +158,10 @@ static void Transform_SSE2(const int16_t* in, uint8_t* dst, int do_two) {
dst3 = _mm_loadl_epi64((__m128i*)(dst + 3 * BPS));
} else {
// Load four bytes/pixels per line.
- dst0 = _mm_cvtsi32_si128(WebPMemToUint32(dst + 0 * BPS));
- dst1 = _mm_cvtsi32_si128(WebPMemToUint32(dst + 1 * BPS));
- dst2 = _mm_cvtsi32_si128(WebPMemToUint32(dst + 2 * BPS));
- dst3 = _mm_cvtsi32_si128(WebPMemToUint32(dst + 3 * BPS));
+ dst0 = _mm_cvtsi32_si128(WebPMemToInt32(dst + 0 * BPS));
+ dst1 = _mm_cvtsi32_si128(WebPMemToInt32(dst + 1 * BPS));
+ dst2 = _mm_cvtsi32_si128(WebPMemToInt32(dst + 2 * BPS));
+ dst3 = _mm_cvtsi32_si128(WebPMemToInt32(dst + 3 * BPS));
}
// Convert to 16b.
dst0 = _mm_unpacklo_epi8(dst0, zero);
@@ -187,10 +187,10 @@ static void Transform_SSE2(const int16_t* in, uint8_t* dst, int do_two) {
_mm_storel_epi64((__m128i*)(dst + 3 * BPS), dst3);
} else {
// Store four bytes/pixels per line.
- WebPUint32ToMem(dst + 0 * BPS, _mm_cvtsi128_si32(dst0));
- WebPUint32ToMem(dst + 1 * BPS, _mm_cvtsi128_si32(dst1));
- WebPUint32ToMem(dst + 2 * BPS, _mm_cvtsi128_si32(dst2));
- WebPUint32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32(dst3));
+ WebPInt32ToMem(dst + 0 * BPS, _mm_cvtsi128_si32(dst0));
+ WebPInt32ToMem(dst + 1 * BPS, _mm_cvtsi128_si32(dst1));
+ WebPInt32ToMem(dst + 2 * BPS, _mm_cvtsi128_si32(dst2));
+ WebPInt32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32(dst3));
}
}
}
@@ -213,10 +213,10 @@ static void TransformAC3(const int16_t* in, uint8_t* dst) {
const __m128i m3 = _mm_subs_epi16(B, d4);
const __m128i zero = _mm_setzero_si128();
// Load the source pixels.
- __m128i dst0 = _mm_cvtsi32_si128(WebPMemToUint32(dst + 0 * BPS));
- __m128i dst1 = _mm_cvtsi32_si128(WebPMemToUint32(dst + 1 * BPS));
- __m128i dst2 = _mm_cvtsi32_si128(WebPMemToUint32(dst + 2 * BPS));
- __m128i dst3 = _mm_cvtsi32_si128(WebPMemToUint32(dst + 3 * BPS));
+ __m128i dst0 = _mm_cvtsi32_si128(WebPMemToInt32(dst + 0 * BPS));
+ __m128i dst1 = _mm_cvtsi32_si128(WebPMemToInt32(dst + 1 * BPS));
+ __m128i dst2 = _mm_cvtsi32_si128(WebPMemToInt32(dst + 2 * BPS));
+ __m128i dst3 = _mm_cvtsi32_si128(WebPMemToInt32(dst + 3 * BPS));
// Convert to 16b.
dst0 = _mm_unpacklo_epi8(dst0, zero);
dst1 = _mm_unpacklo_epi8(dst1, zero);
@@ -233,10 +233,10 @@ static void TransformAC3(const int16_t* in, uint8_t* dst) {
dst2 = _mm_packus_epi16(dst2, dst2);
dst3 = _mm_packus_epi16(dst3, dst3);
// Store the results.
- WebPUint32ToMem(dst + 0 * BPS, _mm_cvtsi128_si32(dst0));
- WebPUint32ToMem(dst + 1 * BPS, _mm_cvtsi128_si32(dst1));
- WebPUint32ToMem(dst + 2 * BPS, _mm_cvtsi128_si32(dst2));
- WebPUint32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32(dst3));
+ WebPInt32ToMem(dst + 0 * BPS, _mm_cvtsi128_si32(dst0));
+ WebPInt32ToMem(dst + 1 * BPS, _mm_cvtsi128_si32(dst1));
+ WebPInt32ToMem(dst + 2 * BPS, _mm_cvtsi128_si32(dst2));
+ WebPInt32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32(dst3));
}
#undef MUL
#endif // USE_TRANSFORM_AC3
@@ -477,11 +477,11 @@ static WEBP_INLINE void Load8x4_SSE2(const uint8_t* const b, int stride,
// A0 = 63 62 61 60 23 22 21 20 43 42 41 40 03 02 01 00
// A1 = 73 72 71 70 33 32 31 30 53 52 51 50 13 12 11 10
const __m128i A0 = _mm_set_epi32(
- WebPMemToUint32(&b[6 * stride]), WebPMemToUint32(&b[2 * stride]),
- WebPMemToUint32(&b[4 * stride]), WebPMemToUint32(&b[0 * stride]));
+ WebPMemToInt32(&b[6 * stride]), WebPMemToInt32(&b[2 * stride]),
+ WebPMemToInt32(&b[4 * stride]), WebPMemToInt32(&b[0 * stride]));
const __m128i A1 = _mm_set_epi32(
- WebPMemToUint32(&b[7 * stride]), WebPMemToUint32(&b[3 * stride]),
- WebPMemToUint32(&b[5 * stride]), WebPMemToUint32(&b[1 * stride]));
+ WebPMemToInt32(&b[7 * stride]), WebPMemToInt32(&b[3 * stride]),
+ WebPMemToInt32(&b[5 * stride]), WebPMemToInt32(&b[1 * stride]));
// B0 = 53 43 52 42 51 41 50 40 13 03 12 02 11 01 10 00
// B1 = 73 63 72 62 71 61 70 60 33 23 32 22 31 21 30 20
@@ -540,7 +540,7 @@ static WEBP_INLINE void Store4x4_SSE2(__m128i* const x,
uint8_t* dst, int stride) {
int i;
for (i = 0; i < 4; ++i, dst += stride) {
- WebPUint32ToMem(dst, _mm_cvtsi128_si32(*x));
+ WebPInt32ToMem(dst, _mm_cvtsi128_si32(*x));
*x = _mm_srli_si128(*x, 4);
}
}
@@ -908,10 +908,10 @@ static void VE4_SSE2(uint8_t* dst) { // vertical
const __m128i lsb = _mm_and_si128(_mm_xor_si128(ABCDEFGH, CDEFGH00), one);
const __m128i b = _mm_subs_epu8(a, lsb);
const __m128i avg = _mm_avg_epu8(b, BCDEFGH0);
- const uint32_t vals = _mm_cvtsi128_si32(avg);
+ const int vals = _mm_cvtsi128_si32(avg);
int i;
for (i = 0; i < 4; ++i) {
- WebPUint32ToMem(dst + i * BPS, vals);
+ WebPInt32ToMem(dst + i * BPS, vals);
}
}
@@ -925,10 +925,10 @@ static void LD4_SSE2(uint8_t* dst) { // Down-Left
const __m128i lsb = _mm_and_si128(_mm_xor_si128(ABCDEFGH, CDEFGHH0), one);
const __m128i avg2 = _mm_subs_epu8(avg1, lsb);
const __m128i abcdefg = _mm_avg_epu8(avg2, BCDEFGH0);
- WebPUint32ToMem(dst + 0 * BPS, _mm_cvtsi128_si32( abcdefg ));
- WebPUint32ToMem(dst + 1 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 1)));
- WebPUint32ToMem(dst + 2 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 2)));
- WebPUint32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 3)));
+ WebPInt32ToMem(dst + 0 * BPS, _mm_cvtsi128_si32( abcdefg ));
+ WebPInt32ToMem(dst + 1 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 1)));
+ WebPInt32ToMem(dst + 2 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 2)));
+ WebPInt32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 3)));
}
static void VR4_SSE2(uint8_t* dst) { // Vertical-Right
@@ -946,10 +946,10 @@ static void VR4_SSE2(uint8_t* dst) { // Vertical-Right
const __m128i lsb = _mm_and_si128(_mm_xor_si128(IXABCD, ABCD0), one);
const __m128i avg2 = _mm_subs_epu8(avg1, lsb);
const __m128i efgh = _mm_avg_epu8(avg2, XABCD);
- WebPUint32ToMem(dst + 0 * BPS, _mm_cvtsi128_si32( abcd ));
- WebPUint32ToMem(dst + 1 * BPS, _mm_cvtsi128_si32( efgh ));
- WebPUint32ToMem(dst + 2 * BPS, _mm_cvtsi128_si32(_mm_slli_si128(abcd, 1)));
- WebPUint32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32(_mm_slli_si128(efgh, 1)));
+ WebPInt32ToMem(dst + 0 * BPS, _mm_cvtsi128_si32( abcd ));
+ WebPInt32ToMem(dst + 1 * BPS, _mm_cvtsi128_si32( efgh ));
+ WebPInt32ToMem(dst + 2 * BPS, _mm_cvtsi128_si32(_mm_slli_si128(abcd, 1)));
+ WebPInt32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32(_mm_slli_si128(efgh, 1)));
// these two are hard to implement in SSE2, so we keep the C-version:
DST(0, 2) = AVG3(J, I, X);
@@ -970,11 +970,12 @@ static void VL4_SSE2(uint8_t* dst) { // Vertical-Left
const __m128i abbc = _mm_or_si128(ab, bc);
const __m128i lsb2 = _mm_and_si128(abbc, lsb1);
const __m128i avg4 = _mm_subs_epu8(avg3, lsb2);
- const uint32_t extra_out = _mm_cvtsi128_si32(_mm_srli_si128(avg4, 4));
- WebPUint32ToMem(dst + 0 * BPS, _mm_cvtsi128_si32( avg1 ));
- WebPUint32ToMem(dst + 1 * BPS, _mm_cvtsi128_si32( avg4 ));
- WebPUint32ToMem(dst + 2 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(avg1, 1)));
- WebPUint32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(avg4, 1)));
+ const uint32_t extra_out =
+ (uint32_t)_mm_cvtsi128_si32(_mm_srli_si128(avg4, 4));
+ WebPInt32ToMem(dst + 0 * BPS, _mm_cvtsi128_si32( avg1 ));
+ WebPInt32ToMem(dst + 1 * BPS, _mm_cvtsi128_si32( avg4 ));
+ WebPInt32ToMem(dst + 2 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(avg1, 1)));
+ WebPInt32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(avg4, 1)));
// these two are hard to get and irregular
DST(3, 2) = (extra_out >> 0) & 0xff;
@@ -990,7 +991,7 @@ static void RD4_SSE2(uint8_t* dst) { // Down-right
const uint32_t K = dst[-1 + 2 * BPS];
const uint32_t L = dst[-1 + 3 * BPS];
const __m128i LKJI_____ =
- _mm_cvtsi32_si128(L | (K << 8) | (J << 16) | (I << 24));
+ _mm_cvtsi32_si128((int)(L | (K << 8) | (J << 16) | (I << 24)));
const __m128i LKJIXABCD = _mm_or_si128(LKJI_____, ____XABCD);
const __m128i KJIXABCD_ = _mm_srli_si128(LKJIXABCD, 1);
const __m128i JIXABCD__ = _mm_srli_si128(LKJIXABCD, 2);
@@ -998,10 +999,10 @@ static void RD4_SSE2(uint8_t* dst) { // Down-right
const __m128i lsb = _mm_and_si128(_mm_xor_si128(JIXABCD__, LKJIXABCD), one);
const __m128i avg2 = _mm_subs_epu8(avg1, lsb);
const __m128i abcdefg = _mm_avg_epu8(avg2, KJIXABCD_);
- WebPUint32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32( abcdefg ));
- WebPUint32ToMem(dst + 2 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 1)));
- WebPUint32ToMem(dst + 1 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 2)));
- WebPUint32ToMem(dst + 0 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 3)));
+ WebPInt32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32( abcdefg ));
+ WebPInt32ToMem(dst + 2 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 1)));
+ WebPInt32ToMem(dst + 1 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 2)));
+ WebPInt32ToMem(dst + 0 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 3)));
}
#undef DST
@@ -1015,13 +1016,13 @@ static WEBP_INLINE void TrueMotion_SSE2(uint8_t* dst, int size) {
const __m128i zero = _mm_setzero_si128();
int y;
if (size == 4) {
- const __m128i top_values = _mm_cvtsi32_si128(WebPMemToUint32(top));
+ const __m128i top_values = _mm_cvtsi32_si128(WebPMemToInt32(top));
const __m128i top_base = _mm_unpacklo_epi8(top_values, zero);
for (y = 0; y < 4; ++y, dst += BPS) {
const int val = dst[-1] - top[-1];
const __m128i base = _mm_set1_epi16(val);
const __m128i out = _mm_packus_epi16(_mm_add_epi16(base, top_base), zero);
- WebPUint32ToMem(dst, _mm_cvtsi128_si32(out));
+ WebPInt32ToMem(dst, _mm_cvtsi128_si32(out));
}
} else if (size == 8) {
const __m128i top_values = _mm_loadl_epi64((const __m128i*)top);
@@ -1062,7 +1063,7 @@ static void VE16_SSE2(uint8_t* dst) {
static void HE16_SSE2(uint8_t* dst) { // horizontal
int j;
for (j = 16; j > 0; --j) {
- const __m128i values = _mm_set1_epi8(dst[-1]);
+ const __m128i values = _mm_set1_epi8((char)dst[-1]);
_mm_storeu_si128((__m128i*)dst, values);
dst += BPS;
}
@@ -1070,7 +1071,7 @@ static void HE16_SSE2(uint8_t* dst) { // horizontal
static WEBP_INLINE void Put16_SSE2(uint8_t v, uint8_t* dst) {
int j;
- const __m128i values = _mm_set1_epi8(v);
+ const __m128i values = _mm_set1_epi8((char)v);
for (j = 0; j < 16; ++j) {
_mm_storeu_si128((__m128i*)(dst + j * BPS), values);
}
@@ -1130,7 +1131,7 @@ static void VE8uv_SSE2(uint8_t* dst) { // vertical
// helper for chroma-DC predictions
static WEBP_INLINE void Put8x8uv_SSE2(uint8_t v, uint8_t* dst) {
int j;
- const __m128i values = _mm_set1_epi8(v);
+ const __m128i values = _mm_set1_epi8((char)v);
for (j = 0; j < 8; ++j) {
_mm_storel_epi64((__m128i*)(dst + j * BPS), values);
}
diff --git a/src/dsp/dec_sse41.c b/src/dsp/dec_sse41.c
index 8f18506d..08a36302 100644
--- a/src/dsp/dec_sse41.c
+++ b/src/dsp/dec_sse41.c
@@ -23,7 +23,7 @@ static void HE16_SSE41(uint8_t* dst) { // horizontal
int j;
const __m128i kShuffle3 = _mm_set1_epi8(3);
for (j = 16; j > 0; --j) {
- const __m128i in = _mm_cvtsi32_si128(WebPMemToUint32(dst - 4));
+ const __m128i in = _mm_cvtsi32_si128(WebPMemToInt32(dst - 4));
const __m128i values = _mm_shuffle_epi8(in, kShuffle3);
_mm_storeu_si128((__m128i*)dst, values);
dst += BPS;
diff --git a/src/dsp/enc_neon.c b/src/dsp/enc_neon.c
index 601962ba..3a04111c 100644
--- a/src/dsp/enc_neon.c
+++ b/src/dsp/enc_neon.c
@@ -764,9 +764,14 @@ static WEBP_INLINE void AccumulateSSE16_NEON(const uint8_t* const a,
// Horizontal sum of all four uint32_t values in 'sum'.
static int SumToInt_NEON(uint32x4_t sum) {
+#if defined(__aarch64__)
+ return (int)vaddvq_u32(sum);
+#else
const uint64x2_t sum2 = vpaddlq_u32(sum);
- const uint64_t sum3 = vgetq_lane_u64(sum2, 0) + vgetq_lane_u64(sum2, 1);
- return (int)sum3;
+ const uint32x2_t sum3 = vadd_u32(vreinterpret_u32_u64(vget_low_u64(sum2)),
+ vreinterpret_u32_u64(vget_high_u64(sum2)));
+ return (int)vget_lane_u32(sum3, 0);
+#endif
}
static int SSE16x16_NEON(const uint8_t* a, const uint8_t* b) {
diff --git a/src/dsp/enc_sse2.c b/src/dsp/enc_sse2.c
index b2e78ed9..1d105566 100644
--- a/src/dsp/enc_sse2.c
+++ b/src/dsp/enc_sse2.c
@@ -156,10 +156,10 @@ static void ITransform_SSE2(const uint8_t* ref, const int16_t* in, uint8_t* dst,
ref3 = _mm_loadl_epi64((const __m128i*)&ref[3 * BPS]);
} else {
// Load four bytes/pixels per line.
- ref0 = _mm_cvtsi32_si128(WebPMemToUint32(&ref[0 * BPS]));
- ref1 = _mm_cvtsi32_si128(WebPMemToUint32(&ref[1 * BPS]));
- ref2 = _mm_cvtsi32_si128(WebPMemToUint32(&ref[2 * BPS]));
- ref3 = _mm_cvtsi32_si128(WebPMemToUint32(&ref[3 * BPS]));
+ ref0 = _mm_cvtsi32_si128(WebPMemToInt32(&ref[0 * BPS]));
+ ref1 = _mm_cvtsi32_si128(WebPMemToInt32(&ref[1 * BPS]));
+ ref2 = _mm_cvtsi32_si128(WebPMemToInt32(&ref[2 * BPS]));
+ ref3 = _mm_cvtsi32_si128(WebPMemToInt32(&ref[3 * BPS]));
}
// Convert to 16b.
ref0 = _mm_unpacklo_epi8(ref0, zero);
@@ -185,10 +185,10 @@ static void ITransform_SSE2(const uint8_t* ref, const int16_t* in, uint8_t* dst,
_mm_storel_epi64((__m128i*)&dst[3 * BPS], ref3);
} else {
// Store four bytes/pixels per line.
- WebPUint32ToMem(&dst[0 * BPS], _mm_cvtsi128_si32(ref0));
- WebPUint32ToMem(&dst[1 * BPS], _mm_cvtsi128_si32(ref1));
- WebPUint32ToMem(&dst[2 * BPS], _mm_cvtsi128_si32(ref2));
- WebPUint32ToMem(&dst[3 * BPS], _mm_cvtsi128_si32(ref3));
+ WebPInt32ToMem(&dst[0 * BPS], _mm_cvtsi128_si32(ref0));
+ WebPInt32ToMem(&dst[1 * BPS], _mm_cvtsi128_si32(ref1));
+ WebPInt32ToMem(&dst[2 * BPS], _mm_cvtsi128_si32(ref2));
+ WebPInt32ToMem(&dst[3 * BPS], _mm_cvtsi128_si32(ref3));
}
}
}
@@ -481,7 +481,7 @@ static void CollectHistogram_SSE2(const uint8_t* ref, const uint8_t* pred,
// helper for chroma-DC predictions
static WEBP_INLINE void Put8x8uv_SSE2(uint8_t v, uint8_t* dst) {
int j;
- const __m128i values = _mm_set1_epi8(v);
+ const __m128i values = _mm_set1_epi8((char)v);
for (j = 0; j < 8; ++j) {
_mm_storel_epi64((__m128i*)(dst + j * BPS), values);
}
@@ -489,7 +489,7 @@ static WEBP_INLINE void Put8x8uv_SSE2(uint8_t v, uint8_t* dst) {
static WEBP_INLINE void Put16_SSE2(uint8_t v, uint8_t* dst) {
int j;
- const __m128i values = _mm_set1_epi8(v);
+ const __m128i values = _mm_set1_epi8((char)v);
for (j = 0; j < 16; ++j) {
_mm_store_si128((__m128i*)(dst + j * BPS), values);
}
@@ -540,7 +540,7 @@ static WEBP_INLINE void VerticalPred_SSE2(uint8_t* dst,
static WEBP_INLINE void HE8uv_SSE2(uint8_t* dst, const uint8_t* left) {
int j;
for (j = 0; j < 8; ++j) {
- const __m128i values = _mm_set1_epi8(left[j]);
+ const __m128i values = _mm_set1_epi8((char)left[j]);
_mm_storel_epi64((__m128i*)dst, values);
dst += BPS;
}
@@ -549,7 +549,7 @@ static WEBP_INLINE void HE8uv_SSE2(uint8_t* dst, const uint8_t* left) {
static WEBP_INLINE void HE16_SSE2(uint8_t* dst, const uint8_t* left) {
int j;
for (j = 0; j < 16; ++j) {
- const __m128i values = _mm_set1_epi8(left[j]);
+ const __m128i values = _mm_set1_epi8((char)left[j]);
_mm_store_si128((__m128i*)dst, values);
dst += BPS;
}
@@ -722,10 +722,10 @@ static WEBP_INLINE void VE4_SSE2(uint8_t* dst,
const __m128i lsb = _mm_and_si128(_mm_xor_si128(ABCDEFGH, CDEFGH00), one);
const __m128i b = _mm_subs_epu8(a, lsb);
const __m128i avg = _mm_avg_epu8(b, BCDEFGH0);
- const uint32_t vals = _mm_cvtsi128_si32(avg);
+ const int vals = _mm_cvtsi128_si32(avg);
int i;
for (i = 0; i < 4; ++i) {
- WebPUint32ToMem(dst + i * BPS, vals);
+ WebPInt32ToMem(dst + i * BPS, vals);
}
}
@@ -760,10 +760,10 @@ static WEBP_INLINE void LD4_SSE2(uint8_t* dst,
const __m128i lsb = _mm_and_si128(_mm_xor_si128(ABCDEFGH, CDEFGHH0), one);
const __m128i avg2 = _mm_subs_epu8(avg1, lsb);
const __m128i abcdefg = _mm_avg_epu8(avg2, BCDEFGH0);
- WebPUint32ToMem(dst + 0 * BPS, _mm_cvtsi128_si32( abcdefg ));
- WebPUint32ToMem(dst + 1 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 1)));
- WebPUint32ToMem(dst + 2 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 2)));
- WebPUint32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 3)));
+ WebPInt32ToMem(dst + 0 * BPS, _mm_cvtsi128_si32( abcdefg ));
+ WebPInt32ToMem(dst + 1 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 1)));
+ WebPInt32ToMem(dst + 2 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 2)));
+ WebPInt32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 3)));
}
static WEBP_INLINE void VR4_SSE2(uint8_t* dst,
@@ -782,10 +782,10 @@ static WEBP_INLINE void VR4_SSE2(uint8_t* dst,
const __m128i lsb = _mm_and_si128(_mm_xor_si128(IXABCD, ABCD0), one);
const __m128i avg2 = _mm_subs_epu8(avg1, lsb);
const __m128i efgh = _mm_avg_epu8(avg2, XABCD);
- WebPUint32ToMem(dst + 0 * BPS, _mm_cvtsi128_si32( abcd ));
- WebPUint32ToMem(dst + 1 * BPS, _mm_cvtsi128_si32( efgh ));
- WebPUint32ToMem(dst + 2 * BPS, _mm_cvtsi128_si32(_mm_slli_si128(abcd, 1)));
- WebPUint32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32(_mm_slli_si128(efgh, 1)));
+ WebPInt32ToMem(dst + 0 * BPS, _mm_cvtsi128_si32( abcd ));
+ WebPInt32ToMem(dst + 1 * BPS, _mm_cvtsi128_si32( efgh ));
+ WebPInt32ToMem(dst + 2 * BPS, _mm_cvtsi128_si32(_mm_slli_si128(abcd, 1)));
+ WebPInt32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32(_mm_slli_si128(efgh, 1)));
// these two are hard to implement in SSE2, so we keep the C-version:
DST(0, 2) = AVG3(J, I, X);
@@ -807,11 +807,12 @@ static WEBP_INLINE void VL4_SSE2(uint8_t* dst,
const __m128i abbc = _mm_or_si128(ab, bc);
const __m128i lsb2 = _mm_and_si128(abbc, lsb1);
const __m128i avg4 = _mm_subs_epu8(avg3, lsb2);
- const uint32_t extra_out = _mm_cvtsi128_si32(_mm_srli_si128(avg4, 4));
- WebPUint32ToMem(dst + 0 * BPS, _mm_cvtsi128_si32( avg1 ));
- WebPUint32ToMem(dst + 1 * BPS, _mm_cvtsi128_si32( avg4 ));
- WebPUint32ToMem(dst + 2 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(avg1, 1)));
- WebPUint32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(avg4, 1)));
+ const uint32_t extra_out =
+ (uint32_t)_mm_cvtsi128_si32(_mm_srli_si128(avg4, 4));
+ WebPInt32ToMem(dst + 0 * BPS, _mm_cvtsi128_si32( avg1 ));
+ WebPInt32ToMem(dst + 1 * BPS, _mm_cvtsi128_si32( avg4 ));
+ WebPInt32ToMem(dst + 2 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(avg1, 1)));
+ WebPInt32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(avg4, 1)));
// these two are hard to get and irregular
DST(3, 2) = (extra_out >> 0) & 0xff;
@@ -829,10 +830,10 @@ static WEBP_INLINE void RD4_SSE2(uint8_t* dst,
const __m128i lsb = _mm_and_si128(_mm_xor_si128(JIXABCD__, LKJIXABCD), one);
const __m128i avg2 = _mm_subs_epu8(avg1, lsb);
const __m128i abcdefg = _mm_avg_epu8(avg2, KJIXABCD_);
- WebPUint32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32( abcdefg ));
- WebPUint32ToMem(dst + 2 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 1)));
- WebPUint32ToMem(dst + 1 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 2)));
- WebPUint32ToMem(dst + 0 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 3)));
+ WebPInt32ToMem(dst + 3 * BPS, _mm_cvtsi128_si32( abcdefg ));
+ WebPInt32ToMem(dst + 2 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 1)));
+ WebPInt32ToMem(dst + 1 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 2)));
+ WebPInt32ToMem(dst + 0 * BPS, _mm_cvtsi128_si32(_mm_srli_si128(abcdefg, 3)));
}
static WEBP_INLINE void HU4_SSE2(uint8_t* dst, const uint8_t* top) {
@@ -875,14 +876,14 @@ static WEBP_INLINE void HD4_SSE2(uint8_t* dst, const uint8_t* top) {
static WEBP_INLINE void TM4_SSE2(uint8_t* dst, const uint8_t* top) {
const __m128i zero = _mm_setzero_si128();
- const __m128i top_values = _mm_cvtsi32_si128(WebPMemToUint32(top));
+ const __m128i top_values = _mm_cvtsi32_si128(WebPMemToInt32(top));
const __m128i top_base = _mm_unpacklo_epi8(top_values, zero);
int y;
for (y = 0; y < 4; ++y, dst += BPS) {
const int val = top[-2 - y] - top[-1];
const __m128i base = _mm_set1_epi16(val);
const __m128i out = _mm_packus_epi16(_mm_add_epi16(base, top_base), zero);
- WebPUint32ToMem(dst, _mm_cvtsi128_si32(out));
+ WebPInt32ToMem(dst, _mm_cvtsi128_si32(out));
}
}
diff --git a/src/dsp/lossless.c b/src/dsp/lossless.c
index 84a54296..fb86e58d 100644
--- a/src/dsp/lossless.c
+++ b/src/dsp/lossless.c
@@ -49,7 +49,7 @@ static WEBP_INLINE uint32_t Clip255(uint32_t a) {
}
static WEBP_INLINE int AddSubtractComponentFull(int a, int b, int c) {
- return Clip255(a + b - c);
+ return Clip255((uint32_t)(a + b - c));
}
static WEBP_INLINE uint32_t ClampedAddSubtractFull(uint32_t c0, uint32_t c1,
@@ -66,7 +66,7 @@ static WEBP_INLINE uint32_t ClampedAddSubtractFull(uint32_t c0, uint32_t c1,
}
static WEBP_INLINE int AddSubtractComponentHalf(int a, int b) {
- return Clip255(a + (a - b) / 2);
+ return Clip255((uint32_t)(a + (a - b) / 2));
}
static WEBP_INLINE uint32_t ClampedAddSubtractHalf(uint32_t c0, uint32_t c1,
@@ -293,10 +293,10 @@ void VP8LTransformColorInverse_C(const VP8LMultipliers* const m,
const uint32_t red = argb >> 16;
int new_red = red & 0xff;
int new_blue = argb & 0xff;
- new_red += ColorTransformDelta(m->green_to_red_, green);
+ new_red += ColorTransformDelta((int8_t)m->green_to_red_, green);
new_red &= 0xff;
- new_blue += ColorTransformDelta(m->green_to_blue_, green);
- new_blue += ColorTransformDelta(m->red_to_blue_, (int8_t)new_red);
+ new_blue += ColorTransformDelta((int8_t)m->green_to_blue_, green);
+ new_blue += ColorTransformDelta((int8_t)m->red_to_blue_, (int8_t)new_red);
new_blue &= 0xff;
dst[i] = (argb & 0xff00ff00u) | (new_red << 16) | (new_blue);
}
@@ -395,7 +395,7 @@ void VP8LInverseTransform(const VP8LTransform* const transform,
assert(row_start < row_end);
assert(row_end <= transform->ysize_);
switch (transform->type_) {
- case SUBTRACT_GREEN:
+ case SUBTRACT_GREEN_TRANSFORM:
VP8LAddGreenToBlueAndRed(in, (row_end - row_start) * width, out);
break;
case PREDICTOR_TRANSFORM:
diff --git a/src/dsp/lossless_enc.c b/src/dsp/lossless_enc.c
index de6c4ace..b1f9f26d 100644
--- a/src/dsp/lossless_enc.c
+++ b/src/dsp/lossless_enc.c
@@ -522,11 +522,11 @@ static void GetCombinedEntropyUnrefined_C(const uint32_t X[],
void VP8LSubtractGreenFromBlueAndRed_C(uint32_t* argb_data, int num_pixels) {
int i;
for (i = 0; i < num_pixels; ++i) {
- const int argb = argb_data[i];
+ const int argb = (int)argb_data[i];
const int green = (argb >> 8) & 0xff;
const uint32_t new_r = (((argb >> 16) & 0xff) - green) & 0xff;
const uint32_t new_b = (((argb >> 0) & 0xff) - green) & 0xff;
- argb_data[i] = (argb & 0xff00ff00u) | (new_r << 16) | new_b;
+ argb_data[i] = ((uint32_t)argb & 0xff00ff00u) | (new_r << 16) | new_b;
}
}
@@ -547,10 +547,10 @@ void VP8LTransformColor_C(const VP8LMultipliers* const m, uint32_t* data,
const int8_t red = U32ToS8(argb >> 16);
int new_red = red & 0xff;
int new_blue = argb & 0xff;
- new_red -= ColorTransformDelta(m->green_to_red_, green);
+ new_red -= ColorTransformDelta((int8_t)m->green_to_red_, green);
new_red &= 0xff;
- new_blue -= ColorTransformDelta(m->green_to_blue_, green);
- new_blue -= ColorTransformDelta(m->red_to_blue_, red);
+ new_blue -= ColorTransformDelta((int8_t)m->green_to_blue_, green);
+ new_blue -= ColorTransformDelta((int8_t)m->red_to_blue_, red);
new_blue &= 0xff;
data[i] = (argb & 0xff00ff00u) | (new_red << 16) | (new_blue);
}
@@ -560,7 +560,7 @@ static WEBP_INLINE uint8_t TransformColorRed(uint8_t green_to_red,
uint32_t argb) {
const int8_t green = U32ToS8(argb >> 8);
int new_red = argb >> 16;
- new_red -= ColorTransformDelta(green_to_red, green);
+ new_red -= ColorTransformDelta((int8_t)green_to_red, green);
return (new_red & 0xff);
}
@@ -569,9 +569,9 @@ static WEBP_INLINE uint8_t TransformColorBlue(uint8_t green_to_blue,
uint32_t argb) {
const int8_t green = U32ToS8(argb >> 8);
const int8_t red = U32ToS8(argb >> 16);
- uint8_t new_blue = argb & 0xff;
- new_blue -= ColorTransformDelta(green_to_blue, green);
- new_blue -= ColorTransformDelta(red_to_blue, red);
+ int new_blue = argb & 0xff;
+ new_blue -= ColorTransformDelta((int8_t)green_to_blue, green);
+ new_blue -= ColorTransformDelta((int8_t)red_to_blue, red);
return (new_blue & 0xff);
}
diff --git a/src/dsp/lossless_enc_sse2.c b/src/dsp/lossless_enc_sse2.c
index 948001a3..66cbaab7 100644
--- a/src/dsp/lossless_enc_sse2.c
+++ b/src/dsp/lossless_enc_sse2.c
@@ -54,8 +54,8 @@ static void TransformColor_SSE2(const VP8LMultipliers* const m,
const __m128i mults_rb = MK_CST_16(CST_5b(m->green_to_red_),
CST_5b(m->green_to_blue_));
const __m128i mults_b2 = MK_CST_16(CST_5b(m->red_to_blue_), 0);
- const __m128i mask_ag = _mm_set1_epi32(0xff00ff00); // alpha-green masks
- const __m128i mask_rb = _mm_set1_epi32(0x00ff00ff); // red-blue masks
+ const __m128i mask_ag = _mm_set1_epi32((int)0xff00ff00); // alpha-green masks
+ const __m128i mask_rb = _mm_set1_epi32(0x00ff00ff); // red-blue masks
int i;
for (i = 0; i + 4 <= num_pixels; i += 4) {
const __m128i in = _mm_loadu_si128((__m128i*)&argb_data[i]); // argb
@@ -376,7 +376,7 @@ static void BundleColorMap_SSE2(const uint8_t* const row, int width, int xbits,
break;
}
case 2: {
- const __m128i mask_or = _mm_set1_epi32(0xff000000);
+ const __m128i mask_or = _mm_set1_epi32((int)0xff000000);
const __m128i mul_cst = _mm_set1_epi16(0x0104);
const __m128i mask_mul = _mm_set1_epi16(0x0f00);
for (x = 0; x + 16 <= width; x += 16, dst += 4) {
@@ -427,7 +427,7 @@ static WEBP_INLINE void Average2_m128i(const __m128i* const a0,
static void PredictorSub0_SSE2(const uint32_t* in, const uint32_t* upper,
int num_pixels, uint32_t* out) {
int i;
- const __m128i black = _mm_set1_epi32(ARGB_BLACK);
+ const __m128i black = _mm_set1_epi32((int)ARGB_BLACK);
for (i = 0; i + 4 <= num_pixels; i += 4) {
const __m128i src = _mm_loadu_si128((const __m128i*)&in[i]);
const __m128i res = _mm_sub_epi8(src, black);
diff --git a/src/dsp/lossless_sse2.c b/src/dsp/lossless_sse2.c
index 396cb0bd..4b6a532c 100644
--- a/src/dsp/lossless_sse2.c
+++ b/src/dsp/lossless_sse2.c
@@ -27,23 +27,22 @@ static WEBP_INLINE uint32_t ClampedAddSubtractFull_SSE2(uint32_t c0,
uint32_t c1,
uint32_t c2) {
const __m128i zero = _mm_setzero_si128();
- const __m128i C0 = _mm_unpacklo_epi8(_mm_cvtsi32_si128(c0), zero);
- const __m128i C1 = _mm_unpacklo_epi8(_mm_cvtsi32_si128(c1), zero);
- const __m128i C2 = _mm_unpacklo_epi8(_mm_cvtsi32_si128(c2), zero);
+ const __m128i C0 = _mm_unpacklo_epi8(_mm_cvtsi32_si128((int)c0), zero);
+ const __m128i C1 = _mm_unpacklo_epi8(_mm_cvtsi32_si128((int)c1), zero);
+ const __m128i C2 = _mm_unpacklo_epi8(_mm_cvtsi32_si128((int)c2), zero);
const __m128i V1 = _mm_add_epi16(C0, C1);
const __m128i V2 = _mm_sub_epi16(V1, C2);
const __m128i b = _mm_packus_epi16(V2, V2);
- const uint32_t output = _mm_cvtsi128_si32(b);
- return output;
+ return (uint32_t)_mm_cvtsi128_si32(b);
}
static WEBP_INLINE uint32_t ClampedAddSubtractHalf_SSE2(uint32_t c0,
uint32_t c1,
uint32_t c2) {
const __m128i zero = _mm_setzero_si128();
- const __m128i C0 = _mm_unpacklo_epi8(_mm_cvtsi32_si128(c0), zero);
- const __m128i C1 = _mm_unpacklo_epi8(_mm_cvtsi32_si128(c1), zero);
- const __m128i B0 = _mm_unpacklo_epi8(_mm_cvtsi32_si128(c2), zero);
+ const __m128i C0 = _mm_unpacklo_epi8(_mm_cvtsi32_si128((int)c0), zero);
+ const __m128i C1 = _mm_unpacklo_epi8(_mm_cvtsi32_si128((int)c1), zero);
+ const __m128i B0 = _mm_unpacklo_epi8(_mm_cvtsi32_si128((int)c2), zero);
const __m128i avg = _mm_add_epi16(C1, C0);
const __m128i A0 = _mm_srli_epi16(avg, 1);
const __m128i A1 = _mm_sub_epi16(A0, B0);
@@ -52,16 +51,15 @@ static WEBP_INLINE uint32_t ClampedAddSubtractHalf_SSE2(uint32_t c0,
const __m128i A3 = _mm_srai_epi16(A2, 1);
const __m128i A4 = _mm_add_epi16(A0, A3);
const __m128i A5 = _mm_packus_epi16(A4, A4);
- const uint32_t output = _mm_cvtsi128_si32(A5);
- return output;
+ return (uint32_t)_mm_cvtsi128_si32(A5);
}
static WEBP_INLINE uint32_t Select_SSE2(uint32_t a, uint32_t b, uint32_t c) {
int pa_minus_pb;
const __m128i zero = _mm_setzero_si128();
- const __m128i A0 = _mm_cvtsi32_si128(a);
- const __m128i B0 = _mm_cvtsi32_si128(b);
- const __m128i C0 = _mm_cvtsi32_si128(c);
+ const __m128i A0 = _mm_cvtsi32_si128((int)a);
+ const __m128i B0 = _mm_cvtsi32_si128((int)b);
+ const __m128i C0 = _mm_cvtsi32_si128((int)c);
const __m128i AC0 = _mm_subs_epu8(A0, C0);
const __m128i CA0 = _mm_subs_epu8(C0, A0);
const __m128i BC0 = _mm_subs_epu8(B0, C0);
@@ -94,8 +92,8 @@ static WEBP_INLINE void Average2_uint32_SSE2(const uint32_t a0,
__m128i* const avg) {
// (a + b) >> 1 = ((a + b + 1) >> 1) - ((a ^ b) & 1)
const __m128i ones = _mm_set1_epi8(1);
- const __m128i A0 = _mm_cvtsi32_si128(a0);
- const __m128i A1 = _mm_cvtsi32_si128(a1);
+ const __m128i A0 = _mm_cvtsi32_si128((int)a0);
+ const __m128i A1 = _mm_cvtsi32_si128((int)a1);
const __m128i avg1 = _mm_avg_epu8(A0, A1);
const __m128i one = _mm_and_si128(_mm_xor_si128(A0, A1), ones);
*avg = _mm_sub_epi8(avg1, one);
@@ -103,8 +101,8 @@ static WEBP_INLINE void Average2_uint32_SSE2(const uint32_t a0,
static WEBP_INLINE __m128i Average2_uint32_16_SSE2(uint32_t a0, uint32_t a1) {
const __m128i zero = _mm_setzero_si128();
- const __m128i A0 = _mm_unpacklo_epi8(_mm_cvtsi32_si128(a0), zero);
- const __m128i A1 = _mm_unpacklo_epi8(_mm_cvtsi32_si128(a1), zero);
+ const __m128i A0 = _mm_unpacklo_epi8(_mm_cvtsi32_si128((int)a0), zero);
+ const __m128i A1 = _mm_unpacklo_epi8(_mm_cvtsi32_si128((int)a1), zero);
const __m128i sum = _mm_add_epi16(A1, A0);
return _mm_srli_epi16(sum, 1);
}
@@ -112,19 +110,18 @@ static WEBP_INLINE __m128i Average2_uint32_16_SSE2(uint32_t a0, uint32_t a1) {
static WEBP_INLINE uint32_t Average2_SSE2(uint32_t a0, uint32_t a1) {
__m128i output;
Average2_uint32_SSE2(a0, a1, &output);
- return _mm_cvtsi128_si32(output);
+ return (uint32_t)_mm_cvtsi128_si32(output);
}
static WEBP_INLINE uint32_t Average3_SSE2(uint32_t a0, uint32_t a1,
uint32_t a2) {
const __m128i zero = _mm_setzero_si128();
const __m128i avg1 = Average2_uint32_16_SSE2(a0, a2);
- const __m128i A1 = _mm_unpacklo_epi8(_mm_cvtsi32_si128(a1), zero);
+ const __m128i A1 = _mm_unpacklo_epi8(_mm_cvtsi32_si128((int)a1), zero);
const __m128i sum = _mm_add_epi16(avg1, A1);
const __m128i avg2 = _mm_srli_epi16(sum, 1);
const __m128i A2 = _mm_packus_epi16(avg2, avg2);
- const uint32_t output = _mm_cvtsi128_si32(A2);
- return output;
+ return (uint32_t)_mm_cvtsi128_si32(A2);
}
static WEBP_INLINE uint32_t Average4_SSE2(uint32_t a0, uint32_t a1,
@@ -134,8 +131,7 @@ static WEBP_INLINE uint32_t Average4_SSE2(uint32_t a0, uint32_t a1,
const __m128i sum = _mm_add_epi16(avg2, avg1);
const __m128i avg3 = _mm_srli_epi16(sum, 1);
const __m128i A0 = _mm_packus_epi16(avg3, avg3);
- const uint32_t output = _mm_cvtsi128_si32(A0);
- return output;
+ return (uint32_t)_mm_cvtsi128_si32(A0);
}
static uint32_t Predictor5_SSE2(const uint32_t* const left,
@@ -192,7 +188,7 @@ static uint32_t Predictor13_SSE2(const uint32_t* const left,
static void PredictorAdd0_SSE2(const uint32_t* in, const uint32_t* upper,
int num_pixels, uint32_t* out) {
int i;
- const __m128i black = _mm_set1_epi32(ARGB_BLACK);
+ const __m128i black = _mm_set1_epi32((int)ARGB_BLACK);
for (i = 0; i + 4 <= num_pixels; i += 4) {
const __m128i src = _mm_loadu_si128((const __m128i*)&in[i]);
const __m128i res = _mm_add_epi8(src, black);
@@ -208,7 +204,7 @@ static void PredictorAdd0_SSE2(const uint32_t* in, const uint32_t* upper,
static void PredictorAdd1_SSE2(const uint32_t* in, const uint32_t* upper,
int num_pixels, uint32_t* out) {
int i;
- __m128i prev = _mm_set1_epi32(out[-1]);
+ __m128i prev = _mm_set1_epi32((int)out[-1]);
for (i = 0; i + 4 <= num_pixels; i += 4) {
// a | b | c | d
const __m128i src = _mm_loadu_si128((const __m128i*)&in[i]);
@@ -285,12 +281,12 @@ GENERATE_PREDICTOR_2(9, upper[i + 1])
#undef GENERATE_PREDICTOR_2
// Predictor10: average of (average of (L,TL), average of (T, TR)).
-#define DO_PRED10(OUT) do { \
- __m128i avgLTL, avg; \
- Average2_m128i(&L, &TL, &avgLTL); \
- Average2_m128i(&avgTTR, &avgLTL, &avg); \
- L = _mm_add_epi8(avg, src); \
- out[i + (OUT)] = _mm_cvtsi128_si32(L); \
+#define DO_PRED10(OUT) do { \
+ __m128i avgLTL, avg; \
+ Average2_m128i(&L, &TL, &avgLTL); \
+ Average2_m128i(&avgTTR, &avgLTL, &avg); \
+ L = _mm_add_epi8(avg, src); \
+ out[i + (OUT)] = (uint32_t)_mm_cvtsi128_si32(L); \
} while (0)
#define DO_PRED10_SHIFT do { \
@@ -303,7 +299,7 @@ GENERATE_PREDICTOR_2(9, upper[i + 1])
static void PredictorAdd10_SSE2(const uint32_t* in, const uint32_t* upper,
int num_pixels, uint32_t* out) {
int i;
- __m128i L = _mm_cvtsi32_si128(out[-1]);
+ __m128i L = _mm_cvtsi32_si128((int)out[-1]);
for (i = 0; i + 4 <= num_pixels; i += 4) {
__m128i src = _mm_loadu_si128((const __m128i*)&in[i]);
__m128i TL = _mm_loadu_si128((const __m128i*)&upper[i - 1]);
@@ -336,7 +332,7 @@ static void PredictorAdd10_SSE2(const uint32_t* in, const uint32_t* upper,
const __m128i B = _mm_andnot_si128(mask, T); \
const __m128i pred = _mm_or_si128(A, B); /* pred = (pa > b)? L : T*/ \
L = _mm_add_epi8(src, pred); \
- out[i + (OUT)] = _mm_cvtsi128_si32(L); \
+ out[i + (OUT)] = (uint32_t)_mm_cvtsi128_si32(L); \
} while (0)
#define DO_PRED11_SHIFT do { \
@@ -351,7 +347,7 @@ static void PredictorAdd11_SSE2(const uint32_t* in, const uint32_t* upper,
int num_pixels, uint32_t* out) {
int i;
__m128i pa;
- __m128i L = _mm_cvtsi32_si128(out[-1]);
+ __m128i L = _mm_cvtsi32_si128((int)out[-1]);
for (i = 0; i + 4 <= num_pixels; i += 4) {
__m128i T = _mm_loadu_si128((const __m128i*)&upper[i]);
__m128i TL = _mm_loadu_si128((const __m128i*)&upper[i - 1]);
@@ -384,12 +380,12 @@ static void PredictorAdd11_SSE2(const uint32_t* in, const uint32_t* upper,
#undef DO_PRED11_SHIFT
// Predictor12: ClampedAddSubtractFull.
-#define DO_PRED12(DIFF, LANE, OUT) do { \
- const __m128i all = _mm_add_epi16(L, (DIFF)); \
- const __m128i alls = _mm_packus_epi16(all, all); \
- const __m128i res = _mm_add_epi8(src, alls); \
- out[i + (OUT)] = _mm_cvtsi128_si32(res); \
- L = _mm_unpacklo_epi8(res, zero); \
+#define DO_PRED12(DIFF, LANE, OUT) do { \
+ const __m128i all = _mm_add_epi16(L, (DIFF)); \
+ const __m128i alls = _mm_packus_epi16(all, all); \
+ const __m128i res = _mm_add_epi8(src, alls); \
+ out[i + (OUT)] = (uint32_t)_mm_cvtsi128_si32(res); \
+ L = _mm_unpacklo_epi8(res, zero); \
} while (0)
#define DO_PRED12_SHIFT(DIFF, LANE) do { \
@@ -402,7 +398,7 @@ static void PredictorAdd12_SSE2(const uint32_t* in, const uint32_t* upper,
int num_pixels, uint32_t* out) {
int i;
const __m128i zero = _mm_setzero_si128();
- const __m128i L8 = _mm_cvtsi32_si128(out[-1]);
+ const __m128i L8 = _mm_cvtsi32_si128((int)out[-1]);
__m128i L = _mm_unpacklo_epi8(L8, zero);
for (i = 0; i + 4 <= num_pixels; i += 4) {
// Load 4 pixels at a time.
@@ -468,7 +464,7 @@ static void TransformColorInverse_SSE2(const VP8LMultipliers* const m,
const __m128i mults_b2 = MK_CST_16(CST(red_to_blue_), 0);
#undef MK_CST_16
#undef CST
- const __m128i mask_ag = _mm_set1_epi32(0xff00ff00); // alpha-green masks
+ const __m128i mask_ag = _mm_set1_epi32((int)0xff00ff00); // alpha-green masks
int i;
for (i = 0; i + 4 <= num_pixels; i += 4) {
const __m128i in = _mm_loadu_si128((const __m128i*)&src[i]); // argb
@@ -532,7 +528,7 @@ static void ConvertBGRAToRGB_SSE2(const uint32_t* src, int num_pixels,
static void ConvertBGRAToRGBA_SSE2(const uint32_t* src,
int num_pixels, uint8_t* dst) {
- const __m128i red_blue_mask = _mm_set1_epi32(0x00ff00ffu);
+ const __m128i red_blue_mask = _mm_set1_epi32(0x00ff00ff);
const __m128i* in = (const __m128i*)src;
__m128i* out = (__m128i*)dst;
while (num_pixels >= 8) {
@@ -561,7 +557,7 @@ static void ConvertBGRAToRGBA_SSE2(const uint32_t* src,
static void ConvertBGRAToRGBA4444_SSE2(const uint32_t* src,
int num_pixels, uint8_t* dst) {
const __m128i mask_0x0f = _mm_set1_epi8(0x0f);
- const __m128i mask_0xf0 = _mm_set1_epi8(0xf0);
+ const __m128i mask_0xf0 = _mm_set1_epi8((char)0xf0);
const __m128i* in = (const __m128i*)src;
__m128i* out = (__m128i*)dst;
while (num_pixels >= 8) {
@@ -596,8 +592,8 @@ static void ConvertBGRAToRGBA4444_SSE2(const uint32_t* src,
static void ConvertBGRAToRGB565_SSE2(const uint32_t* src,
int num_pixels, uint8_t* dst) {
- const __m128i mask_0xe0 = _mm_set1_epi8(0xe0);
- const __m128i mask_0xf8 = _mm_set1_epi8(0xf8);
+ const __m128i mask_0xe0 = _mm_set1_epi8((char)0xe0);
+ const __m128i mask_0xf8 = _mm_set1_epi8((char)0xf8);
const __m128i mask_0x07 = _mm_set1_epi8(0x07);
const __m128i* in = (const __m128i*)src;
__m128i* out = (__m128i*)dst;
diff --git a/src/dsp/lossless_sse41.c b/src/dsp/lossless_sse41.c
index b0d6daa7..bb7ce761 100644
--- a/src/dsp/lossless_sse41.c
+++ b/src/dsp/lossless_sse41.c
@@ -25,11 +25,12 @@ static void TransformColorInverse_SSE41(const VP8LMultipliers* const m,
int num_pixels, uint32_t* dst) {
// sign-extended multiplying constants, pre-shifted by 5.
#define CST(X) (((int16_t)(m->X << 8)) >> 5) // sign-extend
- const __m128i mults_rb = _mm_set1_epi32((uint32_t)CST(green_to_red_) << 16 |
- (CST(green_to_blue_) & 0xffff));
+ const __m128i mults_rb =
+ _mm_set1_epi32((int)((uint32_t)CST(green_to_red_) << 16 |
+ (CST(green_to_blue_) & 0xffff)));
const __m128i mults_b2 = _mm_set1_epi32(CST(red_to_blue_));
#undef CST
- const __m128i mask_ag = _mm_set1_epi32(0xff00ff00);
+ const __m128i mask_ag = _mm_set1_epi32((int)0xff00ff00);
const __m128i perm1 = _mm_setr_epi8(-1, 1, -1, 1, -1, 5, -1, 5,
-1, 9, -1, 9, -1, 13, -1, 13);
const __m128i perm2 = _mm_setr_epi8(-1, 2, -1, -1, -1, 6, -1, -1,
diff --git a/src/dsp/quant.h b/src/dsp/quant.h
index 5e8dba8d..fc099bf9 100644
--- a/src/dsp/quant.h
+++ b/src/dsp/quant.h
@@ -21,10 +21,15 @@
#define IsFlat IsFlat_NEON
-static uint32x2_t horizontal_add_uint32x4(const uint32x4_t a) {
+static uint32_t horizontal_add_uint32x4(const uint32x4_t a) {
+#if defined(__aarch64__)
+ return vaddvq_u32(a);
+#else
const uint64x2_t b = vpaddlq_u32(a);
- return vadd_u32(vreinterpret_u32_u64(vget_low_u64(b)),
- vreinterpret_u32_u64(vget_high_u64(b)));
+ const uint32x2_t c = vadd_u32(vreinterpret_u32_u64(vget_low_u64(b)),
+ vreinterpret_u32_u64(vget_high_u64(b)));
+ return vget_lane_u32(c, 0);
+#endif
}
static WEBP_INLINE int IsFlat(const int16_t* levels, int num_blocks,
@@ -45,7 +50,7 @@ static WEBP_INLINE int IsFlat(const int16_t* levels, int num_blocks,
levels += 16;
}
- return thresh >= (int32_t)vget_lane_u32(horizontal_add_uint32x4(sum), 0);
+ return thresh >= (int)horizontal_add_uint32x4(sum);
}
#else
diff --git a/src/dsp/rescaler_sse2.c b/src/dsp/rescaler_sse2.c
index d7effea1..3f18e94e 100644
--- a/src/dsp/rescaler_sse2.c
+++ b/src/dsp/rescaler_sse2.c
@@ -85,7 +85,7 @@ static void RescalerImportRowExpand_SSE2(WebPRescaler* const wrk,
const __m128i mult = _mm_cvtsi32_si128(((x_add - accum) << 16) | accum);
const __m128i out = _mm_madd_epi16(cur_pixels, mult);
assert(sizeof(*frow) == sizeof(uint32_t));
- WebPUint32ToMem((uint8_t*)frow, _mm_cvtsi128_si32(out));
+ WebPInt32ToMem((uint8_t*)frow, _mm_cvtsi128_si32(out));
frow += 1;
if (frow >= frow_end) break;
accum -= wrk->x_sub;
@@ -132,7 +132,7 @@ static void RescalerImportRowShrink_SSE2(WebPRescaler* const wrk,
__m128i base = zero;
accum += wrk->x_add;
while (accum > 0) {
- const __m128i A = _mm_cvtsi32_si128(WebPMemToUint32(src));
+ const __m128i A = _mm_cvtsi32_si128(WebPMemToInt32(src));
src += 4;
base = _mm_unpacklo_epi8(A, zero);
// To avoid overflow, we need: base * x_add / x_sub < 32768
@@ -198,7 +198,7 @@ static WEBP_INLINE void ProcessRow_SSE2(const __m128i* const A0,
const __m128i* const mult,
uint8_t* const dst) {
const __m128i rounder = _mm_set_epi32(0, ROUNDER, 0, ROUNDER);
- const __m128i mask = _mm_set_epi32(0xffffffffu, 0, 0xffffffffu, 0);
+ const __m128i mask = _mm_set_epi32(~0, 0, ~0, 0);
const __m128i B0 = _mm_mul_epu32(*A0, *mult);
const __m128i B1 = _mm_mul_epu32(*A1, *mult);
const __m128i B2 = _mm_mul_epu32(*A2, *mult);
diff --git a/src/dsp/upsampling_sse2.c b/src/dsp/upsampling_sse2.c
index 340f1e2a..08b6d0b1 100644
--- a/src/dsp/upsampling_sse2.c
+++ b/src/dsp/upsampling_sse2.c
@@ -121,7 +121,7 @@ static void FUNC_NAME(const uint8_t* top_y, const uint8_t* bottom_y, \
int uv_pos, pos; \
/* 16byte-aligned array to cache reconstructed u and v */ \
uint8_t uv_buf[14 * 32 + 15] = { 0 }; \
- uint8_t* const r_u = (uint8_t*)((uintptr_t)(uv_buf + 15) & ~15); \
+ uint8_t* const r_u = (uint8_t*)((uintptr_t)(uv_buf + 15) & ~(uintptr_t)15); \
uint8_t* const r_v = r_u + 32; \
\
assert(top_y != NULL); \
diff --git a/src/dsp/yuv_sse2.c b/src/dsp/yuv_sse2.c
index 970bbb78..01a48f9a 100644
--- a/src/dsp/yuv_sse2.c
+++ b/src/dsp/yuv_sse2.c
@@ -15,10 +15,12 @@
#if defined(WEBP_USE_SSE2)
-#include "src/dsp/common_sse2.h"
#include <stdlib.h>
#include <emmintrin.h>
+#include "src/dsp/common_sse2.h"
+#include "src/utils/utils.h"
+
//-----------------------------------------------------------------------------
// Convert spans of 32 pixels to various RGB formats for the fancy upsampler.
@@ -74,7 +76,7 @@ static WEBP_INLINE __m128i Load_HI_16_SSE2(const uint8_t* src) {
// Load and replicate the U/V samples
static WEBP_INLINE __m128i Load_UV_HI_8_SSE2(const uint8_t* src) {
const __m128i zero = _mm_setzero_si128();
- const __m128i tmp0 = _mm_cvtsi32_si128(*(const uint32_t*)src);
+ const __m128i tmp0 = _mm_cvtsi32_si128(WebPMemToInt32(src));
const __m128i tmp1 = _mm_unpacklo_epi8(zero, tmp0);
return _mm_unpacklo_epi16(tmp1, tmp1); // replicate samples
}
@@ -130,7 +132,7 @@ static WEBP_INLINE void PackAndStore4444_SSE2(const __m128i* const R,
const __m128i rg0 = _mm_packus_epi16(*B, *A);
const __m128i ba0 = _mm_packus_epi16(*R, *G);
#endif
- const __m128i mask_0xf0 = _mm_set1_epi8(0xf0);
+ const __m128i mask_0xf0 = _mm_set1_epi8((char)0xf0);
const __m128i rb1 = _mm_unpacklo_epi8(rg0, ba0); // rbrbrbrbrb...
const __m128i ga1 = _mm_unpackhi_epi8(rg0, ba0); // gagagagaga...
const __m128i rb2 = _mm_and_si128(rb1, mask_0xf0);
@@ -147,9 +149,10 @@ static WEBP_INLINE void PackAndStore565_SSE2(const __m128i* const R,
const __m128i r0 = _mm_packus_epi16(*R, *R);
const __m128i g0 = _mm_packus_epi16(*G, *G);
const __m128i b0 = _mm_packus_epi16(*B, *B);
- const __m128i r1 = _mm_and_si128(r0, _mm_set1_epi8(0xf8));
+ const __m128i r1 = _mm_and_si128(r0, _mm_set1_epi8((char)0xf8));
const __m128i b1 = _mm_and_si128(_mm_srli_epi16(b0, 3), _mm_set1_epi8(0x1f));
- const __m128i g1 = _mm_srli_epi16(_mm_and_si128(g0, _mm_set1_epi8(0xe0)), 5);
+ const __m128i g1 =
+ _mm_srli_epi16(_mm_and_si128(g0, _mm_set1_epi8((char)0xe0)), 5);
const __m128i g2 = _mm_slli_epi16(_mm_and_si128(g0, _mm_set1_epi8(0x1c)), 3);
const __m128i rg = _mm_or_si128(r1, g1);
const __m128i gb = _mm_or_si128(g2, b1);
diff --git a/src/dsp/yuv_sse41.c b/src/dsp/yuv_sse41.c
index 579d1f74..f79b802e 100644
--- a/src/dsp/yuv_sse41.c
+++ b/src/dsp/yuv_sse41.c
@@ -15,10 +15,12 @@
#if defined(WEBP_USE_SSE41)
-#include "src/dsp/common_sse41.h"
#include <stdlib.h>
#include <smmintrin.h>
+#include "src/dsp/common_sse41.h"
+#include "src/utils/utils.h"
+
//-----------------------------------------------------------------------------
// Convert spans of 32 pixels to various RGB formats for the fancy upsampler.
@@ -74,7 +76,7 @@ static WEBP_INLINE __m128i Load_HI_16_SSE41(const uint8_t* src) {
// Load and replicate the U/V samples
static WEBP_INLINE __m128i Load_UV_HI_8_SSE41(const uint8_t* src) {
const __m128i zero = _mm_setzero_si128();
- const __m128i tmp0 = _mm_cvtsi32_si128(*(const uint32_t*)src);
+ const __m128i tmp0 = _mm_cvtsi32_si128(WebPMemToInt32(src));
const __m128i tmp1 = _mm_unpacklo_epi8(zero, tmp0);
return _mm_unpacklo_epi16(tmp1, tmp1); // replicate samples
}
diff --git a/src/enc/analysis_enc.c b/src/enc/analysis_enc.c
index ebb78426..a0001ac0 100644
--- a/src/enc/analysis_enc.c
+++ b/src/enc/analysis_enc.c
@@ -391,12 +391,14 @@ static int DoSegmentsJob(void* arg1, void* arg2) {
return ok;
}
+#ifdef WEBP_USE_THREAD
static void MergeJobs(const SegmentJob* const src, SegmentJob* const dst) {
int i;
for (i = 0; i <= MAX_ALPHA; ++i) dst->alphas[i] += src->alphas[i];
dst->alpha += src->alpha;
dst->uv_alpha += src->uv_alpha;
}
+#endif
// initialize the job struct with some tasks to perform
static void InitSegmentJob(VP8Encoder* const enc, SegmentJob* const job,
@@ -425,10 +427,10 @@ int VP8EncAnalyze(VP8Encoder* const enc) {
(enc->method_ <= 1); // for method 0 - 1, we need preds_[] to be filled.
if (do_segments) {
const int last_row = enc->mb_h_;
- // We give a little more than a half work to the main thread.
- const int split_row = (9 * last_row + 15) >> 4;
const int total_mb = last_row * enc->mb_w_;
#ifdef WEBP_USE_THREAD
+ // We give a little more than a half work to the main thread.
+ const int split_row = (9 * last_row + 15) >> 4;
const int kMinSplitRow = 2; // minimal rows needed for mt to be worth it
const int do_mt = (enc->thread_level_ > 0) && (split_row >= kMinSplitRow);
#else
@@ -438,6 +440,7 @@ int VP8EncAnalyze(VP8Encoder* const enc) {
WebPGetWorkerInterface();
SegmentJob main_job;
if (do_mt) {
+#ifdef WEBP_USE_THREAD
SegmentJob side_job;
// Note the use of '&' instead of '&&' because we must call the functions
// no matter what.
@@ -455,6 +458,7 @@ int VP8EncAnalyze(VP8Encoder* const enc) {
}
worker_interface->End(&side_job.worker);
if (ok) MergeJobs(&side_job, &main_job); // merge results together
+#endif // WEBP_USE_THREAD
} else {
// Even for single-thread case, we use the generic Worker tools.
InitSegmentJob(enc, &main_job, 0, last_row);
diff --git a/src/enc/picture_csp_enc.c b/src/enc/picture_csp_enc.c
index fabebcf2..78c8ca47 100644
--- a/src/enc/picture_csp_enc.c
+++ b/src/enc/picture_csp_enc.c
@@ -69,10 +69,12 @@ static int CheckNonOpaque(const uint8_t* alpha, int width, int height,
int WebPPictureHasTransparency(const WebPPicture* picture) {
if (picture == NULL) return 0;
if (picture->use_argb) {
- const int alpha_offset = ALPHA_OFFSET;
- return CheckNonOpaque((const uint8_t*)picture->argb + alpha_offset,
- picture->width, picture->height,
- 4, picture->argb_stride * sizeof(*picture->argb));
+ if (picture->argb != NULL) {
+ return CheckNonOpaque((const uint8_t*)picture->argb + ALPHA_OFFSET,
+ picture->width, picture->height,
+ 4, picture->argb_stride * sizeof(*picture->argb));
+ }
+ return 0;
}
return CheckNonOpaque(picture->a, picture->width, picture->height,
1, picture->a_stride);
@@ -170,21 +172,6 @@ static const int kMinDimensionIterativeConversion = 4;
//------------------------------------------------------------------------------
// Main function
-extern void SharpYuvInit(VP8CPUInfo cpu_info_func);
-
-static void SafeInitSharpYuv(void) {
-#if defined(WEBP_USE_THREAD) && !defined(_WIN32)
- static pthread_mutex_t initsharpyuv_lock = PTHREAD_MUTEX_INITIALIZER;
- if (pthread_mutex_lock(&initsharpyuv_lock)) return;
-#endif
-
- SharpYuvInit(VP8GetCPUInfo);
-
-#if defined(WEBP_USE_THREAD) && !defined(_WIN32)
- (void)pthread_mutex_unlock(&initsharpyuv_lock);
-#endif
-}
-
static int PreprocessARGB(const uint8_t* r_ptr,
const uint8_t* g_ptr,
const uint8_t* b_ptr,
@@ -481,6 +468,8 @@ static WEBP_INLINE void ConvertRowsToUV(const uint16_t* rgb,
}
}
+extern void SharpYuvInit(VP8CPUInfo cpu_info_func);
+
static int ImportYUVAFromRGBA(const uint8_t* r_ptr,
const uint8_t* g_ptr,
const uint8_t* b_ptr,
@@ -516,7 +505,7 @@ static int ImportYUVAFromRGBA(const uint8_t* r_ptr,
}
if (use_iterative_conversion) {
- SafeInitSharpYuv();
+ SharpYuvInit(VP8GetCPUInfo);
if (!PreprocessARGB(r_ptr, g_ptr, b_ptr, step, rgb_stride, picture)) {
return 0;
}
diff --git a/src/enc/picture_rescale_enc.c b/src/enc/picture_rescale_enc.c
index 21634f3d..839f91ca 100644
--- a/src/enc/picture_rescale_enc.c
+++ b/src/enc/picture_rescale_enc.c
@@ -13,14 +13,15 @@
#include "src/webp/encode.h"
-#if !defined(WEBP_REDUCE_SIZE)
-
#include <assert.h>
#include <stdlib.h>
#include "src/enc/vp8i_enc.h"
+
+#if !defined(WEBP_REDUCE_SIZE)
#include "src/utils/rescaler_utils.h"
#include "src/utils/utils.h"
+#endif // !defined(WEBP_REDUCE_SIZE)
#define HALVE(x) (((x) + 1) >> 1)
@@ -56,6 +57,7 @@ static int AdjustAndCheckRectangle(const WebPPicture* const pic,
return 1;
}
+#if !defined(WEBP_REDUCE_SIZE)
int WebPPictureCopy(const WebPPicture* src, WebPPicture* dst) {
if (src == NULL || dst == NULL) return 0;
if (src == dst) return 1;
@@ -81,6 +83,7 @@ int WebPPictureCopy(const WebPPicture* src, WebPPicture* dst) {
}
return 1;
}
+#endif // !defined(WEBP_REDUCE_SIZE)
int WebPPictureIsView(const WebPPicture* picture) {
if (picture == NULL) return 0;
@@ -120,6 +123,7 @@ int WebPPictureView(const WebPPicture* src,
return 1;
}
+#if !defined(WEBP_REDUCE_SIZE)
//------------------------------------------------------------------------------
// Picture cropping
@@ -277,23 +281,6 @@ int WebPPictureCopy(const WebPPicture* src, WebPPicture* dst) {
return 0;
}
-int WebPPictureIsView(const WebPPicture* picture) {
- (void)picture;
- return 0;
-}
-
-int WebPPictureView(const WebPPicture* src,
- int left, int top, int width, int height,
- WebPPicture* dst) {
- (void)src;
- (void)left;
- (void)top;
- (void)width;
- (void)height;
- (void)dst;
- return 0;
-}
-
int WebPPictureCrop(WebPPicture* pic,
int left, int top, int width, int height) {
(void)pic;
diff --git a/src/enc/vp8i_enc.h b/src/enc/vp8i_enc.h
index 76428ecd..c9927c47 100644
--- a/src/enc/vp8i_enc.h
+++ b/src/enc/vp8i_enc.h
@@ -31,8 +31,8 @@ extern "C" {
// version numbers
#define ENC_MAJ_VERSION 1
-#define ENC_MIN_VERSION 2
-#define ENC_REV_VERSION 3
+#define ENC_MIN_VERSION 3
+#define ENC_REV_VERSION 0
enum { MAX_LF_LEVELS = 64, // Maximum loop filter level
MAX_VARIABLE_LEVEL = 67, // last (inclusive) level with variable cost
diff --git a/src/enc/vp8l_enc.c b/src/enc/vp8l_enc.c
index 2b345df6..0b07e529 100644
--- a/src/enc/vp8l_enc.c
+++ b/src/enc/vp8l_enc.c
@@ -361,10 +361,11 @@ typedef enum {
kHistoTotal // Must be last.
} HistoIx;
-static void AddSingleSubGreen(int p, uint32_t* const r, uint32_t* const b) {
- const int green = p >> 8; // The upper bits are masked away later.
- ++r[((p >> 16) - green) & 0xff];
- ++b[((p >> 0) - green) & 0xff];
+static void AddSingleSubGreen(uint32_t p,
+ uint32_t* const r, uint32_t* const b) {
+ const int green = (int)p >> 8; // The upper bits are masked away later.
+ ++r[(((int)p >> 16) - green) & 0xff];
+ ++b[(((int)p >> 0) - green) & 0xff];
}
static void AddSingle(uint32_t p,
@@ -1354,7 +1355,7 @@ static int EncodeImageInternal(
static void ApplySubtractGreen(VP8LEncoder* const enc, int width, int height,
VP8LBitWriter* const bw) {
VP8LPutBits(bw, TRANSFORM_PRESENT, 1);
- VP8LPutBits(bw, SUBTRACT_GREEN, 2);
+ VP8LPutBits(bw, SUBTRACT_GREEN_TRANSFORM, 2);
VP8LSubtractGreenFromBlueAndRed(enc->argb_, width * height);
}
diff --git a/src/libwebp.pc.in b/src/libwebp.pc.in
index 733bb6db..a755b54e 100644
--- a/src/libwebp.pc.in
+++ b/src/libwebp.pc.in
@@ -6,6 +6,7 @@ includedir=@includedir@
Name: libwebp
Description: Library for the WebP graphics format
Version: @PACKAGE_VERSION@
+Requires: libsharpyuv
Cflags: -I${includedir}
-Libs: -L${libdir} -lwebp
+Libs: -L${libdir} -l@webp_libname_prefix@webp
Libs.private: -lm @PTHREAD_CFLAGS@ @PTHREAD_LIBS@
diff --git a/src/libwebp.rc b/src/libwebp.rc
index 7fdbddd2..6b11dc83 100644
--- a/src/libwebp.rc
+++ b/src/libwebp.rc
@@ -6,8 +6,8 @@
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
VS_VERSION_INFO VERSIONINFO
- FILEVERSION 1,0,2,3
- PRODUCTVERSION 1,0,2,3
+ FILEVERSION 1,0,3,0
+ PRODUCTVERSION 1,0,3,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@@ -24,12 +24,12 @@ BEGIN
BEGIN
VALUE "CompanyName", "Google, Inc."
VALUE "FileDescription", "libwebp DLL"
- VALUE "FileVersion", "1.2.3"
+ VALUE "FileVersion", "1.3.0"
VALUE "InternalName", "libwebp.dll"
VALUE "LegalCopyright", "Copyright (C) 2022"
VALUE "OriginalFilename", "libwebp.dll"
VALUE "ProductName", "WebP Image Codec"
- VALUE "ProductVersion", "1.2.3"
+ VALUE "ProductVersion", "1.3.0"
END
END
BLOCK "VarFileInfo"
diff --git a/src/libwebpdecoder.pc.in b/src/libwebpdecoder.pc.in
index 3ef647a9..134de0e7 100644
--- a/src/libwebpdecoder.pc.in
+++ b/src/libwebpdecoder.pc.in
@@ -7,5 +7,5 @@ Name: libwebpdecoder
Description: Library for the WebP graphics format (decode only)
Version: @PACKAGE_VERSION@
Cflags: -I${includedir}
-Libs: -L${libdir} -lwebpdecoder
+Libs: -L${libdir} -l@webp_libname_prefix@webpdecoder
Libs.private: -lm @PTHREAD_CFLAGS@ @PTHREAD_LIBS@
diff --git a/src/libwebpdecoder.rc b/src/libwebpdecoder.rc
index 2058ab05..44e4f26e 100644
--- a/src/libwebpdecoder.rc
+++ b/src/libwebpdecoder.rc
@@ -6,8 +6,8 @@
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
VS_VERSION_INFO VERSIONINFO
- FILEVERSION 1,0,2,3
- PRODUCTVERSION 1,0,2,3
+ FILEVERSION 1,0,3,0
+ PRODUCTVERSION 1,0,3,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@@ -24,12 +24,12 @@ BEGIN
BEGIN
VALUE "CompanyName", "Google, Inc."
VALUE "FileDescription", "libwebpdecoder DLL"
- VALUE "FileVersion", "1.2.3"
+ VALUE "FileVersion", "1.3.0"
VALUE "InternalName", "libwebpdecoder.dll"
VALUE "LegalCopyright", "Copyright (C) 2022"
VALUE "OriginalFilename", "libwebpdecoder.dll"
VALUE "ProductName", "WebP Image Decoder"
- VALUE "ProductVersion", "1.2.3"
+ VALUE "ProductVersion", "1.3.0"
END
END
BLOCK "VarFileInfo"
diff --git a/src/mux/Makefile.am b/src/mux/Makefile.am
index 63ac6436..8f7f7395 100644
--- a/src/mux/Makefile.am
+++ b/src/mux/Makefile.am
@@ -17,6 +17,6 @@ noinst_HEADERS =
noinst_HEADERS += ../webp/format_constants.h
libwebpmux_la_LIBADD = ../libwebp.la
-libwebpmux_la_LDFLAGS = -no-undefined -version-info 3:9:0 -lm
+libwebpmux_la_LDFLAGS = -no-undefined -version-info 3:11:0 -lm
libwebpmuxincludedir = $(includedir)/webp
pkgconfig_DATA = libwebpmux.pc
diff --git a/src/mux/libwebpmux.pc.in b/src/mux/libwebpmux.pc.in
index a96fac78..9d4d6e1e 100644
--- a/src/mux/libwebpmux.pc.in
+++ b/src/mux/libwebpmux.pc.in
@@ -8,5 +8,5 @@ Description: Library for manipulating the WebP graphics format container
Version: @PACKAGE_VERSION@
Requires: libwebp >= 0.2.0
Cflags: -I${includedir}
-Libs: -L${libdir} -lwebpmux
+Libs: -L${libdir} -l@webp_libname_prefix@webpmux
Libs.private: -lm
diff --git a/src/mux/libwebpmux.rc b/src/mux/libwebpmux.rc
index 140c7f60..a61f5371 100644
--- a/src/mux/libwebpmux.rc
+++ b/src/mux/libwebpmux.rc
@@ -6,8 +6,8 @@
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
VS_VERSION_INFO VERSIONINFO
- FILEVERSION 1,0,2,3
- PRODUCTVERSION 1,0,2,3
+ FILEVERSION 1,0,3,0
+ PRODUCTVERSION 1,0,3,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@@ -24,12 +24,12 @@ BEGIN
BEGIN
VALUE "CompanyName", "Google, Inc."
VALUE "FileDescription", "libwebpmux DLL"
- VALUE "FileVersion", "1.2.3"
+ VALUE "FileVersion", "1.3.0"
VALUE "InternalName", "libwebpmux.dll"
VALUE "LegalCopyright", "Copyright (C) 2022"
VALUE "OriginalFilename", "libwebpmux.dll"
VALUE "ProductName", "WebP Image Muxer"
- VALUE "ProductVersion", "1.2.3"
+ VALUE "ProductVersion", "1.3.0"
END
END
BLOCK "VarFileInfo"
diff --git a/src/mux/muxi.h b/src/mux/muxi.h
index cb6a5c77..7929138c 100644
--- a/src/mux/muxi.h
+++ b/src/mux/muxi.h
@@ -28,8 +28,8 @@ extern "C" {
// Defines and constants.
#define MUX_MAJ_VERSION 1
-#define MUX_MIN_VERSION 2
-#define MUX_REV_VERSION 3
+#define MUX_MIN_VERSION 3
+#define MUX_REV_VERSION 0
// Chunk object.
typedef struct WebPChunk WebPChunk;
diff --git a/src/utils/bit_reader_inl_utils.h b/src/utils/bit_reader_inl_utils.h
index 404b9a6d..24f3af7b 100644
--- a/src/utils/bit_reader_inl_utils.h
+++ b/src/utils/bit_reader_inl_utils.h
@@ -148,9 +148,9 @@ int VP8GetSigned(VP8BitReader* WEBP_RESTRICT const br, int v,
const range_t value = (range_t)(br->value_ >> pos);
const int32_t mask = (int32_t)(split - value) >> 31; // -1 or 0
br->bits_ -= 1;
- br->range_ += mask;
+ br->range_ += (range_t)mask;
br->range_ |= 1;
- br->value_ -= (bit_t)((split + 1) & mask) << pos;
+ br->value_ -= (bit_t)((split + 1) & (uint32_t)mask) << pos;
BT_TRACK(br);
return (v ^ mask) - mask;
}
diff --git a/src/utils/huffman_utils.c b/src/utils/huffman_utils.c
index 0cba0fbb..90c2fbf7 100644
--- a/src/utils/huffman_utils.c
+++ b/src/utils/huffman_utils.c
@@ -142,7 +142,7 @@ static int BuildHuffmanTable(HuffmanCode* const root_table, int root_bits,
{
int step; // step size to replicate values in current table
- uint32_t low = -1; // low bits for current root entry
+ uint32_t low = 0xffffffffu; // low bits for current root entry
uint32_t mask = total_size - 1; // mask for low bits
uint32_t key = 0; // reversed prefix code
int num_nodes = 1; // number of Huffman tree nodes
diff --git a/src/utils/utils.h b/src/utils/utils.h
index ef04f108..c5ee8733 100644
--- a/src/utils/utils.h
+++ b/src/utils/utils.h
@@ -64,7 +64,8 @@ WEBP_EXTERN void WebPSafeFree(void* const ptr);
// Alignment
#define WEBP_ALIGN_CST 31
-#define WEBP_ALIGN(PTR) (((uintptr_t)(PTR) + WEBP_ALIGN_CST) & ~WEBP_ALIGN_CST)
+#define WEBP_ALIGN(PTR) (((uintptr_t)(PTR) + WEBP_ALIGN_CST) & \
+ ~(uintptr_t)WEBP_ALIGN_CST)
#include <string.h>
// memcpy() is the safe way of moving potentially unaligned 32b memory.
@@ -73,10 +74,19 @@ static WEBP_INLINE uint32_t WebPMemToUint32(const uint8_t* const ptr) {
memcpy(&A, ptr, sizeof(A));
return A;
}
+
+static WEBP_INLINE int32_t WebPMemToInt32(const uint8_t* const ptr) {
+ return (int32_t)WebPMemToUint32(ptr);
+}
+
static WEBP_INLINE void WebPUint32ToMem(uint8_t* const ptr, uint32_t val) {
memcpy(ptr, &val, sizeof(val));
}
+static WEBP_INLINE void WebPInt32ToMem(uint8_t* const ptr, int val) {
+ WebPUint32ToMem(ptr, (uint32_t)val);
+}
+
//------------------------------------------------------------------------------
// Reading/writing data.
diff --git a/src/webp/format_constants.h b/src/webp/format_constants.h
index eca6981a..999035c5 100644
--- a/src/webp/format_constants.h
+++ b/src/webp/format_constants.h
@@ -55,7 +55,7 @@
typedef enum {
PREDICTOR_TRANSFORM = 0,
CROSS_COLOR_TRANSFORM = 1,
- SUBTRACT_GREEN = 2,
+ SUBTRACT_GREEN_TRANSFORM = 2,
COLOR_INDEXING_TRANSFORM = 3
} VP8LImageTransformType;
diff --git a/src/webp/types.h b/src/webp/types.h
index 47f7f2b0..f255432e 100644
--- a/src/webp/types.h
+++ b/src/webp/types.h
@@ -42,7 +42,11 @@ typedef long long int int64_t;
# if defined(__GNUC__) && __GNUC__ >= 4
# define WEBP_EXTERN extern __attribute__ ((visibility ("default")))
# else
-# define WEBP_EXTERN extern
+# if defined(_MSC_VER) && defined(WEBP_DLL)
+# define WEBP_EXTERN __declspec(dllexport)
+# else
+# define WEBP_EXTERN extern
+# endif
# endif /* __GNUC__ >= 4 */
#endif /* WEBP_EXTERN */
diff --git a/tests/fuzzer/makefile.unix b/tests/fuzzer/makefile.unix
index e2425639..4a9bff35 100644
--- a/tests/fuzzer/makefile.unix
+++ b/tests/fuzzer/makefile.unix
@@ -9,6 +9,7 @@ CXXFLAGS = $(CFLAGS)
LDFLAGS = -fsanitize=fuzzer
LDLIBS = ../../src/mux/libwebpmux.a ../../src/demux/libwebpdemux.a
LDLIBS += ../../src/libwebp.a ../../imageio/libimageio_util.a
+LDLIBS += ../../sharpyuv/libsharpyuv.a
FUZZERS = advanced_api_fuzzer animation_api_fuzzer animencoder_fuzzer
FUZZERS += animdecoder_fuzzer mux_demux_api_fuzzer enc_dec_fuzzer
diff --git a/webp_js/README.md b/webp_js/README.md
index 174ca9fe..824afa0b 100644
--- a/webp_js/README.md
+++ b/webp_js/README.md
@@ -1,4 +1,4 @@
-# Webp JavaScript decoder
+# WebP JavaScript decoder
```
__ __ ____ ____ ____ __ ____
@@ -26,8 +26,8 @@ Emscripten and CMake.
- compile webp.js using 'emmake make'.
-- that's it! Upon completion, you should have the webp.js and webp.wasm files
- generated.
+- that's it! Upon completion, you should have the 'webp.js', 'webp.js.mem',
+ 'webp_wasm.js' and 'webp_wasm.wasm' 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
@@ -35,11 +35,12 @@ 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.
+The HTML page webp_js/index.html requires the built files 'webp.js' and
+'webp.js.mem' to be copied to webp_js/. An HTTP server to serve the WebP image
+example is also needed. With Python, just run:
```shell
-cd webp_js && python -m SimpleHTTPServer 8080
+cd webp_js && python3 -m http.server 8080
```
and then navigate to http://localhost:8080 in your favorite browser.
@@ -48,8 +49,10 @@ and then navigate to http://localhost:8080 in your favorite browser.
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
+'webp_wasm.js' and 'webp_wasm.wasm' that you then need to copy to 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 2.0.18,
diff --git a/webp_js/index.html b/webp_js/index.html
index 10873a98..33cacb4c 100644
--- a/webp_js/index.html
+++ b/webp_js/index.html
@@ -18,7 +18,7 @@
var WebpToCanvas;
function init() {
- WebpToCanvas = Module.cwrap('WebpToSDL', 'number', ['array', 'number']);
+ WebpToCanvas = Module.cwrap('WebPToSDL', 'number', ['array', 'number']);
}
window.onload = init;
diff --git a/webp_js/index_wasm.html b/webp_js/index_wasm.html
index b77c22c4..5d7c17e8 100644
--- a/webp_js/index_wasm.html
+++ b/webp_js/index_wasm.html
@@ -34,7 +34,7 @@ function decode(webp_data, canvas_id) {
var result;
if (Module["asm"] != undefined) {
// wrapper for the function decoding a WebP into a canvas object
- WebpToCanvas = Module.cwrap('WebpToSDL', 'number', ['array', 'number']);
+ WebpToCanvas = Module.cwrap('WebPToSDL', 'number', ['array', 'number']);
// get the canvas to decode into
var canvas = document.getElementById(canvas_id);
if (canvas == null) return;
diff --git a/xcframeworkbuild.sh b/xcframeworkbuild.sh
index 5310df27..8d484c2a 100755
--- a/xcframeworkbuild.sh
+++ b/xcframeworkbuild.sh
@@ -15,7 +15,7 @@ set -e
# Set these variables based on the desired minimum deployment target.
readonly IOS_MIN_VERSION=6.0
readonly MACOSX_MIN_VERSION=10.15
-readonly MACOSX_CATALYST_MIN_VERSION=13.0
+readonly MACOSX_CATALYST_MIN_VERSION=14.0
# Extract Xcode version.
readonly XCODE=$(xcodebuild -version | grep Xcode | cut -d " " -f2)