mirror of
https://github.com/webmproject/libwebp.git
synced 2025-07-15 05:19:48 +02:00
Compare commits
1 Commits
v1.2.0-rc3
...
sandbox/jz
Author | SHA1 | Date | |
---|---|---|---|
86c756929c |
1
.gitattributes
vendored
1
.gitattributes
vendored
@ -1,6 +1,5 @@
|
||||
.gitattributes export-ignore
|
||||
.gitignore export-ignore
|
||||
.mailmap export-ignore
|
||||
*.bat text eol=crlf
|
||||
*.pdf -text -diff
|
||||
*.ppm -text -diff
|
||||
|
15
.gitignore
vendored
15
.gitignore
vendored
@ -1,7 +1,6 @@
|
||||
*.l[ao]
|
||||
*.[ao]
|
||||
*.pc
|
||||
.DS_Store
|
||||
.deps
|
||||
.libs
|
||||
/aclocal.m4
|
||||
@ -21,11 +20,9 @@
|
||||
Makefile
|
||||
Makefile.in
|
||||
examples/anim_diff
|
||||
examples/anim_dump
|
||||
examples/[cdv]webp
|
||||
examples/gif2webp
|
||||
examples/img2webp
|
||||
examples/webpinfo
|
||||
examples/webpmux
|
||||
src/webp/config.h*
|
||||
src/webp/stamp-h1
|
||||
@ -34,21 +31,11 @@ src/webp/stamp-h1
|
||||
*.idb
|
||||
*.pdb
|
||||
/iosbuild
|
||||
/xcframeworkbuild
|
||||
/WebP*.*framework
|
||||
/WebP.framework
|
||||
CMakeCache.txt
|
||||
CMakeFiles/
|
||||
cmake_install.cmake
|
||||
.gradle
|
||||
/build
|
||||
extras/get_disto
|
||||
extras/vwebp_sdl
|
||||
extras/webp_quality
|
||||
tests/fuzzer/advanced_api_fuzzer
|
||||
tests/fuzzer/animation_api_fuzzer
|
||||
tests/fuzzer/animdecoder_fuzzer
|
||||
tests/fuzzer/animencoder_fuzzer
|
||||
tests/fuzzer/demux_api_fuzzer
|
||||
tests/fuzzer/enc_dec_fuzzer
|
||||
tests/fuzzer/mux_demux_api_fuzzer
|
||||
tests/fuzzer/simple_api_fuzzer
|
||||
|
5
.mailmap
5
.mailmap
@ -1,8 +1,7 @@
|
||||
Johann Koenig <johann.koenig@duck.com>
|
||||
Johann Koenig <johann.koenig@duck.com> <johannkoenig@google.com>
|
||||
<johann.koenig@duck.com> <johannkoenig@google.com>
|
||||
Mikołaj Zalewski <mikolajz@google.com>
|
||||
Pascal Massimino <pascal.massimino@gmail.com>
|
||||
Pascal Massimino <pascal.massimino@gmail.com> <skal@google.com>
|
||||
<pascal.massimino@gmail.com> <skal@google.com>
|
||||
Vikas Arora <vikasa@google.com>
|
||||
<vikasa@google.com> <vikasa@gmail.com>
|
||||
<vikasa@google.com> <vikaas.arora@gmail.com>
|
||||
|
11
AUTHORS
11
AUTHORS
@ -1,19 +1,14 @@
|
||||
Contributors:
|
||||
- Aidan O'Loan (aidanol at gmail dot com)
|
||||
- Alan Browning (browning at google dot com)
|
||||
- Charles Munger (clm at google dot com)
|
||||
- Cheng Yi (cyi at google dot com)
|
||||
- Christian Duvivier (cduvivier at google dot com)
|
||||
- Djordje Pesut (djordje dot pesut at imgtec dot com)
|
||||
- Hui Su (huisu at google 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)
|
||||
- Johann Koenig (johann dot koenig at duck dot com)
|
||||
- Johann (johann dot koenig at duck dot com)
|
||||
- Jovan Zelincevic (jovan dot zelincevic at imgtec dot com)
|
||||
- Jyrki Alakuijala (jyrki at google dot com)
|
||||
- Konstantin Ivlev (tomskside at gmail dot com)
|
||||
- Lode Vandevenne (lode at google dot com)
|
||||
- Lou Quillio (louquillio at google dot com)
|
||||
- Mans Rullgard (mans at mansr dot com)
|
||||
@ -23,7 +18,6 @@ Contributors:
|
||||
- Mislav Bradac (mislavm at google dot com)
|
||||
- Nico Weber (thakis at chromium dot org)
|
||||
- Noel Chromium (noel at chromium dot org)
|
||||
- Oliver Wolff (oliver dot wolff at qt dot io)
|
||||
- Owen Rodley (orodley at google dot com)
|
||||
- Parag Salasakar (img dot mips1 at gmail dot com)
|
||||
- Pascal Massimino (pascal dot massimino at gmail dot com)
|
||||
@ -41,7 +35,4 @@ Contributors:
|
||||
- Urvang Joshi (urvang at google dot com)
|
||||
- Vikas Arora (vikasa at google dot com)
|
||||
- Vincent Rabaud (vrabaud at google dot com)
|
||||
- Vlad Tsyrklevich (vtsyrklevich at chromium dot org)
|
||||
- Wan-Teh Chang (wtc at google dot com)
|
||||
- Yang Zhang (yang dot zhang at arm dot com)
|
||||
- Yannis Guyon (yguyon at google dot com)
|
||||
|
32
Android.mk
32
Android.mk
@ -11,24 +11,12 @@ ifeq ($(APP_OPTIM),release)
|
||||
endif
|
||||
endif
|
||||
|
||||
# mips32 fails to build with clang from r14b
|
||||
# https://bugs.chromium.org/p/webp/issues/detail?id=343
|
||||
ifeq ($(findstring clang,$(NDK_TOOLCHAIN_VERSION)),clang)
|
||||
ifeq ($(TARGET_ARCH),mips)
|
||||
clang_version := $(shell $(TARGET_CC) --version)
|
||||
ifneq ($(findstring clang version 3,$(clang_version)),)
|
||||
WEBP_CFLAGS += -no-integrated-as
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
ifneq ($(findstring armeabi-v7a, $(TARGET_ARCH_ABI)),)
|
||||
# Setting LOCAL_ARM_NEON will enable -mfpu=neon which may cause illegal
|
||||
# instructions to be generated for armv7a code. Instead target the neon code
|
||||
# specifically.
|
||||
NEON := c.neon
|
||||
USE_CPUFEATURES := yes
|
||||
WEBP_CFLAGS += -DHAVE_CPU_FEATURES_H
|
||||
else
|
||||
NEON := c
|
||||
endif
|
||||
@ -55,6 +43,9 @@ dsp_dec_srcs := \
|
||||
src/dsp/alpha_processing_neon.$(NEON) \
|
||||
src/dsp/alpha_processing_sse2.c \
|
||||
src/dsp/alpha_processing_sse41.c \
|
||||
src/dsp/argb.c \
|
||||
src/dsp/argb_mips_dsp_r2.c \
|
||||
src/dsp/argb_sse2.c \
|
||||
src/dsp/cpu.c \
|
||||
src/dsp/dec.c \
|
||||
src/dsp/dec_clip_tables.c \
|
||||
@ -85,21 +76,18 @@ dsp_dec_srcs := \
|
||||
src/dsp/upsampling_msa.c \
|
||||
src/dsp/upsampling_neon.$(NEON) \
|
||||
src/dsp/upsampling_sse2.c \
|
||||
src/dsp/upsampling_sse41.c \
|
||||
src/dsp/yuv.c \
|
||||
src/dsp/yuv_mips32.c \
|
||||
src/dsp/yuv_mips_dsp_r2.c \
|
||||
src/dsp/yuv_neon.$(NEON) \
|
||||
src/dsp/yuv_sse2.c \
|
||||
src/dsp/yuv_sse41.c \
|
||||
|
||||
dsp_enc_srcs := \
|
||||
src/dsp/cost.c \
|
||||
src/dsp/cost_mips32.c \
|
||||
src/dsp/cost_mips_dsp_r2.c \
|
||||
src/dsp/cost_neon.$(NEON) \
|
||||
src/dsp/cost_sse2.c \
|
||||
src/dsp/enc.c \
|
||||
src/dsp/enc_avx2.c \
|
||||
src/dsp/enc_mips32.c \
|
||||
src/dsp/enc_mips_dsp_r2.c \
|
||||
src/dsp/enc_msa.c \
|
||||
@ -113,16 +101,14 @@ dsp_enc_srcs := \
|
||||
src/dsp/lossless_enc_neon.$(NEON) \
|
||||
src/dsp/lossless_enc_sse2.c \
|
||||
src/dsp/lossless_enc_sse41.c \
|
||||
src/dsp/ssim.c \
|
||||
src/dsp/ssim_sse2.c \
|
||||
|
||||
enc_srcs := \
|
||||
src/enc/alpha_enc.c \
|
||||
src/enc/analysis_enc.c \
|
||||
src/enc/backward_references_cost_enc.c \
|
||||
src/enc/backward_references_enc.c \
|
||||
src/enc/config_enc.c \
|
||||
src/enc/cost_enc.c \
|
||||
src/enc/delta_palettization_enc.c \
|
||||
src/enc/filter_enc.c \
|
||||
src/enc/frame_enc.c \
|
||||
src/enc/histogram_enc.c \
|
||||
@ -174,7 +160,7 @@ LOCAL_SRC_FILES := \
|
||||
$(utils_dec_srcs) \
|
||||
|
||||
LOCAL_CFLAGS := $(WEBP_CFLAGS)
|
||||
LOCAL_EXPORT_C_INCLUDES += $(LOCAL_PATH)/src
|
||||
LOCAL_C_INCLUDES += $(LOCAL_PATH)/src
|
||||
|
||||
# prefer arm over thumb mode for performance gains
|
||||
LOCAL_ARM_MODE := arm
|
||||
@ -208,7 +194,7 @@ LOCAL_SRC_FILES := \
|
||||
$(utils_enc_srcs) \
|
||||
|
||||
LOCAL_CFLAGS := $(WEBP_CFLAGS)
|
||||
LOCAL_EXPORT_C_INCLUDES += $(LOCAL_PATH)/src
|
||||
LOCAL_C_INCLUDES += $(LOCAL_PATH)/src
|
||||
|
||||
# prefer arm over thumb mode for performance gains
|
||||
LOCAL_ARM_MODE := arm
|
||||
@ -231,7 +217,7 @@ include $(CLEAR_VARS)
|
||||
LOCAL_SRC_FILES := $(demux_srcs)
|
||||
|
||||
LOCAL_CFLAGS := $(WEBP_CFLAGS)
|
||||
LOCAL_EXPORT_C_INCLUDES += $(LOCAL_PATH)/src
|
||||
LOCAL_C_INCLUDES += $(LOCAL_PATH)/src
|
||||
|
||||
# prefer arm over thumb mode for performance gains
|
||||
LOCAL_ARM_MODE := arm
|
||||
@ -254,7 +240,7 @@ include $(CLEAR_VARS)
|
||||
LOCAL_SRC_FILES := $(mux_srcs)
|
||||
|
||||
LOCAL_CFLAGS := $(WEBP_CFLAGS)
|
||||
LOCAL_EXPORT_C_INCLUDES += $(LOCAL_PATH)/src
|
||||
LOCAL_C_INCLUDES += $(LOCAL_PATH)/src
|
||||
|
||||
# prefer arm over thumb mode for performance gains
|
||||
LOCAL_ARM_MODE := arm
|
||||
|
765
CMakeLists.txt
765
CMakeLists.txt
@ -1,724 +1,189 @@
|
||||
##
|
||||
## Copyright (c) 2020 Google LLC.
|
||||
##
|
||||
## Use of this source code is governed by a BSD-style license
|
||||
## that can be found in the LICENSE 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.
|
||||
cmake_minimum_required(VERSION 2.8.7)
|
||||
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
|
||||
project(WebP C)
|
||||
project(libwebp C)
|
||||
|
||||
# Options for coder / decoder executables.
|
||||
if(NOT EMSCRIPTEN)
|
||||
# Disable SIMD on Emscripten by default, as it's a new unstable Wasm feature.
|
||||
# Users can still explicitly opt-in to make a SIMD-enabled build.
|
||||
set(WEBP_ENABLE_SIMD_DEFAULT ON)
|
||||
endif()
|
||||
option(WEBP_ENABLE_SIMD "Enable any SIMD optimization."
|
||||
${WEBP_ENABLE_SIMD_DEFAULT})
|
||||
option(WEBP_BUILD_ANIM_UTILS "Build animation utilities." ON)
|
||||
option(WEBP_BUILD_CWEBP "Build the cwebp command line tool." ON)
|
||||
option(WEBP_BUILD_DWEBP "Build the dwebp command line tool." ON)
|
||||
option(WEBP_BUILD_GIF2WEBP "Build the gif2webp conversion tool." ON)
|
||||
option(WEBP_BUILD_IMG2WEBP "Build the img2webp animation tool." ON)
|
||||
option(WEBP_BUILD_VWEBP "Build the vwebp viewer tool." ON)
|
||||
option(WEBP_BUILD_WEBPINFO "Build the webpinfo command line tool." ON)
|
||||
option(WEBP_BUILD_WEBPMUX "Build the webpmux command line tool." ON)
|
||||
option(WEBP_BUILD_EXTRAS "Build extras." ON)
|
||||
option(WEBP_BUILD_WEBP_JS "Emscripten build of webp.js." OFF)
|
||||
option(WEBP_NEAR_LOSSLESS "Enable near-lossless encoding" ON)
|
||||
option(WEBP_ENABLE_SWAP_16BIT_CSP "Enable byte swap for 16 bit colorspaces."
|
||||
OFF)
|
||||
set(WEBP_BITTRACE "0" CACHE STRING "Bit trace mode (0=none, 1=bit, 2=bytes)")
|
||||
set_property(CACHE WEBP_BITTRACE PROPERTY STRINGS 0 1 2)
|
||||
|
||||
# Option needed for handling Unicode file names on Windows.
|
||||
if(WIN32)
|
||||
option(WEBP_UNICODE "Build Unicode executables." ON)
|
||||
endif()
|
||||
|
||||
if(WEBP_BUILD_WEBP_JS)
|
||||
set(WEBP_BUILD_ANIM_UTILS OFF)
|
||||
set(WEBP_BUILD_CWEBP OFF)
|
||||
set(WEBP_BUILD_DWEBP OFF)
|
||||
set(WEBP_BUILD_GIF2WEBP OFF)
|
||||
set(WEBP_BUILD_IMG2WEBP OFF)
|
||||
set(WEBP_BUILD_VWEBP OFF)
|
||||
set(WEBP_BUILD_WEBPINFO OFF)
|
||||
set(WEBP_BUILD_WEBPMUX OFF)
|
||||
set(WEBP_BUILD_EXTRAS OFF)
|
||||
|
||||
if(WEBP_ENABLE_SIMD)
|
||||
message("wasm2js does not support SIMD, disabling webp.js generation.")
|
||||
endif()
|
||||
endif()
|
||||
option(WEBP_BUILD_CWEBP "Build the cwebp command line tool." OFF)
|
||||
option(WEBP_BUILD_DWEBP "Build the dwebp command line tool." OFF)
|
||||
option(WEBP_BUILD_GIF2WEBP "Build the gif2webp conversion tool." OFF)
|
||||
option(WEBP_BUILD_IMG2WEBP "Build the img2webp animation tool." OFF)
|
||||
option(WEBP_EXPERIMENTAL_FEATURES "Build with experimental features." OFF)
|
||||
option(WEBP_ENABLE_SWAP_16BIT_CSP "Enable byte swap for 16 bit colorspaces." OFF)
|
||||
|
||||
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)
|
||||
set(CMAKE_BUILD_TYPE "Release" CACHE
|
||||
"Build type: Release, Debug or RelWithDebInfo" STRING FORCE
|
||||
)
|
||||
endif()
|
||||
|
||||
# Include dependencies.
|
||||
include(cmake/deps.cmake)
|
||||
include(GNUInstallDirs)
|
||||
include(cmake/config.h.cmake)
|
||||
|
||||
# ##############################################################################
|
||||
################################################################################
|
||||
# Options.
|
||||
if(WEBP_ENABLE_SWAP_16BIT_CSP)
|
||||
add_definitions(-DWEBP_SWAP_16BIT_CSP=1)
|
||||
add_definitions(-DWEBP_SWAP_16BIT_CSP)
|
||||
endif()
|
||||
|
||||
if(NOT WEBP_BITTRACE STREQUAL "0")
|
||||
add_definitions(-DBITTRACE=${WEBP_BITTRACE})
|
||||
endif()
|
||||
|
||||
if(WEBP_UNICODE)
|
||||
# Windows recommends setting both UNICODE and _UNICODE.
|
||||
add_definitions(-DUNICODE -D_UNICODE)
|
||||
endif()
|
||||
|
||||
set(prefix ${CMAKE_INSTALL_PREFIX})
|
||||
set(exec_prefix "\$\{prefix\}")
|
||||
set(libdir "\$\{prefix\}/lib")
|
||||
set(includedir "\$\{prefix\}/include")
|
||||
set(PTHREAD_LIBS ${CMAKE_THREAD_LIBS_INIT})
|
||||
set(INSTALLED_LIBRARIES)
|
||||
|
||||
# ##############################################################################
|
||||
################################################################################
|
||||
# Android only.
|
||||
if(ANDROID)
|
||||
include_directories(${ANDROID_NDK}/sources/android/cpufeatures)
|
||||
add_library(cpufeatures STATIC
|
||||
${ANDROID_NDK}/sources/android/cpufeatures/cpu-features.c)
|
||||
list(APPEND INSTALLED_LIBRARIES cpufeatures)
|
||||
${ANDROID_NDK}/sources/android/cpufeatures/cpu-features.c
|
||||
)
|
||||
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)
|
||||
add_definitions(-DHAVE_CPU_FEATURES_H=1)
|
||||
set(HAVE_CPU_FEATURES_H 1)
|
||||
else()
|
||||
set(HAVE_CPU_FEATURES_H 0)
|
||||
${ANDROID_NDK}/sources/android/cpufeatures
|
||||
)
|
||||
endif()
|
||||
|
||||
function(configure_pkg_config FILE)
|
||||
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/${FILE}.in"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/${FILE}")
|
||||
################################################################################
|
||||
# WebP source files.
|
||||
# Read the Makefile.am to get the source files.
|
||||
|
||||
if(HAVE_MATH_LIBRARY)
|
||||
# MSVC doesn't have libm
|
||||
file(READ ${CMAKE_CURRENT_BINARY_DIR}/${FILE} data)
|
||||
string(REPLACE "-lm" "" data ${data})
|
||||
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/${FILE} ${data})
|
||||
endif()
|
||||
|
||||
install(
|
||||
FILES "${CMAKE_CURRENT_BINARY_DIR}/${FILE}"
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig
|
||||
)
|
||||
endfunction()
|
||||
|
||||
# ##############################################################################
|
||||
# WebP source files. Read the Makefile.am to get the source files.
|
||||
|
||||
# We expect the Makefiles to define the sources as defined in the first regex.
|
||||
# E.g.: libimagedec_la_SOURCES = image_dec.c image_dec.h
|
||||
function(parse_Makefile_am FOLDER VAR SRC_REGEX)
|
||||
function(parse_Makefile_am FOLDER VAR)
|
||||
file(READ ${FOLDER}/Makefile.am MAKEFILE_AM)
|
||||
string(REGEX MATCHALL
|
||||
"${SRC_REGEX}_SOURCES[ ]*\\+?=[ ]+[0-9a-z\\._ ]*"
|
||||
FILES_PER_LINE
|
||||
${MAKEFILE_AM})
|
||||
string(REGEX MATCHALL "_SOURCES \\+= [^\n]*"
|
||||
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)
|
||||
if(FILES)
|
||||
string(REGEX MATCHALL
|
||||
"[0-9a-z\\._]+"
|
||||
FILES
|
||||
${FILES})
|
||||
foreach(FILE ${FILES})
|
||||
list(APPEND SRCS ${FOLDER}/${FILE})
|
||||
endforeach()
|
||||
endif()
|
||||
string(SUBSTRING ${FILES} 12 -1 FILES)
|
||||
string(REGEX MATCHALL "[0-9a-z\\._]+"
|
||||
FILES ${FILES}
|
||||
)
|
||||
foreach(FILE ${FILES})
|
||||
list(APPEND SRCS ${FOLDER}/${FILE})
|
||||
endforeach()
|
||||
endforeach()
|
||||
set(${VAR} ${SRCS} PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
set(WEBP_SRC_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src)
|
||||
parse_makefile_am(${WEBP_SRC_DIR}/dec "WEBP_DEC_SRCS" "")
|
||||
parse_makefile_am(${WEBP_SRC_DIR}/demux "WEBP_DEMUX_SRCS" "")
|
||||
parse_makefile_am(${WEBP_SRC_DIR}/dsp "WEBP_DSP_COMMON_SRCS" "COMMON")
|
||||
parse_makefile_am(${WEBP_SRC_DIR}/dsp "WEBP_DSP_ENC_SRCS" "ENC")
|
||||
parse_makefile_am(${WEBP_SRC_DIR}/dsp "WEBP_DSP_ENC_SRCS" "dsp_[^ ]*")
|
||||
parse_makefile_am(${WEBP_SRC_DIR}/dsp "WEBP_DSP_DEC_SRCS" "decode_[^ ]*")
|
||||
parse_makefile_am(${WEBP_SRC_DIR}/enc "WEBP_ENC_SRCS" "")
|
||||
parse_makefile_am(${WEBP_SRC_DIR}/utils "WEBP_UTILS_COMMON_SRCS" "COMMON")
|
||||
parse_makefile_am(${WEBP_SRC_DIR}/utils "WEBP_UTILS_ENC_SRCS" "ENC")
|
||||
parse_makefile_am(${WEBP_SRC_DIR}/utils "WEBP_UTILS_DEC_SRCS" "decode_[^ ]*")
|
||||
set(WEBP_SRCS)
|
||||
parse_Makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/src/dec "WEBP_SRCS")
|
||||
parse_Makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/src/demux "WEBP_SRCS")
|
||||
parse_Makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/src/dsp "WEBP_SRCS")
|
||||
parse_Makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/src/enc "WEBP_SRCS")
|
||||
parse_Makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/src/utils "WEBP_SRCS")
|
||||
|
||||
# Remove the files specific to SIMD we don't use.
|
||||
foreach(FILE ${WEBP_SIMD_FILES_NOT_TO_INCLUDE})
|
||||
list(REMOVE_ITEM WEBP_DSP_ENC_SRCS ${FILE})
|
||||
list(REMOVE_ITEM WEBP_DSP_DEC_SRCS ${FILE})
|
||||
list(REMOVE_ITEM WEBP_SRCS ${FILE})
|
||||
endforeach()
|
||||
|
||||
# Generate the config.h file.
|
||||
configure_file(${CMAKE_CURRENT_LIST_DIR}/cmake/config.h.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/src/webp/config.h)
|
||||
add_definitions(-DHAVE_CONFIG_H)
|
||||
|
||||
# ##############################################################################
|
||||
# Build the webpdecoder library.
|
||||
|
||||
# Creates a source file with an unused stub function in $CMAKE_BINARY_DIR and
|
||||
# adds it to the specified target. Currently used only with Xcode.
|
||||
#
|
||||
# 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>."
|
||||
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_code
|
||||
"// Generated file. DO NOT EDIT!\n"
|
||||
"// C source file created for target ${TARGET}.\n"
|
||||
"void libwebp_${TARGET}_stub_function(void)\;\n"
|
||||
"void libwebp_${TARGET}_stub_function(void) {}\n")
|
||||
file(WRITE "${stub_source_file}" ${stub_source_code})
|
||||
|
||||
target_sources(${TARGET} PRIVATE ${stub_source_file})
|
||||
endfunction()
|
||||
|
||||
if(MSVC)
|
||||
# avoid security warnings for e.g., fopen() used in the examples.
|
||||
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
|
||||
else()
|
||||
add_definitions(-Wall)
|
||||
endif()
|
||||
include_directories(${WEBP_DEP_INCLUDE_DIRS})
|
||||
add_library(webpdecode OBJECT ${WEBP_DEC_SRCS})
|
||||
target_include_directories(webpdecode
|
||||
PRIVATE ${CMAKE_CURRENT_BINARY_DIR}
|
||||
${CMAKE_CURRENT_SOURCE_DIR})
|
||||
add_library(webpdspdecode OBJECT ${WEBP_DSP_COMMON_SRCS} ${WEBP_DSP_DEC_SRCS})
|
||||
target_include_directories(webpdspdecode
|
||||
PRIVATE ${CMAKE_CURRENT_BINARY_DIR}
|
||||
${CMAKE_CURRENT_SOURCE_DIR})
|
||||
add_library(webputilsdecode
|
||||
OBJECT
|
||||
${WEBP_UTILS_COMMON_SRCS}
|
||||
${WEBP_UTILS_DEC_SRCS})
|
||||
target_include_directories(webputilsdecode
|
||||
PRIVATE ${CMAKE_CURRENT_BINARY_DIR}
|
||||
${CMAKE_CURRENT_SOURCE_DIR})
|
||||
add_library(webpdecoder
|
||||
$<TARGET_OBJECTS:webpdecode>
|
||||
$<TARGET_OBJECTS:webpdspdecode>
|
||||
$<TARGET_OBJECTS:webputilsdecode>)
|
||||
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}
|
||||
INTERFACE $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
|
||||
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>)
|
||||
set_target_properties(
|
||||
webpdecoder
|
||||
PROPERTIES PUBLIC_HEADER "${CMAKE_CURRENT_SOURCE_DIR}/src/webp/decode.h;\
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/webp/types.h")
|
||||
|
||||
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:webpdecode>
|
||||
$<TARGET_OBJECTS:webpdsp>
|
||||
$<TARGET_OBJECTS:webpencode>
|
||||
$<TARGET_OBJECTS:webputils>)
|
||||
if(XCODE)
|
||||
libwebp_add_stub_file(webp)
|
||||
endif()
|
||||
# Build the library.
|
||||
add_definitions(-Wall)
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/src/ ${WEBP_DEP_INCLUDE_DIRS})
|
||||
add_library(webp ${WEBP_SRCS})
|
||||
target_link_libraries(webp ${WEBP_DEP_LIBRARIES})
|
||||
target_include_directories(webp
|
||||
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${CMAKE_CURRENT_BINARY_DIR}
|
||||
PUBLIC $<INSTALL_INTERFACE:include>)
|
||||
set_target_properties(
|
||||
webp
|
||||
PROPERTIES PUBLIC_HEADER "${CMAKE_CURRENT_SOURCE_DIR}/src/webp/decode.h;\
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/webp/encode.h;\
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/webp/types.h")
|
||||
|
||||
# Make sure the OBJECT libraries are built with position independent code (it is
|
||||
# not ON by default).
|
||||
set_target_properties(webpdecode
|
||||
webpdspdecode
|
||||
webputilsdecode
|
||||
webpencode
|
||||
webpdsp
|
||||
webputils
|
||||
PROPERTIES POSITION_INDEPENDENT_CODE ON)
|
||||
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>)
|
||||
set_target_properties(
|
||||
webpdemux
|
||||
PROPERTIES PUBLIC_HEADER "${CMAKE_CURRENT_SOURCE_DIR}/src/webp/decode.h;\
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/webp/demux.h;\
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/webp/mux_types.h;\
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/webp/types.h")
|
||||
|
||||
configure_pkg_config("src/demux/libwebpdemux.pc")
|
||||
|
||||
# Set the version numbers.
|
||||
function(parse_version FILE NAME VAR)
|
||||
file(READ ${CMAKE_CURRENT_SOURCE_DIR}/src/${FILE} SOURCE_FILE)
|
||||
string(REGEX MATCH
|
||||
"${NAME}_la_LDFLAGS[^\n]* -version-info [0-9:]+"
|
||||
TMP
|
||||
${SOURCE_FILE})
|
||||
string(REGEX MATCH
|
||||
"[0-9:]+"
|
||||
TMP
|
||||
${TMP})
|
||||
string(REGEX
|
||||
REPLACE ":"
|
||||
"."
|
||||
VERSION
|
||||
${TMP})
|
||||
set(${VAR} "${VERSION}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
parse_version(Makefile.am webp WEBP_WEBP_SOVERSION)
|
||||
set_target_properties(webp
|
||||
PROPERTIES VERSION
|
||||
${PACKAGE_VERSION}
|
||||
SOVERSION
|
||||
${WEBP_WEBP_SOVERSION})
|
||||
parse_version(Makefile.am webpdecoder WEBP_DECODER_SOVERSION)
|
||||
set_target_properties(webpdecoder
|
||||
PROPERTIES VERSION
|
||||
${PACKAGE_VERSION}
|
||||
SOVERSION
|
||||
${WEBP_DECODER_SOVERSION})
|
||||
parse_version(demux/Makefile.am webpdemux WEBP_DEMUX_SOVERSION)
|
||||
set_target_properties(webpdemux
|
||||
PROPERTIES VERSION
|
||||
${PACKAGE_VERSION}
|
||||
SOVERSION
|
||||
${WEBP_DEMUX_SOVERSION})
|
||||
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})
|
||||
|
||||
# Define the libraries to install.
|
||||
list(APPEND INSTALLED_LIBRARIES webpdecoder webp webpdemux)
|
||||
|
||||
# Deal with SIMD. Change the compile flags for SIMD files we use.
|
||||
# Change the compile flags for SIMD files we use.
|
||||
list(LENGTH WEBP_SIMD_FILES_TO_INCLUDE WEBP_SIMD_FILES_TO_INCLUDE_LENGTH)
|
||||
math(EXPR WEBP_SIMD_FILES_TO_INCLUDE_RANGE
|
||||
"${WEBP_SIMD_FILES_TO_INCLUDE_LENGTH}-1")
|
||||
"${WEBP_SIMD_FILES_TO_INCLUDE_LENGTH}-1"
|
||||
)
|
||||
|
||||
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(WEBP_BUILD_GIF2WEBP AND NOT GIF_FOUND)
|
||||
set(WEBP_BUILD_GIF2WEBP OFF)
|
||||
endif()
|
||||
|
||||
if(WEBP_BUILD_ANIM_UTILS AND NOT GIF_FOUND)
|
||||
set(WEBP_BUILD_ANIM_UTILS OFF)
|
||||
endif()
|
||||
|
||||
# Build the executables if asked for.
|
||||
if(WEBP_BUILD_ANIM_UTILS
|
||||
OR WEBP_BUILD_CWEBP
|
||||
OR WEBP_BUILD_DWEBP
|
||||
OR WEBP_BUILD_GIF2WEBP
|
||||
OR WEBP_BUILD_IMG2WEBP
|
||||
OR WEBP_BUILD_VWEBP)
|
||||
if(WEBP_BUILD_CWEBP OR WEBP_BUILD_DWEBP OR
|
||||
WEBP_BUILD_GIF2WEBP OR WEBP_BUILD_IMG2WEBP)
|
||||
# Example utility library.
|
||||
parse_makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/examples "EXAMPLEUTIL_SRCS"
|
||||
"example_util_[^ ]*")
|
||||
list(APPEND EXAMPLEUTIL_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/examples/stopwatch.h)
|
||||
add_library(exampleutil STATIC ${EXAMPLEUTIL_SRCS})
|
||||
target_link_libraries(exampleutil imageioutil)
|
||||
target_include_directories(
|
||||
exampleutil
|
||||
PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>)
|
||||
set(exampleutil_SRCS
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/examples/stopwatch.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/examples/example_util.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/examples/example_util.h)
|
||||
add_library(exampleutil ${exampleutil_SRCS})
|
||||
target_link_libraries(exampleutil webp ${WEBP_DEP_LIBRARIES})
|
||||
|
||||
parse_makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/imageio "IMAGEIOUTILS_SRCS"
|
||||
"imageio_util_[^ ]*")
|
||||
add_library(imageioutil STATIC ${IMAGEIOUTILS_SRCS})
|
||||
target_link_libraries(imageioutil webp)
|
||||
set(imageioutil_SRCS
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/imageio/imageio_util.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/imageio/imageio_util.h)
|
||||
add_library(imageioutil ${imageioutil_SRCS})
|
||||
target_link_libraries(imageioutil ${WEBP_DEP_LIBRARIES})
|
||||
|
||||
# Image-decoding utility library.
|
||||
parse_makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/imageio "IMAGEDEC_SRCS"
|
||||
"imagedec_[^ ]*")
|
||||
add_library(imagedec STATIC ${IMAGEDEC_SRCS})
|
||||
target_link_libraries(imagedec
|
||||
imageioutil
|
||||
webpdemux
|
||||
webp
|
||||
${WEBP_DEP_IMG_LIBRARIES})
|
||||
set(imagedec_SRCS
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/examples/gifdec.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/examples/gifdec.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/imageio/image_dec.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/imageio/image_dec.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/imageio/jpegdec.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/imageio/jpegdec.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/imageio/metadata.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/imageio/metadata.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/imageio/pngdec.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/imageio/pngdec.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/imageio/tiffdec.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/imageio/tiffdec.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/imageio/webpdec.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/imageio/webpdec.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/imageio/wicdec.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/imageio/wicdec.h)
|
||||
add_library(imagedec ${imagedec_SRCS})
|
||||
target_link_libraries(imagedec webp ${WEBP_DEP_LIBRARIES}
|
||||
${WEBP_DEP_IMG_LIBRARIES})
|
||||
|
||||
# Image-encoding utility library.
|
||||
parse_makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/imageio "IMAGEENC_SRCS"
|
||||
"imageenc_[^ ]*")
|
||||
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(imageenc_SRCS
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/imageio/image_enc.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/imageio/image_enc.h)
|
||||
add_library(imageenc ${imageenc_SRCS})
|
||||
target_link_libraries(imageenc webp imageioutil
|
||||
${WEBP_DEP_LIBRARIES} ${WEBP_DEP_IMG_LIBRARIES})
|
||||
endif()
|
||||
|
||||
if(WEBP_BUILD_DWEBP)
|
||||
# dwebp
|
||||
parse_makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/examples "DWEBP_SRCS" "dwebp")
|
||||
add_executable(dwebp ${DWEBP_SRCS})
|
||||
target_link_libraries(dwebp exampleutil imagedec imageenc)
|
||||
target_include_directories(dwebp PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/src)
|
||||
install(TARGETS dwebp RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
|
||||
include_directories(${WEBP_DEP_IMG_INCLUDE_DIRS})
|
||||
add_executable(dwebp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/examples/dwebp.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/examples/stopwatch.h)
|
||||
target_link_libraries(dwebp imagedec imageenc webp
|
||||
exampleutil imageioutil
|
||||
${WEBP_DEP_LIBRARIES} ${WEBP_DEP_IMG_LIBRARIES}
|
||||
)
|
||||
endif()
|
||||
|
||||
if(WEBP_BUILD_CWEBP)
|
||||
# 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)
|
||||
install(TARGETS cwebp RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
|
||||
endif()
|
||||
|
||||
if(WEBP_BUILD_GIF2WEBP OR WEBP_BUILD_IMG2WEBP)
|
||||
parse_makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/src/mux "WEBP_MUX_SRCS" "")
|
||||
add_library(libwebpmux ${WEBP_MUX_SRCS})
|
||||
target_link_libraries(libwebpmux webp)
|
||||
target_include_directories(libwebpmux
|
||||
PRIVATE ${CMAKE_CURRENT_BINARY_DIR}
|
||||
${CMAKE_CURRENT_SOURCE_DIR})
|
||||
parse_version(mux/Makefile.am webpmux WEBP_MUX_SOVERSION)
|
||||
set_target_properties(libwebpmux
|
||||
PROPERTIES VERSION
|
||||
${PACKAGE_VERSION}
|
||||
SOVERSION
|
||||
${WEBP_MUX_SOVERSION})
|
||||
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;")
|
||||
set_target_properties(libwebpmux PROPERTIES OUTPUT_NAME webpmux)
|
||||
list(APPEND INSTALLED_LIBRARIES libwebpmux)
|
||||
configure_pkg_config("src/mux/libwebpmux.pc")
|
||||
include_directories(${WEBP_DEP_IMG_INCLUDE_DIRS})
|
||||
add_executable(cwebp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/examples/cwebp.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/examples/stopwatch.h)
|
||||
target_link_libraries(cwebp imagedec webp exampleutil imageioutil
|
||||
${WEBP_DEP_LIBRARIES} ${WEBP_DEP_IMG_LIBRARIES}
|
||||
)
|
||||
endif()
|
||||
|
||||
if(WEBP_BUILD_GIF2WEBP)
|
||||
# gif2webp
|
||||
include_directories(${WEBP_DEP_GIF_INCLUDE_DIRS})
|
||||
parse_makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/examples "GIF2WEBP_SRCS"
|
||||
"gif2webp")
|
||||
include_directories(${WEBP_DEP_IMG_INCLUDE_DIRS})
|
||||
set(GIF2WEBP_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/examples/gif2webp.c)
|
||||
parse_Makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/src/mux "GIF2WEBP_SRCS")
|
||||
add_executable(gif2webp ${GIF2WEBP_SRCS})
|
||||
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})
|
||||
target_link_libraries(gif2webp imagedec webp exampleutil imageioutil
|
||||
${WEBP_DEP_LIBRARIES} ${WEBP_DEP_IMG_LIBRARIES}
|
||||
)
|
||||
endif()
|
||||
|
||||
if(WEBP_BUILD_IMG2WEBP)
|
||||
# img2webp
|
||||
include_directories(${WEBP_DEP_IMG_INCLUDE_DIRS})
|
||||
parse_makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/examples "IMG2WEBP_SRCS"
|
||||
"img2webp")
|
||||
set(IMG2WEBP_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/examples/img2webp.c)
|
||||
parse_Makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/src/mux "IMG2WEBP_SRCS")
|
||||
add_executable(img2webp ${IMG2WEBP_SRCS})
|
||||
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})
|
||||
target_link_libraries(img2webp imagedec webp exampleutil imageioutil
|
||||
${WEBP_DEP_LIBRARIES} ${WEBP_DEP_IMG_LIBRARIES}
|
||||
)
|
||||
endif()
|
||||
|
||||
if(WEBP_BUILD_VWEBP)
|
||||
# vwebp
|
||||
find_package(GLUT)
|
||||
if(GLUT_FOUND)
|
||||
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})
|
||||
install(TARGETS vwebp RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
|
||||
if(${CMAKE_SYSTEM_NAME} STREQUAL "Darwin")
|
||||
check_c_compiler_flag("-Wno-deprecated-declarations" HAS_NO_DEPRECATED)
|
||||
if(HAS_NO_DEPRECATED)
|
||||
target_compile_options(vwebp PRIVATE "-Wno-deprecated-declarations")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(WEBP_BUILD_WEBPINFO)
|
||||
# webpinfo
|
||||
include_directories(${WEBP_DEP_IMG_INCLUDE_DIRS})
|
||||
parse_makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/examples "WEBPINFO_SRCS"
|
||||
"webpinfo")
|
||||
add_executable(webpinfo ${WEBPINFO_SRCS})
|
||||
target_link_libraries(webpinfo exampleutil imageioutil)
|
||||
target_include_directories(webpinfo PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/src)
|
||||
install(TARGETS webpinfo RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
|
||||
endif()
|
||||
|
||||
if(WEBP_BUILD_WEBPMUX)
|
||||
# webpmux
|
||||
parse_makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/examples "WEBPMUX_SRCS"
|
||||
"webpmux")
|
||||
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)
|
||||
set(EXTRAS_MAKEFILE "${CMAKE_CURRENT_SOURCE_DIR}/extras")
|
||||
parse_makefile_am(${EXTRAS_MAKEFILE} "WEBP_EXTRAS_SRCS" "libwebpextras_la")
|
||||
parse_makefile_am(${EXTRAS_MAKEFILE} "GET_DISTO_SRCS" "get_disto")
|
||||
parse_makefile_am(${EXTRAS_MAKEFILE} "WEBP_QUALITY_SRCS" "webp_quality")
|
||||
parse_makefile_am(${EXTRAS_MAKEFILE} "VWEBP_SDL_SRCS" "vwebp_sdl")
|
||||
|
||||
# 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_SOURCE_DIR}/src
|
||||
${CMAKE_CURRENT_BINARY_DIR}/src)
|
||||
install(TARGETS get_disto RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
|
||||
|
||||
# webp_quality
|
||||
add_executable(webp_quality ${WEBP_QUALITY_SRCS} ${WEBP_EXTRAS_SRCS})
|
||||
target_link_libraries(webp_quality exampleutil imagedec)
|
||||
target_include_directories(webp_quality
|
||||
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${CMAKE_CURRENT_BINARY_DIR})
|
||||
install(TARGETS webp_quality RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
|
||||
|
||||
# vwebp_sdl
|
||||
find_package(SDL)
|
||||
if(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_SOURCE_DIR}/src
|
||||
${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)
|
||||
install(TARGETS vwebp_sdl RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(WEBP_BUILD_WEBP_JS)
|
||||
# wasm2js does not support SIMD.
|
||||
if(NOT WEBP_ENABLE_SIMD)
|
||||
# JavaScript version
|
||||
add_executable(webp_js ${CMAKE_CURRENT_SOURCE_DIR}/extras/webp_to_sdl.c)
|
||||
target_link_libraries(webp_js webpdecoder SDL)
|
||||
target_include_directories(webp_js PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
|
||||
set(WEBP_HAVE_SDL 1)
|
||||
set_target_properties(
|
||||
webp_js
|
||||
PROPERTIES LINK_FLAGS "-s WASM=0 \
|
||||
-s EXPORTED_FUNCTIONS='[\"_WebpToSDL\"]' -s INVOKE_RUN=0 \
|
||||
-s EXTRA_EXPORTED_RUNTIME_METHODS='[\"cwrap\"]'")
|
||||
set_target_properties(webp_js PROPERTIES OUTPUT_NAME webp)
|
||||
target_compile_definitions(webp_js PUBLIC EMSCRIPTEN WEBP_HAVE_SDL)
|
||||
endif()
|
||||
|
||||
# WASM version
|
||||
add_executable(webp_wasm ${CMAKE_CURRENT_SOURCE_DIR}/extras/webp_to_sdl.c)
|
||||
target_link_libraries(webp_wasm webpdecoder SDL)
|
||||
target_include_directories(webp_wasm PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
|
||||
set_target_properties(
|
||||
webp_wasm
|
||||
PROPERTIES LINK_FLAGS "-s WASM=1 \
|
||||
-s EXPORTED_FUNCTIONS='[\"_WebpToSDL\"]' -s INVOKE_RUN=0 \
|
||||
-s EXTRA_EXPORTED_RUNTIME_METHODS='[\"cwrap\"]'")
|
||||
target_compile_definitions(webp_wasm PUBLIC EMSCRIPTEN WEBP_HAVE_SDL)
|
||||
|
||||
target_compile_definitions(webpdspdecode PUBLIC EMSCRIPTEN)
|
||||
endif()
|
||||
|
||||
if(WEBP_BUILD_ANIM_UTILS)
|
||||
# anim_diff
|
||||
include_directories(${WEBP_DEP_IMG_INCLUDE_DIRS} ${WEBP_DEP_GIF_INCLUDE_DIRS})
|
||||
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
|
||||
libwebpmux
|
||||
webpdemux
|
||||
${WEBP_DEP_GIF_LIBRARIES})
|
||||
target_include_directories(anim_diff PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/src)
|
||||
|
||||
# anim_dump
|
||||
include_directories(${WEBP_DEP_IMG_INCLUDE_DIRS} ${WEBP_DEP_GIF_INCLUDE_DIRS})
|
||||
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
|
||||
libwebpmux
|
||||
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})
|
||||
set(ConfigPackageLocation ${CMAKE_INSTALL_DATADIR}/${PROJECT_NAME}/cmake/)
|
||||
install(EXPORT ${PROJECT_NAME}Targets
|
||||
NAMESPACE ${PROJECT_NAME}::
|
||||
DESTINATION ${ConfigPackageLocation})
|
||||
|
||||
# Create the CMake version file.
|
||||
include(CMakePackageConfigHelpers)
|
||||
write_basic_package_version_file(
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/WebPConfigVersion.cmake"
|
||||
VERSION ${PACKAGE_VERSION}
|
||||
COMPATIBILITY AnyNewerVersion)
|
||||
|
||||
# Create the Config file.
|
||||
include(CMakePackageConfigHelpers)
|
||||
configure_package_config_file(
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/cmake/WebPConfig.cmake.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/WebPConfig.cmake
|
||||
INSTALL_DESTINATION
|
||||
${ConfigPackageLocation})
|
||||
|
||||
# Install the generated CMake files.
|
||||
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/WebPConfigVersion.cmake"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/WebPConfig.cmake"
|
||||
DESTINATION ${ConfigPackageLocation})
|
||||
|
||||
# Install the man pages.
|
||||
set(MAN_PAGES
|
||||
cwebp.1
|
||||
dwebp.1
|
||||
gif2webp.1
|
||||
img2webp.1
|
||||
vwebp.1
|
||||
webpmux.1
|
||||
webpinfo.1)
|
||||
set(EXEC_BUILDS
|
||||
"CWEBP"
|
||||
"DWEBP"
|
||||
"GIF2WEBP"
|
||||
"IMG2WEBP"
|
||||
"VWEBP"
|
||||
"WEBPMUX"
|
||||
"WEBPINFO")
|
||||
list(LENGTH MAN_PAGES MAN_PAGES_LENGTH)
|
||||
math(EXPR MAN_PAGES_RANGE "${MAN_PAGES_LENGTH} - 1")
|
||||
|
||||
foreach(I_MAN RANGE ${MAN_PAGES_RANGE})
|
||||
list(GET EXEC_BUILDS ${I_MAN} EXEC_BUILD)
|
||||
if(WEBP_BUILD_${EXEC_BUILD})
|
||||
list(GET MAN_PAGES ${I_MAN} MAN_PAGE)
|
||||
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/man/${MAN_PAGE}
|
||||
DESTINATION ${CMAKE_INSTALL_MANDIR}/man1
|
||||
COMPONENT doc)
|
||||
endif()
|
||||
endforeach()
|
||||
|
660
ChangeLog
660
ChangeLog
@ -1,657 +1,9 @@
|
||||
170a8712 Fix check_c_source_compiles with pthread.
|
||||
85995719 disable CombinedShannonEntropy_SSE2 on x86
|
||||
8af7436f Merge "{ios,xcframework}build.sh: make min version(s) more visible" into 1.2.0
|
||||
e56c3c5b pngdec: raise memory limit if needed
|
||||
13b8e9fe {ios,xcframework}build.sh: make min version(s) more visible
|
||||
a9225410 animdecoder_fuzzer: fix memory leak
|
||||
d6c2285d update gradle to 6.1.1
|
||||
52ce6333 update NEWS
|
||||
28c49820 bump version to 1.2.0
|
||||
7363dff2 webp/encode.h: restore WEBP_ENCODER_ABI_VERSION to v1.1.0
|
||||
826aafa5 update AUTHORS
|
||||
63258823 animdecoder_fuzzer: validate canvas size
|
||||
9eb26381 CMake: remove duplicate "include(GNUInstallDirs)"
|
||||
2e7bed79 WebPPicture: clarify the ownership of user-owned data.
|
||||
cccf5e33 webpmux: add an '-set loop <value>' option
|
||||
c9a3f6a1 Merge changes Ie29f9867,I289c54c4
|
||||
319f56f1 iosbuild.sh: sync some aspects of xcframeworkbuild.sh
|
||||
e8e8db98 add xcframeworkbuild.sh
|
||||
ae545534 dsp.h: allow config.h to override MSVC SIMD autodetection
|
||||
fef789f3 Merge "cmake: fix per-file assembly flags"
|
||||
fc14fc03 Have C encoding predictors use decoding predictors.
|
||||
7656f0b3 README,cosmetics: fix a couple typos
|
||||
d2e245ea cmake: disable webp.js if WEBP_ENABLE_SIMD=1
|
||||
96099a79 cmake: fix per-file assembly flags
|
||||
5abb5582 Merge "cmake: fix compilation w/Xcode generator"
|
||||
8484a120 cmake: fix compilation w/Xcode generator
|
||||
d7bf01c9 Merge changes Ifcae0f38,Iee2d7401
|
||||
36c81ff6 WASM-SIMD: port 2 patches from rreverser@'s tree
|
||||
988b02ab Merge "Couple of fixes to allow SIMD on Emscripten"
|
||||
26faf770 wicdec: fail with animated images
|
||||
ab2d08a8 [cd]webp: document lack of animated webp support
|
||||
52273943 Couple of fixes to allow SIMD on Emscripten
|
||||
8870ba7f Fix skia bug #10952
|
||||
4b3c6953 Detect if StoreFrame read more than anmf_payload_size bytes
|
||||
17fd4ba8 webp/decode.h,cosmetics: normalize 'flip' comment
|
||||
411d3677 remove some unreachable break statements
|
||||
3700ffd7 WebPPictureHasTransparency: remove unreachable return
|
||||
83604bf3 {animencoder,enc_dec}_fuzzer: convert some abort()s to returns
|
||||
eb44119c Merge changes I8ae09473,I678c8b1e
|
||||
9f6055fc fuzz_utils.h: rename max() to Max()
|
||||
695788e7 fuzz_utils.h: make functions WEBP_INLINE
|
||||
906c1fcd make ImgIoUtilReadFile use WebPMalloc instead of malloc
|
||||
8cb7e536 rename demux_api_fuzzer.c -> mux_demux_api_fuzzer.c
|
||||
443db47d add animdecoder_fuzzer.cc
|
||||
36a6eea3 Merge "import fuzzers from oss-fuzz/chromium"
|
||||
ec5f12c1 Makefile.vc: remove deprecated /Gm option
|
||||
64425a08 picture_tools_enc: fix windows build warning
|
||||
bd94090a import fuzzers from oss-fuzz/chromium
|
||||
cf847cba use WEBP_DSP_INIT_FUNC for Init{GammaTables*,GetCoeffs}
|
||||
55a080e5 Add WebPReplaceTransparentPixels() in dsp
|
||||
84739717 GetBackgroundColorGIF: promote to uint32_t before << 24
|
||||
def64e92 cwebp: Fix -print_psnr for near_lossless
|
||||
cf2f88b3 Add palette and spatial for q >= 75 and -m 5
|
||||
f0110bae Add no-color cache configuration to the cruncher
|
||||
749a8b99 Better estimate of the cache cost.
|
||||
4f9f00cc Use spatial predictors on top of palette no matter what.
|
||||
7658c686 Add spatial prediction on top of palette in cruncher.
|
||||
133ff0e3 webp_js: force WASM=0 option explicitly
|
||||
e3c259a2 Fix integer overflow in EmitFancyRGB.
|
||||
b3ff0bde man/{gif2,img2}webp,webpmux: normalize some wording
|
||||
f9b30586 fix ABI breakage introduced by 6a0ff358
|
||||
1d58dcfc README.webp_js: update note about emscripten version
|
||||
44070266 README.webp_js: s/fastcomp/upstream/
|
||||
2565fa8f README.webp_js: update cmake command
|
||||
47309ef5 webp: WEBP_OFFSET_PTR()
|
||||
687ab00e DC{4,8,16}_NEON: replace vmovl w/vaddl
|
||||
1b92fe75 DC16_NEON,aarch64: use vaddlv
|
||||
53f3d8cf dec_neon,DC8_NEON: use vaddlv instead of movl+vaddv
|
||||
27d08240 Fix integer overflow in WebPAnimDecoderGetNext()
|
||||
69776e38 Merge "remove call to MBAnalyzeBestIntra4Mode for method >= 5"
|
||||
a99078c1 remove call to MBAnalyzeBestIntra4Mode for method >= 5
|
||||
22e404cc CMakeLists.txt: fix set(CACHE) argument order
|
||||
71690b52 fix MSVC warning
|
||||
6a0ff358 Enc: add a qmin / qmax range for quality factor
|
||||
0fa56f30 Merge tag 'v1.1.0'
|
||||
6cf504d0 PNM decoding: handle max_value != 255
|
||||
d7844e97 update ChangeLog (tag: v1.1.0-rc2, tag: v1.1.0, origin/1.1.0)
|
||||
7f006436 Makefile.vc: fix webp_quality.exe link
|
||||
cf047e83 Makefile.vc: fix webp_quality.exe link
|
||||
c074c653 update NEWS
|
||||
30f09551 bump version to 1.1.0
|
||||
a76694a1 update AUTHORS
|
||||
6e3ef7b3 extras: fix WEBP_SWAP_16BIT_CSP check
|
||||
47178dbd extras: add WebPUnmultiplyARGB() convenience function
|
||||
22cbae33 idec_dec: fix 0 offset of NULL pointer
|
||||
290dd0b4 muxread: fix 0 offset of NULL pointer
|
||||
0df474ac Merge "lossless_(enc_|)sse2: avoid offsetting a NULL pointer"
|
||||
c6b75a19 lossless_(enc_|)sse2: avoid offsetting a NULL pointer
|
||||
295e5e38 fix UBSAN warning
|
||||
e2575e05 DC8_NEON,aarch64: use vaddv
|
||||
b0e09e34 dec_neon: Fix build failure under some toolchains
|
||||
cf0e903c dsp/lossless: Fix non gcc ARM builds
|
||||
bb7bc40b Remove ubsan errors.
|
||||
78881b76 CMake: fix GLUT library link
|
||||
9f750f7a cmake: fix BUILD_SHARED_LIBS build on mac
|
||||
17850e74 libwebp: Remove char-subscripts warning in pnmdec.c
|
||||
2fa2552d Merge "Expose WebPMalloc() in addition to WebPFree()"
|
||||
a4df4aae Expose WebPMalloc() in addition to WebPFree()
|
||||
853ea3d8 imageio/tiff: Return error before allocating bad tile size
|
||||
af650c0b Fix a Wxor-used-as-pow false positive
|
||||
601ef17c libwebp.py: update to swig 3.0.12
|
||||
0e48d889 bugfix: last alpha rows were incorrectly decoded
|
||||
24d2ccb4 webp: Fix imageio ReadPNM() TUPLTYPE
|
||||
fab8f9cf cosmetics: normalize '*' association
|
||||
94138e0e update .gitignore
|
||||
0fe1a89d update ChangeLog (tag: v1.0.3-rc1, tag: v1.0.3)
|
||||
2ad0916d update NEWS
|
||||
1287362b bump version to 1.0.3
|
||||
7b968cc2 update AUTHORS
|
||||
9d6988f4 Fix the oscillating prediction problem at low quality
|
||||
312f74d0 makefile.unix: allow *_LIBS to be overridden w/EXTRA_LIBS
|
||||
92dbf237 filters_sse2,cosmetics: shorten some long lines
|
||||
a277d197 filters_sse2.c: quiet integer sanitizer warnings
|
||||
804540f1 Fix cpufeatures in CMake.
|
||||
bf00c15b Add CMake option for bittrace.
|
||||
a788b498 filters_sse2.c: quiet integer sanitizer warnings
|
||||
e6a92c5e filters.c: quiet integer sanitizer warnings
|
||||
ec1cc40a lossless.c: remove U32 -> S8 conversion warnings
|
||||
1106478f remove conversion U32 -> S8 warnings
|
||||
812a6b49 lossless_enc: fix some conversion warning
|
||||
4627c1c9 lossless_enc,TransformColorBlue: quiet uint32_t conv warning
|
||||
c84673a6 lossless_enc_sse{2,41}: quiet signed conv warnings
|
||||
776a7757 dec_sse2: quiet signed conv warnings
|
||||
bd39c063 Merge "thread_utils: release mutex before signaling"
|
||||
0550576f Merge "(alpha_processing,enc}_sse2: quiet signed conv warnings"
|
||||
6682f2c4 thread_utils: release mutex before signaling
|
||||
e78dea75 (alpha_processing,enc}_sse2: quiet signed conv warnings
|
||||
9acf18ba iosbuild.sh: add WebP{Demux,Mux}.framework
|
||||
b9be7e65 vwebp: remove the -fit option (and make it default)
|
||||
1394a2bb Merge "README.webp_js: update Emscripten.cmake note"
|
||||
dd3e7f8a README.webp_js: update Emscripten.cmake note
|
||||
32cf8801 predictor_enc,GetBestGreenRedToBlue: quiet implicit conv warnings
|
||||
e1c8acb5 Merge "vwebp: add a -fit option"
|
||||
cbd23dd5 vwebp: add a -fit option
|
||||
2e672351 bit_writer_utils,Flush: quiet implicit conversion warnings
|
||||
1326988d swig: update libwebp_python_wrap.c
|
||||
0e7f8548 update generated swig files
|
||||
17ed1438 Merge "PutLE{16,24}: quiet implicit conversion warnings"
|
||||
24686538 PutLE{16,24}: quiet implicit conversion warnings
|
||||
153bb3a0 fix some clang-7 warnings:
|
||||
ab2dc893 Rescaler: fix rounding error
|
||||
aa65f89a HistogramCombineStochastic: fix free of uninit value
|
||||
af0bac64 Merge "encode.h: mention 'exact' default in WebPEncodeLossless*"
|
||||
6d2e11ec encode.h: mention 'exact' default in WebPEncodeLossless*
|
||||
8c3f04fe AndroidCPUInfo: reorder terms in conditional
|
||||
fcfd9c71 BitTrace: if BITTRACE is > 0, record and print syntax bits used
|
||||
067031ea Speedups for unused Huffman groups.
|
||||
01ac46ba libwebp: Display "libjpeg error:" in imageio/jpegdec
|
||||
d9a662e1 WebPRescalerGetScaledDimensions: round scaled dimension up
|
||||
62eb3f08 libwebp: Fix missing '{' in README
|
||||
e05f785a Merge "unicode,INIT_WARGV: add missing cast"
|
||||
63c9a69f tag the VP8LHashPix() function for potential uint roll-over
|
||||
2b7214ab unicode,INIT_WARGV: add missing cast
|
||||
bf424b46 tag the GetPixPairHash64() function for potential uint roll-over
|
||||
7d05d6ca Have the color cache computation be u32-bit only.
|
||||
6bcf8769 Remove BINARYEN_METHOD in wasm settings.
|
||||
2b98df90 update ChangeLog (tag: v1.0.2-rc1, tag: v1.0.2)
|
||||
61e372b7 update NEWS
|
||||
7ae658a0 bump version to 1.0.2
|
||||
51c4907d update AUTHORS
|
||||
666bd6c6 man/cwebp.1: refine near-lossless text
|
||||
561cdce5 Clarify the doc about GetFeatures.
|
||||
aec2cf02 near_lossless: fix fuzzing-detected integer overflow
|
||||
928a75de webp: Fix VP8LBitWriterClone() bug
|
||||
5173d4ee neon IsFlat
|
||||
5b081219 IsFlat: inline when possible
|
||||
381b7b54 IsFlat: use int for thresh
|
||||
6ed15ea1 fix unprobable leak in webp_sdl.c
|
||||
22bbb24e Merge "IsFlat: return int"
|
||||
8b3fb238 Merge tag 'v1.0.1'
|
||||
f435de95 IsFlat: return int
|
||||
41521aed utils.h: only define WEBP_NEED_LOG_TABLE_8BIT when needed
|
||||
9f4d4a3f neon: GetResidualCost
|
||||
0fd7514b neon: SetResidualCoeffs
|
||||
f95a996c Simpler histogram clustering.
|
||||
e85d3313 update ChangeLog (tag: v1.0.1-rc2, tag: v1.0.1)
|
||||
fa8210e4 Fix pair update in stochastic entropy merging.
|
||||
fd198f73 add codereview.settings
|
||||
825389ac README.mux: add a reference to the AnimDecoder API
|
||||
3be698c3 CMake: fix webp_js compilation
|
||||
485ff86f Fix pair update in stochastic entropy merging.
|
||||
4cd0582d CMake: fix webp_js compilation
|
||||
4cbb4caf update NEWS
|
||||
f5a5918d bump version to 1.0.1
|
||||
d61385db Speed-up: Make sure we only initialize histograms when needed.
|
||||
6752904b Speed-up: Make sure we only initialize histograms when needed.
|
||||
0c570316 update AUTHORS
|
||||
301a2dda img2webp: add help note about arguments from a file
|
||||
f0abab92 Speedups for empty histograms.
|
||||
f2dfd925 Split HistogramAdd to only have the high level logic in C.
|
||||
06b7bc7d Fix compilation on windows and clang-cl+ninja.
|
||||
b6284d82 img2webp: add help note about arguments from a file
|
||||
decf6f6b Speedups for empty histograms.
|
||||
dea3e899 Split HistogramAdd to only have the high level logic in C.
|
||||
632798ae Merge "Fix compilation on windows and clang-cl+ninja."
|
||||
dc1a9518 Merge "libwebp: Unicode command tools on Windows"
|
||||
9cf9841b libwebp: Unicode command tools on Windows
|
||||
98179495 remove some minor TODOs
|
||||
a376e7b9 Fix compilation on windows and clang-cl+ninja.
|
||||
cbf82cc0 Remove AVX2 files.
|
||||
5030e902 Merge "TIFF decoder: remove unused KINV definition"
|
||||
ac543311 Remove a few more useless #defines
|
||||
123d3306 TIFF decoder: remove unused KINV definition
|
||||
ef1094b0 Merge "- install pkg-config files during the CMake build"
|
||||
b911fbc9 libwebp: Remove duplicate GIFDisplayError in anim_util
|
||||
eee00b66 - install pkg-config files during the CMake build
|
||||
ac3ec8c9 Merge "Clean-up the common sources in dsp."
|
||||
3e13da7b Clean-up the common sources in dsp.
|
||||
5c395f1d libwebp: cmake-format all
|
||||
e7a69729 libwebp: Add extras targets in CMakeLists.txt
|
||||
e52485d6 libwebp: Rename macros in webpmux.c
|
||||
92dc0f09 clean-up MakeInputImageCopy()
|
||||
39952de2 VP8IteratorImport: add missing 'const'
|
||||
382af7a2 clean-up WebPBlendAlpha
|
||||
14d020f6 libwebp: Use ExUtilGet*() in anim_diff
|
||||
0d92ff25 libwebp: remove useless variable in gif2webp
|
||||
556cb1b4 Merge "CMake: Set WEBP_BUILD_GIF2WEBP to off"
|
||||
da26ee49 CMake: Set WEBP_BUILD_GIF2WEBP to off
|
||||
b2a867c0 cwebp: Don't premultiply during -resize if -exact
|
||||
637141bc pngdec: fix build w/libpng < 1.4.x
|
||||
bc5092b1 pngdec: set memory functions
|
||||
50d8345a Fix CMake math library.
|
||||
6aa3e8aa Fix math library on Visual Studio.
|
||||
d71df4e2 Fix math library finding in CMake.
|
||||
de08d727 cosmetics: normalize include guard comment
|
||||
009562b4 vwebp: Fix bug when Dispose then NoBlend frames
|
||||
423f2579 Fix up CMake to create targets.
|
||||
907208f9 Wait for all threads to be done in DecodeRemaining.
|
||||
4649b3c4 vwebp: Add background color display option
|
||||
78ad57a3 Fix bad glClearColor parameters
|
||||
da96d8d9 Allow for a non-initialized alpha decompressor in DoRemap.
|
||||
2563db47 fix rescaling rounding inaccuracy
|
||||
211f37ee fix endian problems in pattern copy
|
||||
5f0f5c07 Make sure partition #0 is read before VP8 data in IDecode.
|
||||
de98732b fix GetColorf() bug
|
||||
4338cd36 misc fixes in libwebpmux
|
||||
e00af13e fix signatures after a9ceda7ff1
|
||||
a9ceda7f Speed-up chunk list operations.
|
||||
2281bbf6 Merge "Better handling of bogus Huffman codes."
|
||||
39cb9aad Better handling of bogus Huffman codes.
|
||||
89cc9d37 Merge "fix read-overflow while parsing VP8X chunk"
|
||||
95fd6507 fix read-overflow while parsing VP8X chunk
|
||||
9e729fe1 Fix VP8IoTeardownHook being called twice on worker sync failure
|
||||
29fb8562 Merge "muxread,anmf: fail on multiple image chunks"
|
||||
eb82ce76 muxread,anmf: fail on multiple image chunks
|
||||
1344a2e9 fix alpha-filtering crash when image width is larger than radius
|
||||
be738c6d muxread,ChunkVerifyAndAssign: validate chunk_size
|
||||
2c70ad76 muxread,CreateInternal: fix riff size checks
|
||||
569001f1 Fix for thread race heap-use-after-free
|
||||
c56a02d9 Android.mk: use LOCAL_EXPORT_C_INCLUDES w/public libs
|
||||
15795596 CMakeLists.txt,cosmetics: normalize if() formatting
|
||||
1a44c233 Merge "cmake: add support for webpmux"
|
||||
e9569ad7 Merge "configure,*am,cosmetics: s/WANT_/BUILD_/"
|
||||
35c7de6f cmake: add support for webpmux
|
||||
0f25e61c WebpToSDL(): fix the return value in case of error
|
||||
5d8985de configure,*am,cosmetics: s/WANT_/BUILD_/
|
||||
895fd28f Merge "man/Makefile.am: add img2webp.1"
|
||||
5cf3e2af man/Makefile.am: add img2webp.1
|
||||
2a9de5b9 Add build rules for anim_diff & anim_dump utils.
|
||||
71ed73cf fix invalid check for buffer size
|
||||
af0e4fbb gif2webp: fix transcode of loop count=65535
|
||||
dce5d764 Limit memory allocation when reading invalid Huffman codes.
|
||||
f9df0081 Merge "cmake: quiet glut deprecation warnings on OS X"
|
||||
dc39b16f webpmux.1: correct grammar
|
||||
c7aa1264 cwebp.c: fix a missing \n
|
||||
53aa51e9 Merge tag 'v1.0.0'
|
||||
698b8844 update ChangeLog (tag: v1.0.0)
|
||||
8d510751 webp-container-spec: correct frame duration=0 note
|
||||
e6b2164e vwebp: Copy Chrome's behavior w/frame duration == 0
|
||||
094b3b28 cmake: quiet glut deprecation warnings on OS X
|
||||
71c39a06 webp-container-spec: correct frame duration=0 note
|
||||
fd3d5756 vwebp: Copy Chrome's behavior w/frame duration == 0
|
||||
b0c966fb Build vwebp from CMake.
|
||||
d20b7707 update ChangeLog (tag: v1.0.0-rc3)
|
||||
0d5fad46 add WEBP_DSP_INIT / WEBP_DSP_INIT_FUNC
|
||||
d77bf512 add WEBP_DSP_INIT / WEBP_DSP_INIT_FUNC
|
||||
c1cb86af fix 16b overflow in SSE2
|
||||
e577feb7 makefile.unix: add DEBUG flag for compiling w/ debug-symbol
|
||||
99be34b3 cwebp,get_disto: fix bpp output
|
||||
e122e511 cwebp,get_disto: fix bpp output
|
||||
f5565ca8 cmake: Make sure we use near-lossless by default.
|
||||
d898dc14 fix bug in WebPImport565: alpha value was not set
|
||||
1c8f358d Fix CMake with WASM.
|
||||
a0215fb7 webp_js: fix webp_js demo html
|
||||
882784b0 update ChangeLog (tag: v1.0.0-rc2)
|
||||
2f930e08 Revert "Use proper targets for CMake."
|
||||
8165e8fb Use proper targets for CMake.
|
||||
3f157dd5 Remove some very hard TODOs.
|
||||
abb47760 Merge "Use proper targets for CMake."
|
||||
cd758a17 {de,}mux/Makefile.am: add missing headers
|
||||
e155dda0 Use proper targets for CMake.
|
||||
b892b8ba makefile.unix,dist: use ascii for text output
|
||||
64a57d05 add -version option to anim_dump,anim_diff and img2webp
|
||||
994be82d Merge "Remove some very hard TODOs."
|
||||
4033e1d7 Remove some very hard TODOs.
|
||||
fc1b8e3a webp_js: fix webp_js demo html
|
||||
15aa48d9 update ChangeLog (tag: v1.0.0-rc1)
|
||||
e607dabc update AUTHORS
|
||||
38410c08 [CFI] Remove function pointer casts
|
||||
978eec25 [CFI] Remove function pointer casts
|
||||
c57b2736 bump version to 1.0.0
|
||||
cba28853 update NEWS
|
||||
c909d531 Merge "remove some deprecation warning on MacOSX"
|
||||
217443c7 remove some deprecation warning on MacOSX
|
||||
b672bdfa configure: quiet glut deprecation warnings on OS X
|
||||
daa9fcaf configure: use sdl-config if available
|
||||
dd174cae Merge "imagedec: support metadata reading for WebP image decoding"
|
||||
641cedcc imagedec: support metadata reading for WebP image decoding
|
||||
065b2ce1 anim_diff: add a couple missing newlines in Help()
|
||||
c4cc1147 Merge "gif2webp: force low duration frames to 100ms"
|
||||
09333097 gif2webp: force low duration frames to 100ms
|
||||
e03f0ec3 sharp_yuv: use 14b fixed-point precision for gamma
|
||||
b2db361c image_enc,WebPWritePNG: move locals after setjmp
|
||||
74e82ec6 Merge "WebPPictureDistortion: fix big-endian results order"
|
||||
645d04ca Merge "cwebp,get_disto: report bpp"
|
||||
120f58c3 Merge "lossless*sse2: improve non-const 16-bit vector creation"
|
||||
a7fe9412 WebPPictureDistortion: fix big-endian results order
|
||||
e26fe066 cwebp,get_disto: report bpp
|
||||
9df64e28 Merge changes Id5b4a1a4,Ia20ce844
|
||||
8043504f lossless*sse2: improve non-const 16-bit vector creation
|
||||
1e3dfc48 Import: extract condition from loop
|
||||
3b07d327 Import,RGBA: fix for BigEndian import
|
||||
551948e4 Remove unused argument in VP8LBitsEntropy.
|
||||
3005237a ReadWebP: fix for big-endian
|
||||
499c395a Merge "anim_diff: expose the -max_diff option"
|
||||
f69dcd69 Merge "remove WEBP_EXPERIMENTAL_FEATURES"
|
||||
07d884d5 anim_diff: expose the -max_diff option
|
||||
f4dd9256 remove WEBP_EXPERIMENTAL_FEATURES
|
||||
94a8377b extract the command-line parsing helpers to example_util
|
||||
fc09e6e2 PNM decoder: prevent unsupported depth=2 PAM case.
|
||||
6de58603 MIPS64: Fix defined-but-not-used errors with WEBP_REDUCE_CSP
|
||||
cbde5728 gif2webp: add support for reading from stdin
|
||||
cf1c5054 Add an SSE4 version of some lossless color transforms.
|
||||
45a8b5eb Fix lint error with man page.
|
||||
cff38e8f Merge "PNG decoder: handle gAMA chunk"
|
||||
59cb1a48 Merge "enable dc error-diffusion always"
|
||||
78318b30 PNG decoder: handle gAMA chunk
|
||||
664c21dd Merge "remove some TODOs"
|
||||
815652de enable dc error-diffusion always
|
||||
aec45cec remove some TODOs
|
||||
5715dfce fix block-count[] increment in case of large image
|
||||
c2d04f3e enable DC error-diffusion always for multi-pass
|
||||
96bf07c5 use DC error diffusion for U/V at low-quality
|
||||
1c59020b fix missing sse41 targets in makefile.unix
|
||||
7a8e814b cosmetics: s/color_space/colorspace/
|
||||
05f6fe24 upsampling: rm asserts w/REDUCE_CSP+OMIT_C_CODE
|
||||
b4cf5597 Merge "Upsampling SSE2/SSE4 speedup."
|
||||
ccbeb32c Makefile.vc: add missing sse41 files
|
||||
55403a9a Upsampling SSE2/SSE4 speedup.
|
||||
807b53c4 Implement the upsampling/yuv functions in SSE41
|
||||
84101a81 Fix wasm WebP compilation
|
||||
8bebd2a3 fix warning on MSVC
|
||||
a7f93fe3 webpmux: allow reading argument from a file
|
||||
b69f18a7 gif2webp.1: fix -loop_compatibility layout
|
||||
72d530c0 Merge "fix lossless decoding w/WEBP_REDUCE_SIZE"
|
||||
296c7dc4 fix lossless decoding w/WEBP_REDUCE_SIZE
|
||||
0d5d029c Merge "ImgIoUtilReadFile: fix file leak upon error"
|
||||
ae568ce7 ImgIoUtilReadFile: fix file leak upon error
|
||||
796b5a8a Merge tag 'v0.6.1'
|
||||
6b7a95fd update ChangeLog (tag: v0.6.1)
|
||||
f66955de WEBP_REDUCE_CSP: restrict colorspace support
|
||||
1af0df76 Merge "WEBP_REDUCE_CSP: restrict colorspace support"
|
||||
6de20df0 WEBP_REDUCE_CSP: restrict colorspace support
|
||||
a289d8e7 update ChangeLog (tag: v0.6.1-rc2)
|
||||
c10a493c vwebp: disable double buffering on windows & mac
|
||||
0d4466c2 webp_to_sdl.c: fix file mode
|
||||
1b27bf8b WEBP_REDUCE_SIZE: disable all rescaler code
|
||||
126be109 webpinfo: add -version option
|
||||
0df22b9e WEBP_REDUCE_SIZE: disable all rescaler code
|
||||
9add62b5 bump version to 0.6.1
|
||||
d3e26144 update NEWS
|
||||
2edda639 README: add webpinfo section
|
||||
9ca568ef Merge "right-size some tables"
|
||||
31f1995c Merge "SSE2 implementation of HasAlphaXXX"
|
||||
a80c46bd SSE2 implementation of HasAlphaXXX
|
||||
083507f2 right-size some tables
|
||||
2e5785b2 anim_utils.c: remove warning when !defined(WEBP_HAVE_GIF)
|
||||
b299c47e add WEBP_REDUCE_SIZE
|
||||
f593d71a enc: disable pic->stats/extra_info w/WEBP_DISABLE_STATS
|
||||
541179a9 Merge "predictor_enc: fix build w/--disable-near-lossless"
|
||||
5755a7ec predictor_enc: fix build w/--disable-near-lossless
|
||||
eab5bab7 add WEBP_DISABLE_STATS
|
||||
8052c585 remove some petty TODOs from vwebp.
|
||||
c245343d move LOAD8x4 and STORE8x2 closer to their use location
|
||||
b9e734fd dec,cosmetics: normalize function naming style
|
||||
c188d546 dec: harmonize function suffixes
|
||||
28c5ac81 dec_sse41: harmonize function suffixes
|
||||
e65b72a3 Merge "introduce WebPHasAlpha8b and WebPHasAlpha32b"
|
||||
b94cee98 dec_sse2: remove HE8uv_SSE2
|
||||
44a0ee3f introduce WebPHasAlpha8b and WebPHasAlpha32b
|
||||
aebf59ac Merge "WebPPictureAllocARGB: align argb allocation"
|
||||
c184665e WebPPictureAllocARGB: align argb allocation
|
||||
3daf7509 WebPParseHeaders: remove obsolete animation TODO
|
||||
80285d97 cmake: avoid security warnings under msvc
|
||||
650eac55 cmake: don't set -Wall with MSVC
|
||||
c462cd00 Remove useless code.
|
||||
01a98217 Merge "remove WebPWorkerImpl declaration from the header"
|
||||
3c49fc47 Merge "thread_utils: fix potentially bad call to Execute"
|
||||
fde2782e thread_utils: fix potentially bad call to Execute
|
||||
2a270c1d remove WebPWorkerImpl declaration from the header
|
||||
f1f437cc remove mention of 'lossy-only parameters' from the doc
|
||||
3879074d Merge "WebPMemToUint32: remove ptr cast to int"
|
||||
04b029d2 WebPMemToUint32: remove ptr cast to int
|
||||
b7971d0e dsp: avoid defining _C functions w/NEON builds
|
||||
6ba98764 webpdec: correct alloc size check w/use_argb
|
||||
5cfb3b0f normalize include guards
|
||||
f433205e Merge changes Ia17c7dfc,I75423abb,Ia2f716b4,I161caa14,I4210081a, ...
|
||||
8d033b14 {dec,enc}_neon: harmonize function suffixes x2
|
||||
0295e981 upsampling_neon: harmonize function suffixes
|
||||
d572c4e5 yuv_neon: harmonize function suffixes
|
||||
ab9c2500 rescaler_neon: harmonize function suffixes
|
||||
93e0ce27 lossless_neon: harmonize function suffixes
|
||||
22fbc50e lossless_enc_neon: harmonize function suffixes
|
||||
447875b4 filters_neon,cosmetics: fix indent
|
||||
e51bdd43 remove unused VP8TokenToStats() function
|
||||
785da7ea enc_neon: harmonize function suffixes
|
||||
bc1a251f dec_neon: harmonize function suffixes
|
||||
61e535f1 dsp/lossless: workaround gcc-4.8 bug on arm
|
||||
68b2eab7 cwebp: fix alpha reporting w/lossless & metadata
|
||||
30042faa WebPDemuxGetI: add doc details around WebPFormatFeature
|
||||
0a17f471 Merge "WIP: list includes as descendants of the project dir"
|
||||
a4399721 WIP: list includes as descendants of the project dir
|
||||
08275708 Merge "Make sure we reach the full range for alpha blending."
|
||||
d361a6a7 yuv_sse2: harmonize function suffixes
|
||||
6921aa6f upsampling_sse2: harmonize function suffixes
|
||||
08c67d3e ssim_sse2: harmonize function suffixes
|
||||
582a1b57 rescaler_sse2: harmonize function suffixes
|
||||
2c1b18ba lossless_sse2: harmonize function suffixes
|
||||
0ac46e81 lossless_enc_sse2: harmonize function suffixes
|
||||
bc634d57 enc_sse2: harmonize function suffixes
|
||||
bcb7347c dec_sse2: harmonize function suffixes
|
||||
e14ad93c Make sure we reach the full range for alpha blending.
|
||||
7038ca8d demux,StoreFrame: restore hdr size check to min req
|
||||
fb3daad6 cpu: fix ssse3 check
|
||||
be590e06 Merge "Fix CMake redefinition for HAVE_CPU_FEATURES_H"
|
||||
35f736e1 Fix CMake redefinition for HAVE_CPU_FEATURES_H
|
||||
a5216efc Fix integer overflow warning.
|
||||
a9c8916b decode.h,WebPIDecGetRGB: clarify output ptr validity
|
||||
3c74c645 gif2webp: handle 1-frame case properly + fix anim_diff
|
||||
c7f295d3 Merge "gif2webp: introduce -loop_compatibility option"
|
||||
b4e04677 gif2webp: introduce -loop_compatibility option
|
||||
f78da3de add LOCAL_CLANG_PREREQ and avoid WORK_AROUND_GCC w/3.8+
|
||||
01c426f1 define WEBP_USE_INTRINSICS w/gcc-4.9+
|
||||
8635973d use sdl-config (if available) to determine the link flags
|
||||
e9459382 use CPPFLAGS before CFLAGS
|
||||
4a9d788e Merge "Android.mk,mips: fix clang build with r15"
|
||||
4fbdc9fb Android.mk,mips: fix clang build with r15
|
||||
a80fcc4a ifdef code not used by Chrome/Android.
|
||||
3993af12 Fix signed integer overflows.
|
||||
f66f94ef anim_dump: small tool to dump frames from animated WebP
|
||||
6eba857b Merge "rationalize the Makefile.am"
|
||||
c5e34fba function definition cleanup
|
||||
3822762a rationalize the Makefile.am
|
||||
501ef6e4 configure style fix: animdiff -> anim_diff
|
||||
f8bdc268 Merge "protect against NULL dump_folder[] value in ReadAnimatedImage()"
|
||||
23bfc652 protect against NULL dump_folder[] value in ReadAnimatedImage()
|
||||
8dc3d71b cosmetics,ReadAnimatedWebP: correct function comment
|
||||
5bd40066 Merge changes I66a64a0a,I4d2e520f
|
||||
7945575c cosmetics,webpinfo: remove an else after a return
|
||||
8729fa11 cosmetics,cwebp: remove an else after a return
|
||||
f324b7f9 cosmetics: normalize fn proto & decl param names
|
||||
869eb369 CMake cleanups.
|
||||
289e62a3 Remove declaration of unimplemented VP8ApplyNearLosslessPredict
|
||||
20a94186 pnmdec,PAM: validate depth before calculating bytes_per_px
|
||||
34130afe anim_encode: fix integer overflow
|
||||
42c79aa6 Merge "Encoder: harmonize function suffixes"
|
||||
b09307dc Encoder: harmonize function suffixes
|
||||
bed0456d Merge "SSIM: harmonize the function suffix"
|
||||
54f6a3cf lossless_sse2.c: fix some missed suffix changes
|
||||
088f1dcc SSIM: harmonize the function suffix
|
||||
86fc4dd9 webpdec: use ImgIoUtilCheckSizeArgumentsOverflow
|
||||
08ea9ecd imageio: add ability restrict max image size
|
||||
6f9daa4a jpegdec,ReadError: fix leaks on error
|
||||
a0f72a4f VP8LTransformColorFunc: drop an non-respected 'const' from the signature.
|
||||
8c934902 Merge "Lossess dec: harmonize the function suffixes"
|
||||
622242aa Lossess dec: harmonize the function suffixes
|
||||
1411f027 Lossless Enc: harmonize the function suffixes
|
||||
24ad2e3c add const to two variables
|
||||
46efe062 Merge "Allow the lossless cruncher to work for alpha."
|
||||
8c3f9a47 Speed-up LZ77.
|
||||
1aef4c71 Allow the lossless cruncher to work for alpha.
|
||||
b8821dbd Improve the box LZ77 speed.
|
||||
7beed280 add missing ()s to macro parameters
|
||||
6473d20b Merge "fix Android standalone toolchain build"
|
||||
dcefed95 Merge "build.gradle: fix arm64 build"
|
||||
0c83a8bc Merge "yuv: harmonize suffix naming"
|
||||
c6d1db4b fix Android standalone toolchain build
|
||||
663a6d9d unify the ALTERNATE_CODE flag usage
|
||||
73ea9f27 yuv: harmonize suffix naming
|
||||
c71b68ac build.gradle: fix arm64 build
|
||||
c4568b47 Rescaler: harmonize the suffix naming
|
||||
6cb13b05 Merge "alpha_processing: harmonize the naming suffixes to be _C()"
|
||||
83a3e69a Merge "simplify WEBP_EXTERN macro"
|
||||
7295fde2 Merge "filters: harmonize the suffixes naming to _SSE2(), _C(), etc."
|
||||
8e42ba4c simplify WEBP_EXTERN macro
|
||||
331ab34b cost*.c: harmonize the suffix namings
|
||||
b161f670 filters: harmonize the suffixes naming to _SSE2(), _C(), etc.
|
||||
dec5e4d3 alpha_processing: harmonize the naming suffixes to be _C()
|
||||
6878d427 fix memory leak in SDL_Init()
|
||||
461ae555 Merge "configure: fix warnings in sdl check"
|
||||
62486a22 configure: test for -Wundef
|
||||
92982609 dsp.h: fix -Wundef w/__mips_dsp_rev
|
||||
0265cede configure: fix warnings in sdl check
|
||||
88c73d8a backward_references_enc.h: fix WINDOW_SIZE_BITS check
|
||||
4ea49f6b rescaler_sse2.c: fix WEBP_RESCALER_FIX -> _RFIX typo
|
||||
1b526638 Clean-up some CMake
|
||||
87f57a4b Merge "cmake: fix gif lib detection when cross compiling"
|
||||
b34a9db1 cosmetics,dec_sse2: remove some redundant comments
|
||||
471c5755 cmake: fix gif lib detection when cross compiling
|
||||
c793417a cmake: disable gif2webp if gif lib isn't found
|
||||
dcbc1c88 cmake: split gif detection from IMG deps
|
||||
66ad84f0 Merge "muxread: remove unreachable code"
|
||||
50ec3ab7 muxread: remove unreachable code
|
||||
7d67a164 Lossy encoding: smoothen transparent areas to improve compression
|
||||
e50650c7 Merge "fix signature for DISABLE_TOKEN_BUFFER compilation"
|
||||
671d2567 fix signature for DISABLE_TOKEN_BUFFER compilation
|
||||
d6755580 cpu.cmake: use unique flag to test simd disable flags
|
||||
28914528 Merge "Remove the argb* files."
|
||||
8acb4942 Remove the argb* files.
|
||||
3b62347b README: correct cmake invocation note
|
||||
7ca0df13 Have the SSE2 version of PackARGB use common code.
|
||||
7b250459 Merge "Re-use the transformed image when trying several LZ77 in lossless."
|
||||
e132072f Re-use the transformed image when trying several LZ77 in lossless.
|
||||
5d7a50ef Get code to compile in C++.
|
||||
7b012987 configure: test for -Wparentheses-equality
|
||||
f0569adb Fix man pages for multi-threading.
|
||||
f1d5a397 multithread cruncher: only copy stats when picture->stats != NULL
|
||||
f8c2ac15 Multi-thread the lossless cruncher.
|
||||
a88c6522 Merge "Integrate a new LZ77 looking for matches in the neighborhood of a pixel only."
|
||||
8f6df1d0 Unroll Predictors 10, 11 and 12.
|
||||
355c3d1b Integrate a new LZ77 looking for matches in the neighborhood of a pixel only.
|
||||
a1779a01 Refactor LZ77 handling in preparation for a new method.
|
||||
67de68b5 Android.mk/build.gradle: fix mips build with clang from r14b
|
||||
f209a548 Use the plane code and not the distance when computing statistics.
|
||||
b903b80c Split cost-based backward references in its own file.
|
||||
498cad34 Cosmetic changes in backward reference.
|
||||
e4eb4587 lossless, VP8LTransformColor_C: make sure no overflow happens with colors.
|
||||
af6deaff webpinfo: handle alpha flag mismatch
|
||||
7caef29b Fix typo that creeped in.
|
||||
39e19f92 Merge "near lossless: fix unsigned int overflow warnings."
|
||||
9bbc0891 near lossless: fix unsigned int overflow warnings.
|
||||
e1118d62 Merge "cosmetics,FindClosestDiscretized: use uint in mask creation"
|
||||
186bc9b7 Merge "webpinfo: tolerate ALPH+VP8L"
|
||||
b5887297 cosmetics,FindClosestDiscretized: use uint in mask creation
|
||||
f1784aee near_lossless,FindClosestDiscretized: use unsigned ops
|
||||
0d20abb3 webpinfo: tolerate ALPH+VP8L
|
||||
972104b3 webpmux: tolerate false positive Alpha flag
|
||||
dd7e83cc tiffdec,ReadTIFF: ensure data_size is < tsize_t max
|
||||
d988eb7b tiffdec,MyRead: quiet -Wshorten-64-to-32 warning
|
||||
dabda707 webpinfo: add support to parse Alpha bitstream
|
||||
4c117643 webpinfo: correct background color output, BGRA->ARGB
|
||||
defc98d7 Doc: clarify the role of quality in WebPConfig.
|
||||
d78ff780 Merge "Fix code to compile with C++."
|
||||
c8f14093 Fix code to compile with C++.
|
||||
497dc6a7 pnmdec: sanitize invalid header output
|
||||
d78e5867 Merge "configure: test for -Wconstant-conversion"
|
||||
481e91eb Merge "pnmdec,PAM: set bytes_per_px based on depth when missing"
|
||||
93b12753 configure: test for -Wconstant-conversion
|
||||
645f0c53 pnmdec,PAM: set bytes_per_px based on depth when missing
|
||||
e9154605 Merge "vwebp: activate GLUT double-buffering"
|
||||
818d795b vwebp: activate GLUT double-buffering
|
||||
d63e6f4b Add a man page for webpinfo
|
||||
4d708435 Merge "NEON: implement ConvertRGB24ToY/BGR24/ARGB/RGBA32ToUV/ARGBToUV"
|
||||
faf42213 NEON: implement ConvertRGB24ToY/BGR24/ARGB/RGBA32ToUV/ARGBToUV
|
||||
b4d576fa Install man pages with CMake.
|
||||
cbc1b921 webpinfo: add features to parse bitstream header
|
||||
e644c556 Fix bad bit writer initialization.
|
||||
b62cdad2 Merge "Implement a cruncher for lossless at method 6."
|
||||
da3e4dfb use the exact constant for the gamma transfer function
|
||||
a9c701e0 Merge "tiffdec: fix EXTRASAMPLES check"
|
||||
adab8ce0 Implement a cruncher for lossless at method 6.
|
||||
1b92b237 Merge "Fix VP8ApplyNearLossless to respect const and stride."
|
||||
1923ff02 tiffdec: fix EXTRASAMPLES check
|
||||
97cce5ba tiffdec: only request EXTRASAMPLES w/> 3 samples/px
|
||||
0dcd85b6 Fix VP8ApplyNearLossless to respect const and stride.
|
||||
f7682189 yuv: rationalize the C/SSE2 function naming
|
||||
52245424 NEON implementation of some Sharp-YUV420 functions
|
||||
690efd82 Avoid several backward reference copies.
|
||||
4bb1f607 src/dec/vp8_dec.h, cosmetics: fix comments
|
||||
285748be cmake: build/install webpinfo
|
||||
78fd199c backward_references_enc.c: clear -Wshadow warnings
|
||||
ae836410 WebPLog2FloorC: clear -Wshadow warning
|
||||
d0b7404e Merge "WASM support"
|
||||
134e314f WASM support
|
||||
c08adb6f Merge "VP8LEnc: remove use of BitsLog2Ceiling()"
|
||||
28c37ebd VP8LEnc: remove use of BitsLog2Ceiling()
|
||||
2cb58ab2 webpinfo: output format as a human readable string
|
||||
bb175a93 Merge "rename some symbols clashing with MSVC headers"
|
||||
39eda658 Remove a duplicated pixel hash implementation.
|
||||
36b8274d rename some symbols clashing with MSVC headers
|
||||
274daf54 Add webpinfo tool.
|
||||
ec5036e4 add explicit reference to /usr/local/{lib,inc}
|
||||
18f0dfac Merge "fix TIFF encoder regarding rgbA/RGBA"
|
||||
4e2b0b50 Merge "webpdec.h: fix a doc typo"
|
||||
e2eeabff Merge "Install binaries, libraries and headers in CMake."
|
||||
836607e6 webpdec.h: fix a doc typo
|
||||
9273e441 fix TIFF encoder regarding rgbA/RGBA
|
||||
17e3c11f Add limited PAM decoding support
|
||||
5f624871 Install binaries, libraries and headers in CMake.
|
||||
976adac1 Merge "lossless incremental decoding: fix missing eos_ test"
|
||||
f8fad4fa lossless incremental decoding: fix missing eos_ test
|
||||
27415d41 Merge "vwebp_sdl: fix the makefile.unix"
|
||||
49566182 Merge "ImgIoUtilWriteFile(): use ImgIoUtilSetBinaryMode"
|
||||
6f75a51b Analyze the transform entropy on the whole image.
|
||||
a5e4e3af Use palette only if we can in entropy analysis.
|
||||
75a9c3c4 Improve compression by better entropy analysis.
|
||||
39cf6f4f vwebp_sdl: fix the makefile.unix
|
||||
699b0416 ImgIoUtilWriteFile(): use ImgIoUtilSetBinaryMode
|
||||
7d985bd1 Fix small entropy analysis bug.
|
||||
6e7caf06 Optimize the color cache size.
|
||||
833c9219 More efficient stochastic histogram merge.
|
||||
5183326b Refactor the greedy histogram merge.
|
||||
99f6f462 Merge "histogram_enc.c,MyRand: s/ul/u/ for unsigned constants"
|
||||
80a22186 ssim.c: remove dead include
|
||||
a128dfff histogram_enc.c,MyRand: s/ul/u/ for unsigned constants
|
||||
693bf74e move the SSIM calculation code in ssim.c / ssim_sse2.c
|
||||
10d791ca Merge "Fix the random generator in HistogramCombineStochastic."
|
||||
fa63a966 Fix the random generator in HistogramCombineStochastic.
|
||||
16be192f VP8LSetBitPos: remove the eos_ setting
|
||||
027151ca don't erase the surface before blitting.
|
||||
4105d565 disable WEBP_USE_XXX optimisations when EMSCRIPTEN is defined
|
||||
9ee32a75 Merge "WebP-JS: emscripten-based Javascript decoder"
|
||||
ca9f7b7d WebP-JS: emscripten-based Javascript decoder
|
||||
868aa690 Perform greedy histogram merge in a unified way.
|
||||
5b393f2d Merge "fix path typo for vwebp_sdl in Makefile.vc"
|
||||
e0012bea CMake: only use libwebpdecoder for building dwebp
|
||||
84c2a7b0 fix path typo for vwebp_sdl in Makefile.vc
|
||||
1b0e4abf Merge "Add a flag to disable SIMD optimizations."
|
||||
32263250 Add a flag to disable SIMD optimizations.
|
||||
b494fdec optimize the ARGB->ARGB Import to use memcpy
|
||||
f1536039 Merge "ReadWebP: decode directly into a pre-allocated buffer"
|
||||
e69ed291 ReadWebP: decode directly into a pre-allocated buffer
|
||||
57d8de8a Merge "vwebp_sdl: simple viewer based on SDL"
|
||||
5cfd4ebc LZ77 interval speedups. Faster, smaller, simpler.
|
||||
1e7ad88b PNM header decoder: add some basic numerical validation
|
||||
17c7890c Merge "Add a decoder only library for WebP in CMake."
|
||||
be733786 Merge "Add clang build fix for MSA"
|
||||
03cda0e4 Add a decoder only library for WebP in CMake.
|
||||
aa893914 Add clang build fix for MSA
|
||||
31a92e97 Merge "imageio: add limited PNM support for reading"
|
||||
dcf9d82a imageio: add limited PNM support for reading
|
||||
6524fcd6 vwebp_sdl: simple viewer based on SDL
|
||||
6cf24a24 get_disto: fix reference file read
|
||||
43d472aa Merge tag 'v0.6.0'
|
||||
50d1a848 update ChangeLog (tag: v0.6.0, origin/0.6.0)
|
||||
20a7fea0 extras/Makefile.am: fix libwebpextras.la reference
|
||||
415f3ffe update ChangeLog (tag: v0.6.0-rc3)
|
||||
3c6d1224 update NEWS
|
||||
ee4a4141 update AUTHORS
|
||||
32ed856f Fix "all|no frames are keyframes" settings.
|
||||
1c3190b6 Merge "Fix "all|no frames are keyframes" settings."
|
||||
f4dc56fd disable GradientUnfilter_NEON
|
||||
4f3e3bbd disable GradientUnfilter_NEON
|
||||
2dc0bdca Fix "all|no frames are keyframes" settings.
|
||||
0d8e0588 img2webp: treat -loop as a no-op w/single images
|
||||
b0450139 ReadImage(): restore size reporting
|
||||
0ad3b4ef update ChangeLog (tag: v0.6.0-rc2)
|
||||
@ -719,7 +71,7 @@ b016cb91 NEON: faster fancy upsampling
|
||||
f04eb376 Merge tag 'v0.5.2'
|
||||
341d711c NEON: 5% faster conversion to RGB565 and RGBA4444
|
||||
abb54827 remove Clang warnings with unused arch arguments.
|
||||
ece9684f update ChangeLog (tag: v0.5.2-rc2, tag: v0.5.2, origin/0.5.2)
|
||||
ece9684f update ChangeLog (tag: v0.5.2-rc2, tag: v0.5.2, origin/0.5.2, 0.5.2)
|
||||
aa7744ca anim_util: quiet implicit conv warnings in 32-bit
|
||||
d9120271 jpegdec: correct ContextFill signature
|
||||
24eb3940 Remove some errors when compiling the code as C++.
|
||||
@ -1006,7 +358,7 @@ bbb6ecd9 Merge "Add MSA optimized distortion functions"
|
||||
c0991a14 io,EmitRescaledAlphaYUV: factor out a common expr
|
||||
48bf5ed1 build.gradle: remove tab
|
||||
bfef6c9f Merge tag 'v0.5.1'
|
||||
3d97bb75 update ChangeLog (tag: v0.5.1, origin/0.5.1)
|
||||
3d97bb75 update ChangeLog (tag: v0.5.1, origin/0.5.1, 0.5.1)
|
||||
deb54d91 Clarify the expected 'config' lifespan in WebPIDecode()
|
||||
435308e0 Add MSA optimized encoder transform functions
|
||||
dce64bfa Add MSA optimized alpha filter functions
|
||||
@ -1200,7 +552,7 @@ b74657fb configure: fix builtin detection w/-Werror
|
||||
6c1d7631 avoid Yoda style for comparison
|
||||
8ce975ac SSE optimization for vector mismatch.
|
||||
7db53831 Merge tag 'v0.5.0'
|
||||
37f04949 update ChangeLog (tag: v0.5.0-rc1, tag: v0.5.0, origin/0.5.0)
|
||||
37f04949 update ChangeLog (tag: v0.5.0-rc1, tag: v0.5.0, origin/0.5.0, 0.5.0)
|
||||
7e7b6ccc faster rgb565/rgb4444/argb output
|
||||
4c7f565f update NEWS
|
||||
1f62b6b2 update AUTHORS
|
||||
@ -1984,7 +1336,7 @@ b5a36cc9 add -near_lossless [0..100] experimental option
|
||||
0524d9e5 dsp: detect mips64 & disable mips32 code
|
||||
d3485d96 cwebp.1: fix quality description placement
|
||||
29a9fe22 Merge tag 'v0.4.1'
|
||||
8af27718 update ChangeLog (tag: v0.4.1, origin/0.4.1)
|
||||
8af27718 update ChangeLog (tag: v0.4.1, origin/0.4.1, 0.4.1)
|
||||
e09e9ff6 Record & log the image pre-processing time.
|
||||
f59c0b4b iosbuild.sh: specify optimization flags
|
||||
8d34ea3e update ChangeLog (tag: v0.4.1-rc1)
|
||||
@ -2369,7 +1721,7 @@ ea59a8e9 Merge "Merge tag 'v0.4.0'"
|
||||
effcb0fd Merge tag 'v0.4.0'
|
||||
7c76255d autoconf: update ax_pthread.m4
|
||||
fff2a11b make -short work with -print_ssim, -print_psnr, etc.
|
||||
68e7901d update ChangeLog (tag: v0.4.0-rc1, tag: v0.4.0, origin/0.4.0)
|
||||
68e7901d update ChangeLog (tag: v0.4.0-rc1, tag: v0.4.0, origin/0.4.0, 0.4.0)
|
||||
256e4333 update NEWS description with new general features
|
||||
29625340 Merge "gif2webp: don't use C99 %zu" into 0.4.0
|
||||
3b9f9dd0 gif2webp: don't use C99 %zu
|
||||
@ -3145,7 +2497,7 @@ a61a824b Merge "Add NULL check in chunk APIs"
|
||||
a0770727 mux struct naming
|
||||
6c66dde8 Merge "Tune Lossless encoder"
|
||||
ab5ea217 Tune Lossless encoder
|
||||
74fefc8c Update ChangeLog (tag: v0.2.1, origin/0.2.0)
|
||||
74fefc8c Update ChangeLog (tag: v0.2.1, origin/0.2.0, 0.2.0)
|
||||
92f8059c Rename some chunks:
|
||||
3bb4bbeb Merge "Mux API change:"
|
||||
d0c79f05 Mux API change:
|
||||
|
@ -2,7 +2,7 @@ ACLOCAL_AMFLAGS = -I m4
|
||||
SUBDIRS = src imageio man
|
||||
EXTRA_DIST = COPYING autogen.sh
|
||||
|
||||
if BUILD_EXTRAS
|
||||
if WANT_EXTRAS
|
||||
SUBDIRS += extras
|
||||
endif
|
||||
|
||||
|
85
Makefile.vc
85
Makefile.vc
@ -28,8 +28,8 @@ PLATFORM_LDFLAGS = /SAFESEH
|
||||
|
||||
NOLOGO = /nologo
|
||||
CCNODBG = cl.exe $(NOLOGO) /O2 /DNDEBUG
|
||||
CCDEBUG = cl.exe $(NOLOGO) /Od /Zi /D_DEBUG /RTC1
|
||||
CFLAGS = /I. /Isrc $(NOLOGO) /W3 /EHsc /c
|
||||
CCDEBUG = cl.exe $(NOLOGO) /Od /Gm /Zi /D_DEBUG /RTC1
|
||||
CFLAGS = /Isrc $(NOLOGO) /W3 /EHsc /c
|
||||
CFLAGS = $(CFLAGS) /DWIN32 /D_CRT_SECURE_NO_WARNINGS /DWIN32_LEAN_AND_MEAN
|
||||
LDFLAGS = /LARGEADDRESSAWARE /MANIFEST /NXCOMPAT /DYNAMICBASE
|
||||
LDFLAGS = $(LDFLAGS) $(PLATFORM_LDFLAGS)
|
||||
@ -53,6 +53,11 @@ OUTDIR = ..\obj\
|
||||
OUTDIR = $(OBJDIR)
|
||||
!ENDIF
|
||||
|
||||
!IF "$(HAVE_AVX2)" == "1"
|
||||
CFLAGS = $(CFLAGS) /DWEBP_HAVE_AVX2
|
||||
AVX2_FLAGS = /arch:AVX2
|
||||
!ENDIF
|
||||
|
||||
##############################################################
|
||||
# Runtime library configuration
|
||||
!IF "$(RTLIBCFG)" == "static"
|
||||
@ -129,16 +134,12 @@ LIBWEBP_PDBNAME = $(DIROBJ)\$(LIBWEBP_BASENAME)_dll.pdb
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
!IF "$(UNICODE)" == "1"
|
||||
CFLAGS = $(CFLAGS) /D_UNICODE /DUNICODE
|
||||
!ENDIF
|
||||
|
||||
#######################
|
||||
# Usage
|
||||
#
|
||||
!IF "$(CFGSET)" == "FALSE"
|
||||
!MESSAGE Usage: nmake /f Makefile.vc [CFG=<config>]
|
||||
!MESSAGE . [OBJDIR=<path>] [RTLIBCFG=<rtlib>] [UNICODE=1] [<target>]
|
||||
!MESSAGE . [OBJDIR=<path>] [RTLIBCFG=<rtlib>] [<target>]
|
||||
!MESSAGE
|
||||
!MESSAGE where <config> is one of:
|
||||
!MESSAGE - release-static - release static library
|
||||
@ -154,7 +155,6 @@ CFLAGS = $(CFLAGS) /D_UNICODE /DUNICODE
|
||||
!MESSAGE - all - build (de)mux-based targets for CFG
|
||||
!MESSAGE - gif2webp - requires libgif & >= VS2013
|
||||
!MESSAGE - anim_diff - requires libgif & >= VS2013
|
||||
!MESSAGE - anim_dump
|
||||
!MESSAGE
|
||||
!MESSAGE RTLIBCFG controls the runtime library linkage - 'static' or 'dynamic'.
|
||||
!MESSAGE 'legacy' will produce a Windows 2000 compatible library.
|
||||
@ -226,21 +226,21 @@ DSP_DEC_OBJS = \
|
||||
$(DIROBJ)\dsp\upsampling_msa.obj \
|
||||
$(DIROBJ)\dsp\upsampling_neon.obj \
|
||||
$(DIROBJ)\dsp\upsampling_sse2.obj \
|
||||
$(DIROBJ)\dsp\upsampling_sse41.obj \
|
||||
$(DIROBJ)\dsp\yuv.obj \
|
||||
$(DIROBJ)\dsp\yuv_mips32.obj \
|
||||
$(DIROBJ)\dsp\yuv_mips_dsp_r2.obj \
|
||||
$(DIROBJ)\dsp\yuv_neon.obj \
|
||||
$(DIROBJ)\dsp\yuv_sse2.obj \
|
||||
$(DIROBJ)\dsp\yuv_sse41.obj \
|
||||
|
||||
DSP_ENC_OBJS = \
|
||||
$(DIROBJ)\dsp\argb.obj \
|
||||
$(DIROBJ)\dsp\argb_mips_dsp_r2.obj \
|
||||
$(DIROBJ)\dsp\argb_sse2.obj \
|
||||
$(DIROBJ)\dsp\cost.obj \
|
||||
$(DIROBJ)\dsp\cost_mips32.obj \
|
||||
$(DIROBJ)\dsp\cost_mips_dsp_r2.obj \
|
||||
$(DIROBJ)\dsp\cost_neon.obj \
|
||||
$(DIROBJ)\dsp\cost_sse2.obj \
|
||||
$(DIROBJ)\dsp\enc.obj \
|
||||
$(DIROBJ)\dsp\enc_avx2.obj \
|
||||
$(DIROBJ)\dsp\enc_mips32.obj \
|
||||
$(DIROBJ)\dsp\enc_mips_dsp_r2.obj \
|
||||
$(DIROBJ)\dsp\enc_msa.obj \
|
||||
@ -254,8 +254,6 @@ DSP_ENC_OBJS = \
|
||||
$(DIROBJ)\dsp\lossless_enc_neon.obj \
|
||||
$(DIROBJ)\dsp\lossless_enc_sse2.obj \
|
||||
$(DIROBJ)\dsp\lossless_enc_sse41.obj \
|
||||
$(DIROBJ)\dsp\ssim.obj \
|
||||
$(DIROBJ)\dsp\ssim_sse2.obj \
|
||||
|
||||
EX_ANIM_UTIL_OBJS = \
|
||||
$(DIROBJ)\examples\anim_util.obj \
|
||||
@ -265,7 +263,6 @@ IMAGEIO_DEC_OBJS = \
|
||||
$(DIROBJ)\imageio\jpegdec.obj \
|
||||
$(DIROBJ)\imageio\metadata.obj \
|
||||
$(DIROBJ)\imageio\pngdec.obj \
|
||||
$(DIROBJ)\imageio\pnmdec.obj \
|
||||
$(DIROBJ)\imageio\tiffdec.obj \
|
||||
$(DIROBJ)\imageio\webpdec.obj \
|
||||
$(DIROBJ)\imageio\wicdec.obj \
|
||||
@ -282,10 +279,10 @@ EX_UTIL_OBJS = \
|
||||
ENC_OBJS = \
|
||||
$(DIROBJ)\enc\alpha_enc.obj \
|
||||
$(DIROBJ)\enc\analysis_enc.obj \
|
||||
$(DIROBJ)\enc\backward_references_cost_enc.obj \
|
||||
$(DIROBJ)\enc\backward_references_enc.obj \
|
||||
$(DIROBJ)\enc\config_enc.obj \
|
||||
$(DIROBJ)\enc\cost_enc.obj \
|
||||
$(DIROBJ)\enc\delta_palettization_enc.obj \
|
||||
$(DIROBJ)\enc\filter_enc.obj \
|
||||
$(DIROBJ)\enc\frame_enc.obj \
|
||||
$(DIROBJ)\enc\histogram_enc.obj \
|
||||
@ -347,8 +344,7 @@ all: ex
|
||||
OUT_EXAMPLES = $(DIRBIN)\cwebp.exe $(DIRBIN)\dwebp.exe
|
||||
EXTRA_EXAMPLES = $(DIRBIN)\vwebp.exe $(DIRBIN)\webpmux.exe \
|
||||
$(DIRBIN)\img2webp.exe $(DIRBIN)\get_disto.exe \
|
||||
$(DIRBIN)\webp_quality.exe $(DIRBIN)\vwebp_sdl.exe \
|
||||
$(DIRBIN)\webpinfo.exe
|
||||
$(DIRBIN)\webp_quality.exe
|
||||
|
||||
ex: $(OUT_LIBS) $(OUT_EXAMPLES)
|
||||
all: ex $(EXTRA_EXAMPLES)
|
||||
@ -356,58 +352,42 @@ all: ex $(EXTRA_EXAMPLES)
|
||||
# C99 support which is only available from VS2013 onward.
|
||||
gif2webp: $(DIRBIN)\gif2webp.exe
|
||||
anim_diff: $(DIRBIN)\anim_diff.exe
|
||||
anim_dump: $(DIRBIN)\anim_dump.exe
|
||||
|
||||
$(DIRBIN)\anim_diff.exe: $(DIROBJ)\examples\anim_diff.obj $(EX_ANIM_UTIL_OBJS)
|
||||
$(DIRBIN)\anim_diff.exe: $(EX_UTIL_OBJS) $(IMAGEIO_UTIL_OBJS)
|
||||
$(DIRBIN)\anim_diff.exe: $(EX_GIF_DEC_OBJS) $(LIBWEBPDEMUX) $(LIBWEBP)
|
||||
$(DIRBIN)\anim_dump.exe: $(DIROBJ)\examples\anim_dump.obj $(EX_ANIM_UTIL_OBJS)
|
||||
$(DIRBIN)\anim_dump.exe: $(EX_UTIL_OBJS) $(IMAGEIO_UTIL_OBJS)
|
||||
$(DIRBIN)\anim_dump.exe: $(EX_GIF_DEC_OBJS) $(LIBWEBPDEMUX) $(LIBWEBP)
|
||||
$(DIRBIN)\anim_dump.exe: $(IMAGEIO_ENC_OBJS)
|
||||
$(DIRBIN)\cwebp.exe: $(DIROBJ)\examples\cwebp.obj $(IMAGEIO_DEC_OBJS)
|
||||
$(DIRBIN)\cwebp.exe: $(IMAGEIO_UTIL_OBJS)
|
||||
$(DIRBIN)\cwebp.exe: $(LIBWEBPDEMUX)
|
||||
$(DIRBIN)\dwebp.exe: $(DIROBJ)\examples\dwebp.obj $(IMAGEIO_DEC_OBJS)
|
||||
$(DIRBIN)\dwebp.exe: $(IMAGEIO_ENC_OBJS)
|
||||
$(DIRBIN)\dwebp.exe: $(IMAGEIO_UTIL_OBJS)
|
||||
$(DIRBIN)\dwebp.exe: $(LIBWEBPDEMUX)
|
||||
$(DIRBIN)\gif2webp.exe: $(DIROBJ)\examples\gif2webp.obj $(EX_GIF_DEC_OBJS)
|
||||
$(DIRBIN)\gif2webp.exe: $(EX_UTIL_OBJS) $(IMAGEIO_UTIL_OBJS) $(LIBWEBPMUX)
|
||||
$(DIRBIN)\gif2webp.exe: $(LIBWEBP)
|
||||
$(DIRBIN)\vwebp.exe: $(DIROBJ)\examples\vwebp.obj $(EX_UTIL_OBJS)
|
||||
$(DIRBIN)\vwebp.exe: $(IMAGEIO_UTIL_OBJS) $(LIBWEBPDEMUX) $(LIBWEBP)
|
||||
$(DIRBIN)\vwebp_sdl.exe: $(DIROBJ)\extras\vwebp_sdl.obj
|
||||
$(DIRBIN)\vwebp_sdl.exe: $(DIROBJ)\extras\webp_to_sdl.obj
|
||||
$(DIRBIN)\vwebp_sdl.exe: $(IMAGEIO_UTIL_OBJS) $(LIBWEBP)
|
||||
$(DIRBIN)\webpmux.exe: $(DIROBJ)\examples\webpmux.obj $(LIBWEBPMUX)
|
||||
$(DIRBIN)\webpmux.exe: $(EX_UTIL_OBJS) $(IMAGEIO_UTIL_OBJS) $(LIBWEBP)
|
||||
$(DIRBIN)\img2webp.exe: $(DIROBJ)\examples\img2webp.obj $(LIBWEBPMUX)
|
||||
$(DIRBIN)\img2webp.exe: $(IMAGEIO_DEC_OBJS)
|
||||
$(DIRBIN)\img2webp.exe: $(EX_UTIL_OBJS) $(IMAGEIO_UTIL_OBJS)
|
||||
$(DIRBIN)\img2webp.exe: $(LIBWEBPDEMUX) $(LIBWEBP)
|
||||
$(DIRBIN)\img2webp.exe: $(EX_UTIL_OBJS) $(IMAGEIO_UTIL_OBJS) $(LIBWEBP)
|
||||
$(DIRBIN)\get_disto.exe: $(DIROBJ)\extras\get_disto.obj
|
||||
$(DIRBIN)\get_disto.exe: $(IMAGEIO_DEC_OBJS) $(IMAGEIO_UTIL_OBJS)
|
||||
$(DIRBIN)\get_disto.exe: $(LIBWEBPDEMUX) $(LIBWEBP)
|
||||
$(DIRBIN)\get_disto.exe: $(IMAGEIO_DEC_OBJS) $(IMAGEIO_UTIL_OBJS) $(LIBWEBP)
|
||||
|
||||
$(DIRBIN)\webp_quality.exe: $(DIROBJ)\extras\webp_quality.obj
|
||||
$(DIRBIN)\webp_quality.exe: $(IMAGEIO_UTIL_OBJS)
|
||||
$(DIRBIN)\webp_quality.exe: $(EXTRAS_OBJS)
|
||||
# EXTRA_OBJS requires private symbols from dsp. Explicitly add those when
|
||||
# building libwebp as a dll.
|
||||
!IF "$(DLLBUILD)" == "TRUE"
|
||||
$(DIRBIN)\webp_quality.exe: $(DSP_DEC_OBJS)
|
||||
!ENDIF
|
||||
$(DIRBIN)\webp_quality.exe: $(LIBWEBP)
|
||||
$(DIRBIN)\webpinfo.exe: $(DIROBJ)\examples\webpinfo.obj
|
||||
$(DIRBIN)\webpinfo.exe: $(IMAGEIO_DEC_OBJS)
|
||||
$(DIRBIN)\webpinfo.exe: $(EX_UTIL_OBJS) $(IMAGEIO_UTIL_OBJS)
|
||||
$(DIRBIN)\webpinfo.exe: $(LIBWEBPDEMUX) $(LIBWEBP)
|
||||
$(DIRBIN)\webp_quality.exe: $(EXTRAS_OBJS) $(LIBWEBP)
|
||||
|
||||
$(OUT_EXAMPLES): $(EX_UTIL_OBJS) $(LIBWEBP)
|
||||
$(EX_UTIL_OBJS) $(IMAGEIO_UTIL_OBJS): $(OUTPUT_DIRS)
|
||||
$(IMAGEIO_DEC_OBJS) $(IMAGEIO_ENC_OBJS) $(EXTRAS_OBJS): $(OUTPUT_DIRS)
|
||||
!ENDIF # ARCH == ARM
|
||||
|
||||
experimental:
|
||||
$(MAKE) /f Makefile.vc \
|
||||
CFG=$(CFG) \
|
||||
CFLAGS="$(CFLAGS) /DWEBP_EXPERIMENTAL_FEATURES" /$(MAKEFLAGS)
|
||||
|
||||
$(LIBWEBPDECODER): $(LIBWEBPDECODER_OBJS)
|
||||
$(LIBWEBP): $(LIBWEBP_OBJS)
|
||||
$(LIBWEBPMUX): $(LIBWEBPMUX_OBJS)
|
||||
@ -453,18 +433,18 @@ $(OUTPUT_DIRS):
|
||||
$(DIROBJ)\$(DLLINC):
|
||||
@echo #ifndef WEBP_DLL_H_ > $@
|
||||
@echo #define WEBP_DLL_H_ >> $@
|
||||
@echo #define WEBP_EXTERN __declspec(dllexport) >> $@
|
||||
@echo #define WEBP_EXTERN(type) __declspec(dllexport) type >> $@
|
||||
@echo #endif /* WEBP_DLL_H_ */ >> $@
|
||||
|
||||
.SUFFIXES: .c .obj .res .exe
|
||||
# File-specific flag builds. Note batch rules take precedence over wildcards,
|
||||
# so for now name each file individually.
|
||||
$(DIROBJ)\dsp\enc_avx2.obj: src\dsp\enc_avx2.c
|
||||
$(CC) $(CFLAGS) $(AVX2_FLAGS) /Fd$(LIBWEBP_PDBNAME) /Fo$(DIROBJ)\dsp\ \
|
||||
src\dsp\$(@B).c
|
||||
$(DIROBJ)\examples\anim_diff.obj: examples\anim_diff.c
|
||||
$(CC) $(CFLAGS) /DWEBP_HAVE_GIF /Fd$(LIBWEBP_PDBNAME) \
|
||||
/Fo$(DIROBJ)\examples\ examples\$(@B).c
|
||||
$(DIROBJ)\examples\anim_dump.obj: examples\anim_dump.c
|
||||
$(CC) $(CFLAGS) /DWEBP_HAVE_GIF /Fd$(LIBWEBP_PDBNAME) \
|
||||
/Fo$(DIROBJ)\examples\ examples\$(@B).c
|
||||
$(DIROBJ)\examples\anim_util.obj: examples\anim_util.c
|
||||
$(CC) $(CFLAGS) /DWEBP_HAVE_GIF /Fd$(LIBWEBP_PDBNAME) \
|
||||
/Fo$(DIROBJ)\examples\ examples\$(@B).c
|
||||
@ -494,18 +474,15 @@ $(DIROBJ)\examples\gifdec.obj: examples\gifdec.c
|
||||
{src\utils}.c{$(DIROBJ)\utils}.obj::
|
||||
$(CC) $(CFLAGS) /Fd$(LIBWEBP_PDBNAME) /Fo$(DIROBJ)\utils\ $<
|
||||
|
||||
LNKLIBS = ole32.lib windowscodecs.lib shlwapi.lib
|
||||
!IF "$(UNICODE)" == "1"
|
||||
LNKLIBS = $(LNKLIBS) Shell32.lib
|
||||
!ENDIF
|
||||
|
||||
{$(DIROBJ)\examples}.obj{$(DIRBIN)}.exe:
|
||||
$(LNKEXE) $(LDFLAGS) /OUT:$@ $** $(LNKLIBS)
|
||||
$(LNKEXE) $(LDFLAGS) /OUT:$@ $** \
|
||||
ole32.lib windowscodecs.lib shlwapi.lib
|
||||
$(MT) -manifest $@.manifest -outputresource:$@;1
|
||||
del $@.manifest
|
||||
|
||||
{$(DIROBJ)\extras}.obj{$(DIRBIN)}.exe:
|
||||
$(LNKEXE) $(LDFLAGS) /OUT:$@ $** $(LNKLIBS)
|
||||
$(LNKEXE) $(LDFLAGS) /OUT:$@ $** \
|
||||
ole32.lib windowscodecs.lib shlwapi.lib
|
||||
$(MT) -manifest $@.manifest -outputresource:$@;1
|
||||
del $@.manifest
|
||||
|
||||
|
78
NEWS
78
NEWS
@ -1,81 +1,3 @@
|
||||
- 12/23/2020: version 1.2.0
|
||||
* API changes:
|
||||
- libwebp:
|
||||
encode.h: add a qmin / qmax range for quality factor (cwebp adds -qrange)
|
||||
* lossless encoder improvements
|
||||
* SIMD support for Wasm builds
|
||||
* add xcframeworkbuild.sh, supports Mac Catalyst builds
|
||||
* import fuzzers from oss-fuzz & chromium (#409)
|
||||
* webpmux: add an '-set loop <value>' option (#494)
|
||||
* toolchain updates and bug fixes (#449, #463, #470, #475, #477, #478, #479,
|
||||
#488, #491)
|
||||
|
||||
- 12/18/2019: version 1.1.0
|
||||
* API changes:
|
||||
- libwebp:
|
||||
WebPMalloc (issue #442)
|
||||
- extras:
|
||||
WebPUnmultiplyARGB
|
||||
* alpha decode fix (issue #439)
|
||||
* toolchain updates and bug fixes
|
||||
(chromium: #1026858, #1027136, #1027409, #1028620, #1028716, #995200)
|
||||
(oss-fuzz: #19430, #19447)
|
||||
|
||||
- 7/4/2019: version 1.0.3
|
||||
This is a binary compatible release.
|
||||
* resize fixes for Nx1 sizes and the addition of non-opaque alpha values for
|
||||
odd sizes (issues #418, #434)
|
||||
* lossless encode/decode performance improvements
|
||||
* lossy compression performance improvement at low quality levels with flat
|
||||
content (issue #432)
|
||||
* python swig files updated to support python 3
|
||||
Tool updates:
|
||||
vwebp will now preserve the aspect ratio of images that exceed monitor
|
||||
resolution by scaling the image to fit (issue #433)
|
||||
|
||||
- 1/14/2019: version 1.0.2
|
||||
This is a binary compatible release.
|
||||
* (Windows) unicode file support in the tools (linux and mac already had
|
||||
support, issue #398)
|
||||
* lossless encoder speedups
|
||||
* lossy encoder speedup on ARM
|
||||
* lossless multi-threaded security fix (chromium:917029)
|
||||
|
||||
- 11/2/2018: version 1.0.1
|
||||
This is a binary compatible release.
|
||||
* lossless encoder speedups
|
||||
* big-endian fix for alpha decoding (issue #393)
|
||||
* gif2webp fix for loop count=65535 transcode (issue #382)
|
||||
* further security related hardening in libwebp & libwebpmux
|
||||
(issues #383, #385, #386, #387, #388, #391)
|
||||
(oss-fuzz #9099, #9100, #9105, #9106, #9111, #9112, #9119, #9123, #9170,
|
||||
#9178, #9179, #9183, #9186, #9191, #9364, #9417, #9496, #10349,
|
||||
#10423, #10634, #10700, #10838, #10922, #11021, #11088, #11152)
|
||||
* miscellaneous bug & build fixes (issues #381, #394, #396, #397, #400)
|
||||
|
||||
- 4/2/2018: version 1.0.0
|
||||
This is a binary compatible release.
|
||||
* lossy encoder improvements to avoid chroma shifts in various circumstances
|
||||
(issues #308, #340)
|
||||
* big-endian fixes for decode, RGBA import and WebPPictureDistortion
|
||||
Tool updates:
|
||||
gifwebp, anim_diff - default duration behavior (<= 10ms) changed to match
|
||||
web browsers, transcoding tools (issue #379)
|
||||
img2webp, webpmux - allow options to be passed in via a file (issue #355)
|
||||
|
||||
- 11/24/2017: version 0.6.1
|
||||
This is a binary compatible release.
|
||||
* lossless performance and compression improvements + a new 'cruncher' mode
|
||||
(-m 6 -q 100)
|
||||
* ARM performance improvements with clang (15-20% w/ndk r15c, issue #339)
|
||||
* webp-js: emscripten/webassembly based javascript decoder
|
||||
* miscellaneous bug & build fixes (issue #329, #332, #343, #353, #360, #361,
|
||||
#363)
|
||||
Tool updates / additions:
|
||||
added webpinfo - prints file format information (issue #330)
|
||||
gif2webp - loop behavior modified to match Chrome M63+ (crbug.com/649264);
|
||||
'-loop_compatibility' can be used for the old behavior
|
||||
|
||||
- 1/26/2017: version 0.6.0
|
||||
* lossless performance and compression improvements
|
||||
* miscellaneous performance improvements (SSE2, NEON, MSA)
|
||||
|
61
README
61
README
@ -4,7 +4,7 @@
|
||||
\__\__/\____/\_____/__/ ____ ___
|
||||
/ _/ / \ \ / _ \/ _/
|
||||
/ \_/ / / \ \ __/ \__
|
||||
\____/____/\_____/_____/____/v1.2.0
|
||||
\____/____/\_____/_____/____/v0.6.0
|
||||
|
||||
Description:
|
||||
============
|
||||
@ -113,8 +113,8 @@ make install
|
||||
|
||||
CMake:
|
||||
------
|
||||
With CMake, you can compile libwebp, cwebp, dwebp, gif2webp, img2webp, webpinfo
|
||||
and the JS bindings.
|
||||
The support for CMake is minimal: it only helps you compile libwebp, cwebp and
|
||||
dwebp.
|
||||
|
||||
Prerequisites:
|
||||
A compiler (e.g., gcc with autotools) and CMake.
|
||||
@ -123,27 +123,18 @@ minimal build:
|
||||
$ sudo apt-get install build-essential cmake
|
||||
|
||||
When building from git sources, you will need to run cmake to generate the
|
||||
makefiles.
|
||||
configure script.
|
||||
|
||||
mkdir build && cd build && cmake ../
|
||||
make
|
||||
make install
|
||||
|
||||
If you also want any of the executables, you will need to enable them through
|
||||
CMake, e.g.:
|
||||
If you also want cwebp or dwebp, you will need to enable them through CMake:
|
||||
|
||||
cmake -DWEBP_BUILD_CWEBP=ON -DWEBP_BUILD_DWEBP=ON ../
|
||||
|
||||
or through your favorite interface (like ccmake or cmake-qt-gui).
|
||||
|
||||
Use option -DWEBP_UNICODE=ON for Unicode support on Windows (with chcp 65001).
|
||||
|
||||
Finally, once installed, you can also use WebP in your CMake project by doing:
|
||||
|
||||
find_package(WebP)
|
||||
|
||||
which will define the CMake variables WebP_INCLUDE_DIRS and WebP_LIBRARIES.
|
||||
|
||||
Gradle:
|
||||
-------
|
||||
The support for Gradle is minimal: it only helps you compile libwebp, cwebp and
|
||||
@ -225,7 +216,6 @@ Usage:
|
||||
|
||||
If input size (-s) for an image is not specified, it is
|
||||
assumed to be a PNG, JPEG, TIFF or WebP file.
|
||||
Note: Animated PNG and WebP files are not supported.
|
||||
|
||||
Options:
|
||||
-h / -help ............. short help
|
||||
@ -255,8 +245,6 @@ Options:
|
||||
-partition_limit <int> . limit quality to fit the 512k limit on
|
||||
the first partition (0=no degradation ... 100=full)
|
||||
-pass <int> ............ analysis pass number (1..10)
|
||||
-qrange <min> <max> .... specifies the permissible quality range
|
||||
(default: 0 100)
|
||||
-crop <x> <y> <w> <h> .. crop picture with the given rectangle
|
||||
-resize <w> <h> ........ resize picture (after any cropping)
|
||||
-mt .................... use multi-threading if available
|
||||
@ -297,7 +285,6 @@ Experimental Options:
|
||||
-af .................... auto-adjust filter strength
|
||||
-pre <int> ............. pre-processing filter
|
||||
|
||||
|
||||
The main options you might want to try in order to further tune the
|
||||
visual quality are:
|
||||
-preset
|
||||
@ -345,9 +332,7 @@ The full list of options is available using -h:
|
||||
> dwebp -h
|
||||
Usage: dwebp in_file [options] [-o out_file]
|
||||
|
||||
Decodes the WebP image file to PNG format [Default].
|
||||
Note: Animated WebP files are not supported.
|
||||
|
||||
Decodes the WebP image file to PNG format [Default]
|
||||
Use following options to convert into alternate image formats:
|
||||
-pam ......... save the raw RGBA samples as a color PAM
|
||||
-ppm ......... save the raw RGB samples as a color PPM
|
||||
@ -375,23 +360,6 @@ Use following options to convert into alternate image formats:
|
||||
-quiet ....... quiet mode, don't print anything
|
||||
-noasm ....... disable all assembly optimizations
|
||||
|
||||
WebP file analysis tool:
|
||||
========================
|
||||
|
||||
'webpinfo' can be used to print out the chunk level structure and bitstream
|
||||
header information of WebP files. It can also check if the files are of valid
|
||||
WebP format.
|
||||
|
||||
Usage: webpinfo [options] in_files
|
||||
Note: there could be multiple input files;
|
||||
options must come before input files.
|
||||
Options:
|
||||
-version ........... Print version number and exit.
|
||||
-quiet ............. Do not show chunk parsing information.
|
||||
-diag .............. Show parsing error diagnosis.
|
||||
-summary ........... Show chunk stats summary.
|
||||
-bitstream_info .... Parse bitstream header.
|
||||
|
||||
Visualization tool:
|
||||
===================
|
||||
|
||||
@ -410,14 +378,12 @@ Options are:
|
||||
-nofilter .... disable in-loop filtering
|
||||
-dither <int> dithering strength (0..100), default=50
|
||||
-noalphadither disable alpha plane dithering
|
||||
-usebgcolor .. display background color
|
||||
-mt .......... use multi-threading
|
||||
-info ........ print info
|
||||
-h ........... this help message
|
||||
|
||||
Keyboard shortcuts:
|
||||
'c' ................ toggle use of color profile
|
||||
'b' ................ toggle background color display
|
||||
'i' ................ overlay file information
|
||||
'd' ................ disable blending & disposal (debug)
|
||||
'q' / 'Q' / ESC .... quit
|
||||
@ -429,7 +395,7 @@ Prerequisites:
|
||||
1) OpenGL & OpenGL Utility Toolkit (GLUT)
|
||||
Linux:
|
||||
$ sudo apt-get install freeglut3-dev mesa-common-dev
|
||||
Mac + Xcode:
|
||||
Mac + XCode:
|
||||
- These libraries should be available in the OpenGL / GLUT frameworks.
|
||||
Windows:
|
||||
http://freeglut.sourceforge.net/index.php#download
|
||||
@ -468,7 +434,6 @@ File-level options (only used at the start of compression):
|
||||
-mixed ............... use mixed lossy/lossless automatic mode
|
||||
-v ................... verbose mode
|
||||
-h ................... this help
|
||||
-version ............. print version number and exit
|
||||
|
||||
Per-frame options (only used for subsequent images input):
|
||||
-d <int> ............. frame duration in ms (default: 100)
|
||||
@ -480,9 +445,6 @@ Per-frame options (only used for subsequent images input):
|
||||
example: img2webp -loop 2 in0.png -lossy in1.jpg
|
||||
-d 80 in2.tiff -o out.webp
|
||||
|
||||
Note: if a single file name is passed as the argument, the arguments will be
|
||||
tokenized from this file. The file name must not start with the character '-'.
|
||||
|
||||
Animated GIF conversion:
|
||||
========================
|
||||
Animated GIF files can be converted to WebP files with animation using the
|
||||
@ -508,8 +470,6 @@ Options:
|
||||
-metadata <string> ..... comma separated list of metadata to
|
||||
copy from the input to the output if present
|
||||
Valid values: all, none, icc, xmp (default)
|
||||
-loop_compatibility .... use compatibility mode for Chrome
|
||||
version prior to M62 (inclusive)
|
||||
-mt .................... use multi-threading if available
|
||||
|
||||
-version ............... print version number and exit
|
||||
@ -538,11 +498,6 @@ Options:
|
||||
-min_psnr <float> ... minimum per-frame PSNR
|
||||
-raw_comparison ..... if this flag is not used, RGB is
|
||||
premultiplied before comparison
|
||||
-max_diff <int> ..... maximum allowed difference per channel
|
||||
between corresponding pixels in subsequent
|
||||
frames
|
||||
-h .................. this help
|
||||
-version ............ print version number and exit
|
||||
|
||||
Building:
|
||||
---------
|
||||
@ -603,7 +558,7 @@ The encoding flow looks like:
|
||||
// Setup a config, starting form a preset and tuning some additional
|
||||
// parameters
|
||||
WebPConfig config;
|
||||
if (!WebPConfigPreset(&config, WEBP_PRESET_PHOTO, quality_factor)) {
|
||||
if (!WebPConfigPreset(&config, WEBP_PRESET_PHOTO, quality_factor))
|
||||
return 0; // version error
|
||||
}
|
||||
// ... additional tuning
|
||||
|
36
README.mux
36
README.mux
@ -1,7 +1,7 @@
|
||||
__ __ ____ ____ ____ __ __ _ __ __
|
||||
/ \\/ \/ _ \/ _ \/ _ \/ \ \/ \___/_ / _\
|
||||
\ / __/ _ \ __/ / / (_/ /__
|
||||
\__\__/\_____/_____/__/ \__//_/\_____/__/___/v1.2.0
|
||||
\__\__/\_____/_____/__/ \__//_/\_____/__/___/v0.4.0
|
||||
|
||||
|
||||
Description:
|
||||
@ -33,7 +33,6 @@ Usage: webpmux -get GET_OPTIONS INPUT -o OUTPUT
|
||||
webpmux -info INPUT
|
||||
webpmux [-h|-help]
|
||||
webpmux -version
|
||||
webpmux argument_file_name
|
||||
|
||||
GET_OPTIONS:
|
||||
Extract relevant data:
|
||||
@ -44,7 +43,6 @@ GET_OPTIONS:
|
||||
|
||||
SET_OPTIONS:
|
||||
Set color profile/metadata:
|
||||
loop LOOP_COUNT set the loop count
|
||||
icc file.icc set ICC profile
|
||||
exif file.exif set EXIF metadata
|
||||
xmp file.xmp set XMP metadata
|
||||
@ -94,9 +92,6 @@ INPUT & OUTPUT are in WebP format.
|
||||
Note: The nature of EXIF, XMP and ICC data is not checked and is assumed to be
|
||||
valid.
|
||||
|
||||
Note: if a single file name is passed as the argument, the arguments will be
|
||||
tokenized from this file. The file name must not start with the character '-'.
|
||||
|
||||
Visualization tool:
|
||||
===================
|
||||
|
||||
@ -212,35 +207,6 @@ Code example:
|
||||
For a detailed AnimEncoder API reference, please refer to the header file
|
||||
(src/webp/mux.h).
|
||||
|
||||
AnimDecoder API:
|
||||
================
|
||||
This AnimDecoder API allows decoding (possibly) animated WebP images.
|
||||
|
||||
Code Example:
|
||||
|
||||
WebPAnimDecoderOptions dec_options;
|
||||
WebPAnimDecoderOptionsInit(&dec_options);
|
||||
// Tune 'dec_options' as needed.
|
||||
WebPAnimDecoder* dec = WebPAnimDecoderNew(webp_data, &dec_options);
|
||||
WebPAnimInfo anim_info;
|
||||
WebPAnimDecoderGetInfo(dec, &anim_info);
|
||||
for (uint32_t i = 0; i < anim_info.loop_count; ++i) {
|
||||
while (WebPAnimDecoderHasMoreFrames(dec)) {
|
||||
uint8_t* buf;
|
||||
int timestamp;
|
||||
WebPAnimDecoderGetNext(dec, &buf, ×tamp);
|
||||
// ... (Render 'buf' based on 'timestamp').
|
||||
// ... (Do NOT free 'buf', as it is owned by 'dec').
|
||||
}
|
||||
WebPAnimDecoderReset(dec);
|
||||
}
|
||||
const WebPDemuxer* demuxer = WebPAnimDecoderGetDemuxer(dec);
|
||||
// ... (Do something using 'demuxer'; e.g. get EXIF/XMP/ICC data).
|
||||
WebPAnimDecoderDelete(dec);
|
||||
|
||||
For a detailed AnimDecoder API reference, please refer to the header file
|
||||
(src/webp/demux.h).
|
||||
|
||||
|
||||
Bugs:
|
||||
=====
|
||||
|
@ -1,83 +0,0 @@
|
||||
__ __ ____ ____ ____ __ ____
|
||||
/ \\/ \ _ \ _ \ _ \ (__)/ __\
|
||||
\ / __/ _ \ __/ _) \_ \
|
||||
\__\__/_____/____/_/ /____/____/
|
||||
|
||||
Description:
|
||||
============
|
||||
|
||||
This file describes the compilation of libwebp into a JavaScript decoder
|
||||
using Emscripten and CMake.
|
||||
|
||||
- install the Emscripten SDK following the procedure described at:
|
||||
https://kripken.github.io/emscripten-site/docs/getting_started/downloads.html
|
||||
After installation, you should have some global variable positioned to the
|
||||
location of the SDK. In particular, $EMSCRIPTEN should point to the
|
||||
top-level directory containing Emscripten tools.
|
||||
|
||||
- make sure the file $EMSCRIPTEN/cmake/Modules/Platform/Emscripten.cmake is
|
||||
accessible. This is the toolchain file used by CMake to invoke Emscripten.
|
||||
If $EMSCRIPTEN is unset search for Emscripten.cmake under $EMSDK and set
|
||||
$EMSCRIPTEN accordingly, for example:
|
||||
unix-like environments: export EMSCRIPTEN=$EMSDK/upstream/emscripten
|
||||
windows: set EMSCRIPTEN=%EMSDK%\upstream\emscripten
|
||||
|
||||
- configure the project 'WEBP_JS' with CMake using:
|
||||
|
||||
cd webp_js && \
|
||||
cmake -DWEBP_BUILD_WEBP_JS=ON \
|
||||
-DCMAKE_TOOLCHAIN_FILE=$EMSCRIPTEN/cmake/Modules/Platform/Emscripten.cmake \
|
||||
../
|
||||
|
||||
- compile webp.js using 'make'.
|
||||
|
||||
- that's it! Upon completion, you should have the webp.js and
|
||||
webp.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 below for instructions).
|
||||
|
||||
Demo HTML page:
|
||||
===============
|
||||
|
||||
The HTML page webp_js/index.html requires an HTTP server to serve the WebP
|
||||
image example. It's easy to just use Python for that.
|
||||
|
||||
cd webp_js && python -m SimpleHTTPServer 8080
|
||||
|
||||
and then navigate to http://localhost:8080 in your favorite browser.
|
||||
|
||||
|
||||
Web-Assembly (WASM) version:
|
||||
============================
|
||||
|
||||
CMakeLists.txt is configured to build the WASM version when using
|
||||
the option WEBP_BUILD_WEBP_JS=ON. The compilation step will assemble
|
||||
the files 'webp_wasm.js', 'webp_wasm.wasm' in the webp_js/ directory.
|
||||
See webp_js/index_wasm.html for a simple demo page using the WASM version
|
||||
of the library.
|
||||
|
||||
You will need a fairly recent version of Emscripten (at least 1.37.8,
|
||||
latest-upstream is recommended) and of your WASM-enabled browser to run this
|
||||
version.
|
||||
|
||||
Caveat:
|
||||
=======
|
||||
|
||||
- First decoding using the library is usually slower, due to just-in-time
|
||||
compilation.
|
||||
|
||||
- Some versions of llvm produce the following compile error when SSE2 is
|
||||
enabled.
|
||||
|
||||
"Unsupported: %516 = bitcast <8 x i16> %481 to i128
|
||||
LLVM ERROR: BitCast Instruction not yet supported for integer types larger than 64 bits"
|
||||
|
||||
The corresponding Emscripten bug is at:
|
||||
https://github.com/kripken/emscripten/issues/3788
|
||||
|
||||
Therefore, SSE2 optimization is currently disabled in CMakeLists.txt.
|
||||
|
||||
- If WEBP_ENABLE_SIMD is set to 1 the JavaScript version (webp.js) will be
|
||||
disabled as wasm2js does not support SIMD.
|
52
build.gradle
52
build.gradle
@ -74,22 +74,12 @@ model {
|
||||
cCompiler.args "-frename-registers -s"
|
||||
}
|
||||
}
|
||||
// mips32 fails to build with clang from r14b
|
||||
// https://bugs.chromium.org/p/webp/issues/detail?id=343
|
||||
if (toolChain in Clang) {
|
||||
if (getTargetPlatform() == "mips") {
|
||||
cCompiler.args "-no-integrated-as"
|
||||
}
|
||||
}
|
||||
// Check for NEON usage.
|
||||
if (getTargetPlatform() == "arm") {
|
||||
if (getTargetPlatform() == "arm" || getTargetPlatform() == "arm64") {
|
||||
NEON = "c.neon"
|
||||
cCompiler.define "HAVE_CPU_FEATURES_H"
|
||||
} else {
|
||||
NEON = "c"
|
||||
}
|
||||
|
||||
cCompiler.args "-I" + file(".").absolutePath
|
||||
}
|
||||
// Link to pthread for shared libraries.
|
||||
withType(SharedLibraryBinarySpec) {
|
||||
@ -122,6 +112,9 @@ model {
|
||||
include "alpha_processing_neon.$NEON"
|
||||
include "alpha_processing_sse2.c"
|
||||
include "alpha_processing_sse41.c"
|
||||
include "argb.c"
|
||||
include "argb_mips_dsp_r2.c"
|
||||
include "argb_sse2.c"
|
||||
include "cpu.c"
|
||||
include "dec.c"
|
||||
include "dec_clip_tables.c"
|
||||
@ -152,13 +145,10 @@ model {
|
||||
include "upsampling_msa.c"
|
||||
include "upsampling_neon.$NEON"
|
||||
include "upsampling_sse2.c"
|
||||
include "upsampling_sse41.c"
|
||||
include "yuv.c"
|
||||
include "yuv_mips32.c"
|
||||
include "yuv_mips_dsp_r2.c"
|
||||
include "yuv_neon.$NEON"
|
||||
include "yuv_sse2.c"
|
||||
include "yuv_sse41.c"
|
||||
srcDir "src/utils"
|
||||
include "bit_reader_utils.c"
|
||||
include "color_cache_utils.c"
|
||||
@ -173,9 +163,9 @@ model {
|
||||
include "cost.c"
|
||||
include "cost_mips32.c"
|
||||
include "cost_mips_dsp_r2.c"
|
||||
include "cost_neon.$NEON"
|
||||
include "cost_sse2.c"
|
||||
include "enc.c"
|
||||
include "enc_avx2.c"
|
||||
include "enc_mips32.c"
|
||||
include "enc_mips_dsp_r2.c"
|
||||
include "enc_msa.c"
|
||||
@ -189,15 +179,13 @@ model {
|
||||
include "lossless_enc_neon.$NEON"
|
||||
include "lossless_enc_sse2.c"
|
||||
include "lossless_enc_sse41.c"
|
||||
include "ssim.c"
|
||||
include "ssim_sse2.c"
|
||||
srcDir "src/enc"
|
||||
include "alpha_enc.c"
|
||||
include "analysis_enc.c"
|
||||
include "backward_references_cost_enc.c"
|
||||
include "backward_references_enc.c"
|
||||
include "config_enc.c"
|
||||
include "cost_enc.c"
|
||||
include "delta_palettization_enc.c"
|
||||
include "filter_enc.c"
|
||||
include "frame_enc.c"
|
||||
include "histogram_enc.c"
|
||||
@ -289,7 +277,6 @@ model {
|
||||
imagedec(NativeLibrarySpec) {
|
||||
binaries {
|
||||
all {
|
||||
lib library: "webpdemux", linkage: "static"
|
||||
lib library: "webp", linkage: "static"
|
||||
}
|
||||
}
|
||||
@ -301,7 +288,6 @@ model {
|
||||
include "jpegdec.c"
|
||||
include "metadata.c"
|
||||
include "pngdec.c"
|
||||
include "pnmdec.c"
|
||||
include "tiffdec.c"
|
||||
include "webpdec.c"
|
||||
}
|
||||
@ -332,7 +318,6 @@ model {
|
||||
lib library: "example_util", linkage: "static"
|
||||
lib library: "imagedec", linkage: "static"
|
||||
lib library: "imageio_util", linkage: "static"
|
||||
lib library: "webpdemux", linkage: "static"
|
||||
lib library: "webp", linkage: "static"
|
||||
}
|
||||
}
|
||||
@ -353,7 +338,6 @@ model {
|
||||
lib library: "imagedec", linkage: "static"
|
||||
lib library: "imageenc", linkage: "static"
|
||||
lib library: "imageio_util", linkage: "static"
|
||||
lib library: "webpdemux", linkage: "static"
|
||||
lib library: "webp"
|
||||
}
|
||||
}
|
||||
@ -393,7 +377,6 @@ model {
|
||||
lib library: "imagedec", linkage: "static"
|
||||
lib library: "imageio_util", linkage: "static"
|
||||
lib library: "webpmux", linkage: "static"
|
||||
lib library: "webpdemux", linkage: "static"
|
||||
lib library: "webp"
|
||||
}
|
||||
}
|
||||
@ -406,24 +389,6 @@ model {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
webpinfo_example(NativeExecutableSpec) {
|
||||
binaries {
|
||||
all {
|
||||
lib library: "example_util", linkage: "static"
|
||||
lib library: "imageio_util", linkage: "static"
|
||||
lib library: "webp"
|
||||
}
|
||||
}
|
||||
sources {
|
||||
c {
|
||||
source {
|
||||
srcDir "./examples"
|
||||
include "webpinfo.c"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
tasks {
|
||||
// Task to test all possible configurations.
|
||||
@ -432,3 +397,8 @@ model {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Task to generate the wrapper.
|
||||
task wrapper(type: Wrapper) {
|
||||
gradleVersion = '2.13'
|
||||
}
|
||||
|
@ -1,11 +0,0 @@
|
||||
set(WebP_VERSION @PROJECT_VERSION@)
|
||||
set(WEBP_VERSION ${WebP_VERSION})
|
||||
|
||||
@PACKAGE_INIT@
|
||||
|
||||
include ("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Targets.cmake")
|
||||
|
||||
set(WebP_INCLUDE_DIRS "webp")
|
||||
set(WEBP_INCLUDE_DIRS ${WebP_INCLUDE_DIRS})
|
||||
set(WebP_LIBRARIES "@INSTALLED_LIBRARIES@")
|
||||
set(WEBP_LIBRARIES "${WebP_LIBRARIES}")
|
@ -1,44 +1,48 @@
|
||||
# Generate the config.h to compile with specific intrinsics / libs.
|
||||
|
||||
# Check for compiler options.
|
||||
## Check for compiler options.
|
||||
include(CheckCSourceCompiles)
|
||||
check_c_source_compiles("
|
||||
int main(void) {
|
||||
(void)__builtin_bswap16(0);
|
||||
return 0;
|
||||
}
|
||||
" HAVE_BUILTIN_BSWAP16)
|
||||
"
|
||||
HAVE_BUILTIN_BSWAP16
|
||||
)
|
||||
check_c_source_compiles("
|
||||
int main(void) {
|
||||
(void)__builtin_bswap32(0);
|
||||
return 0;
|
||||
}
|
||||
" HAVE_BUILTIN_BSWAP32)
|
||||
"
|
||||
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(NOT WEBP_BUILD_WEBP_JS)
|
||||
# Disable pThreads for WASM.
|
||||
find_package(Threads)
|
||||
endif()
|
||||
## Check for libraries.
|
||||
find_package(Threads)
|
||||
if(Threads_FOUND)
|
||||
# work around cmake bug on QNX (https://cmake.org/Bug/view.php?id=11333)
|
||||
if(CMAKE_USE_PTHREADS_INIT AND NOT CMAKE_SYSTEM_NAME STREQUAL "QNX")
|
||||
if(CMAKE_USE_PTHREADS_INIT)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pthread")
|
||||
endif()
|
||||
check_c_source_compiles("
|
||||
#include <pthread.h>
|
||||
int main (void) {
|
||||
int attr = PTHREAD_PRIO_INHERIT;
|
||||
return attr;
|
||||
}
|
||||
" FLAG_HAVE_PTHREAD_PRIO_INHERIT)
|
||||
set(HAVE_PTHREAD_PRIO_INHERIT ${FLAG_HAVE_PTHREAD_PRIO_INHERIT})
|
||||
foreach(PTHREAD_TEST HAVE_PTHREAD_PRIO_INHERIT PTHREAD_CREATE_UNDETACHED)
|
||||
check_c_source_compiles("
|
||||
#include <pthread.h>
|
||||
int main (void) {
|
||||
int attr = ${PTHREAD_TEST};
|
||||
return attr;
|
||||
}
|
||||
" ${PTHREAD_TEST}
|
||||
)
|
||||
endforeach()
|
||||
list(APPEND WEBP_DEP_LIBRARIES ${CMAKE_THREAD_LIBS_INIT})
|
||||
endif()
|
||||
set(WEBP_USE_THREAD ${Threads_FOUND})
|
||||
@ -47,69 +51,30 @@ set(WEBP_USE_THREAD ${Threads_FOUND})
|
||||
set(LT_OBJDIR ".libs/")
|
||||
|
||||
# Only useful for vwebp, so useless for now.
|
||||
find_package(OpenGL)
|
||||
set(WEBP_HAVE_GL ${OPENGL_FOUND})
|
||||
# find_package(OpenGL)
|
||||
# set(WEBP_HAVE_GL ${OPENGL_FOUND})
|
||||
# set(WEBP_DEP_INCLUDE_DIRS ${WEBP_DEP_INCLUDE_DIRS} ${OPENGL_INCLUDE_DIRS})
|
||||
# set(WEBP_DEP_LIBRARIES ${WEBP_DEP_LIBRARIES} ${OPENGL_LIBRARIES})
|
||||
|
||||
# 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("
|
||||
#include <math.h>
|
||||
int main(int argc, char** argv) {
|
||||
return (int)pow(argc, 2.5);
|
||||
}
|
||||
" HAVE_MATH_LIBRARY)
|
||||
if(NOT HAVE_MATH_LIBRARY)
|
||||
message(STATUS "Adding -lm flag.")
|
||||
list(APPEND WEBP_DEP_LIBRARIES m)
|
||||
# Find the standard C math library.
|
||||
find_library(MATH_LIBRARY NAMES m)
|
||||
if(MATH_LIBRARY)
|
||||
list(APPEND WEBP_DEP_LIBRARIES ${MATH_LIBRARY})
|
||||
endif()
|
||||
|
||||
# Find the standard image libraries.
|
||||
set(WEBP_DEP_IMG_LIBRARIES)
|
||||
set(WEBP_DEP_IMG_INCLUDE_DIRS)
|
||||
foreach(I_LIB PNG JPEG TIFF)
|
||||
foreach(I_LIB PNG JPEG TIFF GIF)
|
||||
find_package(${I_LIB})
|
||||
set(WEBP_HAVE_${I_LIB} ${${I_LIB}_FOUND})
|
||||
if(${I_LIB}_FOUND)
|
||||
list(APPEND WEBP_DEP_IMG_LIBRARIES ${${I_LIB}_LIBRARIES})
|
||||
list(APPEND WEBP_DEP_IMG_INCLUDE_DIRS ${${I_LIB}_INCLUDE_DIR}
|
||||
${${I_LIB}_INCLUDE_DIRS})
|
||||
list(APPEND WEBP_DEP_IMG_INCLUDE_DIRS ${${I_LIB}_INCLUDE_DIRS})
|
||||
endif()
|
||||
endforeach()
|
||||
if(WEBP_DEP_IMG_INCLUDE_DIRS)
|
||||
list(REMOVE_DUPLICATES WEBP_DEP_IMG_INCLUDE_DIRS)
|
||||
endif()
|
||||
|
||||
# GIF detection, gifdec isn't part of the imageio lib.
|
||||
include(CMakePushCheckState)
|
||||
set(WEBP_DEP_GIF_LIBRARIES)
|
||||
set(WEBP_DEP_GIF_INCLUDE_DIRS)
|
||||
find_package(GIF)
|
||||
set(WEBP_HAVE_GIF ${GIF_FOUND})
|
||||
if(GIF_FOUND)
|
||||
# GIF find_package only locates the header and library, it doesn't fail
|
||||
# compile tests when detecting the version, but falls back to 3 (as of at
|
||||
# least cmake 3.7.2). Make sure the library links to avoid incorrect detection
|
||||
# when cross compiling.
|
||||
cmake_push_check_state()
|
||||
set(CMAKE_REQUIRED_LIBRARIES ${GIF_LIBRARIES})
|
||||
set(CMAKE_REQUIRED_INCLUDES ${GIF_INCLUDE_DIR})
|
||||
check_c_source_compiles("
|
||||
#include <gif_lib.h>
|
||||
int main(void) {
|
||||
(void)DGifOpenFileHandle;
|
||||
return 0;
|
||||
}
|
||||
" GIF_COMPILES)
|
||||
cmake_pop_check_state()
|
||||
if(GIF_COMPILES)
|
||||
list(APPEND WEBP_DEP_GIF_LIBRARIES ${GIF_LIBRARIES})
|
||||
list(APPEND WEBP_DEP_GIF_INCLUDE_DIRS ${GIF_INCLUDE_DIR})
|
||||
else()
|
||||
unset(GIF_FOUND)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Check for specific headers.
|
||||
## Check for specific headers.
|
||||
include(CheckIncludeFiles)
|
||||
check_include_files("stdlib.h;stdarg.h;string.h;float.h" STDC_HEADERS)
|
||||
check_include_files(dlfcn.h HAVE_DLFCN_H)
|
||||
@ -131,32 +96,25 @@ 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.
|
||||
## Check for SIMD extensions.
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/cpu.cmake)
|
||||
|
||||
# Define extra info.
|
||||
## Define extra info.
|
||||
set(PACKAGE ${PROJECT_NAME})
|
||||
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
|
||||
${CONFIGURE_AC})
|
||||
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()
|
||||
|
||||
@ -171,3 +129,13 @@ strip_bracket(PACKAGE_URL)
|
||||
set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}")
|
||||
set(PACKAGE_TARNAME ${PACKAGE_NAME})
|
||||
set(VERSION ${PACKAGE_VERSION})
|
||||
|
||||
## Generate the config.h header.
|
||||
configure_file(${CMAKE_CURRENT_LIST_DIR}/config.h.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/include/webp/config.h)
|
||||
add_definitions(-DHAVE_CONFIG_H)
|
||||
# The webp folder is included as we reference config.h as
|
||||
# ../webp/config.h or webp/config.h
|
||||
include_directories(${CMAKE_CURRENT_BINARY_DIR}/include
|
||||
${CMAKE_CURRENT_BINARY_DIR}/include/webp
|
||||
)
|
@ -13,9 +13,6 @@
|
||||
/* Set to 1 if __builtin_bswap64 is available */
|
||||
#cmakedefine HAVE_BUILTIN_BSWAP64 1
|
||||
|
||||
/* Define to 1 if you have the <cpu-features.h> header file. */
|
||||
#cmakedefine HAVE_CPU_FEATURES_H 1
|
||||
|
||||
/* Define to 1 if you have the <dlfcn.h> header file. */
|
||||
#cmakedefine HAVE_DLFCN_H 1
|
||||
|
||||
@ -93,12 +90,22 @@
|
||||
/* Define to the version of this package. */
|
||||
#cmakedefine PACKAGE_VERSION "@PACKAGE_VERSION@"
|
||||
|
||||
/* Define to necessary symbol if this constant uses a non-standard name on
|
||||
your system. */
|
||||
#cmakedefine PTHREAD_CREATE_JOINABLE 1
|
||||
|
||||
/* Define to 1 if you have the ANSI C header files. */
|
||||
#cmakedefine STDC_HEADERS 1
|
||||
|
||||
/* Version number of package */
|
||||
#cmakedefine VERSION "@VERSION@"
|
||||
|
||||
/* Enable experimental code */
|
||||
#cmakedefine WEBP_EXPERIMENTAL_FEATURES 1
|
||||
|
||||
/* Set to 1 if AVX2 is supported */
|
||||
#cmakedefine WEBP_HAVE_AVX2 1
|
||||
|
||||
/* Set to 1 if GIF library is installed */
|
||||
#cmakedefine WEBP_HAVE_GIF 1
|
||||
|
||||
@ -108,19 +115,9 @@
|
||||
/* Set to 1 if JPEG library is installed */
|
||||
#cmakedefine WEBP_HAVE_JPEG 1
|
||||
|
||||
/* Set to 1 if NEON is supported */
|
||||
#cmakedefine WEBP_HAVE_NEON
|
||||
|
||||
/* Set to 1 if runtime detection of NEON is enabled */
|
||||
/* TODO: handle properly in CMake */
|
||||
#cmakedefine WEBP_HAVE_NEON_RTCD
|
||||
|
||||
/* Set to 1 if PNG library is installed */
|
||||
#cmakedefine WEBP_HAVE_PNG 1
|
||||
|
||||
/* Set to 1 if SDL library is installed */
|
||||
#cmakedefine WEBP_HAVE_SDL 1
|
||||
|
||||
/* Set to 1 if SSE2 is supported */
|
||||
#cmakedefine WEBP_HAVE_SSE2 1
|
||||
|
||||
@ -130,9 +127,6 @@
|
||||
/* Set to 1 if TIFF library is installed */
|
||||
#cmakedefine WEBP_HAVE_TIFF 1
|
||||
|
||||
/* Enable near lossless encoding */
|
||||
#cmakedefine WEBP_NEAR_LOSSLESS 1
|
||||
|
||||
/* Undefine this to disable thread support. */
|
||||
#cmakedefine WEBP_USE_THREAD 1
|
||||
|
||||
|
@ -1,15 +1,7 @@
|
||||
# Check for SIMD extensions.
|
||||
include(CMakePushCheckState)
|
||||
## Check for SIMD extensions.
|
||||
|
||||
function(webp_check_compiler_flag WEBP_SIMD_FLAG ENABLE_SIMD)
|
||||
if(NOT ENABLE_SIMD)
|
||||
message(STATUS "Disabling ${WEBP_SIMD_FLAG} optimization.")
|
||||
set(WEBP_HAVE_${WEBP_SIMD_FLAG} 0 PARENT_SCOPE)
|
||||
return()
|
||||
endif()
|
||||
function(webp_check_compiler_flag WEBP_SIMD_FLAG)
|
||||
unset(WEBP_HAVE_FLAG_${WEBP_SIMD_FLAG} CACHE)
|
||||
cmake_push_check_state()
|
||||
set(CMAKE_REQUIRED_INCLUDES ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
check_c_source_compiles("
|
||||
#include \"${CMAKE_CURRENT_LIST_DIR}/../src/dsp/dsp.h\"
|
||||
int main(void) {
|
||||
@ -18,8 +10,8 @@ function(webp_check_compiler_flag WEBP_SIMD_FLAG ENABLE_SIMD)
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
" WEBP_HAVE_FLAG_${WEBP_SIMD_FLAG})
|
||||
cmake_pop_check_state()
|
||||
" WEBP_HAVE_FLAG_${WEBP_SIMD_FLAG}
|
||||
)
|
||||
if(WEBP_HAVE_FLAG_${WEBP_SIMD_FLAG})
|
||||
set(WEBP_HAVE_${WEBP_SIMD_FLAG} 1 PARENT_SCOPE)
|
||||
else()
|
||||
@ -28,26 +20,16 @@ function(webp_check_compiler_flag WEBP_SIMD_FLAG ENABLE_SIMD)
|
||||
endfunction()
|
||||
|
||||
# those are included in the names of WEBP_USE_* in c++ code.
|
||||
set(WEBP_SIMD_FLAGS "SSE41;SSE2;MIPS32;MIPS_DSP_R2;NEON;MSA")
|
||||
set(WEBP_SIMD_FILE_EXTENSIONS
|
||||
"_sse41.c;_sse2.c;_mips32.c;_mips_dsp_r2.c;_neon.c;_msa.c")
|
||||
if(MSVC AND CMAKE_C_COMPILER_ID STREQUAL "MSVC")
|
||||
# With at least Visual Studio 12 (2013)+ /arch is not necessary to build SSE2
|
||||
# or SSE4 code unless a lesser /arch is forced. MSVC does not have a SSE4
|
||||
# flag, but an AVX one. Using that with SSE4 code risks generating illegal
|
||||
# instructions when used on machines with SSE4 only. The flags are left for
|
||||
# older (untested) versions to avoid any potential compatibility issues.
|
||||
if(MSVC_VERSION GREATER_EQUAL 1800 AND NOT CMAKE_C_FLAGS MATCHES "/arch:")
|
||||
set(SIMD_ENABLE_FLAGS)
|
||||
else()
|
||||
set(SIMD_ENABLE_FLAGS "/arch:AVX;/arch:SSE2;;;;")
|
||||
endif()
|
||||
set(WEBP_SIMD_FLAGS "SSE2;SSE41;AVX2;MIPS32;MIPS_DSP_R2;NEON;MSA")
|
||||
set(WEBP_SIMD_FILE_EXTENSIONS "_sse2.c;_sse41.c;_avx2.c;_mips32.c;_mips_dsp_r2.c;_neon.c;_msa.c")
|
||||
if(MSVC)
|
||||
# MSVC does not have a SSE4 flag but AVX2 support implies
|
||||
# SSE4 support.
|
||||
set(SIMD_ENABLE_FLAGS "/arch:SSE2;/arch:AVX2;/arch:AVX2;;;;")
|
||||
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 "-msse2;-msse4.1;-mavx2;-mips32;-mdspr2;-mfpu=neon;-mmsa")
|
||||
set(SIMD_DISABLE_FLAGS "-mno-sse2;-mno-sse4.1;-mno-avx2;;-mno-dspr2;;-mno-msa")
|
||||
endif()
|
||||
|
||||
set(WEBP_SIMD_FILES_TO_NOT_INCLUDE)
|
||||
@ -56,9 +38,10 @@ set(WEBP_SIMD_FLAGS_TO_INCLUDE)
|
||||
|
||||
if(${ANDROID})
|
||||
if(${ANDROID_ABI} STREQUAL "armeabi-v7a")
|
||||
# This is because Android studio uses the configuration "-march=armv7-a
|
||||
# -mfloat-abi=softfp -mfpu=vfpv3-d16" that does not trigger neon
|
||||
# optimizations but should (as this configuration does not exist anymore).
|
||||
# This is because Android studio uses the configuration
|
||||
# "-march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16"
|
||||
# that does not trigger neon optimizations but should
|
||||
# (as this configuration does not exist anymore).
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mfpu=neon ")
|
||||
endif()
|
||||
endif()
|
||||
@ -67,40 +50,25 @@ 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.
|
||||
if(EMSCRIPTEN AND ${I_SIMD} GREATER_EQUAL 2)
|
||||
break()
|
||||
endif()
|
||||
|
||||
list(GET WEBP_SIMD_FLAGS ${I_SIMD} WEBP_SIMD_FLAG)
|
||||
|
||||
# First try with no extra flag added as the compiler might have default flags
|
||||
# (especially on Android).
|
||||
unset(WEBP_HAVE_${WEBP_SIMD_FLAG} CACHE)
|
||||
cmake_push_check_state()
|
||||
set(CMAKE_REQUIRED_FLAGS)
|
||||
webp_check_compiler_flag(${WEBP_SIMD_FLAG} ${WEBP_ENABLE_SIMD})
|
||||
webp_check_compiler_flag(${WEBP_SIMD_FLAG})
|
||||
if(NOT WEBP_HAVE_${WEBP_SIMD_FLAG})
|
||||
list(GET SIMD_ENABLE_FLAGS ${I_SIMD} SIMD_COMPILE_FLAG)
|
||||
if(EMSCRIPTEN)
|
||||
set(SIMD_COMPILE_FLAG "-msimd128 ${SIMD_COMPILE_FLAG}")
|
||||
endif()
|
||||
set(CMAKE_REQUIRED_FLAGS ${SIMD_COMPILE_FLAG})
|
||||
webp_check_compiler_flag(${WEBP_SIMD_FLAG} ${WEBP_ENABLE_SIMD})
|
||||
webp_check_compiler_flag(${WEBP_SIMD_FLAG})
|
||||
else()
|
||||
if(MSVC AND SIMD_ENABLE_FLAGS)
|
||||
# The detection for SSE2/SSE4 support under MSVC is based on the compiler
|
||||
# version so e.g., clang-cl will require flags to enable the assembly.
|
||||
list(GET SIMD_ENABLE_FLAGS ${I_SIMD} SIMD_COMPILE_FLAG)
|
||||
else()
|
||||
set(SIMD_COMPILE_FLAG " ")
|
||||
endif()
|
||||
set(SIMD_COMPILE_FLAG " ")
|
||||
endif()
|
||||
# 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})
|
||||
@ -128,12 +96,11 @@ foreach(I_SIMD RANGE ${WEBP_SIMD_FLAGS_RANGE})
|
||||
set(COMMON_PATTERNS)
|
||||
endif()
|
||||
set(CMAKE_REQUIRED_DEFINITIONS ${SIMD_COMPILE_FLAG})
|
||||
check_c_source_compiles("int main(void) {return 0;}"
|
||||
FLAG_${SIMD_COMPILE_FLAG}
|
||||
FAIL_REGEX
|
||||
"warning: argument unused during compilation:"
|
||||
${COMMON_PATTERNS})
|
||||
if(NOT FLAG_${SIMD_COMPILE_FLAG})
|
||||
check_c_source_compiles("int main(void) {return 0;}" FLAG2
|
||||
FAIL_REGEX "warning: argument unused during compilation:"
|
||||
${COMMON_PATTERNS}
|
||||
)
|
||||
if(NOT FLAG2)
|
||||
unset(HAS_COMPILE_FLAG CACHE)
|
||||
endif()
|
||||
endif()
|
||||
@ -143,5 +110,4 @@ foreach(I_SIMD RANGE ${WEBP_SIMD_FLAGS_RANGE})
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
cmake_pop_check_state()
|
||||
endforeach()
|
||||
|
@ -1,4 +0,0 @@
|
||||
# This file is used by git cl to get repository specific information.
|
||||
GERRIT_HOST: True
|
||||
CODE_REVIEW_SERVER: chromium-review.googlesource.com
|
||||
GERRIT_SQUASH_UPLOADS: False
|
161
configure.ac
161
configure.ac
@ -1,4 +1,4 @@
|
||||
AC_INIT([libwebp], [1.2.0],
|
||||
AC_INIT([libwebp], [0.6.0],
|
||||
[https://bugs.chromium.org/p/webp],,
|
||||
[http://developers.google.com/speed/webp])
|
||||
AC_CANONICAL_HOST
|
||||
@ -67,7 +67,6 @@ AC_DEFUN([TEST_AND_ADD_CFLAGS],
|
||||
CFLAGS="$SAVED_CFLAGS"])
|
||||
TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-fvisibility=hidden])
|
||||
TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wall])
|
||||
TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wconstant-conversion])
|
||||
TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wdeclaration-after-statement])
|
||||
TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wextra])
|
||||
TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wfloat-conversion])
|
||||
@ -76,11 +75,8 @@ TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wformat -Wformat-security])
|
||||
TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wmissing-declarations])
|
||||
TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wmissing-prototypes])
|
||||
TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wold-style-definition])
|
||||
TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wparentheses-equality])
|
||||
TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wshadow])
|
||||
TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wshorten-64-to-32])
|
||||
TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wundef])
|
||||
TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wunreachable-code-aggressive])
|
||||
TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wunreachable-code])
|
||||
TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wunused-but-set-variable])
|
||||
TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wunused])
|
||||
@ -123,6 +119,31 @@ AS_IF([test "$GCC" = "yes" ], [
|
||||
AC_SUBST([AM_CFLAGS])
|
||||
|
||||
dnl === Check for machine specific flags
|
||||
AC_ARG_ENABLE([avx2],
|
||||
AS_HELP_STRING([--disable-avx2],
|
||||
[Disable detection of AVX2 support
|
||||
@<:@default=auto@:>@]))
|
||||
|
||||
AS_IF([test "x$enable_avx2" != "xno" -a "x$enable_sse4_1" != "xno" \
|
||||
-a "x$enable_sse2" != "xno"], [
|
||||
AVX2_CFLAGS="$INTRINSICS_CFLAGS $AVX2_FLAGS"
|
||||
TEST_AND_ADD_CFLAGS([AVX2_FLAGS], [-mavx2])
|
||||
AS_IF([test -n "$AVX2_FLAGS"], [
|
||||
SAVED_CFLAGS=$CFLAGS
|
||||
CFLAGS="$CFLAGS $AVX2_FLAGS"
|
||||
AC_CHECK_HEADER([immintrin.h],
|
||||
[AC_DEFINE(WEBP_HAVE_AVX2, [1],
|
||||
[Set to 1 if AVX2 is supported])],
|
||||
[AVX2_FLAGS=""],
|
||||
dnl it's illegal to directly include avx2intrin.h, but it's
|
||||
dnl included conditionally in immintrin.h, tricky!
|
||||
[#ifndef __AVX2__
|
||||
#error avx2 is not enabled
|
||||
#endif
|
||||
])
|
||||
CFLAGS=$SAVED_CFLAGS])
|
||||
AC_SUBST([AVX2_FLAGS])])
|
||||
|
||||
AC_ARG_ENABLE([sse4.1],
|
||||
AS_HELP_STRING([--disable-sse4.1],
|
||||
[Disable detection of SSE4.1 support
|
||||
@ -220,13 +241,9 @@ AS_IF([test "x$enable_neon" != "xno"], [
|
||||
NEON_FLAGS=""],
|
||||
[AC_DEFINE(WEBP_HAVE_NEON_RTCD, [1],
|
||||
[Set to 1 if runtime detection of NEON is enabled])])])
|
||||
|
||||
case "$host_os" in
|
||||
*android*) AC_CHECK_HEADERS([cpu-features.h]) ;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
AC_SUBST([NEON_FLAGS])])
|
||||
;;
|
||||
esac
|
||||
AC_SUBST([NEON_FLAGS])])
|
||||
|
||||
dnl === CLEAR_LIBVARS([var_pfx])
|
||||
dnl === Clears <var_pfx>_{INCLUDES,LIBS}.
|
||||
@ -323,8 +340,6 @@ AS_IF([test "x$enable_gl" != "xno"], [
|
||||
# override with --with-gl*
|
||||
glut_cflags="$glut_cflags|-framework GLUT -framework OpenGL"
|
||||
glut_ldflags="$glut_ldflags|-framework GLUT -framework OpenGL"
|
||||
# quiet deprecation warnings for glut
|
||||
TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wno-deprecated-declarations])
|
||||
;;
|
||||
esac
|
||||
|
||||
@ -413,67 +428,6 @@ AS_IF([test "x$enable_gl" != "xno"], [
|
||||
])
|
||||
AM_CONDITIONAL([BUILD_VWEBP], [test "$build_vwebp" = "yes"])
|
||||
|
||||
dnl === check for SDL support ===
|
||||
|
||||
AC_ARG_ENABLE([sdl],
|
||||
AS_HELP_STRING([--disable-sdl],
|
||||
[Disable detection of SDL support
|
||||
@<:@default=auto@:>@]))
|
||||
AS_IF([test "x$enable_sdl" != "xno"], [
|
||||
CLEAR_LIBVARS([SDL])
|
||||
AC_PATH_PROGS([LIBSDL_CONFIG], [sdl-config])
|
||||
if test -n "$LIBSDL_CONFIG"; then
|
||||
SDL_INCLUDES=`$LIBSDL_CONFIG --cflags`
|
||||
SDL_LIBS="`$LIBSDL_CONFIG --libs`"
|
||||
fi
|
||||
|
||||
WITHLIB_OPTION([sdl], [SDL])
|
||||
|
||||
sdl_header="no"
|
||||
LIBCHECK_PROLOGUE([SDL])
|
||||
AC_CHECK_HEADER([SDL/SDL.h], [sdl_header="SDL/SDL.h"],
|
||||
[AC_CHECK_HEADER([SDL.h], [sdl_header="SDL.h"],
|
||||
[AC_MSG_WARN(SDL library not available - no sdl.h)])])
|
||||
if test x"$sdl_header" != "xno"; then
|
||||
AC_LANG_PUSH(C)
|
||||
SDL_SAVED_LIBS="$LIBS"
|
||||
for lib in "" "-lSDL" "-lSDLmain -lSDL"; do
|
||||
LIBS="$SDL_SAVED_LIBS $lib"
|
||||
# Perform a full link to ensure SDL_main is resolved if needed.
|
||||
AC_LINK_IFELSE(
|
||||
[AC_LANG_SOURCE([
|
||||
#include <$sdl_header>
|
||||
int main(int argc, char** argv) {
|
||||
SDL_Init(0);
|
||||
return 0;
|
||||
}])],
|
||||
[SDL_LIBS="$LDFLAGS $LIBS"
|
||||
SDL_INCLUDES="$SDL_INCLUDES -DWEBP_HAVE_SDL"
|
||||
AC_DEFINE(WEBP_HAVE_SDL, [1],
|
||||
[Set to 1 if SDL library is installed])
|
||||
sdl_support=yes]
|
||||
)
|
||||
if test x"$sdl_support" = "xyes"; then
|
||||
break
|
||||
fi
|
||||
done
|
||||
# LIBS is restored by LIBCHECK_EPILOGUE
|
||||
AC_LANG_POP
|
||||
if test x"$sdl_header" = "xSDL.h"; then
|
||||
SDL_INCLUDES="$SDL_INCLUDES -DWEBP_HAVE_JUST_SDL_H"
|
||||
fi
|
||||
fi
|
||||
LIBCHECK_EPILOGUE([SDL])
|
||||
|
||||
if test x"$sdl_support" = "xyes"; then
|
||||
build_vwebp_sdl=yes
|
||||
else
|
||||
AC_MSG_WARN(Optional SDL library not found)
|
||||
fi
|
||||
])
|
||||
|
||||
AM_CONDITIONAL([BUILD_VWEBP_SDL], [test "$build_vwebp_sdl" = "yes"])
|
||||
|
||||
dnl === check for PNG support ===
|
||||
|
||||
AC_ARG_ENABLE([png], AS_HELP_STRING([--disable-png],
|
||||
@ -591,7 +545,7 @@ AS_IF([test "x$enable_gif" != "xno"], [
|
||||
|
||||
if test "$gif_support" = "yes" -a \
|
||||
"$enable_libwebpdemux" = "yes"; then
|
||||
build_anim_diff=yes
|
||||
build_animdiff=yes
|
||||
fi
|
||||
|
||||
if test "$gif_support" = "yes" -a \
|
||||
@ -599,19 +553,14 @@ AS_IF([test "x$enable_gif" != "xno"], [
|
||||
build_gif2webp=yes
|
||||
fi
|
||||
])
|
||||
AM_CONDITIONAL([BUILD_ANIMDIFF], [test "${build_anim_diff}" = "yes"])
|
||||
AM_CONDITIONAL([BUILD_ANIMDIFF], [test "${build_animdiff}" = "yes"])
|
||||
AM_CONDITIONAL([BUILD_GIF2WEBP], [test "${build_gif2webp}" = "yes"])
|
||||
|
||||
if test "$enable_libwebpdemux" = "yes" -a "$enable_libwebpmux" = "yes"; then
|
||||
if test "$enable_libwebpmux" = "yes"; then
|
||||
build_img2webp=yes
|
||||
fi
|
||||
AM_CONDITIONAL([BUILD_IMG2WEBP], [test "${build_img2webp}" = "yes"])
|
||||
|
||||
if test "$enable_libwebpmux" = "yes"; then
|
||||
build_webpinfo=yes
|
||||
fi
|
||||
AM_CONDITIONAL([BUILD_WEBPINFO], [test "${build_webpinfo}" = "yes"])
|
||||
|
||||
dnl === check for WIC support ===
|
||||
|
||||
AC_ARG_ENABLE([wic],
|
||||
@ -664,7 +613,7 @@ if test "$enable_wic" = "yes"; then
|
||||
fi
|
||||
esac
|
||||
|
||||
dnl === If --enable-swap-16bit-csp is defined, add -DWEBP_SWAP_16BIT_CSP=1
|
||||
dnl === If --enable-swap-16bit-csp is defined, add -DWEBP_SWAP_16BIT_CSP
|
||||
|
||||
USE_SWAP_16BIT_CSP=""
|
||||
AC_MSG_CHECKING(if --enable-swap-16bit-csp option is specified)
|
||||
@ -672,25 +621,23 @@ AC_ARG_ENABLE([swap-16bit-csp],
|
||||
AS_HELP_STRING([--enable-swap-16bit-csp],
|
||||
[Enable byte swap for 16 bit colorspaces]))
|
||||
if test "$enable_swap_16bit_csp" = "yes"; then
|
||||
USE_SWAP_16BIT_CSP="-DWEBP_SWAP_16BIT_CSP=1"
|
||||
USE_SWAP_16BIT_CSP="-DWEBP_SWAP_16BIT_CSP"
|
||||
fi
|
||||
AC_MSG_RESULT(${enable_swap_16bit_csp-no})
|
||||
AC_SUBST(USE_SWAP_16BIT_CSP)
|
||||
|
||||
dnl === If --disable-near-lossless is defined, add -DWEBP_NEAR_LOSSLESS=0
|
||||
dnl === If --enable-experimental is defined, add -DWEBP_EXPERIMENTAL_FEATURES
|
||||
|
||||
AC_DEFINE(WEBP_NEAR_LOSSLESS, [1], [Enable near lossless encoding])
|
||||
AC_MSG_CHECKING(if --disable-near-lossless option is specified)
|
||||
AC_ARG_ENABLE([near_lossless],
|
||||
AS_HELP_STRING([--disable-near-lossless],
|
||||
[Disable near lossless encoding]),
|
||||
[], [enable_near_lossless=yes])
|
||||
if test "$enable_near_lossless" = "no"; then
|
||||
AC_DEFINE(WEBP_NEAR_LOSSLESS, [0], [Enable near lossless encoding])
|
||||
AC_MSG_RESULT([yes])
|
||||
else
|
||||
AC_MSG_RESULT([no])
|
||||
USE_EXPERIMENTAL_CODE=""
|
||||
AC_MSG_CHECKING(if --enable-experimental option is specified)
|
||||
AC_ARG_ENABLE([experimental], AS_HELP_STRING([--enable-experimental],
|
||||
[Activate experimental features]))
|
||||
if test "$enable_experimental" = "yes"; then
|
||||
AC_DEFINE(WEBP_EXPERIMENTAL_FEATURES, [1], [Enable experimental code])
|
||||
USE_EXPERIMENTAL_CODE="-DWEBP_EXPERIMENTAL_FEATURES"
|
||||
fi
|
||||
AC_MSG_RESULT(${enable_experimental-no})
|
||||
AC_SUBST(USE_EXPERIMENTAL_CODE)
|
||||
|
||||
dnl === Check whether libwebpmux should be built
|
||||
AC_MSG_CHECKING(whether libwebpmux is to be built)
|
||||
@ -698,16 +645,15 @@ AC_ARG_ENABLE([libwebpmux],
|
||||
AS_HELP_STRING([--enable-libwebpmux],
|
||||
[Build libwebpmux @<:@default=no@:>@]))
|
||||
AC_MSG_RESULT(${enable_libwebpmux-no})
|
||||
AM_CONDITIONAL([BUILD_MUX], [test "$enable_libwebpmux" = "yes"])
|
||||
AM_CONDITIONAL([WANT_MUX], [test "$enable_libwebpmux" = "yes"])
|
||||
|
||||
dnl === Check whether libwebpdemux should be built
|
||||
AC_MSG_CHECKING(whether libwebpdemux is to be built)
|
||||
AC_ARG_ENABLE([libwebpdemux],
|
||||
AS_HELP_STRING([--disable-libwebpdemux],
|
||||
[Disable libwebpdemux @<:@default=no@:>@]),
|
||||
[], [enable_libwebpdemux=yes])
|
||||
AS_HELP_STRING([--enable-libwebpdemux],
|
||||
[Build libwebpdemux @<:@default=no@:>@]))
|
||||
AC_MSG_RESULT(${enable_libwebpdemux-no})
|
||||
AM_CONDITIONAL([BUILD_DEMUX], [test "$enable_libwebpdemux" = "yes"])
|
||||
AM_CONDITIONAL([WANT_DEMUX], [test "$enable_libwebpdemux" = "yes"])
|
||||
|
||||
dnl === Check whether decoder library should be built.
|
||||
AC_MSG_CHECKING(whether decoder library is to be built)
|
||||
@ -723,7 +669,7 @@ AC_ARG_ENABLE([libwebpextras],
|
||||
AS_HELP_STRING([--enable-libwebpextras],
|
||||
[Build libwebpextras @<:@default=no@:>@]))
|
||||
AC_MSG_RESULT(${enable_libwebpextras-no})
|
||||
AM_CONDITIONAL([BUILD_EXTRAS], [test "$enable_libwebpextras" = "yes"])
|
||||
AM_CONDITIONAL([WANT_EXTRAS], [test "$enable_libwebpextras" = "yes"])
|
||||
|
||||
dnl =========================
|
||||
|
||||
@ -754,25 +700,22 @@ libwebpmux: ${enable_libwebpmux-no}
|
||||
libwebpextras: ${enable_libwebpextras-no}
|
||||
|
||||
Tools:
|
||||
cwebp : ${enable_libwebpdemux-no}
|
||||
cwebp : yes
|
||||
Input format support
|
||||
====================
|
||||
JPEG : ${jpeg_support-no}
|
||||
PNG : ${png_support-no}
|
||||
TIFF : ${tiff_support-no}
|
||||
WIC : ${wic_support-no}
|
||||
dwebp : ${enable_libwebpdemux-no}
|
||||
dwebp : yes
|
||||
Output format support
|
||||
=====================
|
||||
PNG : ${png_support-no}
|
||||
WIC : ${wic_support-no}
|
||||
GIF support : ${gif_support-no}
|
||||
anim_diff : ${build_anim_diff-no}
|
||||
anim_diff : ${build_animdiff-no}
|
||||
gif2webp : ${build_gif2webp-no}
|
||||
img2webp : ${build_img2webp-no}
|
||||
webpmux : ${enable_libwebpmux-no}
|
||||
vwebp : ${build_vwebp-no}
|
||||
webpinfo : ${build_webpinfo-no}
|
||||
SDL support : ${sdl_support-no}
|
||||
vwebp_sdl : ${build_vwebp_sdl-no}
|
||||
])
|
||||
|
@ -446,9 +446,8 @@ Frame Height Minus One: 24 bits (_uint24_)
|
||||
Frame Duration: 24 bits (_uint24_)
|
||||
|
||||
: The time to wait before displaying the next frame, in 1 millisecond units.
|
||||
Note the interpretation of frame duration of 0 (and often <= 10) is
|
||||
implementation defined. Many tools and browsers assign a minimum duration
|
||||
similar to GIF.
|
||||
In particular, frame duration of 0 is useful when one wants to update
|
||||
multiple areas of the canvas at once during the animation.
|
||||
|
||||
Reserved: 6 bits
|
||||
|
||||
|
@ -26,7 +26,8 @@ LOCAL_SRC_FILES := \
|
||||
cwebp.c \
|
||||
|
||||
LOCAL_CFLAGS := $(WEBP_CFLAGS)
|
||||
LOCAL_STATIC_LIBRARIES := example_util imageio_util imagedec webpdemux webp
|
||||
LOCAL_C_INCLUDES := $(LOCAL_PATH)/../src
|
||||
LOCAL_STATIC_LIBRARIES := example_util imageio_util imagedec webp
|
||||
|
||||
LOCAL_MODULE := cwebp
|
||||
|
||||
@ -41,7 +42,9 @@ LOCAL_SRC_FILES := \
|
||||
dwebp.c \
|
||||
|
||||
LOCAL_CFLAGS := $(WEBP_CFLAGS)
|
||||
LOCAL_STATIC_LIBRARIES := example_util imagedec imageenc webpdemux webp
|
||||
LOCAL_C_INCLUDES := $(LOCAL_PATH)/../src
|
||||
LOCAL_STATIC_LIBRARIES := example_util imagedec imageenc webp
|
||||
|
||||
LOCAL_MODULE := dwebp
|
||||
|
||||
include $(BUILD_EXECUTABLE)
|
||||
@ -55,6 +58,7 @@ LOCAL_SRC_FILES := \
|
||||
webpmux.c \
|
||||
|
||||
LOCAL_CFLAGS := $(WEBP_CFLAGS)
|
||||
LOCAL_C_INCLUDES := $(LOCAL_PATH)/../src
|
||||
LOCAL_STATIC_LIBRARIES := example_util imageio_util webpmux webp
|
||||
|
||||
LOCAL_MODULE := webpmux_example
|
||||
@ -70,24 +74,9 @@ LOCAL_SRC_FILES := \
|
||||
img2webp.c \
|
||||
|
||||
LOCAL_CFLAGS := $(WEBP_CFLAGS)
|
||||
LOCAL_STATIC_LIBRARIES := example_util imageio_util imagedec webpmux webpdemux \
|
||||
webp
|
||||
LOCAL_C_INCLUDES := $(LOCAL_PATH)/../src
|
||||
LOCAL_STATIC_LIBRARIES := example_util imageio_util imagedec webpmux webp
|
||||
|
||||
LOCAL_MODULE := img2webp_example
|
||||
|
||||
include $(BUILD_EXECUTABLE)
|
||||
|
||||
################################################################################
|
||||
# webpinfo
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_SRC_FILES := \
|
||||
webpinfo.c \
|
||||
|
||||
LOCAL_CFLAGS := $(WEBP_CFLAGS)
|
||||
LOCAL_STATIC_LIBRARIES := example_util imageio_util webp
|
||||
|
||||
LOCAL_MODULE := webpinfo_example
|
||||
|
||||
include $(BUILD_EXECUTABLE)
|
||||
|
@ -1,11 +1,8 @@
|
||||
AM_CPPFLAGS += -I$(top_builddir)/src -I$(top_srcdir)/src
|
||||
|
||||
bin_PROGRAMS =
|
||||
if BUILD_DEMUX
|
||||
bin_PROGRAMS += dwebp cwebp
|
||||
endif
|
||||
bin_PROGRAMS = dwebp cwebp
|
||||
if BUILD_ANIMDIFF
|
||||
noinst_PROGRAMS = anim_diff anim_dump
|
||||
noinst_PROGRAMS = anim_diff
|
||||
endif
|
||||
if BUILD_GIF2WEBP
|
||||
bin_PROGRAMS += gif2webp
|
||||
@ -13,53 +10,34 @@ endif
|
||||
if BUILD_IMG2WEBP
|
||||
bin_PROGRAMS += img2webp
|
||||
endif
|
||||
if BUILD_MUX
|
||||
if WANT_MUX
|
||||
bin_PROGRAMS += webpmux
|
||||
endif
|
||||
if BUILD_VWEBP
|
||||
bin_PROGRAMS += vwebp
|
||||
endif
|
||||
if BUILD_WEBPINFO
|
||||
bin_PROGRAMS += webpinfo
|
||||
endif
|
||||
|
||||
noinst_LTLIBRARIES = libexample_util.la
|
||||
|
||||
libexample_util_la_SOURCES = example_util.c example_util.h
|
||||
libexample_util_la_LIBADD = ../src/libwebp.la
|
||||
|
||||
anim_diff_SOURCES = anim_diff.c anim_util.c anim_util.h gifdec.c gifdec.h
|
||||
anim_diff_CPPFLAGS = $(AM_CPPFLAGS) $(GIF_INCLUDES)
|
||||
anim_diff_LDADD =
|
||||
anim_diff_LDADD += ../src/demux/libwebpdemux.la
|
||||
anim_diff_LDADD += libexample_util.la
|
||||
anim_diff_LDADD += ../imageio/libimageio_util.la
|
||||
anim_diff_SOURCES = anim_diff.c anim_util.c anim_util.h
|
||||
anim_diff_CPPFLAGS = $(AM_CPPFLAGS) $(USE_EXPERIMENTAL_CODE) $(GIF_INCLUDES)
|
||||
anim_diff_LDADD = ../src/demux/libwebpdemux.la
|
||||
anim_diff_LDADD += libexample_util.la ../imageio/libimageio_util.la
|
||||
anim_diff_LDADD += $(GIF_LIBS) -lm
|
||||
|
||||
anim_dump_SOURCES = anim_dump.c anim_util.c anim_util.h gifdec.c gifdec.h
|
||||
anim_dump_CPPFLAGS = $(AM_CPPFLAGS) $(PNG_INCLUDES)
|
||||
anim_dump_CPPFLAGS += $(GIF_INCLUDES)
|
||||
anim_dump_LDADD =
|
||||
anim_dump_LDADD += ../src/demux/libwebpdemux.la
|
||||
anim_dump_LDADD += libexample_util.la
|
||||
anim_dump_LDADD += ../imageio/libimageio_util.la
|
||||
anim_dump_LDADD += ../imageio/libimageenc.la
|
||||
anim_dump_LDADD += $(PNG_LIBS) $(GIF_LIBS) $(TIFF_LIBS) -lm
|
||||
|
||||
cwebp_SOURCES = cwebp.c stopwatch.h
|
||||
cwebp_CPPFLAGS = $(AM_CPPFLAGS)
|
||||
cwebp_LDADD =
|
||||
cwebp_LDADD += libexample_util.la
|
||||
cwebp_LDADD += ../imageio/libimageio_util.la
|
||||
cwebp_LDADD += ../imageio/libimagedec.la
|
||||
cwebp_LDADD += ../src/libwebp.la
|
||||
cwebp_CPPFLAGS = $(AM_CPPFLAGS) $(USE_EXPERIMENTAL_CODE)
|
||||
cwebp_LDADD = libexample_util.la ../imageio/libimageio_util.la
|
||||
cwebp_LDADD += ../imageio/libimagedec.la ../src/libwebp.la
|
||||
cwebp_LDADD += $(JPEG_LIBS) $(PNG_LIBS) $(TIFF_LIBS)
|
||||
|
||||
dwebp_SOURCES = dwebp.c stopwatch.h
|
||||
dwebp_CPPFLAGS = $(AM_CPPFLAGS)
|
||||
dwebp_CPPFLAGS = $(AM_CPPFLAGS) $(USE_EXPERIMENTAL_CODE)
|
||||
dwebp_CPPFLAGS += $(JPEG_INCLUDES) $(PNG_INCLUDES)
|
||||
dwebp_LDADD =
|
||||
dwebp_LDADD += libexample_util.la
|
||||
dwebp_LDADD = libexample_util.la
|
||||
dwebp_LDADD += ../imageio/libimagedec.la
|
||||
dwebp_LDADD += ../imageio/libimageenc.la
|
||||
dwebp_LDADD += ../imageio/libimageio_util.la
|
||||
@ -67,53 +45,31 @@ dwebp_LDADD += ../src/libwebp.la
|
||||
dwebp_LDADD +=$(PNG_LIBS) $(JPEG_LIBS)
|
||||
|
||||
gif2webp_SOURCES = gif2webp.c gifdec.c gifdec.h
|
||||
gif2webp_CPPFLAGS = $(AM_CPPFLAGS) $(GIF_INCLUDES)
|
||||
gif2webp_LDADD =
|
||||
gif2webp_LDADD += libexample_util.la
|
||||
gif2webp_LDADD += ../imageio/libimageio_util.la
|
||||
gif2webp_LDADD += ../src/mux/libwebpmux.la
|
||||
gif2webp_LDADD += ../src/libwebp.la
|
||||
gif2webp_LDADD += $(GIF_LIBS)
|
||||
gif2webp_CPPFLAGS = $(AM_CPPFLAGS) $(USE_EXPERIMENTAL_CODE) $(GIF_INCLUDES)
|
||||
gif2webp_LDADD = libexample_util.la ../imageio/libimageio_util.la
|
||||
gif2webp_LDADD += ../src/mux/libwebpmux.la ../src/libwebp.la $(GIF_LIBS)
|
||||
|
||||
vwebp_SOURCES = vwebp.c
|
||||
vwebp_CPPFLAGS = $(AM_CPPFLAGS) $(GL_INCLUDES)
|
||||
vwebp_LDADD =
|
||||
vwebp_LDADD += libexample_util.la
|
||||
vwebp_LDADD += ../imageio/libimageio_util.la
|
||||
vwebp_LDADD += ../src/demux/libwebpdemux.la
|
||||
vwebp_LDADD += $(GL_LIBS)
|
||||
vwebp_CPPFLAGS = $(AM_CPPFLAGS) $(USE_EXPERIMENTAL_CODE) $(GL_INCLUDES)
|
||||
vwebp_LDADD = libexample_util.la ../imageio/libimageio_util.la
|
||||
vwebp_LDADD += ../src/demux/libwebpdemux.la $(GL_LIBS)
|
||||
|
||||
webpmux_SOURCES = webpmux.c
|
||||
webpmux_CPPFLAGS = $(AM_CPPFLAGS)
|
||||
webpmux_LDADD =
|
||||
webpmux_LDADD += libexample_util.la
|
||||
webpmux_LDADD += ../imageio/libimageio_util.la
|
||||
webpmux_LDADD += ../src/mux/libwebpmux.la
|
||||
webpmux_LDADD += ../src/libwebp.la
|
||||
webpmux_CPPFLAGS = $(AM_CPPFLAGS) $(USE_EXPERIMENTAL_CODE)
|
||||
webpmux_LDADD = libexample_util.la ../imageio/libimageio_util.la
|
||||
webpmux_LDADD += ../src/mux/libwebpmux.la ../src/libwebp.la
|
||||
|
||||
img2webp_SOURCES = img2webp.c
|
||||
img2webp_CPPFLAGS = $(AM_CPPFLAGS)
|
||||
img2webp_LDADD =
|
||||
img2webp_LDADD += libexample_util.la
|
||||
img2webp_LDADD += ../imageio/libimageio_util.la
|
||||
img2webp_CPPFLAGS = $(AM_CPPFLAGS) $(USE_EXPERIMENTAL_CODE)
|
||||
img2webp_LDADD = libexample_util.la ../imageio/libimageio_util.la
|
||||
img2webp_LDADD += ../imageio/libimagedec.la
|
||||
img2webp_LDADD += ../src/mux/libwebpmux.la
|
||||
img2webp_LDADD += ../src/libwebp.la
|
||||
img2webp_LDADD += ../src/mux/libwebpmux.la ../src/libwebp.la
|
||||
img2webp_LDADD += $(PNG_LIBS) $(JPEG_LIBS) $(TIFF_LIBS)
|
||||
|
||||
webpinfo_SOURCES = webpinfo.c
|
||||
webpinfo_CPPFLAGS = $(AM_CPPFLAGS)
|
||||
webpinfo_LDADD =
|
||||
webpinfo_LDADD += libexample_util.la
|
||||
webpinfo_LDADD += ../imageio/libimageio_util.la
|
||||
webpinfo_LDADD += ../src/libwebp.la
|
||||
|
||||
if BUILD_LIBWEBPDECODER
|
||||
anim_diff_LDADD += ../src/libwebpdecoder.la
|
||||
anim_dump_LDADD += ../src/libwebpdecoder.la
|
||||
vwebp_LDADD += ../src/libwebpdecoder.la
|
||||
else
|
||||
anim_diff_LDADD += ../src/libwebp.la
|
||||
anim_dump_LDADD += ../src/libwebp.la
|
||||
vwebp_LDADD += ../src/libwebp.la
|
||||
endif
|
||||
|
@ -20,8 +20,6 @@
|
||||
#include <string.h> // for 'strcmp'.
|
||||
|
||||
#include "./anim_util.h"
|
||||
#include "./example_util.h"
|
||||
#include "./unicode.h"
|
||||
|
||||
#if defined(_MSC_VER) && _MSC_VER < 1900
|
||||
#define snprintf _snprintf
|
||||
@ -145,18 +143,8 @@ static int CompareAnimatedImagePair(const AnimatedImage* const img1,
|
||||
if (!ok) return 0; // These are fatal failures, can't proceed.
|
||||
|
||||
if (is_multi_frame_image) { // Checks relevant for multi-frame images only.
|
||||
int max_loop_count_workaround = 0;
|
||||
// Transcodes to webp increase the gif loop count by 1 for compatibility.
|
||||
// When the gif has the maximum value the webp value will be off by one.
|
||||
if ((img1->format == ANIM_GIF && img1->loop_count == 65536 &&
|
||||
img2->format == ANIM_WEBP && img2->loop_count == 65535) ||
|
||||
(img1->format == ANIM_WEBP && img1->loop_count == 65535 &&
|
||||
img2->format == ANIM_GIF && img2->loop_count == 65536)) {
|
||||
max_loop_count_workaround = 1;
|
||||
}
|
||||
ok = (max_loop_count_workaround ||
|
||||
CompareValues(img1->loop_count, img2->loop_count,
|
||||
"Loop count mismatch")) && ok;
|
||||
ok = CompareValues(img1->loop_count, img2->loop_count,
|
||||
"Loop count mismatch") && ok;
|
||||
ok = CompareBackgroundColor(img1->bgcolor, img2->bgcolor,
|
||||
premultiply) && ok;
|
||||
}
|
||||
@ -199,11 +187,11 @@ static void Help(void) {
|
||||
printf(" -min_psnr <float> ... minimum per-frame PSNR\n");
|
||||
printf(" -raw_comparison ..... if this flag is not used, RGB is\n");
|
||||
printf(" premultiplied before comparison\n");
|
||||
printf(" -max_diff <int> ..... maximum allowed difference per channel\n"
|
||||
" between corresponding pixels in subsequent\n"
|
||||
#ifdef WEBP_EXPERIMENTAL_FEATURES
|
||||
printf(" -max_diff <int> ..... maximum allowed difference per channel "
|
||||
" between corresponding pixels in subsequent"
|
||||
" frames\n");
|
||||
printf(" -h .................. this help\n");
|
||||
printf(" -version ............ print version number and exit\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
int main(int argc, const char* argv[]) {
|
||||
@ -219,49 +207,56 @@ int main(int argc, const char* argv[]) {
|
||||
const char* files[2] = { NULL, NULL };
|
||||
AnimatedImage images[2];
|
||||
|
||||
INIT_WARGV(argc, argv);
|
||||
if (argc < 3) {
|
||||
Help();
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (c = 1; c < argc; ++c) {
|
||||
int parse_error = 0;
|
||||
if (!strcmp(argv[c], "-dump_frames")) {
|
||||
if (c < argc - 1) {
|
||||
dump_frames = 1;
|
||||
dump_folder = (const char*)GET_WARGV(argv, ++c);
|
||||
dump_folder = argv[++c];
|
||||
} else {
|
||||
parse_error = 1;
|
||||
}
|
||||
} else if (!strcmp(argv[c], "-min_psnr")) {
|
||||
if (c < argc - 1) {
|
||||
min_psnr = ExUtilGetFloat(argv[++c], &parse_error);
|
||||
const char* const v = argv[++c];
|
||||
char* end = NULL;
|
||||
const double d = strtod(v, &end);
|
||||
if (end == v) {
|
||||
parse_error = 1;
|
||||
fprintf(stderr, "Error! '%s' is not a floating point number.\n", v);
|
||||
}
|
||||
min_psnr = d;
|
||||
} else {
|
||||
parse_error = 1;
|
||||
}
|
||||
} else if (!strcmp(argv[c], "-raw_comparison")) {
|
||||
premultiply = 0;
|
||||
#ifdef WEBP_EXPERIMENTAL_FEATURES
|
||||
} else if (!strcmp(argv[c], "-max_diff")) {
|
||||
if (c < argc - 1) {
|
||||
max_diff = ExUtilGetInt(argv[++c], 0, &parse_error);
|
||||
const char* const v = argv[++c];
|
||||
char* end = NULL;
|
||||
const int n = (int)strtol(v, &end, 10);
|
||||
if (end == v) {
|
||||
parse_error = 1;
|
||||
fprintf(stderr, "Error! '%s' is not an integer.\n", v);
|
||||
}
|
||||
max_diff = n;
|
||||
} else {
|
||||
parse_error = 1;
|
||||
}
|
||||
} else if (!strcmp(argv[c], "-h") || !strcmp(argv[c], "-help")) {
|
||||
Help();
|
||||
FREE_WARGV_AND_RETURN(0);
|
||||
} else if (!strcmp(argv[c], "-version")) {
|
||||
int dec_version, demux_version;
|
||||
GetAnimatedImageVersions(&dec_version, &demux_version);
|
||||
printf("WebP Decoder version: %d.%d.%d\nWebP Demux version: %d.%d.%d\n",
|
||||
(dec_version >> 16) & 0xff, (dec_version >> 8) & 0xff,
|
||||
(dec_version >> 0) & 0xff,
|
||||
(demux_version >> 16) & 0xff, (demux_version >> 8) & 0xff,
|
||||
(demux_version >> 0) & 0xff);
|
||||
FREE_WARGV_AND_RETURN(0);
|
||||
#endif
|
||||
} else {
|
||||
if (!got_input1) {
|
||||
files[0] = (const char*)GET_WARGV(argv, c);
|
||||
files[0] = argv[c];
|
||||
got_input1 = 1;
|
||||
} else if (!got_input2) {
|
||||
files[1] = (const char*)GET_WARGV(argv, c);
|
||||
files[1] = argv[c];
|
||||
got_input2 = 1;
|
||||
} else {
|
||||
parse_error = 1;
|
||||
@ -269,30 +264,23 @@ int main(int argc, const char* argv[]) {
|
||||
}
|
||||
if (parse_error) {
|
||||
Help();
|
||||
FREE_WARGV_AND_RETURN(-1);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (argc < 3) {
|
||||
Help();
|
||||
FREE_WARGV_AND_RETURN(-1);
|
||||
}
|
||||
|
||||
|
||||
if (!got_input2) {
|
||||
Help();
|
||||
FREE_WARGV_AND_RETURN(-1);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (dump_frames) {
|
||||
WPRINTF("Dumping decoded frames in: %s\n", (const W_CHAR*)dump_folder);
|
||||
printf("Dumping decoded frames in: %s\n", dump_folder);
|
||||
}
|
||||
|
||||
memset(images, 0, sizeof(images));
|
||||
for (i = 0; i < 2; ++i) {
|
||||
WPRINTF("Decoding file: %s\n", (const W_CHAR*)files[i]);
|
||||
printf("Decoding file: %s\n", files[i]);
|
||||
if (!ReadAnimatedImage(files[i], &images[i], dump_frames, dump_folder)) {
|
||||
WFPRINTF(stderr, "Error decoding file: %s\n Aborting.\n",
|
||||
(const W_CHAR*)files[i]);
|
||||
fprintf(stderr, "Error decoding file: %s\n Aborting.\n", files[i]);
|
||||
return_code = -2;
|
||||
goto End;
|
||||
} else {
|
||||
@ -302,16 +290,14 @@ int main(int argc, const char* argv[]) {
|
||||
|
||||
if (!CompareAnimatedImagePair(&images[0], &images[1],
|
||||
premultiply, min_psnr)) {
|
||||
WFPRINTF(stderr, "\nFiles %s and %s differ.\n", (const W_CHAR*)files[0],
|
||||
(const W_CHAR*)files[1]);
|
||||
fprintf(stderr, "\nFiles %s and %s differ.\n", files[0], files[1]);
|
||||
return_code = -3;
|
||||
} else {
|
||||
WPRINTF("\nFiles %s and %s are identical.\n", (const W_CHAR*)files[0],
|
||||
(const W_CHAR*)files[1]);
|
||||
printf("\nFiles %s and %s are identical.\n", files[0], files[1]);
|
||||
return_code = 0;
|
||||
}
|
||||
End:
|
||||
ClearAnimatedImage(&images[0]);
|
||||
ClearAnimatedImage(&images[1]);
|
||||
FREE_WARGV_AND_RETURN(return_code);
|
||||
return return_code;
|
||||
}
|
||||
|
@ -1,121 +0,0 @@
|
||||
// Copyright 2017 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// Use of this source code is governed by a BSD-style license
|
||||
// that can be found in the COPYING file in the root of the source
|
||||
// tree. An additional intellectual property rights grant can be found
|
||||
// in the file PATENTS. All contributing project authors may
|
||||
// be found in the AUTHORS file in the root of the source tree.
|
||||
// -----------------------------------------------------------------------------
|
||||
//
|
||||
// Decodes an animated WebP file and dumps the decoded frames as PNG or TIFF.
|
||||
//
|
||||
// Author: Skal (pascal.massimino@gmail.com)
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h> // for 'strcmp'.
|
||||
|
||||
#include "./anim_util.h"
|
||||
#include "webp/decode.h"
|
||||
#include "../imageio/image_enc.h"
|
||||
#include "./unicode.h"
|
||||
|
||||
#if defined(_MSC_VER) && _MSC_VER < 1900
|
||||
#define snprintf _snprintf
|
||||
#endif
|
||||
|
||||
static void Help(void) {
|
||||
printf("Usage: anim_dump [options] files...\n");
|
||||
printf("\nOptions:\n");
|
||||
printf(" -folder <string> .... dump folder (default: '.')\n");
|
||||
printf(" -prefix <string> .... prefix for dumped frames "
|
||||
"(default: 'dump_')\n");
|
||||
printf(" -tiff ............... save frames as TIFF\n");
|
||||
printf(" -pam ................ save frames as PAM\n");
|
||||
printf(" -h .................. this help\n");
|
||||
printf(" -version ............ print version number and exit\n");
|
||||
}
|
||||
|
||||
int main(int argc, const char* argv[]) {
|
||||
int error = 0;
|
||||
const W_CHAR* dump_folder = TO_W_CHAR(".");
|
||||
const W_CHAR* prefix = TO_W_CHAR("dump_");
|
||||
const W_CHAR* suffix = TO_W_CHAR("png");
|
||||
WebPOutputFileFormat format = PNG;
|
||||
int c;
|
||||
|
||||
INIT_WARGV(argc, argv);
|
||||
|
||||
if (argc < 2) {
|
||||
Help();
|
||||
FREE_WARGV_AND_RETURN(-1);
|
||||
}
|
||||
|
||||
for (c = 1; !error && c < argc; ++c) {
|
||||
if (!strcmp(argv[c], "-folder")) {
|
||||
if (c + 1 == argc) {
|
||||
fprintf(stderr, "missing argument after option '%s'\n", argv[c]);
|
||||
error = 1;
|
||||
break;
|
||||
}
|
||||
dump_folder = GET_WARGV(argv, ++c);
|
||||
} else if (!strcmp(argv[c], "-prefix")) {
|
||||
if (c + 1 == argc) {
|
||||
fprintf(stderr, "missing argument after option '%s'\n", argv[c]);
|
||||
error = 1;
|
||||
break;
|
||||
}
|
||||
prefix = GET_WARGV(argv, ++c);
|
||||
} else if (!strcmp(argv[c], "-tiff")) {
|
||||
format = TIFF;
|
||||
suffix = TO_W_CHAR("tiff");
|
||||
} else if (!strcmp(argv[c], "-pam")) {
|
||||
format = PAM;
|
||||
suffix = TO_W_CHAR("pam");
|
||||
} else if (!strcmp(argv[c], "-h") || !strcmp(argv[c], "-help")) {
|
||||
Help();
|
||||
FREE_WARGV_AND_RETURN(0);
|
||||
} else if (!strcmp(argv[c], "-version")) {
|
||||
int dec_version, demux_version;
|
||||
GetAnimatedImageVersions(&dec_version, &demux_version);
|
||||
printf("WebP Decoder version: %d.%d.%d\nWebP Demux version: %d.%d.%d\n",
|
||||
(dec_version >> 16) & 0xff, (dec_version >> 8) & 0xff,
|
||||
(dec_version >> 0) & 0xff,
|
||||
(demux_version >> 16) & 0xff, (demux_version >> 8) & 0xff,
|
||||
(demux_version >> 0) & 0xff);
|
||||
FREE_WARGV_AND_RETURN(0);
|
||||
} else {
|
||||
uint32_t i;
|
||||
AnimatedImage image;
|
||||
const W_CHAR* const file = GET_WARGV(argv, c);
|
||||
memset(&image, 0, sizeof(image));
|
||||
WPRINTF("Decoding file: %s as %s/%sxxxx.%s\n",
|
||||
file, dump_folder, prefix, suffix);
|
||||
if (!ReadAnimatedImage((const char*)file, &image, 0, NULL)) {
|
||||
WFPRINTF(stderr, "Error decoding file: %s\n Aborting.\n", file);
|
||||
error = 1;
|
||||
break;
|
||||
}
|
||||
for (i = 0; !error && i < image.num_frames; ++i) {
|
||||
W_CHAR out_file[1024];
|
||||
WebPDecBuffer buffer;
|
||||
WebPInitDecBuffer(&buffer);
|
||||
buffer.colorspace = MODE_RGBA;
|
||||
buffer.is_external_memory = 1;
|
||||
buffer.width = image.canvas_width;
|
||||
buffer.height = image.canvas_height;
|
||||
buffer.u.RGBA.rgba = image.frames[i].rgba;
|
||||
buffer.u.RGBA.stride = buffer.width * sizeof(uint32_t);
|
||||
buffer.u.RGBA.size = buffer.u.RGBA.stride * buffer.height;
|
||||
WSNPRINTF(out_file, sizeof(out_file), "%s/%s%.4d.%s",
|
||||
dump_folder, prefix, i, suffix);
|
||||
if (!WebPSaveImage(&buffer, format, (const char*)out_file)) {
|
||||
WFPRINTF(stderr, "Error while saving image '%s'\n", out_file);
|
||||
error = 1;
|
||||
}
|
||||
WebPFreeDecBuffer(&buffer);
|
||||
}
|
||||
ClearAnimatedImage(&image);
|
||||
}
|
||||
}
|
||||
FREE_WARGV_AND_RETURN(error ? 1 : 0);
|
||||
}
|
@ -16,16 +16,13 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#if defined(WEBP_HAVE_GIF)
|
||||
#ifdef WEBP_HAVE_GIF
|
||||
#include <gif_lib.h>
|
||||
#endif
|
||||
#include "webp/format_constants.h"
|
||||
#include "webp/decode.h"
|
||||
#include "webp/demux.h"
|
||||
#include "../imageio/imageio_util.h"
|
||||
#include "./gifdec.h"
|
||||
#include "./unicode.h"
|
||||
#include "./unicode_gif.h"
|
||||
|
||||
#if defined(_MSC_VER) && _MSC_VER < 1900
|
||||
#define snprintf _snprintf
|
||||
@ -36,13 +33,11 @@ static const int kNumChannels = 4;
|
||||
// -----------------------------------------------------------------------------
|
||||
// Common utilities.
|
||||
|
||||
#if defined(WEBP_HAVE_GIF)
|
||||
// Returns true if the frame covers the full canvas.
|
||||
static int IsFullFrame(int width, int height,
|
||||
int canvas_width, int canvas_height) {
|
||||
return (width == canvas_width && height == canvas_height);
|
||||
}
|
||||
#endif // WEBP_HAVE_GIF
|
||||
|
||||
static int CheckSizeForOverflow(uint64_t size) {
|
||||
return (size == (size_t)size);
|
||||
@ -60,15 +55,15 @@ static int AllocateFrames(AnimatedImage* const image, uint32_t num_frames) {
|
||||
!CheckSizeForOverflow(total_frame_size)) {
|
||||
return 0;
|
||||
}
|
||||
mem = (uint8_t*)WebPMalloc((size_t)total_size);
|
||||
frames = (DecodedFrame*)WebPMalloc((size_t)total_frame_size);
|
||||
mem = (uint8_t*)malloc((size_t)total_size);
|
||||
frames = (DecodedFrame*)malloc((size_t)total_frame_size);
|
||||
|
||||
if (mem == NULL || frames == NULL) {
|
||||
WebPFree(mem);
|
||||
WebPFree(frames);
|
||||
free(mem);
|
||||
free(frames);
|
||||
return 0;
|
||||
}
|
||||
WebPFree(image->raw_mem);
|
||||
free(image->raw_mem);
|
||||
image->num_frames = num_frames;
|
||||
image->frames = frames;
|
||||
for (i = 0; i < num_frames; ++i) {
|
||||
@ -82,15 +77,14 @@ static int AllocateFrames(AnimatedImage* const image, uint32_t num_frames) {
|
||||
|
||||
void ClearAnimatedImage(AnimatedImage* const image) {
|
||||
if (image != NULL) {
|
||||
WebPFree(image->raw_mem);
|
||||
WebPFree(image->frames);
|
||||
free(image->raw_mem);
|
||||
free(image->frames);
|
||||
image->num_frames = 0;
|
||||
image->frames = NULL;
|
||||
image->raw_mem = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(WEBP_HAVE_GIF)
|
||||
// Clear the canvas to transparent.
|
||||
static void ZeroFillCanvas(uint8_t* rgba,
|
||||
uint32_t canvas_width, uint32_t canvas_height) {
|
||||
@ -132,7 +126,6 @@ static void CopyFrameRectangle(const uint8_t* src, uint8_t* dst, int stride,
|
||||
dst += stride;
|
||||
}
|
||||
}
|
||||
#endif // WEBP_HAVE_GIF
|
||||
|
||||
// Canonicalize all transparent pixels to transparent black to aid comparison.
|
||||
static void CleanupTransparentPixels(uint32_t* rgba,
|
||||
@ -154,42 +147,40 @@ static int DumpFrame(const char filename[], const char dump_folder[],
|
||||
int ok = 0;
|
||||
size_t max_len;
|
||||
int y;
|
||||
const W_CHAR* base_name = NULL;
|
||||
W_CHAR* file_name = NULL;
|
||||
const char* base_name = NULL;
|
||||
char* file_name = NULL;
|
||||
FILE* f = NULL;
|
||||
const char* row;
|
||||
|
||||
if (dump_folder == NULL) dump_folder = (const char*)TO_W_CHAR(".");
|
||||
|
||||
base_name = WSTRRCHR(filename, '/');
|
||||
base_name = (base_name == NULL) ? (const W_CHAR*)filename : base_name + 1;
|
||||
max_len = WSTRLEN(dump_folder) + 1 + WSTRLEN(base_name)
|
||||
base_name = strrchr(filename, '/');
|
||||
base_name = (base_name == NULL) ? filename : base_name + 1;
|
||||
max_len = strlen(dump_folder) + 1 + strlen(base_name)
|
||||
+ strlen("_frame_") + strlen(".pam") + 8;
|
||||
file_name = (W_CHAR*)WebPMalloc(max_len * sizeof(*file_name));
|
||||
file_name = (char*)malloc(max_len * sizeof(*file_name));
|
||||
if (file_name == NULL) goto End;
|
||||
|
||||
if (WSNPRINTF(file_name, max_len, "%s/%s_frame_%d.pam",
|
||||
(const W_CHAR*)dump_folder, base_name, frame_num) < 0) {
|
||||
if (snprintf(file_name, max_len, "%s/%s_frame_%d.pam",
|
||||
dump_folder, base_name, frame_num) < 0) {
|
||||
fprintf(stderr, "Error while generating file name\n");
|
||||
goto End;
|
||||
}
|
||||
|
||||
f = WFOPEN(file_name, "wb");
|
||||
f = fopen(file_name, "wb");
|
||||
if (f == NULL) {
|
||||
WFPRINTF(stderr, "Error opening file for writing: %s\n", file_name);
|
||||
fprintf(stderr, "Error opening file for writing: %s\n", file_name);
|
||||
ok = 0;
|
||||
goto End;
|
||||
}
|
||||
if (fprintf(f, "P7\nWIDTH %d\nHEIGHT %d\n"
|
||||
"DEPTH 4\nMAXVAL 255\nTUPLTYPE RGB_ALPHA\nENDHDR\n",
|
||||
canvas_width, canvas_height) < 0) {
|
||||
WFPRINTF(stderr, "Write error for file %s\n", file_name);
|
||||
fprintf(stderr, "Write error for file %s\n", file_name);
|
||||
goto End;
|
||||
}
|
||||
row = (const char*)rgba;
|
||||
for (y = 0; y < canvas_height; ++y) {
|
||||
if (fwrite(row, canvas_width * kNumChannels, 1, f) != 1) {
|
||||
WFPRINTF(stderr, "Error writing to file: %s\n", file_name);
|
||||
fprintf(stderr, "Error writing to file: %s\n", file_name);
|
||||
goto End;
|
||||
}
|
||||
row += canvas_width * kNumChannels;
|
||||
@ -197,7 +188,7 @@ static int DumpFrame(const char filename[], const char dump_folder[],
|
||||
ok = 1;
|
||||
End:
|
||||
if (f != NULL) fclose(f);
|
||||
WebPFree(file_name);
|
||||
free(file_name);
|
||||
return ok;
|
||||
}
|
||||
|
||||
@ -209,7 +200,7 @@ static int IsWebP(const WebPData* const webp_data) {
|
||||
return (WebPGetInfo(webp_data->bytes, webp_data->size, NULL, NULL) != 0);
|
||||
}
|
||||
|
||||
// Read animated WebP bitstream 'webp_data' into 'AnimatedImage' struct.
|
||||
// Read animated WebP bitstream 'file_str' into 'AnimatedImage' struct.
|
||||
static int ReadAnimatedWebP(const char filename[],
|
||||
const WebPData* const webp_data,
|
||||
AnimatedImage* const image, int dump_frames,
|
||||
@ -225,7 +216,7 @@ static int ReadAnimatedWebP(const char filename[],
|
||||
|
||||
dec = WebPAnimDecoderNew(webp_data, NULL);
|
||||
if (dec == NULL) {
|
||||
WFPRINTF(stderr, "Error parsing image: %s\n", (const W_CHAR*)filename);
|
||||
fprintf(stderr, "Error parsing image: %s\n", filename);
|
||||
goto End;
|
||||
}
|
||||
|
||||
@ -278,7 +269,6 @@ static int ReadAnimatedWebP(const char filename[],
|
||||
prev_frame_timestamp = timestamp;
|
||||
}
|
||||
ok = dump_ok;
|
||||
if (ok) image->format = ANIM_WEBP;
|
||||
|
||||
End:
|
||||
WebPAnimDecoderDelete(dec);
|
||||
@ -288,7 +278,7 @@ static int ReadAnimatedWebP(const char filename[],
|
||||
// -----------------------------------------------------------------------------
|
||||
// GIF Decoding.
|
||||
|
||||
#if defined(WEBP_HAVE_GIF)
|
||||
#ifdef WEBP_HAVE_GIF
|
||||
|
||||
// Returns true if this is a valid GIF bitstream.
|
||||
static int IsGIF(const WebPData* const data) {
|
||||
@ -373,6 +363,26 @@ static int DGifSavedExtensionToGCB(GifFileType* GifFile, int ImageIndex,
|
||||
#define DGifCloseFile(a, b) DGifCloseFile(a)
|
||||
#endif
|
||||
|
||||
static void GIFDisplayError(const GifFileType* const gif, int gif_error) {
|
||||
// libgif 4.2.0 has retired PrintGifError() and added GifErrorString().
|
||||
#if LOCAL_GIF_PREREQ(4, 2)
|
||||
#if LOCAL_GIF_PREREQ(5, 0)
|
||||
const char* error_str =
|
||||
GifErrorString((gif == NULL) ? gif_error : gif->Error);
|
||||
#else
|
||||
const char* error_str = GifErrorString();
|
||||
(void)gif;
|
||||
#endif
|
||||
if (error_str == NULL) error_str = "Unknown error";
|
||||
fprintf(stderr, "GIFLib Error %d: %s\n", gif_error, error_str);
|
||||
#else
|
||||
(void)gif;
|
||||
fprintf(stderr, "GIFLib Error %d: ", gif_error);
|
||||
PrintGifError();
|
||||
fprintf(stderr, "\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
static int IsKeyFrameGIF(const GifImageDesc* prev_desc, int prev_dispose,
|
||||
const DecodedFrame* const prev_frame,
|
||||
int canvas_width, int canvas_height) {
|
||||
@ -405,7 +415,7 @@ static uint32_t GetBackgroundColorGIF(GifFileType* gif) {
|
||||
return 0xffffffff; // Invalid: assume white.
|
||||
} else {
|
||||
const GifColorType color = color_map->Colors[gif->SBackGroundColor];
|
||||
return (0xffu << 24) |
|
||||
return (0xff << 24) |
|
||||
(color.Red << 16) |
|
||||
(color.Green << 8) |
|
||||
(color.Blue << 0);
|
||||
@ -413,11 +423,6 @@ static uint32_t GetBackgroundColorGIF(GifFileType* gif) {
|
||||
}
|
||||
|
||||
// Find appropriate app extension and get loop count from the next extension.
|
||||
// We use Chrome's interpretation of the 'loop_count' semantics:
|
||||
// if not present -> loop once
|
||||
// if present and loop_count == 0, return 0 ('infinite').
|
||||
// if present and loop_count != 0, it's the number of *extra* loops
|
||||
// so we need to return loop_count + 1 as total loop number.
|
||||
static uint32_t GetLoopCountGIF(const GifFileType* const gif) {
|
||||
int i;
|
||||
for (i = 0; i < gif->ImageCount; ++i) {
|
||||
@ -435,13 +440,12 @@ static uint32_t GetLoopCountGIF(const GifFileType* const gif) {
|
||||
if (signature_is_ok &&
|
||||
eb2->Function == CONTINUE_EXT_FUNC_CODE && eb2->ByteCount >= 3 &&
|
||||
eb2->Bytes[0] == 1) {
|
||||
const uint32_t extra_loop = ((uint32_t)(eb2->Bytes[2]) << 8) +
|
||||
((uint32_t)(eb2->Bytes[1]) << 0);
|
||||
return (extra_loop > 0) ? extra_loop + 1 : 0;
|
||||
return ((uint32_t)(eb2->Bytes[2]) << 8) +
|
||||
((uint32_t)(eb2->Bytes[1]) << 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
return 1; // Default.
|
||||
return 0; // Default.
|
||||
}
|
||||
|
||||
// Get duration of 'n'th frame in milliseconds.
|
||||
@ -513,15 +517,15 @@ static int ReadAnimatedGIF(const char filename[], AnimatedImage* const image,
|
||||
int gif_error;
|
||||
GifFileType* gif;
|
||||
|
||||
gif = DGifOpenFileUnicode((const W_CHAR*)filename, NULL);
|
||||
gif = DGifOpenFileName(filename, NULL);
|
||||
if (gif == NULL) {
|
||||
WFPRINTF(stderr, "Could not read file: %s.\n", (const W_CHAR*)filename);
|
||||
fprintf(stderr, "Could not read file: %s.\n", filename);
|
||||
return 0;
|
||||
}
|
||||
|
||||
gif_error = DGifSlurp(gif);
|
||||
if (gif_error != GIF_OK) {
|
||||
WFPRINTF(stderr, "Could not parse image: %s.\n", (const W_CHAR*)filename);
|
||||
fprintf(stderr, "Could not parse image: %s.\n", filename);
|
||||
GIFDisplayError(gif, gif_error);
|
||||
DGifCloseFile(gif, NULL);
|
||||
return 0;
|
||||
@ -577,9 +581,6 @@ static int ReadAnimatedGIF(const char filename[], AnimatedImage* const image,
|
||||
curr_frame = &image->frames[i];
|
||||
curr_rgba = curr_frame->rgba;
|
||||
curr_frame->duration = GetFrameDurationGIF(gif, i);
|
||||
// Force frames with a small or no duration to 100ms to be consistent
|
||||
// with web browsers and other transcoding tools (like gif2webp itself).
|
||||
if (curr_frame->duration <= 10) curr_frame->duration = 100;
|
||||
|
||||
if (i == 0) { // Initialize as transparent.
|
||||
curr_frame->is_key_frame = 1;
|
||||
@ -671,7 +672,6 @@ static int ReadAnimatedGIF(const char filename[], AnimatedImage* const image,
|
||||
}
|
||||
}
|
||||
}
|
||||
image->format = ANIM_GIF;
|
||||
DGifCloseFile(gif, NULL);
|
||||
return 1;
|
||||
}
|
||||
@ -707,7 +707,7 @@ int ReadAnimatedImage(const char filename[], AnimatedImage* const image,
|
||||
memset(image, 0, sizeof(*image));
|
||||
|
||||
if (!ImgIoUtilReadFile(filename, &webp_data.bytes, &webp_data.size)) {
|
||||
WFPRINTF(stderr, "Error reading file: %s\n", (const W_CHAR*)filename);
|
||||
fprintf(stderr, "Error reading file: %s\n", filename);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -717,9 +717,9 @@ int ReadAnimatedImage(const char filename[], AnimatedImage* const image,
|
||||
} else if (IsGIF(&webp_data)) {
|
||||
ok = ReadAnimatedGIF(filename, image, dump_frames, dump_folder);
|
||||
} else {
|
||||
WFPRINTF(stderr,
|
||||
"Unknown file type: %s. Supported file types are WebP and GIF\n",
|
||||
(const W_CHAR*)filename);
|
||||
fprintf(stderr,
|
||||
"Unknown file type: %s. Supported file types are WebP and GIF\n",
|
||||
filename);
|
||||
ok = 0;
|
||||
}
|
||||
if (!ok) ClearAnimatedImage(image);
|
||||
@ -771,9 +771,3 @@ void GetDiffAndPSNR(const uint8_t rgba1[], const uint8_t rgba2[],
|
||||
*psnr = 4.3429448 * log(255. * 255. / sse);
|
||||
}
|
||||
}
|
||||
|
||||
void GetAnimatedImageVersions(int* const decoder_version,
|
||||
int* const demux_version) {
|
||||
*decoder_version = WebPGetDecoderVersion();
|
||||
*demux_version = WebPGetDemuxVersion();
|
||||
}
|
||||
|
@ -22,11 +22,6 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
ANIM_GIF,
|
||||
ANIM_WEBP
|
||||
} AnimatedFileFormat;
|
||||
|
||||
typedef struct {
|
||||
uint8_t* rgba; // Decoded and reconstructed full frame.
|
||||
int duration; // Frame duration in milliseconds.
|
||||
@ -34,7 +29,6 @@ typedef struct {
|
||||
} DecodedFrame;
|
||||
|
||||
typedef struct {
|
||||
AnimatedFileFormat format;
|
||||
uint32_t canvas_width;
|
||||
uint32_t canvas_height;
|
||||
uint32_t bgcolor;
|
||||
@ -62,10 +56,6 @@ void GetDiffAndPSNR(const uint8_t rgba1[], const uint8_t rgba2[],
|
||||
uint32_t width, uint32_t height, int premultiply,
|
||||
int* const max_diff, double* const psnr);
|
||||
|
||||
// Return library versions used by anim_util.
|
||||
void GetAnimatedImageVersions(int* const decoder_version,
|
||||
int* const demux_version);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
332
examples/cwebp.c
332
examples/cwebp.c
@ -12,7 +12,6 @@
|
||||
//
|
||||
// Author: Skal (pascal.massimino@gmail.com)
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@ -24,9 +23,7 @@
|
||||
#include "../examples/example_util.h"
|
||||
#include "../imageio/image_dec.h"
|
||||
#include "../imageio/imageio_util.h"
|
||||
#include "../imageio/webpdec.h"
|
||||
#include "./stopwatch.h"
|
||||
#include "./unicode.h"
|
||||
#include "webp/encode.h"
|
||||
|
||||
#ifndef WEBP_DLL
|
||||
@ -91,10 +88,9 @@ static int ReadPicture(const char* const filename, WebPPicture* const pic,
|
||||
}
|
||||
}
|
||||
if (!ok) {
|
||||
WFPRINTF(stderr, "Error! Could not process file %s\n",
|
||||
(const W_CHAR*)filename);
|
||||
fprintf(stderr, "Error! Could not process file %s\n", filename);
|
||||
}
|
||||
WebPFree((void*)data);
|
||||
free((void*)data);
|
||||
return ok;
|
||||
}
|
||||
|
||||
@ -118,10 +114,9 @@ static int ReadPicture(const char* const filename, WebPPicture* const pic,
|
||||
}
|
||||
End:
|
||||
if (!ok) {
|
||||
WFPRINTF(stderr, "Error! Could not process file %s\n",
|
||||
(const W_CHAR*)filename);
|
||||
fprintf(stderr, "Error! Could not process file %s\n", filename);
|
||||
}
|
||||
WebPFree((void*)data);
|
||||
free((void*)data);
|
||||
return ok;
|
||||
}
|
||||
|
||||
@ -130,8 +125,7 @@ static int ReadPicture(const char* const filename, WebPPicture* const pic,
|
||||
static void AllocExtraInfo(WebPPicture* const pic) {
|
||||
const int mb_w = (pic->width + 15) / 16;
|
||||
const int mb_h = (pic->height + 15) / 16;
|
||||
pic->extra_info =
|
||||
(uint8_t*)WebPMalloc(mb_w * mb_h * sizeof(*pic->extra_info));
|
||||
pic->extra_info = (uint8_t*)malloc(mb_w * mb_h * sizeof(*pic->extra_info));
|
||||
}
|
||||
|
||||
static void PrintByteCount(const int bytes[4], int total_size,
|
||||
@ -146,11 +140,10 @@ static void PrintByteCount(const int bytes[4], int total_size,
|
||||
fprintf(stderr, "| %7d (%.1f%%)\n", total, 100.f * total / total_size);
|
||||
}
|
||||
|
||||
static void PrintPercents(const int counts[4]) {
|
||||
static void PrintPercents(const int counts[4], int total) {
|
||||
int s;
|
||||
const int total = counts[0] + counts[1] + counts[2] + counts[3];
|
||||
for (s = 0; s < 4; ++s) {
|
||||
fprintf(stderr, "| %3d%%", (int)(100. * counts[s] / total + .5));
|
||||
fprintf(stderr, "| %2d%%", 100 * counts[s] / total);
|
||||
}
|
||||
fprintf(stderr, "| %7d\n", total);
|
||||
}
|
||||
@ -191,10 +184,9 @@ static void PrintExtraInfoLossless(const WebPPicture* const pic,
|
||||
if (short_output) {
|
||||
fprintf(stderr, "%7d %2.2f\n", stats->coded_size, stats->PSNR[3]);
|
||||
} else {
|
||||
WFPRINTF(stderr, "File: %s\n", (const W_CHAR*)file_name);
|
||||
fprintf(stderr, "File: %s\n", file_name);
|
||||
fprintf(stderr, "Dimension: %d x %d\n", pic->width, pic->height);
|
||||
fprintf(stderr, "Output: %d bytes (%.2f bpp)\n", stats->coded_size,
|
||||
8.f * stats->coded_size / pic->width / pic->height);
|
||||
fprintf(stderr, "Output: %d bytes\n", stats->coded_size);
|
||||
PrintFullLosslessInfo(stats, "ARGB");
|
||||
}
|
||||
}
|
||||
@ -210,23 +202,20 @@ static void PrintExtraInfoLossy(const WebPPicture* const pic, int short_output,
|
||||
const int num_i16 = stats->block_count[1];
|
||||
const int num_skip = stats->block_count[2];
|
||||
const int total = num_i4 + num_i16;
|
||||
WFPRINTF(stderr, "File: %s\n", (const W_CHAR*)file_name);
|
||||
fprintf(stderr, "File: %s\n", file_name);
|
||||
fprintf(stderr, "Dimension: %d x %d%s\n",
|
||||
pic->width, pic->height,
|
||||
stats->alpha_data_size ? " (with alpha)" : "");
|
||||
fprintf(stderr, "Output: "
|
||||
"%d bytes Y-U-V-All-PSNR %2.2f %2.2f %2.2f %2.2f dB\n"
|
||||
" (%.2f bpp)\n",
|
||||
"%d bytes Y-U-V-All-PSNR %2.2f %2.2f %2.2f %2.2f dB\n",
|
||||
stats->coded_size,
|
||||
stats->PSNR[0], stats->PSNR[1], stats->PSNR[2], stats->PSNR[3],
|
||||
8.f * stats->coded_size / pic->width / pic->height);
|
||||
stats->PSNR[0], stats->PSNR[1], stats->PSNR[2], stats->PSNR[3]);
|
||||
if (total > 0) {
|
||||
int totals[4] = { 0, 0, 0, 0 };
|
||||
fprintf(stderr, "block count: intra4: %6d (%.2f%%)\n"
|
||||
" intra16: %6d (%.2f%%)\n"
|
||||
" skipped: %6d (%.2f%%)\n",
|
||||
num_i4, 100.f * num_i4 / total,
|
||||
num_i16, 100.f * num_i16 / total,
|
||||
fprintf(stderr, "block count: intra4: %d\n"
|
||||
" intra16: %d (-> %.2f%%)\n",
|
||||
num_i4, num_i16, 100.f * num_i16 / total);
|
||||
fprintf(stderr, " skipped block: %d (%.2f%%)\n",
|
||||
num_skip, 100.f * num_skip / total);
|
||||
fprintf(stderr, "bytes used: header: %6d (%.1f%%)\n"
|
||||
" mode-partition: %6d (%.1f%%)\n",
|
||||
@ -250,7 +239,7 @@ static void PrintExtraInfoLossy(const WebPPicture* const pic, int short_output,
|
||||
PrintByteCount(stats->residual_bytes[2], stats->coded_size, totals);
|
||||
}
|
||||
fprintf(stderr, " macroblocks: ");
|
||||
PrintPercents(stats->segment_size);
|
||||
PrintPercents(stats->segment_size, total);
|
||||
fprintf(stderr, " quantizer: ");
|
||||
PrintValues(stats->segment_quant);
|
||||
fprintf(stderr, " filter level: ");
|
||||
@ -315,7 +304,7 @@ static int DumpPicture(const WebPPicture* const picture, const char* PGM_name) {
|
||||
const int alpha_height =
|
||||
WebPPictureHasTransparency(picture) ? picture->height : 0;
|
||||
const int height = picture->height + uv_height + alpha_height;
|
||||
FILE* const f = WFOPEN(PGM_name, "wb");
|
||||
FILE* const f = fopen(PGM_name, "wb");
|
||||
if (f == NULL) return 0;
|
||||
fprintf(f, "P5\n%d %d\n255\n", stride, height);
|
||||
for (y = 0; y < picture->height; ++y) {
|
||||
@ -474,9 +463,8 @@ static int WriteWebPWithMetadata(FILE* const out,
|
||||
} else {
|
||||
const int is_lossless = !memcmp(webp, "VP8L", kTagSize);
|
||||
if (is_lossless) {
|
||||
// Presence of alpha is stored in the 37th bit (29th after the
|
||||
// signature) of VP8L data.
|
||||
if (webp[kChunkHeaderSize + 4] & (1 << 4)) flags |= kAlphaFlag;
|
||||
// Presence of alpha is stored in the 29th bit of VP8L data.
|
||||
if (webp[kChunkHeaderSize + 3] & (1 << 5)) flags |= kAlphaFlag;
|
||||
}
|
||||
ok = ok && (fwrite(kVP8XHeader, kChunkHeaderSize, 1, out) == 1);
|
||||
ok = ok && WriteLE32(out, flags);
|
||||
@ -498,10 +486,10 @@ static int WriteWebPWithMetadata(FILE* const out,
|
||||
*metadata_written |= METADATA_XMP;
|
||||
}
|
||||
return ok;
|
||||
} else {
|
||||
// No metadata, just write the original image file.
|
||||
return (fwrite(webp, webp_size, 1, out) == 1);
|
||||
}
|
||||
|
||||
// No metadata, just write the original image file.
|
||||
return (fwrite(webp, webp_size, 1, out) == 1);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@ -527,7 +515,6 @@ static void HelpLong(void) {
|
||||
printf(" cwebp [-preset <...>] [options] in_file [-o out_file]\n\n");
|
||||
printf("If input size (-s) for an image is not specified, it is\n"
|
||||
"assumed to be a PNG, JPEG, TIFF or WebP file.\n");
|
||||
printf("Note: Animated PNG and WebP files are not supported.\n");
|
||||
#ifdef HAVE_WINCODEC_H
|
||||
printf("Windows builds can take as input any of the files handled by WIC.\n");
|
||||
#endif
|
||||
@ -568,8 +555,6 @@ static void HelpLong(void) {
|
||||
printf(" "
|
||||
"the first partition (0=no degradation ... 100=full)\n");
|
||||
printf(" -pass <int> ............ analysis pass number (1..10)\n");
|
||||
printf(" -qrange <min> <max> .... specifies the permissible quality range\n"
|
||||
" (default: 0 100)\n");
|
||||
printf(" -crop <x> <y> <w> <h> .. crop picture with the given rectangle\n");
|
||||
printf(" -resize <w> <h> ........ resize picture (after any cropping)\n");
|
||||
printf(" -mt .................... use multi-threading if available\n");
|
||||
@ -594,6 +579,9 @@ static void HelpLong(void) {
|
||||
printf(" -near_lossless <int> ... use near-lossless image\n"
|
||||
" preprocessing (0..100=off), "
|
||||
"default=100\n");
|
||||
#ifdef WEBP_EXPERIMENTAL_FEATURES /* not documented yet */
|
||||
printf(" -delta_palette ......... use delta palettization\n");
|
||||
#endif // WEBP_EXPERIMENTAL_FEATURES
|
||||
printf(" -hint <string> ......... specify image characteristics hint,\n");
|
||||
printf(" one of: photo, picture or graph\n");
|
||||
|
||||
@ -646,10 +634,10 @@ static const char* const kErrorMessages[VP8_ENC_ERROR_LAST] = {
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
int main(int argc, const char* argv[]) {
|
||||
int main(int argc, const char *argv[]) {
|
||||
int return_value = -1;
|
||||
const char* in_file = NULL, *out_file = NULL, *dump_file = NULL;
|
||||
FILE* out = NULL;
|
||||
const char *in_file = NULL, *out_file = NULL, *dump_file = NULL;
|
||||
FILE *out = NULL;
|
||||
int c;
|
||||
int short_output = 0;
|
||||
int quiet = 0;
|
||||
@ -669,38 +657,35 @@ int main(int argc, const char* argv[]) {
|
||||
WebPConfig config;
|
||||
WebPAuxStats stats;
|
||||
WebPMemoryWriter memory_writer;
|
||||
int use_memory_writer;
|
||||
Metadata metadata;
|
||||
Stopwatch stop_watch;
|
||||
|
||||
INIT_WARGV(argc, argv);
|
||||
|
||||
MetadataInit(&metadata);
|
||||
WebPMemoryWriterInit(&memory_writer);
|
||||
if (!WebPPictureInit(&picture) ||
|
||||
!WebPPictureInit(&original_picture) ||
|
||||
!WebPConfigInit(&config)) {
|
||||
fprintf(stderr, "Error! Version mismatch!\n");
|
||||
FREE_WARGV_AND_RETURN(-1);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (argc == 1) {
|
||||
HelpShort();
|
||||
FREE_WARGV_AND_RETURN(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (c = 1; c < argc; ++c) {
|
||||
int parse_error = 0;
|
||||
if (!strcmp(argv[c], "-h") || !strcmp(argv[c], "-help")) {
|
||||
HelpShort();
|
||||
FREE_WARGV_AND_RETURN(0);
|
||||
return 0;
|
||||
} else if (!strcmp(argv[c], "-H") || !strcmp(argv[c], "-longhelp")) {
|
||||
HelpLong();
|
||||
FREE_WARGV_AND_RETURN(0);
|
||||
} else if (!strcmp(argv[c], "-o") && c + 1 < argc) {
|
||||
out_file = (const char*)GET_WARGV(argv, ++c);
|
||||
} else if (!strcmp(argv[c], "-d") && c + 1 < argc) {
|
||||
dump_file = (const char*)GET_WARGV(argv, ++c);
|
||||
return 0;
|
||||
} else if (!strcmp(argv[c], "-o") && c < argc - 1) {
|
||||
out_file = argv[++c];
|
||||
} else if (!strcmp(argv[c], "-d") && c < argc - 1) {
|
||||
dump_file = argv[++c];
|
||||
config.show_compressed = 1;
|
||||
} else if (!strcmp(argv[c], "-print_psnr")) {
|
||||
config.show_compressed = 1;
|
||||
@ -713,7 +698,7 @@ int main(int argc, const char* argv[]) {
|
||||
print_distortion = 2;
|
||||
} else if (!strcmp(argv[c], "-short")) {
|
||||
++short_output;
|
||||
} else if (!strcmp(argv[c], "-s") && c + 2 < argc) {
|
||||
} else if (!strcmp(argv[c], "-s") && c < argc - 2) {
|
||||
picture.width = ExUtilGetInt(argv[++c], 0, &parse_error);
|
||||
picture.height = ExUtilGetInt(argv[++c], 0, &parse_error);
|
||||
if (picture.width > WEBP_MAX_DIMENSION || picture.width < 0 ||
|
||||
@ -723,30 +708,30 @@ int main(int argc, const char* argv[]) {
|
||||
picture.width, picture.height);
|
||||
goto Error;
|
||||
}
|
||||
} else if (!strcmp(argv[c], "-m") && c + 1 < argc) {
|
||||
} else if (!strcmp(argv[c], "-m") && c < argc - 1) {
|
||||
config.method = ExUtilGetInt(argv[++c], 0, &parse_error);
|
||||
use_lossless_preset = 0; // disable -z option
|
||||
} else if (!strcmp(argv[c], "-q") && c + 1 < argc) {
|
||||
} else if (!strcmp(argv[c], "-q") && c < argc - 1) {
|
||||
config.quality = ExUtilGetFloat(argv[++c], &parse_error);
|
||||
use_lossless_preset = 0; // disable -z option
|
||||
} else if (!strcmp(argv[c], "-z") && c + 1 < argc) {
|
||||
} else if (!strcmp(argv[c], "-z") && c < argc - 1) {
|
||||
lossless_preset = ExUtilGetInt(argv[++c], 0, &parse_error);
|
||||
if (use_lossless_preset != 0) use_lossless_preset = 1;
|
||||
} else if (!strcmp(argv[c], "-alpha_q") && c + 1 < argc) {
|
||||
} else if (!strcmp(argv[c], "-alpha_q") && c < argc - 1) {
|
||||
config.alpha_quality = ExUtilGetInt(argv[++c], 0, &parse_error);
|
||||
} else if (!strcmp(argv[c], "-alpha_method") && c + 1 < argc) {
|
||||
} else if (!strcmp(argv[c], "-alpha_method") && c < argc - 1) {
|
||||
config.alpha_compression = ExUtilGetInt(argv[++c], 0, &parse_error);
|
||||
} else if (!strcmp(argv[c], "-alpha_cleanup")) {
|
||||
// This flag is obsolete, does opposite of -exact.
|
||||
config.exact = 0;
|
||||
} else if (!strcmp(argv[c], "-exact")) {
|
||||
config.exact = 1;
|
||||
} else if (!strcmp(argv[c], "-blend_alpha") && c + 1 < argc) {
|
||||
} else if (!strcmp(argv[c], "-blend_alpha") && c < argc - 1) {
|
||||
blend_alpha = 1;
|
||||
// background color is given in hex with an optional '0x' prefix
|
||||
background_color = ExUtilGetInt(argv[++c], 16, &parse_error);
|
||||
background_color = background_color & 0x00ffffffu;
|
||||
} else if (!strcmp(argv[c], "-alpha_filter") && c + 1 < argc) {
|
||||
} else if (!strcmp(argv[c], "-alpha_filter") && c < argc - 1) {
|
||||
++c;
|
||||
if (!strcmp(argv[c], "none")) {
|
||||
config.alpha_filtering = 0;
|
||||
@ -762,10 +747,15 @@ int main(int argc, const char* argv[]) {
|
||||
keep_alpha = 0;
|
||||
} else if (!strcmp(argv[c], "-lossless")) {
|
||||
config.lossless = 1;
|
||||
} else if (!strcmp(argv[c], "-near_lossless") && c + 1 < argc) {
|
||||
} else if (!strcmp(argv[c], "-near_lossless") && c < argc - 1) {
|
||||
config.near_lossless = ExUtilGetInt(argv[++c], 0, &parse_error);
|
||||
config.lossless = 1; // use near-lossless only with lossless
|
||||
} else if (!strcmp(argv[c], "-hint") && c + 1 < argc) {
|
||||
#ifdef WEBP_EXPERIMENTAL_FEATURES
|
||||
} else if (!strcmp(argv[c], "-delta_palette")) {
|
||||
config.use_delta_palette = 1;
|
||||
config.lossless = 1; // delta-palette is for lossless only
|
||||
#endif // WEBP_EXPERIMENTAL_FEATURES
|
||||
} else if (!strcmp(argv[c], "-hint") && c < argc - 1) {
|
||||
++c;
|
||||
if (!strcmp(argv[c], "photo")) {
|
||||
config.image_hint = WEBP_HINT_PHOTO;
|
||||
@ -777,13 +767,13 @@ int main(int argc, const char* argv[]) {
|
||||
fprintf(stderr, "Error! Unrecognized image hint: %s\n", argv[c]);
|
||||
goto Error;
|
||||
}
|
||||
} else if (!strcmp(argv[c], "-size") && c + 1 < argc) {
|
||||
} else if (!strcmp(argv[c], "-size") && c < argc - 1) {
|
||||
config.target_size = ExUtilGetInt(argv[++c], 0, &parse_error);
|
||||
} else if (!strcmp(argv[c], "-psnr") && c + 1 < argc) {
|
||||
} else if (!strcmp(argv[c], "-psnr") && c < argc - 1) {
|
||||
config.target_PSNR = ExUtilGetFloat(argv[++c], &parse_error);
|
||||
} else if (!strcmp(argv[c], "-sns") && c + 1 < argc) {
|
||||
} else if (!strcmp(argv[c], "-sns") && c < argc - 1) {
|
||||
config.sns_strength = ExUtilGetInt(argv[++c], 0, &parse_error);
|
||||
} else if (!strcmp(argv[c], "-f") && c + 1 < argc) {
|
||||
} else if (!strcmp(argv[c], "-f") && c < argc - 1) {
|
||||
config.filter_strength = ExUtilGetInt(argv[++c], 0, &parse_error);
|
||||
} else if (!strcmp(argv[c], "-af")) {
|
||||
config.autofilter = 1;
|
||||
@ -797,32 +787,27 @@ int main(int argc, const char* argv[]) {
|
||||
config.filter_type = 1;
|
||||
} else if (!strcmp(argv[c], "-nostrong")) {
|
||||
config.filter_type = 0;
|
||||
} else if (!strcmp(argv[c], "-sharpness") && c + 1 < argc) {
|
||||
} else if (!strcmp(argv[c], "-sharpness") && c < argc - 1) {
|
||||
config.filter_sharpness = ExUtilGetInt(argv[++c], 0, &parse_error);
|
||||
} else if (!strcmp(argv[c], "-sharp_yuv")) {
|
||||
config.use_sharp_yuv = 1;
|
||||
} else if (!strcmp(argv[c], "-pass") && c + 1 < argc) {
|
||||
} else if (!strcmp(argv[c], "-pass") && c < argc - 1) {
|
||||
config.pass = ExUtilGetInt(argv[++c], 0, &parse_error);
|
||||
} else if (!strcmp(argv[c], "-qrange") && c + 2 < argc) {
|
||||
config.qmin = ExUtilGetInt(argv[++c], 0, &parse_error);
|
||||
config.qmax = ExUtilGetInt(argv[++c], 0, &parse_error);
|
||||
if (config.qmin < 0) config.qmin = 0;
|
||||
if (config.qmax > 100) config.qmax = 100;
|
||||
} else if (!strcmp(argv[c], "-pre") && c + 1 < argc) {
|
||||
} else if (!strcmp(argv[c], "-pre") && c < argc - 1) {
|
||||
config.preprocessing = ExUtilGetInt(argv[++c], 0, &parse_error);
|
||||
} else if (!strcmp(argv[c], "-segments") && c + 1 < argc) {
|
||||
} else if (!strcmp(argv[c], "-segments") && c < argc - 1) {
|
||||
config.segments = ExUtilGetInt(argv[++c], 0, &parse_error);
|
||||
} else if (!strcmp(argv[c], "-partition_limit") && c + 1 < argc) {
|
||||
} else if (!strcmp(argv[c], "-partition_limit") && c < argc - 1) {
|
||||
config.partition_limit = ExUtilGetInt(argv[++c], 0, &parse_error);
|
||||
} else if (!strcmp(argv[c], "-map") && c + 1 < argc) {
|
||||
} else if (!strcmp(argv[c], "-map") && c < argc - 1) {
|
||||
picture.extra_info_type = ExUtilGetInt(argv[++c], 0, &parse_error);
|
||||
} else if (!strcmp(argv[c], "-crop") && c + 4 < argc) {
|
||||
} else if (!strcmp(argv[c], "-crop") && c < argc - 4) {
|
||||
crop = 1;
|
||||
crop_x = ExUtilGetInt(argv[++c], 0, &parse_error);
|
||||
crop_y = ExUtilGetInt(argv[++c], 0, &parse_error);
|
||||
crop_w = ExUtilGetInt(argv[++c], 0, &parse_error);
|
||||
crop_h = ExUtilGetInt(argv[++c], 0, &parse_error);
|
||||
} else if (!strcmp(argv[c], "-resize") && c + 2 < argc) {
|
||||
} else if (!strcmp(argv[c], "-resize") && c < argc - 2) {
|
||||
resize_w = ExUtilGetInt(argv[++c], 0, &parse_error);
|
||||
resize_h = ExUtilGetInt(argv[++c], 0, &parse_error);
|
||||
#ifndef WEBP_DLL
|
||||
@ -833,12 +818,12 @@ int main(int argc, const char* argv[]) {
|
||||
const int version = WebPGetEncoderVersion();
|
||||
printf("%d.%d.%d\n",
|
||||
(version >> 16) & 0xff, (version >> 8) & 0xff, version & 0xff);
|
||||
FREE_WARGV_AND_RETURN(0);
|
||||
return 0;
|
||||
} else if (!strcmp(argv[c], "-progress")) {
|
||||
show_progress = 1;
|
||||
} else if (!strcmp(argv[c], "-quiet")) {
|
||||
quiet = 1;
|
||||
} else if (!strcmp(argv[c], "-preset") && c + 1 < argc) {
|
||||
} else if (!strcmp(argv[c], "-preset") && c < argc - 1) {
|
||||
WebPPreset preset;
|
||||
++c;
|
||||
if (!strcmp(argv[c], "default")) {
|
||||
@ -861,7 +846,7 @@ int main(int argc, const char* argv[]) {
|
||||
fprintf(stderr, "Error! Could initialize configuration with preset.\n");
|
||||
goto Error;
|
||||
}
|
||||
} else if (!strcmp(argv[c], "-metadata") && c + 1 < argc) {
|
||||
} else if (!strcmp(argv[c], "-metadata") && c < argc - 1) {
|
||||
static const struct {
|
||||
const char* option;
|
||||
int flag;
|
||||
@ -895,7 +880,8 @@ int main(int argc, const char* argv[]) {
|
||||
if (i == kNumTokens) {
|
||||
fprintf(stderr, "Error! Unknown metadata type '%.*s'\n",
|
||||
(int)(token - start), start);
|
||||
FREE_WARGV_AND_RETURN(-1);
|
||||
HelpLong();
|
||||
return -1;
|
||||
}
|
||||
start = token + 1;
|
||||
}
|
||||
@ -909,19 +895,19 @@ int main(int argc, const char* argv[]) {
|
||||
} else if (!strcmp(argv[c], "-v")) {
|
||||
verbose = 1;
|
||||
} else if (!strcmp(argv[c], "--")) {
|
||||
if (c + 1 < argc) in_file = (const char*)GET_WARGV(argv, ++c);
|
||||
if (c < argc - 1) in_file = argv[++c];
|
||||
break;
|
||||
} else if (argv[c][0] == '-') {
|
||||
fprintf(stderr, "Error! Unknown option '%s'\n", argv[c]);
|
||||
HelpLong();
|
||||
FREE_WARGV_AND_RETURN(-1);
|
||||
return -1;
|
||||
} else {
|
||||
in_file = (const char*)GET_WARGV(argv, c);
|
||||
in_file = argv[c];
|
||||
}
|
||||
|
||||
if (parse_error) {
|
||||
HelpLong();
|
||||
FREE_WARGV_AND_RETURN(-1);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (in_file == NULL) {
|
||||
@ -971,8 +957,7 @@ int main(int argc, const char* argv[]) {
|
||||
}
|
||||
if (!ReadPicture(in_file, &picture, keep_alpha,
|
||||
(keep_metadata == 0) ? NULL : &metadata)) {
|
||||
WFPRINTF(stderr, "Error! Cannot read input picture file '%s'\n",
|
||||
(const W_CHAR*)in_file);
|
||||
fprintf(stderr, "Error! Cannot read input picture file '%s'\n", in_file);
|
||||
goto Error;
|
||||
}
|
||||
picture.progress_hook = (show_progress && !quiet) ? ProgressReport : NULL;
|
||||
@ -985,41 +970,28 @@ int main(int argc, const char* argv[]) {
|
||||
const double read_time = StopwatchReadAndReset(&stop_watch);
|
||||
fprintf(stderr, "Time to read input: %.3fs\n", read_time);
|
||||
}
|
||||
// The bitstream should be kept in memory when metadata must be appended
|
||||
// before writing it to a file/stream, and/or when the near-losslessly encoded
|
||||
// bitstream must be decoded for distortion computation (lossy will modify the
|
||||
// 'picture' but not the lossless pipeline).
|
||||
// Otherwise directly write the bitstream to a file.
|
||||
use_memory_writer = (out_file != NULL && keep_metadata) ||
|
||||
(!quiet && print_distortion >= 0 && config.lossless &&
|
||||
config.near_lossless < 100);
|
||||
|
||||
// Open the output
|
||||
if (out_file != NULL) {
|
||||
const int use_stdout = !WSTRCMP(out_file, "-");
|
||||
out = use_stdout ? ImgIoUtilSetBinaryMode(stdout) : WFOPEN(out_file, "wb");
|
||||
const int use_stdout = !strcmp(out_file, "-");
|
||||
out = use_stdout ? ImgIoUtilSetBinaryMode(stdout) : fopen(out_file, "wb");
|
||||
if (out == NULL) {
|
||||
WFPRINTF(stderr, "Error! Cannot open output file '%s'\n",
|
||||
(const W_CHAR*)out_file);
|
||||
fprintf(stderr, "Error! Cannot open output file '%s'\n", out_file);
|
||||
goto Error;
|
||||
} else {
|
||||
if (!short_output && !quiet) {
|
||||
WFPRINTF(stderr, "Saving file '%s'\n", (const W_CHAR*)out_file);
|
||||
fprintf(stderr, "Saving file '%s'\n", out_file);
|
||||
}
|
||||
}
|
||||
if (use_memory_writer) {
|
||||
picture.writer = WebPMemoryWrite;
|
||||
picture.custom_ptr = (void*)&memory_writer;
|
||||
} else {
|
||||
if (keep_metadata == 0) {
|
||||
picture.writer = MyWriter;
|
||||
picture.custom_ptr = (void*)out;
|
||||
} else {
|
||||
picture.writer = WebPMemoryWrite;
|
||||
picture.custom_ptr = (void*)&memory_writer;
|
||||
}
|
||||
} else {
|
||||
out = NULL;
|
||||
if (use_memory_writer) {
|
||||
picture.writer = WebPMemoryWrite;
|
||||
picture.custom_ptr = (void*)&memory_writer;
|
||||
}
|
||||
if (!quiet && !short_output) {
|
||||
fprintf(stderr, "No output file specified (no -o flag). Encoding will\n");
|
||||
fprintf(stderr, "be performed, but its results discarded.\n\n");
|
||||
@ -1042,53 +1014,10 @@ int main(int argc, const char* argv[]) {
|
||||
}
|
||||
}
|
||||
if ((resize_w | resize_h) > 0) {
|
||||
WebPPicture picture_no_alpha;
|
||||
if (config.exact) {
|
||||
// If -exact, we can't premultiply RGB by A otherwise RGB is lost if A=0.
|
||||
// We rescale an opaque copy and assemble scaled A and non-premultiplied
|
||||
// RGB channels. This is slower but it's a very uncommon use case. Color
|
||||
// leak at sharp alpha edges is possible.
|
||||
if (!WebPPictureCopy(&picture, &picture_no_alpha)) {
|
||||
fprintf(stderr, "Error! Cannot copy temporary picture\n");
|
||||
goto Error;
|
||||
}
|
||||
|
||||
// We enforced picture.use_argb = 1 above. Now, remove the alpha values.
|
||||
{
|
||||
int x, y;
|
||||
uint32_t* argb_no_alpha = picture_no_alpha.argb;
|
||||
for (y = 0; y < picture_no_alpha.height; ++y) {
|
||||
for (x = 0; x < picture_no_alpha.width; ++x) {
|
||||
argb_no_alpha[x] |= 0xff000000; // Opaque copy.
|
||||
}
|
||||
argb_no_alpha += picture_no_alpha.argb_stride;
|
||||
}
|
||||
}
|
||||
|
||||
if (!WebPPictureRescale(&picture_no_alpha, resize_w, resize_h)) {
|
||||
fprintf(stderr, "Error! Cannot resize temporary picture\n");
|
||||
goto Error;
|
||||
}
|
||||
}
|
||||
|
||||
if (!WebPPictureRescale(&picture, resize_w, resize_h)) {
|
||||
fprintf(stderr, "Error! Cannot resize picture\n");
|
||||
goto Error;
|
||||
}
|
||||
|
||||
if (config.exact) { // Put back the alpha information.
|
||||
int x, y;
|
||||
uint32_t* argb_no_alpha = picture_no_alpha.argb;
|
||||
uint32_t* argb = picture.argb;
|
||||
for (y = 0; y < picture_no_alpha.height; ++y) {
|
||||
for (x = 0; x < picture_no_alpha.width; ++x) {
|
||||
argb[x] = (argb[x] & 0xff000000) | (argb_no_alpha[x] & 0x00ffffff);
|
||||
}
|
||||
argb_no_alpha += picture_no_alpha.argb_stride;
|
||||
argb += picture.argb_stride;
|
||||
}
|
||||
WebPPictureFree(&picture_no_alpha);
|
||||
}
|
||||
}
|
||||
if (verbose && (crop != 0 || (resize_w | resize_h) > 0)) {
|
||||
const double preproc_time = StopwatchReadAndReset(&stop_watch);
|
||||
@ -1098,12 +1027,8 @@ int main(int argc, const char* argv[]) {
|
||||
if (picture.extra_info_type > 0) {
|
||||
AllocExtraInfo(&picture);
|
||||
}
|
||||
// Save original picture for later comparison. Only for lossy as lossless does
|
||||
// not modify 'picture' (even near-lossless).
|
||||
if (print_distortion >= 0 && !config.lossless &&
|
||||
!WebPPictureCopy(&picture, &original_picture)) {
|
||||
fprintf(stderr, "Error! Cannot copy temporary picture\n");
|
||||
goto Error;
|
||||
if (print_distortion >= 0) { // Save original picture for later comparison
|
||||
WebPPictureCopy(&picture, &original_picture);
|
||||
}
|
||||
|
||||
// Compress.
|
||||
@ -1121,71 +1046,40 @@ int main(int argc, const char* argv[]) {
|
||||
fprintf(stderr, "Time to encode picture: %.3fs\n", encode_time);
|
||||
}
|
||||
|
||||
// Get the decompressed image for the lossless pipeline.
|
||||
if (!quiet && print_distortion >= 0 && config.lossless) {
|
||||
if (config.near_lossless == 100) {
|
||||
// Pure lossless: image was not modified, make 'original_picture' a view
|
||||
// of 'picture' by copying all members except the freeable pointers.
|
||||
original_picture = picture;
|
||||
original_picture.memory_ = original_picture.memory_argb_ = NULL;
|
||||
} else {
|
||||
// Decode the bitstream stored in 'memory_writer' to get the altered image
|
||||
// to 'picture'; save the 'original_picture' beforehand.
|
||||
assert(use_memory_writer);
|
||||
original_picture = picture;
|
||||
if (!WebPPictureInit(&picture)) { // Do not free 'picture'.
|
||||
fprintf(stderr, "Error! Version mismatch!\n");
|
||||
goto Error;
|
||||
}
|
||||
|
||||
picture.use_argb = 1;
|
||||
if (!ReadWebP(memory_writer.mem, memory_writer.size, &picture,
|
||||
/*keep_alpha=*/WebPPictureHasTransparency(&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]);
|
||||
goto Error;
|
||||
}
|
||||
picture.stats = original_picture.stats;
|
||||
}
|
||||
original_picture.stats = NULL;
|
||||
}
|
||||
|
||||
// Write the YUV planes to a PGM file. Only available for lossy.
|
||||
// Write info
|
||||
if (dump_file) {
|
||||
if (picture.use_argb) {
|
||||
fprintf(stderr, "Warning: can't dump file (-d option) "
|
||||
"in lossless mode.\n");
|
||||
fprintf(stderr, "Warning: can't dump file (-d option) in lossless mode.");
|
||||
} else if (!DumpPicture(&picture, dump_file)) {
|
||||
WFPRINTF(stderr, "Warning, couldn't dump picture %s\n",
|
||||
(const W_CHAR*)dump_file);
|
||||
fprintf(stderr, "Warning, couldn't dump picture %s\n", dump_file);
|
||||
}
|
||||
}
|
||||
|
||||
if (use_memory_writer && out != NULL &&
|
||||
!WriteWebPWithMetadata(out, &picture, &memory_writer, &metadata,
|
||||
keep_metadata, &metadata_written)) {
|
||||
fprintf(stderr, "Error writing WebP file!\n");
|
||||
goto Error;
|
||||
}
|
||||
if (keep_metadata != 0) {
|
||||
if (out != NULL) {
|
||||
if (!WriteWebPWithMetadata(out, &picture, &memory_writer,
|
||||
&metadata, keep_metadata, &metadata_written)) {
|
||||
fprintf(stderr, "Error writing WebP file with metadata!\n");
|
||||
goto Error;
|
||||
}
|
||||
} else { // output is disabled, just display the metadata stats.
|
||||
const struct {
|
||||
const MetadataPayload* const payload;
|
||||
int flag;
|
||||
} *iter, info[] = {
|
||||
{ &metadata.exif, METADATA_EXIF },
|
||||
{ &metadata.iccp, METADATA_ICC },
|
||||
{ &metadata.xmp, METADATA_XMP },
|
||||
{ NULL, 0 }
|
||||
};
|
||||
uint32_t unused1 = 0;
|
||||
uint64_t unused2 = 0;
|
||||
|
||||
if (out == NULL && keep_metadata) {
|
||||
// output is disabled, just display the metadata stats.
|
||||
const struct {
|
||||
const MetadataPayload* const payload;
|
||||
int flag;
|
||||
} *iter, info[] = {{&metadata.exif, METADATA_EXIF},
|
||||
{&metadata.iccp, METADATA_ICC},
|
||||
{&metadata.xmp, METADATA_XMP},
|
||||
{NULL, 0}};
|
||||
uint32_t unused1 = 0;
|
||||
uint64_t unused2 = 0;
|
||||
|
||||
for (iter = info; iter->payload != NULL; ++iter) {
|
||||
if (UpdateFlagsAndSize(iter->payload, !!(keep_metadata & iter->flag),
|
||||
/*flag=*/0, &unused1, &unused2)) {
|
||||
metadata_written |= iter->flag;
|
||||
for (iter = info; iter->payload != NULL; ++iter) {
|
||||
if (UpdateFlagsAndSize(iter->payload, !!(keep_metadata & iter->flag),
|
||||
0, &unused1, &unused2)) {
|
||||
metadata_written |= iter->flag;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1225,7 +1119,7 @@ int main(int argc, const char* argv[]) {
|
||||
|
||||
Error:
|
||||
WebPMemoryWriterClear(&memory_writer);
|
||||
WebPFree(picture.extra_info);
|
||||
free(picture.extra_info);
|
||||
MetadataFree(&metadata);
|
||||
WebPPictureFree(&picture);
|
||||
WebPPictureFree(&original_picture);
|
||||
@ -1233,7 +1127,7 @@ int main(int argc, const char* argv[]) {
|
||||
fclose(out);
|
||||
}
|
||||
|
||||
FREE_WARGV_AND_RETURN(return_value);
|
||||
return return_value;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
@ -24,7 +24,6 @@
|
||||
#include "../imageio/image_enc.h"
|
||||
#include "../imageio/webpdec.h"
|
||||
#include "./stopwatch.h"
|
||||
#include "./unicode.h"
|
||||
|
||||
static int verbose = 0;
|
||||
static int quiet = 0;
|
||||
@ -43,7 +42,7 @@ extern void* VP8GetCPUInfo; // opaque forward declaration.
|
||||
|
||||
static int SaveOutput(const WebPDecBuffer* const buffer,
|
||||
WebPOutputFileFormat format, const char* const out_file) {
|
||||
const int use_stdout = (out_file != NULL) && !WSTRCMP(out_file, "-");
|
||||
const int use_stdout = (out_file != NULL) && !strcmp(out_file, "-");
|
||||
int ok = 1;
|
||||
Stopwatch stop_watch;
|
||||
|
||||
@ -57,7 +56,7 @@ static int SaveOutput(const WebPDecBuffer* const buffer,
|
||||
if (use_stdout) {
|
||||
fprintf(stderr, "Saved to stdout\n");
|
||||
} else {
|
||||
WFPRINTF(stderr, "Saved file %s\n", (const W_CHAR*)out_file);
|
||||
fprintf(stderr, "Saved file %s\n", out_file);
|
||||
}
|
||||
}
|
||||
if (verbose) {
|
||||
@ -68,7 +67,7 @@ static int SaveOutput(const WebPDecBuffer* const buffer,
|
||||
if (use_stdout) {
|
||||
fprintf(stderr, "Error writing to stdout !!\n");
|
||||
} else {
|
||||
WFPRINTF(stderr, "Error writing file %s !!\n", (const W_CHAR*)out_file);
|
||||
fprintf(stderr, "Error writing file %s !!\n", out_file);
|
||||
}
|
||||
}
|
||||
return ok;
|
||||
@ -76,8 +75,7 @@ static int SaveOutput(const WebPDecBuffer* const buffer,
|
||||
|
||||
static void Help(void) {
|
||||
printf("Usage: dwebp in_file [options] [-o out_file]\n\n"
|
||||
"Decodes the WebP image file to PNG format [Default].\n"
|
||||
"Note: Animated WebP files are not supported.\n\n"
|
||||
"Decodes the WebP image file to PNG format [Default]\n"
|
||||
"Use following options to convert into alternate image formats:\n"
|
||||
" -pam ......... save the raw RGBA samples as a color PAM\n"
|
||||
" -ppm ......... save the raw RGB samples as a color PPM\n"
|
||||
@ -133,7 +131,7 @@ static uint8_t* AllocateExternalBuffer(WebPDecoderConfig* config,
|
||||
format == RGB_565) ? 2
|
||||
: 4;
|
||||
uint32_t stride = bpp * w + 7; // <- just for exercising
|
||||
external_buffer = (uint8_t*)WebPMalloc(stride * h);
|
||||
external_buffer = (uint8_t*)malloc(stride * h);
|
||||
if (external_buffer == NULL) return NULL;
|
||||
output_buffer->u.RGBA.stride = stride;
|
||||
output_buffer->u.RGBA.size = stride * h;
|
||||
@ -146,7 +144,7 @@ static uint8_t* AllocateExternalBuffer(WebPDecoderConfig* config,
|
||||
uint32_t total_size = stride * h * (has_alpha ? 2 : 1)
|
||||
+ 2 * uv_stride * (h + 1) / 2;
|
||||
assert(format >= YUV && format <= YUVA);
|
||||
external_buffer = (uint8_t*)WebPMalloc(total_size);
|
||||
external_buffer = (uint8_t*)malloc(total_size);
|
||||
if (external_buffer == NULL) return NULL;
|
||||
tmp = external_buffer;
|
||||
output_buffer->u.YUVA.y = tmp;
|
||||
@ -177,10 +175,10 @@ static uint8_t* AllocateExternalBuffer(WebPDecoderConfig* config,
|
||||
return external_buffer;
|
||||
}
|
||||
|
||||
int main(int argc, const char* argv[]) {
|
||||
int main(int argc, const char *argv[]) {
|
||||
int ok = 0;
|
||||
const char* in_file = NULL;
|
||||
const char* out_file = NULL;
|
||||
const char *in_file = NULL;
|
||||
const char *out_file = NULL;
|
||||
|
||||
WebPDecoderConfig config;
|
||||
WebPDecBuffer* const output_buffer = &config.output;
|
||||
@ -193,20 +191,18 @@ int main(int argc, const char* argv[]) {
|
||||
int incremental = 0;
|
||||
int c;
|
||||
|
||||
INIT_WARGV(argc, argv);
|
||||
|
||||
if (!WebPInitDecoderConfig(&config)) {
|
||||
fprintf(stderr, "Library version mismatch!\n");
|
||||
FREE_WARGV_AND_RETURN(-1);
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (c = 1; c < argc; ++c) {
|
||||
int parse_error = 0;
|
||||
if (!strcmp(argv[c], "-h") || !strcmp(argv[c], "-help")) {
|
||||
Help();
|
||||
FREE_WARGV_AND_RETURN(0);
|
||||
return 0;
|
||||
} else if (!strcmp(argv[c], "-o") && c < argc - 1) {
|
||||
out_file = (const char*)GET_WARGV(argv, ++c);
|
||||
out_file = argv[++c];
|
||||
} else if (!strcmp(argv[c], "-alpha")) {
|
||||
format = ALPHA_PLANE_ONLY;
|
||||
} else if (!strcmp(argv[c], "-nofancy")) {
|
||||
@ -227,7 +223,7 @@ int main(int argc, const char* argv[]) {
|
||||
const int version = WebPGetDecoderVersion();
|
||||
printf("%d.%d.%d\n",
|
||||
(version >> 16) & 0xff, (version >> 8) & 0xff, version & 0xff);
|
||||
FREE_WARGV_AND_RETURN(0);
|
||||
return 0;
|
||||
} else if (!strcmp(argv[c], "-pgm")) {
|
||||
format = PGM;
|
||||
} else if (!strcmp(argv[c], "-yuv")) {
|
||||
@ -288,26 +284,26 @@ int main(int argc, const char* argv[]) {
|
||||
} else if (!strcmp(argv[c], "-incremental")) {
|
||||
incremental = 1;
|
||||
} else if (!strcmp(argv[c], "--")) {
|
||||
if (c < argc - 1) in_file = (const char*)GET_WARGV(argv, ++c);
|
||||
if (c < argc - 1) in_file = argv[++c];
|
||||
break;
|
||||
} else if (argv[c][0] == '-') {
|
||||
fprintf(stderr, "Unknown option '%s'\n", argv[c]);
|
||||
Help();
|
||||
FREE_WARGV_AND_RETURN(-1);
|
||||
return -1;
|
||||
} else {
|
||||
in_file = (const char*)GET_WARGV(argv, c);
|
||||
in_file = argv[c];
|
||||
}
|
||||
|
||||
if (parse_error) {
|
||||
Help();
|
||||
FREE_WARGV_AND_RETURN(-1);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (in_file == NULL) {
|
||||
fprintf(stderr, "missing input file!!\n");
|
||||
Help();
|
||||
FREE_WARGV_AND_RETURN(-1);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (quiet) verbose = 0;
|
||||
@ -316,7 +312,7 @@ int main(int argc, const char* argv[]) {
|
||||
VP8StatusCode status = VP8_STATUS_OK;
|
||||
size_t data_size = 0;
|
||||
if (!LoadWebP(in_file, &data, &data_size, bitstream)) {
|
||||
FREE_WARGV_AND_RETURN(-1);
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch (format) {
|
||||
@ -336,8 +332,9 @@ int main(int argc, const char* argv[]) {
|
||||
case BMP:
|
||||
output_buffer->colorspace = bitstream->has_alpha ? MODE_BGRA : MODE_BGR;
|
||||
break;
|
||||
case TIFF:
|
||||
output_buffer->colorspace = bitstream->has_alpha ? MODE_RGBA : MODE_RGB;
|
||||
case TIFF: // note: force pre-multiplied alpha
|
||||
output_buffer->colorspace =
|
||||
bitstream->has_alpha ? MODE_rgbA : MODE_RGB;
|
||||
break;
|
||||
case PGM:
|
||||
case RAW_YUV:
|
||||
@ -393,18 +390,18 @@ int main(int argc, const char* argv[]) {
|
||||
|
||||
if (out_file != NULL) {
|
||||
if (!quiet) {
|
||||
WFPRINTF(stderr, "Decoded %s.", (const W_CHAR*)in_file);
|
||||
fprintf(stderr, " Dimensions: %d x %d %s. Format: %s. Now saving...\n",
|
||||
output_buffer->width, output_buffer->height,
|
||||
fprintf(stderr, "Decoded %s. Dimensions: %d x %d %s. Format: %s. "
|
||||
"Now saving...\n",
|
||||
in_file, output_buffer->width, output_buffer->height,
|
||||
bitstream->has_alpha ? " (with alpha)" : "",
|
||||
kFormatType[bitstream->format]);
|
||||
}
|
||||
ok = SaveOutput(output_buffer, format, out_file);
|
||||
} else {
|
||||
if (!quiet) {
|
||||
WFPRINTF(stderr, "File %s can be decoded ", (const W_CHAR*)in_file);
|
||||
fprintf(stderr, "(dimensions: %d x %d %s. Format: %s).\n",
|
||||
output_buffer->width, output_buffer->height,
|
||||
fprintf(stderr, "File %s can be decoded "
|
||||
"(dimensions: %d x %d %s. Format: %s).\n",
|
||||
in_file, output_buffer->width, output_buffer->height,
|
||||
bitstream->has_alpha ? " (with alpha)" : "",
|
||||
kFormatType[bitstream->format]);
|
||||
fprintf(stderr, "Nothing written; "
|
||||
@ -413,9 +410,9 @@ int main(int argc, const char* argv[]) {
|
||||
}
|
||||
Exit:
|
||||
WebPFreeDecBuffer(output_buffer);
|
||||
WebPFree((void*)external_buffer);
|
||||
WebPFree((void*)data);
|
||||
FREE_WARGV_AND_RETURN(ok ? 0 : -1);
|
||||
free((void*)external_buffer);
|
||||
free((void*)data);
|
||||
return ok ? 0 : -1;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
@ -12,14 +12,10 @@
|
||||
|
||||
#include "./example_util.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "webp/mux_types.h"
|
||||
#include "../imageio/imageio_util.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// String parsing
|
||||
|
||||
@ -60,76 +56,3 @@ float ExUtilGetFloat(const char* const v, int* const error) {
|
||||
}
|
||||
return f;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
static void ResetCommandLineArguments(int argc, const char* argv[],
|
||||
CommandLineArguments* const args) {
|
||||
assert(args != NULL);
|
||||
args->argc_ = argc;
|
||||
args->argv_ = argv;
|
||||
args->own_argv_ = 0;
|
||||
WebPDataInit(&args->argv_data_);
|
||||
}
|
||||
|
||||
void ExUtilDeleteCommandLineArguments(CommandLineArguments* const args) {
|
||||
if (args != NULL) {
|
||||
if (args->own_argv_) {
|
||||
WebPFree((void*)args->argv_);
|
||||
WebPDataClear(&args->argv_data_);
|
||||
}
|
||||
ResetCommandLineArguments(0, NULL, args);
|
||||
}
|
||||
}
|
||||
|
||||
#define MAX_ARGC 16384
|
||||
int ExUtilInitCommandLineArguments(int argc, const char* argv[],
|
||||
CommandLineArguments* const args) {
|
||||
if (args == NULL || argv == NULL) return 0;
|
||||
ResetCommandLineArguments(argc, argv, args);
|
||||
if (argc == 1 && argv[0][0] != '-') {
|
||||
char* cur;
|
||||
const char sep[] = " \t\r\n\f\v";
|
||||
|
||||
#if defined(_WIN32) && defined(_UNICODE)
|
||||
fprintf(stderr,
|
||||
"Error: Reading arguments from a file is a feature unavailable "
|
||||
"with Unicode binaries.\n");
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
if (!ExUtilReadFileToWebPData(argv[0], &args->argv_data_)) {
|
||||
return 0;
|
||||
}
|
||||
args->own_argv_ = 1;
|
||||
args->argv_ = (const char**)WebPMalloc(MAX_ARGC * sizeof(*args->argv_));
|
||||
if (args->argv_ == NULL) return 0;
|
||||
|
||||
argc = 0;
|
||||
for (cur = strtok((char*)args->argv_data_.bytes, sep);
|
||||
cur != NULL;
|
||||
cur = strtok(NULL, sep)) {
|
||||
if (argc == MAX_ARGC) {
|
||||
fprintf(stderr, "ERROR: Arguments limit %d reached\n", MAX_ARGC);
|
||||
return 0;
|
||||
}
|
||||
assert(strlen(cur) != 0);
|
||||
args->argv_[argc++] = cur;
|
||||
}
|
||||
args->argc_ = argc;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
int ExUtilReadFileToWebPData(const char* const filename,
|
||||
WebPData* const webp_data) {
|
||||
const uint8_t* data;
|
||||
size_t size;
|
||||
if (webp_data == NULL) return 0;
|
||||
if (!ImgIoUtilReadFile(filename, &data, &size)) return 0;
|
||||
webp_data->bytes = data;
|
||||
webp_data->size = size;
|
||||
return 1;
|
||||
}
|
||||
|
@ -14,7 +14,6 @@
|
||||
#define WEBP_EXAMPLES_EXAMPLE_UTIL_H_
|
||||
|
||||
#include "webp/types.h"
|
||||
#include "webp/mux_types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -36,33 +35,6 @@ float ExUtilGetFloat(const char* const v, int* const error);
|
||||
// actually parsed is returned, or -1 if an error occurred.
|
||||
int ExUtilGetInts(const char* v, int base, int max_output, int output[]);
|
||||
|
||||
// Reads a file named 'filename' into a WebPData structure. The content of
|
||||
// webp_data is overwritten. Returns false in case of error.
|
||||
int ExUtilReadFileToWebPData(const char* const filename,
|
||||
WebPData* const webp_data);
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Command-line arguments
|
||||
|
||||
typedef struct {
|
||||
int argc_;
|
||||
const char** argv_;
|
||||
WebPData argv_data_;
|
||||
int own_argv_;
|
||||
} CommandLineArguments;
|
||||
|
||||
// Initializes the structure from the command-line parameters. If there is
|
||||
// only one parameter and it does not start with a '-', then it is assumed to
|
||||
// be a file name. This file will be read and tokenized into command-line
|
||||
// arguments. The content of 'args' is overwritten.
|
||||
// Returns false in case of error (memory allocation failure, non
|
||||
// existing file, too many arguments, ...).
|
||||
int ExUtilInitCommandLineArguments(int argc, const char* argv[],
|
||||
CommandLineArguments* const args);
|
||||
|
||||
// Deallocate all memory and reset 'args'.
|
||||
void ExUtilDeleteCommandLineArguments(CommandLineArguments* const args);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
@ -23,22 +23,12 @@
|
||||
|
||||
#ifdef WEBP_HAVE_GIF
|
||||
|
||||
#if defined(HAVE_UNISTD_H) && HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <gif_lib.h>
|
||||
#include "webp/encode.h"
|
||||
#include "webp/mux.h"
|
||||
#include "../examples/example_util.h"
|
||||
#include "../imageio/imageio_util.h"
|
||||
#include "./gifdec.h"
|
||||
#include "./unicode.h"
|
||||
#include "./unicode_gif.h"
|
||||
|
||||
#if !defined(STDIN_FILENO)
|
||||
#define STDIN_FILENO 0
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@ -82,10 +72,8 @@ static void Help(void) {
|
||||
printf(" -metadata <string> ..... comma separated list of metadata to\n");
|
||||
printf(" ");
|
||||
printf("copy from the input to the output if present\n");
|
||||
printf(" ");
|
||||
printf("Valid values: all, none, icc, xmp (default)\n");
|
||||
printf(" -loop_compatibility .... use compatibility mode for Chrome\n");
|
||||
printf(" version prior to M62 (inclusive)\n");
|
||||
printf(" "
|
||||
"Valid values: all, none, icc, xmp (default)\n");
|
||||
printf(" -mt .................... use multi-threading if available\n");
|
||||
printf("\n");
|
||||
printf(" -version ............... print version number and exit\n");
|
||||
@ -96,12 +84,13 @@ static void Help(void) {
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
int main(int argc, const char* argv[]) {
|
||||
int main(int argc, const char *argv[]) {
|
||||
int verbose = 0;
|
||||
int gif_error = GIF_ERROR;
|
||||
WebPMuxError err = WEBP_MUX_OK;
|
||||
int ok = 0;
|
||||
const W_CHAR* in_file = NULL, *out_file = NULL;
|
||||
const char *in_file = NULL, *out_file = NULL;
|
||||
FILE* out = NULL;
|
||||
GifFileType* gif = NULL;
|
||||
int frame_duration = 0;
|
||||
int frame_timestamp = 0;
|
||||
@ -115,7 +104,7 @@ int main(int argc, const char* argv[]) {
|
||||
WebPAnimEncoderOptions enc_options;
|
||||
WebPConfig config;
|
||||
|
||||
int frame_number = 0; // Whether we are processing the first frame.
|
||||
int is_first_frame = 1; // Whether we are processing the first frame.
|
||||
int done;
|
||||
int c;
|
||||
int quiet = 0;
|
||||
@ -126,21 +115,18 @@ int main(int argc, const char* argv[]) {
|
||||
int stored_icc = 0; // Whether we have already stored an ICC profile.
|
||||
WebPData xmp_data;
|
||||
int stored_xmp = 0; // Whether we have already stored an XMP profile.
|
||||
int loop_count = 0; // default: infinite
|
||||
int loop_count = 0;
|
||||
int stored_loop_count = 0; // Whether we have found an explicit loop count.
|
||||
int loop_compatibility = 0;
|
||||
WebPMux* mux = NULL;
|
||||
|
||||
int default_kmin = 1; // Whether to use default kmin value.
|
||||
int default_kmax = 1;
|
||||
|
||||
INIT_WARGV(argc, argv);
|
||||
|
||||
if (!WebPConfigInit(&config) || !WebPAnimEncoderOptionsInit(&enc_options) ||
|
||||
!WebPPictureInit(&frame) || !WebPPictureInit(&curr_canvas) ||
|
||||
!WebPPictureInit(&prev_canvas)) {
|
||||
fprintf(stderr, "Error! Version mismatch!\n");
|
||||
FREE_WARGV_AND_RETURN(-1);
|
||||
return -1;
|
||||
}
|
||||
config.lossless = 1; // Use lossless compression by default.
|
||||
|
||||
@ -150,23 +136,21 @@ int main(int argc, const char* argv[]) {
|
||||
|
||||
if (argc == 1) {
|
||||
Help();
|
||||
FREE_WARGV_AND_RETURN(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (c = 1; c < argc; ++c) {
|
||||
int parse_error = 0;
|
||||
if (!strcmp(argv[c], "-h") || !strcmp(argv[c], "-help")) {
|
||||
Help();
|
||||
FREE_WARGV_AND_RETURN(0);
|
||||
return 0;
|
||||
} else if (!strcmp(argv[c], "-o") && c < argc - 1) {
|
||||
out_file = GET_WARGV(argv, ++c);
|
||||
out_file = argv[++c];
|
||||
} else if (!strcmp(argv[c], "-lossy")) {
|
||||
config.lossless = 0;
|
||||
} else if (!strcmp(argv[c], "-mixed")) {
|
||||
enc_options.allow_mixed = 1;
|
||||
config.lossless = 0;
|
||||
} else if (!strcmp(argv[c], "-loop_compatibility")) {
|
||||
loop_compatibility = 1;
|
||||
} else if (!strcmp(argv[c], "-q") && c < argc - 1) {
|
||||
config.quality = ExUtilGetFloat(argv[++c], &parse_error);
|
||||
} else if (!strcmp(argv[c], "-m") && c < argc - 1) {
|
||||
@ -216,7 +200,7 @@ int main(int argc, const char* argv[]) {
|
||||
fprintf(stderr, "Error! Unknown metadata type '%.*s'\n",
|
||||
(int)(token - start), start);
|
||||
Help();
|
||||
FREE_WARGV_AND_RETURN(-1);
|
||||
return -1;
|
||||
}
|
||||
start = token + 1;
|
||||
}
|
||||
@ -229,7 +213,7 @@ int main(int argc, const char* argv[]) {
|
||||
(enc_version >> 16) & 0xff, (enc_version >> 8) & 0xff,
|
||||
enc_version & 0xff, (mux_version >> 16) & 0xff,
|
||||
(mux_version >> 8) & 0xff, mux_version & 0xff);
|
||||
FREE_WARGV_AND_RETURN(0);
|
||||
return 0;
|
||||
} else if (!strcmp(argv[c], "-quiet")) {
|
||||
quiet = 1;
|
||||
enc_options.verbose = 0;
|
||||
@ -237,19 +221,19 @@ int main(int argc, const char* argv[]) {
|
||||
verbose = 1;
|
||||
enc_options.verbose = 1;
|
||||
} else if (!strcmp(argv[c], "--")) {
|
||||
if (c < argc - 1) in_file = GET_WARGV(argv, ++c);
|
||||
if (c < argc - 1) in_file = argv[++c];
|
||||
break;
|
||||
} else if (argv[c][0] == '-') {
|
||||
fprintf(stderr, "Error! Unknown option '%s'\n", argv[c]);
|
||||
Help();
|
||||
FREE_WARGV_AND_RETURN(-1);
|
||||
return -1;
|
||||
} else {
|
||||
in_file = GET_WARGV(argv, c);
|
||||
in_file = argv[c];
|
||||
}
|
||||
|
||||
if (parse_error) {
|
||||
Help();
|
||||
FREE_WARGV_AND_RETURN(-1);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
@ -273,7 +257,11 @@ int main(int argc, const char* argv[]) {
|
||||
}
|
||||
|
||||
// Start the decoder object
|
||||
gif = DGifOpenFileUnicode(in_file, &gif_error);
|
||||
#if LOCAL_GIF_PREREQ(5,0)
|
||||
gif = DGifOpenFileName(in_file, &gif_error);
|
||||
#else
|
||||
gif = DGifOpenFileName(in_file);
|
||||
#endif
|
||||
if (gif == NULL) goto End;
|
||||
|
||||
// Loop over GIF images
|
||||
@ -289,7 +277,7 @@ int main(int argc, const char* argv[]) {
|
||||
|
||||
if (!DGifGetImageDesc(gif)) goto End;
|
||||
|
||||
if (frame_number == 0) {
|
||||
if (is_first_frame) {
|
||||
if (verbose) {
|
||||
printf("Canvas screen: %d x %d\n", gif->SWidth, gif->SHeight);
|
||||
}
|
||||
@ -331,6 +319,7 @@ int main(int argc, const char* argv[]) {
|
||||
"a memory error.\n");
|
||||
goto End;
|
||||
}
|
||||
is_first_frame = 0;
|
||||
}
|
||||
|
||||
// Some even more broken GIF can have sub-rect with zero width/height.
|
||||
@ -347,25 +336,13 @@ int main(int argc, const char* argv[]) {
|
||||
GIFBlendFrames(&frame, &gif_rect, &curr_canvas);
|
||||
|
||||
if (!WebPAnimEncoderAdd(enc, &curr_canvas, frame_timestamp, &config)) {
|
||||
fprintf(stderr, "Error while adding frame #%d: %s\n", frame_number,
|
||||
WebPAnimEncoderGetError(enc));
|
||||
goto End;
|
||||
} else {
|
||||
++frame_number;
|
||||
fprintf(stderr, "%s\n", WebPAnimEncoderGetError(enc));
|
||||
}
|
||||
|
||||
// Update canvases.
|
||||
GIFDisposeFrame(orig_dispose, &gif_rect, &prev_canvas, &curr_canvas);
|
||||
GIFCopyPixels(&curr_canvas, &prev_canvas);
|
||||
|
||||
// Force frames with a small or no duration to 100ms to be consistent
|
||||
// with web browsers and other transcoding tools. This also avoids
|
||||
// incorrect durations between frames when padding frames are
|
||||
// discarded.
|
||||
if (frame_duration <= 10) {
|
||||
frame_duration = 100;
|
||||
}
|
||||
|
||||
// Update timestamp (for next frame).
|
||||
frame_timestamp += frame_duration;
|
||||
|
||||
@ -379,7 +356,7 @@ int main(int argc, const char* argv[]) {
|
||||
}
|
||||
case EXTENSION_RECORD_TYPE: {
|
||||
int extension;
|
||||
GifByteType* data = NULL;
|
||||
GifByteType *data = NULL;
|
||||
if (DGifGetExtension(gif, &extension, &data) == GIF_ERROR) {
|
||||
goto End;
|
||||
}
|
||||
@ -409,7 +386,7 @@ int main(int argc, const char* argv[]) {
|
||||
if (verbose) {
|
||||
fprintf(stderr, "Loop count: %d\n", loop_count);
|
||||
}
|
||||
stored_loop_count = loop_compatibility ? (loop_count != 0) : 1;
|
||||
stored_loop_count = (loop_count != 0);
|
||||
} else { // An extension containing metadata.
|
||||
// We only store the first encountered chunk of each type, and
|
||||
// only if requested by the user.
|
||||
@ -466,23 +443,6 @@ int main(int argc, const char* argv[]) {
|
||||
goto End;
|
||||
}
|
||||
|
||||
if (!loop_compatibility) {
|
||||
if (!stored_loop_count) {
|
||||
// if no loop-count element is seen, the default is '1' (loop-once)
|
||||
// and we need to signal it explicitly in WebP. Note however that
|
||||
// in case there's a single frame, we still don't need to store it.
|
||||
if (frame_number > 1) {
|
||||
stored_loop_count = 1;
|
||||
loop_count = 1;
|
||||
}
|
||||
} else if (loop_count > 0 && loop_count < 65535) {
|
||||
// adapt GIF's semantic to WebP's (except in the infinite-loop case)
|
||||
loop_count += 1;
|
||||
}
|
||||
}
|
||||
// loop_count of 0 is the default (infinite), so no need to signal it
|
||||
if (loop_count == 0) stored_loop_count = 0;
|
||||
|
||||
if (stored_loop_count || stored_icc || stored_xmp) {
|
||||
// Re-mux to add loop count and/or metadata as needed.
|
||||
mux = WebPMuxCreate(&webp_data, 1);
|
||||
@ -542,19 +502,13 @@ int main(int argc, const char* argv[]) {
|
||||
}
|
||||
|
||||
if (out_file != NULL) {
|
||||
if (!ImgIoUtilWriteFile((const char*)out_file, webp_data.bytes,
|
||||
webp_data.size)) {
|
||||
WFPRINTF(stderr, "Error writing output file: %s\n", out_file);
|
||||
if (!ImgIoUtilWriteFile(out_file, webp_data.bytes, webp_data.size)) {
|
||||
fprintf(stderr, "Error writing output file: %s\n", out_file);
|
||||
goto End;
|
||||
}
|
||||
if (!quiet) {
|
||||
if (!WSTRCMP(out_file, "-")) {
|
||||
fprintf(stderr, "Saved %d bytes to STDIO\n",
|
||||
(int)webp_data.size);
|
||||
} else {
|
||||
WFPRINTF(stderr, "Saved output file (%d bytes): %s\n",
|
||||
(int)webp_data.size, out_file);
|
||||
}
|
||||
fprintf(stderr, "Saved output file (%d bytes): %s\n",
|
||||
(int)webp_data.size, out_file);
|
||||
}
|
||||
} else {
|
||||
if (!quiet) {
|
||||
@ -576,6 +530,7 @@ int main(int argc, const char* argv[]) {
|
||||
WebPPictureFree(&curr_canvas);
|
||||
WebPPictureFree(&prev_canvas);
|
||||
WebPAnimEncoderDelete(enc);
|
||||
if (out != NULL && out_file != NULL) fclose(out);
|
||||
|
||||
if (gif_error != GIF_OK) {
|
||||
GIFDisplayError(gif, gif_error);
|
||||
@ -588,12 +543,12 @@ int main(int argc, const char* argv[]) {
|
||||
#endif
|
||||
}
|
||||
|
||||
FREE_WARGV_AND_RETURN(!ok);
|
||||
return !ok;
|
||||
}
|
||||
|
||||
#else // !WEBP_HAVE_GIF
|
||||
|
||||
int main(int argc, const char* argv[]) {
|
||||
int main(int argc, const char *argv[]) {
|
||||
fprintf(stderr, "GIF support not enabled in %s.\n", argv[0]);
|
||||
(void)argc;
|
||||
return 0;
|
||||
|
@ -28,17 +28,11 @@
|
||||
#define GIF_DISPOSE_SHIFT 2
|
||||
|
||||
// from utils/utils.h
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
extern void WebPCopyPlane(const uint8_t* src, int src_stride,
|
||||
uint8_t* dst, int dst_stride,
|
||||
int width, int height);
|
||||
extern void WebPCopyPixels(const WebPPicture* const src,
|
||||
WebPPicture* const dst);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
void GIFGetBackgroundColor(const ColorMapObject* const color_map,
|
||||
int bgcolor_index, int transparent_index,
|
||||
@ -137,7 +131,7 @@ int GIFReadFrame(GifFileType* const gif, int transparent_index,
|
||||
}
|
||||
dst = sub_image.argb;
|
||||
|
||||
tmp = (uint8_t*)WebPMalloc(rect.width * sizeof(*tmp));
|
||||
tmp = (uint8_t*)malloc(rect.width * sizeof(*tmp));
|
||||
if (tmp == NULL) goto End;
|
||||
|
||||
if (image_desc->Interlace) { // Interlaced image.
|
||||
@ -168,7 +162,7 @@ int GIFReadFrame(GifFileType* const gif, int transparent_index,
|
||||
End:
|
||||
if (!ok) picture->error_code = sub_image.error_code;
|
||||
WebPPictureFree(&sub_image);
|
||||
WebPFree(tmp);
|
||||
free(tmp);
|
||||
return ok;
|
||||
}
|
||||
|
||||
|
@ -27,7 +27,6 @@
|
||||
#include "../imageio/image_dec.h"
|
||||
#include "../imageio/imageio_util.h"
|
||||
#include "./stopwatch.h"
|
||||
#include "./unicode.h"
|
||||
#include "webp/encode.h"
|
||||
#include "webp/mux.h"
|
||||
|
||||
@ -49,7 +48,6 @@ static void Help(void) {
|
||||
printf(" -mixed ............... use mixed lossy/lossless automatic mode\n");
|
||||
printf(" -v ................... verbose mode\n");
|
||||
printf(" -h ................... this help\n");
|
||||
printf(" -version ............. print version number and exit\n");
|
||||
printf("\n");
|
||||
|
||||
printf("Per-frame options (only used for subsequent images input):\n");
|
||||
@ -62,10 +60,6 @@ static void Help(void) {
|
||||
printf("\n");
|
||||
printf("example: img2webp -loop 2 in0.png -lossy in1.jpg\n"
|
||||
" -d 80 in2.tiff -o out.webp\n");
|
||||
printf("\nNote: if a single file name is passed as the argument, the "
|
||||
"arguments will be\n");
|
||||
printf("tokenized from this file. The file name must not start with "
|
||||
"the character '-'.\n");
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@ -84,7 +78,7 @@ static int ReadImage(const char filename[], WebPPicture* const pic) {
|
||||
if (!ImgIoUtilReadFile(filename, &data, &data_size)) return 0;
|
||||
reader = WebPGuessImageReader(data, data_size);
|
||||
ok = reader(data, data_size, pic, 1, NULL);
|
||||
WebPFree((void*)data);
|
||||
free((void*)data);
|
||||
return ok;
|
||||
}
|
||||
|
||||
@ -123,13 +117,14 @@ static int SetLoopCount(int loop_count, WebPData* const webp_data) {
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
int main(int argc, const char* argv[]) {
|
||||
int main(int argc, char* argv[]) {
|
||||
const char* output = NULL;
|
||||
WebPAnimEncoder* enc = NULL;
|
||||
int verbose = 0;
|
||||
int pic_num = 0;
|
||||
int duration = 100;
|
||||
int timestamp_ms = 0;
|
||||
int ok = 1;
|
||||
int loop_count = 0;
|
||||
int width = 0, height = 0;
|
||||
WebPAnimEncoderOptions anim_config;
|
||||
@ -138,33 +133,22 @@ int main(int argc, const char* argv[]) {
|
||||
WebPData webp_data;
|
||||
int c;
|
||||
int have_input = 0;
|
||||
CommandLineArguments cmd_args;
|
||||
int ok;
|
||||
|
||||
INIT_WARGV(argc, argv);
|
||||
|
||||
ok = ExUtilInitCommandLineArguments(argc - 1, argv + 1, &cmd_args);
|
||||
if (!ok) FREE_WARGV_AND_RETURN(1);
|
||||
|
||||
argc = cmd_args.argc_;
|
||||
argv = cmd_args.argv_;
|
||||
|
||||
WebPDataInit(&webp_data);
|
||||
if (!WebPAnimEncoderOptionsInit(&anim_config) ||
|
||||
!WebPConfigInit(&config) ||
|
||||
!WebPPictureInit(&pic)) {
|
||||
fprintf(stderr, "Library version mismatch!\n");
|
||||
ok = 0;
|
||||
goto End;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// 1st pass of option parsing
|
||||
for (c = 0; ok && c < argc; ++c) {
|
||||
for (c = 1; ok && c < argc; ++c) {
|
||||
if (argv[c][0] == '-') {
|
||||
int parse_error = 0;
|
||||
if (!strcmp(argv[c], "-o") && c + 1 < argc) {
|
||||
argv[c] = NULL;
|
||||
output = (const char*)GET_WARGV_SHIFTED(argv, ++c);
|
||||
output = argv[++c];
|
||||
} else if (!strcmp(argv[c], "-kmin") && c + 1 < argc) {
|
||||
argv[c] = NULL;
|
||||
anim_config.kmin = ExUtilGetInt(argv[++c], 0, &parse_error);
|
||||
@ -187,15 +171,7 @@ int main(int argc, const char* argv[]) {
|
||||
verbose = 1;
|
||||
} else if (!strcmp(argv[c], "-h") || !strcmp(argv[c], "-help")) {
|
||||
Help();
|
||||
goto End;
|
||||
} else if (!strcmp(argv[c], "-version")) {
|
||||
const int enc_version = WebPGetEncoderVersion();
|
||||
const int mux_version = WebPGetMuxVersion();
|
||||
printf("WebP Encoder version: %d.%d.%d\nWebP Mux version: %d.%d.%d\n",
|
||||
(enc_version >> 16) & 0xff, (enc_version >> 8) & 0xff,
|
||||
enc_version & 0xff, (mux_version >> 16) & 0xff,
|
||||
(mux_version >> 8) & 0xff, mux_version & 0xff);
|
||||
goto End;
|
||||
return 0;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
@ -208,13 +184,13 @@ int main(int argc, const char* argv[]) {
|
||||
}
|
||||
if (!have_input) {
|
||||
fprintf(stderr, "No input file(s) for generating animation!\n");
|
||||
goto End;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// image-reading pass
|
||||
pic_num = 0;
|
||||
config.lossless = 1;
|
||||
for (c = 0; ok && c < argc; ++c) {
|
||||
for (c = 1; ok && c < argc; ++c) {
|
||||
if (argv[c] == NULL) continue;
|
||||
if (argv[c][0] == '-') { // parse local options
|
||||
int parse_error = 0;
|
||||
@ -251,7 +227,7 @@ int main(int argc, const char* argv[]) {
|
||||
|
||||
// read next input image
|
||||
pic.use_argb = 1;
|
||||
ok = ReadImage((const char*)GET_WARGV_SHIFTED(argv, c), &pic);
|
||||
ok = ReadImage(argv[c], &pic);
|
||||
if (!ok) goto End;
|
||||
|
||||
if (enc == NULL) {
|
||||
@ -283,8 +259,8 @@ int main(int argc, const char* argv[]) {
|
||||
if (!ok) goto End;
|
||||
|
||||
if (verbose) {
|
||||
WFPRINTF(stderr, "Added frame #%3d at time %4d (file: %s)\n",
|
||||
pic_num, timestamp_ms, GET_WARGV_SHIFTED(argv, c));
|
||||
fprintf(stderr, "Added frame #%3d at time %4d (file: %s)\n",
|
||||
pic_num, timestamp_ms, argv[c]);
|
||||
}
|
||||
timestamp_ms += duration;
|
||||
++pic_num;
|
||||
@ -308,7 +284,7 @@ int main(int argc, const char* argv[]) {
|
||||
if (ok) {
|
||||
if (output != NULL) {
|
||||
ok = ImgIoUtilWriteFile(output, webp_data.bytes, webp_data.size);
|
||||
if (ok) WFPRINTF(stderr, "output file: %s ", (const W_CHAR*)output);
|
||||
if (ok) fprintf(stderr, "output file: %s ", output);
|
||||
} else {
|
||||
fprintf(stderr, "[no output file specified] ");
|
||||
}
|
||||
@ -318,7 +294,7 @@ int main(int argc, const char* argv[]) {
|
||||
fprintf(stderr, "[%d frames, %u bytes].\n",
|
||||
pic_num, (unsigned int)webp_data.size);
|
||||
}
|
||||
|
||||
WebPDataClear(&webp_data);
|
||||
ExUtilDeleteCommandLineArguments(&cmd_args);
|
||||
FREE_WARGV_AND_RETURN(ok ? 0 : 1);
|
||||
return ok ? 0 : 1;
|
||||
}
|
||||
|
@ -60,4 +60,4 @@ static WEBP_INLINE double StopwatchReadAndReset(Stopwatch* watch) {
|
||||
|
||||
#endif /* _WIN32 */
|
||||
|
||||
#endif // WEBP_EXAMPLES_STOPWATCH_H_
|
||||
#endif /* WEBP_EXAMPLES_STOPWATCH_H_ */
|
||||
|
@ -1,102 +0,0 @@
|
||||
// Copyright 2018 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.
|
||||
// -----------------------------------------------------------------------------
|
||||
//
|
||||
// Unicode support for Windows. The main idea is to maintain an array of Unicode
|
||||
// arguments (wargv) and use it only for file paths. The regular argv is used
|
||||
// for everything else.
|
||||
//
|
||||
// Author: Yannis Guyon (yguyon@google.com)
|
||||
|
||||
#ifndef WEBP_EXAMPLES_UNICODE_H_
|
||||
#define WEBP_EXAMPLES_UNICODE_H_
|
||||
|
||||
#if defined(_WIN32) && defined(_UNICODE)
|
||||
|
||||
// wchar_t is used instead of TCHAR because we only perform additional work when
|
||||
// Unicode is enabled and because the output of CommandLineToArgvW() is wchar_t.
|
||||
|
||||
#include <wchar.h>
|
||||
#include <windows.h>
|
||||
#include <shellapi.h>
|
||||
|
||||
// Create a wchar_t array containing Unicode parameters.
|
||||
#define INIT_WARGV(ARGC, ARGV) \
|
||||
int wargc; \
|
||||
const W_CHAR** const wargv = \
|
||||
(const W_CHAR**)CommandLineToArgvW(GetCommandLineW(), &wargc); \
|
||||
do { \
|
||||
if (wargv == NULL || wargc != (ARGC)) { \
|
||||
fprintf(stderr, "Error: Unable to get Unicode arguments.\n"); \
|
||||
FREE_WARGV_AND_RETURN(-1); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
// Use this to get a Unicode argument (e.g. file path).
|
||||
#define GET_WARGV(UNUSED, C) wargv[C]
|
||||
// For cases where argv is shifted by one compared to wargv.
|
||||
#define GET_WARGV_SHIFTED(UNUSED, C) wargv[(C) + 1]
|
||||
#define GET_WARGV_OR_NULL() wargv
|
||||
|
||||
// Release resources. LocalFree() is needed after CommandLineToArgvW().
|
||||
#define FREE_WARGV() LOCAL_FREE((W_CHAR** const)wargv)
|
||||
#define LOCAL_FREE(WARGV) \
|
||||
do { \
|
||||
if ((WARGV) != NULL) LocalFree(WARGV); \
|
||||
} while (0)
|
||||
|
||||
#define W_CHAR wchar_t // WCHAR without underscore might already be defined.
|
||||
#define TO_W_CHAR(STR) (L##STR)
|
||||
|
||||
#define WFOPEN(ARG, OPT) _wfopen((const W_CHAR*)ARG, TO_W_CHAR(OPT))
|
||||
|
||||
#define WPRINTF(STR, ...) wprintf(TO_W_CHAR(STR), __VA_ARGS__)
|
||||
#define WFPRINTF(STDERR, STR, ...) fwprintf(STDERR, TO_W_CHAR(STR), __VA_ARGS__)
|
||||
|
||||
#define WSTRLEN(FILENAME) wcslen((const W_CHAR*)FILENAME)
|
||||
#define WSTRCMP(FILENAME, STR) wcscmp((const W_CHAR*)FILENAME, TO_W_CHAR(STR))
|
||||
#define WSTRRCHR(FILENAME, STR) wcsrchr((const W_CHAR*)FILENAME, TO_W_CHAR(STR))
|
||||
#define WSNPRINTF(A, B, STR, ...) _snwprintf(A, B, TO_W_CHAR(STR), __VA_ARGS__)
|
||||
|
||||
#else
|
||||
|
||||
// Unicode file paths work as is on Unix platforms, and no extra work is done on
|
||||
// Windows either if Unicode is disabled.
|
||||
|
||||
#define INIT_WARGV(ARGC, ARGV)
|
||||
|
||||
#define GET_WARGV(ARGV, C) (ARGV)[C]
|
||||
#define GET_WARGV_SHIFTED(ARGV, C) (ARGV)[C]
|
||||
#define GET_WARGV_OR_NULL() NULL
|
||||
|
||||
#define FREE_WARGV()
|
||||
#define LOCAL_FREE(WARGV)
|
||||
|
||||
#define W_CHAR char
|
||||
#define TO_W_CHAR(STR) (STR)
|
||||
|
||||
#define WFOPEN(ARG, OPT) fopen(ARG, OPT)
|
||||
|
||||
#define WPRINTF(STR, ...) printf(STR, __VA_ARGS__)
|
||||
#define WFPRINTF(STDERR, STR, ...) fprintf(STDERR, STR, __VA_ARGS__)
|
||||
|
||||
#define WSTRLEN(FILENAME) strlen(FILENAME)
|
||||
#define WSTRCMP(FILENAME, STR) strcmp(FILENAME, STR)
|
||||
#define WSTRRCHR(FILENAME, STR) strrchr(FILENAME, STR)
|
||||
#define WSNPRINTF(A, B, STR, ...) snprintf(A, B, STR, __VA_ARGS__)
|
||||
|
||||
#endif // defined(_WIN32) && defined(_UNICODE)
|
||||
|
||||
// Don't forget to free wargv before returning (e.g. from main).
|
||||
#define FREE_WARGV_AND_RETURN(VALUE) \
|
||||
do { \
|
||||
FREE_WARGV(); \
|
||||
return (VALUE); \
|
||||
} while (0)
|
||||
|
||||
#endif // WEBP_EXAMPLES_UNICODE_H_
|
@ -1,75 +0,0 @@
|
||||
// Copyright 2018 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.
|
||||
// -----------------------------------------------------------------------------
|
||||
//
|
||||
// giflib doesn't have a Unicode DGifOpenFileName(). Let's make one.
|
||||
//
|
||||
// Author: Yannis Guyon (yguyon@google.com)
|
||||
|
||||
#ifndef WEBP_EXAMPLES_UNICODE_GIF_H_
|
||||
#define WEBP_EXAMPLES_UNICODE_GIF_H_
|
||||
|
||||
#include "./unicode.h"
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "webp/config.h" // For WEBP_HAVE_GIF
|
||||
#endif
|
||||
|
||||
#if defined(WEBP_HAVE_GIF)
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <fcntl.h> // Not standard, needed for _topen and flags.
|
||||
#include <io.h>
|
||||
#endif
|
||||
|
||||
#include <gif_lib.h>
|
||||
#include <string.h>
|
||||
#include "./gifdec.h"
|
||||
|
||||
#if !defined(STDIN_FILENO)
|
||||
#define STDIN_FILENO 0
|
||||
#endif
|
||||
|
||||
static GifFileType* DGifOpenFileUnicode(const W_CHAR* file_name, int* error) {
|
||||
if (!WSTRCMP(file_name, "-")) {
|
||||
#if LOCAL_GIF_PREREQ(5, 0)
|
||||
return DGifOpenFileHandle(STDIN_FILENO, error);
|
||||
#else
|
||||
(void)error;
|
||||
return DGifOpenFileHandle(STDIN_FILENO);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(_WIN32) && defined(_UNICODE)
|
||||
|
||||
int file_handle = _wopen(file_name, _O_RDONLY | _O_BINARY);
|
||||
if (file_handle == -1) {
|
||||
if (error != NULL) *error = D_GIF_ERR_OPEN_FAILED;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if LOCAL_GIF_PREREQ(5, 0)
|
||||
return DGifOpenFileHandle(file_handle, error);
|
||||
#else
|
||||
return DGifOpenFileHandle(file_handle);
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
#if LOCAL_GIF_PREREQ(5, 0)
|
||||
return DGifOpenFileName(file_name, error);
|
||||
#else
|
||||
return DGifOpenFileName(file_name);
|
||||
#endif
|
||||
|
||||
#endif // defined(_WIN32) && defined(_UNICODE)
|
||||
// DGifCloseFile() is called later.
|
||||
}
|
||||
|
||||
#endif // defined(WEBP_HAVE_GIF)
|
||||
|
||||
#endif // WEBP_EXAMPLES_UNICODE_GIF_H_
|
203
examples/vwebp.c
203
examples/vwebp.c
@ -42,7 +42,6 @@
|
||||
|
||||
#include "../examples/example_util.h"
|
||||
#include "../imageio/imageio_util.h"
|
||||
#include "./unicode.h"
|
||||
|
||||
#if defined(_MSC_VER) && _MSC_VER < 1900
|
||||
#define snprintf _snprintf
|
||||
@ -57,7 +56,6 @@ static struct {
|
||||
int print_info;
|
||||
int only_deltas;
|
||||
int use_color_profile;
|
||||
int draw_anim_background_color;
|
||||
|
||||
int canvas_width, canvas_height;
|
||||
int loop_count;
|
||||
@ -207,11 +205,6 @@ static void decode_callback(int what) {
|
||||
}
|
||||
}
|
||||
duration = curr->duration;
|
||||
// Behavior copied from Chrome, cf:
|
||||
// https://cs.chromium.org/chromium/src/third_party/WebKit/Source/
|
||||
// platform/graphics/DeferredImageDecoder.cpp?
|
||||
// rcl=b4c33049f096cd283f32be9a58b9a9e768227c26&l=246
|
||||
if (duration <= 10) duration = 100;
|
||||
}
|
||||
if (!Decode()) {
|
||||
kParams.decoding_error = 1;
|
||||
@ -227,9 +220,6 @@ static void decode_callback(int what) {
|
||||
// Callbacks
|
||||
|
||||
static void HandleKey(unsigned char key, int pos_x, int pos_y) {
|
||||
// Note: rescaling the window or toggling some features during an animation
|
||||
// generates visual artifacts. This is not fixed because refreshing the frame
|
||||
// may require rendering the whole animation from start till current frame.
|
||||
(void)pos_x;
|
||||
(void)pos_y;
|
||||
if (key == 'q' || key == 'Q' || key == 27 /* Esc */) {
|
||||
@ -257,12 +247,10 @@ static void HandleKey(unsigned char key, int pos_x, int pos_y) {
|
||||
glutPostRedisplay();
|
||||
}
|
||||
}
|
||||
} else if (key == 'b') {
|
||||
kParams.draw_anim_background_color = 1 - kParams.draw_anim_background_color;
|
||||
if (!kParams.has_animation) ClearPreviousFrame();
|
||||
glutPostRedisplay();
|
||||
} else if (key == 'i') {
|
||||
kParams.print_info = 1 - kParams.print_info;
|
||||
// TODO(skal): handle refresh of animation's last-frame too. It's quite
|
||||
// more involved though (need to save the previous frame).
|
||||
if (!kParams.has_animation) ClearPreviousFrame();
|
||||
glutPostRedisplay();
|
||||
} else if (key == 'd') {
|
||||
@ -272,8 +260,8 @@ static void HandleKey(unsigned char key, int pos_x, int pos_y) {
|
||||
}
|
||||
|
||||
static void HandleReshape(int width, int height) {
|
||||
// Note: reshape doesn't preserve aspect ratio, and might
|
||||
// be handling larger-than-screen pictures incorrectly.
|
||||
// TODO(skal): should we preserve aspect ratio?
|
||||
// Also: handle larger-than-screen pictures correctly.
|
||||
glViewport(0, 0, width, height);
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
@ -293,7 +281,7 @@ static void PrintString(const char* const text) {
|
||||
}
|
||||
|
||||
static float GetColorf(uint32_t color, int shift) {
|
||||
return ((color >> shift) & 0xff) / 255.f;
|
||||
return (color >> shift) / 255.f;
|
||||
}
|
||||
|
||||
static void DrawCheckerBoard(void) {
|
||||
@ -316,43 +304,6 @@ static void DrawCheckerBoard(void) {
|
||||
glPopMatrix();
|
||||
}
|
||||
|
||||
static void DrawBackground(void) {
|
||||
// Whole window cleared with clear color, checkerboard rendered on top of it.
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
DrawCheckerBoard();
|
||||
|
||||
// ANIM background color rendered (blend) on top. Default is white for still
|
||||
// images (without ANIM chunk). glClear() can't be used for that (no blend).
|
||||
if (kParams.draw_anim_background_color) {
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
glColor4f(GetColorf(kParams.bg_color, 16), // BGRA from spec
|
||||
GetColorf(kParams.bg_color, 8),
|
||||
GetColorf(kParams.bg_color, 0),
|
||||
GetColorf(kParams.bg_color, 24));
|
||||
glRecti(-1, -1, +1, +1);
|
||||
glPopMatrix();
|
||||
}
|
||||
}
|
||||
|
||||
// Draw background in a scissored rectangle.
|
||||
static void DrawBackgroundScissored(int window_x, int window_y, int frame_w,
|
||||
int frame_h) {
|
||||
// Only update the requested area, not the whole canvas.
|
||||
window_x = window_x * kParams.viewport_width / kParams.canvas_width;
|
||||
window_y = window_y * kParams.viewport_height / kParams.canvas_height;
|
||||
frame_w = frame_w * kParams.viewport_width / kParams.canvas_width;
|
||||
frame_h = frame_h * kParams.viewport_height / kParams.canvas_height;
|
||||
|
||||
// glScissor() takes window coordinates (0,0 at bottom left).
|
||||
window_y = kParams.viewport_height - window_y - frame_h;
|
||||
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
glScissor(window_x, window_y, frame_w, frame_h);
|
||||
DrawBackground();
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
}
|
||||
|
||||
static void HandleDisplay(void) {
|
||||
const WebPDecBuffer* const pic = kParams.pic;
|
||||
const WebPIterator* const curr = &kParams.curr_frame;
|
||||
@ -369,21 +320,38 @@ static void HandleDisplay(void) {
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, pic->u.RGBA.stride / 4);
|
||||
|
||||
if (kParams.only_deltas) {
|
||||
DrawBackground();
|
||||
} else {
|
||||
// The rectangle of the previous frame might be different than the current
|
||||
// frame, so we may need to DrawBackgroundScissored for both.
|
||||
DrawCheckerBoard();
|
||||
} else if (prev->dispose_method == WEBP_MUX_DISPOSE_BACKGROUND ||
|
||||
curr->blend_method == WEBP_MUX_NO_BLEND) {
|
||||
// glScissor() takes window coordinates (0,0 at bottom left).
|
||||
int window_x, window_y;
|
||||
int frame_w, frame_h;
|
||||
if (prev->dispose_method == WEBP_MUX_DISPOSE_BACKGROUND) {
|
||||
// Clear the previous frame rectangle.
|
||||
DrawBackgroundScissored(prev->x_offset, prev->y_offset, prev->width,
|
||||
prev->height);
|
||||
}
|
||||
if (curr->blend_method == WEBP_MUX_NO_BLEND) {
|
||||
window_x = prev->x_offset;
|
||||
window_y = kParams.canvas_height - prev->y_offset - prev->height;
|
||||
frame_w = prev->width;
|
||||
frame_h = prev->height;
|
||||
} else { // curr->blend_method == WEBP_MUX_NO_BLEND.
|
||||
// We simulate no-blending behavior by first clearing the current frame
|
||||
// rectangle and then alpha-blending against it.
|
||||
DrawBackgroundScissored(curr->x_offset, curr->y_offset, curr->width,
|
||||
curr->height);
|
||||
// rectangle (to a checker-board) and then alpha-blending against it.
|
||||
window_x = curr->x_offset;
|
||||
window_y = kParams.canvas_height - curr->y_offset - curr->height;
|
||||
frame_w = curr->width;
|
||||
frame_h = curr->height;
|
||||
}
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
// Only update the requested area, not the whole canvas.
|
||||
window_x = window_x * kParams.viewport_width / kParams.canvas_width;
|
||||
window_y = window_y * kParams.viewport_height / kParams.canvas_height;
|
||||
frame_w = frame_w * kParams.viewport_width / kParams.canvas_width;
|
||||
frame_h = frame_h * kParams.viewport_height / kParams.canvas_height;
|
||||
glScissor(window_x, window_y, frame_w, frame_h);
|
||||
|
||||
glClear(GL_COLOR_BUFFER_BIT); // use clear color
|
||||
DrawCheckerBoard();
|
||||
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
}
|
||||
|
||||
*prev = *curr;
|
||||
@ -410,36 +378,13 @@ static void HandleDisplay(void) {
|
||||
}
|
||||
}
|
||||
glPopMatrix();
|
||||
#if defined(__APPLE__) || defined(_WIN32)
|
||||
glFlush();
|
||||
#else
|
||||
glutSwapBuffers();
|
||||
#endif
|
||||
}
|
||||
|
||||
static void StartDisplay(void) {
|
||||
int width = kParams.canvas_width;
|
||||
int height = kParams.canvas_height;
|
||||
int screen_width, screen_height;
|
||||
// TODO(webp:365) GLUT_DOUBLE results in flickering / old frames to be
|
||||
// partially displayed with animated webp + alpha.
|
||||
#if defined(__APPLE__) || defined(_WIN32)
|
||||
const int width = kParams.canvas_width;
|
||||
const int height = kParams.canvas_height;
|
||||
glutInitDisplayMode(GLUT_RGBA);
|
||||
#else
|
||||
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);
|
||||
#endif
|
||||
screen_width = glutGet(GLUT_SCREEN_WIDTH);
|
||||
screen_height = glutGet(GLUT_SCREEN_HEIGHT);
|
||||
if (width > screen_width || height > screen_height) {
|
||||
if (width > screen_width) {
|
||||
height = (height * screen_width + width - 1) / width;
|
||||
width = screen_width;
|
||||
}
|
||||
if (height > screen_height) {
|
||||
width = (width * screen_height + height - 1) / height;
|
||||
height = screen_height;
|
||||
}
|
||||
}
|
||||
glutInitWindowSize(width, height);
|
||||
glutCreateWindow("WebP viewer");
|
||||
glutDisplayFunc(HandleDisplay);
|
||||
@ -448,59 +393,57 @@ static void StartDisplay(void) {
|
||||
glutKeyboardFunc(HandleKey);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glEnable(GL_BLEND);
|
||||
glClearColor(0, 0, 0, 0); // window will be cleared to black (no blend)
|
||||
DrawBackground();
|
||||
glClearColor(GetColorf(kParams.bg_color, 0),
|
||||
GetColorf(kParams.bg_color, 8),
|
||||
GetColorf(kParams.bg_color, 16),
|
||||
GetColorf(kParams.bg_color, 24));
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
DrawCheckerBoard();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Main
|
||||
|
||||
static void Help(void) {
|
||||
printf(
|
||||
"Usage: vwebp in_file [options]\n\n"
|
||||
"Decodes the WebP image file and visualize it using OpenGL\n"
|
||||
"Options are:\n"
|
||||
" -version ..... print version number and exit\n"
|
||||
" -noicc ....... don't use the icc profile if present\n"
|
||||
" -nofancy ..... don't use the fancy YUV420 upscaler\n"
|
||||
" -nofilter .... disable in-loop filtering\n"
|
||||
" -dither <int> dithering strength (0..100), default=50\n"
|
||||
" -noalphadither disable alpha plane dithering\n"
|
||||
" -usebgcolor .. display background color\n"
|
||||
" -mt .......... use multi-threading\n"
|
||||
" -info ........ print info\n"
|
||||
" -h ........... this help message\n"
|
||||
"\n"
|
||||
"Keyboard shortcuts:\n"
|
||||
" 'c' ................ toggle use of color profile\n"
|
||||
" 'b' ................ toggle background color display\n"
|
||||
" 'i' ................ overlay file information\n"
|
||||
" 'd' ................ disable blending & disposal (debug)\n"
|
||||
" 'q' / 'Q' / ESC .... quit\n");
|
||||
printf("Usage: vwebp in_file [options]\n\n"
|
||||
"Decodes the WebP image file and visualize it using OpenGL\n"
|
||||
"Options are:\n"
|
||||
" -version ..... print version number and exit\n"
|
||||
" -noicc ....... don't use the icc profile if present\n"
|
||||
" -nofancy ..... don't use the fancy YUV420 upscaler\n"
|
||||
" -nofilter .... disable in-loop filtering\n"
|
||||
" -dither <int> dithering strength (0..100), default=50\n"
|
||||
" -noalphadither disable alpha plane dithering\n"
|
||||
" -mt .......... use multi-threading\n"
|
||||
" -info ........ print info\n"
|
||||
" -h ........... this help message\n"
|
||||
"\n"
|
||||
"Keyboard shortcuts:\n"
|
||||
" 'c' ................ toggle use of color profile\n"
|
||||
" 'i' ................ overlay file information\n"
|
||||
" 'd' ................ disable blending & disposal (debug)\n"
|
||||
" 'q' / 'Q' / ESC .... quit\n"
|
||||
);
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
int main(int argc, char *argv[]) {
|
||||
int c;
|
||||
WebPDecoderConfig* const config = &kParams.config;
|
||||
WebPIterator* const curr = &kParams.curr_frame;
|
||||
|
||||
INIT_WARGV(argc, argv);
|
||||
|
||||
if (!WebPInitDecoderConfig(config)) {
|
||||
fprintf(stderr, "Library version mismatch!\n");
|
||||
FREE_WARGV_AND_RETURN(-1);
|
||||
return -1;
|
||||
}
|
||||
config->options.dithering_strength = 50;
|
||||
config->options.alpha_dithering_strength = 100;
|
||||
kParams.use_color_profile = 1;
|
||||
// Background color hidden by default to see transparent areas.
|
||||
kParams.draw_anim_background_color = 0;
|
||||
|
||||
for (c = 1; c < argc; ++c) {
|
||||
int parse_error = 0;
|
||||
if (!strcmp(argv[c], "-h") || !strcmp(argv[c], "-help")) {
|
||||
Help();
|
||||
FREE_WARGV_AND_RETURN(0);
|
||||
return 0;
|
||||
} else if (!strcmp(argv[c], "-noicc")) {
|
||||
kParams.use_color_profile = 0;
|
||||
} else if (!strcmp(argv[c], "-nofancy")) {
|
||||
@ -509,8 +452,6 @@ int main(int argc, char* argv[]) {
|
||||
config->options.bypass_filtering = 1;
|
||||
} else if (!strcmp(argv[c], "-noalphadither")) {
|
||||
config->options.alpha_dithering_strength = 0;
|
||||
} else if (!strcmp(argv[c], "-usebgcolor")) {
|
||||
kParams.draw_anim_background_color = 1;
|
||||
} else if (!strcmp(argv[c], "-dither") && c + 1 < argc) {
|
||||
config->options.dithering_strength =
|
||||
ExUtilGetInt(argv[++c], 0, &parse_error);
|
||||
@ -523,30 +464,30 @@ int main(int argc, char* argv[]) {
|
||||
(dec_version >> 16) & 0xff, (dec_version >> 8) & 0xff,
|
||||
dec_version & 0xff, (dmux_version >> 16) & 0xff,
|
||||
(dmux_version >> 8) & 0xff, dmux_version & 0xff);
|
||||
FREE_WARGV_AND_RETURN(0);
|
||||
return 0;
|
||||
} else if (!strcmp(argv[c], "-mt")) {
|
||||
config->options.use_threads = 1;
|
||||
} else if (!strcmp(argv[c], "--")) {
|
||||
if (c < argc - 1) kParams.file_name = (const char*)GET_WARGV(argv, ++c);
|
||||
if (c < argc - 1) kParams.file_name = argv[++c];
|
||||
break;
|
||||
} else if (argv[c][0] == '-') {
|
||||
printf("Unknown option '%s'\n", argv[c]);
|
||||
Help();
|
||||
FREE_WARGV_AND_RETURN(-1);
|
||||
return -1;
|
||||
} else {
|
||||
kParams.file_name = (const char*)GET_WARGV(argv, c);
|
||||
kParams.file_name = argv[c];
|
||||
}
|
||||
|
||||
if (parse_error) {
|
||||
Help();
|
||||
FREE_WARGV_AND_RETURN(-1);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (kParams.file_name == NULL) {
|
||||
printf("missing input file!!\n");
|
||||
Help();
|
||||
FREE_WARGV_AND_RETURN(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!ImgIoUtilReadFile(kParams.file_name,
|
||||
@ -621,16 +562,16 @@ int main(int argc, char* argv[]) {
|
||||
|
||||
// Should only be reached when using FREEGLUT:
|
||||
ClearParams();
|
||||
FREE_WARGV_AND_RETURN(0);
|
||||
return 0;
|
||||
|
||||
Error:
|
||||
ClearParams();
|
||||
FREE_WARGV_AND_RETURN(-1);
|
||||
return -1;
|
||||
}
|
||||
|
||||
#else // !WEBP_HAVE_GL
|
||||
|
||||
int main(int argc, const char* argv[]) {
|
||||
int main(int argc, const char *argv[]) {
|
||||
fprintf(stderr, "OpenGL support not enabled in %s.\n", argv[0]);
|
||||
(void)argc;
|
||||
return 0;
|
||||
|
1182
examples/webpinfo.c
1182
examples/webpinfo.c
File diff suppressed because it is too large
Load Diff
@ -26,7 +26,6 @@
|
||||
webpmux -set icc image_profile.icc in.webp -o out_icc_container.webp
|
||||
webpmux -set exif image_metadata.exif in.webp -o out_exif_container.webp
|
||||
webpmux -set xmp image_metadata.xmp in.webp -o out_xmp_container.webp
|
||||
webpmux -set loop 1 in.webp -o out_looped.webp
|
||||
|
||||
Extract relevant data from WebP container file:
|
||||
webpmux -get frame n in.webp -o out_frame.webp
|
||||
@ -48,7 +47,6 @@
|
||||
webpmux -info in.webp
|
||||
webpmux [ -h | -help ]
|
||||
webpmux -version
|
||||
webpmux argument_file_name
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
@ -63,7 +61,6 @@
|
||||
#include "webp/mux.h"
|
||||
#include "../examples/example_util.h"
|
||||
#include "../imageio/imageio_util.h"
|
||||
#include "./unicode.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Config object to parse command-line arguments.
|
||||
@ -98,7 +95,6 @@ typedef enum {
|
||||
FEATURE_ICCP,
|
||||
FEATURE_ANMF,
|
||||
FEATURE_DURATION,
|
||||
FEATURE_LOOP,
|
||||
LAST_FEATURE
|
||||
} FeatureType;
|
||||
|
||||
@ -112,26 +108,28 @@ static const char* const kDescriptions[LAST_FEATURE] = {
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
CommandLineArguments cmd_args_;
|
||||
|
||||
ActionType action_type_;
|
||||
const char* input_;
|
||||
const char* output_;
|
||||
FeatureType type_;
|
||||
FeatureArg* args_;
|
||||
int arg_count_;
|
||||
} Config;
|
||||
} Feature;
|
||||
|
||||
typedef struct {
|
||||
ActionType action_type_;
|
||||
const char* input_;
|
||||
const char* output_;
|
||||
Feature feature_;
|
||||
} WebPMuxConfig;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Helper functions.
|
||||
|
||||
static int CountOccurrences(const CommandLineArguments* const args,
|
||||
const char* const arg) {
|
||||
static int CountOccurrences(const char* arglist[], int list_length,
|
||||
const char* arg) {
|
||||
int i;
|
||||
int num_occurences = 0;
|
||||
|
||||
for (i = 0; i < args->argc_; ++i) {
|
||||
if (!strcmp(args->argv_[i], arg)) {
|
||||
for (i = 0; i < list_length; ++i) {
|
||||
if (!strcmp(arglist[i], arg)) {
|
||||
++num_occurences;
|
||||
}
|
||||
}
|
||||
@ -303,7 +301,6 @@ static void PrintHelp(void) {
|
||||
printf(" webpmux -info INPUT\n");
|
||||
printf(" webpmux [-h|-help]\n");
|
||||
printf(" webpmux -version\n");
|
||||
printf(" webpmux argument_file_name\n");
|
||||
|
||||
printf("\n");
|
||||
printf("GET_OPTIONS:\n");
|
||||
@ -316,7 +313,6 @@ static void PrintHelp(void) {
|
||||
printf("\n");
|
||||
printf("SET_OPTIONS:\n");
|
||||
printf(" Set color profile/metadata:\n");
|
||||
printf(" loop LOOP_COUNT set the loop count\n");
|
||||
printf(" icc file.icc set ICC profile\n");
|
||||
printf(" exif file.exif set EXIF metadata\n");
|
||||
printf(" xmp file.xmp set XMP metadata\n");
|
||||
@ -373,10 +369,6 @@ static void PrintHelp(void) {
|
||||
|
||||
printf("\nNote: The nature of EXIF, XMP and ICC data is not checked");
|
||||
printf(" and is assumed to be\nvalid.\n");
|
||||
printf("\nNote: if a single file name is passed as the argument, the "
|
||||
"arguments will be\n");
|
||||
printf("tokenized from this file. The file name must not start with "
|
||||
"the character '-'.\n");
|
||||
}
|
||||
|
||||
static void WarnAboutOddOffset(const WebPMuxFrameInfo* const info) {
|
||||
@ -387,32 +379,40 @@ static void WarnAboutOddOffset(const WebPMuxFrameInfo* const info) {
|
||||
}
|
||||
}
|
||||
|
||||
static int ReadFileToWebPData(const char* const filename,
|
||||
WebPData* const webp_data) {
|
||||
const uint8_t* data;
|
||||
size_t size;
|
||||
if (!ImgIoUtilReadFile(filename, &data, &size)) return 0;
|
||||
webp_data->bytes = data;
|
||||
webp_data->size = size;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int CreateMux(const char* const filename, WebPMux** mux) {
|
||||
WebPData bitstream;
|
||||
assert(mux != NULL);
|
||||
if (!ExUtilReadFileToWebPData(filename, &bitstream)) return 0;
|
||||
if (!ReadFileToWebPData(filename, &bitstream)) return 0;
|
||||
*mux = WebPMuxCreate(&bitstream, 1);
|
||||
WebPDataClear(&bitstream);
|
||||
free((void*)bitstream.bytes);
|
||||
if (*mux != NULL) return 1;
|
||||
WFPRINTF(stderr, "Failed to create mux object from file %s.\n",
|
||||
(const W_CHAR*)filename);
|
||||
fprintf(stderr, "Failed to create mux object from file %s.\n", filename);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int WriteData(const char* filename, const WebPData* const webpdata) {
|
||||
int ok = 0;
|
||||
FILE* fout = WSTRCMP(filename, "-") ? WFOPEN(filename, "wb")
|
||||
: ImgIoUtilSetBinaryMode(stdout);
|
||||
FILE* fout = strcmp(filename, "-") ? fopen(filename, "wb")
|
||||
: ImgIoUtilSetBinaryMode(stdout);
|
||||
if (fout == NULL) {
|
||||
WFPRINTF(stderr, "Error opening output WebP file %s!\n",
|
||||
(const W_CHAR*)filename);
|
||||
fprintf(stderr, "Error opening output WebP file %s!\n", filename);
|
||||
return 0;
|
||||
}
|
||||
if (fwrite(webpdata->bytes, webpdata->size, 1, fout) != 1) {
|
||||
WFPRINTF(stderr, "Error writing file %s!\n", (const W_CHAR*)filename);
|
||||
fprintf(stderr, "Error writing file %s!\n", filename);
|
||||
} else {
|
||||
WFPRINTF(stderr, "Saved file %s (%d bytes)\n",
|
||||
(const W_CHAR*)filename, (int)webpdata->size);
|
||||
fprintf(stderr, "Saved file %s (%d bytes)\n",
|
||||
filename, (int)webpdata->size);
|
||||
ok = 1;
|
||||
}
|
||||
if (fout != stdout) fclose(fout);
|
||||
@ -517,10 +517,9 @@ static int ParseBgcolorArgs(const char* args, uint32_t* const bgcolor) {
|
||||
//------------------------------------------------------------------------------
|
||||
// Clean-up.
|
||||
|
||||
static void DeleteConfig(Config* const config) {
|
||||
static void DeleteConfig(WebPMuxConfig* config) {
|
||||
if (config != NULL) {
|
||||
free(config->args_);
|
||||
ExUtilDeleteCommandLineArguments(&config->cmd_args_);
|
||||
free(config->feature_.args_);
|
||||
memset(config, 0, sizeof(*config));
|
||||
}
|
||||
}
|
||||
@ -532,7 +531,7 @@ static void DeleteConfig(Config* const config) {
|
||||
// Returns 1 on valid, 0 otherwise.
|
||||
// Also fills up num_feature_args to be number of feature arguments given.
|
||||
// (e.g. if there are 4 '-frame's and 1 '-loop', then num_feature_args = 5).
|
||||
static int ValidateCommandLine(const CommandLineArguments* const cmd_args,
|
||||
static int ValidateCommandLine(int argc, const char* argv[],
|
||||
int* num_feature_args) {
|
||||
int num_frame_args;
|
||||
int num_loop_args;
|
||||
@ -544,27 +543,27 @@ static int ValidateCommandLine(const CommandLineArguments* const cmd_args,
|
||||
*num_feature_args = 0;
|
||||
|
||||
// Simple checks.
|
||||
if (CountOccurrences(cmd_args, "-get") > 1) {
|
||||
if (CountOccurrences(argv, argc, "-get") > 1) {
|
||||
ERROR_GOTO1("ERROR: Multiple '-get' arguments specified.\n", ErrValidate);
|
||||
}
|
||||
if (CountOccurrences(cmd_args, "-set") > 1) {
|
||||
if (CountOccurrences(argv, argc, "-set") > 1) {
|
||||
ERROR_GOTO1("ERROR: Multiple '-set' arguments specified.\n", ErrValidate);
|
||||
}
|
||||
if (CountOccurrences(cmd_args, "-strip") > 1) {
|
||||
if (CountOccurrences(argv, argc, "-strip") > 1) {
|
||||
ERROR_GOTO1("ERROR: Multiple '-strip' arguments specified.\n", ErrValidate);
|
||||
}
|
||||
if (CountOccurrences(cmd_args, "-info") > 1) {
|
||||
if (CountOccurrences(argv, argc, "-info") > 1) {
|
||||
ERROR_GOTO1("ERROR: Multiple '-info' arguments specified.\n", ErrValidate);
|
||||
}
|
||||
if (CountOccurrences(cmd_args, "-o") > 1) {
|
||||
if (CountOccurrences(argv, argc, "-o") > 1) {
|
||||
ERROR_GOTO1("ERROR: Multiple output files specified.\n", ErrValidate);
|
||||
}
|
||||
|
||||
// Compound checks.
|
||||
num_frame_args = CountOccurrences(cmd_args, "-frame");
|
||||
num_loop_args = CountOccurrences(cmd_args, "-loop");
|
||||
num_bgcolor_args = CountOccurrences(cmd_args, "-bgcolor");
|
||||
num_durations_args = CountOccurrences(cmd_args, "-duration");
|
||||
num_frame_args = CountOccurrences(argv, argc, "-frame");
|
||||
num_loop_args = CountOccurrences(argv, argc, "-loop");
|
||||
num_bgcolor_args = CountOccurrences(argv, argc, "-bgcolor");
|
||||
num_durations_args = CountOccurrences(argv, argc, "-duration");
|
||||
|
||||
if (num_loop_args > 1) {
|
||||
ERROR_GOTO1("ERROR: Multiple loop counts specified.\n", ErrValidate);
|
||||
@ -599,38 +598,31 @@ static int ValidateCommandLine(const CommandLineArguments* const cmd_args,
|
||||
|
||||
#define ACTION_IS_NIL (config->action_type_ == NIL_ACTION)
|
||||
|
||||
#define FEATURETYPE_IS_NIL (config->type_ == NIL_FEATURE)
|
||||
#define FEATURETYPE_IS_NIL (feature->type_ == NIL_FEATURE)
|
||||
|
||||
#define CHECK_NUM_ARGS_AT_LEAST(NUM, LABEL) \
|
||||
#define CHECK_NUM_ARGS_LESS(NUM, LABEL) \
|
||||
if (argc < i + (NUM)) { \
|
||||
fprintf(stderr, "ERROR: Too few arguments for '%s'.\n", argv[i]); \
|
||||
goto LABEL; \
|
||||
}
|
||||
|
||||
#define CHECK_NUM_ARGS_AT_MOST(NUM, LABEL) \
|
||||
if (argc > i + (NUM)) { \
|
||||
#define CHECK_NUM_ARGS_NOT_EQUAL(NUM, LABEL) \
|
||||
if (argc != i + (NUM)) { \
|
||||
fprintf(stderr, "ERROR: Too many arguments for '%s'.\n", argv[i]); \
|
||||
goto LABEL; \
|
||||
}
|
||||
|
||||
#define CHECK_NUM_ARGS_EXACTLY(NUM, LABEL) \
|
||||
CHECK_NUM_ARGS_AT_LEAST(NUM, LABEL); \
|
||||
CHECK_NUM_ARGS_AT_MOST(NUM, LABEL);
|
||||
|
||||
// Parses command-line arguments to fill up config object. Also performs some
|
||||
// semantic checks. unicode_argv contains wchar_t arguments or is null.
|
||||
static int ParseCommandLine(Config* config, const W_CHAR** const unicode_argv) {
|
||||
// semantic checks.
|
||||
static int ParseCommandLine(int argc, const char* argv[],
|
||||
WebPMuxConfig* config) {
|
||||
int i = 0;
|
||||
int feature_arg_index = 0;
|
||||
int ok = 1;
|
||||
int argc = config->cmd_args_.argc_;
|
||||
const char* const* argv = config->cmd_args_.argv_;
|
||||
// Unicode file paths will be used if available.
|
||||
const char* const* wargv =
|
||||
(unicode_argv != NULL) ? (const char**)(unicode_argv + 1) : argv;
|
||||
|
||||
while (i < argc) {
|
||||
FeatureArg* const arg = &config->args_[feature_arg_index];
|
||||
Feature* const feature = &config->feature_;
|
||||
FeatureArg* const arg = &feature->args_[feature_arg_index];
|
||||
if (argv[i][0] == '-') { // One of the action types or output.
|
||||
if (!strcmp(argv[i], "-set")) {
|
||||
if (ACTION_IS_NIL) {
|
||||
@ -640,14 +632,14 @@ static int ParseCommandLine(Config* config, const W_CHAR** const unicode_argv) {
|
||||
}
|
||||
++i;
|
||||
} else if (!strcmp(argv[i], "-duration")) {
|
||||
CHECK_NUM_ARGS_AT_LEAST(2, ErrParse);
|
||||
CHECK_NUM_ARGS_LESS(2, ErrParse);
|
||||
if (ACTION_IS_NIL || config->action_type_ == ACTION_DURATION) {
|
||||
config->action_type_ = ACTION_DURATION;
|
||||
} else {
|
||||
ERROR_GOTO1("ERROR: Multiple actions specified.\n", ErrParse);
|
||||
}
|
||||
if (FEATURETYPE_IS_NIL || config->type_ == FEATURE_DURATION) {
|
||||
config->type_ = FEATURE_DURATION;
|
||||
if (FEATURETYPE_IS_NIL || feature->type_ == FEATURE_DURATION) {
|
||||
feature->type_ = FEATURE_DURATION;
|
||||
} else {
|
||||
ERROR_GOTO1("ERROR: Multiple features specified.\n", ErrParse);
|
||||
}
|
||||
@ -664,20 +656,20 @@ static int ParseCommandLine(Config* config, const W_CHAR** const unicode_argv) {
|
||||
} else if (!strcmp(argv[i], "-strip")) {
|
||||
if (ACTION_IS_NIL) {
|
||||
config->action_type_ = ACTION_STRIP;
|
||||
config->arg_count_ = 0;
|
||||
feature->arg_count_ = 0;
|
||||
} else {
|
||||
ERROR_GOTO1("ERROR: Multiple actions specified.\n", ErrParse);
|
||||
}
|
||||
++i;
|
||||
} else if (!strcmp(argv[i], "-frame")) {
|
||||
CHECK_NUM_ARGS_AT_LEAST(3, ErrParse);
|
||||
CHECK_NUM_ARGS_LESS(3, ErrParse);
|
||||
if (ACTION_IS_NIL || config->action_type_ == ACTION_SET) {
|
||||
config->action_type_ = ACTION_SET;
|
||||
} else {
|
||||
ERROR_GOTO1("ERROR: Multiple actions specified.\n", ErrParse);
|
||||
}
|
||||
if (FEATURETYPE_IS_NIL || config->type_ == FEATURE_ANMF) {
|
||||
config->type_ = FEATURE_ANMF;
|
||||
if (FEATURETYPE_IS_NIL || feature->type_ == FEATURE_ANMF) {
|
||||
feature->type_ = FEATURE_ANMF;
|
||||
} else {
|
||||
ERROR_GOTO1("ERROR: Multiple features specified.\n", ErrParse);
|
||||
}
|
||||
@ -687,14 +679,14 @@ static int ParseCommandLine(Config* config, const W_CHAR** const unicode_argv) {
|
||||
++feature_arg_index;
|
||||
i += 3;
|
||||
} else if (!strcmp(argv[i], "-loop") || !strcmp(argv[i], "-bgcolor")) {
|
||||
CHECK_NUM_ARGS_AT_LEAST(2, ErrParse);
|
||||
CHECK_NUM_ARGS_LESS(2, ErrParse);
|
||||
if (ACTION_IS_NIL || config->action_type_ == ACTION_SET) {
|
||||
config->action_type_ = ACTION_SET;
|
||||
} else {
|
||||
ERROR_GOTO1("ERROR: Multiple actions specified.\n", ErrParse);
|
||||
}
|
||||
if (FEATURETYPE_IS_NIL || config->type_ == FEATURE_ANMF) {
|
||||
config->type_ = FEATURE_ANMF;
|
||||
if (FEATURETYPE_IS_NIL || feature->type_ == FEATURE_ANMF) {
|
||||
feature->type_ = FEATURE_ANMF;
|
||||
} else {
|
||||
ERROR_GOTO1("ERROR: Multiple features specified.\n", ErrParse);
|
||||
}
|
||||
@ -704,36 +696,34 @@ static int ParseCommandLine(Config* config, const W_CHAR** const unicode_argv) {
|
||||
++feature_arg_index;
|
||||
i += 2;
|
||||
} else if (!strcmp(argv[i], "-o")) {
|
||||
CHECK_NUM_ARGS_AT_LEAST(2, ErrParse);
|
||||
config->output_ = wargv[i + 1];
|
||||
CHECK_NUM_ARGS_LESS(2, ErrParse);
|
||||
config->output_ = argv[i + 1];
|
||||
i += 2;
|
||||
} else if (!strcmp(argv[i], "-info")) {
|
||||
CHECK_NUM_ARGS_EXACTLY(2, ErrParse);
|
||||
CHECK_NUM_ARGS_NOT_EQUAL(2, ErrParse);
|
||||
if (config->action_type_ != NIL_ACTION) {
|
||||
ERROR_GOTO1("ERROR: Multiple actions specified.\n", ErrParse);
|
||||
} else {
|
||||
config->action_type_ = ACTION_INFO;
|
||||
config->arg_count_ = 0;
|
||||
config->input_ = wargv[i + 1];
|
||||
feature->arg_count_ = 0;
|
||||
config->input_ = argv[i + 1];
|
||||
}
|
||||
i += 2;
|
||||
} else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "-help")) {
|
||||
PrintHelp();
|
||||
DeleteConfig(config);
|
||||
LOCAL_FREE((W_CHAR** const)unicode_argv);
|
||||
exit(0);
|
||||
} else if (!strcmp(argv[i], "-version")) {
|
||||
const int version = WebPGetMuxVersion();
|
||||
printf("%d.%d.%d\n",
|
||||
(version >> 16) & 0xff, (version >> 8) & 0xff, version & 0xff);
|
||||
DeleteConfig(config);
|
||||
LOCAL_FREE((W_CHAR** const)unicode_argv);
|
||||
exit(0);
|
||||
} else if (!strcmp(argv[i], "--")) {
|
||||
if (i < argc - 1) {
|
||||
++i;
|
||||
if (config->input_ == NULL) {
|
||||
config->input_ = wargv[i];
|
||||
config->input_ = argv[i];
|
||||
} else {
|
||||
ERROR_GOTO2("ERROR at '%s': Multiple input files specified.\n",
|
||||
argv[i], ErrParse);
|
||||
@ -751,14 +741,14 @@ static int ParseCommandLine(Config* config, const W_CHAR** const unicode_argv) {
|
||||
if (!strcmp(argv[i], "icc") || !strcmp(argv[i], "exif") ||
|
||||
!strcmp(argv[i], "xmp")) {
|
||||
if (FEATURETYPE_IS_NIL) {
|
||||
config->type_ = (!strcmp(argv[i], "icc")) ? FEATURE_ICCP :
|
||||
feature->type_ = (!strcmp(argv[i], "icc")) ? FEATURE_ICCP :
|
||||
(!strcmp(argv[i], "exif")) ? FEATURE_EXIF : FEATURE_XMP;
|
||||
} else {
|
||||
ERROR_GOTO1("ERROR: Multiple features specified.\n", ErrParse);
|
||||
}
|
||||
if (config->action_type_ == ACTION_SET) {
|
||||
CHECK_NUM_ARGS_AT_LEAST(2, ErrParse);
|
||||
arg->filename_ = wargv[i + 1];
|
||||
CHECK_NUM_ARGS_LESS(2, ErrParse);
|
||||
arg->filename_ = argv[i + 1];
|
||||
++feature_arg_index;
|
||||
i += 2;
|
||||
} else {
|
||||
@ -766,21 +756,14 @@ static int ParseCommandLine(Config* config, const W_CHAR** const unicode_argv) {
|
||||
}
|
||||
} else if (!strcmp(argv[i], "frame") &&
|
||||
(config->action_type_ == ACTION_GET)) {
|
||||
CHECK_NUM_ARGS_AT_LEAST(2, ErrParse);
|
||||
config->type_ = FEATURE_ANMF;
|
||||
arg->params_ = argv[i + 1];
|
||||
++feature_arg_index;
|
||||
i += 2;
|
||||
} else if (!strcmp(argv[i], "loop") &&
|
||||
(config->action_type_ == ACTION_SET)) {
|
||||
CHECK_NUM_ARGS_AT_LEAST(2, ErrParse);
|
||||
config->type_ = FEATURE_LOOP;
|
||||
CHECK_NUM_ARGS_LESS(2, ErrParse);
|
||||
feature->type_ = FEATURE_ANMF;
|
||||
arg->params_ = argv[i + 1];
|
||||
++feature_arg_index;
|
||||
i += 2;
|
||||
} else { // Assume input file.
|
||||
if (config->input_ == NULL) {
|
||||
config->input_ = wargv[i];
|
||||
config->input_ = argv[i];
|
||||
} else {
|
||||
ERROR_GOTO2("ERROR at '%s': Multiple input files specified.\n",
|
||||
argv[i], ErrParse);
|
||||
@ -794,8 +777,9 @@ static int ParseCommandLine(Config* config, const W_CHAR** const unicode_argv) {
|
||||
}
|
||||
|
||||
// Additional checks after config is filled.
|
||||
static int ValidateConfig(Config* const config) {
|
||||
static int ValidateConfig(WebPMuxConfig* config) {
|
||||
int ok = 1;
|
||||
Feature* const feature = &config->feature_;
|
||||
|
||||
// Action.
|
||||
if (ACTION_IS_NIL) {
|
||||
@ -811,7 +795,7 @@ static int ValidateConfig(Config* const config) {
|
||||
if (config->input_ == NULL) {
|
||||
if (config->action_type_ != ACTION_SET) {
|
||||
ERROR_GOTO1("ERROR: No input file specified.\n", ErrValidate2);
|
||||
} else if (config->type_ != FEATURE_ANMF) {
|
||||
} else if (feature->type_ != FEATURE_ANMF) {
|
||||
ERROR_GOTO1("ERROR: No input file specified.\n", ErrValidate2);
|
||||
}
|
||||
}
|
||||
@ -826,29 +810,28 @@ static int ValidateConfig(Config* const config) {
|
||||
}
|
||||
|
||||
// Create config object from command-line arguments.
|
||||
static int InitializeConfig(int argc, const char* argv[], Config* const config,
|
||||
const W_CHAR** const unicode_argv) {
|
||||
static int InitializeConfig(int argc, const char* argv[],
|
||||
WebPMuxConfig* config) {
|
||||
int num_feature_args = 0;
|
||||
int ok;
|
||||
int ok = 1;
|
||||
|
||||
assert(config != NULL);
|
||||
memset(config, 0, sizeof(*config));
|
||||
|
||||
ok = ExUtilInitCommandLineArguments(argc, argv, &config->cmd_args_);
|
||||
if (!ok) return 0;
|
||||
|
||||
// Validate command-line arguments.
|
||||
if (!ValidateCommandLine(&config->cmd_args_, &num_feature_args)) {
|
||||
if (!ValidateCommandLine(argc, argv, &num_feature_args)) {
|
||||
ERROR_GOTO1("Exiting due to command-line parsing error.\n", Err1);
|
||||
}
|
||||
|
||||
config->arg_count_ = num_feature_args;
|
||||
config->args_ = (FeatureArg*)calloc(num_feature_args, sizeof(*config->args_));
|
||||
if (config->args_ == NULL) {
|
||||
config->feature_.arg_count_ = num_feature_args;
|
||||
config->feature_.args_ =
|
||||
(FeatureArg*)calloc(num_feature_args, sizeof(*config->feature_.args_));
|
||||
if (config->feature_.args_ == NULL) {
|
||||
ERROR_GOTO1("ERROR: Memory allocation error.\n", Err1);
|
||||
}
|
||||
|
||||
// Parse command-line.
|
||||
if (!ParseCommandLine(config, unicode_argv) || !ValidateConfig(config)) {
|
||||
if (!ParseCommandLine(argc, argv, config) || !ValidateConfig(config)) {
|
||||
ERROR_GOTO1("Exiting due to command-line parsing error.\n", Err1);
|
||||
}
|
||||
|
||||
@ -858,14 +841,13 @@ static int InitializeConfig(int argc, const char* argv[], Config* const config,
|
||||
|
||||
#undef ACTION_IS_NIL
|
||||
#undef FEATURETYPE_IS_NIL
|
||||
#undef CHECK_NUM_ARGS_AT_LEAST
|
||||
#undef CHECK_NUM_ARGS_AT_MOST
|
||||
#undef CHECK_NUM_ARGS_EXACTLY
|
||||
#undef CHECK_NUM_ARGS_LESS
|
||||
#undef CHECK_NUM_ARGS_MORE
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Processing.
|
||||
|
||||
static int GetFrame(const WebPMux* mux, const Config* config) {
|
||||
static int GetFrame(const WebPMux* mux, const WebPMuxConfig* config) {
|
||||
WebPMuxError err = WEBP_MUX_OK;
|
||||
WebPMux* mux_single = NULL;
|
||||
int num = 0;
|
||||
@ -875,7 +857,7 @@ static int GetFrame(const WebPMux* mux, const Config* config) {
|
||||
WebPMuxFrameInfo info;
|
||||
WebPDataInit(&info.bitstream);
|
||||
|
||||
num = ExUtilGetInt(config->args_[0].params_, 10, &parse_error);
|
||||
num = ExUtilGetInt(config->feature_.args_[0].params_, 10, &parse_error);
|
||||
if (num < 0) {
|
||||
ERROR_GOTO1("ERROR: Frame/Fragment index must be non-negative.\n", ErrGet);
|
||||
}
|
||||
@ -909,17 +891,18 @@ static int GetFrame(const WebPMux* mux, const Config* config) {
|
||||
}
|
||||
|
||||
// Read and process config.
|
||||
static int Process(const Config* config) {
|
||||
static int Process(const WebPMuxConfig* config) {
|
||||
WebPMux* mux = NULL;
|
||||
WebPData chunk;
|
||||
WebPMuxError err = WEBP_MUX_OK;
|
||||
int ok = 1;
|
||||
const Feature* const feature = &config->feature_;
|
||||
|
||||
switch (config->action_type_) {
|
||||
case ACTION_GET: {
|
||||
ok = CreateMux(config->input_, &mux);
|
||||
if (!ok) goto Err2;
|
||||
switch (config->type_) {
|
||||
switch (feature->type_) {
|
||||
case FEATURE_ANMF:
|
||||
ok = GetFrame(mux, config);
|
||||
break;
|
||||
@ -927,10 +910,10 @@ static int Process(const Config* config) {
|
||||
case FEATURE_ICCP:
|
||||
case FEATURE_EXIF:
|
||||
case FEATURE_XMP:
|
||||
err = WebPMuxGetChunk(mux, kFourccList[config->type_], &chunk);
|
||||
err = WebPMuxGetChunk(mux, kFourccList[feature->type_], &chunk);
|
||||
if (err != WEBP_MUX_OK) {
|
||||
ERROR_GOTO3("ERROR (%s): Could not get the %s.\n",
|
||||
ErrorString(err), kDescriptions[config->type_], Err2);
|
||||
ErrorString(err), kDescriptions[feature->type_], Err2);
|
||||
}
|
||||
ok = WriteData(config->output_, &chunk);
|
||||
break;
|
||||
@ -942,7 +925,7 @@ static int Process(const Config* config) {
|
||||
break;
|
||||
}
|
||||
case ACTION_SET: {
|
||||
switch (config->type_) {
|
||||
switch (feature->type_) {
|
||||
case FEATURE_ANMF: {
|
||||
int i;
|
||||
WebPMuxAnimParams params = { 0xFFFFFFFF, 0 };
|
||||
@ -951,11 +934,11 @@ static int Process(const Config* config) {
|
||||
ERROR_GOTO2("ERROR (%s): Could not allocate a mux object.\n",
|
||||
ErrorString(WEBP_MUX_MEMORY_ERROR), Err2);
|
||||
}
|
||||
for (i = 0; i < config->arg_count_; ++i) {
|
||||
switch (config->args_[i].subtype_) {
|
||||
for (i = 0; i < feature->arg_count_; ++i) {
|
||||
switch (feature->args_[i].subtype_) {
|
||||
case SUBTYPE_BGCOLOR: {
|
||||
uint32_t bgcolor;
|
||||
ok = ParseBgcolorArgs(config->args_[i].params_, &bgcolor);
|
||||
ok = ParseBgcolorArgs(feature->args_[i].params_, &bgcolor);
|
||||
if (!ok) {
|
||||
ERROR_GOTO1("ERROR: Could not parse the background color \n",
|
||||
Err2);
|
||||
@ -966,7 +949,7 @@ static int Process(const Config* config) {
|
||||
case SUBTYPE_LOOP: {
|
||||
int parse_error = 0;
|
||||
const int loop_count =
|
||||
ExUtilGetInt(config->args_[i].params_, 10, &parse_error);
|
||||
ExUtilGetInt(feature->args_[i].params_, 10, &parse_error);
|
||||
if (loop_count < 0 || loop_count > 65535) {
|
||||
// Note: This is only a 'necessary' condition for loop_count
|
||||
// to be valid. The 'sufficient' conditioned in checked in
|
||||
@ -982,10 +965,10 @@ static int Process(const Config* config) {
|
||||
case SUBTYPE_ANMF: {
|
||||
WebPMuxFrameInfo frame;
|
||||
frame.id = WEBP_CHUNK_ANMF;
|
||||
ok = ExUtilReadFileToWebPData(config->args_[i].filename_,
|
||||
&frame.bitstream);
|
||||
ok = ReadFileToWebPData(feature->args_[i].filename_,
|
||||
&frame.bitstream);
|
||||
if (!ok) goto Err2;
|
||||
ok = ParseFrameArgs(config->args_[i].params_, &frame);
|
||||
ok = ParseFrameArgs(feature->args_[i].params_, &frame);
|
||||
if (!ok) {
|
||||
WebPDataClear(&frame.bitstream);
|
||||
ERROR_GOTO1("ERROR: Could not parse frame properties.\n",
|
||||
@ -1018,38 +1001,13 @@ static int Process(const Config* config) {
|
||||
case FEATURE_XMP: {
|
||||
ok = CreateMux(config->input_, &mux);
|
||||
if (!ok) goto Err2;
|
||||
ok = ExUtilReadFileToWebPData(config->args_[0].filename_, &chunk);
|
||||
ok = ReadFileToWebPData(feature->args_[0].filename_, &chunk);
|
||||
if (!ok) goto Err2;
|
||||
err = WebPMuxSetChunk(mux, kFourccList[config->type_], &chunk, 1);
|
||||
WebPDataClear(&chunk);
|
||||
err = WebPMuxSetChunk(mux, kFourccList[feature->type_], &chunk, 1);
|
||||
free((void*)chunk.bytes);
|
||||
if (err != WEBP_MUX_OK) {
|
||||
ERROR_GOTO3("ERROR (%s): Could not set the %s.\n",
|
||||
ErrorString(err), kDescriptions[config->type_], Err2);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case FEATURE_LOOP: {
|
||||
WebPMuxAnimParams params = { 0xFFFFFFFF, 0 };
|
||||
int parse_error = 0;
|
||||
const int loop_count =
|
||||
ExUtilGetInt(config->args_[0].params_, 10, &parse_error);
|
||||
if (loop_count < 0 || loop_count > 65535 || parse_error) {
|
||||
ERROR_GOTO1("ERROR: Loop count must be in the range 0 to 65535.\n",
|
||||
Err2);
|
||||
}
|
||||
ok = CreateMux(config->input_, &mux);
|
||||
if (!ok) goto Err2;
|
||||
ok = (WebPMuxGetAnimationParams(mux, ¶ms) == WEBP_MUX_OK);
|
||||
if (!ok) {
|
||||
ERROR_GOTO1("ERROR: input file does not seem to be an animation.\n",
|
||||
Err2);
|
||||
}
|
||||
params.loop_count = loop_count;
|
||||
err = WebPMuxSetAnimationParams(mux, ¶ms);
|
||||
ok = (err == WEBP_MUX_OK);
|
||||
if (!ok) {
|
||||
ERROR_GOTO2("ERROR (%s): Could not set animation parameters.\n",
|
||||
ErrorString(err), Err2);
|
||||
ErrorString(err), kDescriptions[feature->type_], Err2);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -1080,16 +1038,16 @@ static int Process(const Config* config) {
|
||||
int* durations = NULL;
|
||||
WebPMux* new_mux = DuplicateMuxHeader(mux);
|
||||
if (new_mux == NULL) goto Err2;
|
||||
durations = (int*)WebPMalloc((size_t)num_frames * sizeof(*durations));
|
||||
durations = (int*)malloc((size_t)num_frames * sizeof(*durations));
|
||||
if (durations == NULL) goto Err2;
|
||||
for (i = 0; i < num_frames; ++i) durations[i] = -1;
|
||||
|
||||
// Parse intervals to process.
|
||||
for (i = 0; i < config->arg_count_; ++i) {
|
||||
for (i = 0; i < feature->arg_count_; ++i) {
|
||||
int k;
|
||||
int args[3];
|
||||
int duration, start, end;
|
||||
const int nb_args = ExUtilGetInts(config->args_[i].params_,
|
||||
const int nb_args = ExUtilGetInts(feature->args_[i].params_,
|
||||
10, 3, args);
|
||||
ok = (nb_args >= 1);
|
||||
if (!ok) goto Err3;
|
||||
@ -1138,7 +1096,7 @@ static int Process(const Config* config) {
|
||||
new_mux = NULL;
|
||||
|
||||
Err3:
|
||||
WebPFree(durations);
|
||||
free(durations);
|
||||
WebPMuxDelete(new_mux);
|
||||
if (!ok) goto Err2;
|
||||
}
|
||||
@ -1147,12 +1105,12 @@ static int Process(const Config* config) {
|
||||
case ACTION_STRIP: {
|
||||
ok = CreateMux(config->input_, &mux);
|
||||
if (!ok) goto Err2;
|
||||
if (config->type_ == FEATURE_ICCP || config->type_ == FEATURE_EXIF ||
|
||||
config->type_ == FEATURE_XMP) {
|
||||
err = WebPMuxDeleteChunk(mux, kFourccList[config->type_]);
|
||||
if (feature->type_ == FEATURE_ICCP || feature->type_ == FEATURE_EXIF ||
|
||||
feature->type_ == FEATURE_XMP) {
|
||||
err = WebPMuxDeleteChunk(mux, kFourccList[feature->type_]);
|
||||
if (err != WEBP_MUX_OK) {
|
||||
ERROR_GOTO3("ERROR (%s): Could not strip the %s.\n",
|
||||
ErrorString(err), kDescriptions[config->type_], Err2);
|
||||
ErrorString(err), kDescriptions[feature->type_], Err2);
|
||||
}
|
||||
} else {
|
||||
ERROR_GOTO1("ERROR: Invalid feature for action 'strip'.\n", Err2);
|
||||
@ -1182,19 +1140,15 @@ static int Process(const Config* config) {
|
||||
// Main.
|
||||
|
||||
int main(int argc, const char* argv[]) {
|
||||
Config config;
|
||||
int ok;
|
||||
|
||||
INIT_WARGV(argc, argv);
|
||||
|
||||
ok = InitializeConfig(argc - 1, argv + 1, &config, GET_WARGV_OR_NULL());
|
||||
WebPMuxConfig config;
|
||||
int ok = InitializeConfig(argc - 1, argv + 1, &config);
|
||||
if (ok) {
|
||||
ok = Process(&config);
|
||||
} else {
|
||||
PrintHelp();
|
||||
}
|
||||
DeleteConfig(&config);
|
||||
FREE_WARGV_AND_RETURN(!ok);
|
||||
return !ok;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
@ -1,4 +1,3 @@
|
||||
AM_CPPFLAGS += -I$(top_builddir) -I$(top_srcdir)
|
||||
AM_CPPFLAGS += -I$(top_builddir)/src -I$(top_srcdir)/src
|
||||
noinst_LTLIBRARIES = libwebpextras.la
|
||||
|
||||
@ -12,33 +11,16 @@ libwebpextras_la_CPPFLAGS = $(AM_CPPFLAGS)
|
||||
libwebpextras_la_LDFLAGS = -lm
|
||||
libwebpextras_la_LIBADD = ../src/libwebp.la
|
||||
|
||||
noinst_PROGRAMS =
|
||||
noinst_PROGRAMS += webp_quality
|
||||
if BUILD_DEMUX
|
||||
noinst_PROGRAMS += get_disto
|
||||
endif
|
||||
if BUILD_VWEBP_SDL
|
||||
noinst_PROGRAMS += vwebp_sdl
|
||||
endif
|
||||
noinst_PROGRAMS = get_disto webp_quality
|
||||
|
||||
get_disto_SOURCES = get_disto.c
|
||||
get_disto_CPPFLAGS = $(AM_CPPFLAGS)
|
||||
get_disto_LDADD =
|
||||
get_disto_LDADD += ../imageio/libimageio_util.la
|
||||
get_disto_LDADD += ../imageio/libimagedec.la
|
||||
get_disto_SOURCES = get_disto.c
|
||||
get_disto_CPPFLAGS = $(AM_CPPFLAGS)
|
||||
get_disto_LDADD = ../imageio/libimageio_util.la ../imageio/libimagedec.la
|
||||
get_disto_LDADD += ../src/libwebp.la
|
||||
get_disto_LDADD += $(PNG_LIBS) $(JPEG_LIBS) $(TIFF_LIBS)
|
||||
|
||||
webp_quality_SOURCES = webp_quality.c
|
||||
webp_quality_CPPFLAGS = $(AM_CPPFLAGS)
|
||||
webp_quality_LDADD =
|
||||
webp_quality_LDADD += ../imageio/libimageio_util.la
|
||||
webp_quality_CPPFLAGS = $(AM_CPPFLAGS) $(USE_EXPERIMENTAL_CODE)
|
||||
webp_quality_LDADD = ../imageio/libimageio_util.la
|
||||
webp_quality_LDADD += libwebpextras.la
|
||||
webp_quality_LDADD += ../src/libwebp.la
|
||||
|
||||
vwebp_sdl_SOURCES = vwebp_sdl.c webp_to_sdl.c webp_to_sdl.h
|
||||
vwebp_sdl_CPPFLAGS = $(AM_CPPFLAGS) $(SDL_INCLUDES)
|
||||
vwebp_sdl_LDADD =
|
||||
vwebp_sdl_LDADD += ../imageio/libimageio_util.la
|
||||
vwebp_sdl_LDADD += ../src/libwebp.la
|
||||
vwebp_sdl_LDADD += $(SDL_LIBS)
|
||||
|
@ -10,15 +10,14 @@
|
||||
// Additional WebP utilities.
|
||||
//
|
||||
|
||||
#include "extras/extras.h"
|
||||
#include "./extras.h"
|
||||
#include "webp/format_constants.h"
|
||||
#include "src/dsp/dsp.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#define XTRA_MAJ_VERSION 1
|
||||
#define XTRA_MIN_VERSION 2
|
||||
#define XTRA_MAJ_VERSION 0
|
||||
#define XTRA_MIN_VERSION 1
|
||||
#define XTRA_REV_VERSION 0
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@ -49,16 +48,15 @@ int WebPImportGray(const uint8_t* gray_data, WebPPicture* pic) {
|
||||
|
||||
int WebPImportRGB565(const uint8_t* rgb565, WebPPicture* pic) {
|
||||
int x, y;
|
||||
uint32_t* dst;
|
||||
if (pic == NULL || rgb565 == NULL) return 0;
|
||||
pic->colorspace = WEBP_YUV420;
|
||||
pic->use_argb = 1;
|
||||
if (!WebPPictureAlloc(pic)) return 0;
|
||||
dst = pic->argb;
|
||||
for (y = 0; y < pic->height; ++y) {
|
||||
const int width = pic->width;
|
||||
uint32_t* dst = pic->argb + y * pic->argb_stride;
|
||||
for (x = 0; x < width; ++x) {
|
||||
#if defined(WEBP_SWAP_16BIT_CSP) && (WEBP_SWAP_16BIT_CSP == 1)
|
||||
#ifdef WEBP_SWAP_16BIT_CSP
|
||||
const uint32_t rg = rgb565[2 * x + 1];
|
||||
const uint32_t gb = rgb565[2 * x + 0];
|
||||
#else
|
||||
@ -72,26 +70,24 @@ int WebPImportRGB565(const uint8_t* rgb565, WebPPicture* pic) {
|
||||
r = r | (r >> 5);
|
||||
g = g | (g >> 6);
|
||||
b = b | (b >> 5);
|
||||
dst[x] = (0xffu << 24) | (r << 16) | (g << 8) | b;
|
||||
dst[x] = (r << 16) | (g << 8) | b;
|
||||
}
|
||||
rgb565 += 2 * width;
|
||||
dst += pic->argb_stride;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int WebPImportRGB4444(const uint8_t* rgb4444, WebPPicture* pic) {
|
||||
int x, y;
|
||||
uint32_t* dst;
|
||||
if (pic == NULL || rgb4444 == NULL) return 0;
|
||||
pic->colorspace = WEBP_YUV420;
|
||||
pic->use_argb = 1;
|
||||
if (!WebPPictureAlloc(pic)) return 0;
|
||||
dst = pic->argb;
|
||||
for (y = 0; y < pic->height; ++y) {
|
||||
const int width = pic->width;
|
||||
uint32_t* dst = pic->argb + y * pic->argb_stride;
|
||||
for (x = 0; x < width; ++x) {
|
||||
#if defined(WEBP_SWAP_16BIT_CSP) && (WEBP_SWAP_16BIT_CSP == 1)
|
||||
#ifdef WEBP_SWAP_16BIT_CSP
|
||||
const uint32_t rg = rgb4444[2 * x + 1];
|
||||
const uint32_t ba = rgb4444[2 * x + 0];
|
||||
#else
|
||||
@ -110,7 +106,6 @@ int WebPImportRGB4444(const uint8_t* rgb4444, WebPPicture* pic) {
|
||||
dst[x] = (a << 24) | (r << 16) | (g << 8) | b;
|
||||
}
|
||||
rgb4444 += 2 * width;
|
||||
dst += pic->argb_stride;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@ -145,18 +140,3 @@ int WebPImportColorMappedARGB(const uint8_t* indexed, int indexed_stride,
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
int WebPUnmultiplyARGB(WebPPicture* pic) {
|
||||
int y;
|
||||
uint32_t* dst;
|
||||
if (pic == NULL || pic->use_argb != 1 || pic->argb == NULL) return 0;
|
||||
WebPInitAlphaProcessing();
|
||||
dst = pic->argb;
|
||||
for (y = 0; y < pic->height; ++y) {
|
||||
WebPMultARGBRow(dst, pic->width, /*inverse=*/1);
|
||||
dst += pic->argb_stride;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
@ -19,45 +19,38 @@ extern "C" {
|
||||
|
||||
#include "webp/encode.h"
|
||||
|
||||
#define WEBP_EXTRAS_ABI_VERSION 0x0002 // MAJOR(8b) + MINOR(8b)
|
||||
#define WEBP_EXTRAS_ABI_VERSION 0x0001 // MAJOR(8b) + MINOR(8b)
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// Returns the version number of the extras library, packed in hexadecimal using
|
||||
// 8bits for each of major/minor/revision. E.g: v2.5.7 is 0x020507.
|
||||
WEBP_EXTERN int WebPGetExtrasVersion(void);
|
||||
WEBP_EXTERN(int) WebPGetExtrasVersion(void);
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Ad-hoc colorspace importers.
|
||||
|
||||
// Import luma sample (gray scale image) into 'picture'. The 'picture'
|
||||
// width and height must be set prior to calling this function.
|
||||
WEBP_EXTERN int WebPImportGray(const uint8_t* gray, WebPPicture* picture);
|
||||
WEBP_EXTERN(int) WebPImportGray(const uint8_t* gray, WebPPicture* picture);
|
||||
|
||||
// Import rgb sample in RGB565 packed format into 'picture'. The 'picture'
|
||||
// width and height must be set prior to calling this function.
|
||||
WEBP_EXTERN int WebPImportRGB565(const uint8_t* rgb565, WebPPicture* pic);
|
||||
WEBP_EXTERN(int) WebPImportRGB565(const uint8_t* rgb565, WebPPicture* pic);
|
||||
|
||||
// Import rgb sample in RGB4444 packed format into 'picture'. The 'picture'
|
||||
// width and height must be set prior to calling this function.
|
||||
WEBP_EXTERN int WebPImportRGB4444(const uint8_t* rgb4444, WebPPicture* pic);
|
||||
WEBP_EXTERN(int) WebPImportRGB4444(const uint8_t* rgb4444, WebPPicture* pic);
|
||||
|
||||
// Import a color mapped image. The number of colors is less or equal to
|
||||
// MAX_PALETTE_SIZE. 'pic' must have been initialized. Its content, if any,
|
||||
// will be discarded. Returns 'false' in case of error, or if indexed[] contains
|
||||
// invalid indices.
|
||||
WEBP_EXTERN int
|
||||
WEBP_EXTERN(int)
|
||||
WebPImportColorMappedARGB(const uint8_t* indexed, int indexed_stride,
|
||||
const uint32_t palette[], int palette_size,
|
||||
WebPPicture* pic);
|
||||
|
||||
// Convert the ARGB content of 'pic' from associated to unassociated.
|
||||
// 'pic' can be for instance the result of calling of some WebPPictureImportXXX
|
||||
// functions, with pic->use_argb set to 'true'. It is assumed (and not checked)
|
||||
// that the pre-multiplied r/g/b values as less or equal than the alpha value.
|
||||
// Return false in case of error (invalid parameter, ...).
|
||||
WEBP_EXTERN int WebPUnmultiplyARGB(WebPPicture* pic);
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// Parse a bitstream, search for VP8 (lossy) header and report a
|
||||
@ -66,7 +59,7 @@ WEBP_EXTERN int WebPUnmultiplyARGB(WebPPicture* pic);
|
||||
// Otherwise (lossy bitstream), the returned value is in the range [0..100].
|
||||
// Any error (invalid bitstream, animated WebP, incomplete header, etc.)
|
||||
// will return a value of -1.
|
||||
WEBP_EXTERN int VP8EstimateQuality(const uint8_t* const data, size_t size);
|
||||
WEBP_EXTERN(int) VP8EstimateQuality(const uint8_t* const data, size_t size);
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@ -74,4 +67,4 @@ WEBP_EXTERN int VP8EstimateQuality(const uint8_t* const data, size_t size);
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // WEBP_EXTRAS_EXTRAS_H_
|
||||
#endif /* WEBP_EXTRAS_EXTRAS_H_ */
|
||||
|
@ -24,9 +24,8 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "webp/encode.h"
|
||||
#include "imageio/image_dec.h"
|
||||
#include "imageio/imageio_util.h"
|
||||
#include "../examples/unicode.h"
|
||||
#include "../imageio/image_dec.h"
|
||||
#include "../imageio/imageio_util.h"
|
||||
|
||||
static size_t ReadPicture(const char* const filename, WebPPicture* const pic,
|
||||
int keep_alpha) {
|
||||
@ -49,8 +48,7 @@ static size_t ReadPicture(const char* const filename, WebPPicture* const pic,
|
||||
|
||||
End:
|
||||
if (!ok) {
|
||||
WFPRINTF(stderr, "Error! Could not process file %s\n",
|
||||
(const W_CHAR*)filename);
|
||||
fprintf(stderr, "Error! Could not process file %s\n", filename);
|
||||
}
|
||||
free((void*)data);
|
||||
return ok ? data_size : 0;
|
||||
@ -226,7 +224,7 @@ static void Help(void) {
|
||||
" Also handles PNG, JPG and TIFF files, in addition to WebP.\n");
|
||||
}
|
||||
|
||||
int main(int argc, const char* argv[]) {
|
||||
int main(int argc, const char *argv[]) {
|
||||
WebPPicture pic1, pic2;
|
||||
size_t size1 = 0, size2 = 0;
|
||||
int ret = 1;
|
||||
@ -241,11 +239,9 @@ int main(int argc, const char* argv[]) {
|
||||
const char* name2 = NULL;
|
||||
const char* output = NULL;
|
||||
|
||||
INIT_WARGV(argc, argv);
|
||||
|
||||
if (!WebPPictureInit(&pic1) || !WebPPictureInit(&pic2)) {
|
||||
fprintf(stderr, "Can't init pictures\n");
|
||||
FREE_WARGV_AND_RETURN(1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
for (c = 1; c < argc; ++c) {
|
||||
@ -267,11 +263,11 @@ int main(int argc, const char* argv[]) {
|
||||
fprintf(stderr, "missing file name after %s option.\n", argv[c - 1]);
|
||||
goto End;
|
||||
}
|
||||
output = (const char*)GET_WARGV(argv, c);
|
||||
output = argv[c];
|
||||
} else if (name1 == NULL) {
|
||||
name1 = (const char*)GET_WARGV(argv, c);
|
||||
name1 = argv[c];
|
||||
} else {
|
||||
name2 = (const char*)GET_WARGV(argv, c);
|
||||
name2 = argv[c];
|
||||
}
|
||||
}
|
||||
if (help || name1 == NULL || name2 == NULL) {
|
||||
@ -282,7 +278,7 @@ int main(int argc, const char* argv[]) {
|
||||
goto End;
|
||||
}
|
||||
size1 = ReadPicture(name1, &pic1, 1);
|
||||
size2 = ReadPicture(name2, &pic2, 1);
|
||||
size2 = ReadPicture(name1, &pic2, 1);
|
||||
if (size1 == 0 || size2 == 0) goto End;
|
||||
|
||||
if (!keep_alpha) {
|
||||
@ -294,10 +290,9 @@ int main(int argc, const char* argv[]) {
|
||||
fprintf(stderr, "Error while computing the distortion.\n");
|
||||
goto End;
|
||||
}
|
||||
printf("%u %.2f %.2f %.2f %.2f %.2f [ %.2f bpp ]\n",
|
||||
printf("%u %.2f %.2f %.2f %.2f %.2f\n",
|
||||
(unsigned int)size1,
|
||||
disto[4], disto[0], disto[1], disto[2], disto[3],
|
||||
8.f * size1 / pic1.width / pic1.height);
|
||||
disto[4], disto[0], disto[1], disto[2], disto[3]);
|
||||
|
||||
if (output != NULL) {
|
||||
uint8_t* data = NULL;
|
||||
@ -327,7 +322,6 @@ int main(int argc, const char* argv[]) {
|
||||
fprintf(stderr, "Can only compute the difference map in ARGB format.\n");
|
||||
goto End;
|
||||
}
|
||||
#if !defined(WEBP_REDUCE_CSP)
|
||||
data_size = WebPEncodeLosslessBGRA((const uint8_t*)pic1.argb,
|
||||
pic1.width, pic1.height,
|
||||
pic1.argb_stride * 4,
|
||||
@ -339,17 +333,11 @@ int main(int argc, const char* argv[]) {
|
||||
ret = ImgIoUtilWriteFile(output, data, data_size) ? 0 : 1;
|
||||
WebPFree(data);
|
||||
if (ret) goto End;
|
||||
#else
|
||||
(void)data;
|
||||
(void)data_size;
|
||||
fprintf(stderr, "Cannot save the difference map. Please recompile "
|
||||
"without the WEBP_REDUCE_CSP flag.\n");
|
||||
#endif // WEBP_REDUCE_CSP
|
||||
}
|
||||
ret = 0;
|
||||
|
||||
End:
|
||||
WebPPictureFree(&pic1);
|
||||
WebPPictureFree(&pic2);
|
||||
FREE_WARGV_AND_RETURN(ret);
|
||||
return ret;
|
||||
}
|
||||
|
@ -11,7 +11,7 @@
|
||||
//
|
||||
// Author: Skal (pascal.massimino@gmail.com)
|
||||
|
||||
#include "extras/extras.h"
|
||||
#include "./extras.h"
|
||||
#include "webp/decode.h"
|
||||
|
||||
#include <math.h>
|
||||
@ -73,7 +73,7 @@ int VP8EstimateQuality(const uint8_t* const data, size_t size) {
|
||||
pos += 4;
|
||||
bit_pos = pos * 8;
|
||||
|
||||
GET_BIT(2); // colorspace + clamp type
|
||||
GET_BIT(2); // color_space + clamp type
|
||||
|
||||
// Segment header
|
||||
if (GET_BIT(1)) { // use_segment_
|
||||
|
@ -1,101 +0,0 @@
|
||||
// Copyright 2017 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// Use of this source code is governed by a BSD-style license
|
||||
// that can be found in the COPYING file in the root of the source
|
||||
// tree. An additional intellectual property rights grant can be found
|
||||
// in the file PATENTS. All contributing project authors may
|
||||
// be found in the AUTHORS file in the root of the source tree.
|
||||
// -----------------------------------------------------------------------------
|
||||
//
|
||||
// Simple SDL-based WebP file viewer.
|
||||
// Does not support animation, just static images.
|
||||
//
|
||||
// Press 'q' to exit.
|
||||
//
|
||||
// Author: James Zern (jzern@google.com)
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "webp/config.h"
|
||||
#endif
|
||||
|
||||
#if defined(WEBP_HAVE_SDL)
|
||||
|
||||
#include "webp_to_sdl.h"
|
||||
#include "webp/decode.h"
|
||||
#include "imageio/imageio_util.h"
|
||||
#include "../examples/unicode.h"
|
||||
|
||||
#if defined(WEBP_HAVE_JUST_SDL_H)
|
||||
#include <SDL.h>
|
||||
#else
|
||||
#include <SDL/SDL.h>
|
||||
#endif
|
||||
|
||||
static void ProcessEvents(void) {
|
||||
int done = 0;
|
||||
SDL_Event event;
|
||||
while (!done && SDL_WaitEvent(&event)) {
|
||||
switch (event.type) {
|
||||
case SDL_KEYUP:
|
||||
switch (event.key.keysym.sym) {
|
||||
case SDLK_q: done = 1; break;
|
||||
default: break;
|
||||
}
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
int c;
|
||||
int ok = 0;
|
||||
|
||||
INIT_WARGV(argc, argv);
|
||||
|
||||
for (c = 1; c < argc; ++c) {
|
||||
const char* file = NULL;
|
||||
const uint8_t* webp = NULL;
|
||||
size_t webp_size = 0;
|
||||
if (!strcmp(argv[c], "-h")) {
|
||||
printf("Usage: %s [-h] image.webp [more_files.webp...]\n", argv[0]);
|
||||
FREE_WARGV_AND_RETURN(0);
|
||||
} else {
|
||||
file = (const char*)GET_WARGV(argv, c);
|
||||
}
|
||||
if (file == NULL) continue;
|
||||
if (!ImgIoUtilReadFile(file, &webp, &webp_size)) {
|
||||
WFPRINTF(stderr, "Error opening file: %s\n", (const W_CHAR*)file);
|
||||
goto Error;
|
||||
}
|
||||
if (webp_size != (size_t)(int)webp_size) {
|
||||
free((void*)webp);
|
||||
fprintf(stderr, "File too large.\n");
|
||||
goto Error;
|
||||
}
|
||||
ok = WebpToSDL((const char*)webp, (int)webp_size);
|
||||
free((void*)webp);
|
||||
if (!ok) {
|
||||
WFPRINTF(stderr, "Error decoding file %s\n", (const W_CHAR*)file);
|
||||
goto Error;
|
||||
}
|
||||
ProcessEvents();
|
||||
}
|
||||
ok = 1;
|
||||
|
||||
Error:
|
||||
SDL_Quit();
|
||||
FREE_WARGV_AND_RETURN(ok ? 0 : 1);
|
||||
}
|
||||
|
||||
#else // !WEBP_HAVE_SDL
|
||||
|
||||
int main(int argc, const char* argv[]) {
|
||||
fprintf(stderr, "SDL support not enabled in %s.\n", argv[0]);
|
||||
(void)argc;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
@ -11,32 +11,28 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "extras/extras.h"
|
||||
#include "imageio/imageio_util.h"
|
||||
#include "../examples/unicode.h"
|
||||
#include "./extras.h"
|
||||
#include "../imageio/imageio_util.h"
|
||||
|
||||
int main(int argc, const char* argv[]) {
|
||||
int main(int argc, const char *argv[]) {
|
||||
int c;
|
||||
int quiet = 0;
|
||||
int ok = 1;
|
||||
|
||||
INIT_WARGV(argc, argv);
|
||||
|
||||
for (c = 1; ok && c < argc; ++c) {
|
||||
if (!strcmp(argv[c], "-quiet")) {
|
||||
quiet = 1;
|
||||
} else if (!strcmp(argv[c], "-help") || !strcmp(argv[c], "-h")) {
|
||||
printf("webp_quality [-h][-quiet] webp_files...\n");
|
||||
FREE_WARGV_AND_RETURN(0);
|
||||
return 0;
|
||||
} else {
|
||||
const char* const filename = (const char*)GET_WARGV(argv, c);
|
||||
const char* const filename = argv[c];
|
||||
const uint8_t* data = NULL;
|
||||
size_t data_size = 0;
|
||||
int q;
|
||||
ok = ImgIoUtilReadFile(filename, &data, &data_size);
|
||||
if (!ok) break;
|
||||
q = VP8EstimateQuality(data, data_size);
|
||||
if (!quiet) WPRINTF("[%s] ", (const W_CHAR*)filename);
|
||||
if (!quiet) printf("[%s] ", filename);
|
||||
if (q < 0) {
|
||||
fprintf(stderr, "Not a WebP file, or not a lossy WebP file.\n");
|
||||
ok = 0;
|
||||
@ -50,5 +46,5 @@ int main(int argc, const char* argv[]) {
|
||||
free((void*)data);
|
||||
}
|
||||
}
|
||||
FREE_WARGV_AND_RETURN(ok ? 0 : 1);
|
||||
return ok ? 0 : 1;
|
||||
}
|
||||
|
@ -1,110 +0,0 @@
|
||||
// Copyright 2017 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// Use of this source code is governed by a BSD-style license
|
||||
// that can be found in the COPYING file in the root of the source
|
||||
// tree. An additional intellectual property rights grant can be found
|
||||
// in the file PATENTS. All contributing project authors may
|
||||
// be found in the AUTHORS file in the root of the source tree.
|
||||
// -----------------------------------------------------------------------------
|
||||
//
|
||||
// Simple WebP-to-SDL wrapper. Useful for emscripten.
|
||||
//
|
||||
// Author: James Zern (jzern@google.com)
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "src/webp/config.h"
|
||||
#endif
|
||||
|
||||
#if defined(WEBP_HAVE_SDL)
|
||||
|
||||
#include "webp_to_sdl.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include "src/webp/decode.h"
|
||||
|
||||
#if defined(WEBP_HAVE_JUST_SDL_H)
|
||||
#include <SDL.h>
|
||||
#else
|
||||
#include <SDL/SDL.h>
|
||||
#endif
|
||||
|
||||
static int init_ok = 0;
|
||||
int WebpToSDL(const char* data, unsigned int data_size) {
|
||||
int ok = 0;
|
||||
VP8StatusCode status;
|
||||
WebPDecoderConfig config;
|
||||
WebPBitstreamFeatures* const input = &config.input;
|
||||
WebPDecBuffer* const output = &config.output;
|
||||
SDL_Surface* screen = NULL;
|
||||
SDL_Surface* surface = NULL;
|
||||
|
||||
if (!WebPInitDecoderConfig(&config)) {
|
||||
fprintf(stderr, "Library version mismatch!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!init_ok) {
|
||||
SDL_Init(SDL_INIT_VIDEO);
|
||||
init_ok = 1;
|
||||
}
|
||||
|
||||
status = WebPGetFeatures((uint8_t*)data, (size_t)data_size, &config.input);
|
||||
if (status != VP8_STATUS_OK) goto Error;
|
||||
|
||||
screen = SDL_SetVideoMode(input->width, input->height, 32, SDL_SWSURFACE);
|
||||
if (screen == NULL) {
|
||||
fprintf(stderr, "Unable to set video mode (32bpp %dx%d)!\n",
|
||||
input->width, input->height);
|
||||
goto Error;
|
||||
}
|
||||
|
||||
surface = SDL_CreateRGBSurface(SDL_SWSURFACE,
|
||||
input->width, input->height, 32,
|
||||
0x000000ffu, // R mask
|
||||
0x0000ff00u, // G mask
|
||||
0x00ff0000u, // B mask
|
||||
0xff000000u); // A mask
|
||||
|
||||
if (surface == NULL) {
|
||||
fprintf(stderr, "Unable to create %dx%d RGBA surface!\n",
|
||||
input->width, input->height);
|
||||
goto Error;
|
||||
}
|
||||
if (SDL_MUSTLOCK(surface)) SDL_LockSurface(surface);
|
||||
|
||||
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
|
||||
output->colorspace = MODE_BGRA;
|
||||
#else
|
||||
output->colorspace = MODE_RGBA;
|
||||
#endif
|
||||
output->width = surface->w;
|
||||
output->height = surface->h;
|
||||
output->u.RGBA.rgba = surface->pixels;
|
||||
output->u.RGBA.stride = surface->pitch;
|
||||
output->u.RGBA.size = surface->pitch * surface->h;
|
||||
output->is_external_memory = 1;
|
||||
|
||||
status = WebPDecode((const uint8_t*)data, (size_t)data_size, &config);
|
||||
if (status != VP8_STATUS_OK) {
|
||||
fprintf(stderr, "Error decoding image (%d)\n", status);
|
||||
goto Error;
|
||||
}
|
||||
|
||||
if (SDL_MUSTLOCK(surface)) SDL_UnlockSurface(surface);
|
||||
if (SDL_BlitSurface(surface, NULL, screen, NULL) ||
|
||||
SDL_Flip(screen)) {
|
||||
goto Error;
|
||||
}
|
||||
|
||||
ok = 1;
|
||||
|
||||
Error:
|
||||
SDL_FreeSurface(surface);
|
||||
SDL_FreeSurface(screen);
|
||||
WebPFreeDecBuffer(output);
|
||||
return ok;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#endif // WEBP_HAVE_SDL
|
@ -1,22 +0,0 @@
|
||||
// Copyright 2017 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// Use of this source code is governed by a BSD-style license
|
||||
// that can be found in the COPYING file in the root of the source
|
||||
// tree. An additional intellectual property rights grant can be found
|
||||
// in the file PATENTS. All contributing project authors may
|
||||
// be found in the AUTHORS file in the root of the source tree.
|
||||
// -----------------------------------------------------------------------------
|
||||
//
|
||||
// Simple WebP-to-SDL wrapper. Useful for emscripten.
|
||||
//
|
||||
// Author: James Zern (jzern@google.com)
|
||||
|
||||
#ifndef WEBP_EXTRAS_WEBP_TO_SDL_H_
|
||||
#define WEBP_EXTRAS_WEBP_TO_SDL_H_
|
||||
|
||||
// Exports the method WebpToSDL(const char* data, int data_size) which decodes
|
||||
// a WebP bitstream into an RGBA SDL surface.
|
||||
// Return false on failure.
|
||||
extern int WebpToSDL(const char* data, unsigned int data_size);
|
||||
|
||||
#endif // WEBP_EXTRAS_WEBP_TO_SDL_H_
|
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Binary file not shown.
3
gradle/wrapper/gradle-wrapper.properties
vendored
3
gradle/wrapper/gradle-wrapper.properties
vendored
@ -1,5 +1,6 @@
|
||||
#Thu May 12 17:06:25 CEST 2016
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-2.13-bin.zip
|
||||
|
65
gradlew
vendored
65
gradlew
vendored
@ -1,20 +1,4 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
#
|
||||
# Copyright 2015 the original author or authors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
#!/usr/bin/env bash
|
||||
|
||||
##############################################################################
|
||||
##
|
||||
@ -44,16 +28,16 @@ APP_NAME="Gradle"
|
||||
APP_BASE_NAME=`basename "$0"`
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
DEFAULT_JVM_OPTS=""
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD="maximum"
|
||||
|
||||
warn () {
|
||||
warn ( ) {
|
||||
echo "$*"
|
||||
}
|
||||
|
||||
die () {
|
||||
die ( ) {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
@ -125,8 +109,8 @@ if $darwin; then
|
||||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||
fi
|
||||
|
||||
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
|
||||
# For Cygwin, switch paths to Windows format before running java
|
||||
if $cygwin ; then
|
||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||
@ -154,30 +138,27 @@ if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
|
||||
else
|
||||
eval `echo args$i`="\"$arg\""
|
||||
fi
|
||||
i=`expr $i + 1`
|
||||
i=$((i+1))
|
||||
done
|
||||
case $i in
|
||||
0) set -- ;;
|
||||
1) set -- "$args0" ;;
|
||||
2) set -- "$args0" "$args1" ;;
|
||||
3) set -- "$args0" "$args1" "$args2" ;;
|
||||
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||
(0) set -- ;;
|
||||
(1) set -- "$args0" ;;
|
||||
(2) set -- "$args0" "$args1" ;;
|
||||
(3) set -- "$args0" "$args1" "$args2" ;;
|
||||
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Escape application args
|
||||
save () {
|
||||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||
echo " "
|
||||
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
|
||||
function splitJvmOpts() {
|
||||
JVM_OPTS=("$@")
|
||||
}
|
||||
APP_ARGS=`save "$@"`
|
||||
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
|
||||
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
|
||||
|
||||
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
||||
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
||||
|
||||
exec "$JAVACMD" "$@"
|
||||
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
|
||||
|
190
gradlew.bat
vendored
190
gradlew.bat
vendored
@ -1,100 +1,90 @@
|
||||
@rem
|
||||
@rem Copyright 2015 the original author or authors.
|
||||
@rem
|
||||
@rem Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@rem you may not use this file except in compliance with the License.
|
||||
@rem You may obtain a copy of the License at
|
||||
@rem
|
||||
@rem https://www.apache.org/licenses/LICENSE-2.0
|
||||
@rem
|
||||
@rem Unless required by applicable law or agreed to in writing, software
|
||||
@rem distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@rem See the License for the specific language governing permissions and
|
||||
@rem limitations under the License.
|
||||
@rem
|
||||
|
||||
@if "%DEBUG%" == "" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@rem
|
||||
@rem ##########################################################################
|
||||
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:findJavaFromJavaHome
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:init
|
||||
@rem Get command-line arguments, handling Windows variants
|
||||
|
||||
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||
|
||||
:win9xME_args
|
||||
@rem Slurp the command line arguments.
|
||||
set CMD_LINE_ARGS=
|
||||
set _SKIP=2
|
||||
|
||||
:win9xME_args_slurp
|
||||
if "x%~1" == "x" goto execute
|
||||
|
||||
set CMD_LINE_ARGS=%*
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||
exit /b 1
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
:omega
|
||||
@if "%DEBUG%" == "" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@rem
|
||||
@rem ##########################################################################
|
||||
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS=
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:findJavaFromJavaHome
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:init
|
||||
@rem Get command-line arguments, handling Windows variants
|
||||
|
||||
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||
if "%@eval[2+2]" == "4" goto 4NT_args
|
||||
|
||||
:win9xME_args
|
||||
@rem Slurp the command line arguments.
|
||||
set CMD_LINE_ARGS=
|
||||
set _SKIP=2
|
||||
|
||||
:win9xME_args_slurp
|
||||
if "x%~1" == "x" goto execute
|
||||
|
||||
set CMD_LINE_ARGS=%*
|
||||
goto execute
|
||||
|
||||
:4NT_args
|
||||
@rem Get arguments from the 4NT Shell from JP Software
|
||||
set CMD_LINE_ARGS=%$
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||
exit /b 1
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
:omega
|
||||
|
@ -25,7 +25,6 @@ LOCAL_SRC_FILES := \
|
||||
jpegdec.c \
|
||||
metadata.c \
|
||||
pngdec.c \
|
||||
pnmdec.c \
|
||||
tiffdec.c \
|
||||
webpdec.c \
|
||||
|
||||
|
@ -1,32 +1,22 @@
|
||||
AM_CPPFLAGS += -I$(top_builddir)/src -I$(top_srcdir)/src
|
||||
noinst_LTLIBRARIES =
|
||||
noinst_LTLIBRARIES += libimageio_util.la
|
||||
if BUILD_DEMUX
|
||||
noinst_LTLIBRARIES += libimagedec.la
|
||||
endif
|
||||
noinst_LTLIBRARIES += libimageenc.la
|
||||
noinst_LTLIBRARIES = libimageio_util.la libimagedec.la libimageenc.la
|
||||
|
||||
noinst_HEADERS =
|
||||
noinst_HEADERS += ../src/webp/decode.h
|
||||
noinst_HEADERS += ../src/webp/types.h
|
||||
|
||||
libimageio_util_la_SOURCES =
|
||||
libimageio_util_la_SOURCES += imageio_util.c imageio_util.h
|
||||
libimageio_util_la_SOURCES = imageio_util.c imageio_util.h
|
||||
|
||||
libimagedec_la_SOURCES =
|
||||
libimagedec_la_SOURCES += image_dec.c image_dec.h
|
||||
libimagedec_la_SOURCES = image_dec.c image_dec.h
|
||||
libimagedec_la_SOURCES += jpegdec.c jpegdec.h
|
||||
libimagedec_la_SOURCES += metadata.c metadata.h
|
||||
libimagedec_la_SOURCES += pngdec.c pngdec.h
|
||||
libimagedec_la_SOURCES += pnmdec.c pnmdec.h
|
||||
libimagedec_la_SOURCES += tiffdec.c tiffdec.h
|
||||
libimagedec_la_SOURCES += webpdec.c webpdec.h
|
||||
libimagedec_la_SOURCES += wicdec.c wicdec.h
|
||||
libimagedec_la_CPPFLAGS = $(JPEG_INCLUDES) $(PNG_INCLUDES) $(TIFF_INCLUDES)
|
||||
libimagedec_la_CPPFLAGS += $(AM_CPPFLAGS)
|
||||
libimagedec_la_LIBADD = ../src/demux/libwebpdemux.la
|
||||
libimagedec_la_CPPFLAGS += $(AM_CPPFLAGS) $(USE_EXPERIMENTAL_CODE)
|
||||
|
||||
libimageenc_la_SOURCES =
|
||||
libimageenc_la_SOURCES += image_enc.c image_enc.h
|
||||
libimageenc_la_SOURCES = image_enc.c image_enc.h
|
||||
libimageenc_la_CPPFLAGS = $(JPEG_INCLUDES) $(PNG_INCLUDES) $(TIFF_INCLUDES)
|
||||
libimageenc_la_CPPFLAGS += $(AM_CPPFLAGS)
|
||||
libimageenc_la_CPPFLAGS += $(AM_CPPFLAGS) $(USE_EXPERIMENTAL_CODE)
|
||||
|
@ -29,10 +29,6 @@ WebPInputFileFormat WebPGuessImageType(const uint8_t* const data,
|
||||
format = WEBP_TIFF_FORMAT;
|
||||
} else if (magic1 == 0x52494646 && magic2 == 0x57454250) {
|
||||
format = WEBP_WEBP_FORMAT;
|
||||
} else if (((magic1 >> 24) & 0xff) == 'P') {
|
||||
const int type = (magic1 >> 16) & 0xff;
|
||||
// we only support 'P5 -> P7' for now.
|
||||
if (type >= '5' && type <= '7') format = WEBP_PNM_FORMAT;
|
||||
}
|
||||
}
|
||||
return format;
|
||||
@ -55,7 +51,6 @@ WebPImageReader WebPGetImageReader(WebPInputFileFormat format) {
|
||||
case WEBP_JPEG_FORMAT: return ReadJPEG;
|
||||
case WEBP_TIFF_FORMAT: return ReadTIFF;
|
||||
case WEBP_WEBP_FORMAT: return ReadWebP;
|
||||
case WEBP_PNM_FORMAT: return ReadPNM;
|
||||
default: return FailReader;
|
||||
}
|
||||
}
|
||||
|
@ -23,7 +23,6 @@
|
||||
#include "./metadata.h"
|
||||
#include "./jpegdec.h"
|
||||
#include "./pngdec.h"
|
||||
#include "./pnmdec.h"
|
||||
#include "./tiffdec.h"
|
||||
#include "./webpdec.h"
|
||||
#include "./wicdec.h"
|
||||
@ -37,7 +36,6 @@ typedef enum {
|
||||
WEBP_JPEG_FORMAT,
|
||||
WEBP_TIFF_FORMAT,
|
||||
WEBP_WEBP_FORMAT,
|
||||
WEBP_PNM_FORMAT,
|
||||
WEBP_UNSUPPORTED_FORMAT
|
||||
} WebPInputFileFormat;
|
||||
|
||||
|
@ -29,13 +29,11 @@
|
||||
// code with COBJMACROS.
|
||||
#include <ole2.h> // CreateStreamOnHGlobal()
|
||||
#include <shlwapi.h>
|
||||
#include <tchar.h>
|
||||
#include <windows.h>
|
||||
#include <wincodec.h>
|
||||
#endif
|
||||
|
||||
#include "./imageio_util.h"
|
||||
#include "../examples/unicode.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// PNG
|
||||
@ -63,12 +61,11 @@ static HRESULT CreateOutputStream(const char* out_file_name,
|
||||
// Output to a memory buffer. This is freed when 'stream' is released.
|
||||
IFS(CreateStreamOnHGlobal(NULL, TRUE, stream));
|
||||
} else {
|
||||
IFS(SHCreateStreamOnFile((const LPTSTR)out_file_name,
|
||||
STGM_WRITE | STGM_CREATE, stream));
|
||||
IFS(SHCreateStreamOnFileA(out_file_name, STGM_WRITE | STGM_CREATE, stream));
|
||||
}
|
||||
if (FAILED(hr)) {
|
||||
_ftprintf(stderr, _T("Error opening output file %s (%08lx)\n"),
|
||||
(const LPTSTR)out_file_name, hr);
|
||||
fprintf(stderr, "Error opening output file %s (%08lx)\n",
|
||||
out_file_name, hr);
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
@ -161,8 +158,14 @@ static void PNGAPI PNGErrorFunction(png_structp png, png_const_charp dummy) {
|
||||
}
|
||||
|
||||
int WebPWritePNG(FILE* out_file, const WebPDecBuffer* const buffer) {
|
||||
const uint32_t width = buffer->width;
|
||||
const uint32_t height = buffer->height;
|
||||
png_bytep row = buffer->u.RGBA.rgba;
|
||||
const int stride = buffer->u.RGBA.stride;
|
||||
const int has_alpha = WebPIsAlphaMode(buffer->colorspace);
|
||||
volatile png_structp png;
|
||||
volatile png_infop info;
|
||||
png_uint_32 y;
|
||||
|
||||
if (out_file == NULL || buffer == NULL) return 0;
|
||||
|
||||
@ -181,23 +184,14 @@ int WebPWritePNG(FILE* out_file, const WebPDecBuffer* const buffer) {
|
||||
return 0;
|
||||
}
|
||||
png_init_io(png, out_file);
|
||||
{
|
||||
const uint32_t width = buffer->width;
|
||||
const uint32_t height = buffer->height;
|
||||
png_bytep row = buffer->u.RGBA.rgba;
|
||||
const int stride = buffer->u.RGBA.stride;
|
||||
const int has_alpha = WebPIsAlphaMode(buffer->colorspace);
|
||||
uint32_t y;
|
||||
|
||||
png_set_IHDR(png, info, width, height, 8,
|
||||
has_alpha ? PNG_COLOR_TYPE_RGBA : PNG_COLOR_TYPE_RGB,
|
||||
PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT,
|
||||
PNG_FILTER_TYPE_DEFAULT);
|
||||
png_write_info(png, info);
|
||||
for (y = 0; y < height; ++y) {
|
||||
png_write_rows(png, &row, 1);
|
||||
row += stride;
|
||||
}
|
||||
png_set_IHDR(png, info, width, height, 8,
|
||||
has_alpha ? PNG_COLOR_TYPE_RGBA : PNG_COLOR_TYPE_RGB,
|
||||
PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT,
|
||||
PNG_FILTER_TYPE_DEFAULT);
|
||||
png_write_info(png, info);
|
||||
for (y = 0; y < height; ++y) {
|
||||
png_write_rows(png, &row, 1);
|
||||
row += stride;
|
||||
}
|
||||
png_write_end(png, info);
|
||||
png_destroy_write_struct((png_structpp)&png, (png_infopp)&info);
|
||||
@ -367,8 +361,6 @@ int WebPWriteTIFF(FILE* fout, const WebPDecBuffer* const buffer) {
|
||||
const uint8_t* rgba = buffer->u.RGBA.rgba;
|
||||
const int stride = buffer->u.RGBA.stride;
|
||||
const uint8_t bytes_per_px = has_alpha ? 4 : 3;
|
||||
const uint8_t assoc_alpha =
|
||||
WebPIsPremultipliedMode(buffer->colorspace) ? 1 : 2;
|
||||
// For non-alpha case, we omit tag 0x152 (ExtraSamples).
|
||||
const uint8_t num_ifd_entries = has_alpha ? NUM_IFD_ENTRIES
|
||||
: NUM_IFD_ENTRIES - 1;
|
||||
@ -396,8 +388,7 @@ int WebPWriteTIFF(FILE* fout, const WebPDecBuffer* const buffer) {
|
||||
EXTRA_DATA_OFFSET + 8, 0, 0, 0,
|
||||
0x1c, 0x01, 3, 0, 1, 0, 0, 0, 1, 0, 0, 0, // 154: PlanarConfiguration
|
||||
0x28, 0x01, 3, 0, 1, 0, 0, 0, 2, 0, 0, 0, // 166: ResolutionUnit (inch)
|
||||
0x52, 0x01, 3, 0, 1, 0, 0, 0,
|
||||
assoc_alpha, 0, 0, 0, // 178: ExtraSamples: rgbA/RGBA
|
||||
0x52, 0x01, 3, 0, 1, 0, 0, 0, 1, 0, 0, 0, // 178: ExtraSamples: rgbA
|
||||
0, 0, 0, 0, // 190: IFD terminator
|
||||
// EXTRA_DATA_OFFSET:
|
||||
8, 0, 8, 0, 8, 0, 8, 0, // BitsPerSample
|
||||
@ -548,26 +539,22 @@ int WebPWriteYUV(FILE* fout, const WebPDecBuffer* const buffer) {
|
||||
// Generic top-level call
|
||||
|
||||
int WebPSaveImage(const WebPDecBuffer* const buffer,
|
||||
WebPOutputFileFormat format,
|
||||
const char* const out_file_name) {
|
||||
WebPOutputFileFormat format, const char* const out_file) {
|
||||
FILE* fout = NULL;
|
||||
int needs_open_file = 1;
|
||||
const int use_stdout =
|
||||
(out_file_name != NULL) && !WSTRCMP(out_file_name, "-");
|
||||
const int use_stdout = (out_file != NULL) && !strcmp(out_file, "-");
|
||||
int ok = 1;
|
||||
|
||||
if (buffer == NULL || out_file_name == NULL) return 0;
|
||||
if (buffer == NULL || out_file == NULL) return 0;
|
||||
|
||||
#ifdef HAVE_WINCODEC_H
|
||||
needs_open_file = (format != PNG);
|
||||
#endif
|
||||
|
||||
if (needs_open_file) {
|
||||
fout = use_stdout ? ImgIoUtilSetBinaryMode(stdout)
|
||||
: WFOPEN(out_file_name, "wb");
|
||||
fout = use_stdout ? ImgIoUtilSetBinaryMode(stdout) : fopen(out_file, "wb");
|
||||
if (fout == NULL) {
|
||||
WFPRINTF(stderr, "Error opening output file %s\n",
|
||||
(const W_CHAR*)out_file_name);
|
||||
fprintf(stderr, "Error opening output file %s\n", out_file);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -576,7 +563,7 @@ int WebPSaveImage(const WebPDecBuffer* const buffer,
|
||||
format == RGBA || format == BGRA || format == ARGB ||
|
||||
format == rgbA || format == bgrA || format == Argb) {
|
||||
#ifdef HAVE_WINCODEC_H
|
||||
ok &= WebPWritePNG(out_file_name, use_stdout, buffer);
|
||||
ok &= WebPWritePNG(out_file, use_stdout, buffer);
|
||||
#else
|
||||
ok &= WebPWritePNG(fout, buffer);
|
||||
#endif
|
||||
|
@ -18,7 +18,6 @@
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "../examples/unicode.h"
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// File I/O
|
||||
@ -48,8 +47,7 @@ int ImgIoUtilReadFromStdin(const uint8_t** data, size_t* data_size) {
|
||||
while (!feof(stdin)) {
|
||||
// We double the buffer size each time and read as much as possible.
|
||||
const size_t extra_size = (max_size == 0) ? kBlockSize : max_size;
|
||||
// we allocate one extra byte for the \0 terminator
|
||||
void* const new_data = realloc(input, max_size + extra_size + 1);
|
||||
void* const new_data = realloc(input, max_size + extra_size);
|
||||
if (new_data == NULL) goto Error;
|
||||
input = (uint8_t*)new_data;
|
||||
max_size += extra_size;
|
||||
@ -57,7 +55,6 @@ int ImgIoUtilReadFromStdin(const uint8_t** data, size_t* data_size) {
|
||||
if (size < max_size) break;
|
||||
}
|
||||
if (ferror(stdin)) goto Error;
|
||||
if (input != NULL) input[size] = '\0'; // convenient 0-terminator
|
||||
*data = input;
|
||||
*data_size = size;
|
||||
return 1;
|
||||
@ -71,10 +68,10 @@ int ImgIoUtilReadFromStdin(const uint8_t** data, size_t* data_size) {
|
||||
int ImgIoUtilReadFile(const char* const file_name,
|
||||
const uint8_t** data, size_t* data_size) {
|
||||
int ok;
|
||||
uint8_t* file_data;
|
||||
void* file_data;
|
||||
size_t file_size;
|
||||
FILE* in;
|
||||
const int from_stdin = (file_name == NULL) || !WSTRCMP(file_name, "-");
|
||||
const int from_stdin = (file_name == NULL) || !strcmp(file_name, "-");
|
||||
|
||||
if (from_stdin) return ImgIoUtilReadFromStdin(data, data_size);
|
||||
|
||||
@ -82,52 +79,42 @@ int ImgIoUtilReadFile(const char* const file_name,
|
||||
*data = NULL;
|
||||
*data_size = 0;
|
||||
|
||||
in = WFOPEN(file_name, "rb");
|
||||
in = fopen(file_name, "rb");
|
||||
if (in == NULL) {
|
||||
WFPRINTF(stderr, "cannot open input file '%s'\n", (const W_CHAR*)file_name);
|
||||
fprintf(stderr, "cannot open input file '%s'\n", file_name);
|
||||
return 0;
|
||||
}
|
||||
fseek(in, 0, SEEK_END);
|
||||
file_size = ftell(in);
|
||||
fseek(in, 0, SEEK_SET);
|
||||
// we allocate one extra byte for the \0 terminator
|
||||
file_data = (uint8_t*)WebPMalloc(file_size + 1);
|
||||
if (file_data == NULL) {
|
||||
fclose(in);
|
||||
WFPRINTF(stderr, "memory allocation failure when reading file %s\n",
|
||||
(const W_CHAR*)file_name);
|
||||
return 0;
|
||||
}
|
||||
file_data = malloc(file_size);
|
||||
if (file_data == NULL) return 0;
|
||||
ok = (fread(file_data, file_size, 1, in) == 1);
|
||||
fclose(in);
|
||||
|
||||
if (!ok) {
|
||||
WFPRINTF(stderr, "Could not read %d bytes of data from file %s\n",
|
||||
(int)file_size, (const W_CHAR*)file_name);
|
||||
WebPFree(file_data);
|
||||
fprintf(stderr, "Could not read %d bytes of data from file %s\n",
|
||||
(int)file_size, file_name);
|
||||
free(file_data);
|
||||
return 0;
|
||||
}
|
||||
file_data[file_size] = '\0'; // convenient 0-terminator
|
||||
*data = file_data;
|
||||
*data = (uint8_t*)file_data;
|
||||
*data_size = file_size;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
int ImgIoUtilWriteFile(const char* const file_name,
|
||||
const uint8_t* data, size_t data_size) {
|
||||
int ok;
|
||||
FILE* out;
|
||||
const int to_stdout = (file_name == NULL) || !WSTRCMP(file_name, "-");
|
||||
const int to_stdout = (file_name == NULL) || !strcmp(file_name, "-");
|
||||
|
||||
if (data == NULL) {
|
||||
return 0;
|
||||
}
|
||||
out = to_stdout ? ImgIoUtilSetBinaryMode(stdout) : WFOPEN(file_name, "wb");
|
||||
out = to_stdout ? stdout : fopen(file_name, "wb");
|
||||
if (out == NULL) {
|
||||
WFPRINTF(stderr, "Error! Cannot open output file '%s'\n",
|
||||
(const W_CHAR*)file_name);
|
||||
fprintf(stderr, "Error! Cannot open output file '%s'\n", file_name);
|
||||
return 0;
|
||||
}
|
||||
ok = (fwrite(data, data_size, 1, out) == 1);
|
||||
@ -150,11 +137,7 @@ void ImgIoUtilCopyPlane(const uint8_t* src, int src_stride,
|
||||
|
||||
int ImgIoUtilCheckSizeArgumentsOverflow(uint64_t nmemb, size_t size) {
|
||||
const uint64_t total_size = nmemb * size;
|
||||
int ok = (total_size == (size_t)total_size);
|
||||
#if defined(WEBP_MAX_IMAGE_SIZE)
|
||||
ok = ok && (total_size <= (uint64_t)WEBP_MAX_IMAGE_SIZE);
|
||||
#endif
|
||||
return ok;
|
||||
return (total_size == (size_t)total_size);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
@ -29,10 +29,7 @@ FILE* ImgIoUtilSetBinaryMode(FILE* file);
|
||||
|
||||
// Allocates storage for entire file 'file_name' and returns contents and size
|
||||
// in 'data' and 'data_size'. Returns 1 on success, 0 otherwise. '*data' should
|
||||
// be deleted using WebPFree().
|
||||
// Note: for convenience, the data will be null-terminated with an extra byte
|
||||
// (not accounted for in *data_size), in case the file is text and intended
|
||||
// to be used as a C-string.
|
||||
// be deleted using free().
|
||||
// If 'file_name' is NULL or equal to "-", input is read from stdin by calling
|
||||
// the function ImgIoUtilReadFromStdin().
|
||||
int ImgIoUtilReadFile(const char* const file_name,
|
||||
|
@ -206,7 +206,6 @@ struct my_error_mgr {
|
||||
|
||||
static void my_error_exit(j_common_ptr dinfo) {
|
||||
struct my_error_mgr* myerr = (struct my_error_mgr*)dinfo->err;
|
||||
fprintf(stderr, "libjpeg error: ");
|
||||
dinfo->err->output_message(dinfo);
|
||||
longjmp(myerr->setjmp_buffer, 1);
|
||||
}
|
||||
@ -305,18 +304,18 @@ int ReadJPEG(const uint8_t* const data, size_t data_size,
|
||||
|
||||
if (stride != (int)stride ||
|
||||
!ImgIoUtilCheckSizeArgumentsOverflow(stride, height)) {
|
||||
goto Error;
|
||||
goto End;
|
||||
}
|
||||
|
||||
rgb = (uint8_t*)malloc((size_t)stride * height);
|
||||
if (rgb == NULL) {
|
||||
goto Error;
|
||||
goto End;
|
||||
}
|
||||
buffer[0] = (JSAMPLE*)rgb;
|
||||
|
||||
while (dinfo.output_scanline < dinfo.output_height) {
|
||||
if (jpeg_read_scanlines((j_decompress_ptr)&dinfo, buffer, 1) != 1) {
|
||||
goto Error;
|
||||
goto End;
|
||||
}
|
||||
buffer[0] += stride;
|
||||
}
|
||||
|
@ -18,9 +18,6 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef WEBP_HAVE_PNG
|
||||
#ifndef PNG_USER_MEM_SUPPORTED
|
||||
#define PNG_USER_MEM_SUPPORTED // for png_create_read_struct_2
|
||||
#endif
|
||||
#include <png.h>
|
||||
#include <setjmp.h> // note: this must be included *after* png.h
|
||||
#include <stdlib.h>
|
||||
@ -30,33 +27,11 @@
|
||||
#include "./imageio_util.h"
|
||||
#include "./metadata.h"
|
||||
|
||||
#define LOCAL_PNG_VERSION ((PNG_LIBPNG_VER_MAJOR << 8) | PNG_LIBPNG_VER_MINOR)
|
||||
#define LOCAL_PNG_PREREQ(maj, min) \
|
||||
(LOCAL_PNG_VERSION >= (((maj) << 8) | (min)))
|
||||
|
||||
static void PNGAPI error_function(png_structp png, png_const_charp error) {
|
||||
if (error != NULL) fprintf(stderr, "libpng error: %s\n", error);
|
||||
longjmp(png_jmpbuf(png), 1);
|
||||
}
|
||||
|
||||
#if LOCAL_PNG_PREREQ(1,4)
|
||||
typedef png_alloc_size_t LocalPngAllocSize;
|
||||
#else
|
||||
typedef png_size_t LocalPngAllocSize;
|
||||
#endif
|
||||
|
||||
static png_voidp MallocFunc(png_structp png_ptr, LocalPngAllocSize size) {
|
||||
(void)png_ptr;
|
||||
if (size != (size_t)size) return NULL;
|
||||
if (!ImgIoUtilCheckSizeArgumentsOverflow(size, 1)) return NULL;
|
||||
return (png_voidp)malloc((size_t)size);
|
||||
}
|
||||
|
||||
static void FreeFunc(png_structp png_ptr, png_voidp ptr) {
|
||||
(void)png_ptr;
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
// Converts the NULL terminated 'hexstring' which contains 2-byte character
|
||||
// representations of hex values to raw data.
|
||||
// 'hexstring' may contain values consisting of [A-F][a-f][0-9] in pairs,
|
||||
@ -196,10 +171,11 @@ static int ExtractMetadataFromPNG(png_structp png,
|
||||
{
|
||||
png_charp name;
|
||||
int comp_type;
|
||||
#if LOCAL_PNG_PREREQ(1,5)
|
||||
png_bytep profile;
|
||||
#else
|
||||
#if ((PNG_LIBPNG_VER_MAJOR << 8) | PNG_LIBPNG_VER_MINOR << 0) < \
|
||||
((1 << 8) | (5 << 0))
|
||||
png_charp profile;
|
||||
#else // >= libpng 1.5.0
|
||||
png_bytep profile;
|
||||
#endif
|
||||
png_uint_32 len;
|
||||
|
||||
@ -209,6 +185,7 @@ static int ExtractMetadataFromPNG(png_structp png,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -248,8 +225,7 @@ int ReadPNG(const uint8_t* const data, size_t data_size,
|
||||
context.data = data;
|
||||
context.data_size = data_size;
|
||||
|
||||
png = png_create_read_struct_2(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL,
|
||||
NULL, MallocFunc, FreeFunc);
|
||||
png = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
|
||||
if (png == NULL) goto End;
|
||||
|
||||
png_set_error_fn(png, 0, error_function, NULL);
|
||||
@ -259,12 +235,6 @@ int ReadPNG(const uint8_t* const data, size_t data_size,
|
||||
goto End;
|
||||
}
|
||||
|
||||
// If it looks like the bitstream is going to need more memory than libpng's
|
||||
// internal limit (default: 8M), try to (reasonably) raise it.
|
||||
if (data_size > png_get_chunk_malloc_max(png) && data_size < (1u << 24)) {
|
||||
png_set_chunk_malloc_max(png, data_size);
|
||||
}
|
||||
|
||||
info = png_create_info_struct(png);
|
||||
if (info == NULL) goto Error;
|
||||
end_info = png_create_info_struct(png);
|
||||
@ -295,16 +265,6 @@ int ReadPNG(const uint8_t* const data, size_t data_size,
|
||||
has_alpha = !!(color_type & PNG_COLOR_MASK_ALPHA);
|
||||
}
|
||||
|
||||
// Apply gamma correction if needed.
|
||||
{
|
||||
double image_gamma = 1 / 2.2, screen_gamma = 2.2;
|
||||
int srgb_intent;
|
||||
if (png_get_sRGB(png, info, &srgb_intent) ||
|
||||
png_get_gAMA(png, info, &image_gamma)) {
|
||||
png_set_gamma(png, screen_gamma, image_gamma);
|
||||
}
|
||||
}
|
||||
|
||||
if (!keep_alpha) {
|
||||
png_set_strip_alpha(png);
|
||||
has_alpha = 0;
|
||||
|
296
imageio/pnmdec.c
296
imageio/pnmdec.c
@ -1,296 +0,0 @@
|
||||
// Copyright 2017 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// Use of this source code is governed by a BSD-style license
|
||||
// that can be found in the COPYING file in the root of the source
|
||||
// tree. An additional intellectual property rights grant can be found
|
||||
// in the file PATENTS. All contributing project authors may
|
||||
// be found in the AUTHORS file in the root of the source tree.
|
||||
// -----------------------------------------------------------------------------
|
||||
//
|
||||
// (limited) PNM decoder
|
||||
|
||||
#include "./pnmdec.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "webp/encode.h"
|
||||
#include "./imageio_util.h"
|
||||
|
||||
typedef enum {
|
||||
WIDTH_FLAG = 1 << 0,
|
||||
HEIGHT_FLAG = 1 << 1,
|
||||
DEPTH_FLAG = 1 << 2,
|
||||
MAXVAL_FLAG = 1 << 3,
|
||||
TUPLE_FLAG = 1 << 4,
|
||||
ALL_NEEDED_FLAGS = WIDTH_FLAG | HEIGHT_FLAG | DEPTH_FLAG | MAXVAL_FLAG
|
||||
} PNMFlags;
|
||||
|
||||
typedef struct {
|
||||
const uint8_t* data;
|
||||
size_t data_size;
|
||||
int width, height;
|
||||
int bytes_per_px;
|
||||
int depth; // 1 (grayscale), 2 (grayscale + alpha), 3 (rgb), 4 (rgba)
|
||||
int max_value;
|
||||
int type; // 5, 6 or 7
|
||||
int seen_flags;
|
||||
} PNMInfo;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// PNM decoding
|
||||
|
||||
#define MAX_LINE_SIZE 1024
|
||||
static const size_t kMinPNMHeaderSize = 3;
|
||||
|
||||
static size_t ReadLine(const uint8_t* const data, size_t off, size_t data_size,
|
||||
char out[MAX_LINE_SIZE + 1], size_t* const out_size) {
|
||||
size_t i = 0;
|
||||
*out_size = 0;
|
||||
redo:
|
||||
for (i = 0; i < MAX_LINE_SIZE && off < data_size; ++i) {
|
||||
out[i] = data[off++];
|
||||
if (out[i] == '\n') break;
|
||||
}
|
||||
if (off < data_size) {
|
||||
if (i == 0) goto redo; // empty line
|
||||
if (out[0] == '#') goto redo; // skip comment
|
||||
}
|
||||
out[i] = 0; // safety sentinel
|
||||
*out_size = i;
|
||||
return off;
|
||||
}
|
||||
|
||||
static size_t FlagError(const char flag[]) {
|
||||
fprintf(stderr, "PAM header error: flags '%s' already seen.\n", flag);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// inspired from http://netpbm.sourceforge.net/doc/pam.html
|
||||
static size_t ReadPAMFields(PNMInfo* const info, size_t off) {
|
||||
char out[MAX_LINE_SIZE + 1];
|
||||
size_t out_size;
|
||||
int tmp;
|
||||
int expected_depth = -1;
|
||||
assert(info != NULL);
|
||||
while (1) {
|
||||
off = ReadLine(info->data, off, info->data_size, out, &out_size);
|
||||
if (off == 0) return 0;
|
||||
if (sscanf(out, "WIDTH %d", &tmp) == 1) {
|
||||
if (info->seen_flags & WIDTH_FLAG) return FlagError("WIDTH");
|
||||
info->seen_flags |= WIDTH_FLAG;
|
||||
info->width = tmp;
|
||||
} else if (sscanf(out, "HEIGHT %d", &tmp) == 1) {
|
||||
if (info->seen_flags & HEIGHT_FLAG) return FlagError("HEIGHT");
|
||||
info->seen_flags |= HEIGHT_FLAG;
|
||||
info->height = tmp;
|
||||
} else if (sscanf(out, "DEPTH %d", &tmp) == 1) {
|
||||
if (info->seen_flags & DEPTH_FLAG) return FlagError("DEPTH");
|
||||
info->seen_flags |= DEPTH_FLAG;
|
||||
info->depth = tmp;
|
||||
} else if (sscanf(out, "MAXVAL %d", &tmp) == 1) {
|
||||
if (info->seen_flags & MAXVAL_FLAG) return FlagError("MAXVAL");
|
||||
info->seen_flags |= MAXVAL_FLAG;
|
||||
info->max_value = tmp;
|
||||
} else if (!strcmp(out, "TUPLTYPE RGB_ALPHA")) {
|
||||
expected_depth = 4;
|
||||
info->seen_flags |= TUPLE_FLAG;
|
||||
} else if (!strcmp(out, "TUPLTYPE RGB")) {
|
||||
expected_depth = 3;
|
||||
info->seen_flags |= TUPLE_FLAG;
|
||||
} else if (!strcmp(out, "TUPLTYPE GRAYSCALE_ALPHA")) {
|
||||
expected_depth = 2;
|
||||
info->seen_flags |= TUPLE_FLAG;
|
||||
} else if (!strcmp(out, "TUPLTYPE GRAYSCALE")) {
|
||||
expected_depth = 1;
|
||||
info->seen_flags |= TUPLE_FLAG;
|
||||
} else if (!strcmp(out, "ENDHDR")) {
|
||||
break;
|
||||
} else {
|
||||
static const char kEllipsis[] = " ...";
|
||||
int i;
|
||||
if (out_size > 20) sprintf(out + 20 - strlen(kEllipsis), kEllipsis);
|
||||
for (i = 0; i < (int)strlen(out); ++i) {
|
||||
// isprint() might trigger a "char-subscripts" warning if given a char.
|
||||
if (!isprint((int)out[i])) out[i] = ' ';
|
||||
}
|
||||
fprintf(stderr, "PAM header error: unrecognized entry [%s]\n", out);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if (!(info->seen_flags & ALL_NEEDED_FLAGS)) {
|
||||
fprintf(stderr, "PAM header error: missing tags%s%s%s%s\n",
|
||||
(info->seen_flags & WIDTH_FLAG) ? "" : " WIDTH",
|
||||
(info->seen_flags & HEIGHT_FLAG) ? "" : " HEIGHT",
|
||||
(info->seen_flags & DEPTH_FLAG) ? "" : " DEPTH",
|
||||
(info->seen_flags & MAXVAL_FLAG) ? "" : " MAXVAL");
|
||||
return 0;
|
||||
}
|
||||
if (expected_depth != -1 && info->depth != expected_depth) {
|
||||
fprintf(stderr, "PAM header error: expected DEPTH %d but got DEPTH %d\n",
|
||||
expected_depth, info->depth);
|
||||
return 0;
|
||||
}
|
||||
return off;
|
||||
}
|
||||
|
||||
static size_t ReadHeader(PNMInfo* const info) {
|
||||
size_t off = 0;
|
||||
char out[MAX_LINE_SIZE + 1];
|
||||
size_t out_size;
|
||||
if (info == NULL) return 0;
|
||||
if (info->data == NULL || info->data_size < kMinPNMHeaderSize) return 0;
|
||||
|
||||
info->width = info->height = 0;
|
||||
info->type = -1;
|
||||
info->seen_flags = 0;
|
||||
info->bytes_per_px = 0;
|
||||
info->depth = 0;
|
||||
info->max_value = 0;
|
||||
|
||||
off = ReadLine(info->data, off, info->data_size, out, &out_size);
|
||||
if (off == 0 || sscanf(out, "P%d", &info->type) != 1) return 0;
|
||||
if (info->type == 7) {
|
||||
off = ReadPAMFields(info, off);
|
||||
} else {
|
||||
off = ReadLine(info->data, off, info->data_size, out, &out_size);
|
||||
if (off == 0 || sscanf(out, "%d %d", &info->width, &info->height) != 2) {
|
||||
return 0;
|
||||
}
|
||||
off = ReadLine(info->data, off, info->data_size, out, &out_size);
|
||||
if (off == 0 || sscanf(out, "%d", &info->max_value) != 1) return 0;
|
||||
|
||||
// finish initializing missing fields
|
||||
info->depth = (info->type == 5) ? 1 : 3;
|
||||
}
|
||||
// perform some basic numerical validation
|
||||
if (info->width <= 0 || info->height <= 0 ||
|
||||
info->type <= 0 || info->type >= 9 ||
|
||||
info->depth <= 0 || info->depth > 4 ||
|
||||
info->max_value <= 0 || info->max_value >= 65536) {
|
||||
return 0;
|
||||
}
|
||||
info->bytes_per_px = info->depth * (info->max_value > 255 ? 2 : 1);
|
||||
return off;
|
||||
}
|
||||
|
||||
int ReadPNM(const uint8_t* const data, size_t data_size,
|
||||
WebPPicture* const pic, int keep_alpha,
|
||||
struct Metadata* const metadata) {
|
||||
int ok = 0;
|
||||
int i, j;
|
||||
uint64_t stride, pixel_bytes, sample_size, depth;
|
||||
uint8_t* rgb = NULL, *tmp_rgb;
|
||||
size_t offset;
|
||||
PNMInfo info;
|
||||
|
||||
info.data = data;
|
||||
info.data_size = data_size;
|
||||
offset = ReadHeader(&info);
|
||||
if (offset == 0) {
|
||||
fprintf(stderr, "Error parsing PNM header.\n");
|
||||
goto End;
|
||||
}
|
||||
|
||||
if (info.type < 5 || info.type > 7) {
|
||||
fprintf(stderr, "Unsupported P%d PNM format.\n", info.type);
|
||||
goto End;
|
||||
}
|
||||
|
||||
// Some basic validations.
|
||||
if (pic == NULL) goto End;
|
||||
if (info.width > WEBP_MAX_DIMENSION || info.height > WEBP_MAX_DIMENSION) {
|
||||
fprintf(stderr, "Invalid %dx%d dimension for PNM\n",
|
||||
info.width, info.height);
|
||||
goto End;
|
||||
}
|
||||
|
||||
pixel_bytes = (uint64_t)info.width * info.height * info.bytes_per_px;
|
||||
if (data_size < offset + pixel_bytes) {
|
||||
fprintf(stderr, "Truncated PNM file (P%d).\n", info.type);
|
||||
goto End;
|
||||
}
|
||||
sample_size = (info.max_value > 255) ? 2 : 1;
|
||||
// final depth
|
||||
depth = (info.depth == 1 || info.depth == 3 || !keep_alpha) ? 3 : 4;
|
||||
stride = depth * info.width;
|
||||
if (stride != (size_t)stride ||
|
||||
!ImgIoUtilCheckSizeArgumentsOverflow(stride, info.height)) {
|
||||
goto End;
|
||||
}
|
||||
|
||||
rgb = (uint8_t*)malloc((size_t)stride * info.height);
|
||||
if (rgb == NULL) goto End;
|
||||
|
||||
// Convert input.
|
||||
// We only optimize for the sample_size=1, max_value=255, depth=1 case.
|
||||
tmp_rgb = rgb;
|
||||
for (j = 0; j < info.height; ++j) {
|
||||
const uint8_t* in = data + offset;
|
||||
offset += info.bytes_per_px * info.width;
|
||||
assert(offset <= data_size);
|
||||
if (info.max_value == 255 && info.depth >= 3) {
|
||||
// RGB or RGBA
|
||||
if (info.depth == 3 || keep_alpha) {
|
||||
memcpy(tmp_rgb, in, info.depth * info.width * sizeof(*in));
|
||||
} else {
|
||||
assert(info.depth == 4 && !keep_alpha);
|
||||
for (i = 0; i < info.width; ++i) {
|
||||
tmp_rgb[3 * i + 0] = in[4 * i + 0];
|
||||
tmp_rgb[3 * i + 1] = in[4 * i + 1];
|
||||
tmp_rgb[3 * i + 2] = in[4 * i + 2];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Unoptimized case, we need to handle non-trivial operations:
|
||||
// * convert 16b to 8b (if max_value > 255)
|
||||
// * rescale to [0..255] range (if max_value != 255)
|
||||
// * drop the alpha channel (if keep_alpha is false)
|
||||
const uint32_t round = info.max_value / 2;
|
||||
int k = 0;
|
||||
for (i = 0; i < info.width * info.depth; ++i) {
|
||||
uint32_t v = (sample_size == 2) ? 256u * in[2 * i + 0] + in[2 * i + 1]
|
||||
: in[i];
|
||||
if (info.max_value != 255) v = (v * 255u + round) / info.max_value;
|
||||
if (v > 255u) v = 255u;
|
||||
if (info.depth > 2) {
|
||||
if (!keep_alpha && info.depth == 4 && (i % 4) == 3) {
|
||||
// skip alpha
|
||||
} else {
|
||||
tmp_rgb[k] = v;
|
||||
k += 1;
|
||||
}
|
||||
} else if (info.depth == 1 || (i % 2) == 0) {
|
||||
tmp_rgb[k + 0] = tmp_rgb[k + 1] = tmp_rgb[k + 2] = v;
|
||||
k += 3;
|
||||
} else if (keep_alpha && info.depth == 2) {
|
||||
tmp_rgb[k] = v;
|
||||
k += 1;
|
||||
} else {
|
||||
// skip alpha
|
||||
}
|
||||
}
|
||||
}
|
||||
tmp_rgb += stride;
|
||||
}
|
||||
|
||||
// WebP conversion.
|
||||
pic->width = info.width;
|
||||
pic->height = info.height;
|
||||
ok = (depth == 4) ? WebPPictureImportRGBA(pic, rgb, (int)stride)
|
||||
: WebPPictureImportRGB(pic, rgb, (int)stride);
|
||||
if (!ok) goto End;
|
||||
|
||||
ok = 1;
|
||||
End:
|
||||
free((void*)rgb);
|
||||
|
||||
(void)metadata;
|
||||
(void)keep_alpha;
|
||||
return ok;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
@ -1,37 +0,0 @@
|
||||
// Copyright 2017 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// Use of this source code is governed by a BSD-style license
|
||||
// that can be found in the COPYING file in the root of the source
|
||||
// tree. An additional intellectual property rights grant can be found
|
||||
// in the file PATENTS. All contributing project authors may
|
||||
// be found in the AUTHORS file in the root of the source tree.
|
||||
// -----------------------------------------------------------------------------
|
||||
//
|
||||
// partial PNM format decoder (ppm/pgm)
|
||||
|
||||
#ifndef WEBP_IMAGEIO_PNMDEC_H_
|
||||
#define WEBP_IMAGEIO_PNMDEC_H_
|
||||
|
||||
#include "webp/types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct Metadata;
|
||||
struct WebPPicture;
|
||||
|
||||
// Reads a PNM file from 'data', returning the decoded output in 'pic'.
|
||||
// The output is RGB or YUV depending on pic->use_argb value.
|
||||
// Returns true on success.
|
||||
// 'metadata' has no effect, but is kept for coherence with other signatures
|
||||
// for image readers.
|
||||
int ReadPNM(const uint8_t* const data, size_t data_size,
|
||||
struct WebPPicture* const pic, int keep_alpha,
|
||||
struct Metadata* const metadata);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // WEBP_IMAGEIO_PNMDEC_H_
|
@ -15,7 +15,6 @@
|
||||
#include "webp/config.h"
|
||||
#endif
|
||||
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
@ -108,7 +107,7 @@ static void MyUnmapFile(thandle_t opaque, void* base, toff_t size) {
|
||||
static tsize_t MyRead(thandle_t opaque, void* dst, tsize_t size) {
|
||||
MyData* const my_data = (MyData*)opaque;
|
||||
if (my_data->pos + size > my_data->size) {
|
||||
size = (tsize_t)(my_data->size - my_data->pos);
|
||||
size = my_data->size - my_data->pos;
|
||||
}
|
||||
if (size > 0) {
|
||||
memcpy(dst, my_data->data + my_data->pos, size);
|
||||
@ -117,57 +116,18 @@ static tsize_t MyRead(thandle_t opaque, void* dst, tsize_t size) {
|
||||
return size;
|
||||
}
|
||||
|
||||
// Unmultiply Argb data. Taken from dsp/alpha_processing
|
||||
// (we don't want to force a dependency to a libdspdec library).
|
||||
#define MFIX 24 // 24bit fixed-point arithmetic
|
||||
#define HALF ((1u << MFIX) >> 1)
|
||||
|
||||
static uint32_t Unmult(uint8_t x, uint32_t mult) {
|
||||
const uint32_t v = (x * mult + HALF) >> MFIX;
|
||||
return (v > 255u) ? 255u : v;
|
||||
}
|
||||
|
||||
static WEBP_INLINE uint32_t GetScale(uint32_t a) {
|
||||
return (255u << MFIX) / a;
|
||||
}
|
||||
|
||||
#undef MFIX
|
||||
#undef HALF
|
||||
|
||||
static void MultARGBRow(uint8_t* ptr, int width) {
|
||||
int x;
|
||||
for (x = 0; x < width; ++x, ptr += 4) {
|
||||
const uint32_t alpha = ptr[3];
|
||||
if (alpha < 255) {
|
||||
if (alpha == 0) { // alpha == 0
|
||||
ptr[0] = ptr[1] = ptr[2] = 0;
|
||||
} else {
|
||||
const uint32_t scale = GetScale(alpha);
|
||||
ptr[0] = Unmult(ptr[0], scale);
|
||||
ptr[1] = Unmult(ptr[1], scale);
|
||||
ptr[2] = Unmult(ptr[2], scale);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int ReadTIFF(const uint8_t* const data, size_t data_size,
|
||||
WebPPicture* const pic, int keep_alpha,
|
||||
Metadata* const metadata) {
|
||||
MyData my_data = { data, (toff_t)data_size, 0 };
|
||||
TIFF* tif;
|
||||
uint32_t image_width, image_height, tile_width, tile_height;
|
||||
uint16_t samples_per_px = 0;
|
||||
uint16_t extra_samples = 0;
|
||||
uint16_t* extra_samples_ptr = NULL;
|
||||
uint32_t* raster;
|
||||
uint32 width, height;
|
||||
uint32* raster;
|
||||
int64_t alloc_size;
|
||||
int ok = 0;
|
||||
tdir_t dircount;
|
||||
|
||||
if (data == NULL || data_size == 0 || data_size > INT_MAX || pic == NULL) {
|
||||
return 0;
|
||||
}
|
||||
if (data == NULL || data_size == 0 || pic == NULL) return 0;
|
||||
|
||||
tif = TIFFClientOpen("Memory", "r", &my_data,
|
||||
MyRead, MyRead, MySeek, MyClose,
|
||||
@ -183,63 +143,32 @@ int ReadTIFF(const uint8_t* const data, size_t data_size,
|
||||
"Only the first will be used, %d will be ignored.\n",
|
||||
dircount - 1);
|
||||
}
|
||||
if (!TIFFGetFieldDefaulted(tif, TIFFTAG_SAMPLESPERPIXEL, &samples_per_px)) {
|
||||
fprintf(stderr, "Error! Cannot retrieve TIFF samples-per-pixel info.\n");
|
||||
goto End;
|
||||
}
|
||||
if (samples_per_px < 3 || samples_per_px > 4) goto End; // not supported
|
||||
|
||||
if (!(TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &image_width) &&
|
||||
TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &image_height))) {
|
||||
if (!(TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &width) &&
|
||||
TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &height))) {
|
||||
fprintf(stderr, "Error! Cannot retrieve TIFF image dimensions.\n");
|
||||
goto End;
|
||||
}
|
||||
if (!ImgIoUtilCheckSizeArgumentsOverflow((uint64_t)image_width * image_height,
|
||||
|
||||
if (!ImgIoUtilCheckSizeArgumentsOverflow((uint64_t)width * height,
|
||||
sizeof(*raster))) {
|
||||
goto End;
|
||||
}
|
||||
// According to spec, a tile can be bigger than the image. However it should
|
||||
// be a multiple of 16 and not way too large, so check that it's not more than
|
||||
// twice the image size, for dimensions above some arbitrary minimum 32.
|
||||
if ((TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tile_width) &&
|
||||
tile_width > 32 && tile_width / 2 > image_width) ||
|
||||
(TIFFGetField(tif, TIFFTAG_TILELENGTH, &tile_height) &&
|
||||
tile_height > 32 && tile_height / 2 > image_height)) {
|
||||
fprintf(stderr, "Error! TIFF tile dimensions are too big.\n");
|
||||
goto End;
|
||||
}
|
||||
if (samples_per_px > 3 && !TIFFGetField(tif, TIFFTAG_EXTRASAMPLES,
|
||||
&extra_samples, &extra_samples_ptr)) {
|
||||
fprintf(stderr, "Error! Cannot retrieve TIFF ExtraSamples info.\n");
|
||||
goto End;
|
||||
}
|
||||
|
||||
// _Tiffmalloc uses a signed type for size.
|
||||
alloc_size =
|
||||
(int64_t)((uint64_t)image_width * image_height * sizeof(*raster));
|
||||
alloc_size = (int64_t)((uint64_t)width * height * sizeof(*raster));
|
||||
if (alloc_size < 0 || alloc_size != (tsize_t)alloc_size) goto End;
|
||||
|
||||
raster = (uint32*)_TIFFmalloc((tsize_t)alloc_size);
|
||||
if (raster != NULL) {
|
||||
if (TIFFReadRGBAImageOriented(tif, image_width, image_height, raster,
|
||||
if (TIFFReadRGBAImageOriented(tif, width, height, raster,
|
||||
ORIENTATION_TOPLEFT, 1)) {
|
||||
const int stride = image_width * sizeof(*raster);
|
||||
pic->width = image_width;
|
||||
pic->height = image_height;
|
||||
const int stride = width * sizeof(*raster);
|
||||
pic->width = width;
|
||||
pic->height = height;
|
||||
// TIFF data is ABGR
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
TIFFSwabArrayOfLong(raster, image_width * image_height);
|
||||
TIFFSwabArrayOfLong(raster, width * height);
|
||||
#endif
|
||||
// if we have an alpha channel, we must un-multiply from rgbA to RGBA
|
||||
if (extra_samples == 1 && extra_samples_ptr != NULL &&
|
||||
extra_samples_ptr[0] == EXTRASAMPLE_ASSOCALPHA) {
|
||||
uint32_t y;
|
||||
uint8_t* tmp = (uint8_t*)raster;
|
||||
for (y = 0; y < image_height; ++y) {
|
||||
MultARGBRow(tmp, image_width);
|
||||
tmp += stride;
|
||||
}
|
||||
}
|
||||
ok = keep_alpha
|
||||
? WebPPictureImportRGBA(pic, (const uint8_t*)raster, stride)
|
||||
: WebPPictureImportRGBX(pic, (const uint8_t*)raster, stride);
|
||||
|
@ -9,20 +9,13 @@
|
||||
//
|
||||
// WebP decode.
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "webp/config.h"
|
||||
#endif
|
||||
|
||||
#include "./webpdec.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "webp/decode.h"
|
||||
#include "webp/demux.h"
|
||||
#include "webp/encode.h"
|
||||
#include "../examples/unicode.h"
|
||||
#include "./imageio_util.h"
|
||||
#include "./metadata.h"
|
||||
|
||||
@ -44,7 +37,7 @@ static void PrintAnimationWarning(const WebPDecoderConfig* const config) {
|
||||
}
|
||||
|
||||
void PrintWebPError(const char* const in_file, int status) {
|
||||
WFPRINTF(stderr, "Decoding of %s failed.\n", (const W_CHAR*)in_file);
|
||||
fprintf(stderr, "Decoding of %s failed.\n", in_file);
|
||||
fprintf(stderr, "Status: %d", status);
|
||||
if (status >= VP8_STATUS_OK && status <= VP8_STATUS_NOT_ENOUGH_DATA) {
|
||||
fprintf(stderr, "(%s)", kStatusMessages[status]);
|
||||
@ -65,7 +58,7 @@ int LoadWebP(const char* const in_file,
|
||||
|
||||
status = WebPGetFeatures(*data, *data_size, bitstream);
|
||||
if (status != VP8_STATUS_OK) {
|
||||
WebPFree((void*)*data);
|
||||
free((void*)*data);
|
||||
*data = NULL;
|
||||
*data_size = 0;
|
||||
PrintWebPError(in_file, status);
|
||||
@ -98,47 +91,25 @@ VP8StatusCode DecodeWebPIncremental(
|
||||
fprintf(stderr, "Failed during WebPINewDecoder().\n");
|
||||
return VP8_STATUS_OUT_OF_MEMORY;
|
||||
} else {
|
||||
#ifdef WEBP_EXPERIMENTAL_FEATURES
|
||||
size_t size = 0;
|
||||
const size_t incr = 2 + (data_size / 20);
|
||||
while (size < data_size) {
|
||||
size_t next_size = size + (rand() % incr);
|
||||
if (next_size > data_size) next_size = data_size;
|
||||
status = WebPIUpdate(idec, data, next_size);
|
||||
if (status != VP8_STATUS_OK && status != VP8_STATUS_SUSPENDED) break;
|
||||
size = next_size;
|
||||
}
|
||||
#else
|
||||
status = WebPIUpdate(idec, data, data_size);
|
||||
#endif
|
||||
WebPIDelete(idec);
|
||||
}
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Metadata
|
||||
|
||||
static int ExtractMetadata(const uint8_t* const data, size_t data_size,
|
||||
Metadata* const metadata) {
|
||||
WebPData webp_data = { data, data_size };
|
||||
WebPDemuxer* const demux = WebPDemux(&webp_data);
|
||||
WebPChunkIterator chunk_iter;
|
||||
uint32_t flags;
|
||||
|
||||
if (demux == NULL) return 0;
|
||||
assert(metadata != NULL);
|
||||
|
||||
flags = WebPDemuxGetI(demux, WEBP_FF_FORMAT_FLAGS);
|
||||
|
||||
if ((flags & ICCP_FLAG) && WebPDemuxGetChunk(demux, "ICCP", 1, &chunk_iter)) {
|
||||
MetadataCopy((const char*)chunk_iter.chunk.bytes, chunk_iter.chunk.size,
|
||||
&metadata->iccp);
|
||||
WebPDemuxReleaseChunkIterator(&chunk_iter);
|
||||
}
|
||||
if ((flags & EXIF_FLAG) && WebPDemuxGetChunk(demux, "EXIF", 1, &chunk_iter)) {
|
||||
MetadataCopy((const char*)chunk_iter.chunk.bytes, chunk_iter.chunk.size,
|
||||
&metadata->exif);
|
||||
WebPDemuxReleaseChunkIterator(&chunk_iter);
|
||||
}
|
||||
if ((flags & XMP_FLAG) && WebPDemuxGetChunk(demux, "XMP ", 1, &chunk_iter)) {
|
||||
MetadataCopy((const char*)chunk_iter.chunk.bytes, chunk_iter.chunk.size,
|
||||
&metadata->xmp);
|
||||
WebPDemuxReleaseChunkIterator(&chunk_iter);
|
||||
}
|
||||
WebPDemuxDelete(demux);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
int ReadWebP(const uint8_t* const data, size_t data_size,
|
||||
@ -152,6 +123,11 @@ int ReadWebP(const uint8_t* const data, size_t data_size,
|
||||
|
||||
if (data == NULL || data_size == 0 || pic == NULL) return 0;
|
||||
|
||||
// TODO(jzern): add Exif/XMP/ICC extraction.
|
||||
if (metadata != NULL) {
|
||||
fprintf(stderr, "Warning: metadata extraction from WebP is unsupported.\n");
|
||||
}
|
||||
|
||||
if (!WebPInitDecoderConfig(&config)) {
|
||||
fprintf(stderr, "Library version mismatch!\n");
|
||||
return 0;
|
||||
@ -162,82 +138,52 @@ int ReadWebP(const uint8_t* const data, size_t data_size,
|
||||
PrintWebPError("input data", status);
|
||||
return 0;
|
||||
}
|
||||
|
||||
do {
|
||||
{
|
||||
const int has_alpha = keep_alpha && bitstream->has_alpha;
|
||||
uint64_t stride;
|
||||
pic->width = bitstream->width;
|
||||
pic->height = bitstream->height;
|
||||
if (pic->use_argb) {
|
||||
stride = (uint64_t)bitstream->width * 4;
|
||||
} else {
|
||||
stride = (uint64_t)bitstream->width * (has_alpha ? 5 : 3) / 2;
|
||||
pic->colorspace = has_alpha ? WEBP_YUV420A : WEBP_YUV420;
|
||||
}
|
||||
|
||||
if (!ImgIoUtilCheckSizeArgumentsOverflow(stride, bitstream->height)) {
|
||||
status = VP8_STATUS_OUT_OF_MEMORY;
|
||||
break;
|
||||
}
|
||||
|
||||
ok = WebPPictureAlloc(pic);
|
||||
if (!ok) {
|
||||
status = VP8_STATUS_OUT_OF_MEMORY;
|
||||
break;
|
||||
}
|
||||
if (pic->use_argb) {
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
output_buffer->colorspace = MODE_ARGB;
|
||||
#else
|
||||
output_buffer->colorspace = MODE_BGRA;
|
||||
#endif
|
||||
output_buffer->u.RGBA.rgba = (uint8_t*)pic->argb;
|
||||
output_buffer->u.RGBA.stride = pic->argb_stride * sizeof(uint32_t);
|
||||
output_buffer->u.RGBA.size = output_buffer->u.RGBA.stride * pic->height;
|
||||
output_buffer->colorspace = has_alpha ? MODE_RGBA : MODE_RGB;
|
||||
} else {
|
||||
output_buffer->colorspace = has_alpha ? MODE_YUVA : MODE_YUV;
|
||||
output_buffer->u.YUVA.y = pic->y;
|
||||
output_buffer->u.YUVA.u = pic->u;
|
||||
output_buffer->u.YUVA.v = pic->v;
|
||||
output_buffer->u.YUVA.a = has_alpha ? pic->a : NULL;
|
||||
output_buffer->u.YUVA.y_stride = pic->y_stride;
|
||||
output_buffer->u.YUVA.u_stride = pic->uv_stride;
|
||||
output_buffer->u.YUVA.v_stride = pic->uv_stride;
|
||||
output_buffer->u.YUVA.a_stride = has_alpha ? pic->a_stride : 0;
|
||||
output_buffer->u.YUVA.y_size = pic->height * pic->y_stride;
|
||||
output_buffer->u.YUVA.u_size = (pic->height + 1) / 2 * pic->uv_stride;
|
||||
output_buffer->u.YUVA.v_size = (pic->height + 1) / 2 * pic->uv_stride;
|
||||
output_buffer->u.YUVA.a_size = pic->height * pic->a_stride;
|
||||
}
|
||||
output_buffer->is_external_memory = 1;
|
||||
|
||||
status = DecodeWebP(data, data_size, &config);
|
||||
ok = (status == VP8_STATUS_OK);
|
||||
if (ok && !keep_alpha && pic->use_argb) {
|
||||
// Need to wipe out the alpha value, as requested.
|
||||
int x, y;
|
||||
uint32_t* argb = pic->argb;
|
||||
for (y = 0; y < pic->height; ++y) {
|
||||
for (x = 0; x < pic->width; ++x) argb[x] |= 0xff000000u;
|
||||
argb += pic->argb_stride;
|
||||
if (status == VP8_STATUS_OK) {
|
||||
pic->width = output_buffer->width;
|
||||
pic->height = output_buffer->height;
|
||||
if (pic->use_argb) {
|
||||
const uint8_t* const rgba = output_buffer->u.RGBA.rgba;
|
||||
const int stride = output_buffer->u.RGBA.stride;
|
||||
ok = has_alpha ? WebPPictureImportRGBA(pic, rgba, stride)
|
||||
: WebPPictureImportRGB(pic, rgba, stride);
|
||||
} else {
|
||||
pic->colorspace = has_alpha ? WEBP_YUV420A : WEBP_YUV420;
|
||||
ok = WebPPictureAlloc(pic);
|
||||
if (!ok) {
|
||||
status = VP8_STATUS_OUT_OF_MEMORY;
|
||||
} else {
|
||||
const WebPYUVABuffer* const yuva = &output_buffer->u.YUVA;
|
||||
const int uv_width = (pic->width + 1) >> 1;
|
||||
const int uv_height = (pic->height + 1) >> 1;
|
||||
ImgIoUtilCopyPlane(yuva->y, yuva->y_stride,
|
||||
pic->y, pic->y_stride, pic->width, pic->height);
|
||||
ImgIoUtilCopyPlane(yuva->u, yuva->u_stride,
|
||||
pic->u, pic->uv_stride, uv_width, uv_height);
|
||||
ImgIoUtilCopyPlane(yuva->v, yuva->v_stride,
|
||||
pic->v, pic->uv_stride, uv_width, uv_height);
|
||||
if (has_alpha) {
|
||||
ImgIoUtilCopyPlane(yuva->a, yuva->a_stride,
|
||||
pic->a, pic->a_stride, pic->width, pic->height);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} while (0); // <- so we can 'break' out of the loop
|
||||
}
|
||||
|
||||
if (status != VP8_STATUS_OK) {
|
||||
PrintWebPError("input data", status);
|
||||
ok = 0;
|
||||
}
|
||||
|
||||
WebPFreeDecBuffer(output_buffer);
|
||||
|
||||
if (ok && metadata != NULL) {
|
||||
ok = ExtractMetadata(data, data_size, metadata);
|
||||
if (!ok) {
|
||||
PrintWebPError("metadata", VP8_STATUS_BITSTREAM_ERROR);
|
||||
}
|
||||
}
|
||||
if (!ok) WebPPictureFree(pic);
|
||||
return ok;
|
||||
}
|
||||
|
||||
|
@ -51,7 +51,7 @@ VP8StatusCode DecodeWebPIncremental(
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// Decodes a WebP contained in 'data', returning the decoded output in 'pic'.
|
||||
// Reads a WebP from 'in_file', returning the decoded output in 'pic'.
|
||||
// Output is RGBA or YUVA, depending on pic->use_argb value.
|
||||
// If 'keep_alpha' is true and the WebP has an alpha channel, the output is RGBA
|
||||
// or YUVA. Otherwise, alpha channel is dropped and output is RGB or YUV.
|
||||
|
@ -29,14 +29,12 @@
|
||||
// code with COBJMACROS.
|
||||
#include <ole2.h> // CreateStreamOnHGlobal()
|
||||
#include <shlwapi.h>
|
||||
#include <tchar.h>
|
||||
#include <windows.h>
|
||||
#include <wincodec.h>
|
||||
|
||||
#include "../examples/unicode.h"
|
||||
#include "webp/encode.h"
|
||||
#include "./imageio_util.h"
|
||||
#include "./metadata.h"
|
||||
#include "webp/encode.h"
|
||||
|
||||
#define IFS(fn) \
|
||||
do { \
|
||||
@ -87,7 +85,7 @@ WEBP_DEFINE_GUID(GUID_WICPixelFormat64bppRGBA_,
|
||||
|
||||
static HRESULT OpenInputStream(const char* filename, IStream** stream) {
|
||||
HRESULT hr = S_OK;
|
||||
if (!WSTRCMP(filename, "-")) {
|
||||
if (!strcmp(filename, "-")) {
|
||||
const uint8_t* data = NULL;
|
||||
size_t data_size = 0;
|
||||
const int ok = ImgIoUtilReadFile(filename, &data, &data_size);
|
||||
@ -110,12 +108,11 @@ static HRESULT OpenInputStream(const char* filename, IStream** stream) {
|
||||
hr = E_FAIL;
|
||||
}
|
||||
} else {
|
||||
IFS(SHCreateStreamOnFile((const LPTSTR)filename, STGM_READ, stream));
|
||||
IFS(SHCreateStreamOnFileA(filename, STGM_READ, stream));
|
||||
}
|
||||
|
||||
if (FAILED(hr)) {
|
||||
_ftprintf(stderr, _T("Error opening input file %s (%08lx)\n"),
|
||||
(const LPTSTR)filename, hr);
|
||||
fprintf(stderr, "Error opening input file %s (%08lx)\n", filename, hr);
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
@ -298,15 +295,9 @@ int ReadPictureWithWIC(const char* const filename,
|
||||
factory, stream, NULL,
|
||||
WICDecodeMetadataCacheOnDemand, &decoder));
|
||||
IFS(IWICBitmapDecoder_GetFrameCount(decoder, &frame_count));
|
||||
if (SUCCEEDED(hr)) {
|
||||
if (frame_count == 0) {
|
||||
fprintf(stderr, "No frame found in input file.\n");
|
||||
hr = E_FAIL;
|
||||
} else if (frame_count > 1) {
|
||||
// WIC will be tried before native WebP decoding so avoid duplicating the
|
||||
// error message.
|
||||
hr = E_FAIL;
|
||||
}
|
||||
if (SUCCEEDED(hr) && frame_count == 0) {
|
||||
fprintf(stderr, "No frame found in input file.\n");
|
||||
hr = E_FAIL;
|
||||
}
|
||||
IFS(IWICBitmapDecoder_GetFrame(decoder, 0, &frame));
|
||||
IFS(IWICBitmapFrameDecode_GetPixelFormat(frame, &src_pixel_format));
|
||||
|
63
iosbuild.sh
63
iosbuild.sh
@ -1,9 +1,8 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# This script generates 'WebP.framework' and 'WebPDecoder.framework',
|
||||
# 'WebPDemux.framework' and 'WebPMux.framework'.
|
||||
# An iOS app can decode WebP images by including 'WebPDecoder.framework' and
|
||||
# both encode and decode WebP images by including 'WebP.framework'.
|
||||
# This script generates 'WebP.framework' and 'WebPDecoder.framework'. An iOS
|
||||
# app can decode WebP images by including 'WebPDecoder.framework' and both
|
||||
# encode and decode WebP images by including 'WebP.framework'.
|
||||
#
|
||||
# Run ./iosbuild.sh to generate the frameworks under the current directory
|
||||
# (the previous build will be erased if it exists).
|
||||
@ -13,9 +12,6 @@
|
||||
|
||||
set -e
|
||||
|
||||
# Set this variable based on the desired minimum deployment target.
|
||||
readonly IOS_MIN_VERSION=6.0
|
||||
|
||||
# Extract the latest SDK version from the final field of the form: iphoneosX.Y
|
||||
readonly SDK=$(xcodebuild -showsdks \
|
||||
| grep iphoneos | sort | tail -n 1 | awk '{print substr($NF, 9)}'
|
||||
@ -39,55 +35,35 @@ readonly TOPDIR=$(pwd)
|
||||
readonly BUILDDIR="${TOPDIR}/iosbuild"
|
||||
readonly TARGETDIR="${TOPDIR}/WebP.framework"
|
||||
readonly DECTARGETDIR="${TOPDIR}/WebPDecoder.framework"
|
||||
readonly MUXTARGETDIR="${TOPDIR}/WebPMux.framework"
|
||||
readonly DEMUXTARGETDIR="${TOPDIR}/WebPDemux.framework"
|
||||
readonly DEVELOPER=$(xcode-select --print-path)
|
||||
readonly PLATFORMSROOT="${DEVELOPER}/Platforms"
|
||||
readonly LIPO=$(xcrun -sdk iphoneos${SDK} -find lipo)
|
||||
LIBLIST=''
|
||||
DECLIBLIST=''
|
||||
MUXLIBLIST=''
|
||||
DEMUXLIBLIST=''
|
||||
|
||||
if [[ -z "${SDK}" ]]; then
|
||||
echo "iOS SDK not available"
|
||||
exit 1
|
||||
elif [[ ${SDK%%.*} -gt 8 ]]; then
|
||||
EXTRA_CFLAGS="-fembed-bitcode"
|
||||
elif [[ ${SDK%%.*} -le 6 ]]; then
|
||||
elif [[ ${SDK} < 6.0 ]]; then
|
||||
echo "You need iOS SDK version 6.0 or above"
|
||||
exit 1
|
||||
else
|
||||
echo "iOS SDK Version ${SDK}"
|
||||
fi
|
||||
|
||||
echo "Xcode Version: ${XCODE}"
|
||||
echo "iOS SDK Version: ${SDK}"
|
||||
|
||||
if [[ -e "${BUILDDIR}" || -e "${TARGETDIR}" || -e "${DECTARGETDIR}" \
|
||||
|| -e "${MUXTARGETDIR}" || -e "${DEMUXTARGETDIR}" ]]; then
|
||||
cat << EOF
|
||||
WARNING: The following directories will be deleted:
|
||||
WARNING: ${BUILDDIR}
|
||||
WARNING: ${TARGETDIR}
|
||||
WARNING: ${DECTARGETDIR}
|
||||
WARNING: ${MUXTARGETDIR}
|
||||
WARNING: ${DEMUXTARGETDIR}
|
||||
WARNING: The build will continue in 5 seconds...
|
||||
EOF
|
||||
sleep 5
|
||||
fi
|
||||
rm -rf ${BUILDDIR} ${TARGETDIR} ${DECTARGETDIR} \
|
||||
${MUXTARGETDIR} ${DEMUXTARGETDIR}
|
||||
mkdir -p ${BUILDDIR} ${TARGETDIR}/Headers/ ${DECTARGETDIR}/Headers/ \
|
||||
${MUXTARGETDIR}/Headers/ ${DEMUXTARGETDIR}/Headers/
|
||||
rm -rf ${BUILDDIR} ${TARGETDIR} ${DECTARGETDIR}
|
||||
mkdir -p ${BUILDDIR} ${TARGETDIR}/Headers/ ${DECTARGETDIR}/Headers/
|
||||
|
||||
if [[ ! -e ${SRCDIR}/configure ]]; then
|
||||
if ! (cd ${SRCDIR} && sh autogen.sh); then
|
||||
cat << EOF
|
||||
cat <<EOT
|
||||
Error creating configure script!
|
||||
This script requires the autoconf/automake and libtool to build. MacPorts can
|
||||
be used to obtain these:
|
||||
http://www.macports.org/install.php
|
||||
EOF
|
||||
EOT
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
@ -121,7 +97,7 @@ for PLATFORM in ${PLATFORMS}; do
|
||||
SDKROOT="${PLATFORMSROOT}/"
|
||||
SDKROOT+="${PLATFORM}.platform/Developer/SDKs/${PLATFORM}${SDK}.sdk/"
|
||||
CFLAGS="-arch ${ARCH2:-${ARCH}} -pipe -isysroot ${SDKROOT} -O3 -DNDEBUG"
|
||||
CFLAGS+=" -miphoneos-version-min=${IOS_MIN_VERSION} ${EXTRA_CFLAGS}"
|
||||
CFLAGS+=" -miphoneos-version-min=6.0 ${EXTRA_CFLAGS}"
|
||||
|
||||
set -x
|
||||
export PATH="${DEVROOT}/usr/bin:${OLDPATH}"
|
||||
@ -129,7 +105,6 @@ for PLATFORM in ${PLATFORMS}; do
|
||||
--build=$(${SRCDIR}/config.guess) \
|
||||
--disable-shared --enable-static \
|
||||
--enable-libwebpdecoder --enable-swap-16bit-csp \
|
||||
--enable-libwebpmux \
|
||||
CFLAGS="${CFLAGS}"
|
||||
set +x
|
||||
|
||||
@ -140,8 +115,6 @@ for PLATFORM in ${PLATFORMS}; do
|
||||
|
||||
LIBLIST+=" ${ROOTDIR}/lib/libwebp.a"
|
||||
DECLIBLIST+=" ${ROOTDIR}/lib/libwebpdecoder.a"
|
||||
MUXLIBLIST+=" ${ROOTDIR}/lib/libwebpmux.a"
|
||||
DEMUXLIBLIST+=" ${ROOTDIR}/lib/libwebpdemux.a"
|
||||
|
||||
make clean
|
||||
cd ..
|
||||
@ -149,22 +122,8 @@ for PLATFORM in ${PLATFORMS}; do
|
||||
export PATH=${OLDPATH}
|
||||
done
|
||||
|
||||
echo "LIBLIST = ${LIBLIST}"
|
||||
cp -a ${SRCDIR}/src/webp/{decode,encode,types}.h ${TARGETDIR}/Headers/
|
||||
${LIPO} -create ${LIBLIST} -output ${TARGETDIR}/WebP
|
||||
|
||||
echo "DECLIBLIST = ${DECLIBLIST}"
|
||||
cp -a ${SRCDIR}/src/webp/{decode,types}.h ${DECTARGETDIR}/Headers/
|
||||
${LIPO} -create ${DECLIBLIST} -output ${DECTARGETDIR}/WebPDecoder
|
||||
|
||||
echo "MUXLIBLIST = ${MUXLIBLIST}"
|
||||
cp -a ${SRCDIR}/src/webp/{types,mux,mux_types}.h \
|
||||
${MUXTARGETDIR}/Headers/
|
||||
${LIPO} -create ${MUXLIBLIST} -output ${MUXTARGETDIR}/WebPMux
|
||||
|
||||
echo "DEMUXLIBLIST = ${DEMUXLIBLIST}"
|
||||
cp -a ${SRCDIR}/src/webp/{decode,types,mux_types,demux}.h \
|
||||
${DEMUXTARGETDIR}/Headers/
|
||||
${LIPO} -create ${DEMUXLIBLIST} -output ${DEMUXTARGETDIR}/WebPDemux
|
||||
|
||||
echo "SUCCESS"
|
||||
|
102
makefile.unix
102
makefile.unix
@ -25,26 +25,13 @@ ifeq ($(strip $(shell uname)), Darwin)
|
||||
# Failure observed with: gcc 4.2.1 and 4.0.1.
|
||||
EXTRA_FLAGS += -fno-common
|
||||
EXTRA_FLAGS += -DHAVE_GLUT_GLUT_H
|
||||
EXTRA_FLAGS += -Wno-deprecated-declarations
|
||||
EXTRA_FLAGS += -I/opt/local/include
|
||||
EXTRA_LIBS += -L/opt/local/lib
|
||||
GL_LIBS = -framework GLUT -framework OpenGL
|
||||
else
|
||||
EXTRA_FLAGS += -I/usr/local/include
|
||||
EXTRA_LIBS += -L/usr/local/lib
|
||||
GL_LIBS = -lglut -lGL
|
||||
endif
|
||||
|
||||
# SDL flags: use sdl-config if it exists
|
||||
SDL_CONFIG = $(shell sdl-config --version 2> /dev/null)
|
||||
ifneq ($(SDL_CONFIG),)
|
||||
SDL_LIBS = $(shell sdl-config --libs)
|
||||
SDL_FLAGS = $(shell sdl-config --cflags)
|
||||
else
|
||||
# use best-guess
|
||||
SDL_LIBS = -lSDL
|
||||
SDL_FLAGS =
|
||||
endif
|
||||
|
||||
# To install libraries on Mac OS X:
|
||||
# 1. Install MacPorts (http://www.macports.org/install.php)
|
||||
@ -64,8 +51,11 @@ endif
|
||||
# 'make -f makefile.unix EXTRA_FLAGS=-m32' to that effect.
|
||||
# EXTRA_FLAGS += -m32
|
||||
|
||||
# Extra flags to enable experimental features and code
|
||||
# EXTRA_FLAGS += -DWEBP_EXPERIMENTAL_FEATURES
|
||||
|
||||
# Extra flags to enable byte swap for 16 bit colorspaces.
|
||||
# EXTRA_FLAGS += -DWEBP_SWAP_16BIT_CSP=1
|
||||
# EXTRA_FLAGS += -DWEBP_SWAP_16BIT_CSP
|
||||
|
||||
# Extra flags to enable multi-threading
|
||||
EXTRA_FLAGS += -DWEBP_USE_THREAD
|
||||
@ -89,6 +79,12 @@ EXTRA_FLAGS += -DWEBP_HAVE_SSE41
|
||||
src/dsp/%_sse41.o: EXTRA_FLAGS += -msse4.1
|
||||
endif
|
||||
|
||||
# AVX2-specific flags:
|
||||
ifeq ($(HAVE_AVX2), 1)
|
||||
EXTRA_FLAGS += -DWEBP_HAVE_AVX2
|
||||
src/dsp/%_avx2.o: EXTRA_FLAGS += -mavx2
|
||||
endif
|
||||
|
||||
# NEON-specific flags:
|
||||
# EXTRA_FLAGS += -march=armv7-a -mfloat-abi=hard -mfpu=neon -mtune=cortex-a8
|
||||
# -> seems to make the overall lib slower: -fno-split-wide-types
|
||||
@ -105,23 +101,14 @@ endif
|
||||
|
||||
AR = ar
|
||||
ARFLAGS = r
|
||||
CPPFLAGS = -I. -Isrc/ -Wall
|
||||
ifeq ($(DEBUG), 1)
|
||||
CFLAGS = -g
|
||||
else
|
||||
CFLAGS = -O3 -DNDEBUG
|
||||
endif
|
||||
CFLAGS += $(EXTRA_FLAGS)
|
||||
CPPFLAGS = -Isrc/ -Wall
|
||||
CFLAGS = -O3 -DNDEBUG $(EXTRA_FLAGS)
|
||||
CC = gcc
|
||||
INSTALL = install
|
||||
GROFF = /usr/bin/groff
|
||||
COL = /usr/bin/col
|
||||
LDFLAGS = $(EXTRA_LIBS) $(EXTRA_FLAGS) -lm
|
||||
|
||||
ifdef BITTRACE
|
||||
CFLAGS += -DBITTRACE=$(BITTRACE)
|
||||
endif
|
||||
|
||||
ANIM_UTIL_OBJS = \
|
||||
examples/anim_util.o \
|
||||
|
||||
@ -177,21 +164,21 @@ DSP_DEC_OBJS = \
|
||||
src/dsp/upsampling_msa.o \
|
||||
src/dsp/upsampling_neon.o \
|
||||
src/dsp/upsampling_sse2.o \
|
||||
src/dsp/upsampling_sse41.o \
|
||||
src/dsp/yuv.o \
|
||||
src/dsp/yuv_mips32.o \
|
||||
src/dsp/yuv_mips_dsp_r2.o \
|
||||
src/dsp/yuv_neon.o \
|
||||
src/dsp/yuv_sse2.o \
|
||||
src/dsp/yuv_sse41.o \
|
||||
|
||||
DSP_ENC_OBJS = \
|
||||
src/dsp/argb.o \
|
||||
src/dsp/argb_mips_dsp_r2.o \
|
||||
src/dsp/argb_sse2.o \
|
||||
src/dsp/cost.o \
|
||||
src/dsp/cost_mips32.o \
|
||||
src/dsp/cost_mips_dsp_r2.o \
|
||||
src/dsp/cost_neon.o \
|
||||
src/dsp/cost_sse2.o \
|
||||
src/dsp/enc.o \
|
||||
src/dsp/enc_avx2.o \
|
||||
src/dsp/enc_mips32.o \
|
||||
src/dsp/enc_mips_dsp_r2.o \
|
||||
src/dsp/enc_msa.o \
|
||||
@ -205,16 +192,14 @@ DSP_ENC_OBJS = \
|
||||
src/dsp/lossless_enc_neon.o \
|
||||
src/dsp/lossless_enc_sse2.o \
|
||||
src/dsp/lossless_enc_sse41.o \
|
||||
src/dsp/ssim.o \
|
||||
src/dsp/ssim_sse2.o \
|
||||
|
||||
ENC_OBJS = \
|
||||
src/enc/alpha_enc.o \
|
||||
src/enc/analysis_enc.o \
|
||||
src/enc/backward_references_cost_enc.o \
|
||||
src/enc/backward_references_enc.o \
|
||||
src/enc/config_enc.o \
|
||||
src/enc/cost_enc.o \
|
||||
src/enc/delta_palettization_enc.o \
|
||||
src/enc/filter_enc.o \
|
||||
src/enc/frame_enc.o \
|
||||
src/enc/histogram_enc.o \
|
||||
@ -238,7 +223,6 @@ EX_FORMAT_DEC_OBJS = \
|
||||
imageio/jpegdec.o \
|
||||
imageio/metadata.o \
|
||||
imageio/pngdec.o \
|
||||
imageio/pnmdec.o \
|
||||
imageio/tiffdec.o \
|
||||
imageio/webpdec.o \
|
||||
|
||||
@ -312,6 +296,7 @@ HDRS = \
|
||||
src/dsp/yuv.h \
|
||||
src/enc/backward_references_enc.h \
|
||||
src/enc/cost_enc.h \
|
||||
src/enc/delta_palettization_enc.h \
|
||||
src/enc/histogram_enc.h \
|
||||
src/enc/vp8i_enc.h \
|
||||
src/enc/vp8li_enc.h \
|
||||
@ -343,9 +328,8 @@ OUT_LIBS += src/libwebp.a
|
||||
EXTRA_LIB = extras/libwebpextras.a
|
||||
OUT_EXAMPLES = examples/cwebp examples/dwebp
|
||||
EXTRA_EXAMPLES = examples/gif2webp examples/vwebp examples/webpmux \
|
||||
examples/anim_diff examples/anim_dump \
|
||||
examples/img2webp examples/webpinfo
|
||||
OTHER_EXAMPLES = extras/get_disto extras/webp_quality extras/vwebp_sdl
|
||||
examples/anim_diff examples/img2webp
|
||||
OTHER_EXAMPLES = extras/get_disto extras/webp_quality
|
||||
|
||||
OUTPUT = $(OUT_LIBS) $(OUT_EXAMPLES)
|
||||
ifeq ($(MAKECMDGOALS),clean)
|
||||
@ -372,7 +356,7 @@ src/utils/bit_reader_utils.o: src/utils/endian_inl_utils.h
|
||||
src/utils/bit_writer_utils.o: src/utils/endian_inl_utils.h
|
||||
|
||||
%.o: %.c $(HDRS)
|
||||
$(CC) $(CPPFLAGS) $(CFLAGS) -c $< -o $@
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) -c $< -o $@
|
||||
|
||||
examples/libanim_util.a: $(ANIM_UTIL_OBJS)
|
||||
examples/libexample_util.a: $(EX_UTIL_OBJS)
|
||||
@ -390,76 +374,52 @@ src/demux/libwebpdemux.a: $(LIBWEBPDEMUX_OBJS)
|
||||
$(AR) $(ARFLAGS) $@ $^
|
||||
|
||||
examples/anim_diff: examples/anim_diff.o $(ANIM_UTIL_OBJS) $(GIFDEC_OBJS)
|
||||
examples/anim_dump: examples/anim_dump.o $(ANIM_UTIL_OBJS) $(GIFDEC_OBJS)
|
||||
examples/cwebp: examples/cwebp.o
|
||||
examples/dwebp: examples/dwebp.o
|
||||
examples/gif2webp: examples/gif2webp.o $(GIFDEC_OBJS)
|
||||
examples/vwebp: examples/vwebp.o
|
||||
examples/webpmux: examples/webpmux.o
|
||||
examples/img2webp: examples/img2webp.o
|
||||
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: override EXTRA_LIBS += $(GIF_LIBS)
|
||||
examples/anim_diff: EXTRA_LIBS += $(GIF_LIBS)
|
||||
examples/anim_diff: EXTRA_FLAGS += -DWEBP_HAVE_GIF
|
||||
examples/anim_dump: examples/libanim_util.a examples/libgifdec.a
|
||||
examples/anim_dump: src/demux/libwebpdemux.a
|
||||
examples/anim_dump: examples/libexample_util.a
|
||||
examples/anim_dump: imageio/libimageio_util.a
|
||||
examples/anim_dump: imageio/libimageenc.a
|
||||
examples/anim_dump: src/libwebp.a
|
||||
examples/anim_dump: 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: override EXTRA_LIBS += $(CWEBP_LIBS)
|
||||
examples/cwebp: EXTRA_LIBS += $(CWEBP_LIBS)
|
||||
examples/dwebp: examples/libexample_util.a
|
||||
examples/dwebp: imageio/libimagedec.a
|
||||
examples/dwebp: src/demux/libwebpdemux.a
|
||||
examples/dwebp: imageio/libimageenc.a
|
||||
examples/dwebp: imageio/libimageio_util.a
|
||||
examples/dwebp: src/libwebp.a
|
||||
examples/dwebp: override EXTRA_LIBS += $(DWEBP_LIBS)
|
||||
examples/dwebp: EXTRA_LIBS += $(DWEBP_LIBS)
|
||||
examples/gif2webp: examples/libexample_util.a imageio/libimageio_util.a
|
||||
examples/gif2webp: examples/libgifdec.a src/mux/libwebpmux.a src/libwebp.a
|
||||
examples/gif2webp: override EXTRA_LIBS += $(GIF_LIBS)
|
||||
examples/gif2webp: EXTRA_LIBS += $(GIF_LIBS)
|
||||
examples/gif2webp: EXTRA_FLAGS += -DWEBP_HAVE_GIF
|
||||
examples/vwebp: examples/libexample_util.a src/demux/libwebpdemux.a
|
||||
examples/vwebp: imageio/libimageio_util.a src/libwebp.a
|
||||
examples/vwebp: override EXTRA_LIBS += $(GL_LIBS)
|
||||
examples/vwebp: EXTRA_LIBS += $(GL_LIBS)
|
||||
examples/vwebp: EXTRA_FLAGS += -DWEBP_HAVE_GL
|
||||
examples/webpmux: examples/libexample_util.a imageio/libimageio_util.a
|
||||
examples/webpmux: src/mux/libwebpmux.a src/libwebpdecoder.a
|
||||
examples/img2webp: examples/libexample_util.a imageio/libimageio_util.a
|
||||
examples/img2webp: imageio/libimagedec.a
|
||||
examples/img2webp: src/demux/libwebpdemux.a
|
||||
examples/img2webp: src/mux/libwebpmux.a src/libwebp.a
|
||||
examples/img2webp: override EXTRA_LIBS += $(CWEBP_LIBS)
|
||||
examples/webpinfo: examples/libexample_util.a imageio/libimageio_util.a
|
||||
examples/webpinfo: src/libwebpdecoder.a
|
||||
examples/img2webp: EXTRA_LIBS += $(CWEBP_LIBS)
|
||||
|
||||
extras/get_disto: extras/get_disto.o
|
||||
extras/get_disto: imageio/libimagedec.a
|
||||
extras/get_disto: src/demux/libwebpdemux.a
|
||||
extras/get_disto: imageio/libimageio_util.a
|
||||
extras/get_disto: src/libwebp.a
|
||||
extras/get_disto: override EXTRA_LIBS += $(CWEBP_LIBS)
|
||||
extras/get_disto: imageio/libimagedec.a imageio/libimageio_util.a src/libwebp.a
|
||||
extras/get_disto: EXTRA_LIBS += $(CWEBP_LIBS)
|
||||
|
||||
extras/webp_quality: extras/webp_quality.o
|
||||
extras/webp_quality: imageio/libimageio_util.a
|
||||
extras/webp_quality: $(EXTRA_LIB) src/libwebp.a
|
||||
|
||||
extras/vwebp_sdl: extras/vwebp_sdl.o
|
||||
extras/vwebp_sdl: extras/webp_to_sdl.o
|
||||
extras/vwebp_sdl: imageio/libimageio_util.a
|
||||
extras/vwebp_sdl: src/libwebp.a
|
||||
extras/vwebp_sdl: EXTRA_FLAGS += -DWEBP_HAVE_SDL $(SDL_FLAGS)
|
||||
extras/vwebp_sdl: override EXTRA_LIBS += $(SDL_LIBS)
|
||||
|
||||
$(OUT_EXAMPLES) $(EXTRA_EXAMPLES) $(OTHER_EXAMPLES):
|
||||
$(CC) -o $@ $^ $(LDFLAGS)
|
||||
|
||||
@ -475,9 +435,9 @@ dist: all
|
||||
$(INSTALL) -m644 src/mux/libwebpmux.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 \
|
||||
man/img2webp.1; do \
|
||||
basenam=$$(basename $$m .1); \
|
||||
$(GROFF) -t -e -man -T ascii $$m \
|
||||
$(GROFF) -t -e -man -T utf8 $$m \
|
||||
| $(COL) -bx >$(DESTDIR)/doc/$${basenam}.txt; \
|
||||
$(GROFF) -t -e -man -T html $$m \
|
||||
| $(COL) -bx >$(DESTDIR)/doc/$${basenam}.html; \
|
||||
|
@ -1,17 +1,11 @@
|
||||
man_MANS = cwebp.1 dwebp.1
|
||||
if BUILD_MUX
|
||||
if WANT_MUX
|
||||
man_MANS += webpmux.1
|
||||
endif
|
||||
if BUILD_GIF2WEBP
|
||||
man_MANS += gif2webp.1
|
||||
endif
|
||||
if BUILD_IMG2WEBP
|
||||
man_MANS += img2webp.1
|
||||
endif
|
||||
if BUILD_VWEBP
|
||||
man_MANS += vwebp.1
|
||||
endif
|
||||
if BUILD_WEBPINFO
|
||||
man_MANS += webpinfo.1
|
||||
endif
|
||||
EXTRA_DIST = $(man_MANS)
|
||||
|
23
man/cwebp.1
23
man/cwebp.1
@ -1,5 +1,5 @@
|
||||
.\" Hey, EMACS: -*- nroff -*-
|
||||
.TH CWEBP 1 "November 19, 2020"
|
||||
.TH CWEBP 1 "January 20, 2017"
|
||||
.SH NAME
|
||||
cwebp \- compress an image file to a WebP file
|
||||
.SH SYNOPSIS
|
||||
@ -13,7 +13,6 @@ command.
|
||||
.PP
|
||||
\fBcwebp\fP compresses an image using the WebP format.
|
||||
Input format can be either PNG, JPEG, TIFF, WebP or raw Y'CbCr samples.
|
||||
Note: Animated PNG and WebP files are not supported.
|
||||
.SH OPTIONS
|
||||
The basic options are:
|
||||
.TP
|
||||
@ -42,12 +41,10 @@ the invisible pixel values (R/G/B or Y/U/V) will be preserved only if the
|
||||
\-exact option is used.
|
||||
.TP
|
||||
.BI \-near_lossless " int
|
||||
Specify the level of near\-lossless image preprocessing. This option adjusts
|
||||
pixel values to help compressibility, but has minimal impact on the visual
|
||||
quality. It triggers lossless compression mode automatically. The range is 0
|
||||
(maximum preprocessing) to 100 (no preprocessing, the default). The typical
|
||||
value is around 60. Note that lossy with \fB\-q 100\fP can at times yield
|
||||
better results.
|
||||
Use near\-lossless image preprocessing. This option adjusts pixel values
|
||||
to help compressibility, but has minimal impact on the visual quality.
|
||||
It triggers lossless compression mode automatically.
|
||||
Range is 0 (maximum preprocessing) to 100 (no preprocessing, the default).
|
||||
.TP
|
||||
.BI \-q " float
|
||||
Specify the compression factor for RGB channels between 0 and 100. The default
|
||||
@ -101,7 +98,8 @@ Crop the source to a rectangle with top\-left corner at coordinates
|
||||
This cropping area must be fully contained within the source rectangle.
|
||||
.TP
|
||||
.B \-mt
|
||||
Use multi\-threading for encoding, if possible.
|
||||
Use multi\-threading for encoding, if possible. This option is only effective
|
||||
when using lossy compression on a source with a transparency channel.
|
||||
.TP
|
||||
.B \-low_memory
|
||||
Reduce memory usage of lossy encoding by saving four times the compressed
|
||||
@ -135,13 +133,6 @@ options \fB\-size\fP or \fB\-psnr\fP. Maximum value is 10, default is 1.
|
||||
If options \fB\-size\fP or \fB\-psnr\fP were used, but \fB\-pass\fP wasn't
|
||||
specified, a default value of '6' passes will be used.
|
||||
.TP
|
||||
.BI \-qrange " int int
|
||||
Specifies the permissible interval for the quality factor. This is particularly
|
||||
useful when using multi-pass (\fB\-size\fP or \fB\-psnr\fP options).
|
||||
Default is 0 100.
|
||||
If the quality factor is outside this range, it will be clamped.
|
||||
If the minimum value must be less or equal to the maximum one.
|
||||
.TP
|
||||
.B \-af
|
||||
Turns auto\-filter on. This algorithm will spend additional time optimizing
|
||||
the filtering strength to reach a well\-balanced quality.
|
||||
|
@ -1,5 +1,5 @@
|
||||
.\" Hey, EMACS: -*- nroff -*-
|
||||
.TH DWEBP 1 "November 19, 2020"
|
||||
.TH DWEBP 1 "June 23, 2016"
|
||||
.SH NAME
|
||||
dwebp \- decompress a WebP file to an image file
|
||||
.SH SYNOPSIS
|
||||
@ -12,7 +12,6 @@ This manual page documents the
|
||||
command.
|
||||
.PP
|
||||
\fBdwebp\fP decompresses WebP files into PNG, PAM, PPM or PGM images.
|
||||
Note: Animated WebP files are not supported.
|
||||
.SH OPTIONS
|
||||
The basic options are:
|
||||
.TP
|
||||
|
@ -1,5 +1,5 @@
|
||||
.\" Hey, EMACS: -*- nroff -*-
|
||||
.TH GIF2WEBP 1 "May 1, 2020"
|
||||
.TH GIF2WEBP 1 "January 25, 2017"
|
||||
.SH NAME
|
||||
gif2webp \- Convert a GIF image to WebP
|
||||
.SH SYNOPSIS
|
||||
@ -20,12 +20,6 @@ Specify the name of the output WebP file. If omitted, \fBgif2webp\fP will
|
||||
perform conversion but only report statistics.
|
||||
Using "\-" as output name will direct output to 'stdout'.
|
||||
.TP
|
||||
.BI \-\- " string
|
||||
Explicitly specify the input file. This option is useful if the input
|
||||
file starts with an '\-' for instance. This option must appear \fBlast\fP.
|
||||
Any other options afterward will be ignored. If the input file is "\-",
|
||||
the data will be read from \fIstdin\fP instead of a file.
|
||||
.TP
|
||||
.B \-h, \-help
|
||||
Usage information.
|
||||
.TP
|
||||
@ -62,9 +56,9 @@ larger file size and lower compression quality.
|
||||
.TP
|
||||
.BI \-min_size
|
||||
Encode image to achieve smallest size. This disables key frame insertion and
|
||||
picks the dispose method resulting in the smallest output for each frame. It
|
||||
uses lossless compression by default, but can be combined with \-q, \-m,
|
||||
\-lossy or \-mixed options.
|
||||
picks the dispose method resulting in smallest output for each frame. It uses
|
||||
lossless compression by default, but can be combined with \-q, \-m, \-lossy or
|
||||
\-mixed options.
|
||||
.TP
|
||||
.BI \-kmin " int
|
||||
.TP
|
||||
@ -114,11 +108,8 @@ the value the smoother the picture will appear. Typical values are usually in
|
||||
the range of 20 to 50.
|
||||
.TP
|
||||
.B \-mt
|
||||
Use multi-threading for encoding, if possible.
|
||||
.TP
|
||||
.B \-loop_compatibility
|
||||
If enabled, handle the loop information in a compatible fashion for Chrome
|
||||
version prior to M62 (inclusive) and Firefox.
|
||||
Use multi-threading for encoding, if possible. This option is only effective
|
||||
when using lossy compression.
|
||||
.TP
|
||||
.B \-v
|
||||
Print extra information.
|
||||
@ -143,8 +134,6 @@ gif2webp \-lossy \-m 3 picture.gif \-o picture_lossy.webp
|
||||
gif2webp \-lossy \-f 50 picture.gif \-o picture.webp
|
||||
.br
|
||||
gif2webp \-q 70 \-o picture.webp \-\- \-\-\-picture.gif
|
||||
.br
|
||||
cat picture.gif | gif2webp \-o \- \-\- \- > output.webp
|
||||
|
||||
.SH AUTHORS
|
||||
\fBgif2webp\fP is a part of libwebp and was written by the WebP team.
|
||||
|
@ -1,13 +1,11 @@
|
||||
.\" Hey, EMACS: -*- nroff -*-
|
||||
.TH IMG2WEBP 1 "May 1, 2020"
|
||||
.TH IMG2WEBP 1 "January 23, 2017"
|
||||
.SH NAME
|
||||
img2webp \- create animated WebP file from a sequence of input images.
|
||||
.SH SYNOPSIS
|
||||
.B img2webp
|
||||
[file_level_options] [files] [per_frame_options...]
|
||||
.br
|
||||
.B img2webp argument_file_name
|
||||
.br
|
||||
.SH DESCRIPTION
|
||||
This manual page documents the
|
||||
.B img2webp
|
||||
@ -15,9 +13,6 @@ command.
|
||||
.PP
|
||||
\fBimg2webp\fP compresses a sequence of images using the animated WebP format.
|
||||
Input images can either be PNG, JPEG, TIFF or WebP.
|
||||
If a single file name (not starting with the character '\-') is supplied as
|
||||
the argument, the command line arguments are actually tokenized from this file.
|
||||
This allows for easy scripting or using a large number of arguments.
|
||||
.SH FILE-LEVEL OPTIONS
|
||||
The file-level options are applied at the beginning of the compression process,
|
||||
before the input frames are read.
|
||||
@ -27,7 +22,7 @@ Specify the name of the output WebP file.
|
||||
.TP
|
||||
.BI \-min_size
|
||||
Encode images to achieve smallest size. This disables key frame insertion and
|
||||
picks the parameters resulting in the smallest output for each frame. It uses
|
||||
picks the parameters resulting in smallest output for each frame. It uses
|
||||
lossless compression by default, but can be combined with \-q, \-m, \-lossy or
|
||||
\-mixed options.
|
||||
.TP
|
||||
@ -45,17 +40,14 @@ lossy or lossless compression for each frame heuristically. This global
|
||||
option disables the local option \fB-lossy\fP and \fB-lossless\fP .
|
||||
.TP
|
||||
.BI \-loop " int
|
||||
Specifies the number of times the animation should loop. Using '0'
|
||||
means 'loop indefinitely'.
|
||||
Specifies the number of times the animation should loop. Using '0' means
|
||||
'loop indefinitely'.
|
||||
.TP
|
||||
.BI \-v
|
||||
Be more verbose.
|
||||
.TP
|
||||
.B \-h, \-help
|
||||
A short usage summary.
|
||||
.TP
|
||||
.B \-version
|
||||
Print the version numbers of the relevant libraries used.
|
||||
|
||||
.SH PER-FRAME OPTIONS
|
||||
The per-frame options are applied for the images following as arguments in the
|
||||
|
@ -1,5 +1,5 @@
|
||||
.\" Hey, EMACS: -*- nroff -*-
|
||||
.TH VWEBP 1 "June 5, 2019"
|
||||
.TH VWEBP 1 "November 25, 2016"
|
||||
.SH NAME
|
||||
vwebp \- decompress a WebP file and display it in a window
|
||||
.SH SYNOPSIS
|
||||
@ -38,10 +38,6 @@ It helps by smoothing gradients and avoiding banding artifacts. Default: 50.
|
||||
By default, quantized transparency planes are dithered during decompression,
|
||||
to smooth the gradients. This flag will prevent this dithering.
|
||||
.TP
|
||||
.B \-usebgcolor
|
||||
Fill transparent areas with the bitstream's own background color instead of
|
||||
checkerboard only. Default is white for non-animated images.
|
||||
.TP
|
||||
.B \-mt
|
||||
Use multi-threading for decoding, if possible.
|
||||
.TP
|
||||
@ -60,9 +56,6 @@ the data will be read from \fIstdin\fP instead of a file.
|
||||
.B 'c'
|
||||
Toggle use of color profile.
|
||||
.TP
|
||||
.B 'b'
|
||||
Toggle display of background color.
|
||||
.TP
|
||||
.B 'i'
|
||||
Overlay file information.
|
||||
.TP
|
||||
|
@ -1,80 +0,0 @@
|
||||
.\" Hey, EMACS: -*- nroff -*-
|
||||
.TH WEBPINFO 1 "November 24, 2017"
|
||||
.SH NAME
|
||||
webpinfo \- print out the chunk level structure of WebP files
|
||||
along with basic integrity checks.
|
||||
.SH SYNOPSIS
|
||||
.B webpinfo
|
||||
.I OPTIONS
|
||||
.I INPUT
|
||||
.br
|
||||
.B webpinfo [\-h|\-help|\-H|\-longhelp]
|
||||
.br
|
||||
|
||||
.SH DESCRIPTION
|
||||
This manual page documents the
|
||||
.B webpinfo
|
||||
command.
|
||||
.PP
|
||||
\fBwebpinfo\fP can be used to print out the chunk level structure and bitstream
|
||||
header information of WebP files. It can also check if the files are of valid
|
||||
WebP format.
|
||||
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.B \-version
|
||||
Print the version number (as major.minor.revision) and exit.
|
||||
.TP
|
||||
.B \-quiet
|
||||
Do not show chunk parsing information.
|
||||
.TP
|
||||
.B \-diag
|
||||
Show parsing error diagnosis.
|
||||
.TP
|
||||
.B \-summary
|
||||
Show chunk stats summary.
|
||||
.TP
|
||||
.BI \-bitstream_info
|
||||
Parse bitstream header.
|
||||
.TP
|
||||
.B \-h, \-help
|
||||
A short usage summary.
|
||||
.TP
|
||||
.B \-H, \-longhelp
|
||||
Detailed usage instructions.
|
||||
|
||||
.SH INPUT
|
||||
Input files in WebP format. Input files must come last, following
|
||||
options (if any). There can be multiple input files.
|
||||
|
||||
.SH BUGS
|
||||
Please report all bugs to the issue tracker:
|
||||
https://bugs.chromium.org/p/webp
|
||||
.br
|
||||
Patches welcome! See this page to get started:
|
||||
http://www.webmproject.org/code/contribute/submitting\-patches/
|
||||
|
||||
.SH EXAMPLES
|
||||
.br
|
||||
webpinfo \-h
|
||||
.br
|
||||
webpinfo \-diag \-summary input_file.webp
|
||||
.br
|
||||
webpinfo \-bitstream_info input_file_1.webp input_file_2.webp
|
||||
.br
|
||||
webpinfo *.webp
|
||||
|
||||
.SH AUTHORS
|
||||
\fBwebpinfo\fP is a part of libwebp and was written by the WebP team.
|
||||
.br
|
||||
The latest source tree is available at
|
||||
https://chromium.googlesource.com/webm/libwebp
|
||||
.PP
|
||||
This manual page was written by Hui Su <huisu@google.com>,
|
||||
for the Debian project (and may be used by others).
|
||||
|
||||
.SH SEE ALSO
|
||||
.BR webpmux (1)
|
||||
.br
|
||||
Please refer to http://developers.google.com/speed/webp/ for additional
|
||||
information.
|
@ -1,5 +1,5 @@
|
||||
.\" Hey, EMACS: -*- nroff -*-
|
||||
.TH WEBPMUX 1 "December 12, 2020"
|
||||
.TH WEBPMUX 1 "November 10, 2016"
|
||||
.SH NAME
|
||||
webpmux \- create animated WebP files from non\-animated WebP images, extract
|
||||
frames from animated WebP images, and manage XMP/EXIF metadata and ICC profile.
|
||||
@ -48,8 +48,6 @@ frames from animated WebP images, and manage XMP/EXIF metadata and ICC profile.
|
||||
.B webpmux [\-h|\-help]
|
||||
.br
|
||||
.B webpmux \-version
|
||||
.br
|
||||
.B webpmux argument_file_name
|
||||
.SH DESCRIPTION
|
||||
This manual page documents the
|
||||
.B webpmux
|
||||
@ -57,9 +55,6 @@ command.
|
||||
.PP
|
||||
\fBwebpmux\fP can be used to create/extract from animated WebP files, as well as
|
||||
to add/extract/strip XMP/EXIF metadata and ICC profile.
|
||||
If a single file name (not starting with the character '\-') is supplied as
|
||||
the argument, the command line arguments are actually tokenized from this file.
|
||||
This allows for easy scripting or using a large number of arguments.
|
||||
.SH OPTIONS
|
||||
.SS GET_OPTIONS (\-get):
|
||||
.TP
|
||||
@ -77,11 +72,6 @@ Get nth frame from an animated image. (n = 0 has a special meaning: last frame).
|
||||
|
||||
.SS SET_OPTIONS (\-set)
|
||||
.TP
|
||||
.BI loop " loop_count
|
||||
Set loop count on an animated file.
|
||||
.P
|
||||
Where: 'loop_count' must be in range [0, 65535].
|
||||
.TP
|
||||
.BI icc " file.icc
|
||||
Set ICC profile.
|
||||
.P
|
||||
|
@ -1,10 +1,10 @@
|
||||
# The mux and demux libraries depend on libwebp, thus the '.' to force
|
||||
# the build order so it's available to them.
|
||||
SUBDIRS = dec enc dsp utils .
|
||||
if BUILD_MUX
|
||||
if WANT_MUX
|
||||
SUBDIRS += mux
|
||||
endif
|
||||
if BUILD_DEMUX
|
||||
if WANT_DEMUX
|
||||
SUBDIRS += demux
|
||||
endif
|
||||
|
||||
@ -22,7 +22,6 @@ commondir = $(includedir)/webp
|
||||
libwebp_la_SOURCES =
|
||||
libwebpinclude_HEADERS =
|
||||
libwebpinclude_HEADERS += webp/encode.h
|
||||
|
||||
noinst_HEADERS =
|
||||
noinst_HEADERS += webp/format_constants.h
|
||||
|
||||
@ -36,7 +35,7 @@ libwebp_la_LIBADD += utils/libwebputils.la
|
||||
# other than the ones listed on the command line, i.e., after linking, it will
|
||||
# not have unresolved symbols. Some platforms (Windows among them) require all
|
||||
# symbols in shared libraries to be resolved at library creation.
|
||||
libwebp_la_LDFLAGS = -no-undefined -version-info 8:1:1
|
||||
libwebp_la_LDFLAGS = -no-undefined -version-info 7:0:0
|
||||
libwebpincludedir = $(includedir)/webp
|
||||
pkgconfig_DATA = libwebp.pc
|
||||
|
||||
@ -48,7 +47,7 @@ if BUILD_LIBWEBPDECODER
|
||||
libwebpdecoder_la_LIBADD += dsp/libwebpdspdecode.la
|
||||
libwebpdecoder_la_LIBADD += utils/libwebputilsdecode.la
|
||||
|
||||
libwebpdecoder_la_LDFLAGS = -no-undefined -version-info 4:1:1
|
||||
libwebpdecoder_la_LDFLAGS = -no-undefined -version-info 3:0:0
|
||||
pkgconfig_DATA += libwebpdecoder.pc
|
||||
endif
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
AM_CPPFLAGS += -I$(top_builddir) -I$(top_srcdir)
|
||||
noinst_LTLIBRARIES = libwebpdecode.la
|
||||
|
||||
libwebpdecode_la_SOURCES =
|
||||
@ -25,5 +24,5 @@ libwebpdecodeinclude_HEADERS += ../webp/types.h
|
||||
noinst_HEADERS =
|
||||
noinst_HEADERS += ../webp/format_constants.h
|
||||
|
||||
libwebpdecode_la_CPPFLAGS = $(AM_CPPFLAGS)
|
||||
libwebpdecode_la_CPPFLAGS = $(AM_CPPFLAGS) $(USE_EXPERIMENTAL_CODE)
|
||||
libwebpdecodeincludedir = $(includedir)/webp
|
||||
|
@ -12,13 +12,13 @@
|
||||
// Author: Skal (pascal.massimino@gmail.com)
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "src/dec/alphai_dec.h"
|
||||
#include "src/dec/vp8i_dec.h"
|
||||
#include "src/dec/vp8li_dec.h"
|
||||
#include "src/dsp/dsp.h"
|
||||
#include "src/utils/quant_levels_dec_utils.h"
|
||||
#include "src/utils/utils.h"
|
||||
#include "src/webp/format_constants.h"
|
||||
#include "./alphai_dec.h"
|
||||
#include "./vp8i_dec.h"
|
||||
#include "./vp8li_dec.h"
|
||||
#include "../dsp/dsp.h"
|
||||
#include "../utils/quant_levels_dec_utils.h"
|
||||
#include "../utils/utils.h"
|
||||
#include "../webp/format_constants.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// ALPHDecoder object.
|
||||
|
@ -11,11 +11,11 @@
|
||||
//
|
||||
// Author: Urvang (urvang@google.com)
|
||||
|
||||
#ifndef WEBP_DEC_ALPHAI_DEC_H_
|
||||
#define WEBP_DEC_ALPHAI_DEC_H_
|
||||
#ifndef WEBP_DEC_ALPHAI_H_
|
||||
#define WEBP_DEC_ALPHAI_H_
|
||||
|
||||
#include "src/dec/webpi_dec.h"
|
||||
#include "src/utils/filters_utils.h"
|
||||
#include "./webpi_dec.h"
|
||||
#include "../utils/filters_utils.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -51,4 +51,4 @@ void WebPDeallocateAlphaMemory(VP8Decoder* const dec);
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // WEBP_DEC_ALPHAI_DEC_H_
|
||||
#endif /* WEBP_DEC_ALPHAI_H_ */
|
||||
|
@ -13,15 +13,15 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "src/dec/vp8i_dec.h"
|
||||
#include "src/dec/webpi_dec.h"
|
||||
#include "src/utils/utils.h"
|
||||
#include "./vp8i_dec.h"
|
||||
#include "./webpi_dec.h"
|
||||
#include "../utils/utils.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// WebPDecBuffer
|
||||
|
||||
// Number of bytes per pixel for the different color-spaces.
|
||||
static const uint8_t kModeBpp[MODE_LAST] = {
|
||||
static const int kModeBpp[MODE_LAST] = {
|
||||
3, 4, 3, 4, 4, 2, 2,
|
||||
4, 4, 4, 2, // pre-multiplied modes
|
||||
1, 1 };
|
||||
@ -36,7 +36,7 @@ static int IsValidColorspace(int webp_csp_mode) {
|
||||
// strictly speaking, the very last (or first, if flipped) row
|
||||
// doesn't require padding.
|
||||
#define MIN_BUFFER_SIZE(WIDTH, HEIGHT, STRIDE) \
|
||||
((uint64_t)(STRIDE) * ((HEIGHT) - 1) + (WIDTH))
|
||||
(uint64_t)(STRIDE) * ((HEIGHT) - 1) + (WIDTH)
|
||||
|
||||
static VP8StatusCode CheckDecBuffer(const WebPDecBuffer* const buffer) {
|
||||
int ok = 1;
|
||||
@ -74,8 +74,7 @@ static VP8StatusCode CheckDecBuffer(const WebPDecBuffer* const buffer) {
|
||||
} else { // RGB checks
|
||||
const WebPRGBABuffer* const buf = &buffer->u.RGBA;
|
||||
const int stride = abs(buf->stride);
|
||||
const uint64_t size =
|
||||
MIN_BUFFER_SIZE(width * kModeBpp[mode], height, stride);
|
||||
const uint64_t size = MIN_BUFFER_SIZE(width, height, stride);
|
||||
ok &= (size <= buf->size);
|
||||
ok &= (stride >= width * kModeBpp[mode]);
|
||||
ok &= (buf->rgba != NULL);
|
||||
@ -99,14 +98,9 @@ static VP8StatusCode AllocateBuffer(WebPDecBuffer* const buffer) {
|
||||
uint64_t uv_size = 0, a_size = 0, total_size;
|
||||
// We need memory and it hasn't been allocated yet.
|
||||
// => initialize output buffer, now that dimensions are known.
|
||||
int stride;
|
||||
uint64_t size;
|
||||
const int stride = w * kModeBpp[mode];
|
||||
const uint64_t size = (uint64_t)stride * h;
|
||||
|
||||
if ((uint64_t)w * kModeBpp[mode] >= (1ull << 32)) {
|
||||
return VP8_STATUS_INVALID_PARAM;
|
||||
}
|
||||
stride = w * kModeBpp[mode];
|
||||
size = (uint64_t)stride * h;
|
||||
if (!WebPIsRGBMode(mode)) {
|
||||
uv_stride = (w + 1) / 2;
|
||||
uv_size = (uint64_t)uv_stride * ((h + 1) / 2);
|
||||
@ -175,11 +169,11 @@ VP8StatusCode WebPFlipBuffer(WebPDecBuffer* const buffer) {
|
||||
return VP8_STATUS_OK;
|
||||
}
|
||||
|
||||
VP8StatusCode WebPAllocateDecBuffer(int width, int height,
|
||||
VP8StatusCode WebPAllocateDecBuffer(int w, int h,
|
||||
const WebPDecoderOptions* const options,
|
||||
WebPDecBuffer* const buffer) {
|
||||
WebPDecBuffer* const out) {
|
||||
VP8StatusCode status;
|
||||
if (buffer == NULL || width <= 0 || height <= 0) {
|
||||
if (out == NULL || w <= 0 || h <= 0) {
|
||||
return VP8_STATUS_INVALID_PARAM;
|
||||
}
|
||||
if (options != NULL) { // First, apply options if there is any.
|
||||
@ -188,39 +182,33 @@ VP8StatusCode WebPAllocateDecBuffer(int width, int height,
|
||||
const int ch = options->crop_height;
|
||||
const int x = options->crop_left & ~1;
|
||||
const int y = options->crop_top & ~1;
|
||||
if (x < 0 || y < 0 || cw <= 0 || ch <= 0 ||
|
||||
x + cw > width || y + ch > height) {
|
||||
if (x < 0 || y < 0 || cw <= 0 || ch <= 0 || x + cw > w || y + ch > h) {
|
||||
return VP8_STATUS_INVALID_PARAM; // out of frame boundary.
|
||||
}
|
||||
width = cw;
|
||||
height = ch;
|
||||
w = cw;
|
||||
h = ch;
|
||||
}
|
||||
|
||||
if (options->use_scaling) {
|
||||
#if !defined(WEBP_REDUCE_SIZE)
|
||||
int scaled_width = options->scaled_width;
|
||||
int scaled_height = options->scaled_height;
|
||||
if (!WebPRescalerGetScaledDimensions(
|
||||
width, height, &scaled_width, &scaled_height)) {
|
||||
w, h, &scaled_width, &scaled_height)) {
|
||||
return VP8_STATUS_INVALID_PARAM;
|
||||
}
|
||||
width = scaled_width;
|
||||
height = scaled_height;
|
||||
#else
|
||||
return VP8_STATUS_INVALID_PARAM; // rescaling not supported
|
||||
#endif
|
||||
w = scaled_width;
|
||||
h = scaled_height;
|
||||
}
|
||||
}
|
||||
buffer->width = width;
|
||||
buffer->height = height;
|
||||
out->width = w;
|
||||
out->height = h;
|
||||
|
||||
// Then, allocate buffer for real.
|
||||
status = AllocateBuffer(buffer);
|
||||
status = AllocateBuffer(out);
|
||||
if (status != VP8_STATUS_OK) return status;
|
||||
|
||||
// Use the stride trick if vertical flip is needed.
|
||||
if (options != NULL && options->flip) {
|
||||
status = WebPFlipBuffer(buffer);
|
||||
status = WebPFlipBuffer(out);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
@ -11,8 +11,8 @@
|
||||
//
|
||||
// Author: Skal (pascal.massimino@gmail.com)
|
||||
|
||||
#ifndef WEBP_DEC_COMMON_DEC_H_
|
||||
#define WEBP_DEC_COMMON_DEC_H_
|
||||
#ifndef WEBP_DEC_COMMON_H_
|
||||
#define WEBP_DEC_COMMON_H_
|
||||
|
||||
// intra prediction modes
|
||||
enum { B_DC_PRED = 0, // 4x4 modes
|
||||
@ -51,4 +51,4 @@ enum { MB_FEATURE_TREE_PROBS = 3,
|
||||
NUM_PROBAS = 11
|
||||
};
|
||||
|
||||
#endif // WEBP_DEC_COMMON_DEC_H_
|
||||
#endif // WEBP_DEC_COMMON_H_
|
||||
|
@ -12,13 +12,13 @@
|
||||
// Author: Skal (pascal.massimino@gmail.com)
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "src/dec/vp8i_dec.h"
|
||||
#include "src/utils/utils.h"
|
||||
#include "./vp8i_dec.h"
|
||||
#include "../utils/utils.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Main reconstruction function.
|
||||
|
||||
static const uint16_t kScan[16] = {
|
||||
static const int kScan[16] = {
|
||||
0 + 0 * BPS, 4 + 0 * BPS, 8 + 0 * BPS, 12 + 0 * BPS,
|
||||
0 + 4 * BPS, 4 + 4 * BPS, 8 + 4 * BPS, 12 + 4 * BPS,
|
||||
0 + 8 * BPS, 4 + 8 * BPS, 8 + 8 * BPS, 12 + 8 * BPS,
|
||||
@ -320,7 +320,7 @@ static void PrecomputeFilterStrengths(VP8Decoder* const dec) {
|
||||
#define MIN_DITHER_AMP 4
|
||||
|
||||
#define DITHER_AMP_TAB_SIZE 12
|
||||
static const uint8_t kQuantToDitherAmp[DITHER_AMP_TAB_SIZE] = {
|
||||
static const int kQuantToDitherAmp[DITHER_AMP_TAB_SIZE] = {
|
||||
// roughly, it's dqm->uv_mat_[1]
|
||||
8, 7, 6, 4, 4, 2, 2, 2, 1, 1, 1, 1
|
||||
};
|
||||
@ -338,6 +338,7 @@ void VP8InitDithering(const WebPDecoderOptions* const options,
|
||||
for (s = 0; s < NUM_MB_SEGMENTS; ++s) {
|
||||
VP8QuantMatrix* const dqm = &dec->dqm_[s];
|
||||
if (dqm->uv_quant_ < DITHER_AMP_TAB_SIZE) {
|
||||
// TODO(skal): should we specially dither more for uv_quant_ < 0?
|
||||
const int idx = (dqm->uv_quant_ < 0) ? 0 : dqm->uv_quant_;
|
||||
dqm->dither_ = (f * kQuantToDitherAmp[idx]) >> 3;
|
||||
}
|
||||
@ -399,9 +400,7 @@ static void DitherRow(VP8Decoder* const dec) {
|
||||
#define MACROBLOCK_VPOS(mb_y) ((mb_y) * 16) // vertical position of a MB
|
||||
|
||||
// Finalize and transmit a complete row. Return false in case of user-abort.
|
||||
static int FinishRow(void* arg1, void* arg2) {
|
||||
VP8Decoder* const dec = (VP8Decoder*)arg1;
|
||||
VP8Io* const io = (VP8Io*)arg2;
|
||||
static int FinishRow(VP8Decoder* const dec, VP8Io* const io) {
|
||||
int ok = 1;
|
||||
const VP8ThreadContext* const ctx = &dec->thread_ctx_;
|
||||
const int cache_id = ctx->id_;
|
||||
@ -449,9 +448,10 @@ static int FinishRow(void* arg1, void* arg2) {
|
||||
if (y_end > io->crop_bottom) {
|
||||
y_end = io->crop_bottom; // make sure we don't overflow on last row.
|
||||
}
|
||||
// If dec->alpha_data_ is not NULL, we have some alpha plane present.
|
||||
io->a = NULL;
|
||||
if (dec->alpha_data_ != NULL && y_start < y_end) {
|
||||
// TODO(skal): testing presence of alpha with dec->alpha_data_ is not a
|
||||
// good idea.
|
||||
io->a = VP8DecompressAlphaRows(dec, io, y_start, y_end - y_start);
|
||||
if (io->a == NULL) {
|
||||
return VP8SetError(dec, VP8_STATUS_BITSTREAM_ERROR,
|
||||
@ -558,6 +558,7 @@ VP8StatusCode VP8EnterCritical(VP8Decoder* const dec, VP8Io* const io) {
|
||||
if (io->bypass_filtering) {
|
||||
dec->filter_type_ = 0;
|
||||
}
|
||||
// TODO(skal): filter type / strength / sharpness forcing
|
||||
|
||||
// Define the area where we can skip in-loop filtering, in case of cropping.
|
||||
//
|
||||
@ -568,6 +569,8 @@ VP8StatusCode VP8EnterCritical(VP8Decoder* const dec, VP8Io* const io) {
|
||||
// Means: there's a dependency chain that goes all the way up to the
|
||||
// top-left corner of the picture (MB #0). We must filter all the previous
|
||||
// macroblocks.
|
||||
// TODO(skal): add an 'approximate_decoding' option, that won't produce
|
||||
// a 1:1 bit-exactness for complex filtering?
|
||||
{
|
||||
const int extra_pixels = kFilterExtraRows[dec->filter_type_];
|
||||
if (dec->filter_type_ == 2) {
|
||||
@ -648,7 +651,7 @@ static int InitThreadContext(VP8Decoder* const dec) {
|
||||
}
|
||||
worker->data1 = dec;
|
||||
worker->data2 = (void*)&dec->thread_ctx_.io_;
|
||||
worker->hook = FinishRow;
|
||||
worker->hook = (WebPWorkerHook)FinishRow;
|
||||
dec->num_caches_ =
|
||||
(dec->filter_type_ > 0) ? MT_CACHE_LINES : MT_CACHE_LINES - 1;
|
||||
} else {
|
||||
@ -668,9 +671,15 @@ int VP8GetThreadMethod(const WebPDecoderOptions* const options,
|
||||
(void)height;
|
||||
assert(headers == NULL || !headers->is_lossless);
|
||||
#if defined(WEBP_USE_THREAD)
|
||||
if (width >= MIN_WIDTH_FOR_THREADS) return 2;
|
||||
if (width < MIN_WIDTH_FOR_THREADS) return 0;
|
||||
// TODO(skal): tune the heuristic further
|
||||
#if 0
|
||||
if (height < 2 * width) return 2;
|
||||
#endif
|
||||
return 2;
|
||||
#else // !WEBP_USE_THREAD
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
#undef MT_CACHE_LINES
|
||||
@ -719,7 +728,7 @@ static int AllocateMemory(VP8Decoder* const dec) {
|
||||
}
|
||||
|
||||
mem = (uint8_t*)dec->mem_;
|
||||
dec->intra_t_ = mem;
|
||||
dec->intra_t_ = (uint8_t*)mem;
|
||||
mem += intra_pred_mode_size;
|
||||
|
||||
dec->yuv_t_ = (VP8TopSamples*)mem;
|
||||
@ -732,7 +741,7 @@ static int AllocateMemory(VP8Decoder* const dec) {
|
||||
mem += f_info_size;
|
||||
dec->thread_ctx_.id_ = 0;
|
||||
dec->thread_ctx_.f_info_ = dec->f_info_;
|
||||
if (dec->filter_type_ > 0 && dec->mt_method_ > 0) {
|
||||
if (dec->mt_method_ > 0) {
|
||||
// secondary cache line. The deblocking process need to make use of the
|
||||
// filtering strength from previous macroblock row, while the new ones
|
||||
// are being decoded in parallel. We'll just swap the pointers.
|
||||
@ -741,7 +750,7 @@ static int AllocateMemory(VP8Decoder* const dec) {
|
||||
|
||||
mem = (uint8_t*)WEBP_ALIGN(mem);
|
||||
assert((yuv_size & WEBP_ALIGN_CST) == 0);
|
||||
dec->yuv_b_ = mem;
|
||||
dec->yuv_b_ = (uint8_t*)mem;
|
||||
mem += yuv_size;
|
||||
|
||||
dec->mb_data_ = (VP8MBData*)mem;
|
||||
@ -757,7 +766,7 @@ static int AllocateMemory(VP8Decoder* const dec) {
|
||||
const int extra_rows = kFilterExtraRows[dec->filter_type_];
|
||||
const int extra_y = extra_rows * dec->cache_y_stride_;
|
||||
const int extra_uv = (extra_rows / 2) * dec->cache_uv_stride_;
|
||||
dec->cache_y_ = mem + extra_y;
|
||||
dec->cache_y_ = ((uint8_t*)mem) + extra_y;
|
||||
dec->cache_u_ = dec->cache_y_
|
||||
+ 16 * num_caches * dec->cache_y_stride_ + extra_uv;
|
||||
dec->cache_v_ = dec->cache_u_
|
||||
@ -767,7 +776,7 @@ static int AllocateMemory(VP8Decoder* const dec) {
|
||||
mem += cache_size;
|
||||
|
||||
// alpha plane
|
||||
dec->alpha_plane_ = alpha_size ? mem : NULL;
|
||||
dec->alpha_plane_ = alpha_size ? (uint8_t*)mem : NULL;
|
||||
mem += alpha_size;
|
||||
assert(mem <= (uint8_t*)dec->mem_ + dec->mem_size_);
|
||||
|
||||
|
@ -15,10 +15,10 @@
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "src/dec/alphai_dec.h"
|
||||
#include "src/dec/webpi_dec.h"
|
||||
#include "src/dec/vp8i_dec.h"
|
||||
#include "src/utils/utils.h"
|
||||
#include "./alphai_dec.h"
|
||||
#include "./webpi_dec.h"
|
||||
#include "./vp8i_dec.h"
|
||||
#include "../utils/utils.h"
|
||||
|
||||
// In append mode, buffer allocations increase as multiples of this value.
|
||||
// Needs to be a power of 2.
|
||||
@ -140,9 +140,10 @@ static void DoRemap(WebPIDecoder* const idec, ptrdiff_t offset) {
|
||||
if (NeedCompressedAlpha(idec)) {
|
||||
ALPHDecoder* const alph_dec = dec->alph_dec_;
|
||||
dec->alpha_data_ += offset;
|
||||
if (alph_dec != NULL && alph_dec->vp8l_dec_ != NULL) {
|
||||
if (alph_dec != NULL) {
|
||||
if (alph_dec->method_ == ALPHA_LOSSLESS_COMPRESSION) {
|
||||
VP8LDecoder* const alph_vp8l_dec = alph_dec->vp8l_dec_;
|
||||
assert(alph_vp8l_dec != NULL);
|
||||
assert(dec->alpha_data_size_ >= ALPHA_HEADER_LEN);
|
||||
VP8LBitReaderSetBuffer(&alph_vp8l_dec->br_,
|
||||
dec->alpha_data_ + ALPHA_HEADER_LEN,
|
||||
@ -166,11 +167,9 @@ static int AppendToMemBuffer(WebPIDecoder* const idec,
|
||||
VP8Decoder* const dec = (VP8Decoder*)idec->dec_;
|
||||
MemBuffer* const mem = &idec->mem_;
|
||||
const int need_compressed_alpha = NeedCompressedAlpha(idec);
|
||||
const uint8_t* const old_start =
|
||||
(mem->buf_ == NULL) ? NULL : mem->buf_ + mem->start_;
|
||||
const uint8_t* const old_start = mem->buf_ + mem->start_;
|
||||
const uint8_t* const old_base =
|
||||
need_compressed_alpha ? dec->alpha_data_ : old_start;
|
||||
assert(mem->buf_ != NULL || mem->start_ == 0);
|
||||
assert(mem->mode_ == MEM_MODE_APPEND);
|
||||
if (data_size > MAX_CHUNK_PAYLOAD) {
|
||||
// security safeguard: trying to allocate more than what the format
|
||||
@ -186,7 +185,7 @@ static int AppendToMemBuffer(WebPIDecoder* const idec,
|
||||
uint8_t* const new_buf =
|
||||
(uint8_t*)WebPSafeMalloc(extra_size, sizeof(*new_buf));
|
||||
if (new_buf == NULL) return 0;
|
||||
if (old_base != NULL) memcpy(new_buf, old_base, current_size);
|
||||
memcpy(new_buf, old_base, current_size);
|
||||
WebPSafeFree(mem->buf_);
|
||||
mem->buf_ = new_buf;
|
||||
mem->buf_size_ = (size_t)extra_size;
|
||||
@ -194,7 +193,6 @@ static int AppendToMemBuffer(WebPIDecoder* const idec,
|
||||
mem->end_ = current_size;
|
||||
}
|
||||
|
||||
assert(mem->buf_ != NULL);
|
||||
memcpy(mem->buf_ + mem->end_, data, data_size);
|
||||
mem->end_ += data_size;
|
||||
assert(mem->end_ <= mem->buf_size_);
|
||||
@ -207,9 +205,7 @@ static int RemapMemBuffer(WebPIDecoder* const idec,
|
||||
const uint8_t* const data, size_t data_size) {
|
||||
MemBuffer* const mem = &idec->mem_;
|
||||
const uint8_t* const old_buf = mem->buf_;
|
||||
const uint8_t* const old_start =
|
||||
(old_buf == NULL) ? NULL : old_buf + mem->start_;
|
||||
assert(old_buf != NULL || mem->start_ == 0);
|
||||
const uint8_t* const old_start = old_buf + mem->start_;
|
||||
assert(mem->mode_ == MEM_MODE_MAP);
|
||||
|
||||
if (data_size < mem->buf_size_) return 0; // can't remap to a shorter buffer!
|
||||
@ -287,8 +283,10 @@ static void RestoreContext(const MBContext* context, VP8Decoder* const dec,
|
||||
|
||||
static VP8StatusCode IDecError(WebPIDecoder* const idec, VP8StatusCode error) {
|
||||
if (idec->state_ == STATE_VP8_DATA) {
|
||||
// Synchronize the thread, clean-up and check for errors.
|
||||
VP8ExitCritical((VP8Decoder*)idec->dec_, &idec->io_);
|
||||
VP8Io* const io = &idec->io_;
|
||||
if (io->teardown != NULL) {
|
||||
io->teardown(io);
|
||||
}
|
||||
}
|
||||
idec->state_ = STATE_ERROR;
|
||||
return error;
|
||||
@ -453,10 +451,7 @@ static VP8StatusCode DecodeRemaining(WebPIDecoder* const idec) {
|
||||
VP8Decoder* const dec = (VP8Decoder*)idec->dec_;
|
||||
VP8Io* const io = &idec->io_;
|
||||
|
||||
// Make sure partition #0 has been read before, to set dec to ready_.
|
||||
if (!dec->ready_) {
|
||||
return IDecError(idec, VP8_STATUS_BITSTREAM_ERROR);
|
||||
}
|
||||
assert(dec->ready_);
|
||||
for (; dec->mb_y_ < dec->mb_h_; ++dec->mb_y_) {
|
||||
if (idec->last_mb_y_ != dec->mb_y_) {
|
||||
if (!VP8ParseIntraModeRow(&dec->br_, dec)) {
|
||||
@ -478,12 +473,6 @@ static VP8StatusCode DecodeRemaining(WebPIDecoder* const idec) {
|
||||
MemDataSize(&idec->mem_) > MAX_MB_SIZE) {
|
||||
return IDecError(idec, VP8_STATUS_BITSTREAM_ERROR);
|
||||
}
|
||||
// Synchronize the threads.
|
||||
if (dec->mt_method_ > 0) {
|
||||
if (!WebPGetWorkerInterface()->Sync(&dec->worker_)) {
|
||||
return IDecError(idec, VP8_STATUS_BITSTREAM_ERROR);
|
||||
}
|
||||
}
|
||||
RestoreContext(&context, dec, token_br);
|
||||
return VP8_STATUS_SUSPENDED;
|
||||
}
|
||||
@ -502,7 +491,6 @@ static VP8StatusCode DecodeRemaining(WebPIDecoder* const idec) {
|
||||
}
|
||||
// Synchronize the thread and check for errors.
|
||||
if (!VP8ExitCritical(dec, io)) {
|
||||
idec->state_ = STATE_ERROR; // prevent re-entry in IDecError
|
||||
return IDecError(idec, VP8_STATUS_USER_ABORT);
|
||||
}
|
||||
dec->ready_ = 0;
|
||||
@ -583,10 +571,6 @@ static VP8StatusCode IDecode(WebPIDecoder* idec) {
|
||||
status = DecodePartition0(idec);
|
||||
}
|
||||
if (idec->state_ == STATE_VP8_DATA) {
|
||||
const VP8Decoder* const dec = (VP8Decoder*)idec->dec_;
|
||||
if (dec == NULL) {
|
||||
return VP8_STATUS_SUSPENDED; // can't continue if we have no decoder.
|
||||
}
|
||||
status = DecodeRemaining(idec);
|
||||
}
|
||||
if (idec->state_ == STATE_VP8L_HEADER) {
|
||||
@ -689,12 +673,12 @@ void WebPIDelete(WebPIDecoder* idec) {
|
||||
//------------------------------------------------------------------------------
|
||||
// Wrapper toward WebPINewDecoder
|
||||
|
||||
WebPIDecoder* WebPINewRGB(WEBP_CSP_MODE csp, uint8_t* output_buffer,
|
||||
WebPIDecoder* WebPINewRGB(WEBP_CSP_MODE mode, uint8_t* output_buffer,
|
||||
size_t output_buffer_size, int output_stride) {
|
||||
const int is_external_memory = (output_buffer != NULL) ? 1 : 0;
|
||||
WebPIDecoder* idec;
|
||||
|
||||
if (csp >= MODE_YUV) return NULL;
|
||||
if (mode >= MODE_YUV) return NULL;
|
||||
if (is_external_memory == 0) { // Overwrite parameters to sane values.
|
||||
output_buffer_size = 0;
|
||||
output_stride = 0;
|
||||
@ -705,7 +689,7 @@ WebPIDecoder* WebPINewRGB(WEBP_CSP_MODE csp, uint8_t* output_buffer,
|
||||
}
|
||||
idec = WebPINewDecoder(NULL);
|
||||
if (idec == NULL) return NULL;
|
||||
idec->output_.colorspace = csp;
|
||||
idec->output_.colorspace = mode;
|
||||
idec->output_.is_external_memory = is_external_memory;
|
||||
idec->output_.u.RGBA.rgba = output_buffer;
|
||||
idec->output_.u.RGBA.stride = output_stride;
|
||||
|
@ -13,11 +13,11 @@
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include "src/dec/vp8i_dec.h"
|
||||
#include "src/dec/webpi_dec.h"
|
||||
#include "src/dsp/dsp.h"
|
||||
#include "src/dsp/yuv.h"
|
||||
#include "src/utils/utils.h"
|
||||
#include "../dec/vp8i_dec.h"
|
||||
#include "./webpi_dec.h"
|
||||
#include "../dsp/dsp.h"
|
||||
#include "../dsp/yuv.h"
|
||||
#include "../utils/utils.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Main YUV<->RGB conversion functions
|
||||
@ -25,16 +25,21 @@
|
||||
static int EmitYUV(const VP8Io* const io, WebPDecParams* const p) {
|
||||
WebPDecBuffer* output = p->output;
|
||||
const WebPYUVABuffer* const buf = &output->u.YUVA;
|
||||
uint8_t* const y_dst = buf->y + (size_t)io->mb_y * buf->y_stride;
|
||||
uint8_t* const u_dst = buf->u + (size_t)(io->mb_y >> 1) * buf->u_stride;
|
||||
uint8_t* const v_dst = buf->v + (size_t)(io->mb_y >> 1) * buf->v_stride;
|
||||
uint8_t* const y_dst = buf->y + io->mb_y * buf->y_stride;
|
||||
uint8_t* const u_dst = buf->u + (io->mb_y >> 1) * buf->u_stride;
|
||||
uint8_t* const v_dst = buf->v + (io->mb_y >> 1) * buf->v_stride;
|
||||
const int mb_w = io->mb_w;
|
||||
const int mb_h = io->mb_h;
|
||||
const int uv_w = (mb_w + 1) / 2;
|
||||
const int uv_h = (mb_h + 1) / 2;
|
||||
WebPCopyPlane(io->y, io->y_stride, y_dst, buf->y_stride, mb_w, mb_h);
|
||||
WebPCopyPlane(io->u, io->uv_stride, u_dst, buf->u_stride, uv_w, uv_h);
|
||||
WebPCopyPlane(io->v, io->uv_stride, v_dst, buf->v_stride, uv_w, uv_h);
|
||||
int j;
|
||||
for (j = 0; j < mb_h; ++j) {
|
||||
memcpy(y_dst + j * buf->y_stride, io->y + j * io->y_stride, mb_w);
|
||||
}
|
||||
for (j = 0; j < uv_h; ++j) {
|
||||
memcpy(u_dst + j * buf->u_stride, io->u + j * io->uv_stride, uv_w);
|
||||
memcpy(v_dst + j * buf->v_stride, io->v + j * io->uv_stride, uv_w);
|
||||
}
|
||||
return io->mb_h;
|
||||
}
|
||||
|
||||
@ -42,7 +47,7 @@ static int EmitYUV(const VP8Io* const io, WebPDecParams* const p) {
|
||||
static int EmitSampledRGB(const VP8Io* const io, WebPDecParams* const p) {
|
||||
WebPDecBuffer* const output = p->output;
|
||||
WebPRGBABuffer* const buf = &output->u.RGBA;
|
||||
uint8_t* const dst = buf->rgba + (size_t)io->mb_y * buf->stride;
|
||||
uint8_t* const dst = buf->rgba + io->mb_y * buf->stride;
|
||||
WebPSamplerProcessPlane(io->y, io->y_stride,
|
||||
io->u, io->v, io->uv_stride,
|
||||
dst, buf->stride, io->mb_w, io->mb_h,
|
||||
@ -57,7 +62,7 @@ static int EmitSampledRGB(const VP8Io* const io, WebPDecParams* const p) {
|
||||
static int EmitFancyRGB(const VP8Io* const io, WebPDecParams* const p) {
|
||||
int num_lines_out = io->mb_h; // a priori guess
|
||||
const WebPRGBABuffer* const buf = &p->output->u.RGBA;
|
||||
uint8_t* dst = buf->rgba + (size_t)io->mb_y * buf->stride;
|
||||
uint8_t* dst = buf->rgba + io->mb_y * buf->stride;
|
||||
WebPUpsampleLinePairFunc upsample = WebPUpsamplers[p->output->colorspace];
|
||||
const uint8_t* cur_y = io->y;
|
||||
const uint8_t* cur_u = io->u;
|
||||
@ -128,7 +133,7 @@ static int EmitAlphaYUV(const VP8Io* const io, WebPDecParams* const p,
|
||||
const WebPYUVABuffer* const buf = &p->output->u.YUVA;
|
||||
const int mb_w = io->mb_w;
|
||||
const int mb_h = io->mb_h;
|
||||
uint8_t* dst = buf->a + (size_t)io->mb_y * buf->a_stride;
|
||||
uint8_t* dst = buf->a + io->mb_y * buf->a_stride;
|
||||
int j;
|
||||
(void)expected_num_lines_out;
|
||||
assert(expected_num_lines_out == mb_h);
|
||||
@ -181,7 +186,7 @@ static int EmitAlphaRGB(const VP8Io* const io, WebPDecParams* const p,
|
||||
(colorspace == MODE_ARGB || colorspace == MODE_Argb);
|
||||
const WebPRGBABuffer* const buf = &p->output->u.RGBA;
|
||||
int num_rows;
|
||||
const size_t start_y = GetAlphaSourceRow(io, &alpha, &num_rows);
|
||||
const int start_y = GetAlphaSourceRow(io, &alpha, &num_rows);
|
||||
uint8_t* const base_rgba = buf->rgba + start_y * buf->stride;
|
||||
uint8_t* const dst = base_rgba + (alpha_first ? 0 : 3);
|
||||
const int has_alpha = WebPDispatchAlpha(alpha, io->width, mb_w,
|
||||
@ -205,9 +210,9 @@ static int EmitAlphaRGBA4444(const VP8Io* const io, WebPDecParams* const p,
|
||||
const WEBP_CSP_MODE colorspace = p->output->colorspace;
|
||||
const WebPRGBABuffer* const buf = &p->output->u.RGBA;
|
||||
int num_rows;
|
||||
const size_t start_y = GetAlphaSourceRow(io, &alpha, &num_rows);
|
||||
const int start_y = GetAlphaSourceRow(io, &alpha, &num_rows);
|
||||
uint8_t* const base_rgba = buf->rgba + start_y * buf->stride;
|
||||
#if (WEBP_SWAP_16BIT_CSP == 1)
|
||||
#ifdef WEBP_SWAP_16BIT_CSP
|
||||
uint8_t* alpha_dst = base_rgba;
|
||||
#else
|
||||
uint8_t* alpha_dst = base_rgba + 1;
|
||||
@ -236,7 +241,6 @@ static int EmitAlphaRGBA4444(const VP8Io* const io, WebPDecParams* const p,
|
||||
//------------------------------------------------------------------------------
|
||||
// YUV rescaling (no final RGB conversion needed)
|
||||
|
||||
#if !defined(WEBP_REDUCE_SIZE)
|
||||
static int Rescale(const uint8_t* src, int src_stride,
|
||||
int new_lines, WebPRescaler* const wrk) {
|
||||
int num_lines_out = 0;
|
||||
@ -271,9 +275,9 @@ static int EmitRescaledYUV(const VP8Io* const io, WebPDecParams* const p) {
|
||||
static int EmitRescaledAlphaYUV(const VP8Io* const io, WebPDecParams* const p,
|
||||
int expected_num_lines_out) {
|
||||
const WebPYUVABuffer* const buf = &p->output->u.YUVA;
|
||||
uint8_t* const dst_a = buf->a + (size_t)p->last_y * buf->a_stride;
|
||||
uint8_t* const dst_a = buf->a + p->last_y * buf->a_stride;
|
||||
if (io->a != NULL) {
|
||||
uint8_t* const dst_y = buf->y + (size_t)p->last_y * buf->y_stride;
|
||||
uint8_t* const dst_y = buf->y + p->last_y * buf->y_stride;
|
||||
const int num_lines_out = Rescale(io->a, io->width, io->mb_h, p->scaler_a);
|
||||
assert(expected_num_lines_out == num_lines_out);
|
||||
if (num_lines_out > 0) { // unmultiply the Y
|
||||
@ -351,7 +355,7 @@ static int ExportRGB(WebPDecParams* const p, int y_pos) {
|
||||
const WebPYUV444Converter convert =
|
||||
WebPYUV444Converters[p->output->colorspace];
|
||||
const WebPRGBABuffer* const buf = &p->output->u.RGBA;
|
||||
uint8_t* dst = buf->rgba + (size_t)y_pos * buf->stride;
|
||||
uint8_t* dst = buf->rgba + y_pos * buf->stride;
|
||||
int num_lines_out = 0;
|
||||
// For RGB rescaling, because of the YUV420, current scan position
|
||||
// U/V can be +1/-1 line from the Y one. Hence the double test.
|
||||
@ -378,15 +382,15 @@ static int EmitRescaledRGB(const VP8Io* const io, WebPDecParams* const p) {
|
||||
while (j < mb_h) {
|
||||
const int y_lines_in =
|
||||
WebPRescalerImport(p->scaler_y, mb_h - j,
|
||||
io->y + (size_t)j * io->y_stride, io->y_stride);
|
||||
io->y + j * io->y_stride, io->y_stride);
|
||||
j += y_lines_in;
|
||||
if (WebPRescaleNeededLines(p->scaler_u, uv_mb_h - uv_j)) {
|
||||
const int u_lines_in = WebPRescalerImport(
|
||||
p->scaler_u, uv_mb_h - uv_j, io->u + (size_t)uv_j * io->uv_stride,
|
||||
io->uv_stride);
|
||||
const int v_lines_in = WebPRescalerImport(
|
||||
p->scaler_v, uv_mb_h - uv_j, io->v + (size_t)uv_j * io->uv_stride,
|
||||
io->uv_stride);
|
||||
const int u_lines_in =
|
||||
WebPRescalerImport(p->scaler_u, uv_mb_h - uv_j,
|
||||
io->u + uv_j * io->uv_stride, io->uv_stride);
|
||||
const int v_lines_in =
|
||||
WebPRescalerImport(p->scaler_v, uv_mb_h - uv_j,
|
||||
io->v + uv_j * io->uv_stride, io->uv_stride);
|
||||
(void)v_lines_in; // remove a gcc warning
|
||||
assert(u_lines_in == v_lines_in);
|
||||
uv_j += u_lines_in;
|
||||
@ -398,7 +402,7 @@ static int EmitRescaledRGB(const VP8Io* const io, WebPDecParams* const p) {
|
||||
|
||||
static int ExportAlpha(WebPDecParams* const p, int y_pos, int max_lines_out) {
|
||||
const WebPRGBABuffer* const buf = &p->output->u.RGBA;
|
||||
uint8_t* const base_rgba = buf->rgba + (size_t)y_pos * buf->stride;
|
||||
uint8_t* const base_rgba = buf->rgba + y_pos * buf->stride;
|
||||
const WEBP_CSP_MODE colorspace = p->output->colorspace;
|
||||
const int alpha_first =
|
||||
(colorspace == MODE_ARGB || colorspace == MODE_Argb);
|
||||
@ -426,8 +430,8 @@ static int ExportAlpha(WebPDecParams* const p, int y_pos, int max_lines_out) {
|
||||
static int ExportAlphaRGBA4444(WebPDecParams* const p, int y_pos,
|
||||
int max_lines_out) {
|
||||
const WebPRGBABuffer* const buf = &p->output->u.RGBA;
|
||||
uint8_t* const base_rgba = buf->rgba + (size_t)y_pos * buf->stride;
|
||||
#if (WEBP_SWAP_16BIT_CSP == 1)
|
||||
uint8_t* const base_rgba = buf->rgba + y_pos * buf->stride;
|
||||
#ifdef WEBP_SWAP_16BIT_CSP
|
||||
uint8_t* alpha_dst = base_rgba;
|
||||
#else
|
||||
uint8_t* alpha_dst = base_rgba + 1;
|
||||
@ -465,7 +469,7 @@ static int EmitRescaledAlphaRGB(const VP8Io* const io, WebPDecParams* const p,
|
||||
int lines_left = expected_num_out_lines;
|
||||
const int y_end = p->last_y + lines_left;
|
||||
while (lines_left > 0) {
|
||||
const int64_t row_offset = (int64_t)scaler->src_y - io->mb_y;
|
||||
const int row_offset = scaler->src_y - io->mb_y;
|
||||
WebPRescalerImport(scaler, io->mb_h + io->mb_y - scaler->src_y,
|
||||
io->a + row_offset * io->width, io->width);
|
||||
lines_left -= p->emit_alpha_row(p, y_end - lines_left, lines_left);
|
||||
@ -537,8 +541,6 @@ static int InitRGBRescaler(const VP8Io* const io, WebPDecParams* const p) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif // WEBP_REDUCE_SIZE
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Default custom functions
|
||||
|
||||
@ -559,14 +561,10 @@ static int CustomSetup(VP8Io* io) {
|
||||
WebPInitUpsamplers();
|
||||
}
|
||||
if (io->use_scaling) {
|
||||
#if !defined(WEBP_REDUCE_SIZE)
|
||||
const int ok = is_rgb ? InitRGBRescaler(io, p) : InitYUVRescaler(io, p);
|
||||
if (!ok) {
|
||||
return 0; // memory error
|
||||
}
|
||||
#else
|
||||
return 0; // rescaling support not compiled
|
||||
#endif
|
||||
} else {
|
||||
if (is_rgb) {
|
||||
WebPInitSamplers();
|
||||
@ -600,6 +598,9 @@ static int CustomSetup(VP8Io* io) {
|
||||
}
|
||||
}
|
||||
|
||||
if (is_rgb) {
|
||||
VP8YUVInit();
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -11,7 +11,7 @@
|
||||
//
|
||||
// Author: Skal (pascal.massimino@gmail.com)
|
||||
|
||||
#include "src/dec/vp8i_dec.h"
|
||||
#include "./vp8i_dec.h"
|
||||
|
||||
static WEBP_INLINE int clip(int v, int M) {
|
||||
return v < 0 ? 0 : v > M ? M : v;
|
||||
@ -61,17 +61,12 @@ static const uint16_t kAcTable[128] = {
|
||||
|
||||
void VP8ParseQuant(VP8Decoder* const dec) {
|
||||
VP8BitReader* const br = &dec->br_;
|
||||
const int base_q0 = VP8GetValue(br, 7, "global-header");
|
||||
const int dqy1_dc = VP8Get(br, "global-header") ?
|
||||
VP8GetSignedValue(br, 4, "global-header") : 0;
|
||||
const int dqy2_dc = VP8Get(br, "global-header") ?
|
||||
VP8GetSignedValue(br, 4, "global-header") : 0;
|
||||
const int dqy2_ac = VP8Get(br, "global-header") ?
|
||||
VP8GetSignedValue(br, 4, "global-header") : 0;
|
||||
const int dquv_dc = VP8Get(br, "global-header") ?
|
||||
VP8GetSignedValue(br, 4, "global-header") : 0;
|
||||
const int dquv_ac = VP8Get(br, "global-header") ?
|
||||
VP8GetSignedValue(br, 4, "global-header") : 0;
|
||||
const int base_q0 = VP8GetValue(br, 7);
|
||||
const int dqy1_dc = VP8Get(br) ? VP8GetSignedValue(br, 4) : 0;
|
||||
const int dqy2_dc = VP8Get(br) ? VP8GetSignedValue(br, 4) : 0;
|
||||
const int dqy2_ac = VP8Get(br) ? VP8GetSignedValue(br, 4) : 0;
|
||||
const int dquv_dc = VP8Get(br) ? VP8GetSignedValue(br, 4) : 0;
|
||||
const int dquv_ac = VP8Get(br) ? VP8GetSignedValue(br, 4) : 0;
|
||||
|
||||
const VP8SegmentHeader* const hdr = &dec->segment_hdr_;
|
||||
int i;
|
||||
|
@ -11,19 +11,15 @@
|
||||
//
|
||||
// Author: Skal (pascal.massimino@gmail.com)
|
||||
|
||||
#include "src/dec/vp8i_dec.h"
|
||||
#include "src/utils/bit_reader_inl_utils.h"
|
||||
#include "./vp8i_dec.h"
|
||||
#include "../utils/bit_reader_inl_utils.h"
|
||||
|
||||
#if !defined(USE_GENERIC_TREE)
|
||||
#if !defined(__arm__) && !defined(_M_ARM) && !defined(__aarch64__)
|
||||
// using a table is ~1-2% slower on ARM. Prefer the coded-tree approach then.
|
||||
#define USE_GENERIC_TREE 1 // ALTERNATE_CODE
|
||||
#else
|
||||
#define USE_GENERIC_TREE 0
|
||||
#define USE_GENERIC_TREE
|
||||
#endif
|
||||
#endif // USE_GENERIC_TREE
|
||||
|
||||
#if (USE_GENERIC_TREE == 1)
|
||||
#ifdef USE_GENERIC_TREE
|
||||
static const int8_t kYModesIntra4[18] = {
|
||||
-B_DC_PRED, 1,
|
||||
-B_TM_PRED, 2,
|
||||
@ -296,21 +292,20 @@ static void ParseIntraMode(VP8BitReader* const br,
|
||||
// to decode more than 1 keyframe.
|
||||
if (dec->segment_hdr_.update_map_) {
|
||||
// Hardcoded tree parsing
|
||||
block->segment_ = !VP8GetBit(br, dec->proba_.segments_[0], "segments")
|
||||
? VP8GetBit(br, dec->proba_.segments_[1], "segments")
|
||||
: VP8GetBit(br, dec->proba_.segments_[2], "segments") + 2;
|
||||
block->segment_ = !VP8GetBit(br, dec->proba_.segments_[0])
|
||||
? VP8GetBit(br, dec->proba_.segments_[1])
|
||||
: 2 + VP8GetBit(br, dec->proba_.segments_[2]);
|
||||
} else {
|
||||
block->segment_ = 0; // default for intra
|
||||
}
|
||||
if (dec->use_skip_proba_) block->skip_ = VP8GetBit(br, dec->skip_p_, "skip");
|
||||
if (dec->use_skip_proba_) block->skip_ = VP8GetBit(br, dec->skip_p_);
|
||||
|
||||
block->is_i4x4_ = !VP8GetBit(br, 145, "block-size");
|
||||
block->is_i4x4_ = !VP8GetBit(br, 145); // decide for B_PRED first
|
||||
if (!block->is_i4x4_) {
|
||||
// Hardcoded 16x16 intra-mode decision tree.
|
||||
const int ymode =
|
||||
VP8GetBit(br, 156, "pred-modes") ?
|
||||
(VP8GetBit(br, 128, "pred-modes") ? TM_PRED : H_PRED) :
|
||||
(VP8GetBit(br, 163, "pred-modes") ? V_PRED : DC_PRED);
|
||||
VP8GetBit(br, 156) ? (VP8GetBit(br, 128) ? TM_PRED : H_PRED)
|
||||
: (VP8GetBit(br, 163) ? V_PRED : DC_PRED);
|
||||
block->imodes_[0] = ymode;
|
||||
memset(top, ymode, 4 * sizeof(*top));
|
||||
memset(left, ymode, 4 * sizeof(*left));
|
||||
@ -322,28 +317,25 @@ static void ParseIntraMode(VP8BitReader* const br,
|
||||
int x;
|
||||
for (x = 0; x < 4; ++x) {
|
||||
const uint8_t* const prob = kBModesProba[top[x]][ymode];
|
||||
#if (USE_GENERIC_TREE == 1)
|
||||
#ifdef USE_GENERIC_TREE
|
||||
// Generic tree-parsing
|
||||
int i = kYModesIntra4[VP8GetBit(br, prob[0], "pred-modes")];
|
||||
int i = kYModesIntra4[VP8GetBit(br, prob[0])];
|
||||
while (i > 0) {
|
||||
i = kYModesIntra4[2 * i + VP8GetBit(br, prob[i], "pred-modes")];
|
||||
i = kYModesIntra4[2 * i + VP8GetBit(br, prob[i])];
|
||||
}
|
||||
ymode = -i;
|
||||
#else
|
||||
// Hardcoded tree parsing
|
||||
ymode = !VP8GetBit(br, prob[0], "pred-modes") ? B_DC_PRED :
|
||||
!VP8GetBit(br, prob[1], "pred-modes") ? B_TM_PRED :
|
||||
!VP8GetBit(br, prob[2], "pred-modes") ? B_VE_PRED :
|
||||
!VP8GetBit(br, prob[3], "pred-modes") ?
|
||||
(!VP8GetBit(br, prob[4], "pred-modes") ? B_HE_PRED :
|
||||
(!VP8GetBit(br, prob[5], "pred-modes") ? B_RD_PRED
|
||||
: B_VR_PRED)) :
|
||||
(!VP8GetBit(br, prob[6], "pred-modes") ? B_LD_PRED :
|
||||
(!VP8GetBit(br, prob[7], "pred-modes") ? B_VL_PRED :
|
||||
(!VP8GetBit(br, prob[8], "pred-modes") ? B_HD_PRED
|
||||
: B_HU_PRED))
|
||||
);
|
||||
#endif // USE_GENERIC_TREE
|
||||
ymode = !VP8GetBit(br, prob[0]) ? B_DC_PRED :
|
||||
!VP8GetBit(br, prob[1]) ? B_TM_PRED :
|
||||
!VP8GetBit(br, prob[2]) ? B_VE_PRED :
|
||||
!VP8GetBit(br, prob[3]) ?
|
||||
(!VP8GetBit(br, prob[4]) ? B_HE_PRED :
|
||||
(!VP8GetBit(br, prob[5]) ? B_RD_PRED : B_VR_PRED)) :
|
||||
(!VP8GetBit(br, prob[6]) ? B_LD_PRED :
|
||||
(!VP8GetBit(br, prob[7]) ? B_VL_PRED :
|
||||
(!VP8GetBit(br, prob[8]) ? B_HD_PRED : B_HU_PRED)));
|
||||
#endif // USE_GENERIC_TREE
|
||||
top[x] = ymode;
|
||||
}
|
||||
memcpy(modes, top, 4 * sizeof(*top));
|
||||
@ -352,9 +344,9 @@ static void ParseIntraMode(VP8BitReader* const br,
|
||||
}
|
||||
}
|
||||
// Hardcoded UVMode decision tree
|
||||
block->uvmode_ = !VP8GetBit(br, 142, "pred-modes-uv") ? DC_PRED
|
||||
: !VP8GetBit(br, 114, "pred-modes-uv") ? V_PRED
|
||||
: VP8GetBit(br, 183, "pred-modes-uv") ? TM_PRED : H_PRED;
|
||||
block->uvmode_ = !VP8GetBit(br, 142) ? DC_PRED
|
||||
: !VP8GetBit(br, 114) ? V_PRED
|
||||
: VP8GetBit(br, 183) ? TM_PRED : H_PRED;
|
||||
}
|
||||
|
||||
int VP8ParseIntraModeRow(VP8BitReader* const br, VP8Decoder* const dec) {
|
||||
@ -506,7 +498,7 @@ static const uint8_t
|
||||
|
||||
// Paragraph 9.9
|
||||
|
||||
static const uint8_t kBands[16 + 1] = {
|
||||
static const int kBands[16 + 1] = {
|
||||
0, 1, 2, 3, 6, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6, 7,
|
||||
0 // extra entry as sentinel
|
||||
};
|
||||
@ -518,10 +510,8 @@ void VP8ParseProba(VP8BitReader* const br, VP8Decoder* const dec) {
|
||||
for (b = 0; b < NUM_BANDS; ++b) {
|
||||
for (c = 0; c < NUM_CTX; ++c) {
|
||||
for (p = 0; p < NUM_PROBAS; ++p) {
|
||||
const int v =
|
||||
VP8GetBit(br, CoeffsUpdateProba[t][b][c][p], "global-header") ?
|
||||
VP8GetValue(br, 8, "global-header") :
|
||||
CoeffsProba0[t][b][c][p];
|
||||
const int v = VP8GetBit(br, CoeffsUpdateProba[t][b][c][p]) ?
|
||||
VP8GetValue(br, 8) : CoeffsProba0[t][b][c][p];
|
||||
proba->bands_[t][b].probas_[c][p] = v;
|
||||
}
|
||||
}
|
||||
@ -530,8 +520,9 @@ void VP8ParseProba(VP8BitReader* const br, VP8Decoder* const dec) {
|
||||
proba->bands_ptr_[t][b] = &proba->bands_[t][kBands[b]];
|
||||
}
|
||||
}
|
||||
dec->use_skip_proba_ = VP8Get(br, "global-header");
|
||||
dec->use_skip_proba_ = VP8Get(br);
|
||||
if (dec->use_skip_proba_) {
|
||||
dec->skip_p_ = VP8GetValue(br, 8, "global-header");
|
||||
dec->skip_p_ = VP8GetValue(br, 8);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -13,12 +13,12 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "src/dec/alphai_dec.h"
|
||||
#include "src/dec/vp8i_dec.h"
|
||||
#include "src/dec/vp8li_dec.h"
|
||||
#include "src/dec/webpi_dec.h"
|
||||
#include "src/utils/bit_reader_inl_utils.h"
|
||||
#include "src/utils/utils.h"
|
||||
#include "./alphai_dec.h"
|
||||
#include "./vp8i_dec.h"
|
||||
#include "./vp8li_dec.h"
|
||||
#include "./webpi_dec.h"
|
||||
#include "../utils/bit_reader_inl_utils.h"
|
||||
#include "../utils/utils.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@ -161,26 +161,23 @@ static int ParseSegmentHeader(VP8BitReader* br,
|
||||
VP8SegmentHeader* hdr, VP8Proba* proba) {
|
||||
assert(br != NULL);
|
||||
assert(hdr != NULL);
|
||||
hdr->use_segment_ = VP8Get(br, "global-header");
|
||||
hdr->use_segment_ = VP8Get(br);
|
||||
if (hdr->use_segment_) {
|
||||
hdr->update_map_ = VP8Get(br, "global-header");
|
||||
if (VP8Get(br, "global-header")) { // update data
|
||||
hdr->update_map_ = VP8Get(br);
|
||||
if (VP8Get(br)) { // update data
|
||||
int s;
|
||||
hdr->absolute_delta_ = VP8Get(br, "global-header");
|
||||
hdr->absolute_delta_ = VP8Get(br);
|
||||
for (s = 0; s < NUM_MB_SEGMENTS; ++s) {
|
||||
hdr->quantizer_[s] = VP8Get(br, "global-header") ?
|
||||
VP8GetSignedValue(br, 7, "global-header") : 0;
|
||||
hdr->quantizer_[s] = VP8Get(br) ? VP8GetSignedValue(br, 7) : 0;
|
||||
}
|
||||
for (s = 0; s < NUM_MB_SEGMENTS; ++s) {
|
||||
hdr->filter_strength_[s] = VP8Get(br, "global-header") ?
|
||||
VP8GetSignedValue(br, 6, "global-header") : 0;
|
||||
hdr->filter_strength_[s] = VP8Get(br) ? VP8GetSignedValue(br, 6) : 0;
|
||||
}
|
||||
}
|
||||
if (hdr->update_map_) {
|
||||
int s;
|
||||
for (s = 0; s < MB_FEATURE_TREE_PROBS; ++s) {
|
||||
proba->segments_[s] = VP8Get(br, "global-header") ?
|
||||
VP8GetValue(br, 8, "global-header") : 255u;
|
||||
proba->segments_[s] = VP8Get(br) ? VP8GetValue(br, 8) : 255u;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -208,7 +205,7 @@ static VP8StatusCode ParsePartitions(VP8Decoder* const dec,
|
||||
size_t last_part;
|
||||
size_t p;
|
||||
|
||||
dec->num_parts_minus_one_ = (1 << VP8GetValue(br, 2, "global-header")) - 1;
|
||||
dec->num_parts_minus_one_ = (1 << VP8GetValue(br, 2)) - 1;
|
||||
last_part = dec->num_parts_minus_one_;
|
||||
if (size < 3 * last_part) {
|
||||
// we can't even read the sizes with sz[]! That's a failure.
|
||||
@ -232,21 +229,21 @@ static VP8StatusCode ParsePartitions(VP8Decoder* const dec,
|
||||
// Paragraph 9.4
|
||||
static int ParseFilterHeader(VP8BitReader* br, VP8Decoder* const dec) {
|
||||
VP8FilterHeader* const hdr = &dec->filter_hdr_;
|
||||
hdr->simple_ = VP8Get(br, "global-header");
|
||||
hdr->level_ = VP8GetValue(br, 6, "global-header");
|
||||
hdr->sharpness_ = VP8GetValue(br, 3, "global-header");
|
||||
hdr->use_lf_delta_ = VP8Get(br, "global-header");
|
||||
hdr->simple_ = VP8Get(br);
|
||||
hdr->level_ = VP8GetValue(br, 6);
|
||||
hdr->sharpness_ = VP8GetValue(br, 3);
|
||||
hdr->use_lf_delta_ = VP8Get(br);
|
||||
if (hdr->use_lf_delta_) {
|
||||
if (VP8Get(br, "global-header")) { // update lf-delta?
|
||||
if (VP8Get(br)) { // update lf-delta?
|
||||
int i;
|
||||
for (i = 0; i < NUM_REF_LF_DELTAS; ++i) {
|
||||
if (VP8Get(br, "global-header")) {
|
||||
hdr->ref_lf_delta_[i] = VP8GetSignedValue(br, 6, "global-header");
|
||||
if (VP8Get(br)) {
|
||||
hdr->ref_lf_delta_[i] = VP8GetSignedValue(br, 6);
|
||||
}
|
||||
}
|
||||
for (i = 0; i < NUM_MODE_LF_DELTAS; ++i) {
|
||||
if (VP8Get(br, "global-header")) {
|
||||
hdr->mode_lf_delta_[i] = VP8GetSignedValue(br, 6, "global-header");
|
||||
if (VP8Get(br)) {
|
||||
hdr->mode_lf_delta_[i] = VP8GetSignedValue(br, 6);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -355,8 +352,8 @@ int VP8GetHeaders(VP8Decoder* const dec, VP8Io* const io) {
|
||||
buf_size -= frm_hdr->partition_length_;
|
||||
|
||||
if (frm_hdr->key_frame_) {
|
||||
pic_hdr->colorspace_ = VP8Get(br, "global-header");
|
||||
pic_hdr->clamp_type_ = VP8Get(br, "global-header");
|
||||
pic_hdr->colorspace_ = VP8Get(br);
|
||||
pic_hdr->clamp_type_ = VP8Get(br);
|
||||
}
|
||||
if (!ParseSegmentHeader(br, &dec->segment_hdr_, &dec->proba_)) {
|
||||
return VP8SetError(dec, VP8_STATUS_BITSTREAM_ERROR,
|
||||
@ -381,7 +378,7 @@ int VP8GetHeaders(VP8Decoder* const dec, VP8Io* const io) {
|
||||
"Not a key frame.");
|
||||
}
|
||||
|
||||
VP8Get(br, "global-header"); // ignore the value of update_proba_
|
||||
VP8Get(br); // ignore the value of update_proba_
|
||||
|
||||
VP8ParseProba(br, dec);
|
||||
|
||||
@ -406,28 +403,28 @@ static const uint8_t kZigzag[16] = {
|
||||
// See section 13-2: http://tools.ietf.org/html/rfc6386#section-13.2
|
||||
static int GetLargeValue(VP8BitReader* const br, const uint8_t* const p) {
|
||||
int v;
|
||||
if (!VP8GetBit(br, p[3], "coeffs")) {
|
||||
if (!VP8GetBit(br, p[4], "coeffs")) {
|
||||
if (!VP8GetBit(br, p[3])) {
|
||||
if (!VP8GetBit(br, p[4])) {
|
||||
v = 2;
|
||||
} else {
|
||||
v = 3 + VP8GetBit(br, p[5], "coeffs");
|
||||
v = 3 + VP8GetBit(br, p[5]);
|
||||
}
|
||||
} else {
|
||||
if (!VP8GetBit(br, p[6], "coeffs")) {
|
||||
if (!VP8GetBit(br, p[7], "coeffs")) {
|
||||
v = 5 + VP8GetBit(br, 159, "coeffs");
|
||||
if (!VP8GetBit(br, p[6])) {
|
||||
if (!VP8GetBit(br, p[7])) {
|
||||
v = 5 + VP8GetBit(br, 159);
|
||||
} else {
|
||||
v = 7 + 2 * VP8GetBit(br, 165, "coeffs");
|
||||
v += VP8GetBit(br, 145, "coeffs");
|
||||
v = 7 + 2 * VP8GetBit(br, 165);
|
||||
v += VP8GetBit(br, 145);
|
||||
}
|
||||
} else {
|
||||
const uint8_t* tab;
|
||||
const int bit1 = VP8GetBit(br, p[8], "coeffs");
|
||||
const int bit0 = VP8GetBit(br, p[9 + bit1], "coeffs");
|
||||
const int bit1 = VP8GetBit(br, p[8]);
|
||||
const int bit0 = VP8GetBit(br, p[9 + bit1]);
|
||||
const int cat = 2 * bit1 + bit0;
|
||||
v = 0;
|
||||
for (tab = kCat3456[cat]; *tab; ++tab) {
|
||||
v += v + VP8GetBit(br, *tab, "coeffs");
|
||||
v += v + VP8GetBit(br, *tab);
|
||||
}
|
||||
v += 3 + (8 << cat);
|
||||
}
|
||||
@ -441,24 +438,24 @@ static int GetCoeffsFast(VP8BitReader* const br,
|
||||
int ctx, const quant_t dq, int n, int16_t* out) {
|
||||
const uint8_t* p = prob[n]->probas_[ctx];
|
||||
for (; n < 16; ++n) {
|
||||
if (!VP8GetBit(br, p[0], "coeffs")) {
|
||||
if (!VP8GetBit(br, p[0])) {
|
||||
return n; // previous coeff was last non-zero coeff
|
||||
}
|
||||
while (!VP8GetBit(br, p[1], "coeffs")) { // sequence of zero coeffs
|
||||
while (!VP8GetBit(br, p[1])) { // sequence of zero coeffs
|
||||
p = prob[++n]->probas_[0];
|
||||
if (n == 16) return 16;
|
||||
}
|
||||
{ // non zero coeff
|
||||
const VP8ProbaArray* const p_ctx = &prob[n + 1]->probas_[0];
|
||||
int v;
|
||||
if (!VP8GetBit(br, p[2], "coeffs")) {
|
||||
if (!VP8GetBit(br, p[2])) {
|
||||
v = 1;
|
||||
p = p_ctx[1];
|
||||
} else {
|
||||
v = GetLargeValue(br, p);
|
||||
p = p_ctx[2];
|
||||
}
|
||||
out[kZigzag[n]] = VP8GetSigned(br, v, "coeffs") * dq[n > 0];
|
||||
out[kZigzag[n]] = VP8GetSigned(br, v) * dq[n > 0];
|
||||
}
|
||||
}
|
||||
return 16;
|
||||
@ -471,34 +468,36 @@ static int GetCoeffsAlt(VP8BitReader* const br,
|
||||
int ctx, const quant_t dq, int n, int16_t* out) {
|
||||
const uint8_t* p = prob[n]->probas_[ctx];
|
||||
for (; n < 16; ++n) {
|
||||
if (!VP8GetBitAlt(br, p[0], "coeffs")) {
|
||||
if (!VP8GetBitAlt(br, p[0])) {
|
||||
return n; // previous coeff was last non-zero coeff
|
||||
}
|
||||
while (!VP8GetBitAlt(br, p[1], "coeffs")) { // sequence of zero coeffs
|
||||
while (!VP8GetBitAlt(br, p[1])) { // sequence of zero coeffs
|
||||
p = prob[++n]->probas_[0];
|
||||
if (n == 16) return 16;
|
||||
}
|
||||
{ // non zero coeff
|
||||
const VP8ProbaArray* const p_ctx = &prob[n + 1]->probas_[0];
|
||||
int v;
|
||||
if (!VP8GetBitAlt(br, p[2], "coeffs")) {
|
||||
if (!VP8GetBitAlt(br, p[2])) {
|
||||
v = 1;
|
||||
p = p_ctx[1];
|
||||
} else {
|
||||
v = GetLargeValue(br, p);
|
||||
p = p_ctx[2];
|
||||
}
|
||||
out[kZigzag[n]] = VP8GetSigned(br, v, "coeffs") * dq[n > 0];
|
||||
out[kZigzag[n]] = VP8GetSigned(br, v) * dq[n > 0];
|
||||
}
|
||||
}
|
||||
return 16;
|
||||
}
|
||||
|
||||
WEBP_DSP_INIT_FUNC(InitGetCoeffs) {
|
||||
if (VP8GetCPUInfo != NULL && VP8GetCPUInfo(kSlowSSSE3)) {
|
||||
GetCoeffs = GetCoeffsAlt;
|
||||
} else {
|
||||
GetCoeffs = GetCoeffsFast;
|
||||
WEBP_TSAN_IGNORE_FUNCTION static void InitGetCoeffs(void) {
|
||||
if (GetCoeffs == NULL) {
|
||||
if (VP8GetCPUInfo != NULL && VP8GetCPUInfo(kSlowSSSE3)) {
|
||||
GetCoeffs = GetCoeffsAlt;
|
||||
} else {
|
||||
GetCoeffs = GetCoeffsFast;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -11,10 +11,10 @@
|
||||
//
|
||||
// Author: Skal (pascal.massimino@gmail.com)
|
||||
|
||||
#ifndef WEBP_DEC_VP8_DEC_H_
|
||||
#define WEBP_DEC_VP8_DEC_H_
|
||||
#ifndef WEBP_WEBP_DECODE_VP8_H_
|
||||
#define WEBP_WEBP_DECODE_VP8_H_
|
||||
|
||||
#include "src/webp/decode.h"
|
||||
#include "../webp/decode.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -33,7 +33,7 @@ extern "C" {
|
||||
// /* customize io's functions (setup()/put()/teardown()) if needed. */
|
||||
//
|
||||
// VP8Decoder* dec = VP8New();
|
||||
// int ok = VP8Decode(dec, &io);
|
||||
// bool ok = VP8Decode(dec);
|
||||
// if (!ok) printf("Error: %s\n", VP8StatusMessage(dec));
|
||||
// VP8Delete(dec);
|
||||
// return ok;
|
||||
@ -157,24 +157,24 @@ void VP8Delete(VP8Decoder* const dec);
|
||||
// Miscellaneous VP8/VP8L bitstream probing functions.
|
||||
|
||||
// Returns true if the next 3 bytes in data contain the VP8 signature.
|
||||
WEBP_EXTERN int VP8CheckSignature(const uint8_t* const data, size_t data_size);
|
||||
WEBP_EXTERN(int) VP8CheckSignature(const uint8_t* const data, size_t data_size);
|
||||
|
||||
// Validates the VP8 data-header and retrieves basic header information viz
|
||||
// width and height. Returns 0 in case of formatting error. *width/*height
|
||||
// can be passed NULL.
|
||||
WEBP_EXTERN int VP8GetInfo(
|
||||
WEBP_EXTERN(int) VP8GetInfo(
|
||||
const uint8_t* data,
|
||||
size_t data_size, // data available so far
|
||||
size_t chunk_size, // total data size expected in the chunk
|
||||
int* const width, int* const height);
|
||||
|
||||
// Returns true if the next byte(s) in data is a VP8L signature.
|
||||
WEBP_EXTERN int VP8LCheckSignature(const uint8_t* const data, size_t size);
|
||||
WEBP_EXTERN(int) VP8LCheckSignature(const uint8_t* const data, size_t size);
|
||||
|
||||
// Validates the VP8L data-header and retrieves basic header information viz
|
||||
// width, height and alpha. Returns 0 in case of formatting error.
|
||||
// width/height/has_alpha can be passed NULL.
|
||||
WEBP_EXTERN int VP8LGetInfo(
|
||||
WEBP_EXTERN(int) VP8LGetInfo(
|
||||
const uint8_t* data, size_t data_size, // data available so far
|
||||
int* const width, int* const height, int* const has_alpha);
|
||||
|
||||
@ -182,4 +182,4 @@ WEBP_EXTERN int VP8LGetInfo(
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // WEBP_DEC_VP8_DEC_H_
|
||||
#endif /* WEBP_WEBP_DECODE_VP8_H_ */
|
||||
|
@ -11,16 +11,16 @@
|
||||
//
|
||||
// Author: Skal (pascal.massimino@gmail.com)
|
||||
|
||||
#ifndef WEBP_DEC_VP8I_DEC_H_
|
||||
#define WEBP_DEC_VP8I_DEC_H_
|
||||
#ifndef WEBP_DEC_VP8I_H_
|
||||
#define WEBP_DEC_VP8I_H_
|
||||
|
||||
#include <string.h> // for memcpy()
|
||||
#include "src/dec/common_dec.h"
|
||||
#include "src/dec/vp8li_dec.h"
|
||||
#include "src/utils/bit_reader_utils.h"
|
||||
#include "src/utils/random_utils.h"
|
||||
#include "src/utils/thread_utils.h"
|
||||
#include "src/dsp/dsp.h"
|
||||
#include "./common_dec.h"
|
||||
#include "./vp8li_dec.h"
|
||||
#include "../utils/bit_reader_utils.h"
|
||||
#include "../utils/random_utils.h"
|
||||
#include "../utils/thread_utils.h"
|
||||
#include "../dsp/dsp.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -30,8 +30,8 @@ extern "C" {
|
||||
// Various defines and enums
|
||||
|
||||
// version numbers
|
||||
#define DEC_MAJ_VERSION 1
|
||||
#define DEC_MIN_VERSION 2
|
||||
#define DEC_MAJ_VERSION 0
|
||||
#define DEC_MIN_VERSION 6
|
||||
#define DEC_REV_VERSION 0
|
||||
|
||||
// YUV-cache parameters. Cache is 32-bytes wide (= one cacheline).
|
||||
@ -57,6 +57,7 @@ extern "C" {
|
||||
// '|' = left sample, '-' = top sample, '+' = top-left sample
|
||||
// 't' = extra top-right sample for 4x4 modes
|
||||
#define YUV_SIZE (BPS * 17 + BPS * 9)
|
||||
#define Y_SIZE (BPS * 17)
|
||||
#define Y_OFF (BPS * 1 + 8)
|
||||
#define U_OFF (Y_OFF + BPS * 16 + BPS)
|
||||
#define V_OFF (U_OFF + 16)
|
||||
@ -316,4 +317,4 @@ const uint8_t* VP8DecompressAlphaRows(VP8Decoder* const dec,
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // WEBP_DEC_VP8I_DEC_H_
|
||||
#endif /* WEBP_DEC_VP8I_H_ */
|
||||
|
@ -14,22 +14,22 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "src/dec/alphai_dec.h"
|
||||
#include "src/dec/vp8li_dec.h"
|
||||
#include "src/dsp/dsp.h"
|
||||
#include "src/dsp/lossless.h"
|
||||
#include "src/dsp/lossless_common.h"
|
||||
#include "src/dsp/yuv.h"
|
||||
#include "src/utils/endian_inl_utils.h"
|
||||
#include "src/utils/huffman_utils.h"
|
||||
#include "src/utils/utils.h"
|
||||
#include "./alphai_dec.h"
|
||||
#include "./vp8li_dec.h"
|
||||
#include "../dsp/dsp.h"
|
||||
#include "../dsp/lossless.h"
|
||||
#include "../dsp/lossless_common.h"
|
||||
#include "../dsp/yuv.h"
|
||||
#include "../utils/endian_inl_utils.h"
|
||||
#include "../utils/huffman_utils.h"
|
||||
#include "../utils/utils.h"
|
||||
|
||||
#define NUM_ARGB_CACHE_ROWS 16
|
||||
|
||||
static const int kCodeLengthLiterals = 16;
|
||||
static const int kCodeLengthRepeatCode = 16;
|
||||
static const uint8_t kCodeLengthExtraBits[3] = { 2, 3, 7 };
|
||||
static const uint8_t kCodeLengthRepeatOffsets[3] = { 3, 3, 11 };
|
||||
static const int kCodeLengthExtraBits[3] = { 2, 3, 7 };
|
||||
static const int kCodeLengthRepeatOffsets[3] = { 3, 3, 11 };
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Five Huffman codes are used at each meta code:
|
||||
@ -86,7 +86,7 @@ static const uint8_t kCodeToPlane[CODE_TO_PLANE_CODES] = {
|
||||
// All values computed for 8-bit first level lookup with Mark Adler's tool:
|
||||
// http://www.hdfgroup.org/ftp/lib-external/zlib/zlib-1.2.5/examples/enough.c
|
||||
#define FIXED_TABLE_SIZE (630 * 3 + 410)
|
||||
static const uint16_t kTableSize[12] = {
|
||||
static const int kTableSize[12] = {
|
||||
FIXED_TABLE_SIZE + 654,
|
||||
FIXED_TABLE_SIZE + 656,
|
||||
FIXED_TABLE_SIZE + 658,
|
||||
@ -363,14 +363,11 @@ static int ReadHuffmanCodes(VP8LDecoder* const dec, int xsize, int ysize,
|
||||
uint32_t* huffman_image = NULL;
|
||||
HTreeGroup* htree_groups = NULL;
|
||||
HuffmanCode* huffman_tables = NULL;
|
||||
HuffmanCode* huffman_table = NULL;
|
||||
HuffmanCode* next = NULL;
|
||||
int num_htree_groups = 1;
|
||||
int num_htree_groups_max = 1;
|
||||
int max_alphabet_size = 0;
|
||||
int* code_lengths = NULL;
|
||||
const int table_size = kTableSize[color_cache_bits];
|
||||
int* mapping = NULL;
|
||||
int ok = 0;
|
||||
|
||||
if (allow_recursion && VP8LReadBits(br, 1)) {
|
||||
// use meta Huffman codes.
|
||||
@ -387,36 +384,10 @@ static int ReadHuffmanCodes(VP8LDecoder* const dec, int xsize, int ysize,
|
||||
// The huffman data is stored in red and green bytes.
|
||||
const int group = (huffman_image[i] >> 8) & 0xffff;
|
||||
huffman_image[i] = group;
|
||||
if (group >= num_htree_groups_max) {
|
||||
num_htree_groups_max = group + 1;
|
||||
if (group >= num_htree_groups) {
|
||||
num_htree_groups = group + 1;
|
||||
}
|
||||
}
|
||||
// Check the validity of num_htree_groups_max. If it seems too big, use a
|
||||
// smaller value for later. This will prevent big memory allocations to end
|
||||
// up with a bad bitstream anyway.
|
||||
// The value of 1000 is totally arbitrary. We know that num_htree_groups_max
|
||||
// is smaller than (1 << 16) and should be smaller than the number of pixels
|
||||
// (though the format allows it to be bigger).
|
||||
if (num_htree_groups_max > 1000 || num_htree_groups_max > xsize * ysize) {
|
||||
// Create a mapping from the used indices to the minimal set of used
|
||||
// values [0, num_htree_groups)
|
||||
mapping = (int*)WebPSafeMalloc(num_htree_groups_max, sizeof(*mapping));
|
||||
if (mapping == NULL) {
|
||||
dec->status_ = VP8_STATUS_OUT_OF_MEMORY;
|
||||
goto Error;
|
||||
}
|
||||
// -1 means a value is unmapped, and therefore unused in the Huffman
|
||||
// image.
|
||||
memset(mapping, 0xff, num_htree_groups_max * sizeof(*mapping));
|
||||
for (num_htree_groups = 0, i = 0; i < huffman_pixs; ++i) {
|
||||
// Get the current mapping for the group and remap the Huffman image.
|
||||
int* const mapped_group = &mapping[huffman_image[i]];
|
||||
if (*mapped_group == -1) *mapped_group = num_htree_groups++;
|
||||
huffman_image[i] = *mapped_group;
|
||||
}
|
||||
} else {
|
||||
num_htree_groups = num_htree_groups_max;
|
||||
}
|
||||
}
|
||||
|
||||
if (br->eos_) goto Error;
|
||||
@ -432,106 +403,88 @@ static int ReadHuffmanCodes(VP8LDecoder* const dec, int xsize, int ysize,
|
||||
}
|
||||
}
|
||||
|
||||
code_lengths = (int*)WebPSafeCalloc((uint64_t)max_alphabet_size,
|
||||
sizeof(*code_lengths));
|
||||
huffman_tables = (HuffmanCode*)WebPSafeMalloc(num_htree_groups * table_size,
|
||||
sizeof(*huffman_tables));
|
||||
htree_groups = VP8LHtreeGroupsNew(num_htree_groups);
|
||||
code_lengths = (int*)WebPSafeCalloc((uint64_t)max_alphabet_size,
|
||||
sizeof(*code_lengths));
|
||||
|
||||
if (htree_groups == NULL || code_lengths == NULL || huffman_tables == NULL) {
|
||||
dec->status_ = VP8_STATUS_OUT_OF_MEMORY;
|
||||
goto Error;
|
||||
}
|
||||
|
||||
huffman_table = huffman_tables;
|
||||
for (i = 0; i < num_htree_groups_max; ++i) {
|
||||
// If the index "i" is unused in the Huffman image, just make sure the
|
||||
// coefficients are valid but do not store them.
|
||||
if (mapping != NULL && mapping[i] == -1) {
|
||||
for (j = 0; j < HUFFMAN_CODES_PER_META_CODE; ++j) {
|
||||
int alphabet_size = kAlphabetSize[j];
|
||||
if (j == 0 && color_cache_bits > 0) {
|
||||
alphabet_size += (1 << color_cache_bits);
|
||||
}
|
||||
// Passing in NULL so that nothing gets filled.
|
||||
if (!ReadHuffmanCode(alphabet_size, dec, code_lengths, NULL)) {
|
||||
goto Error;
|
||||
}
|
||||
next = huffman_tables;
|
||||
for (i = 0; i < num_htree_groups; ++i) {
|
||||
HTreeGroup* const htree_group = &htree_groups[i];
|
||||
HuffmanCode** const htrees = htree_group->htrees;
|
||||
int size;
|
||||
int total_size = 0;
|
||||
int is_trivial_literal = 1;
|
||||
int max_bits = 0;
|
||||
for (j = 0; j < HUFFMAN_CODES_PER_META_CODE; ++j) {
|
||||
int alphabet_size = kAlphabetSize[j];
|
||||
htrees[j] = next;
|
||||
if (j == 0 && color_cache_bits > 0) {
|
||||
alphabet_size += 1 << color_cache_bits;
|
||||
}
|
||||
} else {
|
||||
HTreeGroup* const htree_group =
|
||||
&htree_groups[(mapping == NULL) ? i : mapping[i]];
|
||||
HuffmanCode** const htrees = htree_group->htrees;
|
||||
int size;
|
||||
int total_size = 0;
|
||||
int is_trivial_literal = 1;
|
||||
int max_bits = 0;
|
||||
for (j = 0; j < HUFFMAN_CODES_PER_META_CODE; ++j) {
|
||||
int alphabet_size = kAlphabetSize[j];
|
||||
htrees[j] = huffman_table;
|
||||
if (j == 0 && color_cache_bits > 0) {
|
||||
alphabet_size += (1 << color_cache_bits);
|
||||
}
|
||||
size = ReadHuffmanCode(alphabet_size, dec, code_lengths, huffman_table);
|
||||
if (size == 0) {
|
||||
goto Error;
|
||||
}
|
||||
if (is_trivial_literal && kLiteralMap[j] == 1) {
|
||||
is_trivial_literal = (huffman_table->bits == 0);
|
||||
}
|
||||
total_size += huffman_table->bits;
|
||||
huffman_table += size;
|
||||
if (j <= ALPHA) {
|
||||
int local_max_bits = code_lengths[0];
|
||||
int k;
|
||||
for (k = 1; k < alphabet_size; ++k) {
|
||||
if (code_lengths[k] > local_max_bits) {
|
||||
local_max_bits = code_lengths[k];
|
||||
}
|
||||
size = ReadHuffmanCode(alphabet_size, dec, code_lengths, next);
|
||||
if (size == 0) {
|
||||
goto Error;
|
||||
}
|
||||
if (is_trivial_literal && kLiteralMap[j] == 1) {
|
||||
is_trivial_literal = (next->bits == 0);
|
||||
}
|
||||
total_size += next->bits;
|
||||
next += size;
|
||||
if (j <= ALPHA) {
|
||||
int local_max_bits = code_lengths[0];
|
||||
int k;
|
||||
for (k = 1; k < alphabet_size; ++k) {
|
||||
if (code_lengths[k] > local_max_bits) {
|
||||
local_max_bits = code_lengths[k];
|
||||
}
|
||||
max_bits += local_max_bits;
|
||||
}
|
||||
max_bits += local_max_bits;
|
||||
}
|
||||
htree_group->is_trivial_literal = is_trivial_literal;
|
||||
htree_group->is_trivial_code = 0;
|
||||
if (is_trivial_literal) {
|
||||
const int red = htrees[RED][0].value;
|
||||
const int blue = htrees[BLUE][0].value;
|
||||
const int alpha = htrees[ALPHA][0].value;
|
||||
htree_group->literal_arb = ((uint32_t)alpha << 24) | (red << 16) | blue;
|
||||
if (total_size == 0 && htrees[GREEN][0].value < NUM_LITERAL_CODES) {
|
||||
htree_group->is_trivial_code = 1;
|
||||
htree_group->literal_arb |= htrees[GREEN][0].value << 8;
|
||||
}
|
||||
}
|
||||
htree_group->use_packed_table =
|
||||
!htree_group->is_trivial_code && (max_bits < HUFFMAN_PACKED_BITS);
|
||||
if (htree_group->use_packed_table) BuildPackedTable(htree_group);
|
||||
}
|
||||
htree_group->is_trivial_literal = is_trivial_literal;
|
||||
htree_group->is_trivial_code = 0;
|
||||
if (is_trivial_literal) {
|
||||
const int red = htrees[RED][0].value;
|
||||
const int blue = htrees[BLUE][0].value;
|
||||
const int alpha = htrees[ALPHA][0].value;
|
||||
htree_group->literal_arb =
|
||||
((uint32_t)alpha << 24) | (red << 16) | blue;
|
||||
if (total_size == 0 && htrees[GREEN][0].value < NUM_LITERAL_CODES) {
|
||||
htree_group->is_trivial_code = 1;
|
||||
htree_group->literal_arb |= htrees[GREEN][0].value << 8;
|
||||
}
|
||||
}
|
||||
htree_group->use_packed_table = !htree_group->is_trivial_code &&
|
||||
(max_bits < HUFFMAN_PACKED_BITS);
|
||||
if (htree_group->use_packed_table) BuildPackedTable(htree_group);
|
||||
}
|
||||
ok = 1;
|
||||
WebPSafeFree(code_lengths);
|
||||
|
||||
// All OK. Finalize pointers.
|
||||
// All OK. Finalize pointers and return.
|
||||
hdr->huffman_image_ = huffman_image;
|
||||
hdr->num_htree_groups_ = num_htree_groups;
|
||||
hdr->htree_groups_ = htree_groups;
|
||||
hdr->huffman_tables_ = huffman_tables;
|
||||
return 1;
|
||||
|
||||
Error:
|
||||
WebPSafeFree(code_lengths);
|
||||
WebPSafeFree(mapping);
|
||||
if (!ok) {
|
||||
WebPSafeFree(huffman_image);
|
||||
WebPSafeFree(huffman_tables);
|
||||
VP8LHtreeGroupsFree(htree_groups);
|
||||
}
|
||||
return ok;
|
||||
WebPSafeFree(huffman_image);
|
||||
WebPSafeFree(huffman_tables);
|
||||
VP8LHtreeGroupsFree(htree_groups);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Scaling.
|
||||
|
||||
#if !defined(WEBP_REDUCE_SIZE)
|
||||
static int AllocateAndInitRescaler(VP8LDecoder* const dec, VP8Io* const io) {
|
||||
const int num_channels = 4;
|
||||
const int in_width = io->mb_w;
|
||||
@ -563,13 +516,10 @@ static int AllocateAndInitRescaler(VP8LDecoder* const dec, VP8Io* const io) {
|
||||
out_width, out_height, 0, num_channels, work);
|
||||
return 1;
|
||||
}
|
||||
#endif // WEBP_REDUCE_SIZE
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Export to ARGB
|
||||
|
||||
#if !defined(WEBP_REDUCE_SIZE)
|
||||
|
||||
// We have special "export" function since we need to convert from BGRA
|
||||
static int Export(WebPRescaler* const rescaler, WEBP_CSP_MODE colorspace,
|
||||
int rgba_stride, uint8_t* const rgba) {
|
||||
@ -611,8 +561,6 @@ static int EmitRescaledRowsRGBA(const VP8LDecoder* const dec,
|
||||
return num_lines_out;
|
||||
}
|
||||
|
||||
#endif // WEBP_REDUCE_SIZE
|
||||
|
||||
// Emit rows without any scaling.
|
||||
static int EmitRows(WEBP_CSP_MODE colorspace,
|
||||
const uint8_t* row_in, int in_stride,
|
||||
@ -754,11 +702,11 @@ static WEBP_INLINE HTreeGroup* GetHtreeGroupForPos(VP8LMetadata* const hdr,
|
||||
|
||||
typedef void (*ProcessRowsFunc)(VP8LDecoder* const dec, int row);
|
||||
|
||||
static void ApplyInverseTransforms(VP8LDecoder* const dec,
|
||||
int start_row, int num_rows,
|
||||
static void ApplyInverseTransforms(VP8LDecoder* const dec, int num_rows,
|
||||
const uint32_t* const rows) {
|
||||
int n = dec->next_transform_;
|
||||
const int cache_pixs = dec->width_ * num_rows;
|
||||
const int start_row = dec->last_row_;
|
||||
const int end_row = start_row + num_rows;
|
||||
const uint32_t* rows_in = rows;
|
||||
uint32_t* const rows_out = dec->argb_cache_;
|
||||
@ -789,7 +737,8 @@ static void ProcessRows(VP8LDecoder* const dec, int row) {
|
||||
VP8Io* const io = dec->io_;
|
||||
uint8_t* rows_data = (uint8_t*)dec->argb_cache_;
|
||||
const int in_stride = io->width * sizeof(uint32_t); // in unit of RGBA
|
||||
ApplyInverseTransforms(dec, dec->last_row_, num_rows, rows);
|
||||
|
||||
ApplyInverseTransforms(dec, num_rows, rows);
|
||||
if (!SetCropWindow(io, dec->last_row_, row, &rows_data, in_stride)) {
|
||||
// Nothing to output (this time).
|
||||
} else {
|
||||
@ -797,12 +746,9 @@ static void ProcessRows(VP8LDecoder* const dec, int row) {
|
||||
if (WebPIsRGBMode(output->colorspace)) { // convert to RGBA
|
||||
const WebPRGBABuffer* const buf = &output->u.RGBA;
|
||||
uint8_t* const rgba = buf->rgba + dec->last_out_row_ * buf->stride;
|
||||
const int num_rows_out =
|
||||
#if !defined(WEBP_REDUCE_SIZE)
|
||||
io->use_scaling ?
|
||||
const int num_rows_out = io->use_scaling ?
|
||||
EmitRescaledRowsRGBA(dec, rows_data, in_stride, io->mb_h,
|
||||
rgba, buf->stride) :
|
||||
#endif // WEBP_REDUCE_SIZE
|
||||
EmitRows(output->colorspace, rows_data, in_stride,
|
||||
io->mb_w, io->mb_h, rgba, buf->stride);
|
||||
// Update 'last_out_row_'.
|
||||
@ -929,11 +875,7 @@ static WEBP_INLINE void CopyBlock8b(uint8_t* const dst, int dist, int length) {
|
||||
#endif
|
||||
break;
|
||||
case 2:
|
||||
#if !defined(WORDS_BIGENDIAN)
|
||||
memcpy(&pattern, src, sizeof(uint16_t));
|
||||
#else
|
||||
pattern = ((uint32_t)src[0] << 8) | src[1];
|
||||
#endif
|
||||
#if defined(__arm__) || defined(_M_ARM)
|
||||
pattern |= pattern << 16;
|
||||
#elif defined(WEBP_USE_MIPS_DSP_R2)
|
||||
@ -947,6 +889,7 @@ static WEBP_INLINE void CopyBlock8b(uint8_t* const dst, int dist, int length) {
|
||||
break;
|
||||
default:
|
||||
goto Copy;
|
||||
break;
|
||||
}
|
||||
CopySmallPattern8b(src, dst, length, pattern);
|
||||
return;
|
||||
@ -1069,13 +1012,12 @@ static int DecodeAlphaData(VP8LDecoder* const dec, uint8_t* const data,
|
||||
ok = 0;
|
||||
goto End;
|
||||
}
|
||||
br->eos_ = VP8LIsEndOfStream(br);
|
||||
assert(br->eos_ == VP8LIsEndOfStream(br));
|
||||
}
|
||||
// Process the remaining rows corresponding to last row-block.
|
||||
ExtractPalettedAlphaRows(dec, row > last_row ? last_row : row);
|
||||
|
||||
End:
|
||||
br->eos_ = VP8LIsEndOfStream(br);
|
||||
if (!ok || (br->eos_ && pos < end)) {
|
||||
ok = 0;
|
||||
dec->status_ = br->eos_ ? VP8_STATUS_SUSPENDED
|
||||
@ -1148,12 +1090,11 @@ static int DecodeImageData(VP8LDecoder* const dec, uint32_t* const data,
|
||||
VP8LFillBitWindow(br);
|
||||
if (htree_group->use_packed_table) {
|
||||
code = ReadPackedSymbols(htree_group, br, src);
|
||||
if (VP8LIsEndOfStream(br)) break;
|
||||
if (code == PACKED_NON_LITERAL_CODE) goto AdvanceByOne;
|
||||
} else {
|
||||
code = ReadSymbol(htree_group->htrees[GREEN], br);
|
||||
}
|
||||
if (VP8LIsEndOfStream(br)) break;
|
||||
if (br->eos_) break; // early out
|
||||
if (code < NUM_LITERAL_CODES) { // Literal
|
||||
if (htree_group->is_trivial_literal) {
|
||||
*src = htree_group->literal_arb | (code << 8);
|
||||
@ -1163,7 +1104,7 @@ static int DecodeImageData(VP8LDecoder* const dec, uint32_t* const data,
|
||||
VP8LFillBitWindow(br);
|
||||
blue = ReadSymbol(htree_group->htrees[BLUE], br);
|
||||
alpha = ReadSymbol(htree_group->htrees[ALPHA], br);
|
||||
if (VP8LIsEndOfStream(br)) break;
|
||||
if (br->eos_) break;
|
||||
*src = ((uint32_t)alpha << 24) | (red << 16) | (code << 8) | blue;
|
||||
}
|
||||
AdvanceByOne:
|
||||
@ -1191,8 +1132,7 @@ static int DecodeImageData(VP8LDecoder* const dec, uint32_t* const data,
|
||||
VP8LFillBitWindow(br);
|
||||
dist_code = GetCopyDistance(dist_symbol, br);
|
||||
dist = PlaneCodeToDistance(width, dist_code);
|
||||
|
||||
if (VP8LIsEndOfStream(br)) break;
|
||||
if (br->eos_) break;
|
||||
if (src - data < (ptrdiff_t)dist || src_end - src < (ptrdiff_t)length) {
|
||||
goto Error;
|
||||
} else {
|
||||
@ -1229,9 +1169,9 @@ static int DecodeImageData(VP8LDecoder* const dec, uint32_t* const data,
|
||||
} else { // Not reached
|
||||
goto Error;
|
||||
}
|
||||
assert(br->eos_ == VP8LIsEndOfStream(br));
|
||||
}
|
||||
|
||||
br->eos_ = VP8LIsEndOfStream(br);
|
||||
if (dec->incremental_ && br->eos_ && src < src_end) {
|
||||
RestoreState(dec);
|
||||
} else if (!br->eos_) {
|
||||
@ -1552,7 +1492,7 @@ static void ExtractAlphaRows(VP8LDecoder* const dec, int last_row) {
|
||||
const int cache_pixs = width * num_rows_to_process;
|
||||
uint8_t* const dst = output + width * cur_row;
|
||||
const uint32_t* const src = dec->argb_cache_;
|
||||
ApplyInverseTransforms(dec, cur_row, num_rows_to_process, in);
|
||||
ApplyInverseTransforms(dec, num_rows_to_process, in);
|
||||
WebPExtractGreen(src, dst, cache_pixs);
|
||||
AlphaApplyFilter(alph_dec,
|
||||
cur_row, cur_row + num_rows_to_process, dst, width);
|
||||
@ -1572,6 +1512,7 @@ int VP8LDecodeAlphaHeader(ALPHDecoder* const alph_dec,
|
||||
if (dec == NULL) return 0;
|
||||
|
||||
assert(alph_dec != NULL);
|
||||
alph_dec->vp8l_dec_ = dec;
|
||||
|
||||
dec->width_ = alph_dec->width_;
|
||||
dec->height_ = alph_dec->height_;
|
||||
@ -1603,12 +1544,11 @@ int VP8LDecodeAlphaHeader(ALPHDecoder* const alph_dec,
|
||||
|
||||
if (!ok) goto Err;
|
||||
|
||||
// Only set here, once we are sure it is valid (to avoid thread races).
|
||||
alph_dec->vp8l_dec_ = dec;
|
||||
return 1;
|
||||
|
||||
Err:
|
||||
VP8LDelete(dec);
|
||||
VP8LDelete(alph_dec->vp8l_dec_);
|
||||
alph_dec->vp8l_dec_ = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1690,19 +1630,12 @@ int VP8LDecodeImage(VP8LDecoder* const dec) {
|
||||
|
||||
if (!AllocateInternalBuffers32b(dec, io->width)) goto Err;
|
||||
|
||||
#if !defined(WEBP_REDUCE_SIZE)
|
||||
if (io->use_scaling && !AllocateAndInitRescaler(dec, io)) goto Err;
|
||||
#else
|
||||
if (io->use_scaling) {
|
||||
dec->status_ = VP8_STATUS_INVALID_PARAM;
|
||||
goto Err;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (io->use_scaling || WebPIsPremultipliedMode(dec->output_->colorspace)) {
|
||||
// need the alpha-multiply functions for premultiplied output or rescaling
|
||||
WebPInitAlphaProcessing();
|
||||
}
|
||||
|
||||
if (!WebPIsRGBMode(dec->output_->colorspace)) {
|
||||
WebPInitConvertARGBToYUV();
|
||||
if (dec->output_->u.YUVA.a != NULL) WebPInitAlphaProcessing();
|
||||
|
@ -12,14 +12,14 @@
|
||||
// Author: Skal (pascal.massimino@gmail.com)
|
||||
// Vikas Arora(vikaas.arora@gmail.com)
|
||||
|
||||
#ifndef WEBP_DEC_VP8LI_DEC_H_
|
||||
#define WEBP_DEC_VP8LI_DEC_H_
|
||||
#ifndef WEBP_DEC_VP8LI_H_
|
||||
#define WEBP_DEC_VP8LI_H_
|
||||
|
||||
#include <string.h> // for memcpy()
|
||||
#include "src/dec/webpi_dec.h"
|
||||
#include "src/utils/bit_reader_utils.h"
|
||||
#include "src/utils/color_cache_utils.h"
|
||||
#include "src/utils/huffman_utils.h"
|
||||
#include "./webpi_dec.h"
|
||||
#include "../utils/bit_reader_utils.h"
|
||||
#include "../utils/color_cache_utils.h"
|
||||
#include "../utils/huffman_utils.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -37,7 +37,7 @@ struct VP8LTransform {
|
||||
int bits_; // subsampling bits defining transform window.
|
||||
int xsize_; // transform window X index.
|
||||
int ysize_; // transform window Y index.
|
||||
uint32_t* data_; // transform data.
|
||||
uint32_t *data_; // transform data.
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
@ -48,23 +48,23 @@ typedef struct {
|
||||
int huffman_mask_;
|
||||
int huffman_subsample_bits_;
|
||||
int huffman_xsize_;
|
||||
uint32_t* huffman_image_;
|
||||
uint32_t *huffman_image_;
|
||||
int num_htree_groups_;
|
||||
HTreeGroup* htree_groups_;
|
||||
HuffmanCode* huffman_tables_;
|
||||
HTreeGroup *htree_groups_;
|
||||
HuffmanCode *huffman_tables_;
|
||||
} VP8LMetadata;
|
||||
|
||||
typedef struct VP8LDecoder VP8LDecoder;
|
||||
struct VP8LDecoder {
|
||||
VP8StatusCode status_;
|
||||
VP8LDecodeState state_;
|
||||
VP8Io* io_;
|
||||
VP8Io *io_;
|
||||
|
||||
const WebPDecBuffer* output_; // shortcut to io->opaque->output
|
||||
const WebPDecBuffer *output_; // shortcut to io->opaque->output
|
||||
|
||||
uint32_t* pixels_; // Internal data: either uint8_t* for alpha
|
||||
uint32_t *pixels_; // Internal data: either uint8_t* for alpha
|
||||
// or uint32_t* for BGRA.
|
||||
uint32_t* argb_cache_; // Scratch buffer for temporary BGRA storage.
|
||||
uint32_t *argb_cache_; // Scratch buffer for temporary BGRA storage.
|
||||
|
||||
VP8LBitReader br_;
|
||||
int incremental_; // if true, incremental decoding is expected
|
||||
@ -86,8 +86,8 @@ struct VP8LDecoder {
|
||||
// or'd bitset storing the transforms types.
|
||||
uint32_t transforms_seen_;
|
||||
|
||||
uint8_t* rescaler_memory; // Working memory for rescaling work.
|
||||
WebPRescaler* rescaler; // Common rescaler for all channels.
|
||||
uint8_t *rescaler_memory; // Working memory for rescaling work.
|
||||
WebPRescaler *rescaler; // Common rescaler for all channels.
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@ -132,4 +132,4 @@ void VP8LDelete(VP8LDecoder* const dec);
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // WEBP_DEC_VP8LI_DEC_H_
|
||||
#endif /* WEBP_DEC_VP8LI_H_ */
|
||||
|
@ -13,11 +13,11 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "src/dec/vp8i_dec.h"
|
||||
#include "src/dec/vp8li_dec.h"
|
||||
#include "src/dec/webpi_dec.h"
|
||||
#include "src/utils/utils.h"
|
||||
#include "src/webp/mux_types.h" // ALPHA_FLAG
|
||||
#include "./vp8i_dec.h"
|
||||
#include "./vp8li_dec.h"
|
||||
#include "./webpi_dec.h"
|
||||
#include "../utils/utils.h"
|
||||
#include "../webp/mux_types.h" // ALPHA_FLAG
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// RIFF layout is:
|
||||
@ -421,9 +421,7 @@ VP8StatusCode WebPParseHeaders(WebPHeaderStructure* const headers) {
|
||||
NULL, NULL, NULL, &has_animation,
|
||||
NULL, headers);
|
||||
if (status == VP8_STATUS_OK || status == VP8_STATUS_NOT_ENOUGH_DATA) {
|
||||
// The WebPDemux API + libwebp can be used to decode individual
|
||||
// uncomposited frames or the WebPAnimDecoder can be used to fully
|
||||
// reconstruct them (see webp/demux.h).
|
||||
// TODO(jzern): full support of animation frames will require API additions.
|
||||
if (has_animation) {
|
||||
status = VP8_STATUS_UNSUPPORTED_FEATURE;
|
||||
}
|
||||
|
@ -11,15 +11,15 @@
|
||||
//
|
||||
// Author: somnath@google.com (Somnath Banerjee)
|
||||
|
||||
#ifndef WEBP_DEC_WEBPI_DEC_H_
|
||||
#define WEBP_DEC_WEBPI_DEC_H_
|
||||
#ifndef WEBP_DEC_WEBPI_H_
|
||||
#define WEBP_DEC_WEBPI_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "src/utils/rescaler_utils.h"
|
||||
#include "src/dec/vp8_dec.h"
|
||||
#include "../utils/rescaler_utils.h"
|
||||
#include "./vp8_dec.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// WebPDecParams: Decoding output parameters. Transient internal object.
|
||||
@ -130,4 +130,4 @@ int WebPAvoidSlowMemory(const WebPDecBuffer* const output,
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // WEBP_DEC_WEBPI_DEC_H_
|
||||
#endif /* WEBP_DEC_WEBPI_H_ */
|
||||
|
@ -1,18 +1,14 @@
|
||||
AM_CPPFLAGS += -I$(top_builddir) -I$(top_srcdir)
|
||||
lib_LTLIBRARIES = libwebpdemux.la
|
||||
|
||||
libwebpdemux_la_SOURCES =
|
||||
libwebpdemux_la_SOURCES += anim_decode.c demux.c
|
||||
|
||||
libwebpdemuxinclude_HEADERS =
|
||||
libwebpdemuxinclude_HEADERS += ../webp/decode.h
|
||||
libwebpdemuxinclude_HEADERS += ../webp/demux.h
|
||||
libwebpdemuxinclude_HEADERS += ../webp/mux_types.h
|
||||
libwebpdemuxinclude_HEADERS += ../webp/types.h
|
||||
noinst_HEADERS =
|
||||
noinst_HEADERS += ../webp/format_constants.h
|
||||
|
||||
libwebpdemux_la_LIBADD = ../libwebp.la
|
||||
libwebpdemux_la_LDFLAGS = -no-undefined -version-info 2:7:0
|
||||
libwebpdemux_la_LDFLAGS = -no-undefined -version-info 2:2:0
|
||||
libwebpdemuxincludedir = $(includedir)/webp
|
||||
pkgconfig_DATA = libwebpdemux.pc
|
||||
|
@ -11,15 +11,15 @@
|
||||
//
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "src/webp/config.h"
|
||||
#include "../webp/config.h"
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "src/utils/utils.h"
|
||||
#include "src/webp/decode.h"
|
||||
#include "src/webp/demux.h"
|
||||
#include "../utils/utils.h"
|
||||
#include "../webp/decode.h"
|
||||
#include "../webp/demux.h"
|
||||
|
||||
#define NUM_CHANNELS 4
|
||||
|
||||
@ -346,15 +346,12 @@ int WebPAnimDecoderGetNext(WebPAnimDecoder* dec,
|
||||
{
|
||||
const uint8_t* in = iter.fragment.bytes;
|
||||
const size_t in_size = iter.fragment.size;
|
||||
const uint32_t stride = width * NUM_CHANNELS; // at most 25 + 2 bits
|
||||
const uint64_t out_offset = (uint64_t)iter.y_offset * stride +
|
||||
(uint64_t)iter.x_offset * NUM_CHANNELS; // 53b
|
||||
const uint64_t size = (uint64_t)iter.height * stride; // at most 25 + 27b
|
||||
const size_t out_offset =
|
||||
(iter.y_offset * width + iter.x_offset) * NUM_CHANNELS;
|
||||
WebPDecoderConfig* const config = &dec->config_;
|
||||
WebPRGBABuffer* const buf = &config->output.u.RGBA;
|
||||
if ((size_t)size != size) goto Error;
|
||||
buf->stride = (int)stride;
|
||||
buf->size = (size_t)size;
|
||||
buf->stride = NUM_CHANNELS * width;
|
||||
buf->size = buf->stride * iter.height;
|
||||
buf->rgba = dec->curr_frame_ + out_offset;
|
||||
|
||||
if (WebPDecode(in, in_size, config) != VP8_STATUS_OK) {
|
||||
|
@ -11,21 +11,21 @@
|
||||
//
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "src/webp/config.h"
|
||||
#include "../webp/config.h"
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "src/utils/utils.h"
|
||||
#include "src/webp/decode.h" // WebPGetFeatures
|
||||
#include "src/webp/demux.h"
|
||||
#include "src/webp/format_constants.h"
|
||||
#include "../utils/utils.h"
|
||||
#include "../webp/decode.h" // WebPGetFeatures
|
||||
#include "../webp/demux.h"
|
||||
#include "../webp/format_constants.h"
|
||||
|
||||
#define DMUX_MAJ_VERSION 1
|
||||
#define DMUX_MIN_VERSION 2
|
||||
#define DMUX_REV_VERSION 0
|
||||
#define DMUX_MAJ_VERSION 0
|
||||
#define DMUX_MIN_VERSION 3
|
||||
#define DMUX_REV_VERSION 2
|
||||
|
||||
typedef struct {
|
||||
size_t start_; // start location of the data
|
||||
@ -205,14 +205,12 @@ static void SetFrameInfo(size_t start_offset, size_t size,
|
||||
frame->complete_ = complete;
|
||||
}
|
||||
|
||||
// Store image bearing chunks to 'frame'. 'min_size' is an optional size
|
||||
// requirement, it may be zero.
|
||||
// Store image bearing chunks to 'frame'.
|
||||
static ParseStatus StoreFrame(int frame_num, uint32_t min_size,
|
||||
MemBuffer* const mem, Frame* const frame) {
|
||||
int alpha_chunks = 0;
|
||||
int image_chunks = 0;
|
||||
int done = (MemDataSize(mem) < CHUNK_HEADER_SIZE ||
|
||||
MemDataSize(mem) < min_size);
|
||||
int done = (MemDataSize(mem) < min_size);
|
||||
ParseStatus status = PARSE_OK;
|
||||
|
||||
if (done) return PARSE_NEED_MORE_DATA;
|
||||
@ -312,7 +310,6 @@ static ParseStatus ParseAnimationFrame(
|
||||
int bits;
|
||||
MemBuffer* const mem = &dmux->mem_;
|
||||
Frame* frame;
|
||||
size_t start_offset;
|
||||
ParseStatus status =
|
||||
NewFrame(mem, ANMF_CHUNK_SIZE, frame_chunk_size, &frame);
|
||||
if (status != PARSE_OK) return status;
|
||||
@ -333,11 +330,7 @@ static ParseStatus ParseAnimationFrame(
|
||||
|
||||
// Store a frame only if the animation flag is set there is some data for
|
||||
// this frame is available.
|
||||
start_offset = mem->start_;
|
||||
status = StoreFrame(dmux->num_frames_ + 1, anmf_payload_size, mem, frame);
|
||||
if (status != PARSE_ERROR && mem->start_ - start_offset > anmf_payload_size) {
|
||||
status = PARSE_ERROR;
|
||||
}
|
||||
if (status != PARSE_ERROR && is_animation && frame->frame_num_ > 0) {
|
||||
added_frame = AddFrame(dmux, frame);
|
||||
if (added_frame) {
|
||||
@ -408,9 +401,9 @@ static ParseStatus ParseSingleImage(WebPDemuxer* const dmux) {
|
||||
frame = (Frame*)WebPSafeCalloc(1ULL, sizeof(*frame));
|
||||
if (frame == NULL) return PARSE_ERROR;
|
||||
|
||||
// For the single image case we allow parsing of a partial frame, so no
|
||||
// minimum size is imposed here.
|
||||
status = StoreFrame(1, 0, &dmux->mem_, frame);
|
||||
// For the single image case we allow parsing of a partial frame, but we need
|
||||
// at least CHUNK_HEADER_SIZE for parsing.
|
||||
status = StoreFrame(1, CHUNK_HEADER_SIZE, &dmux->mem_, frame);
|
||||
if (status != PARSE_ERROR) {
|
||||
const int has_alpha = !!(dmux->feature_flags_ & ALPHA_FLAG);
|
||||
// Clear any alpha when the alpha flag is missing.
|
||||
|
@ -6,8 +6,8 @@
|
||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 1,0,2,0
|
||||
PRODUCTVERSION 1,0,2,0
|
||||
FILEVERSION 0,3,0,2
|
||||
PRODUCTVERSION 0,3,0,2
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
@ -24,12 +24,12 @@ BEGIN
|
||||
BEGIN
|
||||
VALUE "CompanyName", "Google, Inc."
|
||||
VALUE "FileDescription", "libwebpdemux DLL"
|
||||
VALUE "FileVersion", "1.2.0"
|
||||
VALUE "FileVersion", "0.3.2"
|
||||
VALUE "InternalName", "libwebpdemux.dll"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2019"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2017"
|
||||
VALUE "OriginalFilename", "libwebpdemux.dll"
|
||||
VALUE "ProductName", "WebP Image Demuxer"
|
||||
VALUE "ProductVersion", "1.2.0"
|
||||
VALUE "ProductVersion", "0.3.2"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user