mirror of
https://github.com/webmproject/libwebp.git
synced 2025-12-24 22:19:11 +01:00
Compare commits
1 Commits
chrome-m10
...
sandbox/jz
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
86c756929c |
1
.gitattributes
vendored
1
.gitattributes
vendored
@@ -1,6 +1,5 @@
|
|||||||
.gitattributes export-ignore
|
.gitattributes export-ignore
|
||||||
.gitignore export-ignore
|
.gitignore export-ignore
|
||||||
.mailmap export-ignore
|
.mailmap export-ignore
|
||||||
*.bat text eol=crlf
|
|
||||||
*.pdf -text -diff
|
*.pdf -text -diff
|
||||||
*.ppm -text -diff
|
*.ppm -text -diff
|
||||||
|
|||||||
17
.gitignore
vendored
17
.gitignore
vendored
@@ -1,11 +1,8 @@
|
|||||||
*.l[ao]
|
*.l[ao]
|
||||||
*.[ao]
|
*.[ao]
|
||||||
*.pc
|
*.pc
|
||||||
.DS_Store
|
|
||||||
.deps
|
.deps
|
||||||
.idea
|
|
||||||
.libs
|
.libs
|
||||||
.vscode
|
|
||||||
/aclocal.m4
|
/aclocal.m4
|
||||||
/ar-lib
|
/ar-lib
|
||||||
/autom4te.cache
|
/autom4te.cache
|
||||||
@@ -23,11 +20,9 @@
|
|||||||
Makefile
|
Makefile
|
||||||
Makefile.in
|
Makefile.in
|
||||||
examples/anim_diff
|
examples/anim_diff
|
||||||
examples/anim_dump
|
|
||||||
examples/[cdv]webp
|
examples/[cdv]webp
|
||||||
examples/gif2webp
|
examples/gif2webp
|
||||||
examples/img2webp
|
examples/img2webp
|
||||||
examples/webpinfo
|
|
||||||
examples/webpmux
|
examples/webpmux
|
||||||
src/webp/config.h*
|
src/webp/config.h*
|
||||||
src/webp/stamp-h1
|
src/webp/stamp-h1
|
||||||
@@ -36,21 +31,11 @@ src/webp/stamp-h1
|
|||||||
*.idb
|
*.idb
|
||||||
*.pdb
|
*.pdb
|
||||||
/iosbuild
|
/iosbuild
|
||||||
/xcframeworkbuild
|
/WebP.framework
|
||||||
/WebP*.*framework
|
|
||||||
CMakeCache.txt
|
CMakeCache.txt
|
||||||
CMakeFiles/
|
CMakeFiles/
|
||||||
cmake_install.cmake
|
cmake_install.cmake
|
||||||
.gradle
|
.gradle
|
||||||
/build
|
/build
|
||||||
extras/get_disto
|
extras/get_disto
|
||||||
extras/vwebp_sdl
|
|
||||||
extras/webp_quality
|
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
|
|
||||||
|
|||||||
10
.mailmap
10
.mailmap
@@ -1,18 +1,12 @@
|
|||||||
Johann Koenig <johann.koenig@duck.com>
|
<johann.koenig@duck.com> <johannkoenig@google.com>
|
||||||
Johann Koenig <johann.koenig@duck.com> <johannkoenig@google.com>
|
|
||||||
Mikołaj Zalewski <mikolajz@google.com>
|
Mikołaj Zalewski <mikolajz@google.com>
|
||||||
Pascal Massimino <pascal.massimino@gmail.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>
|
Vikas Arora <vikasa@google.com>
|
||||||
<vikasa@google.com> <vikasa@gmail.com>
|
<vikasa@google.com> <vikasa@gmail.com>
|
||||||
<vikasa@google.com> <vikaas.arora@gmail.com>
|
<vikasa@google.com> <vikaas.arora@gmail.com>
|
||||||
<slobodan.prijic@imgtec.com> <Slobodan.Prijic@imgtec.com>
|
<slobodan.prijic@imgtec.com> <Slobodan.Prijic@imgtec.com>
|
||||||
<vrabaud@google.com> <vincent.rabaud@gmail.com>
|
<vrabaud@google.com> <vincent.rabaud@gmail.com>
|
||||||
Vincent Rabaud <vrabaud@google.com>
|
|
||||||
Tamar Levy <tamar.levy@intel.com>
|
Tamar Levy <tamar.levy@intel.com>
|
||||||
<qrczak@google.com> <qrczak>
|
<qrczak@google.com> <qrczak>
|
||||||
Hui Su <huisu@google.com>
|
Hui Su <huisu@google.com>
|
||||||
James Zern <jzern@google.com>
|
|
||||||
Roberto Alanis <alanisbaez@google.com>
|
|
||||||
Brian Ledger <brianpl@google.com>
|
|
||||||
Maryla Ustarroz-Calonge <maryla@google.com>
|
|
||||||
|
|||||||
441
.pylintrc
441
.pylintrc
@@ -1,441 +0,0 @@
|
|||||||
# This Pylint rcfile contains a best-effort configuration to uphold the
|
|
||||||
# best-practices and style described in the Google Python style guide:
|
|
||||||
# https://google.github.io/styleguide/pyguide.html
|
|
||||||
#
|
|
||||||
# Its canonical open-source location is:
|
|
||||||
# https://google.github.io/styleguide/pylintrc
|
|
||||||
|
|
||||||
[MASTER]
|
|
||||||
|
|
||||||
# Files or directories to be skipped. They should be base names, not paths.
|
|
||||||
ignore=third_party
|
|
||||||
|
|
||||||
# Files or directories matching the regex patterns are skipped. The regex
|
|
||||||
# matches against base names, not paths.
|
|
||||||
ignore-patterns=
|
|
||||||
|
|
||||||
# Pickle collected data for later comparisons.
|
|
||||||
persistent=no
|
|
||||||
|
|
||||||
# List of plugins (as comma separated values of python modules names) to load,
|
|
||||||
# usually to register additional checkers.
|
|
||||||
load-plugins=
|
|
||||||
|
|
||||||
# Use multiple processes to speed up Pylint.
|
|
||||||
jobs=4
|
|
||||||
|
|
||||||
# Allow loading of arbitrary C extensions. Extensions are imported into the
|
|
||||||
# active Python interpreter and may run arbitrary code.
|
|
||||||
unsafe-load-any-extension=no
|
|
||||||
|
|
||||||
|
|
||||||
[MESSAGES CONTROL]
|
|
||||||
|
|
||||||
# Only show warnings with the listed confidence levels. Leave empty to show
|
|
||||||
# all. Valid levels: HIGH, INFERENCE, INFERENCE_FAILURE, UNDEFINED
|
|
||||||
confidence=
|
|
||||||
|
|
||||||
# Enable the message, report, category or checker with the given id(s). You can
|
|
||||||
# either give multiple identifier separated by comma (,) or put this option
|
|
||||||
# multiple time (only on the command line, not in the configuration file where
|
|
||||||
# it should appear only once). See also the "--disable" option for examples.
|
|
||||||
#enable=
|
|
||||||
|
|
||||||
# Disable the message, report, category or checker with the given id(s). You
|
|
||||||
# can either give multiple identifiers separated by comma (,) or put this
|
|
||||||
# option multiple times (only on the command line, not in the configuration
|
|
||||||
# file where it should appear only once).You can also use "--disable=all" to
|
|
||||||
# disable everything first and then reenable specific checks. For example, if
|
|
||||||
# you want to run only the similarities checker, you can use "--disable=all
|
|
||||||
# --enable=similarities". If you want to run only the classes checker, but have
|
|
||||||
# no Warning level messages displayed, use"--disable=all --enable=classes
|
|
||||||
# --disable=W"
|
|
||||||
disable=abstract-method,
|
|
||||||
apply-builtin,
|
|
||||||
arguments-differ,
|
|
||||||
attribute-defined-outside-init,
|
|
||||||
backtick,
|
|
||||||
bad-option-value,
|
|
||||||
basestring-builtin,
|
|
||||||
buffer-builtin,
|
|
||||||
c-extension-no-member,
|
|
||||||
consider-using-enumerate,
|
|
||||||
cmp-builtin,
|
|
||||||
cmp-method,
|
|
||||||
coerce-builtin,
|
|
||||||
coerce-method,
|
|
||||||
delslice-method,
|
|
||||||
div-method,
|
|
||||||
duplicate-code,
|
|
||||||
eq-without-hash,
|
|
||||||
execfile-builtin,
|
|
||||||
file-builtin,
|
|
||||||
filter-builtin-not-iterating,
|
|
||||||
fixme,
|
|
||||||
getslice-method,
|
|
||||||
global-statement,
|
|
||||||
hex-method,
|
|
||||||
idiv-method,
|
|
||||||
implicit-str-concat-in-sequence,
|
|
||||||
import-error,
|
|
||||||
import-self,
|
|
||||||
import-star-module-level,
|
|
||||||
inconsistent-return-statements,
|
|
||||||
input-builtin,
|
|
||||||
intern-builtin,
|
|
||||||
invalid-str-codec,
|
|
||||||
locally-disabled,
|
|
||||||
long-builtin,
|
|
||||||
long-suffix,
|
|
||||||
map-builtin-not-iterating,
|
|
||||||
misplaced-comparison-constant,
|
|
||||||
missing-function-docstring,
|
|
||||||
metaclass-assignment,
|
|
||||||
next-method-called,
|
|
||||||
next-method-defined,
|
|
||||||
no-absolute-import,
|
|
||||||
no-else-break,
|
|
||||||
no-else-continue,
|
|
||||||
no-else-raise,
|
|
||||||
no-else-return,
|
|
||||||
no-init, # added
|
|
||||||
no-member,
|
|
||||||
no-name-in-module,
|
|
||||||
no-self-use,
|
|
||||||
nonzero-method,
|
|
||||||
oct-method,
|
|
||||||
old-division,
|
|
||||||
old-ne-operator,
|
|
||||||
old-octal-literal,
|
|
||||||
old-raise-syntax,
|
|
||||||
parameter-unpacking,
|
|
||||||
print-statement,
|
|
||||||
raising-string,
|
|
||||||
range-builtin-not-iterating,
|
|
||||||
raw_input-builtin,
|
|
||||||
rdiv-method,
|
|
||||||
reduce-builtin,
|
|
||||||
relative-import,
|
|
||||||
reload-builtin,
|
|
||||||
round-builtin,
|
|
||||||
setslice-method,
|
|
||||||
signature-differs,
|
|
||||||
standarderror-builtin,
|
|
||||||
suppressed-message,
|
|
||||||
sys-max-int,
|
|
||||||
too-few-public-methods,
|
|
||||||
too-many-ancestors,
|
|
||||||
too-many-arguments,
|
|
||||||
too-many-boolean-expressions,
|
|
||||||
too-many-branches,
|
|
||||||
too-many-instance-attributes,
|
|
||||||
too-many-locals,
|
|
||||||
too-many-nested-blocks,
|
|
||||||
too-many-public-methods,
|
|
||||||
too-many-return-statements,
|
|
||||||
too-many-statements,
|
|
||||||
trailing-newlines,
|
|
||||||
unichr-builtin,
|
|
||||||
unicode-builtin,
|
|
||||||
unnecessary-pass,
|
|
||||||
unpacking-in-except,
|
|
||||||
useless-else-on-loop,
|
|
||||||
useless-object-inheritance,
|
|
||||||
useless-suppression,
|
|
||||||
using-cmp-argument,
|
|
||||||
wrong-import-order,
|
|
||||||
xrange-builtin,
|
|
||||||
zip-builtin-not-iterating,
|
|
||||||
|
|
||||||
|
|
||||||
[REPORTS]
|
|
||||||
|
|
||||||
# Set the output format. Available formats are text, parseable, colorized, msvs
|
|
||||||
# (visual studio) and html. You can also give a reporter class, eg
|
|
||||||
# mypackage.mymodule.MyReporterClass.
|
|
||||||
output-format=text
|
|
||||||
|
|
||||||
# Put messages in a separate file for each module / package specified on the
|
|
||||||
# command line instead of printing them on stdout. Reports (if any) will be
|
|
||||||
# written in a file name "pylint_global.[txt|html]". This option is deprecated
|
|
||||||
# and it will be removed in Pylint 2.0.
|
|
||||||
files-output=no
|
|
||||||
|
|
||||||
# Tells whether to display a full report or only the messages
|
|
||||||
reports=no
|
|
||||||
|
|
||||||
# Python expression which should return a note less than 10 (10 is the highest
|
|
||||||
# note). You have access to the variables errors warning, statement which
|
|
||||||
# respectively contain the number of errors / warnings messages and the total
|
|
||||||
# number of statements analyzed. This is used by the global evaluation report
|
|
||||||
# (RP0004).
|
|
||||||
evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10)
|
|
||||||
|
|
||||||
# Template used to display messages. This is a python new-style format string
|
|
||||||
# used to format the message information. See doc for all details
|
|
||||||
#msg-template=
|
|
||||||
|
|
||||||
|
|
||||||
[BASIC]
|
|
||||||
|
|
||||||
# Good variable names which should always be accepted, separated by a comma
|
|
||||||
good-names=main,_,PRESUBMIT
|
|
||||||
|
|
||||||
# Bad variable names which should always be refused, separated by a comma
|
|
||||||
bad-names=
|
|
||||||
|
|
||||||
# Colon-delimited sets of names that determine each other's naming style when
|
|
||||||
# the name regexes allow several styles.
|
|
||||||
name-group=
|
|
||||||
|
|
||||||
# Include a hint for the correct naming format with invalid-name
|
|
||||||
include-naming-hint=no
|
|
||||||
|
|
||||||
# List of decorators that produce properties, such as abc.abstractproperty. Add
|
|
||||||
# to this list to register other decorators that produce valid properties.
|
|
||||||
property-classes=abc.abstractproperty,cached_property.cached_property,cached_property.threaded_cached_property,cached_property.cached_property_with_ttl,cached_property.threaded_cached_property_with_ttl
|
|
||||||
|
|
||||||
# Regular expression matching correct function names
|
|
||||||
function-rgx=^(?:(?P<exempt>setUp|tearDown|setUpModule|tearDownModule)|(?P<camel_case>_?[A-Z][a-zA-Z0-9]*)|(?P<snake_case>_?[a-z][a-z0-9_]*))$
|
|
||||||
|
|
||||||
# Regular expression matching correct variable names
|
|
||||||
variable-rgx=^[a-z][a-z0-9_]*$
|
|
||||||
|
|
||||||
# Regular expression matching correct constant names
|
|
||||||
const-rgx=^(_?[A-Z][A-Z0-9_]*|__[a-z0-9_]+__|_?[a-z][a-z0-9_]*)$
|
|
||||||
|
|
||||||
# Regular expression matching correct attribute names
|
|
||||||
attr-rgx=^_{0,2}[a-z][a-z0-9_]*$
|
|
||||||
|
|
||||||
# Regular expression matching correct argument names
|
|
||||||
argument-rgx=^[a-z][a-z0-9_]*$
|
|
||||||
|
|
||||||
# Regular expression matching correct class attribute names
|
|
||||||
class-attribute-rgx=^(_?[A-Z][A-Z0-9_]*|__[a-z0-9_]+__|_?[a-z][a-z0-9_]*)$
|
|
||||||
|
|
||||||
# Regular expression matching correct inline iteration names
|
|
||||||
inlinevar-rgx=^[a-z][a-z0-9_]*$
|
|
||||||
|
|
||||||
# Regular expression matching correct class names
|
|
||||||
class-rgx=^_?[A-Z][a-zA-Z0-9]*$
|
|
||||||
|
|
||||||
# Regular expression matching correct module names
|
|
||||||
module-rgx=^(_?[a-z][a-z0-9_]*|__init__)$
|
|
||||||
|
|
||||||
# Regular expression matching correct method names
|
|
||||||
method-rgx=(?x)^(?:(?P<exempt>_[a-z0-9_]+__|runTest|setUp|tearDown|setUpTestCase|tearDownTestCase|setupSelf|tearDownClass|setUpClass|(test|assert)_*[A-Z0-9][a-zA-Z0-9_]*|next)|(?P<camel_case>_{0,2}[A-Z][a-zA-Z0-9_]*)|(?P<snake_case>_{0,2}[a-z][a-z0-9_]*))$
|
|
||||||
|
|
||||||
# Regular expression which should only match function or class names that do
|
|
||||||
# not require a docstring.
|
|
||||||
no-docstring-rgx=(__.*__|main|test.*|.*test|.*Test)$
|
|
||||||
|
|
||||||
# Minimum line length for functions/classes that require docstrings, shorter
|
|
||||||
# ones are exempt.
|
|
||||||
docstring-min-length=10
|
|
||||||
|
|
||||||
|
|
||||||
[TYPECHECK]
|
|
||||||
|
|
||||||
# List of decorators that produce context managers, such as
|
|
||||||
# contextlib.contextmanager. Add to this list to register other decorators that
|
|
||||||
# produce valid context managers.
|
|
||||||
contextmanager-decorators=contextlib.contextmanager,contextlib2.contextmanager
|
|
||||||
|
|
||||||
# Tells whether missing members accessed in mixin class should be ignored. A
|
|
||||||
# mixin class is detected if its name ends with "mixin" (case insensitive).
|
|
||||||
ignore-mixin-members=yes
|
|
||||||
|
|
||||||
# List of module names for which member attributes should not be checked
|
|
||||||
# (useful for modules/projects where namespaces are manipulated during runtime
|
|
||||||
# and thus existing member attributes cannot be deduced by static analysis. It
|
|
||||||
# supports qualified module names, as well as Unix pattern matching.
|
|
||||||
ignored-modules=
|
|
||||||
|
|
||||||
# List of class names for which member attributes should not be checked (useful
|
|
||||||
# for classes with dynamically set attributes). This supports the use of
|
|
||||||
# qualified names.
|
|
||||||
ignored-classes=optparse.Values,thread._local,_thread._local
|
|
||||||
|
|
||||||
# List of members which are set dynamically and missed by pylint inference
|
|
||||||
# system, and so shouldn't trigger E1101 when accessed. Python regular
|
|
||||||
# expressions are accepted.
|
|
||||||
generated-members=
|
|
||||||
|
|
||||||
|
|
||||||
[FORMAT]
|
|
||||||
|
|
||||||
# Maximum number of characters on a single line.
|
|
||||||
max-line-length=80
|
|
||||||
|
|
||||||
# TODO(https://github.com/PyCQA/pylint/issues/3352): Direct pylint to exempt
|
|
||||||
# lines made too long by directives to pytype.
|
|
||||||
|
|
||||||
# Regexp for a line that is allowed to be longer than the limit.
|
|
||||||
ignore-long-lines=(?x)(
|
|
||||||
^\s*(\#\ )?<?https?://\S+>?$|
|
|
||||||
^\s*(from\s+\S+\s+)?import\s+.+$)
|
|
||||||
|
|
||||||
# Allow the body of an if to be on the same line as the test if there is no
|
|
||||||
# else.
|
|
||||||
single-line-if-stmt=yes
|
|
||||||
|
|
||||||
# List of optional constructs for which whitespace checking is disabled. `dict-
|
|
||||||
# separator` is used to allow tabulation in dicts, etc.: {1 : 1,\n222: 2}.
|
|
||||||
# `trailing-comma` allows a space between comma and closing bracket: (a, ).
|
|
||||||
# `empty-line` allows space-only lines.
|
|
||||||
no-space-check=
|
|
||||||
|
|
||||||
# Maximum number of lines in a module
|
|
||||||
max-module-lines=99999
|
|
||||||
|
|
||||||
# String used as indentation unit. The internal Google style guide mandates 2
|
|
||||||
# spaces. Google's externaly-published style guide says 4, consistent with
|
|
||||||
# PEP 8. Here, we use 2 spaces, for conformity with many open-sourced Google
|
|
||||||
# projects (like TensorFlow).
|
|
||||||
indent-string=' '
|
|
||||||
|
|
||||||
# Number of spaces of indent required inside a hanging or continued line.
|
|
||||||
indent-after-paren=4
|
|
||||||
|
|
||||||
# Expected format of line ending, e.g. empty (any line ending), LF or CRLF.
|
|
||||||
expected-line-ending-format=
|
|
||||||
|
|
||||||
|
|
||||||
[MISCELLANEOUS]
|
|
||||||
|
|
||||||
# List of note tags to take in consideration, separated by a comma.
|
|
||||||
notes=TODO
|
|
||||||
|
|
||||||
|
|
||||||
[STRING]
|
|
||||||
|
|
||||||
# This flag controls whether inconsistent-quotes generates a warning when the
|
|
||||||
# character used as a quote delimiter is used inconsistently within a module.
|
|
||||||
check-quote-consistency=yes
|
|
||||||
|
|
||||||
|
|
||||||
[VARIABLES]
|
|
||||||
|
|
||||||
# Tells whether we should check for unused import in __init__ files.
|
|
||||||
init-import=no
|
|
||||||
|
|
||||||
# A regular expression matching the name of dummy variables (i.e. expectedly
|
|
||||||
# not used).
|
|
||||||
dummy-variables-rgx=^\*{0,2}(_$|unused_|dummy_)
|
|
||||||
|
|
||||||
# List of additional names supposed to be defined in builtins. Remember that
|
|
||||||
# you should avoid to define new builtins when possible.
|
|
||||||
additional-builtins=
|
|
||||||
|
|
||||||
# List of strings which can identify a callback function by name. A callback
|
|
||||||
# name must start or end with one of those strings.
|
|
||||||
callbacks=cb_,_cb
|
|
||||||
|
|
||||||
# List of qualified module names which can have objects that can redefine
|
|
||||||
# builtins.
|
|
||||||
redefining-builtins-modules=six,six.moves,past.builtins,future.builtins,functools
|
|
||||||
|
|
||||||
|
|
||||||
[LOGGING]
|
|
||||||
|
|
||||||
# Logging modules to check that the string format arguments are in logging
|
|
||||||
# function parameter format
|
|
||||||
logging-modules=logging,absl.logging,tensorflow.io.logging
|
|
||||||
|
|
||||||
|
|
||||||
[SIMILARITIES]
|
|
||||||
|
|
||||||
# Minimum lines number of a similarity.
|
|
||||||
min-similarity-lines=4
|
|
||||||
|
|
||||||
# Ignore comments when computing similarities.
|
|
||||||
ignore-comments=yes
|
|
||||||
|
|
||||||
# Ignore docstrings when computing similarities.
|
|
||||||
ignore-docstrings=yes
|
|
||||||
|
|
||||||
# Ignore imports when computing similarities.
|
|
||||||
ignore-imports=no
|
|
||||||
|
|
||||||
|
|
||||||
[SPELLING]
|
|
||||||
|
|
||||||
# Spelling dictionary name. Available dictionaries: none. To make it working
|
|
||||||
# install python-enchant package.
|
|
||||||
spelling-dict=
|
|
||||||
|
|
||||||
# List of comma separated words that should not be checked.
|
|
||||||
spelling-ignore-words=
|
|
||||||
|
|
||||||
# A path to a file that contains private dictionary; one word per line.
|
|
||||||
spelling-private-dict-file=
|
|
||||||
|
|
||||||
# Tells whether to store unknown words to indicated private dictionary in
|
|
||||||
# --spelling-private-dict-file option instead of raising a message.
|
|
||||||
spelling-store-unknown-words=no
|
|
||||||
|
|
||||||
|
|
||||||
[IMPORTS]
|
|
||||||
|
|
||||||
# Deprecated modules which should not be used, separated by a comma
|
|
||||||
deprecated-modules=regsub,
|
|
||||||
TERMIOS,
|
|
||||||
Bastion,
|
|
||||||
rexec,
|
|
||||||
sets
|
|
||||||
|
|
||||||
# Create a graph of every (i.e. internal and external) dependencies in the
|
|
||||||
# given file (report RP0402 must not be disabled)
|
|
||||||
import-graph=
|
|
||||||
|
|
||||||
# Create a graph of external dependencies in the given file (report RP0402 must
|
|
||||||
# not be disabled)
|
|
||||||
ext-import-graph=
|
|
||||||
|
|
||||||
# Create a graph of internal dependencies in the given file (report RP0402 must
|
|
||||||
# not be disabled)
|
|
||||||
int-import-graph=
|
|
||||||
|
|
||||||
# Force import order to recognize a module as part of the standard
|
|
||||||
# compatibility libraries.
|
|
||||||
known-standard-library=
|
|
||||||
|
|
||||||
# Force import order to recognize a module as part of a third party library.
|
|
||||||
known-third-party=enchant, absl
|
|
||||||
|
|
||||||
# Analyse import fallback blocks. This can be used to support both Python 2 and
|
|
||||||
# 3 compatible code, which means that the block might have code that exists
|
|
||||||
# only in one or another interpreter, leading to false positives when analysed.
|
|
||||||
analyse-fallback-blocks=no
|
|
||||||
|
|
||||||
|
|
||||||
[CLASSES]
|
|
||||||
|
|
||||||
# List of method names used to declare (i.e. assign) instance attributes.
|
|
||||||
defining-attr-methods=__init__,
|
|
||||||
__new__,
|
|
||||||
setUp
|
|
||||||
|
|
||||||
# List of member names, which should be excluded from the protected access
|
|
||||||
# warning.
|
|
||||||
exclude-protected=_asdict,
|
|
||||||
_fields,
|
|
||||||
_replace,
|
|
||||||
_source,
|
|
||||||
_make
|
|
||||||
|
|
||||||
# List of valid names for the first argument in a class method.
|
|
||||||
valid-classmethod-first-arg=cls,
|
|
||||||
class_
|
|
||||||
|
|
||||||
# List of valid names for the first argument in a metaclass class method.
|
|
||||||
valid-metaclass-classmethod-first-arg=mcs
|
|
||||||
|
|
||||||
|
|
||||||
[EXCEPTIONS]
|
|
||||||
|
|
||||||
# Exceptions that will emit a warning when being caught. Defaults to
|
|
||||||
# "Exception"
|
|
||||||
overgeneral-exceptions=StandardError,
|
|
||||||
Exception,
|
|
||||||
BaseException
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
[style]
|
|
||||||
based_on_style = chromium
|
|
||||||
20
AUTHORS
20
AUTHORS
@@ -1,42 +1,28 @@
|
|||||||
Contributors:
|
Contributors:
|
||||||
- Aidan O'Loan (aidanol at gmail dot com)
|
|
||||||
- Alan Browning (browning at google dot com)
|
|
||||||
- Alexandru Ardelean (ardeleanalex at gmail dot com)
|
|
||||||
- Brian Ledger (brianpl at google dot com)
|
|
||||||
- Charles Munger (clm 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)
|
- Christian Duvivier (cduvivier at google dot com)
|
||||||
- Christopher Degawa (ccom at randomderp dot com)
|
|
||||||
- Clement Courbet (courbet at google dot com)
|
|
||||||
- Djordje Pesut (djordje dot pesut at imgtec dot com)
|
- Djordje Pesut (djordje dot pesut at imgtec dot com)
|
||||||
- Frank Barchard (fbarchard at google dot com)
|
|
||||||
- Hui Su (huisu at google dot com)
|
- Hui Su (huisu at google dot com)
|
||||||
- Ilya Kurdyukov (jpegqs at gmail dot com)
|
|
||||||
- Ingvar Stepanyan (rreverser at google dot com)
|
|
||||||
- James Zern (jzern at google dot com)
|
- James Zern (jzern at google dot com)
|
||||||
- Jan Engelhardt (jengelh at medozas dot de)
|
- Jan Engelhardt (jengelh at medozas dot de)
|
||||||
- Jehan (jehan at girinstud dot io)
|
- 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)
|
- Jovan Zelincevic (jovan dot zelincevic at imgtec dot com)
|
||||||
- Jyrki Alakuijala (jyrki at google dot com)
|
- Jyrki Alakuijala (jyrki at google dot com)
|
||||||
- Konstantin Ivlev (tomskside at gmail dot com)
|
|
||||||
- Lode Vandevenne (lode at google dot com)
|
- Lode Vandevenne (lode at google dot com)
|
||||||
- Lou Quillio (louquillio at google dot com)
|
- Lou Quillio (louquillio at google dot com)
|
||||||
- Mans Rullgard (mans at mansr dot com)
|
- Mans Rullgard (mans at mansr dot com)
|
||||||
- Marcin Kowalczyk (qrczak at google dot com)
|
- Marcin Kowalczyk (qrczak at google dot com)
|
||||||
- Martin Olsson (mnemo at minimum dot se)
|
- Martin Olsson (mnemo at minimum dot se)
|
||||||
- Maryla Ustarroz-Calonge (maryla at google dot com)
|
|
||||||
- Mikołaj Zalewski (mikolajz at google dot com)
|
- Mikołaj Zalewski (mikolajz at google dot com)
|
||||||
- Mislav Bradac (mislavm at google dot com)
|
- Mislav Bradac (mislavm at google dot com)
|
||||||
- Nico Weber (thakis at chromium dot org)
|
- Nico Weber (thakis at chromium dot org)
|
||||||
- Noel Chromium (noel 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)
|
- Owen Rodley (orodley at google dot com)
|
||||||
- Parag Salasakar (img dot mips1 at gmail dot com)
|
- Parag Salasakar (img dot mips1 at gmail dot com)
|
||||||
- Pascal Massimino (pascal dot massimino at gmail dot com)
|
- Pascal Massimino (pascal dot massimino at gmail dot com)
|
||||||
- Paweł Hajdan, Jr (phajdan dot jr at chromium dot org)
|
- Paweł Hajdan, Jr (phajdan dot jr at chromium dot org)
|
||||||
- Pierre Joye (pierre dot php at gmail dot com)
|
- Pierre Joye (pierre dot php at gmail dot com)
|
||||||
- Roberto Alanis (alanisbaez at google dot com)
|
|
||||||
- Sam Clegg (sbc at chromium dot org)
|
- Sam Clegg (sbc at chromium dot org)
|
||||||
- Scott Hancher (seh at google dot com)
|
- Scott Hancher (seh at google dot com)
|
||||||
- Scott LaVarnway (slavarnway at google dot com)
|
- Scott LaVarnway (slavarnway at google dot com)
|
||||||
@@ -49,8 +35,4 @@ Contributors:
|
|||||||
- Urvang Joshi (urvang at google dot com)
|
- Urvang Joshi (urvang at google dot com)
|
||||||
- Vikas Arora (vikasa at google dot com)
|
- Vikas Arora (vikasa at google dot com)
|
||||||
- Vincent Rabaud (vrabaud at google dot com)
|
- Vincent Rabaud (vrabaud at google dot com)
|
||||||
- Vlad Tsyrklevich (vtsyrklevich at chromium dot org)
|
|
||||||
- Wan-Teh Chang (wtc at google dot com)
|
|
||||||
- Yang Zhang (yang dot zhang at arm dot com)
|
- Yang Zhang (yang dot zhang at arm dot com)
|
||||||
- Yannis Guyon (yguyon at google dot com)
|
|
||||||
- Zhi An Ng (zhin at chromium dot org)
|
|
||||||
|
|||||||
42
Android.mk
42
Android.mk
@@ -11,36 +11,16 @@ ifeq ($(APP_OPTIM),release)
|
|||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# mips32 fails to build with clang from r14b
|
|
||||||
# https://bugs.chromium.org/p/webp/issues/detail?id=343
|
|
||||||
ifeq ($(findstring clang,$(NDK_TOOLCHAIN_VERSION)),clang)
|
|
||||||
ifeq ($(TARGET_ARCH),mips)
|
|
||||||
clang_version := $(shell $(TARGET_CC) --version)
|
|
||||||
ifneq ($(findstring clang version 3,$(clang_version)),)
|
|
||||||
WEBP_CFLAGS += -no-integrated-as
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifneq ($(findstring armeabi-v7a, $(TARGET_ARCH_ABI)),)
|
ifneq ($(findstring armeabi-v7a, $(TARGET_ARCH_ABI)),)
|
||||||
# Setting LOCAL_ARM_NEON will enable -mfpu=neon which may cause illegal
|
# Setting LOCAL_ARM_NEON will enable -mfpu=neon which may cause illegal
|
||||||
# instructions to be generated for armv7a code. Instead target the neon code
|
# instructions to be generated for armv7a code. Instead target the neon code
|
||||||
# specifically.
|
# specifically.
|
||||||
NEON := c.neon
|
NEON := c.neon
|
||||||
USE_CPUFEATURES := yes
|
USE_CPUFEATURES := yes
|
||||||
WEBP_CFLAGS += -DHAVE_CPU_FEATURES_H
|
|
||||||
else
|
else
|
||||||
NEON := c
|
NEON := c
|
||||||
endif
|
endif
|
||||||
|
|
||||||
sharpyuv_srcs := \
|
|
||||||
sharpyuv/sharpyuv.c \
|
|
||||||
sharpyuv/sharpyuv_csp.c \
|
|
||||||
sharpyuv/sharpyuv_dsp.c \
|
|
||||||
sharpyuv/sharpyuv_gamma.c \
|
|
||||||
sharpyuv/sharpyuv_neon.$(NEON) \
|
|
||||||
sharpyuv/sharpyuv_sse2.c \
|
|
||||||
|
|
||||||
dec_srcs := \
|
dec_srcs := \
|
||||||
src/dec/alpha_dec.c \
|
src/dec/alpha_dec.c \
|
||||||
src/dec/buffer_dec.c \
|
src/dec/buffer_dec.c \
|
||||||
@@ -63,6 +43,9 @@ dsp_dec_srcs := \
|
|||||||
src/dsp/alpha_processing_neon.$(NEON) \
|
src/dsp/alpha_processing_neon.$(NEON) \
|
||||||
src/dsp/alpha_processing_sse2.c \
|
src/dsp/alpha_processing_sse2.c \
|
||||||
src/dsp/alpha_processing_sse41.c \
|
src/dsp/alpha_processing_sse41.c \
|
||||||
|
src/dsp/argb.c \
|
||||||
|
src/dsp/argb_mips_dsp_r2.c \
|
||||||
|
src/dsp/argb_sse2.c \
|
||||||
src/dsp/cpu.c \
|
src/dsp/cpu.c \
|
||||||
src/dsp/dec.c \
|
src/dsp/dec.c \
|
||||||
src/dsp/dec_clip_tables.c \
|
src/dsp/dec_clip_tables.c \
|
||||||
@@ -82,7 +65,6 @@ dsp_dec_srcs := \
|
|||||||
src/dsp/lossless_msa.c \
|
src/dsp/lossless_msa.c \
|
||||||
src/dsp/lossless_neon.$(NEON) \
|
src/dsp/lossless_neon.$(NEON) \
|
||||||
src/dsp/lossless_sse2.c \
|
src/dsp/lossless_sse2.c \
|
||||||
src/dsp/lossless_sse41.c \
|
|
||||||
src/dsp/rescaler.c \
|
src/dsp/rescaler.c \
|
||||||
src/dsp/rescaler_mips32.c \
|
src/dsp/rescaler_mips32.c \
|
||||||
src/dsp/rescaler_mips_dsp_r2.c \
|
src/dsp/rescaler_mips_dsp_r2.c \
|
||||||
@@ -94,21 +76,18 @@ dsp_dec_srcs := \
|
|||||||
src/dsp/upsampling_msa.c \
|
src/dsp/upsampling_msa.c \
|
||||||
src/dsp/upsampling_neon.$(NEON) \
|
src/dsp/upsampling_neon.$(NEON) \
|
||||||
src/dsp/upsampling_sse2.c \
|
src/dsp/upsampling_sse2.c \
|
||||||
src/dsp/upsampling_sse41.c \
|
|
||||||
src/dsp/yuv.c \
|
src/dsp/yuv.c \
|
||||||
src/dsp/yuv_mips32.c \
|
src/dsp/yuv_mips32.c \
|
||||||
src/dsp/yuv_mips_dsp_r2.c \
|
src/dsp/yuv_mips_dsp_r2.c \
|
||||||
src/dsp/yuv_neon.$(NEON) \
|
|
||||||
src/dsp/yuv_sse2.c \
|
src/dsp/yuv_sse2.c \
|
||||||
src/dsp/yuv_sse41.c \
|
|
||||||
|
|
||||||
dsp_enc_srcs := \
|
dsp_enc_srcs := \
|
||||||
src/dsp/cost.c \
|
src/dsp/cost.c \
|
||||||
src/dsp/cost_mips32.c \
|
src/dsp/cost_mips32.c \
|
||||||
src/dsp/cost_mips_dsp_r2.c \
|
src/dsp/cost_mips_dsp_r2.c \
|
||||||
src/dsp/cost_neon.$(NEON) \
|
|
||||||
src/dsp/cost_sse2.c \
|
src/dsp/cost_sse2.c \
|
||||||
src/dsp/enc.c \
|
src/dsp/enc.c \
|
||||||
|
src/dsp/enc_avx2.c \
|
||||||
src/dsp/enc_mips32.c \
|
src/dsp/enc_mips32.c \
|
||||||
src/dsp/enc_mips_dsp_r2.c \
|
src/dsp/enc_mips_dsp_r2.c \
|
||||||
src/dsp/enc_msa.c \
|
src/dsp/enc_msa.c \
|
||||||
@@ -122,16 +101,14 @@ dsp_enc_srcs := \
|
|||||||
src/dsp/lossless_enc_neon.$(NEON) \
|
src/dsp/lossless_enc_neon.$(NEON) \
|
||||||
src/dsp/lossless_enc_sse2.c \
|
src/dsp/lossless_enc_sse2.c \
|
||||||
src/dsp/lossless_enc_sse41.c \
|
src/dsp/lossless_enc_sse41.c \
|
||||||
src/dsp/ssim.c \
|
|
||||||
src/dsp/ssim_sse2.c \
|
|
||||||
|
|
||||||
enc_srcs := \
|
enc_srcs := \
|
||||||
src/enc/alpha_enc.c \
|
src/enc/alpha_enc.c \
|
||||||
src/enc/analysis_enc.c \
|
src/enc/analysis_enc.c \
|
||||||
src/enc/backward_references_cost_enc.c \
|
|
||||||
src/enc/backward_references_enc.c \
|
src/enc/backward_references_enc.c \
|
||||||
src/enc/config_enc.c \
|
src/enc/config_enc.c \
|
||||||
src/enc/cost_enc.c \
|
src/enc/cost_enc.c \
|
||||||
|
src/enc/delta_palettization_enc.c \
|
||||||
src/enc/filter_enc.c \
|
src/enc/filter_enc.c \
|
||||||
src/enc/frame_enc.c \
|
src/enc/frame_enc.c \
|
||||||
src/enc/histogram_enc.c \
|
src/enc/histogram_enc.c \
|
||||||
@@ -183,7 +160,7 @@ LOCAL_SRC_FILES := \
|
|||||||
$(utils_dec_srcs) \
|
$(utils_dec_srcs) \
|
||||||
|
|
||||||
LOCAL_CFLAGS := $(WEBP_CFLAGS)
|
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
|
# prefer arm over thumb mode for performance gains
|
||||||
LOCAL_ARM_MODE := arm
|
LOCAL_ARM_MODE := arm
|
||||||
@@ -212,13 +189,12 @@ endif # ENABLE_SHARED=1
|
|||||||
include $(CLEAR_VARS)
|
include $(CLEAR_VARS)
|
||||||
|
|
||||||
LOCAL_SRC_FILES := \
|
LOCAL_SRC_FILES := \
|
||||||
$(sharpyuv_srcs) \
|
|
||||||
$(dsp_enc_srcs) \
|
$(dsp_enc_srcs) \
|
||||||
$(enc_srcs) \
|
$(enc_srcs) \
|
||||||
$(utils_enc_srcs) \
|
$(utils_enc_srcs) \
|
||||||
|
|
||||||
LOCAL_CFLAGS := $(WEBP_CFLAGS)
|
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
|
# prefer arm over thumb mode for performance gains
|
||||||
LOCAL_ARM_MODE := arm
|
LOCAL_ARM_MODE := arm
|
||||||
@@ -241,7 +217,7 @@ include $(CLEAR_VARS)
|
|||||||
LOCAL_SRC_FILES := $(demux_srcs)
|
LOCAL_SRC_FILES := $(demux_srcs)
|
||||||
|
|
||||||
LOCAL_CFLAGS := $(WEBP_CFLAGS)
|
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
|
# prefer arm over thumb mode for performance gains
|
||||||
LOCAL_ARM_MODE := arm
|
LOCAL_ARM_MODE := arm
|
||||||
@@ -264,7 +240,7 @@ include $(CLEAR_VARS)
|
|||||||
LOCAL_SRC_FILES := $(mux_srcs)
|
LOCAL_SRC_FILES := $(mux_srcs)
|
||||||
|
|
||||||
LOCAL_CFLAGS := $(WEBP_CFLAGS)
|
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
|
# prefer arm over thumb mode for performance gains
|
||||||
LOCAL_ARM_MODE := arm
|
LOCAL_ARM_MODE := arm
|
||||||
|
|||||||
821
CMakeLists.txt
821
CMakeLists.txt
@@ -1,780 +1,189 @@
|
|||||||
# Copyright (c) 2020 Google LLC.
|
cmake_minimum_required(VERSION 2.8.7)
|
||||||
#
|
|
||||||
# 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 3.7)
|
project(libwebp C)
|
||||||
|
|
||||||
if(POLICY CMP0072)
|
|
||||||
cmake_policy(SET CMP0072 NEW)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
project(WebP C)
|
|
||||||
|
|
||||||
# Options for coder / decoder executables.
|
# Options for coder / decoder executables.
|
||||||
if(BUILD_SHARED_LIBS)
|
option(WEBP_BUILD_CWEBP "Build the cwebp command line tool." OFF)
|
||||||
set(WEBP_LINK_STATIC_DEFAULT OFF)
|
option(WEBP_BUILD_DWEBP "Build the dwebp command line tool." OFF)
|
||||||
else()
|
option(WEBP_BUILD_GIF2WEBP "Build the gif2webp conversion tool." OFF)
|
||||||
set(WEBP_LINK_STATIC_DEFAULT ON)
|
option(WEBP_BUILD_IMG2WEBP "Build the img2webp animation tool." OFF)
|
||||||
endif()
|
option(WEBP_EXPERIMENTAL_FEATURES "Build with experimental features." OFF)
|
||||||
option(WEBP_LINK_STATIC
|
option(WEBP_ENABLE_SWAP_16BIT_CSP "Enable byte swap for 16 bit colorspaces." OFF)
|
||||||
"Link using static libraries. If OFF, use dynamic libraries."
|
|
||||||
${WEBP_LINK_STATIC_DEFAULT})
|
|
||||||
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_LIBWEBPMUX "Build the libwebpmux library." 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_USE_THREAD "Enable threading support" ON)
|
|
||||||
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)
|
|
||||||
|
|
||||||
if(WEBP_LINK_STATIC)
|
|
||||||
if(WIN32)
|
|
||||||
SET(CMAKE_FIND_LIBRARY_SUFFIXES .lib .a ${CMAKE_FIND_LIBRARY_SUFFIXES})
|
|
||||||
else()
|
|
||||||
SET(CMAKE_FIND_LIBRARY_SUFFIXES .a ${CMAKE_FIND_LIBRARY_SUFFIXES})
|
|
||||||
endif()
|
|
||||||
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
|
||||||
# vwebp does not compile on Ubuntu with static libraries so disabling it for
|
|
||||||
# now.
|
|
||||||
set(WEBP_BUILD_VWEBP OFF)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# 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)
|
|
||||||
set(WEBP_USE_THREAD OFF)
|
|
||||||
|
|
||||||
if(WEBP_ENABLE_SIMD)
|
|
||||||
message("wasm2js does not support SIMD, disabling webp.js generation.")
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
set(WEBP_DEP_LIBRARIES)
|
set(WEBP_DEP_LIBRARIES)
|
||||||
set(WEBP_DEP_INCLUDE_DIRS)
|
set(WEBP_DEP_INCLUDE_DIRS)
|
||||||
|
|
||||||
if(NOT CMAKE_BUILD_TYPE)
|
if(NOT CMAKE_BUILD_TYPE)
|
||||||
set(CMAKE_BUILD_TYPE "Release"
|
set(CMAKE_BUILD_TYPE "Release" CACHE
|
||||||
CACHE STRING "Build type: Release, Debug, MinSizeRel or RelWithDebInfo"
|
"Build type: Release, Debug or RelWithDebInfo" STRING FORCE
|
||||||
FORCE)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Include dependencies.
|
include(cmake/config.h.cmake)
|
||||||
include(cmake/deps.cmake)
|
|
||||||
include(GNUInstallDirs)
|
|
||||||
|
|
||||||
# ##############################################################################
|
################################################################################
|
||||||
# Options.
|
# Options.
|
||||||
if(WEBP_ENABLE_SWAP_16BIT_CSP)
|
if(WEBP_ENABLE_SWAP_16BIT_CSP)
|
||||||
add_definitions(-DWEBP_SWAP_16BIT_CSP=1)
|
add_definitions(-DWEBP_SWAP_16BIT_CSP)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
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)
|
|
||||||
|
|
||||||
set(CMAKE_C_VISIBILITY_PRESET hidden)
|
|
||||||
|
|
||||||
# ##############################################################################
|
|
||||||
# Android only.
|
# Android only.
|
||||||
if(ANDROID)
|
if(ANDROID)
|
||||||
include_directories(${ANDROID_NDK}/sources/android/cpufeatures)
|
include_directories(${ANDROID_NDK}/sources/android/cpufeatures)
|
||||||
add_library(cpufeatures STATIC
|
add_library(cpufeatures STATIC
|
||||||
${ANDROID_NDK}/sources/android/cpufeatures/cpu-features.c)
|
${ANDROID_NDK}/sources/android/cpufeatures/cpu-features.c
|
||||||
list(APPEND INSTALLED_LIBRARIES cpufeatures)
|
)
|
||||||
target_link_libraries(cpufeatures dl)
|
target_link_libraries(cpufeatures dl)
|
||||||
set(WEBP_DEP_LIBRARIES ${WEBP_DEP_LIBRARIES} cpufeatures)
|
set(WEBP_DEP_LIBRARIES ${WEBP_DEP_LIBRARIES} cpufeatures)
|
||||||
set(WEBP_DEP_INCLUDE_DIRS ${WEBP_DEP_INCLUDE_DIRS}
|
set(WEBP_DEP_INCLUDE_DIRS ${WEBP_DEP_INCLUDE_DIRS}
|
||||||
${ANDROID_NDK}/sources/android/cpufeatures)
|
${ANDROID_NDK}/sources/android/cpufeatures
|
||||||
add_definitions(-DHAVE_CPU_FEATURES_H=1)
|
)
|
||||||
set(HAVE_CPU_FEATURES_H 1)
|
|
||||||
else()
|
|
||||||
set(HAVE_CPU_FEATURES_H 0)
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
function(configure_pkg_config FILE)
|
################################################################################
|
||||||
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/${FILE}.in"
|
# WebP source files.
|
||||||
"${CMAKE_CURRENT_BINARY_DIR}/${FILE}")
|
# Read the Makefile.am to get the source files.
|
||||||
|
|
||||||
if(HAVE_MATH_LIBRARY)
|
function(parse_Makefile_am FOLDER VAR)
|
||||||
# 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)
|
|
||||||
file(READ ${FOLDER}/Makefile.am MAKEFILE_AM)
|
file(READ ${FOLDER}/Makefile.am MAKEFILE_AM)
|
||||||
string(REGEX MATCHALL
|
string(REGEX MATCHALL "_SOURCES \\+= [^\n]*"
|
||||||
"${SRC_REGEX}_SOURCES[ ]*\\+?=[ ]+[0-9a-z\\._ ]*"
|
FILES_PER_LINE ${MAKEFILE_AM}
|
||||||
FILES_PER_LINE
|
)
|
||||||
${MAKEFILE_AM})
|
|
||||||
set(SRCS ${${VAR}})
|
set(SRCS ${${VAR}})
|
||||||
foreach(FILES ${FILES_PER_LINE})
|
foreach(FILES ${FILES_PER_LINE})
|
||||||
string(FIND ${FILES} "=" OFFSET)
|
string(SUBSTRING ${FILES} 12 -1 FILES)
|
||||||
math(EXPR OFFSET "${OFFSET} + 2")
|
string(REGEX MATCHALL "[0-9a-z\\._]+"
|
||||||
string(SUBSTRING ${FILES}
|
FILES ${FILES}
|
||||||
${OFFSET}
|
)
|
||||||
-1
|
foreach(FILE ${FILES})
|
||||||
FILES)
|
list(APPEND SRCS ${FOLDER}/${FILE})
|
||||||
if(FILES)
|
endforeach()
|
||||||
string(REGEX MATCHALL
|
|
||||||
"[0-9a-z\\._]+"
|
|
||||||
FILES
|
|
||||||
${FILES})
|
|
||||||
foreach(FILE ${FILES})
|
|
||||||
list(APPEND SRCS ${FOLDER}/${FILE})
|
|
||||||
endforeach()
|
|
||||||
endif()
|
|
||||||
endforeach()
|
endforeach()
|
||||||
set(${VAR} ${SRCS} PARENT_SCOPE)
|
set(${VAR} ${SRCS} PARENT_SCOPE)
|
||||||
endfunction()
|
endfunction()
|
||||||
|
|
||||||
set(WEBP_SRC_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src)
|
set(WEBP_SRCS)
|
||||||
parse_makefile_am(${WEBP_SRC_DIR}/dec "WEBP_DEC_SRCS" "")
|
parse_Makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/src/dec "WEBP_SRCS")
|
||||||
parse_makefile_am(${WEBP_SRC_DIR}/demux "WEBP_DEMUX_SRCS" "")
|
parse_Makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/src/demux "WEBP_SRCS")
|
||||||
parse_makefile_am(${WEBP_SRC_DIR}/dsp "WEBP_DSP_COMMON_SRCS" "COMMON")
|
parse_Makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/src/dsp "WEBP_SRCS")
|
||||||
parse_makefile_am(${WEBP_SRC_DIR}/dsp "WEBP_DSP_ENC_SRCS" "ENC")
|
parse_Makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/src/enc "WEBP_SRCS")
|
||||||
parse_makefile_am(${WEBP_SRC_DIR}/dsp "WEBP_DSP_ENC_SRCS" "dsp_[^ ]*")
|
parse_Makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/src/utils "WEBP_SRCS")
|
||||||
parse_makefile_am(${WEBP_SRC_DIR}/dsp "WEBP_DSP_DEC_SRCS" "decode_[^ ]*")
|
|
||||||
parse_makefile_am(${WEBP_SRC_DIR}/enc "WEBP_ENC_SRCS" "")
|
|
||||||
parse_makefile_am(${WEBP_SRC_DIR}/utils "WEBP_UTILS_COMMON_SRCS" "COMMON")
|
|
||||||
parse_makefile_am(${WEBP_SRC_DIR}/utils "WEBP_UTILS_ENC_SRCS" "ENC")
|
|
||||||
parse_makefile_am(${WEBP_SRC_DIR}/utils "WEBP_UTILS_DEC_SRCS" "decode_[^ ]*")
|
|
||||||
|
|
||||||
# Remove the files specific to SIMD we don't use.
|
# Remove the files specific to SIMD we don't use.
|
||||||
foreach(FILE ${WEBP_SIMD_FILES_NOT_TO_INCLUDE})
|
foreach(FILE ${WEBP_SIMD_FILES_NOT_TO_INCLUDE})
|
||||||
list(REMOVE_ITEM WEBP_DSP_ENC_SRCS ${FILE})
|
list(REMOVE_ITEM WEBP_SRCS ${FILE})
|
||||||
list(REMOVE_ITEM WEBP_DSP_DEC_SRCS ${FILE})
|
|
||||||
endforeach()
|
endforeach()
|
||||||
|
|
||||||
# Generate the config.h file.
|
# Build the library.
|
||||||
configure_file(${CMAKE_CURRENT_LIST_DIR}/cmake/config.h.in
|
add_definitions(-Wall)
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/src/webp/config.h)
|
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/src/ ${WEBP_DEP_INCLUDE_DIRS})
|
||||||
add_definitions(-DHAVE_CONFIG_H)
|
add_library(webp ${WEBP_SRCS})
|
||||||
|
|
||||||
# ##############################################################################
|
|
||||||
# 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()
|
|
||||||
|
|
||||||
parse_makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/sharpyuv "WEBP_SHARPYUV_SRCS"
|
|
||||||
"")
|
|
||||||
add_library(sharpyuv OBJECT ${WEBP_SHARPYUV_SRCS})
|
|
||||||
target_include_directories(sharpyuv
|
|
||||||
PRIVATE ${CMAKE_CURRENT_BINARY_DIR}
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR})
|
|
||||||
set_target_properties(
|
|
||||||
sharpyuv
|
|
||||||
PROPERTIES PUBLIC_HEADER "${CMAKE_CURRENT_SOURCE_DIR}/sharpyuv/sharpyuv.h;\
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/sharpyuv/sharpyuv_csp.h;\
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/src/webp/types.h")
|
|
||||||
|
|
||||||
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:sharpyuv>
|
|
||||||
$<TARGET_OBJECTS:webpdecode>
|
|
||||||
$<TARGET_OBJECTS:webpdsp>
|
|
||||||
$<TARGET_OBJECTS:webpencode>
|
|
||||||
$<TARGET_OBJECTS:webputils>)
|
|
||||||
if(XCODE)
|
|
||||||
libwebp_add_stub_file(webp)
|
|
||||||
endif()
|
|
||||||
target_link_libraries(webp ${WEBP_DEP_LIBRARIES})
|
target_link_libraries(webp ${WEBP_DEP_LIBRARIES})
|
||||||
target_include_directories(
|
|
||||||
webp
|
|
||||||
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
|
|
||||||
${CMAKE_CURRENT_BINARY_DIR}
|
|
||||||
PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>
|
|
||||||
$<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
|
# Change the compile flags for SIMD files we use.
|
||||||
# not ON by default).
|
|
||||||
set_target_properties(sharpyuv
|
|
||||||
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.
|
|
||||||
macro(set_version FILE TARGET_NAME NAME_IN_MAKEFILE)
|
|
||||||
file(READ ${CMAKE_CURRENT_SOURCE_DIR}/src/${FILE} SOURCE_FILE)
|
|
||||||
string(REGEX MATCH
|
|
||||||
"${NAME_IN_MAKEFILE}_la_LDFLAGS[^\n]* -version-info [0-9:]+"
|
|
||||||
TMP
|
|
||||||
${SOURCE_FILE})
|
|
||||||
string(REGEX MATCH
|
|
||||||
"[0-9:]+"
|
|
||||||
TMP
|
|
||||||
${TMP})
|
|
||||||
string(REGEX
|
|
||||||
REPLACE ":"
|
|
||||||
" "
|
|
||||||
LT_VERSION
|
|
||||||
${TMP})
|
|
||||||
|
|
||||||
# See the libtool docs for more information:
|
|
||||||
# https://www.gnu.org/software/libtool/manual/libtool.html#Updating-version-info
|
|
||||||
#
|
|
||||||
# c=<current>, a=<age>, r=<revision>
|
|
||||||
#
|
|
||||||
# libtool generates a .so file as .so.[c-a].a.r, while -version-info c:r:a is
|
|
||||||
# passed to libtool.
|
|
||||||
#
|
|
||||||
# We set FULL = [c-a].a.r and MAJOR = [c-a].
|
|
||||||
separate_arguments(LT_VERSION)
|
|
||||||
list(GET LT_VERSION 0 LT_CURRENT)
|
|
||||||
list(GET LT_VERSION 1 LT_REVISION)
|
|
||||||
list(GET LT_VERSION 2 LT_AGE)
|
|
||||||
math(EXPR LT_CURRENT_MINUS_AGE "${LT_CURRENT} - ${LT_AGE}")
|
|
||||||
|
|
||||||
set_target_properties(
|
|
||||||
${TARGET_NAME}
|
|
||||||
PROPERTIES VERSION
|
|
||||||
${LT_CURRENT_MINUS_AGE}.${LT_AGE}.${LT_REVISION}
|
|
||||||
SOVERSION
|
|
||||||
${LT_CURRENT_MINUS_AGE})
|
|
||||||
endmacro()
|
|
||||||
set_version(Makefile.am webp webp)
|
|
||||||
set_version(Makefile.am webpdecoder webpdecoder)
|
|
||||||
set_version(demux/Makefile.am webpdemux webpdemux)
|
|
||||||
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.
|
|
||||||
list(LENGTH WEBP_SIMD_FILES_TO_INCLUDE WEBP_SIMD_FILES_TO_INCLUDE_LENGTH)
|
list(LENGTH WEBP_SIMD_FILES_TO_INCLUDE WEBP_SIMD_FILES_TO_INCLUDE_LENGTH)
|
||||||
math(EXPR WEBP_SIMD_FILES_TO_INCLUDE_RANGE
|
math(EXPR WEBP_SIMD_FILES_TO_INCLUDE_RANGE
|
||||||
"${WEBP_SIMD_FILES_TO_INCLUDE_LENGTH}-1")
|
"${WEBP_SIMD_FILES_TO_INCLUDE_LENGTH}-1"
|
||||||
|
)
|
||||||
|
|
||||||
foreach(I_FILE RANGE ${WEBP_SIMD_FILES_TO_INCLUDE_RANGE})
|
foreach(I_FILE RANGE ${WEBP_SIMD_FILES_TO_INCLUDE_RANGE})
|
||||||
list(GET WEBP_SIMD_FILES_TO_INCLUDE ${I_FILE} FILE)
|
list(GET WEBP_SIMD_FILES_TO_INCLUDE ${I_FILE} FILE)
|
||||||
list(GET WEBP_SIMD_FLAGS_TO_INCLUDE ${I_FILE} SIMD_COMPILE_FLAG)
|
list(GET WEBP_SIMD_FLAGS_TO_INCLUDE ${I_FILE} SIMD_COMPILE_FLAG)
|
||||||
set_source_files_properties(${FILE}
|
set_source_files_properties(${FILE} PROPERTIES
|
||||||
PROPERTIES
|
COMPILE_FLAGS ${SIMD_COMPILE_FLAG}
|
||||||
COMPILE_FLAGS
|
)
|
||||||
${SIMD_COMPILE_FLAG})
|
|
||||||
endforeach()
|
endforeach()
|
||||||
|
|
||||||
if(NOT WEBP_BUILD_LIBWEBPMUX)
|
|
||||||
set(WEBP_BUILD_GIF2WEBP OFF)
|
|
||||||
set(WEBP_BUILD_IMG2WEBP OFF)
|
|
||||||
set(WEBP_BUILD_WEBPMUX OFF)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
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.
|
# Build the executables if asked for.
|
||||||
if(WEBP_BUILD_ANIM_UTILS
|
if(WEBP_BUILD_CWEBP OR WEBP_BUILD_DWEBP OR
|
||||||
OR WEBP_BUILD_CWEBP
|
WEBP_BUILD_GIF2WEBP OR WEBP_BUILD_IMG2WEBP)
|
||||||
OR WEBP_BUILD_DWEBP
|
|
||||||
OR WEBP_BUILD_GIF2WEBP
|
|
||||||
OR WEBP_BUILD_IMG2WEBP
|
|
||||||
OR WEBP_BUILD_VWEBP
|
|
||||||
OR WEBP_BUILD_WEBPMUX
|
|
||||||
OR WEBP_BUILD_WEBPINFO)
|
|
||||||
# Example utility library.
|
# Example utility library.
|
||||||
parse_makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/examples "EXAMPLEUTIL_SRCS"
|
set(exampleutil_SRCS
|
||||||
"example_util_[^ ]*")
|
${CMAKE_CURRENT_SOURCE_DIR}/examples/stopwatch.h
|
||||||
list(APPEND EXAMPLEUTIL_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/examples/stopwatch.h)
|
${CMAKE_CURRENT_SOURCE_DIR}/examples/example_util.c
|
||||||
add_library(exampleutil STATIC ${EXAMPLEUTIL_SRCS})
|
${CMAKE_CURRENT_SOURCE_DIR}/examples/example_util.h)
|
||||||
target_include_directories(
|
add_library(exampleutil ${exampleutil_SRCS})
|
||||||
exampleutil
|
target_link_libraries(exampleutil webp ${WEBP_DEP_LIBRARIES})
|
||||||
PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>)
|
|
||||||
|
|
||||||
parse_makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/imageio "IMAGEIOUTILS_SRCS"
|
set(imageioutil_SRCS
|
||||||
"imageio_util_[^ ]*")
|
${CMAKE_CURRENT_SOURCE_DIR}/imageio/imageio_util.c
|
||||||
add_library(imageioutil STATIC ${IMAGEIOUTILS_SRCS})
|
${CMAKE_CURRENT_SOURCE_DIR}/imageio/imageio_util.h)
|
||||||
target_link_libraries(imageioutil webp)
|
add_library(imageioutil ${imageioutil_SRCS})
|
||||||
target_link_libraries(exampleutil imageioutil)
|
target_link_libraries(imageioutil ${WEBP_DEP_LIBRARIES})
|
||||||
|
|
||||||
# Image-decoding utility library.
|
# Image-decoding utility library.
|
||||||
parse_makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/imageio "IMAGEDEC_SRCS"
|
set(imagedec_SRCS
|
||||||
"imagedec_[^ ]*")
|
${CMAKE_CURRENT_SOURCE_DIR}/examples/gifdec.c
|
||||||
add_library(imagedec STATIC ${IMAGEDEC_SRCS})
|
${CMAKE_CURRENT_SOURCE_DIR}/examples/gifdec.h
|
||||||
target_link_libraries(imagedec
|
${CMAKE_CURRENT_SOURCE_DIR}/imageio/image_dec.c
|
||||||
imageioutil
|
${CMAKE_CURRENT_SOURCE_DIR}/imageio/image_dec.h
|
||||||
webpdemux
|
${CMAKE_CURRENT_SOURCE_DIR}/imageio/jpegdec.c
|
||||||
webp
|
${CMAKE_CURRENT_SOURCE_DIR}/imageio/jpegdec.h
|
||||||
${WEBP_DEP_IMG_LIBRARIES})
|
${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.
|
# Image-encoding utility library.
|
||||||
parse_makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/imageio "IMAGEENC_SRCS"
|
set(imageenc_SRCS
|
||||||
"imageenc_[^ ]*")
|
${CMAKE_CURRENT_SOURCE_DIR}/imageio/image_enc.c
|
||||||
add_library(imageenc STATIC ${IMAGEENC_SRCS})
|
${CMAKE_CURRENT_SOURCE_DIR}/imageio/image_enc.h)
|
||||||
target_link_libraries(imageenc imageioutil webp)
|
add_library(imageenc ${imageenc_SRCS})
|
||||||
|
target_link_libraries(imageenc webp imageioutil
|
||||||
set_property(TARGET exampleutil
|
${WEBP_DEP_LIBRARIES} ${WEBP_DEP_IMG_LIBRARIES})
|
||||||
imageioutil
|
|
||||||
imagedec
|
|
||||||
imageenc
|
|
||||||
PROPERTY INCLUDE_DIRECTORIES ${CMAKE_CURRENT_SOURCE_DIR}/src
|
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/src)
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(WEBP_BUILD_DWEBP)
|
if(WEBP_BUILD_DWEBP)
|
||||||
# dwebp
|
# dwebp
|
||||||
parse_makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/examples "DWEBP_SRCS" "dwebp")
|
include_directories(${WEBP_DEP_IMG_INCLUDE_DIRS})
|
||||||
add_executable(dwebp ${DWEBP_SRCS})
|
add_executable(dwebp
|
||||||
target_link_libraries(dwebp exampleutil imagedec imageenc)
|
${CMAKE_CURRENT_SOURCE_DIR}/examples/dwebp.c
|
||||||
target_include_directories(dwebp PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/src)
|
${CMAKE_CURRENT_SOURCE_DIR}/examples/stopwatch.h)
|
||||||
install(TARGETS dwebp RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
|
target_link_libraries(dwebp imagedec imageenc webp
|
||||||
|
exampleutil imageioutil
|
||||||
|
${WEBP_DEP_LIBRARIES} ${WEBP_DEP_IMG_LIBRARIES}
|
||||||
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(WEBP_BUILD_CWEBP)
|
if(WEBP_BUILD_CWEBP)
|
||||||
# cwebp
|
# cwebp
|
||||||
parse_makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/examples "CWEBP_SRCS" "cwebp")
|
include_directories(${WEBP_DEP_IMG_INCLUDE_DIRS})
|
||||||
add_executable(cwebp ${CWEBP_SRCS})
|
add_executable(cwebp
|
||||||
target_link_libraries(cwebp exampleutil imagedec webp)
|
${CMAKE_CURRENT_SOURCE_DIR}/examples/cwebp.c
|
||||||
target_include_directories(cwebp PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/src)
|
${CMAKE_CURRENT_SOURCE_DIR}/examples/stopwatch.h)
|
||||||
install(TARGETS cwebp RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
|
target_link_libraries(cwebp imagedec webp exampleutil imageioutil
|
||||||
endif()
|
${WEBP_DEP_LIBRARIES} ${WEBP_DEP_IMG_LIBRARIES}
|
||||||
|
)
|
||||||
if(WEBP_BUILD_LIBWEBPMUX)
|
|
||||||
parse_makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/src/mux "WEBP_MUX_SRCS" "")
|
|
||||||
add_library(webpmux ${WEBP_MUX_SRCS})
|
|
||||||
target_link_libraries(webpmux webp)
|
|
||||||
target_include_directories(webpmux
|
|
||||||
PRIVATE ${CMAKE_CURRENT_BINARY_DIR}
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR})
|
|
||||||
set_version(mux/Makefile.am webpmux webpmux)
|
|
||||||
set_target_properties(webpmux
|
|
||||||
PROPERTIES PUBLIC_HEADER
|
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}/src/webp/mux.h;\
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/src/webp/mux_types.h;\
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/src/webp/types.h;")
|
|
||||||
list(APPEND INSTALLED_LIBRARIES webpmux)
|
|
||||||
configure_pkg_config("src/mux/libwebpmux.pc")
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(WEBP_BUILD_GIF2WEBP)
|
if(WEBP_BUILD_GIF2WEBP)
|
||||||
# gif2webp
|
# gif2webp
|
||||||
include_directories(${WEBP_DEP_GIF_INCLUDE_DIRS})
|
include_directories(${WEBP_DEP_IMG_INCLUDE_DIRS})
|
||||||
parse_makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/examples "GIF2WEBP_SRCS"
|
set(GIF2WEBP_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/examples/gif2webp.c)
|
||||||
"gif2webp")
|
parse_Makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/src/mux "GIF2WEBP_SRCS")
|
||||||
add_executable(gif2webp ${GIF2WEBP_SRCS})
|
add_executable(gif2webp ${GIF2WEBP_SRCS})
|
||||||
target_link_libraries(gif2webp
|
target_link_libraries(gif2webp imagedec webp exampleutil imageioutil
|
||||||
exampleutil
|
${WEBP_DEP_LIBRARIES} ${WEBP_DEP_IMG_LIBRARIES}
|
||||||
imageioutil
|
)
|
||||||
webp
|
|
||||||
webpmux
|
|
||||||
${WEBP_DEP_GIF_LIBRARIES})
|
|
||||||
target_include_directories(gif2webp PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/src)
|
|
||||||
install(TARGETS gif2webp RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(WEBP_BUILD_IMG2WEBP)
|
if(WEBP_BUILD_IMG2WEBP)
|
||||||
# img2webp
|
# img2webp
|
||||||
include_directories(${WEBP_DEP_IMG_INCLUDE_DIRS})
|
include_directories(${WEBP_DEP_IMG_INCLUDE_DIRS})
|
||||||
parse_makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/examples "IMG2WEBP_SRCS"
|
set(IMG2WEBP_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/examples/img2webp.c)
|
||||||
"img2webp")
|
parse_Makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/src/mux "IMG2WEBP_SRCS")
|
||||||
add_executable(img2webp ${IMG2WEBP_SRCS})
|
add_executable(img2webp ${IMG2WEBP_SRCS})
|
||||||
target_link_libraries(img2webp
|
target_link_libraries(img2webp imagedec webp exampleutil imageioutil
|
||||||
exampleutil
|
${WEBP_DEP_LIBRARIES} ${WEBP_DEP_IMG_LIBRARIES}
|
||||||
imagedec
|
)
|
||||||
imageioutil
|
|
||||||
webp
|
|
||||||
webpmux)
|
|
||||||
target_include_directories(img2webp PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/src)
|
|
||||||
install(TARGETS img2webp RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
|
|
||||||
endif()
|
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
|
|
||||||
${CMAKE_CURRENT_SOURCE_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_app ${WEBPMUX_SRCS})
|
|
||||||
set_target_properties(webpmux_app PROPERTIES OUTPUT_NAME webpmux)
|
|
||||||
target_link_libraries(webpmux_app exampleutil imageioutil webpmux webp)
|
|
||||||
target_include_directories(webpmux_app
|
|
||||||
PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/src)
|
|
||||||
install(TARGETS webpmux_app RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
|
|
||||||
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")
|
|
||||||
|
|
||||||
# libextras
|
|
||||||
add_library(extras STATIC ${WEBP_EXTRAS_SRCS})
|
|
||||||
target_include_directories(extras
|
|
||||||
PRIVATE ${CMAKE_CURRENT_BINARY_DIR}
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/src)
|
|
||||||
|
|
||||||
# get_disto
|
|
||||||
add_executable(get_disto ${GET_DISTO_SRCS})
|
|
||||||
target_link_libraries(get_disto imagedec)
|
|
||||||
target_include_directories(get_disto
|
|
||||||
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
|
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/src)
|
|
||||||
|
|
||||||
# webp_quality
|
|
||||||
add_executable(webp_quality ${WEBP_QUALITY_SRCS})
|
|
||||||
target_link_libraries(webp_quality exampleutil imagedec extras)
|
|
||||||
target_include_directories(webp_quality
|
|
||||||
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
|
|
||||||
${CMAKE_CURRENT_BINARY_DIR})
|
|
||||||
|
|
||||||
# vwebp_sdl
|
|
||||||
find_package(SDL)
|
|
||||||
if(WEBP_BUILD_VWEBP AND SDL_FOUND)
|
|
||||||
add_executable(vwebp_sdl ${VWEBP_SDL_SRCS})
|
|
||||||
target_link_libraries(vwebp_sdl ${SDL_LIBRARY} imageioutil webp)
|
|
||||||
target_include_directories(vwebp_sdl
|
|
||||||
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
|
|
||||||
${CMAKE_CURRENT_BINARY_DIR}
|
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/src
|
|
||||||
${SDL_INCLUDE_DIR})
|
|
||||||
set(WEBP_HAVE_SDL 1)
|
|
||||||
target_compile_definitions(vwebp_sdl PUBLIC WEBP_HAVE_SDL)
|
|
||||||
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 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 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
|
|
||||||
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
|
|
||||||
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()
|
|
||||||
|
|||||||
@@ -1,29 +0,0 @@
|
|||||||
# How to Contribute
|
|
||||||
|
|
||||||
We'd love to accept your patches and contributions to this project. There are
|
|
||||||
just a few small guidelines you need to follow.
|
|
||||||
|
|
||||||
## Contributor License Agreement
|
|
||||||
|
|
||||||
Contributions to this project must be accompanied by a Contributor License
|
|
||||||
Agreement. You (or your employer) retain the copyright to your contribution;
|
|
||||||
this simply gives us permission to use and redistribute your contributions as
|
|
||||||
part of the project. Head over to <https://cla.developers.google.com/> to see
|
|
||||||
your current agreements on file or to sign a new one.
|
|
||||||
|
|
||||||
You generally only need to submit a CLA once, so if you've already submitted one
|
|
||||||
(even if it was for a different project), you probably don't need to do it
|
|
||||||
again.
|
|
||||||
|
|
||||||
## Code reviews
|
|
||||||
|
|
||||||
All submissions, including submissions by project members, require review. We
|
|
||||||
use a [Gerrit](https://www.gerritcodereview.com) instance hosted at
|
|
||||||
https://chromium-review.googlesource.com for this purpose. See the
|
|
||||||
[WebM Project page](https://www.webmproject.org/code/contribute/submitting-patches/)
|
|
||||||
for additional details.
|
|
||||||
|
|
||||||
## Community Guidelines
|
|
||||||
|
|
||||||
This project follows
|
|
||||||
[Google's Open Source Community Guidelines](https://opensource.google.com/conduct/).
|
|
||||||
928
ChangeLog
928
ChangeLog
@@ -1,925 +1,9 @@
|
|||||||
56a480e8 dsp/cpu.h: add missing extern "C"
|
|
||||||
62b45bdd update ChangeLog (tag: v1.2.3-rc1)
|
|
||||||
8764ec7a Merge changes Idb037953,Id582e395 into 1.2.3
|
|
||||||
bcb872c3 vwebp: fix file name display in windows unicode build
|
|
||||||
67c44ac5 webpmux: fix -frame option in windows unicode build
|
|
||||||
8278825a makefile.unix: add sharpyuv objects to clean target
|
|
||||||
14a49e01 update NEWS
|
|
||||||
34b1dc33 bump version to 1.2.3
|
|
||||||
0b397fda update AUTHORS
|
|
||||||
c16488ac update .mailmap
|
|
||||||
5a2d929c Merge "unicode.h: set console mode before using wprintf" into main
|
|
||||||
169f867f unicode.h: set console mode before using wprintf
|
|
||||||
a94b855c Merge "libsharpyuv: add version defines" into main
|
|
||||||
f83bdb52 libsharpyuv: add version defines
|
|
||||||
bef0d797 unicode_gif.h: fix -Wdeclaration-after-statement
|
|
||||||
404c1622 Rename Huffman coding to prefix coding in the bitstream spec
|
|
||||||
8895f8a3 Merge "run_static_analysis.sh: fix scan-build archive path" into main
|
|
||||||
92a673d2 Merge "Add -fvisibility=hidden flag in CMakeLists." into main
|
|
||||||
67c1d722 Merge "add WEBP_MSAN" into main
|
|
||||||
1124ff66 Add -fvisibility=hidden flag in CMakeLists.
|
|
||||||
e15b3560 add WEBP_MSAN
|
|
||||||
ec9e782a sharpyuv: remove minimum image size from sharpyuv library
|
|
||||||
7bd07f3b run_static_analysis.sh: fix scan-build archive path
|
|
||||||
5ecee06f Merge "sharpyuv: increase precision of gamma<->linear conversion" into main
|
|
||||||
f81dd7d6 Merge changes I3d17d529,I53026880,I1bd61639,I6bd4b25d,Icfec8fba into main
|
|
||||||
2d607ee6 sharpyuv: increase precision of gamma<->linear conversion
|
|
||||||
266cbbc5 sharpyuv: add 32bit version of SharpYuvFilterRow.
|
|
||||||
9fc12274 CMake: add src to webpinfo includes
|
|
||||||
7d18f40a CMake: add WEBP_BUILD_WEBPINFO to list of checks for exampleutil
|
|
||||||
11309aa5 CMake: add WEBP_BUILD_WEBPMUX to list of checks for exampleutil
|
|
||||||
4bc762f7 CMake: link imageioutil to exampleutil after defined
|
|
||||||
0d1b9bc4 WEBP_DEP_LIBRARIES: use Threads::Threads
|
|
||||||
20ef48f0 Merge "sharpyuv: add support for 10/12/16 bit rgb and 10/12 bit yuv." into main
|
|
||||||
93c54371 sharpyuv: add support for 10/12/16 bit rgb and 10/12 bit yuv.
|
|
||||||
53cf2b49 normalize WebPValidatePicture declaration w/definition
|
|
||||||
d3006f4b sharpyuv: slightly improve precision
|
|
||||||
ea967098 Merge changes Ia01bd397,Ibf3771af into main
|
|
||||||
11bc8410 Merge changes I2d317c4b,I9e77f6db into main
|
|
||||||
30453ea4 Add an internal WebPValidatePicture.
|
|
||||||
6c43219a Some renamings for consistency.
|
|
||||||
4f59fa73 update .mailmap
|
|
||||||
e74f8a62 webp-lossless-bitstream-spec,cosmetics: normalize range syntax
|
|
||||||
5a709ec0 webp-lossless-bitstream-spec,cosmetics: fix code typo
|
|
||||||
a2093acc webp-lossless-bitstream-spec: add amendment note
|
|
||||||
86c66930 webp-lossless-bitstream-spec: fix BNF
|
|
||||||
232f22da webp-lossless-bitstream-spec: fix 'simple code' snippet
|
|
||||||
44dd765d webp-lossless-bitstream-spec: fix ColorTransform impl
|
|
||||||
7a7e33e9 webp-lossless-bitstream-spec: fix TR-pixel right border note
|
|
||||||
86f94ee0 Update lossless spec with Huffman codes.
|
|
||||||
a3927cc8 sharpyuv.c,cosmetics: fix indent
|
|
||||||
6c45cef7 Make sure the stride has a minimum value in the importer.
|
|
||||||
0c8b0e67 sharpyuv: cleanup/cosmetic changes
|
|
||||||
dc3841e0 {histogram,predictor}_enc: quiet int -> float warnings
|
|
||||||
a19a25bb Replace doubles by floats in lossless misc cost estimations.
|
|
||||||
42888f6c Add an option to enable static builds.
|
|
||||||
7efcf3cc Merge "Fix typo in color constants: Marix -> Matrix" into main
|
|
||||||
8f4b5c62 Fix typo in color constants: Marix -> Matrix
|
|
||||||
90084d84 Merge "demux,IsValidExtendedFormat: remove unused variable" into main
|
|
||||||
ed643f61 Merge changes I452d2485,Ic6d75475 into main
|
|
||||||
8fa053d1 Rename SharpYUV to SharpYuv for consistency.
|
|
||||||
99a87562 SharpYuvComputeConversionMatrix: quiet int->float warnings
|
|
||||||
deb426be Makefile.vc: add sharpyuv_csp.obj to SHARPYUV_OBJS
|
|
||||||
779597d4 demux,IsValidExtendedFormat: remove unused variable
|
|
||||||
40e8aa57 Merge "libsharpyuv: add colorspace utilities" into main
|
|
||||||
01a05de1 libsharpyuv: add colorspace utilities
|
|
||||||
2de4b05a Merge changes Id9890a60,I376d81e6,I1c958838 into main
|
|
||||||
b8bca81f Merge "configure.ac: use LT_INIT if available" into main
|
|
||||||
e8e77b9c Merge changes I479bc487,I39864691,I5d486c2c,I186d13be into main
|
|
||||||
7e7d5d50 Merge ".gitignore: add Android Studio & VS code dirs" into main
|
|
||||||
10c50848 normalize label indent
|
|
||||||
89f774e6 mux{edit,internal}: fix leaks on error
|
|
||||||
2d3293ad ExUtilInitCommandLineArguments: fix leak on error
|
|
||||||
ec34fd70 anim_util: fix leaks on error
|
|
||||||
e4717287 gif2webp: fix segfault on OOM
|
|
||||||
e3cfafaf GetBackwardReferences: fail on alloc error
|
|
||||||
a828a59b BackwardReferencesHashChainDistanceOnly: fix segfault on OOM
|
|
||||||
fe153fae VP8LEncodeStream: fix segfault on OOM
|
|
||||||
919acc0e .gitignore: add Android Studio & VS code dirs
|
|
||||||
efa0731b configure.ac: use LT_INIT if available
|
|
||||||
0957fd69 tiffdec: add grayscale support
|
|
||||||
e685feef Merge "Make libsharpyuv self-contained by removing dependency on cpu.c" into main
|
|
||||||
841960b6 Make libsharpyuv self-contained by removing dependency on cpu.c
|
|
||||||
617cf036 image_dec: add WebPGetEnabledInputFileFormats()
|
|
||||||
7a68afaa Let SharpArgbToYuv caller pass in an RGB>YUV conversion matrix.
|
|
||||||
34bb332c man/cwebp.1: add note about crop/resize order
|
|
||||||
f0e9351c webp-lossless-bitstream-spec,cosmetics: fix some typos
|
|
||||||
5ccbd6ed vp8l_dec.c,cosmetics: fix a few typos
|
|
||||||
c3d0c2d7 fix ios build scripts after sharpyuv dep added
|
|
||||||
d0d2292e Merge "Make libwebp depend on libsharpyuv." into main
|
|
||||||
03d12190 alpha_processing_neon.c: fix 0x01... typo
|
|
||||||
d55d447c Make libwebp depend on libsharpyuv.
|
|
||||||
e4cbcdd2 Fix lossless encoding for MIPS.
|
|
||||||
924e7ca6 alpha_processing_neon.c: fix Dispatch/ExtractAlpha_NEON
|
|
||||||
0fa0ea54 Makefile.vc: use /MANIFEST:EMBED
|
|
||||||
29cc95ce Basic version of libsharpyuv in libwebp, in C.
|
|
||||||
a30f2190 examples/webpmux.c: fix a couple of typos
|
|
||||||
66b3ce23 Fix bad overflow check in ReadTIFF()
|
|
||||||
54e61a38 Markdownify libwebp docs and reorganize them.
|
|
||||||
b4533deb CMakeLists.txt,cosmetics: break long line
|
|
||||||
b9d2f9cd quant_enc.c: use WEBP_RESTRICT qualifier
|
|
||||||
ec178f2c Add progress hook granularity in lossless
|
|
||||||
26139c73 Rename MAX_COST to MAX_BIT_COST in histogram_enc.c
|
|
||||||
13b82816 cmake: fix webpmux lib name for cmake linking
|
|
||||||
88b6a396 webp-container-spec.txt,cosmetics: normalize formatting
|
|
||||||
6f496540 Merge tag 'v1.2.2'
|
|
||||||
4074acf8 dsp.h: bump msvc arm64 version requirement to 16.6
|
|
||||||
b0a86089 update ChangeLog (tag: v1.2.2)
|
|
||||||
6db8248c libwebp: Fix VP8EncTokenLoop() progress
|
|
||||||
827a307f BMP enc: fix the transparency case
|
|
||||||
db25f1b4 libwebp: Fix VP8EncTokenLoop() progress
|
|
||||||
286e7fce libwebp: do not destroy jpeg codec twice on error
|
|
||||||
6e8a4126 libwebp: do not destroy jpeg codec twice on error
|
|
||||||
faf21968 Merge "BMP enc: fix the transparency case" into main
|
|
||||||
480cd51d BMP enc: fix the transparency case
|
|
||||||
9195ea05 update ChangeLog (tag: v1.2.2-rc2)
|
|
||||||
4acae017 update NEWS
|
|
||||||
883f0633 man/img2webp.1: update date
|
|
||||||
567e1f44 Reword img2webp synopsis command line
|
|
||||||
1b0c15db man/img2webp.1: update date
|
|
||||||
17bade38 Merge "Reword img2webp synopsis command line" into main
|
|
||||||
a80954a1 Reword img2webp synopsis command line
|
|
||||||
f084244d anim_decode: fix alpha blending with big-endian
|
|
||||||
b217b4ff webpinfo: fix fourcc comparison w/big-endian
|
|
||||||
ec497b75 Merge "anim_decode: fix alpha blending with big-endian" into main
|
|
||||||
e4886716 anim_decode: fix alpha blending with big-endian
|
|
||||||
e3cb052c webpinfo: fix fourcc comparison w/big-endian
|
|
||||||
a510fedb patch-check: detect duplicated files
|
|
||||||
f035d2e4 update ChangeLog (tag: v1.2.2-rc1)
|
|
||||||
7031946a update NEWS
|
|
||||||
973390b6 bump version to 1.2.2
|
|
||||||
abd6664f update AUTHORS
|
|
||||||
5b7e7930 Merge "add missing USE_{MSA,NEON} checks in headers" into main
|
|
||||||
02ca04c3 add missing USE_{MSA,NEON} checks in headers
|
|
||||||
e94716e2 xcframeworkbuild.sh: place headers in a subdir
|
|
||||||
c846efd8 patch-check: commit subject length check
|
|
||||||
b6f756e8 update http links
|
|
||||||
8f5cb4c1 update rfc links
|
|
||||||
8ea81561 change VP8LPredictorFunc signature to avoid reading 'left'
|
|
||||||
6b1d18c3 webpmux: fix the -bgcolor description
|
|
||||||
3368d876 Merge "webpmux: add "-set bgcolor A,R,G,B"" into main
|
|
||||||
f213abf6 webpinfo: print the number of warnings
|
|
||||||
50c97c30 webpmux: add "-set bgcolor A,R,G,B"
|
|
||||||
2c206aaf Remove CMakeLists.txt check in compile.sh
|
|
||||||
96e3dfef Merge "infra/common.sh: add shard_should_run()" into main
|
|
||||||
0e0f74b7 infra/common.sh: add shard_should_run()
|
|
||||||
35b7436a Jenkins scripts port: update shell function comments
|
|
||||||
21d24b4c webp-container-spec.txt: remove 'experimental' markers
|
|
||||||
cdcf8902 Merge "Port Jenkins script: compile" into main
|
|
||||||
dc683cde Jenkins scripts port: static analysis
|
|
||||||
0858494e Port Jenkins script: compile
|
|
||||||
c2cf6a93 Jenkins scripts port: android compilation
|
|
||||||
df0e808f presubmit: Add pylint-2.7 and .pylintrc
|
|
||||||
676c57db patch-check: shfmt
|
|
||||||
7bb7f747 patch-check: Add shellcheck
|
|
||||||
abcd1797 Reformat docstrings and imports
|
|
||||||
edaf0895 Port Jenkins scripts: compile js
|
|
||||||
b9622063 Set CheckPatchFormatted flags to fail on diffs
|
|
||||||
e23cd548 dsp.h: enable NEON w/VS2019+ ARM64 targets
|
|
||||||
3875c7de CMakeLists.txt: set minimum version to 3.7
|
|
||||||
1a8f0d45 Have a hard-coded value for memset in TrellisQuantizeBlock.
|
|
||||||
93480160 Speed up TrellisQuantizeBlock
|
|
||||||
45eaacc9 Convert deprecated uint32 to uint32_t.
|
|
||||||
42592af8 webp,cmake: Remove unnecessary include dirs
|
|
||||||
e298e05f Add patch-check steps in PRESUBMIT.py
|
|
||||||
29148919 Merge tag 'v1.2.1'
|
|
||||||
9ce5843d update ChangeLog (tag: v1.2.1)
|
|
||||||
d9191588 fuzzer/*: normalize src/ includes
|
|
||||||
c5bc3624 fuzzer/*: normalize src/ includes
|
|
||||||
53b6f762 fix indent
|
|
||||||
d2caaba4 fix indent
|
|
||||||
731246ba update ChangeLog (tag: v1.2.1-rc2)
|
|
||||||
d250f01d dsp/*: use WEBP_HAVE_* to determine Init availability
|
|
||||||
1fe31625 dsp/*: use WEBP_HAVE_* to determine Init availability
|
|
||||||
3a4d3ecd update NEWS
|
|
||||||
b2bc8093 bump version to 1.2.1
|
|
||||||
e542fc7a update AUTHORS
|
|
||||||
e0241154 Merge "libwebp/CMake: Add <BUILD_INTERFACE> to webp incl" into main
|
|
||||||
edea6444 libwebp/CMake: Add <BUILD_INTERFACE> to webp incl
|
|
||||||
ece18e55 dsp.h: respect --disable-sse2/sse4.1/neon
|
|
||||||
a89a3230 wicdec: support alpha from WebP WIC decoder
|
|
||||||
26f4aa01 Merge "alpha_processing: fix visual studio warnings" into main
|
|
||||||
8f594663 alpha_processing: fix visual studio warnings
|
|
||||||
46d844e6 Merge "cpu.cmake: fix compiler flag detection w/3.17.0+" into main
|
|
||||||
298d26ea Merge changes I593adf92,If20675e7,Ifac68eac into main
|
|
||||||
a1e5dae0 alpha_processing*: use WEBP_RESTRICT qualifier
|
|
||||||
327ef24f cpu.cmake: fix compiler flag detection w/3.17.0+
|
|
||||||
f70819de configure: enable libwebpmux by default
|
|
||||||
dc7e2b42 configure: add informational notices when disabling binaries
|
|
||||||
9df23ddd configure: move lib flag checks before binaries
|
|
||||||
a2e18f10 Merge "WebPConfig.config.in: correct WEBP_INCLUDE_DIRS" into main
|
|
||||||
e1a8d4f3 Merge "bit_reader_inl_utils: uniformly apply WEBP_RESTRICT" into main
|
|
||||||
4de35f43 rescaler.c: fix alignment
|
|
||||||
0f13eec7 bit_reader_inl_utils: uniformly apply WEBP_RESTRICT
|
|
||||||
277d3074 Fix size_t overflow in WebPRescalerInit
|
|
||||||
97adbba5 WebPConfig.config.in: correct WEBP_INCLUDE_DIRS
|
|
||||||
b60d4603 advanced_api_fuzzer: add extreme config value coverage
|
|
||||||
72fe52f6 anim_encode.c,cosmetics: normalize indent
|
|
||||||
116d235c anim_encode: Fix encoded_frames_[] overflow
|
|
||||||
6f445b3e CMake: set CMP0072 to NEW
|
|
||||||
b1cf887f define WEBP_RESTRICT for MSVC
|
|
||||||
3e265136 Add WEBP_RESTRICT & use it in VP8BitReader
|
|
||||||
f6d29247 vp8l_dec::ProcessRows: fix int overflow in multiply
|
|
||||||
de3b4ba8 CMake: add WEBP_BUILD_LIBWEBPMUX
|
|
||||||
7f09d3d1 CMakeLists.txt: rm libwebpmux dep from anim_{diff,dump}
|
|
||||||
4edea4a6 Init{RGB,YUV}Rescaler: fix a few more int overflows
|
|
||||||
c9e26bdb rescaler_utils: set max valid scaled w/h to INT_MAX/2
|
|
||||||
28d488e6 utils.h: add SizeOverflow()
|
|
||||||
695bdaa2 Export/EmitRescaledRowsRGBA: fix pointer offset int overflow
|
|
||||||
685d073e Init{RGB,YUV}Rescaler: fix int overflows in multiplication
|
|
||||||
d38bd0dd WebPFlipBuffer: fix integer overflow
|
|
||||||
109ff0f1 utils: allow MALLOC_LIMIT to indicate a max
|
|
||||||
a2fce867 WebPRescalerImportRowExpand_C: promote some vals before multiply
|
|
||||||
776983d4 AllocateBuffer: fix int multiplication overflow check
|
|
||||||
315abbd6 Merge "Revert "Do not use a palette for one color images.""
|
|
||||||
eae815d0 Merge changes Ica3bbf75,I82f82954
|
|
||||||
afbca5a1 Require Emscripten 2.0.18
|
|
||||||
3320416b CMakeLists,emscripten: use EXPORTED_RUNTIME_METHODS
|
|
||||||
29145ed6 Update README instructions for using Emscripten
|
|
||||||
1f579139 cosmetics: remove use of 'sanity' / 'master'
|
|
||||||
29b6129c WebPAnimEncoderNewInternal: remove some unnecessary inits
|
|
||||||
b60869a1 Revert "Do not use a palette for one color images."
|
|
||||||
6fb4cddc demux: move padded size calc post unpadded validation
|
|
||||||
05b72d42 vp8l_enc.c: normalize index types
|
|
||||||
b6513fba Do not use a palette for one color images.
|
|
||||||
98bbe35b Fix multi-threading with palettes.
|
|
||||||
b1674240 Add modified Zeng's method to palette sorting.
|
|
||||||
88c90c45 add CONTRIBUTING.md
|
|
||||||
6a9916d7 WebPRescalerInit: add missing int64_t promotion
|
|
||||||
b6cf52d5 WebPIoInitFromOptions: treat use_scaling as a bool
|
|
||||||
3b12b7f4 WebPIoInitFromOptions: treat use_cropping as a bool
|
|
||||||
595fa13f add WebPCheckCropDimensions()
|
|
||||||
8fdaecb0 Disable cross-color when palette is used.
|
|
||||||
8933bac2 WebPIoInitFromOptions: respect incoming bypass_filtering val
|
|
||||||
7d416ff0 webpdec,cosmetics: match error text to function call
|
|
||||||
ec6cfeb5 Fix typo on WebPPictureAlloc() in README
|
|
||||||
7e58a1a2 *.cmake: add license header
|
|
||||||
5651a6b2 cmake: fix .so versioning
|
|
||||||
25ae67b3 xcframeworkbuild.sh: add arm64 simulator target
|
|
||||||
5d4ee4c3 cosmetics: remove use of the term 'dummy'
|
|
||||||
01b38ee1 faster CollectColorXXXTransforms_SSE41
|
|
||||||
652aa344 Merge "Use BitCtz for FastSLog2Slow_C"
|
|
||||||
0320e1e3 add the missing default BitsCtz() code
|
|
||||||
8886f620 Use BitCtz for FastSLog2Slow_C
|
|
||||||
fae41617 faster CombinedShannonEntropy_SSE2
|
|
||||||
5bd2704e Introduce the BitCtz() function.
|
|
||||||
fee64287 Merge "wicdec,icc: treat unsupported op as non-fatal"
|
|
||||||
33ddb894 lossless_sse{2,41}: remove some unneeded includes
|
|
||||||
b27ea852 wicdec,icc: treat unsupported op as non-fatal
|
|
||||||
b78494a9 Merge "Fix undefined signed shift."
|
|
||||||
e79974cd Fix undefined signed shift.
|
|
||||||
a8853394 SSE4.1 versions of BGRA to RGB/BGR color-space conversions
|
|
||||||
a09a6472 SSE4.1 version of TransformColorInverse
|
|
||||||
401da22b Merge "pngdec: check version before using png_get_chunk_malloc_max"
|
|
||||||
26907822 pngdec: check version before using png_get_chunk_malloc_max
|
|
||||||
06c1e72e Code cleanup
|
|
||||||
8f0d41aa Merge changes Id135bbf4,I99e59797
|
|
||||||
373eb170 gif2webp: don't store loop-count if there's only 1 frame
|
|
||||||
759b9d5a cmake: add WEBP_USE_THREAD option
|
|
||||||
926ce921 cmake: don't install binaries from extras/
|
|
||||||
9c367bc6 WebPAnimDecoderNewInternal: validate bitstream before alloc
|
|
||||||
47f64f6e filters_sse2: import Chromium change
|
|
||||||
cc3577e9 fuzzer/*: use src/ based include paths
|
|
||||||
004d77ff Merge tag 'v1.2.0'
|
|
||||||
fedac6cc update ChangeLog (tag: v1.2.0-rc3, tag: v1.2.0)
|
|
||||||
170a8712 Fix check_c_source_compiles with pthread.
|
|
||||||
ceddb5fc Fix check_c_source_compiles with pthread.
|
|
||||||
85995719 disable CombinedShannonEntropy_SSE2 on x86
|
|
||||||
289757fe TiffDec: enforce stricter mem/dimension limit on tiles
|
|
||||||
8af7436f Merge "{ios,xcframework}build.sh: make min version(s) more visible" into 1.2.0
|
|
||||||
e56c3c5b pngdec: raise memory limit if needed
|
|
||||||
8696147d 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
|
|
||||||
8df77fb1 animdecoder_fuzzer: fix memory leak
|
|
||||||
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)
|
|
||||||
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
|
20a7fea0 extras/Makefile.am: fix libwebpextras.la reference
|
||||||
415f3ffe update ChangeLog (tag: v0.6.0-rc3)
|
415f3ffe update ChangeLog (tag: v0.6.0-rc3)
|
||||||
3c6d1224 update NEWS
|
3c6d1224 update NEWS
|
||||||
ee4a4141 update AUTHORS
|
ee4a4141 update AUTHORS
|
||||||
32ed856f Fix "all|no frames are keyframes" settings.
|
32ed856f Fix "all|no frames are keyframes" settings.
|
||||||
1c3190b6 Merge "Fix "all|no frames are keyframes" settings."
|
|
||||||
f4dc56fd disable GradientUnfilter_NEON
|
f4dc56fd disable GradientUnfilter_NEON
|
||||||
4f3e3bbd disable GradientUnfilter_NEON
|
|
||||||
2dc0bdca Fix "all|no frames are keyframes" settings.
|
|
||||||
0d8e0588 img2webp: treat -loop as a no-op w/single images
|
0d8e0588 img2webp: treat -loop as a no-op w/single images
|
||||||
b0450139 ReadImage(): restore size reporting
|
b0450139 ReadImage(): restore size reporting
|
||||||
0ad3b4ef update ChangeLog (tag: v0.6.0-rc2)
|
0ad3b4ef update ChangeLog (tag: v0.6.0-rc2)
|
||||||
@@ -987,7 +71,7 @@ b016cb91 NEON: faster fancy upsampling
|
|||||||
f04eb376 Merge tag 'v0.5.2'
|
f04eb376 Merge tag 'v0.5.2'
|
||||||
341d711c NEON: 5% faster conversion to RGB565 and RGBA4444
|
341d711c NEON: 5% faster conversion to RGB565 and RGBA4444
|
||||||
abb54827 remove Clang warnings with unused arch arguments.
|
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
|
aa7744ca anim_util: quiet implicit conv warnings in 32-bit
|
||||||
d9120271 jpegdec: correct ContextFill signature
|
d9120271 jpegdec: correct ContextFill signature
|
||||||
24eb3940 Remove some errors when compiling the code as C++.
|
24eb3940 Remove some errors when compiling the code as C++.
|
||||||
@@ -1274,7 +358,7 @@ bbb6ecd9 Merge "Add MSA optimized distortion functions"
|
|||||||
c0991a14 io,EmitRescaledAlphaYUV: factor out a common expr
|
c0991a14 io,EmitRescaledAlphaYUV: factor out a common expr
|
||||||
48bf5ed1 build.gradle: remove tab
|
48bf5ed1 build.gradle: remove tab
|
||||||
bfef6c9f Merge tag 'v0.5.1'
|
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()
|
deb54d91 Clarify the expected 'config' lifespan in WebPIDecode()
|
||||||
435308e0 Add MSA optimized encoder transform functions
|
435308e0 Add MSA optimized encoder transform functions
|
||||||
dce64bfa Add MSA optimized alpha filter functions
|
dce64bfa Add MSA optimized alpha filter functions
|
||||||
@@ -1468,7 +552,7 @@ b74657fb configure: fix builtin detection w/-Werror
|
|||||||
6c1d7631 avoid Yoda style for comparison
|
6c1d7631 avoid Yoda style for comparison
|
||||||
8ce975ac SSE optimization for vector mismatch.
|
8ce975ac SSE optimization for vector mismatch.
|
||||||
7db53831 Merge tag 'v0.5.0'
|
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
|
7e7b6ccc faster rgb565/rgb4444/argb output
|
||||||
4c7f565f update NEWS
|
4c7f565f update NEWS
|
||||||
1f62b6b2 update AUTHORS
|
1f62b6b2 update AUTHORS
|
||||||
@@ -2252,7 +1336,7 @@ b5a36cc9 add -near_lossless [0..100] experimental option
|
|||||||
0524d9e5 dsp: detect mips64 & disable mips32 code
|
0524d9e5 dsp: detect mips64 & disable mips32 code
|
||||||
d3485d96 cwebp.1: fix quality description placement
|
d3485d96 cwebp.1: fix quality description placement
|
||||||
29a9fe22 Merge tag 'v0.4.1'
|
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.
|
e09e9ff6 Record & log the image pre-processing time.
|
||||||
f59c0b4b iosbuild.sh: specify optimization flags
|
f59c0b4b iosbuild.sh: specify optimization flags
|
||||||
8d34ea3e update ChangeLog (tag: v0.4.1-rc1)
|
8d34ea3e update ChangeLog (tag: v0.4.1-rc1)
|
||||||
@@ -2637,7 +1721,7 @@ ea59a8e9 Merge "Merge tag 'v0.4.0'"
|
|||||||
effcb0fd Merge tag 'v0.4.0'
|
effcb0fd Merge tag 'v0.4.0'
|
||||||
7c76255d autoconf: update ax_pthread.m4
|
7c76255d autoconf: update ax_pthread.m4
|
||||||
fff2a11b make -short work with -print_ssim, -print_psnr, etc.
|
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
|
256e4333 update NEWS description with new general features
|
||||||
29625340 Merge "gif2webp: don't use C99 %zu" into 0.4.0
|
29625340 Merge "gif2webp: don't use C99 %zu" into 0.4.0
|
||||||
3b9f9dd0 gif2webp: don't use C99 %zu
|
3b9f9dd0 gif2webp: don't use C99 %zu
|
||||||
@@ -3413,7 +2497,7 @@ a61a824b Merge "Add NULL check in chunk APIs"
|
|||||||
a0770727 mux struct naming
|
a0770727 mux struct naming
|
||||||
6c66dde8 Merge "Tune Lossless encoder"
|
6c66dde8 Merge "Tune Lossless encoder"
|
||||||
ab5ea217 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:
|
92f8059c Rename some chunks:
|
||||||
3bb4bbeb Merge "Mux API change:"
|
3bb4bbeb Merge "Mux API change:"
|
||||||
d0c79f05 Mux API change:
|
d0c79f05 Mux API change:
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
ACLOCAL_AMFLAGS = -I m4
|
ACLOCAL_AMFLAGS = -I m4
|
||||||
SUBDIRS = sharpyuv src imageio man
|
SUBDIRS = src imageio man
|
||||||
EXTRA_DIST = COPYING autogen.sh
|
EXTRA_DIST = COPYING autogen.sh
|
||||||
|
|
||||||
if BUILD_EXTRAS
|
if WANT_EXTRAS
|
||||||
SUBDIRS += extras
|
SUBDIRS += extras
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|||||||
108
Makefile.vc
108
Makefile.vc
@@ -28,14 +28,15 @@ PLATFORM_LDFLAGS = /SAFESEH
|
|||||||
|
|
||||||
NOLOGO = /nologo
|
NOLOGO = /nologo
|
||||||
CCNODBG = cl.exe $(NOLOGO) /O2 /DNDEBUG
|
CCNODBG = cl.exe $(NOLOGO) /O2 /DNDEBUG
|
||||||
CCDEBUG = cl.exe $(NOLOGO) /Od /Zi /D_DEBUG /RTC1
|
CCDEBUG = cl.exe $(NOLOGO) /Od /Gm /Zi /D_DEBUG /RTC1
|
||||||
CFLAGS = /I. /Isrc $(NOLOGO) /W3 /EHsc /c
|
CFLAGS = /Isrc $(NOLOGO) /W3 /EHsc /c
|
||||||
CFLAGS = $(CFLAGS) /DWIN32 /D_CRT_SECURE_NO_WARNINGS /DWIN32_LEAN_AND_MEAN
|
CFLAGS = $(CFLAGS) /DWIN32 /D_CRT_SECURE_NO_WARNINGS /DWIN32_LEAN_AND_MEAN
|
||||||
LDFLAGS = /LARGEADDRESSAWARE /MANIFEST:EMBED /NXCOMPAT /DYNAMICBASE
|
LDFLAGS = /LARGEADDRESSAWARE /MANIFEST /NXCOMPAT /DYNAMICBASE
|
||||||
LDFLAGS = $(LDFLAGS) $(PLATFORM_LDFLAGS)
|
LDFLAGS = $(LDFLAGS) $(PLATFORM_LDFLAGS)
|
||||||
LNKDLL = link.exe /DLL $(NOLOGO)
|
LNKDLL = link.exe /DLL $(NOLOGO)
|
||||||
LNKEXE = link.exe $(NOLOGO)
|
LNKEXE = link.exe $(NOLOGO)
|
||||||
LNKLIB = lib.exe $(NOLOGO)
|
LNKLIB = lib.exe $(NOLOGO)
|
||||||
|
MT = mt.exe $(NOLOGO)
|
||||||
RCNODBG = rc.exe $(NOLOGO) /l"0x0409" # 0x409 = U.S. English
|
RCNODBG = rc.exe $(NOLOGO) /l"0x0409" # 0x409 = U.S. English
|
||||||
RCDEBUG = $(RCNODBG) /D_DEBUG
|
RCDEBUG = $(RCNODBG) /D_DEBUG
|
||||||
|
|
||||||
@@ -52,6 +53,11 @@ OUTDIR = ..\obj\
|
|||||||
OUTDIR = $(OBJDIR)
|
OUTDIR = $(OBJDIR)
|
||||||
!ENDIF
|
!ENDIF
|
||||||
|
|
||||||
|
!IF "$(HAVE_AVX2)" == "1"
|
||||||
|
CFLAGS = $(CFLAGS) /DWEBP_HAVE_AVX2
|
||||||
|
AVX2_FLAGS = /arch:AVX2
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
##############################################################
|
##############################################################
|
||||||
# Runtime library configuration
|
# Runtime library configuration
|
||||||
!IF "$(RTLIBCFG)" == "static"
|
!IF "$(RTLIBCFG)" == "static"
|
||||||
@@ -81,7 +87,6 @@ OUTPUT_DIRS = $(DIRBIN) $(DIRINC) $(DIRLIB) \
|
|||||||
$(DIROBJ)\extras \
|
$(DIROBJ)\extras \
|
||||||
$(DIROBJ)\imageio \
|
$(DIROBJ)\imageio \
|
||||||
$(DIROBJ)\mux \
|
$(DIROBJ)\mux \
|
||||||
$(DIROBJ)\sharpyuv \
|
|
||||||
$(DIROBJ)\utils \
|
$(DIROBJ)\utils \
|
||||||
|
|
||||||
# Target configuration
|
# Target configuration
|
||||||
@@ -129,16 +134,12 @@ LIBWEBP_PDBNAME = $(DIROBJ)\$(LIBWEBP_BASENAME)_dll.pdb
|
|||||||
CFGSET = TRUE
|
CFGSET = TRUE
|
||||||
!ENDIF
|
!ENDIF
|
||||||
|
|
||||||
!IF "$(UNICODE)" == "1"
|
|
||||||
CFLAGS = $(CFLAGS) /D_UNICODE /DUNICODE
|
|
||||||
!ENDIF
|
|
||||||
|
|
||||||
#######################
|
#######################
|
||||||
# Usage
|
# Usage
|
||||||
#
|
#
|
||||||
!IF "$(CFGSET)" == "FALSE"
|
!IF "$(CFGSET)" == "FALSE"
|
||||||
!MESSAGE Usage: nmake /f Makefile.vc [CFG=<config>]
|
!MESSAGE Usage: nmake /f Makefile.vc [CFG=<config>]
|
||||||
!MESSAGE . [OBJDIR=<path>] [RTLIBCFG=<rtlib>] [UNICODE=1] [<target>]
|
!MESSAGE . [OBJDIR=<path>] [RTLIBCFG=<rtlib>] [<target>]
|
||||||
!MESSAGE
|
!MESSAGE
|
||||||
!MESSAGE where <config> is one of:
|
!MESSAGE where <config> is one of:
|
||||||
!MESSAGE - release-static - release static library
|
!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 - all - build (de)mux-based targets for CFG
|
||||||
!MESSAGE - gif2webp - requires libgif & >= VS2013
|
!MESSAGE - gif2webp - requires libgif & >= VS2013
|
||||||
!MESSAGE - anim_diff - requires libgif & >= VS2013
|
!MESSAGE - anim_diff - requires libgif & >= VS2013
|
||||||
!MESSAGE - anim_dump
|
|
||||||
!MESSAGE
|
!MESSAGE
|
||||||
!MESSAGE RTLIBCFG controls the runtime library linkage - 'static' or 'dynamic'.
|
!MESSAGE RTLIBCFG controls the runtime library linkage - 'static' or 'dynamic'.
|
||||||
!MESSAGE 'legacy' will produce a Windows 2000 compatible library.
|
!MESSAGE 'legacy' will produce a Windows 2000 compatible library.
|
||||||
@@ -174,14 +174,6 @@ CFLAGS = $(CFLAGS) /D_UNICODE /DUNICODE
|
|||||||
# A config was provided, so the library can be built.
|
# A config was provided, so the library can be built.
|
||||||
#
|
#
|
||||||
|
|
||||||
SHARPYUV_OBJS = \
|
|
||||||
$(DIROBJ)\sharpyuv\sharpyuv.obj \
|
|
||||||
$(DIROBJ)\sharpyuv\sharpyuv_csp.obj \
|
|
||||||
$(DIROBJ)\sharpyuv\sharpyuv_dsp.obj \
|
|
||||||
$(DIROBJ)\sharpyuv\sharpyuv_gamma.obj \
|
|
||||||
$(DIROBJ)\sharpyuv\sharpyuv_neon.obj \
|
|
||||||
$(DIROBJ)\sharpyuv\sharpyuv_sse2.obj \
|
|
||||||
|
|
||||||
DEC_OBJS = \
|
DEC_OBJS = \
|
||||||
$(DIROBJ)\dec\alpha_dec.obj \
|
$(DIROBJ)\dec\alpha_dec.obj \
|
||||||
$(DIROBJ)\dec\buffer_dec.obj \
|
$(DIROBJ)\dec\buffer_dec.obj \
|
||||||
@@ -223,7 +215,6 @@ DSP_DEC_OBJS = \
|
|||||||
$(DIROBJ)\dsp\lossless_msa.obj \
|
$(DIROBJ)\dsp\lossless_msa.obj \
|
||||||
$(DIROBJ)\dsp\lossless_neon.obj \
|
$(DIROBJ)\dsp\lossless_neon.obj \
|
||||||
$(DIROBJ)\dsp\lossless_sse2.obj \
|
$(DIROBJ)\dsp\lossless_sse2.obj \
|
||||||
$(DIROBJ)\dsp\lossless_sse41.obj \
|
|
||||||
$(DIROBJ)\dsp\rescaler.obj \
|
$(DIROBJ)\dsp\rescaler.obj \
|
||||||
$(DIROBJ)\dsp\rescaler_mips32.obj \
|
$(DIROBJ)\dsp\rescaler_mips32.obj \
|
||||||
$(DIROBJ)\dsp\rescaler_mips_dsp_r2.obj \
|
$(DIROBJ)\dsp\rescaler_mips_dsp_r2.obj \
|
||||||
@@ -235,21 +226,21 @@ DSP_DEC_OBJS = \
|
|||||||
$(DIROBJ)\dsp\upsampling_msa.obj \
|
$(DIROBJ)\dsp\upsampling_msa.obj \
|
||||||
$(DIROBJ)\dsp\upsampling_neon.obj \
|
$(DIROBJ)\dsp\upsampling_neon.obj \
|
||||||
$(DIROBJ)\dsp\upsampling_sse2.obj \
|
$(DIROBJ)\dsp\upsampling_sse2.obj \
|
||||||
$(DIROBJ)\dsp\upsampling_sse41.obj \
|
|
||||||
$(DIROBJ)\dsp\yuv.obj \
|
$(DIROBJ)\dsp\yuv.obj \
|
||||||
$(DIROBJ)\dsp\yuv_mips32.obj \
|
$(DIROBJ)\dsp\yuv_mips32.obj \
|
||||||
$(DIROBJ)\dsp\yuv_mips_dsp_r2.obj \
|
$(DIROBJ)\dsp\yuv_mips_dsp_r2.obj \
|
||||||
$(DIROBJ)\dsp\yuv_neon.obj \
|
|
||||||
$(DIROBJ)\dsp\yuv_sse2.obj \
|
$(DIROBJ)\dsp\yuv_sse2.obj \
|
||||||
$(DIROBJ)\dsp\yuv_sse41.obj \
|
|
||||||
|
|
||||||
DSP_ENC_OBJS = \
|
DSP_ENC_OBJS = \
|
||||||
|
$(DIROBJ)\dsp\argb.obj \
|
||||||
|
$(DIROBJ)\dsp\argb_mips_dsp_r2.obj \
|
||||||
|
$(DIROBJ)\dsp\argb_sse2.obj \
|
||||||
$(DIROBJ)\dsp\cost.obj \
|
$(DIROBJ)\dsp\cost.obj \
|
||||||
$(DIROBJ)\dsp\cost_mips32.obj \
|
$(DIROBJ)\dsp\cost_mips32.obj \
|
||||||
$(DIROBJ)\dsp\cost_mips_dsp_r2.obj \
|
$(DIROBJ)\dsp\cost_mips_dsp_r2.obj \
|
||||||
$(DIROBJ)\dsp\cost_neon.obj \
|
|
||||||
$(DIROBJ)\dsp\cost_sse2.obj \
|
$(DIROBJ)\dsp\cost_sse2.obj \
|
||||||
$(DIROBJ)\dsp\enc.obj \
|
$(DIROBJ)\dsp\enc.obj \
|
||||||
|
$(DIROBJ)\dsp\enc_avx2.obj \
|
||||||
$(DIROBJ)\dsp\enc_mips32.obj \
|
$(DIROBJ)\dsp\enc_mips32.obj \
|
||||||
$(DIROBJ)\dsp\enc_mips_dsp_r2.obj \
|
$(DIROBJ)\dsp\enc_mips_dsp_r2.obj \
|
||||||
$(DIROBJ)\dsp\enc_msa.obj \
|
$(DIROBJ)\dsp\enc_msa.obj \
|
||||||
@@ -263,8 +254,6 @@ DSP_ENC_OBJS = \
|
|||||||
$(DIROBJ)\dsp\lossless_enc_neon.obj \
|
$(DIROBJ)\dsp\lossless_enc_neon.obj \
|
||||||
$(DIROBJ)\dsp\lossless_enc_sse2.obj \
|
$(DIROBJ)\dsp\lossless_enc_sse2.obj \
|
||||||
$(DIROBJ)\dsp\lossless_enc_sse41.obj \
|
$(DIROBJ)\dsp\lossless_enc_sse41.obj \
|
||||||
$(DIROBJ)\dsp\ssim.obj \
|
|
||||||
$(DIROBJ)\dsp\ssim_sse2.obj \
|
|
||||||
|
|
||||||
EX_ANIM_UTIL_OBJS = \
|
EX_ANIM_UTIL_OBJS = \
|
||||||
$(DIROBJ)\examples\anim_util.obj \
|
$(DIROBJ)\examples\anim_util.obj \
|
||||||
@@ -274,7 +263,6 @@ IMAGEIO_DEC_OBJS = \
|
|||||||
$(DIROBJ)\imageio\jpegdec.obj \
|
$(DIROBJ)\imageio\jpegdec.obj \
|
||||||
$(DIROBJ)\imageio\metadata.obj \
|
$(DIROBJ)\imageio\metadata.obj \
|
||||||
$(DIROBJ)\imageio\pngdec.obj \
|
$(DIROBJ)\imageio\pngdec.obj \
|
||||||
$(DIROBJ)\imageio\pnmdec.obj \
|
|
||||||
$(DIROBJ)\imageio\tiffdec.obj \
|
$(DIROBJ)\imageio\tiffdec.obj \
|
||||||
$(DIROBJ)\imageio\webpdec.obj \
|
$(DIROBJ)\imageio\webpdec.obj \
|
||||||
$(DIROBJ)\imageio\wicdec.obj \
|
$(DIROBJ)\imageio\wicdec.obj \
|
||||||
@@ -291,10 +279,10 @@ EX_UTIL_OBJS = \
|
|||||||
ENC_OBJS = \
|
ENC_OBJS = \
|
||||||
$(DIROBJ)\enc\alpha_enc.obj \
|
$(DIROBJ)\enc\alpha_enc.obj \
|
||||||
$(DIROBJ)\enc\analysis_enc.obj \
|
$(DIROBJ)\enc\analysis_enc.obj \
|
||||||
$(DIROBJ)\enc\backward_references_cost_enc.obj \
|
|
||||||
$(DIROBJ)\enc\backward_references_enc.obj \
|
$(DIROBJ)\enc\backward_references_enc.obj \
|
||||||
$(DIROBJ)\enc\config_enc.obj \
|
$(DIROBJ)\enc\config_enc.obj \
|
||||||
$(DIROBJ)\enc\cost_enc.obj \
|
$(DIROBJ)\enc\cost_enc.obj \
|
||||||
|
$(DIROBJ)\enc\delta_palettization_enc.obj \
|
||||||
$(DIROBJ)\enc\filter_enc.obj \
|
$(DIROBJ)\enc\filter_enc.obj \
|
||||||
$(DIROBJ)\enc\frame_enc.obj \
|
$(DIROBJ)\enc\frame_enc.obj \
|
||||||
$(DIROBJ)\enc\histogram_enc.obj \
|
$(DIROBJ)\enc\histogram_enc.obj \
|
||||||
@@ -343,8 +331,8 @@ UTILS_ENC_OBJS = \
|
|||||||
$(DIROBJ)\utils\quant_levels_utils.obj \
|
$(DIROBJ)\utils\quant_levels_utils.obj \
|
||||||
|
|
||||||
LIBWEBPDECODER_OBJS = $(DEC_OBJS) $(DSP_DEC_OBJS) $(UTILS_DEC_OBJS)
|
LIBWEBPDECODER_OBJS = $(DEC_OBJS) $(DSP_DEC_OBJS) $(UTILS_DEC_OBJS)
|
||||||
LIBWEBP_OBJS = $(LIBWEBPDECODER_OBJS) $(SHARPYUV_OBJS) $(ENC_OBJS) \
|
LIBWEBP_OBJS = $(LIBWEBPDECODER_OBJS) $(ENC_OBJS) $(DSP_ENC_OBJS) \
|
||||||
$(DSP_ENC_OBJS) $(UTILS_ENC_OBJS) $(DLL_OBJS)
|
$(UTILS_ENC_OBJS) $(DLL_OBJS)
|
||||||
LIBWEBPMUX_OBJS = $(MUX_OBJS) $(LIBWEBPMUX_OBJS)
|
LIBWEBPMUX_OBJS = $(MUX_OBJS) $(LIBWEBPMUX_OBJS)
|
||||||
LIBWEBPDEMUX_OBJS = $(DEMUX_OBJS) $(LIBWEBPDEMUX_OBJS)
|
LIBWEBPDEMUX_OBJS = $(DEMUX_OBJS) $(LIBWEBPDEMUX_OBJS)
|
||||||
|
|
||||||
@@ -356,8 +344,7 @@ all: ex
|
|||||||
OUT_EXAMPLES = $(DIRBIN)\cwebp.exe $(DIRBIN)\dwebp.exe
|
OUT_EXAMPLES = $(DIRBIN)\cwebp.exe $(DIRBIN)\dwebp.exe
|
||||||
EXTRA_EXAMPLES = $(DIRBIN)\vwebp.exe $(DIRBIN)\webpmux.exe \
|
EXTRA_EXAMPLES = $(DIRBIN)\vwebp.exe $(DIRBIN)\webpmux.exe \
|
||||||
$(DIRBIN)\img2webp.exe $(DIRBIN)\get_disto.exe \
|
$(DIRBIN)\img2webp.exe $(DIRBIN)\get_disto.exe \
|
||||||
$(DIRBIN)\webp_quality.exe $(DIRBIN)\vwebp_sdl.exe \
|
$(DIRBIN)\webp_quality.exe
|
||||||
$(DIRBIN)\webpinfo.exe
|
|
||||||
|
|
||||||
ex: $(OUT_LIBS) $(OUT_EXAMPLES)
|
ex: $(OUT_LIBS) $(OUT_EXAMPLES)
|
||||||
all: ex $(EXTRA_EXAMPLES)
|
all: ex $(EXTRA_EXAMPLES)
|
||||||
@@ -365,58 +352,42 @@ all: ex $(EXTRA_EXAMPLES)
|
|||||||
# C99 support which is only available from VS2013 onward.
|
# C99 support which is only available from VS2013 onward.
|
||||||
gif2webp: $(DIRBIN)\gif2webp.exe
|
gif2webp: $(DIRBIN)\gif2webp.exe
|
||||||
anim_diff: $(DIRBIN)\anim_diff.exe
|
anim_diff: $(DIRBIN)\anim_diff.exe
|
||||||
anim_dump: $(DIRBIN)\anim_dump.exe
|
|
||||||
|
|
||||||
$(DIRBIN)\anim_diff.exe: $(DIROBJ)\examples\anim_diff.obj $(EX_ANIM_UTIL_OBJS)
|
$(DIRBIN)\anim_diff.exe: $(DIROBJ)\examples\anim_diff.obj $(EX_ANIM_UTIL_OBJS)
|
||||||
$(DIRBIN)\anim_diff.exe: $(EX_UTIL_OBJS) $(IMAGEIO_UTIL_OBJS)
|
$(DIRBIN)\anim_diff.exe: $(EX_UTIL_OBJS) $(IMAGEIO_UTIL_OBJS)
|
||||||
$(DIRBIN)\anim_diff.exe: $(EX_GIF_DEC_OBJS) $(LIBWEBPDEMUX) $(LIBWEBP)
|
$(DIRBIN)\anim_diff.exe: $(EX_GIF_DEC_OBJS) $(LIBWEBPDEMUX) $(LIBWEBP)
|
||||||
$(DIRBIN)\anim_dump.exe: $(DIROBJ)\examples\anim_dump.obj $(EX_ANIM_UTIL_OBJS)
|
|
||||||
$(DIRBIN)\anim_dump.exe: $(EX_UTIL_OBJS) $(IMAGEIO_UTIL_OBJS)
|
|
||||||
$(DIRBIN)\anim_dump.exe: $(EX_GIF_DEC_OBJS) $(LIBWEBPDEMUX) $(LIBWEBP)
|
|
||||||
$(DIRBIN)\anim_dump.exe: $(IMAGEIO_ENC_OBJS)
|
|
||||||
$(DIRBIN)\cwebp.exe: $(DIROBJ)\examples\cwebp.obj $(IMAGEIO_DEC_OBJS)
|
$(DIRBIN)\cwebp.exe: $(DIROBJ)\examples\cwebp.obj $(IMAGEIO_DEC_OBJS)
|
||||||
$(DIRBIN)\cwebp.exe: $(IMAGEIO_UTIL_OBJS)
|
$(DIRBIN)\cwebp.exe: $(IMAGEIO_UTIL_OBJS)
|
||||||
$(DIRBIN)\cwebp.exe: $(LIBWEBPDEMUX)
|
|
||||||
$(DIRBIN)\dwebp.exe: $(DIROBJ)\examples\dwebp.obj $(IMAGEIO_DEC_OBJS)
|
$(DIRBIN)\dwebp.exe: $(DIROBJ)\examples\dwebp.obj $(IMAGEIO_DEC_OBJS)
|
||||||
$(DIRBIN)\dwebp.exe: $(IMAGEIO_ENC_OBJS)
|
$(DIRBIN)\dwebp.exe: $(IMAGEIO_ENC_OBJS)
|
||||||
$(DIRBIN)\dwebp.exe: $(IMAGEIO_UTIL_OBJS)
|
$(DIRBIN)\dwebp.exe: $(IMAGEIO_UTIL_OBJS)
|
||||||
$(DIRBIN)\dwebp.exe: $(LIBWEBPDEMUX)
|
|
||||||
$(DIRBIN)\gif2webp.exe: $(DIROBJ)\examples\gif2webp.obj $(EX_GIF_DEC_OBJS)
|
$(DIRBIN)\gif2webp.exe: $(DIROBJ)\examples\gif2webp.obj $(EX_GIF_DEC_OBJS)
|
||||||
$(DIRBIN)\gif2webp.exe: $(EX_UTIL_OBJS) $(IMAGEIO_UTIL_OBJS) $(LIBWEBPMUX)
|
$(DIRBIN)\gif2webp.exe: $(EX_UTIL_OBJS) $(IMAGEIO_UTIL_OBJS) $(LIBWEBPMUX)
|
||||||
$(DIRBIN)\gif2webp.exe: $(LIBWEBP)
|
$(DIRBIN)\gif2webp.exe: $(LIBWEBP)
|
||||||
$(DIRBIN)\vwebp.exe: $(DIROBJ)\examples\vwebp.obj $(EX_UTIL_OBJS)
|
$(DIRBIN)\vwebp.exe: $(DIROBJ)\examples\vwebp.obj $(EX_UTIL_OBJS)
|
||||||
$(DIRBIN)\vwebp.exe: $(IMAGEIO_UTIL_OBJS) $(LIBWEBPDEMUX) $(LIBWEBP)
|
$(DIRBIN)\vwebp.exe: $(IMAGEIO_UTIL_OBJS) $(LIBWEBPDEMUX) $(LIBWEBP)
|
||||||
$(DIRBIN)\vwebp_sdl.exe: $(DIROBJ)\extras\vwebp_sdl.obj
|
|
||||||
$(DIRBIN)\vwebp_sdl.exe: $(DIROBJ)\extras\webp_to_sdl.obj
|
|
||||||
$(DIRBIN)\vwebp_sdl.exe: $(IMAGEIO_UTIL_OBJS) $(LIBWEBP)
|
|
||||||
$(DIRBIN)\webpmux.exe: $(DIROBJ)\examples\webpmux.obj $(LIBWEBPMUX)
|
$(DIRBIN)\webpmux.exe: $(DIROBJ)\examples\webpmux.obj $(LIBWEBPMUX)
|
||||||
$(DIRBIN)\webpmux.exe: $(EX_UTIL_OBJS) $(IMAGEIO_UTIL_OBJS) $(LIBWEBP)
|
$(DIRBIN)\webpmux.exe: $(EX_UTIL_OBJS) $(IMAGEIO_UTIL_OBJS) $(LIBWEBP)
|
||||||
$(DIRBIN)\img2webp.exe: $(DIROBJ)\examples\img2webp.obj $(LIBWEBPMUX)
|
$(DIRBIN)\img2webp.exe: $(DIROBJ)\examples\img2webp.obj $(LIBWEBPMUX)
|
||||||
$(DIRBIN)\img2webp.exe: $(IMAGEIO_DEC_OBJS)
|
$(DIRBIN)\img2webp.exe: $(IMAGEIO_DEC_OBJS)
|
||||||
$(DIRBIN)\img2webp.exe: $(EX_UTIL_OBJS) $(IMAGEIO_UTIL_OBJS)
|
$(DIRBIN)\img2webp.exe: $(EX_UTIL_OBJS) $(IMAGEIO_UTIL_OBJS) $(LIBWEBP)
|
||||||
$(DIRBIN)\img2webp.exe: $(LIBWEBPDEMUX) $(LIBWEBP)
|
|
||||||
$(DIRBIN)\get_disto.exe: $(DIROBJ)\extras\get_disto.obj
|
$(DIRBIN)\get_disto.exe: $(DIROBJ)\extras\get_disto.obj
|
||||||
$(DIRBIN)\get_disto.exe: $(IMAGEIO_DEC_OBJS) $(IMAGEIO_UTIL_OBJS)
|
$(DIRBIN)\get_disto.exe: $(IMAGEIO_DEC_OBJS) $(IMAGEIO_UTIL_OBJS) $(LIBWEBP)
|
||||||
$(DIRBIN)\get_disto.exe: $(LIBWEBPDEMUX) $(LIBWEBP)
|
|
||||||
$(DIRBIN)\webp_quality.exe: $(DIROBJ)\extras\webp_quality.obj
|
$(DIRBIN)\webp_quality.exe: $(DIROBJ)\extras\webp_quality.obj
|
||||||
$(DIRBIN)\webp_quality.exe: $(IMAGEIO_UTIL_OBJS)
|
$(DIRBIN)\webp_quality.exe: $(IMAGEIO_UTIL_OBJS)
|
||||||
$(DIRBIN)\webp_quality.exe: $(EXTRAS_OBJS)
|
$(DIRBIN)\webp_quality.exe: $(EXTRAS_OBJS) $(LIBWEBP)
|
||||||
# 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)
|
|
||||||
|
|
||||||
$(OUT_EXAMPLES): $(EX_UTIL_OBJS) $(LIBWEBP)
|
$(OUT_EXAMPLES): $(EX_UTIL_OBJS) $(LIBWEBP)
|
||||||
$(EX_UTIL_OBJS) $(IMAGEIO_UTIL_OBJS): $(OUTPUT_DIRS)
|
$(EX_UTIL_OBJS) $(IMAGEIO_UTIL_OBJS): $(OUTPUT_DIRS)
|
||||||
$(IMAGEIO_DEC_OBJS) $(IMAGEIO_ENC_OBJS) $(EXTRAS_OBJS): $(OUTPUT_DIRS)
|
$(IMAGEIO_DEC_OBJS) $(IMAGEIO_ENC_OBJS) $(EXTRAS_OBJS): $(OUTPUT_DIRS)
|
||||||
!ENDIF # ARCH == ARM
|
!ENDIF # ARCH == ARM
|
||||||
|
|
||||||
|
experimental:
|
||||||
|
$(MAKE) /f Makefile.vc \
|
||||||
|
CFG=$(CFG) \
|
||||||
|
CFLAGS="$(CFLAGS) /DWEBP_EXPERIMENTAL_FEATURES" /$(MAKEFLAGS)
|
||||||
|
|
||||||
$(LIBWEBPDECODER): $(LIBWEBPDECODER_OBJS)
|
$(LIBWEBPDECODER): $(LIBWEBPDECODER_OBJS)
|
||||||
$(LIBWEBP): $(LIBWEBP_OBJS)
|
$(LIBWEBP): $(LIBWEBP_OBJS)
|
||||||
$(LIBWEBPMUX): $(LIBWEBPMUX_OBJS)
|
$(LIBWEBPMUX): $(LIBWEBPMUX_OBJS)
|
||||||
@@ -462,18 +433,18 @@ $(OUTPUT_DIRS):
|
|||||||
$(DIROBJ)\$(DLLINC):
|
$(DIROBJ)\$(DLLINC):
|
||||||
@echo #ifndef WEBP_DLL_H_ > $@
|
@echo #ifndef WEBP_DLL_H_ > $@
|
||||||
@echo #define WEBP_DLL_H_ >> $@
|
@echo #define WEBP_DLL_H_ >> $@
|
||||||
@echo #define WEBP_EXTERN __declspec(dllexport) >> $@
|
@echo #define WEBP_EXTERN(type) __declspec(dllexport) type >> $@
|
||||||
@echo #endif /* WEBP_DLL_H_ */ >> $@
|
@echo #endif /* WEBP_DLL_H_ */ >> $@
|
||||||
|
|
||||||
.SUFFIXES: .c .obj .res .exe
|
.SUFFIXES: .c .obj .res .exe
|
||||||
# File-specific flag builds. Note batch rules take precedence over wildcards,
|
# File-specific flag builds. Note batch rules take precedence over wildcards,
|
||||||
# so for now name each file individually.
|
# 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
|
$(DIROBJ)\examples\anim_diff.obj: examples\anim_diff.c
|
||||||
$(CC) $(CFLAGS) /DWEBP_HAVE_GIF /Fd$(LIBWEBP_PDBNAME) \
|
$(CC) $(CFLAGS) /DWEBP_HAVE_GIF /Fd$(LIBWEBP_PDBNAME) \
|
||||||
/Fo$(DIROBJ)\examples\ examples\$(@B).c
|
/Fo$(DIROBJ)\examples\ examples\$(@B).c
|
||||||
$(DIROBJ)\examples\anim_dump.obj: examples\anim_dump.c
|
|
||||||
$(CC) $(CFLAGS) /DWEBP_HAVE_GIF /Fd$(LIBWEBP_PDBNAME) \
|
|
||||||
/Fo$(DIROBJ)\examples\ examples\$(@B).c
|
|
||||||
$(DIROBJ)\examples\anim_util.obj: examples\anim_util.c
|
$(DIROBJ)\examples\anim_util.obj: examples\anim_util.c
|
||||||
$(CC) $(CFLAGS) /DWEBP_HAVE_GIF /Fd$(LIBWEBP_PDBNAME) \
|
$(CC) $(CFLAGS) /DWEBP_HAVE_GIF /Fd$(LIBWEBP_PDBNAME) \
|
||||||
/Fo$(DIROBJ)\examples\ examples\$(@B).c
|
/Fo$(DIROBJ)\examples\ examples\$(@B).c
|
||||||
@@ -490,8 +461,6 @@ $(DIROBJ)\examples\gifdec.obj: examples\gifdec.c
|
|||||||
$(CC) $(CFLAGS) /Fd$(DIROBJ)\extras\ /Fo$(DIROBJ)\extras\ $<
|
$(CC) $(CFLAGS) /Fd$(DIROBJ)\extras\ /Fo$(DIROBJ)\extras\ $<
|
||||||
{imageio}.c{$(DIROBJ)\imageio}.obj::
|
{imageio}.c{$(DIROBJ)\imageio}.obj::
|
||||||
$(CC) $(CFLAGS) /Fd$(DIROBJ)\imageio\ /Fo$(DIROBJ)\imageio\ $<
|
$(CC) $(CFLAGS) /Fd$(DIROBJ)\imageio\ /Fo$(DIROBJ)\imageio\ $<
|
||||||
{sharpyuv}.c{$(DIROBJ)\sharpyuv}.obj::
|
|
||||||
$(CC) $(CFLAGS) /Fd$(DIROBJ)\sharpyuv\ /Fo$(DIROBJ)\sharpyuv\ $<
|
|
||||||
{src\dec}.c{$(DIROBJ)\dec}.obj::
|
{src\dec}.c{$(DIROBJ)\dec}.obj::
|
||||||
$(CC) $(CFLAGS) /Fd$(LIBWEBP_PDBNAME) /Fo$(DIROBJ)\dec\ $<
|
$(CC) $(CFLAGS) /Fd$(LIBWEBP_PDBNAME) /Fo$(DIROBJ)\dec\ $<
|
||||||
{src\demux}.c{$(DIROBJ)\demux}.obj::
|
{src\demux}.c{$(DIROBJ)\demux}.obj::
|
||||||
@@ -505,16 +474,17 @@ $(DIROBJ)\examples\gifdec.obj: examples\gifdec.c
|
|||||||
{src\utils}.c{$(DIROBJ)\utils}.obj::
|
{src\utils}.c{$(DIROBJ)\utils}.obj::
|
||||||
$(CC) $(CFLAGS) /Fd$(LIBWEBP_PDBNAME) /Fo$(DIROBJ)\utils\ $<
|
$(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:
|
{$(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:
|
{$(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
|
||||||
|
|
||||||
clean::
|
clean::
|
||||||
@-erase /s $(DIROBJ)\*.dll 2> NUL
|
@-erase /s $(DIROBJ)\*.dll 2> NUL
|
||||||
|
|||||||
106
NEWS
106
NEWS
@@ -1,109 +1,3 @@
|
|||||||
- 6/30/2022: version 1.2.3
|
|
||||||
This is a binary compatible release.
|
|
||||||
* security fix for lossless encoder (#565, chromium:1313709)
|
|
||||||
* improved progress granularity in WebPReportProgress() when using lossless
|
|
||||||
* improved precision in Sharp YUV (-sharp_yuv) conversion
|
|
||||||
* many corrections to webp-lossless-bitstream-spec.txt (#551)
|
|
||||||
* crash/leak fixes on error/OOM and other bug fixes (#558, #563, #569, #573)
|
|
||||||
|
|
||||||
- 1/11/2022: version 1.2.2
|
|
||||||
This is a binary compatible release.
|
|
||||||
* webpmux: add "-set bgcolor A,R,G,B"
|
|
||||||
* add ARM64 NEON support for MSVC builds (#539)
|
|
||||||
* fix duplicate include error in Xcode when using multiple XCFrameworks in a
|
|
||||||
project (#542)
|
|
||||||
* doc updates and bug fixes (#538, #544, #548, #550)
|
|
||||||
|
|
||||||
- 7/20/2021: version 1.2.1
|
|
||||||
This is a binary compatible release.
|
|
||||||
* minor lossless encoder improvements and x86 color conversion speed up
|
|
||||||
* add ARM64 simulator support to xcframeworkbuild.sh (#510)
|
|
||||||
* further security related hardening in libwebp & examples
|
|
||||||
(issues: #497, #508, #518)
|
|
||||||
(chromium: #1196480, #1196773, #1196775, #1196777, #1196778, #1196850)
|
|
||||||
(oss-fuzz: #28658, #28978)
|
|
||||||
* toolchain updates and bug fixes (#498, #501, #502, #504, #505, #506, #509,
|
|
||||||
#533)
|
|
||||||
* use more inclusive language within the source (#507)
|
|
||||||
|
|
||||||
- 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
|
- 1/26/2017: version 0.6.0
|
||||||
* lossless performance and compression improvements
|
* lossless performance and compression improvements
|
||||||
* miscellaneous performance improvements (SSE2, NEON, MSA)
|
* miscellaneous performance improvements (SSE2, NEON, MSA)
|
||||||
|
|||||||
245
PRESUBMIT.py
245
PRESUBMIT.py
@@ -1,245 +0,0 @@
|
|||||||
# Copyright (c) 2021, Google Inc. All rights reserved.
|
|
||||||
#
|
|
||||||
# Redistribution and use in source and binary forms, with or without
|
|
||||||
# modification, are permitted provided that the following conditions are
|
|
||||||
# met:
|
|
||||||
#
|
|
||||||
# * Redistributions of source code must retain the above copyright
|
|
||||||
# notice, this list of conditions and the following disclaimer.
|
|
||||||
#
|
|
||||||
# * Redistributions in binary form must reproduce the above copyright
|
|
||||||
# notice, this list of conditions and the following disclaimer in
|
|
||||||
# the documentation and/or other materials provided with the
|
|
||||||
# distribution.
|
|
||||||
#
|
|
||||||
# * Neither the name of Google nor the names of its contributors may
|
|
||||||
# be used to endorse or promote products derived from this software
|
|
||||||
# without specific prior written permission.
|
|
||||||
#
|
|
||||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
||||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
||||||
# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
||||||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
"""Top-level presubmit script for libwebp.
|
|
||||||
|
|
||||||
See https://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts for
|
|
||||||
details on the presubmit API built into depot_tools.
|
|
||||||
"""
|
|
||||||
|
|
||||||
import re
|
|
||||||
import subprocess2
|
|
||||||
|
|
||||||
USE_PYTHON3 = True
|
|
||||||
_BASH_INDENTATION = "2"
|
|
||||||
_GIT_COMMIT_SUBJECT_LENGTH = 65
|
|
||||||
_INCLUDE_BASH_FILES_ONLY = [r".*\.sh$"]
|
|
||||||
_INCLUDE_MAN_FILES_ONLY = [r"man/.+\.1$"]
|
|
||||||
_INCLUDE_SOURCE_FILES_ONLY = [r".*\.[ch]$"]
|
|
||||||
_LIBWEBP_MAX_LINE_LENGTH = 80
|
|
||||||
|
|
||||||
|
|
||||||
def _CheckCommitSubjectLength(input_api, output_api):
|
|
||||||
"""Ensures commit's subject length is no longer than 65 chars."""
|
|
||||||
name = "git-commit subject"
|
|
||||||
cmd = ["git", "log", "-1", "--pretty=%s"]
|
|
||||||
start = input_api.time.time()
|
|
||||||
proc = subprocess2.Popen(
|
|
||||||
cmd,
|
|
||||||
stderr=subprocess2.PIPE,
|
|
||||||
stdout=subprocess2.PIPE,
|
|
||||||
universal_newlines=True)
|
|
||||||
|
|
||||||
stdout, _ = proc.communicate()
|
|
||||||
duration = input_api.time.time() - start
|
|
||||||
|
|
||||||
if not re.match(r"^Revert",
|
|
||||||
stdout) and (len(stdout) - 1) > _GIT_COMMIT_SUBJECT_LENGTH:
|
|
||||||
failure_msg = (
|
|
||||||
"The commit subject: %s is too long (%d chars)\n"
|
|
||||||
"Try to keep this to 50 or less (up to 65 is permitted for "
|
|
||||||
"non-reverts).\n"
|
|
||||||
"https://www.git-scm.com/book/en/v2/Distributed-Git-Contributing-to-a-"
|
|
||||||
"Project#_commit_guidelines") % (stdout, len(stdout) - 1)
|
|
||||||
return output_api.PresubmitError("%s\n (%4.2fs) failed\n%s" %
|
|
||||||
(name, duration, failure_msg))
|
|
||||||
|
|
||||||
return output_api.PresubmitResult("%s\n (%4.2fs) success" % (name, duration))
|
|
||||||
|
|
||||||
|
|
||||||
def _CheckDuplicateFiles(input_api, output_api):
|
|
||||||
"""Ensures there are not repeated filenames."""
|
|
||||||
all_files = []
|
|
||||||
for f in input_api.change.AllFiles():
|
|
||||||
for include_file in _INCLUDE_SOURCE_FILES_ONLY:
|
|
||||||
if re.match(include_file, f):
|
|
||||||
all_files.append(f)
|
|
||||||
break
|
|
||||||
|
|
||||||
basename_to_path = {}
|
|
||||||
for f in all_files:
|
|
||||||
basename_file = input_api.basename(f)
|
|
||||||
if basename_file in basename_to_path:
|
|
||||||
basename_to_path[basename_file].append(f)
|
|
||||||
else:
|
|
||||||
basename_to_path[basename_file] = [f]
|
|
||||||
|
|
||||||
dupes = []
|
|
||||||
for files in basename_to_path.values():
|
|
||||||
if len(files) > 1:
|
|
||||||
dupes.extend(files)
|
|
||||||
|
|
||||||
if dupes:
|
|
||||||
return output_api.PresubmitError(
|
|
||||||
"Duplicate source files, rebase or rename some to make them unique:\n%s"
|
|
||||||
% dupes)
|
|
||||||
return output_api.PresubmitResult("No duplicates, success\n")
|
|
||||||
|
|
||||||
|
|
||||||
def _GetFilesToSkip(input_api):
|
|
||||||
return list(input_api.DEFAULT_FILES_TO_SKIP) + [
|
|
||||||
r"swig/.*\.py$",
|
|
||||||
r"\.pylintrc$",
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
def _RunManCmd(input_api, output_api, man_file):
|
|
||||||
"""man command wrapper."""
|
|
||||||
cmd = ["man", "--warnings", "-EUTF-8", "-l", "-Tutf8", "-Z", man_file]
|
|
||||||
name = "Check %s file." % man_file
|
|
||||||
start = input_api.time.time()
|
|
||||||
output, _ = subprocess2.communicate(
|
|
||||||
cmd, stdout=None, stderr=subprocess2.PIPE, universal_newlines=True)
|
|
||||||
duration = input_api.time.time() - start
|
|
||||||
if output[1]:
|
|
||||||
return output_api.PresubmitError("%s\n%s (%4.2fs) failed\n%s" %
|
|
||||||
(name, " ".join(cmd), duration, output[1]))
|
|
||||||
return output_api.PresubmitResult("%s\n%s (%4.2fs)\n" %
|
|
||||||
(name, " ".join(cmd), duration))
|
|
||||||
|
|
||||||
|
|
||||||
def _RunShellCheckCmd(input_api, output_api, bash_file):
|
|
||||||
"""shellcheck command wrapper."""
|
|
||||||
cmd = ["shellcheck", "-x", "-oall", "-sbash", bash_file]
|
|
||||||
name = "Check %s file." % bash_file
|
|
||||||
start = input_api.time.time()
|
|
||||||
output, rc = subprocess2.communicate(
|
|
||||||
cmd, stdout=None, stderr=subprocess2.PIPE, universal_newlines=True)
|
|
||||||
duration = input_api.time.time() - start
|
|
||||||
if rc == 0:
|
|
||||||
return output_api.PresubmitResult("%s\n%s (%4.2fs)\n" %
|
|
||||||
(name, " ".join(cmd), duration))
|
|
||||||
return output_api.PresubmitError("%s\n%s (%4.2fs) failed\n%s" %
|
|
||||||
(name, " ".join(cmd), duration, output[1]))
|
|
||||||
|
|
||||||
|
|
||||||
def _RunShfmtCheckCmd(input_api, output_api, bash_file):
|
|
||||||
"""shfmt command wrapper."""
|
|
||||||
cmd = [
|
|
||||||
"shfmt", "-i", _BASH_INDENTATION, "-bn", "-ci", "-sr", "-kp", "-d",
|
|
||||||
bash_file
|
|
||||||
]
|
|
||||||
name = "Check %s file." % bash_file
|
|
||||||
start = input_api.time.time()
|
|
||||||
output, rc = subprocess2.communicate(
|
|
||||||
cmd, stdout=None, stderr=subprocess2.PIPE, universal_newlines=True)
|
|
||||||
duration = input_api.time.time() - start
|
|
||||||
if rc == 0:
|
|
||||||
return output_api.PresubmitResult("%s\n%s (%4.2fs)\n" %
|
|
||||||
(name, " ".join(cmd), duration))
|
|
||||||
return output_api.PresubmitError("%s\n%s (%4.2fs) failed\n%s" %
|
|
||||||
(name, " ".join(cmd), duration, output[1]))
|
|
||||||
|
|
||||||
|
|
||||||
def _RunCmdOnCheckedFiles(input_api, output_api, run_cmd, files_to_check):
|
|
||||||
"""Ensure that libwebp/ files are clean."""
|
|
||||||
file_filter = lambda x: input_api.FilterSourceFile(
|
|
||||||
x, files_to_check=files_to_check, files_to_skip=None)
|
|
||||||
|
|
||||||
affected_files = input_api.change.AffectedFiles(file_filter=file_filter)
|
|
||||||
results = [
|
|
||||||
run_cmd(input_api, output_api, f.AbsoluteLocalPath())
|
|
||||||
for f in affected_files
|
|
||||||
]
|
|
||||||
return results
|
|
||||||
|
|
||||||
|
|
||||||
def _CommonChecks(input_api, output_api):
|
|
||||||
"""Ensures this patch does not have trailing spaces, extra EOLs,
|
|
||||||
or long lines.
|
|
||||||
"""
|
|
||||||
results = []
|
|
||||||
results.extend(
|
|
||||||
input_api.canned_checks.CheckChangeHasNoCrAndHasOnlyOneEol(
|
|
||||||
input_api, output_api))
|
|
||||||
results.extend(
|
|
||||||
input_api.canned_checks.CheckChangeHasNoTabs(input_api, output_api))
|
|
||||||
results.extend(
|
|
||||||
input_api.canned_checks.CheckChangeHasNoStrayWhitespace(
|
|
||||||
input_api, output_api))
|
|
||||||
results.append(_CheckCommitSubjectLength(input_api, output_api))
|
|
||||||
results.append(_CheckDuplicateFiles(input_api, output_api))
|
|
||||||
|
|
||||||
source_file_filter = lambda x: input_api.FilterSourceFile(
|
|
||||||
x, files_to_skip=_GetFilesToSkip(input_api))
|
|
||||||
results.extend(
|
|
||||||
input_api.canned_checks.CheckLongLines(
|
|
||||||
input_api,
|
|
||||||
output_api,
|
|
||||||
maxlen=_LIBWEBP_MAX_LINE_LENGTH,
|
|
||||||
source_file_filter=source_file_filter))
|
|
||||||
|
|
||||||
results.extend(
|
|
||||||
input_api.canned_checks.CheckPatchFormatted(
|
|
||||||
input_api,
|
|
||||||
output_api,
|
|
||||||
check_clang_format=False,
|
|
||||||
check_python=True,
|
|
||||||
result_factory=output_api.PresubmitError))
|
|
||||||
results.extend(
|
|
||||||
_RunCmdOnCheckedFiles(input_api, output_api, _RunManCmd,
|
|
||||||
_INCLUDE_MAN_FILES_ONLY))
|
|
||||||
# Run pylint.
|
|
||||||
results.extend(
|
|
||||||
input_api.canned_checks.RunPylint(
|
|
||||||
input_api,
|
|
||||||
output_api,
|
|
||||||
files_to_skip=_GetFilesToSkip(input_api),
|
|
||||||
pylintrc=".pylintrc",
|
|
||||||
version="2.7"))
|
|
||||||
|
|
||||||
# Binaries shellcheck and shfmt are not installed in depot_tools.
|
|
||||||
# Installation is needed
|
|
||||||
try:
|
|
||||||
subprocess2.communicate(["shellcheck", "--version"])
|
|
||||||
results.extend(
|
|
||||||
_RunCmdOnCheckedFiles(input_api, output_api, _RunShellCheckCmd,
|
|
||||||
_INCLUDE_BASH_FILES_ONLY))
|
|
||||||
print("shfmt")
|
|
||||||
subprocess2.communicate(["shfmt", "-version"])
|
|
||||||
results.extend(
|
|
||||||
_RunCmdOnCheckedFiles(input_api, output_api, _RunShfmtCheckCmd,
|
|
||||||
_INCLUDE_BASH_FILES_ONLY))
|
|
||||||
except OSError as os_error:
|
|
||||||
results.append(
|
|
||||||
output_api.PresubmitPromptWarning(
|
|
||||||
"%s\nPlease install missing binaries locally." % os_error.args[0]))
|
|
||||||
return results
|
|
||||||
|
|
||||||
|
|
||||||
def CheckChangeOnUpload(input_api, output_api):
|
|
||||||
results = []
|
|
||||||
results.extend(_CommonChecks(input_api, output_api))
|
|
||||||
return results
|
|
||||||
|
|
||||||
|
|
||||||
def CheckChangeOnCommit(input_api, output_api):
|
|
||||||
results = []
|
|
||||||
results.extend(_CommonChecks(input_api, output_api))
|
|
||||||
return results
|
|
||||||
750
README
Normal file
750
README
Normal file
@@ -0,0 +1,750 @@
|
|||||||
|
__ __ ____ ____ ____
|
||||||
|
/ \\/ \/ _ \/ _ )/ _ \
|
||||||
|
\ / __/ _ \ __/
|
||||||
|
\__\__/\____/\_____/__/ ____ ___
|
||||||
|
/ _/ / \ \ / _ \/ _/
|
||||||
|
/ \_/ / / \ \ __/ \__
|
||||||
|
\____/____/\_____/_____/____/v0.6.0
|
||||||
|
|
||||||
|
Description:
|
||||||
|
============
|
||||||
|
|
||||||
|
WebP codec: library to encode and decode images in WebP format. This package
|
||||||
|
contains the library that can be used in other programs to add WebP support,
|
||||||
|
as well as the command line tools 'cwebp' and 'dwebp'.
|
||||||
|
|
||||||
|
See http://developers.google.com/speed/webp
|
||||||
|
|
||||||
|
The latest source tree is available at
|
||||||
|
https://chromium.googlesource.com/webm/libwebp
|
||||||
|
|
||||||
|
It is released under the same license as the WebM project.
|
||||||
|
See http://www.webmproject.org/license/software/ or the
|
||||||
|
"COPYING" file for details. An additional intellectual
|
||||||
|
property rights grant can be found in the file PATENTS.
|
||||||
|
|
||||||
|
Building:
|
||||||
|
=========
|
||||||
|
|
||||||
|
Windows build:
|
||||||
|
--------------
|
||||||
|
|
||||||
|
By running:
|
||||||
|
|
||||||
|
nmake /f Makefile.vc CFG=release-static RTLIBCFG=static OBJDIR=output
|
||||||
|
|
||||||
|
the directory output\release-static\(x64|x86)\bin will contain the tools
|
||||||
|
cwebp.exe and dwebp.exe. The directory output\release-static\(x64|x86)\lib will
|
||||||
|
contain the libwebp static library.
|
||||||
|
The target architecture (x86/x64) is detected by Makefile.vc from the Visual
|
||||||
|
Studio compiler (cl.exe) available in the system path.
|
||||||
|
|
||||||
|
Unix build using makefile.unix:
|
||||||
|
-------------------------------
|
||||||
|
|
||||||
|
On platforms with GNU tools installed (gcc and make), running
|
||||||
|
|
||||||
|
make -f makefile.unix
|
||||||
|
|
||||||
|
will build the binaries examples/cwebp and examples/dwebp, along
|
||||||
|
with the static library src/libwebp.a. No system-wide installation
|
||||||
|
is supplied, as this is a simple alternative to the full installation
|
||||||
|
system based on the autoconf tools (see below).
|
||||||
|
Please refer to makefile.unix for additional details and customizations.
|
||||||
|
|
||||||
|
Using autoconf tools:
|
||||||
|
---------------------
|
||||||
|
Prerequisites:
|
||||||
|
A compiler (e.g., gcc), make, autoconf, automake, libtool.
|
||||||
|
On a Debian-like system the following should install everything you need for a
|
||||||
|
minimal build:
|
||||||
|
$ sudo apt-get install gcc make autoconf automake libtool
|
||||||
|
|
||||||
|
When building from git sources, you will need to run autogen.sh to generate the
|
||||||
|
configure script.
|
||||||
|
|
||||||
|
./configure
|
||||||
|
make
|
||||||
|
make install
|
||||||
|
|
||||||
|
should be all you need to have the following files
|
||||||
|
|
||||||
|
/usr/local/include/webp/decode.h
|
||||||
|
/usr/local/include/webp/encode.h
|
||||||
|
/usr/local/include/webp/types.h
|
||||||
|
/usr/local/lib/libwebp.*
|
||||||
|
/usr/local/bin/cwebp
|
||||||
|
/usr/local/bin/dwebp
|
||||||
|
|
||||||
|
installed.
|
||||||
|
|
||||||
|
Note: A decode-only library, libwebpdecoder, is available using the
|
||||||
|
'--enable-libwebpdecoder' flag. The encode library is built separately and can
|
||||||
|
be installed independently using a minor modification in the corresponding
|
||||||
|
Makefile.am configure files (see comments there). See './configure --help' for
|
||||||
|
more options.
|
||||||
|
|
||||||
|
Building for MIPS Linux:
|
||||||
|
------------------------
|
||||||
|
MIPS Linux toolchain stable available releases can be found at:
|
||||||
|
https://community.imgtec.com/developers/mips/tools/codescape-mips-sdk/available-releases/
|
||||||
|
|
||||||
|
# Add toolchain to PATH
|
||||||
|
export PATH=$PATH:/path/to/toolchain/bin
|
||||||
|
|
||||||
|
# 32-bit build for mips32r5 (p5600)
|
||||||
|
HOST=mips-mti-linux-gnu
|
||||||
|
MIPS_CFLAGS="-O3 -mips32r5 -mabi=32 -mtune=p5600 -mmsa -mfp64 \
|
||||||
|
-msched-weight -mload-store-pairs -fPIE"
|
||||||
|
MIPS_LDFLAGS="-mips32r5 -mabi=32 -mmsa -mfp64 -pie"
|
||||||
|
|
||||||
|
# 64-bit build for mips64r6 (i6400)
|
||||||
|
HOST=mips-img-linux-gnu
|
||||||
|
MIPS_CFLAGS="-O3 -mips64r6 -mabi=64 -mtune=i6400 -mmsa -mfp64 \
|
||||||
|
-msched-weight -mload-store-pairs -fPIE"
|
||||||
|
MIPS_LDFLAGS="-mips64r6 -mabi=64 -mmsa -mfp64 -pie"
|
||||||
|
|
||||||
|
./configure --host=${HOST} --build=`config.guess` \
|
||||||
|
CC="${HOST}-gcc -EL" \
|
||||||
|
CFLAGS="$MIPS_CFLAGS" \
|
||||||
|
LDFLAGS="$MIPS_LDFLAGS"
|
||||||
|
make
|
||||||
|
make install
|
||||||
|
|
||||||
|
CMake:
|
||||||
|
------
|
||||||
|
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.
|
||||||
|
On a Debian-like system the following should install everything you need for a
|
||||||
|
minimal build:
|
||||||
|
$ sudo apt-get install build-essential cmake
|
||||||
|
|
||||||
|
When building from git sources, you will need to run cmake to generate the
|
||||||
|
configure script.
|
||||||
|
|
||||||
|
mkdir build && cd build && cmake ../
|
||||||
|
make
|
||||||
|
make install
|
||||||
|
|
||||||
|
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).
|
||||||
|
|
||||||
|
Gradle:
|
||||||
|
-------
|
||||||
|
The support for Gradle is minimal: it only helps you compile libwebp, cwebp and
|
||||||
|
dwebp and webpmux_example.
|
||||||
|
|
||||||
|
Prerequisites:
|
||||||
|
A compiler (e.g., gcc with autotools) and gradle.
|
||||||
|
On a Debian-like system the following should install everything you need for a
|
||||||
|
minimal build:
|
||||||
|
$ sudo apt-get install build-essential gradle
|
||||||
|
|
||||||
|
When building from git sources, you will need to run the Gradle wrapper with the
|
||||||
|
appropriate target, e.g. :
|
||||||
|
|
||||||
|
./gradlew buildAllExecutables
|
||||||
|
|
||||||
|
SWIG bindings:
|
||||||
|
--------------
|
||||||
|
|
||||||
|
To generate language bindings from swig/libwebp.swig at least swig-1.3
|
||||||
|
(http://www.swig.org) is required.
|
||||||
|
|
||||||
|
Currently the following functions are mapped:
|
||||||
|
Decode:
|
||||||
|
WebPGetDecoderVersion
|
||||||
|
WebPGetInfo
|
||||||
|
WebPDecodeRGBA
|
||||||
|
WebPDecodeARGB
|
||||||
|
WebPDecodeBGRA
|
||||||
|
WebPDecodeBGR
|
||||||
|
WebPDecodeRGB
|
||||||
|
|
||||||
|
Encode:
|
||||||
|
WebPGetEncoderVersion
|
||||||
|
WebPEncodeRGBA
|
||||||
|
WebPEncodeBGRA
|
||||||
|
WebPEncodeRGB
|
||||||
|
WebPEncodeBGR
|
||||||
|
WebPEncodeLosslessRGBA
|
||||||
|
WebPEncodeLosslessBGRA
|
||||||
|
WebPEncodeLosslessRGB
|
||||||
|
WebPEncodeLosslessBGR
|
||||||
|
|
||||||
|
See swig/README for more detailed build instructions.
|
||||||
|
|
||||||
|
Java bindings:
|
||||||
|
|
||||||
|
To build the swig-generated JNI wrapper code at least JDK-1.5 (or equivalent)
|
||||||
|
is necessary for enum support. The output is intended to be a shared object /
|
||||||
|
DLL that can be loaded via System.loadLibrary("webp_jni").
|
||||||
|
|
||||||
|
Python bindings:
|
||||||
|
|
||||||
|
To build the swig-generated Python extension code at least Python 2.6 is
|
||||||
|
required. Python < 2.6 may build with some minor changes to libwebp.swig or the
|
||||||
|
generated code, but is untested.
|
||||||
|
|
||||||
|
Encoding tool:
|
||||||
|
==============
|
||||||
|
|
||||||
|
The examples/ directory contains tools for encoding (cwebp) and
|
||||||
|
decoding (dwebp) images.
|
||||||
|
|
||||||
|
The easiest use should look like:
|
||||||
|
cwebp input.png -q 80 -o output.webp
|
||||||
|
which will convert the input file to a WebP file using a quality factor of 80
|
||||||
|
on a 0->100 scale (0 being the lowest quality, 100 being the best. Default
|
||||||
|
value is 75).
|
||||||
|
You might want to try the -lossless flag too, which will compress the source
|
||||||
|
(in RGBA format) without any loss. The -q quality parameter will in this case
|
||||||
|
control the amount of processing time spent trying to make the output file as
|
||||||
|
small as possible.
|
||||||
|
|
||||||
|
A longer list of options is available using the -longhelp command line flag:
|
||||||
|
|
||||||
|
> cwebp -longhelp
|
||||||
|
Usage:
|
||||||
|
cwebp [-preset <...>] [options] in_file [-o out_file]
|
||||||
|
|
||||||
|
If input size (-s) for an image is not specified, it is
|
||||||
|
assumed to be a PNG, JPEG, TIFF or WebP file.
|
||||||
|
|
||||||
|
Options:
|
||||||
|
-h / -help ............. short help
|
||||||
|
-H / -longhelp ......... long help
|
||||||
|
-q <float> ............. quality factor (0:small..100:big), default=75
|
||||||
|
-alpha_q <int> ......... transparency-compression quality (0..100),
|
||||||
|
default=100
|
||||||
|
-preset <string> ....... preset setting, one of:
|
||||||
|
default, photo, picture,
|
||||||
|
drawing, icon, text
|
||||||
|
-preset must come first, as it overwrites other parameters
|
||||||
|
-z <int> ............... activates lossless preset with given
|
||||||
|
level in [0:fast, ..., 9:slowest]
|
||||||
|
|
||||||
|
-m <int> ............... compression method (0=fast, 6=slowest), default=4
|
||||||
|
-segments <int> ........ number of segments to use (1..4), default=4
|
||||||
|
-size <int> ............ target size (in bytes)
|
||||||
|
-psnr <float> .......... target PSNR (in dB. typically: 42)
|
||||||
|
|
||||||
|
-s <int> <int> ......... input size (width x height) for YUV
|
||||||
|
-sns <int> ............. spatial noise shaping (0:off, 100:max), default=50
|
||||||
|
-f <int> ............... filter strength (0=off..100), default=60
|
||||||
|
-sharpness <int> ....... filter sharpness (0:most .. 7:least sharp), default=0
|
||||||
|
-strong ................ use strong filter instead of simple (default)
|
||||||
|
-nostrong .............. use simple filter instead of strong
|
||||||
|
-sharp_yuv ............. use sharper (and slower) RGB->YUV conversion
|
||||||
|
-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)
|
||||||
|
-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
|
||||||
|
-low_memory ............ reduce memory usage (slower encoding)
|
||||||
|
-map <int> ............. print map of extra info
|
||||||
|
-print_psnr ............ prints averaged PSNR distortion
|
||||||
|
-print_ssim ............ prints averaged SSIM distortion
|
||||||
|
-print_lsim ............ prints local-similarity distortion
|
||||||
|
-d <file.pgm> .......... dump the compressed output (PGM file)
|
||||||
|
-alpha_method <int> .... transparency-compression method (0..1), default=1
|
||||||
|
-alpha_filter <string> . predictive filtering for alpha plane,
|
||||||
|
one of: none, fast (default) or best
|
||||||
|
-exact ................. preserve RGB values in transparent area, default=off
|
||||||
|
-blend_alpha <hex> ..... blend colors against background color
|
||||||
|
expressed as RGB values written in
|
||||||
|
hexadecimal, e.g. 0xc0e0d0 for red=0xc0
|
||||||
|
green=0xe0 and blue=0xd0
|
||||||
|
-noalpha ............... discard any transparency information
|
||||||
|
-lossless .............. encode image losslessly, default=off
|
||||||
|
-near_lossless <int> ... use near-lossless image
|
||||||
|
preprocessing (0..100=off), default=100
|
||||||
|
-hint <string> ......... specify image characteristics hint,
|
||||||
|
one of: photo, picture or graph
|
||||||
|
|
||||||
|
-metadata <string> ..... comma separated list of metadata to
|
||||||
|
copy from the input to the output if present.
|
||||||
|
Valid values: all, none (default), exif, icc, xmp
|
||||||
|
|
||||||
|
-short ................. condense printed message
|
||||||
|
-quiet ................. don't print anything
|
||||||
|
-version ............... print version number and exit
|
||||||
|
-noasm ................. disable all assembly optimizations
|
||||||
|
-v ..................... verbose, e.g. print encoding/decoding times
|
||||||
|
-progress .............. report encoding progress
|
||||||
|
|
||||||
|
Experimental Options:
|
||||||
|
-jpeg_like ............. roughly match expected JPEG size
|
||||||
|
-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
|
||||||
|
-sns
|
||||||
|
-f
|
||||||
|
-m
|
||||||
|
|
||||||
|
Namely:
|
||||||
|
* 'preset' will set up a default encoding configuration targeting a
|
||||||
|
particular type of input. It should appear first in the list of options,
|
||||||
|
so that subsequent options can take effect on top of this preset.
|
||||||
|
Default value is 'default'.
|
||||||
|
* 'sns' will progressively turn on (when going from 0 to 100) some additional
|
||||||
|
visual optimizations (like: segmentation map re-enforcement). This option
|
||||||
|
will balance the bit allocation differently. It tries to take bits from the
|
||||||
|
"easy" parts of the picture and use them in the "difficult" ones instead.
|
||||||
|
Usually, raising the sns value (at fixed -q value) leads to larger files,
|
||||||
|
but with better quality.
|
||||||
|
Typical value is around '75'.
|
||||||
|
* 'f' option directly links to the filtering strength used by the codec's
|
||||||
|
in-loop processing. The higher the value, the smoother the
|
||||||
|
highly-compressed area will look. This is particularly useful when aiming
|
||||||
|
at very small files. Typical values are around 20-30. Note that using the
|
||||||
|
option -strong/-nostrong will change the type of filtering. Use "-f 0" to
|
||||||
|
turn filtering off.
|
||||||
|
* 'm' controls the trade-off between encoding speed and quality. Default is 4.
|
||||||
|
You can try -m 5 or -m 6 to explore more (time-consuming) encoding
|
||||||
|
possibilities. A lower value will result in faster encoding at the expense
|
||||||
|
of quality.
|
||||||
|
|
||||||
|
Decoding tool:
|
||||||
|
==============
|
||||||
|
|
||||||
|
There is a decoding sample in examples/dwebp.c which will take
|
||||||
|
a .webp file and decode it to a PNG image file (amongst other formats).
|
||||||
|
This is simply to demonstrate the use of the API. You can verify the
|
||||||
|
file test.webp decodes to exactly the same as test_ref.ppm by using:
|
||||||
|
|
||||||
|
cd examples
|
||||||
|
./dwebp test.webp -ppm -o test.ppm
|
||||||
|
diff test.ppm test_ref.ppm
|
||||||
|
|
||||||
|
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]
|
||||||
|
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
|
||||||
|
-bmp ......... save as uncompressed BMP format
|
||||||
|
-tiff ........ save as uncompressed TIFF format
|
||||||
|
-pgm ......... save the raw YUV samples as a grayscale PGM
|
||||||
|
file with IMC4 layout
|
||||||
|
-yuv ......... save the raw YUV samples in flat layout
|
||||||
|
|
||||||
|
Other options are:
|
||||||
|
-version ..... print version number and exit
|
||||||
|
-nofancy ..... don't use the fancy YUV420 upscaler
|
||||||
|
-nofilter .... disable in-loop filtering
|
||||||
|
-nodither .... disable dithering
|
||||||
|
-dither <d> .. dithering strength (in 0..100)
|
||||||
|
-alpha_dither use alpha-plane dithering if needed
|
||||||
|
-mt .......... use multi-threading
|
||||||
|
-crop <x> <y> <w> <h> ... crop output with the given rectangle
|
||||||
|
-resize <w> <h> ......... scale the output (*after* any cropping)
|
||||||
|
-flip ........ flip the output vertically
|
||||||
|
-alpha ....... only save the alpha plane
|
||||||
|
-incremental . use incremental decoding (useful for tests)
|
||||||
|
-h ........... this help message
|
||||||
|
-v ........... verbose (e.g. print encoding/decoding times)
|
||||||
|
-quiet ....... quiet mode, don't print anything
|
||||||
|
-noasm ....... disable all assembly optimizations
|
||||||
|
|
||||||
|
Visualization tool:
|
||||||
|
===================
|
||||||
|
|
||||||
|
There's a little self-serve visualization tool called 'vwebp' under the
|
||||||
|
examples/ directory. It uses OpenGL to open a simple drawing window and show
|
||||||
|
a decoded WebP file. It's not yet integrated in the automake build system, but
|
||||||
|
you can try to manually compile it using the recommendations below.
|
||||||
|
|
||||||
|
Usage: vwebp in_file [options]
|
||||||
|
|
||||||
|
Decodes the WebP image file and visualize it using OpenGL
|
||||||
|
Options are:
|
||||||
|
-version ..... print version number and exit
|
||||||
|
-noicc ....... don't use the icc profile if present
|
||||||
|
-nofancy ..... don't use the fancy YUV420 upscaler
|
||||||
|
-nofilter .... disable in-loop filtering
|
||||||
|
-dither <int> dithering strength (0..100), default=50
|
||||||
|
-noalphadither disable alpha plane dithering
|
||||||
|
-mt .......... use multi-threading
|
||||||
|
-info ........ print info
|
||||||
|
-h ........... this help message
|
||||||
|
|
||||||
|
Keyboard shortcuts:
|
||||||
|
'c' ................ toggle use of color profile
|
||||||
|
'i' ................ overlay file information
|
||||||
|
'd' ................ disable blending & disposal (debug)
|
||||||
|
'q' / 'Q' / ESC .... quit
|
||||||
|
|
||||||
|
Building:
|
||||||
|
---------
|
||||||
|
|
||||||
|
Prerequisites:
|
||||||
|
1) OpenGL & OpenGL Utility Toolkit (GLUT)
|
||||||
|
Linux:
|
||||||
|
$ sudo apt-get install freeglut3-dev mesa-common-dev
|
||||||
|
Mac + XCode:
|
||||||
|
- These libraries should be available in the OpenGL / GLUT frameworks.
|
||||||
|
Windows:
|
||||||
|
http://freeglut.sourceforge.net/index.php#download
|
||||||
|
|
||||||
|
2) (Optional) qcms (Quick Color Management System)
|
||||||
|
i. Download qcms from Mozilla / Chromium:
|
||||||
|
http://hg.mozilla.org/mozilla-central/file/0e7639e3bdfb/gfx/qcms
|
||||||
|
http://src.chromium.org/viewvc/chrome/trunk/src/third_party/qcms
|
||||||
|
ii. Build and archive the source files as libqcms.a / qcms.lib
|
||||||
|
iii. Update makefile.unix / Makefile.vc
|
||||||
|
a) Define WEBP_HAVE_QCMS
|
||||||
|
b) Update include / library paths to reference the qcms directory.
|
||||||
|
|
||||||
|
Build using makefile.unix / Makefile.vc:
|
||||||
|
$ make -f makefile.unix examples/vwebp
|
||||||
|
> nmake /f Makefile.vc CFG=release-static \
|
||||||
|
../obj/x64/release-static/bin/vwebp.exe
|
||||||
|
|
||||||
|
Animation creation tool:
|
||||||
|
========================
|
||||||
|
The utility 'img2webp' can turn a sequence of input images (PNG, JPEG, ...)
|
||||||
|
into an animated WebP file. It offers fine control over duration, encoding
|
||||||
|
modes, etc.
|
||||||
|
|
||||||
|
Usage:
|
||||||
|
|
||||||
|
img2webp [file-level options] [image files...] [per-frame options...]
|
||||||
|
|
||||||
|
File-level options (only used at the start of compression):
|
||||||
|
-min_size ............ minimize size
|
||||||
|
-loop <int> .......... loop count (default: 0, = infinite loop)
|
||||||
|
-kmax <int> .......... maximum number of frame between key-frames
|
||||||
|
(0=only keyframes)
|
||||||
|
-kmin <int> .......... minimum number of frame between key-frames
|
||||||
|
(0=disable key-frames altogether)
|
||||||
|
-mixed ............... use mixed lossy/lossless automatic mode
|
||||||
|
-v ................... verbose mode
|
||||||
|
-h ................... this help
|
||||||
|
|
||||||
|
Per-frame options (only used for subsequent images input):
|
||||||
|
-d <int> ............. frame duration in ms (default: 100)
|
||||||
|
-lossless ........... use lossless mode (default)
|
||||||
|
-lossy ... ........... use lossy mode
|
||||||
|
-q <float> ........... quality
|
||||||
|
-m <int> ............. method to use
|
||||||
|
|
||||||
|
example: img2webp -loop 2 in0.png -lossy in1.jpg
|
||||||
|
-d 80 in2.tiff -o out.webp
|
||||||
|
|
||||||
|
Animated GIF conversion:
|
||||||
|
========================
|
||||||
|
Animated GIF files can be converted to WebP files with animation using the
|
||||||
|
gif2webp utility available under examples/. The files can then be viewed using
|
||||||
|
vwebp.
|
||||||
|
|
||||||
|
Usage:
|
||||||
|
gif2webp [options] gif_file -o webp_file
|
||||||
|
Options:
|
||||||
|
-h / -help ............. this help
|
||||||
|
-lossy ................. encode image using lossy compression
|
||||||
|
-mixed ................. for each frame in the image, pick lossy
|
||||||
|
or lossless compression heuristically
|
||||||
|
-q <float> ............. quality factor (0:small..100:big)
|
||||||
|
-m <int> ............... compression method (0=fast, 6=slowest)
|
||||||
|
-min_size .............. minimize output size (default:off)
|
||||||
|
lossless compression by default; can be
|
||||||
|
combined with -q, -m, -lossy or -mixed
|
||||||
|
options
|
||||||
|
-kmin <int> ............ min distance between key frames
|
||||||
|
-kmax <int> ............ max distance between key frames
|
||||||
|
-f <int> ............... filter strength (0=off..100)
|
||||||
|
-metadata <string> ..... comma separated list of metadata to
|
||||||
|
copy from the input to the output if present
|
||||||
|
Valid values: all, none, icc, xmp (default)
|
||||||
|
-mt .................... use multi-threading if available
|
||||||
|
|
||||||
|
-version ............... print version number and exit
|
||||||
|
-v ..................... verbose
|
||||||
|
-quiet ................. don't print anything
|
||||||
|
|
||||||
|
Building:
|
||||||
|
---------
|
||||||
|
With the libgif development files installed, gif2webp can be built using
|
||||||
|
makefile.unix:
|
||||||
|
$ make -f makefile.unix examples/gif2webp
|
||||||
|
|
||||||
|
or using autoconf:
|
||||||
|
$ ./configure --enable-everything
|
||||||
|
$ make
|
||||||
|
|
||||||
|
Comparison of animated images:
|
||||||
|
==============================
|
||||||
|
Test utility anim_diff under examples/ can be used to compare two animated
|
||||||
|
images (each can be GIF or WebP).
|
||||||
|
|
||||||
|
Usage: anim_diff <image1> <image2> [options]
|
||||||
|
|
||||||
|
Options:
|
||||||
|
-dump_frames <folder> dump decoded frames in PAM format
|
||||||
|
-min_psnr <float> ... minimum per-frame PSNR
|
||||||
|
-raw_comparison ..... if this flag is not used, RGB is
|
||||||
|
premultiplied before comparison
|
||||||
|
|
||||||
|
Building:
|
||||||
|
---------
|
||||||
|
With the libgif development files and a C++ compiler installed, anim_diff can
|
||||||
|
be built using makefile.unix:
|
||||||
|
$ make -f makefile.unix examples/anim_diff
|
||||||
|
|
||||||
|
or using autoconf:
|
||||||
|
$ ./configure --enable-everything
|
||||||
|
$ make
|
||||||
|
|
||||||
|
Encoding API:
|
||||||
|
=============
|
||||||
|
|
||||||
|
The main encoding functions are available in the header src/webp/encode.h
|
||||||
|
The ready-to-use ones are:
|
||||||
|
size_t WebPEncodeRGB(const uint8_t* rgb, int width, int height, int stride,
|
||||||
|
float quality_factor, uint8_t** output);
|
||||||
|
size_t WebPEncodeBGR(const uint8_t* bgr, int width, int height, int stride,
|
||||||
|
float quality_factor, uint8_t** output);
|
||||||
|
size_t WebPEncodeRGBA(const uint8_t* rgba, int width, int height, int stride,
|
||||||
|
float quality_factor, uint8_t** output);
|
||||||
|
size_t WebPEncodeBGRA(const uint8_t* bgra, int width, int height, int stride,
|
||||||
|
float quality_factor, uint8_t** output);
|
||||||
|
|
||||||
|
They will convert raw RGB samples to a WebP data. The only control supplied
|
||||||
|
is the quality factor.
|
||||||
|
|
||||||
|
There are some variants for using the lossless format:
|
||||||
|
|
||||||
|
size_t WebPEncodeLosslessRGB(const uint8_t* rgb, int width, int height,
|
||||||
|
int stride, uint8_t** output);
|
||||||
|
size_t WebPEncodeLosslessBGR(const uint8_t* bgr, int width, int height,
|
||||||
|
int stride, uint8_t** output);
|
||||||
|
size_t WebPEncodeLosslessRGBA(const uint8_t* rgba, int width, int height,
|
||||||
|
int stride, uint8_t** output);
|
||||||
|
size_t WebPEncodeLosslessBGRA(const uint8_t* bgra, int width, int height,
|
||||||
|
int stride, uint8_t** output);
|
||||||
|
|
||||||
|
Of course in this case, no quality factor is needed since the compression
|
||||||
|
occurs without loss of the input values, at the expense of larger output sizes.
|
||||||
|
|
||||||
|
Advanced encoding API:
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
A more advanced API is based on the WebPConfig and WebPPicture structures.
|
||||||
|
|
||||||
|
WebPConfig contains the encoding settings and is not tied to a particular
|
||||||
|
picture.
|
||||||
|
WebPPicture contains input data, on which some WebPConfig will be used for
|
||||||
|
compression.
|
||||||
|
The encoding flow looks like:
|
||||||
|
|
||||||
|
-------------------------------------- BEGIN PSEUDO EXAMPLE
|
||||||
|
|
||||||
|
#include <webp/encode.h>
|
||||||
|
|
||||||
|
// Setup a config, starting form a preset and tuning some additional
|
||||||
|
// parameters
|
||||||
|
WebPConfig config;
|
||||||
|
if (!WebPConfigPreset(&config, WEBP_PRESET_PHOTO, quality_factor))
|
||||||
|
return 0; // version error
|
||||||
|
}
|
||||||
|
// ... additional tuning
|
||||||
|
config.sns_strength = 90;
|
||||||
|
config.filter_sharpness = 6;
|
||||||
|
config_error = WebPValidateConfig(&config); // not mandatory, but useful
|
||||||
|
|
||||||
|
// Setup the input data
|
||||||
|
WebPPicture pic;
|
||||||
|
if (!WebPPictureInit(&pic)) {
|
||||||
|
return 0; // version error
|
||||||
|
}
|
||||||
|
pic.width = width;
|
||||||
|
pic.height = height;
|
||||||
|
// allocated picture of dimension width x height
|
||||||
|
if (!WebPPictureAllocate(&pic)) {
|
||||||
|
return 0; // memory error
|
||||||
|
}
|
||||||
|
// at this point, 'pic' has been initialized as a container,
|
||||||
|
// and can receive the Y/U/V samples.
|
||||||
|
// Alternatively, one could use ready-made import functions like
|
||||||
|
// WebPPictureImportRGB(), which will take care of memory allocation.
|
||||||
|
// In any case, past this point, one will have to call
|
||||||
|
// WebPPictureFree(&pic) to reclaim memory.
|
||||||
|
|
||||||
|
// Set up a byte-output write method. WebPMemoryWriter, for instance.
|
||||||
|
WebPMemoryWriter wrt;
|
||||||
|
WebPMemoryWriterInit(&wrt); // initialize 'wrt'
|
||||||
|
|
||||||
|
pic.writer = MyFileWriter;
|
||||||
|
pic.custom_ptr = my_opaque_structure_to_make_MyFileWriter_work;
|
||||||
|
|
||||||
|
// Compress!
|
||||||
|
int ok = WebPEncode(&config, &pic); // ok = 0 => error occurred!
|
||||||
|
WebPPictureFree(&pic); // must be called independently of the 'ok' result.
|
||||||
|
|
||||||
|
// output data should have been handled by the writer at that point.
|
||||||
|
// -> compressed data is the memory buffer described by wrt.mem / wrt.size
|
||||||
|
|
||||||
|
// deallocate the memory used by compressed data
|
||||||
|
WebPMemoryWriterClear(&wrt);
|
||||||
|
|
||||||
|
-------------------------------------- END PSEUDO EXAMPLE
|
||||||
|
|
||||||
|
Decoding API:
|
||||||
|
=============
|
||||||
|
|
||||||
|
This is mainly just one function to call:
|
||||||
|
|
||||||
|
#include "webp/decode.h"
|
||||||
|
uint8_t* WebPDecodeRGB(const uint8_t* data, size_t data_size,
|
||||||
|
int* width, int* height);
|
||||||
|
|
||||||
|
Please have a look at the file src/webp/decode.h for the details.
|
||||||
|
There are variants for decoding in BGR/RGBA/ARGB/BGRA order, along with
|
||||||
|
decoding to raw Y'CbCr samples. One can also decode the image directly into a
|
||||||
|
pre-allocated buffer.
|
||||||
|
|
||||||
|
To detect a WebP file and gather the picture's dimensions, the function:
|
||||||
|
int WebPGetInfo(const uint8_t* data, size_t data_size,
|
||||||
|
int* width, int* height);
|
||||||
|
is supplied. No decoding is involved when using it.
|
||||||
|
|
||||||
|
Incremental decoding API:
|
||||||
|
=========================
|
||||||
|
|
||||||
|
In the case when data is being progressively transmitted, pictures can still
|
||||||
|
be incrementally decoded using a slightly more complicated API. Decoder state
|
||||||
|
is stored into an instance of the WebPIDecoder object. This object can be
|
||||||
|
created with the purpose of decoding either RGB or Y'CbCr samples.
|
||||||
|
For instance:
|
||||||
|
|
||||||
|
WebPDecBuffer buffer;
|
||||||
|
WebPInitDecBuffer(&buffer);
|
||||||
|
buffer.colorspace = MODE_BGR;
|
||||||
|
...
|
||||||
|
WebPIDecoder* idec = WebPINewDecoder(&buffer);
|
||||||
|
|
||||||
|
As data is made progressively available, this incremental-decoder object
|
||||||
|
can be used to decode the picture further. There are two (mutually exclusive)
|
||||||
|
ways to pass freshly arrived data:
|
||||||
|
|
||||||
|
either by appending the fresh bytes:
|
||||||
|
|
||||||
|
WebPIAppend(idec, fresh_data, size_of_fresh_data);
|
||||||
|
|
||||||
|
or by just mentioning the new size of the transmitted data:
|
||||||
|
|
||||||
|
WebPIUpdate(idec, buffer, size_of_transmitted_buffer);
|
||||||
|
|
||||||
|
Note that 'buffer' can be modified between each call to WebPIUpdate, in
|
||||||
|
particular when the buffer is resized to accommodate larger data.
|
||||||
|
|
||||||
|
These functions will return the decoding status: either VP8_STATUS_SUSPENDED if
|
||||||
|
decoding is not finished yet or VP8_STATUS_OK when decoding is done. Any other
|
||||||
|
status is an error condition.
|
||||||
|
|
||||||
|
The 'idec' object must always be released (even upon an error condition) by
|
||||||
|
calling: WebPDelete(idec).
|
||||||
|
|
||||||
|
To retrieve partially decoded picture samples, one must use the corresponding
|
||||||
|
method: WebPIDecGetRGB or WebPIDecGetYUVA.
|
||||||
|
It will return the last displayable pixel row.
|
||||||
|
|
||||||
|
Lastly, note that decoding can also be performed into a pre-allocated pixel
|
||||||
|
buffer. This buffer must be passed when creating a WebPIDecoder, calling
|
||||||
|
WebPINewRGB() or WebPINewYUVA().
|
||||||
|
|
||||||
|
Please have a look at the src/webp/decode.h header for further details.
|
||||||
|
|
||||||
|
Advanced Decoding API:
|
||||||
|
======================
|
||||||
|
|
||||||
|
WebP decoding supports an advanced API which provides on-the-fly cropping and
|
||||||
|
rescaling, something of great usefulness on memory-constrained environments like
|
||||||
|
mobile phones. Basically, the memory usage will scale with the output's size,
|
||||||
|
not the input's, when one only needs a quick preview or a zoomed in portion of
|
||||||
|
an otherwise too-large picture. Some CPU can be saved too, incidentally.
|
||||||
|
|
||||||
|
-------------------------------------- BEGIN PSEUDO EXAMPLE
|
||||||
|
// A) Init a configuration object
|
||||||
|
WebPDecoderConfig config;
|
||||||
|
CHECK(WebPInitDecoderConfig(&config));
|
||||||
|
|
||||||
|
// B) optional: retrieve the bitstream's features.
|
||||||
|
CHECK(WebPGetFeatures(data, data_size, &config.input) == VP8_STATUS_OK);
|
||||||
|
|
||||||
|
// C) Adjust 'config' options, if needed
|
||||||
|
config.options.no_fancy_upsampling = 1;
|
||||||
|
config.options.use_scaling = 1;
|
||||||
|
config.options.scaled_width = scaledWidth();
|
||||||
|
config.options.scaled_height = scaledHeight();
|
||||||
|
// etc.
|
||||||
|
|
||||||
|
// D) Specify 'config' output options for specifying output colorspace.
|
||||||
|
// Optionally the external image decode buffer can also be specified.
|
||||||
|
config.output.colorspace = MODE_BGRA;
|
||||||
|
// Optionally, the config.output can be pointed to an external buffer as
|
||||||
|
// well for decoding the image. This externally supplied memory buffer
|
||||||
|
// should be big enough to store the decoded picture.
|
||||||
|
config.output.u.RGBA.rgba = (uint8_t*) memory_buffer;
|
||||||
|
config.output.u.RGBA.stride = scanline_stride;
|
||||||
|
config.output.u.RGBA.size = total_size_of_the_memory_buffer;
|
||||||
|
config.output.is_external_memory = 1;
|
||||||
|
|
||||||
|
// E) Decode the WebP image. There are two variants w.r.t decoding image.
|
||||||
|
// The first one (E.1) decodes the full image and the second one (E.2) is
|
||||||
|
// used to incrementally decode the image using small input buffers.
|
||||||
|
// Any one of these steps can be used to decode the WebP image.
|
||||||
|
|
||||||
|
// E.1) Decode full image.
|
||||||
|
CHECK(WebPDecode(data, data_size, &config) == VP8_STATUS_OK);
|
||||||
|
|
||||||
|
// E.2) Decode image incrementally.
|
||||||
|
WebPIDecoder* const idec = WebPIDecode(NULL, NULL, &config);
|
||||||
|
CHECK(idec != NULL);
|
||||||
|
while (bytes_remaining > 0) {
|
||||||
|
VP8StatusCode status = WebPIAppend(idec, input, bytes_read);
|
||||||
|
if (status == VP8_STATUS_OK || status == VP8_STATUS_SUSPENDED) {
|
||||||
|
bytes_remaining -= bytes_read;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
WebPIDelete(idec);
|
||||||
|
|
||||||
|
// F) Decoded image is now in config.output (and config.output.u.RGBA).
|
||||||
|
// It can be saved, displayed or otherwise processed.
|
||||||
|
|
||||||
|
// G) Reclaim memory allocated in config's object. It's safe to call
|
||||||
|
// this function even if the memory is external and wasn't allocated
|
||||||
|
// by WebPDecode().
|
||||||
|
WebPFreeDecBuffer(&config.output);
|
||||||
|
|
||||||
|
-------------------------------------- END PSEUDO EXAMPLE
|
||||||
|
|
||||||
|
Bugs:
|
||||||
|
=====
|
||||||
|
|
||||||
|
Please report all bugs to the issue tracker:
|
||||||
|
https://bugs.chromium.org/p/webp
|
||||||
|
Patches welcome! See this page to get started:
|
||||||
|
http://www.webmproject.org/code/contribute/submitting-patches/
|
||||||
|
|
||||||
|
Discuss:
|
||||||
|
========
|
||||||
|
|
||||||
|
Email: webp-discuss@webmproject.org
|
||||||
|
Web: http://groups.google.com/a/webmproject.org/group/webp-discuss
|
||||||
53
README.md
53
README.md
@@ -1,53 +0,0 @@
|
|||||||
# WebP Codec
|
|
||||||
|
|
||||||
```
|
|
||||||
__ __ ____ ____ ____
|
|
||||||
/ \\/ \/ _ \/ _ )/ _ \
|
|
||||||
\ / __/ _ \ __/
|
|
||||||
\__\__/\____/\_____/__/ ____ ___
|
|
||||||
/ _/ / \ \ / _ \/ _/
|
|
||||||
/ \_/ / / \ \ __/ \__
|
|
||||||
\____/____/\_____/_____/____/v1.2.3
|
|
||||||
```
|
|
||||||
|
|
||||||
WebP codec is a library to encode and decode images in WebP format. This package
|
|
||||||
contains the library that can be used in other programs to add WebP support, as
|
|
||||||
well as the command line tools 'cwebp' and 'dwebp' to compress and decompress
|
|
||||||
images respectively.
|
|
||||||
|
|
||||||
See https://developers.google.com/speed/webp for details on the image format.
|
|
||||||
|
|
||||||
The latest source tree is available at
|
|
||||||
https://chromium.googlesource.com/webm/libwebp
|
|
||||||
|
|
||||||
It is released under the same license as the WebM project. See
|
|
||||||
https://www.webmproject.org/license/software/ or the "COPYING" file for details.
|
|
||||||
An additional intellectual property rights grant can be found in the file
|
|
||||||
PATENTS.
|
|
||||||
|
|
||||||
## Building
|
|
||||||
|
|
||||||
See the [building documentation](doc/building.md).
|
|
||||||
|
|
||||||
## Encoding and Decoding Tools
|
|
||||||
|
|
||||||
The examples/ directory contains tools to encode and decode images and
|
|
||||||
animations, view information about WebP images, and more. See the
|
|
||||||
[tools documentation](doc/tools.md).
|
|
||||||
|
|
||||||
## APIs
|
|
||||||
|
|
||||||
See the [APIs documentation](doc/api.md), and API usage examples in the
|
|
||||||
`examples/` directory.
|
|
||||||
|
|
||||||
## Bugs
|
|
||||||
|
|
||||||
Please report all bugs to the issue tracker: https://bugs.chromium.org/p/webp
|
|
||||||
|
|
||||||
Patches welcome! See [how to contribute](CONTRIBUTING.md).
|
|
||||||
|
|
||||||
## Discuss
|
|
||||||
|
|
||||||
Email: webp-discuss@webmproject.org
|
|
||||||
|
|
||||||
Web: https://groups.google.com/a/webmproject.org/group/webp-discuss
|
|
||||||
223
README.mux
Normal file
223
README.mux
Normal file
@@ -0,0 +1,223 @@
|
|||||||
|
__ __ ____ ____ ____ __ __ _ __ __
|
||||||
|
/ \\/ \/ _ \/ _ \/ _ \/ \ \/ \___/_ / _\
|
||||||
|
\ / __/ _ \ __/ / / (_/ /__
|
||||||
|
\__\__/\_____/_____/__/ \__//_/\_____/__/___/v0.4.0
|
||||||
|
|
||||||
|
|
||||||
|
Description:
|
||||||
|
============
|
||||||
|
|
||||||
|
WebPMux: set of two libraries 'Mux' and 'Demux' for creation, extraction and
|
||||||
|
manipulation of an extended format WebP file, which can have features like
|
||||||
|
color profile, metadata and animation. Reference command-line tools 'webpmux'
|
||||||
|
and 'vwebp' as well as the WebP container specification
|
||||||
|
'doc/webp-container-spec.txt' are also provided in this package.
|
||||||
|
|
||||||
|
WebP Mux tool:
|
||||||
|
==============
|
||||||
|
|
||||||
|
The examples/ directory contains a tool (webpmux) for manipulating WebP
|
||||||
|
files. The webpmux tool can be used to create an extended format WebP file and
|
||||||
|
also to extract or strip relevant data from such a file.
|
||||||
|
|
||||||
|
A list of options is available using the -help command line flag:
|
||||||
|
|
||||||
|
> webpmux -help
|
||||||
|
Usage: webpmux -get GET_OPTIONS INPUT -o OUTPUT
|
||||||
|
webpmux -set SET_OPTIONS INPUT -o OUTPUT
|
||||||
|
webpmux -duration DURATION_OPTIONS [-duration ...]
|
||||||
|
INPUT -o OUTPUT
|
||||||
|
webpmux -strip STRIP_OPTIONS INPUT -o OUTPUT
|
||||||
|
webpmux -frame FRAME_OPTIONS [-frame...] [-loop LOOP_COUNT]
|
||||||
|
[-bgcolor BACKGROUND_COLOR] -o OUTPUT
|
||||||
|
webpmux -info INPUT
|
||||||
|
webpmux [-h|-help]
|
||||||
|
webpmux -version
|
||||||
|
|
||||||
|
GET_OPTIONS:
|
||||||
|
Extract relevant data:
|
||||||
|
icc get ICC profile
|
||||||
|
exif get EXIF metadata
|
||||||
|
xmp get XMP metadata
|
||||||
|
frame n get nth frame
|
||||||
|
|
||||||
|
SET_OPTIONS:
|
||||||
|
Set color profile/metadata:
|
||||||
|
icc file.icc set ICC profile
|
||||||
|
exif file.exif set EXIF metadata
|
||||||
|
xmp file.xmp set XMP metadata
|
||||||
|
where: 'file.icc' contains the ICC profile to be set,
|
||||||
|
'file.exif' contains the EXIF metadata to be set
|
||||||
|
'file.xmp' contains the XMP metadata to be set
|
||||||
|
|
||||||
|
DURATION_OPTIONS:
|
||||||
|
Set duration of selected frames:
|
||||||
|
duration set duration for each frames
|
||||||
|
duration,frame set duration of a particular frame
|
||||||
|
duration,start,end set duration of frames in the
|
||||||
|
interval [start,end])
|
||||||
|
where: 'duration' is the duration in milliseconds
|
||||||
|
'start' is the start frame index
|
||||||
|
'end' is the inclusive end frame index
|
||||||
|
The special 'end' value '0' means: last frame.
|
||||||
|
|
||||||
|
STRIP_OPTIONS:
|
||||||
|
Strip color profile/metadata:
|
||||||
|
icc strip ICC profile
|
||||||
|
exif strip EXIF metadata
|
||||||
|
xmp strip XMP metadata
|
||||||
|
|
||||||
|
FRAME_OPTIONS(i):
|
||||||
|
Create animation:
|
||||||
|
file_i +di+[xi+yi[+mi[bi]]]
|
||||||
|
where: 'file_i' is the i'th animation frame (WebP format),
|
||||||
|
'di' is the pause duration before next frame,
|
||||||
|
'xi','yi' specify the image offset for this frame,
|
||||||
|
'mi' is the dispose method for this frame (0 or 1),
|
||||||
|
'bi' is the blending method for this frame (+b or -b)
|
||||||
|
|
||||||
|
LOOP_COUNT:
|
||||||
|
Number of times to repeat the animation.
|
||||||
|
Valid range is 0 to 65535 [Default: 0 (infinite)].
|
||||||
|
|
||||||
|
BACKGROUND_COLOR:
|
||||||
|
Background color of the canvas.
|
||||||
|
A,R,G,B
|
||||||
|
where: 'A', 'R', 'G' and 'B' are integers in the range 0 to 255 specifying
|
||||||
|
the Alpha, Red, Green and Blue component values respectively
|
||||||
|
[Default: 255,255,255,255]
|
||||||
|
|
||||||
|
INPUT & OUTPUT are in WebP format.
|
||||||
|
|
||||||
|
Note: The nature of EXIF, XMP and ICC data is not checked and is assumed to be
|
||||||
|
valid.
|
||||||
|
|
||||||
|
Visualization tool:
|
||||||
|
===================
|
||||||
|
|
||||||
|
The examples/ directory also contains a tool (vwebp) for viewing WebP files.
|
||||||
|
It decodes the image and visualizes it using OpenGL. See the libwebp README
|
||||||
|
for details on building and running this program.
|
||||||
|
|
||||||
|
Mux API:
|
||||||
|
========
|
||||||
|
The Mux API contains methods for adding data to and reading data from WebP
|
||||||
|
files. This API currently supports XMP/EXIF metadata, ICC profile and animation.
|
||||||
|
Other features may be added in subsequent releases.
|
||||||
|
|
||||||
|
Example#1 (pseudo code): Creating a WebPMux object with image data, color
|
||||||
|
profile and XMP metadata.
|
||||||
|
|
||||||
|
int copy_data = 0;
|
||||||
|
WebPMux* mux = WebPMuxNew();
|
||||||
|
// ... (Prepare image data).
|
||||||
|
WebPMuxSetImage(mux, &image, copy_data);
|
||||||
|
// ... (Prepare ICC profile data).
|
||||||
|
WebPMuxSetChunk(mux, "ICCP", &icc_profile, copy_data);
|
||||||
|
// ... (Prepare XMP metadata).
|
||||||
|
WebPMuxSetChunk(mux, "XMP ", &xmp, copy_data);
|
||||||
|
// Get data from mux in WebP RIFF format.
|
||||||
|
WebPMuxAssemble(mux, &output_data);
|
||||||
|
WebPMuxDelete(mux);
|
||||||
|
// ... (Consume output_data; e.g. write output_data.bytes to file).
|
||||||
|
WebPDataClear(&output_data);
|
||||||
|
|
||||||
|
|
||||||
|
Example#2 (pseudo code): Get image and color profile data from a WebP file.
|
||||||
|
|
||||||
|
int copy_data = 0;
|
||||||
|
// ... (Read data from file).
|
||||||
|
WebPMux* mux = WebPMuxCreate(&data, copy_data);
|
||||||
|
WebPMuxGetFrame(mux, 1, &image);
|
||||||
|
// ... (Consume image; e.g. call WebPDecode() to decode the data).
|
||||||
|
WebPMuxGetChunk(mux, "ICCP", &icc_profile);
|
||||||
|
// ... (Consume icc_profile).
|
||||||
|
WebPMuxDelete(mux);
|
||||||
|
free(data);
|
||||||
|
|
||||||
|
|
||||||
|
For a detailed Mux API reference, please refer to the header file
|
||||||
|
(src/webp/mux.h).
|
||||||
|
|
||||||
|
Demux API:
|
||||||
|
==========
|
||||||
|
The Demux API enables extraction of images and extended format data from
|
||||||
|
WebP files. This API currently supports reading of XMP/EXIF metadata, ICC
|
||||||
|
profile and animated images. Other features may be added in subsequent
|
||||||
|
releases.
|
||||||
|
|
||||||
|
Code example: Demuxing WebP data to extract all the frames, ICC profile
|
||||||
|
and EXIF/XMP metadata.
|
||||||
|
|
||||||
|
WebPDemuxer* demux = WebPDemux(&webp_data);
|
||||||
|
uint32_t width = WebPDemuxGetI(demux, WEBP_FF_CANVAS_WIDTH);
|
||||||
|
uint32_t height = WebPDemuxGetI(demux, WEBP_FF_CANVAS_HEIGHT);
|
||||||
|
// ... (Get information about the features present in the WebP file).
|
||||||
|
uint32_t flags = WebPDemuxGetI(demux, WEBP_FF_FORMAT_FLAGS);
|
||||||
|
|
||||||
|
// ... (Iterate over all frames).
|
||||||
|
WebPIterator iter;
|
||||||
|
if (WebPDemuxGetFrame(demux, 1, &iter)) {
|
||||||
|
do {
|
||||||
|
// ... (Consume 'iter'; e.g. Decode 'iter.fragment' with WebPDecode(),
|
||||||
|
// ... and get other frame properties like width, height, offsets etc.
|
||||||
|
// ... see 'struct WebPIterator' below for more info).
|
||||||
|
} while (WebPDemuxNextFrame(&iter));
|
||||||
|
WebPDemuxReleaseIterator(&iter);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ... (Extract metadata).
|
||||||
|
WebPChunkIterator chunk_iter;
|
||||||
|
if (flags & ICCP_FLAG) WebPDemuxGetChunk(demux, "ICCP", 1, &chunk_iter);
|
||||||
|
// ... (Consume the ICC profile in 'chunk_iter.chunk').
|
||||||
|
WebPDemuxReleaseChunkIterator(&chunk_iter);
|
||||||
|
if (flags & EXIF_FLAG) WebPDemuxGetChunk(demux, "EXIF", 1, &chunk_iter);
|
||||||
|
// ... (Consume the EXIF metadata in 'chunk_iter.chunk').
|
||||||
|
WebPDemuxReleaseChunkIterator(&chunk_iter);
|
||||||
|
if (flags & XMP_FLAG) WebPDemuxGetChunk(demux, "XMP ", 1, &chunk_iter);
|
||||||
|
// ... (Consume the XMP metadata in 'chunk_iter.chunk').
|
||||||
|
WebPDemuxReleaseChunkIterator(&chunk_iter);
|
||||||
|
WebPDemuxDelete(demux);
|
||||||
|
|
||||||
|
|
||||||
|
For a detailed Demux API reference, please refer to the header file
|
||||||
|
(src/webp/demux.h).
|
||||||
|
|
||||||
|
AnimEncoder API:
|
||||||
|
================
|
||||||
|
The AnimEncoder API can be used to create animated WebP images.
|
||||||
|
|
||||||
|
Code example:
|
||||||
|
|
||||||
|
WebPAnimEncoderOptions enc_options;
|
||||||
|
WebPAnimEncoderOptionsInit(&enc_options);
|
||||||
|
// ... (Tune 'enc_options' as needed).
|
||||||
|
WebPAnimEncoder* enc = WebPAnimEncoderNew(width, height, &enc_options);
|
||||||
|
while(<there are more frames>) {
|
||||||
|
WebPConfig config;
|
||||||
|
WebPConfigInit(&config);
|
||||||
|
// ... (Tune 'config' as needed).
|
||||||
|
WebPAnimEncoderAdd(enc, frame, duration, &config);
|
||||||
|
}
|
||||||
|
WebPAnimEncoderAssemble(enc, webp_data);
|
||||||
|
WebPAnimEncoderDelete(enc);
|
||||||
|
// ... (Write the 'webp_data' to a file, or re-mux it further).
|
||||||
|
|
||||||
|
|
||||||
|
For a detailed AnimEncoder API reference, please refer to the header file
|
||||||
|
(src/webp/mux.h).
|
||||||
|
|
||||||
|
|
||||||
|
Bugs:
|
||||||
|
=====
|
||||||
|
|
||||||
|
Please report all bugs to the issue tracker:
|
||||||
|
https://bugs.chromium.org/p/webp
|
||||||
|
Patches welcome! See this page to get started:
|
||||||
|
http://www.webmproject.org/code/contribute/submitting-patches/
|
||||||
|
|
||||||
|
Discuss:
|
||||||
|
========
|
||||||
|
|
||||||
|
Email: webp-discuss@webmproject.org
|
||||||
|
Web: http://groups.google.com/a/webmproject.org/group/webp-discuss
|
||||||
60
build.gradle
60
build.gradle
@@ -74,22 +74,12 @@ model {
|
|||||||
cCompiler.args "-frename-registers -s"
|
cCompiler.args "-frename-registers -s"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// mips32 fails to build with clang from r14b
|
|
||||||
// https://bugs.chromium.org/p/webp/issues/detail?id=343
|
|
||||||
if (toolChain in Clang) {
|
|
||||||
if (getTargetPlatform() == "mips") {
|
|
||||||
cCompiler.args "-no-integrated-as"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Check for NEON usage.
|
// Check for NEON usage.
|
||||||
if (getTargetPlatform() == "arm") {
|
if (getTargetPlatform() == "arm" || getTargetPlatform() == "arm64") {
|
||||||
NEON = "c.neon"
|
NEON = "c.neon"
|
||||||
cCompiler.define "HAVE_CPU_FEATURES_H"
|
|
||||||
} else {
|
} else {
|
||||||
NEON = "c"
|
NEON = "c"
|
||||||
}
|
}
|
||||||
|
|
||||||
cCompiler.args "-I" + file(".").absolutePath
|
|
||||||
}
|
}
|
||||||
// Link to pthread for shared libraries.
|
// Link to pthread for shared libraries.
|
||||||
withType(SharedLibraryBinarySpec) {
|
withType(SharedLibraryBinarySpec) {
|
||||||
@@ -105,13 +95,6 @@ model {
|
|||||||
sources {
|
sources {
|
||||||
c {
|
c {
|
||||||
source {
|
source {
|
||||||
srcDir "sharpyuv"
|
|
||||||
include "sharpyuv.c"
|
|
||||||
include "sharpyuv_csp.c"
|
|
||||||
include "sharpyuv_dsp.c"
|
|
||||||
include "sharpyuv_gamma.c"
|
|
||||||
include "sharpyuv_neon.c"
|
|
||||||
include "sharpyuv_sse2.c"
|
|
||||||
srcDir "src/dec"
|
srcDir "src/dec"
|
||||||
include "alpha_dec.c"
|
include "alpha_dec.c"
|
||||||
include "buffer_dec.c"
|
include "buffer_dec.c"
|
||||||
@@ -129,6 +112,9 @@ model {
|
|||||||
include "alpha_processing_neon.$NEON"
|
include "alpha_processing_neon.$NEON"
|
||||||
include "alpha_processing_sse2.c"
|
include "alpha_processing_sse2.c"
|
||||||
include "alpha_processing_sse41.c"
|
include "alpha_processing_sse41.c"
|
||||||
|
include "argb.c"
|
||||||
|
include "argb_mips_dsp_r2.c"
|
||||||
|
include "argb_sse2.c"
|
||||||
include "cpu.c"
|
include "cpu.c"
|
||||||
include "dec.c"
|
include "dec.c"
|
||||||
include "dec_clip_tables.c"
|
include "dec_clip_tables.c"
|
||||||
@@ -148,7 +134,6 @@ model {
|
|||||||
include "lossless_msa.c"
|
include "lossless_msa.c"
|
||||||
include "lossless_neon.$NEON"
|
include "lossless_neon.$NEON"
|
||||||
include "lossless_sse2.c"
|
include "lossless_sse2.c"
|
||||||
include "lossless_sse41.c"
|
|
||||||
include "rescaler.c"
|
include "rescaler.c"
|
||||||
include "rescaler_mips32.c"
|
include "rescaler_mips32.c"
|
||||||
include "rescaler_mips_dsp_r2.c"
|
include "rescaler_mips_dsp_r2.c"
|
||||||
@@ -160,13 +145,10 @@ model {
|
|||||||
include "upsampling_msa.c"
|
include "upsampling_msa.c"
|
||||||
include "upsampling_neon.$NEON"
|
include "upsampling_neon.$NEON"
|
||||||
include "upsampling_sse2.c"
|
include "upsampling_sse2.c"
|
||||||
include "upsampling_sse41.c"
|
|
||||||
include "yuv.c"
|
include "yuv.c"
|
||||||
include "yuv_mips32.c"
|
include "yuv_mips32.c"
|
||||||
include "yuv_mips_dsp_r2.c"
|
include "yuv_mips_dsp_r2.c"
|
||||||
include "yuv_neon.$NEON"
|
|
||||||
include "yuv_sse2.c"
|
include "yuv_sse2.c"
|
||||||
include "yuv_sse41.c"
|
|
||||||
srcDir "src/utils"
|
srcDir "src/utils"
|
||||||
include "bit_reader_utils.c"
|
include "bit_reader_utils.c"
|
||||||
include "color_cache_utils.c"
|
include "color_cache_utils.c"
|
||||||
@@ -181,9 +163,9 @@ model {
|
|||||||
include "cost.c"
|
include "cost.c"
|
||||||
include "cost_mips32.c"
|
include "cost_mips32.c"
|
||||||
include "cost_mips_dsp_r2.c"
|
include "cost_mips_dsp_r2.c"
|
||||||
include "cost_neon.$NEON"
|
|
||||||
include "cost_sse2.c"
|
include "cost_sse2.c"
|
||||||
include "enc.c"
|
include "enc.c"
|
||||||
|
include "enc_avx2.c"
|
||||||
include "enc_mips32.c"
|
include "enc_mips32.c"
|
||||||
include "enc_mips_dsp_r2.c"
|
include "enc_mips_dsp_r2.c"
|
||||||
include "enc_msa.c"
|
include "enc_msa.c"
|
||||||
@@ -197,15 +179,13 @@ model {
|
|||||||
include "lossless_enc_neon.$NEON"
|
include "lossless_enc_neon.$NEON"
|
||||||
include "lossless_enc_sse2.c"
|
include "lossless_enc_sse2.c"
|
||||||
include "lossless_enc_sse41.c"
|
include "lossless_enc_sse41.c"
|
||||||
include "ssim.c"
|
|
||||||
include "ssim_sse2.c"
|
|
||||||
srcDir "src/enc"
|
srcDir "src/enc"
|
||||||
include "alpha_enc.c"
|
include "alpha_enc.c"
|
||||||
include "analysis_enc.c"
|
include "analysis_enc.c"
|
||||||
include "backward_references_cost_enc.c"
|
|
||||||
include "backward_references_enc.c"
|
include "backward_references_enc.c"
|
||||||
include "config_enc.c"
|
include "config_enc.c"
|
||||||
include "cost_enc.c"
|
include "cost_enc.c"
|
||||||
|
include "delta_palettization_enc.c"
|
||||||
include "filter_enc.c"
|
include "filter_enc.c"
|
||||||
include "frame_enc.c"
|
include "frame_enc.c"
|
||||||
include "histogram_enc.c"
|
include "histogram_enc.c"
|
||||||
@@ -297,7 +277,6 @@ model {
|
|||||||
imagedec(NativeLibrarySpec) {
|
imagedec(NativeLibrarySpec) {
|
||||||
binaries {
|
binaries {
|
||||||
all {
|
all {
|
||||||
lib library: "webpdemux", linkage: "static"
|
|
||||||
lib library: "webp", linkage: "static"
|
lib library: "webp", linkage: "static"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -309,7 +288,6 @@ model {
|
|||||||
include "jpegdec.c"
|
include "jpegdec.c"
|
||||||
include "metadata.c"
|
include "metadata.c"
|
||||||
include "pngdec.c"
|
include "pngdec.c"
|
||||||
include "pnmdec.c"
|
|
||||||
include "tiffdec.c"
|
include "tiffdec.c"
|
||||||
include "webpdec.c"
|
include "webpdec.c"
|
||||||
}
|
}
|
||||||
@@ -340,7 +318,6 @@ model {
|
|||||||
lib library: "example_util", linkage: "static"
|
lib library: "example_util", linkage: "static"
|
||||||
lib library: "imagedec", linkage: "static"
|
lib library: "imagedec", linkage: "static"
|
||||||
lib library: "imageio_util", linkage: "static"
|
lib library: "imageio_util", linkage: "static"
|
||||||
lib library: "webpdemux", linkage: "static"
|
|
||||||
lib library: "webp", linkage: "static"
|
lib library: "webp", linkage: "static"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -361,7 +338,6 @@ model {
|
|||||||
lib library: "imagedec", linkage: "static"
|
lib library: "imagedec", linkage: "static"
|
||||||
lib library: "imageenc", linkage: "static"
|
lib library: "imageenc", linkage: "static"
|
||||||
lib library: "imageio_util", linkage: "static"
|
lib library: "imageio_util", linkage: "static"
|
||||||
lib library: "webpdemux", linkage: "static"
|
|
||||||
lib library: "webp"
|
lib library: "webp"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -401,7 +377,6 @@ model {
|
|||||||
lib library: "imagedec", linkage: "static"
|
lib library: "imagedec", linkage: "static"
|
||||||
lib library: "imageio_util", linkage: "static"
|
lib library: "imageio_util", linkage: "static"
|
||||||
lib library: "webpmux", linkage: "static"
|
lib library: "webpmux", linkage: "static"
|
||||||
lib library: "webpdemux", linkage: "static"
|
|
||||||
lib library: "webp"
|
lib library: "webp"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -414,24 +389,6 @@ model {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
webpinfo_example(NativeExecutableSpec) {
|
|
||||||
binaries {
|
|
||||||
all {
|
|
||||||
lib library: "example_util", linkage: "static"
|
|
||||||
lib library: "imageio_util", linkage: "static"
|
|
||||||
lib library: "webp"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sources {
|
|
||||||
c {
|
|
||||||
source {
|
|
||||||
srcDir "./examples"
|
|
||||||
include "webpinfo.c"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
tasks {
|
tasks {
|
||||||
// Task to test all possible configurations.
|
// Task to test all possible configurations.
|
||||||
@@ -440,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 "@CMAKE_INSTALL_FULL_INCLUDEDIR@")
|
|
||||||
set(WEBP_INCLUDE_DIRS ${WebP_INCLUDE_DIRS})
|
|
||||||
set(WebP_LIBRARIES "@INSTALLED_LIBRARIES@")
|
|
||||||
set(WEBP_LIBRARIES "${WebP_LIBRARIES}")
|
|
||||||
141
cmake/config.h.cmake
Normal file
141
cmake/config.h.cmake
Normal file
@@ -0,0 +1,141 @@
|
|||||||
|
# Generate the config.h to compile with specific intrinsics / libs.
|
||||||
|
|
||||||
|
## Check for compiler options.
|
||||||
|
include(CheckCSourceCompiles)
|
||||||
|
check_c_source_compiles("
|
||||||
|
int main(void) {
|
||||||
|
(void)__builtin_bswap16(0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
HAVE_BUILTIN_BSWAP16
|
||||||
|
)
|
||||||
|
check_c_source_compiles("
|
||||||
|
int main(void) {
|
||||||
|
(void)__builtin_bswap32(0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
HAVE_BUILTIN_BSWAP32
|
||||||
|
)
|
||||||
|
check_c_source_compiles("
|
||||||
|
int main(void) {
|
||||||
|
(void)__builtin_bswap64(0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
HAVE_BUILTIN_BSWAP64
|
||||||
|
)
|
||||||
|
|
||||||
|
## Check for libraries.
|
||||||
|
find_package(Threads)
|
||||||
|
if(Threads_FOUND)
|
||||||
|
if(CMAKE_USE_PTHREADS_INIT)
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pthread")
|
||||||
|
endif()
|
||||||
|
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})
|
||||||
|
|
||||||
|
# TODO: this seems unused, check with autotools.
|
||||||
|
set(LT_OBJDIR ".libs/")
|
||||||
|
|
||||||
|
# Only useful for vwebp, so useless for now.
|
||||||
|
# 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})
|
||||||
|
|
||||||
|
# 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 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_DIRS})
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
## 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)
|
||||||
|
check_include_files(GLUT/glut.h HAVE_GLUT_GLUT_H)
|
||||||
|
check_include_files(GL/glut.h HAVE_GL_GLUT_H)
|
||||||
|
check_include_files(inttypes.h HAVE_INTTYPES_H)
|
||||||
|
check_include_files(memory.h HAVE_MEMORY_H)
|
||||||
|
check_include_files(OpenGL/glut.h HAVE_OPENGL_GLUT_H)
|
||||||
|
check_include_files(shlwapi.h HAVE_SHLWAPI_H)
|
||||||
|
check_include_files(stdint.h HAVE_STDINT_H)
|
||||||
|
check_include_files(stdlib.h HAVE_STDLIB_H)
|
||||||
|
check_include_files(strings.h HAVE_STRINGS_H)
|
||||||
|
check_include_files(string.h HAVE_STRING_H)
|
||||||
|
check_include_files(sys/stat.h HAVE_SYS_STAT_H)
|
||||||
|
check_include_files(sys/types.h HAVE_SYS_TYPES_H)
|
||||||
|
check_include_files(unistd.h HAVE_UNISTD_H)
|
||||||
|
check_include_files(wincodec.h HAVE_WINCODEC_H)
|
||||||
|
check_include_files(windows.h HAVE_WINDOWS_H)
|
||||||
|
|
||||||
|
# Windows specifics
|
||||||
|
if(HAVE_WINCODEC_H)
|
||||||
|
list(APPEND WEBP_DEP_LIBRARIES shlwapi ole32 windowscodecs)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
## Check for SIMD extensions.
|
||||||
|
include(${CMAKE_CURRENT_LIST_DIR}/cpu.cmake)
|
||||||
|
|
||||||
|
## 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}
|
||||||
|
)
|
||||||
|
function(strip_bracket VAR)
|
||||||
|
string(LENGTH ${${VAR}} TMP_LEN)
|
||||||
|
math(EXPR TMP_LEN ${TMP_LEN}-2)
|
||||||
|
string(SUBSTRING ${${VAR}} 1 ${TMP_LEN} TMP_SUB)
|
||||||
|
set(${VAR} ${TMP_SUB} PARENT_SCOPE)
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
list(GET CONFIGURE_AC_PACKAGE_INFO 1 PACKAGE_VERSION)
|
||||||
|
strip_bracket(PACKAGE_VERSION)
|
||||||
|
list(GET CONFIGURE_AC_PACKAGE_INFO 2 PACKAGE_BUGREPORT)
|
||||||
|
strip_bracket(PACKAGE_BUGREPORT)
|
||||||
|
list(GET CONFIGURE_AC_PACKAGE_INFO 3 PACKAGE_URL)
|
||||||
|
strip_bracket(PACKAGE_URL)
|
||||||
|
|
||||||
|
# Build more info.
|
||||||
|
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 */
|
/* Set to 1 if __builtin_bswap64 is available */
|
||||||
#cmakedefine HAVE_BUILTIN_BSWAP64 1
|
#cmakedefine HAVE_BUILTIN_BSWAP64 1
|
||||||
|
|
||||||
/* Define to 1 if you have the <cpu-features.h> header file. */
|
|
||||||
#cmakedefine HAVE_CPU_FEATURES_H 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <dlfcn.h> header file. */
|
/* Define to 1 if you have the <dlfcn.h> header file. */
|
||||||
#cmakedefine HAVE_DLFCN_H 1
|
#cmakedefine HAVE_DLFCN_H 1
|
||||||
|
|
||||||
@@ -93,12 +90,22 @@
|
|||||||
/* Define to the version of this package. */
|
/* Define to the version of this package. */
|
||||||
#cmakedefine PACKAGE_VERSION "@PACKAGE_VERSION@"
|
#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. */
|
/* Define to 1 if you have the ANSI C header files. */
|
||||||
#cmakedefine STDC_HEADERS 1
|
#cmakedefine STDC_HEADERS 1
|
||||||
|
|
||||||
/* Version number of package */
|
/* Version number of package */
|
||||||
#cmakedefine VERSION "@VERSION@"
|
#cmakedefine VERSION "@VERSION@"
|
||||||
|
|
||||||
|
/* Enable experimental code */
|
||||||
|
#cmakedefine WEBP_EXPERIMENTAL_FEATURES 1
|
||||||
|
|
||||||
|
/* Set to 1 if AVX2 is supported */
|
||||||
|
#cmakedefine WEBP_HAVE_AVX2 1
|
||||||
|
|
||||||
/* Set to 1 if GIF library is installed */
|
/* Set to 1 if GIF library is installed */
|
||||||
#cmakedefine WEBP_HAVE_GIF 1
|
#cmakedefine WEBP_HAVE_GIF 1
|
||||||
|
|
||||||
@@ -108,19 +115,9 @@
|
|||||||
/* Set to 1 if JPEG library is installed */
|
/* Set to 1 if JPEG library is installed */
|
||||||
#cmakedefine WEBP_HAVE_JPEG 1
|
#cmakedefine WEBP_HAVE_JPEG 1
|
||||||
|
|
||||||
/* Set to 1 if NEON is supported */
|
|
||||||
#cmakedefine WEBP_HAVE_NEON
|
|
||||||
|
|
||||||
/* Set to 1 if runtime detection of NEON is enabled */
|
|
||||||
/* TODO: handle properly in CMake */
|
|
||||||
#cmakedefine WEBP_HAVE_NEON_RTCD
|
|
||||||
|
|
||||||
/* Set to 1 if PNG library is installed */
|
/* Set to 1 if PNG library is installed */
|
||||||
#cmakedefine WEBP_HAVE_PNG 1
|
#cmakedefine WEBP_HAVE_PNG 1
|
||||||
|
|
||||||
/* Set to 1 if SDL library is installed */
|
|
||||||
#cmakedefine WEBP_HAVE_SDL 1
|
|
||||||
|
|
||||||
/* Set to 1 if SSE2 is supported */
|
/* Set to 1 if SSE2 is supported */
|
||||||
#cmakedefine WEBP_HAVE_SSE2 1
|
#cmakedefine WEBP_HAVE_SSE2 1
|
||||||
|
|
||||||
@@ -130,9 +127,6 @@
|
|||||||
/* Set to 1 if TIFF library is installed */
|
/* Set to 1 if TIFF library is installed */
|
||||||
#cmakedefine WEBP_HAVE_TIFF 1
|
#cmakedefine WEBP_HAVE_TIFF 1
|
||||||
|
|
||||||
/* Enable near lossless encoding */
|
|
||||||
#cmakedefine WEBP_NEAR_LOSSLESS 1
|
|
||||||
|
|
||||||
/* Undefine this to disable thread support. */
|
/* Undefine this to disable thread support. */
|
||||||
#cmakedefine WEBP_USE_THREAD 1
|
#cmakedefine WEBP_USE_THREAD 1
|
||||||
|
|
||||||
|
|||||||
101
cmake/cpu.cmake
101
cmake/cpu.cmake
@@ -1,23 +1,7 @@
|
|||||||
# Copyright (c) 2021 Google LLC.
|
## Check for SIMD extensions.
|
||||||
#
|
|
||||||
# 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.
|
|
||||||
|
|
||||||
# Check for SIMD extensions.
|
function(webp_check_compiler_flag WEBP_SIMD_FLAG)
|
||||||
include(CMakePushCheckState)
|
|
||||||
|
|
||||||
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()
|
|
||||||
unset(WEBP_HAVE_FLAG_${WEBP_SIMD_FLAG} CACHE)
|
unset(WEBP_HAVE_FLAG_${WEBP_SIMD_FLAG} CACHE)
|
||||||
cmake_push_check_state()
|
|
||||||
set(CMAKE_REQUIRED_INCLUDES ${CMAKE_CURRENT_SOURCE_DIR})
|
|
||||||
check_c_source_compiles("
|
check_c_source_compiles("
|
||||||
#include \"${CMAKE_CURRENT_LIST_DIR}/../src/dsp/dsp.h\"
|
#include \"${CMAKE_CURRENT_LIST_DIR}/../src/dsp/dsp.h\"
|
||||||
int main(void) {
|
int main(void) {
|
||||||
@@ -26,8 +10,8 @@ function(webp_check_compiler_flag WEBP_SIMD_FLAG ENABLE_SIMD)
|
|||||||
#endif
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
" WEBP_HAVE_FLAG_${WEBP_SIMD_FLAG})
|
" WEBP_HAVE_FLAG_${WEBP_SIMD_FLAG}
|
||||||
cmake_pop_check_state()
|
)
|
||||||
if(WEBP_HAVE_FLAG_${WEBP_SIMD_FLAG})
|
if(WEBP_HAVE_FLAG_${WEBP_SIMD_FLAG})
|
||||||
set(WEBP_HAVE_${WEBP_SIMD_FLAG} 1 PARENT_SCOPE)
|
set(WEBP_HAVE_${WEBP_SIMD_FLAG} 1 PARENT_SCOPE)
|
||||||
else()
|
else()
|
||||||
@@ -36,26 +20,16 @@ function(webp_check_compiler_flag WEBP_SIMD_FLAG ENABLE_SIMD)
|
|||||||
endfunction()
|
endfunction()
|
||||||
|
|
||||||
# those are included in the names of WEBP_USE_* in c++ code.
|
# 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_FLAGS "SSE2;SSE41;AVX2;MIPS32;MIPS_DSP_R2;NEON;MSA")
|
||||||
set(WEBP_SIMD_FILE_EXTENSIONS
|
set(WEBP_SIMD_FILE_EXTENSIONS "_sse2.c;_sse41.c;_avx2.c;_mips32.c;_mips_dsp_r2.c;_neon.c;_msa.c")
|
||||||
"_sse41.c;_sse2.c;_mips32.c;_mips_dsp_r2.c;_neon.c;_msa.c")
|
if(MSVC)
|
||||||
if(MSVC AND CMAKE_C_COMPILER_ID STREQUAL "MSVC")
|
# MSVC does not have a SSE4 flag but AVX2 support implies
|
||||||
# With at least Visual Studio 12 (2013)+ /arch is not necessary to build SSE2
|
# SSE4 support.
|
||||||
# or SSE4 code unless a lesser /arch is forced. MSVC does not have a SSE4
|
set(SIMD_ENABLE_FLAGS "/arch:SSE2;/arch:AVX2;/arch:AVX2;;;;")
|
||||||
# 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(SIMD_DISABLE_FLAGS)
|
set(SIMD_DISABLE_FLAGS)
|
||||||
else()
|
else()
|
||||||
set(SIMD_ENABLE_FLAGS
|
set(SIMD_ENABLE_FLAGS "-msse2;-msse4.1;-mavx2;-mips32;-mdspr2;-mfpu=neon;-mmsa")
|
||||||
"-msse4.1;-msse2;-mips32;-mdspr2;-mfpu=neon;-mmsa")
|
set(SIMD_DISABLE_FLAGS "-mno-sse2;-mno-sse4.1;-mno-avx2;;-mno-dspr2;;-mno-msa")
|
||||||
set(SIMD_DISABLE_FLAGS
|
|
||||||
"-mno-sse4.1;-mno-sse2;;-mno-dspr2;;-mno-msa")
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(WEBP_SIMD_FILES_TO_NOT_INCLUDE)
|
set(WEBP_SIMD_FILES_TO_NOT_INCLUDE)
|
||||||
@@ -64,9 +38,10 @@ set(WEBP_SIMD_FLAGS_TO_INCLUDE)
|
|||||||
|
|
||||||
if(${ANDROID})
|
if(${ANDROID})
|
||||||
if(${ANDROID_ABI} STREQUAL "armeabi-v7a")
|
if(${ANDROID_ABI} STREQUAL "armeabi-v7a")
|
||||||
# This is because Android studio uses the configuration "-march=armv7-a
|
# This is because Android studio uses the configuration
|
||||||
# -mfloat-abi=softfp -mfpu=vfpv3-d16" that does not trigger neon
|
# "-march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16"
|
||||||
# optimizations but should (as this configuration does not exist anymore).
|
# that does not trigger neon optimizations but should
|
||||||
|
# (as this configuration does not exist anymore).
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mfpu=neon ")
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mfpu=neon ")
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
@@ -75,40 +50,25 @@ list(LENGTH WEBP_SIMD_FLAGS WEBP_SIMD_FLAGS_LENGTH)
|
|||||||
math(EXPR WEBP_SIMD_FLAGS_RANGE "${WEBP_SIMD_FLAGS_LENGTH} - 1")
|
math(EXPR WEBP_SIMD_FLAGS_RANGE "${WEBP_SIMD_FLAGS_LENGTH} - 1")
|
||||||
|
|
||||||
foreach(I_SIMD RANGE ${WEBP_SIMD_FLAGS_RANGE})
|
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)
|
list(GET WEBP_SIMD_FLAGS ${I_SIMD} WEBP_SIMD_FLAG)
|
||||||
|
|
||||||
# First try with no extra flag added as the compiler might have default flags
|
# First try with no extra flag added as the compiler might have default flags
|
||||||
# (especially on Android).
|
# (especially on Android).
|
||||||
unset(WEBP_HAVE_${WEBP_SIMD_FLAG} CACHE)
|
unset(WEBP_HAVE_${WEBP_SIMD_FLAG} CACHE)
|
||||||
cmake_push_check_state()
|
|
||||||
set(CMAKE_REQUIRED_FLAGS)
|
set(CMAKE_REQUIRED_FLAGS)
|
||||||
webp_check_compiler_flag(${WEBP_SIMD_FLAG} ${WEBP_ENABLE_SIMD})
|
webp_check_compiler_flag(${WEBP_SIMD_FLAG})
|
||||||
if(NOT WEBP_HAVE_${WEBP_SIMD_FLAG})
|
if(NOT WEBP_HAVE_${WEBP_SIMD_FLAG})
|
||||||
list(GET SIMD_ENABLE_FLAGS ${I_SIMD} SIMD_COMPILE_FLAG)
|
list(GET SIMD_ENABLE_FLAGS ${I_SIMD} SIMD_COMPILE_FLAG)
|
||||||
if(EMSCRIPTEN)
|
|
||||||
set(SIMD_COMPILE_FLAG "-msimd128 ${SIMD_COMPILE_FLAG}")
|
|
||||||
endif()
|
|
||||||
set(CMAKE_REQUIRED_FLAGS ${SIMD_COMPILE_FLAG})
|
set(CMAKE_REQUIRED_FLAGS ${SIMD_COMPILE_FLAG})
|
||||||
webp_check_compiler_flag(${WEBP_SIMD_FLAG} ${WEBP_ENABLE_SIMD})
|
webp_check_compiler_flag(${WEBP_SIMD_FLAG})
|
||||||
else()
|
else()
|
||||||
if(MSVC AND SIMD_ENABLE_FLAGS)
|
set(SIMD_COMPILE_FLAG " ")
|
||||||
# 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()
|
|
||||||
endif()
|
endif()
|
||||||
# Check which files we should include or not.
|
# Check which files we should include or not.
|
||||||
list(GET WEBP_SIMD_FILE_EXTENSIONS ${I_SIMD} WEBP_SIMD_FILE_EXTENSION)
|
list(GET WEBP_SIMD_FILE_EXTENSIONS ${I_SIMD} WEBP_SIMD_FILE_EXTENSION)
|
||||||
file(GLOB SIMD_FILES "${CMAKE_CURRENT_LIST_DIR}/../"
|
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})
|
if(WEBP_HAVE_${WEBP_SIMD_FLAG})
|
||||||
# Memorize the file and flags.
|
# Memorize the file and flags.
|
||||||
foreach(FILE ${SIMD_FILES})
|
foreach(FILE ${SIMD_FILES})
|
||||||
@@ -125,12 +85,6 @@ foreach(I_SIMD RANGE ${WEBP_SIMD_FLAGS_RANGE})
|
|||||||
list(GET SIMD_DISABLE_FLAGS ${I_SIMD} SIMD_COMPILE_FLAG)
|
list(GET SIMD_DISABLE_FLAGS ${I_SIMD} SIMD_COMPILE_FLAG)
|
||||||
include(CheckCCompilerFlag)
|
include(CheckCCompilerFlag)
|
||||||
if(SIMD_COMPILE_FLAG)
|
if(SIMD_COMPILE_FLAG)
|
||||||
# Between 3.17.0 and 3.18.2 check_cxx_compiler_flag() sets a normal
|
|
||||||
# variable at parent scope while check_cxx_source_compiles() continues
|
|
||||||
# to set an internal cache variable, so we unset both to avoid the
|
|
||||||
# failure / success state persisting between checks. See
|
|
||||||
# https://gitlab.kitware.com/cmake/cmake/-/issues/21207.
|
|
||||||
unset(HAS_COMPILE_FLAG)
|
|
||||||
unset(HAS_COMPILE_FLAG CACHE)
|
unset(HAS_COMPILE_FLAG CACHE)
|
||||||
check_c_compiler_flag(${SIMD_COMPILE_FLAG} HAS_COMPILE_FLAG)
|
check_c_compiler_flag(${SIMD_COMPILE_FLAG} HAS_COMPILE_FLAG)
|
||||||
if(HAS_COMPILE_FLAG)
|
if(HAS_COMPILE_FLAG)
|
||||||
@@ -142,13 +96,11 @@ foreach(I_SIMD RANGE ${WEBP_SIMD_FLAGS_RANGE})
|
|||||||
set(COMMON_PATTERNS)
|
set(COMMON_PATTERNS)
|
||||||
endif()
|
endif()
|
||||||
set(CMAKE_REQUIRED_DEFINITIONS ${SIMD_COMPILE_FLAG})
|
set(CMAKE_REQUIRED_DEFINITIONS ${SIMD_COMPILE_FLAG})
|
||||||
check_c_source_compiles("int main(void) {return 0;}"
|
check_c_source_compiles("int main(void) {return 0;}" FLAG2
|
||||||
FLAG_${SIMD_COMPILE_FLAG}
|
FAIL_REGEX "warning: argument unused during compilation:"
|
||||||
FAIL_REGEX
|
${COMMON_PATTERNS}
|
||||||
"warning: argument unused during compilation:"
|
)
|
||||||
${COMMON_PATTERNS})
|
if(NOT FLAG2)
|
||||||
if(NOT FLAG_${SIMD_COMPILE_FLAG})
|
|
||||||
unset(HAS_COMPILE_FLAG)
|
|
||||||
unset(HAS_COMPILE_FLAG CACHE)
|
unset(HAS_COMPILE_FLAG CACHE)
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
@@ -158,5 +110,4 @@ foreach(I_SIMD RANGE ${WEBP_SIMD_FLAGS_RANGE})
|
|||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
cmake_pop_check_state()
|
|
||||||
endforeach()
|
endforeach()
|
||||||
|
|||||||
185
cmake/deps.cmake
185
cmake/deps.cmake
@@ -1,185 +0,0 @@
|
|||||||
# Copyright (c) 2021 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.
|
|
||||||
|
|
||||||
# Generate the config.h to compile with specific intrinsics / libs.
|
|
||||||
|
|
||||||
# Check for compiler options.
|
|
||||||
include(CheckCSourceCompiles)
|
|
||||||
check_c_source_compiles("
|
|
||||||
int main(void) {
|
|
||||||
(void)__builtin_bswap16(0);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
" HAVE_BUILTIN_BSWAP16)
|
|
||||||
check_c_source_compiles("
|
|
||||||
int main(void) {
|
|
||||||
(void)__builtin_bswap32(0);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
" HAVE_BUILTIN_BSWAP32)
|
|
||||||
check_c_source_compiles("
|
|
||||||
int main(void) {
|
|
||||||
(void)__builtin_bswap64(0);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
" HAVE_BUILTIN_BSWAP64)
|
|
||||||
|
|
||||||
# Check for libraries.
|
|
||||||
if(WEBP_USE_THREAD)
|
|
||||||
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")
|
|
||||||
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})
|
|
||||||
list(APPEND WEBP_DEP_LIBRARIES Threads::Threads)
|
|
||||||
endif()
|
|
||||||
set(WEBP_USE_THREAD ${Threads_FOUND})
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# TODO: this seems unused, check with autotools.
|
|
||||||
set(LT_OBJDIR ".libs/")
|
|
||||||
|
|
||||||
# Only useful for vwebp, so useless for now.
|
|
||||||
find_package(OpenGL)
|
|
||||||
set(WEBP_HAVE_GL ${OPENGL_FOUND})
|
|
||||||
|
|
||||||
# Check if we need to link to the C math library. We do not look for it as it is
|
|
||||||
# not found when cross-compiling, while it is here.
|
|
||||||
check_c_source_compiles("
|
|
||||||
#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)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Find the standard image libraries.
|
|
||||||
set(WEBP_DEP_IMG_LIBRARIES)
|
|
||||||
set(WEBP_DEP_IMG_INCLUDE_DIRS)
|
|
||||||
foreach(I_LIB PNG JPEG TIFF)
|
|
||||||
# Disable tiff when compiling in static mode as it is failing on Ubuntu.
|
|
||||||
if(WEBP_LINK_STATIC AND ${I_LIB} STREQUAL "TIFF")
|
|
||||||
message("TIFF is disabled when statically linking.")
|
|
||||||
continue()
|
|
||||||
endif()
|
|
||||||
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})
|
|
||||||
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.
|
|
||||||
include(CheckIncludeFiles)
|
|
||||||
check_include_files("stdlib.h;stdarg.h;string.h;float.h" STDC_HEADERS)
|
|
||||||
check_include_files(dlfcn.h HAVE_DLFCN_H)
|
|
||||||
check_include_files(GLUT/glut.h HAVE_GLUT_GLUT_H)
|
|
||||||
check_include_files(GL/glut.h HAVE_GL_GLUT_H)
|
|
||||||
check_include_files(inttypes.h HAVE_INTTYPES_H)
|
|
||||||
check_include_files(memory.h HAVE_MEMORY_H)
|
|
||||||
check_include_files(OpenGL/glut.h HAVE_OPENGL_GLUT_H)
|
|
||||||
check_include_files(shlwapi.h HAVE_SHLWAPI_H)
|
|
||||||
check_include_files(stdint.h HAVE_STDINT_H)
|
|
||||||
check_include_files(stdlib.h HAVE_STDLIB_H)
|
|
||||||
check_include_files(strings.h HAVE_STRINGS_H)
|
|
||||||
check_include_files(string.h HAVE_STRING_H)
|
|
||||||
check_include_files(sys/stat.h HAVE_SYS_STAT_H)
|
|
||||||
check_include_files(sys/types.h HAVE_SYS_TYPES_H)
|
|
||||||
check_include_files(unistd.h HAVE_UNISTD_H)
|
|
||||||
check_include_files(wincodec.h HAVE_WINCODEC_H)
|
|
||||||
check_include_files(windows.h HAVE_WINDOWS_H)
|
|
||||||
|
|
||||||
# Windows specifics
|
|
||||||
if(HAVE_WINCODEC_H)
|
|
||||||
list(APPEND WEBP_DEP_LIBRARIES
|
|
||||||
shlwapi
|
|
||||||
ole32
|
|
||||||
windowscodecs)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Check for SIMD extensions.
|
|
||||||
include(${CMAKE_CURRENT_LIST_DIR}/cpu.cmake)
|
|
||||||
|
|
||||||
# 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})
|
|
||||||
function(strip_bracket VAR)
|
|
||||||
string(LENGTH ${${VAR}} TMP_LEN)
|
|
||||||
math(EXPR TMP_LEN ${TMP_LEN}-2)
|
|
||||||
string(SUBSTRING ${${VAR}}
|
|
||||||
1
|
|
||||||
${TMP_LEN}
|
|
||||||
TMP_SUB)
|
|
||||||
set(${VAR} ${TMP_SUB} PARENT_SCOPE)
|
|
||||||
endfunction()
|
|
||||||
|
|
||||||
list(GET CONFIGURE_AC_PACKAGE_INFO 1 PACKAGE_VERSION)
|
|
||||||
strip_bracket(PACKAGE_VERSION)
|
|
||||||
list(GET CONFIGURE_AC_PACKAGE_INFO 2 PACKAGE_BUGREPORT)
|
|
||||||
strip_bracket(PACKAGE_BUGREPORT)
|
|
||||||
list(GET CONFIGURE_AC_PACKAGE_INFO 3 PACKAGE_URL)
|
|
||||||
strip_bracket(PACKAGE_URL)
|
|
||||||
|
|
||||||
# Build more info.
|
|
||||||
set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}")
|
|
||||||
set(PACKAGE_TARNAME ${PACKAGE_NAME})
|
|
||||||
set(VERSION ${PACKAGE_VERSION})
|
|
||||||
@@ -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
|
|
||||||
244
configure.ac
244
configure.ac
@@ -1,6 +1,6 @@
|
|||||||
AC_INIT([libwebp], [1.2.3],
|
AC_INIT([libwebp], [0.6.0],
|
||||||
[https://bugs.chromium.org/p/webp],,
|
[https://bugs.chromium.org/p/webp],,
|
||||||
[https://developers.google.com/speed/webp])
|
[http://developers.google.com/speed/webp])
|
||||||
AC_CANONICAL_HOST
|
AC_CANONICAL_HOST
|
||||||
AC_PREREQ([2.60])
|
AC_PREREQ([2.60])
|
||||||
AM_INIT_AUTOMAKE([-Wall foreign subdir-objects])
|
AM_INIT_AUTOMAKE([-Wall foreign subdir-objects])
|
||||||
@@ -9,8 +9,7 @@ dnl === automake >= 1.12 requires this for 'unusual archivers' support.
|
|||||||
dnl === it must occur before LT_INIT (AC_PROG_LIBTOOL).
|
dnl === it must occur before LT_INIT (AC_PROG_LIBTOOL).
|
||||||
m4_ifdef([AM_PROG_AR], [AM_PROG_AR])
|
m4_ifdef([AM_PROG_AR], [AM_PROG_AR])
|
||||||
|
|
||||||
dnl === AC_PROG_LIBTOOL is deprecated.
|
AC_PROG_LIBTOOL
|
||||||
m4_ifdef([LT_INIT], [LT_INIT], [AC_PROG_LIBTOOL])
|
|
||||||
AC_PROG_SED
|
AC_PROG_SED
|
||||||
AM_PROG_CC_C_O
|
AM_PROG_CC_C_O
|
||||||
|
|
||||||
@@ -28,46 +27,11 @@ AC_ARG_ENABLE([everything],
|
|||||||
AS_HELP_STRING([--enable-everything],
|
AS_HELP_STRING([--enable-everything],
|
||||||
[Enable all optional targets. These can still be
|
[Enable all optional targets. These can still be
|
||||||
disabled with --disable-target]),
|
disabled with --disable-target]),
|
||||||
[SET_IF_UNSET([enable_libsharpyuv], [$enableval])
|
[SET_IF_UNSET([enable_libwebpdecoder], [$enableval])
|
||||||
SET_IF_UNSET([enable_libwebpdecoder], [$enableval])
|
|
||||||
SET_IF_UNSET([enable_libwebpdemux], [$enableval])
|
SET_IF_UNSET([enable_libwebpdemux], [$enableval])
|
||||||
SET_IF_UNSET([enable_libwebpextras], [$enableval])
|
SET_IF_UNSET([enable_libwebpextras], [$enableval])
|
||||||
SET_IF_UNSET([enable_libwebpmux], [$enableval])])
|
SET_IF_UNSET([enable_libwebpmux], [$enableval])])
|
||||||
|
|
||||||
dnl === Check whether libwebpmux should be built
|
|
||||||
AC_MSG_CHECKING(whether libwebpmux is to be built)
|
|
||||||
AC_ARG_ENABLE([libwebpmux],
|
|
||||||
AS_HELP_STRING([--disable-libwebpmux],
|
|
||||||
[Disable libwebpmux @<:@default=no@:>@]),
|
|
||||||
[], [enable_libwebpmux=yes])
|
|
||||||
AC_MSG_RESULT(${enable_libwebpmux-no})
|
|
||||||
AM_CONDITIONAL([BUILD_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])
|
|
||||||
AC_MSG_RESULT(${enable_libwebpdemux-no})
|
|
||||||
AM_CONDITIONAL([BUILD_DEMUX], [test "$enable_libwebpdemux" = "yes"])
|
|
||||||
|
|
||||||
dnl === Check whether decoder library should be built.
|
|
||||||
AC_MSG_CHECKING(whether decoder library is to be built)
|
|
||||||
AC_ARG_ENABLE([libwebpdecoder],
|
|
||||||
AS_HELP_STRING([--enable-libwebpdecoder],
|
|
||||||
[Build libwebpdecoder @<:@default=no@:>@]))
|
|
||||||
AC_MSG_RESULT(${enable_libwebpdecoder-no})
|
|
||||||
AM_CONDITIONAL([BUILD_LIBWEBPDECODER], [test "$enable_libwebpdecoder" = "yes"])
|
|
||||||
|
|
||||||
dnl === Check whether libwebpextras should be built
|
|
||||||
AC_MSG_CHECKING(whether libwebpextras is to be built)
|
|
||||||
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"])
|
|
||||||
|
|
||||||
dnl === If --enable-asserts is not defined, define NDEBUG
|
dnl === If --enable-asserts is not defined, define NDEBUG
|
||||||
|
|
||||||
AC_MSG_CHECKING(whether asserts are enabled)
|
AC_MSG_CHECKING(whether asserts are enabled)
|
||||||
@@ -103,7 +67,6 @@ AC_DEFUN([TEST_AND_ADD_CFLAGS],
|
|||||||
CFLAGS="$SAVED_CFLAGS"])
|
CFLAGS="$SAVED_CFLAGS"])
|
||||||
TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-fvisibility=hidden])
|
TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-fvisibility=hidden])
|
||||||
TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wall])
|
TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wall])
|
||||||
TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wconstant-conversion])
|
|
||||||
TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wdeclaration-after-statement])
|
TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wdeclaration-after-statement])
|
||||||
TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wextra])
|
TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wextra])
|
||||||
TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wfloat-conversion])
|
TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wfloat-conversion])
|
||||||
@@ -112,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-declarations])
|
||||||
TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wmissing-prototypes])
|
TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wmissing-prototypes])
|
||||||
TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wold-style-definition])
|
TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wold-style-definition])
|
||||||
TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wparentheses-equality])
|
|
||||||
TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wshadow])
|
TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wshadow])
|
||||||
TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wshorten-64-to-32])
|
TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wshorten-64-to-32])
|
||||||
TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wundef])
|
|
||||||
TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wunreachable-code-aggressive])
|
|
||||||
TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wunreachable-code])
|
TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wunreachable-code])
|
||||||
TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wunused-but-set-variable])
|
TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wunused-but-set-variable])
|
||||||
TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wunused])
|
TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wunused])
|
||||||
@@ -159,6 +119,31 @@ AS_IF([test "$GCC" = "yes" ], [
|
|||||||
AC_SUBST([AM_CFLAGS])
|
AC_SUBST([AM_CFLAGS])
|
||||||
|
|
||||||
dnl === Check for machine specific flags
|
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],
|
AC_ARG_ENABLE([sse4.1],
|
||||||
AS_HELP_STRING([--disable-sse4.1],
|
AS_HELP_STRING([--disable-sse4.1],
|
||||||
[Disable detection of SSE4.1 support
|
[Disable detection of SSE4.1 support
|
||||||
@@ -256,16 +241,9 @@ AS_IF([test "x$enable_neon" != "xno"], [
|
|||||||
NEON_FLAGS=""],
|
NEON_FLAGS=""],
|
||||||
[AC_DEFINE(WEBP_HAVE_NEON_RTCD, [1],
|
[AC_DEFINE(WEBP_HAVE_NEON_RTCD, [1],
|
||||||
[Set to 1 if runtime detection of NEON is enabled])])])
|
[Set to 1 if runtime detection of NEON is enabled])])])
|
||||||
|
;;
|
||||||
case "$host_os" in
|
esac
|
||||||
*android*) AC_CHECK_HEADERS([cpu-features.h]) ;;
|
AC_SUBST([NEON_FLAGS])])
|
||||||
esac
|
|
||||||
;;
|
|
||||||
aarch64*|arm64*)
|
|
||||||
AC_DEFINE(WEBP_HAVE_NEON, [1], [Set to 1 if NEON is supported])
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
AC_SUBST([NEON_FLAGS])])
|
|
||||||
|
|
||||||
dnl === CLEAR_LIBVARS([var_pfx])
|
dnl === CLEAR_LIBVARS([var_pfx])
|
||||||
dnl === Clears <var_pfx>_{INCLUDES,LIBS}.
|
dnl === Clears <var_pfx>_{INCLUDES,LIBS}.
|
||||||
@@ -362,8 +340,6 @@ AS_IF([test "x$enable_gl" != "xno"], [
|
|||||||
# override with --with-gl*
|
# override with --with-gl*
|
||||||
glut_cflags="$glut_cflags|-framework GLUT -framework OpenGL"
|
glut_cflags="$glut_cflags|-framework GLUT -framework OpenGL"
|
||||||
glut_ldflags="$glut_ldflags|-framework GLUT -framework OpenGL"
|
glut_ldflags="$glut_ldflags|-framework GLUT -framework OpenGL"
|
||||||
# quiet deprecation warnings for glut
|
|
||||||
TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wno-deprecated-declarations])
|
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
@@ -448,75 +424,10 @@ AS_IF([test "x$enable_gl" != "xno"], [
|
|||||||
|
|
||||||
if test "$glut_support" = "yes" -a "$enable_libwebpdemux" = "yes"; then
|
if test "$glut_support" = "yes" -a "$enable_libwebpdemux" = "yes"; then
|
||||||
build_vwebp=yes
|
build_vwebp=yes
|
||||||
else
|
|
||||||
AC_MSG_NOTICE(
|
|
||||||
m4_normalize([Not building vwebp.
|
|
||||||
OpenGL libraries and --enable-libwebpdemux are required.]))
|
|
||||||
fi
|
fi
|
||||||
])
|
])
|
||||||
AM_CONDITIONAL([BUILD_VWEBP], [test "$build_vwebp" = "yes"])
|
AM_CONDITIONAL([BUILD_VWEBP], [test "$build_vwebp" = "yes"])
|
||||||
|
|
||||||
dnl === check for SDL support ===
|
|
||||||
|
|
||||||
AC_ARG_ENABLE([sdl],
|
|
||||||
AS_HELP_STRING([--disable-sdl],
|
|
||||||
[Disable detection of SDL support
|
|
||||||
@<:@default=auto@:>@]))
|
|
||||||
AS_IF([test "x$enable_sdl" != "xno"], [
|
|
||||||
CLEAR_LIBVARS([SDL])
|
|
||||||
AC_PATH_PROGS([LIBSDL_CONFIG], [sdl-config])
|
|
||||||
if test -n "$LIBSDL_CONFIG"; then
|
|
||||||
SDL_INCLUDES=`$LIBSDL_CONFIG --cflags`
|
|
||||||
SDL_LIBS="`$LIBSDL_CONFIG --libs`"
|
|
||||||
fi
|
|
||||||
|
|
||||||
WITHLIB_OPTION([sdl], [SDL])
|
|
||||||
|
|
||||||
sdl_header="no"
|
|
||||||
LIBCHECK_PROLOGUE([SDL])
|
|
||||||
AC_CHECK_HEADER([SDL/SDL.h], [sdl_header="SDL/SDL.h"],
|
|
||||||
[AC_CHECK_HEADER([SDL.h], [sdl_header="SDL.h"],
|
|
||||||
[AC_MSG_WARN(SDL library not available - no sdl.h)])])
|
|
||||||
if test x"$sdl_header" != "xno"; then
|
|
||||||
AC_LANG_PUSH(C)
|
|
||||||
SDL_SAVED_LIBS="$LIBS"
|
|
||||||
for lib in "" "-lSDL" "-lSDLmain -lSDL"; do
|
|
||||||
LIBS="$SDL_SAVED_LIBS $lib"
|
|
||||||
# Perform a full link to ensure SDL_main is resolved if needed.
|
|
||||||
AC_LINK_IFELSE(
|
|
||||||
[AC_LANG_SOURCE([
|
|
||||||
#include <$sdl_header>
|
|
||||||
int main(int argc, char** argv) {
|
|
||||||
SDL_Init(0);
|
|
||||||
return 0;
|
|
||||||
}])],
|
|
||||||
[SDL_LIBS="$LDFLAGS $LIBS"
|
|
||||||
SDL_INCLUDES="$SDL_INCLUDES -DWEBP_HAVE_SDL"
|
|
||||||
AC_DEFINE(WEBP_HAVE_SDL, [1],
|
|
||||||
[Set to 1 if SDL library is installed])
|
|
||||||
sdl_support=yes]
|
|
||||||
)
|
|
||||||
if test x"$sdl_support" = "xyes"; then
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
# LIBS is restored by LIBCHECK_EPILOGUE
|
|
||||||
AC_LANG_POP
|
|
||||||
if test x"$sdl_header" = "xSDL.h"; then
|
|
||||||
SDL_INCLUDES="$SDL_INCLUDES -DWEBP_HAVE_JUST_SDL_H"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
LIBCHECK_EPILOGUE([SDL])
|
|
||||||
|
|
||||||
if test x"$sdl_support" = "xyes"; then
|
|
||||||
build_vwebp_sdl=yes
|
|
||||||
else
|
|
||||||
AC_MSG_NOTICE([Not building vwebp-sdl. SDL library is required.])
|
|
||||||
fi
|
|
||||||
])
|
|
||||||
|
|
||||||
AM_CONDITIONAL([BUILD_VWEBP_SDL], [test "$build_vwebp_sdl" = "yes"])
|
|
||||||
|
|
||||||
dnl === check for PNG support ===
|
dnl === check for PNG support ===
|
||||||
|
|
||||||
AC_ARG_ENABLE([png], AS_HELP_STRING([--disable-png],
|
AC_ARG_ENABLE([png], AS_HELP_STRING([--disable-png],
|
||||||
@@ -634,39 +545,22 @@ AS_IF([test "x$enable_gif" != "xno"], [
|
|||||||
|
|
||||||
if test "$gif_support" = "yes" -a \
|
if test "$gif_support" = "yes" -a \
|
||||||
"$enable_libwebpdemux" = "yes"; then
|
"$enable_libwebpdemux" = "yes"; then
|
||||||
build_anim_diff=yes
|
build_animdiff=yes
|
||||||
else
|
|
||||||
AC_MSG_NOTICE(
|
|
||||||
[Not building anim_diff. libgif and --enable-libwebpdemux are required.])
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if test "$gif_support" = "yes" -a \
|
if test "$gif_support" = "yes" -a \
|
||||||
"$enable_libwebpmux" = "yes"; then
|
"$enable_libwebpmux" = "yes"; then
|
||||||
build_gif2webp=yes
|
build_gif2webp=yes
|
||||||
else
|
|
||||||
AC_MSG_NOTICE(
|
|
||||||
[Not building gif2webp. libgif and --enable-libwebpmux are required.])
|
|
||||||
fi
|
fi
|
||||||
])
|
])
|
||||||
AM_CONDITIONAL([BUILD_ANIMDIFF], [test "${build_anim_diff}" = "yes"])
|
AM_CONDITIONAL([BUILD_ANIMDIFF], [test "${build_animdiff}" = "yes"])
|
||||||
AM_CONDITIONAL([BUILD_GIF2WEBP], [test "${build_gif2webp}" = "yes"])
|
AM_CONDITIONAL([BUILD_GIF2WEBP], [test "${build_gif2webp}" = "yes"])
|
||||||
|
|
||||||
if test "$enable_libwebpdemux" = "yes" -a "$enable_libwebpmux" = "yes"; then
|
if test "$enable_libwebpmux" = "yes"; then
|
||||||
build_img2webp=yes
|
build_img2webp=yes
|
||||||
else
|
|
||||||
AC_MSG_NOTICE(
|
|
||||||
m4_normalize([Not building img2webp.
|
|
||||||
--enable-libwebpdemux & --enable-libwebpmux are required.]))
|
|
||||||
fi
|
fi
|
||||||
AM_CONDITIONAL([BUILD_IMG2WEBP], [test "${build_img2webp}" = "yes"])
|
AM_CONDITIONAL([BUILD_IMG2WEBP], [test "${build_img2webp}" = "yes"])
|
||||||
|
|
||||||
if test "$enable_libwebpmux" = "yes"; then
|
|
||||||
build_webpinfo=yes
|
|
||||||
else
|
|
||||||
AC_MSG_NOTICE([Not building webpinfo. --enable-libwebpdemux is required.])
|
|
||||||
fi
|
|
||||||
AM_CONDITIONAL([BUILD_WEBPINFO], [test "${build_webpinfo}" = "yes"])
|
|
||||||
|
|
||||||
dnl === check for WIC support ===
|
dnl === check for WIC support ===
|
||||||
|
|
||||||
AC_ARG_ENABLE([wic],
|
AC_ARG_ENABLE([wic],
|
||||||
@@ -719,7 +613,7 @@ if test "$enable_wic" = "yes"; then
|
|||||||
fi
|
fi
|
||||||
esac
|
esac
|
||||||
|
|
||||||
dnl === If --enable-swap-16bit-csp is defined, add -DWEBP_SWAP_16BIT_CSP=1
|
dnl === If --enable-swap-16bit-csp is defined, add -DWEBP_SWAP_16BIT_CSP
|
||||||
|
|
||||||
USE_SWAP_16BIT_CSP=""
|
USE_SWAP_16BIT_CSP=""
|
||||||
AC_MSG_CHECKING(if --enable-swap-16bit-csp option is specified)
|
AC_MSG_CHECKING(if --enable-swap-16bit-csp option is specified)
|
||||||
@@ -727,25 +621,55 @@ AC_ARG_ENABLE([swap-16bit-csp],
|
|||||||
AS_HELP_STRING([--enable-swap-16bit-csp],
|
AS_HELP_STRING([--enable-swap-16bit-csp],
|
||||||
[Enable byte swap for 16 bit colorspaces]))
|
[Enable byte swap for 16 bit colorspaces]))
|
||||||
if test "$enable_swap_16bit_csp" = "yes"; then
|
if test "$enable_swap_16bit_csp" = "yes"; then
|
||||||
USE_SWAP_16BIT_CSP="-DWEBP_SWAP_16BIT_CSP=1"
|
USE_SWAP_16BIT_CSP="-DWEBP_SWAP_16BIT_CSP"
|
||||||
fi
|
fi
|
||||||
AC_MSG_RESULT(${enable_swap_16bit_csp-no})
|
AC_MSG_RESULT(${enable_swap_16bit_csp-no})
|
||||||
AC_SUBST(USE_SWAP_16BIT_CSP)
|
AC_SUBST(USE_SWAP_16BIT_CSP)
|
||||||
|
|
||||||
dnl === If --disable-near-lossless is defined, add -DWEBP_NEAR_LOSSLESS=0
|
dnl === If --enable-experimental is defined, add -DWEBP_EXPERIMENTAL_FEATURES
|
||||||
|
|
||||||
AC_DEFINE(WEBP_NEAR_LOSSLESS, [1], [Enable near lossless encoding])
|
USE_EXPERIMENTAL_CODE=""
|
||||||
AC_MSG_CHECKING(if --disable-near-lossless option is specified)
|
AC_MSG_CHECKING(if --enable-experimental option is specified)
|
||||||
AC_ARG_ENABLE([near_lossless],
|
AC_ARG_ENABLE([experimental], AS_HELP_STRING([--enable-experimental],
|
||||||
AS_HELP_STRING([--disable-near-lossless],
|
[Activate experimental features]))
|
||||||
[Disable near lossless encoding]),
|
if test "$enable_experimental" = "yes"; then
|
||||||
[], [enable_near_lossless=yes])
|
AC_DEFINE(WEBP_EXPERIMENTAL_FEATURES, [1], [Enable experimental code])
|
||||||
if test "$enable_near_lossless" = "no"; then
|
USE_EXPERIMENTAL_CODE="-DWEBP_EXPERIMENTAL_FEATURES"
|
||||||
AC_DEFINE(WEBP_NEAR_LOSSLESS, [0], [Enable near lossless encoding])
|
|
||||||
AC_MSG_RESULT([yes])
|
|
||||||
else
|
|
||||||
AC_MSG_RESULT([no])
|
|
||||||
fi
|
fi
|
||||||
|
AC_MSG_RESULT(${enable_experimental-no})
|
||||||
|
AC_SUBST(USE_EXPERIMENTAL_CODE)
|
||||||
|
|
||||||
|
dnl === Check whether libwebpmux should be built
|
||||||
|
AC_MSG_CHECKING(whether libwebpmux is to be built)
|
||||||
|
AC_ARG_ENABLE([libwebpmux],
|
||||||
|
AS_HELP_STRING([--enable-libwebpmux],
|
||||||
|
[Build libwebpmux @<:@default=no@:>@]))
|
||||||
|
AC_MSG_RESULT(${enable_libwebpmux-no})
|
||||||
|
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([--enable-libwebpdemux],
|
||||||
|
[Build libwebpdemux @<:@default=no@:>@]))
|
||||||
|
AC_MSG_RESULT(${enable_libwebpdemux-no})
|
||||||
|
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)
|
||||||
|
AC_ARG_ENABLE([libwebpdecoder],
|
||||||
|
AS_HELP_STRING([--enable-libwebpdecoder],
|
||||||
|
[Build libwebpdecoder @<:@default=no@:>@]))
|
||||||
|
AC_MSG_RESULT(${enable_libwebpdecoder-no})
|
||||||
|
AM_CONDITIONAL([BUILD_LIBWEBPDECODER], [test "$enable_libwebpdecoder" = "yes"])
|
||||||
|
|
||||||
|
dnl === Check whether libwebpextras should be built
|
||||||
|
AC_MSG_CHECKING(whether libwebpextras is to be built)
|
||||||
|
AC_ARG_ENABLE([libwebpextras],
|
||||||
|
AS_HELP_STRING([--enable-libwebpextras],
|
||||||
|
[Build libwebpextras @<:@default=no@:>@]))
|
||||||
|
AC_MSG_RESULT(${enable_libwebpextras-no})
|
||||||
|
AM_CONDITIONAL([WANT_EXTRAS], [test "$enable_libwebpextras" = "yes"])
|
||||||
|
|
||||||
dnl =========================
|
dnl =========================
|
||||||
|
|
||||||
@@ -753,7 +677,6 @@ AC_CONFIG_MACRO_DIR([m4])
|
|||||||
AC_CONFIG_HEADERS([src/webp/config.h])
|
AC_CONFIG_HEADERS([src/webp/config.h])
|
||||||
AC_CONFIG_FILES([Makefile src/Makefile man/Makefile \
|
AC_CONFIG_FILES([Makefile src/Makefile man/Makefile \
|
||||||
examples/Makefile extras/Makefile imageio/Makefile \
|
examples/Makefile extras/Makefile imageio/Makefile \
|
||||||
sharpyuv/Makefile \
|
|
||||||
src/dec/Makefile src/enc/Makefile src/dsp/Makefile \
|
src/dec/Makefile src/enc/Makefile src/dsp/Makefile \
|
||||||
src/demux/Makefile src/mux/Makefile \
|
src/demux/Makefile src/mux/Makefile \
|
||||||
src/utils/Makefile \
|
src/utils/Makefile \
|
||||||
@@ -777,25 +700,22 @@ libwebpmux: ${enable_libwebpmux-no}
|
|||||||
libwebpextras: ${enable_libwebpextras-no}
|
libwebpextras: ${enable_libwebpextras-no}
|
||||||
|
|
||||||
Tools:
|
Tools:
|
||||||
cwebp : ${enable_libwebpdemux-no}
|
cwebp : yes
|
||||||
Input format support
|
Input format support
|
||||||
====================
|
====================
|
||||||
JPEG : ${jpeg_support-no}
|
JPEG : ${jpeg_support-no}
|
||||||
PNG : ${png_support-no}
|
PNG : ${png_support-no}
|
||||||
TIFF : ${tiff_support-no}
|
TIFF : ${tiff_support-no}
|
||||||
WIC : ${wic_support-no}
|
WIC : ${wic_support-no}
|
||||||
dwebp : ${enable_libwebpdemux-no}
|
dwebp : yes
|
||||||
Output format support
|
Output format support
|
||||||
=====================
|
=====================
|
||||||
PNG : ${png_support-no}
|
PNG : ${png_support-no}
|
||||||
WIC : ${wic_support-no}
|
WIC : ${wic_support-no}
|
||||||
GIF support : ${gif_support-no}
|
GIF support : ${gif_support-no}
|
||||||
anim_diff : ${build_anim_diff-no}
|
anim_diff : ${build_animdiff-no}
|
||||||
gif2webp : ${build_gif2webp-no}
|
gif2webp : ${build_gif2webp-no}
|
||||||
img2webp : ${build_img2webp-no}
|
img2webp : ${build_img2webp-no}
|
||||||
webpmux : ${enable_libwebpmux-no}
|
webpmux : ${enable_libwebpmux-no}
|
||||||
vwebp : ${build_vwebp-no}
|
vwebp : ${build_vwebp-no}
|
||||||
webpinfo : ${build_webpinfo-no}
|
|
||||||
SDL support : ${sdl_support-no}
|
|
||||||
vwebp_sdl : ${build_vwebp_sdl-no}
|
|
||||||
])
|
])
|
||||||
|
|||||||
29
doc/README
Normal file
29
doc/README
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
|
||||||
|
Generate libwebp Container Spec Docs from Text Source
|
||||||
|
=====================================================
|
||||||
|
|
||||||
|
HTML generation requires kramdown [1], easily installed as a
|
||||||
|
rubygem [2]. Rubygems installation should satisfy dependencies
|
||||||
|
automatically.
|
||||||
|
|
||||||
|
[1]: http://kramdown.rubyforge.org/
|
||||||
|
[2]: http://rubygems.org/
|
||||||
|
|
||||||
|
HTML generation can then be done from the project root:
|
||||||
|
|
||||||
|
$ kramdown doc/webp-container-spec.txt --template doc/template.html > \
|
||||||
|
doc/output/webp-container-spec.html
|
||||||
|
|
||||||
|
kramdown can optionally syntax highlight code blocks, using CodeRay [3],
|
||||||
|
a dependency of kramdown that rubygems will install automatically. The
|
||||||
|
following will apply inline CSS styling; an external stylesheet is not
|
||||||
|
needed.
|
||||||
|
|
||||||
|
$ kramdown doc/webp-lossless-bitstream-spec.txt --template \
|
||||||
|
doc/template.html --coderay-css style --coderay-line-numbers ' ' \
|
||||||
|
--coderay-default-lang c > \
|
||||||
|
doc/output/webp-lossless-bitstream-spec.html
|
||||||
|
|
||||||
|
Optimally, use kramdown 0.13.7 or newer if syntax highlighting desired.
|
||||||
|
|
||||||
|
[3]: http://coderay.rubychan.de/
|
||||||
385
doc/api.md
385
doc/api.md
@@ -1,385 +0,0 @@
|
|||||||
# WebP APIs
|
|
||||||
|
|
||||||
## Encoding API
|
|
||||||
|
|
||||||
The main encoding functions are available in the header src/webp/encode.h
|
|
||||||
|
|
||||||
The ready-to-use ones are:
|
|
||||||
|
|
||||||
```c
|
|
||||||
size_t WebPEncodeRGB(const uint8_t* rgb, int width, int height, int stride,
|
|
||||||
float quality_factor, uint8_t** output);
|
|
||||||
size_t WebPEncodeBGR(const uint8_t* bgr, int width, int height, int stride,
|
|
||||||
float quality_factor, uint8_t** output);
|
|
||||||
size_t WebPEncodeRGBA(const uint8_t* rgba, int width, int height, int stride,
|
|
||||||
float quality_factor, uint8_t** output);
|
|
||||||
size_t WebPEncodeBGRA(const uint8_t* bgra, int width, int height, int stride,
|
|
||||||
float quality_factor, uint8_t** output);
|
|
||||||
```
|
|
||||||
|
|
||||||
They will convert raw RGB samples to a WebP data. The only control supplied is
|
|
||||||
the quality factor.
|
|
||||||
|
|
||||||
There are some variants for using the lossless format:
|
|
||||||
|
|
||||||
```c
|
|
||||||
size_t WebPEncodeLosslessRGB(const uint8_t* rgb, int width, int height,
|
|
||||||
int stride, uint8_t** output);
|
|
||||||
size_t WebPEncodeLosslessBGR(const uint8_t* bgr, int width, int height,
|
|
||||||
int stride, uint8_t** output);
|
|
||||||
size_t WebPEncodeLosslessRGBA(const uint8_t* rgba, int width, int height,
|
|
||||||
int stride, uint8_t** output);
|
|
||||||
size_t WebPEncodeLosslessBGRA(const uint8_t* bgra, int width, int height,
|
|
||||||
int stride, uint8_t** output);
|
|
||||||
```
|
|
||||||
|
|
||||||
Of course in this case, no quality factor is needed since the compression occurs
|
|
||||||
without loss of the input values, at the expense of larger output sizes.
|
|
||||||
|
|
||||||
### Advanced encoding API
|
|
||||||
|
|
||||||
A more advanced API is based on the WebPConfig and WebPPicture structures.
|
|
||||||
|
|
||||||
WebPConfig contains the encoding settings and is not tied to a particular
|
|
||||||
picture. WebPPicture contains input data, on which some WebPConfig will be used
|
|
||||||
for compression. The encoding flow looks like:
|
|
||||||
|
|
||||||
```c
|
|
||||||
#include <webp/encode.h>
|
|
||||||
|
|
||||||
// Setup a config, starting form a preset and tuning some additional
|
|
||||||
// parameters
|
|
||||||
WebPConfig config;
|
|
||||||
if (!WebPConfigPreset(&config, WEBP_PRESET_PHOTO, quality_factor)) {
|
|
||||||
return 0; // version error
|
|
||||||
}
|
|
||||||
// ... additional tuning
|
|
||||||
config.sns_strength = 90;
|
|
||||||
config.filter_sharpness = 6;
|
|
||||||
config_error = WebPValidateConfig(&config); // not mandatory, but useful
|
|
||||||
|
|
||||||
// Setup the input data
|
|
||||||
WebPPicture pic;
|
|
||||||
if (!WebPPictureInit(&pic)) {
|
|
||||||
return 0; // version error
|
|
||||||
}
|
|
||||||
pic.width = width;
|
|
||||||
pic.height = height;
|
|
||||||
// allocated picture of dimension width x height
|
|
||||||
if (!WebPPictureAlloc(&pic)) {
|
|
||||||
return 0; // memory error
|
|
||||||
}
|
|
||||||
// at this point, 'pic' has been initialized as a container,
|
|
||||||
// and can receive the Y/U/V samples.
|
|
||||||
// Alternatively, one could use ready-made import functions like
|
|
||||||
// WebPPictureImportRGB(), which will take care of memory allocation.
|
|
||||||
// In any case, past this point, one will have to call
|
|
||||||
// WebPPictureFree(&pic) to reclaim memory.
|
|
||||||
|
|
||||||
// Set up a byte-output write method. WebPMemoryWriter, for instance.
|
|
||||||
WebPMemoryWriter wrt;
|
|
||||||
WebPMemoryWriterInit(&wrt); // initialize 'wrt'
|
|
||||||
|
|
||||||
pic.writer = MyFileWriter;
|
|
||||||
pic.custom_ptr = my_opaque_structure_to_make_MyFileWriter_work;
|
|
||||||
|
|
||||||
// Compress!
|
|
||||||
int ok = WebPEncode(&config, &pic); // ok = 0 => error occurred!
|
|
||||||
WebPPictureFree(&pic); // must be called independently of the 'ok' result.
|
|
||||||
|
|
||||||
// output data should have been handled by the writer at that point.
|
|
||||||
// -> compressed data is the memory buffer described by wrt.mem / wrt.size
|
|
||||||
|
|
||||||
// deallocate the memory used by compressed data
|
|
||||||
WebPMemoryWriterClear(&wrt);
|
|
||||||
```
|
|
||||||
|
|
||||||
## Decoding API
|
|
||||||
|
|
||||||
This is mainly just one function to call:
|
|
||||||
|
|
||||||
```c
|
|
||||||
#include "webp/decode.h"
|
|
||||||
uint8_t* WebPDecodeRGB(const uint8_t* data, size_t data_size,
|
|
||||||
int* width, int* height);
|
|
||||||
```
|
|
||||||
|
|
||||||
Please have a look at the file src/webp/decode.h for the details. There are
|
|
||||||
variants for decoding in BGR/RGBA/ARGB/BGRA order, along with decoding to raw
|
|
||||||
Y'CbCr samples. One can also decode the image directly into a pre-allocated
|
|
||||||
buffer.
|
|
||||||
|
|
||||||
To detect a WebP file and gather the picture's dimensions, the function:
|
|
||||||
|
|
||||||
```c
|
|
||||||
int WebPGetInfo(const uint8_t* data, size_t data_size,
|
|
||||||
int* width, int* height);
|
|
||||||
```
|
|
||||||
|
|
||||||
is supplied. No decoding is involved when using it.
|
|
||||||
|
|
||||||
### Incremental decoding API
|
|
||||||
|
|
||||||
In the case when data is being progressively transmitted, pictures can still be
|
|
||||||
incrementally decoded using a slightly more complicated API. Decoder state is
|
|
||||||
stored into an instance of the WebPIDecoder object. This object can be created
|
|
||||||
with the purpose of decoding either RGB or Y'CbCr samples. For instance:
|
|
||||||
|
|
||||||
```c
|
|
||||||
WebPDecBuffer buffer;
|
|
||||||
WebPInitDecBuffer(&buffer);
|
|
||||||
buffer.colorspace = MODE_BGR;
|
|
||||||
...
|
|
||||||
WebPIDecoder* idec = WebPINewDecoder(&buffer);
|
|
||||||
```
|
|
||||||
|
|
||||||
As data is made progressively available, this incremental-decoder object can be
|
|
||||||
used to decode the picture further. There are two (mutually exclusive) ways to
|
|
||||||
pass freshly arrived data:
|
|
||||||
|
|
||||||
either by appending the fresh bytes:
|
|
||||||
|
|
||||||
```c
|
|
||||||
WebPIAppend(idec, fresh_data, size_of_fresh_data);
|
|
||||||
```
|
|
||||||
|
|
||||||
or by just mentioning the new size of the transmitted data:
|
|
||||||
|
|
||||||
```c
|
|
||||||
WebPIUpdate(idec, buffer, size_of_transmitted_buffer);
|
|
||||||
```
|
|
||||||
|
|
||||||
Note that 'buffer' can be modified between each call to WebPIUpdate, in
|
|
||||||
particular when the buffer is resized to accommodate larger data.
|
|
||||||
|
|
||||||
These functions will return the decoding status: either VP8_STATUS_SUSPENDED if
|
|
||||||
decoding is not finished yet or VP8_STATUS_OK when decoding is done. Any other
|
|
||||||
status is an error condition.
|
|
||||||
|
|
||||||
The 'idec' object must always be released (even upon an error condition) by
|
|
||||||
calling: WebPDelete(idec).
|
|
||||||
|
|
||||||
To retrieve partially decoded picture samples, one must use the corresponding
|
|
||||||
method: WebPIDecGetRGB or WebPIDecGetYUVA. It will return the last displayable
|
|
||||||
pixel row.
|
|
||||||
|
|
||||||
Lastly, note that decoding can also be performed into a pre-allocated pixel
|
|
||||||
buffer. This buffer must be passed when creating a WebPIDecoder, calling
|
|
||||||
WebPINewRGB() or WebPINewYUVA().
|
|
||||||
|
|
||||||
Please have a look at the src/webp/decode.h header for further details.
|
|
||||||
|
|
||||||
### Advanced Decoding API
|
|
||||||
|
|
||||||
WebP decoding supports an advanced API which provides on-the-fly cropping and
|
|
||||||
rescaling, something of great usefulness on memory-constrained environments like
|
|
||||||
mobile phones. Basically, the memory usage will scale with the output's size,
|
|
||||||
not the input's, when one only needs a quick preview or a zoomed in portion of
|
|
||||||
an otherwise too-large picture. Some CPU can be saved too, incidentally.
|
|
||||||
|
|
||||||
```c
|
|
||||||
// A) Init a configuration object
|
|
||||||
WebPDecoderConfig config;
|
|
||||||
CHECK(WebPInitDecoderConfig(&config));
|
|
||||||
|
|
||||||
// B) optional: retrieve the bitstream's features.
|
|
||||||
CHECK(WebPGetFeatures(data, data_size, &config.input) == VP8_STATUS_OK);
|
|
||||||
|
|
||||||
// C) Adjust 'config' options, if needed
|
|
||||||
config.options.no_fancy_upsampling = 1;
|
|
||||||
config.options.use_scaling = 1;
|
|
||||||
config.options.scaled_width = scaledWidth();
|
|
||||||
config.options.scaled_height = scaledHeight();
|
|
||||||
// etc.
|
|
||||||
|
|
||||||
// D) Specify 'config' output options for specifying output colorspace.
|
|
||||||
// Optionally the external image decode buffer can also be specified.
|
|
||||||
config.output.colorspace = MODE_BGRA;
|
|
||||||
// Optionally, the config.output can be pointed to an external buffer as
|
|
||||||
// well for decoding the image. This externally supplied memory buffer
|
|
||||||
// should be big enough to store the decoded picture.
|
|
||||||
config.output.u.RGBA.rgba = (uint8_t*) memory_buffer;
|
|
||||||
config.output.u.RGBA.stride = scanline_stride;
|
|
||||||
config.output.u.RGBA.size = total_size_of_the_memory_buffer;
|
|
||||||
config.output.is_external_memory = 1;
|
|
||||||
|
|
||||||
// E) Decode the WebP image. There are two variants w.r.t decoding image.
|
|
||||||
// The first one (E.1) decodes the full image and the second one (E.2) is
|
|
||||||
// used to incrementally decode the image using small input buffers.
|
|
||||||
// Any one of these steps can be used to decode the WebP image.
|
|
||||||
|
|
||||||
// E.1) Decode full image.
|
|
||||||
CHECK(WebPDecode(data, data_size, &config) == VP8_STATUS_OK);
|
|
||||||
|
|
||||||
// E.2) Decode image incrementally.
|
|
||||||
WebPIDecoder* const idec = WebPIDecode(NULL, NULL, &config);
|
|
||||||
CHECK(idec != NULL);
|
|
||||||
while (bytes_remaining > 0) {
|
|
||||||
VP8StatusCode status = WebPIAppend(idec, input, bytes_read);
|
|
||||||
if (status == VP8_STATUS_OK || status == VP8_STATUS_SUSPENDED) {
|
|
||||||
bytes_remaining -= bytes_read;
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
WebPIDelete(idec);
|
|
||||||
|
|
||||||
// F) Decoded image is now in config.output (and config.output.u.RGBA).
|
|
||||||
// It can be saved, displayed or otherwise processed.
|
|
||||||
|
|
||||||
// G) Reclaim memory allocated in config's object. It's safe to call
|
|
||||||
// this function even if the memory is external and wasn't allocated
|
|
||||||
// by WebPDecode().
|
|
||||||
WebPFreeDecBuffer(&config.output);
|
|
||||||
```
|
|
||||||
|
|
||||||
## Webp Mux
|
|
||||||
|
|
||||||
WebPMux is a set of two libraries 'Mux' and 'Demux' for creation, extraction and
|
|
||||||
manipulation of an extended format WebP file, which can have features like color
|
|
||||||
profile, metadata and animation. Reference command-line tools `webpmux` and
|
|
||||||
`vwebp` as well as the WebP container specification
|
|
||||||
'doc/webp-container-spec.txt' are also provided in this package, see the
|
|
||||||
[tools documentation](tools.md).
|
|
||||||
|
|
||||||
### Mux API
|
|
||||||
|
|
||||||
The Mux API contains methods for adding data to and reading data from WebP
|
|
||||||
files. This API currently supports XMP/EXIF metadata, ICC profile and animation.
|
|
||||||
Other features may be added in subsequent releases.
|
|
||||||
|
|
||||||
Example#1 (pseudo code): Creating a WebPMux object with image data, color
|
|
||||||
profile and XMP metadata.
|
|
||||||
|
|
||||||
```c
|
|
||||||
int copy_data = 0;
|
|
||||||
WebPMux* mux = WebPMuxNew();
|
|
||||||
// ... (Prepare image data).
|
|
||||||
WebPMuxSetImage(mux, &image, copy_data);
|
|
||||||
// ... (Prepare ICC profile data).
|
|
||||||
WebPMuxSetChunk(mux, "ICCP", &icc_profile, copy_data);
|
|
||||||
// ... (Prepare XMP metadata).
|
|
||||||
WebPMuxSetChunk(mux, "XMP ", &xmp, copy_data);
|
|
||||||
// Get data from mux in WebP RIFF format.
|
|
||||||
WebPMuxAssemble(mux, &output_data);
|
|
||||||
WebPMuxDelete(mux);
|
|
||||||
// ... (Consume output_data; e.g. write output_data.bytes to file).
|
|
||||||
WebPDataClear(&output_data);
|
|
||||||
```
|
|
||||||
|
|
||||||
Example#2 (pseudo code): Get image and color profile data from a WebP file.
|
|
||||||
|
|
||||||
```c
|
|
||||||
int copy_data = 0;
|
|
||||||
// ... (Read data from file).
|
|
||||||
WebPMux* mux = WebPMuxCreate(&data, copy_data);
|
|
||||||
WebPMuxGetFrame(mux, 1, &image);
|
|
||||||
// ... (Consume image; e.g. call WebPDecode() to decode the data).
|
|
||||||
WebPMuxGetChunk(mux, "ICCP", &icc_profile);
|
|
||||||
// ... (Consume icc_profile).
|
|
||||||
WebPMuxDelete(mux);
|
|
||||||
free(data);
|
|
||||||
```
|
|
||||||
|
|
||||||
For a detailed Mux API reference, please refer to the header file
|
|
||||||
(src/webp/mux.h).
|
|
||||||
|
|
||||||
### Demux API
|
|
||||||
|
|
||||||
The Demux API enables extraction of images and extended format data from WebP
|
|
||||||
files. This API currently supports reading of XMP/EXIF metadata, ICC profile and
|
|
||||||
animated images. Other features may be added in subsequent releases.
|
|
||||||
|
|
||||||
Code example: Demuxing WebP data to extract all the frames, ICC profile and
|
|
||||||
EXIF/XMP metadata.
|
|
||||||
|
|
||||||
```c
|
|
||||||
WebPDemuxer* demux = WebPDemux(&webp_data);
|
|
||||||
uint32_t width = WebPDemuxGetI(demux, WEBP_FF_CANVAS_WIDTH);
|
|
||||||
uint32_t height = WebPDemuxGetI(demux, WEBP_FF_CANVAS_HEIGHT);
|
|
||||||
// ... (Get information about the features present in the WebP file).
|
|
||||||
uint32_t flags = WebPDemuxGetI(demux, WEBP_FF_FORMAT_FLAGS);
|
|
||||||
|
|
||||||
// ... (Iterate over all frames).
|
|
||||||
WebPIterator iter;
|
|
||||||
if (WebPDemuxGetFrame(demux, 1, &iter)) {
|
|
||||||
do {
|
|
||||||
// ... (Consume 'iter'; e.g. Decode 'iter.fragment' with WebPDecode(),
|
|
||||||
// ... and get other frame properties like width, height, offsets etc.
|
|
||||||
// ... see 'struct WebPIterator' below for more info).
|
|
||||||
} while (WebPDemuxNextFrame(&iter));
|
|
||||||
WebPDemuxReleaseIterator(&iter);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ... (Extract metadata).
|
|
||||||
WebPChunkIterator chunk_iter;
|
|
||||||
if (flags & ICCP_FLAG) WebPDemuxGetChunk(demux, "ICCP", 1, &chunk_iter);
|
|
||||||
// ... (Consume the ICC profile in 'chunk_iter.chunk').
|
|
||||||
WebPDemuxReleaseChunkIterator(&chunk_iter);
|
|
||||||
if (flags & EXIF_FLAG) WebPDemuxGetChunk(demux, "EXIF", 1, &chunk_iter);
|
|
||||||
// ... (Consume the EXIF metadata in 'chunk_iter.chunk').
|
|
||||||
WebPDemuxReleaseChunkIterator(&chunk_iter);
|
|
||||||
if (flags & XMP_FLAG) WebPDemuxGetChunk(demux, "XMP ", 1, &chunk_iter);
|
|
||||||
// ... (Consume the XMP metadata in 'chunk_iter.chunk').
|
|
||||||
WebPDemuxReleaseChunkIterator(&chunk_iter);
|
|
||||||
WebPDemuxDelete(demux);
|
|
||||||
```
|
|
||||||
|
|
||||||
For a detailed Demux API reference, please refer to the header file
|
|
||||||
(src/webp/demux.h).
|
|
||||||
|
|
||||||
## AnimEncoder API
|
|
||||||
|
|
||||||
The AnimEncoder API can be used to create animated WebP images.
|
|
||||||
|
|
||||||
Code example:
|
|
||||||
|
|
||||||
```c
|
|
||||||
WebPAnimEncoderOptions enc_options;
|
|
||||||
WebPAnimEncoderOptionsInit(&enc_options);
|
|
||||||
// ... (Tune 'enc_options' as needed).
|
|
||||||
WebPAnimEncoder* enc = WebPAnimEncoderNew(width, height, &enc_options);
|
|
||||||
while(<there are more frames>) {
|
|
||||||
WebPConfig config;
|
|
||||||
WebPConfigInit(&config);
|
|
||||||
// ... (Tune 'config' as needed).
|
|
||||||
WebPAnimEncoderAdd(enc, frame, duration, &config);
|
|
||||||
}
|
|
||||||
WebPAnimEncoderAssemble(enc, webp_data);
|
|
||||||
WebPAnimEncoderDelete(enc);
|
|
||||||
// ... (Write the 'webp_data' to a file, or re-mux it further).
|
|
||||||
```
|
|
||||||
|
|
||||||
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:
|
|
||||||
|
|
||||||
```c
|
|
||||||
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).
|
|
||||||
213
doc/building.md
213
doc/building.md
@@ -1,213 +0,0 @@
|
|||||||
# Building
|
|
||||||
|
|
||||||
## Windows build
|
|
||||||
|
|
||||||
By running:
|
|
||||||
|
|
||||||
```batch
|
|
||||||
nmake /f Makefile.vc CFG=release-static RTLIBCFG=static OBJDIR=output
|
|
||||||
```
|
|
||||||
|
|
||||||
the directory `output\release-static\(x64|x86)\bin` will contain the tools
|
|
||||||
cwebp.exe and dwebp.exe. The directory `output\release-static\(x64|x86)\lib`
|
|
||||||
will contain the libwebp static library. The target architecture (x86/x64) is
|
|
||||||
detected by Makefile.vc from the Visual Studio compiler (cl.exe) available in
|
|
||||||
the system path.
|
|
||||||
|
|
||||||
## Unix build using makefile.unix
|
|
||||||
|
|
||||||
On platforms with GNU tools installed (gcc and make), running
|
|
||||||
|
|
||||||
```shell
|
|
||||||
make -f makefile.unix
|
|
||||||
```
|
|
||||||
|
|
||||||
will build the binaries examples/cwebp and examples/dwebp, along with the static
|
|
||||||
library src/libwebp.a. No system-wide installation is supplied, as this is a
|
|
||||||
simple alternative to the full installation system based on the autoconf tools
|
|
||||||
(see below). Please refer to makefile.unix for additional details and
|
|
||||||
customizations.
|
|
||||||
|
|
||||||
## Using autoconf tools
|
|
||||||
|
|
||||||
Prerequisites: a compiler (e.g., gcc), make, autoconf, automake, libtool.
|
|
||||||
|
|
||||||
On a Debian-like system the following should install everything you need for a
|
|
||||||
minimal build:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
$ sudo apt-get install gcc make autoconf automake libtool
|
|
||||||
```
|
|
||||||
|
|
||||||
When building from git sources, you will need to run autogen.sh to generate the
|
|
||||||
configure script.
|
|
||||||
|
|
||||||
```shell
|
|
||||||
./configure
|
|
||||||
make
|
|
||||||
make install
|
|
||||||
```
|
|
||||||
|
|
||||||
should be all you need to have the following files
|
|
||||||
|
|
||||||
```
|
|
||||||
/usr/local/include/webp/decode.h
|
|
||||||
/usr/local/include/webp/encode.h
|
|
||||||
/usr/local/include/webp/types.h
|
|
||||||
/usr/local/lib/libwebp.*
|
|
||||||
/usr/local/bin/cwebp
|
|
||||||
/usr/local/bin/dwebp
|
|
||||||
```
|
|
||||||
|
|
||||||
installed.
|
|
||||||
|
|
||||||
Note: A decode-only library, libwebpdecoder, is available using the
|
|
||||||
`--enable-libwebpdecoder` flag. The encode library is built separately and can
|
|
||||||
be installed independently using a minor modification in the corresponding
|
|
||||||
Makefile.am configure files (see comments there). See `./configure --help` for
|
|
||||||
more options.
|
|
||||||
|
|
||||||
## Building for MIPS Linux
|
|
||||||
|
|
||||||
MIPS Linux toolchain stable available releases can be found at:
|
|
||||||
https://community.imgtec.com/developers/mips/tools/codescape-mips-sdk/available-releases/
|
|
||||||
|
|
||||||
```shell
|
|
||||||
# Add toolchain to PATH
|
|
||||||
export PATH=$PATH:/path/to/toolchain/bin
|
|
||||||
|
|
||||||
# 32-bit build for mips32r5 (p5600)
|
|
||||||
HOST=mips-mti-linux-gnu
|
|
||||||
MIPS_CFLAGS="-O3 -mips32r5 -mabi=32 -mtune=p5600 -mmsa -mfp64 \
|
|
||||||
-msched-weight -mload-store-pairs -fPIE"
|
|
||||||
MIPS_LDFLAGS="-mips32r5 -mabi=32 -mmsa -mfp64 -pie"
|
|
||||||
|
|
||||||
# 64-bit build for mips64r6 (i6400)
|
|
||||||
HOST=mips-img-linux-gnu
|
|
||||||
MIPS_CFLAGS="-O3 -mips64r6 -mabi=64 -mtune=i6400 -mmsa -mfp64 \
|
|
||||||
-msched-weight -mload-store-pairs -fPIE"
|
|
||||||
MIPS_LDFLAGS="-mips64r6 -mabi=64 -mmsa -mfp64 -pie"
|
|
||||||
|
|
||||||
./configure --host=${HOST} --build=`config.guess` \
|
|
||||||
CC="${HOST}-gcc -EL" \
|
|
||||||
CFLAGS="$MIPS_CFLAGS" \
|
|
||||||
LDFLAGS="$MIPS_LDFLAGS"
|
|
||||||
make
|
|
||||||
make install
|
|
||||||
```
|
|
||||||
|
|
||||||
## CMake
|
|
||||||
|
|
||||||
With CMake, you can compile libwebp, cwebp, dwebp, gif2webp, img2webp, webpinfo
|
|
||||||
and the JS bindings.
|
|
||||||
|
|
||||||
Prerequisites: a compiler (e.g., gcc with autotools) and CMake.
|
|
||||||
|
|
||||||
On a Debian-like system the following should install everything you need for a
|
|
||||||
minimal build:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
$ sudo apt-get install build-essential cmake
|
|
||||||
```
|
|
||||||
|
|
||||||
When building from git sources, you will need to run cmake to generate the
|
|
||||||
makefiles.
|
|
||||||
|
|
||||||
```shell
|
|
||||||
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.:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
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:
|
|
||||||
|
|
||||||
```cmake
|
|
||||||
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
|
|
||||||
dwebp and webpmux_example.
|
|
||||||
|
|
||||||
Prerequisites: a compiler (e.g., gcc with autotools) and gradle.
|
|
||||||
|
|
||||||
On a Debian-like system the following should install everything you need for a
|
|
||||||
minimal build:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
$ sudo apt-get install build-essential gradle
|
|
||||||
```
|
|
||||||
|
|
||||||
When building from git sources, you will need to run the Gradle wrapper with the
|
|
||||||
appropriate target, e.g. :
|
|
||||||
|
|
||||||
```shell
|
|
||||||
./gradlew buildAllExecutables
|
|
||||||
```
|
|
||||||
|
|
||||||
## SWIG bindings
|
|
||||||
|
|
||||||
To generate language bindings from swig/libwebp.swig at least swig-1.3
|
|
||||||
(http://www.swig.org) is required.
|
|
||||||
|
|
||||||
Currently the following functions are mapped:
|
|
||||||
|
|
||||||
Decode:
|
|
||||||
|
|
||||||
```
|
|
||||||
WebPGetDecoderVersion
|
|
||||||
WebPGetInfo
|
|
||||||
WebPDecodeRGBA
|
|
||||||
WebPDecodeARGB
|
|
||||||
WebPDecodeBGRA
|
|
||||||
WebPDecodeBGR
|
|
||||||
WebPDecodeRGB
|
|
||||||
```
|
|
||||||
|
|
||||||
Encode:
|
|
||||||
|
|
||||||
```
|
|
||||||
WebPGetEncoderVersion
|
|
||||||
WebPEncodeRGBA
|
|
||||||
WebPEncodeBGRA
|
|
||||||
WebPEncodeRGB
|
|
||||||
WebPEncodeBGR
|
|
||||||
WebPEncodeLosslessRGBA
|
|
||||||
WebPEncodeLosslessBGRA
|
|
||||||
WebPEncodeLosslessRGB
|
|
||||||
WebPEncodeLosslessBGR
|
|
||||||
```
|
|
||||||
|
|
||||||
See also the [swig documentation](../swig/README.md) for more detailed build
|
|
||||||
instructions and usage examples.
|
|
||||||
|
|
||||||
### Java bindings
|
|
||||||
|
|
||||||
To build the swig-generated JNI wrapper code at least JDK-1.5 (or equivalent) is
|
|
||||||
necessary for enum support. The output is intended to be a shared object / DLL
|
|
||||||
that can be loaded via `System.loadLibrary("webp_jni")`.
|
|
||||||
|
|
||||||
### Python bindings
|
|
||||||
|
|
||||||
To build the swig-generated Python extension code at least Python 2.6 is
|
|
||||||
required. Python < 2.6 may build with some minor changes to libwebp.swig or the
|
|
||||||
generated code, but is untested.
|
|
||||||
|
|
||||||
## Javascript decoder
|
|
||||||
|
|
||||||
Libwebp can be compiled into a JavaScript decoder using Emscripten and CMake.
|
|
||||||
See the [corresponding documentation](../README.md)
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
# Generate libwebp Container Spec Docs from Text Source
|
|
||||||
|
|
||||||
HTML generation requires [kramdown](https://kramdown.gettalong.org/), easily
|
|
||||||
installed as a [rubygem](https://rubygems.org/). Rubygems installation should
|
|
||||||
satisfy dependencies automatically.
|
|
||||||
|
|
||||||
HTML generation can then be done from the project root:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
$ kramdown doc/webp-container-spec.txt --template doc/template.html > \
|
|
||||||
doc/output/webp-container-spec.html
|
|
||||||
```
|
|
||||||
|
|
||||||
kramdown can optionally syntax highlight code blocks, using
|
|
||||||
[CodeRay](https://github.com/rubychan/coderay), a dependency of kramdown that
|
|
||||||
rubygems will install automatically. The following will apply inline CSS
|
|
||||||
styling; an external stylesheet is not needed.
|
|
||||||
|
|
||||||
```shell
|
|
||||||
$ kramdown doc/webp-lossless-bitstream-spec.txt --template \
|
|
||||||
doc/template.html --coderay-css style --coderay-line-numbers ' ' \
|
|
||||||
--coderay-default-lang c > \
|
|
||||||
doc/output/webp-lossless-bitstream-spec.html
|
|
||||||
```
|
|
||||||
|
|
||||||
Optimally, use kramdown 0.13.7 or newer if syntax highlighting desired.
|
|
||||||
512
doc/tools.md
512
doc/tools.md
@@ -1,512 +0,0 @@
|
|||||||
# WebP tools
|
|
||||||
|
|
||||||
## Encoding tool
|
|
||||||
|
|
||||||
The examples/ directory contains tools for encoding (cwebp) and decoding (dwebp)
|
|
||||||
images.
|
|
||||||
|
|
||||||
The easiest use should look like:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
cwebp input.png -q 80 -o output.webp
|
|
||||||
```
|
|
||||||
|
|
||||||
which will convert the input file to a WebP file using a quality factor of 80 on
|
|
||||||
a 0->100 scale (0 being the lowest quality, 100 being the best. Default value is
|
|
||||||
75).
|
|
||||||
|
|
||||||
You might want to try the `-lossless` flag too, which will compress the source
|
|
||||||
(in RGBA format) without any loss. The `-q` quality parameter will in this case
|
|
||||||
control the amount of processing time spent trying to make the output file as
|
|
||||||
small as possible.
|
|
||||||
|
|
||||||
A longer list of options is available using the `-longhelp` command line flag:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
> cwebp -longhelp
|
|
||||||
Usage:
|
|
||||||
cwebp [-preset <...>] [options] in_file [-o out_file]
|
|
||||||
```
|
|
||||||
|
|
||||||
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
|
|
||||||
-H / -longhelp ......... long help
|
|
||||||
-q <float> ............. quality factor (0:small..100:big), default=75
|
|
||||||
-alpha_q <int> ......... transparency-compression quality (0..100),
|
|
||||||
default=100
|
|
||||||
-preset <string> ....... preset setting, one of:
|
|
||||||
default, photo, picture,
|
|
||||||
drawing, icon, text
|
|
||||||
-preset must come first, as it overwrites other parameters
|
|
||||||
-z <int> ............... activates lossless preset with given
|
|
||||||
level in [0:fast, ..., 9:slowest]
|
|
||||||
|
|
||||||
-m <int> ............... compression method (0=fast, 6=slowest), default=4
|
|
||||||
-segments <int> ........ number of segments to use (1..4), default=4
|
|
||||||
-size <int> ............ target size (in bytes)
|
|
||||||
-psnr <float> .......... target PSNR (in dB. typically: 42)
|
|
||||||
|
|
||||||
-s <int> <int> ......... input size (width x height) for YUV
|
|
||||||
-sns <int> ............. spatial noise shaping (0:off, 100:max), default=50
|
|
||||||
-f <int> ............... filter strength (0=off..100), default=60
|
|
||||||
-sharpness <int> ....... filter sharpness (0:most .. 7:least sharp), default=0
|
|
||||||
-strong ................ use strong filter instead of simple (default)
|
|
||||||
-nostrong .............. use simple filter instead of strong
|
|
||||||
-sharp_yuv ............. use sharper (and slower) RGB->YUV conversion
|
|
||||||
-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
|
|
||||||
-low_memory ............ reduce memory usage (slower encoding)
|
|
||||||
-map <int> ............. print map of extra info
|
|
||||||
-print_psnr ............ prints averaged PSNR distortion
|
|
||||||
-print_ssim ............ prints averaged SSIM distortion
|
|
||||||
-print_lsim ............ prints local-similarity distortion
|
|
||||||
-d <file.pgm> .......... dump the compressed output (PGM file)
|
|
||||||
-alpha_method <int> .... transparency-compression method (0..1), default=1
|
|
||||||
-alpha_filter <string> . predictive filtering for alpha plane,
|
|
||||||
one of: none, fast (default) or best
|
|
||||||
-exact ................. preserve RGB values in transparent area, default=off
|
|
||||||
-blend_alpha <hex> ..... blend colors against background color
|
|
||||||
expressed as RGB values written in
|
|
||||||
hexadecimal, e.g. 0xc0e0d0 for red=0xc0
|
|
||||||
green=0xe0 and blue=0xd0
|
|
||||||
-noalpha ............... discard any transparency information
|
|
||||||
-lossless .............. encode image losslessly, default=off
|
|
||||||
-near_lossless <int> ... use near-lossless image
|
|
||||||
preprocessing (0..100=off), default=100
|
|
||||||
-hint <string> ......... specify image characteristics hint,
|
|
||||||
one of: photo, picture or graph
|
|
||||||
|
|
||||||
-metadata <string> ..... comma separated list of metadata to
|
|
||||||
copy from the input to the output if present.
|
|
||||||
Valid values: all, none (default), exif, icc, xmp
|
|
||||||
|
|
||||||
-short ................. condense printed message
|
|
||||||
-quiet ................. don't print anything
|
|
||||||
-version ............... print version number and exit
|
|
||||||
-noasm ................. disable all assembly optimizations
|
|
||||||
-v ..................... verbose, e.g. print encoding/decoding times
|
|
||||||
-progress .............. report encoding progress
|
|
||||||
```
|
|
||||||
|
|
||||||
Experimental Options:
|
|
||||||
|
|
||||||
```
|
|
||||||
-jpeg_like ............. roughly match expected JPEG size
|
|
||||||
-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 -sns -f -m
|
|
||||||
|
|
||||||
Namely:
|
|
||||||
|
|
||||||
* `preset` will set up a default encoding configuration targeting a particular
|
|
||||||
type of input. It should appear first in the list of options, so that
|
|
||||||
subsequent options can take effect on top of this preset. Default value is
|
|
||||||
'default'.
|
|
||||||
* `sns` will progressively turn on (when going from 0 to 100) some additional
|
|
||||||
visual optimizations (like: segmentation map re-enforcement). This option
|
|
||||||
will balance the bit allocation differently. It tries to take bits from the
|
|
||||||
"easy" parts of the picture and use them in the "difficult" ones instead.
|
|
||||||
Usually, raising the sns value (at fixed -q value) leads to larger files,
|
|
||||||
but with better quality. Typical value is around '75'.
|
|
||||||
* `f` option directly links to the filtering strength used by the codec's
|
|
||||||
in-loop processing. The higher the value, the smoother the highly-compressed
|
|
||||||
area will look. This is particularly useful when aiming at very small files.
|
|
||||||
Typical values are around 20-30. Note that using the option
|
|
||||||
-strong/-nostrong will change the type of filtering. Use "-f 0" to turn
|
|
||||||
filtering off.
|
|
||||||
* `m` controls the trade-off between encoding speed and quality. Default is 4.
|
|
||||||
You can try -m 5 or -m 6 to explore more (time-consuming) encoding
|
|
||||||
possibilities. A lower value will result in faster encoding at the expense
|
|
||||||
of quality.
|
|
||||||
|
|
||||||
## Decoding tool
|
|
||||||
|
|
||||||
There is a decoding sample in examples/dwebp.c which will take a .webp file and
|
|
||||||
decode it to a PNG image file (amongst other formats). This is simply to
|
|
||||||
demonstrate the use of the API. You can verify the file test.webp decodes to
|
|
||||||
exactly the same as test_ref.ppm by using:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
cd examples
|
|
||||||
./dwebp test.webp -ppm -o test.ppm
|
|
||||||
diff test.ppm test_ref.ppm
|
|
||||||
```
|
|
||||||
|
|
||||||
The full list of options is available using -h:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
> 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.
|
|
||||||
|
|
||||||
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
|
|
||||||
-bmp ......... save as uncompressed BMP format
|
|
||||||
-tiff ........ save as uncompressed TIFF format
|
|
||||||
-pgm ......... save the raw YUV samples as a grayscale PGM
|
|
||||||
file with IMC4 layout
|
|
||||||
-yuv ......... save the raw YUV samples in flat layout
|
|
||||||
```
|
|
||||||
|
|
||||||
Other options are:
|
|
||||||
|
|
||||||
```
|
|
||||||
-version ..... print version number and exit
|
|
||||||
-nofancy ..... don't use the fancy YUV420 upscaler
|
|
||||||
-nofilter .... disable in-loop filtering
|
|
||||||
-nodither .... disable dithering
|
|
||||||
-dither <d> .. dithering strength (in 0..100)
|
|
||||||
-alpha_dither use alpha-plane dithering if needed
|
|
||||||
-mt .......... use multi-threading
|
|
||||||
-crop <x> <y> <w> <h> ... crop output with the given rectangle
|
|
||||||
-resize <w> <h> ......... resize output (*after* any cropping)
|
|
||||||
-flip ........ flip the output vertically
|
|
||||||
-alpha ....... only save the alpha plane
|
|
||||||
-incremental . use incremental decoding (useful for tests)
|
|
||||||
-h ........... this help message
|
|
||||||
-v ........... verbose (e.g. print encoding/decoding times)
|
|
||||||
-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:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
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
|
|
||||||
|
|
||||||
There's a little self-serve visualization tool called 'vwebp' under the
|
|
||||||
examples/ directory. It uses OpenGL to open a simple drawing window and show a
|
|
||||||
decoded WebP file. It's not yet integrated in the automake build system, but you
|
|
||||||
can try to manually compile it using the recommendations below.
|
|
||||||
|
|
||||||
Usage:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
vwebp in_file [options]
|
|
||||||
```
|
|
||||||
|
|
||||||
Decodes the WebP image file and visualize it using OpenGL
|
|
||||||
|
|
||||||
Options are:
|
|
||||||
|
|
||||||
```
|
|
||||||
-version ..... print version number and exit
|
|
||||||
-noicc ....... don't use the icc profile if present
|
|
||||||
-nofancy ..... don't use the fancy YUV420 upscaler
|
|
||||||
-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
|
|
||||||
```
|
|
||||||
|
|
||||||
### Building
|
|
||||||
|
|
||||||
Prerequisites:
|
|
||||||
|
|
||||||
1. OpenGL & OpenGL Utility Toolkit (GLUT)
|
|
||||||
|
|
||||||
Linux: `sudo apt-get install freeglut3-dev mesa-common-dev`
|
|
||||||
|
|
||||||
Mac + Xcode: These libraries should be available in the OpenGL / GLUT
|
|
||||||
frameworks.
|
|
||||||
|
|
||||||
Windows: http://freeglut.sourceforge.net/index.php#download
|
|
||||||
|
|
||||||
2. (Optional) qcms (Quick Color Management System)
|
|
||||||
|
|
||||||
1. Download qcms from Mozilla / Chromium:
|
|
||||||
https://hg.mozilla.org/mozilla-central/file/0e7639e3bdfb/gfx/qcms
|
|
||||||
https://source.chromium.org/chromium/chromium/src/+/main:third_party/qcms/;drc=d4a2f8e1ed461d8fc05ed88d1ae2dc94c9773825
|
|
||||||
2. Build and archive the source files as libqcms.a / qcms.lib
|
|
||||||
3. Update makefile.unix / Makefile.vc
|
|
||||||
1. Define WEBP_HAVE_QCMS
|
|
||||||
2. Update include / library paths to reference the qcms directory.
|
|
||||||
|
|
||||||
Build using makefile.unix / Makefile.vc:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
$ make -f makefile.unix examples/vwebp
|
|
||||||
> nmake /f Makefile.vc CFG=release-static \
|
|
||||||
../obj/x64/release-static/bin/vwebp.exe
|
|
||||||
```
|
|
||||||
|
|
||||||
## Animation creation tool
|
|
||||||
|
|
||||||
The utility `img2webp` can turn a sequence of input images (PNG, JPEG, ...) into
|
|
||||||
an animated WebP file. It offers fine control over duration, encoding modes,
|
|
||||||
etc.
|
|
||||||
|
|
||||||
Usage:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
img2webp [file_options] [[frame_options] frame_file]...
|
|
||||||
```
|
|
||||||
|
|
||||||
File-level options (only used at the start of compression):
|
|
||||||
|
|
||||||
```
|
|
||||||
-min_size ............ minimize size
|
|
||||||
-loop <int> .......... loop count (default: 0, = infinite loop)
|
|
||||||
-kmax <int> .......... maximum number of frame between key-frames
|
|
||||||
(0=only keyframes)
|
|
||||||
-kmin <int> .......... minimum number of frame between key-frames
|
|
||||||
(0=disable key-frames altogether)
|
|
||||||
-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)
|
|
||||||
-lossless ........... use lossless mode (default)
|
|
||||||
-lossy ... ........... use lossy mode
|
|
||||||
-q <float> ........... quality
|
|
||||||
-m <int> ............. method to use
|
|
||||||
```
|
|
||||||
|
|
||||||
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
|
|
||||||
gif2webp utility available under examples/. The files can then be viewed using
|
|
||||||
vwebp.
|
|
||||||
|
|
||||||
Usage:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
gif2webp [options] gif_file -o webp_file
|
|
||||||
```
|
|
||||||
|
|
||||||
Options:
|
|
||||||
|
|
||||||
```
|
|
||||||
-h / -help ............. this help
|
|
||||||
-lossy ................. encode image using lossy compression
|
|
||||||
-mixed ................. for each frame in the image, pick lossy
|
|
||||||
or lossless compression heuristically
|
|
||||||
-q <float> ............. quality factor (0:small..100:big)
|
|
||||||
-m <int> ............... compression method (0=fast, 6=slowest)
|
|
||||||
-min_size .............. minimize output size (default:off)
|
|
||||||
lossless compression by default; can be
|
|
||||||
combined with -q, -m, -lossy or -mixed
|
|
||||||
options
|
|
||||||
-kmin <int> ............ min distance between key frames
|
|
||||||
-kmax <int> ............ max distance between key frames
|
|
||||||
-f <int> ............... filter strength (0=off..100)
|
|
||||||
-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
|
|
||||||
-v ..................... verbose
|
|
||||||
-quiet ................. don't print anything
|
|
||||||
```
|
|
||||||
|
|
||||||
### Building
|
|
||||||
|
|
||||||
With the libgif development files installed, gif2webp can be built using
|
|
||||||
makefile.unix:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
$ make -f makefile.unix examples/gif2webp
|
|
||||||
```
|
|
||||||
|
|
||||||
or using autoconf:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
$ ./configure --enable-everything
|
|
||||||
$ make
|
|
||||||
```
|
|
||||||
|
|
||||||
## Comparison of animated images
|
|
||||||
|
|
||||||
Test utility anim_diff under examples/ can be used to compare two animated
|
|
||||||
images (each can be GIF or WebP).
|
|
||||||
|
|
||||||
Usage:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
anim_diff <image1> <image2> [options]
|
|
||||||
```
|
|
||||||
|
|
||||||
Options:
|
|
||||||
|
|
||||||
```
|
|
||||||
-dump_frames <folder> dump decoded frames in PAM format
|
|
||||||
-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
|
|
||||||
|
|
||||||
With the libgif development files installed, anim_diff can be built using
|
|
||||||
makefile.unix:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
$ make -f makefile.unix examples/anim_diff
|
|
||||||
```
|
|
||||||
|
|
||||||
or using autoconf:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
$ ./configure --enable-everything
|
|
||||||
$ make
|
|
||||||
```
|
|
||||||
|
|
||||||
## WebP Mux tool
|
|
||||||
|
|
||||||
The examples/ directory contains a tool (webpmux) for manipulating WebP files.
|
|
||||||
The webpmux tool can be used to create an extended format WebP file and also to
|
|
||||||
extract or strip relevant data from such a file.
|
|
||||||
|
|
||||||
A list of options is available using the -help command line flag:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
> webpmux -help
|
|
||||||
Usage: webpmux -get GET_OPTIONS INPUT -o OUTPUT
|
|
||||||
webpmux -set SET_OPTIONS INPUT -o OUTPUT
|
|
||||||
webpmux -duration DURATION_OPTIONS [-duration ...]
|
|
||||||
INPUT -o OUTPUT
|
|
||||||
webpmux -strip STRIP_OPTIONS INPUT -o OUTPUT
|
|
||||||
webpmux -frame FRAME_OPTIONS [-frame...] [-loop LOOP_COUNT]
|
|
||||||
[-bgcolor BACKGROUND_COLOR] -o OUTPUT
|
|
||||||
webpmux -info INPUT
|
|
||||||
webpmux [-h|-help]
|
|
||||||
webpmux -version
|
|
||||||
webpmux argument_file_name
|
|
||||||
|
|
||||||
GET_OPTIONS:
|
|
||||||
Extract relevant data:
|
|
||||||
icc get ICC profile
|
|
||||||
exif get EXIF metadata
|
|
||||||
xmp get XMP metadata
|
|
||||||
frame n get nth frame
|
|
||||||
|
|
||||||
SET_OPTIONS:
|
|
||||||
Set color profile/metadata/parameters:
|
|
||||||
loop LOOP_COUNT set the loop count
|
|
||||||
bgcolor BACKGROUND_COLOR set the animation background color
|
|
||||||
icc file.icc set ICC profile
|
|
||||||
exif file.exif set EXIF metadata
|
|
||||||
xmp file.xmp set XMP metadata
|
|
||||||
where: 'file.icc' contains the ICC profile to be set,
|
|
||||||
'file.exif' contains the EXIF metadata to be set
|
|
||||||
'file.xmp' contains the XMP metadata to be set
|
|
||||||
|
|
||||||
DURATION_OPTIONS:
|
|
||||||
Set duration of selected frames:
|
|
||||||
duration set duration for all frames
|
|
||||||
duration,frame set duration of a particular frame
|
|
||||||
duration,start,end set duration of frames in the
|
|
||||||
interval [start,end])
|
|
||||||
where: 'duration' is the duration in milliseconds
|
|
||||||
'start' is the start frame index
|
|
||||||
'end' is the inclusive end frame index
|
|
||||||
The special 'end' value '0' means: last frame.
|
|
||||||
|
|
||||||
STRIP_OPTIONS:
|
|
||||||
Strip color profile/metadata:
|
|
||||||
icc strip ICC profile
|
|
||||||
exif strip EXIF metadata
|
|
||||||
xmp strip XMP metadata
|
|
||||||
|
|
||||||
FRAME_OPTIONS(i):
|
|
||||||
Create animation:
|
|
||||||
file_i +di[+xi+yi[+mi[bi]]]
|
|
||||||
where: 'file_i' is the i'th animation frame (WebP format),
|
|
||||||
'di' is the pause duration before next frame,
|
|
||||||
'xi','yi' specify the image offset for this frame,
|
|
||||||
'mi' is the dispose method for this frame (0 or 1),
|
|
||||||
'bi' is the blending method for this frame (+b or -b)
|
|
||||||
|
|
||||||
LOOP_COUNT:
|
|
||||||
Number of times to repeat the animation.
|
|
||||||
Valid range is 0 to 65535 [Default: 0 (infinite)].
|
|
||||||
|
|
||||||
BACKGROUND_COLOR:
|
|
||||||
Background color of the canvas.
|
|
||||||
A,R,G,B
|
|
||||||
where: 'A', 'R', 'G' and 'B' are integers in the range 0 to 255 specifying
|
|
||||||
the Alpha, Red, Green and Blue component values respectively
|
|
||||||
[Default: 255,255,255,255]
|
|
||||||
|
|
||||||
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 '-'.
|
|
||||||
```
|
|
||||||
@@ -2,10 +2,10 @@
|
|||||||
|
|
||||||
Although you may be viewing an alternate representation, this document
|
Although you may be viewing an alternate representation, this document
|
||||||
is sourced in Markdown, a light-duty markup scheme, and is optimized for
|
is sourced in Markdown, a light-duty markup scheme, and is optimized for
|
||||||
the [kramdown](https://kramdown.gettalong.org/) transformer.
|
the [kramdown](http://kramdown.rubyforge.org/) transformer.
|
||||||
|
|
||||||
See the accompanying specs_generation.md. External link targets are referenced
|
See the accompanying README. External link targets are referenced at the
|
||||||
at the end of this file.
|
end of this file.
|
||||||
|
|
||||||
-->
|
-->
|
||||||
|
|
||||||
@@ -36,7 +36,7 @@ for:
|
|||||||
* **Lossless compression.** An image can be losslessly compressed, using the
|
* **Lossless compression.** An image can be losslessly compressed, using the
|
||||||
WebP Lossless Format.
|
WebP Lossless Format.
|
||||||
|
|
||||||
* **Metadata.** An image may have metadata stored in Exif or XMP formats.
|
* **Metadata.** An image may have metadata stored in EXIF or XMP formats.
|
||||||
|
|
||||||
* **Transparency.** An image may have transparency, i.e., an alpha channel.
|
* **Transparency.** An image may have transparency, i.e., an alpha channel.
|
||||||
|
|
||||||
@@ -53,6 +53,10 @@ document are to be interpreted as described in [RFC 2119][].
|
|||||||
Bit numbering in chunk diagrams starts at `0` for the most significant bit
|
Bit numbering in chunk diagrams starts at `0` for the most significant bit
|
||||||
('MSB 0') as described in [RFC 1166][].
|
('MSB 0') as described in [RFC 1166][].
|
||||||
|
|
||||||
|
**Note:** Out of the features mentioned above, lossy compression, lossless
|
||||||
|
compression, transparency, metadata, color profile and animation are finalized
|
||||||
|
and are to be considered stable.
|
||||||
|
|
||||||
Terminology & Basics
|
Terminology & Basics
|
||||||
------------------------
|
------------------------
|
||||||
|
|
||||||
@@ -94,7 +98,7 @@ _1-based_
|
|||||||
RIFF File Format
|
RIFF File Format
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
The WebP file format is based on the RIFF (Resource Interchange File Format)
|
The WebP file format is based on the RIFF (resource interchange file format)
|
||||||
document format.
|
document format.
|
||||||
|
|
||||||
The basic element of a RIFF file is a _chunk_. It consists of:
|
The basic element of a RIFF file is a _chunk_. It consists of:
|
||||||
@@ -261,11 +265,11 @@ An extended format file consists of:
|
|||||||
|
|
||||||
* Image data.
|
* Image data.
|
||||||
|
|
||||||
* An optional 'EXIF' chunk with Exif metadata.
|
* An optional 'EXIF' chunk with EXIF metadata.
|
||||||
|
|
||||||
* An optional 'XMP ' chunk with XMP metadata.
|
* An optional 'XMP ' chunk with XMP metadata.
|
||||||
|
|
||||||
* An optional list of [unknown chunks](#unknown-chunks).
|
* An optional list of [unknown chunks](#unknown-chunks). _\[status: experimental\]_
|
||||||
|
|
||||||
For a _still image_, the _image data_ consists of a single frame, which is made
|
For a _still image_, the _image data_ consists of a single frame, which is made
|
||||||
up of:
|
up of:
|
||||||
@@ -317,9 +321,9 @@ Alpha (L): 1 bit
|
|||||||
: Set if any of the frames of the image contain transparency information
|
: Set if any of the frames of the image contain transparency information
|
||||||
("alpha").
|
("alpha").
|
||||||
|
|
||||||
Exif metadata (E): 1 bit
|
EXIF metadata (E): 1 bit
|
||||||
|
|
||||||
: Set if the file contains Exif metadata.
|
: Set if the file contains EXIF metadata.
|
||||||
|
|
||||||
XMP metadata (X): 1 bit
|
XMP metadata (X): 1 bit
|
||||||
|
|
||||||
@@ -341,12 +345,12 @@ Reserved: 24 bits
|
|||||||
Canvas Width Minus One: 24 bits
|
Canvas Width Minus One: 24 bits
|
||||||
|
|
||||||
: _1-based_ width of the canvas in pixels.
|
: _1-based_ width of the canvas in pixels.
|
||||||
The actual canvas width is `1 + Canvas Width Minus One`.
|
The actual canvas width is '1 + Canvas Width Minus One'
|
||||||
|
|
||||||
Canvas Height Minus One: 24 bits
|
Canvas Height Minus One: 24 bits
|
||||||
|
|
||||||
: _1-based_ height of the canvas in pixels.
|
: _1-based_ height of the canvas in pixels.
|
||||||
The actual canvas height is `1 + Canvas Height Minus One`.
|
The actual canvas height is '1 + Canvas Height Minus One'
|
||||||
|
|
||||||
The product of _Canvas Width_ and _Canvas Height_ MUST be at most `2^32 - 1`.
|
The product of _Canvas Width_ and _Canvas Height_ MUST be at most `2^32 - 1`.
|
||||||
|
|
||||||
@@ -423,28 +427,27 @@ If the _Animation flag_ is not set, then this chunk SHOULD NOT be present.
|
|||||||
|
|
||||||
Frame X: 24 bits (_uint24_)
|
Frame X: 24 bits (_uint24_)
|
||||||
|
|
||||||
: The X coordinate of the upper left corner of the frame is `Frame X * 2`.
|
: The X coordinate of the upper left corner of the frame is `Frame X * 2`
|
||||||
|
|
||||||
Frame Y: 24 bits (_uint24_)
|
Frame Y: 24 bits (_uint24_)
|
||||||
|
|
||||||
: The Y coordinate of the upper left corner of the frame is `Frame Y * 2`.
|
: The Y coordinate of the upper left corner of the frame is `Frame Y * 2`
|
||||||
|
|
||||||
Frame Width Minus One: 24 bits (_uint24_)
|
Frame Width Minus One: 24 bits (_uint24_)
|
||||||
|
|
||||||
: The _1-based_ width of the frame.
|
: The _1-based_ width of the frame.
|
||||||
The frame width is `1 + Frame Width Minus One`.
|
The frame width is `1 + Frame Width Minus One`
|
||||||
|
|
||||||
Frame Height Minus One: 24 bits (_uint24_)
|
Frame Height Minus One: 24 bits (_uint24_)
|
||||||
|
|
||||||
: The _1-based_ height of the frame.
|
: The _1-based_ height of the frame.
|
||||||
The frame height is `1 + Frame Height Minus One`.
|
The frame height is `1 + Frame Height Minus One`
|
||||||
|
|
||||||
Frame Duration: 24 bits (_uint24_)
|
Frame Duration: 24 bits (_uint24_)
|
||||||
|
|
||||||
: The time to wait before displaying the next frame, in 1 millisecond units.
|
: The time to wait before displaying the next frame, in 1 millisecond units.
|
||||||
Note the interpretation of frame duration of 0 (and often <= 10) is
|
In particular, frame duration of 0 is useful when one wants to update
|
||||||
implementation defined. Many tools and browsers assign a minimum duration
|
multiple areas of the canvas at once during the animation.
|
||||||
similar to GIF.
|
|
||||||
|
|
||||||
Reserved: 6 bits
|
Reserved: 6 bits
|
||||||
|
|
||||||
@@ -677,12 +680,12 @@ EXIF chunk:
|
|||||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
| ChunkHeader('EXIF') |
|
| ChunkHeader('EXIF') |
|
||||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
| Exif Metadata |
|
| EXIF Metadata |
|
||||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
|
||||||
Exif Metadata: _Chunk Size_ bytes
|
EXIF Metadata: _Chunk Size_ bytes
|
||||||
|
|
||||||
: image metadata in Exif format.
|
: image metadata in EXIF format.
|
||||||
|
|
||||||
XMP chunk:
|
XMP chunk:
|
||||||
|
|
||||||
@@ -701,7 +704,7 @@ XMP Metadata: _Chunk Size_ bytes
|
|||||||
Additional guidance about handling metadata can be found in the
|
Additional guidance about handling metadata can be found in the
|
||||||
Metadata Working Group's [Guidelines for Handling Metadata][metadata].
|
Metadata Working Group's [Guidelines for Handling Metadata][metadata].
|
||||||
|
|
||||||
#### Unknown Chunks
|
#### Unknown Chunks _\[status: experimental\]_
|
||||||
|
|
||||||
A RIFF chunk (described in [this](#terminology-amp-basics) section) whose _chunk
|
A RIFF chunk (described in [this](#terminology-amp-basics) section) whose _chunk
|
||||||
tag_ is different from any of the chunks described in this document, is
|
tag_ is different from any of the chunks described in this document, is
|
||||||
@@ -798,7 +801,7 @@ RIFF/WEBP
|
|||||||
+- XMP (metadata)
|
+- XMP (metadata)
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
An animated image with Exif metadata may look as follows:
|
An animated image with EXIF metadata may look as follows:
|
||||||
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
RIFF/WEBP
|
RIFF/WEBP
|
||||||
@@ -811,9 +814,9 @@ RIFF/WEBP
|
|||||||
+- EXIF (metadata)
|
+- EXIF (metadata)
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
[vp8spec]: https://datatracker.ietf.org/doc/html/rfc6386
|
[vp8spec]: http://tools.ietf.org/html/rfc6386
|
||||||
[webpllspec]: https://chromium.googlesource.com/webm/libwebp/+/HEAD/doc/webp-lossless-bitstream-spec.txt
|
[webpllspec]: https://chromium.googlesource.com/webm/libwebp/+/master/doc/webp-lossless-bitstream-spec.txt
|
||||||
[iccspec]: https://www.color.org/icc_specs2.xalter
|
[iccspec]: http://www.color.org/icc_specs2.xalter
|
||||||
[metadata]: https://web.archive.org/web/20180919181934/http://www.metadataworkinggroup.org/pdf/mwg_guidance.pdf
|
[metadata]: http://www.metadataworkinggroup.org/pdf/mwg_guidance.pdf
|
||||||
[rfc 1166]: https://datatracker.ietf.org/doc/html/rfc1166
|
[rfc 1166]: http://tools.ietf.org/html/rfc1166
|
||||||
[rfc 2119]: https://datatracker.ietf.org/doc/html/rfc2119
|
[rfc 2119]: http://tools.ietf.org/html/rfc2119
|
||||||
|
|||||||
@@ -2,10 +2,10 @@
|
|||||||
|
|
||||||
Although you may be viewing an alternate representation, this document
|
Although you may be viewing an alternate representation, this document
|
||||||
is sourced in Markdown, a light-duty markup scheme, and is optimized for
|
is sourced in Markdown, a light-duty markup scheme, and is optimized for
|
||||||
the [kramdown](https://kramdown.gettalong.org/) transformer.
|
the [kramdown](http://kramdown.rubyforge.org/) transformer.
|
||||||
|
|
||||||
See the accompanying specs_generation.md. External link targets are referenced
|
See the accompanying README. External link targets are referenced at the
|
||||||
at the end of this file.
|
end of this file.
|
||||||
|
|
||||||
-->
|
-->
|
||||||
|
|
||||||
@@ -16,8 +16,6 @@ _Jyrki Alakuijala, Ph.D., Google, Inc., 2012-06-19_
|
|||||||
|
|
||||||
Paragraphs marked as \[AMENDED\] were amended on 2014-09-16.
|
Paragraphs marked as \[AMENDED\] were amended on 2014-09-16.
|
||||||
|
|
||||||
Paragraphs marked as \[AMENDED2\] were amended on 2022-05-13.
|
|
||||||
|
|
||||||
Abstract
|
Abstract
|
||||||
--------
|
--------
|
||||||
|
|
||||||
@@ -27,7 +25,7 @@ exactly, including the color values for zero alpha pixels. The
|
|||||||
format uses subresolution images, recursively embedded into the format
|
format uses subresolution images, recursively embedded into the format
|
||||||
itself, for storing statistical data about the images, such as the used
|
itself, for storing statistical data about the images, such as the used
|
||||||
entropy codes, spatial predictors, color space conversion, and color
|
entropy codes, spatial predictors, color space conversion, and color
|
||||||
table. LZ77, prefix coding, and a color cache are used for compression
|
table. LZ77, Huffman coding, and a color cache are used for compression
|
||||||
of the bulk data. Decoding speeds faster than PNG have been
|
of the bulk data. Decoding speeds faster than PNG have been
|
||||||
demonstrated, as well as 25% denser compression than can be achieved
|
demonstrated, as well as 25% denser compression than can be achieved
|
||||||
using today's PNG format.
|
using today's PNG format.
|
||||||
@@ -65,9 +63,9 @@ distance mapping
|
|||||||
entropy image
|
entropy image
|
||||||
: A two-dimensional subresolution image indicating which entropy coding
|
: A two-dimensional subresolution image indicating which entropy coding
|
||||||
should be used in a respective square in the image, i.e., each pixel
|
should be used in a respective square in the image, i.e., each pixel
|
||||||
is a meta prefix code.
|
is a meta Huffman code.
|
||||||
|
|
||||||
prefix code
|
Huffman code
|
||||||
: A classic way to do entropy coding where a smaller number of bits are
|
: A classic way to do entropy coding where a smaller number of bits are
|
||||||
used for more frequent codes.
|
used for more frequent codes.
|
||||||
|
|
||||||
@@ -75,9 +73,9 @@ LZ77
|
|||||||
: Dictionary-based sliding window compression algorithm that either
|
: Dictionary-based sliding window compression algorithm that either
|
||||||
emits symbols or describes them as sequences of past symbols.
|
emits symbols or describes them as sequences of past symbols.
|
||||||
|
|
||||||
meta prefix code
|
meta Huffman code
|
||||||
: A small integer (up to 16 bits) that indexes an element in the meta
|
: A small integer (up to 16 bits) that indexes an element in the meta
|
||||||
prefix table.
|
Huffman table.
|
||||||
|
|
||||||
predictor image
|
predictor image
|
||||||
: A two-dimensional subresolution image indicating which spatial
|
: A two-dimensional subresolution image indicating which spatial
|
||||||
@@ -237,7 +235,7 @@ transform, the current pixel value is predicted from the pixels already
|
|||||||
decoded (in scan-line order) and only the residual value (actual -
|
decoded (in scan-line order) and only the residual value (actual -
|
||||||
predicted) is encoded. The _prediction mode_ determines the type of
|
predicted) is encoded. The _prediction mode_ determines the type of
|
||||||
prediction to use. We divide the image into squares and all the pixels
|
prediction to use. We divide the image into squares and all the pixels
|
||||||
in a square use the same prediction mode.
|
in a square use same prediction mode.
|
||||||
|
|
||||||
The first 3 bits of prediction data define the block width and height in
|
The first 3 bits of prediction data define the block width and height in
|
||||||
number of bits. The number of block columns, `block_xsize`, is used in
|
number of bits. The number of block columns, `block_xsize`, is used in
|
||||||
@@ -369,17 +367,15 @@ the predicted value for the left-topmost pixel of the image is
|
|||||||
0xff000000, L-pixel for all pixels on the top row, and T-pixel for all
|
0xff000000, L-pixel for all pixels on the top row, and T-pixel for all
|
||||||
pixels on the leftmost column.
|
pixels on the leftmost column.
|
||||||
|
|
||||||
\[AMENDED2\]
|
|
||||||
Addressing the TR-pixel for pixels on the rightmost column is
|
Addressing the TR-pixel for pixels on the rightmost column is
|
||||||
exceptional. The pixels on the rightmost column are predicted by using
|
exceptional. The pixels on the rightmost column are predicted by using
|
||||||
the modes \[0..13\] just like pixels not on the border, but the leftmost pixel
|
the modes \[0..13\] just like pixels not on border, but by using the
|
||||||
on the same row as the current pixel is instead used as the TR-pixel.
|
leftmost pixel on the same row as the current TR-pixel. The TR-pixel
|
||||||
|
offset in memory is the same for border and non-border pixels.
|
||||||
|
|
||||||
|
|
||||||
### Color Transform
|
### Color Transform
|
||||||
|
|
||||||
\[AMENDED2\]
|
|
||||||
|
|
||||||
The goal of the color transform is to decorrelate the R, G and B values
|
The goal of the color transform is to decorrelate the R, G and B values
|
||||||
of each pixel. Color transform keeps the green (G) value as it is,
|
of each pixel. Color transform keeps the green (G) value as it is,
|
||||||
transforms red (R) based on green and transforms blue (B) based on green
|
transforms red (R) based on green and transforms blue (B) based on green
|
||||||
@@ -400,8 +396,8 @@ typedef struct {
|
|||||||
The actual color transformation is done by defining a color transform
|
The actual color transformation is done by defining a color transform
|
||||||
delta. The color transform delta depends on the `ColorTransformElement`,
|
delta. The color transform delta depends on the `ColorTransformElement`,
|
||||||
which is the same for all the pixels in a particular block. The delta is
|
which is the same for all the pixels in a particular block. The delta is
|
||||||
subtracted during color transform. The inverse color transform then is just
|
added during color transform. The inverse color transform then is just
|
||||||
adding those deltas.
|
subtracting those deltas.
|
||||||
|
|
||||||
The color transform function is defined as follows:
|
The color transform function is defined as follows:
|
||||||
|
|
||||||
@@ -410,13 +406,13 @@ void ColorTransform(uint8 red, uint8 blue, uint8 green,
|
|||||||
ColorTransformElement *trans,
|
ColorTransformElement *trans,
|
||||||
uint8 *new_red, uint8 *new_blue) {
|
uint8 *new_red, uint8 *new_blue) {
|
||||||
// Transformed values of red and blue components
|
// Transformed values of red and blue components
|
||||||
int tmp_red = red;
|
uint32 tmp_red = red;
|
||||||
int tmp_blue = blue;
|
uint32 tmp_blue = blue;
|
||||||
|
|
||||||
// Applying the transform is just subtracting the transform deltas
|
// Applying transform is just adding the transform deltas
|
||||||
tmp_red -= ColorTransformDelta(p->green_to_red_, green);
|
tmp_red += ColorTransformDelta(trans->green_to_red, green);
|
||||||
tmp_blue -= ColorTransformDelta(p->green_to_blue_, green);
|
tmp_blue += ColorTransformDelta(trans->green_to_blue, green);
|
||||||
tmp_blue -= ColorTransformDelta(p->red_to_blue_, red);
|
tmp_blue += ColorTransformDelta(trans->red_to_blue, red);
|
||||||
|
|
||||||
*new_red = tmp_red & 0xff;
|
*new_red = tmp_red & 0xff;
|
||||||
*new_blue = tmp_blue & 0xff;
|
*new_blue = tmp_blue & 0xff;
|
||||||
@@ -434,7 +430,7 @@ int8 ColorTransformDelta(int8 t, int8 c) {
|
|||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
A conversion from the 8-bit unsigned representation (uint8) to the 8-bit
|
A conversion from the 8-bit unsigned representation (uint8) to the 8-bit
|
||||||
signed one (int8) is required before calling `ColorTransformDelta()`.
|
signed one (int8) is required before calling ColorTransformDelta().
|
||||||
It should be performed using 8-bit two's complement (that is: uint8 range
|
It should be performed using 8-bit two's complement (that is: uint8 range
|
||||||
\[128-255\] is mapped to the \[-128, -1\] range of its converted int8 value).
|
\[128-255\] is mapped to the \[-128, -1\] range of its converted int8 value).
|
||||||
|
|
||||||
@@ -472,18 +468,14 @@ channels.
|
|||||||
void InverseTransform(uint8 red, uint8 green, uint8 blue,
|
void InverseTransform(uint8 red, uint8 green, uint8 blue,
|
||||||
ColorTransformElement *p,
|
ColorTransformElement *p,
|
||||||
uint8 *new_red, uint8 *new_blue) {
|
uint8 *new_red, uint8 *new_blue) {
|
||||||
// Transformed values of red and blue components
|
// Applying inverse transform is just subtracting the
|
||||||
int tmp_red = red;
|
|
||||||
int tmp_blue = blue;
|
|
||||||
|
|
||||||
// Applying inverse transform is just adding the
|
|
||||||
// color transform deltas
|
// color transform deltas
|
||||||
tmp_red += ColorTransformDelta(trans->green_to_red, green);
|
red -= ColorTransformDelta(p->green_to_red_, green);
|
||||||
tmp_blue += ColorTransformDelta(trans->green_to_blue, green);
|
blue -= ColorTransformDelta(p->green_to_blue_, green);
|
||||||
tmp_blue += ColorTransformDelta(trans->red_to_blue, tmp_red & 0xff);
|
blue -= ColorTransformDelta(p->red_to_blue_, red & 0xff);
|
||||||
|
|
||||||
*new_red = tmp_red & 0xff;
|
*new_red = red & 0xff;
|
||||||
*new_blue = tmp_blue & 0xff;
|
*new_blue = blue & 0xff;
|
||||||
}
|
}
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
@@ -598,12 +590,12 @@ The values are packed into the green component as follows:
|
|||||||
4 most-significant bits of the green value at x / 2.
|
4 most-significant bits of the green value at x / 2.
|
||||||
* `width_bits` = 2: for every x value where x ≡ 0 (mod 4), a green
|
* `width_bits` = 2: for every x value where x ≡ 0 (mod 4), a green
|
||||||
value at x is positioned into the 2 least-significant bits of the
|
value at x is positioned into the 2 least-significant bits of the
|
||||||
green value at x / 4, green values at x + 1 to x + 3 are positioned in order
|
green value at x / 4, green values at x + 1 to x + 3 in order to the
|
||||||
to the more significant bits of the green value at x / 4.
|
more significant bits of the green value at x / 4.
|
||||||
* `width_bits` = 3: for every x value where x ≡ 0 (mod 8), a green
|
* `width_bits` = 3: for every x value where x ≡ 0 (mod 8), a green
|
||||||
value at x is positioned into the least-significant bit of the green
|
value at x is positioned into the least-significant bit of the green
|
||||||
value at x / 8, green values at x + 1 to x + 7 are positioned in order to
|
value at x / 8, green values at x + 1 to x + 7 in order to the more
|
||||||
the more significant bits of the green value at x / 8.
|
significant bits of the green value at x / 8.
|
||||||
|
|
||||||
|
|
||||||
4 Image Data
|
4 Image Data
|
||||||
@@ -617,8 +609,8 @@ We use image data in five different roles:
|
|||||||
|
|
||||||
1. ARGB image: Stores the actual pixels of the image.
|
1. ARGB image: Stores the actual pixels of the image.
|
||||||
1. Entropy image: Stores the
|
1. Entropy image: Stores the
|
||||||
[meta prefix codes](#decoding-of-meta-prefix-codes). The red and green
|
[meta Huffman codes](#decoding-of-meta-huffman-codes). The red and green
|
||||||
components of a pixel define the meta prefix code used in a particular
|
components of a pixel define the meta Huffman code used in a particular
|
||||||
block of the ARGB image.
|
block of the ARGB image.
|
||||||
1. Predictor image: Stores the metadata for [Predictor
|
1. Predictor image: Stores the metadata for [Predictor
|
||||||
Transform](#predictor-transform). The green component of a pixel defines
|
Transform](#predictor-transform). The green component of a pixel defines
|
||||||
@@ -629,12 +621,12 @@ We use image data in five different roles:
|
|||||||
the image. Each `ColorTransformElement` `'cte'` is treated as a pixel whose
|
the image. Each `ColorTransformElement` `'cte'` is treated as a pixel whose
|
||||||
alpha component is `255`, red component is `cte.red_to_blue`, green
|
alpha component is `255`, red component is `cte.red_to_blue`, green
|
||||||
component is `cte.green_to_blue` and blue component is `cte.green_to_red`.
|
component is `cte.green_to_blue` and blue component is `cte.green_to_red`.
|
||||||
1. Color indexing image: An array of size `color_table_size` (up to 256
|
1. Color indexing image: An array of of size `color_table_size` (up to 256
|
||||||
ARGB values) storing the metadata for the
|
ARGB values) storing the metadata for the
|
||||||
[Color Indexing Transform](#color-indexing-transform). This is stored as an
|
[Color Indexing Transform](#color-indexing-transform). This is stored as an
|
||||||
image of width `color_table_size` and height `1`.
|
image of width `color_table_size` and height `1`.
|
||||||
|
|
||||||
### 4.2 Encoding of Image Data
|
### 4.2 Encoding of Image data
|
||||||
|
|
||||||
The encoding of image data is independent of its role.
|
The encoding of image data is independent of its role.
|
||||||
|
|
||||||
@@ -651,7 +643,7 @@ the image.
|
|||||||
|
|
||||||
Each pixel is encoded using one of the three possible methods:
|
Each pixel is encoded using one of the three possible methods:
|
||||||
|
|
||||||
1. prefix coded literal: each channel (green, red, blue and alpha) is
|
1. Huffman coded literal: each channel (green, red, blue and alpha) is
|
||||||
entropy-coded independently;
|
entropy-coded independently;
|
||||||
2. LZ77 backward reference: a sequence of pixels are copied from elsewhere
|
2. LZ77 backward reference: a sequence of pixels are copied from elsewhere
|
||||||
in the image; or
|
in the image; or
|
||||||
@@ -660,9 +652,9 @@ Each pixel is encoded using one of the three possible methods:
|
|||||||
|
|
||||||
The following sub-sections describe each of these in detail.
|
The following sub-sections describe each of these in detail.
|
||||||
|
|
||||||
#### 4.2.1 Prefix Coded Literals
|
#### 4.2.1 Huffman Coded Literals
|
||||||
|
|
||||||
The pixel is stored as prefix coded values of green, red, blue and alpha (in
|
The pixel is stored as Huffman coded values of green, red, blue and alpha (in
|
||||||
that order). See [this section](#decoding-entropy-coded-image-data) for details.
|
that order). See [this section](#decoding-entropy-coded-image-data) for details.
|
||||||
|
|
||||||
#### 4.2.2 LZ77 Backward Reference
|
#### 4.2.2 LZ77 Backward Reference
|
||||||
@@ -686,7 +678,7 @@ very few values in the image. Thus, this approach results in a better
|
|||||||
compression overall.
|
compression overall.
|
||||||
|
|
||||||
The following table denotes the prefix codes and extra bits used for storing
|
The following table denotes the prefix codes and extra bits used for storing
|
||||||
different ranges of values.
|
different range of values.
|
||||||
|
|
||||||
Note: The maximum backward reference length is limited to 4096. Hence, only the
|
Note: The maximum backward reference length is limited to 4096. Hence, only the
|
||||||
first 24 prefix codes (with the respective extra bits) are meaningful for length
|
first 24 prefix codes (with the respective extra bits) are meaningful for length
|
||||||
@@ -761,13 +753,13 @@ The mapping between distance code `i` and the neighboring pixel offset
|
|||||||
(-6, 7), (7, 6), (-7, 6), (8, 5), (7, 7), (-7, 7), (8, 6), (8, 7)
|
(-6, 7), (7, 6), (-7, 6), (8, 5), (7, 7), (-7, 7), (8, 6), (8, 7)
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
For example, distance code `1` indicates an offset of `(0, 1)` for the
|
For example, distance code `1` indicates offset of `(0, 1)` for the neighboring
|
||||||
neighboring pixel, that is, the pixel above the current pixel (0 pixel
|
pixel, that is, the pixel above the current pixel (0-pixel difference in
|
||||||
difference in X-direction and 1 pixel difference in Y-direction). Similarly,
|
X-direction and 1 pixel difference in Y-direction). Similarly, distance code
|
||||||
distance code `3` indicates left-top pixel.
|
`3` indicates left-top pixel.
|
||||||
|
|
||||||
The decoder can convert a distance code `i` to a scan-line order distance
|
The decoder can convert a distances code 'i' to a scan-line order distance
|
||||||
`dist` as follows:
|
'dist' as follows:
|
||||||
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
(xi, yi) = distance_map[i]
|
(xi, yi) = distance_map[i]
|
||||||
@@ -777,22 +769,21 @@ if (dist < 1) {
|
|||||||
}
|
}
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
where `distance_map` is the mapping noted above and `xsize` is the width of the
|
where 'distance_map' is the mapping noted above and `xsize` is the width of the
|
||||||
image in pixels.
|
image in pixels.
|
||||||
|
|
||||||
|
|
||||||
#### 4.2.3 Color Cache Coding
|
#### 4.2.3 Color Cache Coding
|
||||||
{:#color-cache-code}
|
|
||||||
|
|
||||||
Color cache stores a set of colors that have been recently used in the image.
|
Color cache stores a set of colors that have been recently used in the image.
|
||||||
|
|
||||||
**Rationale:** This way, the recently used colors can sometimes be referred to
|
**Rationale:** This way, the recently used colors can sometimes be referred to
|
||||||
more efficiently than emitting them using the other two methods (described in
|
more efficiently than emitting them using other two methods (described in
|
||||||
[4.2.1](#prefix-coded-literals) and [4.2.2](#lz77-backward-reference)).
|
[4.2.1](#huffman-coded-literals) and [4.2.2](#lz77-backward-reference)).
|
||||||
|
|
||||||
Color cache codes are stored as follows. First, there is a 1-bit value that
|
Color cache codes are stored as follows. First, there is a 1-bit value that
|
||||||
indicates if the color cache is used. If this bit is 0, no color cache codes
|
indicates if the color cache is used. If this bit is 0, no color cache codes
|
||||||
exist, and they are not transmitted in the prefix code that decodes the green
|
exist, and they are not transmitted in the Huffman code that decodes the green
|
||||||
symbols and the length prefix codes. However, if this bit is 1, the color cache
|
symbols and the length prefix codes. However, if this bit is 1, the color cache
|
||||||
size is read next:
|
size is read next:
|
||||||
|
|
||||||
@@ -823,245 +814,130 @@ literals, into the cache in the order they appear in the stream.
|
|||||||
|
|
||||||
### 5.1 Overview
|
### 5.1 Overview
|
||||||
|
|
||||||
Most of the data is coded using a [canonical prefix code][canonical_huff].
|
Most of the data is coded using [canonical Huffman code][canonical_huff]. Hence,
|
||||||
Hence, the codes are transmitted by sending the _prefix code lengths_, as
|
the codes are transmitted by sending the _Huffman code lengths_, as opposed to
|
||||||
opposed to the actual _prefix codes_.
|
the actual _Huffman codes_.
|
||||||
|
|
||||||
In particular, the format uses **spatially-variant prefix coding**. In other
|
In particular, the format uses **spatially-variant Huffman coding**. In other
|
||||||
words, different blocks of the image can potentially use different entropy
|
words, different blocks of the image can potentially use different entropy
|
||||||
codes.
|
codes.
|
||||||
|
|
||||||
**Rationale**: Different areas of the image may have different characteristics.
|
**Rationale**: Different areas of the image may have different characteristics. So, allowing them to use different entropy codes provides more flexibility and
|
||||||
So, allowing them to use different entropy codes provides more flexibility and
|
potentially a better compression.
|
||||||
potentially better compression.
|
|
||||||
|
|
||||||
### 5.2 Details
|
### 5.2 Details
|
||||||
|
|
||||||
The encoded image data consists of several parts:
|
The encoded image data consists of two parts:
|
||||||
|
|
||||||
1. Decoding and building the prefix codes \[AMENDED2\]
|
1. Meta Huffman codes
|
||||||
1. Meta prefix codes
|
|
||||||
1. Entropy-coded image data
|
1. Entropy-coded image data
|
||||||
|
|
||||||
#### 5.2.1 Decoding and Building the Prefix Codes
|
#### 5.2.1 Decoding of Meta Huffman Codes
|
||||||
|
|
||||||
There are several steps in decoding the prefix codes.
|
As noted earlier, the format allows the use of different Huffman codes for
|
||||||
|
different blocks of the image. _Meta Huffman codes_ are indexes identifying
|
||||||
|
which Huffman codes to use in different parts of the image.
|
||||||
|
|
||||||
**Decoding the Code Lengths:**
|
Meta Huffman codes may be used _only_ when the image is being used in the
|
||||||
{:#decoding-the-code-lengths}
|
|
||||||
|
|
||||||
This section describes how to read the prefix code lengths from the bitstream.
|
|
||||||
|
|
||||||
The prefix code lengths can be coded in two ways. The method used is specified
|
|
||||||
by a 1-bit value.
|
|
||||||
|
|
||||||
* If this bit is 1, it is a _simple code length code_, and
|
|
||||||
* If this bit is 0, it is a _normal code length code_.
|
|
||||||
|
|
||||||
In both cases, there can be unused code lengths that are still part of the
|
|
||||||
stream. This may be inefficient, but it is allowed by the format.
|
|
||||||
|
|
||||||
**(i) Simple Code Length Code:**
|
|
||||||
|
|
||||||
\[AMENDED2\]
|
|
||||||
|
|
||||||
This variant is used in the special case when only 1 or 2 prefix symbols are
|
|
||||||
in the range \[0..255\] with code length `1`. All other prefix code lengths
|
|
||||||
are implicitly zeros.
|
|
||||||
|
|
||||||
The first bit indicates the number of symbols:
|
|
||||||
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
int num_symbols = ReadBits(1) + 1;
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
Following are the symbol values.
|
|
||||||
This first symbol is coded using 1 or 8 bits depending on the value of
|
|
||||||
`is_first_8bits`. The range is \[0..1\] or \[0..255\], respectively.
|
|
||||||
The second symbol, if present, is always assumed to be in the range \[0..255\]
|
|
||||||
and coded using 8 bits.
|
|
||||||
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
int is_first_8bits = ReadBits(1);
|
|
||||||
symbol0 = ReadBits(1 + 7 * is_first_8bits);
|
|
||||||
code_lengths[symbol0] = 1;
|
|
||||||
if (num_symbols == 2) {
|
|
||||||
symbol1 = ReadBits(8);
|
|
||||||
code_lengths[symbol1] = 1;
|
|
||||||
}
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
**Note:** Another special case is when _all_ prefix code lengths are _zeros_
|
|
||||||
(an empty prefix code). For example, a prefix code for distance can be empty
|
|
||||||
if there are no backward references. Similarly, prefix codes for alpha, red,
|
|
||||||
and blue can be empty if all pixels within the same meta prefix code are
|
|
||||||
produced using the color cache. However, this case doesn't need a special
|
|
||||||
handling, as empty prefix codes can be coded as those containing a single
|
|
||||||
symbol `0`.
|
|
||||||
|
|
||||||
**(ii) Normal Code Length Code:**
|
|
||||||
|
|
||||||
The code lengths of the prefix code fit in 8 bits and are read as follows.
|
|
||||||
First, `num_code_lengths` specifies the number of code lengths.
|
|
||||||
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
int num_code_lengths = 4 + ReadBits(4);
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
If `num_code_lengths` is > 18, the bitstream is invalid.
|
|
||||||
|
|
||||||
The code lengths are themselves encoded using prefix codes: lower level code
|
|
||||||
lengths `code_length_code_lengths` first have to be read. The rest of those
|
|
||||||
`code_length_code_lengths` (according to the order in `kCodeLengthCodeOrder`)
|
|
||||||
are zeros.
|
|
||||||
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
int kCodeLengthCodes = 19;
|
|
||||||
int kCodeLengthCodeOrder[kCodeLengthCodes] = {
|
|
||||||
17, 18, 0, 1, 2, 3, 4, 5, 16, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
|
|
||||||
};
|
|
||||||
int code_length_code_lengths[kCodeLengthCodes] = { 0 }; // All zeros.
|
|
||||||
for (i = 0; i < num_code_lengths; ++i) {
|
|
||||||
code_length_code_lengths[kCodeLengthCodeOrder[i]] = ReadBits(3);
|
|
||||||
}
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
Next, if `ReadBits(1) == 0`, the maximum number of different read symbols is
|
|
||||||
`num_code_lengths`. Otherwise, it is defined as:
|
|
||||||
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
int length_nbits = 2 + 2 * ReadBits(3);
|
|
||||||
int max_symbol = 2 + ReadBits(length_nbits);
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
A prefix table is then built from `code_length_code_lengths` and used to read
|
|
||||||
up to `max_symbol` code lengths.
|
|
||||||
|
|
||||||
* Code \[0..15\] indicates literal code lengths.
|
|
||||||
* Value 0 means no symbols have been coded.
|
|
||||||
* Values \[1..15\] indicate the bit length of the respective code.
|
|
||||||
* Code 16 repeats the previous non-zero value \[3..6\] times, i.e.,
|
|
||||||
`3 + ReadBits(2)` times. If code 16 is used before a non-zero
|
|
||||||
value has been emitted, a value of 8 is repeated.
|
|
||||||
* Code 17 emits a streak of zeros \[3..10\], i.e., `3 + ReadBits(3)`
|
|
||||||
times.
|
|
||||||
* Code 18 emits a streak of zeros of length \[11..138\], i.e.,
|
|
||||||
`11 + ReadBits(7)` times.
|
|
||||||
|
|
||||||
Once code lengths are read, a prefix code for each symbol type (A, R, G, B,
|
|
||||||
distance) is formed using their respective alphabet sizes:
|
|
||||||
|
|
||||||
* G channel: 256 + 24 + `color_cache_size`
|
|
||||||
* other literals (A,R,B): 256
|
|
||||||
* distance code: 40
|
|
||||||
|
|
||||||
#### 5.2.2 Decoding of Meta Prefix Codes
|
|
||||||
|
|
||||||
As noted earlier, the format allows the use of different prefix codes for
|
|
||||||
different blocks of the image. _Meta prefix codes_ are indexes identifying
|
|
||||||
which prefix codes to use in different parts of the image.
|
|
||||||
|
|
||||||
Meta prefix codes may be used _only_ when the image is being used in the
|
|
||||||
[role](#roles-of-image-data) of an _ARGB image_.
|
[role](#roles-of-image-data) of an _ARGB image_.
|
||||||
|
|
||||||
There are two possibilities for the meta prefix codes, indicated by a 1-bit
|
There are two possibilities for the meta Huffman codes, indicated by a 1-bit
|
||||||
value:
|
value:
|
||||||
|
|
||||||
* If this bit is zero, there is only one meta prefix code used everywhere in
|
* If this bit is zero, there is only one meta Huffman code used everywhere in
|
||||||
the image. No more data is stored.
|
the image. No more data is stored.
|
||||||
* If this bit is one, the image uses multiple meta prefix codes. These meta
|
* If this bit is one, the image uses multiple meta Huffman codes. These meta
|
||||||
prefix codes are stored as an _entropy image_ (described below).
|
Huffman codes are stored as an _entropy image_ (described below).
|
||||||
|
|
||||||
**Entropy image:**
|
**Entropy image:**
|
||||||
|
|
||||||
The entropy image defines which prefix codes are used in different parts of the
|
The entropy image defines which Huffman codes are used in different parts of the
|
||||||
image, as described below.
|
image, as described below.
|
||||||
|
|
||||||
The first 3-bits contain the `prefix_bits` value. The dimensions of the entropy
|
The first 3-bits contain the `huffman_bits` value. The dimensions of the entropy
|
||||||
image are derived from 'prefix_bits'.
|
image are derived from 'huffman_bits'.
|
||||||
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
int prefix_bits = ReadBits(3) + 2;
|
int huffman_bits = ReadBits(3) + 2;
|
||||||
int prefix_xsize = DIV_ROUND_UP(xsize, 1 << prefix_bits);
|
int huffman_xsize = DIV_ROUND_UP(xsize, 1 << huffman_bits);
|
||||||
int prefix_ysize = DIV_ROUND_UP(ysize, 1 << prefix_bits);
|
int huffman_ysize = DIV_ROUND_UP(ysize, 1 << huffman_bits);
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
where `DIV_ROUND_UP` is as defined [earlier](#predictor-transform).
|
where `DIV_ROUND_UP` is as defined [earlier](#predictor-transform).
|
||||||
|
|
||||||
The next bits contain an entropy image of width `prefix_xsize` and height
|
Next bits contain an entropy image of width `huffman_xsize` and height
|
||||||
`prefix_ysize`.
|
`huffman_ysize`.
|
||||||
|
|
||||||
**Interpretation of Meta Prefix Codes:**
|
**Interpretation of Meta Huffman Codes:**
|
||||||
|
|
||||||
For any given pixel (x, y), there is a set of five prefix codes associated with
|
For any given pixel (x, y), there is a set of five Huffman codes associated with
|
||||||
it. These codes are (in bitstream order):
|
it. These codes are (in bitstream order):
|
||||||
|
|
||||||
* **prefix code #1**: used for green channel, backward-reference length and
|
* **Huffman code #1**: used for green channel, backward-reference length and
|
||||||
color cache
|
color cache
|
||||||
* **prefix code #2, #3 and #4**: used for red, blue and alpha channels
|
* **Huffman code #2, #3 and #4**: used for red, blue and alpha channels
|
||||||
respectively.
|
respectively.
|
||||||
* **prefix code #5**: used for backward-reference distance.
|
* **Huffman code #5**: used for backward-reference distance.
|
||||||
|
|
||||||
From here on, we refer to this set as a **prefix code group**.
|
From here on, we refer to this set as a **Huffman code group**.
|
||||||
|
|
||||||
The number of prefix code groups in the ARGB image can be obtained by finding
|
The number of Huffman code groups in the ARGB image can be obtained by finding
|
||||||
the _largest meta prefix code_ from the entropy image:
|
the _largest meta Huffman code_ from the entropy image:
|
||||||
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
int num_prefix_groups = max(entropy image) + 1;
|
int num_huff_groups = max(entropy image) + 1;
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
where `max(entropy image)` indicates the largest prefix code stored in the
|
where `max(entropy image)` indicates the largest Huffman code stored in the
|
||||||
entropy image.
|
entropy image.
|
||||||
|
|
||||||
As each prefix code group contains five prefix codes, the total number of
|
As each Huffman code groups contains five Huffman codes, the total number of
|
||||||
prefix codes is:
|
Huffman codes is:
|
||||||
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
int num_prefix_codes = 5 * num_prefix_groups;
|
int num_huff_codes = 5 * num_huff_groups;
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
Given a pixel (x, y) in the ARGB image, we can obtain the corresponding prefix
|
Given a pixel (x, y) in the ARGB image, we can obtain the corresponding Huffman
|
||||||
codes to be used as follows:
|
codes to be used as follows:
|
||||||
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
int position = (y >> prefix_bits) * prefix_xsize + (x >> prefix_bits);
|
int position = (y >> huffman_bits) * huffman_xsize + (x >> huffman_bits);
|
||||||
int meta_prefix_code = (entropy_image[pos] >> 8) & 0xffff;
|
int meta_huff_code = (entropy_image[pos] >> 8) & 0xffff;
|
||||||
PrefixCodeGroup prefix_group = prefix_code_groups[meta_prefix_code];
|
HuffmanCodeGroup huff_group = huffman_code_groups[meta_huff_code];
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
where, we have assumed the existence of `PrefixCodeGroup` structure, which
|
where, we have assumed the existence of `HuffmanCodeGroup` structure, which
|
||||||
represents a set of five prefix codes. Also, `prefix_code_groups` is an array
|
represents a set of five Huffman codes. Also, `huffman_code_groups` is an array
|
||||||
of `PrefixCodeGroup` (of size `num_prefix_groups`).
|
of `HuffmanCodeGroup` (of size `num_huff_groups`).
|
||||||
|
|
||||||
The decoder then uses prefix code group `prefix_group` to decode the pixel
|
The decoder then uses Huffman code group `huff_group` to decode the pixel
|
||||||
(x, y) as explained in the [next section](#decoding-entropy-coded-image-data).
|
(x, y) as explained in the [next section](#decoding-entropy-coded-image-data).
|
||||||
|
|
||||||
#### 5.2.3 Decoding Entropy-coded Image Data
|
#### 5.2.2 Decoding Entropy-coded Image Data
|
||||||
|
|
||||||
\[AMENDED2\]
|
|
||||||
|
|
||||||
For the current position (x, y) in the image, the decoder first identifies the
|
For the current position (x, y) in the image, the decoder first identifies the
|
||||||
corresponding prefix code group (as explained in the last section). Given the
|
corresponding Huffman code group (as explained in the last section). Given the
|
||||||
prefix code group, the pixel is read and decoded as follows:
|
Huffman code group, the pixel is read and decoded as follows:
|
||||||
|
|
||||||
Read next symbol S from the bitstream using prefix code #1. Note that S is any
|
Read next symbol S from the bitstream using Huffman code #1. \[See
|
||||||
integer in the range `0` to
|
[next section](#decoding-the-code-lengths) for details on decoding the Huffman
|
||||||
`(256 + 24 + ` [`color_cache_size`](#color-cache-code)` - 1)`.
|
code lengths\]. Note that S is any integer in the range `0` to
|
||||||
|
`(256 + 24 + ` [`color_cache_size`](#color-cache-code)`- 1)`.
|
||||||
|
|
||||||
The interpretation of S depends on its value:
|
The interpretation of S depends on its value:
|
||||||
|
|
||||||
1. if S < 256
|
1. if S < 256
|
||||||
1. Use S as the green component.
|
1. Use S as the green component
|
||||||
1. Read red from the bitstream using prefix code #2.
|
1. Read red from the bitstream using Huffman code #2
|
||||||
1. Read blue from the bitstream using prefix code #3.
|
1. Read blue from the bitstream using Huffman code #3
|
||||||
1. Read alpha from the bitstream using prefix code #4.
|
1. Read alpha from the bitstream using Huffman code #4
|
||||||
1. if S >= 256 && S < 256 + 24
|
1. if S < 256 + 24
|
||||||
1. Use S - 256 as a length prefix code.
|
1. Use S - 256 as a length prefix code
|
||||||
1. Read extra bits for length from the bitstream.
|
1. Read extra bits for length from the bitstream
|
||||||
1. Determine backward-reference length L from length prefix code and the
|
1. Determine backward-reference length L from length prefix code and the
|
||||||
extra bits read.
|
extra bits read.
|
||||||
1. Read distance prefix code from the bitstream using prefix code #5.
|
1. Read distance prefix code from the bitstream using Huffman code #5
|
||||||
1. Read extra bits for distance from the bitstream.
|
1. Read extra bits for distance from the bitstream
|
||||||
1. Determine backward-reference distance D from distance prefix code and
|
1. Determine backward-reference distance D from distance prefix code and
|
||||||
the extra bits read.
|
the extra bits read.
|
||||||
1. Copy the L pixels (in scan-line order) from the sequence of pixels
|
1. Copy the L pixels (in scan-line order) from the sequence of pixels
|
||||||
@@ -1071,6 +947,80 @@ The interpretation of S depends on its value:
|
|||||||
1. Get ARGB color from the color cache at that index.
|
1. Get ARGB color from the color cache at that index.
|
||||||
|
|
||||||
|
|
||||||
|
**Decoding the Code Lengths:**
|
||||||
|
{:#decoding-the-code-lengths}
|
||||||
|
|
||||||
|
This section describes the details about reading a symbol from the bitstream by
|
||||||
|
decoding the Huffman code length.
|
||||||
|
|
||||||
|
The Huffman code lengths can be coded in two ways. The method used is specified
|
||||||
|
by a 1-bit value.
|
||||||
|
|
||||||
|
* If this bit is 1, it is a _simple code length code_, and
|
||||||
|
* If this bit is 0, it is a _normal code length code_.
|
||||||
|
|
||||||
|
**(i) Simple Code Length Code:**
|
||||||
|
|
||||||
|
This variant is used in the special case when only 1 or 2 Huffman code lengths
|
||||||
|
are non-zero, and are in the range of \[0, 255\]. All other Huffman code lengths
|
||||||
|
are implicitly zeros.
|
||||||
|
|
||||||
|
The first bit indicates the number of non-zero code lengths:
|
||||||
|
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
int num_code_lengths = ReadBits(1) + 1;
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
The first code length is stored either using a 1-bit code for values of 0 and 1,
|
||||||
|
or using an 8-bit code for values in range \[0, 255\]. The second code length,
|
||||||
|
when present, is coded as an 8-bit code.
|
||||||
|
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
int is_first_8bits = ReadBits(1);
|
||||||
|
code_lengths[0] = ReadBits(1 + 7 * is_first_8bits);
|
||||||
|
if (num_code_lengths == 2) {
|
||||||
|
code_lengths[1] = ReadBits(8);
|
||||||
|
}
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
**Note:** Another special case is when _all_ Huffman code lengths are _zeros_
|
||||||
|
(an empty Huffman code). For example, a Huffman code for distance can be empty
|
||||||
|
if there are no backward references. Similarly, Huffman codes for alpha, red,
|
||||||
|
and blue can be empty if all pixels within the same meta Huffman code are
|
||||||
|
produced using the color cache. However, this case doesn't need a special
|
||||||
|
handling, as empty Huffman codes can be coded as those containing a single
|
||||||
|
symbol `0`.
|
||||||
|
|
||||||
|
**(ii) Normal Code Length Code:**
|
||||||
|
|
||||||
|
The code lengths of a Huffman code are read as follows: `num_code_lengths`
|
||||||
|
specifies the number of code lengths; the rest of the code lengths
|
||||||
|
(according to the order in `kCodeLengthCodeOrder`) are zeros.
|
||||||
|
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
int kCodeLengthCodes = 19;
|
||||||
|
int kCodeLengthCodeOrder[kCodeLengthCodes] = {
|
||||||
|
17, 18, 0, 1, 2, 3, 4, 5, 16, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
|
||||||
|
};
|
||||||
|
int code_lengths[kCodeLengthCodes] = { 0 }; // All zeros.
|
||||||
|
int num_code_lengths = 4 + ReadBits(4);
|
||||||
|
for (i = 0; i < num_code_lengths; ++i) {
|
||||||
|
code_lengths[kCodeLengthCodeOrder[i]] = ReadBits(3);
|
||||||
|
}
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
* Code length code \[0..15\] indicates literal code lengths.
|
||||||
|
* Value 0 means no symbols have been coded.
|
||||||
|
* Values \[1..15\] indicate the bit length of the respective code.
|
||||||
|
* Code 16 repeats the previous non-zero value \[3..6\] times, i.e.,
|
||||||
|
3 + `ReadBits(2)` times. If code 16 is used before a non-zero
|
||||||
|
value has been emitted, a value of 8 is repeated.
|
||||||
|
* Code 17 emits a streak of zeros \[3..10\], i.e., 3 + `ReadBits(3)`
|
||||||
|
times.
|
||||||
|
* Code 18 emits a streak of zeros of length \[11..138\], i.e.,
|
||||||
|
11 + `ReadBits(7)` times.
|
||||||
|
|
||||||
|
|
||||||
6 Overall Structure of the Format
|
6 Overall Structure of the Format
|
||||||
---------------------------------
|
---------------------------------
|
||||||
|
|
||||||
@@ -1106,26 +1056,23 @@ of pixels (xsize * ysize).
|
|||||||
|
|
||||||
#### Structure of the Image Data
|
#### Structure of the Image Data
|
||||||
|
|
||||||
\[AMENDED2\]
|
|
||||||
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
<spatially-coded image> ::= <color cache info><meta prefix><data>
|
<spatially-coded image> ::= <meta huffman><entropy-coded image>
|
||||||
<entropy-coded image> ::= <color cache info><data>
|
<entropy-coded image> ::= <color cache info><huffman codes><lz77-coded image>
|
||||||
|
<meta huffman> ::= 1-bit value 0 |
|
||||||
|
(1-bit value 1; <entropy image>)
|
||||||
|
<entropy image> ::= 3-bit subsample value; <entropy-coded image>
|
||||||
<color cache info> ::= 1 bit value 0 |
|
<color cache info> ::= 1 bit value 0 |
|
||||||
(1-bit value 1; 4-bit value for color cache size)
|
(1-bit value 1; 4-bit value for color cache size)
|
||||||
<meta prefix> ::= 1-bit value 0 |
|
<huffman codes> ::= <huffman code group> | <huffman code group><huffman codes>
|
||||||
(1-bit value 1; <entropy image>)
|
<huffman code group> ::= <huffman code><huffman code><huffman code>
|
||||||
<data> ::= <prefix codes><lz77-coded image>
|
<huffman code><huffman code>
|
||||||
<entropy image> ::= 3-bit subsample value; <entropy-coded image>
|
See "Interpretation of Meta Huffman codes" to
|
||||||
<prefix codes> ::= <prefix code group> | <prefix code group><prefix codes>
|
understand what each of these five Huffman codes are
|
||||||
<prefix code group> ::= <prefix code><prefix code><prefix code>
|
for.
|
||||||
<prefix code><prefix code>
|
<huffman code> ::= <simple huffman code> | <normal huffman code>
|
||||||
See "Interpretation of Meta Prefix Codes" to
|
<simple huffman code> ::= see "Simple code length code" for details
|
||||||
understand what each of these five prefix codes are
|
<normal huffman code> ::= <code length code>; encoded code lengths
|
||||||
for.
|
|
||||||
<prefix code> ::= <simple prefix code> | <normal prefix code>
|
|
||||||
<simple prefix code> ::= see "Simple code length code" for details
|
|
||||||
<normal prefix code> ::= <code length code>; encoded code lengths
|
|
||||||
<code length code> ::= see section "Normal code length code"
|
<code length code> ::= see section "Normal code length code"
|
||||||
<lz77-coded image> ::= ((<argb-pixel> | <lz77-copy> | <color-cache-code>)
|
<lz77-coded image> ::= ((<argb-pixel> | <lz77-copy> | <color-cache-code>)
|
||||||
<lz77-coded image>) | ""
|
<lz77-coded image>) | ""
|
||||||
@@ -1135,8 +1082,9 @@ A possible example sequence:
|
|||||||
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
<RIFF header><image size>1-bit value 1<subtract-green-tx>
|
<RIFF header><image size>1-bit value 1<subtract-green-tx>
|
||||||
1-bit value 1<predictor-tx>1-bit value 0<color cache info>1-bit value 0
|
1-bit value 1<predictor-tx>1-bit value 0<meta huffman>
|
||||||
<prefix codes><lz77-coded image>
|
<color cache info><huffman codes>
|
||||||
|
<lz77-coded image>
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
[canonical_huff]: https://en.wikipedia.org/wiki/Canonical_Huffman_code
|
[canonical_huff]: http://en.wikipedia.org/wiki/Canonical_Huffman_code
|
||||||
|
|||||||
@@ -26,7 +26,8 @@ LOCAL_SRC_FILES := \
|
|||||||
cwebp.c \
|
cwebp.c \
|
||||||
|
|
||||||
LOCAL_CFLAGS := $(WEBP_CFLAGS)
|
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
|
LOCAL_MODULE := cwebp
|
||||||
|
|
||||||
@@ -41,7 +42,9 @@ LOCAL_SRC_FILES := \
|
|||||||
dwebp.c \
|
dwebp.c \
|
||||||
|
|
||||||
LOCAL_CFLAGS := $(WEBP_CFLAGS)
|
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
|
LOCAL_MODULE := dwebp
|
||||||
|
|
||||||
include $(BUILD_EXECUTABLE)
|
include $(BUILD_EXECUTABLE)
|
||||||
@@ -55,6 +58,7 @@ LOCAL_SRC_FILES := \
|
|||||||
webpmux.c \
|
webpmux.c \
|
||||||
|
|
||||||
LOCAL_CFLAGS := $(WEBP_CFLAGS)
|
LOCAL_CFLAGS := $(WEBP_CFLAGS)
|
||||||
|
LOCAL_C_INCLUDES := $(LOCAL_PATH)/../src
|
||||||
LOCAL_STATIC_LIBRARIES := example_util imageio_util webpmux webp
|
LOCAL_STATIC_LIBRARIES := example_util imageio_util webpmux webp
|
||||||
|
|
||||||
LOCAL_MODULE := webpmux_example
|
LOCAL_MODULE := webpmux_example
|
||||||
@@ -70,24 +74,9 @@ LOCAL_SRC_FILES := \
|
|||||||
img2webp.c \
|
img2webp.c \
|
||||||
|
|
||||||
LOCAL_CFLAGS := $(WEBP_CFLAGS)
|
LOCAL_CFLAGS := $(WEBP_CFLAGS)
|
||||||
LOCAL_STATIC_LIBRARIES := example_util imageio_util imagedec webpmux webpdemux \
|
LOCAL_C_INCLUDES := $(LOCAL_PATH)/../src
|
||||||
webp
|
LOCAL_STATIC_LIBRARIES := example_util imageio_util imagedec webpmux webp
|
||||||
|
|
||||||
LOCAL_MODULE := img2webp_example
|
LOCAL_MODULE := img2webp_example
|
||||||
|
|
||||||
include $(BUILD_EXECUTABLE)
|
include $(BUILD_EXECUTABLE)
|
||||||
|
|
||||||
################################################################################
|
|
||||||
# webpinfo
|
|
||||||
|
|
||||||
include $(CLEAR_VARS)
|
|
||||||
|
|
||||||
LOCAL_SRC_FILES := \
|
|
||||||
webpinfo.c \
|
|
||||||
|
|
||||||
LOCAL_CFLAGS := $(WEBP_CFLAGS)
|
|
||||||
LOCAL_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
|
AM_CPPFLAGS += -I$(top_builddir)/src -I$(top_srcdir)/src
|
||||||
|
|
||||||
bin_PROGRAMS =
|
bin_PROGRAMS = dwebp cwebp
|
||||||
if BUILD_DEMUX
|
|
||||||
bin_PROGRAMS += dwebp cwebp
|
|
||||||
endif
|
|
||||||
if BUILD_ANIMDIFF
|
if BUILD_ANIMDIFF
|
||||||
noinst_PROGRAMS = anim_diff anim_dump
|
noinst_PROGRAMS = anim_diff
|
||||||
endif
|
endif
|
||||||
if BUILD_GIF2WEBP
|
if BUILD_GIF2WEBP
|
||||||
bin_PROGRAMS += gif2webp
|
bin_PROGRAMS += gif2webp
|
||||||
@@ -13,53 +10,34 @@ endif
|
|||||||
if BUILD_IMG2WEBP
|
if BUILD_IMG2WEBP
|
||||||
bin_PROGRAMS += img2webp
|
bin_PROGRAMS += img2webp
|
||||||
endif
|
endif
|
||||||
if BUILD_MUX
|
if WANT_MUX
|
||||||
bin_PROGRAMS += webpmux
|
bin_PROGRAMS += webpmux
|
||||||
endif
|
endif
|
||||||
if BUILD_VWEBP
|
if BUILD_VWEBP
|
||||||
bin_PROGRAMS += vwebp
|
bin_PROGRAMS += vwebp
|
||||||
endif
|
endif
|
||||||
if BUILD_WEBPINFO
|
|
||||||
bin_PROGRAMS += webpinfo
|
|
||||||
endif
|
|
||||||
|
|
||||||
noinst_LTLIBRARIES = libexample_util.la
|
noinst_LTLIBRARIES = libexample_util.la
|
||||||
|
|
||||||
libexample_util_la_SOURCES = example_util.c example_util.h
|
libexample_util_la_SOURCES = example_util.c example_util.h
|
||||||
libexample_util_la_LIBADD = ../src/libwebp.la
|
libexample_util_la_LIBADD = ../src/libwebp.la
|
||||||
|
|
||||||
anim_diff_SOURCES = anim_diff.c anim_util.c anim_util.h gifdec.c gifdec.h
|
anim_diff_SOURCES = anim_diff.c anim_util.c anim_util.h
|
||||||
anim_diff_CPPFLAGS = $(AM_CPPFLAGS) $(GIF_INCLUDES)
|
anim_diff_CPPFLAGS = $(AM_CPPFLAGS) $(USE_EXPERIMENTAL_CODE) $(GIF_INCLUDES)
|
||||||
anim_diff_LDADD =
|
anim_diff_LDADD = ../src/demux/libwebpdemux.la
|
||||||
anim_diff_LDADD += ../src/demux/libwebpdemux.la
|
anim_diff_LDADD += libexample_util.la ../imageio/libimageio_util.la
|
||||||
anim_diff_LDADD += libexample_util.la
|
|
||||||
anim_diff_LDADD += ../imageio/libimageio_util.la
|
|
||||||
anim_diff_LDADD += $(GIF_LIBS) -lm
|
anim_diff_LDADD += $(GIF_LIBS) -lm
|
||||||
|
|
||||||
anim_dump_SOURCES = anim_dump.c anim_util.c anim_util.h 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_SOURCES = cwebp.c stopwatch.h
|
||||||
cwebp_CPPFLAGS = $(AM_CPPFLAGS)
|
cwebp_CPPFLAGS = $(AM_CPPFLAGS) $(USE_EXPERIMENTAL_CODE)
|
||||||
cwebp_LDADD =
|
cwebp_LDADD = libexample_util.la ../imageio/libimageio_util.la
|
||||||
cwebp_LDADD += libexample_util.la
|
cwebp_LDADD += ../imageio/libimagedec.la ../src/libwebp.la
|
||||||
cwebp_LDADD += ../imageio/libimageio_util.la
|
|
||||||
cwebp_LDADD += ../imageio/libimagedec.la
|
|
||||||
cwebp_LDADD += ../src/libwebp.la
|
|
||||||
cwebp_LDADD += $(JPEG_LIBS) $(PNG_LIBS) $(TIFF_LIBS)
|
cwebp_LDADD += $(JPEG_LIBS) $(PNG_LIBS) $(TIFF_LIBS)
|
||||||
|
|
||||||
dwebp_SOURCES = dwebp.c stopwatch.h
|
dwebp_SOURCES = dwebp.c stopwatch.h
|
||||||
dwebp_CPPFLAGS = $(AM_CPPFLAGS)
|
dwebp_CPPFLAGS = $(AM_CPPFLAGS) $(USE_EXPERIMENTAL_CODE)
|
||||||
dwebp_CPPFLAGS += $(JPEG_INCLUDES) $(PNG_INCLUDES)
|
dwebp_CPPFLAGS += $(JPEG_INCLUDES) $(PNG_INCLUDES)
|
||||||
dwebp_LDADD =
|
dwebp_LDADD = libexample_util.la
|
||||||
dwebp_LDADD += libexample_util.la
|
|
||||||
dwebp_LDADD += ../imageio/libimagedec.la
|
dwebp_LDADD += ../imageio/libimagedec.la
|
||||||
dwebp_LDADD += ../imageio/libimageenc.la
|
dwebp_LDADD += ../imageio/libimageenc.la
|
||||||
dwebp_LDADD += ../imageio/libimageio_util.la
|
dwebp_LDADD += ../imageio/libimageio_util.la
|
||||||
@@ -67,53 +45,31 @@ dwebp_LDADD += ../src/libwebp.la
|
|||||||
dwebp_LDADD +=$(PNG_LIBS) $(JPEG_LIBS)
|
dwebp_LDADD +=$(PNG_LIBS) $(JPEG_LIBS)
|
||||||
|
|
||||||
gif2webp_SOURCES = gif2webp.c gifdec.c gifdec.h
|
gif2webp_SOURCES = gif2webp.c gifdec.c gifdec.h
|
||||||
gif2webp_CPPFLAGS = $(AM_CPPFLAGS) $(GIF_INCLUDES)
|
gif2webp_CPPFLAGS = $(AM_CPPFLAGS) $(USE_EXPERIMENTAL_CODE) $(GIF_INCLUDES)
|
||||||
gif2webp_LDADD =
|
gif2webp_LDADD = libexample_util.la ../imageio/libimageio_util.la
|
||||||
gif2webp_LDADD += libexample_util.la
|
gif2webp_LDADD += ../src/mux/libwebpmux.la ../src/libwebp.la $(GIF_LIBS)
|
||||||
gif2webp_LDADD += ../imageio/libimageio_util.la
|
|
||||||
gif2webp_LDADD += ../src/mux/libwebpmux.la
|
|
||||||
gif2webp_LDADD += ../src/libwebp.la
|
|
||||||
gif2webp_LDADD += $(GIF_LIBS)
|
|
||||||
|
|
||||||
vwebp_SOURCES = vwebp.c
|
vwebp_SOURCES = vwebp.c
|
||||||
vwebp_CPPFLAGS = $(AM_CPPFLAGS) $(GL_INCLUDES)
|
vwebp_CPPFLAGS = $(AM_CPPFLAGS) $(USE_EXPERIMENTAL_CODE) $(GL_INCLUDES)
|
||||||
vwebp_LDADD =
|
vwebp_LDADD = libexample_util.la ../imageio/libimageio_util.la
|
||||||
vwebp_LDADD += libexample_util.la
|
vwebp_LDADD += ../src/demux/libwebpdemux.la $(GL_LIBS)
|
||||||
vwebp_LDADD += ../imageio/libimageio_util.la
|
|
||||||
vwebp_LDADD += ../src/demux/libwebpdemux.la
|
|
||||||
vwebp_LDADD += $(GL_LIBS)
|
|
||||||
|
|
||||||
webpmux_SOURCES = webpmux.c
|
webpmux_SOURCES = webpmux.c
|
||||||
webpmux_CPPFLAGS = $(AM_CPPFLAGS)
|
webpmux_CPPFLAGS = $(AM_CPPFLAGS) $(USE_EXPERIMENTAL_CODE)
|
||||||
webpmux_LDADD =
|
webpmux_LDADD = libexample_util.la ../imageio/libimageio_util.la
|
||||||
webpmux_LDADD += libexample_util.la
|
webpmux_LDADD += ../src/mux/libwebpmux.la ../src/libwebp.la
|
||||||
webpmux_LDADD += ../imageio/libimageio_util.la
|
|
||||||
webpmux_LDADD += ../src/mux/libwebpmux.la
|
|
||||||
webpmux_LDADD += ../src/libwebp.la
|
|
||||||
|
|
||||||
img2webp_SOURCES = img2webp.c
|
img2webp_SOURCES = img2webp.c
|
||||||
img2webp_CPPFLAGS = $(AM_CPPFLAGS)
|
img2webp_CPPFLAGS = $(AM_CPPFLAGS) $(USE_EXPERIMENTAL_CODE)
|
||||||
img2webp_LDADD =
|
img2webp_LDADD = libexample_util.la ../imageio/libimageio_util.la
|
||||||
img2webp_LDADD += libexample_util.la
|
|
||||||
img2webp_LDADD += ../imageio/libimageio_util.la
|
|
||||||
img2webp_LDADD += ../imageio/libimagedec.la
|
img2webp_LDADD += ../imageio/libimagedec.la
|
||||||
img2webp_LDADD += ../src/mux/libwebpmux.la
|
img2webp_LDADD += ../src/mux/libwebpmux.la ../src/libwebp.la
|
||||||
img2webp_LDADD += ../src/libwebp.la
|
|
||||||
img2webp_LDADD += $(PNG_LIBS) $(JPEG_LIBS) $(TIFF_LIBS)
|
img2webp_LDADD += $(PNG_LIBS) $(JPEG_LIBS) $(TIFF_LIBS)
|
||||||
|
|
||||||
webpinfo_SOURCES = webpinfo.c
|
|
||||||
webpinfo_CPPFLAGS = $(AM_CPPFLAGS)
|
|
||||||
webpinfo_LDADD =
|
|
||||||
webpinfo_LDADD += libexample_util.la
|
|
||||||
webpinfo_LDADD += ../imageio/libimageio_util.la
|
|
||||||
webpinfo_LDADD += ../src/libwebp.la
|
|
||||||
|
|
||||||
if BUILD_LIBWEBPDECODER
|
if BUILD_LIBWEBPDECODER
|
||||||
anim_diff_LDADD += ../src/libwebpdecoder.la
|
anim_diff_LDADD += ../src/libwebpdecoder.la
|
||||||
anim_dump_LDADD += ../src/libwebpdecoder.la
|
|
||||||
vwebp_LDADD += ../src/libwebpdecoder.la
|
vwebp_LDADD += ../src/libwebpdecoder.la
|
||||||
else
|
else
|
||||||
anim_diff_LDADD += ../src/libwebp.la
|
anim_diff_LDADD += ../src/libwebp.la
|
||||||
anim_dump_LDADD += ../src/libwebp.la
|
|
||||||
vwebp_LDADD += ../src/libwebp.la
|
vwebp_LDADD += ../src/libwebp.la
|
||||||
endif
|
endif
|
||||||
|
|||||||
@@ -20,8 +20,6 @@
|
|||||||
#include <string.h> // for 'strcmp'.
|
#include <string.h> // for 'strcmp'.
|
||||||
|
|
||||||
#include "./anim_util.h"
|
#include "./anim_util.h"
|
||||||
#include "./example_util.h"
|
|
||||||
#include "./unicode.h"
|
|
||||||
|
|
||||||
#if defined(_MSC_VER) && _MSC_VER < 1900
|
#if defined(_MSC_VER) && _MSC_VER < 1900
|
||||||
#define snprintf _snprintf
|
#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 (!ok) return 0; // These are fatal failures, can't proceed.
|
||||||
|
|
||||||
if (is_multi_frame_image) { // Checks relevant for multi-frame images only.
|
if (is_multi_frame_image) { // Checks relevant for multi-frame images only.
|
||||||
int max_loop_count_workaround = 0;
|
ok = CompareValues(img1->loop_count, img2->loop_count,
|
||||||
// Transcodes to webp increase the gif loop count by 1 for compatibility.
|
"Loop count mismatch") && ok;
|
||||||
// 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 = CompareBackgroundColor(img1->bgcolor, img2->bgcolor,
|
ok = CompareBackgroundColor(img1->bgcolor, img2->bgcolor,
|
||||||
premultiply) && ok;
|
premultiply) && ok;
|
||||||
}
|
}
|
||||||
@@ -199,11 +187,11 @@ static void Help(void) {
|
|||||||
printf(" -min_psnr <float> ... minimum per-frame PSNR\n");
|
printf(" -min_psnr <float> ... minimum per-frame PSNR\n");
|
||||||
printf(" -raw_comparison ..... if this flag is not used, RGB is\n");
|
printf(" -raw_comparison ..... if this flag is not used, RGB is\n");
|
||||||
printf(" premultiplied before comparison\n");
|
printf(" premultiplied before comparison\n");
|
||||||
printf(" -max_diff <int> ..... maximum allowed difference per channel\n"
|
#ifdef WEBP_EXPERIMENTAL_FEATURES
|
||||||
" between corresponding pixels in subsequent\n"
|
printf(" -max_diff <int> ..... maximum allowed difference per channel "
|
||||||
|
" between corresponding pixels in subsequent"
|
||||||
" frames\n");
|
" frames\n");
|
||||||
printf(" -h .................. this help\n");
|
#endif
|
||||||
printf(" -version ............ print version number and exit\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, const char* argv[]) {
|
int main(int argc, const char* argv[]) {
|
||||||
@@ -219,49 +207,56 @@ int main(int argc, const char* argv[]) {
|
|||||||
const char* files[2] = { NULL, NULL };
|
const char* files[2] = { NULL, NULL };
|
||||||
AnimatedImage images[2];
|
AnimatedImage images[2];
|
||||||
|
|
||||||
INIT_WARGV(argc, argv);
|
if (argc < 3) {
|
||||||
|
Help();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
for (c = 1; c < argc; ++c) {
|
for (c = 1; c < argc; ++c) {
|
||||||
int parse_error = 0;
|
int parse_error = 0;
|
||||||
if (!strcmp(argv[c], "-dump_frames")) {
|
if (!strcmp(argv[c], "-dump_frames")) {
|
||||||
if (c < argc - 1) {
|
if (c < argc - 1) {
|
||||||
dump_frames = 1;
|
dump_frames = 1;
|
||||||
dump_folder = (const char*)GET_WARGV(argv, ++c);
|
dump_folder = argv[++c];
|
||||||
} else {
|
} else {
|
||||||
parse_error = 1;
|
parse_error = 1;
|
||||||
}
|
}
|
||||||
} else if (!strcmp(argv[c], "-min_psnr")) {
|
} else if (!strcmp(argv[c], "-min_psnr")) {
|
||||||
if (c < argc - 1) {
|
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 {
|
} else {
|
||||||
parse_error = 1;
|
parse_error = 1;
|
||||||
}
|
}
|
||||||
} else if (!strcmp(argv[c], "-raw_comparison")) {
|
} else if (!strcmp(argv[c], "-raw_comparison")) {
|
||||||
premultiply = 0;
|
premultiply = 0;
|
||||||
|
#ifdef WEBP_EXPERIMENTAL_FEATURES
|
||||||
} else if (!strcmp(argv[c], "-max_diff")) {
|
} else if (!strcmp(argv[c], "-max_diff")) {
|
||||||
if (c < argc - 1) {
|
if (c < argc - 1) {
|
||||||
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 {
|
} else {
|
||||||
parse_error = 1;
|
parse_error = 1;
|
||||||
}
|
}
|
||||||
} else if (!strcmp(argv[c], "-h") || !strcmp(argv[c], "-help")) {
|
#endif
|
||||||
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 {
|
} else {
|
||||||
if (!got_input1) {
|
if (!got_input1) {
|
||||||
files[0] = (const char*)GET_WARGV(argv, c);
|
files[0] = argv[c];
|
||||||
got_input1 = 1;
|
got_input1 = 1;
|
||||||
} else if (!got_input2) {
|
} else if (!got_input2) {
|
||||||
files[1] = (const char*)GET_WARGV(argv, c);
|
files[1] = argv[c];
|
||||||
got_input2 = 1;
|
got_input2 = 1;
|
||||||
} else {
|
} else {
|
||||||
parse_error = 1;
|
parse_error = 1;
|
||||||
@@ -269,30 +264,23 @@ int main(int argc, const char* argv[]) {
|
|||||||
}
|
}
|
||||||
if (parse_error) {
|
if (parse_error) {
|
||||||
Help();
|
Help();
|
||||||
FREE_WARGV_AND_RETURN(-1);
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (argc < 3) {
|
|
||||||
Help();
|
|
||||||
FREE_WARGV_AND_RETURN(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (!got_input2) {
|
if (!got_input2) {
|
||||||
Help();
|
Help();
|
||||||
FREE_WARGV_AND_RETURN(-1);
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dump_frames) {
|
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));
|
memset(images, 0, sizeof(images));
|
||||||
for (i = 0; i < 2; ++i) {
|
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)) {
|
if (!ReadAnimatedImage(files[i], &images[i], dump_frames, dump_folder)) {
|
||||||
WFPRINTF(stderr, "Error decoding file: %s\n Aborting.\n",
|
fprintf(stderr, "Error decoding file: %s\n Aborting.\n", files[i]);
|
||||||
(const W_CHAR*)files[i]);
|
|
||||||
return_code = -2;
|
return_code = -2;
|
||||||
goto End;
|
goto End;
|
||||||
} else {
|
} else {
|
||||||
@@ -302,16 +290,14 @@ int main(int argc, const char* argv[]) {
|
|||||||
|
|
||||||
if (!CompareAnimatedImagePair(&images[0], &images[1],
|
if (!CompareAnimatedImagePair(&images[0], &images[1],
|
||||||
premultiply, min_psnr)) {
|
premultiply, min_psnr)) {
|
||||||
WFPRINTF(stderr, "\nFiles %s and %s differ.\n", (const W_CHAR*)files[0],
|
fprintf(stderr, "\nFiles %s and %s differ.\n", files[0], files[1]);
|
||||||
(const W_CHAR*)files[1]);
|
|
||||||
return_code = -3;
|
return_code = -3;
|
||||||
} else {
|
} else {
|
||||||
WPRINTF("\nFiles %s and %s are identical.\n", (const W_CHAR*)files[0],
|
printf("\nFiles %s and %s are identical.\n", files[0], files[1]);
|
||||||
(const W_CHAR*)files[1]);
|
|
||||||
return_code = 0;
|
return_code = 0;
|
||||||
}
|
}
|
||||||
End:
|
End:
|
||||||
ClearAnimatedImage(&images[0]);
|
ClearAnimatedImage(&images[0]);
|
||||||
ClearAnimatedImage(&images[1]);
|
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 <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#if defined(WEBP_HAVE_GIF)
|
#ifdef WEBP_HAVE_GIF
|
||||||
#include <gif_lib.h>
|
#include <gif_lib.h>
|
||||||
#endif
|
#endif
|
||||||
#include "webp/format_constants.h"
|
#include "webp/format_constants.h"
|
||||||
#include "webp/decode.h"
|
#include "webp/decode.h"
|
||||||
#include "webp/demux.h"
|
#include "webp/demux.h"
|
||||||
#include "../imageio/imageio_util.h"
|
#include "../imageio/imageio_util.h"
|
||||||
#include "./gifdec.h"
|
|
||||||
#include "./unicode.h"
|
|
||||||
#include "./unicode_gif.h"
|
|
||||||
|
|
||||||
#if defined(_MSC_VER) && _MSC_VER < 1900
|
#if defined(_MSC_VER) && _MSC_VER < 1900
|
||||||
#define snprintf _snprintf
|
#define snprintf _snprintf
|
||||||
@@ -36,13 +33,11 @@ static const int kNumChannels = 4;
|
|||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// Common utilities.
|
// Common utilities.
|
||||||
|
|
||||||
#if defined(WEBP_HAVE_GIF)
|
|
||||||
// Returns true if the frame covers the full canvas.
|
// Returns true if the frame covers the full canvas.
|
||||||
static int IsFullFrame(int width, int height,
|
static int IsFullFrame(int width, int height,
|
||||||
int canvas_width, int canvas_height) {
|
int canvas_width, int canvas_height) {
|
||||||
return (width == canvas_width && height == canvas_height);
|
return (width == canvas_width && height == canvas_height);
|
||||||
}
|
}
|
||||||
#endif // WEBP_HAVE_GIF
|
|
||||||
|
|
||||||
static int CheckSizeForOverflow(uint64_t size) {
|
static int CheckSizeForOverflow(uint64_t size) {
|
||||||
return (size == (size_t)size);
|
return (size == (size_t)size);
|
||||||
@@ -60,15 +55,15 @@ static int AllocateFrames(AnimatedImage* const image, uint32_t num_frames) {
|
|||||||
!CheckSizeForOverflow(total_frame_size)) {
|
!CheckSizeForOverflow(total_frame_size)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
mem = (uint8_t*)WebPMalloc((size_t)total_size);
|
mem = (uint8_t*)malloc((size_t)total_size);
|
||||||
frames = (DecodedFrame*)WebPMalloc((size_t)total_frame_size);
|
frames = (DecodedFrame*)malloc((size_t)total_frame_size);
|
||||||
|
|
||||||
if (mem == NULL || frames == NULL) {
|
if (mem == NULL || frames == NULL) {
|
||||||
WebPFree(mem);
|
free(mem);
|
||||||
WebPFree(frames);
|
free(frames);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
WebPFree(image->raw_mem);
|
free(image->raw_mem);
|
||||||
image->num_frames = num_frames;
|
image->num_frames = num_frames;
|
||||||
image->frames = frames;
|
image->frames = frames;
|
||||||
for (i = 0; i < num_frames; ++i) {
|
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) {
|
void ClearAnimatedImage(AnimatedImage* const image) {
|
||||||
if (image != NULL) {
|
if (image != NULL) {
|
||||||
WebPFree(image->raw_mem);
|
free(image->raw_mem);
|
||||||
WebPFree(image->frames);
|
free(image->frames);
|
||||||
image->num_frames = 0;
|
image->num_frames = 0;
|
||||||
image->frames = NULL;
|
image->frames = NULL;
|
||||||
image->raw_mem = NULL;
|
image->raw_mem = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(WEBP_HAVE_GIF)
|
|
||||||
// Clear the canvas to transparent.
|
// Clear the canvas to transparent.
|
||||||
static void ZeroFillCanvas(uint8_t* rgba,
|
static void ZeroFillCanvas(uint8_t* rgba,
|
||||||
uint32_t canvas_width, uint32_t canvas_height) {
|
uint32_t canvas_width, uint32_t canvas_height) {
|
||||||
@@ -132,7 +126,6 @@ static void CopyFrameRectangle(const uint8_t* src, uint8_t* dst, int stride,
|
|||||||
dst += stride;
|
dst += stride;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif // WEBP_HAVE_GIF
|
|
||||||
|
|
||||||
// Canonicalize all transparent pixels to transparent black to aid comparison.
|
// Canonicalize all transparent pixels to transparent black to aid comparison.
|
||||||
static void CleanupTransparentPixels(uint32_t* rgba,
|
static void CleanupTransparentPixels(uint32_t* rgba,
|
||||||
@@ -154,42 +147,40 @@ static int DumpFrame(const char filename[], const char dump_folder[],
|
|||||||
int ok = 0;
|
int ok = 0;
|
||||||
size_t max_len;
|
size_t max_len;
|
||||||
int y;
|
int y;
|
||||||
const W_CHAR* base_name = NULL;
|
const char* base_name = NULL;
|
||||||
W_CHAR* file_name = NULL;
|
char* file_name = NULL;
|
||||||
FILE* f = NULL;
|
FILE* f = NULL;
|
||||||
const char* row;
|
const char* row;
|
||||||
|
|
||||||
if (dump_folder == NULL) dump_folder = (const char*)TO_W_CHAR(".");
|
base_name = strrchr(filename, '/');
|
||||||
|
base_name = (base_name == NULL) ? filename : base_name + 1;
|
||||||
base_name = WSTRRCHR(filename, '/');
|
max_len = strlen(dump_folder) + 1 + strlen(base_name)
|
||||||
base_name = (base_name == NULL) ? (const W_CHAR*)filename : base_name + 1;
|
|
||||||
max_len = WSTRLEN(dump_folder) + 1 + WSTRLEN(base_name)
|
|
||||||
+ strlen("_frame_") + strlen(".pam") + 8;
|
+ 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 (file_name == NULL) goto End;
|
||||||
|
|
||||||
if (WSNPRINTF(file_name, max_len, "%s/%s_frame_%d.pam",
|
if (snprintf(file_name, max_len, "%s/%s_frame_%d.pam",
|
||||||
(const W_CHAR*)dump_folder, base_name, frame_num) < 0) {
|
dump_folder, base_name, frame_num) < 0) {
|
||||||
fprintf(stderr, "Error while generating file name\n");
|
fprintf(stderr, "Error while generating file name\n");
|
||||||
goto End;
|
goto End;
|
||||||
}
|
}
|
||||||
|
|
||||||
f = WFOPEN(file_name, "wb");
|
f = fopen(file_name, "wb");
|
||||||
if (f == NULL) {
|
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;
|
ok = 0;
|
||||||
goto End;
|
goto End;
|
||||||
}
|
}
|
||||||
if (fprintf(f, "P7\nWIDTH %d\nHEIGHT %d\n"
|
if (fprintf(f, "P7\nWIDTH %d\nHEIGHT %d\n"
|
||||||
"DEPTH 4\nMAXVAL 255\nTUPLTYPE RGB_ALPHA\nENDHDR\n",
|
"DEPTH 4\nMAXVAL 255\nTUPLTYPE RGB_ALPHA\nENDHDR\n",
|
||||||
canvas_width, canvas_height) < 0) {
|
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;
|
goto End;
|
||||||
}
|
}
|
||||||
row = (const char*)rgba;
|
row = (const char*)rgba;
|
||||||
for (y = 0; y < canvas_height; ++y) {
|
for (y = 0; y < canvas_height; ++y) {
|
||||||
if (fwrite(row, canvas_width * kNumChannels, 1, f) != 1) {
|
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;
|
goto End;
|
||||||
}
|
}
|
||||||
row += canvas_width * kNumChannels;
|
row += canvas_width * kNumChannels;
|
||||||
@@ -197,7 +188,7 @@ static int DumpFrame(const char filename[], const char dump_folder[],
|
|||||||
ok = 1;
|
ok = 1;
|
||||||
End:
|
End:
|
||||||
if (f != NULL) fclose(f);
|
if (f != NULL) fclose(f);
|
||||||
WebPFree(file_name);
|
free(file_name);
|
||||||
return ok;
|
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);
|
return (WebPGetInfo(webp_data->bytes, webp_data->size, NULL, NULL) != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read animated WebP bitstream 'webp_data' into 'AnimatedImage' struct.
|
// Read animated WebP bitstream 'file_str' into 'AnimatedImage' struct.
|
||||||
static int ReadAnimatedWebP(const char filename[],
|
static int ReadAnimatedWebP(const char filename[],
|
||||||
const WebPData* const webp_data,
|
const WebPData* const webp_data,
|
||||||
AnimatedImage* const image, int dump_frames,
|
AnimatedImage* const image, int dump_frames,
|
||||||
@@ -225,7 +216,7 @@ static int ReadAnimatedWebP(const char filename[],
|
|||||||
|
|
||||||
dec = WebPAnimDecoderNew(webp_data, NULL);
|
dec = WebPAnimDecoderNew(webp_data, NULL);
|
||||||
if (dec == 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;
|
goto End;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -241,7 +232,7 @@ static int ReadAnimatedWebP(const char filename[],
|
|||||||
image->bgcolor = anim_info.bgcolor;
|
image->bgcolor = anim_info.bgcolor;
|
||||||
|
|
||||||
// Allocate frames.
|
// Allocate frames.
|
||||||
if (!AllocateFrames(image, anim_info.frame_count)) goto End;
|
if (!AllocateFrames(image, anim_info.frame_count)) return 0;
|
||||||
|
|
||||||
// Decode frames.
|
// Decode frames.
|
||||||
while (WebPAnimDecoderHasMoreFrames(dec)) {
|
while (WebPAnimDecoderHasMoreFrames(dec)) {
|
||||||
@@ -278,7 +269,6 @@ static int ReadAnimatedWebP(const char filename[],
|
|||||||
prev_frame_timestamp = timestamp;
|
prev_frame_timestamp = timestamp;
|
||||||
}
|
}
|
||||||
ok = dump_ok;
|
ok = dump_ok;
|
||||||
if (ok) image->format = ANIM_WEBP;
|
|
||||||
|
|
||||||
End:
|
End:
|
||||||
WebPAnimDecoderDelete(dec);
|
WebPAnimDecoderDelete(dec);
|
||||||
@@ -288,7 +278,7 @@ static int ReadAnimatedWebP(const char filename[],
|
|||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// GIF Decoding.
|
// GIF Decoding.
|
||||||
|
|
||||||
#if defined(WEBP_HAVE_GIF)
|
#ifdef WEBP_HAVE_GIF
|
||||||
|
|
||||||
// Returns true if this is a valid GIF bitstream.
|
// Returns true if this is a valid GIF bitstream.
|
||||||
static int IsGIF(const WebPData* const data) {
|
static int IsGIF(const WebPData* const data) {
|
||||||
@@ -373,6 +363,26 @@ static int DGifSavedExtensionToGCB(GifFileType* GifFile, int ImageIndex,
|
|||||||
#define DGifCloseFile(a, b) DGifCloseFile(a)
|
#define DGifCloseFile(a, b) DGifCloseFile(a)
|
||||||
#endif
|
#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,
|
static int IsKeyFrameGIF(const GifImageDesc* prev_desc, int prev_dispose,
|
||||||
const DecodedFrame* const prev_frame,
|
const DecodedFrame* const prev_frame,
|
||||||
int canvas_width, int canvas_height) {
|
int canvas_width, int canvas_height) {
|
||||||
@@ -405,7 +415,7 @@ static uint32_t GetBackgroundColorGIF(GifFileType* gif) {
|
|||||||
return 0xffffffff; // Invalid: assume white.
|
return 0xffffffff; // Invalid: assume white.
|
||||||
} else {
|
} else {
|
||||||
const GifColorType color = color_map->Colors[gif->SBackGroundColor];
|
const GifColorType color = color_map->Colors[gif->SBackGroundColor];
|
||||||
return (0xffu << 24) |
|
return (0xff << 24) |
|
||||||
(color.Red << 16) |
|
(color.Red << 16) |
|
||||||
(color.Green << 8) |
|
(color.Green << 8) |
|
||||||
(color.Blue << 0);
|
(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.
|
// Find appropriate app extension and get loop count from the next extension.
|
||||||
// We use Chrome's interpretation of the 'loop_count' semantics:
|
|
||||||
// if not present -> loop once
|
|
||||||
// if present and loop_count == 0, return 0 ('infinite').
|
|
||||||
// if present and loop_count != 0, it's the number of *extra* loops
|
|
||||||
// so we need to return loop_count + 1 as total loop number.
|
|
||||||
static uint32_t GetLoopCountGIF(const GifFileType* const gif) {
|
static uint32_t GetLoopCountGIF(const GifFileType* const gif) {
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < gif->ImageCount; ++i) {
|
for (i = 0; i < gif->ImageCount; ++i) {
|
||||||
@@ -435,13 +440,12 @@ static uint32_t GetLoopCountGIF(const GifFileType* const gif) {
|
|||||||
if (signature_is_ok &&
|
if (signature_is_ok &&
|
||||||
eb2->Function == CONTINUE_EXT_FUNC_CODE && eb2->ByteCount >= 3 &&
|
eb2->Function == CONTINUE_EXT_FUNC_CODE && eb2->ByteCount >= 3 &&
|
||||||
eb2->Bytes[0] == 1) {
|
eb2->Bytes[0] == 1) {
|
||||||
const uint32_t extra_loop = ((uint32_t)(eb2->Bytes[2]) << 8) +
|
return ((uint32_t)(eb2->Bytes[2]) << 8) +
|
||||||
((uint32_t)(eb2->Bytes[1]) << 0);
|
((uint32_t)(eb2->Bytes[1]) << 0);
|
||||||
return (extra_loop > 0) ? extra_loop + 1 : 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 1; // Default.
|
return 0; // Default.
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get duration of 'n'th frame in milliseconds.
|
// Get duration of 'n'th frame in milliseconds.
|
||||||
@@ -513,15 +517,15 @@ static int ReadAnimatedGIF(const char filename[], AnimatedImage* const image,
|
|||||||
int gif_error;
|
int gif_error;
|
||||||
GifFileType* gif;
|
GifFileType* gif;
|
||||||
|
|
||||||
gif = DGifOpenFileUnicode((const W_CHAR*)filename, NULL);
|
gif = DGifOpenFileName(filename, NULL);
|
||||||
if (gif == 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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
gif_error = DGifSlurp(gif);
|
gif_error = DGifSlurp(gif);
|
||||||
if (gif_error != GIF_OK) {
|
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);
|
GIFDisplayError(gif, gif_error);
|
||||||
DGifCloseFile(gif, NULL);
|
DGifCloseFile(gif, NULL);
|
||||||
return 0;
|
return 0;
|
||||||
@@ -558,10 +562,7 @@ static int ReadAnimatedGIF(const char filename[], AnimatedImage* const image,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Allocate frames.
|
// Allocate frames.
|
||||||
if (!AllocateFrames(image, frame_count)) {
|
AllocateFrames(image, frame_count);
|
||||||
DGifCloseFile(gif, NULL);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
canvas_width = image->canvas_width;
|
canvas_width = image->canvas_width;
|
||||||
canvas_height = image->canvas_height;
|
canvas_height = image->canvas_height;
|
||||||
@@ -580,9 +581,6 @@ static int ReadAnimatedGIF(const char filename[], AnimatedImage* const image,
|
|||||||
curr_frame = &image->frames[i];
|
curr_frame = &image->frames[i];
|
||||||
curr_rgba = curr_frame->rgba;
|
curr_rgba = curr_frame->rgba;
|
||||||
curr_frame->duration = GetFrameDurationGIF(gif, i);
|
curr_frame->duration = GetFrameDurationGIF(gif, i);
|
||||||
// Force frames with a small or no duration to 100ms to be consistent
|
|
||||||
// with web browsers and other transcoding tools (like gif2webp itself).
|
|
||||||
if (curr_frame->duration <= 10) curr_frame->duration = 100;
|
|
||||||
|
|
||||||
if (i == 0) { // Initialize as transparent.
|
if (i == 0) { // Initialize as transparent.
|
||||||
curr_frame->is_key_frame = 1;
|
curr_frame->is_key_frame = 1;
|
||||||
@@ -674,7 +672,6 @@ static int ReadAnimatedGIF(const char filename[], AnimatedImage* const image,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
image->format = ANIM_GIF;
|
|
||||||
DGifCloseFile(gif, NULL);
|
DGifCloseFile(gif, NULL);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -710,7 +707,7 @@ int ReadAnimatedImage(const char filename[], AnimatedImage* const image,
|
|||||||
memset(image, 0, sizeof(*image));
|
memset(image, 0, sizeof(*image));
|
||||||
|
|
||||||
if (!ImgIoUtilReadFile(filename, &webp_data.bytes, &webp_data.size)) {
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -720,9 +717,9 @@ int ReadAnimatedImage(const char filename[], AnimatedImage* const image,
|
|||||||
} else if (IsGIF(&webp_data)) {
|
} else if (IsGIF(&webp_data)) {
|
||||||
ok = ReadAnimatedGIF(filename, image, dump_frames, dump_folder);
|
ok = ReadAnimatedGIF(filename, image, dump_frames, dump_folder);
|
||||||
} else {
|
} else {
|
||||||
WFPRINTF(stderr,
|
fprintf(stderr,
|
||||||
"Unknown file type: %s. Supported file types are WebP and GIF\n",
|
"Unknown file type: %s. Supported file types are WebP and GIF\n",
|
||||||
(const W_CHAR*)filename);
|
filename);
|
||||||
ok = 0;
|
ok = 0;
|
||||||
}
|
}
|
||||||
if (!ok) ClearAnimatedImage(image);
|
if (!ok) ClearAnimatedImage(image);
|
||||||
@@ -774,9 +771,3 @@ void GetDiffAndPSNR(const uint8_t rgba1[], const uint8_t rgba2[],
|
|||||||
*psnr = 4.3429448 * log(255. * 255. / sse);
|
*psnr = 4.3429448 * log(255. * 255. / sse);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GetAnimatedImageVersions(int* const decoder_version,
|
|
||||||
int* const demux_version) {
|
|
||||||
*decoder_version = WebPGetDecoderVersion();
|
|
||||||
*demux_version = WebPGetDemuxVersion();
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -22,11 +22,6 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
ANIM_GIF,
|
|
||||||
ANIM_WEBP
|
|
||||||
} AnimatedFileFormat;
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t* rgba; // Decoded and reconstructed full frame.
|
uint8_t* rgba; // Decoded and reconstructed full frame.
|
||||||
int duration; // Frame duration in milliseconds.
|
int duration; // Frame duration in milliseconds.
|
||||||
@@ -34,7 +29,6 @@ typedef struct {
|
|||||||
} DecodedFrame;
|
} DecodedFrame;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
AnimatedFileFormat format;
|
|
||||||
uint32_t canvas_width;
|
uint32_t canvas_width;
|
||||||
uint32_t canvas_height;
|
uint32_t canvas_height;
|
||||||
uint32_t bgcolor;
|
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,
|
uint32_t width, uint32_t height, int premultiply,
|
||||||
int* const max_diff, double* const psnr);
|
int* const max_diff, double* const psnr);
|
||||||
|
|
||||||
// Return library versions used by anim_util.
|
|
||||||
void GetAnimatedImageVersions(int* const decoder_version,
|
|
||||||
int* const demux_version);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} // extern "C"
|
} // extern "C"
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
335
examples/cwebp.c
335
examples/cwebp.c
@@ -12,7 +12,6 @@
|
|||||||
//
|
//
|
||||||
// Author: Skal (pascal.massimino@gmail.com)
|
// Author: Skal (pascal.massimino@gmail.com)
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@@ -24,9 +23,7 @@
|
|||||||
#include "../examples/example_util.h"
|
#include "../examples/example_util.h"
|
||||||
#include "../imageio/image_dec.h"
|
#include "../imageio/image_dec.h"
|
||||||
#include "../imageio/imageio_util.h"
|
#include "../imageio/imageio_util.h"
|
||||||
#include "../imageio/webpdec.h"
|
|
||||||
#include "./stopwatch.h"
|
#include "./stopwatch.h"
|
||||||
#include "./unicode.h"
|
|
||||||
#include "webp/encode.h"
|
#include "webp/encode.h"
|
||||||
|
|
||||||
#ifndef WEBP_DLL
|
#ifndef WEBP_DLL
|
||||||
@@ -91,10 +88,9 @@ static int ReadPicture(const char* const filename, WebPPicture* const pic,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
WFPRINTF(stderr, "Error! Could not process file %s\n",
|
fprintf(stderr, "Error! Could not process file %s\n", filename);
|
||||||
(const W_CHAR*)filename);
|
|
||||||
}
|
}
|
||||||
WebPFree((void*)data);
|
free((void*)data);
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -118,10 +114,9 @@ static int ReadPicture(const char* const filename, WebPPicture* const pic,
|
|||||||
}
|
}
|
||||||
End:
|
End:
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
WFPRINTF(stderr, "Error! Could not process file %s\n",
|
fprintf(stderr, "Error! Could not process file %s\n", filename);
|
||||||
(const W_CHAR*)filename);
|
|
||||||
}
|
}
|
||||||
WebPFree((void*)data);
|
free((void*)data);
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -130,8 +125,7 @@ static int ReadPicture(const char* const filename, WebPPicture* const pic,
|
|||||||
static void AllocExtraInfo(WebPPicture* const pic) {
|
static void AllocExtraInfo(WebPPicture* const pic) {
|
||||||
const int mb_w = (pic->width + 15) / 16;
|
const int mb_w = (pic->width + 15) / 16;
|
||||||
const int mb_h = (pic->height + 15) / 16;
|
const int mb_h = (pic->height + 15) / 16;
|
||||||
pic->extra_info =
|
pic->extra_info = (uint8_t*)malloc(mb_w * mb_h * sizeof(*pic->extra_info));
|
||||||
(uint8_t*)WebPMalloc(mb_w * mb_h * sizeof(*pic->extra_info));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void PrintByteCount(const int bytes[4], int total_size,
|
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);
|
fprintf(stderr, "| %7d (%.1f%%)\n", total, 100.f * total / total_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void PrintPercents(const int counts[4]) {
|
static void PrintPercents(const int counts[4], int total) {
|
||||||
int s;
|
int s;
|
||||||
const int total = counts[0] + counts[1] + counts[2] + counts[3];
|
|
||||||
for (s = 0; s < 4; ++s) {
|
for (s = 0; s < 4; ++s) {
|
||||||
fprintf(stderr, "| %3d%%", (int)(100. * counts[s] / total + .5));
|
fprintf(stderr, "| %2d%%", 100 * counts[s] / total);
|
||||||
}
|
}
|
||||||
fprintf(stderr, "| %7d\n", total);
|
fprintf(stderr, "| %7d\n", total);
|
||||||
}
|
}
|
||||||
@@ -191,10 +184,9 @@ static void PrintExtraInfoLossless(const WebPPicture* const pic,
|
|||||||
if (short_output) {
|
if (short_output) {
|
||||||
fprintf(stderr, "%7d %2.2f\n", stats->coded_size, stats->PSNR[3]);
|
fprintf(stderr, "%7d %2.2f\n", stats->coded_size, stats->PSNR[3]);
|
||||||
} else {
|
} 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, "Dimension: %d x %d\n", pic->width, pic->height);
|
||||||
fprintf(stderr, "Output: %d bytes (%.2f bpp)\n", stats->coded_size,
|
fprintf(stderr, "Output: %d bytes\n", stats->coded_size);
|
||||||
8.f * stats->coded_size / pic->width / pic->height);
|
|
||||||
PrintFullLosslessInfo(stats, "ARGB");
|
PrintFullLosslessInfo(stats, "ARGB");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -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_i16 = stats->block_count[1];
|
||||||
const int num_skip = stats->block_count[2];
|
const int num_skip = stats->block_count[2];
|
||||||
const int total = num_i4 + num_i16;
|
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",
|
fprintf(stderr, "Dimension: %d x %d%s\n",
|
||||||
pic->width, pic->height,
|
pic->width, pic->height,
|
||||||
stats->alpha_data_size ? " (with alpha)" : "");
|
stats->alpha_data_size ? " (with alpha)" : "");
|
||||||
fprintf(stderr, "Output: "
|
fprintf(stderr, "Output: "
|
||||||
"%d bytes Y-U-V-All-PSNR %2.2f %2.2f %2.2f %2.2f dB\n"
|
"%d bytes Y-U-V-All-PSNR %2.2f %2.2f %2.2f %2.2f dB\n",
|
||||||
" (%.2f bpp)\n",
|
|
||||||
stats->coded_size,
|
stats->coded_size,
|
||||||
stats->PSNR[0], stats->PSNR[1], stats->PSNR[2], stats->PSNR[3],
|
stats->PSNR[0], stats->PSNR[1], stats->PSNR[2], stats->PSNR[3]);
|
||||||
8.f * stats->coded_size / pic->width / pic->height);
|
|
||||||
if (total > 0) {
|
if (total > 0) {
|
||||||
int totals[4] = { 0, 0, 0, 0 };
|
int totals[4] = { 0, 0, 0, 0 };
|
||||||
fprintf(stderr, "block count: intra4: %6d (%.2f%%)\n"
|
fprintf(stderr, "block count: intra4: %d\n"
|
||||||
" intra16: %6d (%.2f%%)\n"
|
" intra16: %d (-> %.2f%%)\n",
|
||||||
" skipped: %6d (%.2f%%)\n",
|
num_i4, num_i16, 100.f * num_i16 / total);
|
||||||
num_i4, 100.f * num_i4 / total,
|
fprintf(stderr, " skipped block: %d (%.2f%%)\n",
|
||||||
num_i16, 100.f * num_i16 / total,
|
|
||||||
num_skip, 100.f * num_skip / total);
|
num_skip, 100.f * num_skip / total);
|
||||||
fprintf(stderr, "bytes used: header: %6d (%.1f%%)\n"
|
fprintf(stderr, "bytes used: header: %6d (%.1f%%)\n"
|
||||||
" mode-partition: %6d (%.1f%%)\n",
|
" mode-partition: %6d (%.1f%%)\n",
|
||||||
@@ -250,7 +239,7 @@ static void PrintExtraInfoLossy(const WebPPicture* const pic, int short_output,
|
|||||||
PrintByteCount(stats->residual_bytes[2], stats->coded_size, totals);
|
PrintByteCount(stats->residual_bytes[2], stats->coded_size, totals);
|
||||||
}
|
}
|
||||||
fprintf(stderr, " macroblocks: ");
|
fprintf(stderr, " macroblocks: ");
|
||||||
PrintPercents(stats->segment_size);
|
PrintPercents(stats->segment_size, total);
|
||||||
fprintf(stderr, " quantizer: ");
|
fprintf(stderr, " quantizer: ");
|
||||||
PrintValues(stats->segment_quant);
|
PrintValues(stats->segment_quant);
|
||||||
fprintf(stderr, " filter level: ");
|
fprintf(stderr, " filter level: ");
|
||||||
@@ -315,7 +304,7 @@ static int DumpPicture(const WebPPicture* const picture, const char* PGM_name) {
|
|||||||
const int alpha_height =
|
const int alpha_height =
|
||||||
WebPPictureHasTransparency(picture) ? picture->height : 0;
|
WebPPictureHasTransparency(picture) ? picture->height : 0;
|
||||||
const int height = picture->height + uv_height + alpha_height;
|
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;
|
if (f == NULL) return 0;
|
||||||
fprintf(f, "P5\n%d %d\n255\n", stride, height);
|
fprintf(f, "P5\n%d %d\n255\n", stride, height);
|
||||||
for (y = 0; y < picture->height; ++y) {
|
for (y = 0; y < picture->height; ++y) {
|
||||||
@@ -474,9 +463,8 @@ static int WriteWebPWithMetadata(FILE* const out,
|
|||||||
} else {
|
} else {
|
||||||
const int is_lossless = !memcmp(webp, "VP8L", kTagSize);
|
const int is_lossless = !memcmp(webp, "VP8L", kTagSize);
|
||||||
if (is_lossless) {
|
if (is_lossless) {
|
||||||
// Presence of alpha is stored in the 37th bit (29th after the
|
// Presence of alpha is stored in the 29th bit of VP8L data.
|
||||||
// signature) of VP8L data.
|
if (webp[kChunkHeaderSize + 3] & (1 << 5)) flags |= kAlphaFlag;
|
||||||
if (webp[kChunkHeaderSize + 4] & (1 << 4)) flags |= kAlphaFlag;
|
|
||||||
}
|
}
|
||||||
ok = ok && (fwrite(kVP8XHeader, kChunkHeaderSize, 1, out) == 1);
|
ok = ok && (fwrite(kVP8XHeader, kChunkHeaderSize, 1, out) == 1);
|
||||||
ok = ok && WriteLE32(out, flags);
|
ok = ok && WriteLE32(out, flags);
|
||||||
@@ -498,10 +486,10 @@ static int WriteWebPWithMetadata(FILE* const out,
|
|||||||
*metadata_written |= METADATA_XMP;
|
*metadata_written |= METADATA_XMP;
|
||||||
}
|
}
|
||||||
return ok;
|
return ok;
|
||||||
|
} else {
|
||||||
|
// No metadata, just write the original image file.
|
||||||
|
return (fwrite(webp, webp_size, 1, out) == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// No metadata, just write the original image file.
|
|
||||||
return (fwrite(webp, webp_size, 1, out) == 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
@@ -527,7 +515,6 @@ static void HelpLong(void) {
|
|||||||
printf(" cwebp [-preset <...>] [options] in_file [-o out_file]\n\n");
|
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"
|
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");
|
"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
|
#ifdef HAVE_WINCODEC_H
|
||||||
printf("Windows builds can take as input any of the files handled by WIC.\n");
|
printf("Windows builds can take as input any of the files handled by WIC.\n");
|
||||||
#endif
|
#endif
|
||||||
@@ -568,10 +555,8 @@ static void HelpLong(void) {
|
|||||||
printf(" "
|
printf(" "
|
||||||
"the first partition (0=no degradation ... 100=full)\n");
|
"the first partition (0=no degradation ... 100=full)\n");
|
||||||
printf(" -pass <int> ............ analysis pass number (1..10)\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(" -crop <x> <y> <w> <h> .. crop picture with the given rectangle\n");
|
||||||
printf(" -resize <w> <h> ........ resize picture (*after* any cropping)\n");
|
printf(" -resize <w> <h> ........ resize picture (after any cropping)\n");
|
||||||
printf(" -mt .................... use multi-threading if available\n");
|
printf(" -mt .................... use multi-threading if available\n");
|
||||||
printf(" -low_memory ............ reduce memory usage (slower encoding)\n");
|
printf(" -low_memory ............ reduce memory usage (slower encoding)\n");
|
||||||
printf(" -map <int> ............. print map of extra info\n");
|
printf(" -map <int> ............. print map of extra info\n");
|
||||||
@@ -594,6 +579,9 @@ static void HelpLong(void) {
|
|||||||
printf(" -near_lossless <int> ... use near-lossless image\n"
|
printf(" -near_lossless <int> ... use near-lossless image\n"
|
||||||
" preprocessing (0..100=off), "
|
" preprocessing (0..100=off), "
|
||||||
"default=100\n");
|
"default=100\n");
|
||||||
|
#ifdef WEBP_EXPERIMENTAL_FEATURES /* not documented yet */
|
||||||
|
printf(" -delta_palette ......... use delta palettization\n");
|
||||||
|
#endif // WEBP_EXPERIMENTAL_FEATURES
|
||||||
printf(" -hint <string> ......... specify image characteristics hint,\n");
|
printf(" -hint <string> ......... specify image characteristics hint,\n");
|
||||||
printf(" one of: photo, picture or graph\n");
|
printf(" one of: photo, picture or graph\n");
|
||||||
|
|
||||||
@@ -620,7 +608,6 @@ static void HelpLong(void) {
|
|||||||
printf(" -af .................... auto-adjust filter strength\n");
|
printf(" -af .................... auto-adjust filter strength\n");
|
||||||
printf(" -pre <int> ............. pre-processing filter\n");
|
printf(" -pre <int> ............. pre-processing filter\n");
|
||||||
printf("\n");
|
printf("\n");
|
||||||
printf("Supported input formats:\n %s\n", WebPGetEnabledInputFileFormats());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
@@ -647,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;
|
int return_value = -1;
|
||||||
const char* in_file = NULL, *out_file = NULL, *dump_file = NULL;
|
const char *in_file = NULL, *out_file = NULL, *dump_file = NULL;
|
||||||
FILE* out = NULL;
|
FILE *out = NULL;
|
||||||
int c;
|
int c;
|
||||||
int short_output = 0;
|
int short_output = 0;
|
||||||
int quiet = 0;
|
int quiet = 0;
|
||||||
@@ -670,38 +657,35 @@ int main(int argc, const char* argv[]) {
|
|||||||
WebPConfig config;
|
WebPConfig config;
|
||||||
WebPAuxStats stats;
|
WebPAuxStats stats;
|
||||||
WebPMemoryWriter memory_writer;
|
WebPMemoryWriter memory_writer;
|
||||||
int use_memory_writer;
|
|
||||||
Metadata metadata;
|
Metadata metadata;
|
||||||
Stopwatch stop_watch;
|
Stopwatch stop_watch;
|
||||||
|
|
||||||
INIT_WARGV(argc, argv);
|
|
||||||
|
|
||||||
MetadataInit(&metadata);
|
MetadataInit(&metadata);
|
||||||
WebPMemoryWriterInit(&memory_writer);
|
WebPMemoryWriterInit(&memory_writer);
|
||||||
if (!WebPPictureInit(&picture) ||
|
if (!WebPPictureInit(&picture) ||
|
||||||
!WebPPictureInit(&original_picture) ||
|
!WebPPictureInit(&original_picture) ||
|
||||||
!WebPConfigInit(&config)) {
|
!WebPConfigInit(&config)) {
|
||||||
fprintf(stderr, "Error! Version mismatch!\n");
|
fprintf(stderr, "Error! Version mismatch!\n");
|
||||||
FREE_WARGV_AND_RETURN(-1);
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (argc == 1) {
|
if (argc == 1) {
|
||||||
HelpShort();
|
HelpShort();
|
||||||
FREE_WARGV_AND_RETURN(0);
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (c = 1; c < argc; ++c) {
|
for (c = 1; c < argc; ++c) {
|
||||||
int parse_error = 0;
|
int parse_error = 0;
|
||||||
if (!strcmp(argv[c], "-h") || !strcmp(argv[c], "-help")) {
|
if (!strcmp(argv[c], "-h") || !strcmp(argv[c], "-help")) {
|
||||||
HelpShort();
|
HelpShort();
|
||||||
FREE_WARGV_AND_RETURN(0);
|
return 0;
|
||||||
} else if (!strcmp(argv[c], "-H") || !strcmp(argv[c], "-longhelp")) {
|
} else if (!strcmp(argv[c], "-H") || !strcmp(argv[c], "-longhelp")) {
|
||||||
HelpLong();
|
HelpLong();
|
||||||
FREE_WARGV_AND_RETURN(0);
|
return 0;
|
||||||
} else if (!strcmp(argv[c], "-o") && c + 1 < argc) {
|
} 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], "-d") && c + 1 < argc) {
|
} else if (!strcmp(argv[c], "-d") && c < argc - 1) {
|
||||||
dump_file = (const char*)GET_WARGV(argv, ++c);
|
dump_file = argv[++c];
|
||||||
config.show_compressed = 1;
|
config.show_compressed = 1;
|
||||||
} else if (!strcmp(argv[c], "-print_psnr")) {
|
} else if (!strcmp(argv[c], "-print_psnr")) {
|
||||||
config.show_compressed = 1;
|
config.show_compressed = 1;
|
||||||
@@ -714,7 +698,7 @@ int main(int argc, const char* argv[]) {
|
|||||||
print_distortion = 2;
|
print_distortion = 2;
|
||||||
} else if (!strcmp(argv[c], "-short")) {
|
} else if (!strcmp(argv[c], "-short")) {
|
||||||
++short_output;
|
++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.width = ExUtilGetInt(argv[++c], 0, &parse_error);
|
||||||
picture.height = ExUtilGetInt(argv[++c], 0, &parse_error);
|
picture.height = ExUtilGetInt(argv[++c], 0, &parse_error);
|
||||||
if (picture.width > WEBP_MAX_DIMENSION || picture.width < 0 ||
|
if (picture.width > WEBP_MAX_DIMENSION || picture.width < 0 ||
|
||||||
@@ -724,30 +708,30 @@ int main(int argc, const char* argv[]) {
|
|||||||
picture.width, picture.height);
|
picture.width, picture.height);
|
||||||
goto Error;
|
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);
|
config.method = ExUtilGetInt(argv[++c], 0, &parse_error);
|
||||||
use_lossless_preset = 0; // disable -z option
|
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);
|
config.quality = ExUtilGetFloat(argv[++c], &parse_error);
|
||||||
use_lossless_preset = 0; // disable -z option
|
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);
|
lossless_preset = ExUtilGetInt(argv[++c], 0, &parse_error);
|
||||||
if (use_lossless_preset != 0) use_lossless_preset = 1;
|
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);
|
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);
|
config.alpha_compression = ExUtilGetInt(argv[++c], 0, &parse_error);
|
||||||
} else if (!strcmp(argv[c], "-alpha_cleanup")) {
|
} else if (!strcmp(argv[c], "-alpha_cleanup")) {
|
||||||
// This flag is obsolete, does opposite of -exact.
|
// This flag is obsolete, does opposite of -exact.
|
||||||
config.exact = 0;
|
config.exact = 0;
|
||||||
} else if (!strcmp(argv[c], "-exact")) {
|
} else if (!strcmp(argv[c], "-exact")) {
|
||||||
config.exact = 1;
|
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;
|
blend_alpha = 1;
|
||||||
// background color is given in hex with an optional '0x' prefix
|
// background color is given in hex with an optional '0x' prefix
|
||||||
background_color = ExUtilGetInt(argv[++c], 16, &parse_error);
|
background_color = ExUtilGetInt(argv[++c], 16, &parse_error);
|
||||||
background_color = background_color & 0x00ffffffu;
|
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;
|
++c;
|
||||||
if (!strcmp(argv[c], "none")) {
|
if (!strcmp(argv[c], "none")) {
|
||||||
config.alpha_filtering = 0;
|
config.alpha_filtering = 0;
|
||||||
@@ -763,10 +747,15 @@ int main(int argc, const char* argv[]) {
|
|||||||
keep_alpha = 0;
|
keep_alpha = 0;
|
||||||
} else if (!strcmp(argv[c], "-lossless")) {
|
} else if (!strcmp(argv[c], "-lossless")) {
|
||||||
config.lossless = 1;
|
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.near_lossless = ExUtilGetInt(argv[++c], 0, &parse_error);
|
||||||
config.lossless = 1; // use near-lossless only with lossless
|
config.lossless = 1; // use near-lossless only with lossless
|
||||||
} 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;
|
++c;
|
||||||
if (!strcmp(argv[c], "photo")) {
|
if (!strcmp(argv[c], "photo")) {
|
||||||
config.image_hint = WEBP_HINT_PHOTO;
|
config.image_hint = WEBP_HINT_PHOTO;
|
||||||
@@ -778,13 +767,13 @@ int main(int argc, const char* argv[]) {
|
|||||||
fprintf(stderr, "Error! Unrecognized image hint: %s\n", argv[c]);
|
fprintf(stderr, "Error! Unrecognized image hint: %s\n", argv[c]);
|
||||||
goto Error;
|
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);
|
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);
|
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);
|
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);
|
config.filter_strength = ExUtilGetInt(argv[++c], 0, &parse_error);
|
||||||
} else if (!strcmp(argv[c], "-af")) {
|
} else if (!strcmp(argv[c], "-af")) {
|
||||||
config.autofilter = 1;
|
config.autofilter = 1;
|
||||||
@@ -798,32 +787,27 @@ int main(int argc, const char* argv[]) {
|
|||||||
config.filter_type = 1;
|
config.filter_type = 1;
|
||||||
} else if (!strcmp(argv[c], "-nostrong")) {
|
} else if (!strcmp(argv[c], "-nostrong")) {
|
||||||
config.filter_type = 0;
|
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);
|
config.filter_sharpness = ExUtilGetInt(argv[++c], 0, &parse_error);
|
||||||
} else if (!strcmp(argv[c], "-sharp_yuv")) {
|
} else if (!strcmp(argv[c], "-sharp_yuv")) {
|
||||||
config.use_sharp_yuv = 1;
|
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);
|
config.pass = ExUtilGetInt(argv[++c], 0, &parse_error);
|
||||||
} else if (!strcmp(argv[c], "-qrange") && c + 2 < argc) {
|
} else if (!strcmp(argv[c], "-pre") && c < argc - 1) {
|
||||||
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) {
|
|
||||||
config.preprocessing = ExUtilGetInt(argv[++c], 0, &parse_error);
|
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);
|
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);
|
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);
|
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 = 1;
|
||||||
crop_x = ExUtilGetInt(argv[++c], 0, &parse_error);
|
crop_x = ExUtilGetInt(argv[++c], 0, &parse_error);
|
||||||
crop_y = ExUtilGetInt(argv[++c], 0, &parse_error);
|
crop_y = ExUtilGetInt(argv[++c], 0, &parse_error);
|
||||||
crop_w = ExUtilGetInt(argv[++c], 0, &parse_error);
|
crop_w = ExUtilGetInt(argv[++c], 0, &parse_error);
|
||||||
crop_h = 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_w = ExUtilGetInt(argv[++c], 0, &parse_error);
|
||||||
resize_h = ExUtilGetInt(argv[++c], 0, &parse_error);
|
resize_h = ExUtilGetInt(argv[++c], 0, &parse_error);
|
||||||
#ifndef WEBP_DLL
|
#ifndef WEBP_DLL
|
||||||
@@ -834,12 +818,12 @@ int main(int argc, const char* argv[]) {
|
|||||||
const int version = WebPGetEncoderVersion();
|
const int version = WebPGetEncoderVersion();
|
||||||
printf("%d.%d.%d\n",
|
printf("%d.%d.%d\n",
|
||||||
(version >> 16) & 0xff, (version >> 8) & 0xff, version & 0xff);
|
(version >> 16) & 0xff, (version >> 8) & 0xff, version & 0xff);
|
||||||
FREE_WARGV_AND_RETURN(0);
|
return 0;
|
||||||
} else if (!strcmp(argv[c], "-progress")) {
|
} else if (!strcmp(argv[c], "-progress")) {
|
||||||
show_progress = 1;
|
show_progress = 1;
|
||||||
} else if (!strcmp(argv[c], "-quiet")) {
|
} else if (!strcmp(argv[c], "-quiet")) {
|
||||||
quiet = 1;
|
quiet = 1;
|
||||||
} else if (!strcmp(argv[c], "-preset") && c + 1 < argc) {
|
} else if (!strcmp(argv[c], "-preset") && c < argc - 1) {
|
||||||
WebPPreset preset;
|
WebPPreset preset;
|
||||||
++c;
|
++c;
|
||||||
if (!strcmp(argv[c], "default")) {
|
if (!strcmp(argv[c], "default")) {
|
||||||
@@ -862,7 +846,7 @@ int main(int argc, const char* argv[]) {
|
|||||||
fprintf(stderr, "Error! Could initialize configuration with preset.\n");
|
fprintf(stderr, "Error! Could initialize configuration with preset.\n");
|
||||||
goto Error;
|
goto Error;
|
||||||
}
|
}
|
||||||
} else if (!strcmp(argv[c], "-metadata") && c + 1 < argc) {
|
} else if (!strcmp(argv[c], "-metadata") && c < argc - 1) {
|
||||||
static const struct {
|
static const struct {
|
||||||
const char* option;
|
const char* option;
|
||||||
int flag;
|
int flag;
|
||||||
@@ -896,7 +880,8 @@ int main(int argc, const char* argv[]) {
|
|||||||
if (i == kNumTokens) {
|
if (i == kNumTokens) {
|
||||||
fprintf(stderr, "Error! Unknown metadata type '%.*s'\n",
|
fprintf(stderr, "Error! Unknown metadata type '%.*s'\n",
|
||||||
(int)(token - start), start);
|
(int)(token - start), start);
|
||||||
FREE_WARGV_AND_RETURN(-1);
|
HelpLong();
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
start = token + 1;
|
start = token + 1;
|
||||||
}
|
}
|
||||||
@@ -910,19 +895,19 @@ int main(int argc, const char* argv[]) {
|
|||||||
} else if (!strcmp(argv[c], "-v")) {
|
} else if (!strcmp(argv[c], "-v")) {
|
||||||
verbose = 1;
|
verbose = 1;
|
||||||
} else if (!strcmp(argv[c], "--")) {
|
} 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;
|
break;
|
||||||
} else if (argv[c][0] == '-') {
|
} else if (argv[c][0] == '-') {
|
||||||
fprintf(stderr, "Error! Unknown option '%s'\n", argv[c]);
|
fprintf(stderr, "Error! Unknown option '%s'\n", argv[c]);
|
||||||
HelpLong();
|
HelpLong();
|
||||||
FREE_WARGV_AND_RETURN(-1);
|
return -1;
|
||||||
} else {
|
} else {
|
||||||
in_file = (const char*)GET_WARGV(argv, c);
|
in_file = argv[c];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parse_error) {
|
if (parse_error) {
|
||||||
HelpLong();
|
HelpLong();
|
||||||
FREE_WARGV_AND_RETURN(-1);
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (in_file == NULL) {
|
if (in_file == NULL) {
|
||||||
@@ -972,8 +957,7 @@ int main(int argc, const char* argv[]) {
|
|||||||
}
|
}
|
||||||
if (!ReadPicture(in_file, &picture, keep_alpha,
|
if (!ReadPicture(in_file, &picture, keep_alpha,
|
||||||
(keep_metadata == 0) ? NULL : &metadata)) {
|
(keep_metadata == 0) ? NULL : &metadata)) {
|
||||||
WFPRINTF(stderr, "Error! Cannot read input picture file '%s'\n",
|
fprintf(stderr, "Error! Cannot read input picture file '%s'\n", in_file);
|
||||||
(const W_CHAR*)in_file);
|
|
||||||
goto Error;
|
goto Error;
|
||||||
}
|
}
|
||||||
picture.progress_hook = (show_progress && !quiet) ? ProgressReport : NULL;
|
picture.progress_hook = (show_progress && !quiet) ? ProgressReport : NULL;
|
||||||
@@ -986,41 +970,28 @@ int main(int argc, const char* argv[]) {
|
|||||||
const double read_time = StopwatchReadAndReset(&stop_watch);
|
const double read_time = StopwatchReadAndReset(&stop_watch);
|
||||||
fprintf(stderr, "Time to read input: %.3fs\n", read_time);
|
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
|
// Open the output
|
||||||
if (out_file != NULL) {
|
if (out_file != NULL) {
|
||||||
const int use_stdout = !WSTRCMP(out_file, "-");
|
const int use_stdout = !strcmp(out_file, "-");
|
||||||
out = use_stdout ? ImgIoUtilSetBinaryMode(stdout) : WFOPEN(out_file, "wb");
|
out = use_stdout ? ImgIoUtilSetBinaryMode(stdout) : fopen(out_file, "wb");
|
||||||
if (out == NULL) {
|
if (out == NULL) {
|
||||||
WFPRINTF(stderr, "Error! Cannot open output file '%s'\n",
|
fprintf(stderr, "Error! Cannot open output file '%s'\n", out_file);
|
||||||
(const W_CHAR*)out_file);
|
|
||||||
goto Error;
|
goto Error;
|
||||||
} else {
|
} else {
|
||||||
if (!short_output && !quiet) {
|
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) {
|
if (keep_metadata == 0) {
|
||||||
picture.writer = WebPMemoryWrite;
|
|
||||||
picture.custom_ptr = (void*)&memory_writer;
|
|
||||||
} else {
|
|
||||||
picture.writer = MyWriter;
|
picture.writer = MyWriter;
|
||||||
picture.custom_ptr = (void*)out;
|
picture.custom_ptr = (void*)out;
|
||||||
|
} else {
|
||||||
|
picture.writer = WebPMemoryWrite;
|
||||||
|
picture.custom_ptr = (void*)&memory_writer;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
out = NULL;
|
out = NULL;
|
||||||
if (use_memory_writer) {
|
|
||||||
picture.writer = WebPMemoryWrite;
|
|
||||||
picture.custom_ptr = (void*)&memory_writer;
|
|
||||||
}
|
|
||||||
if (!quiet && !short_output) {
|
if (!quiet && !short_output) {
|
||||||
fprintf(stderr, "No output file specified (no -o flag). Encoding will\n");
|
fprintf(stderr, "No output file specified (no -o flag). Encoding will\n");
|
||||||
fprintf(stderr, "be performed, but its results discarded.\n\n");
|
fprintf(stderr, "be performed, but its results discarded.\n\n");
|
||||||
@@ -1043,53 +1014,10 @@ int main(int argc, const char* argv[]) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((resize_w | resize_h) > 0) {
|
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)) {
|
if (!WebPPictureRescale(&picture, resize_w, resize_h)) {
|
||||||
fprintf(stderr, "Error! Cannot resize picture\n");
|
fprintf(stderr, "Error! Cannot resize picture\n");
|
||||||
goto Error;
|
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)) {
|
if (verbose && (crop != 0 || (resize_w | resize_h) > 0)) {
|
||||||
const double preproc_time = StopwatchReadAndReset(&stop_watch);
|
const double preproc_time = StopwatchReadAndReset(&stop_watch);
|
||||||
@@ -1099,12 +1027,8 @@ int main(int argc, const char* argv[]) {
|
|||||||
if (picture.extra_info_type > 0) {
|
if (picture.extra_info_type > 0) {
|
||||||
AllocExtraInfo(&picture);
|
AllocExtraInfo(&picture);
|
||||||
}
|
}
|
||||||
// Save original picture for later comparison. Only for lossy as lossless does
|
if (print_distortion >= 0) { // Save original picture for later comparison
|
||||||
// not modify 'picture' (even near-lossless).
|
WebPPictureCopy(&picture, &original_picture);
|
||||||
if (print_distortion >= 0 && !config.lossless &&
|
|
||||||
!WebPPictureCopy(&picture, &original_picture)) {
|
|
||||||
fprintf(stderr, "Error! Cannot copy temporary picture\n");
|
|
||||||
goto Error;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compress.
|
// Compress.
|
||||||
@@ -1122,71 +1046,40 @@ int main(int argc, const char* argv[]) {
|
|||||||
fprintf(stderr, "Time to encode picture: %.3fs\n", encode_time);
|
fprintf(stderr, "Time to encode picture: %.3fs\n", encode_time);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the decompressed image for the lossless pipeline.
|
// Write info
|
||||||
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.
|
|
||||||
if (dump_file) {
|
if (dump_file) {
|
||||||
if (picture.use_argb) {
|
if (picture.use_argb) {
|
||||||
fprintf(stderr, "Warning: can't dump file (-d option) "
|
fprintf(stderr, "Warning: can't dump file (-d option) in lossless mode.");
|
||||||
"in lossless mode.\n");
|
|
||||||
} else if (!DumpPicture(&picture, dump_file)) {
|
} else if (!DumpPicture(&picture, dump_file)) {
|
||||||
WFPRINTF(stderr, "Warning, couldn't dump picture %s\n",
|
fprintf(stderr, "Warning, couldn't dump picture %s\n", dump_file);
|
||||||
(const W_CHAR*)dump_file);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (use_memory_writer && out != NULL &&
|
if (keep_metadata != 0) {
|
||||||
!WriteWebPWithMetadata(out, &picture, &memory_writer, &metadata,
|
if (out != NULL) {
|
||||||
keep_metadata, &metadata_written)) {
|
if (!WriteWebPWithMetadata(out, &picture, &memory_writer,
|
||||||
fprintf(stderr, "Error writing WebP file!\n");
|
&metadata, keep_metadata, &metadata_written)) {
|
||||||
goto Error;
|
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) {
|
for (iter = info; iter->payload != NULL; ++iter) {
|
||||||
// output is disabled, just display the metadata stats.
|
if (UpdateFlagsAndSize(iter->payload, !!(keep_metadata & iter->flag),
|
||||||
const struct {
|
0, &unused1, &unused2)) {
|
||||||
const MetadataPayload* const payload;
|
metadata_written |= iter->flag;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1226,7 +1119,7 @@ int main(int argc, const char* argv[]) {
|
|||||||
|
|
||||||
Error:
|
Error:
|
||||||
WebPMemoryWriterClear(&memory_writer);
|
WebPMemoryWriterClear(&memory_writer);
|
||||||
WebPFree(picture.extra_info);
|
free(picture.extra_info);
|
||||||
MetadataFree(&metadata);
|
MetadataFree(&metadata);
|
||||||
WebPPictureFree(&picture);
|
WebPPictureFree(&picture);
|
||||||
WebPPictureFree(&original_picture);
|
WebPPictureFree(&original_picture);
|
||||||
@@ -1234,7 +1127,7 @@ int main(int argc, const char* argv[]) {
|
|||||||
fclose(out);
|
fclose(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
FREE_WARGV_AND_RETURN(return_value);
|
return return_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -24,7 +24,6 @@
|
|||||||
#include "../imageio/image_enc.h"
|
#include "../imageio/image_enc.h"
|
||||||
#include "../imageio/webpdec.h"
|
#include "../imageio/webpdec.h"
|
||||||
#include "./stopwatch.h"
|
#include "./stopwatch.h"
|
||||||
#include "./unicode.h"
|
|
||||||
|
|
||||||
static int verbose = 0;
|
static int verbose = 0;
|
||||||
static int quiet = 0;
|
static int quiet = 0;
|
||||||
@@ -43,7 +42,7 @@ extern void* VP8GetCPUInfo; // opaque forward declaration.
|
|||||||
|
|
||||||
static int SaveOutput(const WebPDecBuffer* const buffer,
|
static int SaveOutput(const WebPDecBuffer* const buffer,
|
||||||
WebPOutputFileFormat format, const char* const out_file) {
|
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;
|
int ok = 1;
|
||||||
Stopwatch stop_watch;
|
Stopwatch stop_watch;
|
||||||
|
|
||||||
@@ -57,7 +56,7 @@ static int SaveOutput(const WebPDecBuffer* const buffer,
|
|||||||
if (use_stdout) {
|
if (use_stdout) {
|
||||||
fprintf(stderr, "Saved to stdout\n");
|
fprintf(stderr, "Saved to stdout\n");
|
||||||
} else {
|
} else {
|
||||||
WFPRINTF(stderr, "Saved file %s\n", (const W_CHAR*)out_file);
|
fprintf(stderr, "Saved file %s\n", out_file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (verbose) {
|
if (verbose) {
|
||||||
@@ -68,7 +67,7 @@ static int SaveOutput(const WebPDecBuffer* const buffer,
|
|||||||
if (use_stdout) {
|
if (use_stdout) {
|
||||||
fprintf(stderr, "Error writing to stdout !!\n");
|
fprintf(stderr, "Error writing to stdout !!\n");
|
||||||
} else {
|
} else {
|
||||||
WFPRINTF(stderr, "Error writing file %s !!\n", (const W_CHAR*)out_file);
|
fprintf(stderr, "Error writing file %s !!\n", out_file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ok;
|
return ok;
|
||||||
@@ -76,8 +75,7 @@ static int SaveOutput(const WebPDecBuffer* const buffer,
|
|||||||
|
|
||||||
static void Help(void) {
|
static void Help(void) {
|
||||||
printf("Usage: dwebp in_file [options] [-o out_file]\n\n"
|
printf("Usage: dwebp in_file [options] [-o out_file]\n\n"
|
||||||
"Decodes the WebP image file to PNG format [Default].\n"
|
"Decodes the WebP image file to PNG format [Default]\n"
|
||||||
"Note: Animated WebP files are not supported.\n\n"
|
|
||||||
"Use following options to convert into alternate image formats:\n"
|
"Use following options to convert into alternate image formats:\n"
|
||||||
" -pam ......... save the raw RGBA samples as a color PAM\n"
|
" -pam ......... save the raw RGBA samples as a color PAM\n"
|
||||||
" -ppm ......... save the raw RGB samples as a color PPM\n"
|
" -ppm ......... save the raw RGB samples as a color PPM\n"
|
||||||
@@ -96,7 +94,7 @@ static void Help(void) {
|
|||||||
" -alpha_dither use alpha-plane dithering if needed\n"
|
" -alpha_dither use alpha-plane dithering if needed\n"
|
||||||
" -mt .......... use multi-threading\n"
|
" -mt .......... use multi-threading\n"
|
||||||
" -crop <x> <y> <w> <h> ... crop output with the given rectangle\n"
|
" -crop <x> <y> <w> <h> ... crop output with the given rectangle\n"
|
||||||
" -resize <w> <h> ......... resize output (*after* any cropping)\n"
|
" -resize <w> <h> ......... scale the output (*after* any cropping)\n"
|
||||||
" -flip ........ flip the output vertically\n"
|
" -flip ........ flip the output vertically\n"
|
||||||
" -alpha ....... only save the alpha plane\n"
|
" -alpha ....... only save the alpha plane\n"
|
||||||
" -incremental . use incremental decoding (useful for tests)\n"
|
" -incremental . use incremental decoding (useful for tests)\n"
|
||||||
@@ -133,7 +131,7 @@ static uint8_t* AllocateExternalBuffer(WebPDecoderConfig* config,
|
|||||||
format == RGB_565) ? 2
|
format == RGB_565) ? 2
|
||||||
: 4;
|
: 4;
|
||||||
uint32_t stride = bpp * w + 7; // <- just for exercising
|
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;
|
if (external_buffer == NULL) return NULL;
|
||||||
output_buffer->u.RGBA.stride = stride;
|
output_buffer->u.RGBA.stride = stride;
|
||||||
output_buffer->u.RGBA.size = stride * h;
|
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)
|
uint32_t total_size = stride * h * (has_alpha ? 2 : 1)
|
||||||
+ 2 * uv_stride * (h + 1) / 2;
|
+ 2 * uv_stride * (h + 1) / 2;
|
||||||
assert(format >= YUV && format <= YUVA);
|
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;
|
if (external_buffer == NULL) return NULL;
|
||||||
tmp = external_buffer;
|
tmp = external_buffer;
|
||||||
output_buffer->u.YUVA.y = tmp;
|
output_buffer->u.YUVA.y = tmp;
|
||||||
@@ -177,10 +175,10 @@ static uint8_t* AllocateExternalBuffer(WebPDecoderConfig* config,
|
|||||||
return external_buffer;
|
return external_buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, const char* argv[]) {
|
int main(int argc, const char *argv[]) {
|
||||||
int ok = 0;
|
int ok = 0;
|
||||||
const char* in_file = NULL;
|
const char *in_file = NULL;
|
||||||
const char* out_file = NULL;
|
const char *out_file = NULL;
|
||||||
|
|
||||||
WebPDecoderConfig config;
|
WebPDecoderConfig config;
|
||||||
WebPDecBuffer* const output_buffer = &config.output;
|
WebPDecBuffer* const output_buffer = &config.output;
|
||||||
@@ -193,20 +191,18 @@ int main(int argc, const char* argv[]) {
|
|||||||
int incremental = 0;
|
int incremental = 0;
|
||||||
int c;
|
int c;
|
||||||
|
|
||||||
INIT_WARGV(argc, argv);
|
|
||||||
|
|
||||||
if (!WebPInitDecoderConfig(&config)) {
|
if (!WebPInitDecoderConfig(&config)) {
|
||||||
fprintf(stderr, "Library version mismatch!\n");
|
fprintf(stderr, "Library version mismatch!\n");
|
||||||
FREE_WARGV_AND_RETURN(-1);
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (c = 1; c < argc; ++c) {
|
for (c = 1; c < argc; ++c) {
|
||||||
int parse_error = 0;
|
int parse_error = 0;
|
||||||
if (!strcmp(argv[c], "-h") || !strcmp(argv[c], "-help")) {
|
if (!strcmp(argv[c], "-h") || !strcmp(argv[c], "-help")) {
|
||||||
Help();
|
Help();
|
||||||
FREE_WARGV_AND_RETURN(0);
|
return 0;
|
||||||
} else if (!strcmp(argv[c], "-o") && c < argc - 1) {
|
} 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")) {
|
} else if (!strcmp(argv[c], "-alpha")) {
|
||||||
format = ALPHA_PLANE_ONLY;
|
format = ALPHA_PLANE_ONLY;
|
||||||
} else if (!strcmp(argv[c], "-nofancy")) {
|
} else if (!strcmp(argv[c], "-nofancy")) {
|
||||||
@@ -227,7 +223,7 @@ int main(int argc, const char* argv[]) {
|
|||||||
const int version = WebPGetDecoderVersion();
|
const int version = WebPGetDecoderVersion();
|
||||||
printf("%d.%d.%d\n",
|
printf("%d.%d.%d\n",
|
||||||
(version >> 16) & 0xff, (version >> 8) & 0xff, version & 0xff);
|
(version >> 16) & 0xff, (version >> 8) & 0xff, version & 0xff);
|
||||||
FREE_WARGV_AND_RETURN(0);
|
return 0;
|
||||||
} else if (!strcmp(argv[c], "-pgm")) {
|
} else if (!strcmp(argv[c], "-pgm")) {
|
||||||
format = PGM;
|
format = PGM;
|
||||||
} else if (!strcmp(argv[c], "-yuv")) {
|
} else if (!strcmp(argv[c], "-yuv")) {
|
||||||
@@ -288,26 +284,26 @@ int main(int argc, const char* argv[]) {
|
|||||||
} else if (!strcmp(argv[c], "-incremental")) {
|
} else if (!strcmp(argv[c], "-incremental")) {
|
||||||
incremental = 1;
|
incremental = 1;
|
||||||
} else if (!strcmp(argv[c], "--")) {
|
} 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;
|
break;
|
||||||
} else if (argv[c][0] == '-') {
|
} else if (argv[c][0] == '-') {
|
||||||
fprintf(stderr, "Unknown option '%s'\n", argv[c]);
|
fprintf(stderr, "Unknown option '%s'\n", argv[c]);
|
||||||
Help();
|
Help();
|
||||||
FREE_WARGV_AND_RETURN(-1);
|
return -1;
|
||||||
} else {
|
} else {
|
||||||
in_file = (const char*)GET_WARGV(argv, c);
|
in_file = argv[c];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parse_error) {
|
if (parse_error) {
|
||||||
Help();
|
Help();
|
||||||
FREE_WARGV_AND_RETURN(-1);
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (in_file == NULL) {
|
if (in_file == NULL) {
|
||||||
fprintf(stderr, "missing input file!!\n");
|
fprintf(stderr, "missing input file!!\n");
|
||||||
Help();
|
Help();
|
||||||
FREE_WARGV_AND_RETURN(-1);
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (quiet) verbose = 0;
|
if (quiet) verbose = 0;
|
||||||
@@ -316,7 +312,7 @@ int main(int argc, const char* argv[]) {
|
|||||||
VP8StatusCode status = VP8_STATUS_OK;
|
VP8StatusCode status = VP8_STATUS_OK;
|
||||||
size_t data_size = 0;
|
size_t data_size = 0;
|
||||||
if (!LoadWebP(in_file, &data, &data_size, bitstream)) {
|
if (!LoadWebP(in_file, &data, &data_size, bitstream)) {
|
||||||
FREE_WARGV_AND_RETURN(-1);
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (format) {
|
switch (format) {
|
||||||
@@ -336,8 +332,9 @@ int main(int argc, const char* argv[]) {
|
|||||||
case BMP:
|
case BMP:
|
||||||
output_buffer->colorspace = bitstream->has_alpha ? MODE_BGRA : MODE_BGR;
|
output_buffer->colorspace = bitstream->has_alpha ? MODE_BGRA : MODE_BGR;
|
||||||
break;
|
break;
|
||||||
case TIFF:
|
case TIFF: // note: force pre-multiplied alpha
|
||||||
output_buffer->colorspace = bitstream->has_alpha ? MODE_RGBA : MODE_RGB;
|
output_buffer->colorspace =
|
||||||
|
bitstream->has_alpha ? MODE_rgbA : MODE_RGB;
|
||||||
break;
|
break;
|
||||||
case PGM:
|
case PGM:
|
||||||
case RAW_YUV:
|
case RAW_YUV:
|
||||||
@@ -393,18 +390,18 @@ int main(int argc, const char* argv[]) {
|
|||||||
|
|
||||||
if (out_file != NULL) {
|
if (out_file != NULL) {
|
||||||
if (!quiet) {
|
if (!quiet) {
|
||||||
WFPRINTF(stderr, "Decoded %s.", (const W_CHAR*)in_file);
|
fprintf(stderr, "Decoded %s. Dimensions: %d x %d %s. Format: %s. "
|
||||||
fprintf(stderr, " Dimensions: %d x %d %s. Format: %s. Now saving...\n",
|
"Now saving...\n",
|
||||||
output_buffer->width, output_buffer->height,
|
in_file, output_buffer->width, output_buffer->height,
|
||||||
bitstream->has_alpha ? " (with alpha)" : "",
|
bitstream->has_alpha ? " (with alpha)" : "",
|
||||||
kFormatType[bitstream->format]);
|
kFormatType[bitstream->format]);
|
||||||
}
|
}
|
||||||
ok = SaveOutput(output_buffer, format, out_file);
|
ok = SaveOutput(output_buffer, format, out_file);
|
||||||
} else {
|
} else {
|
||||||
if (!quiet) {
|
if (!quiet) {
|
||||||
WFPRINTF(stderr, "File %s can be decoded ", (const W_CHAR*)in_file);
|
fprintf(stderr, "File %s can be decoded "
|
||||||
fprintf(stderr, "(dimensions: %d x %d %s. Format: %s).\n",
|
"(dimensions: %d x %d %s. Format: %s).\n",
|
||||||
output_buffer->width, output_buffer->height,
|
in_file, output_buffer->width, output_buffer->height,
|
||||||
bitstream->has_alpha ? " (with alpha)" : "",
|
bitstream->has_alpha ? " (with alpha)" : "",
|
||||||
kFormatType[bitstream->format]);
|
kFormatType[bitstream->format]);
|
||||||
fprintf(stderr, "Nothing written; "
|
fprintf(stderr, "Nothing written; "
|
||||||
@@ -413,9 +410,9 @@ int main(int argc, const char* argv[]) {
|
|||||||
}
|
}
|
||||||
Exit:
|
Exit:
|
||||||
WebPFreeDecBuffer(output_buffer);
|
WebPFreeDecBuffer(output_buffer);
|
||||||
WebPFree((void*)external_buffer);
|
free((void*)external_buffer);
|
||||||
WebPFree((void*)data);
|
free((void*)data);
|
||||||
FREE_WARGV_AND_RETURN(ok ? 0 : -1);
|
return ok ? 0 : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -12,14 +12,10 @@
|
|||||||
|
|
||||||
#include "./example_util.h"
|
#include "./example_util.h"
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "webp/mux_types.h"
|
|
||||||
#include "../imageio/imageio_util.h"
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// String parsing
|
// String parsing
|
||||||
|
|
||||||
@@ -60,80 +56,3 @@ float ExUtilGetFloat(const char* const v, int* const error) {
|
|||||||
}
|
}
|
||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
static void ResetCommandLineArguments(int argc, const char* argv[],
|
|
||||||
CommandLineArguments* const args) {
|
|
||||||
assert(args != NULL);
|
|
||||||
args->argc_ = argc;
|
|
||||||
args->argv_ = argv;
|
|
||||||
args->own_argv_ = 0;
|
|
||||||
WebPDataInit(&args->argv_data_);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ExUtilDeleteCommandLineArguments(CommandLineArguments* const args) {
|
|
||||||
if (args != NULL) {
|
|
||||||
if (args->own_argv_) {
|
|
||||||
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) {
|
|
||||||
ExUtilDeleteCommandLineArguments(args);
|
|
||||||
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);
|
|
||||||
ExUtilDeleteCommandLineArguments(args);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
assert(strlen(cur) != 0);
|
|
||||||
args->argv_[argc++] = cur;
|
|
||||||
}
|
|
||||||
args->argc_ = argc;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
int ExUtilReadFileToWebPData(const char* const filename,
|
|
||||||
WebPData* const webp_data) {
|
|
||||||
const uint8_t* data;
|
|
||||||
size_t size;
|
|
||||||
if (webp_data == NULL) return 0;
|
|
||||||
if (!ImgIoUtilReadFile(filename, &data, &size)) return 0;
|
|
||||||
webp_data->bytes = data;
|
|
||||||
webp_data->size = size;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -14,7 +14,6 @@
|
|||||||
#define WEBP_EXAMPLES_EXAMPLE_UTIL_H_
|
#define WEBP_EXAMPLES_EXAMPLE_UTIL_H_
|
||||||
|
|
||||||
#include "webp/types.h"
|
#include "webp/types.h"
|
||||||
#include "webp/mux_types.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@@ -36,33 +35,6 @@ float ExUtilGetFloat(const char* const v, int* const error);
|
|||||||
// actually parsed is returned, or -1 if an error occurred.
|
// actually parsed is returned, or -1 if an error occurred.
|
||||||
int ExUtilGetInts(const char* v, int base, int max_output, int output[]);
|
int ExUtilGetInts(const char* v, int base, int max_output, int output[]);
|
||||||
|
|
||||||
// Reads a file named 'filename' into a WebPData structure. The content of
|
|
||||||
// webp_data is overwritten. Returns false in case of error.
|
|
||||||
int ExUtilReadFileToWebPData(const char* const filename,
|
|
||||||
WebPData* const webp_data);
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
// Command-line arguments
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
int argc_;
|
|
||||||
const char** argv_;
|
|
||||||
WebPData argv_data_;
|
|
||||||
int own_argv_;
|
|
||||||
} CommandLineArguments;
|
|
||||||
|
|
||||||
// Initializes the structure from the command-line parameters. If there is
|
|
||||||
// only one parameter and it does not start with a '-', then it is assumed to
|
|
||||||
// be a file name. This file will be read and tokenized into command-line
|
|
||||||
// arguments. The content of 'args' is overwritten.
|
|
||||||
// Returns false in case of error (memory allocation failure, non
|
|
||||||
// existing file, too many arguments, ...).
|
|
||||||
int ExUtilInitCommandLineArguments(int argc, const char* argv[],
|
|
||||||
CommandLineArguments* const args);
|
|
||||||
|
|
||||||
// Deallocate all memory and reset 'args'.
|
|
||||||
void ExUtilDeleteCommandLineArguments(CommandLineArguments* const args);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} // extern "C"
|
} // extern "C"
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -23,22 +23,12 @@
|
|||||||
|
|
||||||
#ifdef WEBP_HAVE_GIF
|
#ifdef WEBP_HAVE_GIF
|
||||||
|
|
||||||
#if defined(HAVE_UNISTD_H) && HAVE_UNISTD_H
|
|
||||||
#include <unistd.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <gif_lib.h>
|
#include <gif_lib.h>
|
||||||
#include "webp/encode.h"
|
#include "webp/encode.h"
|
||||||
#include "webp/mux.h"
|
#include "webp/mux.h"
|
||||||
#include "../examples/example_util.h"
|
#include "../examples/example_util.h"
|
||||||
#include "../imageio/imageio_util.h"
|
#include "../imageio/imageio_util.h"
|
||||||
#include "./gifdec.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(" -metadata <string> ..... comma separated list of metadata to\n");
|
||||||
printf(" ");
|
printf(" ");
|
||||||
printf("copy from the input to the output if present\n");
|
printf("copy from the input to the output if present\n");
|
||||||
printf(" ");
|
printf(" "
|
||||||
printf("Valid values: all, none, icc, xmp (default)\n");
|
"Valid values: all, none, icc, xmp (default)\n");
|
||||||
printf(" -loop_compatibility .... use compatibility mode for Chrome\n");
|
|
||||||
printf(" version prior to M62 (inclusive)\n");
|
|
||||||
printf(" -mt .................... use multi-threading if available\n");
|
printf(" -mt .................... use multi-threading if available\n");
|
||||||
printf("\n");
|
printf("\n");
|
||||||
printf(" -version ............... print version number and exit\n");
|
printf(" -version ............... print version number and exit\n");
|
||||||
@@ -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 verbose = 0;
|
||||||
int gif_error = GIF_ERROR;
|
int gif_error = GIF_ERROR;
|
||||||
WebPMuxError err = WEBP_MUX_OK;
|
WebPMuxError err = WEBP_MUX_OK;
|
||||||
int ok = 0;
|
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;
|
GifFileType* gif = NULL;
|
||||||
int frame_duration = 0;
|
int frame_duration = 0;
|
||||||
int frame_timestamp = 0;
|
int frame_timestamp = 0;
|
||||||
@@ -115,7 +104,7 @@ int main(int argc, const char* argv[]) {
|
|||||||
WebPAnimEncoderOptions enc_options;
|
WebPAnimEncoderOptions enc_options;
|
||||||
WebPConfig config;
|
WebPConfig config;
|
||||||
|
|
||||||
int frame_number = 0; // Whether we are processing the first frame.
|
int is_first_frame = 1; // Whether we are processing the first frame.
|
||||||
int done;
|
int done;
|
||||||
int c;
|
int c;
|
||||||
int quiet = 0;
|
int quiet = 0;
|
||||||
@@ -126,21 +115,18 @@ int main(int argc, const char* argv[]) {
|
|||||||
int stored_icc = 0; // Whether we have already stored an ICC profile.
|
int stored_icc = 0; // Whether we have already stored an ICC profile.
|
||||||
WebPData xmp_data;
|
WebPData xmp_data;
|
||||||
int stored_xmp = 0; // Whether we have already stored an XMP profile.
|
int stored_xmp = 0; // Whether we have already stored an XMP profile.
|
||||||
int loop_count = 0; // default: infinite
|
int loop_count = 0;
|
||||||
int stored_loop_count = 0; // Whether we have found an explicit loop count.
|
int stored_loop_count = 0; // Whether we have found an explicit loop count.
|
||||||
int loop_compatibility = 0;
|
|
||||||
WebPMux* mux = NULL;
|
WebPMux* mux = NULL;
|
||||||
|
|
||||||
int default_kmin = 1; // Whether to use default kmin value.
|
int default_kmin = 1; // Whether to use default kmin value.
|
||||||
int default_kmax = 1;
|
int default_kmax = 1;
|
||||||
|
|
||||||
INIT_WARGV(argc, argv);
|
|
||||||
|
|
||||||
if (!WebPConfigInit(&config) || !WebPAnimEncoderOptionsInit(&enc_options) ||
|
if (!WebPConfigInit(&config) || !WebPAnimEncoderOptionsInit(&enc_options) ||
|
||||||
!WebPPictureInit(&frame) || !WebPPictureInit(&curr_canvas) ||
|
!WebPPictureInit(&frame) || !WebPPictureInit(&curr_canvas) ||
|
||||||
!WebPPictureInit(&prev_canvas)) {
|
!WebPPictureInit(&prev_canvas)) {
|
||||||
fprintf(stderr, "Error! Version mismatch!\n");
|
fprintf(stderr, "Error! Version mismatch!\n");
|
||||||
FREE_WARGV_AND_RETURN(-1);
|
return -1;
|
||||||
}
|
}
|
||||||
config.lossless = 1; // Use lossless compression by default.
|
config.lossless = 1; // Use lossless compression by default.
|
||||||
|
|
||||||
@@ -150,23 +136,21 @@ int main(int argc, const char* argv[]) {
|
|||||||
|
|
||||||
if (argc == 1) {
|
if (argc == 1) {
|
||||||
Help();
|
Help();
|
||||||
FREE_WARGV_AND_RETURN(0);
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (c = 1; c < argc; ++c) {
|
for (c = 1; c < argc; ++c) {
|
||||||
int parse_error = 0;
|
int parse_error = 0;
|
||||||
if (!strcmp(argv[c], "-h") || !strcmp(argv[c], "-help")) {
|
if (!strcmp(argv[c], "-h") || !strcmp(argv[c], "-help")) {
|
||||||
Help();
|
Help();
|
||||||
FREE_WARGV_AND_RETURN(0);
|
return 0;
|
||||||
} else if (!strcmp(argv[c], "-o") && c < argc - 1) {
|
} 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")) {
|
} else if (!strcmp(argv[c], "-lossy")) {
|
||||||
config.lossless = 0;
|
config.lossless = 0;
|
||||||
} else if (!strcmp(argv[c], "-mixed")) {
|
} else if (!strcmp(argv[c], "-mixed")) {
|
||||||
enc_options.allow_mixed = 1;
|
enc_options.allow_mixed = 1;
|
||||||
config.lossless = 0;
|
config.lossless = 0;
|
||||||
} else if (!strcmp(argv[c], "-loop_compatibility")) {
|
|
||||||
loop_compatibility = 1;
|
|
||||||
} else if (!strcmp(argv[c], "-q") && c < argc - 1) {
|
} else if (!strcmp(argv[c], "-q") && c < argc - 1) {
|
||||||
config.quality = ExUtilGetFloat(argv[++c], &parse_error);
|
config.quality = ExUtilGetFloat(argv[++c], &parse_error);
|
||||||
} else if (!strcmp(argv[c], "-m") && c < argc - 1) {
|
} else if (!strcmp(argv[c], "-m") && c < argc - 1) {
|
||||||
@@ -216,7 +200,7 @@ int main(int argc, const char* argv[]) {
|
|||||||
fprintf(stderr, "Error! Unknown metadata type '%.*s'\n",
|
fprintf(stderr, "Error! Unknown metadata type '%.*s'\n",
|
||||||
(int)(token - start), start);
|
(int)(token - start), start);
|
||||||
Help();
|
Help();
|
||||||
FREE_WARGV_AND_RETURN(-1);
|
return -1;
|
||||||
}
|
}
|
||||||
start = token + 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 >> 16) & 0xff, (enc_version >> 8) & 0xff,
|
||||||
enc_version & 0xff, (mux_version >> 16) & 0xff,
|
enc_version & 0xff, (mux_version >> 16) & 0xff,
|
||||||
(mux_version >> 8) & 0xff, mux_version & 0xff);
|
(mux_version >> 8) & 0xff, mux_version & 0xff);
|
||||||
FREE_WARGV_AND_RETURN(0);
|
return 0;
|
||||||
} else if (!strcmp(argv[c], "-quiet")) {
|
} else if (!strcmp(argv[c], "-quiet")) {
|
||||||
quiet = 1;
|
quiet = 1;
|
||||||
enc_options.verbose = 0;
|
enc_options.verbose = 0;
|
||||||
@@ -237,19 +221,19 @@ int main(int argc, const char* argv[]) {
|
|||||||
verbose = 1;
|
verbose = 1;
|
||||||
enc_options.verbose = 1;
|
enc_options.verbose = 1;
|
||||||
} else if (!strcmp(argv[c], "--")) {
|
} else if (!strcmp(argv[c], "--")) {
|
||||||
if (c < argc - 1) in_file = GET_WARGV(argv, ++c);
|
if (c < argc - 1) in_file = argv[++c];
|
||||||
break;
|
break;
|
||||||
} else if (argv[c][0] == '-') {
|
} else if (argv[c][0] == '-') {
|
||||||
fprintf(stderr, "Error! Unknown option '%s'\n", argv[c]);
|
fprintf(stderr, "Error! Unknown option '%s'\n", argv[c]);
|
||||||
Help();
|
Help();
|
||||||
FREE_WARGV_AND_RETURN(-1);
|
return -1;
|
||||||
} else {
|
} else {
|
||||||
in_file = GET_WARGV(argv, c);
|
in_file = argv[c];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parse_error) {
|
if (parse_error) {
|
||||||
Help();
|
Help();
|
||||||
FREE_WARGV_AND_RETURN(-1);
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -273,7 +257,11 @@ int main(int argc, const char* argv[]) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Start the decoder object
|
// 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;
|
if (gif == NULL) goto End;
|
||||||
|
|
||||||
// Loop over GIF images
|
// Loop over GIF images
|
||||||
@@ -289,7 +277,7 @@ int main(int argc, const char* argv[]) {
|
|||||||
|
|
||||||
if (!DGifGetImageDesc(gif)) goto End;
|
if (!DGifGetImageDesc(gif)) goto End;
|
||||||
|
|
||||||
if (frame_number == 0) {
|
if (is_first_frame) {
|
||||||
if (verbose) {
|
if (verbose) {
|
||||||
printf("Canvas screen: %d x %d\n", gif->SWidth, gif->SHeight);
|
printf("Canvas screen: %d x %d\n", gif->SWidth, gif->SHeight);
|
||||||
}
|
}
|
||||||
@@ -314,11 +302,8 @@ int main(int argc, const char* argv[]) {
|
|||||||
frame.use_argb = 1;
|
frame.use_argb = 1;
|
||||||
if (!WebPPictureAlloc(&frame)) goto End;
|
if (!WebPPictureAlloc(&frame)) goto End;
|
||||||
GIFClearPic(&frame, NULL);
|
GIFClearPic(&frame, NULL);
|
||||||
if (!(WebPPictureCopy(&frame, &curr_canvas) &&
|
WebPPictureCopy(&frame, &curr_canvas);
|
||||||
WebPPictureCopy(&frame, &prev_canvas))) {
|
WebPPictureCopy(&frame, &prev_canvas);
|
||||||
fprintf(stderr, "Error allocating canvas.\n");
|
|
||||||
goto End;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Background color.
|
// Background color.
|
||||||
GIFGetBackgroundColor(gif->SColorMap, gif->SBackGroundColor,
|
GIFGetBackgroundColor(gif->SColorMap, gif->SBackGroundColor,
|
||||||
@@ -334,6 +319,7 @@ int main(int argc, const char* argv[]) {
|
|||||||
"a memory error.\n");
|
"a memory error.\n");
|
||||||
goto End;
|
goto End;
|
||||||
}
|
}
|
||||||
|
is_first_frame = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Some even more broken GIF can have sub-rect with zero width/height.
|
// Some even more broken GIF can have sub-rect with zero width/height.
|
||||||
@@ -350,25 +336,13 @@ int main(int argc, const char* argv[]) {
|
|||||||
GIFBlendFrames(&frame, &gif_rect, &curr_canvas);
|
GIFBlendFrames(&frame, &gif_rect, &curr_canvas);
|
||||||
|
|
||||||
if (!WebPAnimEncoderAdd(enc, &curr_canvas, frame_timestamp, &config)) {
|
if (!WebPAnimEncoderAdd(enc, &curr_canvas, frame_timestamp, &config)) {
|
||||||
fprintf(stderr, "Error while adding frame #%d: %s\n", frame_number,
|
fprintf(stderr, "%s\n", WebPAnimEncoderGetError(enc));
|
||||||
WebPAnimEncoderGetError(enc));
|
|
||||||
goto End;
|
|
||||||
} else {
|
|
||||||
++frame_number;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update canvases.
|
// Update canvases.
|
||||||
GIFDisposeFrame(orig_dispose, &gif_rect, &prev_canvas, &curr_canvas);
|
GIFDisposeFrame(orig_dispose, &gif_rect, &prev_canvas, &curr_canvas);
|
||||||
GIFCopyPixels(&curr_canvas, &prev_canvas);
|
GIFCopyPixels(&curr_canvas, &prev_canvas);
|
||||||
|
|
||||||
// Force frames with a small or no duration to 100ms to be consistent
|
|
||||||
// with web browsers and other transcoding tools. This also avoids
|
|
||||||
// incorrect durations between frames when padding frames are
|
|
||||||
// discarded.
|
|
||||||
if (frame_duration <= 10) {
|
|
||||||
frame_duration = 100;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update timestamp (for next frame).
|
// Update timestamp (for next frame).
|
||||||
frame_timestamp += frame_duration;
|
frame_timestamp += frame_duration;
|
||||||
|
|
||||||
@@ -382,7 +356,7 @@ int main(int argc, const char* argv[]) {
|
|||||||
}
|
}
|
||||||
case EXTENSION_RECORD_TYPE: {
|
case EXTENSION_RECORD_TYPE: {
|
||||||
int extension;
|
int extension;
|
||||||
GifByteType* data = NULL;
|
GifByteType *data = NULL;
|
||||||
if (DGifGetExtension(gif, &extension, &data) == GIF_ERROR) {
|
if (DGifGetExtension(gif, &extension, &data) == GIF_ERROR) {
|
||||||
goto End;
|
goto End;
|
||||||
}
|
}
|
||||||
@@ -412,7 +386,7 @@ int main(int argc, const char* argv[]) {
|
|||||||
if (verbose) {
|
if (verbose) {
|
||||||
fprintf(stderr, "Loop count: %d\n", loop_count);
|
fprintf(stderr, "Loop count: %d\n", loop_count);
|
||||||
}
|
}
|
||||||
stored_loop_count = loop_compatibility ? (loop_count != 0) : 1;
|
stored_loop_count = (loop_count != 0);
|
||||||
} else { // An extension containing metadata.
|
} else { // An extension containing metadata.
|
||||||
// We only store the first encountered chunk of each type, and
|
// We only store the first encountered chunk of each type, and
|
||||||
// only if requested by the user.
|
// only if requested by the user.
|
||||||
@@ -468,25 +442,6 @@ int main(int argc, const char* argv[]) {
|
|||||||
fprintf(stderr, "%s\n", WebPAnimEncoderGetError(enc));
|
fprintf(stderr, "%s\n", WebPAnimEncoderGetError(enc));
|
||||||
goto End;
|
goto End;
|
||||||
}
|
}
|
||||||
// If there's only one frame, we don't need to handle loop count.
|
|
||||||
if (frame_number == 1) {
|
|
||||||
loop_count = 0;
|
|
||||||
} else 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) {
|
if (stored_loop_count || stored_icc || stored_xmp) {
|
||||||
// Re-mux to add loop count and/or metadata as needed.
|
// Re-mux to add loop count and/or metadata as needed.
|
||||||
@@ -547,19 +502,13 @@ int main(int argc, const char* argv[]) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (out_file != NULL) {
|
if (out_file != NULL) {
|
||||||
if (!ImgIoUtilWriteFile((const char*)out_file, webp_data.bytes,
|
if (!ImgIoUtilWriteFile(out_file, webp_data.bytes, webp_data.size)) {
|
||||||
webp_data.size)) {
|
fprintf(stderr, "Error writing output file: %s\n", out_file);
|
||||||
WFPRINTF(stderr, "Error writing output file: %s\n", out_file);
|
|
||||||
goto End;
|
goto End;
|
||||||
}
|
}
|
||||||
if (!quiet) {
|
if (!quiet) {
|
||||||
if (!WSTRCMP(out_file, "-")) {
|
fprintf(stderr, "Saved output file (%d bytes): %s\n",
|
||||||
fprintf(stderr, "Saved %d bytes to STDIO\n",
|
(int)webp_data.size, out_file);
|
||||||
(int)webp_data.size);
|
|
||||||
} else {
|
|
||||||
WFPRINTF(stderr, "Saved output file (%d bytes): %s\n",
|
|
||||||
(int)webp_data.size, out_file);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!quiet) {
|
if (!quiet) {
|
||||||
@@ -581,6 +530,7 @@ int main(int argc, const char* argv[]) {
|
|||||||
WebPPictureFree(&curr_canvas);
|
WebPPictureFree(&curr_canvas);
|
||||||
WebPPictureFree(&prev_canvas);
|
WebPPictureFree(&prev_canvas);
|
||||||
WebPAnimEncoderDelete(enc);
|
WebPAnimEncoderDelete(enc);
|
||||||
|
if (out != NULL && out_file != NULL) fclose(out);
|
||||||
|
|
||||||
if (gif_error != GIF_OK) {
|
if (gif_error != GIF_OK) {
|
||||||
GIFDisplayError(gif, gif_error);
|
GIFDisplayError(gif, gif_error);
|
||||||
@@ -593,12 +543,12 @@ int main(int argc, const char* argv[]) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
FREE_WARGV_AND_RETURN(!ok);
|
return !ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
#else // !WEBP_HAVE_GIF
|
#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]);
|
fprintf(stderr, "GIF support not enabled in %s.\n", argv[0]);
|
||||||
(void)argc;
|
(void)argc;
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -28,17 +28,11 @@
|
|||||||
#define GIF_DISPOSE_SHIFT 2
|
#define GIF_DISPOSE_SHIFT 2
|
||||||
|
|
||||||
// from utils/utils.h
|
// from utils/utils.h
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
extern void WebPCopyPlane(const uint8_t* src, int src_stride,
|
extern void WebPCopyPlane(const uint8_t* src, int src_stride,
|
||||||
uint8_t* dst, int dst_stride,
|
uint8_t* dst, int dst_stride,
|
||||||
int width, int height);
|
int width, int height);
|
||||||
extern void WebPCopyPixels(const WebPPicture* const src,
|
extern void WebPCopyPixels(const WebPPicture* const src,
|
||||||
WebPPicture* const dst);
|
WebPPicture* const dst);
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void GIFGetBackgroundColor(const ColorMapObject* const color_map,
|
void GIFGetBackgroundColor(const ColorMapObject* const color_map,
|
||||||
int bgcolor_index, int transparent_index,
|
int bgcolor_index, int transparent_index,
|
||||||
@@ -137,7 +131,7 @@ int GIFReadFrame(GifFileType* const gif, int transparent_index,
|
|||||||
}
|
}
|
||||||
dst = sub_image.argb;
|
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 (tmp == NULL) goto End;
|
||||||
|
|
||||||
if (image_desc->Interlace) { // Interlaced image.
|
if (image_desc->Interlace) { // Interlaced image.
|
||||||
@@ -168,7 +162,7 @@ int GIFReadFrame(GifFileType* const gif, int transparent_index,
|
|||||||
End:
|
End:
|
||||||
if (!ok) picture->error_code = sub_image.error_code;
|
if (!ok) picture->error_code = sub_image.error_code;
|
||||||
WebPPictureFree(&sub_image);
|
WebPPictureFree(&sub_image);
|
||||||
WebPFree(tmp);
|
free(tmp);
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -27,7 +27,6 @@
|
|||||||
#include "../imageio/image_dec.h"
|
#include "../imageio/image_dec.h"
|
||||||
#include "../imageio/imageio_util.h"
|
#include "../imageio/imageio_util.h"
|
||||||
#include "./stopwatch.h"
|
#include "./stopwatch.h"
|
||||||
#include "./unicode.h"
|
|
||||||
#include "webp/encode.h"
|
#include "webp/encode.h"
|
||||||
#include "webp/mux.h"
|
#include "webp/mux.h"
|
||||||
|
|
||||||
@@ -35,7 +34,8 @@
|
|||||||
|
|
||||||
static void Help(void) {
|
static void Help(void) {
|
||||||
printf("Usage:\n\n");
|
printf("Usage:\n\n");
|
||||||
printf(" img2webp [file_options] [[frame_options] frame_file]...\n");
|
printf(" img2webp [file-level options] [image files...] "
|
||||||
|
"[per-frame options...]\n");
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
|
||||||
printf("File-level options (only used at the start of compression):\n");
|
printf("File-level options (only used at the start of compression):\n");
|
||||||
@@ -48,7 +48,6 @@ static void Help(void) {
|
|||||||
printf(" -mixed ............... use mixed lossy/lossless automatic mode\n");
|
printf(" -mixed ............... use mixed lossy/lossless automatic mode\n");
|
||||||
printf(" -v ................... verbose mode\n");
|
printf(" -v ................... verbose mode\n");
|
||||||
printf(" -h ................... this help\n");
|
printf(" -h ................... this help\n");
|
||||||
printf(" -version ............. print version number and exit\n");
|
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
|
||||||
printf("Per-frame options (only used for subsequent images input):\n");
|
printf("Per-frame options (only used for subsequent images input):\n");
|
||||||
@@ -61,12 +60,6 @@ static void Help(void) {
|
|||||||
printf("\n");
|
printf("\n");
|
||||||
printf("example: img2webp -loop 2 in0.png -lossy in1.jpg\n"
|
printf("example: img2webp -loop 2 in0.png -lossy in1.jpg\n"
|
||||||
" -d 80 in2.tiff -o out.webp\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");
|
|
||||||
printf("\nSupported input formats:\n %s\n",
|
|
||||||
WebPGetEnabledInputFileFormats());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
@@ -85,7 +78,7 @@ static int ReadImage(const char filename[], WebPPicture* const pic) {
|
|||||||
if (!ImgIoUtilReadFile(filename, &data, &data_size)) return 0;
|
if (!ImgIoUtilReadFile(filename, &data, &data_size)) return 0;
|
||||||
reader = WebPGuessImageReader(data, data_size);
|
reader = WebPGuessImageReader(data, data_size);
|
||||||
ok = reader(data, data_size, pic, 1, NULL);
|
ok = reader(data, data_size, pic, 1, NULL);
|
||||||
WebPFree((void*)data);
|
free((void*)data);
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -124,13 +117,14 @@ static int SetLoopCount(int loop_count, WebPData* const webp_data) {
|
|||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
int main(int argc, const char* argv[]) {
|
int main(int argc, char* argv[]) {
|
||||||
const char* output = NULL;
|
const char* output = NULL;
|
||||||
WebPAnimEncoder* enc = NULL;
|
WebPAnimEncoder* enc = NULL;
|
||||||
int verbose = 0;
|
int verbose = 0;
|
||||||
int pic_num = 0;
|
int pic_num = 0;
|
||||||
int duration = 100;
|
int duration = 100;
|
||||||
int timestamp_ms = 0;
|
int timestamp_ms = 0;
|
||||||
|
int ok = 1;
|
||||||
int loop_count = 0;
|
int loop_count = 0;
|
||||||
int width = 0, height = 0;
|
int width = 0, height = 0;
|
||||||
WebPAnimEncoderOptions anim_config;
|
WebPAnimEncoderOptions anim_config;
|
||||||
@@ -139,33 +133,22 @@ int main(int argc, const char* argv[]) {
|
|||||||
WebPData webp_data;
|
WebPData webp_data;
|
||||||
int c;
|
int c;
|
||||||
int have_input = 0;
|
int have_input = 0;
|
||||||
CommandLineArguments cmd_args;
|
|
||||||
int ok;
|
|
||||||
|
|
||||||
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);
|
WebPDataInit(&webp_data);
|
||||||
if (!WebPAnimEncoderOptionsInit(&anim_config) ||
|
if (!WebPAnimEncoderOptionsInit(&anim_config) ||
|
||||||
!WebPConfigInit(&config) ||
|
!WebPConfigInit(&config) ||
|
||||||
!WebPPictureInit(&pic)) {
|
!WebPPictureInit(&pic)) {
|
||||||
fprintf(stderr, "Library version mismatch!\n");
|
fprintf(stderr, "Library version mismatch!\n");
|
||||||
ok = 0;
|
return 1;
|
||||||
goto End;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 1st pass of option parsing
|
// 1st pass of option parsing
|
||||||
for (c = 0; ok && c < argc; ++c) {
|
for (c = 1; ok && c < argc; ++c) {
|
||||||
if (argv[c][0] == '-') {
|
if (argv[c][0] == '-') {
|
||||||
int parse_error = 0;
|
int parse_error = 0;
|
||||||
if (!strcmp(argv[c], "-o") && c + 1 < argc) {
|
if (!strcmp(argv[c], "-o") && c + 1 < argc) {
|
||||||
argv[c] = NULL;
|
argv[c] = NULL;
|
||||||
output = (const char*)GET_WARGV_SHIFTED(argv, ++c);
|
output = argv[++c];
|
||||||
} else if (!strcmp(argv[c], "-kmin") && c + 1 < argc) {
|
} else if (!strcmp(argv[c], "-kmin") && c + 1 < argc) {
|
||||||
argv[c] = NULL;
|
argv[c] = NULL;
|
||||||
anim_config.kmin = ExUtilGetInt(argv[++c], 0, &parse_error);
|
anim_config.kmin = ExUtilGetInt(argv[++c], 0, &parse_error);
|
||||||
@@ -188,15 +171,7 @@ int main(int argc, const char* argv[]) {
|
|||||||
verbose = 1;
|
verbose = 1;
|
||||||
} else if (!strcmp(argv[c], "-h") || !strcmp(argv[c], "-help")) {
|
} else if (!strcmp(argv[c], "-h") || !strcmp(argv[c], "-help")) {
|
||||||
Help();
|
Help();
|
||||||
FREE_WARGV_AND_RETURN(0);
|
return 0;
|
||||||
} else if (!strcmp(argv[c], "-version")) {
|
|
||||||
const int enc_version = WebPGetEncoderVersion();
|
|
||||||
const int mux_version = WebPGetMuxVersion();
|
|
||||||
printf("WebP Encoder version: %d.%d.%d\nWebP Mux version: %d.%d.%d\n",
|
|
||||||
(enc_version >> 16) & 0xff, (enc_version >> 8) & 0xff,
|
|
||||||
enc_version & 0xff, (mux_version >> 16) & 0xff,
|
|
||||||
(mux_version >> 8) & 0xff, mux_version & 0xff);
|
|
||||||
goto End;
|
|
||||||
} else {
|
} else {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -209,13 +184,13 @@ int main(int argc, const char* argv[]) {
|
|||||||
}
|
}
|
||||||
if (!have_input) {
|
if (!have_input) {
|
||||||
fprintf(stderr, "No input file(s) for generating animation!\n");
|
fprintf(stderr, "No input file(s) for generating animation!\n");
|
||||||
goto End;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// image-reading pass
|
// image-reading pass
|
||||||
pic_num = 0;
|
pic_num = 0;
|
||||||
config.lossless = 1;
|
config.lossless = 1;
|
||||||
for (c = 0; ok && c < argc; ++c) {
|
for (c = 1; ok && c < argc; ++c) {
|
||||||
if (argv[c] == NULL) continue;
|
if (argv[c] == NULL) continue;
|
||||||
if (argv[c][0] == '-') { // parse local options
|
if (argv[c][0] == '-') { // parse local options
|
||||||
int parse_error = 0;
|
int parse_error = 0;
|
||||||
@@ -252,7 +227,7 @@ int main(int argc, const char* argv[]) {
|
|||||||
|
|
||||||
// read next input image
|
// read next input image
|
||||||
pic.use_argb = 1;
|
pic.use_argb = 1;
|
||||||
ok = ReadImage((const char*)GET_WARGV_SHIFTED(argv, c), &pic);
|
ok = ReadImage(argv[c], &pic);
|
||||||
if (!ok) goto End;
|
if (!ok) goto End;
|
||||||
|
|
||||||
if (enc == NULL) {
|
if (enc == NULL) {
|
||||||
@@ -284,8 +259,8 @@ int main(int argc, const char* argv[]) {
|
|||||||
if (!ok) goto End;
|
if (!ok) goto End;
|
||||||
|
|
||||||
if (verbose) {
|
if (verbose) {
|
||||||
WFPRINTF(stderr, "Added frame #%3d at time %4d (file: %s)\n",
|
fprintf(stderr, "Added frame #%3d at time %4d (file: %s)\n",
|
||||||
pic_num, timestamp_ms, GET_WARGV_SHIFTED(argv, c));
|
pic_num, timestamp_ms, argv[c]);
|
||||||
}
|
}
|
||||||
timestamp_ms += duration;
|
timestamp_ms += duration;
|
||||||
++pic_num;
|
++pic_num;
|
||||||
@@ -309,7 +284,7 @@ int main(int argc, const char* argv[]) {
|
|||||||
if (ok) {
|
if (ok) {
|
||||||
if (output != NULL) {
|
if (output != NULL) {
|
||||||
ok = ImgIoUtilWriteFile(output, webp_data.bytes, webp_data.size);
|
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 {
|
} else {
|
||||||
fprintf(stderr, "[no output file specified] ");
|
fprintf(stderr, "[no output file specified] ");
|
||||||
}
|
}
|
||||||
@@ -319,7 +294,7 @@ int main(int argc, const char* argv[]) {
|
|||||||
fprintf(stderr, "[%d frames, %u bytes].\n",
|
fprintf(stderr, "[%d frames, %u bytes].\n",
|
||||||
pic_num, (unsigned int)webp_data.size);
|
pic_num, (unsigned int)webp_data.size);
|
||||||
}
|
}
|
||||||
|
|
||||||
WebPDataClear(&webp_data);
|
WebPDataClear(&webp_data);
|
||||||
ExUtilDeleteCommandLineArguments(&cmd_args);
|
return ok ? 0 : 1;
|
||||||
FREE_WARGV_AND_RETURN(ok ? 0 : 1);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,4 +60,4 @@ static WEBP_INLINE double StopwatchReadAndReset(Stopwatch* watch) {
|
|||||||
|
|
||||||
#endif /* _WIN32 */
|
#endif /* _WIN32 */
|
||||||
|
|
||||||
#endif // WEBP_EXAMPLES_STOPWATCH_H_
|
#endif /* WEBP_EXAMPLES_STOPWATCH_H_ */
|
||||||
|
|||||||
@@ -1,116 +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_
|
|
||||||
|
|
||||||
#include <stdio.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 <fcntl.h>
|
|
||||||
#include <io.h>
|
|
||||||
#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 WFPRINTF(STREAM, STR, ...) \
|
|
||||||
do { \
|
|
||||||
int prev_mode; \
|
|
||||||
fflush(STREAM); \
|
|
||||||
prev_mode = _setmode(_fileno(STREAM), _O_U8TEXT); \
|
|
||||||
fwprintf(STREAM, TO_W_CHAR(STR), __VA_ARGS__); \
|
|
||||||
fflush(STREAM); \
|
|
||||||
(void)_setmode(_fileno(STREAM), prev_mode); \
|
|
||||||
} while (0)
|
|
||||||
#define WPRINTF(STR, ...) WFPRINTF(stdout, 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
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
// 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(STREAM, STR, ...) fprintf(STREAM, 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,76 +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_
|
|
||||||
218
examples/vwebp.c
218
examples/vwebp.c
@@ -42,7 +42,6 @@
|
|||||||
|
|
||||||
#include "../examples/example_util.h"
|
#include "../examples/example_util.h"
|
||||||
#include "../imageio/imageio_util.h"
|
#include "../imageio/imageio_util.h"
|
||||||
#include "./unicode.h"
|
|
||||||
|
|
||||||
#if defined(_MSC_VER) && _MSC_VER < 1900
|
#if defined(_MSC_VER) && _MSC_VER < 1900
|
||||||
#define snprintf _snprintf
|
#define snprintf _snprintf
|
||||||
@@ -57,7 +56,6 @@ static struct {
|
|||||||
int print_info;
|
int print_info;
|
||||||
int only_deltas;
|
int only_deltas;
|
||||||
int use_color_profile;
|
int use_color_profile;
|
||||||
int draw_anim_background_color;
|
|
||||||
|
|
||||||
int canvas_width, canvas_height;
|
int canvas_width, canvas_height;
|
||||||
int loop_count;
|
int loop_count;
|
||||||
@@ -207,11 +205,6 @@ static void decode_callback(int what) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
duration = curr->duration;
|
duration = curr->duration;
|
||||||
// Behavior copied from Chrome, cf:
|
|
||||||
// https://cs.chromium.org/chromium/src/third_party/WebKit/Source/
|
|
||||||
// platform/graphics/DeferredImageDecoder.cpp?
|
|
||||||
// rcl=b4c33049f096cd283f32be9a58b9a9e768227c26&l=246
|
|
||||||
if (duration <= 10) duration = 100;
|
|
||||||
}
|
}
|
||||||
if (!Decode()) {
|
if (!Decode()) {
|
||||||
kParams.decoding_error = 1;
|
kParams.decoding_error = 1;
|
||||||
@@ -227,9 +220,6 @@ static void decode_callback(int what) {
|
|||||||
// Callbacks
|
// Callbacks
|
||||||
|
|
||||||
static void HandleKey(unsigned char key, int pos_x, int pos_y) {
|
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_x;
|
||||||
(void)pos_y;
|
(void)pos_y;
|
||||||
if (key == 'q' || key == 'Q' || key == 27 /* Esc */) {
|
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();
|
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') {
|
} else if (key == 'i') {
|
||||||
kParams.print_info = 1 - kParams.print_info;
|
kParams.print_info = 1 - kParams.print_info;
|
||||||
|
// TODO(skal): handle refresh of animation's last-frame too. It's quite
|
||||||
|
// more involved though (need to save the previous frame).
|
||||||
if (!kParams.has_animation) ClearPreviousFrame();
|
if (!kParams.has_animation) ClearPreviousFrame();
|
||||||
glutPostRedisplay();
|
glutPostRedisplay();
|
||||||
} else if (key == 'd') {
|
} else if (key == 'd') {
|
||||||
@@ -272,8 +260,8 @@ static void HandleKey(unsigned char key, int pos_x, int pos_y) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void HandleReshape(int width, int height) {
|
static void HandleReshape(int width, int height) {
|
||||||
// Note: reshape doesn't preserve aspect ratio, and might
|
// TODO(skal): should we preserve aspect ratio?
|
||||||
// be handling larger-than-screen pictures incorrectly.
|
// Also: handle larger-than-screen pictures correctly.
|
||||||
glViewport(0, 0, width, height);
|
glViewport(0, 0, width, height);
|
||||||
glMatrixMode(GL_PROJECTION);
|
glMatrixMode(GL_PROJECTION);
|
||||||
glLoadIdentity();
|
glLoadIdentity();
|
||||||
@@ -292,21 +280,8 @@ static void PrintString(const char* const text) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void PrintStringW(const char* const text) {
|
|
||||||
#if defined(_WIN32) && defined(_UNICODE)
|
|
||||||
void* const font = GLUT_BITMAP_9_BY_15;
|
|
||||||
const W_CHAR* const wtext = (const W_CHAR*)text;
|
|
||||||
int i;
|
|
||||||
for (i = 0; wtext[i]; ++i) {
|
|
||||||
glutBitmapCharacter(font, wtext[i]);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
PrintString(text);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static float GetColorf(uint32_t color, int shift) {
|
static float GetColorf(uint32_t color, int shift) {
|
||||||
return ((color >> shift) & 0xff) / 255.f;
|
return (color >> shift) / 255.f;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void DrawCheckerBoard(void) {
|
static void DrawCheckerBoard(void) {
|
||||||
@@ -329,43 +304,6 @@ static void DrawCheckerBoard(void) {
|
|||||||
glPopMatrix();
|
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) {
|
static void HandleDisplay(void) {
|
||||||
const WebPDecBuffer* const pic = kParams.pic;
|
const WebPDecBuffer* const pic = kParams.pic;
|
||||||
const WebPIterator* const curr = &kParams.curr_frame;
|
const WebPIterator* const curr = &kParams.curr_frame;
|
||||||
@@ -382,21 +320,38 @@ static void HandleDisplay(void) {
|
|||||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, pic->u.RGBA.stride / 4);
|
glPixelStorei(GL_UNPACK_ROW_LENGTH, pic->u.RGBA.stride / 4);
|
||||||
|
|
||||||
if (kParams.only_deltas) {
|
if (kParams.only_deltas) {
|
||||||
DrawBackground();
|
DrawCheckerBoard();
|
||||||
} else {
|
} else if (prev->dispose_method == WEBP_MUX_DISPOSE_BACKGROUND ||
|
||||||
// The rectangle of the previous frame might be different than the current
|
curr->blend_method == WEBP_MUX_NO_BLEND) {
|
||||||
// frame, so we may need to DrawBackgroundScissored for both.
|
// 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) {
|
if (prev->dispose_method == WEBP_MUX_DISPOSE_BACKGROUND) {
|
||||||
// Clear the previous frame rectangle.
|
// Clear the previous frame rectangle.
|
||||||
DrawBackgroundScissored(prev->x_offset, prev->y_offset, prev->width,
|
window_x = prev->x_offset;
|
||||||
prev->height);
|
window_y = kParams.canvas_height - prev->y_offset - prev->height;
|
||||||
}
|
frame_w = prev->width;
|
||||||
if (curr->blend_method == WEBP_MUX_NO_BLEND) {
|
frame_h = prev->height;
|
||||||
|
} else { // curr->blend_method == WEBP_MUX_NO_BLEND.
|
||||||
// We simulate no-blending behavior by first clearing the current frame
|
// We simulate no-blending behavior by first clearing the current frame
|
||||||
// rectangle and then alpha-blending against it.
|
// rectangle (to a checker-board) and then alpha-blending against it.
|
||||||
DrawBackgroundScissored(curr->x_offset, curr->y_offset, curr->width,
|
window_x = curr->x_offset;
|
||||||
curr->height);
|
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;
|
*prev = *curr;
|
||||||
@@ -409,7 +364,7 @@ static void HandleDisplay(void) {
|
|||||||
|
|
||||||
glColor4f(0.90f, 0.0f, 0.90f, 1.0f);
|
glColor4f(0.90f, 0.0f, 0.90f, 1.0f);
|
||||||
glRasterPos2f(-0.95f, 0.90f);
|
glRasterPos2f(-0.95f, 0.90f);
|
||||||
PrintStringW(kParams.file_name);
|
PrintString(kParams.file_name);
|
||||||
|
|
||||||
snprintf(tmp, sizeof(tmp), "Dimension:%d x %d", pic->width, pic->height);
|
snprintf(tmp, sizeof(tmp), "Dimension:%d x %d", pic->width, pic->height);
|
||||||
glColor4f(0.90f, 0.0f, 0.90f, 1.0f);
|
glColor4f(0.90f, 0.0f, 0.90f, 1.0f);
|
||||||
@@ -423,36 +378,13 @@ static void HandleDisplay(void) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
glPopMatrix();
|
glPopMatrix();
|
||||||
#if defined(__APPLE__) || defined(_WIN32)
|
|
||||||
glFlush();
|
glFlush();
|
||||||
#else
|
|
||||||
glutSwapBuffers();
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void StartDisplay(void) {
|
static void StartDisplay(void) {
|
||||||
int width = kParams.canvas_width;
|
const int width = kParams.canvas_width;
|
||||||
int height = kParams.canvas_height;
|
const 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)
|
|
||||||
glutInitDisplayMode(GLUT_RGBA);
|
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);
|
glutInitWindowSize(width, height);
|
||||||
glutCreateWindow("WebP viewer");
|
glutCreateWindow("WebP viewer");
|
||||||
glutDisplayFunc(HandleDisplay);
|
glutDisplayFunc(HandleDisplay);
|
||||||
@@ -461,59 +393,57 @@ static void StartDisplay(void) {
|
|||||||
glutKeyboardFunc(HandleKey);
|
glutKeyboardFunc(HandleKey);
|
||||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
glEnable(GL_BLEND);
|
glEnable(GL_BLEND);
|
||||||
glClearColor(0, 0, 0, 0); // window will be cleared to black (no blend)
|
glClearColor(GetColorf(kParams.bg_color, 0),
|
||||||
DrawBackground();
|
GetColorf(kParams.bg_color, 8),
|
||||||
|
GetColorf(kParams.bg_color, 16),
|
||||||
|
GetColorf(kParams.bg_color, 24));
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
DrawCheckerBoard();
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Main
|
// Main
|
||||||
|
|
||||||
static void Help(void) {
|
static void Help(void) {
|
||||||
printf(
|
printf("Usage: vwebp in_file [options]\n\n"
|
||||||
"Usage: vwebp in_file [options]\n\n"
|
"Decodes the WebP image file and visualize it using OpenGL\n"
|
||||||
"Decodes the WebP image file and visualize it using OpenGL\n"
|
"Options are:\n"
|
||||||
"Options are:\n"
|
" -version ..... print version number and exit\n"
|
||||||
" -version ..... print version number and exit\n"
|
" -noicc ....... don't use the icc profile if present\n"
|
||||||
" -noicc ....... don't use the icc profile if present\n"
|
" -nofancy ..... don't use the fancy YUV420 upscaler\n"
|
||||||
" -nofancy ..... don't use the fancy YUV420 upscaler\n"
|
" -nofilter .... disable in-loop filtering\n"
|
||||||
" -nofilter .... disable in-loop filtering\n"
|
" -dither <int> dithering strength (0..100), default=50\n"
|
||||||
" -dither <int> dithering strength (0..100), default=50\n"
|
" -noalphadither disable alpha plane dithering\n"
|
||||||
" -noalphadither disable alpha plane dithering\n"
|
" -mt .......... use multi-threading\n"
|
||||||
" -usebgcolor .. display background color\n"
|
" -info ........ print info\n"
|
||||||
" -mt .......... use multi-threading\n"
|
" -h ........... this help message\n"
|
||||||
" -info ........ print info\n"
|
"\n"
|
||||||
" -h ........... this help message\n"
|
"Keyboard shortcuts:\n"
|
||||||
"\n"
|
" 'c' ................ toggle use of color profile\n"
|
||||||
"Keyboard shortcuts:\n"
|
" 'i' ................ overlay file information\n"
|
||||||
" 'c' ................ toggle use of color profile\n"
|
" 'd' ................ disable blending & disposal (debug)\n"
|
||||||
" 'b' ................ toggle background color display\n"
|
" 'q' / 'Q' / ESC .... quit\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;
|
int c;
|
||||||
WebPDecoderConfig* const config = &kParams.config;
|
WebPDecoderConfig* const config = &kParams.config;
|
||||||
WebPIterator* const curr = &kParams.curr_frame;
|
WebPIterator* const curr = &kParams.curr_frame;
|
||||||
|
|
||||||
INIT_WARGV(argc, argv);
|
|
||||||
|
|
||||||
if (!WebPInitDecoderConfig(config)) {
|
if (!WebPInitDecoderConfig(config)) {
|
||||||
fprintf(stderr, "Library version mismatch!\n");
|
fprintf(stderr, "Library version mismatch!\n");
|
||||||
FREE_WARGV_AND_RETURN(-1);
|
return -1;
|
||||||
}
|
}
|
||||||
config->options.dithering_strength = 50;
|
config->options.dithering_strength = 50;
|
||||||
config->options.alpha_dithering_strength = 100;
|
config->options.alpha_dithering_strength = 100;
|
||||||
kParams.use_color_profile = 1;
|
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) {
|
for (c = 1; c < argc; ++c) {
|
||||||
int parse_error = 0;
|
int parse_error = 0;
|
||||||
if (!strcmp(argv[c], "-h") || !strcmp(argv[c], "-help")) {
|
if (!strcmp(argv[c], "-h") || !strcmp(argv[c], "-help")) {
|
||||||
Help();
|
Help();
|
||||||
FREE_WARGV_AND_RETURN(0);
|
return 0;
|
||||||
} else if (!strcmp(argv[c], "-noicc")) {
|
} else if (!strcmp(argv[c], "-noicc")) {
|
||||||
kParams.use_color_profile = 0;
|
kParams.use_color_profile = 0;
|
||||||
} else if (!strcmp(argv[c], "-nofancy")) {
|
} else if (!strcmp(argv[c], "-nofancy")) {
|
||||||
@@ -522,8 +452,6 @@ int main(int argc, char* argv[]) {
|
|||||||
config->options.bypass_filtering = 1;
|
config->options.bypass_filtering = 1;
|
||||||
} else if (!strcmp(argv[c], "-noalphadither")) {
|
} else if (!strcmp(argv[c], "-noalphadither")) {
|
||||||
config->options.alpha_dithering_strength = 0;
|
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) {
|
} else if (!strcmp(argv[c], "-dither") && c + 1 < argc) {
|
||||||
config->options.dithering_strength =
|
config->options.dithering_strength =
|
||||||
ExUtilGetInt(argv[++c], 0, &parse_error);
|
ExUtilGetInt(argv[++c], 0, &parse_error);
|
||||||
@@ -536,30 +464,30 @@ int main(int argc, char* argv[]) {
|
|||||||
(dec_version >> 16) & 0xff, (dec_version >> 8) & 0xff,
|
(dec_version >> 16) & 0xff, (dec_version >> 8) & 0xff,
|
||||||
dec_version & 0xff, (dmux_version >> 16) & 0xff,
|
dec_version & 0xff, (dmux_version >> 16) & 0xff,
|
||||||
(dmux_version >> 8) & 0xff, dmux_version & 0xff);
|
(dmux_version >> 8) & 0xff, dmux_version & 0xff);
|
||||||
FREE_WARGV_AND_RETURN(0);
|
return 0;
|
||||||
} else if (!strcmp(argv[c], "-mt")) {
|
} else if (!strcmp(argv[c], "-mt")) {
|
||||||
config->options.use_threads = 1;
|
config->options.use_threads = 1;
|
||||||
} else if (!strcmp(argv[c], "--")) {
|
} 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;
|
break;
|
||||||
} else if (argv[c][0] == '-') {
|
} else if (argv[c][0] == '-') {
|
||||||
printf("Unknown option '%s'\n", argv[c]);
|
printf("Unknown option '%s'\n", argv[c]);
|
||||||
Help();
|
Help();
|
||||||
FREE_WARGV_AND_RETURN(-1);
|
return -1;
|
||||||
} else {
|
} else {
|
||||||
kParams.file_name = (const char*)GET_WARGV(argv, c);
|
kParams.file_name = argv[c];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parse_error) {
|
if (parse_error) {
|
||||||
Help();
|
Help();
|
||||||
FREE_WARGV_AND_RETURN(-1);
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (kParams.file_name == NULL) {
|
if (kParams.file_name == NULL) {
|
||||||
printf("missing input file!!\n");
|
printf("missing input file!!\n");
|
||||||
Help();
|
Help();
|
||||||
FREE_WARGV_AND_RETURN(0);
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ImgIoUtilReadFile(kParams.file_name,
|
if (!ImgIoUtilReadFile(kParams.file_name,
|
||||||
@@ -634,16 +562,16 @@ int main(int argc, char* argv[]) {
|
|||||||
|
|
||||||
// Should only be reached when using FREEGLUT:
|
// Should only be reached when using FREEGLUT:
|
||||||
ClearParams();
|
ClearParams();
|
||||||
FREE_WARGV_AND_RETURN(0);
|
return 0;
|
||||||
|
|
||||||
Error:
|
Error:
|
||||||
ClearParams();
|
ClearParams();
|
||||||
FREE_WARGV_AND_RETURN(-1);
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#else // !WEBP_HAVE_GL
|
#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]);
|
fprintf(stderr, "OpenGL support not enabled in %s.\n", argv[0]);
|
||||||
(void)argc;
|
(void)argc;
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
1186
examples/webpinfo.c
1186
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 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 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 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:
|
Extract relevant data from WebP container file:
|
||||||
webpmux -get frame n in.webp -o out_frame.webp
|
webpmux -get frame n in.webp -o out_frame.webp
|
||||||
@@ -48,7 +47,6 @@
|
|||||||
webpmux -info in.webp
|
webpmux -info in.webp
|
||||||
webpmux [ -h | -help ]
|
webpmux [ -h | -help ]
|
||||||
webpmux -version
|
webpmux -version
|
||||||
webpmux argument_file_name
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
@@ -63,7 +61,6 @@
|
|||||||
#include "webp/mux.h"
|
#include "webp/mux.h"
|
||||||
#include "../examples/example_util.h"
|
#include "../examples/example_util.h"
|
||||||
#include "../imageio/imageio_util.h"
|
#include "../imageio/imageio_util.h"
|
||||||
#include "./unicode.h"
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Config object to parse command-line arguments.
|
// Config object to parse command-line arguments.
|
||||||
@@ -98,8 +95,6 @@ typedef enum {
|
|||||||
FEATURE_ICCP,
|
FEATURE_ICCP,
|
||||||
FEATURE_ANMF,
|
FEATURE_ANMF,
|
||||||
FEATURE_DURATION,
|
FEATURE_DURATION,
|
||||||
FEATURE_LOOP,
|
|
||||||
FEATURE_BGCOLOR,
|
|
||||||
LAST_FEATURE
|
LAST_FEATURE
|
||||||
} FeatureType;
|
} FeatureType;
|
||||||
|
|
||||||
@@ -113,26 +108,28 @@ static const char* const kDescriptions[LAST_FEATURE] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
CommandLineArguments cmd_args_;
|
|
||||||
|
|
||||||
ActionType action_type_;
|
|
||||||
const char* input_;
|
|
||||||
const char* output_;
|
|
||||||
FeatureType type_;
|
FeatureType type_;
|
||||||
FeatureArg* args_;
|
FeatureArg* args_;
|
||||||
int arg_count_;
|
int arg_count_;
|
||||||
} Config;
|
} Feature;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
ActionType action_type_;
|
||||||
|
const char* input_;
|
||||||
|
const char* output_;
|
||||||
|
Feature feature_;
|
||||||
|
} WebPMuxConfig;
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Helper functions.
|
// Helper functions.
|
||||||
|
|
||||||
static int CountOccurrences(const CommandLineArguments* const args,
|
static int CountOccurrences(const char* arglist[], int list_length,
|
||||||
const char* const arg) {
|
const char* arg) {
|
||||||
int i;
|
int i;
|
||||||
int num_occurences = 0;
|
int num_occurences = 0;
|
||||||
|
|
||||||
for (i = 0; i < args->argc_; ++i) {
|
for (i = 0; i < list_length; ++i) {
|
||||||
if (!strcmp(args->argv_[i], arg)) {
|
if (!strcmp(arglist[i], arg)) {
|
||||||
++num_occurences;
|
++num_occurences;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -304,7 +301,6 @@ static void PrintHelp(void) {
|
|||||||
printf(" webpmux -info INPUT\n");
|
printf(" webpmux -info INPUT\n");
|
||||||
printf(" webpmux [-h|-help]\n");
|
printf(" webpmux [-h|-help]\n");
|
||||||
printf(" webpmux -version\n");
|
printf(" webpmux -version\n");
|
||||||
printf(" webpmux argument_file_name\n");
|
|
||||||
|
|
||||||
printf("\n");
|
printf("\n");
|
||||||
printf("GET_OPTIONS:\n");
|
printf("GET_OPTIONS:\n");
|
||||||
@@ -316,12 +312,10 @@ static void PrintHelp(void) {
|
|||||||
|
|
||||||
printf("\n");
|
printf("\n");
|
||||||
printf("SET_OPTIONS:\n");
|
printf("SET_OPTIONS:\n");
|
||||||
printf(" Set color profile/metadata/parameters:\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(" bgcolor BACKGROUND_COLOR set the animation background color\n");
|
printf(" exif file.exif set EXIF metadata\n");
|
||||||
printf(" icc file.icc set ICC profile\n");
|
printf(" xmp file.xmp set XMP metadata\n");
|
||||||
printf(" exif file.exif set EXIF metadata\n");
|
|
||||||
printf(" xmp file.xmp set XMP metadata\n");
|
|
||||||
printf(" where: 'file.icc' contains the ICC profile to be set,\n");
|
printf(" where: 'file.icc' contains the ICC profile to be set,\n");
|
||||||
printf(" 'file.exif' contains the EXIF metadata to be set\n");
|
printf(" 'file.exif' contains the EXIF metadata to be set\n");
|
||||||
printf(" 'file.xmp' contains the XMP metadata to be set\n");
|
printf(" 'file.xmp' contains the XMP metadata to be set\n");
|
||||||
@@ -329,7 +323,7 @@ static void PrintHelp(void) {
|
|||||||
printf("\n");
|
printf("\n");
|
||||||
printf("DURATION_OPTIONS:\n");
|
printf("DURATION_OPTIONS:\n");
|
||||||
printf(" Set duration of selected frames:\n");
|
printf(" Set duration of selected frames:\n");
|
||||||
printf(" duration set duration for all frames\n");
|
printf(" duration set duration for each frames\n");
|
||||||
printf(" duration,frame set duration of a particular frame\n");
|
printf(" duration,frame set duration of a particular frame\n");
|
||||||
printf(" duration,start,end set duration of frames in the\n");
|
printf(" duration,start,end set duration of frames in the\n");
|
||||||
printf(" interval [start,end])\n");
|
printf(" interval [start,end])\n");
|
||||||
@@ -348,7 +342,7 @@ static void PrintHelp(void) {
|
|||||||
printf("\n");
|
printf("\n");
|
||||||
printf("FRAME_OPTIONS(i):\n");
|
printf("FRAME_OPTIONS(i):\n");
|
||||||
printf(" Create animation:\n");
|
printf(" Create animation:\n");
|
||||||
printf(" file_i +di[+xi+yi[+mi[bi]]]\n");
|
printf(" file_i +di+[xi+yi[+mi[bi]]]\n");
|
||||||
printf(" where: 'file_i' is the i'th animation frame (WebP format),\n");
|
printf(" where: 'file_i' is the i'th animation frame (WebP format),\n");
|
||||||
printf(" 'di' is the pause duration before next frame,\n");
|
printf(" 'di' is the pause duration before next frame,\n");
|
||||||
printf(" 'xi','yi' specify the image offset for this frame,\n");
|
printf(" 'xi','yi' specify the image offset for this frame,\n");
|
||||||
@@ -375,10 +369,6 @@ static void PrintHelp(void) {
|
|||||||
|
|
||||||
printf("\nNote: The nature of EXIF, XMP and ICC data is not checked");
|
printf("\nNote: The nature of EXIF, XMP and ICC data is not checked");
|
||||||
printf(" and is assumed to be\nvalid.\n");
|
printf(" and is assumed to be\nvalid.\n");
|
||||||
printf("\nNote: if a single file name is passed as the argument, the "
|
|
||||||
"arguments will be\n");
|
|
||||||
printf("tokenized from this file. The file name must not start with "
|
|
||||||
"the character '-'.\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void WarnAboutOddOffset(const WebPMuxFrameInfo* const info) {
|
static void WarnAboutOddOffset(const WebPMuxFrameInfo* const info) {
|
||||||
@@ -389,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) {
|
static int CreateMux(const char* const filename, WebPMux** mux) {
|
||||||
WebPData bitstream;
|
WebPData bitstream;
|
||||||
assert(mux != NULL);
|
assert(mux != NULL);
|
||||||
if (!ExUtilReadFileToWebPData(filename, &bitstream)) return 0;
|
if (!ReadFileToWebPData(filename, &bitstream)) return 0;
|
||||||
*mux = WebPMuxCreate(&bitstream, 1);
|
*mux = WebPMuxCreate(&bitstream, 1);
|
||||||
WebPDataClear(&bitstream);
|
free((void*)bitstream.bytes);
|
||||||
if (*mux != NULL) return 1;
|
if (*mux != NULL) return 1;
|
||||||
WFPRINTF(stderr, "Failed to create mux object from file %s.\n",
|
fprintf(stderr, "Failed to create mux object from file %s.\n", filename);
|
||||||
(const W_CHAR*)filename);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int WriteData(const char* filename, const WebPData* const webpdata) {
|
static int WriteData(const char* filename, const WebPData* const webpdata) {
|
||||||
int ok = 0;
|
int ok = 0;
|
||||||
FILE* fout = WSTRCMP(filename, "-") ? WFOPEN(filename, "wb")
|
FILE* fout = strcmp(filename, "-") ? fopen(filename, "wb")
|
||||||
: ImgIoUtilSetBinaryMode(stdout);
|
: ImgIoUtilSetBinaryMode(stdout);
|
||||||
if (fout == NULL) {
|
if (fout == NULL) {
|
||||||
WFPRINTF(stderr, "Error opening output WebP file %s!\n",
|
fprintf(stderr, "Error opening output WebP file %s!\n", filename);
|
||||||
(const W_CHAR*)filename);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (fwrite(webpdata->bytes, webpdata->size, 1, fout) != 1) {
|
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 {
|
} else {
|
||||||
WFPRINTF(stderr, "Saved file %s (%d bytes)\n",
|
fprintf(stderr, "Saved file %s (%d bytes)\n",
|
||||||
(const W_CHAR*)filename, (int)webpdata->size);
|
filename, (int)webpdata->size);
|
||||||
ok = 1;
|
ok = 1;
|
||||||
}
|
}
|
||||||
if (fout != stdout) fclose(fout);
|
if (fout != stdout) fclose(fout);
|
||||||
@@ -460,8 +458,7 @@ static WebPMux* DuplicateMuxHeader(const WebPMux* const mux) {
|
|||||||
if (err == WEBP_MUX_OK && metadata.size > 0) {
|
if (err == WEBP_MUX_OK && metadata.size > 0) {
|
||||||
err = WebPMuxSetChunk(new_mux, kFourccList[i], &metadata, 1);
|
err = WebPMuxSetChunk(new_mux, kFourccList[i], &metadata, 1);
|
||||||
if (err != WEBP_MUX_OK) {
|
if (err != WEBP_MUX_OK) {
|
||||||
ERROR_GOTO1("Error transferring metadata in DuplicateMuxHeader().",
|
ERROR_GOTO1("Error transferring metadata in DuplicateMux().", End);
|
||||||
End);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -475,11 +472,11 @@ static WebPMux* DuplicateMuxHeader(const WebPMux* const mux) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int ParseFrameArgs(const char* args, WebPMuxFrameInfo* const info) {
|
static int ParseFrameArgs(const char* args, WebPMuxFrameInfo* const info) {
|
||||||
int dispose_method, unused;
|
int dispose_method, dummy;
|
||||||
char plus_minus, blend_method;
|
char plus_minus, blend_method;
|
||||||
const int num_args = sscanf(args, "+%d+%d+%d+%d%c%c+%d", &info->duration,
|
const int num_args = sscanf(args, "+%d+%d+%d+%d%c%c+%d", &info->duration,
|
||||||
&info->x_offset, &info->y_offset, &dispose_method,
|
&info->x_offset, &info->y_offset, &dispose_method,
|
||||||
&plus_minus, &blend_method, &unused);
|
&plus_minus, &blend_method, &dummy);
|
||||||
switch (num_args) {
|
switch (num_args) {
|
||||||
case 1:
|
case 1:
|
||||||
info->x_offset = info->y_offset = 0; // fall through
|
info->x_offset = info->y_offset = 0; // fall through
|
||||||
@@ -498,7 +495,7 @@ static int ParseFrameArgs(const char* args, WebPMuxFrameInfo* const info) {
|
|||||||
|
|
||||||
WarnAboutOddOffset(info);
|
WarnAboutOddOffset(info);
|
||||||
|
|
||||||
// Note: The validity of the following conversion is checked by
|
// Note: The sanity of the following conversion is checked by
|
||||||
// WebPMuxPushFrame().
|
// WebPMuxPushFrame().
|
||||||
info->dispose_method = (WebPMuxAnimDispose)dispose_method;
|
info->dispose_method = (WebPMuxAnimDispose)dispose_method;
|
||||||
|
|
||||||
@@ -520,10 +517,9 @@ static int ParseBgcolorArgs(const char* args, uint32_t* const bgcolor) {
|
|||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Clean-up.
|
// Clean-up.
|
||||||
|
|
||||||
static void DeleteConfig(Config* const config) {
|
static void DeleteConfig(WebPMuxConfig* config) {
|
||||||
if (config != NULL) {
|
if (config != NULL) {
|
||||||
free(config->args_);
|
free(config->feature_.args_);
|
||||||
ExUtilDeleteCommandLineArguments(&config->cmd_args_);
|
|
||||||
memset(config, 0, sizeof(*config));
|
memset(config, 0, sizeof(*config));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -535,7 +531,7 @@ static void DeleteConfig(Config* const config) {
|
|||||||
// Returns 1 on valid, 0 otherwise.
|
// Returns 1 on valid, 0 otherwise.
|
||||||
// Also fills up num_feature_args to be number of feature arguments given.
|
// Also fills up num_feature_args to be number of feature arguments given.
|
||||||
// (e.g. if there are 4 '-frame's and 1 '-loop', then num_feature_args = 5).
|
// (e.g. if there are 4 '-frame's and 1 '-loop', then num_feature_args = 5).
|
||||||
static int ValidateCommandLine(const CommandLineArguments* const cmd_args,
|
static int ValidateCommandLine(int argc, const char* argv[],
|
||||||
int* num_feature_args) {
|
int* num_feature_args) {
|
||||||
int num_frame_args;
|
int num_frame_args;
|
||||||
int num_loop_args;
|
int num_loop_args;
|
||||||
@@ -547,27 +543,27 @@ static int ValidateCommandLine(const CommandLineArguments* const cmd_args,
|
|||||||
*num_feature_args = 0;
|
*num_feature_args = 0;
|
||||||
|
|
||||||
// Simple checks.
|
// Simple checks.
|
||||||
if (CountOccurrences(cmd_args, "-get") > 1) {
|
if (CountOccurrences(argv, argc, "-get") > 1) {
|
||||||
ERROR_GOTO1("ERROR: Multiple '-get' arguments specified.\n", ErrValidate);
|
ERROR_GOTO1("ERROR: Multiple '-get' arguments specified.\n", ErrValidate);
|
||||||
}
|
}
|
||||||
if (CountOccurrences(cmd_args, "-set") > 1) {
|
if (CountOccurrences(argv, argc, "-set") > 1) {
|
||||||
ERROR_GOTO1("ERROR: Multiple '-set' arguments specified.\n", ErrValidate);
|
ERROR_GOTO1("ERROR: Multiple '-set' arguments specified.\n", ErrValidate);
|
||||||
}
|
}
|
||||||
if (CountOccurrences(cmd_args, "-strip") > 1) {
|
if (CountOccurrences(argv, argc, "-strip") > 1) {
|
||||||
ERROR_GOTO1("ERROR: Multiple '-strip' arguments specified.\n", ErrValidate);
|
ERROR_GOTO1("ERROR: Multiple '-strip' arguments specified.\n", ErrValidate);
|
||||||
}
|
}
|
||||||
if (CountOccurrences(cmd_args, "-info") > 1) {
|
if (CountOccurrences(argv, argc, "-info") > 1) {
|
||||||
ERROR_GOTO1("ERROR: Multiple '-info' arguments specified.\n", ErrValidate);
|
ERROR_GOTO1("ERROR: Multiple '-info' arguments specified.\n", ErrValidate);
|
||||||
}
|
}
|
||||||
if (CountOccurrences(cmd_args, "-o") > 1) {
|
if (CountOccurrences(argv, argc, "-o") > 1) {
|
||||||
ERROR_GOTO1("ERROR: Multiple output files specified.\n", ErrValidate);
|
ERROR_GOTO1("ERROR: Multiple output files specified.\n", ErrValidate);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compound checks.
|
// Compound checks.
|
||||||
num_frame_args = CountOccurrences(cmd_args, "-frame");
|
num_frame_args = CountOccurrences(argv, argc, "-frame");
|
||||||
num_loop_args = CountOccurrences(cmd_args, "-loop");
|
num_loop_args = CountOccurrences(argv, argc, "-loop");
|
||||||
num_bgcolor_args = CountOccurrences(cmd_args, "-bgcolor");
|
num_bgcolor_args = CountOccurrences(argv, argc, "-bgcolor");
|
||||||
num_durations_args = CountOccurrences(cmd_args, "-duration");
|
num_durations_args = CountOccurrences(argv, argc, "-duration");
|
||||||
|
|
||||||
if (num_loop_args > 1) {
|
if (num_loop_args > 1) {
|
||||||
ERROR_GOTO1("ERROR: Multiple loop counts specified.\n", ErrValidate);
|
ERROR_GOTO1("ERROR: Multiple loop counts specified.\n", ErrValidate);
|
||||||
@@ -602,38 +598,31 @@ static int ValidateCommandLine(const CommandLineArguments* const cmd_args,
|
|||||||
|
|
||||||
#define ACTION_IS_NIL (config->action_type_ == NIL_ACTION)
|
#define ACTION_IS_NIL (config->action_type_ == NIL_ACTION)
|
||||||
|
|
||||||
#define FEATURETYPE_IS_NIL (config->type_ == NIL_FEATURE)
|
#define FEATURETYPE_IS_NIL (feature->type_ == NIL_FEATURE)
|
||||||
|
|
||||||
#define CHECK_NUM_ARGS_AT_LEAST(NUM, LABEL) \
|
#define CHECK_NUM_ARGS_LESS(NUM, LABEL) \
|
||||||
if (argc < i + (NUM)) { \
|
if (argc < i + (NUM)) { \
|
||||||
fprintf(stderr, "ERROR: Too few arguments for '%s'.\n", argv[i]); \
|
fprintf(stderr, "ERROR: Too few arguments for '%s'.\n", argv[i]); \
|
||||||
goto LABEL; \
|
goto LABEL; \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define CHECK_NUM_ARGS_AT_MOST(NUM, LABEL) \
|
#define CHECK_NUM_ARGS_NOT_EQUAL(NUM, LABEL) \
|
||||||
if (argc > i + (NUM)) { \
|
if (argc != i + (NUM)) { \
|
||||||
fprintf(stderr, "ERROR: Too many arguments for '%s'.\n", argv[i]); \
|
fprintf(stderr, "ERROR: Too many arguments for '%s'.\n", argv[i]); \
|
||||||
goto LABEL; \
|
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
|
// Parses command-line arguments to fill up config object. Also performs some
|
||||||
// semantic checks. unicode_argv contains wchar_t arguments or is null.
|
// semantic checks.
|
||||||
static int ParseCommandLine(Config* config, const W_CHAR** const unicode_argv) {
|
static int ParseCommandLine(int argc, const char* argv[],
|
||||||
|
WebPMuxConfig* config) {
|
||||||
int i = 0;
|
int i = 0;
|
||||||
int feature_arg_index = 0;
|
int feature_arg_index = 0;
|
||||||
int ok = 1;
|
int ok = 1;
|
||||||
int argc = config->cmd_args_.argc_;
|
|
||||||
const char* const* argv = config->cmd_args_.argv_;
|
|
||||||
// Unicode file paths will be used if available.
|
|
||||||
const char* const* wargv =
|
|
||||||
(unicode_argv != NULL) ? (const char**)(unicode_argv + 1) : argv;
|
|
||||||
|
|
||||||
while (i < argc) {
|
while (i < argc) {
|
||||||
FeatureArg* const arg = &config->args_[feature_arg_index];
|
Feature* const feature = &config->feature_;
|
||||||
|
FeatureArg* const arg = &feature->args_[feature_arg_index];
|
||||||
if (argv[i][0] == '-') { // One of the action types or output.
|
if (argv[i][0] == '-') { // One of the action types or output.
|
||||||
if (!strcmp(argv[i], "-set")) {
|
if (!strcmp(argv[i], "-set")) {
|
||||||
if (ACTION_IS_NIL) {
|
if (ACTION_IS_NIL) {
|
||||||
@@ -643,14 +632,14 @@ static int ParseCommandLine(Config* config, const W_CHAR** const unicode_argv) {
|
|||||||
}
|
}
|
||||||
++i;
|
++i;
|
||||||
} else if (!strcmp(argv[i], "-duration")) {
|
} 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) {
|
if (ACTION_IS_NIL || config->action_type_ == ACTION_DURATION) {
|
||||||
config->action_type_ = ACTION_DURATION;
|
config->action_type_ = ACTION_DURATION;
|
||||||
} else {
|
} else {
|
||||||
ERROR_GOTO1("ERROR: Multiple actions specified.\n", ErrParse);
|
ERROR_GOTO1("ERROR: Multiple actions specified.\n", ErrParse);
|
||||||
}
|
}
|
||||||
if (FEATURETYPE_IS_NIL || config->type_ == FEATURE_DURATION) {
|
if (FEATURETYPE_IS_NIL || feature->type_ == FEATURE_DURATION) {
|
||||||
config->type_ = FEATURE_DURATION;
|
feature->type_ = FEATURE_DURATION;
|
||||||
} else {
|
} else {
|
||||||
ERROR_GOTO1("ERROR: Multiple features specified.\n", ErrParse);
|
ERROR_GOTO1("ERROR: Multiple features specified.\n", ErrParse);
|
||||||
}
|
}
|
||||||
@@ -667,37 +656,37 @@ static int ParseCommandLine(Config* config, const W_CHAR** const unicode_argv) {
|
|||||||
} else if (!strcmp(argv[i], "-strip")) {
|
} else if (!strcmp(argv[i], "-strip")) {
|
||||||
if (ACTION_IS_NIL) {
|
if (ACTION_IS_NIL) {
|
||||||
config->action_type_ = ACTION_STRIP;
|
config->action_type_ = ACTION_STRIP;
|
||||||
config->arg_count_ = 0;
|
feature->arg_count_ = 0;
|
||||||
} else {
|
} else {
|
||||||
ERROR_GOTO1("ERROR: Multiple actions specified.\n", ErrParse);
|
ERROR_GOTO1("ERROR: Multiple actions specified.\n", ErrParse);
|
||||||
}
|
}
|
||||||
++i;
|
++i;
|
||||||
} else if (!strcmp(argv[i], "-frame")) {
|
} 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) {
|
if (ACTION_IS_NIL || config->action_type_ == ACTION_SET) {
|
||||||
config->action_type_ = ACTION_SET;
|
config->action_type_ = ACTION_SET;
|
||||||
} else {
|
} else {
|
||||||
ERROR_GOTO1("ERROR: Multiple actions specified.\n", ErrParse);
|
ERROR_GOTO1("ERROR: Multiple actions specified.\n", ErrParse);
|
||||||
}
|
}
|
||||||
if (FEATURETYPE_IS_NIL || config->type_ == FEATURE_ANMF) {
|
if (FEATURETYPE_IS_NIL || feature->type_ == FEATURE_ANMF) {
|
||||||
config->type_ = FEATURE_ANMF;
|
feature->type_ = FEATURE_ANMF;
|
||||||
} else {
|
} else {
|
||||||
ERROR_GOTO1("ERROR: Multiple features specified.\n", ErrParse);
|
ERROR_GOTO1("ERROR: Multiple features specified.\n", ErrParse);
|
||||||
}
|
}
|
||||||
arg->subtype_ = SUBTYPE_ANMF;
|
arg->subtype_ = SUBTYPE_ANMF;
|
||||||
arg->filename_ = wargv[i + 1];
|
arg->filename_ = argv[i + 1];
|
||||||
arg->params_ = argv[i + 2];
|
arg->params_ = argv[i + 2];
|
||||||
++feature_arg_index;
|
++feature_arg_index;
|
||||||
i += 3;
|
i += 3;
|
||||||
} else if (!strcmp(argv[i], "-loop") || !strcmp(argv[i], "-bgcolor")) {
|
} 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) {
|
if (ACTION_IS_NIL || config->action_type_ == ACTION_SET) {
|
||||||
config->action_type_ = ACTION_SET;
|
config->action_type_ = ACTION_SET;
|
||||||
} else {
|
} else {
|
||||||
ERROR_GOTO1("ERROR: Multiple actions specified.\n", ErrParse);
|
ERROR_GOTO1("ERROR: Multiple actions specified.\n", ErrParse);
|
||||||
}
|
}
|
||||||
if (FEATURETYPE_IS_NIL || config->type_ == FEATURE_ANMF) {
|
if (FEATURETYPE_IS_NIL || feature->type_ == FEATURE_ANMF) {
|
||||||
config->type_ = FEATURE_ANMF;
|
feature->type_ = FEATURE_ANMF;
|
||||||
} else {
|
} else {
|
||||||
ERROR_GOTO1("ERROR: Multiple features specified.\n", ErrParse);
|
ERROR_GOTO1("ERROR: Multiple features specified.\n", ErrParse);
|
||||||
}
|
}
|
||||||
@@ -707,36 +696,34 @@ static int ParseCommandLine(Config* config, const W_CHAR** const unicode_argv) {
|
|||||||
++feature_arg_index;
|
++feature_arg_index;
|
||||||
i += 2;
|
i += 2;
|
||||||
} else if (!strcmp(argv[i], "-o")) {
|
} else if (!strcmp(argv[i], "-o")) {
|
||||||
CHECK_NUM_ARGS_AT_LEAST(2, ErrParse);
|
CHECK_NUM_ARGS_LESS(2, ErrParse);
|
||||||
config->output_ = wargv[i + 1];
|
config->output_ = argv[i + 1];
|
||||||
i += 2;
|
i += 2;
|
||||||
} else if (!strcmp(argv[i], "-info")) {
|
} 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) {
|
if (config->action_type_ != NIL_ACTION) {
|
||||||
ERROR_GOTO1("ERROR: Multiple actions specified.\n", ErrParse);
|
ERROR_GOTO1("ERROR: Multiple actions specified.\n", ErrParse);
|
||||||
} else {
|
} else {
|
||||||
config->action_type_ = ACTION_INFO;
|
config->action_type_ = ACTION_INFO;
|
||||||
config->arg_count_ = 0;
|
feature->arg_count_ = 0;
|
||||||
config->input_ = wargv[i + 1];
|
config->input_ = argv[i + 1];
|
||||||
}
|
}
|
||||||
i += 2;
|
i += 2;
|
||||||
} else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "-help")) {
|
} else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "-help")) {
|
||||||
PrintHelp();
|
PrintHelp();
|
||||||
DeleteConfig(config);
|
DeleteConfig(config);
|
||||||
LOCAL_FREE((W_CHAR** const)unicode_argv);
|
|
||||||
exit(0);
|
exit(0);
|
||||||
} else if (!strcmp(argv[i], "-version")) {
|
} else if (!strcmp(argv[i], "-version")) {
|
||||||
const int version = WebPGetMuxVersion();
|
const int version = WebPGetMuxVersion();
|
||||||
printf("%d.%d.%d\n",
|
printf("%d.%d.%d\n",
|
||||||
(version >> 16) & 0xff, (version >> 8) & 0xff, version & 0xff);
|
(version >> 16) & 0xff, (version >> 8) & 0xff, version & 0xff);
|
||||||
DeleteConfig(config);
|
DeleteConfig(config);
|
||||||
LOCAL_FREE((W_CHAR** const)unicode_argv);
|
|
||||||
exit(0);
|
exit(0);
|
||||||
} else if (!strcmp(argv[i], "--")) {
|
} else if (!strcmp(argv[i], "--")) {
|
||||||
if (i < argc - 1) {
|
if (i < argc - 1) {
|
||||||
++i;
|
++i;
|
||||||
if (config->input_ == NULL) {
|
if (config->input_ == NULL) {
|
||||||
config->input_ = wargv[i];
|
config->input_ = argv[i];
|
||||||
} else {
|
} else {
|
||||||
ERROR_GOTO2("ERROR at '%s': Multiple input files specified.\n",
|
ERROR_GOTO2("ERROR at '%s': Multiple input files specified.\n",
|
||||||
argv[i], ErrParse);
|
argv[i], ErrParse);
|
||||||
@@ -754,14 +741,14 @@ static int ParseCommandLine(Config* config, const W_CHAR** const unicode_argv) {
|
|||||||
if (!strcmp(argv[i], "icc") || !strcmp(argv[i], "exif") ||
|
if (!strcmp(argv[i], "icc") || !strcmp(argv[i], "exif") ||
|
||||||
!strcmp(argv[i], "xmp")) {
|
!strcmp(argv[i], "xmp")) {
|
||||||
if (FEATURETYPE_IS_NIL) {
|
if (FEATURETYPE_IS_NIL) {
|
||||||
config->type_ = (!strcmp(argv[i], "icc")) ? FEATURE_ICCP :
|
feature->type_ = (!strcmp(argv[i], "icc")) ? FEATURE_ICCP :
|
||||||
(!strcmp(argv[i], "exif")) ? FEATURE_EXIF : FEATURE_XMP;
|
(!strcmp(argv[i], "exif")) ? FEATURE_EXIF : FEATURE_XMP;
|
||||||
} else {
|
} else {
|
||||||
ERROR_GOTO1("ERROR: Multiple features specified.\n", ErrParse);
|
ERROR_GOTO1("ERROR: Multiple features specified.\n", ErrParse);
|
||||||
}
|
}
|
||||||
if (config->action_type_ == ACTION_SET) {
|
if (config->action_type_ == ACTION_SET) {
|
||||||
CHECK_NUM_ARGS_AT_LEAST(2, ErrParse);
|
CHECK_NUM_ARGS_LESS(2, ErrParse);
|
||||||
arg->filename_ = wargv[i + 1];
|
arg->filename_ = argv[i + 1];
|
||||||
++feature_arg_index;
|
++feature_arg_index;
|
||||||
i += 2;
|
i += 2;
|
||||||
} else {
|
} else {
|
||||||
@@ -769,28 +756,14 @@ static int ParseCommandLine(Config* config, const W_CHAR** const unicode_argv) {
|
|||||||
}
|
}
|
||||||
} else if (!strcmp(argv[i], "frame") &&
|
} else if (!strcmp(argv[i], "frame") &&
|
||||||
(config->action_type_ == ACTION_GET)) {
|
(config->action_type_ == ACTION_GET)) {
|
||||||
CHECK_NUM_ARGS_AT_LEAST(2, ErrParse);
|
CHECK_NUM_ARGS_LESS(2, ErrParse);
|
||||||
config->type_ = FEATURE_ANMF;
|
feature->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;
|
|
||||||
arg->params_ = argv[i + 1];
|
|
||||||
++feature_arg_index;
|
|
||||||
i += 2;
|
|
||||||
} else if (!strcmp(argv[i], "bgcolor") &&
|
|
||||||
(config->action_type_ == ACTION_SET)) {
|
|
||||||
CHECK_NUM_ARGS_AT_LEAST(2, ErrParse);
|
|
||||||
config->type_ = FEATURE_BGCOLOR;
|
|
||||||
arg->params_ = argv[i + 1];
|
arg->params_ = argv[i + 1];
|
||||||
++feature_arg_index;
|
++feature_arg_index;
|
||||||
i += 2;
|
i += 2;
|
||||||
} else { // Assume input file.
|
} else { // Assume input file.
|
||||||
if (config->input_ == NULL) {
|
if (config->input_ == NULL) {
|
||||||
config->input_ = wargv[i];
|
config->input_ = argv[i];
|
||||||
} else {
|
} else {
|
||||||
ERROR_GOTO2("ERROR at '%s': Multiple input files specified.\n",
|
ERROR_GOTO2("ERROR at '%s': Multiple input files specified.\n",
|
||||||
argv[i], ErrParse);
|
argv[i], ErrParse);
|
||||||
@@ -804,8 +777,9 @@ static int ParseCommandLine(Config* config, const W_CHAR** const unicode_argv) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Additional checks after config is filled.
|
// Additional checks after config is filled.
|
||||||
static int ValidateConfig(Config* const config) {
|
static int ValidateConfig(WebPMuxConfig* config) {
|
||||||
int ok = 1;
|
int ok = 1;
|
||||||
|
Feature* const feature = &config->feature_;
|
||||||
|
|
||||||
// Action.
|
// Action.
|
||||||
if (ACTION_IS_NIL) {
|
if (ACTION_IS_NIL) {
|
||||||
@@ -821,7 +795,7 @@ static int ValidateConfig(Config* const config) {
|
|||||||
if (config->input_ == NULL) {
|
if (config->input_ == NULL) {
|
||||||
if (config->action_type_ != ACTION_SET) {
|
if (config->action_type_ != ACTION_SET) {
|
||||||
ERROR_GOTO1("ERROR: No input file specified.\n", ErrValidate2);
|
ERROR_GOTO1("ERROR: No input file specified.\n", ErrValidate2);
|
||||||
} else if (config->type_ != FEATURE_ANMF) {
|
} else if (feature->type_ != FEATURE_ANMF) {
|
||||||
ERROR_GOTO1("ERROR: No input file specified.\n", ErrValidate2);
|
ERROR_GOTO1("ERROR: No input file specified.\n", ErrValidate2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -836,29 +810,28 @@ static int ValidateConfig(Config* const config) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create config object from command-line arguments.
|
// Create config object from command-line arguments.
|
||||||
static int InitializeConfig(int argc, const char* argv[], Config* const config,
|
static int InitializeConfig(int argc, const char* argv[],
|
||||||
const W_CHAR** const unicode_argv) {
|
WebPMuxConfig* config) {
|
||||||
int num_feature_args = 0;
|
int num_feature_args = 0;
|
||||||
int ok;
|
int ok = 1;
|
||||||
|
|
||||||
|
assert(config != NULL);
|
||||||
memset(config, 0, sizeof(*config));
|
memset(config, 0, sizeof(*config));
|
||||||
|
|
||||||
ok = ExUtilInitCommandLineArguments(argc, argv, &config->cmd_args_);
|
|
||||||
if (!ok) return 0;
|
|
||||||
|
|
||||||
// Validate command-line arguments.
|
// Validate command-line arguments.
|
||||||
if (!ValidateCommandLine(&config->cmd_args_, &num_feature_args)) {
|
if (!ValidateCommandLine(argc, argv, &num_feature_args)) {
|
||||||
ERROR_GOTO1("Exiting due to command-line parsing error.\n", Err1);
|
ERROR_GOTO1("Exiting due to command-line parsing error.\n", Err1);
|
||||||
}
|
}
|
||||||
|
|
||||||
config->arg_count_ = num_feature_args;
|
config->feature_.arg_count_ = num_feature_args;
|
||||||
config->args_ = (FeatureArg*)calloc(num_feature_args, sizeof(*config->args_));
|
config->feature_.args_ =
|
||||||
if (config->args_ == NULL) {
|
(FeatureArg*)calloc(num_feature_args, sizeof(*config->feature_.args_));
|
||||||
|
if (config->feature_.args_ == NULL) {
|
||||||
ERROR_GOTO1("ERROR: Memory allocation error.\n", Err1);
|
ERROR_GOTO1("ERROR: Memory allocation error.\n", Err1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse command-line.
|
// Parse command-line.
|
||||||
if (!ParseCommandLine(config, unicode_argv) || !ValidateConfig(config)) {
|
if (!ParseCommandLine(argc, argv, config) || !ValidateConfig(config)) {
|
||||||
ERROR_GOTO1("Exiting due to command-line parsing error.\n", Err1);
|
ERROR_GOTO1("Exiting due to command-line parsing error.\n", Err1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -868,14 +841,13 @@ static int InitializeConfig(int argc, const char* argv[], Config* const config,
|
|||||||
|
|
||||||
#undef ACTION_IS_NIL
|
#undef ACTION_IS_NIL
|
||||||
#undef FEATURETYPE_IS_NIL
|
#undef FEATURETYPE_IS_NIL
|
||||||
#undef CHECK_NUM_ARGS_AT_LEAST
|
#undef CHECK_NUM_ARGS_LESS
|
||||||
#undef CHECK_NUM_ARGS_AT_MOST
|
#undef CHECK_NUM_ARGS_MORE
|
||||||
#undef CHECK_NUM_ARGS_EXACTLY
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Processing.
|
// Processing.
|
||||||
|
|
||||||
static int GetFrame(const WebPMux* mux, const Config* config) {
|
static int GetFrame(const WebPMux* mux, const WebPMuxConfig* config) {
|
||||||
WebPMuxError err = WEBP_MUX_OK;
|
WebPMuxError err = WEBP_MUX_OK;
|
||||||
WebPMux* mux_single = NULL;
|
WebPMux* mux_single = NULL;
|
||||||
int num = 0;
|
int num = 0;
|
||||||
@@ -885,7 +857,7 @@ static int GetFrame(const WebPMux* mux, const Config* config) {
|
|||||||
WebPMuxFrameInfo info;
|
WebPMuxFrameInfo info;
|
||||||
WebPDataInit(&info.bitstream);
|
WebPDataInit(&info.bitstream);
|
||||||
|
|
||||||
num = ExUtilGetInt(config->args_[0].params_, 10, &parse_error);
|
num = ExUtilGetInt(config->feature_.args_[0].params_, 10, &parse_error);
|
||||||
if (num < 0) {
|
if (num < 0) {
|
||||||
ERROR_GOTO1("ERROR: Frame/Fragment index must be non-negative.\n", ErrGet);
|
ERROR_GOTO1("ERROR: Frame/Fragment index must be non-negative.\n", ErrGet);
|
||||||
}
|
}
|
||||||
@@ -919,17 +891,18 @@ static int GetFrame(const WebPMux* mux, const Config* config) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Read and process config.
|
// Read and process config.
|
||||||
static int Process(const Config* config) {
|
static int Process(const WebPMuxConfig* config) {
|
||||||
WebPMux* mux = NULL;
|
WebPMux* mux = NULL;
|
||||||
WebPData chunk;
|
WebPData chunk;
|
||||||
WebPMuxError err = WEBP_MUX_OK;
|
WebPMuxError err = WEBP_MUX_OK;
|
||||||
int ok = 1;
|
int ok = 1;
|
||||||
|
const Feature* const feature = &config->feature_;
|
||||||
|
|
||||||
switch (config->action_type_) {
|
switch (config->action_type_) {
|
||||||
case ACTION_GET: {
|
case ACTION_GET: {
|
||||||
ok = CreateMux(config->input_, &mux);
|
ok = CreateMux(config->input_, &mux);
|
||||||
if (!ok) goto Err2;
|
if (!ok) goto Err2;
|
||||||
switch (config->type_) {
|
switch (feature->type_) {
|
||||||
case FEATURE_ANMF:
|
case FEATURE_ANMF:
|
||||||
ok = GetFrame(mux, config);
|
ok = GetFrame(mux, config);
|
||||||
break;
|
break;
|
||||||
@@ -937,10 +910,10 @@ static int Process(const Config* config) {
|
|||||||
case FEATURE_ICCP:
|
case FEATURE_ICCP:
|
||||||
case FEATURE_EXIF:
|
case FEATURE_EXIF:
|
||||||
case FEATURE_XMP:
|
case FEATURE_XMP:
|
||||||
err = WebPMuxGetChunk(mux, kFourccList[config->type_], &chunk);
|
err = WebPMuxGetChunk(mux, kFourccList[feature->type_], &chunk);
|
||||||
if (err != WEBP_MUX_OK) {
|
if (err != WEBP_MUX_OK) {
|
||||||
ERROR_GOTO3("ERROR (%s): Could not get the %s.\n",
|
ERROR_GOTO3("ERROR (%s): Could not get the %s.\n",
|
||||||
ErrorString(err), kDescriptions[config->type_], Err2);
|
ErrorString(err), kDescriptions[feature->type_], Err2);
|
||||||
}
|
}
|
||||||
ok = WriteData(config->output_, &chunk);
|
ok = WriteData(config->output_, &chunk);
|
||||||
break;
|
break;
|
||||||
@@ -952,7 +925,7 @@ static int Process(const Config* config) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ACTION_SET: {
|
case ACTION_SET: {
|
||||||
switch (config->type_) {
|
switch (feature->type_) {
|
||||||
case FEATURE_ANMF: {
|
case FEATURE_ANMF: {
|
||||||
int i;
|
int i;
|
||||||
WebPMuxAnimParams params = { 0xFFFFFFFF, 0 };
|
WebPMuxAnimParams params = { 0xFFFFFFFF, 0 };
|
||||||
@@ -961,11 +934,11 @@ static int Process(const Config* config) {
|
|||||||
ERROR_GOTO2("ERROR (%s): Could not allocate a mux object.\n",
|
ERROR_GOTO2("ERROR (%s): Could not allocate a mux object.\n",
|
||||||
ErrorString(WEBP_MUX_MEMORY_ERROR), Err2);
|
ErrorString(WEBP_MUX_MEMORY_ERROR), Err2);
|
||||||
}
|
}
|
||||||
for (i = 0; i < config->arg_count_; ++i) {
|
for (i = 0; i < feature->arg_count_; ++i) {
|
||||||
switch (config->args_[i].subtype_) {
|
switch (feature->args_[i].subtype_) {
|
||||||
case SUBTYPE_BGCOLOR: {
|
case SUBTYPE_BGCOLOR: {
|
||||||
uint32_t bgcolor;
|
uint32_t bgcolor;
|
||||||
ok = ParseBgcolorArgs(config->args_[i].params_, &bgcolor);
|
ok = ParseBgcolorArgs(feature->args_[i].params_, &bgcolor);
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
ERROR_GOTO1("ERROR: Could not parse the background color \n",
|
ERROR_GOTO1("ERROR: Could not parse the background color \n",
|
||||||
Err2);
|
Err2);
|
||||||
@@ -976,7 +949,7 @@ static int Process(const Config* config) {
|
|||||||
case SUBTYPE_LOOP: {
|
case SUBTYPE_LOOP: {
|
||||||
int parse_error = 0;
|
int parse_error = 0;
|
||||||
const int loop_count =
|
const int loop_count =
|
||||||
ExUtilGetInt(config->args_[i].params_, 10, &parse_error);
|
ExUtilGetInt(feature->args_[i].params_, 10, &parse_error);
|
||||||
if (loop_count < 0 || loop_count > 65535) {
|
if (loop_count < 0 || loop_count > 65535) {
|
||||||
// Note: This is only a 'necessary' condition for loop_count
|
// Note: This is only a 'necessary' condition for loop_count
|
||||||
// to be valid. The 'sufficient' conditioned in checked in
|
// to be valid. The 'sufficient' conditioned in checked in
|
||||||
@@ -992,10 +965,10 @@ static int Process(const Config* config) {
|
|||||||
case SUBTYPE_ANMF: {
|
case SUBTYPE_ANMF: {
|
||||||
WebPMuxFrameInfo frame;
|
WebPMuxFrameInfo frame;
|
||||||
frame.id = WEBP_CHUNK_ANMF;
|
frame.id = WEBP_CHUNK_ANMF;
|
||||||
ok = ExUtilReadFileToWebPData(config->args_[i].filename_,
|
ok = ReadFileToWebPData(feature->args_[i].filename_,
|
||||||
&frame.bitstream);
|
&frame.bitstream);
|
||||||
if (!ok) goto Err2;
|
if (!ok) goto Err2;
|
||||||
ok = ParseFrameArgs(config->args_[i].params_, &frame);
|
ok = ParseFrameArgs(feature->args_[i].params_, &frame);
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
WebPDataClear(&frame.bitstream);
|
WebPDataClear(&frame.bitstream);
|
||||||
ERROR_GOTO1("ERROR: Could not parse frame properties.\n",
|
ERROR_GOTO1("ERROR: Could not parse frame properties.\n",
|
||||||
@@ -1028,62 +1001,13 @@ static int Process(const Config* config) {
|
|||||||
case FEATURE_XMP: {
|
case FEATURE_XMP: {
|
||||||
ok = CreateMux(config->input_, &mux);
|
ok = CreateMux(config->input_, &mux);
|
||||||
if (!ok) goto Err2;
|
if (!ok) goto Err2;
|
||||||
ok = ExUtilReadFileToWebPData(config->args_[0].filename_, &chunk);
|
ok = ReadFileToWebPData(feature->args_[0].filename_, &chunk);
|
||||||
if (!ok) goto Err2;
|
if (!ok) goto Err2;
|
||||||
err = WebPMuxSetChunk(mux, kFourccList[config->type_], &chunk, 1);
|
err = WebPMuxSetChunk(mux, kFourccList[feature->type_], &chunk, 1);
|
||||||
WebPDataClear(&chunk);
|
free((void*)chunk.bytes);
|
||||||
if (err != WEBP_MUX_OK) {
|
if (err != WEBP_MUX_OK) {
|
||||||
ERROR_GOTO3("ERROR (%s): Could not set the %s.\n",
|
ERROR_GOTO3("ERROR (%s): Could not set the %s.\n",
|
||||||
ErrorString(err), kDescriptions[config->type_], Err2);
|
ErrorString(err), kDescriptions[feature->type_], Err2);
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case FEATURE_BGCOLOR: {
|
|
||||||
WebPMuxAnimParams params = { 0xFFFFFFFF, 0 };
|
|
||||||
uint32_t bgcolor;
|
|
||||||
ok = ParseBgcolorArgs(config->args_[0].params_, &bgcolor);
|
|
||||||
if (!ok) {
|
|
||||||
ERROR_GOTO1("ERROR: Could not parse the background color.\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.bgcolor = bgcolor;
|
|
||||||
err = WebPMuxSetAnimationParams(mux, ¶ms);
|
|
||||||
ok = (err == WEBP_MUX_OK);
|
|
||||||
if (!ok) {
|
|
||||||
ERROR_GOTO2("ERROR (%s): Could not set animation parameters.\n",
|
|
||||||
ErrorString(err), Err2);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1114,16 +1038,16 @@ static int Process(const Config* config) {
|
|||||||
int* durations = NULL;
|
int* durations = NULL;
|
||||||
WebPMux* new_mux = DuplicateMuxHeader(mux);
|
WebPMux* new_mux = DuplicateMuxHeader(mux);
|
||||||
if (new_mux == NULL) goto Err2;
|
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;
|
if (durations == NULL) goto Err2;
|
||||||
for (i = 0; i < num_frames; ++i) durations[i] = -1;
|
for (i = 0; i < num_frames; ++i) durations[i] = -1;
|
||||||
|
|
||||||
// Parse intervals to process.
|
// Parse intervals to process.
|
||||||
for (i = 0; i < config->arg_count_; ++i) {
|
for (i = 0; i < feature->arg_count_; ++i) {
|
||||||
int k;
|
int k;
|
||||||
int args[3];
|
int args[3];
|
||||||
int duration, start, end;
|
int duration, start, end;
|
||||||
const int nb_args = ExUtilGetInts(config->args_[i].params_,
|
const int nb_args = ExUtilGetInts(feature->args_[i].params_,
|
||||||
10, 3, args);
|
10, 3, args);
|
||||||
ok = (nb_args >= 1);
|
ok = (nb_args >= 1);
|
||||||
if (!ok) goto Err3;
|
if (!ok) goto Err3;
|
||||||
@@ -1172,7 +1096,7 @@ static int Process(const Config* config) {
|
|||||||
new_mux = NULL;
|
new_mux = NULL;
|
||||||
|
|
||||||
Err3:
|
Err3:
|
||||||
WebPFree(durations);
|
free(durations);
|
||||||
WebPMuxDelete(new_mux);
|
WebPMuxDelete(new_mux);
|
||||||
if (!ok) goto Err2;
|
if (!ok) goto Err2;
|
||||||
}
|
}
|
||||||
@@ -1181,12 +1105,12 @@ static int Process(const Config* config) {
|
|||||||
case ACTION_STRIP: {
|
case ACTION_STRIP: {
|
||||||
ok = CreateMux(config->input_, &mux);
|
ok = CreateMux(config->input_, &mux);
|
||||||
if (!ok) goto Err2;
|
if (!ok) goto Err2;
|
||||||
if (config->type_ == FEATURE_ICCP || config->type_ == FEATURE_EXIF ||
|
if (feature->type_ == FEATURE_ICCP || feature->type_ == FEATURE_EXIF ||
|
||||||
config->type_ == FEATURE_XMP) {
|
feature->type_ == FEATURE_XMP) {
|
||||||
err = WebPMuxDeleteChunk(mux, kFourccList[config->type_]);
|
err = WebPMuxDeleteChunk(mux, kFourccList[feature->type_]);
|
||||||
if (err != WEBP_MUX_OK) {
|
if (err != WEBP_MUX_OK) {
|
||||||
ERROR_GOTO3("ERROR (%s): Could not strip the %s.\n",
|
ERROR_GOTO3("ERROR (%s): Could not strip the %s.\n",
|
||||||
ErrorString(err), kDescriptions[config->type_], Err2);
|
ErrorString(err), kDescriptions[feature->type_], Err2);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ERROR_GOTO1("ERROR: Invalid feature for action 'strip'.\n", Err2);
|
ERROR_GOTO1("ERROR: Invalid feature for action 'strip'.\n", Err2);
|
||||||
@@ -1216,19 +1140,15 @@ static int Process(const Config* config) {
|
|||||||
// Main.
|
// Main.
|
||||||
|
|
||||||
int main(int argc, const char* argv[]) {
|
int main(int argc, const char* argv[]) {
|
||||||
Config config;
|
WebPMuxConfig config;
|
||||||
int ok;
|
int ok = InitializeConfig(argc - 1, argv + 1, &config);
|
||||||
|
|
||||||
INIT_WARGV(argc, argv);
|
|
||||||
|
|
||||||
ok = InitializeConfig(argc - 1, argv + 1, &config, GET_WARGV_OR_NULL());
|
|
||||||
if (ok) {
|
if (ok) {
|
||||||
ok = Process(&config);
|
ok = Process(&config);
|
||||||
} else {
|
} else {
|
||||||
PrintHelp();
|
PrintHelp();
|
||||||
}
|
}
|
||||||
DeleteConfig(&config);
|
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
|
AM_CPPFLAGS += -I$(top_builddir)/src -I$(top_srcdir)/src
|
||||||
noinst_LTLIBRARIES = libwebpextras.la
|
noinst_LTLIBRARIES = libwebpextras.la
|
||||||
|
|
||||||
@@ -12,33 +11,16 @@ libwebpextras_la_CPPFLAGS = $(AM_CPPFLAGS)
|
|||||||
libwebpextras_la_LDFLAGS = -lm
|
libwebpextras_la_LDFLAGS = -lm
|
||||||
libwebpextras_la_LIBADD = ../src/libwebp.la
|
libwebpextras_la_LIBADD = ../src/libwebp.la
|
||||||
|
|
||||||
noinst_PROGRAMS =
|
noinst_PROGRAMS = get_disto webp_quality
|
||||||
noinst_PROGRAMS += webp_quality
|
|
||||||
if BUILD_DEMUX
|
|
||||||
noinst_PROGRAMS += get_disto
|
|
||||||
endif
|
|
||||||
if BUILD_VWEBP_SDL
|
|
||||||
noinst_PROGRAMS += vwebp_sdl
|
|
||||||
endif
|
|
||||||
|
|
||||||
get_disto_SOURCES = get_disto.c
|
get_disto_SOURCES = get_disto.c
|
||||||
get_disto_CPPFLAGS = $(AM_CPPFLAGS)
|
get_disto_CPPFLAGS = $(AM_CPPFLAGS)
|
||||||
get_disto_LDADD =
|
get_disto_LDADD = ../imageio/libimageio_util.la ../imageio/libimagedec.la
|
||||||
get_disto_LDADD += ../imageio/libimageio_util.la
|
|
||||||
get_disto_LDADD += ../imageio/libimagedec.la
|
|
||||||
get_disto_LDADD += ../src/libwebp.la
|
get_disto_LDADD += ../src/libwebp.la
|
||||||
get_disto_LDADD += $(PNG_LIBS) $(JPEG_LIBS) $(TIFF_LIBS)
|
get_disto_LDADD += $(PNG_LIBS) $(JPEG_LIBS) $(TIFF_LIBS)
|
||||||
|
|
||||||
webp_quality_SOURCES = webp_quality.c
|
webp_quality_SOURCES = webp_quality.c
|
||||||
webp_quality_CPPFLAGS = $(AM_CPPFLAGS)
|
webp_quality_CPPFLAGS = $(AM_CPPFLAGS) $(USE_EXPERIMENTAL_CODE)
|
||||||
webp_quality_LDADD =
|
webp_quality_LDADD = ../imageio/libimageio_util.la
|
||||||
webp_quality_LDADD += ../imageio/libimageio_util.la
|
|
||||||
webp_quality_LDADD += libwebpextras.la
|
webp_quality_LDADD += libwebpextras.la
|
||||||
webp_quality_LDADD += ../src/libwebp.la
|
webp_quality_LDADD += ../src/libwebp.la
|
||||||
|
|
||||||
vwebp_sdl_SOURCES = vwebp_sdl.c webp_to_sdl.c webp_to_sdl.h
|
|
||||||
vwebp_sdl_CPPFLAGS = $(AM_CPPFLAGS) $(SDL_INCLUDES)
|
|
||||||
vwebp_sdl_LDADD =
|
|
||||||
vwebp_sdl_LDADD += ../imageio/libimageio_util.la
|
|
||||||
vwebp_sdl_LDADD += ../src/libwebp.la
|
|
||||||
vwebp_sdl_LDADD += $(SDL_LIBS)
|
|
||||||
|
|||||||
@@ -10,16 +10,15 @@
|
|||||||
// Additional WebP utilities.
|
// Additional WebP utilities.
|
||||||
//
|
//
|
||||||
|
|
||||||
#include "extras/extras.h"
|
#include "./extras.h"
|
||||||
#include "webp/format_constants.h"
|
#include "webp/format_constants.h"
|
||||||
#include "src/dsp/dsp.h"
|
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#define XTRA_MAJ_VERSION 1
|
#define XTRA_MAJ_VERSION 0
|
||||||
#define XTRA_MIN_VERSION 2
|
#define XTRA_MIN_VERSION 1
|
||||||
#define XTRA_REV_VERSION 3
|
#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 WebPImportRGB565(const uint8_t* rgb565, WebPPicture* pic) {
|
||||||
int x, y;
|
int x, y;
|
||||||
uint32_t* dst;
|
|
||||||
if (pic == NULL || rgb565 == NULL) return 0;
|
if (pic == NULL || rgb565 == NULL) return 0;
|
||||||
pic->colorspace = WEBP_YUV420;
|
pic->colorspace = WEBP_YUV420;
|
||||||
pic->use_argb = 1;
|
pic->use_argb = 1;
|
||||||
if (!WebPPictureAlloc(pic)) return 0;
|
if (!WebPPictureAlloc(pic)) return 0;
|
||||||
dst = pic->argb;
|
|
||||||
for (y = 0; y < pic->height; ++y) {
|
for (y = 0; y < pic->height; ++y) {
|
||||||
const int width = pic->width;
|
const int width = pic->width;
|
||||||
|
uint32_t* dst = pic->argb + y * pic->argb_stride;
|
||||||
for (x = 0; x < width; ++x) {
|
for (x = 0; x < width; ++x) {
|
||||||
#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 rg = rgb565[2 * x + 1];
|
||||||
const uint32_t gb = rgb565[2 * x + 0];
|
const uint32_t gb = rgb565[2 * x + 0];
|
||||||
#else
|
#else
|
||||||
@@ -72,26 +70,24 @@ int WebPImportRGB565(const uint8_t* rgb565, WebPPicture* pic) {
|
|||||||
r = r | (r >> 5);
|
r = r | (r >> 5);
|
||||||
g = g | (g >> 6);
|
g = g | (g >> 6);
|
||||||
b = b | (b >> 5);
|
b = b | (b >> 5);
|
||||||
dst[x] = (0xffu << 24) | (r << 16) | (g << 8) | b;
|
dst[x] = (r << 16) | (g << 8) | b;
|
||||||
}
|
}
|
||||||
rgb565 += 2 * width;
|
rgb565 += 2 * width;
|
||||||
dst += pic->argb_stride;
|
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int WebPImportRGB4444(const uint8_t* rgb4444, WebPPicture* pic) {
|
int WebPImportRGB4444(const uint8_t* rgb4444, WebPPicture* pic) {
|
||||||
int x, y;
|
int x, y;
|
||||||
uint32_t* dst;
|
|
||||||
if (pic == NULL || rgb4444 == NULL) return 0;
|
if (pic == NULL || rgb4444 == NULL) return 0;
|
||||||
pic->colorspace = WEBP_YUV420;
|
pic->colorspace = WEBP_YUV420;
|
||||||
pic->use_argb = 1;
|
pic->use_argb = 1;
|
||||||
if (!WebPPictureAlloc(pic)) return 0;
|
if (!WebPPictureAlloc(pic)) return 0;
|
||||||
dst = pic->argb;
|
|
||||||
for (y = 0; y < pic->height; ++y) {
|
for (y = 0; y < pic->height; ++y) {
|
||||||
const int width = pic->width;
|
const int width = pic->width;
|
||||||
|
uint32_t* dst = pic->argb + y * pic->argb_stride;
|
||||||
for (x = 0; x < width; ++x) {
|
for (x = 0; x < width; ++x) {
|
||||||
#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 rg = rgb4444[2 * x + 1];
|
||||||
const uint32_t ba = rgb4444[2 * x + 0];
|
const uint32_t ba = rgb4444[2 * x + 0];
|
||||||
#else
|
#else
|
||||||
@@ -110,7 +106,6 @@ int WebPImportRGB4444(const uint8_t* rgb4444, WebPPicture* pic) {
|
|||||||
dst[x] = (a << 24) | (r << 16) | (g << 8) | b;
|
dst[x] = (a << 24) | (r << 16) | (g << 8) | b;
|
||||||
}
|
}
|
||||||
rgb4444 += 2 * width;
|
rgb4444 += 2 * width;
|
||||||
dst += pic->argb_stride;
|
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -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"
|
#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
|
// Returns the version number of the extras library, packed in hexadecimal using
|
||||||
// 8bits for each of major/minor/revision. E.g: v2.5.7 is 0x020507.
|
// 8bits for each of major/minor/revision. E.g: v2.5.7 is 0x020507.
|
||||||
WEBP_EXTERN int WebPGetExtrasVersion(void);
|
WEBP_EXTERN(int) WebPGetExtrasVersion(void);
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Ad-hoc colorspace importers.
|
// Ad-hoc colorspace importers.
|
||||||
|
|
||||||
// Import luma sample (gray scale image) into 'picture'. The 'picture'
|
// Import luma sample (gray scale image) into 'picture'. The 'picture'
|
||||||
// width and height must be set prior to calling this function.
|
// width and height must be set prior to calling this function.
|
||||||
WEBP_EXTERN int WebPImportGray(const uint8_t* gray, WebPPicture* picture);
|
WEBP_EXTERN(int) WebPImportGray(const uint8_t* gray, WebPPicture* picture);
|
||||||
|
|
||||||
// Import rgb sample in RGB565 packed format into 'picture'. The 'picture'
|
// Import rgb sample in RGB565 packed format into 'picture'. The 'picture'
|
||||||
// width and height must be set prior to calling this function.
|
// width and height must be set prior to calling this function.
|
||||||
WEBP_EXTERN int WebPImportRGB565(const uint8_t* rgb565, WebPPicture* pic);
|
WEBP_EXTERN(int) WebPImportRGB565(const uint8_t* rgb565, WebPPicture* pic);
|
||||||
|
|
||||||
// Import rgb sample in RGB4444 packed format into 'picture'. The 'picture'
|
// Import rgb sample in RGB4444 packed format into 'picture'. The 'picture'
|
||||||
// width and height must be set prior to calling this function.
|
// width and height must be set prior to calling this function.
|
||||||
WEBP_EXTERN int WebPImportRGB4444(const uint8_t* rgb4444, WebPPicture* pic);
|
WEBP_EXTERN(int) WebPImportRGB4444(const uint8_t* rgb4444, WebPPicture* pic);
|
||||||
|
|
||||||
// Import a color mapped image. The number of colors is less or equal to
|
// Import a color mapped image. The number of colors is less or equal to
|
||||||
// MAX_PALETTE_SIZE. 'pic' must have been initialized. Its content, if any,
|
// MAX_PALETTE_SIZE. 'pic' must have been initialized. Its content, if any,
|
||||||
// will be discarded. Returns 'false' in case of error, or if indexed[] contains
|
// will be discarded. Returns 'false' in case of error, or if indexed[] contains
|
||||||
// invalid indices.
|
// invalid indices.
|
||||||
WEBP_EXTERN int
|
WEBP_EXTERN(int)
|
||||||
WebPImportColorMappedARGB(const uint8_t* indexed, int indexed_stride,
|
WebPImportColorMappedARGB(const uint8_t* indexed, int indexed_stride,
|
||||||
const uint32_t palette[], int palette_size,
|
const uint32_t palette[], int palette_size,
|
||||||
WebPPicture* pic);
|
WebPPicture* pic);
|
||||||
|
|
||||||
// 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
|
// 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].
|
// Otherwise (lossy bitstream), the returned value is in the range [0..100].
|
||||||
// Any error (invalid bitstream, animated WebP, incomplete header, etc.)
|
// Any error (invalid bitstream, animated WebP, incomplete header, etc.)
|
||||||
// will return a value of -1.
|
// will return a value of -1.
|
||||||
WEBP_EXTERN int VP8EstimateQuality(const uint8_t* const data, size_t size);
|
WEBP_EXTERN(int) VP8EstimateQuality(const uint8_t* const data, size_t size);
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
@@ -74,4 +67,4 @@ WEBP_EXTERN int VP8EstimateQuality(const uint8_t* const data, size_t size);
|
|||||||
} // extern "C"
|
} // extern "C"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif // WEBP_EXTRAS_EXTRAS_H_
|
#endif /* WEBP_EXTRAS_EXTRAS_H_ */
|
||||||
|
|||||||
@@ -24,9 +24,8 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "webp/encode.h"
|
#include "webp/encode.h"
|
||||||
#include "imageio/image_dec.h"
|
#include "../imageio/image_dec.h"
|
||||||
#include "imageio/imageio_util.h"
|
#include "../imageio/imageio_util.h"
|
||||||
#include "../examples/unicode.h"
|
|
||||||
|
|
||||||
static size_t ReadPicture(const char* const filename, WebPPicture* const pic,
|
static size_t ReadPicture(const char* const filename, WebPPicture* const pic,
|
||||||
int keep_alpha) {
|
int keep_alpha) {
|
||||||
@@ -49,8 +48,7 @@ static size_t ReadPicture(const char* const filename, WebPPicture* const pic,
|
|||||||
|
|
||||||
End:
|
End:
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
WFPRINTF(stderr, "Error! Could not process file %s\n",
|
fprintf(stderr, "Error! Could not process file %s\n", filename);
|
||||||
(const W_CHAR*)filename);
|
|
||||||
}
|
}
|
||||||
free((void*)data);
|
free((void*)data);
|
||||||
return ok ? data_size : 0;
|
return ok ? data_size : 0;
|
||||||
@@ -223,11 +221,10 @@ static void Help(void) {
|
|||||||
" -o <file> . save the diff map as a WebP lossless file\n"
|
" -o <file> . save the diff map as a WebP lossless file\n"
|
||||||
" -scale .... scale the difference map to fit [0..255] range\n"
|
" -scale .... scale the difference map to fit [0..255] range\n"
|
||||||
" -gray ..... use grayscale for difference map (-scale)\n"
|
" -gray ..... use grayscale for difference map (-scale)\n"
|
||||||
"\nSupported input formats:\n %s\n",
|
" Also handles PNG, JPG and TIFF files, in addition to WebP.\n");
|
||||||
WebPGetEnabledInputFileFormats());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, const char* argv[]) {
|
int main(int argc, const char *argv[]) {
|
||||||
WebPPicture pic1, pic2;
|
WebPPicture pic1, pic2;
|
||||||
size_t size1 = 0, size2 = 0;
|
size_t size1 = 0, size2 = 0;
|
||||||
int ret = 1;
|
int ret = 1;
|
||||||
@@ -242,11 +239,9 @@ int main(int argc, const char* argv[]) {
|
|||||||
const char* name2 = NULL;
|
const char* name2 = NULL;
|
||||||
const char* output = NULL;
|
const char* output = NULL;
|
||||||
|
|
||||||
INIT_WARGV(argc, argv);
|
|
||||||
|
|
||||||
if (!WebPPictureInit(&pic1) || !WebPPictureInit(&pic2)) {
|
if (!WebPPictureInit(&pic1) || !WebPPictureInit(&pic2)) {
|
||||||
fprintf(stderr, "Can't init pictures\n");
|
fprintf(stderr, "Can't init pictures\n");
|
||||||
FREE_WARGV_AND_RETURN(1);
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (c = 1; c < argc; ++c) {
|
for (c = 1; c < argc; ++c) {
|
||||||
@@ -268,11 +263,11 @@ int main(int argc, const char* argv[]) {
|
|||||||
fprintf(stderr, "missing file name after %s option.\n", argv[c - 1]);
|
fprintf(stderr, "missing file name after %s option.\n", argv[c - 1]);
|
||||||
goto End;
|
goto End;
|
||||||
}
|
}
|
||||||
output = (const char*)GET_WARGV(argv, c);
|
output = argv[c];
|
||||||
} else if (name1 == NULL) {
|
} else if (name1 == NULL) {
|
||||||
name1 = (const char*)GET_WARGV(argv, c);
|
name1 = argv[c];
|
||||||
} else {
|
} else {
|
||||||
name2 = (const char*)GET_WARGV(argv, c);
|
name2 = argv[c];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (help || name1 == NULL || name2 == NULL) {
|
if (help || name1 == NULL || name2 == NULL) {
|
||||||
@@ -283,7 +278,7 @@ int main(int argc, const char* argv[]) {
|
|||||||
goto End;
|
goto End;
|
||||||
}
|
}
|
||||||
size1 = ReadPicture(name1, &pic1, 1);
|
size1 = ReadPicture(name1, &pic1, 1);
|
||||||
size2 = ReadPicture(name2, &pic2, 1);
|
size2 = ReadPicture(name1, &pic2, 1);
|
||||||
if (size1 == 0 || size2 == 0) goto End;
|
if (size1 == 0 || size2 == 0) goto End;
|
||||||
|
|
||||||
if (!keep_alpha) {
|
if (!keep_alpha) {
|
||||||
@@ -295,10 +290,9 @@ int main(int argc, const char* argv[]) {
|
|||||||
fprintf(stderr, "Error while computing the distortion.\n");
|
fprintf(stderr, "Error while computing the distortion.\n");
|
||||||
goto End;
|
goto End;
|
||||||
}
|
}
|
||||||
printf("%u %.2f %.2f %.2f %.2f %.2f [ %.2f bpp ]\n",
|
printf("%u %.2f %.2f %.2f %.2f %.2f\n",
|
||||||
(unsigned int)size1,
|
(unsigned int)size1,
|
||||||
disto[4], disto[0], disto[1], disto[2], disto[3],
|
disto[4], disto[0], disto[1], disto[2], disto[3]);
|
||||||
8.f * size1 / pic1.width / pic1.height);
|
|
||||||
|
|
||||||
if (output != NULL) {
|
if (output != NULL) {
|
||||||
uint8_t* data = NULL;
|
uint8_t* data = NULL;
|
||||||
@@ -328,7 +322,6 @@ int main(int argc, const char* argv[]) {
|
|||||||
fprintf(stderr, "Can only compute the difference map in ARGB format.\n");
|
fprintf(stderr, "Can only compute the difference map in ARGB format.\n");
|
||||||
goto End;
|
goto End;
|
||||||
}
|
}
|
||||||
#if !defined(WEBP_REDUCE_CSP)
|
|
||||||
data_size = WebPEncodeLosslessBGRA((const uint8_t*)pic1.argb,
|
data_size = WebPEncodeLosslessBGRA((const uint8_t*)pic1.argb,
|
||||||
pic1.width, pic1.height,
|
pic1.width, pic1.height,
|
||||||
pic1.argb_stride * 4,
|
pic1.argb_stride * 4,
|
||||||
@@ -340,17 +333,11 @@ int main(int argc, const char* argv[]) {
|
|||||||
ret = ImgIoUtilWriteFile(output, data, data_size) ? 0 : 1;
|
ret = ImgIoUtilWriteFile(output, data, data_size) ? 0 : 1;
|
||||||
WebPFree(data);
|
WebPFree(data);
|
||||||
if (ret) goto End;
|
if (ret) goto End;
|
||||||
#else
|
|
||||||
(void)data;
|
|
||||||
(void)data_size;
|
|
||||||
fprintf(stderr, "Cannot save the difference map. Please recompile "
|
|
||||||
"without the WEBP_REDUCE_CSP flag.\n");
|
|
||||||
#endif // WEBP_REDUCE_CSP
|
|
||||||
}
|
}
|
||||||
ret = 0;
|
ret = 0;
|
||||||
|
|
||||||
End:
|
End:
|
||||||
WebPPictureFree(&pic1);
|
WebPPictureFree(&pic1);
|
||||||
WebPPictureFree(&pic2);
|
WebPPictureFree(&pic2);
|
||||||
FREE_WARGV_AND_RETURN(ret);
|
return ret;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
//
|
//
|
||||||
// Author: Skal (pascal.massimino@gmail.com)
|
// Author: Skal (pascal.massimino@gmail.com)
|
||||||
|
|
||||||
#include "extras/extras.h"
|
#include "./extras.h"
|
||||||
#include "webp/decode.h"
|
#include "webp/decode.h"
|
||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
@@ -73,7 +73,7 @@ int VP8EstimateQuality(const uint8_t* const data, size_t size) {
|
|||||||
pos += 4;
|
pos += 4;
|
||||||
bit_pos = pos * 8;
|
bit_pos = pos * 8;
|
||||||
|
|
||||||
GET_BIT(2); // colorspace + clamp type
|
GET_BIT(2); // color_space + clamp type
|
||||||
|
|
||||||
// Segment header
|
// Segment header
|
||||||
if (GET_BIT(1)) { // use_segment_
|
if (GET_BIT(1)) { // use_segment_
|
||||||
|
|||||||
@@ -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 <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "extras/extras.h"
|
#include "./extras.h"
|
||||||
#include "imageio/imageio_util.h"
|
#include "../imageio/imageio_util.h"
|
||||||
#include "../examples/unicode.h"
|
|
||||||
|
|
||||||
int main(int argc, const char* argv[]) {
|
int main(int argc, const char *argv[]) {
|
||||||
int c;
|
int c;
|
||||||
int quiet = 0;
|
int quiet = 0;
|
||||||
int ok = 1;
|
int ok = 1;
|
||||||
|
|
||||||
INIT_WARGV(argc, argv);
|
|
||||||
|
|
||||||
for (c = 1; ok && c < argc; ++c) {
|
for (c = 1; ok && c < argc; ++c) {
|
||||||
if (!strcmp(argv[c], "-quiet")) {
|
if (!strcmp(argv[c], "-quiet")) {
|
||||||
quiet = 1;
|
quiet = 1;
|
||||||
} else if (!strcmp(argv[c], "-help") || !strcmp(argv[c], "-h")) {
|
} else if (!strcmp(argv[c], "-help") || !strcmp(argv[c], "-h")) {
|
||||||
printf("webp_quality [-h][-quiet] webp_files...\n");
|
printf("webp_quality [-h][-quiet] webp_files...\n");
|
||||||
FREE_WARGV_AND_RETURN(0);
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
const char* const filename = (const char*)GET_WARGV(argv, c);
|
const char* const filename = argv[c];
|
||||||
const uint8_t* data = NULL;
|
const uint8_t* data = NULL;
|
||||||
size_t data_size = 0;
|
size_t data_size = 0;
|
||||||
int q;
|
int q;
|
||||||
ok = ImgIoUtilReadFile(filename, &data, &data_size);
|
ok = ImgIoUtilReadFile(filename, &data, &data_size);
|
||||||
if (!ok) break;
|
if (!ok) break;
|
||||||
q = VP8EstimateQuality(data, data_size);
|
q = VP8EstimateQuality(data, data_size);
|
||||||
if (!quiet) WPRINTF("[%s] ", (const W_CHAR*)filename);
|
if (!quiet) printf("[%s] ", filename);
|
||||||
if (q < 0) {
|
if (q < 0) {
|
||||||
fprintf(stderr, "Not a WebP file, or not a lossy WebP file.\n");
|
fprintf(stderr, "Not a WebP file, or not a lossy WebP file.\n");
|
||||||
ok = 0;
|
ok = 0;
|
||||||
@@ -50,5 +46,5 @@ int main(int argc, const char* argv[]) {
|
|||||||
free((void*)data);
|
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
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-bin.zip
|
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
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
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
#
|
|
||||||
# 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.
|
|
||||||
#
|
|
||||||
|
|
||||||
##############################################################################
|
##############################################################################
|
||||||
##
|
##
|
||||||
@@ -44,16 +28,16 @@ APP_NAME="Gradle"
|
|||||||
APP_BASE_NAME=`basename "$0"`
|
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.
|
# 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.
|
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||||
MAX_FD="maximum"
|
MAX_FD="maximum"
|
||||||
|
|
||||||
warn () {
|
warn ( ) {
|
||||||
echo "$*"
|
echo "$*"
|
||||||
}
|
}
|
||||||
|
|
||||||
die () {
|
die ( ) {
|
||||||
echo
|
echo
|
||||||
echo "$*"
|
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\""
|
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# For Cygwin or MSYS, switch paths to Windows format before running java
|
# For Cygwin, switch paths to Windows format before running java
|
||||||
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
|
if $cygwin ; then
|
||||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||||
JAVACMD=`cygpath --unix "$JAVACMD"`
|
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||||
@@ -154,30 +138,27 @@ if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
|
|||||||
else
|
else
|
||||||
eval `echo args$i`="\"$arg\""
|
eval `echo args$i`="\"$arg\""
|
||||||
fi
|
fi
|
||||||
i=`expr $i + 1`
|
i=$((i+1))
|
||||||
done
|
done
|
||||||
case $i in
|
case $i in
|
||||||
0) set -- ;;
|
(0) set -- ;;
|
||||||
1) set -- "$args0" ;;
|
(1) set -- "$args0" ;;
|
||||||
2) set -- "$args0" "$args1" ;;
|
(2) set -- "$args0" "$args1" ;;
|
||||||
3) set -- "$args0" "$args1" "$args2" ;;
|
(3) set -- "$args0" "$args1" "$args2" ;;
|
||||||
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||||
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||||
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||||
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||||
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||||
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||||
esac
|
esac
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Escape application args
|
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
|
||||||
save () {
|
function splitJvmOpts() {
|
||||||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
JVM_OPTS=("$@")
|
||||||
echo " "
|
|
||||||
}
|
}
|
||||||
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
|
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
|
||||||
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" "$@"
|
|
||||||
|
|||||||
24
gradlew.bat
vendored
24
gradlew.bat
vendored
@@ -1,19 +1,3 @@
|
|||||||
@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
|
@if "%DEBUG%" == "" @echo off
|
||||||
@rem ##########################################################################
|
@rem ##########################################################################
|
||||||
@rem
|
@rem
|
||||||
@@ -30,7 +14,7 @@ set APP_BASE_NAME=%~n0
|
|||||||
set APP_HOME=%DIRNAME%
|
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.
|
@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"
|
set DEFAULT_JVM_OPTS=
|
||||||
|
|
||||||
@rem Find java.exe
|
@rem Find java.exe
|
||||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||||
@@ -65,6 +49,7 @@ goto fail
|
|||||||
@rem Get command-line arguments, handling Windows variants
|
@rem Get command-line arguments, handling Windows variants
|
||||||
|
|
||||||
if not "%OS%" == "Windows_NT" goto win9xME_args
|
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||||
|
if "%@eval[2+2]" == "4" goto 4NT_args
|
||||||
|
|
||||||
:win9xME_args
|
:win9xME_args
|
||||||
@rem Slurp the command line arguments.
|
@rem Slurp the command line arguments.
|
||||||
@@ -75,6 +60,11 @@ set _SKIP=2
|
|||||||
if "x%~1" == "x" goto execute
|
if "x%~1" == "x" goto execute
|
||||||
|
|
||||||
set CMD_LINE_ARGS=%*
|
set CMD_LINE_ARGS=%*
|
||||||
|
goto execute
|
||||||
|
|
||||||
|
:4NT_args
|
||||||
|
@rem Get arguments from the 4NT Shell from JP Software
|
||||||
|
set CMD_LINE_ARGS=%$
|
||||||
|
|
||||||
:execute
|
:execute
|
||||||
@rem Setup the command line
|
@rem Setup the command line
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ LOCAL_SRC_FILES := \
|
|||||||
jpegdec.c \
|
jpegdec.c \
|
||||||
metadata.c \
|
metadata.c \
|
||||||
pngdec.c \
|
pngdec.c \
|
||||||
pnmdec.c \
|
|
||||||
tiffdec.c \
|
tiffdec.c \
|
||||||
webpdec.c \
|
webpdec.c \
|
||||||
|
|
||||||
|
|||||||
@@ -1,32 +1,22 @@
|
|||||||
AM_CPPFLAGS += -I$(top_builddir)/src -I$(top_srcdir)/src
|
AM_CPPFLAGS += -I$(top_builddir)/src -I$(top_srcdir)/src
|
||||||
noinst_LTLIBRARIES =
|
noinst_LTLIBRARIES = libimageio_util.la libimagedec.la libimageenc.la
|
||||||
noinst_LTLIBRARIES += libimageio_util.la
|
|
||||||
if BUILD_DEMUX
|
|
||||||
noinst_LTLIBRARIES += libimagedec.la
|
|
||||||
endif
|
|
||||||
noinst_LTLIBRARIES += libimageenc.la
|
|
||||||
|
|
||||||
noinst_HEADERS =
|
noinst_HEADERS =
|
||||||
noinst_HEADERS += ../src/webp/decode.h
|
noinst_HEADERS += ../src/webp/decode.h
|
||||||
noinst_HEADERS += ../src/webp/types.h
|
noinst_HEADERS += ../src/webp/types.h
|
||||||
|
|
||||||
libimageio_util_la_SOURCES =
|
libimageio_util_la_SOURCES = imageio_util.c imageio_util.h
|
||||||
libimageio_util_la_SOURCES += imageio_util.c imageio_util.h
|
|
||||||
|
|
||||||
libimagedec_la_SOURCES =
|
libimagedec_la_SOURCES = image_dec.c image_dec.h
|
||||||
libimagedec_la_SOURCES += image_dec.c image_dec.h
|
|
||||||
libimagedec_la_SOURCES += jpegdec.c jpegdec.h
|
libimagedec_la_SOURCES += jpegdec.c jpegdec.h
|
||||||
libimagedec_la_SOURCES += metadata.c metadata.h
|
libimagedec_la_SOURCES += metadata.c metadata.h
|
||||||
libimagedec_la_SOURCES += pngdec.c pngdec.h
|
libimagedec_la_SOURCES += pngdec.c pngdec.h
|
||||||
libimagedec_la_SOURCES += pnmdec.c pnmdec.h
|
|
||||||
libimagedec_la_SOURCES += tiffdec.c tiffdec.h
|
libimagedec_la_SOURCES += tiffdec.c tiffdec.h
|
||||||
libimagedec_la_SOURCES += webpdec.c webpdec.h
|
libimagedec_la_SOURCES += webpdec.c webpdec.h
|
||||||
libimagedec_la_SOURCES += wicdec.c wicdec.h
|
libimagedec_la_SOURCES += wicdec.c wicdec.h
|
||||||
libimagedec_la_CPPFLAGS = $(JPEG_INCLUDES) $(PNG_INCLUDES) $(TIFF_INCLUDES)
|
libimagedec_la_CPPFLAGS = $(JPEG_INCLUDES) $(PNG_INCLUDES) $(TIFF_INCLUDES)
|
||||||
libimagedec_la_CPPFLAGS += $(AM_CPPFLAGS)
|
libimagedec_la_CPPFLAGS += $(AM_CPPFLAGS) $(USE_EXPERIMENTAL_CODE)
|
||||||
libimagedec_la_LIBADD = ../src/demux/libwebpdemux.la
|
|
||||||
|
|
||||||
libimageenc_la_SOURCES =
|
libimageenc_la_SOURCES = image_enc.c image_enc.h
|
||||||
libimageenc_la_SOURCES += image_enc.c image_enc.h
|
|
||||||
libimageenc_la_CPPFLAGS = $(JPEG_INCLUDES) $(PNG_INCLUDES) $(TIFF_INCLUDES)
|
libimageenc_la_CPPFLAGS = $(JPEG_INCLUDES) $(PNG_INCLUDES) $(TIFF_INCLUDES)
|
||||||
libimageenc_la_CPPFLAGS += $(AM_CPPFLAGS)
|
libimageenc_la_CPPFLAGS += $(AM_CPPFLAGS) $(USE_EXPERIMENTAL_CODE)
|
||||||
|
|||||||
@@ -11,24 +11,6 @@
|
|||||||
|
|
||||||
#include "./image_dec.h"
|
#include "./image_dec.h"
|
||||||
|
|
||||||
const char* WebPGetEnabledInputFileFormats(void) {
|
|
||||||
return "WebP"
|
|
||||||
#ifdef WEBP_HAVE_JPEG
|
|
||||||
", JPEG"
|
|
||||||
#endif
|
|
||||||
#ifdef WEBP_HAVE_PNG
|
|
||||||
", PNG"
|
|
||||||
#endif
|
|
||||||
", PNM (PGM, PPM, PAM)"
|
|
||||||
#ifdef WEBP_HAVE_TIFF
|
|
||||||
", TIFF"
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_WINCODEC_H
|
|
||||||
", Windows Imaging Component (WIC)"
|
|
||||||
#endif
|
|
||||||
"";
|
|
||||||
}
|
|
||||||
|
|
||||||
static WEBP_INLINE uint32_t GetBE32(const uint8_t buf[]) {
|
static WEBP_INLINE uint32_t GetBE32(const uint8_t buf[]) {
|
||||||
return ((uint32_t)buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
|
return ((uint32_t)buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
|
||||||
}
|
}
|
||||||
@@ -47,10 +29,6 @@ WebPInputFileFormat WebPGuessImageType(const uint8_t* const data,
|
|||||||
format = WEBP_TIFF_FORMAT;
|
format = WEBP_TIFF_FORMAT;
|
||||||
} else if (magic1 == 0x52494646 && magic2 == 0x57454250) {
|
} else if (magic1 == 0x52494646 && magic2 == 0x57454250) {
|
||||||
format = WEBP_WEBP_FORMAT;
|
format = WEBP_WEBP_FORMAT;
|
||||||
} else if (((magic1 >> 24) & 0xff) == 'P') {
|
|
||||||
const int type = (magic1 >> 16) & 0xff;
|
|
||||||
// we only support 'P5 -> P7' for now.
|
|
||||||
if (type >= '5' && type <= '7') format = WEBP_PNM_FORMAT;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return format;
|
return format;
|
||||||
@@ -73,7 +51,6 @@ WebPImageReader WebPGetImageReader(WebPInputFileFormat format) {
|
|||||||
case WEBP_JPEG_FORMAT: return ReadJPEG;
|
case WEBP_JPEG_FORMAT: return ReadJPEG;
|
||||||
case WEBP_TIFF_FORMAT: return ReadTIFF;
|
case WEBP_TIFF_FORMAT: return ReadTIFF;
|
||||||
case WEBP_WEBP_FORMAT: return ReadWebP;
|
case WEBP_WEBP_FORMAT: return ReadWebP;
|
||||||
case WEBP_PNM_FORMAT: return ReadPNM;
|
|
||||||
default: return FailReader;
|
default: return FailReader;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,7 +23,6 @@
|
|||||||
#include "./metadata.h"
|
#include "./metadata.h"
|
||||||
#include "./jpegdec.h"
|
#include "./jpegdec.h"
|
||||||
#include "./pngdec.h"
|
#include "./pngdec.h"
|
||||||
#include "./pnmdec.h"
|
|
||||||
#include "./tiffdec.h"
|
#include "./tiffdec.h"
|
||||||
#include "./webpdec.h"
|
#include "./webpdec.h"
|
||||||
#include "./wicdec.h"
|
#include "./wicdec.h"
|
||||||
@@ -37,13 +36,9 @@ typedef enum {
|
|||||||
WEBP_JPEG_FORMAT,
|
WEBP_JPEG_FORMAT,
|
||||||
WEBP_TIFF_FORMAT,
|
WEBP_TIFF_FORMAT,
|
||||||
WEBP_WEBP_FORMAT,
|
WEBP_WEBP_FORMAT,
|
||||||
WEBP_PNM_FORMAT,
|
|
||||||
WEBP_UNSUPPORTED_FORMAT
|
WEBP_UNSUPPORTED_FORMAT
|
||||||
} WebPInputFileFormat;
|
} WebPInputFileFormat;
|
||||||
|
|
||||||
// Returns a comma separated list of enabled input formats.
|
|
||||||
const char* WebPGetEnabledInputFileFormats(void);
|
|
||||||
|
|
||||||
// Try to infer the image format. 'data_size' should be larger than 12.
|
// Try to infer the image format. 'data_size' should be larger than 12.
|
||||||
// Returns WEBP_UNSUPPORTED_FORMAT if format can't be guess safely.
|
// Returns WEBP_UNSUPPORTED_FORMAT if format can't be guess safely.
|
||||||
WebPInputFileFormat WebPGuessImageType(const uint8_t* const data,
|
WebPInputFileFormat WebPGuessImageType(const uint8_t* const data,
|
||||||
|
|||||||
@@ -29,13 +29,11 @@
|
|||||||
// code with COBJMACROS.
|
// code with COBJMACROS.
|
||||||
#include <ole2.h> // CreateStreamOnHGlobal()
|
#include <ole2.h> // CreateStreamOnHGlobal()
|
||||||
#include <shlwapi.h>
|
#include <shlwapi.h>
|
||||||
#include <tchar.h>
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <wincodec.h>
|
#include <wincodec.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "./imageio_util.h"
|
#include "./imageio_util.h"
|
||||||
#include "../examples/unicode.h"
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// PNG
|
// 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.
|
// Output to a memory buffer. This is freed when 'stream' is released.
|
||||||
IFS(CreateStreamOnHGlobal(NULL, TRUE, stream));
|
IFS(CreateStreamOnHGlobal(NULL, TRUE, stream));
|
||||||
} else {
|
} else {
|
||||||
IFS(SHCreateStreamOnFile((const LPTSTR)out_file_name,
|
IFS(SHCreateStreamOnFileA(out_file_name, STGM_WRITE | STGM_CREATE, stream));
|
||||||
STGM_WRITE | STGM_CREATE, stream));
|
|
||||||
}
|
}
|
||||||
if (FAILED(hr)) {
|
if (FAILED(hr)) {
|
||||||
_ftprintf(stderr, _T("Error opening output file %s (%08lx)\n"),
|
fprintf(stderr, "Error opening output file %s (%08lx)\n",
|
||||||
(const LPTSTR)out_file_name, hr);
|
out_file_name, hr);
|
||||||
}
|
}
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
@@ -155,14 +152,20 @@ int WebPWritePNG(const char* out_file_name, int use_stdout,
|
|||||||
}
|
}
|
||||||
|
|
||||||
#elif defined(WEBP_HAVE_PNG) // !HAVE_WINCODEC_H
|
#elif defined(WEBP_HAVE_PNG) // !HAVE_WINCODEC_H
|
||||||
static void PNGAPI PNGErrorFunction(png_structp png, png_const_charp unused) {
|
static void PNGAPI PNGErrorFunction(png_structp png, png_const_charp dummy) {
|
||||||
(void)unused; // remove variable-unused warning
|
(void)dummy; // remove variable-unused warning
|
||||||
longjmp(png_jmpbuf(png), 1);
|
longjmp(png_jmpbuf(png), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
int WebPWritePNG(FILE* out_file, const WebPDecBuffer* const buffer) {
|
int WebPWritePNG(FILE* out_file, const WebPDecBuffer* const buffer) {
|
||||||
|
const uint32_t width = buffer->width;
|
||||||
|
const uint32_t height = buffer->height;
|
||||||
|
png_bytep row = buffer->u.RGBA.rgba;
|
||||||
|
const int stride = buffer->u.RGBA.stride;
|
||||||
|
const int has_alpha = WebPIsAlphaMode(buffer->colorspace);
|
||||||
volatile png_structp png;
|
volatile png_structp png;
|
||||||
volatile png_infop info;
|
volatile png_infop info;
|
||||||
|
png_uint_32 y;
|
||||||
|
|
||||||
if (out_file == NULL || buffer == NULL) return 0;
|
if (out_file == NULL || buffer == NULL) return 0;
|
||||||
|
|
||||||
@@ -181,23 +184,14 @@ int WebPWritePNG(FILE* out_file, const WebPDecBuffer* const buffer) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
png_init_io(png, out_file);
|
png_init_io(png, out_file);
|
||||||
{
|
png_set_IHDR(png, info, width, height, 8,
|
||||||
const uint32_t width = buffer->width;
|
has_alpha ? PNG_COLOR_TYPE_RGBA : PNG_COLOR_TYPE_RGB,
|
||||||
const uint32_t height = buffer->height;
|
PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT,
|
||||||
png_bytep row = buffer->u.RGBA.rgba;
|
PNG_FILTER_TYPE_DEFAULT);
|
||||||
const int stride = buffer->u.RGBA.stride;
|
png_write_info(png, info);
|
||||||
const int has_alpha = WebPIsAlphaMode(buffer->colorspace);
|
for (y = 0; y < height; ++y) {
|
||||||
uint32_t y;
|
png_write_rows(png, &row, 1);
|
||||||
|
row += stride;
|
||||||
png_set_IHDR(png, info, width, height, 8,
|
|
||||||
has_alpha ? PNG_COLOR_TYPE_RGBA : PNG_COLOR_TYPE_RGB,
|
|
||||||
PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT,
|
|
||||||
PNG_FILTER_TYPE_DEFAULT);
|
|
||||||
png_write_info(png, info);
|
|
||||||
for (y = 0; y < height; ++y) {
|
|
||||||
png_write_rows(png, &row, 1);
|
|
||||||
row += stride;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
png_write_end(png, info);
|
png_write_end(png, info);
|
||||||
png_destroy_write_struct((png_structpp)&png, (png_infopp)&info);
|
png_destroy_write_struct((png_structpp)&png, (png_infopp)&info);
|
||||||
@@ -280,7 +274,7 @@ int WebPWrite16bAsPGM(FILE* fout, const WebPDecBuffer* const buffer) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// BMP (see https://en.wikipedia.org/wiki/BMP_file_format#Pixel_storage)
|
// BMP
|
||||||
|
|
||||||
static void PutLE16(uint8_t* const dst, uint32_t value) {
|
static void PutLE16(uint8_t* const dst, uint32_t value) {
|
||||||
dst[0] = (value >> 0) & 0xff;
|
dst[0] = (value >> 0) & 0xff;
|
||||||
@@ -293,11 +287,8 @@ static void PutLE32(uint8_t* const dst, uint32_t value) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#define BMP_HEADER_SIZE 54
|
#define BMP_HEADER_SIZE 54
|
||||||
#define BMP_HEADER_ALPHA_EXTRA_SIZE 16 // for alpha info
|
|
||||||
int WebPWriteBMP(FILE* fout, const WebPDecBuffer* const buffer) {
|
int WebPWriteBMP(FILE* fout, const WebPDecBuffer* const buffer) {
|
||||||
const int has_alpha = WebPIsAlphaMode(buffer->colorspace);
|
const int has_alpha = WebPIsAlphaMode(buffer->colorspace);
|
||||||
const int header_size =
|
|
||||||
BMP_HEADER_SIZE + (has_alpha ? BMP_HEADER_ALPHA_EXTRA_SIZE : 0);
|
|
||||||
const uint32_t width = buffer->width;
|
const uint32_t width = buffer->width;
|
||||||
const uint32_t height = buffer->height;
|
const uint32_t height = buffer->height;
|
||||||
const uint8_t* rgba = buffer->u.RGBA.rgba;
|
const uint8_t* rgba = buffer->u.RGBA.rgba;
|
||||||
@@ -306,9 +297,8 @@ int WebPWriteBMP(FILE* fout, const WebPDecBuffer* const buffer) {
|
|||||||
uint32_t y;
|
uint32_t y;
|
||||||
const uint32_t line_size = bytes_per_px * width;
|
const uint32_t line_size = bytes_per_px * width;
|
||||||
const uint32_t bmp_stride = (line_size + 3) & ~3; // pad to 4
|
const uint32_t bmp_stride = (line_size + 3) & ~3; // pad to 4
|
||||||
const uint32_t image_size = bmp_stride * height;
|
const uint32_t total_size = bmp_stride * height + BMP_HEADER_SIZE;
|
||||||
const uint32_t total_size = image_size + header_size;
|
uint8_t bmp_header[BMP_HEADER_SIZE] = { 0 };
|
||||||
uint8_t bmp_header[BMP_HEADER_SIZE + BMP_HEADER_ALPHA_EXTRA_SIZE] = { 0 };
|
|
||||||
|
|
||||||
if (fout == NULL || buffer == NULL || rgba == NULL) return 0;
|
if (fout == NULL || buffer == NULL || rgba == NULL) return 0;
|
||||||
|
|
||||||
@@ -316,37 +306,30 @@ int WebPWriteBMP(FILE* fout, const WebPDecBuffer* const buffer) {
|
|||||||
PutLE16(bmp_header + 0, 0x4d42); // signature 'BM'
|
PutLE16(bmp_header + 0, 0x4d42); // signature 'BM'
|
||||||
PutLE32(bmp_header + 2, total_size); // size including header
|
PutLE32(bmp_header + 2, total_size); // size including header
|
||||||
PutLE32(bmp_header + 6, 0); // reserved
|
PutLE32(bmp_header + 6, 0); // reserved
|
||||||
PutLE32(bmp_header + 10, header_size); // offset to pixel array
|
PutLE32(bmp_header + 10, BMP_HEADER_SIZE); // offset to pixel array
|
||||||
// bitmap info header
|
// bitmap info header
|
||||||
PutLE32(bmp_header + 14, header_size - 14); // DIB header size
|
PutLE32(bmp_header + 14, 40); // DIB header size
|
||||||
PutLE32(bmp_header + 18, width); // dimensions
|
PutLE32(bmp_header + 18, width); // dimensions
|
||||||
PutLE32(bmp_header + 22, height); // no vertical flip
|
PutLE32(bmp_header + 22, -(int)height); // vertical flip!
|
||||||
PutLE16(bmp_header + 26, 1); // number of planes
|
PutLE16(bmp_header + 26, 1); // number of planes
|
||||||
PutLE16(bmp_header + 28, bytes_per_px * 8); // bits per pixel
|
PutLE16(bmp_header + 28, bytes_per_px * 8); // bits per pixel
|
||||||
PutLE32(bmp_header + 30, has_alpha ? 3 : 0); // BI_BITFIELDS or BI_RGB
|
PutLE32(bmp_header + 30, 0); // no compression (BI_RGB)
|
||||||
PutLE32(bmp_header + 34, image_size);
|
PutLE32(bmp_header + 34, 0); // image size (dummy)
|
||||||
PutLE32(bmp_header + 38, 2400); // x pixels/meter
|
PutLE32(bmp_header + 38, 2400); // x pixels/meter
|
||||||
PutLE32(bmp_header + 42, 2400); // y pixels/meter
|
PutLE32(bmp_header + 42, 2400); // y pixels/meter
|
||||||
PutLE32(bmp_header + 46, 0); // number of palette colors
|
PutLE32(bmp_header + 46, 0); // number of palette colors
|
||||||
PutLE32(bmp_header + 50, 0); // important color count
|
PutLE32(bmp_header + 50, 0); // important color count
|
||||||
if (has_alpha) { // BITMAPV3INFOHEADER complement
|
|
||||||
PutLE32(bmp_header + 54, 0x00ff0000); // red mask
|
|
||||||
PutLE32(bmp_header + 58, 0x0000ff00); // green mask
|
|
||||||
PutLE32(bmp_header + 62, 0x000000ff); // blue mask
|
|
||||||
PutLE32(bmp_header + 66, 0xff000000); // alpha mask
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO(skal): color profile
|
// TODO(skal): color profile
|
||||||
|
|
||||||
// write header
|
// write header
|
||||||
if (fwrite(bmp_header, header_size, 1, fout) != 1) {
|
if (fwrite(bmp_header, sizeof(bmp_header), 1, fout) != 1) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// write pixel array, bottom to top
|
// write pixel array
|
||||||
for (y = 0; y < height; ++y) {
|
for (y = 0; y < height; ++y) {
|
||||||
const uint8_t* const src = &rgba[(uint64_t)(height - 1 - y) * stride];
|
if (fwrite(rgba, line_size, 1, fout) != 1) {
|
||||||
if (fwrite(src, line_size, 1, fout) != 1) {
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
// write padding zeroes
|
// write padding zeroes
|
||||||
@@ -356,11 +339,11 @@ int WebPWriteBMP(FILE* fout, const WebPDecBuffer* const buffer) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
rgba += stride;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
#undef BMP_HEADER_SIZE
|
#undef BMP_HEADER_SIZE
|
||||||
#undef BMP_HEADER_ALPHA_EXTRA_SIZE
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// TIFF
|
// TIFF
|
||||||
@@ -378,8 +361,6 @@ int WebPWriteTIFF(FILE* fout, const WebPDecBuffer* const buffer) {
|
|||||||
const uint8_t* rgba = buffer->u.RGBA.rgba;
|
const uint8_t* rgba = buffer->u.RGBA.rgba;
|
||||||
const int stride = buffer->u.RGBA.stride;
|
const int stride = buffer->u.RGBA.stride;
|
||||||
const uint8_t bytes_per_px = has_alpha ? 4 : 3;
|
const uint8_t bytes_per_px = has_alpha ? 4 : 3;
|
||||||
const uint8_t assoc_alpha =
|
|
||||||
WebPIsPremultipliedMode(buffer->colorspace) ? 1 : 2;
|
|
||||||
// For non-alpha case, we omit tag 0x152 (ExtraSamples).
|
// For non-alpha case, we omit tag 0x152 (ExtraSamples).
|
||||||
const uint8_t num_ifd_entries = has_alpha ? NUM_IFD_ENTRIES
|
const uint8_t num_ifd_entries = has_alpha ? NUM_IFD_ENTRIES
|
||||||
: NUM_IFD_ENTRIES - 1;
|
: NUM_IFD_ENTRIES - 1;
|
||||||
@@ -407,8 +388,7 @@ int WebPWriteTIFF(FILE* fout, const WebPDecBuffer* const buffer) {
|
|||||||
EXTRA_DATA_OFFSET + 8, 0, 0, 0,
|
EXTRA_DATA_OFFSET + 8, 0, 0, 0,
|
||||||
0x1c, 0x01, 3, 0, 1, 0, 0, 0, 1, 0, 0, 0, // 154: PlanarConfiguration
|
0x1c, 0x01, 3, 0, 1, 0, 0, 0, 1, 0, 0, 0, // 154: PlanarConfiguration
|
||||||
0x28, 0x01, 3, 0, 1, 0, 0, 0, 2, 0, 0, 0, // 166: ResolutionUnit (inch)
|
0x28, 0x01, 3, 0, 1, 0, 0, 0, 2, 0, 0, 0, // 166: ResolutionUnit (inch)
|
||||||
0x52, 0x01, 3, 0, 1, 0, 0, 0,
|
0x52, 0x01, 3, 0, 1, 0, 0, 0, 1, 0, 0, 0, // 178: ExtraSamples: rgbA
|
||||||
assoc_alpha, 0, 0, 0, // 178: ExtraSamples: rgbA/RGBA
|
|
||||||
0, 0, 0, 0, // 190: IFD terminator
|
0, 0, 0, 0, // 190: IFD terminator
|
||||||
// EXTRA_DATA_OFFSET:
|
// EXTRA_DATA_OFFSET:
|
||||||
8, 0, 8, 0, 8, 0, 8, 0, // BitsPerSample
|
8, 0, 8, 0, 8, 0, 8, 0, // BitsPerSample
|
||||||
@@ -559,26 +539,22 @@ int WebPWriteYUV(FILE* fout, const WebPDecBuffer* const buffer) {
|
|||||||
// Generic top-level call
|
// Generic top-level call
|
||||||
|
|
||||||
int WebPSaveImage(const WebPDecBuffer* const buffer,
|
int WebPSaveImage(const WebPDecBuffer* const buffer,
|
||||||
WebPOutputFileFormat format,
|
WebPOutputFileFormat format, const char* const out_file) {
|
||||||
const char* const out_file_name) {
|
|
||||||
FILE* fout = NULL;
|
FILE* fout = NULL;
|
||||||
int needs_open_file = 1;
|
int needs_open_file = 1;
|
||||||
const int use_stdout =
|
const int use_stdout = (out_file != NULL) && !strcmp(out_file, "-");
|
||||||
(out_file_name != NULL) && !WSTRCMP(out_file_name, "-");
|
|
||||||
int ok = 1;
|
int ok = 1;
|
||||||
|
|
||||||
if (buffer == NULL || out_file_name == NULL) return 0;
|
if (buffer == NULL || out_file == NULL) return 0;
|
||||||
|
|
||||||
#ifdef HAVE_WINCODEC_H
|
#ifdef HAVE_WINCODEC_H
|
||||||
needs_open_file = (format != PNG);
|
needs_open_file = (format != PNG);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (needs_open_file) {
|
if (needs_open_file) {
|
||||||
fout = use_stdout ? ImgIoUtilSetBinaryMode(stdout)
|
fout = use_stdout ? ImgIoUtilSetBinaryMode(stdout) : fopen(out_file, "wb");
|
||||||
: WFOPEN(out_file_name, "wb");
|
|
||||||
if (fout == NULL) {
|
if (fout == NULL) {
|
||||||
WFPRINTF(stderr, "Error opening output file %s\n",
|
fprintf(stderr, "Error opening output file %s\n", out_file);
|
||||||
(const W_CHAR*)out_file_name);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -587,7 +563,7 @@ int WebPSaveImage(const WebPDecBuffer* const buffer,
|
|||||||
format == RGBA || format == BGRA || format == ARGB ||
|
format == RGBA || format == BGRA || format == ARGB ||
|
||||||
format == rgbA || format == bgrA || format == Argb) {
|
format == rgbA || format == bgrA || format == Argb) {
|
||||||
#ifdef HAVE_WINCODEC_H
|
#ifdef HAVE_WINCODEC_H
|
||||||
ok &= WebPWritePNG(out_file_name, use_stdout, buffer);
|
ok &= WebPWritePNG(out_file, use_stdout, buffer);
|
||||||
#else
|
#else
|
||||||
ok &= WebPWritePNG(fout, buffer);
|
ok &= WebPWritePNG(fout, buffer);
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ int WebPWriteTIFF(FILE* fout, const struct WebPDecBuffer* const buffer);
|
|||||||
int WebPWriteAlphaPlane(FILE* fout, const struct WebPDecBuffer* const buffer);
|
int WebPWriteAlphaPlane(FILE* fout, const struct WebPDecBuffer* const buffer);
|
||||||
|
|
||||||
// Save as YUV samples as PGM format (using IMC4 layout).
|
// Save as YUV samples as PGM format (using IMC4 layout).
|
||||||
// See: https://www.fourcc.org/yuv.php#IMC4.
|
// See: http://www.fourcc.org/yuv.php#IMC4.
|
||||||
// (very convenient format for viewing the samples, esp. for odd dimensions).
|
// (very convenient format for viewing the samples, esp. for odd dimensions).
|
||||||
int WebPWritePGM(FILE* fout, const struct WebPDecBuffer* const buffer);
|
int WebPWritePGM(FILE* fout, const struct WebPDecBuffer* const buffer);
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,6 @@
|
|||||||
#endif
|
#endif
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "../examples/unicode.h"
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// File I/O
|
// File I/O
|
||||||
@@ -48,8 +47,7 @@ int ImgIoUtilReadFromStdin(const uint8_t** data, size_t* data_size) {
|
|||||||
while (!feof(stdin)) {
|
while (!feof(stdin)) {
|
||||||
// We double the buffer size each time and read as much as possible.
|
// We double the buffer size each time and read as much as possible.
|
||||||
const size_t extra_size = (max_size == 0) ? kBlockSize : max_size;
|
const size_t extra_size = (max_size == 0) ? kBlockSize : max_size;
|
||||||
// we allocate one extra byte for the \0 terminator
|
void* const new_data = realloc(input, max_size + extra_size);
|
||||||
void* const new_data = realloc(input, max_size + extra_size + 1);
|
|
||||||
if (new_data == NULL) goto Error;
|
if (new_data == NULL) goto Error;
|
||||||
input = (uint8_t*)new_data;
|
input = (uint8_t*)new_data;
|
||||||
max_size += extra_size;
|
max_size += extra_size;
|
||||||
@@ -57,7 +55,6 @@ int ImgIoUtilReadFromStdin(const uint8_t** data, size_t* data_size) {
|
|||||||
if (size < max_size) break;
|
if (size < max_size) break;
|
||||||
}
|
}
|
||||||
if (ferror(stdin)) goto Error;
|
if (ferror(stdin)) goto Error;
|
||||||
if (input != NULL) input[size] = '\0'; // convenient 0-terminator
|
|
||||||
*data = input;
|
*data = input;
|
||||||
*data_size = size;
|
*data_size = size;
|
||||||
return 1;
|
return 1;
|
||||||
@@ -71,10 +68,10 @@ int ImgIoUtilReadFromStdin(const uint8_t** data, size_t* data_size) {
|
|||||||
int ImgIoUtilReadFile(const char* const file_name,
|
int ImgIoUtilReadFile(const char* const file_name,
|
||||||
const uint8_t** data, size_t* data_size) {
|
const uint8_t** data, size_t* data_size) {
|
||||||
int ok;
|
int ok;
|
||||||
uint8_t* file_data;
|
void* file_data;
|
||||||
size_t file_size;
|
size_t file_size;
|
||||||
FILE* in;
|
FILE* in;
|
||||||
const int from_stdin = (file_name == NULL) || !WSTRCMP(file_name, "-");
|
const int from_stdin = (file_name == NULL) || !strcmp(file_name, "-");
|
||||||
|
|
||||||
if (from_stdin) return ImgIoUtilReadFromStdin(data, data_size);
|
if (from_stdin) return ImgIoUtilReadFromStdin(data, data_size);
|
||||||
|
|
||||||
@@ -82,52 +79,42 @@ int ImgIoUtilReadFile(const char* const file_name,
|
|||||||
*data = NULL;
|
*data = NULL;
|
||||||
*data_size = 0;
|
*data_size = 0;
|
||||||
|
|
||||||
in = WFOPEN(file_name, "rb");
|
in = fopen(file_name, "rb");
|
||||||
if (in == NULL) {
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
fseek(in, 0, SEEK_END);
|
fseek(in, 0, SEEK_END);
|
||||||
file_size = ftell(in);
|
file_size = ftell(in);
|
||||||
fseek(in, 0, SEEK_SET);
|
fseek(in, 0, SEEK_SET);
|
||||||
// we allocate one extra byte for the \0 terminator
|
file_data = malloc(file_size);
|
||||||
file_data = (uint8_t*)WebPMalloc(file_size + 1);
|
if (file_data == NULL) return 0;
|
||||||
if (file_data == NULL) {
|
|
||||||
fclose(in);
|
|
||||||
WFPRINTF(stderr, "memory allocation failure when reading file %s\n",
|
|
||||||
(const W_CHAR*)file_name);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
ok = (fread(file_data, file_size, 1, in) == 1);
|
ok = (fread(file_data, file_size, 1, in) == 1);
|
||||||
fclose(in);
|
fclose(in);
|
||||||
|
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
WFPRINTF(stderr, "Could not read %d bytes of data from file %s\n",
|
fprintf(stderr, "Could not read %d bytes of data from file %s\n",
|
||||||
(int)file_size, (const W_CHAR*)file_name);
|
(int)file_size, file_name);
|
||||||
WebPFree(file_data);
|
free(file_data);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
file_data[file_size] = '\0'; // convenient 0-terminator
|
*data = (uint8_t*)file_data;
|
||||||
*data = file_data;
|
|
||||||
*data_size = file_size;
|
*data_size = file_size;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
int ImgIoUtilWriteFile(const char* const file_name,
|
int ImgIoUtilWriteFile(const char* const file_name,
|
||||||
const uint8_t* data, size_t data_size) {
|
const uint8_t* data, size_t data_size) {
|
||||||
int ok;
|
int ok;
|
||||||
FILE* out;
|
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) {
|
if (data == NULL) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
out = to_stdout ? ImgIoUtilSetBinaryMode(stdout) : WFOPEN(file_name, "wb");
|
out = to_stdout ? stdout : fopen(file_name, "wb");
|
||||||
if (out == NULL) {
|
if (out == NULL) {
|
||||||
WFPRINTF(stderr, "Error! Cannot open output file '%s'\n",
|
fprintf(stderr, "Error! Cannot open output file '%s'\n", file_name);
|
||||||
(const W_CHAR*)file_name);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
ok = (fwrite(data, data_size, 1, out) == 1);
|
ok = (fwrite(data, data_size, 1, out) == 1);
|
||||||
@@ -148,15 +135,9 @@ void ImgIoUtilCopyPlane(const uint8_t* src, int src_stride,
|
|||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
int ImgIoUtilCheckSizeArgumentsOverflow(uint64_t stride, size_t height) {
|
int ImgIoUtilCheckSizeArgumentsOverflow(uint64_t nmemb, size_t size) {
|
||||||
const uint64_t total_size = stride * height;
|
const uint64_t total_size = nmemb * size;
|
||||||
int ok = (total_size == (size_t)total_size);
|
return (total_size == (size_t)total_size);
|
||||||
// check that 'stride' is representable as int:
|
|
||||||
ok = ok && ((uint64_t)(int)stride == stride);
|
|
||||||
#if defined(WEBP_MAX_IMAGE_SIZE)
|
|
||||||
ok = ok && (total_size <= (uint64_t)WEBP_MAX_IMAGE_SIZE);
|
|
||||||
#endif
|
|
||||||
return ok;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -29,10 +29,7 @@ FILE* ImgIoUtilSetBinaryMode(FILE* file);
|
|||||||
|
|
||||||
// Allocates storage for entire file 'file_name' and returns contents and size
|
// Allocates storage for entire file 'file_name' and returns contents and size
|
||||||
// in 'data' and 'data_size'. Returns 1 on success, 0 otherwise. '*data' should
|
// in 'data' and 'data_size'. Returns 1 on success, 0 otherwise. '*data' should
|
||||||
// be deleted using WebPFree().
|
// be deleted using free().
|
||||||
// Note: for convenience, the data will be null-terminated with an extra byte
|
|
||||||
// (not accounted for in *data_size), in case the file is text and intended
|
|
||||||
// to be used as a C-string.
|
|
||||||
// If 'file_name' is NULL or equal to "-", input is read from stdin by calling
|
// If 'file_name' is NULL or equal to "-", input is read from stdin by calling
|
||||||
// the function ImgIoUtilReadFromStdin().
|
// the function ImgIoUtilReadFromStdin().
|
||||||
int ImgIoUtilReadFile(const char* const file_name,
|
int ImgIoUtilReadFile(const char* const file_name,
|
||||||
@@ -54,8 +51,8 @@ void ImgIoUtilCopyPlane(const uint8_t* src, int src_stride,
|
|||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
// Returns 0 in case of overflow, memory over-allocation or excessive dimension.
|
// Returns 0 in case of overflow of nmemb * size.
|
||||||
int ImgIoUtilCheckSizeArgumentsOverflow(uint64_t stride, size_t height);
|
int ImgIoUtilCheckSizeArgumentsOverflow(uint64_t nmemb, size_t size);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} // extern "C"
|
} // extern "C"
|
||||||
|
|||||||
@@ -206,7 +206,6 @@ struct my_error_mgr {
|
|||||||
|
|
||||||
static void my_error_exit(j_common_ptr dinfo) {
|
static void my_error_exit(j_common_ptr dinfo) {
|
||||||
struct my_error_mgr* myerr = (struct my_error_mgr*)dinfo->err;
|
struct my_error_mgr* myerr = (struct my_error_mgr*)dinfo->err;
|
||||||
fprintf(stderr, "libjpeg error: ");
|
|
||||||
dinfo->err->output_message(dinfo);
|
dinfo->err->output_message(dinfo);
|
||||||
longjmp(myerr->setjmp_buffer, 1);
|
longjmp(myerr->setjmp_buffer, 1);
|
||||||
}
|
}
|
||||||
@@ -274,7 +273,7 @@ int ReadJPEG(const uint8_t* const data, size_t data_size,
|
|||||||
ctx.data = data;
|
ctx.data = data;
|
||||||
ctx.data_size = data_size;
|
ctx.data_size = data_size;
|
||||||
|
|
||||||
memset((j_decompress_ptr)&dinfo, 0, sizeof(dinfo)); // for setjmp safety
|
memset((j_decompress_ptr)&dinfo, 0, sizeof(dinfo)); // for setjmp sanity
|
||||||
dinfo.err = jpeg_std_error(&jerr.pub);
|
dinfo.err = jpeg_std_error(&jerr.pub);
|
||||||
jerr.pub.error_exit = my_error_exit;
|
jerr.pub.error_exit = my_error_exit;
|
||||||
|
|
||||||
@@ -305,18 +304,18 @@ int ReadJPEG(const uint8_t* const data, size_t data_size,
|
|||||||
|
|
||||||
if (stride != (int)stride ||
|
if (stride != (int)stride ||
|
||||||
!ImgIoUtilCheckSizeArgumentsOverflow(stride, height)) {
|
!ImgIoUtilCheckSizeArgumentsOverflow(stride, height)) {
|
||||||
goto Error;
|
goto End;
|
||||||
}
|
}
|
||||||
|
|
||||||
rgb = (uint8_t*)malloc((size_t)stride * height);
|
rgb = (uint8_t*)malloc((size_t)stride * height);
|
||||||
if (rgb == NULL) {
|
if (rgb == NULL) {
|
||||||
goto Error;
|
goto End;
|
||||||
}
|
}
|
||||||
buffer[0] = (JSAMPLE*)rgb;
|
buffer[0] = (JSAMPLE*)rgb;
|
||||||
|
|
||||||
while (dinfo.output_scanline < dinfo.output_height) {
|
while (dinfo.output_scanline < dinfo.output_height) {
|
||||||
if (jpeg_read_scanlines((j_decompress_ptr)&dinfo, buffer, 1) != 1) {
|
if (jpeg_read_scanlines((j_decompress_ptr)&dinfo, buffer, 1) != 1) {
|
||||||
goto Error;
|
goto End;
|
||||||
}
|
}
|
||||||
buffer[0] += stride;
|
buffer[0] += stride;
|
||||||
}
|
}
|
||||||
@@ -336,11 +335,7 @@ int ReadJPEG(const uint8_t* const data, size_t data_size,
|
|||||||
pic->width = width;
|
pic->width = width;
|
||||||
pic->height = height;
|
pic->height = height;
|
||||||
ok = WebPPictureImportRGB(pic, rgb, (int)stride);
|
ok = WebPPictureImportRGB(pic, rgb, (int)stride);
|
||||||
if (!ok) {
|
if (!ok) goto Error;
|
||||||
pic->width = 0; // WebPPictureImportRGB() barely touches 'pic' on failure.
|
|
||||||
pic->height = 0; // Just reset dimensions but keep any 'custom_ptr' etc.
|
|
||||||
MetadataFree(metadata); // In case the caller forgets to free it on error.
|
|
||||||
}
|
|
||||||
|
|
||||||
End:
|
End:
|
||||||
free(rgb);
|
free(rgb);
|
||||||
|
|||||||
@@ -18,9 +18,6 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#ifdef WEBP_HAVE_PNG
|
#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 <png.h>
|
||||||
#include <setjmp.h> // note: this must be included *after* png.h
|
#include <setjmp.h> // note: this must be included *after* png.h
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@@ -30,33 +27,11 @@
|
|||||||
#include "./imageio_util.h"
|
#include "./imageio_util.h"
|
||||||
#include "./metadata.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) {
|
static void PNGAPI error_function(png_structp png, png_const_charp error) {
|
||||||
if (error != NULL) fprintf(stderr, "libpng error: %s\n", error);
|
if (error != NULL) fprintf(stderr, "libpng error: %s\n", error);
|
||||||
longjmp(png_jmpbuf(png), 1);
|
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
|
// Converts the NULL terminated 'hexstring' which contains 2-byte character
|
||||||
// representations of hex values to raw data.
|
// representations of hex values to raw data.
|
||||||
// 'hexstring' may contain values consisting of [A-F][a-f][0-9] in pairs,
|
// 'hexstring' may contain values consisting of [A-F][a-f][0-9] in pairs,
|
||||||
@@ -133,7 +108,7 @@ static const struct {
|
|||||||
MetadataPayload* const payload);
|
MetadataPayload* const payload);
|
||||||
size_t storage_offset;
|
size_t storage_offset;
|
||||||
} kPNGMetadataMap[] = {
|
} kPNGMetadataMap[] = {
|
||||||
// https://exiftool.org/TagNames/PNG.html#TextualData
|
// http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/PNG.html#TextualData
|
||||||
// See also: ExifTool on CPAN.
|
// See also: ExifTool on CPAN.
|
||||||
{ "Raw profile type exif", ProcessRawProfile, METADATA_OFFSET(exif) },
|
{ "Raw profile type exif", ProcessRawProfile, METADATA_OFFSET(exif) },
|
||||||
{ "Raw profile type xmp", ProcessRawProfile, METADATA_OFFSET(xmp) },
|
{ "Raw profile type xmp", ProcessRawProfile, METADATA_OFFSET(xmp) },
|
||||||
@@ -196,10 +171,11 @@ static int ExtractMetadataFromPNG(png_structp png,
|
|||||||
{
|
{
|
||||||
png_charp name;
|
png_charp name;
|
||||||
int comp_type;
|
int comp_type;
|
||||||
#if LOCAL_PNG_PREREQ(1,5)
|
#if ((PNG_LIBPNG_VER_MAJOR << 8) | PNG_LIBPNG_VER_MINOR << 0) < \
|
||||||
png_bytep profile;
|
((1 << 8) | (5 << 0))
|
||||||
#else
|
|
||||||
png_charp profile;
|
png_charp profile;
|
||||||
|
#else // >= libpng 1.5.0
|
||||||
|
png_bytep profile;
|
||||||
#endif
|
#endif
|
||||||
png_uint_32 len;
|
png_uint_32 len;
|
||||||
|
|
||||||
@@ -209,6 +185,7 @@ static int ExtractMetadataFromPNG(png_structp png,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -248,8 +225,7 @@ int ReadPNG(const uint8_t* const data, size_t data_size,
|
|||||||
context.data = data;
|
context.data = data;
|
||||||
context.data_size = data_size;
|
context.data_size = data_size;
|
||||||
|
|
||||||
png = png_create_read_struct_2(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL,
|
png = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
|
||||||
NULL, MallocFunc, FreeFunc);
|
|
||||||
if (png == NULL) goto End;
|
if (png == NULL) goto End;
|
||||||
|
|
||||||
png_set_error_fn(png, 0, error_function, NULL);
|
png_set_error_fn(png, 0, error_function, NULL);
|
||||||
@@ -259,15 +235,6 @@ int ReadPNG(const uint8_t* const data, size_t data_size,
|
|||||||
goto End;
|
goto End;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if LOCAL_PNG_PREREQ(1,5) || \
|
|
||||||
(LOCAL_PNG_PREREQ(1,4) && PNG_LIBPNG_VER_RELEASE >= 1)
|
|
||||||
// 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);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
info = png_create_info_struct(png);
|
info = png_create_info_struct(png);
|
||||||
if (info == NULL) goto Error;
|
if (info == NULL) goto Error;
|
||||||
end_info = png_create_info_struct(png);
|
end_info = png_create_info_struct(png);
|
||||||
@@ -298,16 +265,6 @@ int ReadPNG(const uint8_t* const data, size_t data_size,
|
|||||||
has_alpha = !!(color_type & PNG_COLOR_MASK_ALPHA);
|
has_alpha = !!(color_type & PNG_COLOR_MASK_ALPHA);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply gamma correction if needed.
|
|
||||||
{
|
|
||||||
double image_gamma = 1 / 2.2, screen_gamma = 2.2;
|
|
||||||
int srgb_intent;
|
|
||||||
if (png_get_sRGB(png, info, &srgb_intent) ||
|
|
||||||
png_get_gAMA(png, info, &image_gamma)) {
|
|
||||||
png_set_gamma(png, screen_gamma, image_gamma);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!keep_alpha) {
|
if (!keep_alpha) {
|
||||||
png_set_strip_alpha(png);
|
png_set_strip_alpha(png);
|
||||||
has_alpha = 0;
|
has_alpha = 0;
|
||||||
|
|||||||
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"
|
#include "webp/config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <limits.h>
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
@@ -46,7 +45,7 @@ static int ExtractMetadataFromTIFF(TIFF* const tif, Metadata* const metadata) {
|
|||||||
(MetadataPayload*)((uint8_t*)metadata +
|
(MetadataPayload*)((uint8_t*)metadata +
|
||||||
kTIFFMetadataMap[i].storage_offset);
|
kTIFFMetadataMap[i].storage_offset);
|
||||||
void* tag_data;
|
void* tag_data;
|
||||||
uint32_t tag_data_len;
|
uint32 tag_data_len;
|
||||||
|
|
||||||
if (TIFFGetField(tif, kTIFFMetadataMap[i].tag, &tag_data_len, &tag_data) &&
|
if (TIFFGetField(tif, kTIFFMetadataMap[i].tag, &tag_data_len, &tag_data) &&
|
||||||
!MetadataCopy((const char*)tag_data, tag_data_len, payload)) {
|
!MetadataCopy((const char*)tag_data, tag_data_len, payload)) {
|
||||||
@@ -108,7 +107,7 @@ static void MyUnmapFile(thandle_t opaque, void* base, toff_t size) {
|
|||||||
static tsize_t MyRead(thandle_t opaque, void* dst, tsize_t size) {
|
static tsize_t MyRead(thandle_t opaque, void* dst, tsize_t size) {
|
||||||
MyData* const my_data = (MyData*)opaque;
|
MyData* const my_data = (MyData*)opaque;
|
||||||
if (my_data->pos + size > my_data->size) {
|
if (my_data->pos + size > my_data->size) {
|
||||||
size = (tsize_t)(my_data->size - my_data->pos);
|
size = my_data->size - my_data->pos;
|
||||||
}
|
}
|
||||||
if (size > 0) {
|
if (size > 0) {
|
||||||
memcpy(dst, my_data->data + my_data->pos, size);
|
memcpy(dst, my_data->data + my_data->pos, size);
|
||||||
@@ -117,58 +116,18 @@ static tsize_t MyRead(thandle_t opaque, void* dst, tsize_t size) {
|
|||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unmultiply Argb data. Taken from dsp/alpha_processing
|
|
||||||
// (we don't want to force a dependency to a libdspdec library).
|
|
||||||
#define MFIX 24 // 24bit fixed-point arithmetic
|
|
||||||
#define HALF ((1u << MFIX) >> 1)
|
|
||||||
|
|
||||||
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,
|
int ReadTIFF(const uint8_t* const data, size_t data_size,
|
||||||
WebPPicture* const pic, int keep_alpha,
|
WebPPicture* const pic, int keep_alpha,
|
||||||
Metadata* const metadata) {
|
Metadata* const metadata) {
|
||||||
MyData my_data = { data, (toff_t)data_size, 0 };
|
MyData my_data = { data, (toff_t)data_size, 0 };
|
||||||
TIFF* tif;
|
TIFF* tif;
|
||||||
uint32_t image_width, image_height, tile_width, tile_height;
|
uint32 width, height;
|
||||||
uint64_t stride;
|
uint32* raster;
|
||||||
uint16_t samples_per_px = 0;
|
|
||||||
uint16_t extra_samples = 0;
|
|
||||||
uint16_t* extra_samples_ptr = NULL;
|
|
||||||
uint32_t* raster;
|
|
||||||
int64_t alloc_size;
|
int64_t alloc_size;
|
||||||
int ok = 0;
|
int ok = 0;
|
||||||
tdir_t dircount;
|
tdir_t dircount;
|
||||||
|
|
||||||
if (data == NULL || data_size == 0 || data_size > INT_MAX || pic == NULL) {
|
if (data == NULL || data_size == 0 || pic == NULL) return 0;
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
tif = TIFFClientOpen("Memory", "r", &my_data,
|
tif = TIFFClientOpen("Memory", "r", &my_data,
|
||||||
MyRead, MyRead, MySeek, MyClose,
|
MyRead, MyRead, MySeek, MyClose,
|
||||||
@@ -184,77 +143,35 @@ int ReadTIFF(const uint8_t* const data, size_t data_size,
|
|||||||
"Only the first will be used, %d will be ignored.\n",
|
"Only the first will be used, %d will be ignored.\n",
|
||||||
dircount - 1);
|
dircount - 1);
|
||||||
}
|
}
|
||||||
if (!TIFFGetFieldDefaulted(tif, TIFFTAG_SAMPLESPERPIXEL, &samples_per_px)) {
|
|
||||||
fprintf(stderr, "Error! Cannot retrieve TIFF samples-per-pixel info.\n");
|
|
||||||
goto End;
|
|
||||||
}
|
|
||||||
if (!(samples_per_px == 1 || samples_per_px == 3 || samples_per_px == 4)) {
|
|
||||||
goto End; // not supported
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &image_width) &&
|
if (!(TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &width) &&
|
||||||
TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &image_height))) {
|
TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &height))) {
|
||||||
fprintf(stderr, "Error! Cannot retrieve TIFF image dimensions.\n");
|
fprintf(stderr, "Error! Cannot retrieve TIFF image dimensions.\n");
|
||||||
goto End;
|
goto End;
|
||||||
}
|
}
|
||||||
stride = (uint64_t)image_width * sizeof(*raster);
|
|
||||||
if (!ImgIoUtilCheckSizeArgumentsOverflow(stride, image_height)) {
|
if (!ImgIoUtilCheckSizeArgumentsOverflow((uint64_t)width * height,
|
||||||
fprintf(stderr, "Error! TIFF image dimension (%d x %d) is too large.\n",
|
sizeof(*raster))) {
|
||||||
image_width, image_height);
|
|
||||||
goto End;
|
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. We also check that they respect WebP's dimension and memory limit.
|
|
||||||
// Note that a tile can be 6byte/px in some cases. Here we assume
|
|
||||||
// 4byte/px with sizeof(*raster), to be conservative.
|
|
||||||
if (TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tile_width) &&
|
|
||||||
TIFFGetField(tif, TIFFTAG_TILELENGTH, &tile_height)) {
|
|
||||||
if ((tile_width > 32 && tile_width / 2 > image_width) ||
|
|
||||||
(tile_height > 32 && tile_height / 2 > image_height) ||
|
|
||||||
!ImgIoUtilCheckSizeArgumentsOverflow(
|
|
||||||
(uint64_t)tile_width * sizeof(*raster), tile_height)) {
|
|
||||||
fprintf(stderr, "Error! TIFF tile dimension (%d x %d) is too large.\n",
|
|
||||||
tile_width, tile_height);
|
|
||||||
goto End;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (samples_per_px > 3 && !TIFFGetField(tif, TIFFTAG_EXTRASAMPLES,
|
|
||||||
&extra_samples, &extra_samples_ptr)) {
|
|
||||||
fprintf(stderr, "Error! Cannot retrieve TIFF ExtraSamples info.\n");
|
|
||||||
goto End;
|
|
||||||
}
|
|
||||||
|
|
||||||
// _Tiffmalloc uses a signed type for size.
|
// _Tiffmalloc uses a signed type for size.
|
||||||
alloc_size = (int64_t)(stride * image_height);
|
alloc_size = (int64_t)((uint64_t)width * height * sizeof(*raster));
|
||||||
if (alloc_size < 0 || alloc_size != (tsize_t)alloc_size) goto End;
|
if (alloc_size < 0 || alloc_size != (tsize_t)alloc_size) goto End;
|
||||||
|
|
||||||
raster = (uint32_t*)_TIFFmalloc((tsize_t)alloc_size);
|
raster = (uint32*)_TIFFmalloc((tsize_t)alloc_size);
|
||||||
if (raster != NULL) {
|
if (raster != NULL) {
|
||||||
if (TIFFReadRGBAImageOriented(tif, image_width, image_height, raster,
|
if (TIFFReadRGBAImageOriented(tif, width, height, raster,
|
||||||
ORIENTATION_TOPLEFT, 1)) {
|
ORIENTATION_TOPLEFT, 1)) {
|
||||||
pic->width = image_width;
|
const int stride = width * sizeof(*raster);
|
||||||
pic->height = image_height;
|
pic->width = width;
|
||||||
|
pic->height = height;
|
||||||
// TIFF data is ABGR
|
// TIFF data is ABGR
|
||||||
#ifdef WORDS_BIGENDIAN
|
#ifdef WORDS_BIGENDIAN
|
||||||
TIFFSwabArrayOfLong(raster, image_width * image_height);
|
TIFFSwabArrayOfLong(raster, width * height);
|
||||||
#endif
|
#endif
|
||||||
// if we have an alpha channel, we must un-multiply from rgbA to RGBA
|
|
||||||
if (extra_samples == 1 && extra_samples_ptr != NULL &&
|
|
||||||
extra_samples_ptr[0] == EXTRASAMPLE_ASSOCALPHA) {
|
|
||||||
uint32_t y;
|
|
||||||
uint8_t* tmp = (uint8_t*)raster;
|
|
||||||
for (y = 0; y < image_height; ++y) {
|
|
||||||
MultARGBRow(tmp, image_width);
|
|
||||||
tmp += stride;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ok = keep_alpha
|
ok = keep_alpha
|
||||||
? WebPPictureImportRGBA(pic, (const uint8_t*)raster, (int)stride)
|
? WebPPictureImportRGBA(pic, (const uint8_t*)raster, stride)
|
||||||
: WebPPictureImportRGBX(pic, (const uint8_t*)raster, (int)stride);
|
: WebPPictureImportRGBX(pic, (const uint8_t*)raster, stride);
|
||||||
}
|
}
|
||||||
_TIFFfree(raster);
|
_TIFFfree(raster);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -9,20 +9,13 @@
|
|||||||
//
|
//
|
||||||
// WebP decode.
|
// WebP decode.
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "webp/config.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "./webpdec.h"
|
#include "./webpdec.h"
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "webp/decode.h"
|
#include "webp/decode.h"
|
||||||
#include "webp/demux.h"
|
|
||||||
#include "webp/encode.h"
|
#include "webp/encode.h"
|
||||||
#include "../examples/unicode.h"
|
|
||||||
#include "./imageio_util.h"
|
#include "./imageio_util.h"
|
||||||
#include "./metadata.h"
|
#include "./metadata.h"
|
||||||
|
|
||||||
@@ -44,7 +37,7 @@ static void PrintAnimationWarning(const WebPDecoderConfig* const config) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void PrintWebPError(const char* const in_file, int status) {
|
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);
|
fprintf(stderr, "Status: %d", status);
|
||||||
if (status >= VP8_STATUS_OK && status <= VP8_STATUS_NOT_ENOUGH_DATA) {
|
if (status >= VP8_STATUS_OK && status <= VP8_STATUS_NOT_ENOUGH_DATA) {
|
||||||
fprintf(stderr, "(%s)", kStatusMessages[status]);
|
fprintf(stderr, "(%s)", kStatusMessages[status]);
|
||||||
@@ -65,7 +58,7 @@ int LoadWebP(const char* const in_file,
|
|||||||
|
|
||||||
status = WebPGetFeatures(*data, *data_size, bitstream);
|
status = WebPGetFeatures(*data, *data_size, bitstream);
|
||||||
if (status != VP8_STATUS_OK) {
|
if (status != VP8_STATUS_OK) {
|
||||||
WebPFree((void*)*data);
|
free((void*)*data);
|
||||||
*data = NULL;
|
*data = NULL;
|
||||||
*data_size = 0;
|
*data_size = 0;
|
||||||
PrintWebPError(in_file, status);
|
PrintWebPError(in_file, status);
|
||||||
@@ -95,50 +88,28 @@ VP8StatusCode DecodeWebPIncremental(
|
|||||||
{
|
{
|
||||||
WebPIDecoder* const idec = WebPIDecode(data, data_size, config);
|
WebPIDecoder* const idec = WebPIDecode(data, data_size, config);
|
||||||
if (idec == NULL) {
|
if (idec == NULL) {
|
||||||
fprintf(stderr, "Failed during WebPIDecode().\n");
|
fprintf(stderr, "Failed during WebPINewDecoder().\n");
|
||||||
return VP8_STATUS_OUT_OF_MEMORY;
|
return VP8_STATUS_OUT_OF_MEMORY;
|
||||||
} else {
|
} else {
|
||||||
|
#ifdef WEBP_EXPERIMENTAL_FEATURES
|
||||||
|
size_t size = 0;
|
||||||
|
const size_t incr = 2 + (data_size / 20);
|
||||||
|
while (size < data_size) {
|
||||||
|
size_t next_size = size + (rand() % incr);
|
||||||
|
if (next_size > data_size) next_size = data_size;
|
||||||
|
status = WebPIUpdate(idec, data, next_size);
|
||||||
|
if (status != VP8_STATUS_OK && status != VP8_STATUS_SUSPENDED) break;
|
||||||
|
size = next_size;
|
||||||
|
}
|
||||||
|
#else
|
||||||
status = WebPIUpdate(idec, data, data_size);
|
status = WebPIUpdate(idec, data, data_size);
|
||||||
|
#endif
|
||||||
WebPIDelete(idec);
|
WebPIDelete(idec);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
// Metadata
|
|
||||||
|
|
||||||
static int ExtractMetadata(const uint8_t* const data, size_t data_size,
|
|
||||||
Metadata* const metadata) {
|
|
||||||
WebPData webp_data = { data, data_size };
|
|
||||||
WebPDemuxer* const demux = WebPDemux(&webp_data);
|
|
||||||
WebPChunkIterator chunk_iter;
|
|
||||||
uint32_t flags;
|
|
||||||
|
|
||||||
if (demux == NULL) return 0;
|
|
||||||
assert(metadata != NULL);
|
|
||||||
|
|
||||||
flags = WebPDemuxGetI(demux, WEBP_FF_FORMAT_FLAGS);
|
|
||||||
|
|
||||||
if ((flags & ICCP_FLAG) && WebPDemuxGetChunk(demux, "ICCP", 1, &chunk_iter)) {
|
|
||||||
MetadataCopy((const char*)chunk_iter.chunk.bytes, chunk_iter.chunk.size,
|
|
||||||
&metadata->iccp);
|
|
||||||
WebPDemuxReleaseChunkIterator(&chunk_iter);
|
|
||||||
}
|
|
||||||
if ((flags & EXIF_FLAG) && WebPDemuxGetChunk(demux, "EXIF", 1, &chunk_iter)) {
|
|
||||||
MetadataCopy((const char*)chunk_iter.chunk.bytes, chunk_iter.chunk.size,
|
|
||||||
&metadata->exif);
|
|
||||||
WebPDemuxReleaseChunkIterator(&chunk_iter);
|
|
||||||
}
|
|
||||||
if ((flags & XMP_FLAG) && WebPDemuxGetChunk(demux, "XMP ", 1, &chunk_iter)) {
|
|
||||||
MetadataCopy((const char*)chunk_iter.chunk.bytes, chunk_iter.chunk.size,
|
|
||||||
&metadata->xmp);
|
|
||||||
WebPDemuxReleaseChunkIterator(&chunk_iter);
|
|
||||||
}
|
|
||||||
WebPDemuxDelete(demux);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
int ReadWebP(const uint8_t* const data, size_t data_size,
|
int ReadWebP(const uint8_t* const data, size_t data_size,
|
||||||
@@ -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;
|
if (data == NULL || data_size == 0 || pic == NULL) return 0;
|
||||||
|
|
||||||
|
// TODO(jzern): add Exif/XMP/ICC extraction.
|
||||||
|
if (metadata != NULL) {
|
||||||
|
fprintf(stderr, "Warning: metadata extraction from WebP is unsupported.\n");
|
||||||
|
}
|
||||||
|
|
||||||
if (!WebPInitDecoderConfig(&config)) {
|
if (!WebPInitDecoderConfig(&config)) {
|
||||||
fprintf(stderr, "Library version mismatch!\n");
|
fprintf(stderr, "Library version mismatch!\n");
|
||||||
return 0;
|
return 0;
|
||||||
@@ -162,82 +138,52 @@ int ReadWebP(const uint8_t* const data, size_t data_size,
|
|||||||
PrintWebPError("input data", status);
|
PrintWebPError("input data", status);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
{
|
||||||
do {
|
|
||||||
const int has_alpha = keep_alpha && bitstream->has_alpha;
|
const int has_alpha = keep_alpha && bitstream->has_alpha;
|
||||||
uint64_t stride;
|
|
||||||
pic->width = bitstream->width;
|
|
||||||
pic->height = bitstream->height;
|
|
||||||
if (pic->use_argb) {
|
if (pic->use_argb) {
|
||||||
stride = (uint64_t)bitstream->width * 4;
|
output_buffer->colorspace = has_alpha ? MODE_RGBA : MODE_RGB;
|
||||||
} else {
|
|
||||||
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;
|
|
||||||
} else {
|
} else {
|
||||||
output_buffer->colorspace = has_alpha ? MODE_YUVA : MODE_YUV;
|
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);
|
status = DecodeWebP(data, data_size, &config);
|
||||||
ok = (status == VP8_STATUS_OK);
|
if (status == VP8_STATUS_OK) {
|
||||||
if (ok && !keep_alpha && pic->use_argb) {
|
pic->width = output_buffer->width;
|
||||||
// Need to wipe out the alpha value, as requested.
|
pic->height = output_buffer->height;
|
||||||
int x, y;
|
if (pic->use_argb) {
|
||||||
uint32_t* argb = pic->argb;
|
const uint8_t* const rgba = output_buffer->u.RGBA.rgba;
|
||||||
for (y = 0; y < pic->height; ++y) {
|
const int stride = output_buffer->u.RGBA.stride;
|
||||||
for (x = 0; x < pic->width; ++x) argb[x] |= 0xff000000u;
|
ok = has_alpha ? WebPPictureImportRGBA(pic, rgba, stride)
|
||||||
argb += pic->argb_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) {
|
if (status != VP8_STATUS_OK) {
|
||||||
PrintWebPError("input data", status);
|
PrintWebPError("input data", status);
|
||||||
ok = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
WebPFreeDecBuffer(output_buffer);
|
WebPFreeDecBuffer(output_buffer);
|
||||||
|
|
||||||
if (ok && metadata != NULL) {
|
|
||||||
ok = ExtractMetadata(data, data_size, metadata);
|
|
||||||
if (!ok) {
|
|
||||||
PrintWebPError("metadata", VP8_STATUS_BITSTREAM_ERROR);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!ok) WebPPictureFree(pic);
|
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ VP8StatusCode DecodeWebPIncremental(
|
|||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
// Decodes a WebP contained in 'data', returning the decoded output in 'pic'.
|
// Reads a WebP from 'in_file', returning the decoded output in 'pic'.
|
||||||
// Output is RGBA or YUVA, depending on pic->use_argb value.
|
// Output is RGBA or YUVA, depending on pic->use_argb value.
|
||||||
// If 'keep_alpha' is true and the WebP has an alpha channel, the output is RGBA
|
// If 'keep_alpha' is true and the WebP has an alpha channel, the output is RGBA
|
||||||
// or YUVA. Otherwise, alpha channel is dropped and output is RGB or YUV.
|
// or YUVA. Otherwise, alpha channel is dropped and output is RGB or YUV.
|
||||||
|
|||||||
@@ -29,14 +29,12 @@
|
|||||||
// code with COBJMACROS.
|
// code with COBJMACROS.
|
||||||
#include <ole2.h> // CreateStreamOnHGlobal()
|
#include <ole2.h> // CreateStreamOnHGlobal()
|
||||||
#include <shlwapi.h>
|
#include <shlwapi.h>
|
||||||
#include <tchar.h>
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <wincodec.h>
|
#include <wincodec.h>
|
||||||
|
|
||||||
#include "../examples/unicode.h"
|
#include "webp/encode.h"
|
||||||
#include "./imageio_util.h"
|
#include "./imageio_util.h"
|
||||||
#include "./metadata.h"
|
#include "./metadata.h"
|
||||||
#include "webp/encode.h"
|
|
||||||
|
|
||||||
#define IFS(fn) \
|
#define IFS(fn) \
|
||||||
do { \
|
do { \
|
||||||
@@ -87,7 +85,7 @@ WEBP_DEFINE_GUID(GUID_WICPixelFormat64bppRGBA_,
|
|||||||
|
|
||||||
static HRESULT OpenInputStream(const char* filename, IStream** stream) {
|
static HRESULT OpenInputStream(const char* filename, IStream** stream) {
|
||||||
HRESULT hr = S_OK;
|
HRESULT hr = S_OK;
|
||||||
if (!WSTRCMP(filename, "-")) {
|
if (!strcmp(filename, "-")) {
|
||||||
const uint8_t* data = NULL;
|
const uint8_t* data = NULL;
|
||||||
size_t data_size = 0;
|
size_t data_size = 0;
|
||||||
const int ok = ImgIoUtilReadFile(filename, &data, &data_size);
|
const int ok = ImgIoUtilReadFile(filename, &data, &data_size);
|
||||||
@@ -110,12 +108,11 @@ static HRESULT OpenInputStream(const char* filename, IStream** stream) {
|
|||||||
hr = E_FAIL;
|
hr = E_FAIL;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
IFS(SHCreateStreamOnFile((const LPTSTR)filename, STGM_READ, stream));
|
IFS(SHCreateStreamOnFileA(filename, STGM_READ, stream));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FAILED(hr)) {
|
if (FAILED(hr)) {
|
||||||
_ftprintf(stderr, _T("Error opening input file %s (%08lx)\n"),
|
fprintf(stderr, "Error opening input file %s (%08lx)\n", filename, hr);
|
||||||
(const LPTSTR)filename, hr);
|
|
||||||
}
|
}
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
@@ -134,10 +131,7 @@ static HRESULT ExtractICCP(IWICImagingFactory* const factory,
|
|||||||
IWICColorContext** color_contexts;
|
IWICColorContext** color_contexts;
|
||||||
|
|
||||||
IFS(IWICBitmapFrameDecode_GetColorContexts(frame, 0, NULL, &count));
|
IFS(IWICBitmapFrameDecode_GetColorContexts(frame, 0, NULL, &count));
|
||||||
if (FAILED(hr) || count == 0) {
|
if (FAILED(hr) || count == 0) return hr;
|
||||||
// Treat unsupported operation as a non-fatal error. See crbug.com/webp/506.
|
|
||||||
return (hr == WINCODEC_ERR_UNSUPPORTEDOPERATION) ? S_OK : hr;
|
|
||||||
}
|
|
||||||
|
|
||||||
color_contexts = (IWICColorContext**)calloc(count, sizeof(*color_contexts));
|
color_contexts = (IWICColorContext**)calloc(count, sizeof(*color_contexts));
|
||||||
if (color_contexts == NULL) return E_OUTOFMEMORY;
|
if (color_contexts == NULL) return E_OUTOFMEMORY;
|
||||||
@@ -273,15 +267,10 @@ int ReadPictureWithWIC(const char* const filename,
|
|||||||
WICPixelFormatGUID src_pixel_format = GUID_WICPixelFormatUndefined;
|
WICPixelFormatGUID src_pixel_format = GUID_WICPixelFormatUndefined;
|
||||||
const WICFormatImporter* importer = NULL;
|
const WICFormatImporter* importer = NULL;
|
||||||
GUID src_container_format = GUID_NULL_;
|
GUID src_container_format = GUID_NULL_;
|
||||||
// From Windows Kits\10\Include\10.0.19041.0\um\wincodec.h
|
|
||||||
WEBP_DEFINE_GUID(GUID_ContainerFormatWebp_,
|
|
||||||
0xe094b0e2, 0x67f2, 0x45b3,
|
|
||||||
0xb0, 0xea, 0x11, 0x53, 0x37, 0xca, 0x7c, 0xf3);
|
|
||||||
static const GUID* kAlphaContainers[] = {
|
static const GUID* kAlphaContainers[] = {
|
||||||
&GUID_ContainerFormatBmp,
|
&GUID_ContainerFormatBmp,
|
||||||
&GUID_ContainerFormatPng,
|
&GUID_ContainerFormatPng,
|
||||||
&GUID_ContainerFormatTiff,
|
&GUID_ContainerFormatTiff,
|
||||||
&GUID_ContainerFormatWebp_,
|
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
int has_alpha = 0;
|
int has_alpha = 0;
|
||||||
@@ -306,15 +295,9 @@ int ReadPictureWithWIC(const char* const filename,
|
|||||||
factory, stream, NULL,
|
factory, stream, NULL,
|
||||||
WICDecodeMetadataCacheOnDemand, &decoder));
|
WICDecodeMetadataCacheOnDemand, &decoder));
|
||||||
IFS(IWICBitmapDecoder_GetFrameCount(decoder, &frame_count));
|
IFS(IWICBitmapDecoder_GetFrameCount(decoder, &frame_count));
|
||||||
if (SUCCEEDED(hr)) {
|
if (SUCCEEDED(hr) && frame_count == 0) {
|
||||||
if (frame_count == 0) {
|
fprintf(stderr, "No frame found in input file.\n");
|
||||||
fprintf(stderr, "No frame found in input file.\n");
|
hr = E_FAIL;
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
IFS(IWICBitmapDecoder_GetFrame(decoder, 0, &frame));
|
IFS(IWICBitmapDecoder_GetFrame(decoder, 0, &frame));
|
||||||
IFS(IWICBitmapFrameDecode_GetPixelFormat(frame, &src_pixel_format));
|
IFS(IWICBitmapFrameDecode_GetPixelFormat(frame, &src_pixel_format));
|
||||||
|
|||||||
106
infra/common.sh
106
infra/common.sh
@@ -1,106 +0,0 @@
|
|||||||
# Copyright (c) 2021, Google Inc. All rights reserved.
|
|
||||||
#
|
|
||||||
# Redistribution and use in source and binary forms, with or without
|
|
||||||
# modification, are permitted provided that the following conditions are
|
|
||||||
# met:
|
|
||||||
#
|
|
||||||
# * Redistributions of source code must retain the above copyright
|
|
||||||
# notice, this list of conditions and the following disclaimer.
|
|
||||||
#
|
|
||||||
# * Redistributions in binary form must reproduce the above copyright
|
|
||||||
# notice, this list of conditions and the following disclaimer in
|
|
||||||
# the documentation and/or other materials provided with the
|
|
||||||
# distribution.
|
|
||||||
#
|
|
||||||
# * Neither the name of Google nor the names of its contributors may
|
|
||||||
# be used to endorse or promote products derived from this software
|
|
||||||
# without specific prior written permission.
|
|
||||||
#
|
|
||||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
||||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
||||||
# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
||||||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
|
|
||||||
log_err() {
|
|
||||||
echo "[$(date +'%Y-%m-%dT%H:%M:%S%z')]: $*" >&2
|
|
||||||
}
|
|
||||||
|
|
||||||
#######################################
|
|
||||||
# Create build directory. Build directory will be deleted if it exists.
|
|
||||||
# Arguments:
|
|
||||||
# None.
|
|
||||||
# Returns:
|
|
||||||
# mkdir result.
|
|
||||||
#######################################
|
|
||||||
make_build_dir() {
|
|
||||||
if [[ "$#" -ne 1 ]]; then
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
local build_dir
|
|
||||||
build_dir="$1"
|
|
||||||
rm -rf "${build_dir}"
|
|
||||||
mkdir -p "${build_dir}"
|
|
||||||
}
|
|
||||||
|
|
||||||
#######################################
|
|
||||||
# Cleanup files from the build directory.
|
|
||||||
# Globals:
|
|
||||||
# LIBWEBP_ROOT repository's root path.
|
|
||||||
# Arguments:
|
|
||||||
# $1 build directory.
|
|
||||||
#######################################
|
|
||||||
cleanup() {
|
|
||||||
# $1 is not completely removed to allow for binary artifacts to be
|
|
||||||
# extracted.
|
|
||||||
find "${1:?"Build directory not defined"}" \
|
|
||||||
\( -name "*.[ao]" -o -name "*.l[ao]" \) -exec rm -f {} +
|
|
||||||
}
|
|
||||||
|
|
||||||
#######################################
|
|
||||||
# Setup ccache for toolchain.
|
|
||||||
# Globals:
|
|
||||||
# PATH
|
|
||||||
# Arguments:
|
|
||||||
# None.
|
|
||||||
#######################################
|
|
||||||
setup_ccache() {
|
|
||||||
if [[ -x "$(command -v ccache)" ]]; then
|
|
||||||
export CCACHE_CPP2=yes
|
|
||||||
export PATH="/usr/lib/ccache:${PATH}"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
#######################################
|
|
||||||
# Detects whether test block should be run in the current test shard.
|
|
||||||
# Globals:
|
|
||||||
# TEST_TOTAL_SHARDS: Valid range: [1, N]. Defaults to 1.
|
|
||||||
# TEST_SHARD_INDEX: Valid range: [0, TEST_TOTAL_SHARDS). Defaults to 0.
|
|
||||||
# libwebp_test_id: current test number; incremented with each call.
|
|
||||||
# Arguments:
|
|
||||||
# None
|
|
||||||
# Returns:
|
|
||||||
# true if the shard is active
|
|
||||||
# false if the shard is inactive
|
|
||||||
#######################################
|
|
||||||
shard_should_run() {
|
|
||||||
TEST_TOTAL_SHARDS=${TEST_TOTAL_SHARDS:=1}
|
|
||||||
TEST_SHARD_INDEX=${TEST_SHARD_INDEX:=0}
|
|
||||||
libwebp_test_id=${libwebp_test_id:=-1}
|
|
||||||
: $((libwebp_test_id += 1))
|
|
||||||
|
|
||||||
if [[ "${TEST_SHARD_INDEX}" -lt 0 ||
|
|
||||||
"${TEST_SHARD_INDEX}" -ge "${TEST_TOTAL_SHARDS}" ]]; then
|
|
||||||
log_err "Invalid TEST_SHARD_INDEX (${TEST_SHARD_INDEX})!" \
|
|
||||||
"Expected [0, ${TEST_TOTAL_SHARDS})."
|
|
||||||
fi
|
|
||||||
|
|
||||||
[[ "$((libwebp_test_id % TEST_TOTAL_SHARDS))" -eq "${TEST_SHARD_INDEX}" ]]
|
|
||||||
}
|
|
||||||
401
infra/compile.sh
401
infra/compile.sh
@@ -1,401 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
# Copyright (c) 2021, Google Inc. All rights reserved.
|
|
||||||
#
|
|
||||||
# Redistribution and use in source and binary forms, with or without
|
|
||||||
# modification, are permitted provided that the following conditions are
|
|
||||||
# met:
|
|
||||||
#
|
|
||||||
# * Redistributions of source code must retain the above copyright
|
|
||||||
# notice, this list of conditions and the following disclaimer.
|
|
||||||
#
|
|
||||||
# * Redistributions in binary form must reproduce the above copyright
|
|
||||||
# notice, this list of conditions and the following disclaimer in
|
|
||||||
# the documentation and/or other materials provided with the
|
|
||||||
# distribution.
|
|
||||||
#
|
|
||||||
# * Neither the name of Google nor the names of its contributors may
|
|
||||||
# be used to endorse or promote products derived from this software
|
|
||||||
# without specific prior written permission.
|
|
||||||
#
|
|
||||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
||||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
||||||
# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
||||||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
|
|
||||||
set -xe
|
|
||||||
LIBWEBP_ROOT="$(realpath "$(dirname "$0")/..")"
|
|
||||||
WORKSPACE=${WORKSPACE:-"$(mktemp -d -t webp.XXX)"}
|
|
||||||
|
|
||||||
# shellcheck source=infra/common.sh
|
|
||||||
source "${LIBWEBP_ROOT}/infra/common.sh"
|
|
||||||
|
|
||||||
usage() {
|
|
||||||
cat << EOF
|
|
||||||
Usage: compile.sh BUILD_TYPE TARGET
|
|
||||||
Options:
|
|
||||||
BUILD_TYPE supported build type: (shared, static, static-debug)
|
|
||||||
TARGET supported target platforms:
|
|
||||||
aarch64-linux-clang
|
|
||||||
aarch64-linux-gnu
|
|
||||||
arm-linux-gnueabi
|
|
||||||
arm-neon-linux-gnueabi
|
|
||||||
cmake
|
|
||||||
cmake-aarch64
|
|
||||||
cmake-arm
|
|
||||||
cmake-clang
|
|
||||||
disable-near-lossless
|
|
||||||
disable-sse4.1
|
|
||||||
disable-stats
|
|
||||||
force-aligned-32
|
|
||||||
force-aligned-64
|
|
||||||
gradle
|
|
||||||
i686-linux-asan
|
|
||||||
i686-linux-clang
|
|
||||||
i686-linux-gnu
|
|
||||||
i686-w64-mingw32
|
|
||||||
mips2el-linux-gnu
|
|
||||||
mips32dspr2el-linux-gnu
|
|
||||||
mips32eb-linux-gnu
|
|
||||||
mips32el-linux-gnu
|
|
||||||
mips32r2el-linux-gnu
|
|
||||||
mips32r5el-linux-gnu
|
|
||||||
mips64r2el-linux-gnu
|
|
||||||
mips64r6el-linux-gnu
|
|
||||||
native
|
|
||||||
reduce-csp
|
|
||||||
reduce-size
|
|
||||||
reduce-size-disable-stats
|
|
||||||
visibility-default-gnu
|
|
||||||
visibility-hidden-clang
|
|
||||||
visibility-hidden-gnu
|
|
||||||
wasm
|
|
||||||
x86_64-linux-clang
|
|
||||||
x86_64-linux-gnu
|
|
||||||
x86_64-linux-msan
|
|
||||||
x86_64-w64-mingw32
|
|
||||||
Environment variables:
|
|
||||||
WORKSPACE directory where the build is done
|
|
||||||
EOF
|
|
||||||
}
|
|
||||||
|
|
||||||
################################################################################
|
|
||||||
echo "Building libwebp in ${WORKSPACE}"
|
|
||||||
|
|
||||||
if [[ ! -d "${WORKSPACE}" ]]; then
|
|
||||||
log_err "${WORKSPACE} directory does not exist"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
BUILD_TYPE=${1:?"Build type not defined.$(
|
|
||||||
echo
|
|
||||||
usage
|
|
||||||
)"}
|
|
||||||
TARGET=${2:?"Target not defined.$(
|
|
||||||
echo
|
|
||||||
usage
|
|
||||||
)"}
|
|
||||||
readonly BUILD_DIR="${WORKSPACE}/build-${BUILD_TYPE}"
|
|
||||||
|
|
||||||
trap 'cleanup ${BUILD_DIR}' EXIT
|
|
||||||
make_build_dir "${BUILD_DIR}"
|
|
||||||
|
|
||||||
config_flags=()
|
|
||||||
case "${BUILD_TYPE}" in
|
|
||||||
shared*) ;; # Valid BUILD_TYPE but no setup required
|
|
||||||
static*) config_flags+=("--disable-shared") ;;
|
|
||||||
experimental) config_flags+=("--enable-experimental") ;;
|
|
||||||
*)
|
|
||||||
log_err "Invalid BUILD_TYPE"
|
|
||||||
usage
|
|
||||||
exit 1
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
if grep -m 1 -q "enable-asserts" "${LIBWEBP_ROOT}/configure.ac"; then
|
|
||||||
config_flags+=("--enable-asserts")
|
|
||||||
fi
|
|
||||||
|
|
||||||
case "${TARGET}" in
|
|
||||||
aarch64-linux-clang)
|
|
||||||
TARGET="aarch64-linux-gnu"
|
|
||||||
CC="clang"
|
|
||||||
CC="${CC} --target=aarch64-linux-gnu"
|
|
||||||
export CC
|
|
||||||
export CFLAGS="-isystem /usr/aarch64-linux-gnu/include"
|
|
||||||
;;
|
|
||||||
arm-linux-gnueabi)
|
|
||||||
export CFLAGS="-O3 -march=armv7-a -mfloat-abi=softfp -ftree-vectorize"
|
|
||||||
;;
|
|
||||||
arm-neon-linux-gnueabi)
|
|
||||||
TARGET="arm-linux-gnueabi"
|
|
||||||
CFLAGS="-O3 -march=armv7-a -mfpu=neon -mfloat-abi=softfp -ftree-vectorize"
|
|
||||||
export CFLAGS
|
|
||||||
;;
|
|
||||||
mips2el-linux-gnu)
|
|
||||||
export CFLAGS="-EL -O2 -mips2"
|
|
||||||
TARGET="mipsel-linux-gnu"
|
|
||||||
;;
|
|
||||||
mips32el-linux-gnu)
|
|
||||||
export CFLAGS="-EL -O2 -mips32"
|
|
||||||
TARGET="mipsel-linux-gnu"
|
|
||||||
;;
|
|
||||||
mips32r2el-linux-gnu)
|
|
||||||
export CFLAGS="-EL -O2 -mips32r2"
|
|
||||||
TARGET="mipsel-linux-gnu"
|
|
||||||
;;
|
|
||||||
mips32dspr2el-linux-gnu)
|
|
||||||
export CFLAGS="-EL -O2 -mdspr2"
|
|
||||||
TARGET="mipsel-linux-gnu"
|
|
||||||
;;
|
|
||||||
mips32r5el-linux-gnu)
|
|
||||||
export CFLAGS="-EL -O2 -mips32r5 -mmsa"
|
|
||||||
TARGET="mipsel-linux-gnu"
|
|
||||||
;;
|
|
||||||
mips32eb-linux-gnu)
|
|
||||||
export CFLAGS="-EB -O2 -mips32"
|
|
||||||
TARGET="mips-linux-gnu"
|
|
||||||
;;
|
|
||||||
mips64r2el-linux-gnu)
|
|
||||||
export CFLAGS="-EL -O2 -mips64r2 -mabi=64"
|
|
||||||
TARGET="mips64el-linux-gnuabi64"
|
|
||||||
;;
|
|
||||||
mips64r6el-linux-gnu)
|
|
||||||
export CFLAGS="-EL -O2 -mips64r6 -mabi=64 -mmsa"
|
|
||||||
TARGET="mips-img-linux-gnu"
|
|
||||||
;;
|
|
||||||
i686-linux-gnu)
|
|
||||||
export CC="gcc -m32"
|
|
||||||
;;
|
|
||||||
i686-linux-clang)
|
|
||||||
TARGET="i686-linux-gnu"
|
|
||||||
export CC="clang -m32"
|
|
||||||
;;
|
|
||||||
i686-linux-asan)
|
|
||||||
TARGET="i686-linux-gnu"
|
|
||||||
export CC="clang -m32 -fsanitize=address"
|
|
||||||
;;
|
|
||||||
i686-linux-msan)
|
|
||||||
TARGET="i686-linux-gnu"
|
|
||||||
export CC="clang -m32 -fsanitize=memory"
|
|
||||||
;;
|
|
||||||
x86_64-linux-clang)
|
|
||||||
TARGET="x86_64-linux-gnu"
|
|
||||||
export CC=clang
|
|
||||||
;;
|
|
||||||
x86_64-linux-msan)
|
|
||||||
TARGET="x86_64-linux-gnu"
|
|
||||||
export CC="clang -fsanitize=memory"
|
|
||||||
;;
|
|
||||||
force-aligned-32)
|
|
||||||
config_flags+=("--enable-aligned")
|
|
||||||
TARGET="i686-linux-gnu"
|
|
||||||
export CC="gcc -m32"
|
|
||||||
;;
|
|
||||||
force-aligned-64)
|
|
||||||
config_flags+=("--enable-aligned")
|
|
||||||
TARGET="x86_64-linux-gnu"
|
|
||||||
;;
|
|
||||||
visibility-default-*)
|
|
||||||
export CFLAGS="-O2 -g -fvisibility=default"
|
|
||||||
TARGET="x86_64-linux-gnu"
|
|
||||||
;;
|
|
||||||
visibility-hidden-*)
|
|
||||||
export CFLAGS="-O2 -g -fvisibility=hidden"
|
|
||||||
if [[ "${TARGET}" = "visibility-hidden-clang" ]]; then
|
|
||||||
export CC=clang
|
|
||||||
fi
|
|
||||||
TARGET="x86_64-linux-gnu"
|
|
||||||
;;
|
|
||||||
disable-sse4.1)
|
|
||||||
grep "${TARGET}" "${LIBWEBP_ROOT}/configure.ac" || exit 0
|
|
||||||
config_flags+=("--${TARGET}")
|
|
||||||
TARGET="x86_64-linux-gnu"
|
|
||||||
;;
|
|
||||||
disable-near-lossless)
|
|
||||||
grep "${TARGET}" "${LIBWEBP_ROOT}/configure.ac" || exit 0
|
|
||||||
config_flags+=("--${TARGET}")
|
|
||||||
TARGET="x86_64-linux-gnu"
|
|
||||||
;;
|
|
||||||
disable-stats)
|
|
||||||
git -C "${LIBWEBP_ROOT}" grep WEBP_DISABLE_STATS || exit 0
|
|
||||||
export CFLAGS="-O2 -g -DWEBP_DISABLE_STATS"
|
|
||||||
TARGET="x86_64-linux-gnu"
|
|
||||||
;;
|
|
||||||
reduce-size)
|
|
||||||
git -C "${LIBWEBP_ROOT}" grep WEBP_REDUCE_SIZE || exit 0
|
|
||||||
export CFLAGS="-O2 -g -DWEBP_REDUCE_SIZE"
|
|
||||||
TARGET="x86_64-linux-gnu"
|
|
||||||
;;
|
|
||||||
reduce-size-disable-stats)
|
|
||||||
git -C "${LIBWEBP_ROOT}" grep -e WEBP_DISABLE_STATS -e WEBP_REDUCE_SIZE \
|
|
||||||
|| exit 0
|
|
||||||
export CFLAGS="-O2 -g -DWEBP_DISABLE_STATS -DWEBP_REDUCE_SIZE"
|
|
||||||
TARGET="x86_64-linux-gnu"
|
|
||||||
;;
|
|
||||||
reduce-csp)
|
|
||||||
git -C "${LIBWEBP_ROOT}" grep WEBP_REDUCE_CSP || exit 0
|
|
||||||
export CFLAGS="-O2 -g -DWEBP_REDUCE_CSP"
|
|
||||||
TARGET="x86_64-linux-gnu"
|
|
||||||
;;
|
|
||||||
x86_64-linux-gnu | *mingw32 | aarch64*) ;; # Default target configuration
|
|
||||||
# non-configure based builds
|
|
||||||
native)
|
|
||||||
setup_ccache
|
|
||||||
# exercise makefile.unix then quit
|
|
||||||
make -C "${LIBWEBP_ROOT}" -f makefile.unix -j all
|
|
||||||
for tgt in extras examples/anim_diff; do
|
|
||||||
grep -q -m 1 "${tgt}" "${LIBWEBP_ROOT}/makefile.unix" \
|
|
||||||
&& make -C "${LIBWEBP_ROOT}" -f makefile.unix -j "${tgt}"
|
|
||||||
done
|
|
||||||
[[ -d "${LIBWEBP_ROOT}/tests/fuzzer" ]] \
|
|
||||||
&& make -j -C "${LIBWEBP_ROOT}/tests/fuzzer" -f makefile.unix
|
|
||||||
exit 0
|
|
||||||
;;
|
|
||||||
cmake*)
|
|
||||||
setup_ccache
|
|
||||||
# exercise cmake then quit
|
|
||||||
opts=()
|
|
||||||
case "${TARGET}" in
|
|
||||||
cmake-clang)
|
|
||||||
opts+=("-DCMAKE_C_COMPILER=clang")
|
|
||||||
;;
|
|
||||||
cmake-arm)
|
|
||||||
opts+=("-DCMAKE_C_COMPILER=arm-linux-gnueabi-gcc")
|
|
||||||
case "${GERRIT_BRANCH:-}" in
|
|
||||||
portable-intrinsics | 0.6.1) exit 0 ;;
|
|
||||||
*) ;; # Skip configuration
|
|
||||||
esac
|
|
||||||
;;
|
|
||||||
cmake-aarch64)
|
|
||||||
opts+=("-DCMAKE_C_COMPILER=aarch64-linux-gnu-gcc")
|
|
||||||
case "${GERRIT_BRANCH:-}" in
|
|
||||||
portable-intrinsics | 0.6.1) exit 0 ;;
|
|
||||||
*) ;; # Skip configuration
|
|
||||||
esac
|
|
||||||
;;
|
|
||||||
*) ;; # Skip configuration
|
|
||||||
esac
|
|
||||||
case "${BUILD_TYPE}" in
|
|
||||||
static*)
|
|
||||||
opts+=("-DBUILD_SHARED_LIBS=OFF")
|
|
||||||
;;
|
|
||||||
experimental)
|
|
||||||
opts+=("-DWEBP_EXPERIMENTAL_FEATURES=ON" "-DBUILD_SHARED_LIBS=ON")
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
opts+=("-DBUILD_SHARED_LIBS=ON")
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
case "${BUILD_TYPE}" in
|
|
||||||
*debug) opts+=("-DCMAKE_BUILD_TYPE=Debug") ;;
|
|
||||||
*) opts+=("-DCMAKE_BUILD_TYPE=RelWithDebInfo") ;;
|
|
||||||
esac
|
|
||||||
cd "${BUILD_DIR}"
|
|
||||||
opts+=("-DWEBP_BUILD_CWEBP=ON" "-DWEBP_BUILD_DWEBP=ON")
|
|
||||||
grep -m 1 -q WEBP_BUILD_GIF2WEBP "${LIBWEBP_ROOT}/CMakeLists.txt" \
|
|
||||||
&& opts+=("-DWEBP_BUILD_GIF2WEBP=ON")
|
|
||||||
grep -m 1 -q WEBP_BUILD_IMG2WEBP "${LIBWEBP_ROOT}/CMakeLists.txt" \
|
|
||||||
&& opts+=("-DWEBP_BUILD_IMG2WEBP=ON")
|
|
||||||
cmake "${opts[@]}" "${LIBWEBP_ROOT}"
|
|
||||||
make VERBOSE=1 -j
|
|
||||||
case "${BUILD_TYPE}" in
|
|
||||||
static)
|
|
||||||
mkdir -p examples
|
|
||||||
cp [cd]webp examples
|
|
||||||
;;
|
|
||||||
*) ;; # Skip configuration.
|
|
||||||
esac
|
|
||||||
|
|
||||||
grep "install" "${LIBWEBP_ROOT}/CMakeLists.txt" || exit 0
|
|
||||||
|
|
||||||
make DESTDIR="${BUILD_DIR}/webp-install" install/strip
|
|
||||||
mkdir tmp
|
|
||||||
cd tmp
|
|
||||||
cat > CMakeLists.txt << EOF
|
|
||||||
cmake_minimum_required(VERSION 2.8.7)
|
|
||||||
|
|
||||||
project(libwebp C)
|
|
||||||
|
|
||||||
find_package(WebP)
|
|
||||||
if (NOT WebP_FOUND)
|
|
||||||
message(FATAL_ERROR "WebP package not found")
|
|
||||||
endif ()
|
|
||||||
message("WebP_FOUND: \${WebP_FOUND}")
|
|
||||||
message("WebP_INCLUDE_DIRS: \${WebP_INCLUDE_DIRS}")
|
|
||||||
message("WebP_LIBRARIES: \${WebP_LIBRARIES}")
|
|
||||||
message("WEBP_INCLUDE_DIRS: \${WEBP_INCLUDE_DIRS}")
|
|
||||||
message("WEBP_LIBRARIES: \${WEBP_LIBRARIES}")
|
|
||||||
EOF
|
|
||||||
cmake . "${opts[@]}" \
|
|
||||||
"-DCMAKE_PREFIX_PATH=${BUILD_DIR}/webp-install/usr/local"
|
|
||||||
exit 0
|
|
||||||
;;
|
|
||||||
gradle)
|
|
||||||
setup_ccache
|
|
||||||
# exercise gradle then quit
|
|
||||||
[[ -f "${LIBWEBP_ROOT}/gradlew" ]] || exit 0
|
|
||||||
|
|
||||||
cd "${BUILD_DIR}"
|
|
||||||
# TODO -g / --gradle-user-home could be used if there's a race between jobs
|
|
||||||
"${LIBWEBP_ROOT}/gradlew" -p "${LIBWEBP_ROOT}" buildAllExecutables
|
|
||||||
exit 0
|
|
||||||
;;
|
|
||||||
wasm)
|
|
||||||
grep -m 1 -q WEBP_ENABLE_WASM "${LIBWEBP_ROOT}/CMakeLists.txt" || exit 0
|
|
||||||
opts+=("-DCMAKE_C_COMPILER=clang" "-DWEBP_ENABLE_WASM=ON")
|
|
||||||
opts+=("-DWEBP_BUILD_CWEBP=ON" "-DWEBP_BUILD_DWEBP=ON")
|
|
||||||
case "${BUILD_TYPE}" in
|
|
||||||
*debug) opts+=("-DCMAKE_BUILD_TYPE=Debug") ;;
|
|
||||||
*) opts+=("-DCMAKE_BUILD_TYPE=RelWithDebInfo") ;;
|
|
||||||
esac
|
|
||||||
cd "${BUILD_DIR}"
|
|
||||||
cmake "${opts[@]}" "${LIBWEBP_ROOT}"
|
|
||||||
make VERBOSE=1 -j
|
|
||||||
mkdir examples
|
|
||||||
case "${BUILD_TYPE}" in
|
|
||||||
static)
|
|
||||||
mkdir -p examples
|
|
||||||
cp [cd]webp examples
|
|
||||||
;;
|
|
||||||
*) ;; # Skip configuration
|
|
||||||
esac
|
|
||||||
exit 0
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
log_err "Invalid TARGET"
|
|
||||||
usage
|
|
||||||
exit 1
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
case "${TARGET}" in
|
|
||||||
*mingw32) ;; # Skip configuration
|
|
||||||
*)
|
|
||||||
case "${TARGET}-${CC}" in
|
|
||||||
static-debug-gcc* | static-debug-)
|
|
||||||
CFLAGS="${CFLAGS} -fprofile-arcs -ftest-coverage -O0 -g"
|
|
||||||
CXXFLAGS="${CXXFLAGS} -fprofile-arcs -ftest-coverage -O0 -g"
|
|
||||||
export CFLAGS CXXFLAGS
|
|
||||||
;;
|
|
||||||
*) ;; # This case should not be reached.
|
|
||||||
esac
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
setup_ccache
|
|
||||||
|
|
||||||
cd "${LIBWEBP_ROOT}"
|
|
||||||
./autogen.sh
|
|
||||||
|
|
||||||
cd "${BUILD_DIR}"
|
|
||||||
"${LIBWEBP_ROOT}/configure" \
|
|
||||||
--host "${TARGET}" --build "$("${LIBWEBP_ROOT}/config.guess")" \
|
|
||||||
--enable-everything "${config_flags[@]}"
|
|
||||||
make -j V=1
|
|
||||||
@@ -1,224 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
# Copyright (c) 2021, Google Inc. All rights reserved.
|
|
||||||
#
|
|
||||||
# Redistribution and use in source and binary forms, with or without
|
|
||||||
# modification, are permitted provided that the following conditions are
|
|
||||||
# met:
|
|
||||||
#
|
|
||||||
# * Redistributions of source code must retain the above copyright
|
|
||||||
# notice, this list of conditions and the following disclaimer.
|
|
||||||
#
|
|
||||||
# * Redistributions in binary form must reproduce the above copyright
|
|
||||||
# notice, this list of conditions and the following disclaimer in
|
|
||||||
# the documentation and/or other materials provided with the
|
|
||||||
# distribution.
|
|
||||||
#
|
|
||||||
# * Neither the name of Google nor the names of its contributors may
|
|
||||||
# be used to endorse or promote products derived from this software
|
|
||||||
# without specific prior written permission.
|
|
||||||
#
|
|
||||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
||||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
||||||
# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
||||||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
|
|
||||||
set -xe
|
|
||||||
LIBWEBP_ROOT="$(realpath "$(dirname "$0")/..")"
|
|
||||||
readonly LIBWEBP_ROOT
|
|
||||||
readonly WORKSPACE=${WORKSPACE:-"$(mktemp -d -t webp.android.XXX)"}
|
|
||||||
# shellcheck source=infra/common.sh
|
|
||||||
source "${LIBWEBP_ROOT}/infra/common.sh"
|
|
||||||
|
|
||||||
usage() {
|
|
||||||
cat << EOF
|
|
||||||
Usage: $(basename "$0") BUILD_TYPE APP_ABI
|
|
||||||
Options:
|
|
||||||
BUILD_TYPE supported build types:
|
|
||||||
static
|
|
||||||
static-debug
|
|
||||||
shared
|
|
||||||
shared-debug
|
|
||||||
APP_ABI supported application binary interfaces:
|
|
||||||
armeabi-v7a
|
|
||||||
arm64-v8a
|
|
||||||
x86
|
|
||||||
x86_64
|
|
||||||
Environment variables:
|
|
||||||
WORKSPACE directory where the build is done.
|
|
||||||
ANDROID_NDK_DIR directory where the android ndk tools are.
|
|
||||||
EOF
|
|
||||||
}
|
|
||||||
|
|
||||||
################################################################################
|
|
||||||
echo "Building libwebp for Android in ${WORKSPACE}"
|
|
||||||
|
|
||||||
if [[ ! -d "${WORKSPACE}" ]]; then
|
|
||||||
log_err "${WORKSPACE} directory does not exist."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
readonly BUILD_TYPE=${1:?"BUILD_TYPE is not defined.$(
|
|
||||||
echo
|
|
||||||
usage
|
|
||||||
)"}
|
|
||||||
readonly APP_ABI=${2:?"APP_ABI not defined.$(
|
|
||||||
echo
|
|
||||||
usage
|
|
||||||
)"}
|
|
||||||
readonly ANDROID_NDK_DIR=${ANDROID_NDK_DIR:?"ANDROID_NDK_DIR is not defined.$(
|
|
||||||
echo
|
|
||||||
usage
|
|
||||||
)"}
|
|
||||||
readonly BUILD_DIR="${WORKSPACE}/build-${BUILD_TYPE}"
|
|
||||||
readonly STANDALONE_ANDROID_DIR="${WORKSPACE}/android"
|
|
||||||
|
|
||||||
if [[ ! -x "${ANDROID_NDK_DIR}/ndk-build" ]]; then
|
|
||||||
log_err "unable to find ndk-build in ANDROID_NDK_DIR: ${ANDROID_NDK_DIR}."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
CFLAGS=
|
|
||||||
LDFLAGS=
|
|
||||||
opts=()
|
|
||||||
case "${BUILD_TYPE}" in
|
|
||||||
*debug)
|
|
||||||
readonly APP_OPTIM="debug"
|
|
||||||
CFLAGS="-O0 -g"
|
|
||||||
opts+=("--enable-asserts")
|
|
||||||
;;
|
|
||||||
static* | shared*)
|
|
||||||
readonly APP_OPTIM="release"
|
|
||||||
CFLAGS="-O2 -g"
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
usage
|
|
||||||
exit 1
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
case "${BUILD_TYPE}" in
|
|
||||||
shared*) readonly SHARED="1" ;;
|
|
||||||
*)
|
|
||||||
readonly SHARED="0"
|
|
||||||
CFLAGS="${CFLAGS} -fPIE"
|
|
||||||
LDFLAGS="${LDFLAGS} -Wl,-pie"
|
|
||||||
opts+=("--disable-shared")
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
# Create a fresh build directory
|
|
||||||
make_build_dir "${BUILD_DIR}"
|
|
||||||
cd "${BUILD_DIR}"
|
|
||||||
ln -s "${LIBWEBP_ROOT}" jni
|
|
||||||
|
|
||||||
"${ANDROID_NDK_DIR}/ndk-build" -j2 \
|
|
||||||
APP_ABI="${APP_ABI}" \
|
|
||||||
APP_OPTIM="${APP_OPTIM}" \
|
|
||||||
ENABLE_SHARED="${SHARED}"
|
|
||||||
|
|
||||||
cd "${LIBWEBP_ROOT}"
|
|
||||||
./autogen.sh
|
|
||||||
|
|
||||||
case "${APP_ABI}" in
|
|
||||||
armeabi*) arch="arm" ;;
|
|
||||||
arm64*) arch="arm64" ;;
|
|
||||||
*) arch="${APP_ABI}" ;;
|
|
||||||
esac
|
|
||||||
# TODO(b/185520507): remove this and use the binaries from
|
|
||||||
# toolchains/llvm/prebuilt/ directly.
|
|
||||||
rm -rf "${STANDALONE_ANDROID_DIR}"
|
|
||||||
"${ANDROID_NDK_DIR}/build/tools/make_standalone_toolchain.py" \
|
|
||||||
--api 24 --arch "${arch}" --stl gnustl --install-dir \
|
|
||||||
"${STANDALONE_ANDROID_DIR}"
|
|
||||||
export PATH="${STANDALONE_ANDROID_DIR}/bin:${PATH}"
|
|
||||||
|
|
||||||
rm -rf "${BUILD_DIR}"
|
|
||||||
make_build_dir "${BUILD_DIR}"
|
|
||||||
cd "${BUILD_DIR}"
|
|
||||||
|
|
||||||
case "${arch}" in
|
|
||||||
arm)
|
|
||||||
host="arm-linux-androideabi"
|
|
||||||
case "${APP_ABI}" in
|
|
||||||
armeabi) ;;
|
|
||||||
armeabi-v7a)
|
|
||||||
CFLAGS="${CFLAGS} -march=armv7-a -mfpu=neon -mfloat-abi=softfp"
|
|
||||||
;;
|
|
||||||
*) ;; # No configuration needed
|
|
||||||
esac
|
|
||||||
;;
|
|
||||||
arm64)
|
|
||||||
host="aarch64-linux-android"
|
|
||||||
;;
|
|
||||||
x86)
|
|
||||||
host="i686-linux-android"
|
|
||||||
;;
|
|
||||||
x86_64)
|
|
||||||
host="x86_64-linux-android"
|
|
||||||
;;
|
|
||||||
*) ;; # Skip configuration
|
|
||||||
esac
|
|
||||||
|
|
||||||
setup_ccache
|
|
||||||
CC="clang"
|
|
||||||
|
|
||||||
"${LIBWEBP_ROOT}/configure" --host "${host}" --build \
|
|
||||||
"$("${LIBWEBP_ROOT}/config.guess")" CC="${CC}" CFLAGS="${CFLAGS}" \
|
|
||||||
LDFLAGS="${LDFLAGS}" "${opts[@]}"
|
|
||||||
make -j
|
|
||||||
|
|
||||||
if [[ "${GERRIT_REFSPEC:-}" = "refs/heads/portable-intrinsics" ]] \
|
|
||||||
|| [[ "${GERRIT_BRANCH:-}" = "portable-intrinsics" ]]; then
|
|
||||||
cd "${WORKSPACE}"
|
|
||||||
rm -rf build && mkdir build
|
|
||||||
cd build
|
|
||||||
standalone="${WORKSPACE}/android"
|
|
||||||
cmake ../libwebp \
|
|
||||||
-DWEBP_BUILD_DWEBP=1 \
|
|
||||||
-DCMAKE_C_COMPILER="${standalone}/bin/clang" \
|
|
||||||
-DCMAKE_PREFIX_PATH="${standalone}/sysroot/usr/lib" \
|
|
||||||
-DCMAKE_C_FLAGS=-fPIE \
|
|
||||||
-DCMAKE_EXE_LINKER_FLAGS=-Wl,-pie \
|
|
||||||
-DCMAKE_BUILD_TYPE=Release \
|
|
||||||
-DWEBP_ENABLE_WASM=1
|
|
||||||
make -j2
|
|
||||||
|
|
||||||
cd "${WORKSPACE}"
|
|
||||||
make_build_dir "${BUILD_DIR}"
|
|
||||||
cd "${BUILD_DIR}"
|
|
||||||
case "${APP_ABI}" in
|
|
||||||
armeabi-v7a | arm64*)
|
|
||||||
cmake "${LIBWEBP_ROOT}" \
|
|
||||||
-DWEBP_BUILD_DWEBP=1 \
|
|
||||||
-DCMAKE_C_COMPILER="${standalone}/bin/clang" \
|
|
||||||
-DCMAKE_PREFIX_PATH="${standalone}/sysroot/usr/lib" \
|
|
||||||
-DCMAKE_C_FLAGS='-fPIE -DENABLE_NEON_BUILTIN_MULHI_INT16X8' \
|
|
||||||
-DCMAKE_EXE_LINKER_FLAGS=-Wl,-pie \
|
|
||||||
-DCMAKE_BUILD_TYPE=Release \
|
|
||||||
-DWEBP_ENABLE_WASM=1
|
|
||||||
make -j2
|
|
||||||
;;
|
|
||||||
x86*)
|
|
||||||
cmake "${LIBWEBP_ROOT}" \
|
|
||||||
-DWEBP_BUILD_DWEBP=1 \
|
|
||||||
-DCMAKE_C_COMPILER="${standalone}/bin/clang" \
|
|
||||||
-DCMAKE_PREFIX_PATH="${standalone}/sysroot/usr/lib" \
|
|
||||||
-DCMAKE_C_FLAGS='-fPIE -DENABLE_X86_BUILTIN_MULHI_INT16X8' \
|
|
||||||
-DCMAKE_EXE_LINKER_FLAGS=-Wl,-pie \
|
|
||||||
-DCMAKE_BUILD_TYPE=Release \
|
|
||||||
-DWEBP_ENABLE_WASM=1
|
|
||||||
make -j2
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
log_err "APP_ABI not supported."
|
|
||||||
exit 1
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
fi
|
|
||||||
@@ -1,75 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
# Copyright (c) 2021, Google Inc. All rights reserved.
|
|
||||||
#
|
|
||||||
# Redistribution and use in source and binary forms, with or without
|
|
||||||
# modification, are permitted provided that the following conditions are
|
|
||||||
# met:
|
|
||||||
#
|
|
||||||
# * Redistributions of source code must retain the above copyright
|
|
||||||
# notice, this list of conditions and the following disclaimer.
|
|
||||||
#
|
|
||||||
# * Redistributions in binary form must reproduce the above copyright
|
|
||||||
# notice, this list of conditions and the following disclaimer in
|
|
||||||
# the documentation and/or other materials provided with the
|
|
||||||
# distribution.
|
|
||||||
#
|
|
||||||
# * Neither the name of Google nor the names of its contributors may
|
|
||||||
# be used to endorse or promote products derived from this software
|
|
||||||
# without specific prior written permission.
|
|
||||||
#
|
|
||||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
||||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
||||||
# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
||||||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
|
|
||||||
set -ex
|
|
||||||
|
|
||||||
readonly WORKSPACE="${WORKSPACE:-"$(mktemp -d -t webp.js.XXX)"}"
|
|
||||||
readonly BUILD_DIR="${WORKSPACE}/webp_js/"
|
|
||||||
readonly LIBWEBP_ROOT="$(realpath "$(dirname "$0")/..")"
|
|
||||||
|
|
||||||
# shellcheck source=infra/common.sh
|
|
||||||
source "${LIBWEBP_ROOT}/infra/common.sh"
|
|
||||||
|
|
||||||
usage() {
|
|
||||||
cat << EOF
|
|
||||||
Usage: $(basename "$0")
|
|
||||||
Environment variables:
|
|
||||||
WORKSPACE directory where the build is done
|
|
||||||
EMSDK_DIR directory where emsdk is installed
|
|
||||||
EOF
|
|
||||||
}
|
|
||||||
|
|
||||||
[[ -d "${EMSDK_DIR:?Not defined}" ]] \
|
|
||||||
|| (log_err "${EMSDK_DIR} is not a valid directory." && exit 1)
|
|
||||||
|
|
||||||
# shellcheck source=/opt/emsdk/emsdk_env.sh
|
|
||||||
source "${EMSDK_DIR}/emsdk_env.sh"
|
|
||||||
|
|
||||||
readonly EMSCRIPTEN=${EMSCRIPTEN:-"${EMSDK}/upstream/emscripten"}
|
|
||||||
readonly \
|
|
||||||
EMSCRIPTEN_CMAKE_FILE="${EMSCRIPTEN}/cmake/Modules/Platform/Emscripten.cmake"
|
|
||||||
make_build_dir "${BUILD_DIR}"
|
|
||||||
|
|
||||||
pushd "${BUILD_DIR}"
|
|
||||||
opts=("-GUnix Makefiles" "-DWEBP_BUILD_WEBP_JS=ON")
|
|
||||||
if [[ -z "$(command -v emcmake)" ]]; then
|
|
||||||
opts+=("-DCMAKE_TOOLCHAIN_FILE=${EMSCRIPTEN_CMAKE_FILE}")
|
|
||||||
cmake \
|
|
||||||
"${opts[@]}" \
|
|
||||||
"${LIBWEBP_ROOT}"
|
|
||||||
make -j
|
|
||||||
else
|
|
||||||
emcmake cmake \
|
|
||||||
"${opts[@]}" \
|
|
||||||
"${LIBWEBP_ROOT}"
|
|
||||||
emmake make -j
|
|
||||||
fi
|
|
||||||
popd
|
|
||||||
@@ -1,98 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
# Copyright (c) 2021, Google Inc. All rights reserved.
|
|
||||||
#
|
|
||||||
# Redistribution and use in source and binary forms, with or without
|
|
||||||
# modification, are permitted provided that the following conditions are
|
|
||||||
# met:
|
|
||||||
#
|
|
||||||
# * Redistributions of source code must retain the above copyright
|
|
||||||
# notice, this list of conditions and the following disclaimer.
|
|
||||||
#
|
|
||||||
# * Redistributions in binary form must reproduce the above copyright
|
|
||||||
# notice, this list of conditions and the following disclaimer in
|
|
||||||
# the documentation and/or other materials provided with the
|
|
||||||
# distribution.
|
|
||||||
#
|
|
||||||
# * Neither the name of Google nor the names of its contributors may
|
|
||||||
# be used to endorse or promote products derived from this software
|
|
||||||
# without specific prior written permission.
|
|
||||||
#
|
|
||||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
||||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
||||||
# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
||||||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
|
|
||||||
set -xe
|
|
||||||
|
|
||||||
LIBWEBP_ROOT="$(realpath "$(dirname "$0")/..")"
|
|
||||||
readonly LIBWEBP_ROOT
|
|
||||||
readonly WORKSPACE=${WORKSPACE:-"$(mktemp -d -t webp.scanbuild.XXX)"}
|
|
||||||
|
|
||||||
# shellcheck source=infra/common.sh
|
|
||||||
source "${LIBWEBP_ROOT}/infra/common.sh"
|
|
||||||
|
|
||||||
usage() {
|
|
||||||
cat << EOF
|
|
||||||
Usage: $(basename "$0") MODE
|
|
||||||
Options:
|
|
||||||
MODE supported scan modes: (shallow|deep)
|
|
||||||
Environment variables:
|
|
||||||
WORKSPACE directory where the build is done.
|
|
||||||
EOF
|
|
||||||
}
|
|
||||||
|
|
||||||
#######################################
|
|
||||||
# Wrap clang-tools scan-build.
|
|
||||||
# Globals:
|
|
||||||
# OUTPUT_DIR target directory where scan-build report is generated.
|
|
||||||
# MODE scan-build mode
|
|
||||||
# Arguments:
|
|
||||||
# $* scan-build additional args.
|
|
||||||
# Returns:
|
|
||||||
# scan-build retcode
|
|
||||||
#######################################
|
|
||||||
scan_build() {
|
|
||||||
scan-build -o "${OUTPUT_DIR}" --use-analyzer="$(command -v clang)" \
|
|
||||||
-analyzer-config mode="${MODE}" "$*"
|
|
||||||
}
|
|
||||||
|
|
||||||
MODE=${1:?"MODE is not specified.$(
|
|
||||||
echo
|
|
||||||
usage
|
|
||||||
)"}
|
|
||||||
|
|
||||||
readonly OUTPUT_DIR="${WORKSPACE}/output-${MODE}"
|
|
||||||
readonly BUILD_DIR="${WORKSPACE}/build"
|
|
||||||
|
|
||||||
make_build_dir "${OUTPUT_DIR}"
|
|
||||||
make_build_dir "${BUILD_DIR}"
|
|
||||||
|
|
||||||
cd "${LIBWEBP_ROOT}"
|
|
||||||
./autogen.sh
|
|
||||||
|
|
||||||
cd "${BUILD_DIR}"
|
|
||||||
grep -m 1 -q 'enable-asserts' "${LIBWEBP_ROOT}/configure.ac" \
|
|
||||||
&& args='--enable-asserts'
|
|
||||||
scan_build "${LIBWEBP_ROOT}/configure" --enable-everything "${args}"
|
|
||||||
scan_build make -j4
|
|
||||||
|
|
||||||
index="$(find "${OUTPUT_DIR}" -name index.html)"
|
|
||||||
if [[ -f "${index}" ]]; then
|
|
||||||
mv "$(dirname "${index}")/"* "${OUTPUT_DIR}"
|
|
||||||
else
|
|
||||||
# make a empty report to wipe out any old bug reports.
|
|
||||||
cat << EOT > "${OUTPUT_DIR}/index.html"
|
|
||||||
<html>
|
|
||||||
<body>
|
|
||||||
No bugs reported.
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
EOT
|
|
||||||
fi
|
|
||||||
75
iosbuild.sh
75
iosbuild.sh
@@ -1,21 +1,17 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
#
|
#
|
||||||
# This script generates 'WebP.framework' and 'WebPDecoder.framework',
|
# This script generates 'WebP.framework' and 'WebPDecoder.framework'. An iOS
|
||||||
# 'WebPDemux.framework' and 'WebPMux.framework'.
|
# app can decode WebP images by including 'WebPDecoder.framework' and both
|
||||||
# An iOS app can decode WebP images by including 'WebPDecoder.framework' and
|
# encode and decode WebP images by including 'WebP.framework'.
|
||||||
# both encode and decode WebP images by including 'WebP.framework'.
|
|
||||||
#
|
#
|
||||||
# Run ./iosbuild.sh to generate the frameworks under the current directory
|
# Run ./iosbuild.sh to generate the frameworks under the current directory
|
||||||
# (the previous build will be erased if it exists).
|
# (the previous build will be erased if it exists).
|
||||||
#
|
#
|
||||||
# This script is inspired by the build script written by Carson McDonald.
|
# This script is inspired by the build script written by Carson McDonald.
|
||||||
# (https://www.ioncannon.net/programming/1483/using-webp-to-reduce-native-ios-app-size/).
|
# (http://www.ioncannon.net/programming/1483/using-webp-to-reduce-native-ios-app-size/).
|
||||||
|
|
||||||
set -e
|
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
|
# Extract the latest SDK version from the final field of the form: iphoneosX.Y
|
||||||
readonly SDK=$(xcodebuild -showsdks \
|
readonly SDK=$(xcodebuild -showsdks \
|
||||||
| grep iphoneos | sort | tail -n 1 | awk '{print substr($NF, 9)}'
|
| grep iphoneos | sort | tail -n 1 | awk '{print substr($NF, 9)}'
|
||||||
@@ -39,55 +35,35 @@ readonly TOPDIR=$(pwd)
|
|||||||
readonly BUILDDIR="${TOPDIR}/iosbuild"
|
readonly BUILDDIR="${TOPDIR}/iosbuild"
|
||||||
readonly TARGETDIR="${TOPDIR}/WebP.framework"
|
readonly TARGETDIR="${TOPDIR}/WebP.framework"
|
||||||
readonly DECTARGETDIR="${TOPDIR}/WebPDecoder.framework"
|
readonly DECTARGETDIR="${TOPDIR}/WebPDecoder.framework"
|
||||||
readonly MUXTARGETDIR="${TOPDIR}/WebPMux.framework"
|
|
||||||
readonly DEMUXTARGETDIR="${TOPDIR}/WebPDemux.framework"
|
|
||||||
readonly DEVELOPER=$(xcode-select --print-path)
|
readonly DEVELOPER=$(xcode-select --print-path)
|
||||||
readonly PLATFORMSROOT="${DEVELOPER}/Platforms"
|
readonly PLATFORMSROOT="${DEVELOPER}/Platforms"
|
||||||
readonly LIPO=$(xcrun -sdk iphoneos${SDK} -find lipo)
|
readonly LIPO=$(xcrun -sdk iphoneos${SDK} -find lipo)
|
||||||
LIBLIST=''
|
LIBLIST=''
|
||||||
DECLIBLIST=''
|
DECLIBLIST=''
|
||||||
MUXLIBLIST=''
|
|
||||||
DEMUXLIBLIST=''
|
|
||||||
|
|
||||||
if [[ -z "${SDK}" ]]; then
|
if [[ -z "${SDK}" ]]; then
|
||||||
echo "iOS SDK not available"
|
echo "iOS SDK not available"
|
||||||
exit 1
|
exit 1
|
||||||
elif [[ ${SDK%%.*} -gt 8 ]]; then
|
elif [[ ${SDK%%.*} -gt 8 ]]; then
|
||||||
EXTRA_CFLAGS="-fembed-bitcode"
|
EXTRA_CFLAGS="-fembed-bitcode"
|
||||||
elif [[ ${SDK%%.*} -le 6 ]]; then
|
elif [[ ${SDK} < 6.0 ]]; then
|
||||||
echo "You need iOS SDK version 6.0 or above"
|
echo "You need iOS SDK version 6.0 or above"
|
||||||
exit 1
|
exit 1
|
||||||
|
else
|
||||||
|
echo "iOS SDK Version ${SDK}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "Xcode Version: ${XCODE}"
|
rm -rf ${BUILDDIR} ${TARGETDIR} ${DECTARGETDIR}
|
||||||
echo "iOS SDK Version: ${SDK}"
|
mkdir -p ${BUILDDIR} ${TARGETDIR}/Headers/ ${DECTARGETDIR}/Headers/
|
||||||
|
|
||||||
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/
|
|
||||||
|
|
||||||
if [[ ! -e ${SRCDIR}/configure ]]; then
|
if [[ ! -e ${SRCDIR}/configure ]]; then
|
||||||
if ! (cd ${SRCDIR} && sh autogen.sh); then
|
if ! (cd ${SRCDIR} && sh autogen.sh); then
|
||||||
cat << EOF
|
cat <<EOT
|
||||||
Error creating configure script!
|
Error creating configure script!
|
||||||
This script requires the autoconf/automake and libtool to build. MacPorts can
|
This script requires the autoconf/automake and libtool to build. MacPorts can
|
||||||
be used to obtain these:
|
be used to obtain these:
|
||||||
https://www.macports.org/install.php
|
http://www.macports.org/install.php
|
||||||
EOF
|
EOT
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
@@ -121,7 +97,7 @@ for PLATFORM in ${PLATFORMS}; do
|
|||||||
SDKROOT="${PLATFORMSROOT}/"
|
SDKROOT="${PLATFORMSROOT}/"
|
||||||
SDKROOT+="${PLATFORM}.platform/Developer/SDKs/${PLATFORM}${SDK}.sdk/"
|
SDKROOT+="${PLATFORM}.platform/Developer/SDKs/${PLATFORM}${SDK}.sdk/"
|
||||||
CFLAGS="-arch ${ARCH2:-${ARCH}} -pipe -isysroot ${SDKROOT} -O3 -DNDEBUG"
|
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
|
set -x
|
||||||
export PATH="${DEVROOT}/usr/bin:${OLDPATH}"
|
export PATH="${DEVROOT}/usr/bin:${OLDPATH}"
|
||||||
@@ -129,40 +105,25 @@ for PLATFORM in ${PLATFORMS}; do
|
|||||||
--build=$(${SRCDIR}/config.guess) \
|
--build=$(${SRCDIR}/config.guess) \
|
||||||
--disable-shared --enable-static \
|
--disable-shared --enable-static \
|
||||||
--enable-libwebpdecoder --enable-swap-16bit-csp \
|
--enable-libwebpdecoder --enable-swap-16bit-csp \
|
||||||
--enable-libwebpmux \
|
|
||||||
CFLAGS="${CFLAGS}"
|
CFLAGS="${CFLAGS}"
|
||||||
set +x
|
set +x
|
||||||
|
|
||||||
# Build only the libraries, skip the examples.
|
# run make only in the src/ directory to create libwebp.a/libwebpdecoder.a
|
||||||
make V=0 -C sharpyuv
|
cd src/
|
||||||
make V=0 -C src install
|
make V=0
|
||||||
|
make install
|
||||||
|
|
||||||
LIBLIST+=" ${ROOTDIR}/lib/libwebp.a"
|
LIBLIST+=" ${ROOTDIR}/lib/libwebp.a"
|
||||||
DECLIBLIST+=" ${ROOTDIR}/lib/libwebpdecoder.a"
|
DECLIBLIST+=" ${ROOTDIR}/lib/libwebpdecoder.a"
|
||||||
MUXLIBLIST+=" ${ROOTDIR}/lib/libwebpmux.a"
|
|
||||||
DEMUXLIBLIST+=" ${ROOTDIR}/lib/libwebpdemux.a"
|
|
||||||
|
|
||||||
make clean
|
make clean
|
||||||
|
cd ..
|
||||||
|
|
||||||
export PATH=${OLDPATH}
|
export PATH=${OLDPATH}
|
||||||
done
|
done
|
||||||
|
|
||||||
echo "LIBLIST = ${LIBLIST}"
|
|
||||||
cp -a ${SRCDIR}/src/webp/{decode,encode,types}.h ${TARGETDIR}/Headers/
|
cp -a ${SRCDIR}/src/webp/{decode,encode,types}.h ${TARGETDIR}/Headers/
|
||||||
${LIPO} -create ${LIBLIST} -output ${TARGETDIR}/WebP
|
${LIPO} -create ${LIBLIST} -output ${TARGETDIR}/WebP
|
||||||
|
|
||||||
echo "DECLIBLIST = ${DECLIBLIST}"
|
|
||||||
cp -a ${SRCDIR}/src/webp/{decode,types}.h ${DECTARGETDIR}/Headers/
|
cp -a ${SRCDIR}/src/webp/{decode,types}.h ${DECTARGETDIR}/Headers/
|
||||||
${LIPO} -create ${DECLIBLIST} -output ${DECTARGETDIR}/WebPDecoder
|
${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"
|
|
||||||
|
|||||||
119
makefile.unix
119
makefile.unix
@@ -25,29 +25,16 @@ ifeq ($(strip $(shell uname)), Darwin)
|
|||||||
# Failure observed with: gcc 4.2.1 and 4.0.1.
|
# Failure observed with: gcc 4.2.1 and 4.0.1.
|
||||||
EXTRA_FLAGS += -fno-common
|
EXTRA_FLAGS += -fno-common
|
||||||
EXTRA_FLAGS += -DHAVE_GLUT_GLUT_H
|
EXTRA_FLAGS += -DHAVE_GLUT_GLUT_H
|
||||||
EXTRA_FLAGS += -Wno-deprecated-declarations
|
|
||||||
EXTRA_FLAGS += -I/opt/local/include
|
EXTRA_FLAGS += -I/opt/local/include
|
||||||
EXTRA_LIBS += -L/opt/local/lib
|
EXTRA_LIBS += -L/opt/local/lib
|
||||||
GL_LIBS = -framework GLUT -framework OpenGL
|
GL_LIBS = -framework GLUT -framework OpenGL
|
||||||
else
|
else
|
||||||
EXTRA_FLAGS += -I/usr/local/include
|
|
||||||
EXTRA_LIBS += -L/usr/local/lib
|
|
||||||
GL_LIBS = -lglut -lGL
|
GL_LIBS = -lglut -lGL
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# SDL flags: use sdl-config if it exists
|
|
||||||
SDL_CONFIG = $(shell sdl-config --version 2> /dev/null)
|
|
||||||
ifneq ($(SDL_CONFIG),)
|
|
||||||
SDL_LIBS = $(shell sdl-config --libs)
|
|
||||||
SDL_FLAGS = $(shell sdl-config --cflags)
|
|
||||||
else
|
|
||||||
# use best-guess
|
|
||||||
SDL_LIBS = -lSDL
|
|
||||||
SDL_FLAGS =
|
|
||||||
endif
|
|
||||||
|
|
||||||
# To install libraries on Mac OS X:
|
# To install libraries on Mac OS X:
|
||||||
# 1. Install MacPorts (https://www.macports.org/install.php)
|
# 1. Install MacPorts (http://www.macports.org/install.php)
|
||||||
# 2. Run "sudo port install jpeg"
|
# 2. Run "sudo port install jpeg"
|
||||||
# 3. Run "sudo port install libpng"
|
# 3. Run "sudo port install libpng"
|
||||||
# 4. Run "sudo port install tiff"
|
# 4. Run "sudo port install tiff"
|
||||||
@@ -64,8 +51,11 @@ endif
|
|||||||
# 'make -f makefile.unix EXTRA_FLAGS=-m32' to that effect.
|
# 'make -f makefile.unix EXTRA_FLAGS=-m32' to that effect.
|
||||||
# EXTRA_FLAGS += -m32
|
# EXTRA_FLAGS += -m32
|
||||||
|
|
||||||
|
# Extra flags to enable experimental features and code
|
||||||
|
# EXTRA_FLAGS += -DWEBP_EXPERIMENTAL_FEATURES
|
||||||
|
|
||||||
# Extra flags to enable byte swap for 16 bit colorspaces.
|
# Extra flags to enable byte swap for 16 bit colorspaces.
|
||||||
# EXTRA_FLAGS += -DWEBP_SWAP_16BIT_CSP=1
|
# EXTRA_FLAGS += -DWEBP_SWAP_16BIT_CSP
|
||||||
|
|
||||||
# Extra flags to enable multi-threading
|
# Extra flags to enable multi-threading
|
||||||
EXTRA_FLAGS += -DWEBP_USE_THREAD
|
EXTRA_FLAGS += -DWEBP_USE_THREAD
|
||||||
@@ -89,6 +79,12 @@ EXTRA_FLAGS += -DWEBP_HAVE_SSE41
|
|||||||
src/dsp/%_sse41.o: EXTRA_FLAGS += -msse4.1
|
src/dsp/%_sse41.o: EXTRA_FLAGS += -msse4.1
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
# AVX2-specific flags:
|
||||||
|
ifeq ($(HAVE_AVX2), 1)
|
||||||
|
EXTRA_FLAGS += -DWEBP_HAVE_AVX2
|
||||||
|
src/dsp/%_avx2.o: EXTRA_FLAGS += -mavx2
|
||||||
|
endif
|
||||||
|
|
||||||
# NEON-specific flags:
|
# NEON-specific flags:
|
||||||
# EXTRA_FLAGS += -march=armv7-a -mfloat-abi=hard -mfpu=neon -mtune=cortex-a8
|
# EXTRA_FLAGS += -march=armv7-a -mfloat-abi=hard -mfpu=neon -mtune=cortex-a8
|
||||||
# -> seems to make the overall lib slower: -fno-split-wide-types
|
# -> seems to make the overall lib slower: -fno-split-wide-types
|
||||||
@@ -105,34 +101,17 @@ endif
|
|||||||
|
|
||||||
AR = ar
|
AR = ar
|
||||||
ARFLAGS = r
|
ARFLAGS = r
|
||||||
CPPFLAGS = -I. -Isrc/ -Wall
|
CPPFLAGS = -Isrc/ -Wall
|
||||||
ifeq ($(DEBUG), 1)
|
CFLAGS = -O3 -DNDEBUG $(EXTRA_FLAGS)
|
||||||
CFLAGS = -g
|
|
||||||
else
|
|
||||||
CFLAGS = -O3 -DNDEBUG
|
|
||||||
endif
|
|
||||||
CFLAGS += $(EXTRA_FLAGS)
|
|
||||||
CC = gcc
|
CC = gcc
|
||||||
INSTALL = install
|
INSTALL = install
|
||||||
GROFF = /usr/bin/groff
|
GROFF = /usr/bin/groff
|
||||||
COL = /usr/bin/col
|
COL = /usr/bin/col
|
||||||
LDFLAGS = $(EXTRA_LIBS) $(EXTRA_FLAGS) -lm
|
LDFLAGS = $(EXTRA_LIBS) $(EXTRA_FLAGS) -lm
|
||||||
|
|
||||||
ifdef BITTRACE
|
|
||||||
CFLAGS += -DBITTRACE=$(BITTRACE)
|
|
||||||
endif
|
|
||||||
|
|
||||||
ANIM_UTIL_OBJS = \
|
ANIM_UTIL_OBJS = \
|
||||||
examples/anim_util.o \
|
examples/anim_util.o \
|
||||||
|
|
||||||
SHARPYUV_OBJS = \
|
|
||||||
sharpyuv/sharpyuv.o \
|
|
||||||
sharpyuv/sharpyuv_csp.o \
|
|
||||||
sharpyuv/sharpyuv_dsp.o \
|
|
||||||
sharpyuv/sharpyuv_gamma.o \
|
|
||||||
sharpyuv/sharpyuv_neon.o \
|
|
||||||
sharpyuv/sharpyuv_sse2.o \
|
|
||||||
|
|
||||||
DEC_OBJS = \
|
DEC_OBJS = \
|
||||||
src/dec/alpha_dec.o \
|
src/dec/alpha_dec.o \
|
||||||
src/dec/buffer_dec.o \
|
src/dec/buffer_dec.o \
|
||||||
@@ -174,7 +153,6 @@ DSP_DEC_OBJS = \
|
|||||||
src/dsp/lossless_msa.o \
|
src/dsp/lossless_msa.o \
|
||||||
src/dsp/lossless_neon.o \
|
src/dsp/lossless_neon.o \
|
||||||
src/dsp/lossless_sse2.o \
|
src/dsp/lossless_sse2.o \
|
||||||
src/dsp/lossless_sse41.o \
|
|
||||||
src/dsp/rescaler.o \
|
src/dsp/rescaler.o \
|
||||||
src/dsp/rescaler_mips32.o \
|
src/dsp/rescaler_mips32.o \
|
||||||
src/dsp/rescaler_mips_dsp_r2.o \
|
src/dsp/rescaler_mips_dsp_r2.o \
|
||||||
@@ -186,21 +164,21 @@ DSP_DEC_OBJS = \
|
|||||||
src/dsp/upsampling_msa.o \
|
src/dsp/upsampling_msa.o \
|
||||||
src/dsp/upsampling_neon.o \
|
src/dsp/upsampling_neon.o \
|
||||||
src/dsp/upsampling_sse2.o \
|
src/dsp/upsampling_sse2.o \
|
||||||
src/dsp/upsampling_sse41.o \
|
|
||||||
src/dsp/yuv.o \
|
src/dsp/yuv.o \
|
||||||
src/dsp/yuv_mips32.o \
|
src/dsp/yuv_mips32.o \
|
||||||
src/dsp/yuv_mips_dsp_r2.o \
|
src/dsp/yuv_mips_dsp_r2.o \
|
||||||
src/dsp/yuv_neon.o \
|
|
||||||
src/dsp/yuv_sse2.o \
|
src/dsp/yuv_sse2.o \
|
||||||
src/dsp/yuv_sse41.o \
|
|
||||||
|
|
||||||
DSP_ENC_OBJS = \
|
DSP_ENC_OBJS = \
|
||||||
|
src/dsp/argb.o \
|
||||||
|
src/dsp/argb_mips_dsp_r2.o \
|
||||||
|
src/dsp/argb_sse2.o \
|
||||||
src/dsp/cost.o \
|
src/dsp/cost.o \
|
||||||
src/dsp/cost_mips32.o \
|
src/dsp/cost_mips32.o \
|
||||||
src/dsp/cost_mips_dsp_r2.o \
|
src/dsp/cost_mips_dsp_r2.o \
|
||||||
src/dsp/cost_neon.o \
|
|
||||||
src/dsp/cost_sse2.o \
|
src/dsp/cost_sse2.o \
|
||||||
src/dsp/enc.o \
|
src/dsp/enc.o \
|
||||||
|
src/dsp/enc_avx2.o \
|
||||||
src/dsp/enc_mips32.o \
|
src/dsp/enc_mips32.o \
|
||||||
src/dsp/enc_mips_dsp_r2.o \
|
src/dsp/enc_mips_dsp_r2.o \
|
||||||
src/dsp/enc_msa.o \
|
src/dsp/enc_msa.o \
|
||||||
@@ -214,16 +192,14 @@ DSP_ENC_OBJS = \
|
|||||||
src/dsp/lossless_enc_neon.o \
|
src/dsp/lossless_enc_neon.o \
|
||||||
src/dsp/lossless_enc_sse2.o \
|
src/dsp/lossless_enc_sse2.o \
|
||||||
src/dsp/lossless_enc_sse41.o \
|
src/dsp/lossless_enc_sse41.o \
|
||||||
src/dsp/ssim.o \
|
|
||||||
src/dsp/ssim_sse2.o \
|
|
||||||
|
|
||||||
ENC_OBJS = \
|
ENC_OBJS = \
|
||||||
src/enc/alpha_enc.o \
|
src/enc/alpha_enc.o \
|
||||||
src/enc/analysis_enc.o \
|
src/enc/analysis_enc.o \
|
||||||
src/enc/backward_references_cost_enc.o \
|
|
||||||
src/enc/backward_references_enc.o \
|
src/enc/backward_references_enc.o \
|
||||||
src/enc/config_enc.o \
|
src/enc/config_enc.o \
|
||||||
src/enc/cost_enc.o \
|
src/enc/cost_enc.o \
|
||||||
|
src/enc/delta_palettization_enc.o \
|
||||||
src/enc/filter_enc.o \
|
src/enc/filter_enc.o \
|
||||||
src/enc/frame_enc.o \
|
src/enc/frame_enc.o \
|
||||||
src/enc/histogram_enc.o \
|
src/enc/histogram_enc.o \
|
||||||
@@ -247,7 +223,6 @@ EX_FORMAT_DEC_OBJS = \
|
|||||||
imageio/jpegdec.o \
|
imageio/jpegdec.o \
|
||||||
imageio/metadata.o \
|
imageio/metadata.o \
|
||||||
imageio/pngdec.o \
|
imageio/pngdec.o \
|
||||||
imageio/pnmdec.o \
|
|
||||||
imageio/tiffdec.o \
|
imageio/tiffdec.o \
|
||||||
imageio/webpdec.o \
|
imageio/webpdec.o \
|
||||||
|
|
||||||
@@ -290,8 +265,8 @@ EXTRA_OBJS = \
|
|||||||
extras/quality_estimate.o \
|
extras/quality_estimate.o \
|
||||||
|
|
||||||
LIBWEBPDECODER_OBJS = $(DEC_OBJS) $(DSP_DEC_OBJS) $(UTILS_DEC_OBJS)
|
LIBWEBPDECODER_OBJS = $(DEC_OBJS) $(DSP_DEC_OBJS) $(UTILS_DEC_OBJS)
|
||||||
LIBWEBP_OBJS = $(SHARPYUV_OBJS) $(LIBWEBPDECODER_OBJS) $(ENC_OBJS) \
|
LIBWEBP_OBJS = $(LIBWEBPDECODER_OBJS) $(ENC_OBJS) $(DSP_ENC_OBJS) \
|
||||||
$(DSP_ENC_OBJS) $(UTILS_ENC_OBJS)
|
$(UTILS_ENC_OBJS)
|
||||||
LIBWEBPMUX_OBJS = $(MUX_OBJS)
|
LIBWEBPMUX_OBJS = $(MUX_OBJS)
|
||||||
LIBWEBPDEMUX_OBJS = $(DEMUX_OBJS)
|
LIBWEBPDEMUX_OBJS = $(DEMUX_OBJS)
|
||||||
LIBWEBPEXTRA_OBJS = $(EXTRA_OBJS)
|
LIBWEBPEXTRA_OBJS = $(EXTRA_OBJS)
|
||||||
@@ -312,7 +287,6 @@ HDRS = \
|
|||||||
src/dec/vp8li_dec.h \
|
src/dec/vp8li_dec.h \
|
||||||
src/dec/webpi_dec.h \
|
src/dec/webpi_dec.h \
|
||||||
src/dsp/common_sse2.h \
|
src/dsp/common_sse2.h \
|
||||||
src/dsp/cpu.h \
|
|
||||||
src/dsp/dsp.h \
|
src/dsp/dsp.h \
|
||||||
src/dsp/lossless.h \
|
src/dsp/lossless.h \
|
||||||
src/dsp/lossless_common.h \
|
src/dsp/lossless_common.h \
|
||||||
@@ -322,6 +296,7 @@ HDRS = \
|
|||||||
src/dsp/yuv.h \
|
src/dsp/yuv.h \
|
||||||
src/enc/backward_references_enc.h \
|
src/enc/backward_references_enc.h \
|
||||||
src/enc/cost_enc.h \
|
src/enc/cost_enc.h \
|
||||||
|
src/enc/delta_palettization_enc.h \
|
||||||
src/enc/histogram_enc.h \
|
src/enc/histogram_enc.h \
|
||||||
src/enc/vp8i_enc.h \
|
src/enc/vp8i_enc.h \
|
||||||
src/enc/vp8li_enc.h \
|
src/enc/vp8li_enc.h \
|
||||||
@@ -353,9 +328,8 @@ OUT_LIBS += src/libwebp.a
|
|||||||
EXTRA_LIB = extras/libwebpextras.a
|
EXTRA_LIB = extras/libwebpextras.a
|
||||||
OUT_EXAMPLES = examples/cwebp examples/dwebp
|
OUT_EXAMPLES = examples/cwebp examples/dwebp
|
||||||
EXTRA_EXAMPLES = examples/gif2webp examples/vwebp examples/webpmux \
|
EXTRA_EXAMPLES = examples/gif2webp examples/vwebp examples/webpmux \
|
||||||
examples/anim_diff examples/anim_dump \
|
examples/anim_diff examples/img2webp
|
||||||
examples/img2webp examples/webpinfo
|
OTHER_EXAMPLES = extras/get_disto extras/webp_quality
|
||||||
OTHER_EXAMPLES = extras/get_disto extras/webp_quality extras/vwebp_sdl
|
|
||||||
|
|
||||||
OUTPUT = $(OUT_LIBS) $(OUT_EXAMPLES)
|
OUTPUT = $(OUT_LIBS) $(OUT_EXAMPLES)
|
||||||
ifeq ($(MAKECMDGOALS),clean)
|
ifeq ($(MAKECMDGOALS),clean)
|
||||||
@@ -382,7 +356,7 @@ src/utils/bit_reader_utils.o: src/utils/endian_inl_utils.h
|
|||||||
src/utils/bit_writer_utils.o: src/utils/endian_inl_utils.h
|
src/utils/bit_writer_utils.o: src/utils/endian_inl_utils.h
|
||||||
|
|
||||||
%.o: %.c $(HDRS)
|
%.o: %.c $(HDRS)
|
||||||
$(CC) $(CPPFLAGS) $(CFLAGS) -c $< -o $@
|
$(CC) $(CFLAGS) $(CPPFLAGS) -c $< -o $@
|
||||||
|
|
||||||
examples/libanim_util.a: $(ANIM_UTIL_OBJS)
|
examples/libanim_util.a: $(ANIM_UTIL_OBJS)
|
||||||
examples/libexample_util.a: $(EX_UTIL_OBJS)
|
examples/libexample_util.a: $(EX_UTIL_OBJS)
|
||||||
@@ -400,76 +374,52 @@ src/demux/libwebpdemux.a: $(LIBWEBPDEMUX_OBJS)
|
|||||||
$(AR) $(ARFLAGS) $@ $^
|
$(AR) $(ARFLAGS) $@ $^
|
||||||
|
|
||||||
examples/anim_diff: examples/anim_diff.o $(ANIM_UTIL_OBJS) $(GIFDEC_OBJS)
|
examples/anim_diff: examples/anim_diff.o $(ANIM_UTIL_OBJS) $(GIFDEC_OBJS)
|
||||||
examples/anim_dump: examples/anim_dump.o $(ANIM_UTIL_OBJS) $(GIFDEC_OBJS)
|
|
||||||
examples/cwebp: examples/cwebp.o
|
examples/cwebp: examples/cwebp.o
|
||||||
examples/dwebp: examples/dwebp.o
|
examples/dwebp: examples/dwebp.o
|
||||||
examples/gif2webp: examples/gif2webp.o $(GIFDEC_OBJS)
|
examples/gif2webp: examples/gif2webp.o $(GIFDEC_OBJS)
|
||||||
examples/vwebp: examples/vwebp.o
|
examples/vwebp: examples/vwebp.o
|
||||||
examples/webpmux: examples/webpmux.o
|
examples/webpmux: examples/webpmux.o
|
||||||
examples/img2webp: examples/img2webp.o
|
examples/img2webp: examples/img2webp.o
|
||||||
examples/webpinfo: examples/webpinfo.o
|
|
||||||
|
|
||||||
examples/anim_diff: examples/libanim_util.a examples/libgifdec.a
|
examples/anim_diff: examples/libanim_util.a examples/libgifdec.a
|
||||||
examples/anim_diff: src/demux/libwebpdemux.a examples/libexample_util.a
|
examples/anim_diff: src/demux/libwebpdemux.a examples/libexample_util.a
|
||||||
examples/anim_diff: imageio/libimageio_util.a src/libwebp.a
|
examples/anim_diff: imageio/libimageio_util.a src/libwebp.a
|
||||||
examples/anim_diff: override EXTRA_LIBS += $(GIF_LIBS)
|
examples/anim_diff: EXTRA_LIBS += $(GIF_LIBS)
|
||||||
examples/anim_diff: EXTRA_FLAGS += -DWEBP_HAVE_GIF
|
examples/anim_diff: EXTRA_FLAGS += -DWEBP_HAVE_GIF
|
||||||
examples/anim_dump: examples/libanim_util.a examples/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: examples/libexample_util.a
|
||||||
examples/cwebp: imageio/libimagedec.a
|
examples/cwebp: imageio/libimagedec.a
|
||||||
examples/cwebp: src/demux/libwebpdemux.a
|
|
||||||
examples/cwebp: imageio/libimageio_util.a
|
examples/cwebp: imageio/libimageio_util.a
|
||||||
examples/cwebp: src/libwebp.a
|
examples/cwebp: src/libwebp.a
|
||||||
examples/cwebp: override EXTRA_LIBS += $(CWEBP_LIBS)
|
examples/cwebp: EXTRA_LIBS += $(CWEBP_LIBS)
|
||||||
examples/dwebp: examples/libexample_util.a
|
examples/dwebp: examples/libexample_util.a
|
||||||
examples/dwebp: imageio/libimagedec.a
|
examples/dwebp: imageio/libimagedec.a
|
||||||
examples/dwebp: src/demux/libwebpdemux.a
|
|
||||||
examples/dwebp: imageio/libimageenc.a
|
examples/dwebp: imageio/libimageenc.a
|
||||||
examples/dwebp: imageio/libimageio_util.a
|
examples/dwebp: imageio/libimageio_util.a
|
||||||
examples/dwebp: src/libwebp.a
|
examples/dwebp: src/libwebp.a
|
||||||
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/libexample_util.a imageio/libimageio_util.a
|
||||||
examples/gif2webp: examples/libgifdec.a src/mux/libwebpmux.a src/libwebp.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/gif2webp: EXTRA_FLAGS += -DWEBP_HAVE_GIF
|
||||||
examples/vwebp: examples/libexample_util.a src/demux/libwebpdemux.a
|
examples/vwebp: examples/libexample_util.a src/demux/libwebpdemux.a
|
||||||
examples/vwebp: imageio/libimageio_util.a src/libwebp.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/vwebp: EXTRA_FLAGS += -DWEBP_HAVE_GL
|
||||||
examples/webpmux: examples/libexample_util.a imageio/libimageio_util.a
|
examples/webpmux: examples/libexample_util.a imageio/libimageio_util.a
|
||||||
examples/webpmux: src/mux/libwebpmux.a src/libwebpdecoder.a
|
examples/webpmux: src/mux/libwebpmux.a src/libwebpdecoder.a
|
||||||
examples/img2webp: examples/libexample_util.a imageio/libimageio_util.a
|
examples/img2webp: examples/libexample_util.a imageio/libimageio_util.a
|
||||||
examples/img2webp: imageio/libimagedec.a
|
examples/img2webp: imageio/libimagedec.a
|
||||||
examples/img2webp: src/demux/libwebpdemux.a
|
|
||||||
examples/img2webp: src/mux/libwebpmux.a src/libwebp.a
|
examples/img2webp: src/mux/libwebpmux.a src/libwebp.a
|
||||||
examples/img2webp: override EXTRA_LIBS += $(CWEBP_LIBS)
|
examples/img2webp: EXTRA_LIBS += $(CWEBP_LIBS)
|
||||||
examples/webpinfo: examples/libexample_util.a imageio/libimageio_util.a
|
|
||||||
examples/webpinfo: src/libwebpdecoder.a
|
|
||||||
|
|
||||||
extras/get_disto: extras/get_disto.o
|
extras/get_disto: extras/get_disto.o
|
||||||
extras/get_disto: imageio/libimagedec.a
|
extras/get_disto: imageio/libimagedec.a imageio/libimageio_util.a src/libwebp.a
|
||||||
extras/get_disto: src/demux/libwebpdemux.a
|
extras/get_disto: EXTRA_LIBS += $(CWEBP_LIBS)
|
||||||
extras/get_disto: imageio/libimageio_util.a
|
|
||||||
extras/get_disto: src/libwebp.a
|
|
||||||
extras/get_disto: override EXTRA_LIBS += $(CWEBP_LIBS)
|
|
||||||
|
|
||||||
extras/webp_quality: extras/webp_quality.o
|
extras/webp_quality: extras/webp_quality.o
|
||||||
extras/webp_quality: imageio/libimageio_util.a
|
extras/webp_quality: imageio/libimageio_util.a
|
||||||
extras/webp_quality: $(EXTRA_LIB) src/libwebp.a
|
extras/webp_quality: $(EXTRA_LIB) src/libwebp.a
|
||||||
|
|
||||||
extras/vwebp_sdl: extras/vwebp_sdl.o
|
|
||||||
extras/vwebp_sdl: extras/webp_to_sdl.o
|
|
||||||
extras/vwebp_sdl: imageio/libimageio_util.a
|
|
||||||
extras/vwebp_sdl: src/libwebp.a
|
|
||||||
extras/vwebp_sdl: EXTRA_FLAGS += -DWEBP_HAVE_SDL $(SDL_FLAGS)
|
|
||||||
extras/vwebp_sdl: override EXTRA_LIBS += $(SDL_LIBS)
|
|
||||||
|
|
||||||
$(OUT_EXAMPLES) $(EXTRA_EXAMPLES) $(OTHER_EXAMPLES):
|
$(OUT_EXAMPLES) $(EXTRA_EXAMPLES) $(OTHER_EXAMPLES):
|
||||||
$(CC) -o $@ $^ $(LDFLAGS)
|
$(CC) -o $@ $^ $(LDFLAGS)
|
||||||
|
|
||||||
@@ -485,9 +435,9 @@ dist: all
|
|||||||
$(INSTALL) -m644 src/mux/libwebpmux.a $(DESTDIR)/lib
|
$(INSTALL) -m644 src/mux/libwebpmux.a $(DESTDIR)/lib
|
||||||
umask 022; \
|
umask 022; \
|
||||||
for m in man/[cdv]webp.1 man/gif2webp.1 man/webpmux.1 \
|
for m in man/[cdv]webp.1 man/gif2webp.1 man/webpmux.1 \
|
||||||
man/img2webp.1 man/webpinfo.1; do \
|
man/img2webp.1; do \
|
||||||
basenam=$$(basename $$m .1); \
|
basenam=$$(basename $$m .1); \
|
||||||
$(GROFF) -t -e -man -T ascii $$m \
|
$(GROFF) -t -e -man -T utf8 $$m \
|
||||||
| $(COL) -bx >$(DESTDIR)/doc/$${basenam}.txt; \
|
| $(COL) -bx >$(DESTDIR)/doc/$${basenam}.txt; \
|
||||||
$(GROFF) -t -e -man -T html $$m \
|
$(GROFF) -t -e -man -T html $$m \
|
||||||
| $(COL) -bx >$(DESTDIR)/doc/$${basenam}.html; \
|
| $(COL) -bx >$(DESTDIR)/doc/$${basenam}.html; \
|
||||||
@@ -498,7 +448,6 @@ clean:
|
|||||||
examples/*.o examples/*~ \
|
examples/*.o examples/*~ \
|
||||||
extras/*.o extras/*~ \
|
extras/*.o extras/*~ \
|
||||||
imageio/*.o imageio/*~ \
|
imageio/*.o imageio/*~ \
|
||||||
sharpyuv/*.o sharpyuv/*~ \
|
|
||||||
src/dec/*.o src/dec/*~ \
|
src/dec/*.o src/dec/*~ \
|
||||||
src/demux/*.o src/demux/*~ \
|
src/demux/*.o src/demux/*~ \
|
||||||
src/dsp/*.o src/dsp/*~ \
|
src/dsp/*.o src/dsp/*~ \
|
||||||
|
|||||||
@@ -1,17 +1,11 @@
|
|||||||
man_MANS = cwebp.1 dwebp.1
|
man_MANS = cwebp.1 dwebp.1
|
||||||
if BUILD_MUX
|
if WANT_MUX
|
||||||
man_MANS += webpmux.1
|
man_MANS += webpmux.1
|
||||||
endif
|
endif
|
||||||
if BUILD_GIF2WEBP
|
if BUILD_GIF2WEBP
|
||||||
man_MANS += gif2webp.1
|
man_MANS += gif2webp.1
|
||||||
endif
|
endif
|
||||||
if BUILD_IMG2WEBP
|
|
||||||
man_MANS += img2webp.1
|
|
||||||
endif
|
|
||||||
if BUILD_VWEBP
|
if BUILD_VWEBP
|
||||||
man_MANS += vwebp.1
|
man_MANS += vwebp.1
|
||||||
endif
|
endif
|
||||||
if BUILD_WEBPINFO
|
|
||||||
man_MANS += webpinfo.1
|
|
||||||
endif
|
|
||||||
EXTRA_DIST = $(man_MANS)
|
EXTRA_DIST = $(man_MANS)
|
||||||
|
|||||||
41
man/cwebp.1
41
man/cwebp.1
@@ -1,5 +1,5 @@
|
|||||||
.\" Hey, EMACS: -*- nroff -*-
|
.\" Hey, EMACS: -*- nroff -*-
|
||||||
.TH CWEBP 1 "March 17, 2022"
|
.TH CWEBP 1 "January 20, 2017"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
cwebp \- compress an image file to a WebP file
|
cwebp \- compress an image file to a WebP file
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
@@ -13,7 +13,6 @@ command.
|
|||||||
.PP
|
.PP
|
||||||
\fBcwebp\fP compresses an image using the WebP format.
|
\fBcwebp\fP compresses an image using the WebP format.
|
||||||
Input format can be either PNG, JPEG, TIFF, WebP or raw Y'CbCr samples.
|
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
|
.SH OPTIONS
|
||||||
The basic options are:
|
The basic options are:
|
||||||
.TP
|
.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.
|
\-exact option is used.
|
||||||
.TP
|
.TP
|
||||||
.BI \-near_lossless " int
|
.BI \-near_lossless " int
|
||||||
Specify the level of near\-lossless image preprocessing. This option adjusts
|
Use near\-lossless image preprocessing. This option adjusts pixel values
|
||||||
pixel values to help compressibility, but has minimal impact on the visual
|
to help compressibility, but has minimal impact on the visual quality.
|
||||||
quality. It triggers lossless compression mode automatically. The range is 0
|
It triggers lossless compression mode automatically.
|
||||||
(maximum preprocessing) to 100 (no preprocessing, the default). The typical
|
Range is 0 (maximum preprocessing) to 100 (no preprocessing, the default).
|
||||||
value is around 60. Note that lossy with \fB\-q 100\fP can at times yield
|
|
||||||
better results.
|
|
||||||
.TP
|
.TP
|
||||||
.BI \-q " float
|
.BI \-q " float
|
||||||
Specify the compression factor for RGB channels between 0 and 100. The default
|
Specify the compression factor for RGB channels between 0 and 100. The default
|
||||||
@@ -90,20 +87,19 @@ additional encoding possibilities and decide on the quality gain.
|
|||||||
Lower value can result in faster processing time at the expense of
|
Lower value can result in faster processing time at the expense of
|
||||||
larger file size and lower compression quality.
|
larger file size and lower compression quality.
|
||||||
.TP
|
.TP
|
||||||
|
.BI \-resize " width height
|
||||||
|
Resize the source to a rectangle with size \fBwidth\fP x \fBheight\fP.
|
||||||
|
If either (but not both) of the \fBwidth\fP or \fBheight\fP parameters is 0,
|
||||||
|
the value will be calculated preserving the aspect\-ratio.
|
||||||
|
.TP
|
||||||
.BI \-crop " x_position y_position width height
|
.BI \-crop " x_position y_position width height
|
||||||
Crop the source to a rectangle with top\-left corner at coordinates
|
Crop the source to a rectangle with top\-left corner at coordinates
|
||||||
(\fBx_position\fP, \fBy_position\fP) and size \fBwidth\fP x \fBheight\fP.
|
(\fBx_position\fP, \fBy_position\fP) and size \fBwidth\fP x \fBheight\fP.
|
||||||
This cropping area must be fully contained within the source rectangle.
|
This cropping area must be fully contained within the source rectangle.
|
||||||
Note: the cropping is applied \fIbefore\fP any scaling.
|
|
||||||
.TP
|
|
||||||
.BI \-resize " width height
|
|
||||||
Resize the source to a rectangle with size \fBwidth\fP x \fBheight\fP.
|
|
||||||
If either (but not both) of the \fBwidth\fP or \fBheight\fP parameters is 0,
|
|
||||||
the value will be calculated preserving the aspect\-ratio. Note: scaling
|
|
||||||
is applied \fIafter\fP cropping.
|
|
||||||
.TP
|
.TP
|
||||||
.B \-mt
|
.B \-mt
|
||||||
Use multi\-threading for encoding, if possible.
|
Use multi\-threading for encoding, if possible. This option is only effective
|
||||||
|
when using lossy compression on a source with a transparency channel.
|
||||||
.TP
|
.TP
|
||||||
.B \-low_memory
|
.B \-low_memory
|
||||||
Reduce memory usage of lossy encoding by saving four times the compressed
|
Reduce memory usage of lossy encoding by saving four times the compressed
|
||||||
@@ -137,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
|
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.
|
specified, a default value of '6' passes will be used.
|
||||||
.TP
|
.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
|
.B \-af
|
||||||
Turns auto\-filter on. This algorithm will spend additional time optimizing
|
Turns auto\-filter on. This algorithm will spend additional time optimizing
|
||||||
the filtering strength to reach a well\-balanced quality.
|
the filtering strength to reach a well\-balanced quality.
|
||||||
@@ -224,7 +213,7 @@ Compute and report average PSNR (Peak\-Signal\-To\-Noise ratio).
|
|||||||
.TP
|
.TP
|
||||||
.B \-print_ssim
|
.B \-print_ssim
|
||||||
Compute and report average SSIM (structural similarity
|
Compute and report average SSIM (structural similarity
|
||||||
metric, see https://en.wikipedia.org/wiki/SSIM for additional details).
|
metric, see http://en.wikipedia.org/wiki/SSIM for additional details).
|
||||||
.TP
|
.TP
|
||||||
.B \-print_lsim
|
.B \-print_lsim
|
||||||
Compute and report local similarity metric (sum of lowest error amongst the
|
Compute and report local similarity metric (sum of lowest error amongst the
|
||||||
@@ -300,7 +289,7 @@ Please report all bugs to the issue tracker:
|
|||||||
https://bugs.chromium.org/p/webp
|
https://bugs.chromium.org/p/webp
|
||||||
.br
|
.br
|
||||||
Patches welcome! See this page to get started:
|
Patches welcome! See this page to get started:
|
||||||
https://www.webmproject.org/code/contribute/submitting\-patches/
|
http://www.webmproject.org/code/contribute/submitting\-patches/
|
||||||
|
|
||||||
.SH EXAMPLES
|
.SH EXAMPLES
|
||||||
cwebp \-q 50 -lossless picture.png \-o picture_lossless.webp
|
cwebp \-q 50 -lossless picture.png \-o picture_lossless.webp
|
||||||
@@ -324,5 +313,5 @@ for the Debian project (and may be used by others).
|
|||||||
.BR dwebp (1),
|
.BR dwebp (1),
|
||||||
.BR gif2webp (1)
|
.BR gif2webp (1)
|
||||||
.br
|
.br
|
||||||
Please refer to https://developers.google.com/speed/webp/ for additional
|
Please refer to http://developers.google.com/speed/webp/ for additional
|
||||||
information.
|
information.
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
.\" Hey, EMACS: -*- nroff -*-
|
.\" Hey, EMACS: -*- nroff -*-
|
||||||
.TH DWEBP 1 "November 17, 2021"
|
.TH DWEBP 1 "June 23, 2016"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
dwebp \- decompress a WebP file to an image file
|
dwebp \- decompress a WebP file to an image file
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
@@ -12,7 +12,6 @@ This manual page documents the
|
|||||||
command.
|
command.
|
||||||
.PP
|
.PP
|
||||||
\fBdwebp\fP decompresses WebP files into PNG, PAM, PPM or PGM images.
|
\fBdwebp\fP decompresses WebP files into PNG, PAM, PPM or PGM images.
|
||||||
Note: Animated WebP files are not supported.
|
|
||||||
.SH OPTIONS
|
.SH OPTIONS
|
||||||
The basic options are:
|
The basic options are:
|
||||||
.TP
|
.TP
|
||||||
@@ -113,7 +112,7 @@ Please report all bugs to the issue tracker:
|
|||||||
https://bugs.chromium.org/p/webp
|
https://bugs.chromium.org/p/webp
|
||||||
.br
|
.br
|
||||||
Patches welcome! See this page to get started:
|
Patches welcome! See this page to get started:
|
||||||
https://www.webmproject.org/code/contribute/submitting\-patches/
|
http://www.webmproject.org/code/contribute/submitting-patches/
|
||||||
|
|
||||||
.SH EXAMPLES
|
.SH EXAMPLES
|
||||||
dwebp picture.webp \-o output.png
|
dwebp picture.webp \-o output.png
|
||||||
@@ -138,7 +137,7 @@ for the Debian project (and may be used by others).
|
|||||||
.BR gif2webp (1),
|
.BR gif2webp (1),
|
||||||
.BR webpmux (1)
|
.BR webpmux (1)
|
||||||
.br
|
.br
|
||||||
Please refer to https://developers.google.com/speed/webp/ for additional
|
Please refer to http://developers.google.com/speed/webp/ for additional
|
||||||
information.
|
information.
|
||||||
.SS Output file format details
|
.SS Output file format details
|
||||||
PAM: http://netpbm.sourceforge.net/doc/pam.html
|
PAM: http://netpbm.sourceforge.net/doc/pam.html
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
.\" Hey, EMACS: -*- nroff -*-
|
.\" Hey, EMACS: -*- nroff -*-
|
||||||
.TH GIF2WEBP 1 "November 17, 2021"
|
.TH GIF2WEBP 1 "January 25, 2017"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
gif2webp \- Convert a GIF image to WebP
|
gif2webp \- Convert a GIF image to WebP
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
@@ -20,12 +20,6 @@ Specify the name of the output WebP file. If omitted, \fBgif2webp\fP will
|
|||||||
perform conversion but only report statistics.
|
perform conversion but only report statistics.
|
||||||
Using "\-" as output name will direct output to 'stdout'.
|
Using "\-" as output name will direct output to 'stdout'.
|
||||||
.TP
|
.TP
|
||||||
.BI \-\- " string
|
|
||||||
Explicitly specify the input file. This option is useful if the input
|
|
||||||
file starts with an '\-' for instance. This option must appear \fBlast\fP.
|
|
||||||
Any other options afterward will be ignored. If the input file is "\-",
|
|
||||||
the data will be read from \fIstdin\fP instead of a file.
|
|
||||||
.TP
|
|
||||||
.B \-h, \-help
|
.B \-h, \-help
|
||||||
Usage information.
|
Usage information.
|
||||||
.TP
|
.TP
|
||||||
@@ -62,9 +56,9 @@ larger file size and lower compression quality.
|
|||||||
.TP
|
.TP
|
||||||
.BI \-min_size
|
.BI \-min_size
|
||||||
Encode image to achieve smallest size. This disables key frame insertion and
|
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
|
picks the dispose method resulting in smallest output for each frame. It uses
|
||||||
uses lossless compression by default, but can be combined with \-q, \-m,
|
lossless compression by default, but can be combined with \-q, \-m, \-lossy or
|
||||||
\-lossy or \-mixed options.
|
\-mixed options.
|
||||||
.TP
|
.TP
|
||||||
.BI \-kmin " int
|
.BI \-kmin " int
|
||||||
.TP
|
.TP
|
||||||
@@ -114,11 +108,8 @@ the value the smoother the picture will appear. Typical values are usually in
|
|||||||
the range of 20 to 50.
|
the range of 20 to 50.
|
||||||
.TP
|
.TP
|
||||||
.B \-mt
|
.B \-mt
|
||||||
Use multi-threading for encoding, if possible.
|
Use multi-threading for encoding, if possible. This option is only effective
|
||||||
.TP
|
when using lossy compression.
|
||||||
.B \-loop_compatibility
|
|
||||||
If enabled, handle the loop information in a compatible fashion for Chrome
|
|
||||||
version prior to M62 (inclusive) and Firefox.
|
|
||||||
.TP
|
.TP
|
||||||
.B \-v
|
.B \-v
|
||||||
Print extra information.
|
Print extra information.
|
||||||
@@ -131,7 +122,7 @@ Please report all bugs to the issue tracker:
|
|||||||
https://bugs.chromium.org/p/webp
|
https://bugs.chromium.org/p/webp
|
||||||
.br
|
.br
|
||||||
Patches welcome! See this page to get started:
|
Patches welcome! See this page to get started:
|
||||||
https://www.webmproject.org/code/contribute/submitting\-patches/
|
http://www.webmproject.org/code/contribute/submitting-patches/
|
||||||
|
|
||||||
.SH EXAMPLES
|
.SH EXAMPLES
|
||||||
gif2webp picture.gif \-o picture.webp
|
gif2webp picture.gif \-o picture.webp
|
||||||
@@ -143,8 +134,6 @@ gif2webp \-lossy \-m 3 picture.gif \-o picture_lossy.webp
|
|||||||
gif2webp \-lossy \-f 50 picture.gif \-o picture.webp
|
gif2webp \-lossy \-f 50 picture.gif \-o picture.webp
|
||||||
.br
|
.br
|
||||||
gif2webp \-q 70 \-o picture.webp \-\- \-\-\-picture.gif
|
gif2webp \-q 70 \-o picture.webp \-\- \-\-\-picture.gif
|
||||||
.br
|
|
||||||
cat picture.gif | gif2webp \-o \- \-\- \- > output.webp
|
|
||||||
|
|
||||||
.SH AUTHORS
|
.SH AUTHORS
|
||||||
\fBgif2webp\fP is a part of libwebp and was written by the WebP team.
|
\fBgif2webp\fP is a part of libwebp and was written by the WebP team.
|
||||||
@@ -160,5 +149,5 @@ Debian project (and may be used by others).
|
|||||||
.BR dwebp (1),
|
.BR dwebp (1),
|
||||||
.BR webpmux (1)
|
.BR webpmux (1)
|
||||||
.br
|
.br
|
||||||
Please refer to https://developers.google.com/speed/webp/ for additional
|
Please refer to http://developers.google.com/speed/webp/ for additional
|
||||||
information.
|
information.
|
||||||
|
|||||||
@@ -1,12 +1,10 @@
|
|||||||
.\" Hey, EMACS: -*- nroff -*-
|
.\" Hey, EMACS: -*- nroff -*-
|
||||||
.TH IMG2WEBP 1 "January 5, 2022"
|
.TH IMG2WEBP 1 "January 23, 2017"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
img2webp \- create animated WebP file from a sequence of input images.
|
img2webp \- create animated WebP file from a sequence of input images.
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
.B img2webp
|
.B img2webp
|
||||||
[file_options] [[frame_options] frame_file]...
|
[file_level_options] [files] [per_frame_options...]
|
||||||
.br
|
|
||||||
.B img2webp argument_file_name
|
|
||||||
.br
|
.br
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
This manual page documents the
|
This manual page documents the
|
||||||
@@ -15,9 +13,6 @@ command.
|
|||||||
.PP
|
.PP
|
||||||
\fBimg2webp\fP compresses a sequence of images using the animated WebP format.
|
\fBimg2webp\fP compresses a sequence of images using the animated WebP format.
|
||||||
Input images can either be PNG, JPEG, TIFF or WebP.
|
Input images can either be PNG, JPEG, TIFF or WebP.
|
||||||
If a single file name (not starting with the character '\-') is supplied as
|
|
||||||
the argument, the command line arguments are actually tokenized from this file.
|
|
||||||
This allows for easy scripting or using a large number of arguments.
|
|
||||||
.SH FILE-LEVEL OPTIONS
|
.SH FILE-LEVEL OPTIONS
|
||||||
The file-level options are applied at the beginning of the compression process,
|
The file-level options are applied at the beginning of the compression process,
|
||||||
before the input frames are read.
|
before the input frames are read.
|
||||||
@@ -27,7 +22,7 @@ Specify the name of the output WebP file.
|
|||||||
.TP
|
.TP
|
||||||
.BI \-min_size
|
.BI \-min_size
|
||||||
Encode images to achieve smallest size. This disables key frame insertion and
|
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
|
lossless compression by default, but can be combined with \-q, \-m, \-lossy or
|
||||||
\-mixed options.
|
\-mixed options.
|
||||||
.TP
|
.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 .
|
option disables the local option \fB-lossy\fP and \fB-lossless\fP .
|
||||||
.TP
|
.TP
|
||||||
.BI \-loop " int
|
.BI \-loop " int
|
||||||
Specifies the number of times the animation should loop. Using '0'
|
Specifies the number of times the animation should loop. Using '0' means
|
||||||
means 'loop indefinitely'.
|
'loop indefinitely'.
|
||||||
.TP
|
.TP
|
||||||
.BI \-v
|
.BI \-v
|
||||||
Be more verbose.
|
Be more verbose.
|
||||||
.TP
|
.TP
|
||||||
.B \-h, \-help
|
.B \-h, \-help
|
||||||
A short usage summary.
|
A short usage summary.
|
||||||
.TP
|
|
||||||
.B \-version
|
|
||||||
Print the version numbers of the relevant libraries used.
|
|
||||||
|
|
||||||
.SH PER-FRAME OPTIONS
|
.SH PER-FRAME OPTIONS
|
||||||
The per-frame options are applied for the images following as arguments in the
|
The per-frame options are applied for the images following as arguments in the
|
||||||
@@ -86,7 +78,7 @@ Please report all bugs to the issue tracker:
|
|||||||
https://bugs.chromium.org/p/webp
|
https://bugs.chromium.org/p/webp
|
||||||
.br
|
.br
|
||||||
Patches welcome! See this page to get started:
|
Patches welcome! See this page to get started:
|
||||||
https://www.webmproject.org/code/contribute/submitting\-patches/
|
http://www.webmproject.org/code/contribute/submitting\-patches/
|
||||||
|
|
||||||
.SH AUTHORS
|
.SH AUTHORS
|
||||||
\fBimg2webp\fP is a part of libwebp and was written by the WebP team.
|
\fBimg2webp\fP is a part of libwebp and was written by the WebP team.
|
||||||
@@ -101,5 +93,5 @@ for the Debian project (and may be used by others).
|
|||||||
.BR webpmux (1),
|
.BR webpmux (1),
|
||||||
.BR gif2webp (1)
|
.BR gif2webp (1)
|
||||||
.br
|
.br
|
||||||
Please refer to https://developers.google.com/speed/webp/ for additional
|
Please refer to http://developers.google.com/speed/webp/ for additional
|
||||||
information.
|
information.
|
||||||
|
|||||||
13
man/vwebp.1
13
man/vwebp.1
@@ -1,5 +1,5 @@
|
|||||||
.\" Hey, EMACS: -*- nroff -*-
|
.\" Hey, EMACS: -*- nroff -*-
|
||||||
.TH VWEBP 1 "November 17, 2021"
|
.TH VWEBP 1 "November 25, 2016"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
vwebp \- decompress a WebP file and display it in a window
|
vwebp \- decompress a WebP file and display it in a window
|
||||||
.SH SYNOPSIS
|
.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,
|
By default, quantized transparency planes are dithered during decompression,
|
||||||
to smooth the gradients. This flag will prevent this dithering.
|
to smooth the gradients. This flag will prevent this dithering.
|
||||||
.TP
|
.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
|
.B \-mt
|
||||||
Use multi-threading for decoding, if possible.
|
Use multi-threading for decoding, if possible.
|
||||||
.TP
|
.TP
|
||||||
@@ -60,9 +56,6 @@ the data will be read from \fIstdin\fP instead of a file.
|
|||||||
.B 'c'
|
.B 'c'
|
||||||
Toggle use of color profile.
|
Toggle use of color profile.
|
||||||
.TP
|
.TP
|
||||||
.B 'b'
|
|
||||||
Toggle display of background color.
|
|
||||||
.TP
|
|
||||||
.B 'i'
|
.B 'i'
|
||||||
Overlay file information.
|
Overlay file information.
|
||||||
.TP
|
.TP
|
||||||
@@ -77,7 +70,7 @@ Please report all bugs to the issue tracker:
|
|||||||
https://bugs.chromium.org/p/webp
|
https://bugs.chromium.org/p/webp
|
||||||
.br
|
.br
|
||||||
Patches welcome! See this page to get started:
|
Patches welcome! See this page to get started:
|
||||||
https://www.webmproject.org/code/contribute/submitting\-patches/
|
http://www.webmproject.org/code/contribute/submitting-patches/
|
||||||
|
|
||||||
.SH EXAMPLES
|
.SH EXAMPLES
|
||||||
vwebp picture.webp
|
vwebp picture.webp
|
||||||
@@ -97,5 +90,5 @@ This manual page was written for the Debian project (and may be used by others).
|
|||||||
.SH SEE ALSO
|
.SH SEE ALSO
|
||||||
.BR dwebp (1)
|
.BR dwebp (1)
|
||||||
.br
|
.br
|
||||||
Please refer to https://developers.google.com/speed/webp/ for additional
|
Please refer to http://developers.google.com/speed/webp/ for additional
|
||||||
information.
|
information.
|
||||||
|
|||||||
@@ -1,80 +0,0 @@
|
|||||||
.\" Hey, EMACS: -*- nroff -*-
|
|
||||||
.TH WEBPINFO 1 "November 17, 2021"
|
|
||||||
.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:
|
|
||||||
https://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 https://developers.google.com/speed/webp/ for additional
|
|
||||||
information.
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
.\" Hey, EMACS: -*- nroff -*-
|
.\" Hey, EMACS: -*- nroff -*-
|
||||||
.TH WEBPMUX 1 "November 17, 2021"
|
.TH WEBPMUX 1 "November 10, 2016"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
webpmux \- create animated WebP files from non\-animated WebP images, extract
|
webpmux \- create animated WebP files from non\-animated WebP images, extract
|
||||||
frames from animated WebP images, and manage XMP/EXIF metadata and ICC profile.
|
frames from animated WebP images, and manage XMP/EXIF metadata and ICC profile.
|
||||||
@@ -48,8 +48,6 @@ frames from animated WebP images, and manage XMP/EXIF metadata and ICC profile.
|
|||||||
.B webpmux [\-h|\-help]
|
.B webpmux [\-h|\-help]
|
||||||
.br
|
.br
|
||||||
.B webpmux \-version
|
.B webpmux \-version
|
||||||
.br
|
|
||||||
.B webpmux argument_file_name
|
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
This manual page documents the
|
This manual page documents the
|
||||||
.B webpmux
|
.B webpmux
|
||||||
@@ -57,9 +55,6 @@ command.
|
|||||||
.PP
|
.PP
|
||||||
\fBwebpmux\fP can be used to create/extract from animated WebP files, as well as
|
\fBwebpmux\fP can be used to create/extract from animated WebP files, as well as
|
||||||
to add/extract/strip XMP/EXIF metadata and ICC profile.
|
to add/extract/strip XMP/EXIF metadata and ICC profile.
|
||||||
If a single file name (not starting with the character '\-') is supplied as
|
|
||||||
the argument, the command line arguments are actually tokenized from this file.
|
|
||||||
This allows for easy scripting or using a large number of arguments.
|
|
||||||
.SH OPTIONS
|
.SH OPTIONS
|
||||||
.SS GET_OPTIONS (\-get):
|
.SS GET_OPTIONS (\-get):
|
||||||
.TP
|
.TP
|
||||||
@@ -77,17 +72,6 @@ Get nth frame from an animated image. (n = 0 has a special meaning: last frame).
|
|||||||
|
|
||||||
.SS SET_OPTIONS (\-set)
|
.SS SET_OPTIONS (\-set)
|
||||||
.TP
|
.TP
|
||||||
.BI loop " loop_count
|
|
||||||
Set loop count on an animated file.
|
|
||||||
.P
|
|
||||||
Where: 'loop_count' must be in range [0, 65535].
|
|
||||||
.TP
|
|
||||||
.BI bgcolor " A,R,G,B
|
|
||||||
Set the background color of the canvas on an animated file.
|
|
||||||
.P
|
|
||||||
where: 'A', 'R', 'G' and 'B' are integers in the range 0 to 255 specifying the
|
|
||||||
Alpha, Red, Green and Blue component values respectively.
|
|
||||||
.TP
|
|
||||||
.BI icc " file.icc
|
.BI icc " file.icc
|
||||||
Set ICC profile.
|
Set ICC profile.
|
||||||
.P
|
.P
|
||||||
@@ -191,7 +175,7 @@ Please report all bugs to the issue tracker:
|
|||||||
https://bugs.chromium.org/p/webp
|
https://bugs.chromium.org/p/webp
|
||||||
.br
|
.br
|
||||||
Patches welcome! See this page to get started:
|
Patches welcome! See this page to get started:
|
||||||
https://www.webmproject.org/code/contribute/submitting\-patches/
|
http://www.webmproject.org/code/contribute/submitting\-patches/
|
||||||
|
|
||||||
.SH EXAMPLES
|
.SH EXAMPLES
|
||||||
.P
|
.P
|
||||||
@@ -267,5 +251,5 @@ for the Debian project (and may be used by others).
|
|||||||
.BR dwebp (1),
|
.BR dwebp (1),
|
||||||
.BR gif2webp (1)
|
.BR gif2webp (1)
|
||||||
.br
|
.br
|
||||||
Please refer to https://developers.google.com/speed/webp/ for additional
|
Please refer to http://developers.google.com/speed/webp/ for additional
|
||||||
information.
|
information.
|
||||||
|
|||||||
@@ -1,34 +0,0 @@
|
|||||||
AM_CPPFLAGS += -I$(top_builddir) -I$(top_srcdir)
|
|
||||||
AM_CPPFLAGS += -I$(top_builddir)/src -I$(top_srcdir)/src
|
|
||||||
noinst_LTLIBRARIES =
|
|
||||||
noinst_LTLIBRARIES += libsharpyuv.la
|
|
||||||
noinst_LTLIBRARIES += libsharpyuv_sse2.la
|
|
||||||
noinst_LTLIBRARIES += libsharpyuv_neon.la
|
|
||||||
|
|
||||||
noinst_HEADERS =
|
|
||||||
noinst_HEADERS += ../src/webp/types.h
|
|
||||||
noinst_HEADERS += ../src/dsp/cpu.h
|
|
||||||
|
|
||||||
libsharpyuv_sse2_la_SOURCES =
|
|
||||||
libsharpyuv_sse2_la_SOURCES += sharpyuv_sse2.c
|
|
||||||
libsharpyuv_sse2_la_CPPFLAGS = $(libsharpyuv_la_CPPFLAGS)
|
|
||||||
libsharpyuv_sse2_la_CFLAGS = $(AM_CFLAGS) $(SSE2_FLAGS)
|
|
||||||
|
|
||||||
libsharpyuv_neon_la_SOURCES =
|
|
||||||
libsharpyuv_neon_la_SOURCES += sharpyuv_neon.c
|
|
||||||
libsharpyuv_neon_la_CPPFLAGS = $(libsharpyuv_la_CPPFLAGS)
|
|
||||||
libsharpyuv_neon_la_CFLAGS = $(AM_CFLAGS) $(NEON_FLAGS)
|
|
||||||
|
|
||||||
libsharpyuv_la_SOURCES =
|
|
||||||
libsharpyuv_la_SOURCES += sharpyuv_csp.c sharpyuv_csp.h
|
|
||||||
libsharpyuv_la_SOURCES += sharpyuv_dsp.c sharpyuv_dsp.h
|
|
||||||
libsharpyuv_la_SOURCES += sharpyuv_gamma.c sharpyuv_gamma.h
|
|
||||||
libsharpyuv_la_SOURCES += sharpyuv.c sharpyuv.h
|
|
||||||
|
|
||||||
libsharpyuv_la_CPPFLAGS = $(AM_CPPFLAGS)
|
|
||||||
libsharpyuv_la_LDFLAGS =
|
|
||||||
libsharpyuv_la_LIBADD =
|
|
||||||
libsharpyuv_la_LIBADD += libsharpyuv_sse2.la
|
|
||||||
libsharpyuv_la_LIBADD += libsharpyuv_neon.la
|
|
||||||
|
|
||||||
noinst_PROGRAMS =
|
|
||||||
@@ -1,498 +0,0 @@
|
|||||||
// Copyright 2022 Google Inc. All Rights Reserved.
|
|
||||||
//
|
|
||||||
// Use of this source code is governed by a BSD-style license
|
|
||||||
// that can be found in the COPYING file in the root of the source
|
|
||||||
// tree. An additional intellectual property rights grant can be found
|
|
||||||
// in the file PATENTS. All contributing project authors may
|
|
||||||
// be found in the AUTHORS file in the root of the source tree.
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// Sharp RGB to YUV conversion.
|
|
||||||
//
|
|
||||||
// Author: Skal (pascal.massimino@gmail.com)
|
|
||||||
|
|
||||||
#include "sharpyuv/sharpyuv.h"
|
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
#include <limits.h>
|
|
||||||
#include <math.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include "src/webp/types.h"
|
|
||||||
#include "src/dsp/cpu.h"
|
|
||||||
#include "sharpyuv/sharpyuv_dsp.h"
|
|
||||||
#include "sharpyuv/sharpyuv_gamma.h"
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
// Sharp RGB->YUV conversion
|
|
||||||
|
|
||||||
static const int kNumIterations = 4;
|
|
||||||
|
|
||||||
#define YUV_FIX 16 // fixed-point precision for RGB->YUV
|
|
||||||
static const int kYuvHalf = 1 << (YUV_FIX - 1);
|
|
||||||
|
|
||||||
// Max bit depth so that intermediate calculations fit in 16 bits.
|
|
||||||
static const int kMaxBitDepth = 14;
|
|
||||||
|
|
||||||
// Returns the precision shift to use based on the input rgb_bit_depth.
|
|
||||||
static int GetPrecisionShift(int rgb_bit_depth) {
|
|
||||||
// Try to add 2 bits of precision if it fits in kMaxBitDepth. Otherwise remove
|
|
||||||
// bits if needed.
|
|
||||||
return ((rgb_bit_depth + 2) <= kMaxBitDepth) ? 2
|
|
||||||
: (kMaxBitDepth - rgb_bit_depth);
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef int16_t fixed_t; // signed type with extra precision for UV
|
|
||||||
typedef uint16_t fixed_y_t; // unsigned type with extra precision for W
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
static uint8_t clip_8b(fixed_t v) {
|
|
||||||
return (!(v & ~0xff)) ? (uint8_t)v : (v < 0) ? 0u : 255u;
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint16_t clip(fixed_t v, int max) {
|
|
||||||
return (v < 0) ? 0 : (v > max) ? max : (uint16_t)v;
|
|
||||||
}
|
|
||||||
|
|
||||||
static fixed_y_t clip_bit_depth(int y, int bit_depth) {
|
|
||||||
const int max = (1 << bit_depth) - 1;
|
|
||||||
return (!(y & ~max)) ? (fixed_y_t)y : (y < 0) ? 0 : max;
|
|
||||||
}
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
static int RGBToGray(int64_t r, int64_t g, int64_t b) {
|
|
||||||
const int64_t luma = 13933 * r + 46871 * g + 4732 * b + kYuvHalf;
|
|
||||||
return (int)(luma >> YUV_FIX);
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint32_t ScaleDown(uint16_t a, uint16_t b, uint16_t c, uint16_t d,
|
|
||||||
int rgb_bit_depth) {
|
|
||||||
const int bit_depth = rgb_bit_depth + GetPrecisionShift(rgb_bit_depth);
|
|
||||||
const uint32_t A = SharpYuvGammaToLinear(a, bit_depth);
|
|
||||||
const uint32_t B = SharpYuvGammaToLinear(b, bit_depth);
|
|
||||||
const uint32_t C = SharpYuvGammaToLinear(c, bit_depth);
|
|
||||||
const uint32_t D = SharpYuvGammaToLinear(d, bit_depth);
|
|
||||||
return SharpYuvLinearToGamma((A + B + C + D + 2) >> 2, bit_depth);
|
|
||||||
}
|
|
||||||
|
|
||||||
static WEBP_INLINE void UpdateW(const fixed_y_t* src, fixed_y_t* dst, int w,
|
|
||||||
int rgb_bit_depth) {
|
|
||||||
const int bit_depth = rgb_bit_depth + GetPrecisionShift(rgb_bit_depth);
|
|
||||||
int i;
|
|
||||||
for (i = 0; i < w; ++i) {
|
|
||||||
const uint32_t R = SharpYuvGammaToLinear(src[0 * w + i], bit_depth);
|
|
||||||
const uint32_t G = SharpYuvGammaToLinear(src[1 * w + i], bit_depth);
|
|
||||||
const uint32_t B = SharpYuvGammaToLinear(src[2 * w + i], bit_depth);
|
|
||||||
const uint32_t Y = RGBToGray(R, G, B);
|
|
||||||
dst[i] = (fixed_y_t)SharpYuvLinearToGamma(Y, bit_depth);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void UpdateChroma(const fixed_y_t* src1, const fixed_y_t* src2,
|
|
||||||
fixed_t* dst, int uv_w, int rgb_bit_depth) {
|
|
||||||
int i;
|
|
||||||
for (i = 0; i < uv_w; ++i) {
|
|
||||||
const int r =
|
|
||||||
ScaleDown(src1[0 * uv_w + 0], src1[0 * uv_w + 1], src2[0 * uv_w + 0],
|
|
||||||
src2[0 * uv_w + 1], rgb_bit_depth);
|
|
||||||
const int g =
|
|
||||||
ScaleDown(src1[2 * uv_w + 0], src1[2 * uv_w + 1], src2[2 * uv_w + 0],
|
|
||||||
src2[2 * uv_w + 1], rgb_bit_depth);
|
|
||||||
const int b =
|
|
||||||
ScaleDown(src1[4 * uv_w + 0], src1[4 * uv_w + 1], src2[4 * uv_w + 0],
|
|
||||||
src2[4 * uv_w + 1], rgb_bit_depth);
|
|
||||||
const int W = RGBToGray(r, g, b);
|
|
||||||
dst[0 * uv_w] = (fixed_t)(r - W);
|
|
||||||
dst[1 * uv_w] = (fixed_t)(g - W);
|
|
||||||
dst[2 * uv_w] = (fixed_t)(b - W);
|
|
||||||
dst += 1;
|
|
||||||
src1 += 2;
|
|
||||||
src2 += 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void StoreGray(const fixed_y_t* rgb, fixed_y_t* y, int w) {
|
|
||||||
int i;
|
|
||||||
assert(w > 0);
|
|
||||||
for (i = 0; i < w; ++i) {
|
|
||||||
y[i] = RGBToGray(rgb[0 * w + i], rgb[1 * w + i], rgb[2 * w + i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
static WEBP_INLINE fixed_y_t Filter2(int A, int B, int W0, int bit_depth) {
|
|
||||||
const int v0 = (A * 3 + B + 2) >> 2;
|
|
||||||
return clip_bit_depth(v0 + W0, bit_depth);
|
|
||||||
}
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
static WEBP_INLINE int Shift(int v, int shift) {
|
|
||||||
return (shift >= 0) ? (v << shift) : (v >> -shift);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImportOneRow(const uint8_t* const r_ptr,
|
|
||||||
const uint8_t* const g_ptr,
|
|
||||||
const uint8_t* const b_ptr,
|
|
||||||
int rgb_step,
|
|
||||||
int rgb_bit_depth,
|
|
||||||
int pic_width,
|
|
||||||
fixed_y_t* const dst) {
|
|
||||||
// Convert the rgb_step from a number of bytes to a number of uint8_t or
|
|
||||||
// uint16_t values depending the bit depth.
|
|
||||||
const int step = (rgb_bit_depth > 8) ? rgb_step / 2 : rgb_step;
|
|
||||||
int i;
|
|
||||||
const int w = (pic_width + 1) & ~1;
|
|
||||||
for (i = 0; i < pic_width; ++i) {
|
|
||||||
const int off = i * step;
|
|
||||||
const int shift = GetPrecisionShift(rgb_bit_depth);
|
|
||||||
if (rgb_bit_depth == 8) {
|
|
||||||
dst[i + 0 * w] = Shift(r_ptr[off], shift);
|
|
||||||
dst[i + 1 * w] = Shift(g_ptr[off], shift);
|
|
||||||
dst[i + 2 * w] = Shift(b_ptr[off], shift);
|
|
||||||
} else {
|
|
||||||
dst[i + 0 * w] = Shift(((uint16_t*)r_ptr)[off], shift);
|
|
||||||
dst[i + 1 * w] = Shift(((uint16_t*)g_ptr)[off], shift);
|
|
||||||
dst[i + 2 * w] = Shift(((uint16_t*)b_ptr)[off], shift);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (pic_width & 1) { // replicate rightmost pixel
|
|
||||||
dst[pic_width + 0 * w] = dst[pic_width + 0 * w - 1];
|
|
||||||
dst[pic_width + 1 * w] = dst[pic_width + 1 * w - 1];
|
|
||||||
dst[pic_width + 2 * w] = dst[pic_width + 2 * w - 1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void InterpolateTwoRows(const fixed_y_t* const best_y,
|
|
||||||
const fixed_t* prev_uv,
|
|
||||||
const fixed_t* cur_uv,
|
|
||||||
const fixed_t* next_uv,
|
|
||||||
int w,
|
|
||||||
fixed_y_t* out1,
|
|
||||||
fixed_y_t* out2,
|
|
||||||
int rgb_bit_depth) {
|
|
||||||
const int uv_w = w >> 1;
|
|
||||||
const int len = (w - 1) >> 1; // length to filter
|
|
||||||
int k = 3;
|
|
||||||
const int bit_depth = rgb_bit_depth + GetPrecisionShift(rgb_bit_depth);
|
|
||||||
while (k-- > 0) { // process each R/G/B segments in turn
|
|
||||||
// special boundary case for i==0
|
|
||||||
out1[0] = Filter2(cur_uv[0], prev_uv[0], best_y[0], bit_depth);
|
|
||||||
out2[0] = Filter2(cur_uv[0], next_uv[0], best_y[w], bit_depth);
|
|
||||||
|
|
||||||
SharpYuvFilterRow(cur_uv, prev_uv, len, best_y + 0 + 1, out1 + 1,
|
|
||||||
bit_depth);
|
|
||||||
SharpYuvFilterRow(cur_uv, next_uv, len, best_y + w + 1, out2 + 1,
|
|
||||||
bit_depth);
|
|
||||||
|
|
||||||
// special boundary case for i == w - 1 when w is even
|
|
||||||
if (!(w & 1)) {
|
|
||||||
out1[w - 1] = Filter2(cur_uv[uv_w - 1], prev_uv[uv_w - 1],
|
|
||||||
best_y[w - 1 + 0], bit_depth);
|
|
||||||
out2[w - 1] = Filter2(cur_uv[uv_w - 1], next_uv[uv_w - 1],
|
|
||||||
best_y[w - 1 + w], bit_depth);
|
|
||||||
}
|
|
||||||
out1 += w;
|
|
||||||
out2 += w;
|
|
||||||
prev_uv += uv_w;
|
|
||||||
cur_uv += uv_w;
|
|
||||||
next_uv += uv_w;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static WEBP_INLINE int RGBToYUVComponent(int r, int g, int b,
|
|
||||||
const int coeffs[4], int sfix) {
|
|
||||||
const int srounder = 1 << (YUV_FIX + sfix - 1);
|
|
||||||
const int luma = coeffs[0] * r + coeffs[1] * g + coeffs[2] * b +
|
|
||||||
coeffs[3] + srounder;
|
|
||||||
return (luma >> (YUV_FIX + sfix));
|
|
||||||
}
|
|
||||||
|
|
||||||
static int ConvertWRGBToYUV(const fixed_y_t* best_y, const fixed_t* best_uv,
|
|
||||||
uint8_t* y_ptr, int y_stride, uint8_t* u_ptr,
|
|
||||||
int u_stride, uint8_t* v_ptr, int v_stride,
|
|
||||||
int rgb_bit_depth,
|
|
||||||
int yuv_bit_depth, int width, int height,
|
|
||||||
const SharpYuvConversionMatrix* yuv_matrix) {
|
|
||||||
int i, j;
|
|
||||||
const fixed_t* const best_uv_base = best_uv;
|
|
||||||
const int w = (width + 1) & ~1;
|
|
||||||
const int h = (height + 1) & ~1;
|
|
||||||
const int uv_w = w >> 1;
|
|
||||||
const int uv_h = h >> 1;
|
|
||||||
const int sfix = GetPrecisionShift(rgb_bit_depth);
|
|
||||||
const int yuv_max = (1 << yuv_bit_depth) - 1;
|
|
||||||
|
|
||||||
for (best_uv = best_uv_base, j = 0; j < height; ++j) {
|
|
||||||
for (i = 0; i < width; ++i) {
|
|
||||||
const int off = (i >> 1);
|
|
||||||
const int W = best_y[i];
|
|
||||||
const int r = best_uv[off + 0 * uv_w] + W;
|
|
||||||
const int g = best_uv[off + 1 * uv_w] + W;
|
|
||||||
const int b = best_uv[off + 2 * uv_w] + W;
|
|
||||||
const int y = RGBToYUVComponent(r, g, b, yuv_matrix->rgb_to_y, sfix);
|
|
||||||
if (yuv_bit_depth <= 8) {
|
|
||||||
y_ptr[i] = clip_8b(y);
|
|
||||||
} else {
|
|
||||||
((uint16_t*)y_ptr)[i] = clip(y, yuv_max);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
best_y += w;
|
|
||||||
best_uv += (j & 1) * 3 * uv_w;
|
|
||||||
y_ptr += y_stride;
|
|
||||||
}
|
|
||||||
for (best_uv = best_uv_base, j = 0; j < uv_h; ++j) {
|
|
||||||
for (i = 0; i < uv_w; ++i) {
|
|
||||||
const int off = i;
|
|
||||||
// Note r, g and b values here are off by W, but a constant offset on all
|
|
||||||
// 3 components doesn't change the value of u and v with a YCbCr matrix.
|
|
||||||
const int r = best_uv[off + 0 * uv_w];
|
|
||||||
const int g = best_uv[off + 1 * uv_w];
|
|
||||||
const int b = best_uv[off + 2 * uv_w];
|
|
||||||
const int u = RGBToYUVComponent(r, g, b, yuv_matrix->rgb_to_u, sfix);
|
|
||||||
const int v = RGBToYUVComponent(r, g, b, yuv_matrix->rgb_to_v, sfix);
|
|
||||||
if (yuv_bit_depth <= 8) {
|
|
||||||
u_ptr[i] = clip_8b(u);
|
|
||||||
v_ptr[i] = clip_8b(v);
|
|
||||||
} else {
|
|
||||||
((uint16_t*)u_ptr)[i] = clip(u, yuv_max);
|
|
||||||
((uint16_t*)v_ptr)[i] = clip(v, yuv_max);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
best_uv += 3 * uv_w;
|
|
||||||
u_ptr += u_stride;
|
|
||||||
v_ptr += v_stride;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
// Main function
|
|
||||||
|
|
||||||
static void* SafeMalloc(uint64_t nmemb, size_t size) {
|
|
||||||
const uint64_t total_size = nmemb * (uint64_t)size;
|
|
||||||
if (total_size != (size_t)total_size) return NULL;
|
|
||||||
return malloc((size_t)total_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define SAFE_ALLOC(W, H, T) ((T*)SafeMalloc((W) * (H), sizeof(T)))
|
|
||||||
|
|
||||||
static int DoSharpArgbToYuv(const uint8_t* r_ptr, const uint8_t* g_ptr,
|
|
||||||
const uint8_t* b_ptr, int rgb_step, int rgb_stride,
|
|
||||||
int rgb_bit_depth, uint8_t* y_ptr, int y_stride,
|
|
||||||
uint8_t* u_ptr, int u_stride, uint8_t* v_ptr,
|
|
||||||
int v_stride, int yuv_bit_depth, int width,
|
|
||||||
int height,
|
|
||||||
const SharpYuvConversionMatrix* yuv_matrix) {
|
|
||||||
// we expand the right/bottom border if needed
|
|
||||||
const int w = (width + 1) & ~1;
|
|
||||||
const int h = (height + 1) & ~1;
|
|
||||||
const int uv_w = w >> 1;
|
|
||||||
const int uv_h = h >> 1;
|
|
||||||
uint64_t prev_diff_y_sum = ~0;
|
|
||||||
int j, iter;
|
|
||||||
|
|
||||||
// TODO(skal): allocate one big memory chunk. But for now, it's easier
|
|
||||||
// for valgrind debugging to have several chunks.
|
|
||||||
fixed_y_t* const tmp_buffer = SAFE_ALLOC(w * 3, 2, fixed_y_t); // scratch
|
|
||||||
fixed_y_t* const best_y_base = SAFE_ALLOC(w, h, fixed_y_t);
|
|
||||||
fixed_y_t* const target_y_base = SAFE_ALLOC(w, h, fixed_y_t);
|
|
||||||
fixed_y_t* const best_rgb_y = SAFE_ALLOC(w, 2, fixed_y_t);
|
|
||||||
fixed_t* const best_uv_base = SAFE_ALLOC(uv_w * 3, uv_h, fixed_t);
|
|
||||||
fixed_t* const target_uv_base = SAFE_ALLOC(uv_w * 3, uv_h, fixed_t);
|
|
||||||
fixed_t* const best_rgb_uv = SAFE_ALLOC(uv_w * 3, 1, fixed_t);
|
|
||||||
fixed_y_t* best_y = best_y_base;
|
|
||||||
fixed_y_t* target_y = target_y_base;
|
|
||||||
fixed_t* best_uv = best_uv_base;
|
|
||||||
fixed_t* target_uv = target_uv_base;
|
|
||||||
const uint64_t diff_y_threshold = (uint64_t)(3.0 * w * h);
|
|
||||||
int ok;
|
|
||||||
assert(w > 0);
|
|
||||||
assert(h > 0);
|
|
||||||
|
|
||||||
if (best_y_base == NULL || best_uv_base == NULL ||
|
|
||||||
target_y_base == NULL || target_uv_base == NULL ||
|
|
||||||
best_rgb_y == NULL || best_rgb_uv == NULL ||
|
|
||||||
tmp_buffer == NULL) {
|
|
||||||
ok = 0;
|
|
||||||
goto End;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Import RGB samples to W/RGB representation.
|
|
||||||
for (j = 0; j < height; j += 2) {
|
|
||||||
const int is_last_row = (j == height - 1);
|
|
||||||
fixed_y_t* const src1 = tmp_buffer + 0 * w;
|
|
||||||
fixed_y_t* const src2 = tmp_buffer + 3 * w;
|
|
||||||
|
|
||||||
// prepare two rows of input
|
|
||||||
ImportOneRow(r_ptr, g_ptr, b_ptr, rgb_step, rgb_bit_depth, width,
|
|
||||||
src1);
|
|
||||||
if (!is_last_row) {
|
|
||||||
ImportOneRow(r_ptr + rgb_stride, g_ptr + rgb_stride, b_ptr + rgb_stride,
|
|
||||||
rgb_step, rgb_bit_depth, width, src2);
|
|
||||||
} else {
|
|
||||||
memcpy(src2, src1, 3 * w * sizeof(*src2));
|
|
||||||
}
|
|
||||||
StoreGray(src1, best_y + 0, w);
|
|
||||||
StoreGray(src2, best_y + w, w);
|
|
||||||
|
|
||||||
UpdateW(src1, target_y, w, rgb_bit_depth);
|
|
||||||
UpdateW(src2, target_y + w, w, rgb_bit_depth);
|
|
||||||
UpdateChroma(src1, src2, target_uv, uv_w, rgb_bit_depth);
|
|
||||||
memcpy(best_uv, target_uv, 3 * uv_w * sizeof(*best_uv));
|
|
||||||
best_y += 2 * w;
|
|
||||||
best_uv += 3 * uv_w;
|
|
||||||
target_y += 2 * w;
|
|
||||||
target_uv += 3 * uv_w;
|
|
||||||
r_ptr += 2 * rgb_stride;
|
|
||||||
g_ptr += 2 * rgb_stride;
|
|
||||||
b_ptr += 2 * rgb_stride;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Iterate and resolve clipping conflicts.
|
|
||||||
for (iter = 0; iter < kNumIterations; ++iter) {
|
|
||||||
const fixed_t* cur_uv = best_uv_base;
|
|
||||||
const fixed_t* prev_uv = best_uv_base;
|
|
||||||
uint64_t diff_y_sum = 0;
|
|
||||||
|
|
||||||
best_y = best_y_base;
|
|
||||||
best_uv = best_uv_base;
|
|
||||||
target_y = target_y_base;
|
|
||||||
target_uv = target_uv_base;
|
|
||||||
for (j = 0; j < h; j += 2) {
|
|
||||||
fixed_y_t* const src1 = tmp_buffer + 0 * w;
|
|
||||||
fixed_y_t* const src2 = tmp_buffer + 3 * w;
|
|
||||||
{
|
|
||||||
const fixed_t* const next_uv = cur_uv + ((j < h - 2) ? 3 * uv_w : 0);
|
|
||||||
InterpolateTwoRows(best_y, prev_uv, cur_uv, next_uv, w,
|
|
||||||
src1, src2, rgb_bit_depth);
|
|
||||||
prev_uv = cur_uv;
|
|
||||||
cur_uv = next_uv;
|
|
||||||
}
|
|
||||||
|
|
||||||
UpdateW(src1, best_rgb_y + 0 * w, w, rgb_bit_depth);
|
|
||||||
UpdateW(src2, best_rgb_y + 1 * w, w, rgb_bit_depth);
|
|
||||||
UpdateChroma(src1, src2, best_rgb_uv, uv_w, rgb_bit_depth);
|
|
||||||
|
|
||||||
// update two rows of Y and one row of RGB
|
|
||||||
diff_y_sum +=
|
|
||||||
SharpYuvUpdateY(target_y, best_rgb_y, best_y, 2 * w,
|
|
||||||
rgb_bit_depth + GetPrecisionShift(rgb_bit_depth));
|
|
||||||
SharpYuvUpdateRGB(target_uv, best_rgb_uv, best_uv, 3 * uv_w);
|
|
||||||
|
|
||||||
best_y += 2 * w;
|
|
||||||
best_uv += 3 * uv_w;
|
|
||||||
target_y += 2 * w;
|
|
||||||
target_uv += 3 * uv_w;
|
|
||||||
}
|
|
||||||
// test exit condition
|
|
||||||
if (iter > 0) {
|
|
||||||
if (diff_y_sum < diff_y_threshold) break;
|
|
||||||
if (diff_y_sum > prev_diff_y_sum) break;
|
|
||||||
}
|
|
||||||
prev_diff_y_sum = diff_y_sum;
|
|
||||||
}
|
|
||||||
|
|
||||||
// final reconstruction
|
|
||||||
ok = ConvertWRGBToYUV(best_y_base, best_uv_base, y_ptr, y_stride, u_ptr,
|
|
||||||
u_stride, v_ptr, v_stride, rgb_bit_depth, yuv_bit_depth,
|
|
||||||
width, height, yuv_matrix);
|
|
||||||
|
|
||||||
End:
|
|
||||||
free(best_y_base);
|
|
||||||
free(best_uv_base);
|
|
||||||
free(target_y_base);
|
|
||||||
free(target_uv_base);
|
|
||||||
free(best_rgb_y);
|
|
||||||
free(best_rgb_uv);
|
|
||||||
free(tmp_buffer);
|
|
||||||
return ok;
|
|
||||||
}
|
|
||||||
#undef SAFE_ALLOC
|
|
||||||
|
|
||||||
// Hidden exported init function.
|
|
||||||
// By default SharpYuvConvert calls it with NULL. If needed, users can declare
|
|
||||||
// it as extern and call it with a VP8CPUInfo function.
|
|
||||||
extern void SharpYuvInit(VP8CPUInfo cpu_info_func);
|
|
||||||
void SharpYuvInit(VP8CPUInfo cpu_info_func) {
|
|
||||||
static volatile VP8CPUInfo sharpyuv_last_cpuinfo_used =
|
|
||||||
(VP8CPUInfo)&sharpyuv_last_cpuinfo_used;
|
|
||||||
const int initialized =
|
|
||||||
(sharpyuv_last_cpuinfo_used != (VP8CPUInfo)&sharpyuv_last_cpuinfo_used);
|
|
||||||
if (cpu_info_func == NULL && initialized) return;
|
|
||||||
if (sharpyuv_last_cpuinfo_used == cpu_info_func) return;
|
|
||||||
|
|
||||||
SharpYuvInitDsp(cpu_info_func);
|
|
||||||
if (!initialized) {
|
|
||||||
SharpYuvInitGammaTables();
|
|
||||||
}
|
|
||||||
|
|
||||||
sharpyuv_last_cpuinfo_used = cpu_info_func;
|
|
||||||
}
|
|
||||||
|
|
||||||
int SharpYuvConvert(const void* r_ptr, const void* g_ptr,
|
|
||||||
const void* b_ptr, int rgb_step, int rgb_stride,
|
|
||||||
int rgb_bit_depth, void* y_ptr, int y_stride,
|
|
||||||
void* u_ptr, int u_stride, void* v_ptr,
|
|
||||||
int v_stride, int yuv_bit_depth, int width,
|
|
||||||
int height, const SharpYuvConversionMatrix* yuv_matrix) {
|
|
||||||
SharpYuvConversionMatrix scaled_matrix;
|
|
||||||
const int rgb_max = (1 << rgb_bit_depth) - 1;
|
|
||||||
const int rgb_round = 1 << (rgb_bit_depth - 1);
|
|
||||||
const int yuv_max = (1 << yuv_bit_depth) - 1;
|
|
||||||
const int sfix = GetPrecisionShift(rgb_bit_depth);
|
|
||||||
|
|
||||||
if (width < 1 || height < 1 || width == INT_MAX || height == INT_MAX ||
|
|
||||||
r_ptr == NULL || g_ptr == NULL || b_ptr == NULL || y_ptr == NULL ||
|
|
||||||
u_ptr == NULL || v_ptr == NULL) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (rgb_bit_depth != 8 && rgb_bit_depth != 10 && rgb_bit_depth != 12 &&
|
|
||||||
rgb_bit_depth != 16) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (yuv_bit_depth != 8 && yuv_bit_depth != 10 && yuv_bit_depth != 12) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (rgb_bit_depth > 8 && (rgb_step % 2 != 0 || rgb_stride %2 != 0)) {
|
|
||||||
// Step/stride should be even for uint16_t buffers.
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (yuv_bit_depth > 8 &&
|
|
||||||
(y_stride % 2 != 0 || u_stride % 2 != 0 || v_stride % 2 != 0)) {
|
|
||||||
// Stride should be even for uint16_t buffers.
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
SharpYuvInit(NULL);
|
|
||||||
|
|
||||||
// Add scaling factor to go from rgb_bit_depth to yuv_bit_depth, to the
|
|
||||||
// rgb->yuv conversion matrix.
|
|
||||||
if (rgb_bit_depth == yuv_bit_depth) {
|
|
||||||
memcpy(&scaled_matrix, yuv_matrix, sizeof(scaled_matrix));
|
|
||||||
} else {
|
|
||||||
int i;
|
|
||||||
for (i = 0; i < 3; ++i) {
|
|
||||||
scaled_matrix.rgb_to_y[i] =
|
|
||||||
(yuv_matrix->rgb_to_y[i] * yuv_max + rgb_round) / rgb_max;
|
|
||||||
scaled_matrix.rgb_to_u[i] =
|
|
||||||
(yuv_matrix->rgb_to_u[i] * yuv_max + rgb_round) / rgb_max;
|
|
||||||
scaled_matrix.rgb_to_v[i] =
|
|
||||||
(yuv_matrix->rgb_to_v[i] * yuv_max + rgb_round) / rgb_max;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Also incorporate precision change scaling.
|
|
||||||
scaled_matrix.rgb_to_y[3] = Shift(yuv_matrix->rgb_to_y[3], sfix);
|
|
||||||
scaled_matrix.rgb_to_u[3] = Shift(yuv_matrix->rgb_to_u[3], sfix);
|
|
||||||
scaled_matrix.rgb_to_v[3] = Shift(yuv_matrix->rgb_to_v[3], sfix);
|
|
||||||
|
|
||||||
return DoSharpArgbToYuv(r_ptr, g_ptr, b_ptr, rgb_step, rgb_stride,
|
|
||||||
rgb_bit_depth, y_ptr, y_stride, u_ptr, u_stride,
|
|
||||||
v_ptr, v_stride, yuv_bit_depth, width, height,
|
|
||||||
&scaled_matrix);
|
|
||||||
}
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
@@ -1,81 +0,0 @@
|
|||||||
// Copyright 2022 Google Inc. All Rights Reserved.
|
|
||||||
//
|
|
||||||
// Use of this source code is governed by a BSD-style license
|
|
||||||
// that can be found in the COPYING file in the root of the source
|
|
||||||
// tree. An additional intellectual property rights grant can be found
|
|
||||||
// in the file PATENTS. All contributing project authors may
|
|
||||||
// be found in the AUTHORS file in the root of the source tree.
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// Sharp RGB to YUV conversion.
|
|
||||||
|
|
||||||
#ifndef WEBP_SHARPYUV_SHARPYUV_H_
|
|
||||||
#define WEBP_SHARPYUV_SHARPYUV_H_
|
|
||||||
|
|
||||||
#include <inttypes.h>
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// SharpYUV API version following the convention from semver.org
|
|
||||||
#define SHARPYUV_VERSION_MAJOR 0
|
|
||||||
#define SHARPYUV_VERSION_MINOR 1
|
|
||||||
#define SHARPYUV_VERSION_PATCH 0
|
|
||||||
// Version as a uint32_t. The major number is the high 8 bits.
|
|
||||||
// The minor number is the middle 8 bits. The patch number is the low 16 bits.
|
|
||||||
#define SHARPYUV_MAKE_VERSION(MAJOR, MINOR, PATCH) \
|
|
||||||
(((MAJOR) << 24) | ((MINOR) << 16) | (PATCH))
|
|
||||||
#define SHARPYUV_VERSION \
|
|
||||||
SHARPYUV_MAKE_VERSION(SHARPYUV_VERSION_MAJOR, SHARPYUV_VERSION_MINOR, \
|
|
||||||
SHARPYUV_VERSION_PATCH)
|
|
||||||
|
|
||||||
// RGB to YUV conversion matrix, in 16 bit fixed point.
|
|
||||||
// y = rgb_to_y[0] * r + rgb_to_y[1] * g + rgb_to_y[2] * b + rgb_to_y[3]
|
|
||||||
// u = rgb_to_u[0] * r + rgb_to_u[1] * g + rgb_to_u[2] * b + rgb_to_u[3]
|
|
||||||
// v = rgb_to_v[0] * r + rgb_to_v[1] * g + rgb_to_v[2] * b + rgb_to_v[3]
|
|
||||||
// Then y, u and v values are divided by 1<<16 and rounded.
|
|
||||||
typedef struct {
|
|
||||||
int rgb_to_y[4];
|
|
||||||
int rgb_to_u[4];
|
|
||||||
int rgb_to_v[4];
|
|
||||||
} SharpYuvConversionMatrix;
|
|
||||||
|
|
||||||
// Converts RGB to YUV420 using a downsampling algorithm that minimizes
|
|
||||||
// artefacts caused by chroma subsampling.
|
|
||||||
// This is slower than standard downsampling (averaging of 4 UV values).
|
|
||||||
// Assumes that the image will be upsampled using a bilinear filter. If nearest
|
|
||||||
// neighbor is used instead, the upsampled image might look worse than with
|
|
||||||
// standard downsampling.
|
|
||||||
// r_ptr, g_ptr, b_ptr: pointers to the source r, g and b channels. Should point
|
|
||||||
// to uint8_t buffers if rgb_bit_depth is 8, or uint16_t buffers otherwise.
|
|
||||||
// rgb_step: distance in bytes between two horizontally adjacent pixels on the
|
|
||||||
// r, g and b channels. If rgb_bit_depth is > 8, it should be a
|
|
||||||
// multiple of 2.
|
|
||||||
// rgb_stride: distance in bytes between two vertically adjacent pixels on the
|
|
||||||
// r, g, and b channels. If rgb_bit_depth is > 8, it should be a
|
|
||||||
// multiple of 2.
|
|
||||||
// rgb_bit_depth: number of bits for each r/g/b value. One of: 8, 10, 12, 16.
|
|
||||||
// Note: 16 bit input is truncated to 14 bits before conversion to yuv.
|
|
||||||
// yuv_bit_depth: number of bits for each y/u/v value. One of: 8, 10, 12.
|
|
||||||
// y_ptr, u_ptr, v_ptr: pointers to the destination y, u and v channels. Should
|
|
||||||
// point to uint8_t buffers if yuv_bit_depth is 8, or uint16_t buffers
|
|
||||||
// otherwise.
|
|
||||||
// y_stride, u_stride, v_stride: distance in bytes between two vertically
|
|
||||||
// adjacent pixels on the y, u and v channels. If yuv_bit_depth > 8, they
|
|
||||||
// should be multiples of 2.
|
|
||||||
// width, height: width and height of the image in pixels
|
|
||||||
int SharpYuvConvert(const void* r_ptr, const void* g_ptr, const void* b_ptr,
|
|
||||||
int rgb_step, int rgb_stride, int rgb_bit_depth,
|
|
||||||
void* y_ptr, int y_stride, void* u_ptr, int u_stride,
|
|
||||||
void* v_ptr, int v_stride, int yuv_bit_depth, int width,
|
|
||||||
int height, const SharpYuvConversionMatrix* yuv_matrix);
|
|
||||||
|
|
||||||
// TODO(b/194336375): Add YUV444 to YUV420 conversion. Maybe also add 422
|
|
||||||
// support (it's rarely used in practice, especially for images).
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
} // extern "C"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // WEBP_SHARPYUV_SHARPYUV_H_
|
|
||||||
@@ -1,110 +0,0 @@
|
|||||||
// Copyright 2022 Google Inc. All Rights Reserved.
|
|
||||||
//
|
|
||||||
// Use of this source code is governed by a BSD-style license
|
|
||||||
// that can be found in the COPYING file in the root of the source
|
|
||||||
// tree. An additional intellectual property rights grant can be found
|
|
||||||
// in the file PATENTS. All contributing project authors may
|
|
||||||
// be found in the AUTHORS file in the root of the source tree.
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// Colorspace utilities.
|
|
||||||
|
|
||||||
#include "sharpyuv/sharpyuv_csp.h"
|
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
#include <math.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
static int ToFixed16(float f) { return (int)floor(f * (1 << 16) + 0.5f); }
|
|
||||||
|
|
||||||
void SharpYuvComputeConversionMatrix(const SharpYuvColorSpace* yuv_color_space,
|
|
||||||
SharpYuvConversionMatrix* matrix) {
|
|
||||||
const float kr = yuv_color_space->kr;
|
|
||||||
const float kb = yuv_color_space->kb;
|
|
||||||
const float kg = 1.0f - kr - kb;
|
|
||||||
const float cr = 0.5f / (1.0f - kb);
|
|
||||||
const float cb = 0.5f / (1.0f - kr);
|
|
||||||
|
|
||||||
const int shift = yuv_color_space->bit_depth - 8;
|
|
||||||
|
|
||||||
const float denom = (float)((1 << yuv_color_space->bit_depth) - 1);
|
|
||||||
float scale_y = 1.0f;
|
|
||||||
float add_y = 0.0f;
|
|
||||||
float scale_u = cr;
|
|
||||||
float scale_v = cb;
|
|
||||||
float add_uv = (float)(128 << shift);
|
|
||||||
assert(yuv_color_space->bit_depth >= 8);
|
|
||||||
|
|
||||||
if (yuv_color_space->range == kSharpYuvRangeLimited) {
|
|
||||||
scale_y *= (219 << shift) / denom;
|
|
||||||
scale_u *= (224 << shift) / denom;
|
|
||||||
scale_v *= (224 << shift) / denom;
|
|
||||||
add_y = (float)(16 << shift);
|
|
||||||
}
|
|
||||||
|
|
||||||
matrix->rgb_to_y[0] = ToFixed16(kr * scale_y);
|
|
||||||
matrix->rgb_to_y[1] = ToFixed16(kg * scale_y);
|
|
||||||
matrix->rgb_to_y[2] = ToFixed16(kb * scale_y);
|
|
||||||
matrix->rgb_to_y[3] = ToFixed16(add_y);
|
|
||||||
|
|
||||||
matrix->rgb_to_u[0] = ToFixed16(-kr * scale_u);
|
|
||||||
matrix->rgb_to_u[1] = ToFixed16(-kg * scale_u);
|
|
||||||
matrix->rgb_to_u[2] = ToFixed16((1 - kb) * scale_u);
|
|
||||||
matrix->rgb_to_u[3] = ToFixed16(add_uv);
|
|
||||||
|
|
||||||
matrix->rgb_to_v[0] = ToFixed16((1 - kr) * scale_v);
|
|
||||||
matrix->rgb_to_v[1] = ToFixed16(-kg * scale_v);
|
|
||||||
matrix->rgb_to_v[2] = ToFixed16(-kb * scale_v);
|
|
||||||
matrix->rgb_to_v[3] = ToFixed16(add_uv);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Matrices are in YUV_FIX fixed point precision.
|
|
||||||
// WebP's matrix, similar but not identical to kRec601LimitedMatrix.
|
|
||||||
static const SharpYuvConversionMatrix kWebpMatrix = {
|
|
||||||
{16839, 33059, 6420, 16 << 16},
|
|
||||||
{-9719, -19081, 28800, 128 << 16},
|
|
||||||
{28800, -24116, -4684, 128 << 16},
|
|
||||||
};
|
|
||||||
// Kr=0.2990f Kb=0.1140f bits=8 range=kSharpYuvRangeLimited
|
|
||||||
static const SharpYuvConversionMatrix kRec601LimitedMatrix = {
|
|
||||||
{16829, 33039, 6416, 16 << 16},
|
|
||||||
{-9714, -19071, 28784, 128 << 16},
|
|
||||||
{28784, -24103, -4681, 128 << 16},
|
|
||||||
};
|
|
||||||
// Kr=0.2990f Kb=0.1140f bits=8 range=kSharpYuvRangeFull
|
|
||||||
static const SharpYuvConversionMatrix kRec601FullMatrix = {
|
|
||||||
{19595, 38470, 7471, 0},
|
|
||||||
{-11058, -21710, 32768, 128 << 16},
|
|
||||||
{32768, -27439, -5329, 128 << 16},
|
|
||||||
};
|
|
||||||
// Kr=0.2126f Kb=0.0722f bits=8 range=kSharpYuvRangeLimited
|
|
||||||
static const SharpYuvConversionMatrix kRec709LimitedMatrix = {
|
|
||||||
{11966, 40254, 4064, 16 << 16},
|
|
||||||
{-6596, -22189, 28784, 128 << 16},
|
|
||||||
{28784, -26145, -2639, 128 << 16},
|
|
||||||
};
|
|
||||||
// Kr=0.2126f Kb=0.0722f bits=8 range=kSharpYuvRangeFull
|
|
||||||
static const SharpYuvConversionMatrix kRec709FullMatrix = {
|
|
||||||
{13933, 46871, 4732, 0},
|
|
||||||
{-7509, -25259, 32768, 128 << 16},
|
|
||||||
{32768, -29763, -3005, 128 << 16},
|
|
||||||
};
|
|
||||||
|
|
||||||
const SharpYuvConversionMatrix* SharpYuvGetConversionMatrix(
|
|
||||||
SharpYuvMatrixType matrix_type) {
|
|
||||||
switch (matrix_type) {
|
|
||||||
case kSharpYuvMatrixWebp:
|
|
||||||
return &kWebpMatrix;
|
|
||||||
case kSharpYuvMatrixRec601Limited:
|
|
||||||
return &kRec601LimitedMatrix;
|
|
||||||
case kSharpYuvMatrixRec601Full:
|
|
||||||
return &kRec601FullMatrix;
|
|
||||||
case kSharpYuvMatrixRec709Limited:
|
|
||||||
return &kRec709LimitedMatrix;
|
|
||||||
case kSharpYuvMatrixRec709Full:
|
|
||||||
return &kRec709FullMatrix;
|
|
||||||
case kSharpYuvMatrixNum:
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
@@ -1,59 +0,0 @@
|
|||||||
// Copyright 2022 Google Inc. All Rights Reserved.
|
|
||||||
//
|
|
||||||
// Use of this source code is governed by a BSD-style license
|
|
||||||
// that can be found in the COPYING file in the root of the source
|
|
||||||
// tree. An additional intellectual property rights grant can be found
|
|
||||||
// in the file PATENTS. All contributing project authors may
|
|
||||||
// be found in the AUTHORS file in the root of the source tree.
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// Colorspace utilities.
|
|
||||||
|
|
||||||
#ifndef WEBP_SHARPYUV_SHARPYUV_CSP_H_
|
|
||||||
#define WEBP_SHARPYUV_SHARPYUV_CSP_H_
|
|
||||||
|
|
||||||
#include "sharpyuv/sharpyuv.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Range of YUV values.
|
|
||||||
typedef enum {
|
|
||||||
kSharpYuvRangeFull, // YUV values between [0;255] (for 8 bit)
|
|
||||||
kSharpYuvRangeLimited // Y in [16;235], YUV in [16;240] (for 8 bit)
|
|
||||||
} SharpYuvRange;
|
|
||||||
|
|
||||||
// Constants that define a YUV color space.
|
|
||||||
typedef struct {
|
|
||||||
// Kr and Kb are defined such that:
|
|
||||||
// Y = Kr * r + Kg * g + Kb * b where Kg = 1 - Kr - Kb.
|
|
||||||
float kr;
|
|
||||||
float kb;
|
|
||||||
int bit_depth; // 8, 10 or 12
|
|
||||||
SharpYuvRange range;
|
|
||||||
} SharpYuvColorSpace;
|
|
||||||
|
|
||||||
// Fills in 'matrix' for the given YUVColorSpace.
|
|
||||||
void SharpYuvComputeConversionMatrix(const SharpYuvColorSpace* yuv_color_space,
|
|
||||||
SharpYuvConversionMatrix* matrix);
|
|
||||||
|
|
||||||
// Enums for precomputed conversion matrices.
|
|
||||||
typedef enum {
|
|
||||||
kSharpYuvMatrixWebp = 0,
|
|
||||||
kSharpYuvMatrixRec601Limited,
|
|
||||||
kSharpYuvMatrixRec601Full,
|
|
||||||
kSharpYuvMatrixRec709Limited,
|
|
||||||
kSharpYuvMatrixRec709Full,
|
|
||||||
kSharpYuvMatrixNum
|
|
||||||
} SharpYuvMatrixType;
|
|
||||||
|
|
||||||
// Returns a pointer to a matrix for one of the predefined colorspaces.
|
|
||||||
const SharpYuvConversionMatrix* SharpYuvGetConversionMatrix(
|
|
||||||
SharpYuvMatrixType matrix_type);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
} // extern "C"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // WEBP_SHARPYUV_SHARPYUV_CSP_H_
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user