mirror of
https://github.com/webmproject/libwebp.git
synced 2025-07-15 21:39:59 +02:00
Compare commits
9 Commits
Author | SHA1 | Date | |
---|---|---|---|
8d9916da90 | |||
d01505c777 | |||
3f74b25288 | |||
880207c0a7 | |||
d29567c347 | |||
db94456bd1 | |||
34e5da5d29 | |||
7cc4fd6115 | |||
8bac4561bf |
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
|
||||||
|
15
.gitignore
vendored
15
.gitignore
vendored
@ -1,7 +1,6 @@
|
|||||||
*.l[ao]
|
*.l[ao]
|
||||||
*.[ao]
|
*.[ao]
|
||||||
*.pc
|
*.pc
|
||||||
.DS_Store
|
|
||||||
.deps
|
.deps
|
||||||
.libs
|
.libs
|
||||||
/aclocal.m4
|
/aclocal.m4
|
||||||
@ -21,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
|
||||||
@ -34,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
|
|
||||||
|
1
.mailmap
1
.mailmap
@ -11,4 +11,3 @@ Vikas Arora <vikasa@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>
|
|
||||||
|
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
|
|
8
AUTHORS
8
AUTHORS
@ -2,14 +2,9 @@ Contributors:
|
|||||||
- Aidan O'Loan (aidanol at gmail dot com)
|
- Aidan O'Loan (aidanol at gmail dot com)
|
||||||
- Alan Browning (browning at google dot com)
|
- Alan Browning (browning 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)
|
||||||
- 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)
|
||||||
@ -26,7 +21,6 @@ Contributors:
|
|||||||
- 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)
|
||||||
@ -45,7 +39,5 @@ Contributors:
|
|||||||
- 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)
|
- 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)
|
- Yannis Guyon (yguyon at google dot com)
|
||||||
- Zhi An Ng (zhin at chromium dot org)
|
|
||||||
|
@ -74,7 +74,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 \
|
||||||
|
203
CMakeLists.txt
203
CMakeLists.txt
@ -1,30 +1,9 @@
|
|||||||
# Copyright (c) 2020 Google LLC.
|
cmake_minimum_required(VERSION 3.5)
|
||||||
#
|
|
||||||
# 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)
|
|
||||||
|
|
||||||
if(POLICY CMP0072)
|
|
||||||
cmake_policy(SET CMP0072 NEW)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
project(WebP C)
|
project(WebP C)
|
||||||
|
|
||||||
# Options for coder / decoder executables.
|
# Options for coder / decoder executables.
|
||||||
if(NOT EMSCRIPTEN)
|
option(WEBP_ENABLE_SIMD "Enable any SIMD optimization." ON)
|
||||||
# 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})
|
|
||||||
# Emscripten supports SSE builds using its compatibility headers, by default it
|
|
||||||
# will use SSE4 if WEBP_ENABLE_WASM_SIMD is OFF and WEBP_ENABLE_SIMD is ON.
|
|
||||||
option(WEBP_ENABLE_WASM_SIMD "Enable WebAssembly SIMD optimizations" OFF)
|
|
||||||
option(WEBP_BUILD_ANIM_UTILS "Build animation utilities." ON)
|
option(WEBP_BUILD_ANIM_UTILS "Build animation utilities." ON)
|
||||||
option(WEBP_BUILD_CWEBP "Build the cwebp command line tool." 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_DWEBP "Build the dwebp command line tool." ON)
|
||||||
@ -32,11 +11,9 @@ option(WEBP_BUILD_GIF2WEBP "Build the gif2webp conversion tool." ON)
|
|||||||
option(WEBP_BUILD_IMG2WEBP "Build the img2webp animation 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_VWEBP "Build the vwebp viewer tool." ON)
|
||||||
option(WEBP_BUILD_WEBPINFO "Build the webpinfo command line 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_WEBPMUX "Build the webpmux command line tool." ON)
|
||||||
option(WEBP_BUILD_EXTRAS "Build extras." ON)
|
option(WEBP_BUILD_EXTRAS "Build extras." ON)
|
||||||
option(WEBP_BUILD_WEBP_JS "Emscripten build of webp.js." OFF)
|
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_NEAR_LOSSLESS "Enable near-lossless encoding" ON)
|
||||||
option(WEBP_ENABLE_SWAP_16BIT_CSP "Enable byte swap for 16 bit colorspaces."
|
option(WEBP_ENABLE_SWAP_16BIT_CSP "Enable byte swap for 16 bit colorspaces."
|
||||||
OFF)
|
OFF)
|
||||||
@ -49,19 +26,16 @@ if(WIN32)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(WEBP_BUILD_WEBP_JS)
|
if(WEBP_BUILD_WEBP_JS)
|
||||||
|
set(WEBP_ENABLE_SIMD OFF)
|
||||||
set(WEBP_BUILD_ANIM_UTILS OFF)
|
set(WEBP_BUILD_ANIM_UTILS OFF)
|
||||||
set(WEBP_BUILD_CWEBP OFF)
|
set(WEBP_BUILD_CWEBP OFF)
|
||||||
|
set(WEBP_BUILD_DWEBP OFF)
|
||||||
set(WEBP_BUILD_GIF2WEBP OFF)
|
set(WEBP_BUILD_GIF2WEBP OFF)
|
||||||
set(WEBP_BUILD_IMG2WEBP OFF)
|
set(WEBP_BUILD_IMG2WEBP OFF)
|
||||||
set(WEBP_BUILD_VWEBP OFF)
|
set(WEBP_BUILD_VWEBP OFF)
|
||||||
set(WEBP_BUILD_WEBPINFO OFF)
|
set(WEBP_BUILD_WEBPINFO OFF)
|
||||||
set(WEBP_BUILD_WEBPMUX OFF)
|
set(WEBP_BUILD_WEBPMUX OFF)
|
||||||
set(WEBP_BUILD_EXTRAS 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()
|
endif()
|
||||||
|
|
||||||
set(WEBP_DEP_LIBRARIES)
|
set(WEBP_DEP_LIBRARIES)
|
||||||
@ -69,7 +43,7 @@ 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 STRING "Build type: Release, Debug, MinSizeRel or RelWithDebInfo"
|
CACHE "Build type: Release, Debug, MinSizeRel or RelWithDebInfo" STRING
|
||||||
FORCE)
|
FORCE)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
@ -82,9 +56,6 @@ include(GNUInstallDirs)
|
|||||||
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=1)
|
||||||
endif()
|
endif()
|
||||||
if(WEBP_ENABLE_WASM_SIMD)
|
|
||||||
add_definitions(-DWEBP_ENABLE_WASM_SIMD_INTRINSICS)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(NOT WEBP_BITTRACE STREQUAL "0")
|
if(NOT WEBP_BITTRACE STREQUAL "0")
|
||||||
add_definitions(-DBITTRACE=${WEBP_BITTRACE})
|
add_definitions(-DBITTRACE=${WEBP_BITTRACE})
|
||||||
@ -193,29 +164,6 @@ add_definitions(-DHAVE_CONFIG_H)
|
|||||||
|
|
||||||
# ##############################################################################
|
# ##############################################################################
|
||||||
# Build the webpdecoder library.
|
# Build the webpdecoder library.
|
||||||
|
|
||||||
# Creates a source file with an unused stub function in $CMAKE_BINARY_DIR and
|
|
||||||
# adds it to the specified target. Currently used only with Xcode.
|
|
||||||
#
|
|
||||||
# See also:
|
|
||||||
# https://cmake.org/cmake/help/v3.18/command/add_library.html#object-libraries
|
|
||||||
# "Some native build systems (such as Xcode) may not like targets that have
|
|
||||||
# only object files, so consider adding at least one real source file to any
|
|
||||||
# target that references $<TARGET_OBJECTS:objlib>."
|
|
||||||
function(libwebp_add_stub_file TARGET)
|
|
||||||
set(stub_source_dir "${CMAKE_BINARY_DIR}")
|
|
||||||
set(stub_source_file
|
|
||||||
"${stub_source_dir}/libwebp_${TARGET}_stub.c")
|
|
||||||
set(stub_source_code
|
|
||||||
"// Generated file. DO NOT EDIT!\n"
|
|
||||||
"// C source file created for target ${TARGET}.\n"
|
|
||||||
"void libwebp_${TARGET}_stub_function(void)\;\n"
|
|
||||||
"void libwebp_${TARGET}_stub_function(void) {}\n")
|
|
||||||
file(WRITE "${stub_source_file}" ${stub_source_code})
|
|
||||||
|
|
||||||
target_sources(${TARGET} PRIVATE ${stub_source_file})
|
|
||||||
endfunction()
|
|
||||||
|
|
||||||
if(MSVC)
|
if(MSVC)
|
||||||
# avoid security warnings for e.g., fopen() used in the examples.
|
# avoid security warnings for e.g., fopen() used in the examples.
|
||||||
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
|
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
|
||||||
@ -242,9 +190,6 @@ add_library(webpdecoder
|
|||||||
$<TARGET_OBJECTS:webpdecode>
|
$<TARGET_OBJECTS:webpdecode>
|
||||||
$<TARGET_OBJECTS:webpdspdecode>
|
$<TARGET_OBJECTS:webpdspdecode>
|
||||||
$<TARGET_OBJECTS:webputilsdecode>)
|
$<TARGET_OBJECTS:webputilsdecode>)
|
||||||
if(XCODE)
|
|
||||||
libwebp_add_stub_file(webpdecoder)
|
|
||||||
endif()
|
|
||||||
target_link_libraries(webpdecoder ${WEBP_DEP_LIBRARIES})
|
target_link_libraries(webpdecoder ${WEBP_DEP_LIBRARIES})
|
||||||
target_include_directories(
|
target_include_directories(
|
||||||
webpdecoder
|
webpdecoder
|
||||||
@ -284,16 +229,11 @@ add_library(webp
|
|||||||
$<TARGET_OBJECTS:webpdsp>
|
$<TARGET_OBJECTS:webpdsp>
|
||||||
$<TARGET_OBJECTS:webpencode>
|
$<TARGET_OBJECTS:webpencode>
|
||||||
$<TARGET_OBJECTS:webputils>)
|
$<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(
|
target_include_directories(webp
|
||||||
webp
|
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
|
||||||
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
|
${CMAKE_CURRENT_BINARY_DIR}
|
||||||
${CMAKE_CURRENT_BINARY_DIR}
|
PUBLIC $<INSTALL_INTERFACE:include>)
|
||||||
PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>
|
|
||||||
$<INSTALL_INTERFACE:include>)
|
|
||||||
set_target_properties(
|
set_target_properties(
|
||||||
webp
|
webp
|
||||||
PROPERTIES PUBLIC_HEADER "${CMAKE_CURRENT_SOURCE_DIR}/src/webp/decode.h;\
|
PROPERTIES PUBLIC_HEADER "${CMAKE_CURRENT_SOURCE_DIR}/src/webp/decode.h;\
|
||||||
@ -328,10 +268,10 @@ ${CMAKE_CURRENT_SOURCE_DIR}/src/webp/types.h")
|
|||||||
configure_pkg_config("src/demux/libwebpdemux.pc")
|
configure_pkg_config("src/demux/libwebpdemux.pc")
|
||||||
|
|
||||||
# Set the version numbers.
|
# Set the version numbers.
|
||||||
macro(set_version FILE TARGET_NAME NAME_IN_MAKEFILE)
|
function(parse_version FILE NAME VAR)
|
||||||
file(READ ${CMAKE_CURRENT_SOURCE_DIR}/src/${FILE} SOURCE_FILE)
|
file(READ ${CMAKE_CURRENT_SOURCE_DIR}/src/${FILE} SOURCE_FILE)
|
||||||
string(REGEX MATCH
|
string(REGEX MATCH
|
||||||
"${NAME_IN_MAKEFILE}_la_LDFLAGS[^\n]* -version-info [0-9:]+"
|
"${NAME}_la_LDFLAGS[^\n]* -version-info [0-9:]+"
|
||||||
TMP
|
TMP
|
||||||
${SOURCE_FILE})
|
${SOURCE_FILE})
|
||||||
string(REGEX MATCH
|
string(REGEX MATCH
|
||||||
@ -340,35 +280,29 @@ macro(set_version FILE TARGET_NAME NAME_IN_MAKEFILE)
|
|||||||
${TMP})
|
${TMP})
|
||||||
string(REGEX
|
string(REGEX
|
||||||
REPLACE ":"
|
REPLACE ":"
|
||||||
" "
|
"."
|
||||||
LT_VERSION
|
VERSION
|
||||||
${TMP})
|
${TMP})
|
||||||
|
set(${VAR} "${VERSION}" PARENT_SCOPE)
|
||||||
# See the libtool docs for more information:
|
endfunction()
|
||||||
# https://www.gnu.org/software/libtool/manual/libtool.html#Updating-version-info
|
parse_version(Makefile.am webp WEBP_WEBP_SOVERSION)
|
||||||
#
|
set_target_properties(webp
|
||||||
# c=<current>, a=<age>, r=<revision>
|
PROPERTIES VERSION
|
||||||
#
|
${PACKAGE_VERSION}
|
||||||
# libtool generates a .so file as .so.[c-a].a.r, while -version-info c:r:a is
|
SOVERSION
|
||||||
# passed to libtool.
|
${WEBP_WEBP_SOVERSION})
|
||||||
#
|
parse_version(Makefile.am webpdecoder WEBP_DECODER_SOVERSION)
|
||||||
# We set FULL = [c-a].a.r and MAJOR = [c-a].
|
set_target_properties(webpdecoder
|
||||||
separate_arguments(LT_VERSION)
|
PROPERTIES VERSION
|
||||||
list(GET LT_VERSION 0 LT_CURRENT)
|
${PACKAGE_VERSION}
|
||||||
list(GET LT_VERSION 1 LT_REVISION)
|
SOVERSION
|
||||||
list(GET LT_VERSION 2 LT_AGE)
|
${WEBP_DECODER_SOVERSION})
|
||||||
math(EXPR LT_CURRENT_MINUS_AGE "${LT_CURRENT} - ${LT_AGE}")
|
parse_version(demux/Makefile.am webpdemux WEBP_DEMUX_SOVERSION)
|
||||||
|
set_target_properties(webpdemux
|
||||||
set_target_properties(
|
PROPERTIES VERSION
|
||||||
${TARGET_NAME}
|
${PACKAGE_VERSION}
|
||||||
PROPERTIES VERSION
|
SOVERSION
|
||||||
${LT_CURRENT_MINUS_AGE}.${LT_AGE}.${LT_REVISION}
|
${WEBP_DEMUX_SOVERSION})
|
||||||
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)
|
file(READ ${CMAKE_CURRENT_SOURCE_DIR}/configure.ac CONFIGURE_FILE)
|
||||||
string(REGEX MATCH
|
string(REGEX MATCH
|
||||||
"AC_INIT\\([^\n]*\\[[0-9\\.]+\\]"
|
"AC_INIT\\([^\n]*\\[[0-9\\.]+\\]"
|
||||||
@ -396,12 +330,6 @@ foreach(I_FILE RANGE ${WEBP_SIMD_FILES_TO_INCLUDE_RANGE})
|
|||||||
${SIMD_COMPILE_FLAG})
|
${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)
|
if(WEBP_BUILD_GIF2WEBP AND NOT GIF_FOUND)
|
||||||
set(WEBP_BUILD_GIF2WEBP OFF)
|
set(WEBP_BUILD_GIF2WEBP OFF)
|
||||||
endif()
|
endif()
|
||||||
@ -421,21 +349,20 @@ if(WEBP_BUILD_ANIM_UTILS
|
|||||||
parse_makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/examples "EXAMPLEUTIL_SRCS"
|
parse_makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/examples "EXAMPLEUTIL_SRCS"
|
||||||
"example_util_[^ ]*")
|
"example_util_[^ ]*")
|
||||||
list(APPEND EXAMPLEUTIL_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/examples/stopwatch.h)
|
list(APPEND EXAMPLEUTIL_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/examples/stopwatch.h)
|
||||||
add_library(exampleutil STATIC ${EXAMPLEUTIL_SRCS})
|
add_library(exampleutil ${EXAMPLEUTIL_SRCS})
|
||||||
target_link_libraries(exampleutil imageioutil)
|
|
||||||
target_include_directories(
|
target_include_directories(
|
||||||
exampleutil
|
exampleutil
|
||||||
PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>)
|
PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>)
|
||||||
|
|
||||||
parse_makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/imageio "IMAGEIOUTILS_SRCS"
|
parse_makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/imageio "IMAGEIOUTILS_SRCS"
|
||||||
"imageio_util_[^ ]*")
|
"imageio_util_[^ ]*")
|
||||||
add_library(imageioutil STATIC ${IMAGEIOUTILS_SRCS})
|
add_library(imageioutil ${IMAGEIOUTILS_SRCS})
|
||||||
target_link_libraries(imageioutil webp)
|
target_link_libraries(imageioutil webp)
|
||||||
|
|
||||||
# Image-decoding utility library.
|
# Image-decoding utility library.
|
||||||
parse_makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/imageio "IMAGEDEC_SRCS"
|
parse_makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/imageio "IMAGEDEC_SRCS"
|
||||||
"imagedec_[^ ]*")
|
"imagedec_[^ ]*")
|
||||||
add_library(imagedec STATIC ${IMAGEDEC_SRCS})
|
add_library(imagedec ${IMAGEDEC_SRCS})
|
||||||
target_link_libraries(imagedec
|
target_link_libraries(imagedec
|
||||||
imageioutil
|
imageioutil
|
||||||
webpdemux
|
webpdemux
|
||||||
@ -445,8 +372,8 @@ if(WEBP_BUILD_ANIM_UTILS
|
|||||||
# Image-encoding utility library.
|
# Image-encoding utility library.
|
||||||
parse_makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/imageio "IMAGEENC_SRCS"
|
parse_makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/imageio "IMAGEENC_SRCS"
|
||||||
"imageenc_[^ ]*")
|
"imageenc_[^ ]*")
|
||||||
add_library(imageenc STATIC ${IMAGEENC_SRCS})
|
add_library(imageenc ${IMAGEENC_SRCS})
|
||||||
target_link_libraries(imageenc imageioutil webp)
|
target_link_libraries(imageenc webp)
|
||||||
|
|
||||||
set_property(TARGET exampleutil
|
set_property(TARGET exampleutil
|
||||||
imageioutil
|
imageioutil
|
||||||
@ -474,14 +401,19 @@ if(WEBP_BUILD_CWEBP)
|
|||||||
install(TARGETS cwebp RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
|
install(TARGETS cwebp RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(WEBP_BUILD_LIBWEBPMUX)
|
if(WEBP_BUILD_GIF2WEBP OR WEBP_BUILD_IMG2WEBP)
|
||||||
parse_makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/src/mux "WEBP_MUX_SRCS" "")
|
parse_makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/src/mux "WEBP_MUX_SRCS" "")
|
||||||
add_library(libwebpmux ${WEBP_MUX_SRCS})
|
add_library(libwebpmux ${WEBP_MUX_SRCS})
|
||||||
target_link_libraries(libwebpmux webp)
|
target_link_libraries(libwebpmux webp)
|
||||||
target_include_directories(libwebpmux
|
target_include_directories(libwebpmux
|
||||||
PRIVATE ${CMAKE_CURRENT_BINARY_DIR}
|
PRIVATE ${CMAKE_CURRENT_BINARY_DIR}
|
||||||
${CMAKE_CURRENT_SOURCE_DIR})
|
${CMAKE_CURRENT_SOURCE_DIR})
|
||||||
set_version(mux/Makefile.am libwebpmux webpmux)
|
parse_version(mux/Makefile.am webpmux WEBP_MUX_SOVERSION)
|
||||||
|
set_target_properties(libwebpmux
|
||||||
|
PROPERTIES VERSION
|
||||||
|
${PACKAGE_VERSION}
|
||||||
|
SOVERSION
|
||||||
|
${WEBP_MUX_SOVERSION})
|
||||||
set_target_properties(libwebpmux
|
set_target_properties(libwebpmux
|
||||||
PROPERTIES PUBLIC_HEADER
|
PROPERTIES PUBLIC_HEADER
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}/src/webp/mux.h;\
|
"${CMAKE_CURRENT_SOURCE_DIR}/src/webp/mux.h;\
|
||||||
@ -534,12 +466,12 @@ if(WEBP_BUILD_VWEBP)
|
|||||||
target_link_libraries(vwebp
|
target_link_libraries(vwebp
|
||||||
${OPENGL_LIBRARIES}
|
${OPENGL_LIBRARIES}
|
||||||
exampleutil
|
exampleutil
|
||||||
${GLUT_glut_LIBRARY}
|
GLUT::GLUT
|
||||||
imageioutil
|
imageioutil
|
||||||
webp
|
webp
|
||||||
webpdemux)
|
webpdemux)
|
||||||
target_include_directories(vwebp
|
target_include_directories(vwebp
|
||||||
PRIVATE ${GLUT_INCLUDE_DIR}
|
PRIVATE GLUT::GLUT
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/src
|
${CMAKE_CURRENT_BINARY_DIR}/src
|
||||||
${OPENGL_INCLUDE_DIR})
|
${OPENGL_INCLUDE_DIR})
|
||||||
install(TARGETS vwebp RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
|
install(TARGETS vwebp RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
|
||||||
@ -585,14 +517,15 @@ if(WEBP_BUILD_EXTRAS)
|
|||||||
target_link_libraries(get_disto imagedec)
|
target_link_libraries(get_disto imagedec)
|
||||||
target_include_directories(get_disto
|
target_include_directories(get_disto
|
||||||
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
|
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/src
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/src)
|
${CMAKE_CURRENT_BINARY_DIR}/src)
|
||||||
|
install(TARGETS get_disto RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
|
||||||
|
|
||||||
# webp_quality
|
# webp_quality
|
||||||
add_executable(webp_quality ${WEBP_QUALITY_SRCS} ${WEBP_EXTRAS_SRCS})
|
add_executable(webp_quality ${WEBP_QUALITY_SRCS} ${WEBP_EXTRAS_SRCS})
|
||||||
target_link_libraries(webp_quality exampleutil imagedec)
|
target_link_libraries(webp_quality exampleutil imagedec)
|
||||||
target_include_directories(webp_quality
|
target_include_directories(webp_quality PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
|
||||||
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
|
install(TARGETS webp_quality RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
|
||||||
${CMAKE_CURRENT_BINARY_DIR})
|
|
||||||
|
|
||||||
# vwebp_sdl
|
# vwebp_sdl
|
||||||
find_package(SDL)
|
find_package(SDL)
|
||||||
@ -601,30 +534,29 @@ if(WEBP_BUILD_EXTRAS)
|
|||||||
target_link_libraries(vwebp_sdl ${SDL_LIBRARY} imageioutil webp)
|
target_link_libraries(vwebp_sdl ${SDL_LIBRARY} imageioutil webp)
|
||||||
target_include_directories(vwebp_sdl
|
target_include_directories(vwebp_sdl
|
||||||
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
|
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/src
|
||||||
${CMAKE_CURRENT_BINARY_DIR}
|
${CMAKE_CURRENT_BINARY_DIR}
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/src
|
${CMAKE_CURRENT_BINARY_DIR}/src
|
||||||
${SDL_INCLUDE_DIR})
|
${SDL_INCLUDE_DIR})
|
||||||
set(WEBP_HAVE_SDL 1)
|
set(WEBP_HAVE_SDL 1)
|
||||||
target_compile_definitions(vwebp_sdl PUBLIC WEBP_HAVE_SDL)
|
target_compile_definitions(vwebp_sdl PUBLIC WEBP_HAVE_SDL)
|
||||||
|
install(TARGETS vwebp_sdl RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(WEBP_BUILD_WEBP_JS)
|
if(WEBP_BUILD_WEBP_JS)
|
||||||
# wasm2js does not support SIMD.
|
# JavaScript version
|
||||||
if(NOT WEBP_ENABLE_SIMD)
|
add_executable(webp_js ${CMAKE_CURRENT_SOURCE_DIR}/extras/webp_to_sdl.c)
|
||||||
# JavaScript version
|
target_link_libraries(webp_js webpdecoder SDL)
|
||||||
add_executable(webp_js ${CMAKE_CURRENT_SOURCE_DIR}/extras/webp_to_sdl.c)
|
target_include_directories(webp_js PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
|
||||||
target_link_libraries(webp_js webpdecoder SDL)
|
set(WEBP_HAVE_SDL 1)
|
||||||
target_include_directories(webp_js PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
|
set_target_properties(
|
||||||
set(WEBP_HAVE_SDL 1)
|
webp_js
|
||||||
set_target_properties(
|
PROPERTIES LINK_FLAGS
|
||||||
webp_js
|
"-s EXPORTED_FUNCTIONS='[\"_WebpToSDL\"]' -s INVOKE_RUN=0 \
|
||||||
PROPERTIES LINK_FLAGS "-s WASM=0 \
|
-s EXTRA_EXPORTED_RUNTIME_METHODS='[\"cwrap\"]'")
|
||||||
-s EXPORTED_FUNCTIONS='[\"_WebpToSDL\"]' -s INVOKE_RUN=0 \
|
set_target_properties(webp_js PROPERTIES OUTPUT_NAME webp)
|
||||||
-s EXPORTED_RUNTIME_METHODS='[\"cwrap\"]'")
|
target_compile_definitions(webp_js PUBLIC EMSCRIPTEN WEBP_HAVE_SDL)
|
||||||
set_target_properties(webp_js PROPERTIES OUTPUT_NAME webp)
|
|
||||||
target_compile_definitions(webp_js PUBLIC EMSCRIPTEN WEBP_HAVE_SDL)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# WASM version
|
# WASM version
|
||||||
add_executable(webp_wasm ${CMAKE_CURRENT_SOURCE_DIR}/extras/webp_to_sdl.c)
|
add_executable(webp_wasm ${CMAKE_CURRENT_SOURCE_DIR}/extras/webp_to_sdl.c)
|
||||||
@ -634,7 +566,7 @@ if(WEBP_BUILD_WEBP_JS)
|
|||||||
webp_wasm
|
webp_wasm
|
||||||
PROPERTIES LINK_FLAGS "-s WASM=1 \
|
PROPERTIES LINK_FLAGS "-s WASM=1 \
|
||||||
-s EXPORTED_FUNCTIONS='[\"_WebpToSDL\"]' -s INVOKE_RUN=0 \
|
-s EXPORTED_FUNCTIONS='[\"_WebpToSDL\"]' -s INVOKE_RUN=0 \
|
||||||
-s EXPORTED_RUNTIME_METHODS='[\"cwrap\"]'")
|
-s EXTRA_EXPORTED_RUNTIME_METHODS='[\"cwrap\"]'")
|
||||||
target_compile_definitions(webp_wasm PUBLIC EMSCRIPTEN WEBP_HAVE_SDL)
|
target_compile_definitions(webp_wasm PUBLIC EMSCRIPTEN WEBP_HAVE_SDL)
|
||||||
|
|
||||||
target_compile_definitions(webpdspdecode PUBLIC EMSCRIPTEN)
|
target_compile_definitions(webpdspdecode PUBLIC EMSCRIPTEN)
|
||||||
@ -652,6 +584,7 @@ if(WEBP_BUILD_ANIM_UTILS)
|
|||||||
imageenc
|
imageenc
|
||||||
imageioutil
|
imageioutil
|
||||||
webp
|
webp
|
||||||
|
libwebpmux
|
||||||
webpdemux
|
webpdemux
|
||||||
${WEBP_DEP_GIF_LIBRARIES})
|
${WEBP_DEP_GIF_LIBRARIES})
|
||||||
target_include_directories(anim_diff PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/src)
|
target_include_directories(anim_diff PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/src)
|
||||||
@ -667,12 +600,14 @@ if(WEBP_BUILD_ANIM_UTILS)
|
|||||||
imageenc
|
imageenc
|
||||||
imageioutil
|
imageioutil
|
||||||
webp
|
webp
|
||||||
|
libwebpmux
|
||||||
webpdemux
|
webpdemux
|
||||||
${WEBP_DEP_GIF_LIBRARIES})
|
${WEBP_DEP_GIF_LIBRARIES})
|
||||||
target_include_directories(anim_dump PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/src)
|
target_include_directories(anim_dump PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/src)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Install the different headers and libraries.
|
# Install the different headers and libraries.
|
||||||
|
include(GNUInstallDirs)
|
||||||
install(TARGETS ${INSTALLED_LIBRARIES}
|
install(TARGETS ${INSTALLED_LIBRARIES}
|
||||||
EXPORT ${PROJECT_NAME}Targets
|
EXPORT ${PROJECT_NAME}Targets
|
||||||
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/webp
|
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/webp
|
||||||
|
@ -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/).
|
|
205
ChangeLog
205
ChangeLog
@ -1,208 +1,3 @@
|
|||||||
d9191588 fuzzer/*: normalize src/ includes
|
|
||||||
53b6f762 fix indent
|
|
||||||
731246ba update ChangeLog (tag: v1.2.1-rc2)
|
|
||||||
d250f01d 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, origin/1.1.0)
|
|
||||||
7f006436 Makefile.vc: fix webp_quality.exe link
|
|
||||||
cf047e83 Makefile.vc: fix webp_quality.exe link
|
|
||||||
c074c653 update NEWS
|
|
||||||
30f09551 bump version to 1.1.0
|
|
||||||
a76694a1 update AUTHORS
|
|
||||||
6e3ef7b3 extras: fix WEBP_SWAP_16BIT_CSP check
|
|
||||||
47178dbd extras: add WebPUnmultiplyARGB() convenience function
|
|
||||||
22cbae33 idec_dec: fix 0 offset of NULL pointer
|
|
||||||
290dd0b4 muxread: fix 0 offset of NULL pointer
|
|
||||||
0df474ac Merge "lossless_(enc_|)sse2: avoid offsetting a NULL pointer"
|
|
||||||
c6b75a19 lossless_(enc_|)sse2: avoid offsetting a NULL pointer
|
|
||||||
295e5e38 fix UBSAN warning
|
|
||||||
e2575e05 DC8_NEON,aarch64: use vaddv
|
|
||||||
b0e09e34 dec_neon: Fix build failure under some toolchains
|
|
||||||
cf0e903c dsp/lossless: Fix non gcc ARM builds
|
|
||||||
bb7bc40b Remove ubsan errors.
|
|
||||||
78881b76 CMake: fix GLUT library link
|
|
||||||
9f750f7a cmake: fix BUILD_SHARED_LIBS build on mac
|
|
||||||
17850e74 libwebp: Remove char-subscripts warning in pnmdec.c
|
|
||||||
2fa2552d Merge "Expose WebPMalloc() in addition to WebPFree()"
|
|
||||||
a4df4aae Expose WebPMalloc() in addition to WebPFree()
|
|
||||||
853ea3d8 imageio/tiff: Return error before allocating bad tile size
|
|
||||||
af650c0b Fix a Wxor-used-as-pow false positive
|
|
||||||
601ef17c libwebp.py: update to swig 3.0.12
|
|
||||||
0e48d889 bugfix: last alpha rows were incorrectly decoded
|
|
||||||
24d2ccb4 webp: Fix imageio ReadPNM() TUPLTYPE
|
|
||||||
fab8f9cf cosmetics: normalize '*' association
|
|
||||||
94138e0e update .gitignore
|
|
||||||
0fe1a89d update ChangeLog (tag: v1.0.3-rc1, tag: v1.0.3)
|
|
||||||
2ad0916d update NEWS
|
2ad0916d update NEWS
|
||||||
1287362b bump version to 1.0.3
|
1287362b bump version to 1.0.3
|
||||||
7b968cc2 update AUTHORS
|
7b968cc2 update AUTHORS
|
||||||
|
11
Makefile.vc
11
Makefile.vc
@ -28,7 +28,7 @@ PLATFORM_LDFLAGS = /SAFESEH
|
|||||||
|
|
||||||
NOLOGO = /nologo
|
NOLOGO = /nologo
|
||||||
CCNODBG = cl.exe $(NOLOGO) /O2 /DNDEBUG
|
CCNODBG = cl.exe $(NOLOGO) /O2 /DNDEBUG
|
||||||
CCDEBUG = cl.exe $(NOLOGO) /Od /Zi /D_DEBUG /RTC1
|
CCDEBUG = cl.exe $(NOLOGO) /Od /Gm /Zi /D_DEBUG /RTC1
|
||||||
CFLAGS = /I. /Isrc $(NOLOGO) /W3 /EHsc /c
|
CFLAGS = /I. /Isrc $(NOLOGO) /W3 /EHsc /c
|
||||||
CFLAGS = $(CFLAGS) /DWIN32 /D_CRT_SECURE_NO_WARNINGS /DWIN32_LEAN_AND_MEAN
|
CFLAGS = $(CFLAGS) /DWIN32 /D_CRT_SECURE_NO_WARNINGS /DWIN32_LEAN_AND_MEAN
|
||||||
LDFLAGS = /LARGEADDRESSAWARE /MANIFEST /NXCOMPAT /DYNAMICBASE
|
LDFLAGS = /LARGEADDRESSAWARE /MANIFEST /NXCOMPAT /DYNAMICBASE
|
||||||
@ -215,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 \
|
||||||
@ -392,13 +391,7 @@ $(DIRBIN)\get_disto.exe: $(IMAGEIO_DEC_OBJS) $(IMAGEIO_UTIL_OBJS)
|
|||||||
$(DIRBIN)\get_disto.exe: $(LIBWEBPDEMUX) $(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: $(DIROBJ)\examples\webpinfo.obj
|
||||||
$(DIRBIN)\webpinfo.exe: $(IMAGEIO_DEC_OBJS)
|
$(DIRBIN)\webpinfo.exe: $(IMAGEIO_DEC_OBJS)
|
||||||
$(DIRBIN)\webpinfo.exe: $(EX_UTIL_OBJS) $(IMAGEIO_UTIL_OBJS)
|
$(DIRBIN)\webpinfo.exe: $(EX_UTIL_OBJS) $(IMAGEIO_UTIL_OBJS)
|
||||||
|
35
NEWS
35
NEWS
@ -1,38 +1,3 @@
|
|||||||
- 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
|
- 7/4/2019: version 1.0.3
|
||||||
This is a binary compatible release.
|
This is a binary compatible release.
|
||||||
* resize fixes for Nx1 sizes and the addition of non-opaque alpha values for
|
* resize fixes for Nx1 sizes and the addition of non-opaque alpha values for
|
||||||
|
183
PRESUBMIT.py
183
PRESUBMIT.py
@ -1,183 +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 subprocess2
|
|
||||||
|
|
||||||
USE_PYTHON3 = True
|
|
||||||
_BASH_INDENTATION = "2"
|
|
||||||
_INCLUDE_BASH_FILES_ONLY = [r".*\.sh$"]
|
|
||||||
_INCLUDE_MAN_FILES_ONLY = [r"man/.+\.1$"]
|
|
||||||
_LIBWEBP_MAX_LINE_LENGTH = 80
|
|
||||||
|
|
||||||
|
|
||||||
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))
|
|
||||||
|
|
||||||
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
|
|
16
README
16
README
@ -4,7 +4,7 @@
|
|||||||
\__\__/\____/\_____/__/ ____ ___
|
\__\__/\____/\_____/__/ ____ ___
|
||||||
/ _/ / \ \ / _ \/ _/
|
/ _/ / \ \ / _ \/ _/
|
||||||
/ \_/ / / \ \ __/ \__
|
/ \_/ / / \ \ __/ \__
|
||||||
\____/____/\_____/_____/____/v1.2.1
|
\____/____/\_____/_____/____/v1.0.3
|
||||||
|
|
||||||
Description:
|
Description:
|
||||||
============
|
============
|
||||||
@ -113,7 +113,7 @@ make install
|
|||||||
|
|
||||||
CMake:
|
CMake:
|
||||||
------
|
------
|
||||||
With CMake, you can compile libwebp, cwebp, dwebp, gif2webp, img2webp, webpinfo
|
With CMake, you can compile libwebp, cwebp, dwebp, gif2web, img2webp, webpinfo
|
||||||
and the JS bindings.
|
and the JS bindings.
|
||||||
|
|
||||||
Prerequisites:
|
Prerequisites:
|
||||||
@ -225,7 +225,6 @@ Usage:
|
|||||||
|
|
||||||
If input size (-s) for an image is not specified, it is
|
If input size (-s) for an image is not specified, it is
|
||||||
assumed to be a PNG, JPEG, TIFF or WebP file.
|
assumed to be a PNG, JPEG, TIFF or WebP file.
|
||||||
Note: Animated PNG and WebP files are not supported.
|
|
||||||
|
|
||||||
Options:
|
Options:
|
||||||
-h / -help ............. short help
|
-h / -help ............. short help
|
||||||
@ -255,8 +254,6 @@ Options:
|
|||||||
-partition_limit <int> . limit quality to fit the 512k limit on
|
-partition_limit <int> . limit quality to fit the 512k limit on
|
||||||
the first partition (0=no degradation ... 100=full)
|
the first partition (0=no degradation ... 100=full)
|
||||||
-pass <int> ............ analysis pass number (1..10)
|
-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
|
-crop <x> <y> <w> <h> .. crop picture with the given rectangle
|
||||||
-resize <w> <h> ........ resize picture (after any cropping)
|
-resize <w> <h> ........ resize picture (after any cropping)
|
||||||
-mt .................... use multi-threading if available
|
-mt .................... use multi-threading if available
|
||||||
@ -297,7 +294,6 @@ Experimental Options:
|
|||||||
-af .................... auto-adjust filter strength
|
-af .................... auto-adjust filter strength
|
||||||
-pre <int> ............. pre-processing filter
|
-pre <int> ............. pre-processing filter
|
||||||
|
|
||||||
|
|
||||||
The main options you might want to try in order to further tune the
|
The main options you might want to try in order to further tune the
|
||||||
visual quality are:
|
visual quality are:
|
||||||
-preset
|
-preset
|
||||||
@ -345,9 +341,7 @@ The full list of options is available using -h:
|
|||||||
> dwebp -h
|
> dwebp -h
|
||||||
Usage: dwebp in_file [options] [-o out_file]
|
Usage: dwebp in_file [options] [-o out_file]
|
||||||
|
|
||||||
Decodes the WebP image file to PNG format [Default].
|
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:
|
Use following options to convert into alternate image formats:
|
||||||
-pam ......... save the raw RGBA samples as a color PAM
|
-pam ......... save the raw RGBA samples as a color PAM
|
||||||
-ppm ......... save the raw RGB samples as a color PPM
|
-ppm ......... save the raw RGB samples as a color PPM
|
||||||
@ -429,7 +423,7 @@ Prerequisites:
|
|||||||
1) OpenGL & OpenGL Utility Toolkit (GLUT)
|
1) OpenGL & OpenGL Utility Toolkit (GLUT)
|
||||||
Linux:
|
Linux:
|
||||||
$ sudo apt-get install freeglut3-dev mesa-common-dev
|
$ sudo apt-get install freeglut3-dev mesa-common-dev
|
||||||
Mac + Xcode:
|
Mac + XCode:
|
||||||
- These libraries should be available in the OpenGL / GLUT frameworks.
|
- These libraries should be available in the OpenGL / GLUT frameworks.
|
||||||
Windows:
|
Windows:
|
||||||
http://freeglut.sourceforge.net/index.php#download
|
http://freeglut.sourceforge.net/index.php#download
|
||||||
@ -619,7 +613,7 @@ The encoding flow looks like:
|
|||||||
pic.width = width;
|
pic.width = width;
|
||||||
pic.height = height;
|
pic.height = height;
|
||||||
// allocated picture of dimension width x height
|
// allocated picture of dimension width x height
|
||||||
if (!WebPPictureAlloc(&pic)) {
|
if (!WebPPictureAllocate(&pic)) {
|
||||||
return 0; // memory error
|
return 0; // memory error
|
||||||
}
|
}
|
||||||
// at this point, 'pic' has been initialized as a container,
|
// at this point, 'pic' has been initialized as a container,
|
||||||
|
12
README.mux
12
README.mux
@ -1,7 +1,7 @@
|
|||||||
__ __ ____ ____ ____ __ __ _ __ __
|
__ __ ____ ____ ____ __ __ _ __ __
|
||||||
/ \\/ \/ _ \/ _ \/ _ \/ \ \/ \___/_ / _\
|
/ \\/ \/ _ \/ _ \/ _ \/ \ \/ \___/_ / _\
|
||||||
\ / __/ _ \ __/ / / (_/ /__
|
\ / __/ _ \ __/ / / (_/ /__
|
||||||
\__\__/\_____/_____/__/ \__//_/\_____/__/___/v1.2.1
|
\__\__/\_____/_____/__/ \__//_/\_____/__/___/v1.0.3
|
||||||
|
|
||||||
|
|
||||||
Description:
|
Description:
|
||||||
@ -43,12 +43,10 @@ GET_OPTIONS:
|
|||||||
frame n get nth frame
|
frame n get nth frame
|
||||||
|
|
||||||
SET_OPTIONS:
|
SET_OPTIONS:
|
||||||
Set color profile/metadata/parameters:
|
Set color profile/metadata:
|
||||||
loop LOOP_COUNT set the loop count
|
icc file.icc set ICC profile
|
||||||
bgcolor BACKGROUND_COLOR set the animation background color
|
exif file.exif set EXIF metadata
|
||||||
icc file.icc set ICC profile
|
xmp file.xmp set XMP metadata
|
||||||
exif file.exif set EXIF metadata
|
|
||||||
xmp file.xmp set XMP metadata
|
|
||||||
where: 'file.icc' contains the ICC profile to be set,
|
where: 'file.icc' contains the ICC profile to be set,
|
||||||
'file.exif' contains the EXIF metadata to be set
|
'file.exif' contains the EXIF metadata to be set
|
||||||
'file.xmp' contains the XMP metadata to be set
|
'file.xmp' contains the XMP metadata to be set
|
||||||
|
@ -10,21 +10,30 @@ This file describes the compilation of libwebp into a JavaScript decoder
|
|||||||
using Emscripten and CMake.
|
using Emscripten and CMake.
|
||||||
|
|
||||||
- install the Emscripten SDK following the procedure described at:
|
- install the Emscripten SDK following the procedure described at:
|
||||||
https://emscripten.org/docs/getting_started/downloads.html#installation-instructions-using-the-emsdk-recommended
|
https://kripken.github.io/emscripten-site/docs/getting_started/downloads.html
|
||||||
After installation, you should have some global variable positioned to the
|
After installation, you should have some global variable positioned to the
|
||||||
location of the SDK. In particular, $EMSDK should point to the
|
location of the SDK. In particular, $EMSCRIPTEN should point to the
|
||||||
top-level directory containing Emscripten tools.
|
top-level directory containing Emscripten tools.
|
||||||
|
|
||||||
|
- make sure the file $EMSCRIPTEN/cmake/Modules/Platform/Emscripten.cmake is
|
||||||
|
accessible. This is the toolchain file used by CMake to invoke Emscripten.
|
||||||
|
If $EMSCRIPTEN is unset search for Emscripten.cmake under $EMSDK and set
|
||||||
|
$EMSCRIPTEN accordingly, for example:
|
||||||
|
unix-like environments: export EMSCRIPTEN=$EMSDK/fastcomp/emscripten
|
||||||
|
windows: set EMSCRIPTEN=%EMSDK%\fastcomp\emscripten
|
||||||
|
|
||||||
- configure the project 'WEBP_JS' with CMake using:
|
- configure the project 'WEBP_JS' with CMake using:
|
||||||
|
|
||||||
cd webp_js && \
|
cd webp_js && \
|
||||||
emcmake cmake -DWEBP_BUILD_WEBP_JS=ON \
|
cmake -DWEBP_BUILD_WEBP_JS=ON \
|
||||||
|
-DEMSCRIPTEN_GENERATE_BITCODE_STATIC_LIBRARIES=1 \
|
||||||
|
-DCMAKE_TOOLCHAIN_FILE=$EMSCRIPTEN/cmake/Modules/Platform/Emscripten.cmake \
|
||||||
../
|
../
|
||||||
|
|
||||||
- compile webp.js using 'emmake make'.
|
- compile webp.js using 'make'.
|
||||||
|
|
||||||
- that's it! Upon completion, you should have the webp.js and
|
- that's it! Upon completion, you should have the webp.js and
|
||||||
webp.wasm files generated.
|
webp.js.mem files generated.
|
||||||
|
|
||||||
The callable JavaScript function is WebPToSDL(), which decodes a raw WebP
|
The callable JavaScript function is WebPToSDL(), which decodes a raw WebP
|
||||||
bitstream into a canvas. See webp_js/index.html for a simple usage sample
|
bitstream into a canvas. See webp_js/index.html for a simple usage sample
|
||||||
@ -50,9 +59,8 @@ Web-Assembly (WASM) version:
|
|||||||
See webp_js/index_wasm.html for a simple demo page using the WASM version
|
See webp_js/index_wasm.html for a simple demo page using the WASM version
|
||||||
of the library.
|
of the library.
|
||||||
|
|
||||||
You will need a fairly recent version of Emscripten (at least 2.0.18,
|
You will need a fairly recent version of Emscripten (at least 1.37.8) and of
|
||||||
latest-upstream is recommended) and of your WASM-enabled browser to run this
|
your WASM-enabled browser to run this version. Consider it very experimental!
|
||||||
version.
|
|
||||||
|
|
||||||
Caveat:
|
Caveat:
|
||||||
=======
|
=======
|
||||||
@ -70,6 +78,3 @@ Caveat:
|
|||||||
https://github.com/kripken/emscripten/issues/3788
|
https://github.com/kripken/emscripten/issues/3788
|
||||||
|
|
||||||
Therefore, SSE2 optimization is currently disabled in CMakeLists.txt.
|
Therefore, SSE2 optimization is currently disabled in CMakeLists.txt.
|
||||||
|
|
||||||
- If WEBP_ENABLE_SIMD is set to 1 the JavaScript version (webp.js) will be
|
|
||||||
disabled as wasm2js does not support SIMD.
|
|
||||||
|
@ -141,7 +141,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"
|
||||||
@ -433,3 +432,8 @@ model {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Task to generate the wrapper.
|
||||||
|
task wrapper(type: Wrapper) {
|
||||||
|
gradleVersion = '2.13'
|
||||||
|
}
|
||||||
|
@ -5,7 +5,7 @@ set(WEBP_VERSION ${WebP_VERSION})
|
|||||||
|
|
||||||
include ("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Targets.cmake")
|
include ("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Targets.cmake")
|
||||||
|
|
||||||
set(WebP_INCLUDE_DIRS "@CMAKE_INSTALL_FULL_INCLUDEDIR@")
|
set(WebP_INCLUDE_DIRS "webp")
|
||||||
set(WEBP_INCLUDE_DIRS ${WebP_INCLUDE_DIRS})
|
set(WEBP_INCLUDE_DIRS ${WebP_INCLUDE_DIRS})
|
||||||
set(WebP_LIBRARIES "@INSTALLED_LIBRARIES@")
|
set(WebP_LIBRARIES "@INSTALLED_LIBRARIES@")
|
||||||
set(WEBP_LIBRARIES "${WebP_LIBRARIES}")
|
set(WEBP_LIBRARIES "${WebP_LIBRARIES}")
|
||||||
|
@ -93,6 +93,10 @@
|
|||||||
/* 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
|
||||||
|
|
||||||
@ -108,9 +112,6 @@
|
|||||||
/* 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 Wasm SIMD is supported */
|
|
||||||
#cmakedefine WEBP_HAVE_WASM_SIMD
|
|
||||||
|
|
||||||
/* Set to 1 if NEON is supported */
|
/* Set to 1 if NEON is supported */
|
||||||
#cmakedefine WEBP_HAVE_NEON
|
#cmakedefine WEBP_HAVE_NEON
|
||||||
|
|
||||||
|
@ -1,11 +1,3 @@
|
|||||||
# 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.
|
|
||||||
|
|
||||||
# Check for SIMD extensions.
|
# Check for SIMD extensions.
|
||||||
include(CMakePushCheckState)
|
include(CMakePushCheckState)
|
||||||
|
|
||||||
@ -36,26 +28,18 @@ 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 "WASM_SIMD;SSE41;SSE2;MIPS32;MIPS_DSP_R2;NEON;MSA")
|
set(WEBP_SIMD_FLAGS "SSE41;SSE2;MIPS32;MIPS_DSP_R2;NEON;MSA")
|
||||||
set(WEBP_SIMD_FILE_EXTENSIONS
|
set(WEBP_SIMD_FILE_EXTENSIONS
|
||||||
"_wasm.c;_sse41.c;_sse2.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 AND CMAKE_C_COMPILER_ID STREQUAL "MSVC")
|
if(MSVC)
|
||||||
# With at least Visual Studio 12 (2013)+ /arch is not necessary to build SSE2
|
# MSVC does not have a SSE4 flag but AVX support implies SSE4 support.
|
||||||
# or SSE4 code unless a lesser /arch is forced. MSVC does not have a SSE4
|
set(SIMD_ENABLE_FLAGS "/arch:AVX;/arch:SSE2;;;;")
|
||||||
# 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
|
||||||
"-msimd128;-msse4.1;-msse2;-mips32;-mdspr2;-mfpu=neon;-mmsa")
|
"-msse4.1;-msse2;-mips32;-mdspr2;-mfpu=neon;-mmsa")
|
||||||
set(SIMD_DISABLE_FLAGS
|
set(SIMD_DISABLE_FLAGS
|
||||||
"-mno-simd128;-mno-sse4.1;-mno-sse2;;-mno-dspr2;;-mno-msa")
|
"-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)
|
||||||
@ -73,19 +57,9 @@ endif()
|
|||||||
|
|
||||||
list(LENGTH WEBP_SIMD_FLAGS WEBP_SIMD_FLAGS_LENGTH)
|
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")
|
||||||
|
unset(HIGHEST_SSE_FLAG)
|
||||||
|
|
||||||
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 5)
|
|
||||||
break()
|
|
||||||
endif()
|
|
||||||
# Emscripten supports SSE via compat headers, if WEBP_ENABLED_WASM_SIMD is
|
|
||||||
# specified skip testing those (because it will succeed).
|
|
||||||
if (EMSCRIPTEN AND ${I_SIMD} GREATER_EQUAL 1 AND ${WEBP_ENABLE_WASM_SIMD})
|
|
||||||
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
|
||||||
@ -96,16 +70,10 @@ foreach(I_SIMD RANGE ${WEBP_SIMD_FLAGS_RANGE})
|
|||||||
webp_check_compiler_flag(${WEBP_SIMD_FLAG} ${WEBP_ENABLE_SIMD})
|
webp_check_compiler_flag(${WEBP_SIMD_FLAG} ${WEBP_ENABLE_SIMD})
|
||||||
if(NOT WEBP_HAVE_${WEBP_SIMD_FLAG})
|
if(NOT WEBP_HAVE_${WEBP_SIMD_FLAG})
|
||||||
list(GET SIMD_ENABLE_FLAGS ${I_SIMD} SIMD_COMPILE_FLAG)
|
list(GET SIMD_ENABLE_FLAGS ${I_SIMD} SIMD_COMPILE_FLAG)
|
||||||
# This enables using Emscripten's SSE compatibility headers.
|
|
||||||
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} ${WEBP_ENABLE_SIMD})
|
||||||
else()
|
else()
|
||||||
if(MSVC AND SIMD_ENABLE_FLAGS)
|
if(MSVC)
|
||||||
# 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)
|
list(GET SIMD_ENABLE_FLAGS ${I_SIMD} SIMD_COMPILE_FLAG)
|
||||||
else()
|
else()
|
||||||
set(SIMD_COMPILE_FLAG " ")
|
set(SIMD_COMPILE_FLAG " ")
|
||||||
@ -116,10 +84,17 @@ foreach(I_SIMD RANGE ${WEBP_SIMD_FLAGS_RANGE})
|
|||||||
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})
|
||||||
|
if(${I_SIMD} LESS 2 AND NOT HIGHEST_SSE_FLAG)
|
||||||
|
set(HIGHEST_SSE_FLAG ${SIMD_COMPILE_FLAG})
|
||||||
|
endif()
|
||||||
# Memorize the file and flags.
|
# Memorize the file and flags.
|
||||||
foreach(FILE ${SIMD_FILES})
|
foreach(FILE ${SIMD_FILES})
|
||||||
list(APPEND WEBP_SIMD_FILES_TO_INCLUDE ${FILE})
|
list(APPEND WEBP_SIMD_FILES_TO_INCLUDE ${FILE})
|
||||||
list(APPEND WEBP_SIMD_FLAGS_TO_INCLUDE ${SIMD_COMPILE_FLAG})
|
if(${I_SIMD} LESS 2)
|
||||||
|
list(APPEND WEBP_SIMD_FLAGS_TO_INCLUDE ${HIGHEST_SSE_FLAG})
|
||||||
|
else()
|
||||||
|
list(APPEND WEBP_SIMD_FLAGS_TO_INCLUDE ${SIMD_COMPILE_FLAG})
|
||||||
|
endif()
|
||||||
endforeach()
|
endforeach()
|
||||||
else()
|
else()
|
||||||
# Remove the file from the list.
|
# Remove the file from the list.
|
||||||
@ -131,12 +106,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)
|
||||||
@ -154,7 +123,6 @@ foreach(I_SIMD RANGE ${WEBP_SIMD_FLAGS_RANGE})
|
|||||||
"warning: argument unused during compilation:"
|
"warning: argument unused during compilation:"
|
||||||
${COMMON_PATTERNS})
|
${COMMON_PATTERNS})
|
||||||
if(NOT FLAG_${SIMD_COMPILE_FLAG})
|
if(NOT FLAG_${SIMD_COMPILE_FLAG})
|
||||||
unset(HAS_COMPILE_FLAG)
|
|
||||||
unset(HAS_COMPILE_FLAG CACHE)
|
unset(HAS_COMPILE_FLAG CACHE)
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
@ -1,11 +1,3 @@
|
|||||||
# 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.
|
# Generate the config.h to compile with specific intrinsics / libs.
|
||||||
|
|
||||||
# Check for compiler options.
|
# Check for compiler options.
|
||||||
@ -30,25 +22,23 @@ check_c_source_compiles("
|
|||||||
" HAVE_BUILTIN_BSWAP64)
|
" HAVE_BUILTIN_BSWAP64)
|
||||||
|
|
||||||
# Check for libraries.
|
# Check for libraries.
|
||||||
if(WEBP_USE_THREAD)
|
find_package(Threads)
|
||||||
find_package(Threads)
|
if(Threads_FOUND)
|
||||||
if(Threads_FOUND)
|
if(CMAKE_USE_PTHREADS_INIT)
|
||||||
# work around cmake bug on QNX (https://cmake.org/Bug/view.php?id=11333)
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pthread")
|
||||||
if(CMAKE_USE_PTHREADS_INIT AND NOT CMAKE_SYSTEM_NAME STREQUAL "QNX")
|
endif()
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pthread")
|
foreach(PTHREAD_TEST HAVE_PTHREAD_PRIO_INHERIT PTHREAD_CREATE_UNDETACHED)
|
||||||
endif()
|
|
||||||
check_c_source_compiles("
|
check_c_source_compiles("
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
int main (void) {
|
int main (void) {
|
||||||
int attr = PTHREAD_PRIO_INHERIT;
|
int attr = ${PTHREAD_TEST};
|
||||||
return attr;
|
return attr;
|
||||||
}
|
}
|
||||||
" FLAG_HAVE_PTHREAD_PRIO_INHERIT)
|
" ${PTHREAD_TEST})
|
||||||
set(HAVE_PTHREAD_PRIO_INHERIT ${FLAG_HAVE_PTHREAD_PRIO_INHERIT})
|
endforeach()
|
||||||
list(APPEND WEBP_DEP_LIBRARIES ${CMAKE_THREAD_LIBS_INIT})
|
list(APPEND WEBP_DEP_LIBRARIES ${CMAKE_THREAD_LIBS_INIT})
|
||||||
endif()
|
|
||||||
set(WEBP_USE_THREAD ${Threads_FOUND})
|
|
||||||
endif()
|
endif()
|
||||||
|
set(WEBP_USE_THREAD ${Threads_FOUND})
|
||||||
|
|
||||||
# TODO: this seems unused, check with autotools.
|
# TODO: this seems unused, check with autotools.
|
||||||
set(LT_OBJDIR ".libs/")
|
set(LT_OBJDIR ".libs/")
|
||||||
|
91
configure.ac
91
configure.ac
@ -1,4 +1,4 @@
|
|||||||
AC_INIT([libwebp], [1.2.1],
|
AC_INIT([libwebp], [1.0.3],
|
||||||
[https://bugs.chromium.org/p/webp],,
|
[https://bugs.chromium.org/p/webp],,
|
||||||
[http://developers.google.com/speed/webp])
|
[http://developers.google.com/speed/webp])
|
||||||
AC_CANONICAL_HOST
|
AC_CANONICAL_HOST
|
||||||
@ -32,40 +32,6 @@ AC_ARG_ENABLE([everything],
|
|||||||
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)
|
||||||
@ -114,7 +80,6 @@ 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], [-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])
|
||||||
@ -259,9 +224,6 @@ AS_IF([test "x$enable_neon" != "xno"], [
|
|||||||
*android*) AC_CHECK_HEADERS([cpu-features.h]) ;;
|
*android*) AC_CHECK_HEADERS([cpu-features.h]) ;;
|
||||||
esac
|
esac
|
||||||
;;
|
;;
|
||||||
aarch64*|arm64*)
|
|
||||||
AC_DEFINE(WEBP_HAVE_NEON, [1], [Set to 1 if NEON is supported])
|
|
||||||
;;
|
|
||||||
esac
|
esac
|
||||||
AC_SUBST([NEON_FLAGS])])
|
AC_SUBST([NEON_FLAGS])])
|
||||||
|
|
||||||
@ -446,10 +408,6 @@ 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"])
|
||||||
@ -509,7 +467,7 @@ AS_IF([test "x$enable_sdl" != "xno"], [
|
|||||||
if test x"$sdl_support" = "xyes"; then
|
if test x"$sdl_support" = "xyes"; then
|
||||||
build_vwebp_sdl=yes
|
build_vwebp_sdl=yes
|
||||||
else
|
else
|
||||||
AC_MSG_NOTICE([Not building vwebp-sdl. SDL library is required.])
|
AC_MSG_WARN(Optional SDL library not found)
|
||||||
fi
|
fi
|
||||||
])
|
])
|
||||||
|
|
||||||
@ -633,17 +591,11 @@ 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_anim_diff=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_anim_diff}" = "yes"])
|
||||||
@ -651,17 +603,11 @@ AM_CONDITIONAL([BUILD_GIF2WEBP], [test "${build_gif2webp}" = "yes"])
|
|||||||
|
|
||||||
if test "$enable_libwebpdemux" = "yes" -a "$enable_libwebpmux" = "yes"; then
|
if test "$enable_libwebpdemux" = "yes" -a "$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
|
if test "$enable_libwebpmux" = "yes"; then
|
||||||
build_webpinfo=yes
|
build_webpinfo=yes
|
||||||
else
|
|
||||||
AC_MSG_NOTICE([Not building webpinfo. --enable-libwebpdemux is required.])
|
|
||||||
fi
|
fi
|
||||||
AM_CONDITIONAL([BUILD_WEBPINFO], [test "${build_webpinfo}" = "yes"])
|
AM_CONDITIONAL([BUILD_WEBPINFO], [test "${build_webpinfo}" = "yes"])
|
||||||
|
|
||||||
@ -745,6 +691,39 @@ else
|
|||||||
AC_MSG_RESULT([no])
|
AC_MSG_RESULT([no])
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
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([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 =========================
|
dnl =========================
|
||||||
|
|
||||||
AC_CONFIG_MACRO_DIR([m4])
|
AC_CONFIG_MACRO_DIR([m4])
|
||||||
|
@ -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
|
||||||
------------------------
|
------------------------
|
||||||
|
|
||||||
@ -265,7 +269,7 @@ An extended format file consists of:
|
|||||||
|
|
||||||
* 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:
|
||||||
@ -701,7 +705,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
|
||||||
@ -812,7 +816,7 @@ RIFF/WEBP
|
|||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
[vp8spec]: http://tools.ietf.org/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]: http://www.color.org/icc_specs2.xalter
|
[iccspec]: http://www.color.org/icc_specs2.xalter
|
||||||
[metadata]: http://www.metadataworkinggroup.org/pdf/mwg_guidance.pdf
|
[metadata]: http://www.metadataworkinggroup.org/pdf/mwg_guidance.pdf
|
||||||
[rfc 1166]: http://tools.ietf.org/html/rfc1166
|
[rfc 1166]: http://tools.ietf.org/html/rfc1166
|
||||||
|
@ -60,15 +60,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,8 +82,8 @@ 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;
|
||||||
@ -165,7 +165,7 @@ static int DumpFrame(const char filename[], const char dump_folder[],
|
|||||||
base_name = (base_name == NULL) ? (const W_CHAR*)filename : base_name + 1;
|
base_name = (base_name == NULL) ? (const W_CHAR*)filename : base_name + 1;
|
||||||
max_len = WSTRLEN(dump_folder) + 1 + WSTRLEN(base_name)
|
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 = (W_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 (WSNPRINTF(file_name, max_len, "%s/%s_frame_%d.pam",
|
||||||
@ -197,7 +197,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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -405,7 +405,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);
|
||||||
|
189
examples/cwebp.c
189
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,7 +23,6 @@
|
|||||||
#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 "./unicode.h"
|
||||||
#include "webp/encode.h"
|
#include "webp/encode.h"
|
||||||
@ -94,7 +92,7 @@ static int ReadPicture(const char* const filename, WebPPicture* const pic,
|
|||||||
WFPRINTF(stderr, "Error! Could not process file %s\n",
|
WFPRINTF(stderr, "Error! Could not process file %s\n",
|
||||||
(const W_CHAR*)filename);
|
(const W_CHAR*)filename);
|
||||||
}
|
}
|
||||||
WebPFree((void*)data);
|
free((void*)data);
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -121,7 +119,7 @@ static int ReadPicture(const char* const filename, WebPPicture* const pic,
|
|||||||
WFPRINTF(stderr, "Error! Could not process file %s\n",
|
WFPRINTF(stderr, "Error! Could not process file %s\n",
|
||||||
(const W_CHAR*)filename);
|
(const W_CHAR*)filename);
|
||||||
}
|
}
|
||||||
WebPFree((void*)data);
|
free((void*)data);
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -130,8 +128,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,
|
||||||
@ -150,7 +147,7 @@ static void PrintPercents(const int counts[4]) {
|
|||||||
int s;
|
int s;
|
||||||
const int total = counts[0] + counts[1] + counts[2] + counts[3];
|
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%%", (int)(100. * counts[s] / total + .5));
|
||||||
}
|
}
|
||||||
fprintf(stderr, "| %7d\n", total);
|
fprintf(stderr, "| %7d\n", total);
|
||||||
}
|
}
|
||||||
@ -527,7 +524,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,8 +564,6 @@ 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");
|
||||||
@ -646,10 +640,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;
|
||||||
@ -669,7 +663,6 @@ 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;
|
||||||
|
|
||||||
@ -697,9 +690,9 @@ int main(int argc, const char* argv[]) {
|
|||||||
} 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);
|
FREE_WARGV_AND_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 = (const char*)GET_WARGV(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 = (const char*)GET_WARGV(argv, ++c);
|
||||||
config.show_compressed = 1;
|
config.show_compressed = 1;
|
||||||
} else if (!strcmp(argv[c], "-print_psnr")) {
|
} else if (!strcmp(argv[c], "-print_psnr")) {
|
||||||
@ -713,7 +706,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 ||
|
||||||
@ -723,30 +716,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;
|
||||||
@ -762,10 +755,10 @@ 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) {
|
} 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;
|
||||||
@ -777,13 +770,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;
|
||||||
@ -797,32 +790,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
|
||||||
@ -838,7 +826,7 @@ int main(int argc, const char* argv[]) {
|
|||||||
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")) {
|
||||||
@ -861,7 +849,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;
|
||||||
@ -909,7 +897,7 @@ 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 = (const char*)GET_WARGV(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]);
|
||||||
@ -985,14 +973,6 @@ 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) {
|
||||||
@ -1007,19 +987,15 @@ int main(int argc, const char* argv[]) {
|
|||||||
WFPRINTF(stderr, "Saving file '%s'\n", (const W_CHAR*)out_file);
|
WFPRINTF(stderr, "Saving file '%s'\n", (const W_CHAR*)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");
|
||||||
@ -1098,12 +1074,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.
|
||||||
@ -1121,38 +1093,7 @@ 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) "
|
||||||
@ -1163,29 +1104,31 @@ int main(int argc, const char* argv[]) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1225,7 +1168,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);
|
||||||
|
@ -76,8 +76,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"
|
||||||
@ -133,7 +132,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 +145,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 +176,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;
|
||||||
@ -413,8 +412,8 @@ 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);
|
FREE_WARGV_AND_RETURN(ok ? 0 : -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,7 +75,7 @@ static void ResetCommandLineArguments(int argc, const char* argv[],
|
|||||||
void ExUtilDeleteCommandLineArguments(CommandLineArguments* const args) {
|
void ExUtilDeleteCommandLineArguments(CommandLineArguments* const args) {
|
||||||
if (args != NULL) {
|
if (args != NULL) {
|
||||||
if (args->own_argv_) {
|
if (args->own_argv_) {
|
||||||
WebPFree((void*)args->argv_);
|
free((void*)args->argv_);
|
||||||
WebPDataClear(&args->argv_data_);
|
WebPDataClear(&args->argv_data_);
|
||||||
}
|
}
|
||||||
ResetCommandLineArguments(0, NULL, args);
|
ResetCommandLineArguments(0, NULL, args);
|
||||||
@ -102,7 +102,7 @@ int ExUtilInitCommandLineArguments(int argc, const char* argv[],
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
args->own_argv_ = 1;
|
args->own_argv_ = 1;
|
||||||
args->argv_ = (const char**)WebPMalloc(MAX_ARGC * sizeof(*args->argv_));
|
args->argv_ = (const char**)malloc(MAX_ARGC * sizeof(*args->argv_));
|
||||||
if (args->argv_ == NULL) return 0;
|
if (args->argv_ == NULL) return 0;
|
||||||
|
|
||||||
argc = 0;
|
argc = 0;
|
||||||
|
@ -96,12 +96,12 @@ 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 W_CHAR *in_file = NULL, *out_file = NULL;
|
||||||
GifFileType* gif = NULL;
|
GifFileType* gif = NULL;
|
||||||
int frame_duration = 0;
|
int frame_duration = 0;
|
||||||
int frame_timestamp = 0;
|
int frame_timestamp = 0;
|
||||||
@ -379,7 +379,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;
|
||||||
}
|
}
|
||||||
@ -465,10 +465,8 @@ 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) {
|
if (!loop_compatibility) {
|
||||||
loop_count = 0;
|
|
||||||
} else if (!loop_compatibility) {
|
|
||||||
if (!stored_loop_count) {
|
if (!stored_loop_count) {
|
||||||
// if no loop-count element is seen, the default is '1' (loop-once)
|
// 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
|
// and we need to signal it explicitly in WebP. Note however that
|
||||||
@ -595,7 +593,7 @@ int main(int argc, const char* argv[]) {
|
|||||||
|
|
||||||
#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;
|
||||||
|
@ -137,7 +137,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 +168,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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,7 +84,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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -479,7 +479,7 @@ static void Help(void) {
|
|||||||
" 'q' / 'Q' / ESC .... quit\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;
|
||||||
@ -630,7 +630,7 @@ int main(int argc, char* argv[]) {
|
|||||||
|
|
||||||
#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;
|
||||||
|
@ -41,7 +41,6 @@
|
|||||||
if (webp_info->show_diagnosis_) { \
|
if (webp_info->show_diagnosis_) { \
|
||||||
fprintf(stderr, "Warning: %s\n", MESSAGE); \
|
fprintf(stderr, "Warning: %s\n", MESSAGE); \
|
||||||
} \
|
} \
|
||||||
++webp_info->num_warnings_; \
|
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
static const char* const kFormats[3] = {
|
static const char* const kFormats[3] = {
|
||||||
@ -117,7 +116,6 @@ typedef struct WebPInfo {
|
|||||||
int is_processing_anim_frame_, seen_alpha_subchunk_, seen_image_subchunk_;
|
int is_processing_anim_frame_, seen_alpha_subchunk_, seen_image_subchunk_;
|
||||||
// Print output control.
|
// Print output control.
|
||||||
int quiet_, show_diagnosis_, show_summary_;
|
int quiet_, show_diagnosis_, show_summary_;
|
||||||
int num_warnings_;
|
|
||||||
int parse_bitstream_;
|
int parse_bitstream_;
|
||||||
} WebPInfo;
|
} WebPInfo;
|
||||||
|
|
||||||
@ -582,7 +580,7 @@ static WebPInfoStatus ParseAlphaHeader(const ChunkData* const chunk_data,
|
|||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// Chunk parsing.
|
// Chunk parsing.
|
||||||
|
|
||||||
static WebPInfoStatus ParseRIFFHeader(WebPInfo* const webp_info,
|
static WebPInfoStatus ParseRIFFHeader(const WebPInfo* const webp_info,
|
||||||
MemBuffer* const mem) {
|
MemBuffer* const mem) {
|
||||||
const size_t min_size = RIFF_HEADER_SIZE + CHUNK_HEADER_SIZE;
|
const size_t min_size = RIFF_HEADER_SIZE + CHUNK_HEADER_SIZE;
|
||||||
size_t riff_size;
|
size_t riff_size;
|
||||||
@ -990,7 +988,7 @@ static WebPInfoStatus ProcessChunk(const ChunkData* const chunk_data,
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
static WebPInfoStatus Validate(WebPInfo* const webp_info) {
|
static WebPInfoStatus Validate(const WebPInfo* const webp_info) {
|
||||||
if (webp_info->num_frames_ < 1) {
|
if (webp_info->num_frames_ < 1) {
|
||||||
LOG_ERROR("No image/frame detected.");
|
LOG_ERROR("No image/frame detected.");
|
||||||
return WEBP_INFO_MISSING_DATA;
|
return WEBP_INFO_MISSING_DATA;
|
||||||
@ -1095,14 +1093,16 @@ static WebPInfoStatus AnalyzeWebP(WebPInfo* const webp_info,
|
|||||||
} else {
|
} else {
|
||||||
printf("Errors detected.\n");
|
printf("Errors detected.\n");
|
||||||
}
|
}
|
||||||
if (webp_info->num_warnings_ > 0) {
|
|
||||||
printf("There were %d warning(s).\n", webp_info->num_warnings_);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return webp_info_status;
|
return webp_info_status;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Help(void) {
|
static void HelpShort(void) {
|
||||||
|
printf("Usage: webpinfo [options] in_files\n"
|
||||||
|
"Try -longhelp for an exhaustive list of options.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void HelpLong(void) {
|
||||||
printf("Usage: webpinfo [options] in_files\n"
|
printf("Usage: webpinfo [options] in_files\n"
|
||||||
"Note: there could be multiple input files;\n"
|
"Note: there could be multiple input files;\n"
|
||||||
" options must come before input files.\n"
|
" options must come before input files.\n"
|
||||||
@ -1123,15 +1123,17 @@ int main(int argc, const char* argv[]) {
|
|||||||
INIT_WARGV(argc, argv);
|
INIT_WARGV(argc, argv);
|
||||||
|
|
||||||
if (argc == 1) {
|
if (argc == 1) {
|
||||||
Help();
|
HelpShort();
|
||||||
FREE_WARGV_AND_RETURN(WEBP_INFO_OK);
|
FREE_WARGV_AND_RETURN(WEBP_INFO_OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse command-line input.
|
// Parse command-line input.
|
||||||
for (c = 1; c < argc; ++c) {
|
for (c = 1; c < argc; ++c) {
|
||||||
if (!strcmp(argv[c], "-h") || !strcmp(argv[c], "-help") ||
|
if (!strcmp(argv[c], "-h") || !strcmp(argv[c], "-help")) {
|
||||||
!strcmp(argv[c], "-H") || !strcmp(argv[c], "-longhelp")) {
|
HelpShort();
|
||||||
Help();
|
FREE_WARGV_AND_RETURN(WEBP_INFO_OK);
|
||||||
|
} else if (!strcmp(argv[c], "-H") || !strcmp(argv[c], "-longhelp")) {
|
||||||
|
HelpLong();
|
||||||
FREE_WARGV_AND_RETURN(WEBP_INFO_OK);
|
FREE_WARGV_AND_RETURN(WEBP_INFO_OK);
|
||||||
} else if (!strcmp(argv[c], "-quiet")) {
|
} else if (!strcmp(argv[c], "-quiet")) {
|
||||||
quiet = 1;
|
quiet = 1;
|
||||||
@ -1152,7 +1154,7 @@ int main(int argc, const char* argv[]) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (c == argc) {
|
if (c == argc) {
|
||||||
Help();
|
HelpShort();
|
||||||
FREE_WARGV_AND_RETURN(WEBP_INFO_INVALID_COMMAND);
|
FREE_WARGV_AND_RETURN(WEBP_INFO_INVALID_COMMAND);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
@ -98,8 +97,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;
|
||||||
|
|
||||||
@ -316,12 +313,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");
|
||||||
@ -474,11 +469,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
|
||||||
@ -497,7 +492,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;
|
||||||
|
|
||||||
@ -773,20 +768,6 @@ static int ParseCommandLine(Config* config, const W_CHAR** const unicode_argv) {
|
|||||||
arg->params_ = argv[i + 1];
|
arg->params_ = argv[i + 1];
|
||||||
++feature_arg_index;
|
++feature_arg_index;
|
||||||
i += 2;
|
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];
|
|
||||||
++feature_arg_index;
|
|
||||||
i += 2;
|
|
||||||
} else { // Assume input file.
|
} else { // Assume input file.
|
||||||
if (config->input_ == NULL) {
|
if (config->input_ == NULL) {
|
||||||
config->input_ = wargv[i];
|
config->input_ = wargv[i];
|
||||||
@ -1030,62 +1011,13 @@ static int Process(const Config* config) {
|
|||||||
ok = ExUtilReadFileToWebPData(config->args_[0].filename_, &chunk);
|
ok = ExUtilReadFileToWebPData(config->args_[0].filename_, &chunk);
|
||||||
if (!ok) goto Err2;
|
if (!ok) goto Err2;
|
||||||
err = WebPMuxSetChunk(mux, kFourccList[config->type_], &chunk, 1);
|
err = WebPMuxSetChunk(mux, kFourccList[config->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[config->type_], Err2);
|
||||||
}
|
}
|
||||||
break;
|
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;
|
|
||||||
}
|
|
||||||
default: {
|
default: {
|
||||||
ERROR_GOTO1("ERROR: Invalid feature for action 'set'.\n", Err2);
|
ERROR_GOTO1("ERROR: Invalid feature for action 'set'.\n", Err2);
|
||||||
break;
|
break;
|
||||||
@ -1113,7 +1045,7 @@ 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;
|
||||||
|
|
||||||
@ -1171,7 +1103,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;
|
||||||
}
|
}
|
||||||
|
@ -12,14 +12,13 @@
|
|||||||
|
|
||||||
#include "extras/extras.h"
|
#include "extras/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 1
|
||||||
#define XTRA_MIN_VERSION 2
|
#define XTRA_MIN_VERSION 0
|
||||||
#define XTRA_REV_VERSION 1
|
#define XTRA_REV_VERSION 3
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
@ -58,7 +57,7 @@ int WebPImportRGB565(const uint8_t* rgb565, WebPPicture* pic) {
|
|||||||
for (y = 0; y < pic->height; ++y) {
|
for (y = 0; y < pic->height; ++y) {
|
||||||
const int width = pic->width;
|
const int width = pic->width;
|
||||||
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
|
||||||
@ -91,7 +90,7 @@ int WebPImportRGB4444(const uint8_t* rgb4444, WebPPicture* pic) {
|
|||||||
for (y = 0; y < pic->height; ++y) {
|
for (y = 0; y < pic->height; ++y) {
|
||||||
const int width = pic->width;
|
const int width = pic->width;
|
||||||
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
|
||||||
@ -145,18 +144,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,7 +19,7 @@ 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)
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
@ -51,13 +51,6 @@ 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
|
||||||
|
@ -226,7 +226,7 @@ static void Help(void) {
|
|||||||
" Also handles PNG, JPG and TIFF files, in addition to WebP.\n");
|
" Also handles PNG, JPG and TIFF files, in addition to WebP.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, const char* argv[]) {
|
int main(int argc, const char *argv[]) {
|
||||||
WebPPicture pic1, pic2;
|
WebPPicture pic1, pic2;
|
||||||
size_t size1 = 0, size2 = 0;
|
size_t size1 = 0, size2 = 0;
|
||||||
int ret = 1;
|
int ret = 1;
|
||||||
|
@ -92,7 +92,7 @@ int main(int argc, char* argv[]) {
|
|||||||
|
|
||||||
#else // !WEBP_HAVE_SDL
|
#else // !WEBP_HAVE_SDL
|
||||||
|
|
||||||
int main(int argc, const char* argv[]) {
|
int main(int argc, const char *argv[]) {
|
||||||
fprintf(stderr, "SDL support not enabled in %s.\n", argv[0]);
|
fprintf(stderr, "SDL support not enabled in %s.\n", argv[0]);
|
||||||
(void)argc;
|
(void)argc;
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
#include "imageio/imageio_util.h"
|
#include "imageio/imageio_util.h"
|
||||||
#include "../examples/unicode.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;
|
||||||
|
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" "$@"
|
|
||||||
|
190
gradlew.bat
vendored
190
gradlew.bat
vendored
@ -1,100 +1,90 @@
|
|||||||
@rem
|
@if "%DEBUG%" == "" @echo off
|
||||||
@rem Copyright 2015 the original author or authors.
|
@rem ##########################################################################
|
||||||
@rem
|
@rem
|
||||||
@rem Licensed under the Apache License, Version 2.0 (the "License");
|
@rem Gradle startup script for Windows
|
||||||
@rem you may not use this file except in compliance with the License.
|
@rem
|
||||||
@rem You may obtain a copy of the License at
|
@rem ##########################################################################
|
||||||
@rem
|
|
||||||
@rem https://www.apache.org/licenses/LICENSE-2.0
|
@rem Set local scope for the variables with windows NT shell
|
||||||
@rem
|
if "%OS%"=="Windows_NT" setlocal
|
||||||
@rem Unless required by applicable law or agreed to in writing, software
|
|
||||||
@rem distributed under the License is distributed on an "AS IS" BASIS,
|
set DIRNAME=%~dp0
|
||||||
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
if "%DIRNAME%" == "" set DIRNAME=.
|
||||||
@rem See the License for the specific language governing permissions and
|
set APP_BASE_NAME=%~n0
|
||||||
@rem limitations under the License.
|
set APP_HOME=%DIRNAME%
|
||||||
@rem
|
|
||||||
|
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||||
@if "%DEBUG%" == "" @echo off
|
set DEFAULT_JVM_OPTS=
|
||||||
@rem ##########################################################################
|
|
||||||
@rem
|
@rem Find java.exe
|
||||||
@rem Gradle startup script for Windows
|
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||||
@rem
|
|
||||||
@rem ##########################################################################
|
set JAVA_EXE=java.exe
|
||||||
|
%JAVA_EXE% -version >NUL 2>&1
|
||||||
@rem Set local scope for the variables with windows NT shell
|
if "%ERRORLEVEL%" == "0" goto init
|
||||||
if "%OS%"=="Windows_NT" setlocal
|
|
||||||
|
echo.
|
||||||
set DIRNAME=%~dp0
|
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||||
if "%DIRNAME%" == "" set DIRNAME=.
|
echo.
|
||||||
set APP_BASE_NAME=%~n0
|
echo Please set the JAVA_HOME variable in your environment to match the
|
||||||
set APP_HOME=%DIRNAME%
|
echo location of your Java installation.
|
||||||
|
|
||||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
goto fail
|
||||||
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
|
||||||
|
:findJavaFromJavaHome
|
||||||
@rem Find java.exe
|
set JAVA_HOME=%JAVA_HOME:"=%
|
||||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||||
|
|
||||||
set JAVA_EXE=java.exe
|
if exist "%JAVA_EXE%" goto init
|
||||||
%JAVA_EXE% -version >NUL 2>&1
|
|
||||||
if "%ERRORLEVEL%" == "0" goto init
|
echo.
|
||||||
|
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||||
echo.
|
echo.
|
||||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
echo Please set the JAVA_HOME variable in your environment to match the
|
||||||
echo.
|
echo location of your Java installation.
|
||||||
echo Please set the JAVA_HOME variable in your environment to match the
|
|
||||||
echo location of your Java installation.
|
goto fail
|
||||||
|
|
||||||
goto fail
|
:init
|
||||||
|
@rem Get command-line arguments, handling Windows variants
|
||||||
:findJavaFromJavaHome
|
|
||||||
set JAVA_HOME=%JAVA_HOME:"=%
|
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
if "%@eval[2+2]" == "4" goto 4NT_args
|
||||||
|
|
||||||
if exist "%JAVA_EXE%" goto init
|
:win9xME_args
|
||||||
|
@rem Slurp the command line arguments.
|
||||||
echo.
|
set CMD_LINE_ARGS=
|
||||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
set _SKIP=2
|
||||||
echo.
|
|
||||||
echo Please set the JAVA_HOME variable in your environment to match the
|
:win9xME_args_slurp
|
||||||
echo location of your Java installation.
|
if "x%~1" == "x" goto execute
|
||||||
|
|
||||||
goto fail
|
set CMD_LINE_ARGS=%*
|
||||||
|
goto execute
|
||||||
:init
|
|
||||||
@rem Get command-line arguments, handling Windows variants
|
:4NT_args
|
||||||
|
@rem Get arguments from the 4NT Shell from JP Software
|
||||||
if not "%OS%" == "Windows_NT" goto win9xME_args
|
set CMD_LINE_ARGS=%$
|
||||||
|
|
||||||
:win9xME_args
|
:execute
|
||||||
@rem Slurp the command line arguments.
|
@rem Setup the command line
|
||||||
set CMD_LINE_ARGS=
|
|
||||||
set _SKIP=2
|
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||||
|
|
||||||
:win9xME_args_slurp
|
@rem Execute Gradle
|
||||||
if "x%~1" == "x" goto execute
|
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
||||||
|
|
||||||
set CMD_LINE_ARGS=%*
|
:end
|
||||||
|
@rem End local scope for the variables with windows NT shell
|
||||||
:execute
|
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||||
@rem Setup the command line
|
|
||||||
|
:fail
|
||||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||||
|
rem the _cmd.exe /c_ return code!
|
||||||
@rem Execute Gradle
|
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
exit /b 1
|
||||||
|
|
||||||
:end
|
:mainEnd
|
||||||
@rem End local scope for the variables with windows NT shell
|
if "%OS%"=="Windows_NT" endlocal
|
||||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
|
||||||
|
:omega
|
||||||
:fail
|
|
||||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
|
||||||
rem the _cmd.exe /c_ return code!
|
|
||||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
|
||||||
exit /b 1
|
|
||||||
|
|
||||||
:mainEnd
|
|
||||||
if "%OS%"=="Windows_NT" endlocal
|
|
||||||
|
|
||||||
:omega
|
|
||||||
|
@ -155,8 +155,8 @@ 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -320,7 +320,7 @@ int WebPWriteBMP(FILE* fout, const WebPDecBuffer* const buffer) {
|
|||||||
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, 0); // no compression (BI_RGB)
|
PutLE32(bmp_header + 30, 0); // no compression (BI_RGB)
|
||||||
PutLE32(bmp_header + 34, 0); // image size (placeholder)
|
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
|
||||||
|
@ -91,7 +91,7 @@ int ImgIoUtilReadFile(const char* const file_name,
|
|||||||
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
|
// we allocate one extra byte for the \0 terminator
|
||||||
file_data = (uint8_t*)WebPMalloc(file_size + 1);
|
file_data = (uint8_t*)malloc(file_size + 1);
|
||||||
if (file_data == NULL) {
|
if (file_data == NULL) {
|
||||||
fclose(in);
|
fclose(in);
|
||||||
WFPRINTF(stderr, "memory allocation failure when reading file %s\n",
|
WFPRINTF(stderr, "memory allocation failure when reading file %s\n",
|
||||||
@ -104,7 +104,7 @@ int ImgIoUtilReadFile(const char* const file_name,
|
|||||||
if (!ok) {
|
if (!ok) {
|
||||||
WFPRINTF(stderr, "Could not read %d bytes of data from file %s\n",
|
WFPRINTF(stderr, "Could not read %d bytes of data from file %s\n",
|
||||||
(int)file_size, (const W_CHAR*)file_name);
|
(int)file_size, (const W_CHAR*)file_name);
|
||||||
WebPFree(file_data);
|
free(file_data);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
file_data[file_size] = '\0'; // convenient 0-terminator
|
file_data[file_size] = '\0'; // convenient 0-terminator
|
||||||
@ -148,11 +148,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);
|
int ok = (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)
|
#if defined(WEBP_MAX_IMAGE_SIZE)
|
||||||
ok = ok && (total_size <= (uint64_t)WEBP_MAX_IMAGE_SIZE);
|
ok = ok && (total_size <= (uint64_t)WEBP_MAX_IMAGE_SIZE);
|
||||||
#endif
|
#endif
|
||||||
|
@ -29,7 +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
|
// 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
|
// (not accounted for in *data_size), in case the file is text and intended
|
||||||
// to be used as a C-string.
|
// to be used as a C-string.
|
||||||
@ -54,8 +54,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"
|
||||||
|
@ -274,7 +274,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;
|
||||||
|
|
||||||
|
@ -259,15 +259,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);
|
||||||
|
113
imageio/pnmdec.c
113
imageio/pnmdec.c
@ -26,15 +26,15 @@ typedef enum {
|
|||||||
DEPTH_FLAG = 1 << 2,
|
DEPTH_FLAG = 1 << 2,
|
||||||
MAXVAL_FLAG = 1 << 3,
|
MAXVAL_FLAG = 1 << 3,
|
||||||
TUPLE_FLAG = 1 << 4,
|
TUPLE_FLAG = 1 << 4,
|
||||||
ALL_NEEDED_FLAGS = WIDTH_FLAG | HEIGHT_FLAG | DEPTH_FLAG | MAXVAL_FLAG
|
ALL_NEEDED_FLAGS = 0x1f
|
||||||
} PNMFlags;
|
} PNMFlags;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
const uint8_t* data;
|
const uint8_t* data;
|
||||||
size_t data_size;
|
size_t data_size;
|
||||||
int width, height;
|
int width, height;
|
||||||
int bytes_per_px;
|
int bytes_per_px; // 1, 3, 4
|
||||||
int depth; // 1 (grayscale), 2 (grayscale + alpha), 3 (rgb), 4 (rgba)
|
int depth;
|
||||||
int max_value;
|
int max_value;
|
||||||
int type; // 5, 6 or 7
|
int type; // 5, 6 or 7
|
||||||
int seen_flags;
|
int seen_flags;
|
||||||
@ -74,7 +74,6 @@ static size_t ReadPAMFields(PNMInfo* const info, size_t off) {
|
|||||||
char out[MAX_LINE_SIZE + 1];
|
char out[MAX_LINE_SIZE + 1];
|
||||||
size_t out_size;
|
size_t out_size;
|
||||||
int tmp;
|
int tmp;
|
||||||
int expected_depth = -1;
|
|
||||||
assert(info != NULL);
|
assert(info != NULL);
|
||||||
while (1) {
|
while (1) {
|
||||||
off = ReadLine(info->data, off, info->data_size, out, &out_size);
|
off = ReadLine(info->data, off, info->data_size, out, &out_size);
|
||||||
@ -96,16 +95,13 @@ static size_t ReadPAMFields(PNMInfo* const info, size_t off) {
|
|||||||
info->seen_flags |= MAXVAL_FLAG;
|
info->seen_flags |= MAXVAL_FLAG;
|
||||||
info->max_value = tmp;
|
info->max_value = tmp;
|
||||||
} else if (!strcmp(out, "TUPLTYPE RGB_ALPHA")) {
|
} else if (!strcmp(out, "TUPLTYPE RGB_ALPHA")) {
|
||||||
expected_depth = 4;
|
info->bytes_per_px = 4;
|
||||||
info->seen_flags |= TUPLE_FLAG;
|
info->seen_flags |= TUPLE_FLAG;
|
||||||
} else if (!strcmp(out, "TUPLTYPE RGB")) {
|
} else if (!strcmp(out, "TUPLTYPE RGB")) {
|
||||||
expected_depth = 3;
|
info->bytes_per_px = 3;
|
||||||
info->seen_flags |= TUPLE_FLAG;
|
|
||||||
} else if (!strcmp(out, "TUPLTYPE GRAYSCALE_ALPHA")) {
|
|
||||||
expected_depth = 2;
|
|
||||||
info->seen_flags |= TUPLE_FLAG;
|
info->seen_flags |= TUPLE_FLAG;
|
||||||
} else if (!strcmp(out, "TUPLTYPE GRAYSCALE")) {
|
} else if (!strcmp(out, "TUPLTYPE GRAYSCALE")) {
|
||||||
expected_depth = 1;
|
info->bytes_per_px = 1;
|
||||||
info->seen_flags |= TUPLE_FLAG;
|
info->seen_flags |= TUPLE_FLAG;
|
||||||
} else if (!strcmp(out, "ENDHDR")) {
|
} else if (!strcmp(out, "ENDHDR")) {
|
||||||
break;
|
break;
|
||||||
@ -114,24 +110,23 @@ static size_t ReadPAMFields(PNMInfo* const info, size_t off) {
|
|||||||
int i;
|
int i;
|
||||||
if (out_size > 20) sprintf(out + 20 - strlen(kEllipsis), kEllipsis);
|
if (out_size > 20) sprintf(out + 20 - strlen(kEllipsis), kEllipsis);
|
||||||
for (i = 0; i < (int)strlen(out); ++i) {
|
for (i = 0; i < (int)strlen(out); ++i) {
|
||||||
// isprint() might trigger a "char-subscripts" warning if given a char.
|
if (!isprint(out[i])) out[i] = ' ';
|
||||||
if (!isprint((int)out[i])) out[i] = ' ';
|
|
||||||
}
|
}
|
||||||
fprintf(stderr, "PAM header error: unrecognized entry [%s]\n", out);
|
fprintf(stderr, "PAM header error: unrecognized entry [%s]\n", out);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!(info->seen_flags & ALL_NEEDED_FLAGS)) {
|
if (!(info->seen_flags & TUPLE_FLAG)) {
|
||||||
fprintf(stderr, "PAM header error: missing tags%s%s%s%s\n",
|
if (info->depth > 0 && info->depth <= 4 && info->depth != 2) {
|
||||||
(info->seen_flags & WIDTH_FLAG) ? "" : " WIDTH",
|
info->seen_flags |= TUPLE_FLAG;
|
||||||
(info->seen_flags & HEIGHT_FLAG) ? "" : " HEIGHT",
|
info->bytes_per_px = info->depth * (info->max_value > 255 ? 2 : 1);
|
||||||
(info->seen_flags & DEPTH_FLAG) ? "" : " DEPTH",
|
} else {
|
||||||
(info->seen_flags & MAXVAL_FLAG) ? "" : " MAXVAL");
|
fprintf(stderr, "PAM: invalid bitdepth (%d).\n", info->depth);
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (expected_depth != -1 && info->depth != expected_depth) {
|
if (info->seen_flags != ALL_NEEDED_FLAGS) {
|
||||||
fprintf(stderr, "PAM header error: expected DEPTH %d but got DEPTH %d\n",
|
fprintf(stderr, "PAM: incomplete header.\n");
|
||||||
expected_depth, info->depth);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return off;
|
return off;
|
||||||
@ -165,15 +160,16 @@ static size_t ReadHeader(PNMInfo* const info) {
|
|||||||
|
|
||||||
// finish initializing missing fields
|
// finish initializing missing fields
|
||||||
info->depth = (info->type == 5) ? 1 : 3;
|
info->depth = (info->type == 5) ? 1 : 3;
|
||||||
|
info->bytes_per_px = info->depth * (info->max_value > 255 ? 2 : 1);
|
||||||
}
|
}
|
||||||
// perform some basic numerical validation
|
// perform some basic numerical validation
|
||||||
if (info->width <= 0 || info->height <= 0 ||
|
if (info->width <= 0 || info->height <= 0 ||
|
||||||
info->type <= 0 || info->type >= 9 ||
|
info->type <= 0 || info->type >= 9 ||
|
||||||
info->depth <= 0 || info->depth > 4 ||
|
info->depth <= 0 || info->depth == 2 || info->depth > 4 ||
|
||||||
|
info->bytes_per_px < info->depth ||
|
||||||
info->max_value <= 0 || info->max_value >= 65536) {
|
info->max_value <= 0 || info->max_value >= 65536) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
info->bytes_per_px = info->depth * (info->max_value > 255 ? 2 : 1);
|
|
||||||
return off;
|
return off;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -182,7 +178,7 @@ int ReadPNM(const uint8_t* const data, size_t data_size,
|
|||||||
struct Metadata* const metadata) {
|
struct Metadata* const metadata) {
|
||||||
int ok = 0;
|
int ok = 0;
|
||||||
int i, j;
|
int i, j;
|
||||||
uint64_t stride, pixel_bytes, sample_size, depth;
|
uint64_t stride, pixel_bytes;
|
||||||
uint8_t* rgb = NULL, *tmp_rgb;
|
uint8_t* rgb = NULL, *tmp_rgb;
|
||||||
size_t offset;
|
size_t offset;
|
||||||
PNMInfo info;
|
PNMInfo info;
|
||||||
@ -213,10 +209,8 @@ int ReadPNM(const uint8_t* const data, size_t data_size,
|
|||||||
fprintf(stderr, "Truncated PNM file (P%d).\n", info.type);
|
fprintf(stderr, "Truncated PNM file (P%d).\n", info.type);
|
||||||
goto End;
|
goto End;
|
||||||
}
|
}
|
||||||
sample_size = (info.max_value > 255) ? 2 : 1;
|
stride =
|
||||||
// final depth
|
(uint64_t)(info.bytes_per_px < 3 ? 3 : info.bytes_per_px) * info.width;
|
||||||
depth = (info.depth == 1 || info.depth == 3 || !keep_alpha) ? 3 : 4;
|
|
||||||
stride = depth * info.width;
|
|
||||||
if (stride != (size_t)stride ||
|
if (stride != (size_t)stride ||
|
||||||
!ImgIoUtilCheckSizeArgumentsOverflow(stride, info.height)) {
|
!ImgIoUtilCheckSizeArgumentsOverflow(stride, info.height)) {
|
||||||
goto End;
|
goto End;
|
||||||
@ -225,63 +219,30 @@ int ReadPNM(const uint8_t* const data, size_t data_size,
|
|||||||
rgb = (uint8_t*)malloc((size_t)stride * info.height);
|
rgb = (uint8_t*)malloc((size_t)stride * info.height);
|
||||||
if (rgb == NULL) goto End;
|
if (rgb == NULL) goto End;
|
||||||
|
|
||||||
// Convert input.
|
// Convert input
|
||||||
// We only optimize for the sample_size=1, max_value=255, depth=1 case.
|
|
||||||
tmp_rgb = rgb;
|
tmp_rgb = rgb;
|
||||||
for (j = 0; j < info.height; ++j) {
|
for (j = 0; j < info.height; ++j) {
|
||||||
const uint8_t* in = data + offset;
|
assert(offset + info.bytes_per_px * info.width <= data_size);
|
||||||
offset += info.bytes_per_px * info.width;
|
if (info.depth == 1) {
|
||||||
assert(offset <= data_size);
|
// convert grayscale -> RGB
|
||||||
if (info.max_value == 255 && info.depth >= 3) {
|
for (i = 0; i < info.width; ++i) {
|
||||||
// RGB or RGBA
|
const uint8_t v = data[offset + i];
|
||||||
if (info.depth == 3 || keep_alpha) {
|
tmp_rgb[3 * i + 0] = tmp_rgb[3 * i + 1] = tmp_rgb[3 * i + 2] = v;
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
} else if (info.depth == 3) { // RGB
|
||||||
|
memcpy(tmp_rgb, data + offset, 3 * info.width * sizeof(*data));
|
||||||
|
} else if (info.depth == 4) { // RGBA
|
||||||
|
memcpy(tmp_rgb, data + offset, 4 * info.width * sizeof(*data));
|
||||||
}
|
}
|
||||||
|
offset += info.bytes_per_px * info.width;
|
||||||
tmp_rgb += stride;
|
tmp_rgb += stride;
|
||||||
}
|
}
|
||||||
|
|
||||||
// WebP conversion.
|
// WebP conversion.
|
||||||
pic->width = info.width;
|
pic->width = info.width;
|
||||||
pic->height = info.height;
|
pic->height = info.height;
|
||||||
ok = (depth == 4) ? WebPPictureImportRGBA(pic, rgb, (int)stride)
|
ok = (info.depth == 4) ? WebPPictureImportRGBA(pic, rgb, (int)stride)
|
||||||
: WebPPictureImportRGB(pic, rgb, (int)stride);
|
: WebPPictureImportRGB(pic, rgb, (int)stride);
|
||||||
if (!ok) goto End;
|
if (!ok) goto End;
|
||||||
|
|
||||||
ok = 1;
|
ok = 1;
|
||||||
|
@ -46,7 +46,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)) {
|
||||||
@ -156,8 +156,7 @@ int ReadTIFF(const uint8_t* const data, size_t data_size,
|
|||||||
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_t width, height;
|
||||||
uint64_t stride;
|
|
||||||
uint16_t samples_per_px = 0;
|
uint16_t samples_per_px = 0;
|
||||||
uint16_t extra_samples = 0;
|
uint16_t extra_samples = 0;
|
||||||
uint16_t* extra_samples_ptr = NULL;
|
uint16_t* extra_samples_ptr = NULL;
|
||||||
@ -190,36 +189,15 @@ int ReadTIFF(const uint8_t* const data, size_t data_size,
|
|||||||
}
|
}
|
||||||
if (samples_per_px < 3 || samples_per_px > 4) goto End; // not supported
|
if (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((uint64_t)width * height,
|
||||||
if (!ImgIoUtilCheckSizeArgumentsOverflow(stride, image_height)) {
|
sizeof(*raster))) {
|
||||||
fprintf(stderr, "Error! TIFF image dimension (%d x %d) is too large.\n",
|
|
||||||
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,
|
if (samples_per_px > 3 && !TIFFGetField(tif, TIFFTAG_EXTRASAMPLES,
|
||||||
&extra_samples, &extra_samples_ptr)) {
|
&extra_samples, &extra_samples_ptr)) {
|
||||||
fprintf(stderr, "Error! Cannot retrieve TIFF ExtraSamples info.\n");
|
fprintf(stderr, "Error! Cannot retrieve TIFF ExtraSamples info.\n");
|
||||||
@ -227,32 +205,33 @@ int ReadTIFF(const uint8_t* const data, size_t data_size,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// _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 we have an alpha channel, we must un-multiply from rgbA to RGBA
|
||||||
if (extra_samples == 1 && extra_samples_ptr != NULL &&
|
if (extra_samples == 1 && extra_samples_ptr != NULL &&
|
||||||
extra_samples_ptr[0] == EXTRASAMPLE_ASSOCALPHA) {
|
extra_samples_ptr[0] == EXTRASAMPLE_ASSOCALPHA) {
|
||||||
uint32_t y;
|
uint32_t y;
|
||||||
uint8_t* tmp = (uint8_t*)raster;
|
uint8_t* tmp = (uint8_t*)raster;
|
||||||
for (y = 0; y < image_height; ++y) {
|
for (y = 0; y < height; ++y) {
|
||||||
MultARGBRow(tmp, image_width);
|
MultARGBRow(tmp, width);
|
||||||
tmp += stride;
|
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 {
|
||||||
|
@ -65,7 +65,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,7 +95,7 @@ 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 {
|
||||||
status = WebPIUpdate(idec, data, data_size);
|
status = WebPIUpdate(idec, data, data_size);
|
||||||
|
@ -134,10 +134,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 +270,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 +298,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}")/"* .
|
|
||||||
else
|
|
||||||
# make a empty report to wipe out any old bug reports.
|
|
||||||
cat << EOT > index.html
|
|
||||||
<html>
|
|
||||||
<body>
|
|
||||||
No bugs reported.
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
EOT
|
|
||||||
fi
|
|
38
iosbuild.sh
38
iosbuild.sh
@ -1,9 +1,8 @@
|
|||||||
#!/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).
|
||||||
@ -13,9 +12,6 @@
|
|||||||
|
|
||||||
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)}'
|
||||||
@ -54,27 +50,13 @@ if [[ -z "${SDK}" ]]; then
|
|||||||
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}"
|
|
||||||
echo "iOS SDK Version: ${SDK}"
|
|
||||||
|
|
||||||
if [[ -e "${BUILDDIR}" || -e "${TARGETDIR}" || -e "${DECTARGETDIR}" \
|
|
||||||
|| -e "${MUXTARGETDIR}" || -e "${DEMUXTARGETDIR}" ]]; then
|
|
||||||
cat << EOF
|
|
||||||
WARNING: The following directories will be deleted:
|
|
||||||
WARNING: ${BUILDDIR}
|
|
||||||
WARNING: ${TARGETDIR}
|
|
||||||
WARNING: ${DECTARGETDIR}
|
|
||||||
WARNING: ${MUXTARGETDIR}
|
|
||||||
WARNING: ${DEMUXTARGETDIR}
|
|
||||||
WARNING: The build will continue in 5 seconds...
|
|
||||||
EOF
|
|
||||||
sleep 5
|
|
||||||
fi
|
|
||||||
rm -rf ${BUILDDIR} ${TARGETDIR} ${DECTARGETDIR} \
|
rm -rf ${BUILDDIR} ${TARGETDIR} ${DECTARGETDIR} \
|
||||||
${MUXTARGETDIR} ${DEMUXTARGETDIR}
|
${MUXTARGETDIR} ${DEMUXTARGETDIR}
|
||||||
mkdir -p ${BUILDDIR} ${TARGETDIR}/Headers/ ${DECTARGETDIR}/Headers/ \
|
mkdir -p ${BUILDDIR} ${TARGETDIR}/Headers/ ${DECTARGETDIR}/Headers/ \
|
||||||
@ -82,12 +64,12 @@ mkdir -p ${BUILDDIR} ${TARGETDIR}/Headers/ ${DECTARGETDIR}/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:
|
||||||
http://www.macports.org/install.php
|
http://www.macports.org/install.php
|
||||||
EOF
|
EOT
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
@ -121,7 +103,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}"
|
||||||
@ -166,5 +148,3 @@ echo "DEMUXLIBLIST = ${DEMUXLIBLIST}"
|
|||||||
cp -a ${SRCDIR}/src/webp/{decode,types,mux_types,demux}.h \
|
cp -a ${SRCDIR}/src/webp/{decode,types,mux_types,demux}.h \
|
||||||
${DEMUXTARGETDIR}/Headers/
|
${DEMUXTARGETDIR}/Headers/
|
||||||
${LIPO} -create ${DEMUXLIBLIST} -output ${DEMUXTARGETDIR}/WebPDemux
|
${LIPO} -create ${DEMUXLIBLIST} -output ${DEMUXTARGETDIR}/WebPDemux
|
||||||
|
|
||||||
echo "SUCCESS"
|
|
||||||
|
@ -166,7 +166,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 \
|
||||||
|
10
man/cwebp.1
10
man/cwebp.1
@ -1,5 +1,5 @@
|
|||||||
.\" Hey, EMACS: -*- nroff -*-
|
.\" Hey, EMACS: -*- nroff -*-
|
||||||
.TH CWEBP 1 "November 19, 2020"
|
.TH CWEBP 1 "January 11, 2019"
|
||||||
.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
|
||||||
@ -135,13 +134,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.
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
.\" Hey, EMACS: -*- nroff -*-
|
.\" Hey, EMACS: -*- nroff -*-
|
||||||
.TH DWEBP 1 "November 19, 2020"
|
.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
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
.\" Hey, EMACS: -*- nroff -*-
|
.\" Hey, EMACS: -*- nroff -*-
|
||||||
.TH GIF2WEBP 1 "May 1, 2020"
|
.TH GIF2WEBP 1 "January 25, 2018"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
gif2webp \- Convert a GIF image to WebP
|
gif2webp \- Convert a GIF image to WebP
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
@ -62,9 +62,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
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
.\" Hey, EMACS: -*- nroff -*-
|
.\" Hey, EMACS: -*- nroff -*-
|
||||||
.TH IMG2WEBP 1 "May 1, 2020"
|
.TH IMG2WEBP 1 "April 3, 2018"
|
||||||
.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
|
||||||
@ -16,8 +16,8 @@ command.
|
|||||||
\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
|
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.
|
the argument, the command line argument are actually tokenized from this file.
|
||||||
This allows for easy scripting or using a large number of arguments.
|
This allows for easy scripting or using large number of arguments.
|
||||||
.SH FILE-LEVEL OPTIONS
|
.SH FILE-LEVEL OPTIONS
|
||||||
The file-level options are applied at the beginning of the compression process,
|
The file-level options are applied at the beginning of the compression process,
|
||||||
before the input frames are read.
|
before the input frames are read.
|
||||||
@ -27,7 +27,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
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
.\" Hey, EMACS: -*- nroff -*-
|
.\" Hey, EMACS: -*- nroff -*-
|
||||||
.TH WEBPMUX 1 "November 3, 2021"
|
.TH WEBPMUX 1 "April 23, 2018"
|
||||||
.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.
|
||||||
@ -59,7 +59,7 @@ command.
|
|||||||
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
|
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.
|
the argument, the command line arguments are actually tokenized from this file.
|
||||||
This allows for easy scripting or using a large number of arguments.
|
This allows for easy scripting or using large number of arguments.
|
||||||
.SH OPTIONS
|
.SH OPTIONS
|
||||||
.SS GET_OPTIONS (\-get):
|
.SS GET_OPTIONS (\-get):
|
||||||
.TP
|
.TP
|
||||||
@ -77,17 +77,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
|
||||||
|
@ -36,7 +36,7 @@ libwebp_la_LIBADD += utils/libwebputils.la
|
|||||||
# other than the ones listed on the command line, i.e., after linking, it will
|
# other than the ones listed on the command line, i.e., after linking, it will
|
||||||
# not have unresolved symbols. Some platforms (Windows among them) require all
|
# not have unresolved symbols. Some platforms (Windows among them) require all
|
||||||
# symbols in shared libraries to be resolved at library creation.
|
# symbols in shared libraries to be resolved at library creation.
|
||||||
libwebp_la_LDFLAGS = -no-undefined -version-info 8:2:1
|
libwebp_la_LDFLAGS = -no-undefined -version-info 7:5:0
|
||||||
libwebpincludedir = $(includedir)/webp
|
libwebpincludedir = $(includedir)/webp
|
||||||
pkgconfig_DATA = libwebp.pc
|
pkgconfig_DATA = libwebp.pc
|
||||||
|
|
||||||
@ -48,7 +48,7 @@ if BUILD_LIBWEBPDECODER
|
|||||||
libwebpdecoder_la_LIBADD += dsp/libwebpdspdecode.la
|
libwebpdecoder_la_LIBADD += dsp/libwebpdspdecode.la
|
||||||
libwebpdecoder_la_LIBADD += utils/libwebputilsdecode.la
|
libwebpdecoder_la_LIBADD += utils/libwebputilsdecode.la
|
||||||
|
|
||||||
libwebpdecoder_la_LDFLAGS = -no-undefined -version-info 4:2:1
|
libwebpdecoder_la_LDFLAGS = -no-undefined -version-info 3:5:0
|
||||||
pkgconfig_DATA += libwebpdecoder.pc
|
pkgconfig_DATA += libwebpdecoder.pc
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
@ -183,7 +183,7 @@ const uint8_t* VP8DecompressAlphaRows(VP8Decoder* const dec,
|
|||||||
assert(dec != NULL && io != NULL);
|
assert(dec != NULL && io != NULL);
|
||||||
|
|
||||||
if (row < 0 || num_rows <= 0 || row + num_rows > height) {
|
if (row < 0 || num_rows <= 0 || row + num_rows > height) {
|
||||||
return NULL;
|
return NULL; // sanity check.
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!dec->is_alpha_decoded_) {
|
if (!dec->is_alpha_decoded_) {
|
||||||
|
@ -102,7 +102,7 @@ static VP8StatusCode AllocateBuffer(WebPDecBuffer* const buffer) {
|
|||||||
int stride;
|
int stride;
|
||||||
uint64_t size;
|
uint64_t size;
|
||||||
|
|
||||||
if ((uint64_t)w * kModeBpp[mode] >= (1ull << 31)) {
|
if ((uint64_t)w * kModeBpp[mode] >= (1ull << 32)) {
|
||||||
return VP8_STATUS_INVALID_PARAM;
|
return VP8_STATUS_INVALID_PARAM;
|
||||||
}
|
}
|
||||||
stride = w * kModeBpp[mode];
|
stride = w * kModeBpp[mode];
|
||||||
@ -117,6 +117,7 @@ static VP8StatusCode AllocateBuffer(WebPDecBuffer* const buffer) {
|
|||||||
}
|
}
|
||||||
total_size = size + 2 * uv_size + a_size;
|
total_size = size + 2 * uv_size + a_size;
|
||||||
|
|
||||||
|
// Security/sanity checks
|
||||||
output = (uint8_t*)WebPSafeMalloc(total_size, sizeof(*output));
|
output = (uint8_t*)WebPSafeMalloc(total_size, sizeof(*output));
|
||||||
if (output == NULL) {
|
if (output == NULL) {
|
||||||
return VP8_STATUS_OUT_OF_MEMORY;
|
return VP8_STATUS_OUT_OF_MEMORY;
|
||||||
@ -155,11 +156,11 @@ VP8StatusCode WebPFlipBuffer(WebPDecBuffer* const buffer) {
|
|||||||
}
|
}
|
||||||
if (WebPIsRGBMode(buffer->colorspace)) {
|
if (WebPIsRGBMode(buffer->colorspace)) {
|
||||||
WebPRGBABuffer* const buf = &buffer->u.RGBA;
|
WebPRGBABuffer* const buf = &buffer->u.RGBA;
|
||||||
buf->rgba += (int64_t)(buffer->height - 1) * buf->stride;
|
buf->rgba += (buffer->height - 1) * buf->stride;
|
||||||
buf->stride = -buf->stride;
|
buf->stride = -buf->stride;
|
||||||
} else {
|
} else {
|
||||||
WebPYUVABuffer* const buf = &buffer->u.YUVA;
|
WebPYUVABuffer* const buf = &buffer->u.YUVA;
|
||||||
const int64_t H = buffer->height;
|
const int H = buffer->height;
|
||||||
buf->y += (H - 1) * buf->y_stride;
|
buf->y += (H - 1) * buf->y_stride;
|
||||||
buf->y_stride = -buf->y_stride;
|
buf->y_stride = -buf->y_stride;
|
||||||
buf->u += ((H - 1) >> 1) * buf->u_stride;
|
buf->u += ((H - 1) >> 1) * buf->u_stride;
|
||||||
@ -187,7 +188,8 @@ VP8StatusCode WebPAllocateDecBuffer(int width, int height,
|
|||||||
const int ch = options->crop_height;
|
const int ch = options->crop_height;
|
||||||
const int x = options->crop_left & ~1;
|
const int x = options->crop_left & ~1;
|
||||||
const int y = options->crop_top & ~1;
|
const int y = options->crop_top & ~1;
|
||||||
if (!WebPCheckCropDimensions(width, height, x, y, cw, ch)) {
|
if (x < 0 || y < 0 || cw <= 0 || ch <= 0 ||
|
||||||
|
x + cw > width || y + ch > height) {
|
||||||
return VP8_STATUS_INVALID_PARAM; // out of frame boundary.
|
return VP8_STATUS_INVALID_PARAM; // out of frame boundary.
|
||||||
}
|
}
|
||||||
width = cw;
|
width = cw;
|
||||||
|
@ -705,7 +705,7 @@ static int AllocateMemory(VP8Decoder* const dec) {
|
|||||||
+ cache_size + alpha_size + WEBP_ALIGN_CST;
|
+ cache_size + alpha_size + WEBP_ALIGN_CST;
|
||||||
uint8_t* mem;
|
uint8_t* mem;
|
||||||
|
|
||||||
if (!CheckSizeOverflow(needed)) return 0; // check for overflow
|
if (needed != (size_t)needed) return 0; // check for overflow
|
||||||
if (needed > dec->mem_size_) {
|
if (needed > dec->mem_size_) {
|
||||||
WebPSafeFree(dec->mem_);
|
WebPSafeFree(dec->mem_);
|
||||||
dec->mem_size_ = 0;
|
dec->mem_size_ = 0;
|
||||||
@ -732,7 +732,7 @@ static int AllocateMemory(VP8Decoder* const dec) {
|
|||||||
mem += f_info_size;
|
mem += f_info_size;
|
||||||
dec->thread_ctx_.id_ = 0;
|
dec->thread_ctx_.id_ = 0;
|
||||||
dec->thread_ctx_.f_info_ = dec->f_info_;
|
dec->thread_ctx_.f_info_ = dec->f_info_;
|
||||||
if (dec->filter_type_ > 0 && dec->mt_method_ > 0) {
|
if (dec->mt_method_ > 0) {
|
||||||
// secondary cache line. The deblocking process need to make use of the
|
// secondary cache line. The deblocking process need to make use of the
|
||||||
// filtering strength from previous macroblock row, while the new ones
|
// filtering strength from previous macroblock row, while the new ones
|
||||||
// are being decoded in parallel. We'll just swap the pointers.
|
// are being decoded in parallel. We'll just swap the pointers.
|
||||||
|
@ -166,11 +166,9 @@ static int AppendToMemBuffer(WebPIDecoder* const idec,
|
|||||||
VP8Decoder* const dec = (VP8Decoder*)idec->dec_;
|
VP8Decoder* const dec = (VP8Decoder*)idec->dec_;
|
||||||
MemBuffer* const mem = &idec->mem_;
|
MemBuffer* const mem = &idec->mem_;
|
||||||
const int need_compressed_alpha = NeedCompressedAlpha(idec);
|
const int need_compressed_alpha = NeedCompressedAlpha(idec);
|
||||||
const uint8_t* const old_start =
|
const uint8_t* const old_start = mem->buf_ + mem->start_;
|
||||||
(mem->buf_ == NULL) ? NULL : mem->buf_ + mem->start_;
|
|
||||||
const uint8_t* const old_base =
|
const uint8_t* const old_base =
|
||||||
need_compressed_alpha ? dec->alpha_data_ : old_start;
|
need_compressed_alpha ? dec->alpha_data_ : old_start;
|
||||||
assert(mem->buf_ != NULL || mem->start_ == 0);
|
|
||||||
assert(mem->mode_ == MEM_MODE_APPEND);
|
assert(mem->mode_ == MEM_MODE_APPEND);
|
||||||
if (data_size > MAX_CHUNK_PAYLOAD) {
|
if (data_size > MAX_CHUNK_PAYLOAD) {
|
||||||
// security safeguard: trying to allocate more than what the format
|
// security safeguard: trying to allocate more than what the format
|
||||||
@ -186,7 +184,7 @@ static int AppendToMemBuffer(WebPIDecoder* const idec,
|
|||||||
uint8_t* const new_buf =
|
uint8_t* const new_buf =
|
||||||
(uint8_t*)WebPSafeMalloc(extra_size, sizeof(*new_buf));
|
(uint8_t*)WebPSafeMalloc(extra_size, sizeof(*new_buf));
|
||||||
if (new_buf == NULL) return 0;
|
if (new_buf == NULL) return 0;
|
||||||
if (old_base != NULL) memcpy(new_buf, old_base, current_size);
|
memcpy(new_buf, old_base, current_size);
|
||||||
WebPSafeFree(mem->buf_);
|
WebPSafeFree(mem->buf_);
|
||||||
mem->buf_ = new_buf;
|
mem->buf_ = new_buf;
|
||||||
mem->buf_size_ = (size_t)extra_size;
|
mem->buf_size_ = (size_t)extra_size;
|
||||||
@ -194,7 +192,6 @@ static int AppendToMemBuffer(WebPIDecoder* const idec,
|
|||||||
mem->end_ = current_size;
|
mem->end_ = current_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(mem->buf_ != NULL);
|
|
||||||
memcpy(mem->buf_ + mem->end_, data, data_size);
|
memcpy(mem->buf_ + mem->end_, data, data_size);
|
||||||
mem->end_ += data_size;
|
mem->end_ += data_size;
|
||||||
assert(mem->end_ <= mem->buf_size_);
|
assert(mem->end_ <= mem->buf_size_);
|
||||||
@ -207,9 +204,7 @@ static int RemapMemBuffer(WebPIDecoder* const idec,
|
|||||||
const uint8_t* const data, size_t data_size) {
|
const uint8_t* const data, size_t data_size) {
|
||||||
MemBuffer* const mem = &idec->mem_;
|
MemBuffer* const mem = &idec->mem_;
|
||||||
const uint8_t* const old_buf = mem->buf_;
|
const uint8_t* const old_buf = mem->buf_;
|
||||||
const uint8_t* const old_start =
|
const uint8_t* const old_start = old_buf + mem->start_;
|
||||||
(old_buf == NULL) ? NULL : old_buf + mem->start_;
|
|
||||||
assert(old_buf != NULL || mem->start_ == 0);
|
|
||||||
assert(mem->mode_ == MEM_MODE_MAP);
|
assert(mem->mode_ == MEM_MODE_MAP);
|
||||||
|
|
||||||
if (data_size < mem->buf_size_) return 0; // can't remap to a shorter buffer!
|
if (data_size < mem->buf_size_) return 0; // can't remap to a shorter buffer!
|
||||||
|
151
src/dec/io_dec.c
151
src/dec/io_dec.c
@ -25,16 +25,21 @@
|
|||||||
static int EmitYUV(const VP8Io* const io, WebPDecParams* const p) {
|
static int EmitYUV(const VP8Io* const io, WebPDecParams* const p) {
|
||||||
WebPDecBuffer* output = p->output;
|
WebPDecBuffer* output = p->output;
|
||||||
const WebPYUVABuffer* const buf = &output->u.YUVA;
|
const WebPYUVABuffer* const buf = &output->u.YUVA;
|
||||||
uint8_t* const y_dst = buf->y + (size_t)io->mb_y * buf->y_stride;
|
uint8_t* const y_dst = buf->y + io->mb_y * buf->y_stride;
|
||||||
uint8_t* const u_dst = buf->u + (size_t)(io->mb_y >> 1) * buf->u_stride;
|
uint8_t* const u_dst = buf->u + (io->mb_y >> 1) * buf->u_stride;
|
||||||
uint8_t* const v_dst = buf->v + (size_t)(io->mb_y >> 1) * buf->v_stride;
|
uint8_t* const v_dst = buf->v + (io->mb_y >> 1) * buf->v_stride;
|
||||||
const int mb_w = io->mb_w;
|
const int mb_w = io->mb_w;
|
||||||
const int mb_h = io->mb_h;
|
const int mb_h = io->mb_h;
|
||||||
const int uv_w = (mb_w + 1) / 2;
|
const int uv_w = (mb_w + 1) / 2;
|
||||||
const int uv_h = (mb_h + 1) / 2;
|
const int uv_h = (mb_h + 1) / 2;
|
||||||
WebPCopyPlane(io->y, io->y_stride, y_dst, buf->y_stride, mb_w, mb_h);
|
int j;
|
||||||
WebPCopyPlane(io->u, io->uv_stride, u_dst, buf->u_stride, uv_w, uv_h);
|
for (j = 0; j < mb_h; ++j) {
|
||||||
WebPCopyPlane(io->v, io->uv_stride, v_dst, buf->v_stride, uv_w, uv_h);
|
memcpy(y_dst + j * buf->y_stride, io->y + j * io->y_stride, mb_w);
|
||||||
|
}
|
||||||
|
for (j = 0; j < uv_h; ++j) {
|
||||||
|
memcpy(u_dst + j * buf->u_stride, io->u + j * io->uv_stride, uv_w);
|
||||||
|
memcpy(v_dst + j * buf->v_stride, io->v + j * io->uv_stride, uv_w);
|
||||||
|
}
|
||||||
return io->mb_h;
|
return io->mb_h;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -42,7 +47,7 @@ static int EmitYUV(const VP8Io* const io, WebPDecParams* const p) {
|
|||||||
static int EmitSampledRGB(const VP8Io* const io, WebPDecParams* const p) {
|
static int EmitSampledRGB(const VP8Io* const io, WebPDecParams* const p) {
|
||||||
WebPDecBuffer* const output = p->output;
|
WebPDecBuffer* const output = p->output;
|
||||||
WebPRGBABuffer* const buf = &output->u.RGBA;
|
WebPRGBABuffer* const buf = &output->u.RGBA;
|
||||||
uint8_t* const dst = buf->rgba + (size_t)io->mb_y * buf->stride;
|
uint8_t* const dst = buf->rgba + io->mb_y * buf->stride;
|
||||||
WebPSamplerProcessPlane(io->y, io->y_stride,
|
WebPSamplerProcessPlane(io->y, io->y_stride,
|
||||||
io->u, io->v, io->uv_stride,
|
io->u, io->v, io->uv_stride,
|
||||||
dst, buf->stride, io->mb_w, io->mb_h,
|
dst, buf->stride, io->mb_w, io->mb_h,
|
||||||
@ -57,7 +62,7 @@ static int EmitSampledRGB(const VP8Io* const io, WebPDecParams* const p) {
|
|||||||
static int EmitFancyRGB(const VP8Io* const io, WebPDecParams* const p) {
|
static int EmitFancyRGB(const VP8Io* const io, WebPDecParams* const p) {
|
||||||
int num_lines_out = io->mb_h; // a priori guess
|
int num_lines_out = io->mb_h; // a priori guess
|
||||||
const WebPRGBABuffer* const buf = &p->output->u.RGBA;
|
const WebPRGBABuffer* const buf = &p->output->u.RGBA;
|
||||||
uint8_t* dst = buf->rgba + (size_t)io->mb_y * buf->stride;
|
uint8_t* dst = buf->rgba + io->mb_y * buf->stride;
|
||||||
WebPUpsampleLinePairFunc upsample = WebPUpsamplers[p->output->colorspace];
|
WebPUpsampleLinePairFunc upsample = WebPUpsamplers[p->output->colorspace];
|
||||||
const uint8_t* cur_y = io->y;
|
const uint8_t* cur_y = io->y;
|
||||||
const uint8_t* cur_u = io->u;
|
const uint8_t* cur_u = io->u;
|
||||||
@ -128,7 +133,7 @@ static int EmitAlphaYUV(const VP8Io* const io, WebPDecParams* const p,
|
|||||||
const WebPYUVABuffer* const buf = &p->output->u.YUVA;
|
const WebPYUVABuffer* const buf = &p->output->u.YUVA;
|
||||||
const int mb_w = io->mb_w;
|
const int mb_w = io->mb_w;
|
||||||
const int mb_h = io->mb_h;
|
const int mb_h = io->mb_h;
|
||||||
uint8_t* dst = buf->a + (size_t)io->mb_y * buf->a_stride;
|
uint8_t* dst = buf->a + io->mb_y * buf->a_stride;
|
||||||
int j;
|
int j;
|
||||||
(void)expected_num_lines_out;
|
(void)expected_num_lines_out;
|
||||||
assert(expected_num_lines_out == mb_h);
|
assert(expected_num_lines_out == mb_h);
|
||||||
@ -181,7 +186,7 @@ static int EmitAlphaRGB(const VP8Io* const io, WebPDecParams* const p,
|
|||||||
(colorspace == MODE_ARGB || colorspace == MODE_Argb);
|
(colorspace == MODE_ARGB || colorspace == MODE_Argb);
|
||||||
const WebPRGBABuffer* const buf = &p->output->u.RGBA;
|
const WebPRGBABuffer* const buf = &p->output->u.RGBA;
|
||||||
int num_rows;
|
int num_rows;
|
||||||
const size_t start_y = GetAlphaSourceRow(io, &alpha, &num_rows);
|
const int start_y = GetAlphaSourceRow(io, &alpha, &num_rows);
|
||||||
uint8_t* const base_rgba = buf->rgba + start_y * buf->stride;
|
uint8_t* const base_rgba = buf->rgba + start_y * buf->stride;
|
||||||
uint8_t* const dst = base_rgba + (alpha_first ? 0 : 3);
|
uint8_t* const dst = base_rgba + (alpha_first ? 0 : 3);
|
||||||
const int has_alpha = WebPDispatchAlpha(alpha, io->width, mb_w,
|
const int has_alpha = WebPDispatchAlpha(alpha, io->width, mb_w,
|
||||||
@ -205,7 +210,7 @@ static int EmitAlphaRGBA4444(const VP8Io* const io, WebPDecParams* const p,
|
|||||||
const WEBP_CSP_MODE colorspace = p->output->colorspace;
|
const WEBP_CSP_MODE colorspace = p->output->colorspace;
|
||||||
const WebPRGBABuffer* const buf = &p->output->u.RGBA;
|
const WebPRGBABuffer* const buf = &p->output->u.RGBA;
|
||||||
int num_rows;
|
int num_rows;
|
||||||
const size_t start_y = GetAlphaSourceRow(io, &alpha, &num_rows);
|
const int start_y = GetAlphaSourceRow(io, &alpha, &num_rows);
|
||||||
uint8_t* const base_rgba = buf->rgba + start_y * buf->stride;
|
uint8_t* const base_rgba = buf->rgba + start_y * buf->stride;
|
||||||
#if (WEBP_SWAP_16BIT_CSP == 1)
|
#if (WEBP_SWAP_16BIT_CSP == 1)
|
||||||
uint8_t* alpha_dst = base_rgba;
|
uint8_t* alpha_dst = base_rgba;
|
||||||
@ -271,9 +276,9 @@ static int EmitRescaledYUV(const VP8Io* const io, WebPDecParams* const p) {
|
|||||||
static int EmitRescaledAlphaYUV(const VP8Io* const io, WebPDecParams* const p,
|
static int EmitRescaledAlphaYUV(const VP8Io* const io, WebPDecParams* const p,
|
||||||
int expected_num_lines_out) {
|
int expected_num_lines_out) {
|
||||||
const WebPYUVABuffer* const buf = &p->output->u.YUVA;
|
const WebPYUVABuffer* const buf = &p->output->u.YUVA;
|
||||||
uint8_t* const dst_a = buf->a + (size_t)p->last_y * buf->a_stride;
|
uint8_t* const dst_a = buf->a + p->last_y * buf->a_stride;
|
||||||
if (io->a != NULL) {
|
if (io->a != NULL) {
|
||||||
uint8_t* const dst_y = buf->y + (size_t)p->last_y * buf->y_stride;
|
uint8_t* const dst_y = buf->y + p->last_y * buf->y_stride;
|
||||||
const int num_lines_out = Rescale(io->a, io->width, io->mb_h, p->scaler_a);
|
const int num_lines_out = Rescale(io->a, io->width, io->mb_h, p->scaler_a);
|
||||||
assert(expected_num_lines_out == num_lines_out);
|
assert(expected_num_lines_out == num_lines_out);
|
||||||
if (num_lines_out > 0) { // unmultiply the Y
|
if (num_lines_out > 0) { // unmultiply the Y
|
||||||
@ -298,57 +303,46 @@ static int InitYUVRescaler(const VP8Io* const io, WebPDecParams* const p) {
|
|||||||
const int uv_out_height = (out_height + 1) >> 1;
|
const int uv_out_height = (out_height + 1) >> 1;
|
||||||
const int uv_in_width = (io->mb_w + 1) >> 1;
|
const int uv_in_width = (io->mb_w + 1) >> 1;
|
||||||
const int uv_in_height = (io->mb_h + 1) >> 1;
|
const int uv_in_height = (io->mb_h + 1) >> 1;
|
||||||
// scratch memory for luma rescaler
|
const size_t work_size = 2 * out_width; // scratch memory for luma rescaler
|
||||||
const size_t work_size = 2 * (size_t)out_width;
|
|
||||||
const size_t uv_work_size = 2 * uv_out_width; // and for each u/v ones
|
const size_t uv_work_size = 2 * uv_out_width; // and for each u/v ones
|
||||||
uint64_t total_size;
|
size_t tmp_size, rescaler_size;
|
||||||
size_t rescaler_size;
|
|
||||||
rescaler_t* work;
|
rescaler_t* work;
|
||||||
WebPRescaler* scalers;
|
WebPRescaler* scalers;
|
||||||
const int num_rescalers = has_alpha ? 4 : 3;
|
const int num_rescalers = has_alpha ? 4 : 3;
|
||||||
|
|
||||||
total_size = ((uint64_t)work_size + 2 * uv_work_size) * sizeof(*work);
|
tmp_size = (work_size + 2 * uv_work_size) * sizeof(*work);
|
||||||
if (has_alpha) {
|
if (has_alpha) {
|
||||||
total_size += (uint64_t)work_size * sizeof(*work);
|
tmp_size += work_size * sizeof(*work);
|
||||||
}
|
}
|
||||||
rescaler_size = num_rescalers * sizeof(*p->scaler_y) + WEBP_ALIGN_CST;
|
rescaler_size = num_rescalers * sizeof(*p->scaler_y) + WEBP_ALIGN_CST;
|
||||||
total_size += rescaler_size;
|
|
||||||
if (!CheckSizeOverflow(total_size)) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
p->memory = WebPSafeMalloc(1ULL, (size_t)total_size);
|
p->memory = WebPSafeMalloc(1ULL, tmp_size + rescaler_size);
|
||||||
if (p->memory == NULL) {
|
if (p->memory == NULL) {
|
||||||
return 0; // memory error
|
return 0; // memory error
|
||||||
}
|
}
|
||||||
work = (rescaler_t*)p->memory;
|
work = (rescaler_t*)p->memory;
|
||||||
|
|
||||||
scalers = (WebPRescaler*)WEBP_ALIGN(
|
scalers = (WebPRescaler*)WEBP_ALIGN((const uint8_t*)work + tmp_size);
|
||||||
(const uint8_t*)work + total_size - rescaler_size);
|
|
||||||
p->scaler_y = &scalers[0];
|
p->scaler_y = &scalers[0];
|
||||||
p->scaler_u = &scalers[1];
|
p->scaler_u = &scalers[1];
|
||||||
p->scaler_v = &scalers[2];
|
p->scaler_v = &scalers[2];
|
||||||
p->scaler_a = has_alpha ? &scalers[3] : NULL;
|
p->scaler_a = has_alpha ? &scalers[3] : NULL;
|
||||||
|
|
||||||
if (!WebPRescalerInit(p->scaler_y, io->mb_w, io->mb_h,
|
WebPRescalerInit(p->scaler_y, io->mb_w, io->mb_h,
|
||||||
buf->y, out_width, out_height, buf->y_stride, 1,
|
buf->y, out_width, out_height, buf->y_stride, 1,
|
||||||
work) ||
|
work);
|
||||||
!WebPRescalerInit(p->scaler_u, uv_in_width, uv_in_height,
|
WebPRescalerInit(p->scaler_u, uv_in_width, uv_in_height,
|
||||||
buf->u, uv_out_width, uv_out_height, buf->u_stride, 1,
|
buf->u, uv_out_width, uv_out_height, buf->u_stride, 1,
|
||||||
work + work_size) ||
|
work + work_size);
|
||||||
!WebPRescalerInit(p->scaler_v, uv_in_width, uv_in_height,
|
WebPRescalerInit(p->scaler_v, uv_in_width, uv_in_height,
|
||||||
buf->v, uv_out_width, uv_out_height, buf->v_stride, 1,
|
buf->v, uv_out_width, uv_out_height, buf->v_stride, 1,
|
||||||
work + work_size + uv_work_size)) {
|
work + work_size + uv_work_size);
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
p->emit = EmitRescaledYUV;
|
p->emit = EmitRescaledYUV;
|
||||||
|
|
||||||
if (has_alpha) {
|
if (has_alpha) {
|
||||||
if (!WebPRescalerInit(p->scaler_a, io->mb_w, io->mb_h,
|
WebPRescalerInit(p->scaler_a, io->mb_w, io->mb_h,
|
||||||
buf->a, out_width, out_height, buf->a_stride, 1,
|
buf->a, out_width, out_height, buf->a_stride, 1,
|
||||||
work + work_size + 2 * uv_work_size)) {
|
work + work_size + 2 * uv_work_size);
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
p->emit_alpha = EmitRescaledAlphaYUV;
|
p->emit_alpha = EmitRescaledAlphaYUV;
|
||||||
WebPInitAlphaProcessing();
|
WebPInitAlphaProcessing();
|
||||||
}
|
}
|
||||||
@ -362,7 +356,7 @@ static int ExportRGB(WebPDecParams* const p, int y_pos) {
|
|||||||
const WebPYUV444Converter convert =
|
const WebPYUV444Converter convert =
|
||||||
WebPYUV444Converters[p->output->colorspace];
|
WebPYUV444Converters[p->output->colorspace];
|
||||||
const WebPRGBABuffer* const buf = &p->output->u.RGBA;
|
const WebPRGBABuffer* const buf = &p->output->u.RGBA;
|
||||||
uint8_t* dst = buf->rgba + (size_t)y_pos * buf->stride;
|
uint8_t* dst = buf->rgba + y_pos * buf->stride;
|
||||||
int num_lines_out = 0;
|
int num_lines_out = 0;
|
||||||
// For RGB rescaling, because of the YUV420, current scan position
|
// For RGB rescaling, because of the YUV420, current scan position
|
||||||
// U/V can be +1/-1 line from the Y one. Hence the double test.
|
// U/V can be +1/-1 line from the Y one. Hence the double test.
|
||||||
@ -389,15 +383,15 @@ static int EmitRescaledRGB(const VP8Io* const io, WebPDecParams* const p) {
|
|||||||
while (j < mb_h) {
|
while (j < mb_h) {
|
||||||
const int y_lines_in =
|
const int y_lines_in =
|
||||||
WebPRescalerImport(p->scaler_y, mb_h - j,
|
WebPRescalerImport(p->scaler_y, mb_h - j,
|
||||||
io->y + (size_t)j * io->y_stride, io->y_stride);
|
io->y + j * io->y_stride, io->y_stride);
|
||||||
j += y_lines_in;
|
j += y_lines_in;
|
||||||
if (WebPRescaleNeededLines(p->scaler_u, uv_mb_h - uv_j)) {
|
if (WebPRescaleNeededLines(p->scaler_u, uv_mb_h - uv_j)) {
|
||||||
const int u_lines_in = WebPRescalerImport(
|
const int u_lines_in =
|
||||||
p->scaler_u, uv_mb_h - uv_j, io->u + (size_t)uv_j * io->uv_stride,
|
WebPRescalerImport(p->scaler_u, uv_mb_h - uv_j,
|
||||||
io->uv_stride);
|
io->u + uv_j * io->uv_stride, io->uv_stride);
|
||||||
const int v_lines_in = WebPRescalerImport(
|
const int v_lines_in =
|
||||||
p->scaler_v, uv_mb_h - uv_j, io->v + (size_t)uv_j * io->uv_stride,
|
WebPRescalerImport(p->scaler_v, uv_mb_h - uv_j,
|
||||||
io->uv_stride);
|
io->v + uv_j * io->uv_stride, io->uv_stride);
|
||||||
(void)v_lines_in; // remove a gcc warning
|
(void)v_lines_in; // remove a gcc warning
|
||||||
assert(u_lines_in == v_lines_in);
|
assert(u_lines_in == v_lines_in);
|
||||||
uv_j += u_lines_in;
|
uv_j += u_lines_in;
|
||||||
@ -409,7 +403,7 @@ static int EmitRescaledRGB(const VP8Io* const io, WebPDecParams* const p) {
|
|||||||
|
|
||||||
static int ExportAlpha(WebPDecParams* const p, int y_pos, int max_lines_out) {
|
static int ExportAlpha(WebPDecParams* const p, int y_pos, int max_lines_out) {
|
||||||
const WebPRGBABuffer* const buf = &p->output->u.RGBA;
|
const WebPRGBABuffer* const buf = &p->output->u.RGBA;
|
||||||
uint8_t* const base_rgba = buf->rgba + (size_t)y_pos * buf->stride;
|
uint8_t* const base_rgba = buf->rgba + y_pos * buf->stride;
|
||||||
const WEBP_CSP_MODE colorspace = p->output->colorspace;
|
const WEBP_CSP_MODE colorspace = p->output->colorspace;
|
||||||
const int alpha_first =
|
const int alpha_first =
|
||||||
(colorspace == MODE_ARGB || colorspace == MODE_Argb);
|
(colorspace == MODE_ARGB || colorspace == MODE_Argb);
|
||||||
@ -437,7 +431,7 @@ static int ExportAlpha(WebPDecParams* const p, int y_pos, int max_lines_out) {
|
|||||||
static int ExportAlphaRGBA4444(WebPDecParams* const p, int y_pos,
|
static int ExportAlphaRGBA4444(WebPDecParams* const p, int y_pos,
|
||||||
int max_lines_out) {
|
int max_lines_out) {
|
||||||
const WebPRGBABuffer* const buf = &p->output->u.RGBA;
|
const WebPRGBABuffer* const buf = &p->output->u.RGBA;
|
||||||
uint8_t* const base_rgba = buf->rgba + (size_t)y_pos * buf->stride;
|
uint8_t* const base_rgba = buf->rgba + y_pos * buf->stride;
|
||||||
#if (WEBP_SWAP_16BIT_CSP == 1)
|
#if (WEBP_SWAP_16BIT_CSP == 1)
|
||||||
uint8_t* alpha_dst = base_rgba;
|
uint8_t* alpha_dst = base_rgba;
|
||||||
#else
|
#else
|
||||||
@ -476,7 +470,7 @@ static int EmitRescaledAlphaRGB(const VP8Io* const io, WebPDecParams* const p,
|
|||||||
int lines_left = expected_num_out_lines;
|
int lines_left = expected_num_out_lines;
|
||||||
const int y_end = p->last_y + lines_left;
|
const int y_end = p->last_y + lines_left;
|
||||||
while (lines_left > 0) {
|
while (lines_left > 0) {
|
||||||
const int64_t row_offset = (int64_t)scaler->src_y - io->mb_y;
|
const int row_offset = scaler->src_y - io->mb_y;
|
||||||
WebPRescalerImport(scaler, io->mb_h + io->mb_y - scaler->src_y,
|
WebPRescalerImport(scaler, io->mb_h + io->mb_y - scaler->src_y,
|
||||||
io->a + row_offset * io->width, io->width);
|
io->a + row_offset * io->width, io->width);
|
||||||
lines_left -= p->emit_alpha_row(p, y_end - lines_left, lines_left);
|
lines_left -= p->emit_alpha_row(p, y_end - lines_left, lines_left);
|
||||||
@ -491,58 +485,51 @@ static int InitRGBRescaler(const VP8Io* const io, WebPDecParams* const p) {
|
|||||||
const int out_height = io->scaled_height;
|
const int out_height = io->scaled_height;
|
||||||
const int uv_in_width = (io->mb_w + 1) >> 1;
|
const int uv_in_width = (io->mb_w + 1) >> 1;
|
||||||
const int uv_in_height = (io->mb_h + 1) >> 1;
|
const int uv_in_height = (io->mb_h + 1) >> 1;
|
||||||
// scratch memory for one rescaler
|
const size_t work_size = 2 * out_width; // scratch memory for one rescaler
|
||||||
const size_t work_size = 2 * (size_t)out_width;
|
|
||||||
rescaler_t* work; // rescalers work area
|
rescaler_t* work; // rescalers work area
|
||||||
uint8_t* tmp; // tmp storage for scaled YUV444 samples before RGB conversion
|
uint8_t* tmp; // tmp storage for scaled YUV444 samples before RGB conversion
|
||||||
uint64_t tmp_size1, tmp_size2, total_size;
|
size_t tmp_size1, tmp_size2, total_size, rescaler_size;
|
||||||
size_t rescaler_size;
|
|
||||||
WebPRescaler* scalers;
|
WebPRescaler* scalers;
|
||||||
const int num_rescalers = has_alpha ? 4 : 3;
|
const int num_rescalers = has_alpha ? 4 : 3;
|
||||||
|
|
||||||
tmp_size1 = (uint64_t)num_rescalers * work_size;
|
tmp_size1 = 3 * work_size;
|
||||||
tmp_size2 = (uint64_t)num_rescalers * out_width;
|
tmp_size2 = 3 * out_width;
|
||||||
|
if (has_alpha) {
|
||||||
|
tmp_size1 += work_size;
|
||||||
|
tmp_size2 += out_width;
|
||||||
|
}
|
||||||
total_size = tmp_size1 * sizeof(*work) + tmp_size2 * sizeof(*tmp);
|
total_size = tmp_size1 * sizeof(*work) + tmp_size2 * sizeof(*tmp);
|
||||||
rescaler_size = num_rescalers * sizeof(*p->scaler_y) + WEBP_ALIGN_CST;
|
rescaler_size = num_rescalers * sizeof(*p->scaler_y) + WEBP_ALIGN_CST;
|
||||||
total_size += rescaler_size;
|
|
||||||
if (!CheckSizeOverflow(total_size)) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
p->memory = WebPSafeMalloc(1ULL, (size_t)total_size);
|
p->memory = WebPSafeMalloc(1ULL, total_size + rescaler_size);
|
||||||
if (p->memory == NULL) {
|
if (p->memory == NULL) {
|
||||||
return 0; // memory error
|
return 0; // memory error
|
||||||
}
|
}
|
||||||
work = (rescaler_t*)p->memory;
|
work = (rescaler_t*)p->memory;
|
||||||
tmp = (uint8_t*)(work + tmp_size1);
|
tmp = (uint8_t*)(work + tmp_size1);
|
||||||
|
|
||||||
scalers = (WebPRescaler*)WEBP_ALIGN(
|
scalers = (WebPRescaler*)WEBP_ALIGN((const uint8_t*)work + total_size);
|
||||||
(const uint8_t*)work + total_size - rescaler_size);
|
|
||||||
p->scaler_y = &scalers[0];
|
p->scaler_y = &scalers[0];
|
||||||
p->scaler_u = &scalers[1];
|
p->scaler_u = &scalers[1];
|
||||||
p->scaler_v = &scalers[2];
|
p->scaler_v = &scalers[2];
|
||||||
p->scaler_a = has_alpha ? &scalers[3] : NULL;
|
p->scaler_a = has_alpha ? &scalers[3] : NULL;
|
||||||
|
|
||||||
if (!WebPRescalerInit(p->scaler_y, io->mb_w, io->mb_h,
|
WebPRescalerInit(p->scaler_y, io->mb_w, io->mb_h,
|
||||||
tmp + 0 * out_width, out_width, out_height, 0, 1,
|
tmp + 0 * out_width, out_width, out_height, 0, 1,
|
||||||
work + 0 * work_size) ||
|
work + 0 * work_size);
|
||||||
!WebPRescalerInit(p->scaler_u, uv_in_width, uv_in_height,
|
WebPRescalerInit(p->scaler_u, uv_in_width, uv_in_height,
|
||||||
tmp + 1 * out_width, out_width, out_height, 0, 1,
|
tmp + 1 * out_width, out_width, out_height, 0, 1,
|
||||||
work + 1 * work_size) ||
|
work + 1 * work_size);
|
||||||
!WebPRescalerInit(p->scaler_v, uv_in_width, uv_in_height,
|
WebPRescalerInit(p->scaler_v, uv_in_width, uv_in_height,
|
||||||
tmp + 2 * out_width, out_width, out_height, 0, 1,
|
tmp + 2 * out_width, out_width, out_height, 0, 1,
|
||||||
work + 2 * work_size)) {
|
work + 2 * work_size);
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
p->emit = EmitRescaledRGB;
|
p->emit = EmitRescaledRGB;
|
||||||
WebPInitYUV444Converters();
|
WebPInitYUV444Converters();
|
||||||
|
|
||||||
if (has_alpha) {
|
if (has_alpha) {
|
||||||
if (!WebPRescalerInit(p->scaler_a, io->mb_w, io->mb_h,
|
WebPRescalerInit(p->scaler_a, io->mb_w, io->mb_h,
|
||||||
tmp + 3 * out_width, out_width, out_height, 0, 1,
|
tmp + 3 * out_width, out_width, out_height, 0, 1,
|
||||||
work + 3 * work_size)) {
|
work + 3 * work_size);
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
p->emit_alpha = EmitRescaledAlphaRGB;
|
p->emit_alpha = EmitRescaledAlphaRGB;
|
||||||
if (p->output->colorspace == MODE_RGBA_4444 ||
|
if (p->output->colorspace == MODE_RGBA_4444 ||
|
||||||
p->output->colorspace == MODE_rgbA_4444) {
|
p->output->colorspace == MODE_rgbA_4444) {
|
||||||
|
@ -335,7 +335,7 @@ int VP8GetHeaders(VP8Decoder* const dec, VP8Io* const io) {
|
|||||||
io->scaled_width = io->width;
|
io->scaled_width = io->width;
|
||||||
io->scaled_height = io->height;
|
io->scaled_height = io->height;
|
||||||
|
|
||||||
io->mb_w = io->width; // for soundness
|
io->mb_w = io->width; // sanity check
|
||||||
io->mb_h = io->height; // ditto
|
io->mb_h = io->height; // ditto
|
||||||
|
|
||||||
VP8ResetProba(&dec->proba_);
|
VP8ResetProba(&dec->proba_);
|
||||||
@ -494,11 +494,13 @@ static int GetCoeffsAlt(VP8BitReader* const br,
|
|||||||
return 16;
|
return 16;
|
||||||
}
|
}
|
||||||
|
|
||||||
WEBP_DSP_INIT_FUNC(InitGetCoeffs) {
|
static WEBP_TSAN_IGNORE_FUNCTION void InitGetCoeffs(void) {
|
||||||
if (VP8GetCPUInfo != NULL && VP8GetCPUInfo(kSlowSSSE3)) {
|
if (GetCoeffs == NULL) {
|
||||||
GetCoeffs = GetCoeffsAlt;
|
if (VP8GetCPUInfo != NULL && VP8GetCPUInfo(kSlowSSSE3)) {
|
||||||
} else {
|
GetCoeffs = GetCoeffsAlt;
|
||||||
GetCoeffs = GetCoeffsFast;
|
} else {
|
||||||
|
GetCoeffs = GetCoeffsFast;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,8 +31,8 @@ extern "C" {
|
|||||||
|
|
||||||
// version numbers
|
// version numbers
|
||||||
#define DEC_MAJ_VERSION 1
|
#define DEC_MAJ_VERSION 1
|
||||||
#define DEC_MIN_VERSION 2
|
#define DEC_MIN_VERSION 0
|
||||||
#define DEC_REV_VERSION 1
|
#define DEC_REV_VERSION 3
|
||||||
|
|
||||||
// YUV-cache parameters. Cache is 32-bytes wide (= one cacheline).
|
// YUV-cache parameters. Cache is 32-bytes wide (= one cacheline).
|
||||||
// Constraints are: We need to store one 16x16 block of luma samples (y),
|
// Constraints are: We need to store one 16x16 block of luma samples (y),
|
||||||
|
@ -253,11 +253,11 @@ static int ReadHuffmanCodeLengths(
|
|||||||
int symbol;
|
int symbol;
|
||||||
int max_symbol;
|
int max_symbol;
|
||||||
int prev_code_len = DEFAULT_CODE_LENGTH;
|
int prev_code_len = DEFAULT_CODE_LENGTH;
|
||||||
HuffmanCode table[1 << LENGTHS_TABLE_BITS];
|
HuffmanTables tables;
|
||||||
|
|
||||||
if (!VP8LBuildHuffmanTable(table, LENGTHS_TABLE_BITS,
|
if (!VP8LHuffmanTablesAllocate(1 << LENGTHS_TABLE_BITS, &tables) ||
|
||||||
code_length_code_lengths,
|
!VP8LBuildHuffmanTable(&tables, LENGTHS_TABLE_BITS,
|
||||||
NUM_CODE_LENGTH_CODES)) {
|
code_length_code_lengths, NUM_CODE_LENGTH_CODES)) {
|
||||||
goto End;
|
goto End;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -277,7 +277,7 @@ static int ReadHuffmanCodeLengths(
|
|||||||
int code_len;
|
int code_len;
|
||||||
if (max_symbol-- == 0) break;
|
if (max_symbol-- == 0) break;
|
||||||
VP8LFillBitWindow(br);
|
VP8LFillBitWindow(br);
|
||||||
p = &table[VP8LPrefetchBits(br) & LENGTHS_TABLE_MASK];
|
p = &tables.curr_segment->start[VP8LPrefetchBits(br) & LENGTHS_TABLE_MASK];
|
||||||
VP8LSetBitPos(br, br->bit_pos_ + p->bits);
|
VP8LSetBitPos(br, br->bit_pos_ + p->bits);
|
||||||
code_len = p->value;
|
code_len = p->value;
|
||||||
if (code_len < kCodeLengthLiterals) {
|
if (code_len < kCodeLengthLiterals) {
|
||||||
@ -300,6 +300,7 @@ static int ReadHuffmanCodeLengths(
|
|||||||
ok = 1;
|
ok = 1;
|
||||||
|
|
||||||
End:
|
End:
|
||||||
|
VP8LHuffmanTablesDeallocate(&tables);
|
||||||
if (!ok) dec->status_ = VP8_STATUS_BITSTREAM_ERROR;
|
if (!ok) dec->status_ = VP8_STATUS_BITSTREAM_ERROR;
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
@ -307,7 +308,8 @@ static int ReadHuffmanCodeLengths(
|
|||||||
// 'code_lengths' is pre-allocated temporary buffer, used for creating Huffman
|
// 'code_lengths' is pre-allocated temporary buffer, used for creating Huffman
|
||||||
// tree.
|
// tree.
|
||||||
static int ReadHuffmanCode(int alphabet_size, VP8LDecoder* const dec,
|
static int ReadHuffmanCode(int alphabet_size, VP8LDecoder* const dec,
|
||||||
int* const code_lengths, HuffmanCode* const table) {
|
int* const code_lengths,
|
||||||
|
HuffmanTables* const table) {
|
||||||
int ok = 0;
|
int ok = 0;
|
||||||
int size = 0;
|
int size = 0;
|
||||||
VP8LBitReader* const br = &dec->br_;
|
VP8LBitReader* const br = &dec->br_;
|
||||||
@ -362,8 +364,7 @@ static int ReadHuffmanCodes(VP8LDecoder* const dec, int xsize, int ysize,
|
|||||||
VP8LMetadata* const hdr = &dec->hdr_;
|
VP8LMetadata* const hdr = &dec->hdr_;
|
||||||
uint32_t* huffman_image = NULL;
|
uint32_t* huffman_image = NULL;
|
||||||
HTreeGroup* htree_groups = NULL;
|
HTreeGroup* htree_groups = NULL;
|
||||||
HuffmanCode* huffman_tables = NULL;
|
HuffmanTables* huffman_tables = &hdr->huffman_tables_;
|
||||||
HuffmanCode* huffman_table = NULL;
|
|
||||||
int num_htree_groups = 1;
|
int num_htree_groups = 1;
|
||||||
int num_htree_groups_max = 1;
|
int num_htree_groups_max = 1;
|
||||||
int max_alphabet_size = 0;
|
int max_alphabet_size = 0;
|
||||||
@ -372,6 +373,10 @@ static int ReadHuffmanCodes(VP8LDecoder* const dec, int xsize, int ysize,
|
|||||||
int* mapping = NULL;
|
int* mapping = NULL;
|
||||||
int ok = 0;
|
int ok = 0;
|
||||||
|
|
||||||
|
// Check the table has been 0 initialized (through InitMetadata).
|
||||||
|
assert(huffman_tables->root.start == NULL);
|
||||||
|
assert(huffman_tables->curr_segment == NULL);
|
||||||
|
|
||||||
if (allow_recursion && VP8LReadBits(br, 1)) {
|
if (allow_recursion && VP8LReadBits(br, 1)) {
|
||||||
// use meta Huffman codes.
|
// use meta Huffman codes.
|
||||||
const int huffman_precision = VP8LReadBits(br, 3) + 2;
|
const int huffman_precision = VP8LReadBits(br, 3) + 2;
|
||||||
@ -434,16 +439,15 @@ static int ReadHuffmanCodes(VP8LDecoder* const dec, int xsize, int ysize,
|
|||||||
|
|
||||||
code_lengths = (int*)WebPSafeCalloc((uint64_t)max_alphabet_size,
|
code_lengths = (int*)WebPSafeCalloc((uint64_t)max_alphabet_size,
|
||||||
sizeof(*code_lengths));
|
sizeof(*code_lengths));
|
||||||
huffman_tables = (HuffmanCode*)WebPSafeMalloc(num_htree_groups * table_size,
|
|
||||||
sizeof(*huffman_tables));
|
|
||||||
htree_groups = VP8LHtreeGroupsNew(num_htree_groups);
|
htree_groups = VP8LHtreeGroupsNew(num_htree_groups);
|
||||||
|
|
||||||
if (htree_groups == NULL || code_lengths == NULL || huffman_tables == NULL) {
|
if (htree_groups == NULL || code_lengths == NULL ||
|
||||||
|
!VP8LHuffmanTablesAllocate(num_htree_groups * table_size,
|
||||||
|
huffman_tables)) {
|
||||||
dec->status_ = VP8_STATUS_OUT_OF_MEMORY;
|
dec->status_ = VP8_STATUS_OUT_OF_MEMORY;
|
||||||
goto Error;
|
goto Error;
|
||||||
}
|
}
|
||||||
|
|
||||||
huffman_table = huffman_tables;
|
|
||||||
for (i = 0; i < num_htree_groups_max; ++i) {
|
for (i = 0; i < num_htree_groups_max; ++i) {
|
||||||
// If the index "i" is unused in the Huffman image, just make sure the
|
// If the index "i" is unused in the Huffman image, just make sure the
|
||||||
// coefficients are valid but do not store them.
|
// coefficients are valid but do not store them.
|
||||||
@ -468,19 +472,20 @@ static int ReadHuffmanCodes(VP8LDecoder* const dec, int xsize, int ysize,
|
|||||||
int max_bits = 0;
|
int max_bits = 0;
|
||||||
for (j = 0; j < HUFFMAN_CODES_PER_META_CODE; ++j) {
|
for (j = 0; j < HUFFMAN_CODES_PER_META_CODE; ++j) {
|
||||||
int alphabet_size = kAlphabetSize[j];
|
int alphabet_size = kAlphabetSize[j];
|
||||||
htrees[j] = huffman_table;
|
|
||||||
if (j == 0 && color_cache_bits > 0) {
|
if (j == 0 && color_cache_bits > 0) {
|
||||||
alphabet_size += (1 << color_cache_bits);
|
alphabet_size += (1 << color_cache_bits);
|
||||||
}
|
}
|
||||||
size = ReadHuffmanCode(alphabet_size, dec, code_lengths, huffman_table);
|
size =
|
||||||
|
ReadHuffmanCode(alphabet_size, dec, code_lengths, huffman_tables);
|
||||||
|
htrees[j] = huffman_tables->curr_segment->curr_table;
|
||||||
if (size == 0) {
|
if (size == 0) {
|
||||||
goto Error;
|
goto Error;
|
||||||
}
|
}
|
||||||
if (is_trivial_literal && kLiteralMap[j] == 1) {
|
if (is_trivial_literal && kLiteralMap[j] == 1) {
|
||||||
is_trivial_literal = (huffman_table->bits == 0);
|
is_trivial_literal = (htrees[j]->bits == 0);
|
||||||
}
|
}
|
||||||
total_size += huffman_table->bits;
|
total_size += htrees[j]->bits;
|
||||||
huffman_table += size;
|
huffman_tables->curr_segment->curr_table += size;
|
||||||
if (j <= ALPHA) {
|
if (j <= ALPHA) {
|
||||||
int local_max_bits = code_lengths[0];
|
int local_max_bits = code_lengths[0];
|
||||||
int k;
|
int k;
|
||||||
@ -515,14 +520,13 @@ static int ReadHuffmanCodes(VP8LDecoder* const dec, int xsize, int ysize,
|
|||||||
hdr->huffman_image_ = huffman_image;
|
hdr->huffman_image_ = huffman_image;
|
||||||
hdr->num_htree_groups_ = num_htree_groups;
|
hdr->num_htree_groups_ = num_htree_groups;
|
||||||
hdr->htree_groups_ = htree_groups;
|
hdr->htree_groups_ = htree_groups;
|
||||||
hdr->huffman_tables_ = huffman_tables;
|
|
||||||
|
|
||||||
Error:
|
Error:
|
||||||
WebPSafeFree(code_lengths);
|
WebPSafeFree(code_lengths);
|
||||||
WebPSafeFree(mapping);
|
WebPSafeFree(mapping);
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
WebPSafeFree(huffman_image);
|
WebPSafeFree(huffman_image);
|
||||||
WebPSafeFree(huffman_tables);
|
VP8LHuffmanTablesDeallocate(huffman_tables);
|
||||||
VP8LHtreeGroupsFree(htree_groups);
|
VP8LHtreeGroupsFree(htree_groups);
|
||||||
}
|
}
|
||||||
return ok;
|
return ok;
|
||||||
@ -559,11 +563,8 @@ static int AllocateAndInitRescaler(VP8LDecoder* const dec, VP8Io* const io) {
|
|||||||
memory += work_size * sizeof(*work);
|
memory += work_size * sizeof(*work);
|
||||||
scaled_data = (uint32_t*)memory;
|
scaled_data = (uint32_t*)memory;
|
||||||
|
|
||||||
if (!WebPRescalerInit(dec->rescaler, in_width, in_height,
|
WebPRescalerInit(dec->rescaler, in_width, in_height, (uint8_t*)scaled_data,
|
||||||
(uint8_t*)scaled_data, out_width, out_height,
|
out_width, out_height, 0, num_channels, work);
|
||||||
0, num_channels, work)) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
#endif // WEBP_REDUCE_SIZE
|
#endif // WEBP_REDUCE_SIZE
|
||||||
@ -577,14 +578,13 @@ static int AllocateAndInitRescaler(VP8LDecoder* const dec, VP8Io* const io) {
|
|||||||
static int Export(WebPRescaler* const rescaler, WEBP_CSP_MODE colorspace,
|
static int Export(WebPRescaler* const rescaler, WEBP_CSP_MODE colorspace,
|
||||||
int rgba_stride, uint8_t* const rgba) {
|
int rgba_stride, uint8_t* const rgba) {
|
||||||
uint32_t* const src = (uint32_t*)rescaler->dst;
|
uint32_t* const src = (uint32_t*)rescaler->dst;
|
||||||
uint8_t* dst = rgba;
|
|
||||||
const int dst_width = rescaler->dst_width;
|
const int dst_width = rescaler->dst_width;
|
||||||
int num_lines_out = 0;
|
int num_lines_out = 0;
|
||||||
while (WebPRescalerHasPendingOutput(rescaler)) {
|
while (WebPRescalerHasPendingOutput(rescaler)) {
|
||||||
|
uint8_t* const dst = rgba + num_lines_out * rgba_stride;
|
||||||
WebPRescalerExportRow(rescaler);
|
WebPRescalerExportRow(rescaler);
|
||||||
WebPMultARGBRow(src, dst_width, 1);
|
WebPMultARGBRow(src, dst_width, 1);
|
||||||
VP8LConvertFromBGRA(src, dst_width, colorspace, dst);
|
VP8LConvertFromBGRA(src, dst_width, colorspace, dst);
|
||||||
dst += rgba_stride;
|
|
||||||
++num_lines_out;
|
++num_lines_out;
|
||||||
}
|
}
|
||||||
return num_lines_out;
|
return num_lines_out;
|
||||||
@ -598,8 +598,8 @@ static int EmitRescaledRowsRGBA(const VP8LDecoder* const dec,
|
|||||||
int num_lines_in = 0;
|
int num_lines_in = 0;
|
||||||
int num_lines_out = 0;
|
int num_lines_out = 0;
|
||||||
while (num_lines_in < mb_h) {
|
while (num_lines_in < mb_h) {
|
||||||
uint8_t* const row_in = in + (uint64_t)num_lines_in * in_stride;
|
uint8_t* const row_in = in + num_lines_in * in_stride;
|
||||||
uint8_t* const row_out = out + (uint64_t)num_lines_out * out_stride;
|
uint8_t* const row_out = out + num_lines_out * out_stride;
|
||||||
const int lines_left = mb_h - num_lines_in;
|
const int lines_left = mb_h - num_lines_in;
|
||||||
const int needed_lines = WebPRescaleNeededLines(dec->rescaler, lines_left);
|
const int needed_lines = WebPRescaleNeededLines(dec->rescaler, lines_left);
|
||||||
int lines_imported;
|
int lines_imported;
|
||||||
@ -800,8 +800,7 @@ static void ProcessRows(VP8LDecoder* const dec, int row) {
|
|||||||
const WebPDecBuffer* const output = dec->output_;
|
const WebPDecBuffer* const output = dec->output_;
|
||||||
if (WebPIsRGBMode(output->colorspace)) { // convert to RGBA
|
if (WebPIsRGBMode(output->colorspace)) { // convert to RGBA
|
||||||
const WebPRGBABuffer* const buf = &output->u.RGBA;
|
const WebPRGBABuffer* const buf = &output->u.RGBA;
|
||||||
uint8_t* const rgba =
|
uint8_t* const rgba = buf->rgba + dec->last_out_row_ * buf->stride;
|
||||||
buf->rgba + (int64_t)dec->last_out_row_ * buf->stride;
|
|
||||||
const int num_rows_out =
|
const int num_rows_out =
|
||||||
#if !defined(WEBP_REDUCE_SIZE)
|
#if !defined(WEBP_REDUCE_SIZE)
|
||||||
io->use_scaling ?
|
io->use_scaling ?
|
||||||
@ -952,6 +951,7 @@ static WEBP_INLINE void CopyBlock8b(uint8_t* const dst, int dist, int length) {
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
goto Copy;
|
goto Copy;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
CopySmallPattern8b(src, dst, length, pattern);
|
CopySmallPattern8b(src, dst, length, pattern);
|
||||||
return;
|
return;
|
||||||
@ -1358,7 +1358,7 @@ static void ClearMetadata(VP8LMetadata* const hdr) {
|
|||||||
assert(hdr != NULL);
|
assert(hdr != NULL);
|
||||||
|
|
||||||
WebPSafeFree(hdr->huffman_image_);
|
WebPSafeFree(hdr->huffman_image_);
|
||||||
WebPSafeFree(hdr->huffman_tables_);
|
VP8LHuffmanTablesDeallocate(&hdr->huffman_tables_);
|
||||||
VP8LHtreeGroupsFree(hdr->htree_groups_);
|
VP8LHtreeGroupsFree(hdr->htree_groups_);
|
||||||
VP8LColorCacheClear(&hdr->color_cache_);
|
VP8LColorCacheClear(&hdr->color_cache_);
|
||||||
VP8LColorCacheClear(&hdr->saved_color_cache_);
|
VP8LColorCacheClear(&hdr->saved_color_cache_);
|
||||||
@ -1519,7 +1519,7 @@ static int AllocateInternalBuffers32b(VP8LDecoder* const dec, int final_width) {
|
|||||||
assert(dec->width_ <= final_width);
|
assert(dec->width_ <= final_width);
|
||||||
dec->pixels_ = (uint32_t*)WebPSafeMalloc(total_num_pixels, sizeof(uint32_t));
|
dec->pixels_ = (uint32_t*)WebPSafeMalloc(total_num_pixels, sizeof(uint32_t));
|
||||||
if (dec->pixels_ == NULL) {
|
if (dec->pixels_ == NULL) {
|
||||||
dec->argb_cache_ = NULL; // for soundness
|
dec->argb_cache_ = NULL; // for sanity check
|
||||||
dec->status_ = VP8_STATUS_OUT_OF_MEMORY;
|
dec->status_ = VP8_STATUS_OUT_OF_MEMORY;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1529,7 +1529,7 @@ static int AllocateInternalBuffers32b(VP8LDecoder* const dec, int final_width) {
|
|||||||
|
|
||||||
static int AllocateInternalBuffers8b(VP8LDecoder* const dec) {
|
static int AllocateInternalBuffers8b(VP8LDecoder* const dec) {
|
||||||
const uint64_t total_num_pixels = (uint64_t)dec->width_ * dec->height_;
|
const uint64_t total_num_pixels = (uint64_t)dec->width_ * dec->height_;
|
||||||
dec->argb_cache_ = NULL; // for soundness
|
dec->argb_cache_ = NULL; // for sanity check
|
||||||
dec->pixels_ = (uint32_t*)WebPSafeMalloc(total_num_pixels, sizeof(uint8_t));
|
dec->pixels_ = (uint32_t*)WebPSafeMalloc(total_num_pixels, sizeof(uint8_t));
|
||||||
if (dec->pixels_ == NULL) {
|
if (dec->pixels_ == NULL) {
|
||||||
dec->status_ = VP8_STATUS_OUT_OF_MEMORY;
|
dec->status_ = VP8_STATUS_OUT_OF_MEMORY;
|
||||||
@ -1671,9 +1671,10 @@ int VP8LDecodeImage(VP8LDecoder* const dec) {
|
|||||||
VP8Io* io = NULL;
|
VP8Io* io = NULL;
|
||||||
WebPDecParams* params = NULL;
|
WebPDecParams* params = NULL;
|
||||||
|
|
||||||
|
// Sanity checks.
|
||||||
if (dec == NULL) return 0;
|
if (dec == NULL) return 0;
|
||||||
|
|
||||||
assert(dec->hdr_.huffman_tables_ != NULL);
|
assert(dec->hdr_.huffman_tables_.root.start != NULL);
|
||||||
assert(dec->hdr_.htree_groups_ != NULL);
|
assert(dec->hdr_.htree_groups_ != NULL);
|
||||||
assert(dec->hdr_.num_htree_groups_ > 0);
|
assert(dec->hdr_.num_htree_groups_ > 0);
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ struct VP8LTransform {
|
|||||||
int bits_; // subsampling bits defining transform window.
|
int bits_; // subsampling bits defining transform window.
|
||||||
int xsize_; // transform window X index.
|
int xsize_; // transform window X index.
|
||||||
int ysize_; // transform window Y index.
|
int ysize_; // transform window Y index.
|
||||||
uint32_t* data_; // transform data.
|
uint32_t *data_; // transform data.
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -48,23 +48,23 @@ typedef struct {
|
|||||||
int huffman_mask_;
|
int huffman_mask_;
|
||||||
int huffman_subsample_bits_;
|
int huffman_subsample_bits_;
|
||||||
int huffman_xsize_;
|
int huffman_xsize_;
|
||||||
uint32_t* huffman_image_;
|
uint32_t *huffman_image_;
|
||||||
int num_htree_groups_;
|
int num_htree_groups_;
|
||||||
HTreeGroup* htree_groups_;
|
HTreeGroup *htree_groups_;
|
||||||
HuffmanCode* huffman_tables_;
|
HuffmanTables huffman_tables_;
|
||||||
} VP8LMetadata;
|
} VP8LMetadata;
|
||||||
|
|
||||||
typedef struct VP8LDecoder VP8LDecoder;
|
typedef struct VP8LDecoder VP8LDecoder;
|
||||||
struct VP8LDecoder {
|
struct VP8LDecoder {
|
||||||
VP8StatusCode status_;
|
VP8StatusCode status_;
|
||||||
VP8LDecodeState state_;
|
VP8LDecodeState state_;
|
||||||
VP8Io* io_;
|
VP8Io *io_;
|
||||||
|
|
||||||
const WebPDecBuffer* output_; // shortcut to io->opaque->output
|
const WebPDecBuffer *output_; // shortcut to io->opaque->output
|
||||||
|
|
||||||
uint32_t* pixels_; // Internal data: either uint8_t* for alpha
|
uint32_t *pixels_; // Internal data: either uint8_t* for alpha
|
||||||
// or uint32_t* for BGRA.
|
// or uint32_t* for BGRA.
|
||||||
uint32_t* argb_cache_; // Scratch buffer for temporary BGRA storage.
|
uint32_t *argb_cache_; // Scratch buffer for temporary BGRA storage.
|
||||||
|
|
||||||
VP8LBitReader br_;
|
VP8LBitReader br_;
|
||||||
int incremental_; // if true, incremental decoding is expected
|
int incremental_; // if true, incremental decoding is expected
|
||||||
@ -86,8 +86,8 @@ struct VP8LDecoder {
|
|||||||
// or'd bitset storing the transforms types.
|
// or'd bitset storing the transforms types.
|
||||||
uint32_t transforms_seen_;
|
uint32_t transforms_seen_;
|
||||||
|
|
||||||
uint8_t* rescaler_memory; // Working memory for rescaling work.
|
uint8_t *rescaler_memory; // Working memory for rescaling work.
|
||||||
WebPRescaler* rescaler; // Common rescaler for all channels.
|
WebPRescaler *rescaler; // Common rescaler for all channels.
|
||||||
};
|
};
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
@ -785,13 +785,6 @@ VP8StatusCode WebPDecode(const uint8_t* data, size_t data_size,
|
|||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Cropping and rescaling.
|
// Cropping and rescaling.
|
||||||
|
|
||||||
int WebPCheckCropDimensions(int image_width, int image_height,
|
|
||||||
int x, int y, int w, int h) {
|
|
||||||
return !(x < 0 || y < 0 || w <= 0 || h <= 0 ||
|
|
||||||
x >= image_width || w > image_width || w > image_width - x ||
|
|
||||||
y >= image_height || h > image_height || h > image_height - y);
|
|
||||||
}
|
|
||||||
|
|
||||||
int WebPIoInitFromOptions(const WebPDecoderOptions* const options,
|
int WebPIoInitFromOptions(const WebPDecoderOptions* const options,
|
||||||
VP8Io* const io, WEBP_CSP_MODE src_colorspace) {
|
VP8Io* const io, WEBP_CSP_MODE src_colorspace) {
|
||||||
const int W = io->width;
|
const int W = io->width;
|
||||||
@ -799,7 +792,7 @@ int WebPIoInitFromOptions(const WebPDecoderOptions* const options,
|
|||||||
int x = 0, y = 0, w = W, h = H;
|
int x = 0, y = 0, w = W, h = H;
|
||||||
|
|
||||||
// Cropping
|
// Cropping
|
||||||
io->use_cropping = (options != NULL) && options->use_cropping;
|
io->use_cropping = (options != NULL) && (options->use_cropping > 0);
|
||||||
if (io->use_cropping) {
|
if (io->use_cropping) {
|
||||||
w = options->crop_width;
|
w = options->crop_width;
|
||||||
h = options->crop_height;
|
h = options->crop_height;
|
||||||
@ -809,7 +802,7 @@ int WebPIoInitFromOptions(const WebPDecoderOptions* const options,
|
|||||||
x &= ~1;
|
x &= ~1;
|
||||||
y &= ~1;
|
y &= ~1;
|
||||||
}
|
}
|
||||||
if (!WebPCheckCropDimensions(W, H, x, y, w, h)) {
|
if (x < 0 || y < 0 || w <= 0 || h <= 0 || x + w > W || y + h > H) {
|
||||||
return 0; // out of frame boundary error
|
return 0; // out of frame boundary error
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -821,7 +814,7 @@ int WebPIoInitFromOptions(const WebPDecoderOptions* const options,
|
|||||||
io->mb_h = h;
|
io->mb_h = h;
|
||||||
|
|
||||||
// Scaling
|
// Scaling
|
||||||
io->use_scaling = (options != NULL) && options->use_scaling;
|
io->use_scaling = (options != NULL) && (options->use_scaling > 0);
|
||||||
if (io->use_scaling) {
|
if (io->use_scaling) {
|
||||||
int scaled_width = options->scaled_width;
|
int scaled_width = options->scaled_width;
|
||||||
int scaled_height = options->scaled_height;
|
int scaled_height = options->scaled_height;
|
||||||
@ -842,8 +835,8 @@ int WebPIoInitFromOptions(const WebPDecoderOptions* const options,
|
|||||||
|
|
||||||
if (io->use_scaling) {
|
if (io->use_scaling) {
|
||||||
// disable filter (only for large downscaling ratio).
|
// disable filter (only for large downscaling ratio).
|
||||||
io->bypass_filtering |= (io->scaled_width < W * 3 / 4) &&
|
io->bypass_filtering = (io->scaled_width < W * 3 / 4) &&
|
||||||
(io->scaled_height < H * 3 / 4);
|
(io->scaled_height < H * 3 / 4);
|
||||||
io->fancy_upsampling = 0;
|
io->fancy_upsampling = 0;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -77,10 +77,6 @@ VP8StatusCode WebPParseHeaders(WebPHeaderStructure* const headers);
|
|||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Misc utils
|
// Misc utils
|
||||||
|
|
||||||
// Returns true if crop dimensions are within image bounds.
|
|
||||||
int WebPCheckCropDimensions(int image_width, int image_height,
|
|
||||||
int x, int y, int w, int h);
|
|
||||||
|
|
||||||
// Initializes VP8Io with custom setup, io and teardown functions. The default
|
// Initializes VP8Io with custom setup, io and teardown functions. The default
|
||||||
// hooks will use the supplied 'params' as io->opaque handle.
|
// hooks will use the supplied 'params' as io->opaque handle.
|
||||||
void WebPInitCustomIo(WebPDecParams* const params, VP8Io* const io);
|
void WebPInitCustomIo(WebPDecParams* const params, VP8Io* const io);
|
||||||
|
@ -13,6 +13,6 @@ noinst_HEADERS =
|
|||||||
noinst_HEADERS += ../webp/format_constants.h
|
noinst_HEADERS += ../webp/format_constants.h
|
||||||
|
|
||||||
libwebpdemux_la_LIBADD = ../libwebp.la
|
libwebpdemux_la_LIBADD = ../libwebp.la
|
||||||
libwebpdemux_la_LDFLAGS = -no-undefined -version-info 2:8:0
|
libwebpdemux_la_LDFLAGS = -no-undefined -version-info 2:6:0
|
||||||
libwebpdemuxincludedir = $(includedir)/webp
|
libwebpdemuxincludedir = $(includedir)/webp
|
||||||
pkgconfig_DATA = libwebpdemux.pc
|
pkgconfig_DATA = libwebpdemux.pc
|
||||||
|
@ -87,19 +87,11 @@ WebPAnimDecoder* WebPAnimDecoderNewInternal(
|
|||||||
int abi_version) {
|
int abi_version) {
|
||||||
WebPAnimDecoderOptions options;
|
WebPAnimDecoderOptions options;
|
||||||
WebPAnimDecoder* dec = NULL;
|
WebPAnimDecoder* dec = NULL;
|
||||||
WebPBitstreamFeatures features;
|
|
||||||
if (webp_data == NULL ||
|
if (webp_data == NULL ||
|
||||||
WEBP_ABI_IS_INCOMPATIBLE(abi_version, WEBP_DEMUX_ABI_VERSION)) {
|
WEBP_ABI_IS_INCOMPATIBLE(abi_version, WEBP_DEMUX_ABI_VERSION)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate the bitstream before doing expensive allocations. The demuxer may
|
|
||||||
// be more tolerant than the decoder.
|
|
||||||
if (WebPGetFeatures(webp_data->bytes, webp_data->size, &features) !=
|
|
||||||
VP8_STATUS_OK) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Note: calloc() so that the pointer members are initialized to NULL.
|
// Note: calloc() so that the pointer members are initialized to NULL.
|
||||||
dec = (WebPAnimDecoder*)WebPSafeCalloc(1ULL, sizeof(*dec));
|
dec = (WebPAnimDecoder*)WebPSafeCalloc(1ULL, sizeof(*dec));
|
||||||
if (dec == NULL) goto Error;
|
if (dec == NULL) goto Error;
|
||||||
@ -153,7 +145,7 @@ static int ZeroFillCanvas(uint8_t* buf, uint32_t canvas_width,
|
|||||||
uint32_t canvas_height) {
|
uint32_t canvas_height) {
|
||||||
const uint64_t size =
|
const uint64_t size =
|
||||||
(uint64_t)canvas_width * canvas_height * NUM_CHANNELS * sizeof(*buf);
|
(uint64_t)canvas_width * canvas_height * NUM_CHANNELS * sizeof(*buf);
|
||||||
if (!CheckSizeOverflow(size)) return 0;
|
if (size != (size_t)size) return 0;
|
||||||
memset(buf, 0, (size_t)size);
|
memset(buf, 0, (size_t)size);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -174,7 +166,7 @@ static void ZeroFillFrameRect(uint8_t* buf, int buf_stride, int x_offset,
|
|||||||
static int CopyCanvas(const uint8_t* src, uint8_t* dst,
|
static int CopyCanvas(const uint8_t* src, uint8_t* dst,
|
||||||
uint32_t width, uint32_t height) {
|
uint32_t width, uint32_t height) {
|
||||||
const uint64_t size = (uint64_t)width * height * NUM_CHANNELS;
|
const uint64_t size = (uint64_t)width * height * NUM_CHANNELS;
|
||||||
if (!CheckSizeOverflow(size)) return 0;
|
if (size != (size_t)size) return 0;
|
||||||
assert(src != NULL && dst != NULL);
|
assert(src != NULL && dst != NULL);
|
||||||
memcpy(dst, src, (size_t)size);
|
memcpy(dst, src, (size_t)size);
|
||||||
return 1;
|
return 1;
|
||||||
@ -354,15 +346,12 @@ int WebPAnimDecoderGetNext(WebPAnimDecoder* dec,
|
|||||||
{
|
{
|
||||||
const uint8_t* in = iter.fragment.bytes;
|
const uint8_t* in = iter.fragment.bytes;
|
||||||
const size_t in_size = iter.fragment.size;
|
const size_t in_size = iter.fragment.size;
|
||||||
const uint32_t stride = width * NUM_CHANNELS; // at most 25 + 2 bits
|
const size_t out_offset =
|
||||||
const uint64_t out_offset = (uint64_t)iter.y_offset * stride +
|
(iter.y_offset * width + iter.x_offset) * NUM_CHANNELS;
|
||||||
(uint64_t)iter.x_offset * NUM_CHANNELS; // 53b
|
|
||||||
const uint64_t size = (uint64_t)iter.height * stride; // at most 25 + 27b
|
|
||||||
WebPDecoderConfig* const config = &dec->config_;
|
WebPDecoderConfig* const config = &dec->config_;
|
||||||
WebPRGBABuffer* const buf = &config->output.u.RGBA;
|
WebPRGBABuffer* const buf = &config->output.u.RGBA;
|
||||||
if ((size_t)size != size) goto Error;
|
buf->stride = NUM_CHANNELS * width;
|
||||||
buf->stride = (int)stride;
|
buf->size = buf->stride * iter.height;
|
||||||
buf->size = (size_t)size;
|
|
||||||
buf->rgba = dec->curr_frame_ + out_offset;
|
buf->rgba = dec->curr_frame_ + out_offset;
|
||||||
|
|
||||||
if (WebPDecode(in, in_size, config) != VP8_STATUS_OK) {
|
if (WebPDecode(in, in_size, config) != VP8_STATUS_OK) {
|
||||||
|
@ -24,8 +24,8 @@
|
|||||||
#include "src/webp/format_constants.h"
|
#include "src/webp/format_constants.h"
|
||||||
|
|
||||||
#define DMUX_MAJ_VERSION 1
|
#define DMUX_MAJ_VERSION 1
|
||||||
#define DMUX_MIN_VERSION 2
|
#define DMUX_MIN_VERSION 0
|
||||||
#define DMUX_REV_VERSION 1
|
#define DMUX_REV_VERSION 3
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
size_t start_; // start location of the data
|
size_t start_; // start location of the data
|
||||||
@ -221,16 +221,12 @@ static ParseStatus StoreFrame(int frame_num, uint32_t min_size,
|
|||||||
const size_t chunk_start_offset = mem->start_;
|
const size_t chunk_start_offset = mem->start_;
|
||||||
const uint32_t fourcc = ReadLE32(mem);
|
const uint32_t fourcc = ReadLE32(mem);
|
||||||
const uint32_t payload_size = ReadLE32(mem);
|
const uint32_t payload_size = ReadLE32(mem);
|
||||||
uint32_t payload_size_padded;
|
const uint32_t payload_size_padded = payload_size + (payload_size & 1);
|
||||||
size_t payload_available;
|
const size_t payload_available = (payload_size_padded > MemDataSize(mem))
|
||||||
size_t chunk_size;
|
? MemDataSize(mem) : payload_size_padded;
|
||||||
|
const size_t chunk_size = CHUNK_HEADER_SIZE + payload_available;
|
||||||
|
|
||||||
if (payload_size > MAX_CHUNK_PAYLOAD) return PARSE_ERROR;
|
if (payload_size > MAX_CHUNK_PAYLOAD) return PARSE_ERROR;
|
||||||
|
|
||||||
payload_size_padded = payload_size + (payload_size & 1);
|
|
||||||
payload_available = (payload_size_padded > MemDataSize(mem))
|
|
||||||
? MemDataSize(mem) : payload_size_padded;
|
|
||||||
chunk_size = CHUNK_HEADER_SIZE + payload_available;
|
|
||||||
if (SizeIsInvalid(mem, payload_size_padded)) return PARSE_ERROR;
|
if (SizeIsInvalid(mem, payload_size_padded)) return PARSE_ERROR;
|
||||||
if (payload_size_padded > MemDataSize(mem)) status = PARSE_NEED_MORE_DATA;
|
if (payload_size_padded > MemDataSize(mem)) status = PARSE_NEED_MORE_DATA;
|
||||||
|
|
||||||
@ -316,7 +312,6 @@ static ParseStatus ParseAnimationFrame(
|
|||||||
int bits;
|
int bits;
|
||||||
MemBuffer* const mem = &dmux->mem_;
|
MemBuffer* const mem = &dmux->mem_;
|
||||||
Frame* frame;
|
Frame* frame;
|
||||||
size_t start_offset;
|
|
||||||
ParseStatus status =
|
ParseStatus status =
|
||||||
NewFrame(mem, ANMF_CHUNK_SIZE, frame_chunk_size, &frame);
|
NewFrame(mem, ANMF_CHUNK_SIZE, frame_chunk_size, &frame);
|
||||||
if (status != PARSE_OK) return status;
|
if (status != PARSE_OK) return status;
|
||||||
@ -337,11 +332,7 @@ static ParseStatus ParseAnimationFrame(
|
|||||||
|
|
||||||
// Store a frame only if the animation flag is set there is some data for
|
// Store a frame only if the animation flag is set there is some data for
|
||||||
// this frame is available.
|
// this frame is available.
|
||||||
start_offset = mem->start_;
|
|
||||||
status = StoreFrame(dmux->num_frames_ + 1, anmf_payload_size, mem, frame);
|
status = StoreFrame(dmux->num_frames_ + 1, anmf_payload_size, mem, frame);
|
||||||
if (status != PARSE_ERROR && mem->start_ - start_offset > anmf_payload_size) {
|
|
||||||
status = PARSE_ERROR;
|
|
||||||
}
|
|
||||||
if (status != PARSE_ERROR && is_animation && frame->frame_num_ > 0) {
|
if (status != PARSE_ERROR && is_animation && frame->frame_num_ > 0) {
|
||||||
added_frame = AddFrame(dmux, frame);
|
added_frame = AddFrame(dmux, frame);
|
||||||
if (added_frame) {
|
if (added_frame) {
|
||||||
@ -455,11 +446,9 @@ static ParseStatus ParseVP8XChunks(WebPDemuxer* const dmux) {
|
|||||||
const size_t chunk_start_offset = mem->start_;
|
const size_t chunk_start_offset = mem->start_;
|
||||||
const uint32_t fourcc = ReadLE32(mem);
|
const uint32_t fourcc = ReadLE32(mem);
|
||||||
const uint32_t chunk_size = ReadLE32(mem);
|
const uint32_t chunk_size = ReadLE32(mem);
|
||||||
uint32_t chunk_size_padded;
|
const uint32_t chunk_size_padded = chunk_size + (chunk_size & 1);
|
||||||
|
|
||||||
if (chunk_size > MAX_CHUNK_PAYLOAD) return PARSE_ERROR;
|
if (chunk_size > MAX_CHUNK_PAYLOAD) return PARSE_ERROR;
|
||||||
|
|
||||||
chunk_size_padded = chunk_size + (chunk_size & 1);
|
|
||||||
if (SizeIsInvalid(mem, chunk_size_padded)) return PARSE_ERROR;
|
if (SizeIsInvalid(mem, chunk_size_padded)) return PARSE_ERROR;
|
||||||
|
|
||||||
switch (fourcc) {
|
switch (fourcc) {
|
||||||
|
@ -6,8 +6,8 @@
|
|||||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||||
|
|
||||||
VS_VERSION_INFO VERSIONINFO
|
VS_VERSION_INFO VERSIONINFO
|
||||||
FILEVERSION 1,0,2,1
|
FILEVERSION 1,0,0,3
|
||||||
PRODUCTVERSION 1,0,2,1
|
PRODUCTVERSION 1,0,0,3
|
||||||
FILEFLAGSMASK 0x3fL
|
FILEFLAGSMASK 0x3fL
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
FILEFLAGS 0x1L
|
FILEFLAGS 0x1L
|
||||||
@ -24,12 +24,12 @@ BEGIN
|
|||||||
BEGIN
|
BEGIN
|
||||||
VALUE "CompanyName", "Google, Inc."
|
VALUE "CompanyName", "Google, Inc."
|
||||||
VALUE "FileDescription", "libwebpdemux DLL"
|
VALUE "FileDescription", "libwebpdemux DLL"
|
||||||
VALUE "FileVersion", "1.2.1"
|
VALUE "FileVersion", "1.0.3"
|
||||||
VALUE "InternalName", "libwebpdemux.dll"
|
VALUE "InternalName", "libwebpdemux.dll"
|
||||||
VALUE "LegalCopyright", "Copyright (C) 2021"
|
VALUE "LegalCopyright", "Copyright (C) 2019"
|
||||||
VALUE "OriginalFilename", "libwebpdemux.dll"
|
VALUE "OriginalFilename", "libwebpdemux.dll"
|
||||||
VALUE "ProductName", "WebP Image Demuxer"
|
VALUE "ProductName", "WebP Image Demuxer"
|
||||||
VALUE "ProductVersion", "1.2.1"
|
VALUE "ProductVersion", "1.0.3"
|
||||||
END
|
END
|
||||||
END
|
END
|
||||||
BLOCK "VarFileInfo"
|
BLOCK "VarFileInfo"
|
||||||
|
@ -13,7 +13,6 @@ noinst_LTLIBRARIES += libwebpdsp_mips32.la
|
|||||||
noinst_LTLIBRARIES += libwebpdspdecode_mips32.la
|
noinst_LTLIBRARIES += libwebpdspdecode_mips32.la
|
||||||
noinst_LTLIBRARIES += libwebpdsp_mips_dsp_r2.la
|
noinst_LTLIBRARIES += libwebpdsp_mips_dsp_r2.la
|
||||||
noinst_LTLIBRARIES += libwebpdspdecode_mips_dsp_r2.la
|
noinst_LTLIBRARIES += libwebpdspdecode_mips_dsp_r2.la
|
||||||
noinst_LTLIBRARIES += libwebpdspdecode_wasm.la
|
|
||||||
|
|
||||||
if BUILD_LIBWEBPDECODER
|
if BUILD_LIBWEBPDECODER
|
||||||
noinst_LTLIBRARIES += libwebpdspdecode.la
|
noinst_LTLIBRARIES += libwebpdspdecode.la
|
||||||
@ -47,7 +46,6 @@ ENC_SOURCES += ssim.c
|
|||||||
libwebpdspdecode_sse41_la_SOURCES =
|
libwebpdspdecode_sse41_la_SOURCES =
|
||||||
libwebpdspdecode_sse41_la_SOURCES += alpha_processing_sse41.c
|
libwebpdspdecode_sse41_la_SOURCES += alpha_processing_sse41.c
|
||||||
libwebpdspdecode_sse41_la_SOURCES += dec_sse41.c
|
libwebpdspdecode_sse41_la_SOURCES += dec_sse41.c
|
||||||
libwebpdspdecode_sse41_la_SOURCES += lossless_sse41.c
|
|
||||||
libwebpdspdecode_sse41_la_SOURCES += upsampling_sse41.c
|
libwebpdspdecode_sse41_la_SOURCES += upsampling_sse41.c
|
||||||
libwebpdspdecode_sse41_la_SOURCES += yuv_sse41.c
|
libwebpdspdecode_sse41_la_SOURCES += yuv_sse41.c
|
||||||
libwebpdspdecode_sse41_la_CPPFLAGS = $(libwebpdsp_la_CPPFLAGS)
|
libwebpdspdecode_sse41_la_CPPFLAGS = $(libwebpdsp_la_CPPFLAGS)
|
||||||
@ -107,8 +105,6 @@ libwebpdspdecode_mips_dsp_r2_la_SOURCES += yuv_mips_dsp_r2.c
|
|||||||
libwebpdspdecode_mips_dsp_r2_la_CPPFLAGS = $(libwebpdsp_mips_dsp_r2_la_CPPFLAGS)
|
libwebpdspdecode_mips_dsp_r2_la_CPPFLAGS = $(libwebpdsp_mips_dsp_r2_la_CPPFLAGS)
|
||||||
libwebpdspdecode_mips_dsp_r2_la_CFLAGS = $(libwebpdsp_mips_dsp_r2_la_CFLAGS)
|
libwebpdspdecode_mips_dsp_r2_la_CFLAGS = $(libwebpdsp_mips_dsp_r2_la_CFLAGS)
|
||||||
|
|
||||||
libwebpdspdecode_wasm_la_SOURCES = dec_wasm.c
|
|
||||||
|
|
||||||
libwebpdsp_sse2_la_SOURCES =
|
libwebpdsp_sse2_la_SOURCES =
|
||||||
libwebpdsp_sse2_la_SOURCES += cost_sse2.c
|
libwebpdsp_sse2_la_SOURCES += cost_sse2.c
|
||||||
libwebpdsp_sse2_la_SOURCES += enc_sse2.c
|
libwebpdsp_sse2_la_SOURCES += enc_sse2.c
|
||||||
|
@ -157,8 +157,7 @@ void WebPMultARGBRow_C(uint32_t* const ptr, int width, int inverse) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebPMultRow_C(uint8_t* WEBP_RESTRICT const ptr,
|
void WebPMultRow_C(uint8_t* const ptr, const uint8_t* const alpha,
|
||||||
const uint8_t* WEBP_RESTRICT const alpha,
|
|
||||||
int width, int inverse) {
|
int width, int inverse) {
|
||||||
int x;
|
int x;
|
||||||
for (x = 0; x < width; ++x) {
|
for (x = 0; x < width; ++x) {
|
||||||
@ -179,8 +178,7 @@ void WebPMultRow_C(uint8_t* WEBP_RESTRICT const ptr,
|
|||||||
#undef MFIX
|
#undef MFIX
|
||||||
|
|
||||||
void (*WebPMultARGBRow)(uint32_t* const ptr, int width, int inverse);
|
void (*WebPMultARGBRow)(uint32_t* const ptr, int width, int inverse);
|
||||||
void (*WebPMultRow)(uint8_t* WEBP_RESTRICT const ptr,
|
void (*WebPMultRow)(uint8_t* const ptr, const uint8_t* const alpha,
|
||||||
const uint8_t* WEBP_RESTRICT const alpha,
|
|
||||||
int width, int inverse);
|
int width, int inverse);
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
@ -195,8 +193,8 @@ void WebPMultARGBRows(uint8_t* ptr, int stride, int width, int num_rows,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebPMultRows(uint8_t* WEBP_RESTRICT ptr, int stride,
|
void WebPMultRows(uint8_t* ptr, int stride,
|
||||||
const uint8_t* WEBP_RESTRICT alpha, int alpha_stride,
|
const uint8_t* alpha, int alpha_stride,
|
||||||
int width, int num_rows, int inverse) {
|
int width, int num_rows, int inverse) {
|
||||||
int n;
|
int n;
|
||||||
for (n = 0; n < num_rows; ++n) {
|
for (n = 0; n < num_rows; ++n) {
|
||||||
@ -292,9 +290,9 @@ static void ApplyAlphaMultiply_16b_C(uint8_t* rgba4444,
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if !WEBP_NEON_OMIT_C_CODE
|
#if !WEBP_NEON_OMIT_C_CODE
|
||||||
static int DispatchAlpha_C(const uint8_t* WEBP_RESTRICT alpha, int alpha_stride,
|
static int DispatchAlpha_C(const uint8_t* alpha, int alpha_stride,
|
||||||
int width, int height,
|
int width, int height,
|
||||||
uint8_t* WEBP_RESTRICT dst, int dst_stride) {
|
uint8_t* dst, int dst_stride) {
|
||||||
uint32_t alpha_mask = 0xff;
|
uint32_t alpha_mask = 0xff;
|
||||||
int i, j;
|
int i, j;
|
||||||
|
|
||||||
@ -311,10 +309,9 @@ static int DispatchAlpha_C(const uint8_t* WEBP_RESTRICT alpha, int alpha_stride,
|
|||||||
return (alpha_mask != 0xff);
|
return (alpha_mask != 0xff);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void DispatchAlphaToGreen_C(const uint8_t* WEBP_RESTRICT alpha,
|
static void DispatchAlphaToGreen_C(const uint8_t* alpha, int alpha_stride,
|
||||||
int alpha_stride, int width, int height,
|
int width, int height,
|
||||||
uint32_t* WEBP_RESTRICT dst,
|
uint32_t* dst, int dst_stride) {
|
||||||
int dst_stride) {
|
|
||||||
int i, j;
|
int i, j;
|
||||||
for (j = 0; j < height; ++j) {
|
for (j = 0; j < height; ++j) {
|
||||||
for (i = 0; i < width; ++i) {
|
for (i = 0; i < width; ++i) {
|
||||||
@ -325,9 +322,9 @@ static void DispatchAlphaToGreen_C(const uint8_t* WEBP_RESTRICT alpha,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ExtractAlpha_C(const uint8_t* WEBP_RESTRICT argb, int argb_stride,
|
static int ExtractAlpha_C(const uint8_t* argb, int argb_stride,
|
||||||
int width, int height,
|
int width, int height,
|
||||||
uint8_t* WEBP_RESTRICT alpha, int alpha_stride) {
|
uint8_t* alpha, int alpha_stride) {
|
||||||
uint8_t alpha_mask = 0xff;
|
uint8_t alpha_mask = 0xff;
|
||||||
int i, j;
|
int i, j;
|
||||||
|
|
||||||
@ -343,8 +340,7 @@ static int ExtractAlpha_C(const uint8_t* WEBP_RESTRICT argb, int argb_stride,
|
|||||||
return (alpha_mask == 0xff);
|
return (alpha_mask == 0xff);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ExtractGreen_C(const uint32_t* WEBP_RESTRICT argb,
|
static void ExtractGreen_C(const uint32_t* argb, uint8_t* alpha, int size) {
|
||||||
uint8_t* WEBP_RESTRICT alpha, int size) {
|
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < size; ++i) alpha[i] = argb[i] >> 8;
|
for (i = 0; i < size; ++i) alpha[i] = argb[i] >> 8;
|
||||||
}
|
}
|
||||||
@ -363,11 +359,6 @@ static int HasAlpha32b_C(const uint8_t* src, int length) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void AlphaReplace_C(uint32_t* src, int length, uint32_t color) {
|
|
||||||
int x;
|
|
||||||
for (x = 0; x < length; ++x) if ((src[x] >> 24) == 0) src[x] = color;
|
|
||||||
}
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Simple channel manipulations.
|
// Simple channel manipulations.
|
||||||
|
|
||||||
@ -376,11 +367,8 @@ static WEBP_INLINE uint32_t MakeARGB32(int a, int r, int g, int b) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef WORDS_BIGENDIAN
|
#ifdef WORDS_BIGENDIAN
|
||||||
static void PackARGB_C(const uint8_t* WEBP_RESTRICT a,
|
static void PackARGB_C(const uint8_t* a, const uint8_t* r, const uint8_t* g,
|
||||||
const uint8_t* WEBP_RESTRICT r,
|
const uint8_t* b, int len, uint32_t* out) {
|
||||||
const uint8_t* WEBP_RESTRICT g,
|
|
||||||
const uint8_t* WEBP_RESTRICT b,
|
|
||||||
int len, uint32_t* WEBP_RESTRICT out) {
|
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < len; ++i) {
|
for (i = 0; i < len; ++i) {
|
||||||
out[i] = MakeARGB32(a[4 * i], r[4 * i], g[4 * i], b[4 * i]);
|
out[i] = MakeARGB32(a[4 * i], r[4 * i], g[4 * i], b[4 * i]);
|
||||||
@ -388,10 +376,8 @@ static void PackARGB_C(const uint8_t* WEBP_RESTRICT a,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void PackRGB_C(const uint8_t* WEBP_RESTRICT r,
|
static void PackRGB_C(const uint8_t* r, const uint8_t* g, const uint8_t* b,
|
||||||
const uint8_t* WEBP_RESTRICT g,
|
int len, int step, uint32_t* out) {
|
||||||
const uint8_t* WEBP_RESTRICT b,
|
|
||||||
int len, int step, uint32_t* WEBP_RESTRICT out) {
|
|
||||||
int i, offset = 0;
|
int i, offset = 0;
|
||||||
for (i = 0; i < len; ++i) {
|
for (i = 0; i < len; ++i) {
|
||||||
out[i] = MakeARGB32(0xff, r[offset], g[offset], b[offset]);
|
out[i] = MakeARGB32(0xff, r[offset], g[offset], b[offset]);
|
||||||
@ -401,26 +387,19 @@ static void PackRGB_C(const uint8_t* WEBP_RESTRICT r,
|
|||||||
|
|
||||||
void (*WebPApplyAlphaMultiply)(uint8_t*, int, int, int, int);
|
void (*WebPApplyAlphaMultiply)(uint8_t*, int, int, int, int);
|
||||||
void (*WebPApplyAlphaMultiply4444)(uint8_t*, int, int, int);
|
void (*WebPApplyAlphaMultiply4444)(uint8_t*, int, int, int);
|
||||||
int (*WebPDispatchAlpha)(const uint8_t* WEBP_RESTRICT, int, int, int,
|
int (*WebPDispatchAlpha)(const uint8_t*, int, int, int, uint8_t*, int);
|
||||||
uint8_t* WEBP_RESTRICT, int);
|
void (*WebPDispatchAlphaToGreen)(const uint8_t*, int, int, int, uint32_t*, int);
|
||||||
void (*WebPDispatchAlphaToGreen)(const uint8_t* WEBP_RESTRICT, int, int, int,
|
int (*WebPExtractAlpha)(const uint8_t*, int, int, int, uint8_t*, int);
|
||||||
uint32_t* WEBP_RESTRICT, int);
|
void (*WebPExtractGreen)(const uint32_t* argb, uint8_t* alpha, int size);
|
||||||
int (*WebPExtractAlpha)(const uint8_t* WEBP_RESTRICT, int, int, int,
|
|
||||||
uint8_t* WEBP_RESTRICT, int);
|
|
||||||
void (*WebPExtractGreen)(const uint32_t* WEBP_RESTRICT argb,
|
|
||||||
uint8_t* WEBP_RESTRICT alpha, int size);
|
|
||||||
#ifdef WORDS_BIGENDIAN
|
#ifdef WORDS_BIGENDIAN
|
||||||
void (*WebPPackARGB)(const uint8_t* a, const uint8_t* r, const uint8_t* g,
|
void (*WebPPackARGB)(const uint8_t* a, const uint8_t* r, const uint8_t* g,
|
||||||
const uint8_t* b, int, uint32_t*);
|
const uint8_t* b, int, uint32_t*);
|
||||||
#endif
|
#endif
|
||||||
void (*WebPPackRGB)(const uint8_t* WEBP_RESTRICT r,
|
void (*WebPPackRGB)(const uint8_t* r, const uint8_t* g, const uint8_t* b,
|
||||||
const uint8_t* WEBP_RESTRICT g,
|
int len, int step, uint32_t* out);
|
||||||
const uint8_t* WEBP_RESTRICT b,
|
|
||||||
int len, int step, uint32_t* WEBP_RESTRICT out);
|
|
||||||
|
|
||||||
int (*WebPHasAlpha8b)(const uint8_t* src, int length);
|
int (*WebPHasAlpha8b)(const uint8_t* src, int length);
|
||||||
int (*WebPHasAlpha32b)(const uint8_t* src, int length);
|
int (*WebPHasAlpha32b)(const uint8_t* src, int length);
|
||||||
void (*WebPAlphaReplace)(uint32_t* src, int length, uint32_t color);
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Init function
|
// Init function
|
||||||
@ -449,14 +428,13 @@ WEBP_DSP_INIT_FUNC(WebPInitAlphaProcessing) {
|
|||||||
|
|
||||||
WebPHasAlpha8b = HasAlpha8b_C;
|
WebPHasAlpha8b = HasAlpha8b_C;
|
||||||
WebPHasAlpha32b = HasAlpha32b_C;
|
WebPHasAlpha32b = HasAlpha32b_C;
|
||||||
WebPAlphaReplace = AlphaReplace_C;
|
|
||||||
|
|
||||||
// If defined, use CPUInfo() to overwrite some pointers with faster versions.
|
// If defined, use CPUInfo() to overwrite some pointers with faster versions.
|
||||||
if (VP8GetCPUInfo != NULL) {
|
if (VP8GetCPUInfo != NULL) {
|
||||||
#if defined(WEBP_HAVE_SSE2)
|
#if defined(WEBP_USE_SSE2)
|
||||||
if (VP8GetCPUInfo(kSSE2)) {
|
if (VP8GetCPUInfo(kSSE2)) {
|
||||||
WebPInitAlphaProcessingSSE2();
|
WebPInitAlphaProcessingSSE2();
|
||||||
#if defined(WEBP_HAVE_SSE41)
|
#if defined(WEBP_USE_SSE41)
|
||||||
if (VP8GetCPUInfo(kSSE4_1)) {
|
if (VP8GetCPUInfo(kSSE4_1)) {
|
||||||
WebPInitAlphaProcessingSSE41();
|
WebPInitAlphaProcessingSSE41();
|
||||||
}
|
}
|
||||||
@ -470,7 +448,7 @@ WEBP_DSP_INIT_FUNC(WebPInitAlphaProcessing) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(WEBP_HAVE_NEON)
|
#if defined(WEBP_USE_NEON)
|
||||||
if (WEBP_NEON_OMIT_C_CODE ||
|
if (WEBP_NEON_OMIT_C_CODE ||
|
||||||
(VP8GetCPUInfo != NULL && VP8GetCPUInfo(kNEON))) {
|
(VP8GetCPUInfo != NULL && VP8GetCPUInfo(kNEON))) {
|
||||||
WebPInitAlphaProcessingNEON();
|
WebPInitAlphaProcessingNEON();
|
||||||
@ -491,5 +469,4 @@ WEBP_DSP_INIT_FUNC(WebPInitAlphaProcessing) {
|
|||||||
assert(WebPPackRGB != NULL);
|
assert(WebPPackRGB != NULL);
|
||||||
assert(WebPHasAlpha8b != NULL);
|
assert(WebPHasAlpha8b != NULL);
|
||||||
assert(WebPHasAlpha32b != NULL);
|
assert(WebPHasAlpha32b != NULL);
|
||||||
assert(WebPAlphaReplace != NULL);
|
|
||||||
}
|
}
|
||||||
|
@ -80,10 +80,10 @@ static void ApplyAlphaMultiply_NEON(uint8_t* rgba, int alpha_first,
|
|||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
static int DispatchAlpha_NEON(const uint8_t* WEBP_RESTRICT alpha,
|
static int DispatchAlpha_NEON(const uint8_t* alpha, int alpha_stride,
|
||||||
int alpha_stride, int width, int height,
|
int width, int height,
|
||||||
uint8_t* WEBP_RESTRICT dst, int dst_stride) {
|
uint8_t* dst, int dst_stride) {
|
||||||
uint32_t alpha_mask = 0xffffffffu;
|
uint32_t alpha_mask = 0xffu;
|
||||||
uint8x8_t mask8 = vdup_n_u8(0xff);
|
uint8x8_t mask8 = vdup_n_u8(0xff);
|
||||||
uint32_t tmp[2];
|
uint32_t tmp[2];
|
||||||
int i, j;
|
int i, j;
|
||||||
@ -107,15 +107,15 @@ static int DispatchAlpha_NEON(const uint8_t* WEBP_RESTRICT alpha,
|
|||||||
dst += dst_stride;
|
dst += dst_stride;
|
||||||
}
|
}
|
||||||
vst1_u8((uint8_t*)tmp, mask8);
|
vst1_u8((uint8_t*)tmp, mask8);
|
||||||
|
alpha_mask *= 0x01010101;
|
||||||
alpha_mask &= tmp[0];
|
alpha_mask &= tmp[0];
|
||||||
alpha_mask &= tmp[1];
|
alpha_mask &= tmp[1];
|
||||||
return (alpha_mask != 0xffffffffu);
|
return (alpha_mask != 0xffffffffu);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void DispatchAlphaToGreen_NEON(const uint8_t* WEBP_RESTRICT alpha,
|
static void DispatchAlphaToGreen_NEON(const uint8_t* alpha, int alpha_stride,
|
||||||
int alpha_stride, int width, int height,
|
int width, int height,
|
||||||
uint32_t* WEBP_RESTRICT dst,
|
uint32_t* dst, int dst_stride) {
|
||||||
int dst_stride) {
|
|
||||||
int i, j;
|
int i, j;
|
||||||
uint8x8x4_t greens; // leave A/R/B channels zero'd.
|
uint8x8x4_t greens; // leave A/R/B channels zero'd.
|
||||||
greens.val[0] = vdup_n_u8(0);
|
greens.val[0] = vdup_n_u8(0);
|
||||||
@ -132,10 +132,10 @@ static void DispatchAlphaToGreen_NEON(const uint8_t* WEBP_RESTRICT alpha,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ExtractAlpha_NEON(const uint8_t* WEBP_RESTRICT argb, int argb_stride,
|
static int ExtractAlpha_NEON(const uint8_t* argb, int argb_stride,
|
||||||
int width, int height,
|
int width, int height,
|
||||||
uint8_t* WEBP_RESTRICT alpha, int alpha_stride) {
|
uint8_t* alpha, int alpha_stride) {
|
||||||
uint32_t alpha_mask = 0xffffffffu;
|
uint32_t alpha_mask = 0xffu;
|
||||||
uint8x8_t mask8 = vdup_n_u8(0xff);
|
uint8x8_t mask8 = vdup_n_u8(0xff);
|
||||||
uint32_t tmp[2];
|
uint32_t tmp[2];
|
||||||
int i, j;
|
int i, j;
|
||||||
@ -157,13 +157,14 @@ static int ExtractAlpha_NEON(const uint8_t* WEBP_RESTRICT argb, int argb_stride,
|
|||||||
alpha += alpha_stride;
|
alpha += alpha_stride;
|
||||||
}
|
}
|
||||||
vst1_u8((uint8_t*)tmp, mask8);
|
vst1_u8((uint8_t*)tmp, mask8);
|
||||||
|
alpha_mask *= 0x01010101;
|
||||||
alpha_mask &= tmp[0];
|
alpha_mask &= tmp[0];
|
||||||
alpha_mask &= tmp[1];
|
alpha_mask &= tmp[1];
|
||||||
return (alpha_mask == 0xffffffffu);
|
return (alpha_mask == 0xffffffffu);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ExtractGreen_NEON(const uint32_t* WEBP_RESTRICT argb,
|
static void ExtractGreen_NEON(const uint32_t* argb,
|
||||||
uint8_t* WEBP_RESTRICT alpha, int size) {
|
uint8_t* alpha, int size) {
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i + 16 <= size; i += 16) {
|
for (i = 0; i + 16 <= size; i += 16) {
|
||||||
const uint8x16x4_t rgbX = vld4q_u8((const uint8_t*)(argb + i));
|
const uint8x16x4_t rgbX = vld4q_u8((const uint8_t*)(argb + i));
|
||||||
|
@ -18,9 +18,9 @@
|
|||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
static int DispatchAlpha_SSE2(const uint8_t* WEBP_RESTRICT alpha,
|
static int DispatchAlpha_SSE2(const uint8_t* alpha, int alpha_stride,
|
||||||
int alpha_stride, int width, int height,
|
int width, int height,
|
||||||
uint8_t* WEBP_RESTRICT dst, int dst_stride) {
|
uint8_t* dst, int dst_stride) {
|
||||||
// alpha_and stores an 'and' operation of all the alpha[] values. The final
|
// alpha_and stores an 'and' operation of all the alpha[] values. The final
|
||||||
// value is not 0xff if any of the alpha[] is not equal to 0xff.
|
// value is not 0xff if any of the alpha[] is not equal to 0xff.
|
||||||
uint32_t alpha_and = 0xff;
|
uint32_t alpha_and = 0xff;
|
||||||
@ -72,10 +72,9 @@ static int DispatchAlpha_SSE2(const uint8_t* WEBP_RESTRICT alpha,
|
|||||||
return (alpha_and != 0xff);
|
return (alpha_and != 0xff);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void DispatchAlphaToGreen_SSE2(const uint8_t* WEBP_RESTRICT alpha,
|
static void DispatchAlphaToGreen_SSE2(const uint8_t* alpha, int alpha_stride,
|
||||||
int alpha_stride, int width, int height,
|
int width, int height,
|
||||||
uint32_t* WEBP_RESTRICT dst,
|
uint32_t* dst, int dst_stride) {
|
||||||
int dst_stride) {
|
|
||||||
int i, j;
|
int i, j;
|
||||||
const __m128i zero = _mm_setzero_si128();
|
const __m128i zero = _mm_setzero_si128();
|
||||||
const int limit = width & ~15;
|
const int limit = width & ~15;
|
||||||
@ -99,9 +98,9 @@ static void DispatchAlphaToGreen_SSE2(const uint8_t* WEBP_RESTRICT alpha,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ExtractAlpha_SSE2(const uint8_t* WEBP_RESTRICT argb, int argb_stride,
|
static int ExtractAlpha_SSE2(const uint8_t* argb, int argb_stride,
|
||||||
int width, int height,
|
int width, int height,
|
||||||
uint8_t* WEBP_RESTRICT alpha, int alpha_stride) {
|
uint8_t* alpha, int alpha_stride) {
|
||||||
// alpha_and stores an 'and' operation of all the alpha[] values. The final
|
// alpha_and stores an 'and' operation of all the alpha[] values. The final
|
||||||
// value is not 0xff if any of the alpha[] is not equal to 0xff.
|
// value is not 0xff if any of the alpha[] is not equal to 0xff.
|
||||||
uint32_t alpha_and = 0xff;
|
uint32_t alpha_and = 0xff;
|
||||||
@ -266,27 +265,6 @@ static int HasAlpha32b_SSE2(const uint8_t* src, int length) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void AlphaReplace_SSE2(uint32_t* src, int length, uint32_t color) {
|
|
||||||
const __m128i m_color = _mm_set1_epi32(color);
|
|
||||||
const __m128i zero = _mm_setzero_si128();
|
|
||||||
int i = 0;
|
|
||||||
for (; i + 8 <= length; i += 8) {
|
|
||||||
const __m128i a0 = _mm_loadu_si128((const __m128i*)(src + i + 0));
|
|
||||||
const __m128i a1 = _mm_loadu_si128((const __m128i*)(src + i + 4));
|
|
||||||
const __m128i b0 = _mm_srai_epi32(a0, 24);
|
|
||||||
const __m128i b1 = _mm_srai_epi32(a1, 24);
|
|
||||||
const __m128i c0 = _mm_cmpeq_epi32(b0, zero);
|
|
||||||
const __m128i c1 = _mm_cmpeq_epi32(b1, zero);
|
|
||||||
const __m128i d0 = _mm_and_si128(c0, m_color);
|
|
||||||
const __m128i d1 = _mm_and_si128(c1, m_color);
|
|
||||||
const __m128i e0 = _mm_andnot_si128(c0, a0);
|
|
||||||
const __m128i e1 = _mm_andnot_si128(c1, a1);
|
|
||||||
_mm_storeu_si128((__m128i*)(src + i + 0), _mm_or_si128(d0, e0));
|
|
||||||
_mm_storeu_si128((__m128i*)(src + i + 4), _mm_or_si128(d1, e1));
|
|
||||||
}
|
|
||||||
for (; i < length; ++i) if ((src[i] >> 24) == 0) src[i] = color;
|
|
||||||
}
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// Apply alpha value to rows
|
// Apply alpha value to rows
|
||||||
|
|
||||||
@ -318,8 +296,7 @@ static void MultARGBRow_SSE2(uint32_t* const ptr, int width, int inverse) {
|
|||||||
if (width > 0) WebPMultARGBRow_C(ptr + x, width, inverse);
|
if (width > 0) WebPMultARGBRow_C(ptr + x, width, inverse);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void MultRow_SSE2(uint8_t* WEBP_RESTRICT const ptr,
|
static void MultRow_SSE2(uint8_t* const ptr, const uint8_t* const alpha,
|
||||||
const uint8_t* WEBP_RESTRICT const alpha,
|
|
||||||
int width, int inverse) {
|
int width, int inverse) {
|
||||||
int x = 0;
|
int x = 0;
|
||||||
if (!inverse) {
|
if (!inverse) {
|
||||||
@ -357,7 +334,6 @@ WEBP_TSAN_IGNORE_FUNCTION void WebPInitAlphaProcessingSSE2(void) {
|
|||||||
|
|
||||||
WebPHasAlpha8b = HasAlpha8b_SSE2;
|
WebPHasAlpha8b = HasAlpha8b_SSE2;
|
||||||
WebPHasAlpha32b = HasAlpha32b_SSE2;
|
WebPHasAlpha32b = HasAlpha32b_SSE2;
|
||||||
WebPAlphaReplace = AlphaReplace_SSE2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#else // !WEBP_USE_SSE2
|
#else // !WEBP_USE_SSE2
|
||||||
|
@ -19,9 +19,9 @@
|
|||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
static int ExtractAlpha_SSE41(const uint8_t* WEBP_RESTRICT argb,
|
static int ExtractAlpha_SSE41(const uint8_t* argb, int argb_stride,
|
||||||
int argb_stride, int width, int height,
|
int width, int height,
|
||||||
uint8_t* WEBP_RESTRICT alpha, int alpha_stride) {
|
uint8_t* alpha, int alpha_stride) {
|
||||||
// alpha_and stores an 'and' operation of all the alpha[] values. The final
|
// alpha_and stores an 'and' operation of all the alpha[] values. The final
|
||||||
// value is not 0xff if any of the alpha[] is not equal to 0xff.
|
// value is not 0xff if any of the alpha[] is not equal to 0xff.
|
||||||
uint32_t alpha_and = 0xff;
|
uint32_t alpha_and = 0xff;
|
||||||
|
@ -395,12 +395,12 @@ WEBP_DSP_INIT_FUNC(VP8EncDspCostInit) {
|
|||||||
VP8EncDspCostInitMIPSdspR2();
|
VP8EncDspCostInitMIPSdspR2();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#if defined(WEBP_HAVE_SSE2)
|
#if defined(WEBP_USE_SSE2)
|
||||||
if (VP8GetCPUInfo(kSSE2)) {
|
if (VP8GetCPUInfo(kSSE2)) {
|
||||||
VP8EncDspCostInitSSE2();
|
VP8EncDspCostInitSSE2();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#if defined(WEBP_HAVE_NEON)
|
#if defined(WEBP_USE_NEON)
|
||||||
if (VP8GetCPUInfo(kNEON)) {
|
if (VP8GetCPUInfo(kNEON)) {
|
||||||
VP8EncDspCostInitNEON();
|
VP8EncDspCostInitNEON();
|
||||||
}
|
}
|
||||||
|
@ -26,10 +26,8 @@
|
|||||||
// SSE2 detection.
|
// SSE2 detection.
|
||||||
//
|
//
|
||||||
|
|
||||||
// Skip SSE detection if using Wasm SIMD build.
|
|
||||||
#if defined(WEBP_USE_WASM_SIMD)
|
|
||||||
// apple/darwin gcc-4.0.1 defines __PIC__, but not __pic__ with -fPIC.
|
// apple/darwin gcc-4.0.1 defines __PIC__, but not __pic__ with -fPIC.
|
||||||
#elif (defined(__pic__) || defined(__PIC__)) && defined(__i386__)
|
#if (defined(__pic__) || defined(__PIC__)) && defined(__i386__)
|
||||||
static WEBP_INLINE void GetCPUInfo(int cpu_info[4], int info_type) {
|
static WEBP_INLINE void GetCPUInfo(int cpu_info[4], int info_type) {
|
||||||
__asm__ volatile (
|
__asm__ volatile (
|
||||||
"mov %%ebx, %%edi\n"
|
"mov %%ebx, %%edi\n"
|
||||||
@ -57,24 +55,16 @@ static WEBP_INLINE void GetCPUInfo(int cpu_info[4], int info_type) {
|
|||||||
: "=a"(cpu_info[0]), "=b"(cpu_info[1]), "=c"(cpu_info[2]), "=d"(cpu_info[3])
|
: "=a"(cpu_info[0]), "=b"(cpu_info[1]), "=c"(cpu_info[2]), "=d"(cpu_info[3])
|
||||||
: "a"(info_type), "c"(0));
|
: "a"(info_type), "c"(0));
|
||||||
}
|
}
|
||||||
#elif defined(_MSC_VER) && (defined(_M_X64) || defined(_M_IX86))
|
#elif (defined(_M_X64) || defined(_M_IX86)) && \
|
||||||
|
defined(_MSC_FULL_VER) && _MSC_FULL_VER >= 150030729 // >= VS2008 SP1
|
||||||
#if defined(_MSC_FULL_VER) && _MSC_FULL_VER >= 150030729 // >= VS2008 SP1
|
|
||||||
#include <intrin.h>
|
#include <intrin.h>
|
||||||
#define GetCPUInfo(info, type) __cpuidex(info, type, 0) // set ecx=0
|
#define GetCPUInfo(info, type) __cpuidex(info, type, 0) // set ecx=0
|
||||||
#define WEBP_HAVE_MSC_CPUID
|
#elif defined(WEBP_MSC_SSE2)
|
||||||
#elif _MSC_VER > 1310
|
|
||||||
#include <intrin.h>
|
|
||||||
#define GetCPUInfo __cpuid
|
#define GetCPUInfo __cpuid
|
||||||
#define WEBP_HAVE_MSC_CPUID
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Skip xgetbv definition if using Wasm SIMD build.
|
|
||||||
#if defined(WEBP_USE_WASM_SIMD)
|
|
||||||
// NaCl has no support for xgetbv or the raw opcode.
|
// NaCl has no support for xgetbv or the raw opcode.
|
||||||
#elif !defined(__native_client__) && (defined(__i386__) || defined(__x86_64__))
|
#if !defined(__native_client__) && (defined(__i386__) || defined(__x86_64__))
|
||||||
static WEBP_INLINE uint64_t xgetbv(void) {
|
static WEBP_INLINE uint64_t xgetbv(void) {
|
||||||
const uint32_t ecx = 0;
|
const uint32_t ecx = 0;
|
||||||
uint32_t eax, edx;
|
uint32_t eax, edx;
|
||||||
@ -104,13 +94,7 @@ static WEBP_INLINE uint64_t xgetbv(void) {
|
|||||||
#define xgetbv() 0U // no AVX for older x64 or unrecognized toolchains.
|
#define xgetbv() 0U // no AVX for older x64 or unrecognized toolchains.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(WEBP_USE_WASM_SIMD)
|
#if defined(__i386__) || defined(__x86_64__) || defined(WEBP_MSC_SSE2)
|
||||||
static int wasmCPUInfo(CPUFeature feature) {
|
|
||||||
if (feature != kWasmSIMD) return 0;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
VP8CPUInfo VP8GetCPUInfo = wasmCPUInfo;
|
|
||||||
#elif defined(__i386__) || defined(__x86_64__) || defined(WEBP_HAVE_MSC_CPUID)
|
|
||||||
|
|
||||||
// helper function for run-time detection of slow SSSE3 platforms
|
// helper function for run-time detection of slow SSSE3 platforms
|
||||||
static int CheckSlowModel(int info) {
|
static int CheckSlowModel(int info) {
|
||||||
@ -195,34 +179,9 @@ static int AndroidCPUInfo(CPUFeature feature) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
VP8CPUInfo VP8GetCPUInfo = AndroidCPUInfo;
|
VP8CPUInfo VP8GetCPUInfo = AndroidCPUInfo;
|
||||||
#elif defined(EMSCRIPTEN) // also needs to be before generic NEON test
|
#elif defined(WEBP_USE_NEON)
|
||||||
// Use compile flags as an indicator of SIMD support instead of a runtime check.
|
// define a dummy function to enable turning off NEON at runtime by setting
|
||||||
static int wasmCPUInfo(CPUFeature feature) {
|
// VP8DecGetCPUInfo = NULL
|
||||||
switch (feature) {
|
|
||||||
#ifdef WEBP_HAVE_SSE2
|
|
||||||
case kSSE2:
|
|
||||||
return 1;
|
|
||||||
#endif
|
|
||||||
#ifdef WEBP_HAVE_SSE41
|
|
||||||
case kSSE3:
|
|
||||||
case kSlowSSSE3:
|
|
||||||
case kSSE4_1:
|
|
||||||
return 1;
|
|
||||||
#endif
|
|
||||||
#ifdef WEBP_HAVE_NEON
|
|
||||||
case kNEON:
|
|
||||||
return 1;
|
|
||||||
#endif
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
VP8CPUInfo VP8GetCPUInfo = wasmCPUInfo;
|
|
||||||
#elif defined(WEBP_HAVE_NEON)
|
|
||||||
// In most cases this function doesn't check for NEON support (it's assumed by
|
|
||||||
// the configuration), but enables turning off NEON at runtime, for testing
|
|
||||||
// purposes, by setting VP8DecGetCPUInfo = NULL.
|
|
||||||
static int armCPUInfo(CPUFeature feature) {
|
static int armCPUInfo(CPUFeature feature) {
|
||||||
if (feature != kNEON) return 0;
|
if (feature != kNEON) return 0;
|
||||||
#if defined(__linux__) && defined(WEBP_HAVE_NEON_RTCD)
|
#if defined(__linux__) && defined(WEBP_HAVE_NEON_RTCD)
|
||||||
|
@ -740,7 +740,6 @@ extern void VP8DspInitNEON(void);
|
|||||||
extern void VP8DspInitMIPS32(void);
|
extern void VP8DspInitMIPS32(void);
|
||||||
extern void VP8DspInitMIPSdspR2(void);
|
extern void VP8DspInitMIPSdspR2(void);
|
||||||
extern void VP8DspInitMSA(void);
|
extern void VP8DspInitMSA(void);
|
||||||
extern void VP8DspInitWasmSIMD(void);
|
|
||||||
|
|
||||||
WEBP_DSP_INIT_FUNC(VP8DspInit) {
|
WEBP_DSP_INIT_FUNC(VP8DspInit) {
|
||||||
VP8InitClipTables();
|
VP8InitClipTables();
|
||||||
@ -808,10 +807,10 @@ WEBP_DSP_INIT_FUNC(VP8DspInit) {
|
|||||||
|
|
||||||
// If defined, use CPUInfo() to overwrite some pointers with faster versions.
|
// If defined, use CPUInfo() to overwrite some pointers with faster versions.
|
||||||
if (VP8GetCPUInfo != NULL) {
|
if (VP8GetCPUInfo != NULL) {
|
||||||
#if defined(WEBP_HAVE_SSE2)
|
#if defined(WEBP_USE_SSE2)
|
||||||
if (VP8GetCPUInfo(kSSE2)) {
|
if (VP8GetCPUInfo(kSSE2)) {
|
||||||
VP8DspInitSSE2();
|
VP8DspInitSSE2();
|
||||||
#if defined(WEBP_HAVE_SSE41)
|
#if defined(WEBP_USE_SSE41)
|
||||||
if (VP8GetCPUInfo(kSSE4_1)) {
|
if (VP8GetCPUInfo(kSSE4_1)) {
|
||||||
VP8DspInitSSE41();
|
VP8DspInitSSE41();
|
||||||
}
|
}
|
||||||
@ -832,16 +831,10 @@ WEBP_DSP_INIT_FUNC(VP8DspInit) {
|
|||||||
if (VP8GetCPUInfo(kMSA)) {
|
if (VP8GetCPUInfo(kMSA)) {
|
||||||
VP8DspInitMSA();
|
VP8DspInitMSA();
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
#if defined(WEBP_USE_WASM_SIMD) && defined(WEBP_ENABLE_WASM_SIMD_INTRINSICS)
|
|
||||||
// Check that SIMD is supported and that we want to use Wasm intrinsics.
|
|
||||||
if (VP8GetCPUInfo(kWasmSIMD)) {
|
|
||||||
VP8DspInitWasmSIMD();
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(WEBP_HAVE_NEON)
|
#if defined(WEBP_USE_NEON)
|
||||||
if (WEBP_NEON_OMIT_C_CODE ||
|
if (WEBP_NEON_OMIT_C_CODE ||
|
||||||
(VP8GetCPUInfo != NULL && VP8GetCPUInfo(kNEON))) {
|
(VP8GetCPUInfo != NULL && VP8GetCPUInfo(kNEON))) {
|
||||||
VP8DspInitNEON();
|
VP8DspInitNEON();
|
||||||
|
@ -1283,12 +1283,12 @@ static void DC4_NEON(uint8_t* dst) { // DC
|
|||||||
const uint8x8_t A = vld1_u8(dst - BPS); // top row
|
const uint8x8_t A = vld1_u8(dst - BPS); // top row
|
||||||
const uint16x4_t p0 = vpaddl_u8(A); // cascading summation of the top
|
const uint16x4_t p0 = vpaddl_u8(A); // cascading summation of the top
|
||||||
const uint16x4_t p1 = vpadd_u16(p0, p0);
|
const uint16x4_t p1 = vpadd_u16(p0, p0);
|
||||||
const uint8x8_t L0 = vld1_u8(dst + 0 * BPS - 1);
|
const uint16x8_t L0 = vmovl_u8(vld1_u8(dst + 0 * BPS - 1));
|
||||||
const uint8x8_t L1 = vld1_u8(dst + 1 * BPS - 1);
|
const uint16x8_t L1 = vmovl_u8(vld1_u8(dst + 1 * BPS - 1));
|
||||||
const uint8x8_t L2 = vld1_u8(dst + 2 * BPS - 1);
|
const uint16x8_t L2 = vmovl_u8(vld1_u8(dst + 2 * BPS - 1));
|
||||||
const uint8x8_t L3 = vld1_u8(dst + 3 * BPS - 1);
|
const uint16x8_t L3 = vmovl_u8(vld1_u8(dst + 3 * BPS - 1));
|
||||||
const uint16x8_t s0 = vaddl_u8(L0, L1);
|
const uint16x8_t s0 = vaddq_u16(L0, L1);
|
||||||
const uint16x8_t s1 = vaddl_u8(L2, L3);
|
const uint16x8_t s1 = vaddq_u16(L2, L3);
|
||||||
const uint16x8_t s01 = vaddq_u16(s0, s1);
|
const uint16x8_t s01 = vaddq_u16(s0, s1);
|
||||||
const uint16x8_t sum = vaddq_u16(s01, vcombine_u16(p1, p1));
|
const uint16x8_t sum = vaddq_u16(s01, vcombine_u16(p1, p1));
|
||||||
const uint8x8_t dc0 = vrshrn_n_u16(sum, 3); // (sum + 4) >> 3
|
const uint8x8_t dc0 = vrshrn_n_u16(sum, 3); // (sum + 4) >> 3
|
||||||
@ -1361,8 +1361,7 @@ static void RD4_NEON(uint8_t* dst) { // Down-right
|
|||||||
const uint32_t J = dst[-1 + 1 * BPS];
|
const uint32_t J = dst[-1 + 1 * BPS];
|
||||||
const uint32_t K = dst[-1 + 2 * BPS];
|
const uint32_t K = dst[-1 + 2 * BPS];
|
||||||
const uint32_t L = dst[-1 + 3 * BPS];
|
const uint32_t L = dst[-1 + 3 * BPS];
|
||||||
const uint64x1_t LKJI____ =
|
const uint64x1_t LKJI____ = vcreate_u64(L | (K << 8) | (J << 16) | (I << 24));
|
||||||
vcreate_u64((uint64_t)L | (K << 8) | (J << 16) | (I << 24));
|
|
||||||
const uint64x1_t LKJIXABC = vorr_u64(LKJI____, ____XABC);
|
const uint64x1_t LKJIXABC = vorr_u64(LKJI____, ____XABC);
|
||||||
const uint8x8_t KJIXABC_ = vreinterpret_u8_u64(vshr_n_u64(LKJIXABC, 8));
|
const uint8x8_t KJIXABC_ = vreinterpret_u8_u64(vshr_n_u64(LKJIXABC, 8));
|
||||||
const uint8x8_t JIXABC__ = vreinterpret_u8_u64(vshr_n_u64(LKJIXABC, 16));
|
const uint8x8_t JIXABC__ = vreinterpret_u8_u64(vshr_n_u64(LKJIXABC, 16));
|
||||||
@ -1428,30 +1427,25 @@ static WEBP_INLINE void DC8_NEON(uint8_t* dst, int do_top, int do_left) {
|
|||||||
|
|
||||||
if (do_top) {
|
if (do_top) {
|
||||||
const uint8x8_t A = vld1_u8(dst - BPS); // top row
|
const uint8x8_t A = vld1_u8(dst - BPS); // top row
|
||||||
#if defined(__aarch64__)
|
|
||||||
const uint16_t p2 = vaddlv_u8(A);
|
|
||||||
sum_top = vdupq_n_u16(p2);
|
|
||||||
#else
|
|
||||||
const uint16x4_t p0 = vpaddl_u8(A); // cascading summation of the top
|
const uint16x4_t p0 = vpaddl_u8(A); // cascading summation of the top
|
||||||
const uint16x4_t p1 = vpadd_u16(p0, p0);
|
const uint16x4_t p1 = vpadd_u16(p0, p0);
|
||||||
const uint16x4_t p2 = vpadd_u16(p1, p1);
|
const uint16x4_t p2 = vpadd_u16(p1, p1);
|
||||||
sum_top = vcombine_u16(p2, p2);
|
sum_top = vcombine_u16(p2, p2);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (do_left) {
|
if (do_left) {
|
||||||
const uint8x8_t L0 = vld1_u8(dst + 0 * BPS - 1);
|
const uint16x8_t L0 = vmovl_u8(vld1_u8(dst + 0 * BPS - 1));
|
||||||
const uint8x8_t L1 = vld1_u8(dst + 1 * BPS - 1);
|
const uint16x8_t L1 = vmovl_u8(vld1_u8(dst + 1 * BPS - 1));
|
||||||
const uint8x8_t L2 = vld1_u8(dst + 2 * BPS - 1);
|
const uint16x8_t L2 = vmovl_u8(vld1_u8(dst + 2 * BPS - 1));
|
||||||
const uint8x8_t L3 = vld1_u8(dst + 3 * BPS - 1);
|
const uint16x8_t L3 = vmovl_u8(vld1_u8(dst + 3 * BPS - 1));
|
||||||
const uint8x8_t L4 = vld1_u8(dst + 4 * BPS - 1);
|
const uint16x8_t L4 = vmovl_u8(vld1_u8(dst + 4 * BPS - 1));
|
||||||
const uint8x8_t L5 = vld1_u8(dst + 5 * BPS - 1);
|
const uint16x8_t L5 = vmovl_u8(vld1_u8(dst + 5 * BPS - 1));
|
||||||
const uint8x8_t L6 = vld1_u8(dst + 6 * BPS - 1);
|
const uint16x8_t L6 = vmovl_u8(vld1_u8(dst + 6 * BPS - 1));
|
||||||
const uint8x8_t L7 = vld1_u8(dst + 7 * BPS - 1);
|
const uint16x8_t L7 = vmovl_u8(vld1_u8(dst + 7 * BPS - 1));
|
||||||
const uint16x8_t s0 = vaddl_u8(L0, L1);
|
const uint16x8_t s0 = vaddq_u16(L0, L1);
|
||||||
const uint16x8_t s1 = vaddl_u8(L2, L3);
|
const uint16x8_t s1 = vaddq_u16(L2, L3);
|
||||||
const uint16x8_t s2 = vaddl_u8(L4, L5);
|
const uint16x8_t s2 = vaddq_u16(L4, L5);
|
||||||
const uint16x8_t s3 = vaddl_u8(L6, L7);
|
const uint16x8_t s3 = vaddq_u16(L6, L7);
|
||||||
const uint16x8_t s01 = vaddq_u16(s0, s1);
|
const uint16x8_t s01 = vaddq_u16(s0, s1);
|
||||||
const uint16x8_t s23 = vaddq_u16(s2, s3);
|
const uint16x8_t s23 = vaddq_u16(s2, s3);
|
||||||
sum_left = vaddq_u16(s01, s23);
|
sum_left = vaddq_u16(s01, s23);
|
||||||
@ -1511,34 +1505,29 @@ static WEBP_INLINE void DC16_NEON(uint8_t* dst, int do_top, int do_left) {
|
|||||||
|
|
||||||
if (do_top) {
|
if (do_top) {
|
||||||
const uint8x16_t A = vld1q_u8(dst - BPS); // top row
|
const uint8x16_t A = vld1q_u8(dst - BPS); // top row
|
||||||
#if defined(__aarch64__)
|
|
||||||
const uint16_t p3 = vaddlvq_u8(A);
|
|
||||||
sum_top = vdupq_n_u16(p3);
|
|
||||||
#else
|
|
||||||
const uint16x8_t p0 = vpaddlq_u8(A); // cascading summation of the top
|
const uint16x8_t p0 = vpaddlq_u8(A); // cascading summation of the top
|
||||||
const uint16x4_t p1 = vadd_u16(vget_low_u16(p0), vget_high_u16(p0));
|
const uint16x4_t p1 = vadd_u16(vget_low_u16(p0), vget_high_u16(p0));
|
||||||
const uint16x4_t p2 = vpadd_u16(p1, p1);
|
const uint16x4_t p2 = vpadd_u16(p1, p1);
|
||||||
const uint16x4_t p3 = vpadd_u16(p2, p2);
|
const uint16x4_t p3 = vpadd_u16(p2, p2);
|
||||||
sum_top = vcombine_u16(p3, p3);
|
sum_top = vcombine_u16(p3, p3);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (do_left) {
|
if (do_left) {
|
||||||
int i;
|
int i;
|
||||||
sum_left = vdupq_n_u16(0);
|
sum_left = vdupq_n_u16(0);
|
||||||
for (i = 0; i < 16; i += 8) {
|
for (i = 0; i < 16; i += 8) {
|
||||||
const uint8x8_t L0 = vld1_u8(dst + (i + 0) * BPS - 1);
|
const uint16x8_t L0 = vmovl_u8(vld1_u8(dst + (i + 0) * BPS - 1));
|
||||||
const uint8x8_t L1 = vld1_u8(dst + (i + 1) * BPS - 1);
|
const uint16x8_t L1 = vmovl_u8(vld1_u8(dst + (i + 1) * BPS - 1));
|
||||||
const uint8x8_t L2 = vld1_u8(dst + (i + 2) * BPS - 1);
|
const uint16x8_t L2 = vmovl_u8(vld1_u8(dst + (i + 2) * BPS - 1));
|
||||||
const uint8x8_t L3 = vld1_u8(dst + (i + 3) * BPS - 1);
|
const uint16x8_t L3 = vmovl_u8(vld1_u8(dst + (i + 3) * BPS - 1));
|
||||||
const uint8x8_t L4 = vld1_u8(dst + (i + 4) * BPS - 1);
|
const uint16x8_t L4 = vmovl_u8(vld1_u8(dst + (i + 4) * BPS - 1));
|
||||||
const uint8x8_t L5 = vld1_u8(dst + (i + 5) * BPS - 1);
|
const uint16x8_t L5 = vmovl_u8(vld1_u8(dst + (i + 5) * BPS - 1));
|
||||||
const uint8x8_t L6 = vld1_u8(dst + (i + 6) * BPS - 1);
|
const uint16x8_t L6 = vmovl_u8(vld1_u8(dst + (i + 6) * BPS - 1));
|
||||||
const uint8x8_t L7 = vld1_u8(dst + (i + 7) * BPS - 1);
|
const uint16x8_t L7 = vmovl_u8(vld1_u8(dst + (i + 7) * BPS - 1));
|
||||||
const uint16x8_t s0 = vaddl_u8(L0, L1);
|
const uint16x8_t s0 = vaddq_u16(L0, L1);
|
||||||
const uint16x8_t s1 = vaddl_u8(L2, L3);
|
const uint16x8_t s1 = vaddq_u16(L2, L3);
|
||||||
const uint16x8_t s2 = vaddl_u8(L4, L5);
|
const uint16x8_t s2 = vaddq_u16(L4, L5);
|
||||||
const uint16x8_t s3 = vaddl_u8(L6, L7);
|
const uint16x8_t s3 = vaddq_u16(L6, L7);
|
||||||
const uint16x8_t s01 = vaddq_u16(s0, s1);
|
const uint16x8_t s01 = vaddq_u16(s0, s1);
|
||||||
const uint16x8_t s23 = vaddq_u16(s2, s3);
|
const uint16x8_t s23 = vaddq_u16(s2, s3);
|
||||||
const uint16x8_t sum = vaddq_u16(s01, s23);
|
const uint16x8_t sum = vaddq_u16(s01, s23);
|
||||||
|
@ -1,32 +0,0 @@
|
|||||||
// Copyright 2021 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.
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// WebAssembly (Wasm) version of some decoding functions.
|
|
||||||
//
|
|
||||||
// This will contain Wasm implementation of some decoding functions.
|
|
||||||
|
|
||||||
#include "./dsp.h"
|
|
||||||
|
|
||||||
#if defined(WEBP_USE_WASM_SIMD)
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
// Entry point
|
|
||||||
|
|
||||||
extern void VP8DspInitWasmSIMD(void);
|
|
||||||
|
|
||||||
WEBP_TSAN_IGNORE_FUNCTION void VP8DspInitWasmSIMD(void) {
|
|
||||||
// TODO(crbug.com/v8/12371): No special implementation for Wasm yet, will be
|
|
||||||
// added later.
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
WEBP_DSP_INIT_STUB(VP8DspInitWasmSIMD)
|
|
||||||
|
|
||||||
#endif // WEBP_USE_WASM_SIMD
|
|
125
src/dsp/dsp.h
125
src/dsp/dsp.h
@ -26,23 +26,6 @@ extern "C" {
|
|||||||
|
|
||||||
#define BPS 32 // this is the common stride for enc/dec
|
#define BPS 32 // this is the common stride for enc/dec
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
// WEBP_RESTRICT
|
|
||||||
|
|
||||||
// Declares a pointer with the restrict type qualifier if available.
|
|
||||||
// This allows code to hint to the compiler that only this pointer references a
|
|
||||||
// particular object or memory region within the scope of the block in which it
|
|
||||||
// is declared. This may allow for improved optimizations due to the lack of
|
|
||||||
// pointer aliasing. See also:
|
|
||||||
// https://en.cppreference.com/w/c/language/restrict
|
|
||||||
#if defined(__GNUC__)
|
|
||||||
#define WEBP_RESTRICT __restrict__
|
|
||||||
#elif defined(_MSC_VER)
|
|
||||||
#define WEBP_RESTRICT __restrict
|
|
||||||
#else
|
|
||||||
#define WEBP_RESTRICT
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// CPU detection
|
// CPU detection
|
||||||
|
|
||||||
@ -68,7 +51,9 @@ extern "C" {
|
|||||||
# define __has_builtin(x) 0
|
# define __has_builtin(x) 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(HAVE_CONFIG_H)
|
// for now, none of the optimizations below are available in emscripten
|
||||||
|
#if !defined(EMSCRIPTEN)
|
||||||
|
|
||||||
#if defined(_MSC_VER) && _MSC_VER > 1310 && \
|
#if defined(_MSC_VER) && _MSC_VER > 1310 && \
|
||||||
(defined(_M_X64) || defined(_M_IX86))
|
(defined(_M_X64) || defined(_M_IX86))
|
||||||
#define WEBP_MSC_SSE2 // Visual C++ SSE2 targets
|
#define WEBP_MSC_SSE2 // Visual C++ SSE2 targets
|
||||||
@ -78,42 +63,23 @@ extern "C" {
|
|||||||
(defined(_M_X64) || defined(_M_IX86))
|
(defined(_M_X64) || defined(_M_IX86))
|
||||||
#define WEBP_MSC_SSE41 // Visual C++ SSE4.1 targets
|
#define WEBP_MSC_SSE41 // Visual C++ SSE4.1 targets
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
|
|
||||||
#if (defined(EMSCRIPTEN) || defined(WEBP_HAVE_WASM_SIMD)) && \
|
|
||||||
defined(__wasm_simd128__)
|
|
||||||
#define WEBP_USE_WASM_SIMD
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// WEBP_HAVE_* are used to indicate the presence of the instruction set in dsp
|
// WEBP_HAVE_* are used to indicate the presence of the instruction set in dsp
|
||||||
// files without intrinsics, allowing the corresponding Init() to be called.
|
// files without intrinsics, allowing the corresponding Init() to be called.
|
||||||
// Files containing intrinsics will need to be built targeting the instruction
|
// Files containing intrinsics will need to be built targeting the instruction
|
||||||
// set so should succeed on one of the earlier tests.
|
// set so should succeed on one of the earlier tests.
|
||||||
#if (defined(__SSE2__) || defined(WEBP_MSC_SSE2)) && \
|
#if defined(__SSE2__) || defined(WEBP_MSC_SSE2) || defined(WEBP_HAVE_SSE2)
|
||||||
(!defined(HAVE_CONFIG_H) || defined(WEBP_HAVE_SSE2))
|
|
||||||
#define WEBP_USE_SSE2
|
#define WEBP_USE_SSE2
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(WEBP_USE_SSE2) && !defined(WEBP_HAVE_SSE2)
|
#if defined(__SSE4_1__) || defined(WEBP_MSC_SSE41) || defined(WEBP_HAVE_SSE41)
|
||||||
#define WEBP_HAVE_SSE2
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if (defined(__SSE4_1__) || defined(WEBP_MSC_SSE41)) && \
|
|
||||||
(!defined(HAVE_CONFIG_H) || defined(WEBP_HAVE_SSE41))
|
|
||||||
#define WEBP_USE_SSE41
|
#define WEBP_USE_SSE41
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(WEBP_USE_SSE41) && !defined(WEBP_HAVE_SSE41)
|
|
||||||
#define WEBP_HAVE_SSE41
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#undef WEBP_MSC_SSE41
|
|
||||||
#undef WEBP_MSC_SSE2
|
|
||||||
|
|
||||||
// The intrinsics currently cause compiler errors with arm-nacl-gcc and the
|
// The intrinsics currently cause compiler errors with arm-nacl-gcc and the
|
||||||
// inline assembly would need to be modified for use with Native Client.
|
// inline assembly would need to be modified for use with Native Client.
|
||||||
#if ((defined(__ARM_NEON__) || defined(__aarch64__)) && \
|
#if (defined(__ARM_NEON__) || \
|
||||||
(!defined(HAVE_CONFIG_H) || defined(WEBP_HAVE_NEON))) && \
|
defined(__aarch64__) || defined(WEBP_HAVE_NEON)) && \
|
||||||
!defined(__native_client__)
|
!defined(__native_client__)
|
||||||
#define WEBP_USE_NEON
|
#define WEBP_USE_NEON
|
||||||
#endif
|
#endif
|
||||||
@ -124,20 +90,11 @@ extern "C" {
|
|||||||
#define WEBP_USE_NEON
|
#define WEBP_USE_NEON
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Note: ARM64 is supported in Visual Studio 2017, but requires the direct
|
#if defined(_MSC_VER) && _MSC_VER >= 1700 && defined(_M_ARM)
|
||||||
// inclusion of arm64_neon.h; Visual Studio 2019 includes this file in
|
|
||||||
// arm_neon.h.
|
|
||||||
#if defined(_MSC_VER) && \
|
|
||||||
((_MSC_VER >= 1700 && defined(_M_ARM)) || \
|
|
||||||
(_MSC_VER >= 1920 && defined(_M_ARM64)))
|
|
||||||
#define WEBP_USE_NEON
|
#define WEBP_USE_NEON
|
||||||
#define WEBP_USE_INTRINSICS
|
#define WEBP_USE_INTRINSICS
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(WEBP_USE_NEON) && !defined(WEBP_HAVE_NEON)
|
|
||||||
#define WEBP_HAVE_NEON
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(__mips__) && !defined(__mips64) && \
|
#if defined(__mips__) && !defined(__mips64) && \
|
||||||
defined(__mips_isa_rev) && (__mips_isa_rev >= 1) && (__mips_isa_rev < 6)
|
defined(__mips_isa_rev) && (__mips_isa_rev >= 1) && (__mips_isa_rev < 6)
|
||||||
#define WEBP_USE_MIPS32
|
#define WEBP_USE_MIPS32
|
||||||
@ -153,11 +110,13 @@ extern "C" {
|
|||||||
#define WEBP_USE_MSA
|
#define WEBP_USE_MSA
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#endif /* EMSCRIPTEN */
|
||||||
|
|
||||||
#ifndef WEBP_DSP_OMIT_C_CODE
|
#ifndef WEBP_DSP_OMIT_C_CODE
|
||||||
#define WEBP_DSP_OMIT_C_CODE 1
|
#define WEBP_DSP_OMIT_C_CODE 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(WEBP_USE_NEON) && WEBP_DSP_OMIT_C_CODE
|
#if (defined(__aarch64__) || defined(__ARM_NEON__)) && WEBP_DSP_OMIT_C_CODE
|
||||||
#define WEBP_NEON_OMIT_C_CODE 1
|
#define WEBP_NEON_OMIT_C_CODE 1
|
||||||
#else
|
#else
|
||||||
#define WEBP_NEON_OMIT_C_CODE 0
|
#define WEBP_NEON_OMIT_C_CODE 0
|
||||||
@ -234,12 +193,6 @@ extern "C" {
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// If 'ptr' is NULL, returns NULL. Otherwise returns 'ptr + off'.
|
|
||||||
// Prevents undefined behavior sanitizer nullptr-with-nonzero-offset warning.
|
|
||||||
#if !defined(WEBP_OFFSET_PTR)
|
|
||||||
#define WEBP_OFFSET_PTR(ptr, off) (((ptr) == NULL) ? NULL : ((ptr) + (off)))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Regularize the definition of WEBP_SWAP_16BIT_CSP (backward compatibility)
|
// Regularize the definition of WEBP_SWAP_16BIT_CSP (backward compatibility)
|
||||||
#if !defined(WEBP_SWAP_16BIT_CSP)
|
#if !defined(WEBP_SWAP_16BIT_CSP)
|
||||||
#define WEBP_SWAP_16BIT_CSP 0
|
#define WEBP_SWAP_16BIT_CSP 0
|
||||||
@ -262,8 +215,7 @@ typedef enum {
|
|||||||
kNEON,
|
kNEON,
|
||||||
kMIPS32,
|
kMIPS32,
|
||||||
kMIPSdspR2,
|
kMIPSdspR2,
|
||||||
kMSA,
|
kMSA
|
||||||
kWasmSIMD
|
|
||||||
} CPUFeature;
|
} CPUFeature;
|
||||||
// returns true if the CPU supports the feature.
|
// returns true if the CPU supports the feature.
|
||||||
typedef int (*VP8CPUInfo)(CPUFeature feature);
|
typedef int (*VP8CPUInfo)(CPUFeature feature);
|
||||||
@ -294,9 +246,9 @@ extern VP8Fdct VP8FTransform2; // performs two transforms at a time
|
|||||||
extern VP8WHT VP8FTransformWHT;
|
extern VP8WHT VP8FTransformWHT;
|
||||||
// Predictions
|
// Predictions
|
||||||
// *dst is the destination block. *top and *left can be NULL.
|
// *dst is the destination block. *top and *left can be NULL.
|
||||||
typedef void (*VP8IntraPreds)(uint8_t* dst, const uint8_t* left,
|
typedef void (*VP8IntraPreds)(uint8_t *dst, const uint8_t* left,
|
||||||
const uint8_t* top);
|
const uint8_t* top);
|
||||||
typedef void (*VP8Intra4Preds)(uint8_t* dst, const uint8_t* top);
|
typedef void (*VP8Intra4Preds)(uint8_t *dst, const uint8_t* top);
|
||||||
extern VP8Intra4Preds VP8EncPredLuma4;
|
extern VP8Intra4Preds VP8EncPredLuma4;
|
||||||
extern VP8IntraPreds VP8EncPredLuma16;
|
extern VP8IntraPreds VP8EncPredLuma16;
|
||||||
extern VP8IntraPreds VP8EncPredChroma8;
|
extern VP8IntraPreds VP8EncPredChroma8;
|
||||||
@ -620,29 +572,26 @@ extern void (*WebPApplyAlphaMultiply4444)(
|
|||||||
|
|
||||||
// Dispatch the values from alpha[] plane to the ARGB destination 'dst'.
|
// Dispatch the values from alpha[] plane to the ARGB destination 'dst'.
|
||||||
// Returns true if alpha[] plane has non-trivial values different from 0xff.
|
// Returns true if alpha[] plane has non-trivial values different from 0xff.
|
||||||
extern int (*WebPDispatchAlpha)(const uint8_t* WEBP_RESTRICT alpha,
|
extern int (*WebPDispatchAlpha)(const uint8_t* alpha, int alpha_stride,
|
||||||
int alpha_stride, int width, int height,
|
int width, int height,
|
||||||
uint8_t* WEBP_RESTRICT dst, int dst_stride);
|
uint8_t* dst, int dst_stride);
|
||||||
|
|
||||||
// Transfer packed 8b alpha[] values to green channel in dst[], zero'ing the
|
// Transfer packed 8b alpha[] values to green channel in dst[], zero'ing the
|
||||||
// A/R/B values. 'dst_stride' is the stride for dst[] in uint32_t units.
|
// A/R/B values. 'dst_stride' is the stride for dst[] in uint32_t units.
|
||||||
extern void (*WebPDispatchAlphaToGreen)(const uint8_t* WEBP_RESTRICT alpha,
|
extern void (*WebPDispatchAlphaToGreen)(const uint8_t* alpha, int alpha_stride,
|
||||||
int alpha_stride, int width, int height,
|
int width, int height,
|
||||||
uint32_t* WEBP_RESTRICT dst,
|
uint32_t* dst, int dst_stride);
|
||||||
int dst_stride);
|
|
||||||
|
|
||||||
// Extract the alpha values from 32b values in argb[] and pack them into alpha[]
|
// Extract the alpha values from 32b values in argb[] and pack them into alpha[]
|
||||||
// (this is the opposite of WebPDispatchAlpha).
|
// (this is the opposite of WebPDispatchAlpha).
|
||||||
// Returns true if there's only trivial 0xff alpha values.
|
// Returns true if there's only trivial 0xff alpha values.
|
||||||
extern int (*WebPExtractAlpha)(const uint8_t* WEBP_RESTRICT argb,
|
extern int (*WebPExtractAlpha)(const uint8_t* argb, int argb_stride,
|
||||||
int argb_stride, int width, int height,
|
int width, int height,
|
||||||
uint8_t* WEBP_RESTRICT alpha,
|
uint8_t* alpha, int alpha_stride);
|
||||||
int alpha_stride);
|
|
||||||
|
|
||||||
// Extract the green values from 32b values in argb[] and pack them into alpha[]
|
// Extract the green values from 32b values in argb[] and pack them into alpha[]
|
||||||
// (this is the opposite of WebPDispatchAlphaToGreen).
|
// (this is the opposite of WebPDispatchAlphaToGreen).
|
||||||
extern void (*WebPExtractGreen)(const uint32_t* WEBP_RESTRICT argb,
|
extern void (*WebPExtractGreen)(const uint32_t* argb, uint8_t* alpha, int size);
|
||||||
uint8_t* WEBP_RESTRICT alpha, int size);
|
|
||||||
|
|
||||||
// Pre-Multiply operation transforms x into x * A / 255 (where x=Y,R,G or B).
|
// Pre-Multiply operation transforms x into x * A / 255 (where x=Y,R,G or B).
|
||||||
// Un-Multiply operation transforms x into x * 255 / A.
|
// Un-Multiply operation transforms x into x * 255 / A.
|
||||||
@ -655,42 +604,34 @@ void WebPMultARGBRows(uint8_t* ptr, int stride, int width, int num_rows,
|
|||||||
int inverse);
|
int inverse);
|
||||||
|
|
||||||
// Same for a row of single values, with side alpha values.
|
// Same for a row of single values, with side alpha values.
|
||||||
extern void (*WebPMultRow)(uint8_t* WEBP_RESTRICT const ptr,
|
extern void (*WebPMultRow)(uint8_t* const ptr, const uint8_t* const alpha,
|
||||||
const uint8_t* WEBP_RESTRICT const alpha,
|
|
||||||
int width, int inverse);
|
int width, int inverse);
|
||||||
|
|
||||||
// Same a WebPMultRow(), but for several 'num_rows' rows.
|
// Same a WebPMultRow(), but for several 'num_rows' rows.
|
||||||
void WebPMultRows(uint8_t* WEBP_RESTRICT ptr, int stride,
|
void WebPMultRows(uint8_t* ptr, int stride,
|
||||||
const uint8_t* WEBP_RESTRICT alpha, int alpha_stride,
|
const uint8_t* alpha, int alpha_stride,
|
||||||
int width, int num_rows, int inverse);
|
int width, int num_rows, int inverse);
|
||||||
|
|
||||||
// Plain-C versions, used as fallback by some implementations.
|
// Plain-C versions, used as fallback by some implementations.
|
||||||
void WebPMultRow_C(uint8_t* WEBP_RESTRICT const ptr,
|
void WebPMultRow_C(uint8_t* const ptr, const uint8_t* const alpha,
|
||||||
const uint8_t* WEBP_RESTRICT const alpha,
|
|
||||||
int width, int inverse);
|
int width, int inverse);
|
||||||
void WebPMultARGBRow_C(uint32_t* const ptr, int width, int inverse);
|
void WebPMultARGBRow_C(uint32_t* const ptr, int width, int inverse);
|
||||||
|
|
||||||
#ifdef WORDS_BIGENDIAN
|
#ifdef WORDS_BIGENDIAN
|
||||||
// ARGB packing function: a/r/g/b input is rgba or bgra order.
|
// ARGB packing function: a/r/g/b input is rgba or bgra order.
|
||||||
extern void (*WebPPackARGB)(const uint8_t* WEBP_RESTRICT a,
|
extern void (*WebPPackARGB)(const uint8_t* a, const uint8_t* r,
|
||||||
const uint8_t* WEBP_RESTRICT r,
|
const uint8_t* g, const uint8_t* b, int len,
|
||||||
const uint8_t* WEBP_RESTRICT g,
|
uint32_t* out);
|
||||||
const uint8_t* WEBP_RESTRICT b,
|
|
||||||
int len, uint32_t* WEBP_RESTRICT out);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// RGB packing function. 'step' can be 3 or 4. r/g/b input is rgb or bgr order.
|
// RGB packing function. 'step' can be 3 or 4. r/g/b input is rgb or bgr order.
|
||||||
extern void (*WebPPackRGB)(const uint8_t* WEBP_RESTRICT r,
|
extern void (*WebPPackRGB)(const uint8_t* r, const uint8_t* g, const uint8_t* b,
|
||||||
const uint8_t* WEBP_RESTRICT g,
|
int len, int step, uint32_t* out);
|
||||||
const uint8_t* WEBP_RESTRICT b,
|
|
||||||
int len, int step, uint32_t* WEBP_RESTRICT out);
|
|
||||||
|
|
||||||
// This function returns true if src[i] contains a value different from 0xff.
|
// This function returns true if src[i] contains a value different from 0xff.
|
||||||
extern int (*WebPHasAlpha8b)(const uint8_t* src, int length);
|
extern int (*WebPHasAlpha8b)(const uint8_t* src, int length);
|
||||||
// This function returns true if src[4*i] contains a value different from 0xff.
|
// This function returns true if src[4*i] contains a value different from 0xff.
|
||||||
extern int (*WebPHasAlpha32b)(const uint8_t* src, int length);
|
extern int (*WebPHasAlpha32b)(const uint8_t* src, int length);
|
||||||
// replaces transparent values in src[] by 'color'.
|
|
||||||
extern void (*WebPAlphaReplace)(uint32_t* src, int length, uint32_t color);
|
|
||||||
|
|
||||||
// To be called first before using the above.
|
// To be called first before using the above.
|
||||||
void WebPInitAlphaProcessing(void);
|
void WebPInitAlphaProcessing(void);
|
||||||
|
@ -773,10 +773,10 @@ WEBP_DSP_INIT_FUNC(VP8EncDspInit) {
|
|||||||
|
|
||||||
// If defined, use CPUInfo() to overwrite some pointers with faster versions.
|
// If defined, use CPUInfo() to overwrite some pointers with faster versions.
|
||||||
if (VP8GetCPUInfo != NULL) {
|
if (VP8GetCPUInfo != NULL) {
|
||||||
#if defined(WEBP_HAVE_SSE2)
|
#if defined(WEBP_USE_SSE2)
|
||||||
if (VP8GetCPUInfo(kSSE2)) {
|
if (VP8GetCPUInfo(kSSE2)) {
|
||||||
VP8EncDspInitSSE2();
|
VP8EncDspInitSSE2();
|
||||||
#if defined(WEBP_HAVE_SSE41)
|
#if defined(WEBP_USE_SSE41)
|
||||||
if (VP8GetCPUInfo(kSSE4_1)) {
|
if (VP8GetCPUInfo(kSSE4_1)) {
|
||||||
VP8EncDspInitSSE41();
|
VP8EncDspInitSSE41();
|
||||||
}
|
}
|
||||||
@ -800,7 +800,7 @@ WEBP_DSP_INIT_FUNC(VP8EncDspInit) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(WEBP_HAVE_NEON)
|
#if defined(WEBP_USE_NEON)
|
||||||
if (WEBP_NEON_OMIT_C_CODE ||
|
if (WEBP_NEON_OMIT_C_CODE ||
|
||||||
(VP8GetCPUInfo != NULL && VP8GetCPUInfo(kNEON))) {
|
(VP8GetCPUInfo != NULL && VP8GetCPUInfo(kNEON))) {
|
||||||
VP8EncDspInitNEON();
|
VP8EncDspInitNEON();
|
||||||
|
@ -254,7 +254,7 @@ WEBP_DSP_INIT_FUNC(VP8FiltersInit) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (VP8GetCPUInfo != NULL) {
|
if (VP8GetCPUInfo != NULL) {
|
||||||
#if defined(WEBP_HAVE_SSE2)
|
#if defined(WEBP_USE_SSE2)
|
||||||
if (VP8GetCPUInfo(kSSE2)) {
|
if (VP8GetCPUInfo(kSSE2)) {
|
||||||
VP8FiltersInitSSE2();
|
VP8FiltersInitSSE2();
|
||||||
}
|
}
|
||||||
@ -271,7 +271,7 @@ WEBP_DSP_INIT_FUNC(VP8FiltersInit) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(WEBP_HAVE_NEON)
|
#if defined(WEBP_USE_NEON)
|
||||||
if (WEBP_NEON_OMIT_C_CODE ||
|
if (WEBP_NEON_OMIT_C_CODE ||
|
||||||
(VP8GetCPUInfo != NULL && VP8GetCPUInfo(kNEON))) {
|
(VP8GetCPUInfo != NULL && VP8GetCPUInfo(kNEON))) {
|
||||||
VP8FiltersInitNEON();
|
VP8FiltersInitNEON();
|
||||||
|
@ -320,12 +320,7 @@ extern void VP8FiltersInitSSE2(void);
|
|||||||
|
|
||||||
WEBP_TSAN_IGNORE_FUNCTION void VP8FiltersInitSSE2(void) {
|
WEBP_TSAN_IGNORE_FUNCTION void VP8FiltersInitSSE2(void) {
|
||||||
WebPUnfilters[WEBP_FILTER_HORIZONTAL] = HorizontalUnfilter_SSE2;
|
WebPUnfilters[WEBP_FILTER_HORIZONTAL] = HorizontalUnfilter_SSE2;
|
||||||
#if defined(CHROMIUM)
|
|
||||||
// TODO(crbug.com/654974)
|
|
||||||
(void)VerticalUnfilter_SSE2;
|
|
||||||
#else
|
|
||||||
WebPUnfilters[WEBP_FILTER_VERTICAL] = VerticalUnfilter_SSE2;
|
WebPUnfilters[WEBP_FILTER_VERTICAL] = VerticalUnfilter_SSE2;
|
||||||
#endif
|
|
||||||
WebPUnfilters[WEBP_FILTER_GRADIENT] = GradientUnfilter_SSE2;
|
WebPUnfilters[WEBP_FILTER_GRADIENT] = GradientUnfilter_SSE2;
|
||||||
|
|
||||||
WebPFilters[WEBP_FILTER_HORIZONTAL] = HorizontalFilter_SSE2;
|
WebPFilters[WEBP_FILTER_HORIZONTAL] = HorizontalFilter_SSE2;
|
||||||
|
@ -81,7 +81,7 @@ static WEBP_INLINE uint32_t ClampedAddSubtractHalf(uint32_t c0, uint32_t c1,
|
|||||||
|
|
||||||
// gcc <= 4.9 on ARM generates incorrect code in Select() when Sub3() is
|
// gcc <= 4.9 on ARM generates incorrect code in Select() when Sub3() is
|
||||||
// inlined.
|
// inlined.
|
||||||
#if defined(__arm__) && defined(__GNUC__) && LOCAL_GCC_VERSION <= 0x409
|
#if defined(__arm__) && LOCAL_GCC_VERSION <= 0x409
|
||||||
# define LOCAL_INLINE __attribute__ ((noinline))
|
# define LOCAL_INLINE __attribute__ ((noinline))
|
||||||
#else
|
#else
|
||||||
# define LOCAL_INLINE WEBP_INLINE
|
# define LOCAL_INLINE WEBP_INLINE
|
||||||
@ -107,93 +107,88 @@ static WEBP_INLINE uint32_t Select(uint32_t a, uint32_t b, uint32_t c) {
|
|||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Predictors
|
// Predictors
|
||||||
|
|
||||||
uint32_t VP8LPredictor0_C(uint32_t left, const uint32_t* const top) {
|
static uint32_t Predictor0_C(uint32_t left, const uint32_t* const top) {
|
||||||
(void)top;
|
(void)top;
|
||||||
(void)left;
|
(void)left;
|
||||||
return ARGB_BLACK;
|
return ARGB_BLACK;
|
||||||
}
|
}
|
||||||
uint32_t VP8LPredictor1_C(uint32_t left, const uint32_t* const top) {
|
static uint32_t Predictor1_C(uint32_t left, const uint32_t* const top) {
|
||||||
(void)top;
|
(void)top;
|
||||||
return left;
|
return left;
|
||||||
}
|
}
|
||||||
uint32_t VP8LPredictor2_C(uint32_t left, const uint32_t* const top) {
|
static uint32_t Predictor2_C(uint32_t left, const uint32_t* const top) {
|
||||||
(void)left;
|
(void)left;
|
||||||
return top[0];
|
return top[0];
|
||||||
}
|
}
|
||||||
uint32_t VP8LPredictor3_C(uint32_t left, const uint32_t* const top) {
|
static uint32_t Predictor3_C(uint32_t left, const uint32_t* const top) {
|
||||||
(void)left;
|
(void)left;
|
||||||
return top[1];
|
return top[1];
|
||||||
}
|
}
|
||||||
uint32_t VP8LPredictor4_C(uint32_t left, const uint32_t* const top) {
|
static uint32_t Predictor4_C(uint32_t left, const uint32_t* const top) {
|
||||||
(void)left;
|
(void)left;
|
||||||
return top[-1];
|
return top[-1];
|
||||||
}
|
}
|
||||||
uint32_t VP8LPredictor5_C(uint32_t left, const uint32_t* const top) {
|
static uint32_t Predictor5_C(uint32_t left, const uint32_t* const top) {
|
||||||
const uint32_t pred = Average3(left, top[0], top[1]);
|
const uint32_t pred = Average3(left, top[0], top[1]);
|
||||||
return pred;
|
return pred;
|
||||||
}
|
}
|
||||||
uint32_t VP8LPredictor6_C(uint32_t left, const uint32_t* const top) {
|
static uint32_t Predictor6_C(uint32_t left, const uint32_t* const top) {
|
||||||
const uint32_t pred = Average2(left, top[-1]);
|
const uint32_t pred = Average2(left, top[-1]);
|
||||||
return pred;
|
return pred;
|
||||||
}
|
}
|
||||||
uint32_t VP8LPredictor7_C(uint32_t left, const uint32_t* const top) {
|
static uint32_t Predictor7_C(uint32_t left, const uint32_t* const top) {
|
||||||
const uint32_t pred = Average2(left, top[0]);
|
const uint32_t pred = Average2(left, top[0]);
|
||||||
return pred;
|
return pred;
|
||||||
}
|
}
|
||||||
uint32_t VP8LPredictor8_C(uint32_t left, const uint32_t* const top) {
|
static uint32_t Predictor8_C(uint32_t left, const uint32_t* const top) {
|
||||||
const uint32_t pred = Average2(top[-1], top[0]);
|
const uint32_t pred = Average2(top[-1], top[0]);
|
||||||
(void)left;
|
(void)left;
|
||||||
return pred;
|
return pred;
|
||||||
}
|
}
|
||||||
uint32_t VP8LPredictor9_C(uint32_t left, const uint32_t* const top) {
|
static uint32_t Predictor9_C(uint32_t left, const uint32_t* const top) {
|
||||||
const uint32_t pred = Average2(top[0], top[1]);
|
const uint32_t pred = Average2(top[0], top[1]);
|
||||||
(void)left;
|
(void)left;
|
||||||
return pred;
|
return pred;
|
||||||
}
|
}
|
||||||
uint32_t VP8LPredictor10_C(uint32_t left, const uint32_t* const top) {
|
static uint32_t Predictor10_C(uint32_t left, const uint32_t* const top) {
|
||||||
const uint32_t pred = Average4(left, top[-1], top[0], top[1]);
|
const uint32_t pred = Average4(left, top[-1], top[0], top[1]);
|
||||||
return pred;
|
return pred;
|
||||||
}
|
}
|
||||||
uint32_t VP8LPredictor11_C(uint32_t left, const uint32_t* const top) {
|
static uint32_t Predictor11_C(uint32_t left, const uint32_t* const top) {
|
||||||
const uint32_t pred = Select(top[0], left, top[-1]);
|
const uint32_t pred = Select(top[0], left, top[-1]);
|
||||||
return pred;
|
return pred;
|
||||||
}
|
}
|
||||||
uint32_t VP8LPredictor12_C(uint32_t left, const uint32_t* const top) {
|
static uint32_t Predictor12_C(uint32_t left, const uint32_t* const top) {
|
||||||
const uint32_t pred = ClampedAddSubtractFull(left, top[0], top[-1]);
|
const uint32_t pred = ClampedAddSubtractFull(left, top[0], top[-1]);
|
||||||
return pred;
|
return pred;
|
||||||
}
|
}
|
||||||
uint32_t VP8LPredictor13_C(uint32_t left, const uint32_t* const top) {
|
static uint32_t Predictor13_C(uint32_t left, const uint32_t* const top) {
|
||||||
const uint32_t pred = ClampedAddSubtractHalf(left, top[0], top[-1]);
|
const uint32_t pred = ClampedAddSubtractHalf(left, top[0], top[-1]);
|
||||||
return pred;
|
return pred;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void PredictorAdd0_C(const uint32_t* in, const uint32_t* upper,
|
GENERATE_PREDICTOR_ADD(Predictor0_C, PredictorAdd0_C)
|
||||||
int num_pixels, uint32_t* out) {
|
|
||||||
int x;
|
|
||||||
(void)upper;
|
|
||||||
for (x = 0; x < num_pixels; ++x) out[x] = VP8LAddPixels(in[x], ARGB_BLACK);
|
|
||||||
}
|
|
||||||
static void PredictorAdd1_C(const uint32_t* in, const uint32_t* upper,
|
static void PredictorAdd1_C(const uint32_t* in, const uint32_t* upper,
|
||||||
int num_pixels, uint32_t* out) {
|
int num_pixels, uint32_t* out) {
|
||||||
int i;
|
int i;
|
||||||
uint32_t left = out[-1];
|
uint32_t left = out[-1];
|
||||||
(void)upper;
|
|
||||||
for (i = 0; i < num_pixels; ++i) {
|
for (i = 0; i < num_pixels; ++i) {
|
||||||
out[i] = left = VP8LAddPixels(in[i], left);
|
out[i] = left = VP8LAddPixels(in[i], left);
|
||||||
}
|
}
|
||||||
|
(void)upper;
|
||||||
}
|
}
|
||||||
GENERATE_PREDICTOR_ADD(VP8LPredictor2_C, PredictorAdd2_C)
|
GENERATE_PREDICTOR_ADD(Predictor2_C, PredictorAdd2_C)
|
||||||
GENERATE_PREDICTOR_ADD(VP8LPredictor3_C, PredictorAdd3_C)
|
GENERATE_PREDICTOR_ADD(Predictor3_C, PredictorAdd3_C)
|
||||||
GENERATE_PREDICTOR_ADD(VP8LPredictor4_C, PredictorAdd4_C)
|
GENERATE_PREDICTOR_ADD(Predictor4_C, PredictorAdd4_C)
|
||||||
GENERATE_PREDICTOR_ADD(VP8LPredictor5_C, PredictorAdd5_C)
|
GENERATE_PREDICTOR_ADD(Predictor5_C, PredictorAdd5_C)
|
||||||
GENERATE_PREDICTOR_ADD(VP8LPredictor6_C, PredictorAdd6_C)
|
GENERATE_PREDICTOR_ADD(Predictor6_C, PredictorAdd6_C)
|
||||||
GENERATE_PREDICTOR_ADD(VP8LPredictor7_C, PredictorAdd7_C)
|
GENERATE_PREDICTOR_ADD(Predictor7_C, PredictorAdd7_C)
|
||||||
GENERATE_PREDICTOR_ADD(VP8LPredictor8_C, PredictorAdd8_C)
|
GENERATE_PREDICTOR_ADD(Predictor8_C, PredictorAdd8_C)
|
||||||
GENERATE_PREDICTOR_ADD(VP8LPredictor9_C, PredictorAdd9_C)
|
GENERATE_PREDICTOR_ADD(Predictor9_C, PredictorAdd9_C)
|
||||||
GENERATE_PREDICTOR_ADD(VP8LPredictor10_C, PredictorAdd10_C)
|
GENERATE_PREDICTOR_ADD(Predictor10_C, PredictorAdd10_C)
|
||||||
GENERATE_PREDICTOR_ADD(VP8LPredictor11_C, PredictorAdd11_C)
|
GENERATE_PREDICTOR_ADD(Predictor11_C, PredictorAdd11_C)
|
||||||
GENERATE_PREDICTOR_ADD(VP8LPredictor12_C, PredictorAdd12_C)
|
GENERATE_PREDICTOR_ADD(Predictor12_C, PredictorAdd12_C)
|
||||||
GENERATE_PREDICTOR_ADD(VP8LPredictor13_C, PredictorAdd13_C)
|
GENERATE_PREDICTOR_ADD(Predictor13_C, PredictorAdd13_C)
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
@ -562,6 +557,7 @@ VP8LPredictorFunc VP8LPredictors[16];
|
|||||||
|
|
||||||
// exposed plain-C implementations
|
// exposed plain-C implementations
|
||||||
VP8LPredictorAddSubFunc VP8LPredictorsAdd_C[16];
|
VP8LPredictorAddSubFunc VP8LPredictorsAdd_C[16];
|
||||||
|
VP8LPredictorFunc VP8LPredictors_C[16];
|
||||||
|
|
||||||
VP8LTransformColorInverseFunc VP8LTransformColorInverse;
|
VP8LTransformColorInverseFunc VP8LTransformColorInverse;
|
||||||
|
|
||||||
@ -575,7 +571,6 @@ VP8LMapARGBFunc VP8LMapColor32b;
|
|||||||
VP8LMapAlphaFunc VP8LMapColor8b;
|
VP8LMapAlphaFunc VP8LMapColor8b;
|
||||||
|
|
||||||
extern void VP8LDspInitSSE2(void);
|
extern void VP8LDspInitSSE2(void);
|
||||||
extern void VP8LDspInitSSE41(void);
|
|
||||||
extern void VP8LDspInitNEON(void);
|
extern void VP8LDspInitNEON(void);
|
||||||
extern void VP8LDspInitMIPSdspR2(void);
|
extern void VP8LDspInitMIPSdspR2(void);
|
||||||
extern void VP8LDspInitMSA(void);
|
extern void VP8LDspInitMSA(void);
|
||||||
@ -600,7 +595,8 @@ extern void VP8LDspInitMSA(void);
|
|||||||
} while (0);
|
} while (0);
|
||||||
|
|
||||||
WEBP_DSP_INIT_FUNC(VP8LDspInit) {
|
WEBP_DSP_INIT_FUNC(VP8LDspInit) {
|
||||||
COPY_PREDICTOR_ARRAY(VP8LPredictor, VP8LPredictors)
|
COPY_PREDICTOR_ARRAY(Predictor, VP8LPredictors)
|
||||||
|
COPY_PREDICTOR_ARRAY(Predictor, VP8LPredictors_C)
|
||||||
COPY_PREDICTOR_ARRAY(PredictorAdd, VP8LPredictorsAdd)
|
COPY_PREDICTOR_ARRAY(PredictorAdd, VP8LPredictorsAdd)
|
||||||
COPY_PREDICTOR_ARRAY(PredictorAdd, VP8LPredictorsAdd_C)
|
COPY_PREDICTOR_ARRAY(PredictorAdd, VP8LPredictorsAdd_C)
|
||||||
|
|
||||||
@ -622,14 +618,9 @@ WEBP_DSP_INIT_FUNC(VP8LDspInit) {
|
|||||||
|
|
||||||
// If defined, use CPUInfo() to overwrite some pointers with faster versions.
|
// If defined, use CPUInfo() to overwrite some pointers with faster versions.
|
||||||
if (VP8GetCPUInfo != NULL) {
|
if (VP8GetCPUInfo != NULL) {
|
||||||
#if defined(WEBP_HAVE_SSE2)
|
#if defined(WEBP_USE_SSE2)
|
||||||
if (VP8GetCPUInfo(kSSE2)) {
|
if (VP8GetCPUInfo(kSSE2)) {
|
||||||
VP8LDspInitSSE2();
|
VP8LDspInitSSE2();
|
||||||
#if defined(WEBP_HAVE_SSE41)
|
|
||||||
if (VP8GetCPUInfo(kSSE4_1)) {
|
|
||||||
VP8LDspInitSSE41();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#if defined(WEBP_USE_MIPS_DSP_R2)
|
#if defined(WEBP_USE_MIPS_DSP_R2)
|
||||||
@ -644,7 +635,7 @@ WEBP_DSP_INIT_FUNC(VP8LDspInit) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(WEBP_HAVE_NEON)
|
#if defined(WEBP_USE_NEON)
|
||||||
if (WEBP_NEON_OMIT_C_CODE ||
|
if (WEBP_NEON_OMIT_C_CODE ||
|
||||||
(VP8GetCPUInfo != NULL && VP8GetCPUInfo(kNEON))) {
|
(VP8GetCPUInfo != NULL && VP8GetCPUInfo(kNEON))) {
|
||||||
VP8LDspInitNEON();
|
VP8LDspInitNEON();
|
||||||
|
@ -30,22 +30,7 @@ extern "C" {
|
|||||||
|
|
||||||
typedef uint32_t (*VP8LPredictorFunc)(uint32_t left, const uint32_t* const top);
|
typedef uint32_t (*VP8LPredictorFunc)(uint32_t left, const uint32_t* const top);
|
||||||
extern VP8LPredictorFunc VP8LPredictors[16];
|
extern VP8LPredictorFunc VP8LPredictors[16];
|
||||||
|
extern VP8LPredictorFunc VP8LPredictors_C[16];
|
||||||
uint32_t VP8LPredictor0_C(uint32_t left, const uint32_t* const top);
|
|
||||||
uint32_t VP8LPredictor1_C(uint32_t left, const uint32_t* const top);
|
|
||||||
uint32_t VP8LPredictor2_C(uint32_t left, const uint32_t* const top);
|
|
||||||
uint32_t VP8LPredictor3_C(uint32_t left, const uint32_t* const top);
|
|
||||||
uint32_t VP8LPredictor4_C(uint32_t left, const uint32_t* const top);
|
|
||||||
uint32_t VP8LPredictor5_C(uint32_t left, const uint32_t* const top);
|
|
||||||
uint32_t VP8LPredictor6_C(uint32_t left, const uint32_t* const top);
|
|
||||||
uint32_t VP8LPredictor7_C(uint32_t left, const uint32_t* const top);
|
|
||||||
uint32_t VP8LPredictor8_C(uint32_t left, const uint32_t* const top);
|
|
||||||
uint32_t VP8LPredictor9_C(uint32_t left, const uint32_t* const top);
|
|
||||||
uint32_t VP8LPredictor10_C(uint32_t left, const uint32_t* const top);
|
|
||||||
uint32_t VP8LPredictor11_C(uint32_t left, const uint32_t* const top);
|
|
||||||
uint32_t VP8LPredictor12_C(uint32_t left, const uint32_t* const top);
|
|
||||||
uint32_t VP8LPredictor13_C(uint32_t left, const uint32_t* const top);
|
|
||||||
|
|
||||||
// These Add/Sub function expects upper[-1] and out[-1] to be readable.
|
// These Add/Sub function expects upper[-1] and out[-1] to be readable.
|
||||||
typedef void (*VP8LPredictorAddSubFunc)(const uint32_t* in,
|
typedef void (*VP8LPredictorAddSubFunc)(const uint32_t* in,
|
||||||
const uint32_t* upper, int num_pixels,
|
const uint32_t* upper, int num_pixels,
|
||||||
|
@ -177,13 +177,24 @@ uint32_t VP8LSubPixels(uint32_t a, uint32_t b) {
|
|||||||
static void PREDICTOR_ADD(const uint32_t* in, const uint32_t* upper, \
|
static void PREDICTOR_ADD(const uint32_t* in, const uint32_t* upper, \
|
||||||
int num_pixels, uint32_t* out) { \
|
int num_pixels, uint32_t* out) { \
|
||||||
int x; \
|
int x; \
|
||||||
assert(upper != NULL); \
|
|
||||||
for (x = 0; x < num_pixels; ++x) { \
|
for (x = 0; x < num_pixels; ++x) { \
|
||||||
const uint32_t pred = (PREDICTOR)(out[x - 1], upper + x); \
|
const uint32_t pred = (PREDICTOR)(out[x - 1], upper + x); \
|
||||||
out[x] = VP8LAddPixels(in[x], pred); \
|
out[x] = VP8LAddPixels(in[x], pred); \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// It subtracts the prediction from the input pixel and stores the residual
|
||||||
|
// in the output pixel.
|
||||||
|
#define GENERATE_PREDICTOR_SUB(PREDICTOR, PREDICTOR_SUB) \
|
||||||
|
static void PREDICTOR_SUB(const uint32_t* in, const uint32_t* upper, \
|
||||||
|
int num_pixels, uint32_t* out) { \
|
||||||
|
int x; \
|
||||||
|
for (x = 0; x < num_pixels; ++x) { \
|
||||||
|
const uint32_t pred = (PREDICTOR)(in[x - 1], upper + x); \
|
||||||
|
out[x] = VP8LSubPixels(in[x], pred); \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} // extern "C"
|
} // extern "C"
|
||||||
#endif
|
#endif
|
||||||
|
@ -329,15 +329,6 @@ const uint8_t kPrefixEncodeExtraBitsValue[PREFIX_LOOKUP_IDX_MAX] = {
|
|||||||
static float FastSLog2Slow_C(uint32_t v) {
|
static float FastSLog2Slow_C(uint32_t v) {
|
||||||
assert(v >= LOG_LOOKUP_IDX_MAX);
|
assert(v >= LOG_LOOKUP_IDX_MAX);
|
||||||
if (v < APPROX_LOG_WITH_CORRECTION_MAX) {
|
if (v < APPROX_LOG_WITH_CORRECTION_MAX) {
|
||||||
#if !defined(WEBP_HAVE_SLOW_CLZ_CTZ)
|
|
||||||
// use clz if available
|
|
||||||
const int log_cnt = BitsLog2Floor(v) - 7;
|
|
||||||
const uint32_t y = 1 << log_cnt;
|
|
||||||
int correction = 0;
|
|
||||||
const float v_f = (float)v;
|
|
||||||
const uint32_t orig_v = v;
|
|
||||||
v >>= log_cnt;
|
|
||||||
#else
|
|
||||||
int log_cnt = 0;
|
int log_cnt = 0;
|
||||||
uint32_t y = 1;
|
uint32_t y = 1;
|
||||||
int correction = 0;
|
int correction = 0;
|
||||||
@ -348,7 +339,6 @@ static float FastSLog2Slow_C(uint32_t v) {
|
|||||||
v = v >> 1;
|
v = v >> 1;
|
||||||
y = y << 1;
|
y = y << 1;
|
||||||
} while (v >= LOG_LOOKUP_IDX_MAX);
|
} while (v >= LOG_LOOKUP_IDX_MAX);
|
||||||
#endif
|
|
||||||
// vf = (2^log_cnt) * Xf; where y = 2^log_cnt and Xf < 256
|
// vf = (2^log_cnt) * Xf; where y = 2^log_cnt and Xf < 256
|
||||||
// Xf = floor(Xf) * (1 + (v % y) / v)
|
// Xf = floor(Xf) * (1 + (v % y) / v)
|
||||||
// log2(Xf) = log2(floor(Xf)) + log2(1 + (v % y) / v)
|
// log2(Xf) = log2(floor(Xf)) + log2(1 + (v % y) / v)
|
||||||
@ -365,14 +355,6 @@ static float FastSLog2Slow_C(uint32_t v) {
|
|||||||
static float FastLog2Slow_C(uint32_t v) {
|
static float FastLog2Slow_C(uint32_t v) {
|
||||||
assert(v >= LOG_LOOKUP_IDX_MAX);
|
assert(v >= LOG_LOOKUP_IDX_MAX);
|
||||||
if (v < APPROX_LOG_WITH_CORRECTION_MAX) {
|
if (v < APPROX_LOG_WITH_CORRECTION_MAX) {
|
||||||
#if !defined(WEBP_HAVE_SLOW_CLZ_CTZ)
|
|
||||||
// use clz if available
|
|
||||||
const int log_cnt = BitsLog2Floor(v) - 7;
|
|
||||||
const uint32_t y = 1 << log_cnt;
|
|
||||||
const uint32_t orig_v = v;
|
|
||||||
double log_2;
|
|
||||||
v >>= log_cnt;
|
|
||||||
#else
|
|
||||||
int log_cnt = 0;
|
int log_cnt = 0;
|
||||||
uint32_t y = 1;
|
uint32_t y = 1;
|
||||||
const uint32_t orig_v = v;
|
const uint32_t orig_v = v;
|
||||||
@ -382,7 +364,6 @@ static float FastLog2Slow_C(uint32_t v) {
|
|||||||
v = v >> 1;
|
v = v >> 1;
|
||||||
y = y << 1;
|
y = y << 1;
|
||||||
} while (v >= LOG_LOOKUP_IDX_MAX);
|
} while (v >= LOG_LOOKUP_IDX_MAX);
|
||||||
#endif
|
|
||||||
log_2 = kLog2Table[v] + log_cnt;
|
log_2 = kLog2Table[v] + log_cnt;
|
||||||
if (orig_v >= APPROX_LOG_MAX) {
|
if (orig_v >= APPROX_LOG_MAX) {
|
||||||
// Since the division is still expensive, add this correction factor only
|
// Since the division is still expensive, add this correction factor only
|
||||||
@ -721,6 +702,140 @@ void VP8LHistogramAdd(const VP8LHistogram* const a,
|
|||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Image transforms.
|
// Image transforms.
|
||||||
|
|
||||||
|
static WEBP_INLINE uint32_t Average2(uint32_t a0, uint32_t a1) {
|
||||||
|
return (((a0 ^ a1) & 0xfefefefeu) >> 1) + (a0 & a1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static WEBP_INLINE uint32_t Average3(uint32_t a0, uint32_t a1, uint32_t a2) {
|
||||||
|
return Average2(Average2(a0, a2), a1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static WEBP_INLINE uint32_t Average4(uint32_t a0, uint32_t a1,
|
||||||
|
uint32_t a2, uint32_t a3) {
|
||||||
|
return Average2(Average2(a0, a1), Average2(a2, a3));
|
||||||
|
}
|
||||||
|
|
||||||
|
static WEBP_INLINE uint32_t Clip255(uint32_t a) {
|
||||||
|
if (a < 256) {
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
// return 0, when a is a negative integer.
|
||||||
|
// return 255, when a is positive.
|
||||||
|
return ~a >> 24;
|
||||||
|
}
|
||||||
|
|
||||||
|
static WEBP_INLINE int AddSubtractComponentFull(int a, int b, int c) {
|
||||||
|
return Clip255(a + b - c);
|
||||||
|
}
|
||||||
|
|
||||||
|
static WEBP_INLINE uint32_t ClampedAddSubtractFull(uint32_t c0, uint32_t c1,
|
||||||
|
uint32_t c2) {
|
||||||
|
const int a = AddSubtractComponentFull(c0 >> 24, c1 >> 24, c2 >> 24);
|
||||||
|
const int r = AddSubtractComponentFull((c0 >> 16) & 0xff,
|
||||||
|
(c1 >> 16) & 0xff,
|
||||||
|
(c2 >> 16) & 0xff);
|
||||||
|
const int g = AddSubtractComponentFull((c0 >> 8) & 0xff,
|
||||||
|
(c1 >> 8) & 0xff,
|
||||||
|
(c2 >> 8) & 0xff);
|
||||||
|
const int b = AddSubtractComponentFull(c0 & 0xff, c1 & 0xff, c2 & 0xff);
|
||||||
|
return ((uint32_t)a << 24) | (r << 16) | (g << 8) | b;
|
||||||
|
}
|
||||||
|
|
||||||
|
static WEBP_INLINE int AddSubtractComponentHalf(int a, int b) {
|
||||||
|
return Clip255(a + (a - b) / 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
static WEBP_INLINE uint32_t ClampedAddSubtractHalf(uint32_t c0, uint32_t c1,
|
||||||
|
uint32_t c2) {
|
||||||
|
const uint32_t ave = Average2(c0, c1);
|
||||||
|
const int a = AddSubtractComponentHalf(ave >> 24, c2 >> 24);
|
||||||
|
const int r = AddSubtractComponentHalf((ave >> 16) & 0xff, (c2 >> 16) & 0xff);
|
||||||
|
const int g = AddSubtractComponentHalf((ave >> 8) & 0xff, (c2 >> 8) & 0xff);
|
||||||
|
const int b = AddSubtractComponentHalf((ave >> 0) & 0xff, (c2 >> 0) & 0xff);
|
||||||
|
return ((uint32_t)a << 24) | (r << 16) | (g << 8) | b;
|
||||||
|
}
|
||||||
|
|
||||||
|
// gcc-4.9 on ARM generates incorrect code in Select() when Sub3() is inlined.
|
||||||
|
#if defined(__arm__) && \
|
||||||
|
(LOCAL_GCC_VERSION == 0x409 || LOCAL_GCC_VERSION == 0x408)
|
||||||
|
# define LOCAL_INLINE __attribute__ ((noinline))
|
||||||
|
#else
|
||||||
|
# define LOCAL_INLINE WEBP_INLINE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static LOCAL_INLINE int Sub3(int a, int b, int c) {
|
||||||
|
const int pb = b - c;
|
||||||
|
const int pa = a - c;
|
||||||
|
return abs(pb) - abs(pa);
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef LOCAL_INLINE
|
||||||
|
|
||||||
|
static WEBP_INLINE uint32_t Select(uint32_t a, uint32_t b, uint32_t c) {
|
||||||
|
const int pa_minus_pb =
|
||||||
|
Sub3((a >> 24) , (b >> 24) , (c >> 24) ) +
|
||||||
|
Sub3((a >> 16) & 0xff, (b >> 16) & 0xff, (c >> 16) & 0xff) +
|
||||||
|
Sub3((a >> 8) & 0xff, (b >> 8) & 0xff, (c >> 8) & 0xff) +
|
||||||
|
Sub3((a ) & 0xff, (b ) & 0xff, (c ) & 0xff);
|
||||||
|
return (pa_minus_pb <= 0) ? a : b;
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Predictors
|
||||||
|
|
||||||
|
static uint32_t Predictor2(uint32_t left, const uint32_t* const top) {
|
||||||
|
(void)left;
|
||||||
|
return top[0];
|
||||||
|
}
|
||||||
|
static uint32_t Predictor3(uint32_t left, const uint32_t* const top) {
|
||||||
|
(void)left;
|
||||||
|
return top[1];
|
||||||
|
}
|
||||||
|
static uint32_t Predictor4(uint32_t left, const uint32_t* const top) {
|
||||||
|
(void)left;
|
||||||
|
return top[-1];
|
||||||
|
}
|
||||||
|
static uint32_t Predictor5(uint32_t left, const uint32_t* const top) {
|
||||||
|
const uint32_t pred = Average3(left, top[0], top[1]);
|
||||||
|
return pred;
|
||||||
|
}
|
||||||
|
static uint32_t Predictor6(uint32_t left, const uint32_t* const top) {
|
||||||
|
const uint32_t pred = Average2(left, top[-1]);
|
||||||
|
return pred;
|
||||||
|
}
|
||||||
|
static uint32_t Predictor7(uint32_t left, const uint32_t* const top) {
|
||||||
|
const uint32_t pred = Average2(left, top[0]);
|
||||||
|
return pred;
|
||||||
|
}
|
||||||
|
static uint32_t Predictor8(uint32_t left, const uint32_t* const top) {
|
||||||
|
const uint32_t pred = Average2(top[-1], top[0]);
|
||||||
|
(void)left;
|
||||||
|
return pred;
|
||||||
|
}
|
||||||
|
static uint32_t Predictor9(uint32_t left, const uint32_t* const top) {
|
||||||
|
const uint32_t pred = Average2(top[0], top[1]);
|
||||||
|
(void)left;
|
||||||
|
return pred;
|
||||||
|
}
|
||||||
|
static uint32_t Predictor10(uint32_t left, const uint32_t* const top) {
|
||||||
|
const uint32_t pred = Average4(left, top[-1], top[0], top[1]);
|
||||||
|
return pred;
|
||||||
|
}
|
||||||
|
static uint32_t Predictor11(uint32_t left, const uint32_t* const top) {
|
||||||
|
const uint32_t pred = Select(top[0], left, top[-1]);
|
||||||
|
return pred;
|
||||||
|
}
|
||||||
|
static uint32_t Predictor12(uint32_t left, const uint32_t* const top) {
|
||||||
|
const uint32_t pred = ClampedAddSubtractFull(left, top[0], top[-1]);
|
||||||
|
return pred;
|
||||||
|
}
|
||||||
|
static uint32_t Predictor13(uint32_t left, const uint32_t* const top) {
|
||||||
|
const uint32_t pred = ClampedAddSubtractHalf(left, top[0], top[-1]);
|
||||||
|
return pred;
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
static void PredictorSub0_C(const uint32_t* in, const uint32_t* upper,
|
static void PredictorSub0_C(const uint32_t* in, const uint32_t* upper,
|
||||||
int num_pixels, uint32_t* out) {
|
int num_pixels, uint32_t* out) {
|
||||||
int i;
|
int i;
|
||||||
@ -735,33 +850,18 @@ static void PredictorSub1_C(const uint32_t* in, const uint32_t* upper,
|
|||||||
(void)upper;
|
(void)upper;
|
||||||
}
|
}
|
||||||
|
|
||||||
// It subtracts the prediction from the input pixel and stores the residual
|
GENERATE_PREDICTOR_SUB(Predictor2, PredictorSub2_C)
|
||||||
// in the output pixel.
|
GENERATE_PREDICTOR_SUB(Predictor3, PredictorSub3_C)
|
||||||
#define GENERATE_PREDICTOR_SUB(PREDICTOR_I) \
|
GENERATE_PREDICTOR_SUB(Predictor4, PredictorSub4_C)
|
||||||
static void PredictorSub##PREDICTOR_I##_C(const uint32_t* in, \
|
GENERATE_PREDICTOR_SUB(Predictor5, PredictorSub5_C)
|
||||||
const uint32_t* upper, \
|
GENERATE_PREDICTOR_SUB(Predictor6, PredictorSub6_C)
|
||||||
int num_pixels, uint32_t* out) { \
|
GENERATE_PREDICTOR_SUB(Predictor7, PredictorSub7_C)
|
||||||
int x; \
|
GENERATE_PREDICTOR_SUB(Predictor8, PredictorSub8_C)
|
||||||
assert(upper != NULL); \
|
GENERATE_PREDICTOR_SUB(Predictor9, PredictorSub9_C)
|
||||||
for (x = 0; x < num_pixels; ++x) { \
|
GENERATE_PREDICTOR_SUB(Predictor10, PredictorSub10_C)
|
||||||
const uint32_t pred = \
|
GENERATE_PREDICTOR_SUB(Predictor11, PredictorSub11_C)
|
||||||
VP8LPredictor##PREDICTOR_I##_C(in[x - 1], upper + x); \
|
GENERATE_PREDICTOR_SUB(Predictor12, PredictorSub12_C)
|
||||||
out[x] = VP8LSubPixels(in[x], pred); \
|
GENERATE_PREDICTOR_SUB(Predictor13, PredictorSub13_C)
|
||||||
} \
|
|
||||||
}
|
|
||||||
|
|
||||||
GENERATE_PREDICTOR_SUB(2)
|
|
||||||
GENERATE_PREDICTOR_SUB(3)
|
|
||||||
GENERATE_PREDICTOR_SUB(4)
|
|
||||||
GENERATE_PREDICTOR_SUB(5)
|
|
||||||
GENERATE_PREDICTOR_SUB(6)
|
|
||||||
GENERATE_PREDICTOR_SUB(7)
|
|
||||||
GENERATE_PREDICTOR_SUB(8)
|
|
||||||
GENERATE_PREDICTOR_SUB(9)
|
|
||||||
GENERATE_PREDICTOR_SUB(10)
|
|
||||||
GENERATE_PREDICTOR_SUB(11)
|
|
||||||
GENERATE_PREDICTOR_SUB(12)
|
|
||||||
GENERATE_PREDICTOR_SUB(13)
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
@ -862,10 +962,10 @@ WEBP_DSP_INIT_FUNC(VP8LEncDspInit) {
|
|||||||
|
|
||||||
// If defined, use CPUInfo() to overwrite some pointers with faster versions.
|
// If defined, use CPUInfo() to overwrite some pointers with faster versions.
|
||||||
if (VP8GetCPUInfo != NULL) {
|
if (VP8GetCPUInfo != NULL) {
|
||||||
#if defined(WEBP_HAVE_SSE2)
|
#if defined(WEBP_USE_SSE2)
|
||||||
if (VP8GetCPUInfo(kSSE2)) {
|
if (VP8GetCPUInfo(kSSE2)) {
|
||||||
VP8LEncDspInitSSE2();
|
VP8LEncDspInitSSE2();
|
||||||
#if defined(WEBP_HAVE_SSE41)
|
#if defined(WEBP_USE_SSE41)
|
||||||
if (VP8GetCPUInfo(kSSE4_1)) {
|
if (VP8GetCPUInfo(kSSE4_1)) {
|
||||||
VP8LEncDspInitSSE41();
|
VP8LEncDspInitSSE41();
|
||||||
}
|
}
|
||||||
@ -889,7 +989,7 @@ WEBP_DSP_INIT_FUNC(VP8LEncDspInit) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(WEBP_HAVE_NEON)
|
#if defined(WEBP_USE_NEON)
|
||||||
if (WEBP_NEON_OMIT_C_CODE ||
|
if (WEBP_NEON_OMIT_C_CODE ||
|
||||||
(VP8GetCPUInfo != NULL && VP8GetCPUInfo(kNEON))) {
|
(VP8GetCPUInfo != NULL && VP8GetCPUInfo(kNEON))) {
|
||||||
VP8LEncDspInitNEON();
|
VP8LEncDspInitNEON();
|
||||||
|
@ -347,24 +347,24 @@ static void GetCombinedEntropyUnrefined_MIPS32(const uint32_t X[],
|
|||||||
static void AddVector_MIPS32(const uint32_t* pa, const uint32_t* pb,
|
static void AddVector_MIPS32(const uint32_t* pa, const uint32_t* pb,
|
||||||
uint32_t* pout, int size) {
|
uint32_t* pout, int size) {
|
||||||
uint32_t temp0, temp1, temp2, temp3, temp4, temp5, temp6, temp7;
|
uint32_t temp0, temp1, temp2, temp3, temp4, temp5, temp6, temp7;
|
||||||
const uint32_t end = ((size) / 4) * 4;
|
const int end = ((size) / 4) * 4;
|
||||||
const uint32_t* const LoopEnd = pa + end;
|
const uint32_t* const LoopEnd = pa + end;
|
||||||
int i;
|
int i;
|
||||||
ASM_START
|
ASM_START
|
||||||
ADD_TO_OUT(0, 4, 8, 12, 1, pa, pb, pout)
|
ADD_TO_OUT(0, 4, 8, 12, 1, pa, pb, pout)
|
||||||
ASM_END_0
|
ASM_END_0
|
||||||
for (i = end; i < size; ++i) pout[i] = pa[i] + pb[i];
|
for (i = 0; i < size - end; ++i) pout[i] = pa[i] + pb[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
static void AddVectorEq_MIPS32(const uint32_t* pa, uint32_t* pout, int size) {
|
static void AddVectorEq_MIPS32(const uint32_t* pa, uint32_t* pout, int size) {
|
||||||
uint32_t temp0, temp1, temp2, temp3, temp4, temp5, temp6, temp7;
|
uint32_t temp0, temp1, temp2, temp3, temp4, temp5, temp6, temp7;
|
||||||
const uint32_t end = ((size) / 4) * 4;
|
const int end = ((size) / 4) * 4;
|
||||||
const uint32_t* const LoopEnd = pa + end;
|
const uint32_t* const LoopEnd = pa + end;
|
||||||
int i;
|
int i;
|
||||||
ASM_START
|
ASM_START
|
||||||
ADD_TO_OUT(0, 4, 8, 12, 0, pa, pout, pout)
|
ADD_TO_OUT(0, 4, 8, 12, 0, pa, pout, pout)
|
||||||
ASM_END_1
|
ASM_END_1
|
||||||
for (i = end; i < size; ++i) pout[i] += pa[i];
|
for (i = 0; i < size - end; ++i) pout[i] += pa[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef ASM_END_1
|
#undef ASM_END_1
|
||||||
|
@ -232,55 +232,76 @@ static void AddVectorEq_SSE2(const uint32_t* a, uint32_t* out, int size) {
|
|||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Entropy
|
// Entropy
|
||||||
|
|
||||||
// TODO(https://crbug.com/webp/499): this function produces different results
|
// Checks whether the X or Y contribution is worth computing and adding.
|
||||||
// from the C code due to use of double/float resulting in output differences
|
// Used in loop unrolling.
|
||||||
// when compared to -noasm.
|
#define ANALYZE_X_OR_Y(x_or_y, j) \
|
||||||
#if !(defined(WEBP_HAVE_SLOW_CLZ_CTZ) || defined(__i386__) || defined(_M_IX86))
|
do { \
|
||||||
|
if ((x_or_y)[i + (j)] != 0) retval -= VP8LFastSLog2((x_or_y)[i + (j)]); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
// Checks whether the X + Y contribution is worth computing and adding.
|
||||||
|
// Used in loop unrolling.
|
||||||
|
#define ANALYZE_XY(j) \
|
||||||
|
do { \
|
||||||
|
if (tmp[j] != 0) { \
|
||||||
|
retval -= VP8LFastSLog2(tmp[j]); \
|
||||||
|
ANALYZE_X_OR_Y(X, j); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
static float CombinedShannonEntropy_SSE2(const int X[256], const int Y[256]) {
|
static float CombinedShannonEntropy_SSE2(const int X[256], const int Y[256]) {
|
||||||
int i;
|
int i;
|
||||||
double retval = 0.;
|
double retval = 0.;
|
||||||
int sumX = 0, sumXY = 0;
|
int sumX, sumXY;
|
||||||
const __m128i zero = _mm_setzero_si128();
|
int32_t tmp[4];
|
||||||
|
__m128i zero = _mm_setzero_si128();
|
||||||
|
// Sums up X + Y, 4 ints at a time (and will merge it at the end for sumXY).
|
||||||
|
__m128i sumXY_128 = zero;
|
||||||
|
__m128i sumX_128 = zero;
|
||||||
|
|
||||||
for (i = 0; i < 256; i += 16) {
|
for (i = 0; i < 256; i += 4) {
|
||||||
const __m128i x0 = _mm_loadu_si128((const __m128i*)(X + i + 0));
|
const __m128i x = _mm_loadu_si128((const __m128i*)(X + i));
|
||||||
const __m128i y0 = _mm_loadu_si128((const __m128i*)(Y + i + 0));
|
const __m128i y = _mm_loadu_si128((const __m128i*)(Y + i));
|
||||||
const __m128i x1 = _mm_loadu_si128((const __m128i*)(X + i + 4));
|
|
||||||
const __m128i y1 = _mm_loadu_si128((const __m128i*)(Y + i + 4));
|
// Check if any X is non-zero: this actually provides a speedup as X is
|
||||||
const __m128i x2 = _mm_loadu_si128((const __m128i*)(X + i + 8));
|
// usually sparse.
|
||||||
const __m128i y2 = _mm_loadu_si128((const __m128i*)(Y + i + 8));
|
if (_mm_movemask_epi8(_mm_cmpeq_epi32(x, zero)) != 0xFFFF) {
|
||||||
const __m128i x3 = _mm_loadu_si128((const __m128i*)(X + i + 12));
|
const __m128i xy_128 = _mm_add_epi32(x, y);
|
||||||
const __m128i y3 = _mm_loadu_si128((const __m128i*)(Y + i + 12));
|
sumXY_128 = _mm_add_epi32(sumXY_128, xy_128);
|
||||||
const __m128i x4 = _mm_packs_epi16(_mm_packs_epi32(x0, x1),
|
|
||||||
_mm_packs_epi32(x2, x3));
|
sumX_128 = _mm_add_epi32(sumX_128, x);
|
||||||
const __m128i y4 = _mm_packs_epi16(_mm_packs_epi32(y0, y1),
|
|
||||||
_mm_packs_epi32(y2, y3));
|
// Analyze the different X + Y.
|
||||||
const int32_t mx = _mm_movemask_epi8(_mm_cmpgt_epi8(x4, zero));
|
_mm_storeu_si128((__m128i*)tmp, xy_128);
|
||||||
int32_t my = _mm_movemask_epi8(_mm_cmpgt_epi8(y4, zero)) | mx;
|
|
||||||
while (my) {
|
ANALYZE_XY(0);
|
||||||
const int32_t j = BitsCtz(my);
|
ANALYZE_XY(1);
|
||||||
int xy;
|
ANALYZE_XY(2);
|
||||||
if ((mx >> j) & 1) {
|
ANALYZE_XY(3);
|
||||||
const int x = X[i + j];
|
} else {
|
||||||
sumXY += x;
|
// X is fully 0, so only deal with Y.
|
||||||
retval -= VP8LFastSLog2(x);
|
sumXY_128 = _mm_add_epi32(sumXY_128, y);
|
||||||
}
|
|
||||||
xy = X[i + j] + Y[i + j];
|
ANALYZE_X_OR_Y(Y, 0);
|
||||||
sumX += xy;
|
ANALYZE_X_OR_Y(Y, 1);
|
||||||
retval -= VP8LFastSLog2(xy);
|
ANALYZE_X_OR_Y(Y, 2);
|
||||||
my &= my - 1;
|
ANALYZE_X_OR_Y(Y, 3);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Sum up sumX_128 to get sumX.
|
||||||
|
_mm_storeu_si128((__m128i*)tmp, sumX_128);
|
||||||
|
sumX = tmp[3] + tmp[2] + tmp[1] + tmp[0];
|
||||||
|
|
||||||
|
// Sum up sumXY_128 to get sumXY.
|
||||||
|
_mm_storeu_si128((__m128i*)tmp, sumXY_128);
|
||||||
|
sumXY = tmp[3] + tmp[2] + tmp[1] + tmp[0];
|
||||||
|
|
||||||
retval += VP8LFastSLog2(sumX) + VP8LFastSLog2(sumXY);
|
retval += VP8LFastSLog2(sumX) + VP8LFastSLog2(sumXY);
|
||||||
return (float)retval;
|
return (float)retval;
|
||||||
}
|
}
|
||||||
|
#undef ANALYZE_X_OR_Y
|
||||||
#else
|
#undef ANALYZE_XY
|
||||||
|
|
||||||
#define DONT_USE_COMBINED_SHANNON_ENTROPY_SSE2_FUNC // won't be faster
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
@ -434,27 +455,24 @@ static void PredictorSub0_SSE2(const uint32_t* in, const uint32_t* upper,
|
|||||||
_mm_storeu_si128((__m128i*)&out[i], res);
|
_mm_storeu_si128((__m128i*)&out[i], res);
|
||||||
}
|
}
|
||||||
if (i != num_pixels) {
|
if (i != num_pixels) {
|
||||||
VP8LPredictorsSub_C[0](in + i, NULL, num_pixels - i, out + i);
|
VP8LPredictorsSub_C[0](in + i, upper + i, num_pixels - i, out + i);
|
||||||
}
|
}
|
||||||
(void)upper;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define GENERATE_PREDICTOR_1(X, IN) \
|
#define GENERATE_PREDICTOR_1(X, IN) \
|
||||||
static void PredictorSub##X##_SSE2(const uint32_t* const in, \
|
static void PredictorSub##X##_SSE2(const uint32_t* in, const uint32_t* upper, \
|
||||||
const uint32_t* const upper, \
|
int num_pixels, uint32_t* out) { \
|
||||||
int num_pixels, uint32_t* const out) { \
|
int i; \
|
||||||
int i; \
|
for (i = 0; i + 4 <= num_pixels; i += 4) { \
|
||||||
for (i = 0; i + 4 <= num_pixels; i += 4) { \
|
const __m128i src = _mm_loadu_si128((const __m128i*)&in[i]); \
|
||||||
const __m128i src = _mm_loadu_si128((const __m128i*)&in[i]); \
|
const __m128i pred = _mm_loadu_si128((const __m128i*)&(IN)); \
|
||||||
const __m128i pred = _mm_loadu_si128((const __m128i*)&(IN)); \
|
const __m128i res = _mm_sub_epi8(src, pred); \
|
||||||
const __m128i res = _mm_sub_epi8(src, pred); \
|
_mm_storeu_si128((__m128i*)&out[i], res); \
|
||||||
_mm_storeu_si128((__m128i*)&out[i], res); \
|
} \
|
||||||
} \
|
if (i != num_pixels) { \
|
||||||
if (i != num_pixels) { \
|
VP8LPredictorsSub_C[(X)](in + i, upper + i, num_pixels - i, out + i); \
|
||||||
VP8LPredictorsSub_C[(X)](in + i, WEBP_OFFSET_PTR(upper, i), \
|
} \
|
||||||
num_pixels - i, out + i); \
|
}
|
||||||
} \
|
|
||||||
}
|
|
||||||
|
|
||||||
GENERATE_PREDICTOR_1(1, in[i - 1]) // Predictor1: L
|
GENERATE_PREDICTOR_1(1, in[i - 1]) // Predictor1: L
|
||||||
GENERATE_PREDICTOR_1(2, upper[i]) // Predictor2: T
|
GENERATE_PREDICTOR_1(2, upper[i]) // Predictor2: T
|
||||||
@ -638,9 +656,7 @@ WEBP_TSAN_IGNORE_FUNCTION void VP8LEncDspInitSSE2(void) {
|
|||||||
VP8LCollectColorRedTransforms = CollectColorRedTransforms_SSE2;
|
VP8LCollectColorRedTransforms = CollectColorRedTransforms_SSE2;
|
||||||
VP8LAddVector = AddVector_SSE2;
|
VP8LAddVector = AddVector_SSE2;
|
||||||
VP8LAddVectorEq = AddVectorEq_SSE2;
|
VP8LAddVectorEq = AddVectorEq_SSE2;
|
||||||
#if !defined(DONT_USE_COMBINED_SHANNON_ENTROPY_SSE2_FUNC)
|
|
||||||
VP8LCombinedShannonEntropy = CombinedShannonEntropy_SSE2;
|
VP8LCombinedShannonEntropy = CombinedShannonEntropy_SSE2;
|
||||||
#endif
|
|
||||||
VP8LVectorMismatch = VectorMismatch_SSE2;
|
VP8LVectorMismatch = VectorMismatch_SSE2;
|
||||||
VP8LBundleColorMap = BundleColorMap_SSE2;
|
VP8LBundleColorMap = BundleColorMap_SSE2;
|
||||||
|
|
||||||
|
@ -44,47 +44,46 @@ static void SubtractGreenFromBlueAndRed_SSE41(uint32_t* argb_data,
|
|||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Color Transform
|
// Color Transform
|
||||||
|
|
||||||
#define MK_CST_16(HI, LO) \
|
#define SPAN 8
|
||||||
_mm_set1_epi32((int)(((uint32_t)(HI) << 16) | ((LO) & 0xffff)))
|
|
||||||
|
|
||||||
static void CollectColorBlueTransforms_SSE41(const uint32_t* argb, int stride,
|
static void CollectColorBlueTransforms_SSE41(const uint32_t* argb, int stride,
|
||||||
int tile_width, int tile_height,
|
int tile_width, int tile_height,
|
||||||
int green_to_blue, int red_to_blue,
|
int green_to_blue, int red_to_blue,
|
||||||
int histo[]) {
|
int histo[]) {
|
||||||
const __m128i mult =
|
const __m128i mults_r = _mm_set1_epi16(CST_5b(red_to_blue));
|
||||||
MK_CST_16(CST_5b(red_to_blue) + 256,CST_5b(green_to_blue));
|
const __m128i mults_g = _mm_set1_epi16(CST_5b(green_to_blue));
|
||||||
const __m128i perm =
|
const __m128i mask_g = _mm_set1_epi16((short)0xff00); // green mask
|
||||||
_mm_setr_epi8(-1, 1, -1, 2, -1, 5, -1, 6, -1, 9, -1, 10, -1, 13, -1, 14);
|
const __m128i mask_gb = _mm_set1_epi32(0xffff); // green/blue mask
|
||||||
if (tile_width >= 4) {
|
const __m128i mask_b = _mm_set1_epi16(0x00ff); // blue mask
|
||||||
int y;
|
const __m128i shuffler_lo = _mm_setr_epi8(-1, 2, -1, 6, -1, 10, -1, 14, -1,
|
||||||
for (y = 0; y < tile_height; ++y) {
|
-1, -1, -1, -1, -1, -1, -1);
|
||||||
const uint32_t* const src = argb + y * stride;
|
const __m128i shuffler_hi = _mm_setr_epi8(-1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||||
const __m128i A1 = _mm_loadu_si128((const __m128i*)src);
|
2, -1, 6, -1, 10, -1, 14);
|
||||||
const __m128i B1 = _mm_shuffle_epi8(A1, perm);
|
int y;
|
||||||
const __m128i C1 = _mm_mulhi_epi16(B1, mult);
|
for (y = 0; y < tile_height; ++y) {
|
||||||
const __m128i D1 = _mm_sub_epi16(A1, C1);
|
const uint32_t* const src = argb + y * stride;
|
||||||
__m128i E = _mm_add_epi16(_mm_srli_epi32(D1, 16), D1);
|
int i, x;
|
||||||
int x;
|
for (x = 0; x + SPAN <= tile_width; x += SPAN) {
|
||||||
for (x = 4; x + 4 <= tile_width; x += 4) {
|
uint16_t values[SPAN];
|
||||||
const __m128i A2 = _mm_loadu_si128((const __m128i*)(src + x));
|
const __m128i in0 = _mm_loadu_si128((__m128i*)&src[x + 0]);
|
||||||
__m128i B2, C2, D2;
|
const __m128i in1 = _mm_loadu_si128((__m128i*)&src[x + SPAN / 2]);
|
||||||
++histo[_mm_extract_epi8(E, 0)];
|
const __m128i r0 = _mm_shuffle_epi8(in0, shuffler_lo);
|
||||||
B2 = _mm_shuffle_epi8(A2, perm);
|
const __m128i r1 = _mm_shuffle_epi8(in1, shuffler_hi);
|
||||||
++histo[_mm_extract_epi8(E, 4)];
|
const __m128i r = _mm_or_si128(r0, r1); // r 0
|
||||||
C2 = _mm_mulhi_epi16(B2, mult);
|
const __m128i gb0 = _mm_and_si128(in0, mask_gb);
|
||||||
++histo[_mm_extract_epi8(E, 8)];
|
const __m128i gb1 = _mm_and_si128(in1, mask_gb);
|
||||||
D2 = _mm_sub_epi16(A2, C2);
|
const __m128i gb = _mm_packus_epi32(gb0, gb1); // g b
|
||||||
++histo[_mm_extract_epi8(E, 12)];
|
const __m128i g = _mm_and_si128(gb, mask_g); // g 0
|
||||||
E = _mm_add_epi16(_mm_srli_epi32(D2, 16), D2);
|
const __m128i A = _mm_mulhi_epi16(r, mults_r); // x dbr
|
||||||
}
|
const __m128i B = _mm_mulhi_epi16(g, mults_g); // x dbg
|
||||||
++histo[_mm_extract_epi8(E, 0)];
|
const __m128i C = _mm_sub_epi8(gb, B); // x b'
|
||||||
++histo[_mm_extract_epi8(E, 4)];
|
const __m128i D = _mm_sub_epi8(C, A); // x b''
|
||||||
++histo[_mm_extract_epi8(E, 8)];
|
const __m128i E = _mm_and_si128(D, mask_b); // 0 b''
|
||||||
++histo[_mm_extract_epi8(E, 12)];
|
_mm_storeu_si128((__m128i*)values, E);
|
||||||
|
for (i = 0; i < SPAN; ++i) ++histo[values[i]];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
const int left_over = tile_width & 3;
|
const int left_over = tile_width & (SPAN - 1);
|
||||||
if (left_over > 0) {
|
if (left_over > 0) {
|
||||||
VP8LCollectColorBlueTransforms_C(argb + tile_width - left_over, stride,
|
VP8LCollectColorBlueTransforms_C(argb + tile_width - left_over, stride,
|
||||||
left_over, tile_height,
|
left_over, tile_height,
|
||||||
@ -96,37 +95,33 @@ static void CollectColorBlueTransforms_SSE41(const uint32_t* argb, int stride,
|
|||||||
static void CollectColorRedTransforms_SSE41(const uint32_t* argb, int stride,
|
static void CollectColorRedTransforms_SSE41(const uint32_t* argb, int stride,
|
||||||
int tile_width, int tile_height,
|
int tile_width, int tile_height,
|
||||||
int green_to_red, int histo[]) {
|
int green_to_red, int histo[]) {
|
||||||
|
const __m128i mults_g = _mm_set1_epi16(CST_5b(green_to_red));
|
||||||
|
const __m128i mask_g = _mm_set1_epi32(0x00ff00); // green mask
|
||||||
|
const __m128i mask = _mm_set1_epi16(0xff);
|
||||||
|
|
||||||
const __m128i mult = MK_CST_16(0, CST_5b(green_to_red));
|
int y;
|
||||||
const __m128i mask_g = _mm_set1_epi32(0x0000ff00);
|
for (y = 0; y < tile_height; ++y) {
|
||||||
if (tile_width >= 4) {
|
const uint32_t* const src = argb + y * stride;
|
||||||
int y;
|
int i, x;
|
||||||
for (y = 0; y < tile_height; ++y) {
|
for (x = 0; x + SPAN <= tile_width; x += SPAN) {
|
||||||
const uint32_t* const src = argb + y * stride;
|
uint16_t values[SPAN];
|
||||||
const __m128i A1 = _mm_loadu_si128((const __m128i*)src);
|
const __m128i in0 = _mm_loadu_si128((__m128i*)&src[x + 0]);
|
||||||
const __m128i B1 = _mm_and_si128(A1, mask_g);
|
const __m128i in1 = _mm_loadu_si128((__m128i*)&src[x + SPAN / 2]);
|
||||||
const __m128i C1 = _mm_madd_epi16(B1, mult);
|
const __m128i g0 = _mm_and_si128(in0, mask_g); // 0 0 | g 0
|
||||||
__m128i D = _mm_sub_epi16(A1, C1);
|
const __m128i g1 = _mm_and_si128(in1, mask_g);
|
||||||
int x;
|
const __m128i g = _mm_packus_epi32(g0, g1); // g 0
|
||||||
for (x = 4; x + 4 <= tile_width; x += 4) {
|
const __m128i A0 = _mm_srli_epi32(in0, 16); // 0 0 | x r
|
||||||
const __m128i A2 = _mm_loadu_si128((const __m128i*)(src + x));
|
const __m128i A1 = _mm_srli_epi32(in1, 16);
|
||||||
__m128i B2, C2;
|
const __m128i A = _mm_packus_epi32(A0, A1); // x r
|
||||||
++histo[_mm_extract_epi8(D, 2)];
|
const __m128i B = _mm_mulhi_epi16(g, mults_g); // x dr
|
||||||
B2 = _mm_and_si128(A2, mask_g);
|
const __m128i C = _mm_sub_epi8(A, B); // x r'
|
||||||
++histo[_mm_extract_epi8(D, 6)];
|
const __m128i D = _mm_and_si128(C, mask); // 0 r'
|
||||||
C2 = _mm_madd_epi16(B2, mult);
|
_mm_storeu_si128((__m128i*)values, D);
|
||||||
++histo[_mm_extract_epi8(D, 10)];
|
for (i = 0; i < SPAN; ++i) ++histo[values[i]];
|
||||||
++histo[_mm_extract_epi8(D, 14)];
|
|
||||||
D = _mm_sub_epi16(A2, C2);
|
|
||||||
}
|
|
||||||
++histo[_mm_extract_epi8(D, 2)];
|
|
||||||
++histo[_mm_extract_epi8(D, 6)];
|
|
||||||
++histo[_mm_extract_epi8(D, 10)];
|
|
||||||
++histo[_mm_extract_epi8(D, 14)];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
const int left_over = tile_width & 3;
|
const int left_over = tile_width & (SPAN - 1);
|
||||||
if (left_over > 0) {
|
if (left_over > 0) {
|
||||||
VP8LCollectColorRedTransforms_C(argb + tile_width - left_over, stride,
|
VP8LCollectColorRedTransforms_C(argb + tile_width - left_over, stride,
|
||||||
left_over, tile_height, green_to_red,
|
left_over, tile_height, green_to_red,
|
||||||
@ -135,8 +130,6 @@ static void CollectColorRedTransforms_SSE41(const uint32_t* argb, int stride,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef MK_CST_16
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Entry point
|
// Entry point
|
||||||
|
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user