mirror of
https://github.com/webmproject/libwebp.git
synced 2025-07-15 13:29:54 +02:00
Compare commits
140 Commits
v1.2.0-rc3
...
v1.2.2-rc1
Author | SHA1 | Date | |
---|---|---|---|
f035d2e40d | |||
7031946ad8 | |||
973390b618 | |||
abd6664fee | |||
5b7e79303a | |||
02ca04c348 | |||
e94716e27c | |||
c846efd888 | |||
b6f756e82b | |||
8f5cb4c18e | |||
8ea81561d2 | |||
6b1d18c362 | |||
3368d8768a | |||
f213abf620 | |||
50c97c301d | |||
2c206aaf96 | |||
96e3dfef26 | |||
0e0f74b7e3 | |||
35b7436a21 | |||
21d24b4c08 | |||
cdcf89020e | |||
dc683cdef5 | |||
0858494e96 | |||
c2cf6a93b0 | |||
df0e808fed | |||
676c57dba4 | |||
7bb7f7474e | |||
abcd1797a1 | |||
edaf08952d | |||
b96220636b | |||
e23cd5481c | |||
3875c7de07 | |||
1a8f0d45d3 | |||
934801604e | |||
45eaacc939 | |||
42592af875 | |||
e298e05f66 | |||
29148919e0 | |||
9ce5843dba | |||
d9191588ab | |||
c5bc36243a | |||
53b6f76209 | |||
d2caaba435 | |||
731246ba3b | |||
d250f01d95 | |||
1fe3162541 | |||
3a4d3ecd40 | |||
b2bc809346 | |||
e542fc7a8a | |||
e024115490 | |||
edea64442c | |||
ece18e5520 | |||
a89a3230c9 | |||
26f4aa0115 | |||
8f5946634e | |||
46d844e6cf | |||
298d26eac2 | |||
a1e5dae0f0 | |||
327ef24fbd | |||
f70819de51 | |||
dc7e2b42e7 | |||
9df23dddc2 | |||
a2e18f10eb | |||
e1a8d4f3fe | |||
4de35f4383 | |||
0f13eec7bf | |||
277d30749f | |||
97adbba513 | |||
b60d460318 | |||
72fe52f623 | |||
116d235c30 | |||
6f445b3e3d | |||
b1cf887f86 | |||
3e26513656 | |||
f6d2924757 | |||
de3b4ba813 | |||
7f09d3d132 | |||
4edea4a695 | |||
c9e26bdb35 | |||
28d488e6f1 | |||
695bdaa2f6 | |||
685d073ee1 | |||
d38bd0dda0 | |||
109ff0f100 | |||
a2fce86744 | |||
776983d427 | |||
315abbd60b | |||
eae815d0d1 | |||
afbca5a152 | |||
3320416b2e | |||
29145ed692 | |||
1f5791398c | |||
29b6129c78 | |||
b60869a18e | |||
6fb4cddc93 | |||
05b72d4205 | |||
b6513fbaa8 | |||
98bbe35b51 | |||
b1674240f9 | |||
88c90c4528 | |||
6a9916d734 | |||
b6cf52d5b8 | |||
3b12b7f4b4 | |||
595fa13f83 | |||
8fdaecb09d | |||
8933bac212 | |||
7d416ff085 | |||
ec6cfeb51e | |||
7e58a1a260 | |||
5651a6b2ed | |||
25ae67b3de | |||
5d4ee4c3c0 | |||
01b38ee19a | |||
652aa34424 | |||
0320e1e36f | |||
8886f620c0 | |||
fae416179e | |||
5bd2704e30 | |||
fee642870e | |||
33ddb894b1 | |||
b27ea8525a | |||
b78494a933 | |||
e79974cd6a | |||
a885339448 | |||
a09a647241 | |||
401da22bd6 | |||
2690782292 | |||
06c1e72e71 | |||
8f0d41aac0 | |||
373eb170f1 | |||
759b9d5a06 | |||
926ce921f3 | |||
9c367bc602 | |||
47f64f6edd | |||
cc3577e9b9 | |||
004d77ffab | |||
ceddb5fc8d | |||
289757fe1e | |||
8696147da4 | |||
8df77fb1b1 |
2
.mailmap
2
.mailmap
@ -11,3 +11,5 @@ 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>
|
||||||
|
Roberto Alanis <alanisbaez@google.com>
|
||||||
|
441
.pylintrc
Normal file
441
.pylintrc
Normal file
@ -0,0 +1,441 @@
|
|||||||
|
# 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
|
2
.style.yapf
Normal file
2
.style.yapf
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
[style]
|
||||||
|
based_on_style = chromium
|
5
AUTHORS
5
AUTHORS
@ -4,8 +4,11 @@ Contributors:
|
|||||||
- Charles Munger (clm at google dot com)
|
- Charles Munger (clm at google dot com)
|
||||||
- Cheng Yi (cyi 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)
|
- 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)
|
||||||
@ -29,6 +32,7 @@ Contributors:
|
|||||||
- Pascal Massimino (pascal dot massimino at gmail dot com)
|
- Pascal Massimino (pascal dot massimino at gmail dot com)
|
||||||
- Paweł Hajdan, Jr (phajdan dot jr at chromium dot org)
|
- Paweł Hajdan, Jr (phajdan dot jr at chromium dot org)
|
||||||
- Pierre Joye (pierre dot php at gmail dot com)
|
- Pierre Joye (pierre dot php at gmail dot com)
|
||||||
|
- Roberto Alanis (alanisbaez at google dot com)
|
||||||
- Sam Clegg (sbc at chromium dot org)
|
- Sam Clegg (sbc at chromium dot org)
|
||||||
- Scott Hancher (seh at google dot com)
|
- Scott Hancher (seh at google dot com)
|
||||||
- Scott LaVarnway (slavarnway at google dot com)
|
- Scott LaVarnway (slavarnway at google dot com)
|
||||||
@ -45,3 +49,4 @@ Contributors:
|
|||||||
- Wan-Teh Chang (wtc at google dot com)
|
- 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,6 +74,7 @@ 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 \
|
||||||
|
114
CMakeLists.txt
114
CMakeLists.txt
@ -1,13 +1,16 @@
|
|||||||
##
|
# Copyright (c) 2020 Google LLC.
|
||||||
## Copyright (c) 2020 Google LLC.
|
#
|
||||||
##
|
# Use of this source code is governed by a BSD-style license
|
||||||
## 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
|
||||||
## that can be found in the LICENSE file in the root of the source
|
# tree. An additional intellectual property rights grant can be found
|
||||||
## tree. An additional intellectual property rights grant can be found
|
# in the file PATENTS. All contributing project authors may
|
||||||
## in the file PATENTS. All contributing project authors may
|
# be found in the AUTHORS file in the root of the source tree.
|
||||||
## be found in the AUTHORS file in the root of the source tree.
|
|
||||||
|
|
||||||
cmake_minimum_required(VERSION 3.5)
|
cmake_minimum_required(VERSION 3.7)
|
||||||
|
|
||||||
|
if(POLICY CMP0072)
|
||||||
|
cmake_policy(SET CMP0072 NEW)
|
||||||
|
endif()
|
||||||
|
|
||||||
project(WebP C)
|
project(WebP C)
|
||||||
|
|
||||||
@ -26,9 +29,11 @@ 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)
|
||||||
@ -50,6 +55,7 @@ if(WEBP_BUILD_WEBP_JS)
|
|||||||
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)
|
if(WEBP_ENABLE_SIMD)
|
||||||
message("wasm2js does not support SIMD, disabling webp.js generation.")
|
message("wasm2js does not support SIMD, disabling webp.js generation.")
|
||||||
@ -277,10 +283,12 @@ if(XCODE)
|
|||||||
libwebp_add_stub_file(webp)
|
libwebp_add_stub_file(webp)
|
||||||
endif()
|
endif()
|
||||||
target_link_libraries(webp ${WEBP_DEP_LIBRARIES})
|
target_link_libraries(webp ${WEBP_DEP_LIBRARIES})
|
||||||
target_include_directories(webp
|
target_include_directories(
|
||||||
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
|
webp
|
||||||
${CMAKE_CURRENT_BINARY_DIR}
|
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
|
||||||
PUBLIC $<INSTALL_INTERFACE:include>)
|
${CMAKE_CURRENT_BINARY_DIR}
|
||||||
|
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;\
|
||||||
@ -315,10 +323,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.
|
||||||
function(parse_version FILE NAME VAR)
|
macro(set_version FILE TARGET_NAME NAME_IN_MAKEFILE)
|
||||||
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}_la_LDFLAGS[^\n]* -version-info [0-9:]+"
|
"${NAME_IN_MAKEFILE}_la_LDFLAGS[^\n]* -version-info [0-9:]+"
|
||||||
TMP
|
TMP
|
||||||
${SOURCE_FILE})
|
${SOURCE_FILE})
|
||||||
string(REGEX MATCH
|
string(REGEX MATCH
|
||||||
@ -327,29 +335,35 @@ function(parse_version FILE NAME VAR)
|
|||||||
${TMP})
|
${TMP})
|
||||||
string(REGEX
|
string(REGEX
|
||||||
REPLACE ":"
|
REPLACE ":"
|
||||||
"."
|
" "
|
||||||
VERSION
|
LT_VERSION
|
||||||
${TMP})
|
${TMP})
|
||||||
set(${VAR} "${VERSION}" PARENT_SCOPE)
|
|
||||||
endfunction()
|
# See the libtool docs for more information:
|
||||||
parse_version(Makefile.am webp WEBP_WEBP_SOVERSION)
|
# https://www.gnu.org/software/libtool/manual/libtool.html#Updating-version-info
|
||||||
set_target_properties(webp
|
#
|
||||||
PROPERTIES VERSION
|
# c=<current>, a=<age>, r=<revision>
|
||||||
${PACKAGE_VERSION}
|
#
|
||||||
SOVERSION
|
# libtool generates a .so file as .so.[c-a].a.r, while -version-info c:r:a is
|
||||||
${WEBP_WEBP_SOVERSION})
|
# passed to libtool.
|
||||||
parse_version(Makefile.am webpdecoder WEBP_DECODER_SOVERSION)
|
#
|
||||||
set_target_properties(webpdecoder
|
# We set FULL = [c-a].a.r and MAJOR = [c-a].
|
||||||
PROPERTIES VERSION
|
separate_arguments(LT_VERSION)
|
||||||
${PACKAGE_VERSION}
|
list(GET LT_VERSION 0 LT_CURRENT)
|
||||||
SOVERSION
|
list(GET LT_VERSION 1 LT_REVISION)
|
||||||
${WEBP_DECODER_SOVERSION})
|
list(GET LT_VERSION 2 LT_AGE)
|
||||||
parse_version(demux/Makefile.am webpdemux WEBP_DEMUX_SOVERSION)
|
math(EXPR LT_CURRENT_MINUS_AGE "${LT_CURRENT} - ${LT_AGE}")
|
||||||
set_target_properties(webpdemux
|
|
||||||
PROPERTIES VERSION
|
set_target_properties(
|
||||||
${PACKAGE_VERSION}
|
${TARGET_NAME}
|
||||||
SOVERSION
|
PROPERTIES VERSION
|
||||||
${WEBP_DEMUX_SOVERSION})
|
${LT_CURRENT_MINUS_AGE}.${LT_AGE}.${LT_REVISION}
|
||||||
|
SOVERSION
|
||||||
|
${LT_CURRENT_MINUS_AGE})
|
||||||
|
endmacro()
|
||||||
|
set_version(Makefile.am webp webp)
|
||||||
|
set_version(Makefile.am webpdecoder webpdecoder)
|
||||||
|
set_version(demux/Makefile.am webpdemux webpdemux)
|
||||||
file(READ ${CMAKE_CURRENT_SOURCE_DIR}/configure.ac CONFIGURE_FILE)
|
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\\.]+\\]"
|
||||||
@ -377,6 +391,12 @@ 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()
|
||||||
@ -449,19 +469,14 @@ 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_GIF2WEBP OR WEBP_BUILD_IMG2WEBP)
|
if(WEBP_BUILD_LIBWEBPMUX)
|
||||||
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})
|
||||||
parse_version(mux/Makefile.am webpmux WEBP_MUX_SOVERSION)
|
set_version(mux/Makefile.am libwebpmux webpmux)
|
||||||
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;\
|
||||||
@ -565,9 +580,7 @@ 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})
|
||||||
@ -575,7 +588,6 @@ if(WEBP_BUILD_EXTRAS)
|
|||||||
target_include_directories(webp_quality
|
target_include_directories(webp_quality
|
||||||
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
|
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
|
||||||
${CMAKE_CURRENT_BINARY_DIR})
|
${CMAKE_CURRENT_BINARY_DIR})
|
||||||
install(TARGETS webp_quality RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
|
|
||||||
|
|
||||||
# vwebp_sdl
|
# vwebp_sdl
|
||||||
find_package(SDL)
|
find_package(SDL)
|
||||||
@ -584,13 +596,11 @@ 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()
|
||||||
|
|
||||||
@ -606,7 +616,7 @@ if(WEBP_BUILD_WEBP_JS)
|
|||||||
webp_js
|
webp_js
|
||||||
PROPERTIES LINK_FLAGS "-s WASM=0 \
|
PROPERTIES LINK_FLAGS "-s WASM=0 \
|
||||||
-s EXPORTED_FUNCTIONS='[\"_WebpToSDL\"]' -s INVOKE_RUN=0 \
|
-s EXPORTED_FUNCTIONS='[\"_WebpToSDL\"]' -s INVOKE_RUN=0 \
|
||||||
-s EXTRA_EXPORTED_RUNTIME_METHODS='[\"cwrap\"]'")
|
-s EXPORTED_RUNTIME_METHODS='[\"cwrap\"]'")
|
||||||
set_target_properties(webp_js PROPERTIES OUTPUT_NAME webp)
|
set_target_properties(webp_js PROPERTIES OUTPUT_NAME webp)
|
||||||
target_compile_definitions(webp_js PUBLIC EMSCRIPTEN WEBP_HAVE_SDL)
|
target_compile_definitions(webp_js PUBLIC EMSCRIPTEN WEBP_HAVE_SDL)
|
||||||
endif()
|
endif()
|
||||||
@ -619,7 +629,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 EXTRA_EXPORTED_RUNTIME_METHODS='[\"cwrap\"]'")
|
-s 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)
|
||||||
@ -637,7 +647,6 @@ 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)
|
||||||
@ -653,7 +662,6 @@ 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)
|
||||||
|
29
CONTRIBUTING.md
Normal file
29
CONTRIBUTING.md
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
# 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/).
|
140
ChangeLog
140
ChangeLog
@ -1,10 +1,150 @@
|
|||||||
|
7031946a update NEWS
|
||||||
|
973390b6 bump version to 1.2.2
|
||||||
|
abd6664f update AUTHORS
|
||||||
|
5b7e7930 Merge "add missing USE_{MSA,NEON} checks in headers" into main
|
||||||
|
02ca04c3 add missing USE_{MSA,NEON} checks in headers
|
||||||
|
e94716e2 xcframeworkbuild.sh: place headers in a subdir
|
||||||
|
c846efd8 patch-check: commit subject length check
|
||||||
|
b6f756e8 update http links
|
||||||
|
8f5cb4c1 update rfc links
|
||||||
|
8ea81561 change VP8LPredictorFunc signature to avoid reading 'left'
|
||||||
|
6b1d18c3 webpmux: fix the -bgcolor description
|
||||||
|
3368d876 Merge "webpmux: add "-set bgcolor A,R,G,B"" into main
|
||||||
|
f213abf6 webpinfo: print the number of warnings
|
||||||
|
50c97c30 webpmux: add "-set bgcolor A,R,G,B"
|
||||||
|
2c206aaf Remove CMakeLists.txt check in compile.sh
|
||||||
|
96e3dfef Merge "infra/common.sh: add shard_should_run()" into main
|
||||||
|
0e0f74b7 infra/common.sh: add shard_should_run()
|
||||||
|
35b7436a Jenkins scripts port: update shell function comments
|
||||||
|
21d24b4c webp-container-spec.txt: remove 'experimental' markers
|
||||||
|
cdcf8902 Merge "Port Jenkins script: compile" into main
|
||||||
|
dc683cde Jenkins scripts port: static analysis
|
||||||
|
0858494e Port Jenkins script: compile
|
||||||
|
c2cf6a93 Jenkins scripts port: android compilation
|
||||||
|
df0e808f presubmit: Add pylint-2.7 and .pylintrc
|
||||||
|
676c57db patch-check: shfmt
|
||||||
|
7bb7f747 patch-check: Add shellcheck
|
||||||
|
abcd1797 Reformat docstrings and imports
|
||||||
|
edaf0895 Port Jenkins scripts: compile js
|
||||||
|
b9622063 Set CheckPatchFormatted flags to fail on diffs
|
||||||
|
e23cd548 dsp.h: enable NEON w/VS2019+ ARM64 targets
|
||||||
|
3875c7de CMakeLists.txt: set minimum version to 3.7
|
||||||
|
1a8f0d45 Have a hard-coded value for memset in TrellisQuantizeBlock.
|
||||||
|
93480160 Speed up TrellisQuantizeBlock
|
||||||
|
45eaacc9 Convert deprecated uint32 to uint32_t.
|
||||||
|
42592af8 webp,cmake: Remove unnecessary include dirs
|
||||||
|
e298e05f Add patch-check steps in PRESUBMIT.py
|
||||||
|
29148919 Merge tag 'v1.2.1'
|
||||||
|
9ce5843d update ChangeLog (tag: v1.2.1, origin/1.2.1)
|
||||||
|
d9191588 fuzzer/*: normalize src/ includes
|
||||||
|
c5bc3624 fuzzer/*: normalize src/ includes
|
||||||
|
53b6f762 fix indent
|
||||||
|
d2caaba4 fix indent
|
||||||
|
731246ba update ChangeLog (tag: v1.2.1-rc2)
|
||||||
|
d250f01d dsp/*: use WEBP_HAVE_* to determine Init availability
|
||||||
|
1fe31625 dsp/*: use WEBP_HAVE_* to determine Init availability
|
||||||
|
3a4d3ecd update NEWS
|
||||||
|
b2bc8093 bump version to 1.2.1
|
||||||
|
e542fc7a update AUTHORS
|
||||||
|
e0241154 Merge "libwebp/CMake: Add <BUILD_INTERFACE> to webp incl" into main
|
||||||
|
edea6444 libwebp/CMake: Add <BUILD_INTERFACE> to webp incl
|
||||||
|
ece18e55 dsp.h: respect --disable-sse2/sse4.1/neon
|
||||||
|
a89a3230 wicdec: support alpha from WebP WIC decoder
|
||||||
|
26f4aa01 Merge "alpha_processing: fix visual studio warnings" into main
|
||||||
|
8f594663 alpha_processing: fix visual studio warnings
|
||||||
|
46d844e6 Merge "cpu.cmake: fix compiler flag detection w/3.17.0+" into main
|
||||||
|
298d26ea Merge changes I593adf92,If20675e7,Ifac68eac into main
|
||||||
|
a1e5dae0 alpha_processing*: use WEBP_RESTRICT qualifier
|
||||||
|
327ef24f cpu.cmake: fix compiler flag detection w/3.17.0+
|
||||||
|
f70819de configure: enable libwebpmux by default
|
||||||
|
dc7e2b42 configure: add informational notices when disabling binaries
|
||||||
|
9df23ddd configure: move lib flag checks before binaries
|
||||||
|
a2e18f10 Merge "WebPConfig.config.in: correct WEBP_INCLUDE_DIRS" into main
|
||||||
|
e1a8d4f3 Merge "bit_reader_inl_utils: uniformly apply WEBP_RESTRICT" into main
|
||||||
|
4de35f43 rescaler.c: fix alignment
|
||||||
|
0f13eec7 bit_reader_inl_utils: uniformly apply WEBP_RESTRICT
|
||||||
|
277d3074 Fix size_t overflow in WebPRescalerInit
|
||||||
|
97adbba5 WebPConfig.config.in: correct WEBP_INCLUDE_DIRS
|
||||||
|
b60d4603 advanced_api_fuzzer: add extreme config value coverage
|
||||||
|
72fe52f6 anim_encode.c,cosmetics: normalize indent
|
||||||
|
116d235c anim_encode: Fix encoded_frames_[] overflow
|
||||||
|
6f445b3e CMake: set CMP0072 to NEW
|
||||||
|
b1cf887f define WEBP_RESTRICT for MSVC
|
||||||
|
3e265136 Add WEBP_RESTRICT & use it in VP8BitReader
|
||||||
|
f6d29247 vp8l_dec::ProcessRows: fix int overflow in multiply
|
||||||
|
de3b4ba8 CMake: add WEBP_BUILD_LIBWEBPMUX
|
||||||
|
7f09d3d1 CMakeLists.txt: rm libwebpmux dep from anim_{diff,dump}
|
||||||
|
4edea4a6 Init{RGB,YUV}Rescaler: fix a few more int overflows
|
||||||
|
c9e26bdb rescaler_utils: set max valid scaled w/h to INT_MAX/2
|
||||||
|
28d488e6 utils.h: add SizeOverflow()
|
||||||
|
695bdaa2 Export/EmitRescaledRowsRGBA: fix pointer offset int overflow
|
||||||
|
685d073e Init{RGB,YUV}Rescaler: fix int overflows in multiplication
|
||||||
|
d38bd0dd WebPFlipBuffer: fix integer overflow
|
||||||
|
109ff0f1 utils: allow MALLOC_LIMIT to indicate a max
|
||||||
|
a2fce867 WebPRescalerImportRowExpand_C: promote some vals before multiply
|
||||||
|
776983d4 AllocateBuffer: fix int multiplication overflow check
|
||||||
|
315abbd6 Merge "Revert "Do not use a palette for one color images.""
|
||||||
|
eae815d0 Merge changes Ica3bbf75,I82f82954
|
||||||
|
afbca5a1 Require Emscripten 2.0.18
|
||||||
|
3320416b CMakeLists,emscripten: use EXPORTED_RUNTIME_METHODS
|
||||||
|
29145ed6 Update README instructions for using Emscripten
|
||||||
|
1f579139 cosmetics: remove use of 'sanity' / 'master'
|
||||||
|
29b6129c WebPAnimEncoderNewInternal: remove some unnecessary inits
|
||||||
|
b60869a1 Revert "Do not use a palette for one color images."
|
||||||
|
6fb4cddc demux: move padded size calc post unpadded validation
|
||||||
|
05b72d42 vp8l_enc.c: normalize index types
|
||||||
|
b6513fba Do not use a palette for one color images.
|
||||||
|
98bbe35b Fix multi-threading with palettes.
|
||||||
|
b1674240 Add modified Zeng's method to palette sorting.
|
||||||
|
88c90c45 add CONTRIBUTING.md
|
||||||
|
6a9916d7 WebPRescalerInit: add missing int64_t promotion
|
||||||
|
b6cf52d5 WebPIoInitFromOptions: treat use_scaling as a bool
|
||||||
|
3b12b7f4 WebPIoInitFromOptions: treat use_cropping as a bool
|
||||||
|
595fa13f add WebPCheckCropDimensions()
|
||||||
|
8fdaecb0 Disable cross-color when palette is used.
|
||||||
|
8933bac2 WebPIoInitFromOptions: respect incoming bypass_filtering val
|
||||||
|
7d416ff0 webpdec,cosmetics: match error text to function call
|
||||||
|
ec6cfeb5 Fix typo on WebPPictureAlloc() in README
|
||||||
|
7e58a1a2 *.cmake: add license header
|
||||||
|
5651a6b2 cmake: fix .so versioning
|
||||||
|
25ae67b3 xcframeworkbuild.sh: add arm64 simulator target
|
||||||
|
5d4ee4c3 cosmetics: remove use of the term 'dummy'
|
||||||
|
01b38ee1 faster CollectColorXXXTransforms_SSE41
|
||||||
|
652aa344 Merge "Use BitCtz for FastSLog2Slow_C"
|
||||||
|
0320e1e3 add the missing default BitsCtz() code
|
||||||
|
8886f620 Use BitCtz for FastSLog2Slow_C
|
||||||
|
fae41617 faster CombinedShannonEntropy_SSE2
|
||||||
|
5bd2704e Introduce the BitCtz() function.
|
||||||
|
fee64287 Merge "wicdec,icc: treat unsupported op as non-fatal"
|
||||||
|
33ddb894 lossless_sse{2,41}: remove some unneeded includes
|
||||||
|
b27ea852 wicdec,icc: treat unsupported op as non-fatal
|
||||||
|
b78494a9 Merge "Fix undefined signed shift."
|
||||||
|
e79974cd Fix undefined signed shift.
|
||||||
|
a8853394 SSE4.1 versions of BGRA to RGB/BGR color-space conversions
|
||||||
|
a09a6472 SSE4.1 version of TransformColorInverse
|
||||||
|
401da22b Merge "pngdec: check version before using png_get_chunk_malloc_max"
|
||||||
|
26907822 pngdec: check version before using png_get_chunk_malloc_max
|
||||||
|
06c1e72e Code cleanup
|
||||||
|
8f0d41aa Merge changes Id135bbf4,I99e59797
|
||||||
|
373eb170 gif2webp: don't store loop-count if there's only 1 frame
|
||||||
|
759b9d5a cmake: add WEBP_USE_THREAD option
|
||||||
|
926ce921 cmake: don't install binaries from extras/
|
||||||
|
9c367bc6 WebPAnimDecoderNewInternal: validate bitstream before alloc
|
||||||
|
47f64f6e filters_sse2: import Chromium change
|
||||||
|
cc3577e9 fuzzer/*: use src/ based include paths
|
||||||
|
004d77ff Merge tag 'v1.2.0'
|
||||||
|
fedac6cc update ChangeLog (tag: v1.2.0-rc3, tag: v1.2.0)
|
||||||
170a8712 Fix check_c_source_compiles with pthread.
|
170a8712 Fix check_c_source_compiles with pthread.
|
||||||
|
ceddb5fc Fix check_c_source_compiles with pthread.
|
||||||
85995719 disable CombinedShannonEntropy_SSE2 on x86
|
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
|
8af7436f Merge "{ios,xcframework}build.sh: make min version(s) more visible" into 1.2.0
|
||||||
e56c3c5b pngdec: raise memory limit if needed
|
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
|
13b8e9fe {ios,xcframework}build.sh: make min version(s) more visible
|
||||||
a9225410 animdecoder_fuzzer: fix memory leak
|
a9225410 animdecoder_fuzzer: fix memory leak
|
||||||
d6c2285d update gradle to 6.1.1
|
d6c2285d update gradle to 6.1.1
|
||||||
|
8df77fb1 animdecoder_fuzzer: fix memory leak
|
||||||
52ce6333 update NEWS
|
52ce6333 update NEWS
|
||||||
28c49820 bump version to 1.2.0
|
28c49820 bump version to 1.2.0
|
||||||
7363dff2 webp/encode.h: restore WEBP_ENCODER_ABI_VERSION to v1.1.0
|
7363dff2 webp/encode.h: restore WEBP_ENCODER_ABI_VERSION to v1.1.0
|
||||||
|
@ -215,6 +215,7 @@ 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 \
|
||||||
|
20
NEWS
20
NEWS
@ -1,3 +1,23 @@
|
|||||||
|
- 12/15/2021: version 1.2.2
|
||||||
|
This is a binary compatible release.
|
||||||
|
* webpmux: add "-set bgcolor A,R,G,B"
|
||||||
|
* add ARM64 NEON support for MSVC builds (#539)
|
||||||
|
* fix duplicate include error in Xcode when using multiple XCFrameworks in a
|
||||||
|
project (#542)
|
||||||
|
* doc updates and bug fixes (#538, #544)
|
||||||
|
|
||||||
|
- 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
|
- 12/23/2020: version 1.2.0
|
||||||
* API changes:
|
* API changes:
|
||||||
- libwebp:
|
- libwebp:
|
||||||
|
214
PRESUBMIT.py
Normal file
214
PRESUBMIT.py
Normal file
@ -0,0 +1,214 @@
|
|||||||
|
# Copyright (c) 2021, Google Inc. All rights reserved.
|
||||||
|
#
|
||||||
|
# Redistribution and use in source and binary forms, with or without
|
||||||
|
# modification, are permitted provided that the following conditions are
|
||||||
|
# met:
|
||||||
|
#
|
||||||
|
# * Redistributions of source code must retain the above copyright
|
||||||
|
# notice, this list of conditions and the following disclaimer.
|
||||||
|
#
|
||||||
|
# * Redistributions in binary form must reproduce the above copyright
|
||||||
|
# notice, this list of conditions and the following disclaimer in
|
||||||
|
# the documentation and/or other materials provided with the
|
||||||
|
# distribution.
|
||||||
|
#
|
||||||
|
# * Neither the name of Google nor the names of its contributors may
|
||||||
|
# be used to endorse or promote products derived from this software
|
||||||
|
# without specific prior written permission.
|
||||||
|
#
|
||||||
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
"""Top-level presubmit script for libwebp.
|
||||||
|
|
||||||
|
See https://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts for
|
||||||
|
details on the presubmit API built into depot_tools.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import re
|
||||||
|
import subprocess2
|
||||||
|
|
||||||
|
USE_PYTHON3 = True
|
||||||
|
_BASH_INDENTATION = "2"
|
||||||
|
_GIT_COMMIT_SUBJECT_LENGTH = 65
|
||||||
|
_INCLUDE_BASH_FILES_ONLY = [r".*\.sh$"]
|
||||||
|
_INCLUDE_MAN_FILES_ONLY = [r"man/.+\.1$"]
|
||||||
|
_LIBWEBP_MAX_LINE_LENGTH = 80
|
||||||
|
|
||||||
|
|
||||||
|
def _CheckCommitSubjectLength(input_api, output_api):
|
||||||
|
"""Ensures commit's subject length is no longer than 65 chars."""
|
||||||
|
name = "git-commit subject"
|
||||||
|
cmd = ["git", "log", "-1", "--pretty=%s"]
|
||||||
|
start = input_api.time.time()
|
||||||
|
proc = subprocess2.Popen(
|
||||||
|
cmd,
|
||||||
|
stderr=subprocess2.PIPE,
|
||||||
|
stdout=subprocess2.PIPE,
|
||||||
|
universal_newlines=True)
|
||||||
|
|
||||||
|
stdout, _ = proc.communicate()
|
||||||
|
duration = input_api.time.time() - start
|
||||||
|
|
||||||
|
if not re.match(r"^Revert",
|
||||||
|
stdout) and (len(stdout) - 1) > _GIT_COMMIT_SUBJECT_LENGTH:
|
||||||
|
failure_msg = (
|
||||||
|
"The commit subject: %s is too long (%d chars)\n"
|
||||||
|
"Try to keep this to 50 or less (up to 65 is permitted for "
|
||||||
|
"non-reverts).\n"
|
||||||
|
"https://www.git-scm.com/book/en/v2/Distributed-Git-Contributing-to-a-"
|
||||||
|
"Project#_commit_guidelines") % (stdout, len(stdout) - 1)
|
||||||
|
return output_api.PresubmitError("%s\n (%4.2fs) failed\n%s" %
|
||||||
|
(name, duration, failure_msg))
|
||||||
|
|
||||||
|
return output_api.PresubmitResult("%s\n (%4.2fs) success" % (name, duration))
|
||||||
|
|
||||||
|
|
||||||
|
def _GetFilesToSkip(input_api):
|
||||||
|
return list(input_api.DEFAULT_FILES_TO_SKIP) + [
|
||||||
|
r"swig/.*\.py$",
|
||||||
|
r"\.pylintrc$",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def _RunManCmd(input_api, output_api, man_file):
|
||||||
|
"""man command wrapper."""
|
||||||
|
cmd = ["man", "--warnings", "-EUTF-8", "-l", "-Tutf8", "-Z", man_file]
|
||||||
|
name = "Check %s file." % man_file
|
||||||
|
start = input_api.time.time()
|
||||||
|
output, _ = subprocess2.communicate(
|
||||||
|
cmd, stdout=None, stderr=subprocess2.PIPE, universal_newlines=True)
|
||||||
|
duration = input_api.time.time() - start
|
||||||
|
if output[1]:
|
||||||
|
return output_api.PresubmitError("%s\n%s (%4.2fs) failed\n%s" %
|
||||||
|
(name, " ".join(cmd), duration, output[1]))
|
||||||
|
return output_api.PresubmitResult("%s\n%s (%4.2fs)\n" %
|
||||||
|
(name, " ".join(cmd), duration))
|
||||||
|
|
||||||
|
|
||||||
|
def _RunShellCheckCmd(input_api, output_api, bash_file):
|
||||||
|
"""shellcheck command wrapper."""
|
||||||
|
cmd = ["shellcheck", "-x", "-oall", "-sbash", bash_file]
|
||||||
|
name = "Check %s file." % bash_file
|
||||||
|
start = input_api.time.time()
|
||||||
|
output, rc = subprocess2.communicate(
|
||||||
|
cmd, stdout=None, stderr=subprocess2.PIPE, universal_newlines=True)
|
||||||
|
duration = input_api.time.time() - start
|
||||||
|
if rc == 0:
|
||||||
|
return output_api.PresubmitResult("%s\n%s (%4.2fs)\n" %
|
||||||
|
(name, " ".join(cmd), duration))
|
||||||
|
return output_api.PresubmitError("%s\n%s (%4.2fs) failed\n%s" %
|
||||||
|
(name, " ".join(cmd), duration, output[1]))
|
||||||
|
|
||||||
|
|
||||||
|
def _RunShfmtCheckCmd(input_api, output_api, bash_file):
|
||||||
|
"""shfmt command wrapper."""
|
||||||
|
cmd = [
|
||||||
|
"shfmt", "-i", _BASH_INDENTATION, "-bn", "-ci", "-sr", "-kp", "-d",
|
||||||
|
bash_file
|
||||||
|
]
|
||||||
|
name = "Check %s file." % bash_file
|
||||||
|
start = input_api.time.time()
|
||||||
|
output, rc = subprocess2.communicate(
|
||||||
|
cmd, stdout=None, stderr=subprocess2.PIPE, universal_newlines=True)
|
||||||
|
duration = input_api.time.time() - start
|
||||||
|
if rc == 0:
|
||||||
|
return output_api.PresubmitResult("%s\n%s (%4.2fs)\n" %
|
||||||
|
(name, " ".join(cmd), duration))
|
||||||
|
return output_api.PresubmitError("%s\n%s (%4.2fs) failed\n%s" %
|
||||||
|
(name, " ".join(cmd), duration, output[1]))
|
||||||
|
|
||||||
|
|
||||||
|
def _RunCmdOnCheckedFiles(input_api, output_api, run_cmd, files_to_check):
|
||||||
|
"""Ensure that libwebp/ files are clean."""
|
||||||
|
file_filter = lambda x: input_api.FilterSourceFile(
|
||||||
|
x, files_to_check=files_to_check, files_to_skip=None)
|
||||||
|
|
||||||
|
affected_files = input_api.change.AffectedFiles(file_filter=file_filter)
|
||||||
|
results = [
|
||||||
|
run_cmd(input_api, output_api, f.AbsoluteLocalPath())
|
||||||
|
for f in affected_files
|
||||||
|
]
|
||||||
|
return results
|
||||||
|
|
||||||
|
|
||||||
|
def _CommonChecks(input_api, output_api):
|
||||||
|
"""Ensures this patch does not have trailing spaces, extra EOLs,
|
||||||
|
or long lines.
|
||||||
|
"""
|
||||||
|
results = []
|
||||||
|
results.extend(
|
||||||
|
input_api.canned_checks.CheckChangeHasNoCrAndHasOnlyOneEol(
|
||||||
|
input_api, output_api))
|
||||||
|
results.extend(
|
||||||
|
input_api.canned_checks.CheckChangeHasNoTabs(input_api, output_api))
|
||||||
|
results.extend(
|
||||||
|
input_api.canned_checks.CheckChangeHasNoStrayWhitespace(
|
||||||
|
input_api, output_api))
|
||||||
|
results.append(_CheckCommitSubjectLength(input_api, output_api))
|
||||||
|
|
||||||
|
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.0
|
\____/____/\_____/_____/____/v1.2.2
|
||||||
|
|
||||||
Description:
|
Description:
|
||||||
============
|
============
|
||||||
@ -13,13 +13,13 @@ WebP codec: library to encode and decode images in WebP format. This package
|
|||||||
contains the library that can be used in other programs to add WebP support,
|
contains the library that can be used in other programs to add WebP support,
|
||||||
as well as the command line tools 'cwebp' and 'dwebp'.
|
as well as the command line tools 'cwebp' and 'dwebp'.
|
||||||
|
|
||||||
See http://developers.google.com/speed/webp
|
See https://developers.google.com/speed/webp
|
||||||
|
|
||||||
The latest source tree is available at
|
The latest source tree is available at
|
||||||
https://chromium.googlesource.com/webm/libwebp
|
https://chromium.googlesource.com/webm/libwebp
|
||||||
|
|
||||||
It is released under the same license as the WebM project.
|
It is released under the same license as the WebM project.
|
||||||
See http://www.webmproject.org/license/software/ or the
|
See https://www.webmproject.org/license/software/ or the
|
||||||
"COPYING" file for details. An additional intellectual
|
"COPYING" file for details. An additional intellectual
|
||||||
property rights grant can be found in the file PATENTS.
|
property rights grant can be found in the file PATENTS.
|
||||||
|
|
||||||
@ -436,8 +436,8 @@ Prerequisites:
|
|||||||
|
|
||||||
2) (Optional) qcms (Quick Color Management System)
|
2) (Optional) qcms (Quick Color Management System)
|
||||||
i. Download qcms from Mozilla / Chromium:
|
i. Download qcms from Mozilla / Chromium:
|
||||||
http://hg.mozilla.org/mozilla-central/file/0e7639e3bdfb/gfx/qcms
|
https://hg.mozilla.org/mozilla-central/file/0e7639e3bdfb/gfx/qcms
|
||||||
http://src.chromium.org/viewvc/chrome/trunk/src/third_party/qcms
|
https://source.chromium.org/chromium/chromium/src/+/main:third_party/qcms/;drc=d4a2f8e1ed461d8fc05ed88d1ae2dc94c9773825
|
||||||
ii. Build and archive the source files as libqcms.a / qcms.lib
|
ii. Build and archive the source files as libqcms.a / qcms.lib
|
||||||
iii. Update makefile.unix / Makefile.vc
|
iii. Update makefile.unix / Makefile.vc
|
||||||
a) Define WEBP_HAVE_QCMS
|
a) Define WEBP_HAVE_QCMS
|
||||||
@ -619,7 +619,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 (!WebPPictureAllocate(&pic)) {
|
if (!WebPPictureAlloc(&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,
|
||||||
@ -786,10 +786,10 @@ Bugs:
|
|||||||
Please report all bugs to the issue tracker:
|
Please report all bugs to the issue tracker:
|
||||||
https://bugs.chromium.org/p/webp
|
https://bugs.chromium.org/p/webp
|
||||||
Patches welcome! See this page to get started:
|
Patches welcome! See this page to get started:
|
||||||
http://www.webmproject.org/code/contribute/submitting-patches/
|
https://www.webmproject.org/code/contribute/submitting-patches/
|
||||||
|
|
||||||
Discuss:
|
Discuss:
|
||||||
========
|
========
|
||||||
|
|
||||||
Email: webp-discuss@webmproject.org
|
Email: webp-discuss@webmproject.org
|
||||||
Web: http://groups.google.com/a/webmproject.org/group/webp-discuss
|
Web: https://groups.google.com/a/webmproject.org/group/webp-discuss
|
||||||
|
17
README.mux
17
README.mux
@ -1,7 +1,7 @@
|
|||||||
__ __ ____ ____ ____ __ __ _ __ __
|
__ __ ____ ____ ____ __ __ _ __ __
|
||||||
/ \\/ \/ _ \/ _ \/ _ \/ \ \/ \___/_ / _\
|
/ \\/ \/ _ \/ _ \/ _ \/ \ \/ \___/_ / _\
|
||||||
\ / __/ _ \ __/ / / (_/ /__
|
\ / __/ _ \ __/ / / (_/ /__
|
||||||
\__\__/\_____/_____/__/ \__//_/\_____/__/___/v1.2.0
|
\__\__/\_____/_____/__/ \__//_/\_____/__/___/v1.2.2
|
||||||
|
|
||||||
|
|
||||||
Description:
|
Description:
|
||||||
@ -43,11 +43,12 @@ GET_OPTIONS:
|
|||||||
frame n get nth frame
|
frame n get nth frame
|
||||||
|
|
||||||
SET_OPTIONS:
|
SET_OPTIONS:
|
||||||
Set color profile/metadata:
|
Set color profile/metadata/parameters:
|
||||||
loop LOOP_COUNT set the loop count
|
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
|
||||||
@ -248,10 +249,10 @@ Bugs:
|
|||||||
Please report all bugs to the issue tracker:
|
Please report all bugs to the issue tracker:
|
||||||
https://bugs.chromium.org/p/webp
|
https://bugs.chromium.org/p/webp
|
||||||
Patches welcome! See this page to get started:
|
Patches welcome! See this page to get started:
|
||||||
http://www.webmproject.org/code/contribute/submitting-patches/
|
https://www.webmproject.org/code/contribute/submitting-patches/
|
||||||
|
|
||||||
Discuss:
|
Discuss:
|
||||||
========
|
========
|
||||||
|
|
||||||
Email: webp-discuss@webmproject.org
|
Email: webp-discuss@webmproject.org
|
||||||
Web: http://groups.google.com/a/webmproject.org/group/webp-discuss
|
Web: https://groups.google.com/a/webmproject.org/group/webp-discuss
|
||||||
|
@ -10,26 +10,18 @@ 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://kripken.github.io/emscripten-site/docs/getting_started/downloads.html
|
https://emscripten.org/docs/getting_started/downloads.html#installation-instructions-using-the-emsdk-recommended
|
||||||
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, $EMSCRIPTEN should point to the
|
location of the SDK. In particular, $EMSDK 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/upstream/emscripten
|
|
||||||
windows: set EMSCRIPTEN=%EMSDK%\upstream\emscripten
|
|
||||||
|
|
||||||
- configure the project 'WEBP_JS' with CMake using:
|
- configure the project 'WEBP_JS' with CMake using:
|
||||||
|
|
||||||
cd webp_js && \
|
cd webp_js && \
|
||||||
cmake -DWEBP_BUILD_WEBP_JS=ON \
|
emcmake cmake -DWEBP_BUILD_WEBP_JS=ON \
|
||||||
-DCMAKE_TOOLCHAIN_FILE=$EMSCRIPTEN/cmake/Modules/Platform/Emscripten.cmake \
|
|
||||||
../
|
../
|
||||||
|
|
||||||
- compile webp.js using 'make'.
|
- compile webp.js using 'emmake 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.wasm files generated.
|
||||||
@ -58,7 +50,7 @@ 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 1.37.8,
|
You will need a fairly recent version of Emscripten (at least 2.0.18,
|
||||||
latest-upstream is recommended) and of your WASM-enabled browser to run this
|
latest-upstream is recommended) and of your WASM-enabled browser to run this
|
||||||
version.
|
version.
|
||||||
|
|
||||||
|
@ -141,6 +141,7 @@ 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"
|
||||||
|
@ -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 "webp")
|
set(WebP_INCLUDE_DIRS "@CMAKE_INSTALL_FULL_INCLUDEDIR@")
|
||||||
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}")
|
||||||
|
@ -1,3 +1,11 @@
|
|||||||
|
# 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)
|
||||||
|
|
||||||
@ -117,6 +125,12 @@ 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)
|
||||||
@ -134,6 +148,7 @@ 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,3 +1,11 @@
|
|||||||
|
# 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.
|
||||||
@ -22,26 +30,25 @@ check_c_source_compiles("
|
|||||||
" HAVE_BUILTIN_BSWAP64)
|
" HAVE_BUILTIN_BSWAP64)
|
||||||
|
|
||||||
# Check for libraries.
|
# Check for libraries.
|
||||||
if(NOT WEBP_BUILD_WEBP_JS)
|
if(WEBP_USE_THREAD)
|
||||||
# Disable pThreads for WASM.
|
|
||||||
find_package(Threads)
|
find_package(Threads)
|
||||||
endif()
|
if(Threads_FOUND)
|
||||||
if(Threads_FOUND)
|
# work around cmake bug on QNX (https://cmake.org/Bug/view.php?id=11333)
|
||||||
# work around cmake bug on QNX (https://cmake.org/Bug/view.php?id=11333)
|
if(CMAKE_USE_PTHREADS_INIT AND NOT CMAKE_SYSTEM_NAME STREQUAL "QNX")
|
||||||
if(CMAKE_USE_PTHREADS_INIT AND NOT CMAKE_SYSTEM_NAME STREQUAL "QNX")
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pthread")
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pthread")
|
endif()
|
||||||
|
check_c_source_compiles("
|
||||||
|
#include <pthread.h>
|
||||||
|
int main (void) {
|
||||||
|
int attr = PTHREAD_PRIO_INHERIT;
|
||||||
|
return attr;
|
||||||
|
}
|
||||||
|
" FLAG_HAVE_PTHREAD_PRIO_INHERIT)
|
||||||
|
set(HAVE_PTHREAD_PRIO_INHERIT ${FLAG_HAVE_PTHREAD_PRIO_INHERIT})
|
||||||
|
list(APPEND WEBP_DEP_LIBRARIES ${CMAKE_THREAD_LIBS_INIT})
|
||||||
endif()
|
endif()
|
||||||
check_c_source_compiles("
|
set(WEBP_USE_THREAD ${Threads_FOUND})
|
||||||
#include <pthread.h>
|
|
||||||
int main (void) {
|
|
||||||
int attr = PTHREAD_PRIO_INHERIT;
|
|
||||||
return attr;
|
|
||||||
}
|
|
||||||
" FLAG_HAVE_PTHREAD_PRIO_INHERIT)
|
|
||||||
set(HAVE_PTHREAD_PRIO_INHERIT ${FLAG_HAVE_PTHREAD_PRIO_INHERIT})
|
|
||||||
list(APPEND WEBP_DEP_LIBRARIES ${CMAKE_THREAD_LIBS_INIT})
|
|
||||||
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/")
|
||||||
|
92
configure.ac
92
configure.ac
@ -1,6 +1,6 @@
|
|||||||
AC_INIT([libwebp], [1.2.0],
|
AC_INIT([libwebp], [1.2.2],
|
||||||
[https://bugs.chromium.org/p/webp],,
|
[https://bugs.chromium.org/p/webp],,
|
||||||
[http://developers.google.com/speed/webp])
|
[https://developers.google.com/speed/webp])
|
||||||
AC_CANONICAL_HOST
|
AC_CANONICAL_HOST
|
||||||
AC_PREREQ([2.60])
|
AC_PREREQ([2.60])
|
||||||
AM_INIT_AUTOMAKE([-Wall foreign subdir-objects])
|
AM_INIT_AUTOMAKE([-Wall foreign subdir-objects])
|
||||||
@ -32,6 +32,40 @@ 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)
|
||||||
@ -225,6 +259,9 @@ 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])])
|
||||||
|
|
||||||
@ -409,6 +446,10 @@ AS_IF([test "x$enable_gl" != "xno"], [
|
|||||||
|
|
||||||
if test "$glut_support" = "yes" -a "$enable_libwebpdemux" = "yes"; then
|
if test "$glut_support" = "yes" -a "$enable_libwebpdemux" = "yes"; then
|
||||||
build_vwebp=yes
|
build_vwebp=yes
|
||||||
|
else
|
||||||
|
AC_MSG_NOTICE(
|
||||||
|
m4_normalize([Not building vwebp.
|
||||||
|
OpenGL libraries and --enable-libwebpdemux are required.]))
|
||||||
fi
|
fi
|
||||||
])
|
])
|
||||||
AM_CONDITIONAL([BUILD_VWEBP], [test "$build_vwebp" = "yes"])
|
AM_CONDITIONAL([BUILD_VWEBP], [test "$build_vwebp" = "yes"])
|
||||||
@ -468,7 +509,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_WARN(Optional SDL library not found)
|
AC_MSG_NOTICE([Not building vwebp-sdl. SDL library is required.])
|
||||||
fi
|
fi
|
||||||
])
|
])
|
||||||
|
|
||||||
@ -592,11 +633,17 @@ 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"])
|
||||||
@ -604,11 +651,17 @@ 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"])
|
||||||
|
|
||||||
@ -692,39 +745,6 @@ 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])
|
||||||
|
@ -6,8 +6,8 @@ HTML generation requires kramdown [1], easily installed as a
|
|||||||
rubygem [2]. Rubygems installation should satisfy dependencies
|
rubygem [2]. Rubygems installation should satisfy dependencies
|
||||||
automatically.
|
automatically.
|
||||||
|
|
||||||
[1]: http://kramdown.rubyforge.org/
|
[1]: https://kramdown.gettalong.org/
|
||||||
[2]: http://rubygems.org/
|
[2]: https://rubygems.org/
|
||||||
|
|
||||||
HTML generation can then be done from the project root:
|
HTML generation can then be done from the project root:
|
||||||
|
|
||||||
@ -26,4 +26,4 @@ $ kramdown doc/webp-lossless-bitstream-spec.txt --template \
|
|||||||
|
|
||||||
Optimally, use kramdown 0.13.7 or newer if syntax highlighting desired.
|
Optimally, use kramdown 0.13.7 or newer if syntax highlighting desired.
|
||||||
|
|
||||||
[3]: http://coderay.rubychan.de/
|
[3]: https://github.com/rubychan/coderay
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
Although you may be viewing an alternate representation, this document
|
Although you may be viewing an alternate representation, this document
|
||||||
is sourced in Markdown, a light-duty markup scheme, and is optimized for
|
is sourced in Markdown, a light-duty markup scheme, and is optimized for
|
||||||
the [kramdown](http://kramdown.rubyforge.org/) transformer.
|
the [kramdown](https://kramdown.gettalong.org/) transformer.
|
||||||
|
|
||||||
See the accompanying README. External link targets are referenced at the
|
See the accompanying README. External link targets are referenced at the
|
||||||
end of this file.
|
end of this file.
|
||||||
@ -53,10 +53,6 @@ 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
|
||||||
------------------------
|
------------------------
|
||||||
|
|
||||||
@ -269,7 +265,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). _\[status: experimental\]_
|
* An optional list of [unknown chunks](#unknown-chunks).
|
||||||
|
|
||||||
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:
|
||||||
@ -705,7 +701,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 _\[status: experimental\]_
|
#### Unknown Chunks
|
||||||
|
|
||||||
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
|
||||||
@ -815,9 +811,9 @@ RIFF/WEBP
|
|||||||
+- EXIF (metadata)
|
+- EXIF (metadata)
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
[vp8spec]: http://tools.ietf.org/html/rfc6386
|
[vp8spec]: https://datatracker.ietf.org/doc/html/rfc6386
|
||||||
[webpllspec]: https://chromium.googlesource.com/webm/libwebp/+/master/doc/webp-lossless-bitstream-spec.txt
|
[webpllspec]: https://chromium.googlesource.com/webm/libwebp/+/HEAD/doc/webp-lossless-bitstream-spec.txt
|
||||||
[iccspec]: http://www.color.org/icc_specs2.xalter
|
[iccspec]: https://www.color.org/icc_specs2.xalter
|
||||||
[metadata]: http://www.metadataworkinggroup.org/pdf/mwg_guidance.pdf
|
[metadata]: https://web.archive.org/web/20180919181934/http://www.metadataworkinggroup.org/pdf/mwg_guidance.pdf
|
||||||
[rfc 1166]: http://tools.ietf.org/html/rfc1166
|
[rfc 1166]: https://datatracker.ietf.org/doc/html/rfc1166
|
||||||
[rfc 2119]: http://tools.ietf.org/html/rfc2119
|
[rfc 2119]: https://datatracker.ietf.org/doc/html/rfc2119
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
Although you may be viewing an alternate representation, this document
|
Although you may be viewing an alternate representation, this document
|
||||||
is sourced in Markdown, a light-duty markup scheme, and is optimized for
|
is sourced in Markdown, a light-duty markup scheme, and is optimized for
|
||||||
the [kramdown](http://kramdown.rubyforge.org/) transformer.
|
the [kramdown](https://kramdown.gettalong.org/) transformer.
|
||||||
|
|
||||||
See the accompanying README. External link targets are referenced at the
|
See the accompanying README. External link targets are referenced at the
|
||||||
end of this file.
|
end of this file.
|
||||||
@ -1087,4 +1087,4 @@ A possible example sequence:
|
|||||||
<lz77-coded image>
|
<lz77-coded image>
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
[canonical_huff]: http://en.wikipedia.org/wiki/Canonical_Huffman_code
|
[canonical_huff]: https://en.wikipedia.org/wiki/Canonical_Huffman_code
|
||||||
|
@ -465,8 +465,10 @@ 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 (!loop_compatibility) {
|
if (frame_number == 1) {
|
||||||
|
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
|
||||||
|
@ -41,6 +41,7 @@
|
|||||||
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] = {
|
||||||
@ -116,6 +117,7 @@ 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;
|
||||||
|
|
||||||
@ -580,7 +582,7 @@ static WebPInfoStatus ParseAlphaHeader(const ChunkData* const chunk_data,
|
|||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// Chunk parsing.
|
// Chunk parsing.
|
||||||
|
|
||||||
static WebPInfoStatus ParseRIFFHeader(const WebPInfo* const webp_info,
|
static WebPInfoStatus ParseRIFFHeader(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;
|
||||||
@ -988,7 +990,7 @@ static WebPInfoStatus ProcessChunk(const ChunkData* const chunk_data,
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
static WebPInfoStatus Validate(const WebPInfo* const webp_info) {
|
static WebPInfoStatus Validate(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;
|
||||||
@ -1093,16 +1095,14 @@ 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 HelpShort(void) {
|
static void Help(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,17 +1123,15 @@ int main(int argc, const char* argv[]) {
|
|||||||
INIT_WARGV(argc, argv);
|
INIT_WARGV(argc, argv);
|
||||||
|
|
||||||
if (argc == 1) {
|
if (argc == 1) {
|
||||||
HelpShort();
|
Help();
|
||||||
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") ||
|
||||||
HelpShort();
|
!strcmp(argv[c], "-H") || !strcmp(argv[c], "-longhelp")) {
|
||||||
FREE_WARGV_AND_RETURN(WEBP_INFO_OK);
|
Help();
|
||||||
} 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;
|
||||||
@ -1154,7 +1152,7 @@ int main(int argc, const char* argv[]) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (c == argc) {
|
if (c == argc) {
|
||||||
HelpShort();
|
Help();
|
||||||
FREE_WARGV_AND_RETURN(WEBP_INFO_INVALID_COMMAND);
|
FREE_WARGV_AND_RETURN(WEBP_INFO_INVALID_COMMAND);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,6 +99,7 @@ typedef enum {
|
|||||||
FEATURE_ANMF,
|
FEATURE_ANMF,
|
||||||
FEATURE_DURATION,
|
FEATURE_DURATION,
|
||||||
FEATURE_LOOP,
|
FEATURE_LOOP,
|
||||||
|
FEATURE_BGCOLOR,
|
||||||
LAST_FEATURE
|
LAST_FEATURE
|
||||||
} FeatureType;
|
} FeatureType;
|
||||||
|
|
||||||
@ -315,11 +316,12 @@ static void PrintHelp(void) {
|
|||||||
|
|
||||||
printf("\n");
|
printf("\n");
|
||||||
printf("SET_OPTIONS:\n");
|
printf("SET_OPTIONS:\n");
|
||||||
printf(" Set color profile/metadata:\n");
|
printf(" Set color profile/metadata/parameters:\n");
|
||||||
printf(" loop LOOP_COUNT set the loop count\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");
|
||||||
@ -472,11 +474,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, dummy;
|
int dispose_method, unused;
|
||||||
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, &dummy);
|
&plus_minus, &blend_method, &unused);
|
||||||
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
|
||||||
@ -495,7 +497,7 @@ static int ParseFrameArgs(const char* args, WebPMuxFrameInfo* const info) {
|
|||||||
|
|
||||||
WarnAboutOddOffset(info);
|
WarnAboutOddOffset(info);
|
||||||
|
|
||||||
// Note: The sanity of the following conversion is checked by
|
// Note: The validity of the following conversion is checked by
|
||||||
// WebPMuxPushFrame().
|
// WebPMuxPushFrame().
|
||||||
info->dispose_method = (WebPMuxAnimDispose)dispose_method;
|
info->dispose_method = (WebPMuxAnimDispose)dispose_method;
|
||||||
|
|
||||||
@ -778,6 +780,13 @@ 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], "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];
|
||||||
@ -1053,6 +1062,30 @@ static int Process(const Config* config) {
|
|||||||
}
|
}
|
||||||
break;
|
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;
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
|
|
||||||
#define XTRA_MAJ_VERSION 1
|
#define XTRA_MAJ_VERSION 1
|
||||||
#define XTRA_MIN_VERSION 2
|
#define XTRA_MIN_VERSION 2
|
||||||
#define XTRA_REV_VERSION 0
|
#define XTRA_REV_VERSION 2
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -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 dummy) {
|
static void PNGAPI PNGErrorFunction(png_structp png, png_const_charp unused) {
|
||||||
(void)dummy; // remove variable-unused warning
|
(void)unused; // 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 (dummy)
|
PutLE32(bmp_header + 34, 0); // image size (placeholder)
|
||||||
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
|
||||||
|
@ -79,7 +79,7 @@ int WebPWriteTIFF(FILE* fout, const struct WebPDecBuffer* const buffer);
|
|||||||
int WebPWriteAlphaPlane(FILE* fout, const struct WebPDecBuffer* const buffer);
|
int WebPWriteAlphaPlane(FILE* fout, const struct WebPDecBuffer* const buffer);
|
||||||
|
|
||||||
// Save as YUV samples as PGM format (using IMC4 layout).
|
// Save as YUV samples as PGM format (using IMC4 layout).
|
||||||
// See: http://www.fourcc.org/yuv.php#IMC4.
|
// See: https://www.fourcc.org/yuv.php#IMC4.
|
||||||
// (very convenient format for viewing the samples, esp. for odd dimensions).
|
// (very convenient format for viewing the samples, esp. for odd dimensions).
|
||||||
int WebPWritePGM(FILE* fout, const struct WebPDecBuffer* const buffer);
|
int WebPWritePGM(FILE* fout, const struct WebPDecBuffer* const buffer);
|
||||||
|
|
||||||
|
@ -148,9 +148,11 @@ void ImgIoUtilCopyPlane(const uint8_t* src, int src_stride,
|
|||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
int ImgIoUtilCheckSizeArgumentsOverflow(uint64_t nmemb, size_t size) {
|
int ImgIoUtilCheckSizeArgumentsOverflow(uint64_t stride, size_t height) {
|
||||||
const uint64_t total_size = nmemb * size;
|
const uint64_t total_size = stride * height;
|
||||||
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
|
||||||
|
@ -54,8 +54,8 @@ void ImgIoUtilCopyPlane(const uint8_t* src, int src_stride,
|
|||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
// Returns 0 in case of overflow of nmemb * size.
|
// Returns 0 in case of overflow, memory over-allocation or excessive dimension.
|
||||||
int ImgIoUtilCheckSizeArgumentsOverflow(uint64_t nmemb, size_t size);
|
int ImgIoUtilCheckSizeArgumentsOverflow(uint64_t stride, size_t height);
|
||||||
|
|
||||||
#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 sanity
|
memset((j_decompress_ptr)&dinfo, 0, sizeof(dinfo)); // for setjmp safety
|
||||||
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;
|
||||||
|
|
||||||
|
@ -133,7 +133,7 @@ static const struct {
|
|||||||
MetadataPayload* const payload);
|
MetadataPayload* const payload);
|
||||||
size_t storage_offset;
|
size_t storage_offset;
|
||||||
} kPNGMetadataMap[] = {
|
} kPNGMetadataMap[] = {
|
||||||
// http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/PNG.html#TextualData
|
// https://exiftool.org/TagNames/PNG.html#TextualData
|
||||||
// See also: ExifTool on CPAN.
|
// See also: ExifTool on CPAN.
|
||||||
{ "Raw profile type exif", ProcessRawProfile, METADATA_OFFSET(exif) },
|
{ "Raw profile type exif", ProcessRawProfile, METADATA_OFFSET(exif) },
|
||||||
{ "Raw profile type xmp", ProcessRawProfile, METADATA_OFFSET(xmp) },
|
{ "Raw profile type xmp", ProcessRawProfile, METADATA_OFFSET(xmp) },
|
||||||
@ -259,11 +259,14 @@ 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
|
// If it looks like the bitstream is going to need more memory than libpng's
|
||||||
// internal limit (default: 8M), try to (reasonably) raise it.
|
// internal limit (default: 8M), try to (reasonably) raise it.
|
||||||
if (data_size > png_get_chunk_malloc_max(png) && data_size < (1u << 24)) {
|
if (data_size > png_get_chunk_malloc_max(png) && data_size < (1u << 24)) {
|
||||||
png_set_chunk_malloc_max(png, data_size);
|
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;
|
||||||
|
@ -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 tag_data_len;
|
uint32_t 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)) {
|
||||||
@ -157,6 +157,7 @@ int ReadTIFF(const uint8_t* const data, size_t data_size,
|
|||||||
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 image_width, image_height, tile_width, tile_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;
|
||||||
@ -194,20 +195,31 @@ int ReadTIFF(const uint8_t* const data, size_t data_size,
|
|||||||
fprintf(stderr, "Error! Cannot retrieve TIFF image dimensions.\n");
|
fprintf(stderr, "Error! Cannot retrieve TIFF image dimensions.\n");
|
||||||
goto End;
|
goto End;
|
||||||
}
|
}
|
||||||
if (!ImgIoUtilCheckSizeArgumentsOverflow((uint64_t)image_width * image_height,
|
stride = (uint64_t)image_width * sizeof(*raster);
|
||||||
sizeof(*raster))) {
|
if (!ImgIoUtilCheckSizeArgumentsOverflow(stride, image_height)) {
|
||||||
|
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
|
// 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
|
// be a multiple of 16 and not way too large, so check that it's not more
|
||||||
// twice the image size, for dimensions above some arbitrary minimum 32.
|
// than twice the image size, for dimensions above some arbitrary minimum
|
||||||
if ((TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tile_width) &&
|
// 32. We also check that they respect WebP's dimension and memory limit.
|
||||||
tile_width > 32 && tile_width / 2 > image_width) ||
|
// Note that a tile can be 6byte/px in some cases. Here we assume
|
||||||
(TIFFGetField(tif, TIFFTAG_TILELENGTH, &tile_height) &&
|
// 4byte/px with sizeof(*raster), to be conservative.
|
||||||
tile_height > 32 && tile_height / 2 > image_height)) {
|
if (TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tile_width) &&
|
||||||
fprintf(stderr, "Error! TIFF tile dimensions are too big.\n");
|
TIFFGetField(tif, TIFFTAG_TILELENGTH, &tile_height)) {
|
||||||
goto End;
|
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");
|
||||||
@ -215,15 +227,13 @@ 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 =
|
alloc_size = (int64_t)(stride * image_height);
|
||||||
(int64_t)((uint64_t)image_width * image_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*)_TIFFmalloc((tsize_t)alloc_size);
|
raster = (uint32_t*)_TIFFmalloc((tsize_t)alloc_size);
|
||||||
if (raster != NULL) {
|
if (raster != NULL) {
|
||||||
if (TIFFReadRGBAImageOriented(tif, image_width, image_height, raster,
|
if (TIFFReadRGBAImageOriented(tif, image_width, image_height, raster,
|
||||||
ORIENTATION_TOPLEFT, 1)) {
|
ORIENTATION_TOPLEFT, 1)) {
|
||||||
const int stride = image_width * sizeof(*raster);
|
|
||||||
pic->width = image_width;
|
pic->width = image_width;
|
||||||
pic->height = image_height;
|
pic->height = image_height;
|
||||||
// TIFF data is ABGR
|
// TIFF data is ABGR
|
||||||
@ -241,8 +251,8 @@ int ReadTIFF(const uint8_t* const data, size_t data_size,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
ok = keep_alpha
|
ok = keep_alpha
|
||||||
? WebPPictureImportRGBA(pic, (const uint8_t*)raster, stride)
|
? WebPPictureImportRGBA(pic, (const uint8_t*)raster, (int)stride)
|
||||||
: WebPPictureImportRGBX(pic, (const uint8_t*)raster, stride);
|
: WebPPictureImportRGBX(pic, (const uint8_t*)raster, (int)stride);
|
||||||
}
|
}
|
||||||
_TIFFfree(raster);
|
_TIFFfree(raster);
|
||||||
} else {
|
} else {
|
||||||
|
@ -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 WebPINewDecoder().\n");
|
fprintf(stderr, "Failed during WebPIDecode().\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,7 +134,10 @@ 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) return hr;
|
if (FAILED(hr) || count == 0) {
|
||||||
|
// 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;
|
||||||
@ -270,10 +273,15 @@ 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;
|
||||||
|
106
infra/common.sh
Normal file
106
infra/common.sh
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
# 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
Executable file
401
infra/compile.sh
Executable file
@ -0,0 +1,401 @@
|
|||||||
|
#!/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
|
224
infra/compile_android.sh
Executable file
224
infra/compile_android.sh
Executable file
@ -0,0 +1,224 @@
|
|||||||
|
#!/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
|
75
infra/compile_js.sh
Executable file
75
infra/compile_js.sh
Executable file
@ -0,0 +1,75 @@
|
|||||||
|
#!/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
|
98
infra/run_static_analysis.sh
Executable file
98
infra/run_static_analysis.sh
Executable file
@ -0,0 +1,98 @@
|
|||||||
|
#!/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
|
@ -9,7 +9,7 @@
|
|||||||
# (the previous build will be erased if it exists).
|
# (the previous build will be erased if it exists).
|
||||||
#
|
#
|
||||||
# This script is inspired by the build script written by Carson McDonald.
|
# This script is inspired by the build script written by Carson McDonald.
|
||||||
# (http://www.ioncannon.net/programming/1483/using-webp-to-reduce-native-ios-app-size/).
|
# (https://www.ioncannon.net/programming/1483/using-webp-to-reduce-native-ios-app-size/).
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
@ -86,7 +86,7 @@ if [[ ! -e ${SRCDIR}/configure ]]; then
|
|||||||
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
|
https://www.macports.org/install.php
|
||||||
EOF
|
EOF
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
@ -47,7 +47,7 @@ else
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
# To install libraries on Mac OS X:
|
# To install libraries on Mac OS X:
|
||||||
# 1. Install MacPorts (http://www.macports.org/install.php)
|
# 1. Install MacPorts (https://www.macports.org/install.php)
|
||||||
# 2. Run "sudo port install jpeg"
|
# 2. Run "sudo port install jpeg"
|
||||||
# 3. Run "sudo port install libpng"
|
# 3. Run "sudo port install libpng"
|
||||||
# 4. Run "sudo port install tiff"
|
# 4. Run "sudo port install tiff"
|
||||||
@ -166,6 +166,7 @@ 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 \
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
.\" Hey, EMACS: -*- nroff -*-
|
.\" Hey, EMACS: -*- nroff -*-
|
||||||
.TH CWEBP 1 "November 19, 2020"
|
.TH CWEBP 1 "November 17, 2021"
|
||||||
.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
|
||||||
@ -222,7 +222,7 @@ Compute and report average PSNR (Peak\-Signal\-To\-Noise ratio).
|
|||||||
.TP
|
.TP
|
||||||
.B \-print_ssim
|
.B \-print_ssim
|
||||||
Compute and report average SSIM (structural similarity
|
Compute and report average SSIM (structural similarity
|
||||||
metric, see http://en.wikipedia.org/wiki/SSIM for additional details).
|
metric, see https://en.wikipedia.org/wiki/SSIM for additional details).
|
||||||
.TP
|
.TP
|
||||||
.B \-print_lsim
|
.B \-print_lsim
|
||||||
Compute and report local similarity metric (sum of lowest error amongst the
|
Compute and report local similarity metric (sum of lowest error amongst the
|
||||||
@ -298,7 +298,7 @@ Please report all bugs to the issue tracker:
|
|||||||
https://bugs.chromium.org/p/webp
|
https://bugs.chromium.org/p/webp
|
||||||
.br
|
.br
|
||||||
Patches welcome! See this page to get started:
|
Patches welcome! See this page to get started:
|
||||||
http://www.webmproject.org/code/contribute/submitting\-patches/
|
https://www.webmproject.org/code/contribute/submitting\-patches/
|
||||||
|
|
||||||
.SH EXAMPLES
|
.SH EXAMPLES
|
||||||
cwebp \-q 50 -lossless picture.png \-o picture_lossless.webp
|
cwebp \-q 50 -lossless picture.png \-o picture_lossless.webp
|
||||||
@ -322,5 +322,5 @@ for the Debian project (and may be used by others).
|
|||||||
.BR dwebp (1),
|
.BR dwebp (1),
|
||||||
.BR gif2webp (1)
|
.BR gif2webp (1)
|
||||||
.br
|
.br
|
||||||
Please refer to http://developers.google.com/speed/webp/ for additional
|
Please refer to https://developers.google.com/speed/webp/ for additional
|
||||||
information.
|
information.
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
.\" Hey, EMACS: -*- nroff -*-
|
.\" Hey, EMACS: -*- nroff -*-
|
||||||
.TH DWEBP 1 "November 19, 2020"
|
.TH DWEBP 1 "November 17, 2021"
|
||||||
.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
|
||||||
@ -113,7 +113,7 @@ Please report all bugs to the issue tracker:
|
|||||||
https://bugs.chromium.org/p/webp
|
https://bugs.chromium.org/p/webp
|
||||||
.br
|
.br
|
||||||
Patches welcome! See this page to get started:
|
Patches welcome! See this page to get started:
|
||||||
http://www.webmproject.org/code/contribute/submitting-patches/
|
https://www.webmproject.org/code/contribute/submitting\-patches/
|
||||||
|
|
||||||
.SH EXAMPLES
|
.SH EXAMPLES
|
||||||
dwebp picture.webp \-o output.png
|
dwebp picture.webp \-o output.png
|
||||||
@ -138,7 +138,7 @@ for the Debian project (and may be used by others).
|
|||||||
.BR gif2webp (1),
|
.BR gif2webp (1),
|
||||||
.BR webpmux (1)
|
.BR webpmux (1)
|
||||||
.br
|
.br
|
||||||
Please refer to http://developers.google.com/speed/webp/ for additional
|
Please refer to https://developers.google.com/speed/webp/ for additional
|
||||||
information.
|
information.
|
||||||
.SS Output file format details
|
.SS Output file format details
|
||||||
PAM: http://netpbm.sourceforge.net/doc/pam.html
|
PAM: http://netpbm.sourceforge.net/doc/pam.html
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
.\" Hey, EMACS: -*- nroff -*-
|
.\" Hey, EMACS: -*- nroff -*-
|
||||||
.TH GIF2WEBP 1 "May 1, 2020"
|
.TH GIF2WEBP 1 "November 17, 2021"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
gif2webp \- Convert a GIF image to WebP
|
gif2webp \- Convert a GIF image to WebP
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
@ -131,7 +131,7 @@ Please report all bugs to the issue tracker:
|
|||||||
https://bugs.chromium.org/p/webp
|
https://bugs.chromium.org/p/webp
|
||||||
.br
|
.br
|
||||||
Patches welcome! See this page to get started:
|
Patches welcome! See this page to get started:
|
||||||
http://www.webmproject.org/code/contribute/submitting-patches/
|
https://www.webmproject.org/code/contribute/submitting\-patches/
|
||||||
|
|
||||||
.SH EXAMPLES
|
.SH EXAMPLES
|
||||||
gif2webp picture.gif \-o picture.webp
|
gif2webp picture.gif \-o picture.webp
|
||||||
@ -160,5 +160,5 @@ Debian project (and may be used by others).
|
|||||||
.BR dwebp (1),
|
.BR dwebp (1),
|
||||||
.BR webpmux (1)
|
.BR webpmux (1)
|
||||||
.br
|
.br
|
||||||
Please refer to http://developers.google.com/speed/webp/ for additional
|
Please refer to https://developers.google.com/speed/webp/ for additional
|
||||||
information.
|
information.
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
.\" Hey, EMACS: -*- nroff -*-
|
.\" Hey, EMACS: -*- nroff -*-
|
||||||
.TH IMG2WEBP 1 "May 1, 2020"
|
.TH IMG2WEBP 1 "November 17, 2021"
|
||||||
.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
|
||||||
@ -86,7 +86,7 @@ Please report all bugs to the issue tracker:
|
|||||||
https://bugs.chromium.org/p/webp
|
https://bugs.chromium.org/p/webp
|
||||||
.br
|
.br
|
||||||
Patches welcome! See this page to get started:
|
Patches welcome! See this page to get started:
|
||||||
http://www.webmproject.org/code/contribute/submitting\-patches/
|
https://www.webmproject.org/code/contribute/submitting\-patches/
|
||||||
|
|
||||||
.SH AUTHORS
|
.SH AUTHORS
|
||||||
\fBimg2webp\fP is a part of libwebp and was written by the WebP team.
|
\fBimg2webp\fP is a part of libwebp and was written by the WebP team.
|
||||||
@ -101,5 +101,5 @@ for the Debian project (and may be used by others).
|
|||||||
.BR webpmux (1),
|
.BR webpmux (1),
|
||||||
.BR gif2webp (1)
|
.BR gif2webp (1)
|
||||||
.br
|
.br
|
||||||
Please refer to http://developers.google.com/speed/webp/ for additional
|
Please refer to https://developers.google.com/speed/webp/ for additional
|
||||||
information.
|
information.
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
.\" Hey, EMACS: -*- nroff -*-
|
.\" Hey, EMACS: -*- nroff -*-
|
||||||
.TH VWEBP 1 "June 5, 2019"
|
.TH VWEBP 1 "November 17, 2021"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
vwebp \- decompress a WebP file and display it in a window
|
vwebp \- decompress a WebP file and display it in a window
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
@ -77,7 +77,7 @@ Please report all bugs to the issue tracker:
|
|||||||
https://bugs.chromium.org/p/webp
|
https://bugs.chromium.org/p/webp
|
||||||
.br
|
.br
|
||||||
Patches welcome! See this page to get started:
|
Patches welcome! See this page to get started:
|
||||||
http://www.webmproject.org/code/contribute/submitting-patches/
|
https://www.webmproject.org/code/contribute/submitting\-patches/
|
||||||
|
|
||||||
.SH EXAMPLES
|
.SH EXAMPLES
|
||||||
vwebp picture.webp
|
vwebp picture.webp
|
||||||
@ -97,5 +97,5 @@ This manual page was written for the Debian project (and may be used by others).
|
|||||||
.SH SEE ALSO
|
.SH SEE ALSO
|
||||||
.BR dwebp (1)
|
.BR dwebp (1)
|
||||||
.br
|
.br
|
||||||
Please refer to http://developers.google.com/speed/webp/ for additional
|
Please refer to https://developers.google.com/speed/webp/ for additional
|
||||||
information.
|
information.
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
.\" Hey, EMACS: -*- nroff -*-
|
.\" Hey, EMACS: -*- nroff -*-
|
||||||
.TH WEBPINFO 1 "November 24, 2017"
|
.TH WEBPINFO 1 "November 17, 2021"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
webpinfo \- print out the chunk level structure of WebP files
|
webpinfo \- print out the chunk level structure of WebP files
|
||||||
along with basic integrity checks.
|
along with basic integrity checks.
|
||||||
@ -52,7 +52,7 @@ Please report all bugs to the issue tracker:
|
|||||||
https://bugs.chromium.org/p/webp
|
https://bugs.chromium.org/p/webp
|
||||||
.br
|
.br
|
||||||
Patches welcome! See this page to get started:
|
Patches welcome! See this page to get started:
|
||||||
http://www.webmproject.org/code/contribute/submitting\-patches/
|
https://www.webmproject.org/code/contribute/submitting\-patches/
|
||||||
|
|
||||||
.SH EXAMPLES
|
.SH EXAMPLES
|
||||||
.br
|
.br
|
||||||
@ -76,5 +76,5 @@ for the Debian project (and may be used by others).
|
|||||||
.SH SEE ALSO
|
.SH SEE ALSO
|
||||||
.BR webpmux (1)
|
.BR webpmux (1)
|
||||||
.br
|
.br
|
||||||
Please refer to http://developers.google.com/speed/webp/ for additional
|
Please refer to https://developers.google.com/speed/webp/ for additional
|
||||||
information.
|
information.
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
.\" Hey, EMACS: -*- nroff -*-
|
.\" Hey, EMACS: -*- nroff -*-
|
||||||
.TH WEBPMUX 1 "December 12, 2020"
|
.TH WEBPMUX 1 "November 17, 2021"
|
||||||
.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.
|
||||||
@ -82,6 +82,12 @@ Set loop count on an animated file.
|
|||||||
.P
|
.P
|
||||||
Where: 'loop_count' must be in range [0, 65535].
|
Where: 'loop_count' must be in range [0, 65535].
|
||||||
.TP
|
.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
|
||||||
@ -185,7 +191,7 @@ Please report all bugs to the issue tracker:
|
|||||||
https://bugs.chromium.org/p/webp
|
https://bugs.chromium.org/p/webp
|
||||||
.br
|
.br
|
||||||
Patches welcome! See this page to get started:
|
Patches welcome! See this page to get started:
|
||||||
http://www.webmproject.org/code/contribute/submitting\-patches/
|
https://www.webmproject.org/code/contribute/submitting\-patches/
|
||||||
|
|
||||||
.SH EXAMPLES
|
.SH EXAMPLES
|
||||||
.P
|
.P
|
||||||
@ -261,5 +267,5 @@ for the Debian project (and may be used by others).
|
|||||||
.BR dwebp (1),
|
.BR dwebp (1),
|
||||||
.BR gif2webp (1)
|
.BR gif2webp (1)
|
||||||
.br
|
.br
|
||||||
Please refer to http://developers.google.com/speed/webp/ for additional
|
Please refer to https://developers.google.com/speed/webp/ for additional
|
||||||
information.
|
information.
|
||||||
|
@ -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:1:1
|
libwebp_la_LDFLAGS = -no-undefined -version-info 8:3:1
|
||||||
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:1:1
|
libwebpdecoder_la_LDFLAGS = -no-undefined -version-info 4:3:1
|
||||||
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; // sanity check.
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
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 << 32)) {
|
if ((uint64_t)w * kModeBpp[mode] >= (1ull << 31)) {
|
||||||
return VP8_STATUS_INVALID_PARAM;
|
return VP8_STATUS_INVALID_PARAM;
|
||||||
}
|
}
|
||||||
stride = w * kModeBpp[mode];
|
stride = w * kModeBpp[mode];
|
||||||
@ -117,7 +117,6 @@ 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;
|
||||||
@ -156,11 +155,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 += (buffer->height - 1) * buf->stride;
|
buf->rgba += (int64_t)(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 int H = buffer->height;
|
const int64_t 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;
|
||||||
@ -188,8 +187,7 @@ VP8StatusCode WebPAllocateDecBuffer(int width, int height,
|
|||||||
const int ch = options->crop_height;
|
const int ch = options->crop_height;
|
||||||
const int x = options->crop_left & ~1;
|
const int x = options->crop_left & ~1;
|
||||||
const int y = options->crop_top & ~1;
|
const int y = options->crop_top & ~1;
|
||||||
if (x < 0 || y < 0 || cw <= 0 || ch <= 0 ||
|
if (!WebPCheckCropDimensions(width, height, x, y, cw, ch)) {
|
||||||
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 (needed != (size_t)needed) return 0; // check for overflow
|
if (!CheckSizeOverflow(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;
|
||||||
|
@ -298,46 +298,57 @@ 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;
|
||||||
const size_t work_size = 2 * out_width; // scratch memory for luma rescaler
|
// 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
|
||||||
size_t tmp_size, rescaler_size;
|
uint64_t total_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;
|
||||||
|
|
||||||
tmp_size = (work_size + 2 * uv_work_size) * sizeof(*work);
|
total_size = ((uint64_t)work_size + 2 * uv_work_size) * sizeof(*work);
|
||||||
if (has_alpha) {
|
if (has_alpha) {
|
||||||
tmp_size += work_size * sizeof(*work);
|
total_size += (uint64_t)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, tmp_size + rescaler_size);
|
p->memory = WebPSafeMalloc(1ULL, (size_t)total_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((const uint8_t*)work + tmp_size);
|
scalers = (WebPRescaler*)WEBP_ALIGN(
|
||||||
|
(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;
|
||||||
|
|
||||||
WebPRescalerInit(p->scaler_y, io->mb_w, io->mb_h,
|
if (!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) {
|
||||||
WebPRescalerInit(p->scaler_a, io->mb_w, io->mb_h,
|
if (!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();
|
||||||
}
|
}
|
||||||
@ -480,51 +491,58 @@ 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;
|
||||||
const size_t work_size = 2 * out_width; // scratch memory for one rescaler
|
// 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
|
||||||
size_t tmp_size1, tmp_size2, total_size, rescaler_size;
|
uint64_t tmp_size1, tmp_size2, total_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 = 3 * work_size;
|
tmp_size1 = (uint64_t)num_rescalers * work_size;
|
||||||
tmp_size2 = 3 * out_width;
|
tmp_size2 = (uint64_t)num_rescalers * 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, total_size + rescaler_size);
|
p->memory = WebPSafeMalloc(1ULL, (size_t)total_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((const uint8_t*)work + total_size);
|
scalers = (WebPRescaler*)WEBP_ALIGN(
|
||||||
|
(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;
|
||||||
|
|
||||||
WebPRescalerInit(p->scaler_y, io->mb_w, io->mb_h,
|
if (!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) {
|
||||||
WebPRescalerInit(p->scaler_a, io->mb_w, io->mb_h,
|
if (!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; // sanity check
|
io->mb_w = io->width; // for soundness
|
||||||
io->mb_h = io->height; // ditto
|
io->mb_h = io->height; // ditto
|
||||||
|
|
||||||
VP8ResetProba(&dec->proba_);
|
VP8ResetProba(&dec->proba_);
|
||||||
@ -403,7 +403,7 @@ static const uint8_t kZigzag[16] = {
|
|||||||
0, 1, 4, 8, 5, 2, 3, 6, 9, 12, 13, 10, 7, 11, 14, 15
|
0, 1, 4, 8, 5, 2, 3, 6, 9, 12, 13, 10, 7, 11, 14, 15
|
||||||
};
|
};
|
||||||
|
|
||||||
// See section 13-2: http://tools.ietf.org/html/rfc6386#section-13.2
|
// See section 13-2: https://datatracker.ietf.org/doc/html/rfc6386#section-13.2
|
||||||
static int GetLargeValue(VP8BitReader* const br, const uint8_t* const p) {
|
static int GetLargeValue(VP8BitReader* const br, const uint8_t* const p) {
|
||||||
int v;
|
int v;
|
||||||
if (!VP8GetBit(br, p[3], "coeffs")) {
|
if (!VP8GetBit(br, p[3], "coeffs")) {
|
||||||
|
@ -32,7 +32,7 @@ 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 2
|
||||||
#define DEC_REV_VERSION 0
|
#define DEC_REV_VERSION 2
|
||||||
|
|
||||||
// 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),
|
||||||
|
@ -84,7 +84,7 @@ static const uint8_t kCodeToPlane[CODE_TO_PLANE_CODES] = {
|
|||||||
// to 256 (green component values) + 24 (length prefix values)
|
// to 256 (green component values) + 24 (length prefix values)
|
||||||
// + color_cache_size (between 0 and 2048).
|
// + color_cache_size (between 0 and 2048).
|
||||||
// All values computed for 8-bit first level lookup with Mark Adler's tool:
|
// All values computed for 8-bit first level lookup with Mark Adler's tool:
|
||||||
// http://www.hdfgroup.org/ftp/lib-external/zlib/zlib-1.2.5/examples/enough.c
|
// https://github.com/madler/zlib/blob/v1.2.5/examples/enough.c
|
||||||
#define FIXED_TABLE_SIZE (630 * 3 + 410)
|
#define FIXED_TABLE_SIZE (630 * 3 + 410)
|
||||||
static const uint16_t kTableSize[12] = {
|
static const uint16_t kTableSize[12] = {
|
||||||
FIXED_TABLE_SIZE + 654,
|
FIXED_TABLE_SIZE + 654,
|
||||||
@ -559,8 +559,11 @@ 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;
|
||||||
|
|
||||||
WebPRescalerInit(dec->rescaler, in_width, in_height, (uint8_t*)scaled_data,
|
if (!WebPRescalerInit(dec->rescaler, in_width, in_height,
|
||||||
out_width, out_height, 0, num_channels, work);
|
(uint8_t*)scaled_data, out_width, out_height,
|
||||||
|
0, num_channels, work)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
#endif // WEBP_REDUCE_SIZE
|
#endif // WEBP_REDUCE_SIZE
|
||||||
@ -574,13 +577,14 @@ 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;
|
||||||
@ -594,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 + num_lines_in * in_stride;
|
uint8_t* const row_in = in + (uint64_t)num_lines_in * in_stride;
|
||||||
uint8_t* const row_out = out + num_lines_out * out_stride;
|
uint8_t* const row_out = out + (uint64_t)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;
|
||||||
@ -796,7 +800,8 @@ 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 = buf->rgba + dec->last_out_row_ * buf->stride;
|
uint8_t* const rgba =
|
||||||
|
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 ?
|
||||||
@ -1514,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 sanity check
|
dec->argb_cache_ = NULL; // for soundness
|
||||||
dec->status_ = VP8_STATUS_OUT_OF_MEMORY;
|
dec->status_ = VP8_STATUS_OUT_OF_MEMORY;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1524,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 sanity check
|
dec->argb_cache_ = NULL; // for soundness
|
||||||
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;
|
||||||
@ -1666,7 +1671,6 @@ 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_ != NULL);
|
||||||
|
@ -785,6 +785,13 @@ 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;
|
||||||
@ -792,7 +799,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 > 0);
|
io->use_cropping = (options != NULL) && options->use_cropping;
|
||||||
if (io->use_cropping) {
|
if (io->use_cropping) {
|
||||||
w = options->crop_width;
|
w = options->crop_width;
|
||||||
h = options->crop_height;
|
h = options->crop_height;
|
||||||
@ -802,7 +809,7 @@ int WebPIoInitFromOptions(const WebPDecoderOptions* const options,
|
|||||||
x &= ~1;
|
x &= ~1;
|
||||||
y &= ~1;
|
y &= ~1;
|
||||||
}
|
}
|
||||||
if (x < 0 || y < 0 || w <= 0 || h <= 0 || x + w > W || y + h > H) {
|
if (!WebPCheckCropDimensions(W, H, x, y, w, h)) {
|
||||||
return 0; // out of frame boundary error
|
return 0; // out of frame boundary error
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -814,7 +821,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 > 0);
|
io->use_scaling = (options != NULL) && options->use_scaling;
|
||||||
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;
|
||||||
@ -835,8 +842,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,6 +77,10 @@ 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:7:0
|
libwebpdemux_la_LDFLAGS = -no-undefined -version-info 2:9:0
|
||||||
libwebpdemuxincludedir = $(includedir)/webp
|
libwebpdemuxincludedir = $(includedir)/webp
|
||||||
pkgconfig_DATA = libwebpdemux.pc
|
pkgconfig_DATA = libwebpdemux.pc
|
||||||
|
@ -87,11 +87,19 @@ 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;
|
||||||
@ -145,7 +153,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 (size != (size_t)size) return 0;
|
if (!CheckSizeOverflow(size)) return 0;
|
||||||
memset(buf, 0, (size_t)size);
|
memset(buf, 0, (size_t)size);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -166,7 +174,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 (size != (size_t)size) return 0;
|
if (!CheckSizeOverflow(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;
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
|
|
||||||
#define DMUX_MAJ_VERSION 1
|
#define DMUX_MAJ_VERSION 1
|
||||||
#define DMUX_MIN_VERSION 2
|
#define DMUX_MIN_VERSION 2
|
||||||
#define DMUX_REV_VERSION 0
|
#define DMUX_REV_VERSION 2
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
size_t start_; // start location of the data
|
size_t start_; // start location of the data
|
||||||
@ -221,12 +221,16 @@ 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);
|
||||||
const uint32_t payload_size_padded = payload_size + (payload_size & 1);
|
uint32_t payload_size_padded;
|
||||||
const size_t payload_available = (payload_size_padded > MemDataSize(mem))
|
size_t payload_available;
|
||||||
? MemDataSize(mem) : payload_size_padded;
|
size_t chunk_size;
|
||||||
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;
|
||||||
|
|
||||||
@ -451,9 +455,11 @@ 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);
|
||||||
const uint32_t chunk_size_padded = chunk_size + (chunk_size & 1);
|
uint32_t chunk_size_padded;
|
||||||
|
|
||||||
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,0
|
FILEVERSION 1,0,2,2
|
||||||
PRODUCTVERSION 1,0,2,0
|
PRODUCTVERSION 1,0,2,2
|
||||||
FILEFLAGSMASK 0x3fL
|
FILEFLAGSMASK 0x3fL
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
FILEFLAGS 0x1L
|
FILEFLAGS 0x1L
|
||||||
@ -24,12 +24,12 @@ BEGIN
|
|||||||
BEGIN
|
BEGIN
|
||||||
VALUE "CompanyName", "Google, Inc."
|
VALUE "CompanyName", "Google, Inc."
|
||||||
VALUE "FileDescription", "libwebpdemux DLL"
|
VALUE "FileDescription", "libwebpdemux DLL"
|
||||||
VALUE "FileVersion", "1.2.0"
|
VALUE "FileVersion", "1.2.2"
|
||||||
VALUE "InternalName", "libwebpdemux.dll"
|
VALUE "InternalName", "libwebpdemux.dll"
|
||||||
VALUE "LegalCopyright", "Copyright (C) 2019"
|
VALUE "LegalCopyright", "Copyright (C) 2021"
|
||||||
VALUE "OriginalFilename", "libwebpdemux.dll"
|
VALUE "OriginalFilename", "libwebpdemux.dll"
|
||||||
VALUE "ProductName", "WebP Image Demuxer"
|
VALUE "ProductName", "WebP Image Demuxer"
|
||||||
VALUE "ProductVersion", "1.2.0"
|
VALUE "ProductVersion", "1.2.2"
|
||||||
END
|
END
|
||||||
END
|
END
|
||||||
BLOCK "VarFileInfo"
|
BLOCK "VarFileInfo"
|
||||||
|
@ -46,6 +46,7 @@ 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)
|
||||||
|
@ -157,7 +157,8 @@ void WebPMultARGBRow_C(uint32_t* const ptr, int width, int inverse) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebPMultRow_C(uint8_t* const ptr, const uint8_t* const alpha,
|
void WebPMultRow_C(uint8_t* WEBP_RESTRICT const ptr,
|
||||||
|
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) {
|
||||||
@ -178,7 +179,8 @@ void WebPMultRow_C(uint8_t* const ptr, const uint8_t* const alpha,
|
|||||||
#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* const ptr, const uint8_t* const alpha,
|
void (*WebPMultRow)(uint8_t* WEBP_RESTRICT const ptr,
|
||||||
|
const uint8_t* WEBP_RESTRICT const alpha,
|
||||||
int width, int inverse);
|
int width, int inverse);
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
@ -193,8 +195,8 @@ void WebPMultARGBRows(uint8_t* ptr, int stride, int width, int num_rows,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebPMultRows(uint8_t* ptr, int stride,
|
void WebPMultRows(uint8_t* WEBP_RESTRICT ptr, int stride,
|
||||||
const uint8_t* alpha, int alpha_stride,
|
const uint8_t* WEBP_RESTRICT 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) {
|
||||||
@ -290,9 +292,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* alpha, int alpha_stride,
|
static int DispatchAlpha_C(const uint8_t* WEBP_RESTRICT alpha, int alpha_stride,
|
||||||
int width, int height,
|
int width, int height,
|
||||||
uint8_t* dst, int dst_stride) {
|
uint8_t* WEBP_RESTRICT dst, int dst_stride) {
|
||||||
uint32_t alpha_mask = 0xff;
|
uint32_t alpha_mask = 0xff;
|
||||||
int i, j;
|
int i, j;
|
||||||
|
|
||||||
@ -309,9 +311,10 @@ static int DispatchAlpha_C(const uint8_t* alpha, int alpha_stride,
|
|||||||
return (alpha_mask != 0xff);
|
return (alpha_mask != 0xff);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void DispatchAlphaToGreen_C(const uint8_t* alpha, int alpha_stride,
|
static void DispatchAlphaToGreen_C(const uint8_t* WEBP_RESTRICT alpha,
|
||||||
int width, int height,
|
int alpha_stride, int width, int height,
|
||||||
uint32_t* dst, int dst_stride) {
|
uint32_t* WEBP_RESTRICT dst,
|
||||||
|
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) {
|
||||||
@ -322,9 +325,9 @@ static void DispatchAlphaToGreen_C(const uint8_t* alpha, int alpha_stride,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ExtractAlpha_C(const uint8_t* argb, int argb_stride,
|
static int ExtractAlpha_C(const uint8_t* WEBP_RESTRICT argb, int argb_stride,
|
||||||
int width, int height,
|
int width, int height,
|
||||||
uint8_t* alpha, int alpha_stride) {
|
uint8_t* WEBP_RESTRICT alpha, int alpha_stride) {
|
||||||
uint8_t alpha_mask = 0xff;
|
uint8_t alpha_mask = 0xff;
|
||||||
int i, j;
|
int i, j;
|
||||||
|
|
||||||
@ -340,7 +343,8 @@ static int ExtractAlpha_C(const uint8_t* argb, int argb_stride,
|
|||||||
return (alpha_mask == 0xff);
|
return (alpha_mask == 0xff);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ExtractGreen_C(const uint32_t* argb, uint8_t* alpha, int size) {
|
static void ExtractGreen_C(const uint32_t* WEBP_RESTRICT argb,
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
@ -372,8 +376,11 @@ 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* a, const uint8_t* r, const uint8_t* g,
|
static void PackARGB_C(const uint8_t* WEBP_RESTRICT a,
|
||||||
const uint8_t* b, int len, uint32_t* out) {
|
const uint8_t* WEBP_RESTRICT r,
|
||||||
|
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]);
|
||||||
@ -381,8 +388,10 @@ static void PackARGB_C(const uint8_t* a, const uint8_t* r, const uint8_t* g,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void PackRGB_C(const uint8_t* r, const uint8_t* g, const uint8_t* b,
|
static void PackRGB_C(const uint8_t* WEBP_RESTRICT r,
|
||||||
int len, int step, uint32_t* out) {
|
const uint8_t* WEBP_RESTRICT g,
|
||||||
|
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]);
|
||||||
@ -392,16 +401,22 @@ static void PackRGB_C(const uint8_t* r, const uint8_t* g, const uint8_t* b,
|
|||||||
|
|
||||||
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*, int, int, int, uint8_t*, int);
|
int (*WebPDispatchAlpha)(const uint8_t* WEBP_RESTRICT, int, int, int,
|
||||||
void (*WebPDispatchAlphaToGreen)(const uint8_t*, int, int, int, uint32_t*, int);
|
uint8_t* WEBP_RESTRICT, int);
|
||||||
int (*WebPExtractAlpha)(const uint8_t*, int, int, int, uint8_t*, int);
|
void (*WebPDispatchAlphaToGreen)(const uint8_t* WEBP_RESTRICT, int, int, int,
|
||||||
void (*WebPExtractGreen)(const uint32_t* argb, uint8_t* alpha, int size);
|
uint32_t* WEBP_RESTRICT, int);
|
||||||
|
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* r, const uint8_t* g, const uint8_t* b,
|
void (*WebPPackRGB)(const uint8_t* WEBP_RESTRICT r,
|
||||||
int len, int step, uint32_t* out);
|
const uint8_t* WEBP_RESTRICT g,
|
||||||
|
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);
|
||||||
@ -438,10 +453,10 @@ WEBP_DSP_INIT_FUNC(WebPInitAlphaProcessing) {
|
|||||||
|
|
||||||
// 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_USE_SSE2)
|
#if defined(WEBP_HAVE_SSE2)
|
||||||
if (VP8GetCPUInfo(kSSE2)) {
|
if (VP8GetCPUInfo(kSSE2)) {
|
||||||
WebPInitAlphaProcessingSSE2();
|
WebPInitAlphaProcessingSSE2();
|
||||||
#if defined(WEBP_USE_SSE41)
|
#if defined(WEBP_HAVE_SSE41)
|
||||||
if (VP8GetCPUInfo(kSSE4_1)) {
|
if (VP8GetCPUInfo(kSSE4_1)) {
|
||||||
WebPInitAlphaProcessingSSE41();
|
WebPInitAlphaProcessingSSE41();
|
||||||
}
|
}
|
||||||
@ -455,7 +470,7 @@ WEBP_DSP_INIT_FUNC(WebPInitAlphaProcessing) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(WEBP_USE_NEON)
|
#if defined(WEBP_HAVE_NEON)
|
||||||
if (WEBP_NEON_OMIT_C_CODE ||
|
if (WEBP_NEON_OMIT_C_CODE ||
|
||||||
(VP8GetCPUInfo != NULL && VP8GetCPUInfo(kNEON))) {
|
(VP8GetCPUInfo != NULL && VP8GetCPUInfo(kNEON))) {
|
||||||
WebPInitAlphaProcessingNEON();
|
WebPInitAlphaProcessingNEON();
|
||||||
|
@ -80,9 +80,9 @@ static void ApplyAlphaMultiply_NEON(uint8_t* rgba, int alpha_first,
|
|||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
static int DispatchAlpha_NEON(const uint8_t* alpha, int alpha_stride,
|
static int DispatchAlpha_NEON(const uint8_t* WEBP_RESTRICT alpha,
|
||||||
int width, int height,
|
int alpha_stride, int width, int height,
|
||||||
uint8_t* dst, int dst_stride) {
|
uint8_t* WEBP_RESTRICT dst, int dst_stride) {
|
||||||
uint32_t alpha_mask = 0xffffffffu;
|
uint32_t alpha_mask = 0xffffffffu;
|
||||||
uint8x8_t mask8 = vdup_n_u8(0xff);
|
uint8x8_t mask8 = vdup_n_u8(0xff);
|
||||||
uint32_t tmp[2];
|
uint32_t tmp[2];
|
||||||
@ -112,9 +112,10 @@ static int DispatchAlpha_NEON(const uint8_t* alpha, int alpha_stride,
|
|||||||
return (alpha_mask != 0xffffffffu);
|
return (alpha_mask != 0xffffffffu);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void DispatchAlphaToGreen_NEON(const uint8_t* alpha, int alpha_stride,
|
static void DispatchAlphaToGreen_NEON(const uint8_t* WEBP_RESTRICT alpha,
|
||||||
int width, int height,
|
int alpha_stride, int width, int height,
|
||||||
uint32_t* dst, int dst_stride) {
|
uint32_t* WEBP_RESTRICT dst,
|
||||||
|
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);
|
||||||
@ -131,9 +132,9 @@ static void DispatchAlphaToGreen_NEON(const uint8_t* alpha, int alpha_stride,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ExtractAlpha_NEON(const uint8_t* argb, int argb_stride,
|
static int ExtractAlpha_NEON(const uint8_t* WEBP_RESTRICT argb, int argb_stride,
|
||||||
int width, int height,
|
int width, int height,
|
||||||
uint8_t* alpha, int alpha_stride) {
|
uint8_t* WEBP_RESTRICT alpha, int alpha_stride) {
|
||||||
uint32_t alpha_mask = 0xffffffffu;
|
uint32_t alpha_mask = 0xffffffffu;
|
||||||
uint8x8_t mask8 = vdup_n_u8(0xff);
|
uint8x8_t mask8 = vdup_n_u8(0xff);
|
||||||
uint32_t tmp[2];
|
uint32_t tmp[2];
|
||||||
@ -161,8 +162,8 @@ static int ExtractAlpha_NEON(const uint8_t* argb, int argb_stride,
|
|||||||
return (alpha_mask == 0xffffffffu);
|
return (alpha_mask == 0xffffffffu);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ExtractGreen_NEON(const uint32_t* argb,
|
static void ExtractGreen_NEON(const uint32_t* WEBP_RESTRICT argb,
|
||||||
uint8_t* alpha, int size) {
|
uint8_t* WEBP_RESTRICT 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* alpha, int alpha_stride,
|
static int DispatchAlpha_SSE2(const uint8_t* WEBP_RESTRICT alpha,
|
||||||
int width, int height,
|
int alpha_stride, int width, int height,
|
||||||
uint8_t* dst, int dst_stride) {
|
uint8_t* WEBP_RESTRICT 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,9 +72,10 @@ static int DispatchAlpha_SSE2(const uint8_t* alpha, int alpha_stride,
|
|||||||
return (alpha_and != 0xff);
|
return (alpha_and != 0xff);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void DispatchAlphaToGreen_SSE2(const uint8_t* alpha, int alpha_stride,
|
static void DispatchAlphaToGreen_SSE2(const uint8_t* WEBP_RESTRICT alpha,
|
||||||
int width, int height,
|
int alpha_stride, int width, int height,
|
||||||
uint32_t* dst, int dst_stride) {
|
uint32_t* WEBP_RESTRICT dst,
|
||||||
|
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;
|
||||||
@ -98,9 +99,9 @@ static void DispatchAlphaToGreen_SSE2(const uint8_t* alpha, int alpha_stride,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ExtractAlpha_SSE2(const uint8_t* argb, int argb_stride,
|
static int ExtractAlpha_SSE2(const uint8_t* WEBP_RESTRICT argb, int argb_stride,
|
||||||
int width, int height,
|
int width, int height,
|
||||||
uint8_t* alpha, int alpha_stride) {
|
uint8_t* WEBP_RESTRICT 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;
|
||||||
@ -317,7 +318,8 @@ 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* const ptr, const uint8_t* const alpha,
|
static void MultRow_SSE2(uint8_t* WEBP_RESTRICT const ptr,
|
||||||
|
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) {
|
||||||
|
@ -19,9 +19,9 @@
|
|||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
static int ExtractAlpha_SSE41(const uint8_t* argb, int argb_stride,
|
static int ExtractAlpha_SSE41(const uint8_t* WEBP_RESTRICT argb,
|
||||||
int width, int height,
|
int argb_stride, int width, int height,
|
||||||
uint8_t* alpha, int alpha_stride) {
|
uint8_t* WEBP_RESTRICT 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_USE_SSE2)
|
#if defined(WEBP_HAVE_SSE2)
|
||||||
if (VP8GetCPUInfo(kSSE2)) {
|
if (VP8GetCPUInfo(kSSE2)) {
|
||||||
VP8EncDspCostInitSSE2();
|
VP8EncDspCostInitSSE2();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#if defined(WEBP_USE_NEON)
|
#if defined(WEBP_HAVE_NEON)
|
||||||
if (VP8GetCPUInfo(kNEON)) {
|
if (VP8GetCPUInfo(kNEON)) {
|
||||||
VP8EncDspCostInitNEON();
|
VP8EncDspCostInitNEON();
|
||||||
}
|
}
|
||||||
|
@ -189,17 +189,17 @@ VP8CPUInfo VP8GetCPUInfo = AndroidCPUInfo;
|
|||||||
// Use compile flags as an indicator of SIMD support instead of a runtime check.
|
// Use compile flags as an indicator of SIMD support instead of a runtime check.
|
||||||
static int wasmCPUInfo(CPUFeature feature) {
|
static int wasmCPUInfo(CPUFeature feature) {
|
||||||
switch (feature) {
|
switch (feature) {
|
||||||
#ifdef WEBP_USE_SSE2
|
#ifdef WEBP_HAVE_SSE2
|
||||||
case kSSE2:
|
case kSSE2:
|
||||||
return 1;
|
return 1;
|
||||||
#endif
|
#endif
|
||||||
#ifdef WEBP_USE_SSE41
|
#ifdef WEBP_HAVE_SSE41
|
||||||
case kSSE3:
|
case kSSE3:
|
||||||
case kSlowSSSE3:
|
case kSlowSSSE3:
|
||||||
case kSSE4_1:
|
case kSSE4_1:
|
||||||
return 1;
|
return 1;
|
||||||
#endif
|
#endif
|
||||||
#ifdef WEBP_USE_NEON
|
#ifdef WEBP_HAVE_NEON
|
||||||
case kNEON:
|
case kNEON:
|
||||||
return 1;
|
return 1;
|
||||||
#endif
|
#endif
|
||||||
@ -209,9 +209,10 @@ static int wasmCPUInfo(CPUFeature feature) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
VP8CPUInfo VP8GetCPUInfo = wasmCPUInfo;
|
VP8CPUInfo VP8GetCPUInfo = wasmCPUInfo;
|
||||||
#elif defined(WEBP_USE_NEON)
|
#elif defined(WEBP_HAVE_NEON)
|
||||||
// define a dummy function to enable turning off NEON at runtime by setting
|
// In most cases this function doesn't check for NEON support (it's assumed by
|
||||||
// VP8DecGetCPUInfo = NULL
|
// 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)
|
||||||
|
@ -807,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_USE_SSE2)
|
#if defined(WEBP_HAVE_SSE2)
|
||||||
if (VP8GetCPUInfo(kSSE2)) {
|
if (VP8GetCPUInfo(kSSE2)) {
|
||||||
VP8DspInitSSE2();
|
VP8DspInitSSE2();
|
||||||
#if defined(WEBP_USE_SSE41)
|
#if defined(WEBP_HAVE_SSE41)
|
||||||
if (VP8GetCPUInfo(kSSE4_1)) {
|
if (VP8GetCPUInfo(kSSE4_1)) {
|
||||||
VP8DspInitSSE41();
|
VP8DspInitSSE41();
|
||||||
}
|
}
|
||||||
@ -834,7 +834,7 @@ WEBP_DSP_INIT_FUNC(VP8DspInit) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(WEBP_USE_NEON)
|
#if defined(WEBP_HAVE_NEON)
|
||||||
if (WEBP_NEON_OMIT_C_CODE ||
|
if (WEBP_NEON_OMIT_C_CODE ||
|
||||||
(VP8GetCPUInfo != NULL && VP8GetCPUInfo(kNEON))) {
|
(VP8GetCPUInfo != NULL && VP8GetCPUInfo(kNEON))) {
|
||||||
VP8DspInitNEON();
|
VP8DspInitNEON();
|
||||||
|
@ -26,6 +26,23 @@ 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
|
||||||
|
|
||||||
@ -67,21 +84,31 @@ extern "C" {
|
|||||||
// 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) || defined(WEBP_HAVE_SSE2)
|
#if (defined(__SSE2__) || defined(WEBP_MSC_SSE2)) && \
|
||||||
|
(!defined(HAVE_CONFIG_H) || defined(WEBP_HAVE_SSE2))
|
||||||
#define WEBP_USE_SSE2
|
#define WEBP_USE_SSE2
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(__SSE4_1__) || defined(WEBP_MSC_SSE41) || defined(WEBP_HAVE_SSE41)
|
#if defined(WEBP_USE_SSE2) && !defined(WEBP_HAVE_SSE2)
|
||||||
|
#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_SSE41
|
||||||
#undef WEBP_MSC_SSE2
|
#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__) || \
|
#if ((defined(__ARM_NEON__) || defined(__aarch64__)) && \
|
||||||
defined(__aarch64__) || defined(WEBP_HAVE_NEON)) && \
|
(!defined(HAVE_CONFIG_H) || defined(WEBP_HAVE_NEON))) && \
|
||||||
!defined(__native_client__)
|
!defined(__native_client__)
|
||||||
#define WEBP_USE_NEON
|
#define WEBP_USE_NEON
|
||||||
#endif
|
#endif
|
||||||
@ -92,11 +119,20 @@ extern "C" {
|
|||||||
#define WEBP_USE_NEON
|
#define WEBP_USE_NEON
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(_MSC_VER) && _MSC_VER >= 1700 && defined(_M_ARM)
|
// Note: ARM64 is supported in Visual Studio 2017, but requires the direct
|
||||||
|
// 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
|
||||||
@ -116,7 +152,7 @@ extern "C" {
|
|||||||
#define WEBP_DSP_OMIT_C_CODE 1
|
#define WEBP_DSP_OMIT_C_CODE 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (defined(__aarch64__) || defined(__ARM_NEON__)) && WEBP_DSP_OMIT_C_CODE
|
#if defined(WEBP_USE_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
|
||||||
@ -578,26 +614,29 @@ 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* alpha, int alpha_stride,
|
extern int (*WebPDispatchAlpha)(const uint8_t* WEBP_RESTRICT alpha,
|
||||||
int width, int height,
|
int alpha_stride, int width, int height,
|
||||||
uint8_t* dst, int dst_stride);
|
uint8_t* WEBP_RESTRICT 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* alpha, int alpha_stride,
|
extern void (*WebPDispatchAlphaToGreen)(const uint8_t* WEBP_RESTRICT alpha,
|
||||||
int width, int height,
|
int alpha_stride, int width, int height,
|
||||||
uint32_t* dst, int dst_stride);
|
uint32_t* WEBP_RESTRICT dst,
|
||||||
|
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* argb, int argb_stride,
|
extern int (*WebPExtractAlpha)(const uint8_t* WEBP_RESTRICT argb,
|
||||||
int width, int height,
|
int argb_stride, int width, int height,
|
||||||
uint8_t* alpha, int alpha_stride);
|
uint8_t* WEBP_RESTRICT alpha,
|
||||||
|
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* argb, uint8_t* alpha, int size);
|
extern void (*WebPExtractGreen)(const uint32_t* WEBP_RESTRICT argb,
|
||||||
|
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.
|
||||||
@ -610,29 +649,35 @@ 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* const ptr, const uint8_t* const alpha,
|
extern void (*WebPMultRow)(uint8_t* WEBP_RESTRICT const ptr,
|
||||||
|
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* ptr, int stride,
|
void WebPMultRows(uint8_t* WEBP_RESTRICT ptr, int stride,
|
||||||
const uint8_t* alpha, int alpha_stride,
|
const uint8_t* WEBP_RESTRICT 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* const ptr, const uint8_t* const alpha,
|
void WebPMultRow_C(uint8_t* WEBP_RESTRICT const ptr,
|
||||||
|
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* a, const uint8_t* r,
|
extern void (*WebPPackARGB)(const uint8_t* WEBP_RESTRICT a,
|
||||||
const uint8_t* g, const uint8_t* b, int len,
|
const uint8_t* WEBP_RESTRICT r,
|
||||||
uint32_t* out);
|
const uint8_t* WEBP_RESTRICT g,
|
||||||
|
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* r, const uint8_t* g, const uint8_t* b,
|
extern void (*WebPPackRGB)(const uint8_t* WEBP_RESTRICT r,
|
||||||
int len, int step, uint32_t* out);
|
const uint8_t* WEBP_RESTRICT g,
|
||||||
|
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);
|
||||||
|
@ -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_USE_SSE2)
|
#if defined(WEBP_HAVE_SSE2)
|
||||||
if (VP8GetCPUInfo(kSSE2)) {
|
if (VP8GetCPUInfo(kSSE2)) {
|
||||||
VP8EncDspInitSSE2();
|
VP8EncDspInitSSE2();
|
||||||
#if defined(WEBP_USE_SSE41)
|
#if defined(WEBP_HAVE_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_USE_NEON)
|
#if defined(WEBP_HAVE_NEON)
|
||||||
if (WEBP_NEON_OMIT_C_CODE ||
|
if (WEBP_NEON_OMIT_C_CODE ||
|
||||||
(VP8GetCPUInfo != NULL && VP8GetCPUInfo(kNEON))) {
|
(VP8GetCPUInfo != NULL && VP8GetCPUInfo(kNEON))) {
|
||||||
VP8EncDspInitNEON();
|
VP8EncDspInitNEON();
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
//
|
//
|
||||||
// ARM NEON version of speed-critical encoding functions.
|
// ARM NEON version of speed-critical encoding functions.
|
||||||
//
|
//
|
||||||
// adapted from libvpx (http://www.webmproject.org/code/)
|
// adapted from libvpx (https://www.webmproject.org/code/)
|
||||||
|
|
||||||
#include "src/dsp/dsp.h"
|
#include "src/dsp/dsp.h"
|
||||||
|
|
||||||
|
@ -254,7 +254,7 @@ WEBP_DSP_INIT_FUNC(VP8FiltersInit) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (VP8GetCPUInfo != NULL) {
|
if (VP8GetCPUInfo != NULL) {
|
||||||
#if defined(WEBP_USE_SSE2)
|
#if defined(WEBP_HAVE_SSE2)
|
||||||
if (VP8GetCPUInfo(kSSE2)) {
|
if (VP8GetCPUInfo(kSSE2)) {
|
||||||
VP8FiltersInitSSE2();
|
VP8FiltersInitSSE2();
|
||||||
}
|
}
|
||||||
@ -271,7 +271,7 @@ WEBP_DSP_INIT_FUNC(VP8FiltersInit) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(WEBP_USE_NEON)
|
#if defined(WEBP_HAVE_NEON)
|
||||||
if (WEBP_NEON_OMIT_C_CODE ||
|
if (WEBP_NEON_OMIT_C_CODE ||
|
||||||
(VP8GetCPUInfo != NULL && VP8GetCPUInfo(kNEON))) {
|
(VP8GetCPUInfo != NULL && VP8GetCPUInfo(kNEON))) {
|
||||||
VP8FiltersInitNEON();
|
VP8FiltersInitNEON();
|
||||||
|
@ -320,7 +320,12 @@ 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;
|
||||||
|
@ -107,63 +107,77 @@ 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) {
|
uint32_t VP8LPredictor0_C(const uint32_t* const 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) {
|
uint32_t VP8LPredictor1_C(const uint32_t* const 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) {
|
uint32_t VP8LPredictor2_C(const uint32_t* const 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) {
|
uint32_t VP8LPredictor3_C(const uint32_t* const 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) {
|
uint32_t VP8LPredictor4_C(const uint32_t* const 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) {
|
uint32_t VP8LPredictor5_C(const uint32_t* const left,
|
||||||
const uint32_t pred = Average3(left, top[0], top[1]);
|
const uint32_t* const top) {
|
||||||
|
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) {
|
uint32_t VP8LPredictor6_C(const uint32_t* const left,
|
||||||
const uint32_t pred = Average2(left, top[-1]);
|
const uint32_t* const top) {
|
||||||
|
const uint32_t pred = Average2(*left, top[-1]);
|
||||||
return pred;
|
return pred;
|
||||||
}
|
}
|
||||||
uint32_t VP8LPredictor7_C(uint32_t left, const uint32_t* const top) {
|
uint32_t VP8LPredictor7_C(const uint32_t* const left,
|
||||||
const uint32_t pred = Average2(left, top[0]);
|
const uint32_t* const top) {
|
||||||
|
const uint32_t pred = Average2(*left, top[0]);
|
||||||
return pred;
|
return pred;
|
||||||
}
|
}
|
||||||
uint32_t VP8LPredictor8_C(uint32_t left, const uint32_t* const top) {
|
uint32_t VP8LPredictor8_C(const uint32_t* const 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) {
|
uint32_t VP8LPredictor9_C(const uint32_t* const 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) {
|
uint32_t VP8LPredictor10_C(const uint32_t* const left,
|
||||||
const uint32_t pred = Average4(left, top[-1], top[0], top[1]);
|
const uint32_t* const top) {
|
||||||
|
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) {
|
uint32_t VP8LPredictor11_C(const uint32_t* const left,
|
||||||
const uint32_t pred = Select(top[0], left, top[-1]);
|
const uint32_t* const top) {
|
||||||
|
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) {
|
uint32_t VP8LPredictor12_C(const uint32_t* const left,
|
||||||
const uint32_t pred = ClampedAddSubtractFull(left, top[0], top[-1]);
|
const uint32_t* const top) {
|
||||||
|
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) {
|
uint32_t VP8LPredictor13_C(const uint32_t* const left,
|
||||||
const uint32_t pred = ClampedAddSubtractHalf(left, top[0], top[-1]);
|
const uint32_t* const top) {
|
||||||
|
const uint32_t pred = ClampedAddSubtractHalf(*left, top[0], top[-1]);
|
||||||
return pred;
|
return pred;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -575,6 +589,7 @@ 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);
|
||||||
@ -621,9 +636,14 @@ 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_USE_SSE2)
|
#if defined(WEBP_HAVE_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)
|
||||||
@ -638,7 +658,7 @@ WEBP_DSP_INIT_FUNC(VP8LDspInit) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(WEBP_USE_NEON)
|
#if defined(WEBP_HAVE_NEON)
|
||||||
if (WEBP_NEON_OMIT_C_CODE ||
|
if (WEBP_NEON_OMIT_C_CODE ||
|
||||||
(VP8GetCPUInfo != NULL && VP8GetCPUInfo(kNEON))) {
|
(VP8GetCPUInfo != NULL && VP8GetCPUInfo(kNEON))) {
|
||||||
VP8LDspInitNEON();
|
VP8LDspInitNEON();
|
||||||
|
@ -28,23 +28,38 @@ extern "C" {
|
|||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Decoding
|
// Decoding
|
||||||
|
|
||||||
typedef uint32_t (*VP8LPredictorFunc)(uint32_t left, const uint32_t* const top);
|
typedef uint32_t (*VP8LPredictorFunc)(const uint32_t* const left,
|
||||||
|
const uint32_t* const top);
|
||||||
extern VP8LPredictorFunc VP8LPredictors[16];
|
extern VP8LPredictorFunc VP8LPredictors[16];
|
||||||
|
|
||||||
uint32_t VP8LPredictor0_C(uint32_t left, const uint32_t* const top);
|
uint32_t VP8LPredictor0_C(const uint32_t* const left,
|
||||||
uint32_t VP8LPredictor1_C(uint32_t left, const uint32_t* const top);
|
const uint32_t* const top);
|
||||||
uint32_t VP8LPredictor2_C(uint32_t left, const uint32_t* const top);
|
uint32_t VP8LPredictor1_C(const uint32_t* const left,
|
||||||
uint32_t VP8LPredictor3_C(uint32_t left, const uint32_t* const top);
|
const uint32_t* const top);
|
||||||
uint32_t VP8LPredictor4_C(uint32_t left, const uint32_t* const top);
|
uint32_t VP8LPredictor2_C(const uint32_t* const left,
|
||||||
uint32_t VP8LPredictor5_C(uint32_t left, const uint32_t* const top);
|
const uint32_t* const top);
|
||||||
uint32_t VP8LPredictor6_C(uint32_t left, const uint32_t* const top);
|
uint32_t VP8LPredictor3_C(const uint32_t* const left,
|
||||||
uint32_t VP8LPredictor7_C(uint32_t left, const uint32_t* const top);
|
const uint32_t* const top);
|
||||||
uint32_t VP8LPredictor8_C(uint32_t left, const uint32_t* const top);
|
uint32_t VP8LPredictor4_C(const uint32_t* const left,
|
||||||
uint32_t VP8LPredictor9_C(uint32_t left, const uint32_t* const top);
|
const uint32_t* const top);
|
||||||
uint32_t VP8LPredictor10_C(uint32_t left, const uint32_t* const top);
|
uint32_t VP8LPredictor5_C(const uint32_t* const left,
|
||||||
uint32_t VP8LPredictor11_C(uint32_t left, const uint32_t* const top);
|
const uint32_t* const top);
|
||||||
uint32_t VP8LPredictor12_C(uint32_t left, const uint32_t* const top);
|
uint32_t VP8LPredictor6_C(const uint32_t* const left,
|
||||||
uint32_t VP8LPredictor13_C(uint32_t left, const uint32_t* const top);
|
const uint32_t* const top);
|
||||||
|
uint32_t VP8LPredictor7_C(const uint32_t* const left,
|
||||||
|
const uint32_t* const top);
|
||||||
|
uint32_t VP8LPredictor8_C(const uint32_t* const left,
|
||||||
|
const uint32_t* const top);
|
||||||
|
uint32_t VP8LPredictor9_C(const uint32_t* const left,
|
||||||
|
const uint32_t* const top);
|
||||||
|
uint32_t VP8LPredictor10_C(const uint32_t* const left,
|
||||||
|
const uint32_t* const top);
|
||||||
|
uint32_t VP8LPredictor11_C(const uint32_t* const left,
|
||||||
|
const uint32_t* const top);
|
||||||
|
uint32_t VP8LPredictor12_C(const uint32_t* const left,
|
||||||
|
const uint32_t* const top);
|
||||||
|
uint32_t VP8LPredictor13_C(const uint32_t* const 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,
|
||||||
|
@ -179,7 +179,7 @@ static void PREDICTOR_ADD(const uint32_t* in, const uint32_t* upper, \
|
|||||||
int x; \
|
int x; \
|
||||||
assert(upper != NULL); \
|
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); \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
@ -329,6 +329,15 @@ 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;
|
||||||
@ -339,6 +348,7 @@ 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)
|
||||||
@ -355,6 +365,14 @@ 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;
|
||||||
@ -364,6 +382,7 @@ 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
|
||||||
@ -726,7 +745,7 @@ static void PredictorSub##PREDICTOR_I##_C(const uint32_t* in, \
|
|||||||
assert(upper != NULL); \
|
assert(upper != NULL); \
|
||||||
for (x = 0; x < num_pixels; ++x) { \
|
for (x = 0; x < num_pixels; ++x) { \
|
||||||
const uint32_t pred = \
|
const uint32_t pred = \
|
||||||
VP8LPredictor##PREDICTOR_I##_C(in[x - 1], upper + x); \
|
VP8LPredictor##PREDICTOR_I##_C(&in[x - 1], upper + x); \
|
||||||
out[x] = VP8LSubPixels(in[x], pred); \
|
out[x] = VP8LSubPixels(in[x], pred); \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
@ -843,10 +862,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_USE_SSE2)
|
#if defined(WEBP_HAVE_SSE2)
|
||||||
if (VP8GetCPUInfo(kSSE2)) {
|
if (VP8GetCPUInfo(kSSE2)) {
|
||||||
VP8LEncDspInitSSE2();
|
VP8LEncDspInitSSE2();
|
||||||
#if defined(WEBP_USE_SSE41)
|
#if defined(WEBP_HAVE_SSE41)
|
||||||
if (VP8GetCPUInfo(kSSE4_1)) {
|
if (VP8GetCPUInfo(kSSE4_1)) {
|
||||||
VP8LEncDspInitSSE41();
|
VP8LEncDspInitSSE41();
|
||||||
}
|
}
|
||||||
@ -870,7 +889,7 @@ WEBP_DSP_INIT_FUNC(VP8LEncDspInit) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(WEBP_USE_NEON)
|
#if defined(WEBP_HAVE_NEON)
|
||||||
if (WEBP_NEON_OMIT_C_CODE ||
|
if (WEBP_NEON_OMIT_C_CODE ||
|
||||||
(VP8GetCPUInfo != NULL && VP8GetCPUInfo(kNEON))) {
|
(VP8GetCPUInfo != NULL && VP8GetCPUInfo(kNEON))) {
|
||||||
VP8LEncDspInitNEON();
|
VP8LEncDspInitNEON();
|
||||||
|
@ -232,79 +232,55 @@ static void AddVectorEq_SSE2(const uint32_t* a, uint32_t* out, int size) {
|
|||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Entropy
|
// Entropy
|
||||||
|
|
||||||
// Checks whether the X or Y contribution is worth computing and adding.
|
// TODO(https://crbug.com/webp/499): this function produces different results
|
||||||
// Used in loop unrolling.
|
// from the C code due to use of double/float resulting in output differences
|
||||||
#define ANALYZE_X_OR_Y(x_or_y, j) \
|
// when compared to -noasm.
|
||||||
do { \
|
#if !(defined(WEBP_HAVE_SLOW_CLZ_CTZ) || defined(__i386__) || defined(_M_IX86))
|
||||||
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)
|
|
||||||
|
|
||||||
#if !(defined(__i386__) || defined(_M_IX86))
|
|
||||||
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, sumXY;
|
int sumX = 0, sumXY = 0;
|
||||||
int32_t tmp[4];
|
const __m128i zero = _mm_setzero_si128();
|
||||||
__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 += 4) {
|
for (i = 0; i < 256; i += 16) {
|
||||||
const __m128i x = _mm_loadu_si128((const __m128i*)(X + i));
|
const __m128i x0 = _mm_loadu_si128((const __m128i*)(X + i + 0));
|
||||||
const __m128i y = _mm_loadu_si128((const __m128i*)(Y + i));
|
const __m128i y0 = _mm_loadu_si128((const __m128i*)(Y + i + 0));
|
||||||
|
const __m128i x1 = _mm_loadu_si128((const __m128i*)(X + i + 4));
|
||||||
// Check if any X is non-zero: this actually provides a speedup as X is
|
const __m128i y1 = _mm_loadu_si128((const __m128i*)(Y + i + 4));
|
||||||
// usually sparse.
|
const __m128i x2 = _mm_loadu_si128((const __m128i*)(X + i + 8));
|
||||||
if (_mm_movemask_epi8(_mm_cmpeq_epi32(x, zero)) != 0xFFFF) {
|
const __m128i y2 = _mm_loadu_si128((const __m128i*)(Y + i + 8));
|
||||||
const __m128i xy_128 = _mm_add_epi32(x, y);
|
const __m128i x3 = _mm_loadu_si128((const __m128i*)(X + i + 12));
|
||||||
sumXY_128 = _mm_add_epi32(sumXY_128, xy_128);
|
const __m128i y3 = _mm_loadu_si128((const __m128i*)(Y + i + 12));
|
||||||
|
const __m128i x4 = _mm_packs_epi16(_mm_packs_epi32(x0, x1),
|
||||||
sumX_128 = _mm_add_epi32(sumX_128, x);
|
_mm_packs_epi32(x2, x3));
|
||||||
|
const __m128i y4 = _mm_packs_epi16(_mm_packs_epi32(y0, y1),
|
||||||
// Analyze the different X + Y.
|
_mm_packs_epi32(y2, y3));
|
||||||
_mm_storeu_si128((__m128i*)tmp, xy_128);
|
const int32_t mx = _mm_movemask_epi8(_mm_cmpgt_epi8(x4, zero));
|
||||||
|
int32_t my = _mm_movemask_epi8(_mm_cmpgt_epi8(y4, zero)) | mx;
|
||||||
ANALYZE_XY(0);
|
while (my) {
|
||||||
ANALYZE_XY(1);
|
const int32_t j = BitsCtz(my);
|
||||||
ANALYZE_XY(2);
|
int xy;
|
||||||
ANALYZE_XY(3);
|
if ((mx >> j) & 1) {
|
||||||
} else {
|
const int x = X[i + j];
|
||||||
// X is fully 0, so only deal with Y.
|
sumXY += x;
|
||||||
sumXY_128 = _mm_add_epi32(sumXY_128, y);
|
retval -= VP8LFastSLog2(x);
|
||||||
|
}
|
||||||
ANALYZE_X_OR_Y(Y, 0);
|
xy = X[i + j] + Y[i + j];
|
||||||
ANALYZE_X_OR_Y(Y, 1);
|
sumX += xy;
|
||||||
ANALYZE_X_OR_Y(Y, 2);
|
retval -= VP8LFastSLog2(xy);
|
||||||
ANALYZE_X_OR_Y(Y, 3);
|
my &= my - 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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;
|
||||||
}
|
}
|
||||||
#endif // !(defined(__i386__) || defined(_M_IX86))
|
|
||||||
|
|
||||||
#undef ANALYZE_X_OR_Y
|
#else
|
||||||
#undef ANALYZE_XY
|
|
||||||
|
#define DONT_USE_COMBINED_SHANNON_ENTROPY_SSE2_FUNC // won't be faster
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
@ -662,10 +638,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;
|
||||||
// TODO(https://crbug.com/webp/499): this function produces different results
|
#if !defined(DONT_USE_COMBINED_SHANNON_ENTROPY_SSE2_FUNC)
|
||||||
// from the C code due to use of double/float resulting in output differences
|
|
||||||
// when compared to -noasm.
|
|
||||||
#if !(defined(__i386__) || defined(_M_IX86))
|
|
||||||
VP8LCombinedShannonEntropy = CombinedShannonEntropy_SSE2;
|
VP8LCombinedShannonEntropy = CombinedShannonEntropy_SSE2;
|
||||||
#endif
|
#endif
|
||||||
VP8LVectorMismatch = VectorMismatch_SSE2;
|
VP8LVectorMismatch = VectorMismatch_SSE2;
|
||||||
|
@ -44,46 +44,47 @@ static void SubtractGreenFromBlueAndRed_SSE41(uint32_t* argb_data,
|
|||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Color Transform
|
// Color Transform
|
||||||
|
|
||||||
#define SPAN 8
|
#define MK_CST_16(HI, LO) \
|
||||||
|
_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 mults_r = _mm_set1_epi16(CST_5b(red_to_blue));
|
const __m128i mult =
|
||||||
const __m128i mults_g = _mm_set1_epi16(CST_5b(green_to_blue));
|
MK_CST_16(CST_5b(red_to_blue) + 256,CST_5b(green_to_blue));
|
||||||
const __m128i mask_g = _mm_set1_epi16((short)0xff00); // green mask
|
const __m128i perm =
|
||||||
const __m128i mask_gb = _mm_set1_epi32(0xffff); // green/blue mask
|
_mm_setr_epi8(-1, 1, -1, 2, -1, 5, -1, 6, -1, 9, -1, 10, -1, 13, -1, 14);
|
||||||
const __m128i mask_b = _mm_set1_epi16(0x00ff); // blue mask
|
if (tile_width >= 4) {
|
||||||
const __m128i shuffler_lo = _mm_setr_epi8(-1, 2, -1, 6, -1, 10, -1, 14, -1,
|
int y;
|
||||||
-1, -1, -1, -1, -1, -1, -1);
|
for (y = 0; y < tile_height; ++y) {
|
||||||
const __m128i shuffler_hi = _mm_setr_epi8(-1, -1, -1, -1, -1, -1, -1, -1, -1,
|
const uint32_t* const src = argb + y * stride;
|
||||||
2, -1, 6, -1, 10, -1, 14);
|
const __m128i A1 = _mm_loadu_si128((const __m128i*)src);
|
||||||
int y;
|
const __m128i B1 = _mm_shuffle_epi8(A1, perm);
|
||||||
for (y = 0; y < tile_height; ++y) {
|
const __m128i C1 = _mm_mulhi_epi16(B1, mult);
|
||||||
const uint32_t* const src = argb + y * stride;
|
const __m128i D1 = _mm_sub_epi16(A1, C1);
|
||||||
int i, x;
|
__m128i E = _mm_add_epi16(_mm_srli_epi32(D1, 16), D1);
|
||||||
for (x = 0; x + SPAN <= tile_width; x += SPAN) {
|
int x;
|
||||||
uint16_t values[SPAN];
|
for (x = 4; x + 4 <= tile_width; x += 4) {
|
||||||
const __m128i in0 = _mm_loadu_si128((__m128i*)&src[x + 0]);
|
const __m128i A2 = _mm_loadu_si128((const __m128i*)(src + x));
|
||||||
const __m128i in1 = _mm_loadu_si128((__m128i*)&src[x + SPAN / 2]);
|
__m128i B2, C2, D2;
|
||||||
const __m128i r0 = _mm_shuffle_epi8(in0, shuffler_lo);
|
++histo[_mm_extract_epi8(E, 0)];
|
||||||
const __m128i r1 = _mm_shuffle_epi8(in1, shuffler_hi);
|
B2 = _mm_shuffle_epi8(A2, perm);
|
||||||
const __m128i r = _mm_or_si128(r0, r1); // r 0
|
++histo[_mm_extract_epi8(E, 4)];
|
||||||
const __m128i gb0 = _mm_and_si128(in0, mask_gb);
|
C2 = _mm_mulhi_epi16(B2, mult);
|
||||||
const __m128i gb1 = _mm_and_si128(in1, mask_gb);
|
++histo[_mm_extract_epi8(E, 8)];
|
||||||
const __m128i gb = _mm_packus_epi32(gb0, gb1); // g b
|
D2 = _mm_sub_epi16(A2, C2);
|
||||||
const __m128i g = _mm_and_si128(gb, mask_g); // g 0
|
++histo[_mm_extract_epi8(E, 12)];
|
||||||
const __m128i A = _mm_mulhi_epi16(r, mults_r); // x dbr
|
E = _mm_add_epi16(_mm_srli_epi32(D2, 16), D2);
|
||||||
const __m128i B = _mm_mulhi_epi16(g, mults_g); // x dbg
|
}
|
||||||
const __m128i C = _mm_sub_epi8(gb, B); // x b'
|
++histo[_mm_extract_epi8(E, 0)];
|
||||||
const __m128i D = _mm_sub_epi8(C, A); // x b''
|
++histo[_mm_extract_epi8(E, 4)];
|
||||||
const __m128i E = _mm_and_si128(D, mask_b); // 0 b''
|
++histo[_mm_extract_epi8(E, 8)];
|
||||||
_mm_storeu_si128((__m128i*)values, E);
|
++histo[_mm_extract_epi8(E, 12)];
|
||||||
for (i = 0; i < SPAN; ++i) ++histo[values[i]];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
const int left_over = tile_width & (SPAN - 1);
|
const int left_over = tile_width & 3;
|
||||||
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,
|
||||||
@ -95,33 +96,37 @@ 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);
|
|
||||||
|
|
||||||
int y;
|
const __m128i mult = MK_CST_16(0, CST_5b(green_to_red));
|
||||||
for (y = 0; y < tile_height; ++y) {
|
const __m128i mask_g = _mm_set1_epi32(0x0000ff00);
|
||||||
const uint32_t* const src = argb + y * stride;
|
if (tile_width >= 4) {
|
||||||
int i, x;
|
int y;
|
||||||
for (x = 0; x + SPAN <= tile_width; x += SPAN) {
|
for (y = 0; y < tile_height; ++y) {
|
||||||
uint16_t values[SPAN];
|
const uint32_t* const src = argb + y * stride;
|
||||||
const __m128i in0 = _mm_loadu_si128((__m128i*)&src[x + 0]);
|
const __m128i A1 = _mm_loadu_si128((const __m128i*)src);
|
||||||
const __m128i in1 = _mm_loadu_si128((__m128i*)&src[x + SPAN / 2]);
|
const __m128i B1 = _mm_and_si128(A1, mask_g);
|
||||||
const __m128i g0 = _mm_and_si128(in0, mask_g); // 0 0 | g 0
|
const __m128i C1 = _mm_madd_epi16(B1, mult);
|
||||||
const __m128i g1 = _mm_and_si128(in1, mask_g);
|
__m128i D = _mm_sub_epi16(A1, C1);
|
||||||
const __m128i g = _mm_packus_epi32(g0, g1); // g 0
|
int x;
|
||||||
const __m128i A0 = _mm_srli_epi32(in0, 16); // 0 0 | x r
|
for (x = 4; x + 4 <= tile_width; x += 4) {
|
||||||
const __m128i A1 = _mm_srli_epi32(in1, 16);
|
const __m128i A2 = _mm_loadu_si128((const __m128i*)(src + x));
|
||||||
const __m128i A = _mm_packus_epi32(A0, A1); // x r
|
__m128i B2, C2;
|
||||||
const __m128i B = _mm_mulhi_epi16(g, mults_g); // x dr
|
++histo[_mm_extract_epi8(D, 2)];
|
||||||
const __m128i C = _mm_sub_epi8(A, B); // x r'
|
B2 = _mm_and_si128(A2, mask_g);
|
||||||
const __m128i D = _mm_and_si128(C, mask); // 0 r'
|
++histo[_mm_extract_epi8(D, 6)];
|
||||||
_mm_storeu_si128((__m128i*)values, D);
|
C2 = _mm_madd_epi16(B2, mult);
|
||||||
for (i = 0; i < SPAN; ++i) ++histo[values[i]];
|
++histo[_mm_extract_epi8(D, 10)];
|
||||||
|
++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 & (SPAN - 1);
|
const int left_over = tile_width & 3;
|
||||||
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,
|
||||||
@ -130,6 +135,8 @@ static void CollectColorRedTransforms_SSE41(const uint32_t* argb, int stride,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#undef MK_CST_16
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Entry point
|
// Entry point
|
||||||
|
|
||||||
|
@ -188,46 +188,51 @@ static WEBP_INLINE uint32_t Average4(uint32_t a0, uint32_t a1,
|
|||||||
return Average2(Average2(a0, a1), Average2(a2, a3));
|
return Average2(Average2(a0, a1), Average2(a2, a3));
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t Predictor5_MIPSdspR2(uint32_t left, const uint32_t* const top) {
|
static uint32_t Predictor5_MIPSdspR2(const uint32_t* const left,
|
||||||
return Average3(left, top[0], top[1]);
|
const uint32_t* const top) {
|
||||||
|
return Average3(*left, top[0], top[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t Predictor6_MIPSdspR2(uint32_t left, const uint32_t* const top) {
|
static uint32_t Predictor6_MIPSdspR2(const uint32_t* const left,
|
||||||
return Average2(left, top[-1]);
|
const uint32_t* const top) {
|
||||||
|
return Average2(*left, top[-1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t Predictor7_MIPSdspR2(uint32_t left, const uint32_t* const top) {
|
static uint32_t Predictor7_MIPSdspR2(const uint32_t* const left,
|
||||||
return Average2(left, top[0]);
|
const uint32_t* const top) {
|
||||||
|
return Average2(*left, top[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t Predictor8_MIPSdspR2(uint32_t left, const uint32_t* const top) {
|
static uint32_t Predictor8_MIPSdspR2(const uint32_t* const left,
|
||||||
|
const uint32_t* const top) {
|
||||||
(void)left;
|
(void)left;
|
||||||
return Average2(top[-1], top[0]);
|
return Average2(top[-1], top[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t Predictor9_MIPSdspR2(uint32_t left, const uint32_t* const top) {
|
static uint32_t Predictor9_MIPSdspR2(const uint32_t* const left,
|
||||||
|
const uint32_t* const top) {
|
||||||
(void)left;
|
(void)left;
|
||||||
return Average2(top[0], top[1]);
|
return Average2(top[0], top[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t Predictor10_MIPSdspR2(uint32_t left,
|
static uint32_t Predictor10_MIPSdspR2(const uint32_t* const left,
|
||||||
const uint32_t* const top) {
|
const uint32_t* const top) {
|
||||||
return Average4(left, top[-1], top[0], top[1]);
|
return Average4(*left, top[-1], top[0], top[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t Predictor11_MIPSdspR2(uint32_t left,
|
static uint32_t Predictor11_MIPSdspR2(const uint32_t* const left,
|
||||||
const uint32_t* const top) {
|
const uint32_t* const top) {
|
||||||
return Select(top[0], left, top[-1]);
|
return Select(top[0], *left, top[-1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t Predictor12_MIPSdspR2(uint32_t left,
|
static uint32_t Predictor12_MIPSdspR2(const uint32_t* const left,
|
||||||
const uint32_t* const top) {
|
const uint32_t* const top) {
|
||||||
return ClampedAddSubtractFull(left, top[0], top[-1]);
|
return ClampedAddSubtractFull(*left, top[0], top[-1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t Predictor13_MIPSdspR2(uint32_t left,
|
static uint32_t Predictor13_MIPSdspR2(const uint32_t* const left,
|
||||||
const uint32_t* const top) {
|
const uint32_t* const top) {
|
||||||
return ClampedAddSubtractHalf(left, top[0], top[-1]);
|
return ClampedAddSubtractHalf(*left, top[0], top[-1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add green to blue and red channels (i.e. perform the inverse transform of
|
// Add green to blue and red channels (i.e. perform the inverse transform of
|
||||||
|
@ -188,17 +188,21 @@ static WEBP_INLINE uint32_t Average3_NEON(uint32_t a0, uint32_t a1,
|
|||||||
return avg;
|
return avg;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t Predictor5_NEON(uint32_t left, const uint32_t* const top) {
|
static uint32_t Predictor5_NEON(const uint32_t* const left,
|
||||||
return Average3_NEON(left, top[0], top[1]);
|
const uint32_t* const top) {
|
||||||
|
return Average3_NEON(*left, top[0], top[1]);
|
||||||
}
|
}
|
||||||
static uint32_t Predictor6_NEON(uint32_t left, const uint32_t* const top) {
|
static uint32_t Predictor6_NEON(const uint32_t* const left,
|
||||||
return Average2_NEON(left, top[-1]);
|
const uint32_t* const top) {
|
||||||
|
return Average2_NEON(*left, top[-1]);
|
||||||
}
|
}
|
||||||
static uint32_t Predictor7_NEON(uint32_t left, const uint32_t* const top) {
|
static uint32_t Predictor7_NEON(const uint32_t* const left,
|
||||||
return Average2_NEON(left, top[0]);
|
const uint32_t* const top) {
|
||||||
|
return Average2_NEON(*left, top[0]);
|
||||||
}
|
}
|
||||||
static uint32_t Predictor13_NEON(uint32_t left, const uint32_t* const top) {
|
static uint32_t Predictor13_NEON(const uint32_t* const left,
|
||||||
return ClampedAddSubtractHalf_NEON(left, top[0], top[-1]);
|
const uint32_t* const top) {
|
||||||
|
return ClampedAddSubtractHalf_NEON(*left, top[0], top[-1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Batch versions of those functions.
|
// Batch versions of those functions.
|
||||||
|
@ -18,7 +18,6 @@
|
|||||||
#include "src/dsp/common_sse2.h"
|
#include "src/dsp/common_sse2.h"
|
||||||
#include "src/dsp/lossless.h"
|
#include "src/dsp/lossless.h"
|
||||||
#include "src/dsp/lossless_common.h"
|
#include "src/dsp/lossless_common.h"
|
||||||
#include <assert.h>
|
|
||||||
#include <emmintrin.h>
|
#include <emmintrin.h>
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
@ -139,42 +138,51 @@ static WEBP_INLINE uint32_t Average4_SSE2(uint32_t a0, uint32_t a1,
|
|||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t Predictor5_SSE2(uint32_t left, const uint32_t* const top) {
|
static uint32_t Predictor5_SSE2(const uint32_t* const left,
|
||||||
const uint32_t pred = Average3_SSE2(left, top[0], top[1]);
|
const uint32_t* const top) {
|
||||||
|
const uint32_t pred = Average3_SSE2(*left, top[0], top[1]);
|
||||||
return pred;
|
return pred;
|
||||||
}
|
}
|
||||||
static uint32_t Predictor6_SSE2(uint32_t left, const uint32_t* const top) {
|
static uint32_t Predictor6_SSE2(const uint32_t* const left,
|
||||||
const uint32_t pred = Average2_SSE2(left, top[-1]);
|
const uint32_t* const top) {
|
||||||
|
const uint32_t pred = Average2_SSE2(*left, top[-1]);
|
||||||
return pred;
|
return pred;
|
||||||
}
|
}
|
||||||
static uint32_t Predictor7_SSE2(uint32_t left, const uint32_t* const top) {
|
static uint32_t Predictor7_SSE2(const uint32_t* const left,
|
||||||
const uint32_t pred = Average2_SSE2(left, top[0]);
|
const uint32_t* const top) {
|
||||||
|
const uint32_t pred = Average2_SSE2(*left, top[0]);
|
||||||
return pred;
|
return pred;
|
||||||
}
|
}
|
||||||
static uint32_t Predictor8_SSE2(uint32_t left, const uint32_t* const top) {
|
static uint32_t Predictor8_SSE2(const uint32_t* const left,
|
||||||
|
const uint32_t* const top) {
|
||||||
const uint32_t pred = Average2_SSE2(top[-1], top[0]);
|
const uint32_t pred = Average2_SSE2(top[-1], top[0]);
|
||||||
(void)left;
|
(void)left;
|
||||||
return pred;
|
return pred;
|
||||||
}
|
}
|
||||||
static uint32_t Predictor9_SSE2(uint32_t left, const uint32_t* const top) {
|
static uint32_t Predictor9_SSE2(const uint32_t* const left,
|
||||||
|
const uint32_t* const top) {
|
||||||
const uint32_t pred = Average2_SSE2(top[0], top[1]);
|
const uint32_t pred = Average2_SSE2(top[0], top[1]);
|
||||||
(void)left;
|
(void)left;
|
||||||
return pred;
|
return pred;
|
||||||
}
|
}
|
||||||
static uint32_t Predictor10_SSE2(uint32_t left, const uint32_t* const top) {
|
static uint32_t Predictor10_SSE2(const uint32_t* const left,
|
||||||
const uint32_t pred = Average4_SSE2(left, top[-1], top[0], top[1]);
|
const uint32_t* const top) {
|
||||||
|
const uint32_t pred = Average4_SSE2(*left, top[-1], top[0], top[1]);
|
||||||
return pred;
|
return pred;
|
||||||
}
|
}
|
||||||
static uint32_t Predictor11_SSE2(uint32_t left, const uint32_t* const top) {
|
static uint32_t Predictor11_SSE2(const uint32_t* const left,
|
||||||
const uint32_t pred = Select_SSE2(top[0], left, top[-1]);
|
const uint32_t* const top) {
|
||||||
|
const uint32_t pred = Select_SSE2(top[0], *left, top[-1]);
|
||||||
return pred;
|
return pred;
|
||||||
}
|
}
|
||||||
static uint32_t Predictor12_SSE2(uint32_t left, const uint32_t* const top) {
|
static uint32_t Predictor12_SSE2(const uint32_t* const left,
|
||||||
const uint32_t pred = ClampedAddSubtractFull_SSE2(left, top[0], top[-1]);
|
const uint32_t* const top) {
|
||||||
|
const uint32_t pred = ClampedAddSubtractFull_SSE2(*left, top[0], top[-1]);
|
||||||
return pred;
|
return pred;
|
||||||
}
|
}
|
||||||
static uint32_t Predictor13_SSE2(uint32_t left, const uint32_t* const top) {
|
static uint32_t Predictor13_SSE2(const uint32_t* const left,
|
||||||
const uint32_t pred = ClampedAddSubtractHalf_SSE2(left, top[0], top[-1]);
|
const uint32_t* const top) {
|
||||||
|
const uint32_t pred = ClampedAddSubtractHalf_SSE2(*left, top[0], top[-1]);
|
||||||
return pred;
|
return pred;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
132
src/dsp/lossless_sse41.c
Normal file
132
src/dsp/lossless_sse41.c
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
// 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.
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// SSE41 variant of methods for lossless decoder
|
||||||
|
|
||||||
|
#include "src/dsp/dsp.h"
|
||||||
|
|
||||||
|
#if defined(WEBP_USE_SSE41)
|
||||||
|
|
||||||
|
#include "src/dsp/common_sse41.h"
|
||||||
|
#include "src/dsp/lossless.h"
|
||||||
|
#include "src/dsp/lossless_common.h"
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Color-space conversion functions
|
||||||
|
|
||||||
|
static void TransformColorInverse_SSE41(const VP8LMultipliers* const m,
|
||||||
|
const uint32_t* const src,
|
||||||
|
int num_pixels, uint32_t* dst) {
|
||||||
|
// sign-extended multiplying constants, pre-shifted by 5.
|
||||||
|
#define CST(X) (((int16_t)(m->X << 8)) >> 5) // sign-extend
|
||||||
|
const __m128i mults_rb = _mm_set1_epi32((uint32_t)CST(green_to_red_) << 16 |
|
||||||
|
(CST(green_to_blue_) & 0xffff));
|
||||||
|
const __m128i mults_b2 = _mm_set1_epi32(CST(red_to_blue_));
|
||||||
|
#undef CST
|
||||||
|
const __m128i mask_ag = _mm_set1_epi32(0xff00ff00);
|
||||||
|
const __m128i perm1 = _mm_setr_epi8(-1, 1, -1, 1, -1, 5, -1, 5,
|
||||||
|
-1, 9, -1, 9, -1, 13, -1, 13);
|
||||||
|
const __m128i perm2 = _mm_setr_epi8(-1, 2, -1, -1, -1, 6, -1, -1,
|
||||||
|
-1, 10, -1, -1, -1, 14, -1, -1);
|
||||||
|
int i;
|
||||||
|
for (i = 0; i + 4 <= num_pixels; i += 4) {
|
||||||
|
const __m128i A = _mm_loadu_si128((const __m128i*)(src + i));
|
||||||
|
const __m128i B = _mm_shuffle_epi8(A, perm1); // argb -> g0g0
|
||||||
|
const __m128i C = _mm_mulhi_epi16(B, mults_rb);
|
||||||
|
const __m128i D = _mm_add_epi8(A, C);
|
||||||
|
const __m128i E = _mm_shuffle_epi8(D, perm2);
|
||||||
|
const __m128i F = _mm_mulhi_epi16(E, mults_b2);
|
||||||
|
const __m128i G = _mm_add_epi8(D, F);
|
||||||
|
const __m128i out = _mm_blendv_epi8(G, A, mask_ag);
|
||||||
|
_mm_storeu_si128((__m128i*)&dst[i], out);
|
||||||
|
}
|
||||||
|
// Fall-back to C-version for left-overs.
|
||||||
|
if (i != num_pixels) {
|
||||||
|
VP8LTransformColorInverse_C(m, src + i, num_pixels - i, dst + i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#define ARGB_TO_RGB_SSE41 do { \
|
||||||
|
while (num_pixels >= 16) { \
|
||||||
|
const __m128i in0 = _mm_loadu_si128(in + 0); \
|
||||||
|
const __m128i in1 = _mm_loadu_si128(in + 1); \
|
||||||
|
const __m128i in2 = _mm_loadu_si128(in + 2); \
|
||||||
|
const __m128i in3 = _mm_loadu_si128(in + 3); \
|
||||||
|
const __m128i a0 = _mm_shuffle_epi8(in0, perm0); \
|
||||||
|
const __m128i a1 = _mm_shuffle_epi8(in1, perm1); \
|
||||||
|
const __m128i a2 = _mm_shuffle_epi8(in2, perm2); \
|
||||||
|
const __m128i a3 = _mm_shuffle_epi8(in3, perm3); \
|
||||||
|
const __m128i b0 = _mm_blend_epi16(a0, a1, 0xc0); \
|
||||||
|
const __m128i b1 = _mm_blend_epi16(a1, a2, 0xf0); \
|
||||||
|
const __m128i b2 = _mm_blend_epi16(a2, a3, 0xfc); \
|
||||||
|
_mm_storeu_si128(out + 0, b0); \
|
||||||
|
_mm_storeu_si128(out + 1, b1); \
|
||||||
|
_mm_storeu_si128(out + 2, b2); \
|
||||||
|
in += 4; \
|
||||||
|
out += 3; \
|
||||||
|
num_pixels -= 16; \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
static void ConvertBGRAToRGB_SSE41(const uint32_t* src, int num_pixels,
|
||||||
|
uint8_t* dst) {
|
||||||
|
const __m128i* in = (const __m128i*)src;
|
||||||
|
__m128i* out = (__m128i*)dst;
|
||||||
|
const __m128i perm0 = _mm_setr_epi8(2, 1, 0, 6, 5, 4, 10, 9,
|
||||||
|
8, 14, 13, 12, -1, -1, -1, -1);
|
||||||
|
const __m128i perm1 = _mm_shuffle_epi32(perm0, 0x39);
|
||||||
|
const __m128i perm2 = _mm_shuffle_epi32(perm0, 0x4e);
|
||||||
|
const __m128i perm3 = _mm_shuffle_epi32(perm0, 0x93);
|
||||||
|
|
||||||
|
ARGB_TO_RGB_SSE41;
|
||||||
|
|
||||||
|
// left-overs
|
||||||
|
if (num_pixels > 0) {
|
||||||
|
VP8LConvertBGRAToRGB_C((const uint32_t*)in, num_pixels, (uint8_t*)out);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ConvertBGRAToBGR_SSE41(const uint32_t* src,
|
||||||
|
int num_pixels, uint8_t* dst) {
|
||||||
|
const __m128i* in = (const __m128i*)src;
|
||||||
|
__m128i* out = (__m128i*)dst;
|
||||||
|
const __m128i perm0 = _mm_setr_epi8(0, 1, 2, 4, 5, 6, 8, 9, 10,
|
||||||
|
12, 13, 14, -1, -1, -1, -1);
|
||||||
|
const __m128i perm1 = _mm_shuffle_epi32(perm0, 0x39);
|
||||||
|
const __m128i perm2 = _mm_shuffle_epi32(perm0, 0x4e);
|
||||||
|
const __m128i perm3 = _mm_shuffle_epi32(perm0, 0x93);
|
||||||
|
|
||||||
|
ARGB_TO_RGB_SSE41;
|
||||||
|
|
||||||
|
// left-overs
|
||||||
|
if (num_pixels > 0) {
|
||||||
|
VP8LConvertBGRAToBGR_C((const uint32_t*)in, num_pixels, (uint8_t*)out);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef ARGB_TO_RGB_SSE41
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Entry point
|
||||||
|
|
||||||
|
extern void VP8LDspInitSSE41(void);
|
||||||
|
|
||||||
|
WEBP_TSAN_IGNORE_FUNCTION void VP8LDspInitSSE41(void) {
|
||||||
|
VP8LTransformColorInverse = TransformColorInverse_SSE41;
|
||||||
|
VP8LConvertBGRAToRGB = ConvertBGRAToRGB_SSE41;
|
||||||
|
VP8LConvertBGRAToBGR = ConvertBGRAToBGR_SSE41;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else // !WEBP_USE_SSE41
|
||||||
|
|
||||||
|
WEBP_DSP_INIT_STUB(VP8LDspInitSSE41)
|
||||||
|
|
||||||
|
#endif // WEBP_USE_SSE41
|
@ -14,6 +14,10 @@
|
|||||||
#ifndef WEBP_DSP_MSA_MACRO_H_
|
#ifndef WEBP_DSP_MSA_MACRO_H_
|
||||||
#define WEBP_DSP_MSA_MACRO_H_
|
#define WEBP_DSP_MSA_MACRO_H_
|
||||||
|
|
||||||
|
#include "src/dsp/dsp.h"
|
||||||
|
|
||||||
|
#if defined(WEBP_USE_MSA)
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <msa.h>
|
#include <msa.h>
|
||||||
|
|
||||||
@ -1389,4 +1393,5 @@ static WEBP_INLINE uint32_t func_hadd_uh_u32(v8u16 in) {
|
|||||||
} while (0)
|
} while (0)
|
||||||
#define AVER_UB2_UB(...) AVER_UB2(v16u8, __VA_ARGS__)
|
#define AVER_UB2_UB(...) AVER_UB2(v16u8, __VA_ARGS__)
|
||||||
|
|
||||||
|
#endif // WEBP_USE_MSA
|
||||||
#endif // WEBP_DSP_MSA_MACRO_H_
|
#endif // WEBP_DSP_MSA_MACRO_H_
|
||||||
|
@ -12,10 +12,12 @@
|
|||||||
#ifndef WEBP_DSP_NEON_H_
|
#ifndef WEBP_DSP_NEON_H_
|
||||||
#define WEBP_DSP_NEON_H_
|
#define WEBP_DSP_NEON_H_
|
||||||
|
|
||||||
#include <arm_neon.h>
|
|
||||||
|
|
||||||
#include "src/dsp/dsp.h"
|
#include "src/dsp/dsp.h"
|
||||||
|
|
||||||
|
#if defined(WEBP_USE_NEON)
|
||||||
|
|
||||||
|
#include <arm_neon.h>
|
||||||
|
|
||||||
// Right now, some intrinsics functions seem slower, so we disable them
|
// Right now, some intrinsics functions seem slower, so we disable them
|
||||||
// everywhere except newer clang/gcc or aarch64 where the inline assembly is
|
// everywhere except newer clang/gcc or aarch64 where the inline assembly is
|
||||||
// incompatible.
|
// incompatible.
|
||||||
@ -98,4 +100,5 @@ static WEBP_INLINE int32x4x4_t Transpose4x4_NEON(const int32x4x4_t rows) {
|
|||||||
} while (0)
|
} while (0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#endif // WEBP_USE_NEON
|
||||||
#endif // WEBP_DSP_NEON_H_
|
#endif // WEBP_DSP_NEON_H_
|
||||||
|
@ -38,8 +38,9 @@ void WebPRescalerImportRowExpand_C(WebPRescaler* const wrk,
|
|||||||
int x_out = channel;
|
int x_out = channel;
|
||||||
// simple bilinear interpolation
|
// simple bilinear interpolation
|
||||||
int accum = wrk->x_add;
|
int accum = wrk->x_add;
|
||||||
int left = src[x_in];
|
rescaler_t left = (rescaler_t)src[x_in];
|
||||||
int right = (wrk->src_width > 1) ? src[x_in + x_stride] : left;
|
rescaler_t right =
|
||||||
|
(wrk->src_width > 1) ? (rescaler_t)src[x_in + x_stride] : left;
|
||||||
x_in += x_stride;
|
x_in += x_stride;
|
||||||
while (1) {
|
while (1) {
|
||||||
wrk->frow[x_out] = right * wrk->x_add + (left - right) * accum;
|
wrk->frow[x_out] = right * wrk->x_add + (left - right) * accum;
|
||||||
@ -50,7 +51,7 @@ void WebPRescalerImportRowExpand_C(WebPRescaler* const wrk,
|
|||||||
left = right;
|
left = right;
|
||||||
x_in += x_stride;
|
x_in += x_stride;
|
||||||
assert(x_in < wrk->src_width * x_stride);
|
assert(x_in < wrk->src_width * x_stride);
|
||||||
right = src[x_in];
|
right = (rescaler_t)src[x_in];
|
||||||
accum += wrk->x_add;
|
accum += wrk->x_add;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -213,7 +214,7 @@ WEBP_DSP_INIT_FUNC(WebPRescalerDspInit) {
|
|||||||
WebPRescalerImportRowShrink = WebPRescalerImportRowShrink_C;
|
WebPRescalerImportRowShrink = WebPRescalerImportRowShrink_C;
|
||||||
|
|
||||||
if (VP8GetCPUInfo != NULL) {
|
if (VP8GetCPUInfo != NULL) {
|
||||||
#if defined(WEBP_USE_SSE2)
|
#if defined(WEBP_HAVE_SSE2)
|
||||||
if (VP8GetCPUInfo(kSSE2)) {
|
if (VP8GetCPUInfo(kSSE2)) {
|
||||||
WebPRescalerDspInitSSE2();
|
WebPRescalerDspInitSSE2();
|
||||||
}
|
}
|
||||||
@ -235,7 +236,7 @@ WEBP_DSP_INIT_FUNC(WebPRescalerDspInit) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(WEBP_USE_NEON)
|
#if defined(WEBP_HAVE_NEON)
|
||||||
if (WEBP_NEON_OMIT_C_CODE ||
|
if (WEBP_NEON_OMIT_C_CODE ||
|
||||||
(VP8GetCPUInfo != NULL && VP8GetCPUInfo(kNEON))) {
|
(VP8GetCPUInfo != NULL && VP8GetCPUInfo(kNEON))) {
|
||||||
WebPRescalerDspInitNEON();
|
WebPRescalerDspInitNEON();
|
||||||
|
@ -150,7 +150,7 @@ WEBP_DSP_INIT_FUNC(VP8SSIMDspInit) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (VP8GetCPUInfo != NULL) {
|
if (VP8GetCPUInfo != NULL) {
|
||||||
#if defined(WEBP_USE_SSE2)
|
#if defined(WEBP_HAVE_SSE2)
|
||||||
if (VP8GetCPUInfo(kSSE2)) {
|
if (VP8GetCPUInfo(kSSE2)) {
|
||||||
VP8SSIMDspInitSSE2();
|
VP8SSIMDspInitSSE2();
|
||||||
}
|
}
|
||||||
|
@ -233,12 +233,12 @@ WEBP_DSP_INIT_FUNC(WebPInitYUV444Converters) {
|
|||||||
WebPYUV444Converters[MODE_rgbA_4444] = WebPYuv444ToRgba4444_C;
|
WebPYUV444Converters[MODE_rgbA_4444] = WebPYuv444ToRgba4444_C;
|
||||||
|
|
||||||
if (VP8GetCPUInfo != NULL) {
|
if (VP8GetCPUInfo != NULL) {
|
||||||
#if defined(WEBP_USE_SSE2)
|
#if defined(WEBP_HAVE_SSE2)
|
||||||
if (VP8GetCPUInfo(kSSE2)) {
|
if (VP8GetCPUInfo(kSSE2)) {
|
||||||
WebPInitYUV444ConvertersSSE2();
|
WebPInitYUV444ConvertersSSE2();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#if defined(WEBP_USE_SSE41)
|
#if defined(WEBP_HAVE_SSE41)
|
||||||
if (VP8GetCPUInfo(kSSE4_1)) {
|
if (VP8GetCPUInfo(kSSE4_1)) {
|
||||||
WebPInitYUV444ConvertersSSE41();
|
WebPInitYUV444ConvertersSSE41();
|
||||||
}
|
}
|
||||||
@ -278,12 +278,12 @@ WEBP_DSP_INIT_FUNC(WebPInitUpsamplers) {
|
|||||||
|
|
||||||
// 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_USE_SSE2)
|
#if defined(WEBP_HAVE_SSE2)
|
||||||
if (VP8GetCPUInfo(kSSE2)) {
|
if (VP8GetCPUInfo(kSSE2)) {
|
||||||
WebPInitUpsamplersSSE2();
|
WebPInitUpsamplersSSE2();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#if defined(WEBP_USE_SSE41)
|
#if defined(WEBP_HAVE_SSE41)
|
||||||
if (VP8GetCPUInfo(kSSE4_1)) {
|
if (VP8GetCPUInfo(kSSE4_1)) {
|
||||||
WebPInitUpsamplersSSE41();
|
WebPInitUpsamplersSSE41();
|
||||||
}
|
}
|
||||||
@ -300,7 +300,7 @@ WEBP_DSP_INIT_FUNC(WebPInitUpsamplers) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(WEBP_USE_NEON)
|
#if defined(WEBP_HAVE_NEON)
|
||||||
if (WEBP_NEON_OMIT_C_CODE ||
|
if (WEBP_NEON_OMIT_C_CODE ||
|
||||||
(VP8GetCPUInfo != NULL && VP8GetCPUInfo(kNEON))) {
|
(VP8GetCPUInfo != NULL && VP8GetCPUInfo(kNEON))) {
|
||||||
WebPInitUpsamplersNEON();
|
WebPInitUpsamplersNEON();
|
||||||
|
@ -90,16 +90,16 @@ WEBP_DSP_INIT_FUNC(WebPInitSamplers) {
|
|||||||
|
|
||||||
// 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_USE_SSE2)
|
#if defined(WEBP_HAVE_SSE2)
|
||||||
if (VP8GetCPUInfo(kSSE2)) {
|
if (VP8GetCPUInfo(kSSE2)) {
|
||||||
WebPInitSamplersSSE2();
|
WebPInitSamplersSSE2();
|
||||||
}
|
}
|
||||||
#endif // WEBP_USE_SSE2
|
#endif // WEBP_HAVE_SSE2
|
||||||
#if defined(WEBP_USE_SSE41)
|
#if defined(WEBP_HAVE_SSE41)
|
||||||
if (VP8GetCPUInfo(kSSE4_1)) {
|
if (VP8GetCPUInfo(kSSE4_1)) {
|
||||||
WebPInitSamplersSSE41();
|
WebPInitSamplersSSE41();
|
||||||
}
|
}
|
||||||
#endif // WEBP_USE_SSE41
|
#endif // WEBP_HAVE_SSE41
|
||||||
#if defined(WEBP_USE_MIPS32)
|
#if defined(WEBP_USE_MIPS32)
|
||||||
if (VP8GetCPUInfo(kMIPS32)) {
|
if (VP8GetCPUInfo(kMIPS32)) {
|
||||||
WebPInitSamplersMIPS32();
|
WebPInitSamplersMIPS32();
|
||||||
@ -276,26 +276,26 @@ WEBP_DSP_INIT_FUNC(WebPInitConvertARGBToYUV) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (VP8GetCPUInfo != NULL) {
|
if (VP8GetCPUInfo != NULL) {
|
||||||
#if defined(WEBP_USE_SSE2)
|
#if defined(WEBP_HAVE_SSE2)
|
||||||
if (VP8GetCPUInfo(kSSE2)) {
|
if (VP8GetCPUInfo(kSSE2)) {
|
||||||
WebPInitConvertARGBToYUVSSE2();
|
WebPInitConvertARGBToYUVSSE2();
|
||||||
WebPInitSharpYUVSSE2();
|
WebPInitSharpYUVSSE2();
|
||||||
}
|
}
|
||||||
#endif // WEBP_USE_SSE2
|
#endif // WEBP_HAVE_SSE2
|
||||||
#if defined(WEBP_USE_SSE41)
|
#if defined(WEBP_HAVE_SSE41)
|
||||||
if (VP8GetCPUInfo(kSSE4_1)) {
|
if (VP8GetCPUInfo(kSSE4_1)) {
|
||||||
WebPInitConvertARGBToYUVSSE41();
|
WebPInitConvertARGBToYUVSSE41();
|
||||||
}
|
}
|
||||||
#endif // WEBP_USE_SSE41
|
#endif // WEBP_HAVE_SSE41
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(WEBP_USE_NEON)
|
#if defined(WEBP_HAVE_NEON)
|
||||||
if (WEBP_NEON_OMIT_C_CODE ||
|
if (WEBP_NEON_OMIT_C_CODE ||
|
||||||
(VP8GetCPUInfo != NULL && VP8GetCPUInfo(kNEON))) {
|
(VP8GetCPUInfo != NULL && VP8GetCPUInfo(kNEON))) {
|
||||||
WebPInitConvertARGBToYUVNEON();
|
WebPInitConvertARGBToYUVNEON();
|
||||||
WebPInitSharpYUVNEON();
|
WebPInitSharpYUVNEON();
|
||||||
}
|
}
|
||||||
#endif // WEBP_USE_NEON
|
#endif // WEBP_HAVE_NEON
|
||||||
|
|
||||||
assert(WebPConvertARGBToY != NULL);
|
assert(WebPConvertARGBToY != NULL);
|
||||||
assert(WebPConvertARGBToUV != NULL);
|
assert(WebPConvertARGBToUV != NULL);
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
// inline YUV<->RGB conversion function
|
// inline YUV<->RGB conversion function
|
||||||
//
|
//
|
||||||
// The exact naming is Y'CbCr, following the ITU-R BT.601 standard.
|
// The exact naming is Y'CbCr, following the ITU-R BT.601 standard.
|
||||||
// More information at: http://en.wikipedia.org/wiki/YCbCr
|
// More information at: https://en.wikipedia.org/wiki/YCbCr
|
||||||
// Y = 0.2569 * R + 0.5044 * G + 0.0979 * B + 16
|
// Y = 0.2569 * R + 0.5044 * G + 0.0979 * B + 16
|
||||||
// U = -0.1483 * R - 0.2911 * G + 0.4394 * B + 128
|
// U = -0.1483 * R - 0.2911 * G + 0.4394 * B + 128
|
||||||
// V = 0.4394 * R - 0.3679 * G - 0.0715 * B + 128
|
// V = 0.4394 * R - 0.3679 * G - 0.0715 * B + 128
|
||||||
|
@ -303,7 +303,7 @@ static int EncodeAlpha(VP8Encoder* const enc,
|
|||||||
int ok = 1;
|
int ok = 1;
|
||||||
const int reduce_levels = (quality < 100);
|
const int reduce_levels = (quality < 100);
|
||||||
|
|
||||||
// quick sanity checks
|
// quick correctness checks
|
||||||
assert((uint64_t)data_size == (uint64_t)width * height); // as per spec
|
assert((uint64_t)data_size == (uint64_t)width * height); // as per spec
|
||||||
assert(enc != NULL && pic != NULL && pic->a != NULL);
|
assert(enc != NULL && pic != NULL && pic->a != NULL);
|
||||||
assert(output != NULL && output_size != NULL);
|
assert(output != NULL && output_size != NULL);
|
||||||
@ -361,7 +361,7 @@ static int EncodeAlpha(VP8Encoder* const enc,
|
|||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Main calls
|
// Main calls
|
||||||
|
|
||||||
static int CompressAlphaJob(void* arg1, void* dummy) {
|
static int CompressAlphaJob(void* arg1, void* unused) {
|
||||||
VP8Encoder* const enc = (VP8Encoder*)arg1;
|
VP8Encoder* const enc = (VP8Encoder*)arg1;
|
||||||
const WebPConfig* config = enc->config_;
|
const WebPConfig* config = enc->config_;
|
||||||
uint8_t* alpha_data = NULL;
|
uint8_t* alpha_data = NULL;
|
||||||
@ -375,13 +375,13 @@ static int CompressAlphaJob(void* arg1, void* dummy) {
|
|||||||
filter, effort_level, &alpha_data, &alpha_size)) {
|
filter, effort_level, &alpha_data, &alpha_size)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (alpha_size != (uint32_t)alpha_size) { // Sanity check.
|
if (alpha_size != (uint32_t)alpha_size) { // Soundness check.
|
||||||
WebPSafeFree(alpha_data);
|
WebPSafeFree(alpha_data);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
enc->alpha_data_size_ = (uint32_t)alpha_size;
|
enc->alpha_data_size_ = (uint32_t)alpha_size;
|
||||||
enc->alpha_data_ = alpha_data;
|
enc->alpha_data_ = alpha_data;
|
||||||
(void)dummy;
|
(void)unused;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1171,13 +1171,15 @@ static void RemoveEmptyHistograms(VP8LHistogramSet* const image_histo) {
|
|||||||
int VP8LGetHistoImageSymbols(int xsize, int ysize,
|
int VP8LGetHistoImageSymbols(int xsize, int ysize,
|
||||||
const VP8LBackwardRefs* const refs,
|
const VP8LBackwardRefs* const refs,
|
||||||
int quality, int low_effort,
|
int quality, int low_effort,
|
||||||
int histo_bits, int cache_bits,
|
int histogram_bits, int cache_bits,
|
||||||
VP8LHistogramSet* const image_histo,
|
VP8LHistogramSet* const image_histo,
|
||||||
VP8LHistogram* const tmp_histo,
|
VP8LHistogram* const tmp_histo,
|
||||||
uint16_t* const histogram_symbols) {
|
uint16_t* const histogram_symbols) {
|
||||||
int ok = 0;
|
int ok = 0;
|
||||||
const int histo_xsize = histo_bits ? VP8LSubSampleSize(xsize, histo_bits) : 1;
|
const int histo_xsize =
|
||||||
const int histo_ysize = histo_bits ? VP8LSubSampleSize(ysize, histo_bits) : 1;
|
histogram_bits ? VP8LSubSampleSize(xsize, histogram_bits) : 1;
|
||||||
|
const int histo_ysize =
|
||||||
|
histogram_bits ? VP8LSubSampleSize(ysize, histogram_bits) : 1;
|
||||||
const int image_histo_raw_size = histo_xsize * histo_ysize;
|
const int image_histo_raw_size = histo_xsize * histo_ysize;
|
||||||
VP8LHistogramSet* const orig_histo =
|
VP8LHistogramSet* const orig_histo =
|
||||||
VP8LAllocateHistogramSet(image_histo_raw_size, cache_bits);
|
VP8LAllocateHistogramSet(image_histo_raw_size, cache_bits);
|
||||||
@ -1193,7 +1195,7 @@ int VP8LGetHistoImageSymbols(int xsize, int ysize,
|
|||||||
if (orig_histo == NULL || map_tmp == NULL) goto Error;
|
if (orig_histo == NULL || map_tmp == NULL) goto Error;
|
||||||
|
|
||||||
// Construct the histograms from backward references.
|
// Construct the histograms from backward references.
|
||||||
HistogramBuild(xsize, histo_bits, refs, orig_histo);
|
HistogramBuild(xsize, histogram_bits, refs, orig_histo);
|
||||||
// Copies the histograms and computes its bit_cost.
|
// Copies the histograms and computes its bit_cost.
|
||||||
// histogram_symbols is optimized
|
// histogram_symbols is optimized
|
||||||
HistogramCopyAndAnalyze(orig_histo, image_histo, &num_used,
|
HistogramCopyAndAnalyze(orig_histo, image_histo, &num_used,
|
||||||
|
@ -64,8 +64,8 @@ void VP8LHistogramCreate(VP8LHistogram* const p,
|
|||||||
const VP8LBackwardRefs* const refs,
|
const VP8LBackwardRefs* const refs,
|
||||||
int palette_code_bits);
|
int palette_code_bits);
|
||||||
|
|
||||||
// Return the size of the histogram for a given palette_code_bits.
|
// Return the size of the histogram for a given cache_bits.
|
||||||
int VP8LGetHistogramSize(int palette_code_bits);
|
int VP8LGetHistogramSize(int cache_bits);
|
||||||
|
|
||||||
// Set the palette_code_bits and reset the stats.
|
// Set the palette_code_bits and reset the stats.
|
||||||
// If init_arrays is true, the arrays are also filled with 0's.
|
// If init_arrays is true, the arrays are also filled with 0's.
|
||||||
@ -110,7 +110,7 @@ int VP8LGetHistoImageSymbols(int xsize, int ysize,
|
|||||||
const VP8LBackwardRefs* const refs,
|
const VP8LBackwardRefs* const refs,
|
||||||
int quality, int low_effort,
|
int quality, int low_effort,
|
||||||
int histogram_bits, int cache_bits,
|
int histogram_bits, int cache_bits,
|
||||||
VP8LHistogramSet* const image_in,
|
VP8LHistogramSet* const image_histo,
|
||||||
VP8LHistogram* const tmp_histo,
|
VP8LHistogram* const tmp_histo,
|
||||||
uint16_t* const histogram_symbols);
|
uint16_t* const histogram_symbols);
|
||||||
|
|
||||||
|
@ -164,22 +164,25 @@ int WebPPictureCrop(WebPPicture* pic,
|
|||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Simple picture rescaler
|
// Simple picture rescaler
|
||||||
|
|
||||||
static void RescalePlane(const uint8_t* src,
|
static int RescalePlane(const uint8_t* src,
|
||||||
int src_width, int src_height, int src_stride,
|
int src_width, int src_height, int src_stride,
|
||||||
uint8_t* dst,
|
uint8_t* dst,
|
||||||
int dst_width, int dst_height, int dst_stride,
|
int dst_width, int dst_height, int dst_stride,
|
||||||
rescaler_t* const work,
|
rescaler_t* const work,
|
||||||
int num_channels) {
|
int num_channels) {
|
||||||
WebPRescaler rescaler;
|
WebPRescaler rescaler;
|
||||||
int y = 0;
|
int y = 0;
|
||||||
WebPRescalerInit(&rescaler, src_width, src_height,
|
if (!WebPRescalerInit(&rescaler, src_width, src_height,
|
||||||
dst, dst_width, dst_height, dst_stride,
|
dst, dst_width, dst_height, dst_stride,
|
||||||
num_channels, work);
|
num_channels, work)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
while (y < src_height) {
|
while (y < src_height) {
|
||||||
y += WebPRescalerImport(&rescaler, src_height - y,
|
y += WebPRescalerImport(&rescaler, src_height - y,
|
||||||
src + y * src_stride, src_stride);
|
src + y * src_stride, src_stride);
|
||||||
WebPRescalerExport(&rescaler);
|
WebPRescalerExport(&rescaler);
|
||||||
}
|
}
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void AlphaMultiplyARGB(WebPPicture* const pic, int inverse) {
|
static void AlphaMultiplyARGB(WebPPicture* const pic, int inverse) {
|
||||||
@ -222,25 +225,28 @@ int WebPPictureRescale(WebPPicture* pic, int width, int height) {
|
|||||||
// If present, we need to rescale alpha first (for AlphaMultiplyY).
|
// If present, we need to rescale alpha first (for AlphaMultiplyY).
|
||||||
if (pic->a != NULL) {
|
if (pic->a != NULL) {
|
||||||
WebPInitAlphaProcessing();
|
WebPInitAlphaProcessing();
|
||||||
RescalePlane(pic->a, prev_width, prev_height, pic->a_stride,
|
if (!RescalePlane(pic->a, prev_width, prev_height, pic->a_stride,
|
||||||
tmp.a, width, height, tmp.a_stride, work, 1);
|
tmp.a, width, height, tmp.a_stride, work, 1)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// We take transparency into account on the luma plane only. That's not
|
// We take transparency into account on the luma plane only. That's not
|
||||||
// totally exact blending, but still is a good approximation.
|
// totally exact blending, but still is a good approximation.
|
||||||
AlphaMultiplyY(pic, 0);
|
AlphaMultiplyY(pic, 0);
|
||||||
RescalePlane(pic->y, prev_width, prev_height, pic->y_stride,
|
if (!RescalePlane(pic->y, prev_width, prev_height, pic->y_stride,
|
||||||
tmp.y, width, height, tmp.y_stride, work, 1);
|
tmp.y, width, height, tmp.y_stride, work, 1) ||
|
||||||
|
!RescalePlane(pic->u,
|
||||||
|
HALVE(prev_width), HALVE(prev_height), pic->uv_stride,
|
||||||
|
tmp.u,
|
||||||
|
HALVE(width), HALVE(height), tmp.uv_stride, work, 1) ||
|
||||||
|
!RescalePlane(pic->v,
|
||||||
|
HALVE(prev_width), HALVE(prev_height), pic->uv_stride,
|
||||||
|
tmp.v,
|
||||||
|
HALVE(width), HALVE(height), tmp.uv_stride, work, 1)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
AlphaMultiplyY(&tmp, 1);
|
AlphaMultiplyY(&tmp, 1);
|
||||||
|
|
||||||
RescalePlane(pic->u,
|
|
||||||
HALVE(prev_width), HALVE(prev_height), pic->uv_stride,
|
|
||||||
tmp.u,
|
|
||||||
HALVE(width), HALVE(height), tmp.uv_stride, work, 1);
|
|
||||||
RescalePlane(pic->v,
|
|
||||||
HALVE(prev_width), HALVE(prev_height), pic->uv_stride,
|
|
||||||
tmp.v,
|
|
||||||
HALVE(width), HALVE(height), tmp.uv_stride, work, 1);
|
|
||||||
} else {
|
} else {
|
||||||
work = (rescaler_t*)WebPSafeMalloc(2ULL * width * 4, sizeof(*work));
|
work = (rescaler_t*)WebPSafeMalloc(2ULL * width * 4, sizeof(*work));
|
||||||
if (work == NULL) {
|
if (work == NULL) {
|
||||||
@ -252,11 +258,12 @@ int WebPPictureRescale(WebPPicture* pic, int width, int height) {
|
|||||||
// the premultiplication afterward (while preserving the alpha channel).
|
// the premultiplication afterward (while preserving the alpha channel).
|
||||||
WebPInitAlphaProcessing();
|
WebPInitAlphaProcessing();
|
||||||
AlphaMultiplyARGB(pic, 0);
|
AlphaMultiplyARGB(pic, 0);
|
||||||
RescalePlane((const uint8_t*)pic->argb, prev_width, prev_height,
|
if (!RescalePlane((const uint8_t*)pic->argb, prev_width, prev_height,
|
||||||
pic->argb_stride * 4,
|
pic->argb_stride * 4,
|
||||||
(uint8_t*)tmp.argb, width, height,
|
(uint8_t*)tmp.argb, width, height,
|
||||||
tmp.argb_stride * 4,
|
tmp.argb_stride * 4, work, 4)) {
|
||||||
work, 4);
|
return 0;
|
||||||
|
}
|
||||||
AlphaMultiplyARGB(&tmp, 1);
|
AlphaMultiplyARGB(&tmp, 1);
|
||||||
}
|
}
|
||||||
WebPPictureFree(pic);
|
WebPPictureFree(pic);
|
||||||
|
@ -249,7 +249,7 @@ static WEBP_INLINE void GetResidual(
|
|||||||
} else if (x == 0) {
|
} else if (x == 0) {
|
||||||
predict = upper_row[x]; // Top.
|
predict = upper_row[x]; // Top.
|
||||||
} else {
|
} else {
|
||||||
predict = pred_func(current_row[x - 1], upper_row + x);
|
predict = pred_func(¤t_row[x - 1], upper_row + x);
|
||||||
}
|
}
|
||||||
#if (WEBP_NEAR_LOSSLESS == 1)
|
#if (WEBP_NEAR_LOSSLESS == 1)
|
||||||
if (max_quantization == 1 || mode == 0 || y == 0 || y == height - 1 ||
|
if (max_quantization == 1 || mode == 0 || y == 0 || y == height - 1 ||
|
||||||
|
@ -585,6 +585,9 @@ static WEBP_INLINE score_t RDScoreTrellis(int lambda, score_t rate,
|
|||||||
return rate * lambda + RD_DISTO_MULT * distortion;
|
return rate * lambda + RD_DISTO_MULT * distortion;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Coefficient type.
|
||||||
|
enum { TYPE_I16_AC = 0, TYPE_I16_DC = 1, TYPE_CHROMA_A = 2, TYPE_I4_AC = 3 };
|
||||||
|
|
||||||
static int TrellisQuantizeBlock(const VP8Encoder* const enc,
|
static int TrellisQuantizeBlock(const VP8Encoder* const enc,
|
||||||
int16_t in[16], int16_t out[16],
|
int16_t in[16], int16_t out[16],
|
||||||
int ctx0, int coeff_type,
|
int ctx0, int coeff_type,
|
||||||
@ -593,7 +596,7 @@ static int TrellisQuantizeBlock(const VP8Encoder* const enc,
|
|||||||
const ProbaArray* const probas = enc->proba_.coeffs_[coeff_type];
|
const ProbaArray* const probas = enc->proba_.coeffs_[coeff_type];
|
||||||
CostArrayPtr const costs =
|
CostArrayPtr const costs =
|
||||||
(CostArrayPtr)enc->proba_.remapped_costs_[coeff_type];
|
(CostArrayPtr)enc->proba_.remapped_costs_[coeff_type];
|
||||||
const int first = (coeff_type == 0) ? 1 : 0;
|
const int first = (coeff_type == TYPE_I16_AC) ? 1 : 0;
|
||||||
Node nodes[16][NUM_NODES];
|
Node nodes[16][NUM_NODES];
|
||||||
ScoreState score_states[2][NUM_NODES];
|
ScoreState score_states[2][NUM_NODES];
|
||||||
ScoreState* ss_cur = &SCORE_STATE(0, MIN_DELTA);
|
ScoreState* ss_cur = &SCORE_STATE(0, MIN_DELTA);
|
||||||
@ -657,16 +660,17 @@ static int TrellisQuantizeBlock(const VP8Encoder* const enc,
|
|||||||
// test all alternate level values around level0.
|
// test all alternate level values around level0.
|
||||||
for (m = -MIN_DELTA; m <= MAX_DELTA; ++m) {
|
for (m = -MIN_DELTA; m <= MAX_DELTA; ++m) {
|
||||||
Node* const cur = &NODE(n, m);
|
Node* const cur = &NODE(n, m);
|
||||||
int level = level0 + m;
|
const int level = level0 + m;
|
||||||
const int ctx = (level > 2) ? 2 : level;
|
const int ctx = (level > 2) ? 2 : level;
|
||||||
const int band = VP8EncBands[n + 1];
|
const int band = VP8EncBands[n + 1];
|
||||||
score_t base_score;
|
score_t base_score;
|
||||||
score_t best_cur_score = MAX_COST;
|
score_t best_cur_score;
|
||||||
int best_prev = 0; // default, in case
|
int best_prev;
|
||||||
|
score_t cost, score;
|
||||||
|
|
||||||
ss_cur[m].score = MAX_COST;
|
|
||||||
ss_cur[m].costs = costs[n + 1][ctx];
|
ss_cur[m].costs = costs[n + 1][ctx];
|
||||||
if (level < 0 || level > thresh_level) {
|
if (level < 0 || level > thresh_level) {
|
||||||
|
ss_cur[m].score = MAX_COST;
|
||||||
// Node is dead.
|
// Node is dead.
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -682,18 +686,24 @@ static int TrellisQuantizeBlock(const VP8Encoder* const enc,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Inspect all possible non-dead predecessors. Retain only the best one.
|
// Inspect all possible non-dead predecessors. Retain only the best one.
|
||||||
for (p = -MIN_DELTA; p <= MAX_DELTA; ++p) {
|
// The base_score is added to all scores so it is only added for the final
|
||||||
|
// value after the loop.
|
||||||
|
cost = VP8LevelCost(ss_prev[-MIN_DELTA].costs, level);
|
||||||
|
best_cur_score =
|
||||||
|
ss_prev[-MIN_DELTA].score + RDScoreTrellis(lambda, cost, 0);
|
||||||
|
best_prev = -MIN_DELTA;
|
||||||
|
for (p = -MIN_DELTA + 1; p <= MAX_DELTA; ++p) {
|
||||||
// Dead nodes (with ss_prev[p].score >= MAX_COST) are automatically
|
// Dead nodes (with ss_prev[p].score >= MAX_COST) are automatically
|
||||||
// eliminated since their score can't be better than the current best.
|
// eliminated since their score can't be better than the current best.
|
||||||
const score_t cost = VP8LevelCost(ss_prev[p].costs, level);
|
cost = VP8LevelCost(ss_prev[p].costs, level);
|
||||||
// Examine node assuming it's a non-terminal one.
|
// Examine node assuming it's a non-terminal one.
|
||||||
const score_t score =
|
score = ss_prev[p].score + RDScoreTrellis(lambda, cost, 0);
|
||||||
base_score + ss_prev[p].score + RDScoreTrellis(lambda, cost, 0);
|
|
||||||
if (score < best_cur_score) {
|
if (score < best_cur_score) {
|
||||||
best_cur_score = score;
|
best_cur_score = score;
|
||||||
best_prev = p;
|
best_prev = p;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
best_cur_score += base_score;
|
||||||
// Store best finding in current node.
|
// Store best finding in current node.
|
||||||
cur->sign = sign;
|
cur->sign = sign;
|
||||||
cur->level = level;
|
cur->level = level;
|
||||||
@ -701,11 +711,11 @@ static int TrellisQuantizeBlock(const VP8Encoder* const enc,
|
|||||||
ss_cur[m].score = best_cur_score;
|
ss_cur[m].score = best_cur_score;
|
||||||
|
|
||||||
// Now, record best terminal node (and thus best entry in the graph).
|
// Now, record best terminal node (and thus best entry in the graph).
|
||||||
if (level != 0) {
|
if (level != 0 && best_cur_score < best_score) {
|
||||||
const score_t last_pos_cost =
|
const score_t last_pos_cost =
|
||||||
(n < 15) ? VP8BitCost(0, probas[band][ctx][0]) : 0;
|
(n < 15) ? VP8BitCost(0, probas[band][ctx][0]) : 0;
|
||||||
const score_t last_pos_score = RDScoreTrellis(lambda, last_pos_cost, 0);
|
const score_t last_pos_score = RDScoreTrellis(lambda, last_pos_cost, 0);
|
||||||
const score_t score = best_cur_score + last_pos_score;
|
score = best_cur_score + last_pos_score;
|
||||||
if (score < best_score) {
|
if (score < best_score) {
|
||||||
best_score = score;
|
best_score = score;
|
||||||
best_path[0] = n; // best eob position
|
best_path[0] = n; // best eob position
|
||||||
@ -717,10 +727,16 @@ static int TrellisQuantizeBlock(const VP8Encoder* const enc,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Fresh start
|
// Fresh start
|
||||||
memset(in + first, 0, (16 - first) * sizeof(*in));
|
// Beware! We must preserve in[0]/out[0] value for TYPE_I16_AC case.
|
||||||
memset(out + first, 0, (16 - first) * sizeof(*out));
|
if (coeff_type == TYPE_I16_AC) {
|
||||||
|
memset(in + 1, 0, 15 * sizeof(*in));
|
||||||
|
memset(out + 1, 0, 15 * sizeof(*out));
|
||||||
|
} else {
|
||||||
|
memset(in, 0, 16 * sizeof(*in));
|
||||||
|
memset(out, 0, 16 * sizeof(*out));
|
||||||
|
}
|
||||||
if (best_path[0] == -1) {
|
if (best_path[0] == -1) {
|
||||||
return 0; // skip!
|
return 0; // skip!
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -775,9 +791,9 @@ static int ReconstructIntra16(VP8EncIterator* const it,
|
|||||||
for (y = 0, n = 0; y < 4; ++y) {
|
for (y = 0, n = 0; y < 4; ++y) {
|
||||||
for (x = 0; x < 4; ++x, ++n) {
|
for (x = 0; x < 4; ++x, ++n) {
|
||||||
const int ctx = it->top_nz_[x] + it->left_nz_[y];
|
const int ctx = it->top_nz_[x] + it->left_nz_[y];
|
||||||
const int non_zero =
|
const int non_zero = TrellisQuantizeBlock(
|
||||||
TrellisQuantizeBlock(enc, tmp[n], rd->y_ac_levels[n], ctx, 0,
|
enc, tmp[n], rd->y_ac_levels[n], ctx, TYPE_I16_AC, &dqm->y1_,
|
||||||
&dqm->y1_, dqm->lambda_trellis_i16_);
|
dqm->lambda_trellis_i16_);
|
||||||
it->top_nz_[x] = it->left_nz_[y] = non_zero;
|
it->top_nz_[x] = it->left_nz_[y] = non_zero;
|
||||||
rd->y_ac_levels[n][0] = 0;
|
rd->y_ac_levels[n][0] = 0;
|
||||||
nz |= non_zero << n;
|
nz |= non_zero << n;
|
||||||
@ -818,7 +834,7 @@ static int ReconstructIntra4(VP8EncIterator* const it,
|
|||||||
if (DO_TRELLIS_I4 && it->do_trellis_) {
|
if (DO_TRELLIS_I4 && it->do_trellis_) {
|
||||||
const int x = it->i4_ & 3, y = it->i4_ >> 2;
|
const int x = it->i4_ & 3, y = it->i4_ >> 2;
|
||||||
const int ctx = it->top_nz_[x] + it->left_nz_[y];
|
const int ctx = it->top_nz_[x] + it->left_nz_[y];
|
||||||
nz = TrellisQuantizeBlock(enc, tmp, levels, ctx, 3, &dqm->y1_,
|
nz = TrellisQuantizeBlock(enc, tmp, levels, ctx, TYPE_I4_AC, &dqm->y1_,
|
||||||
dqm->lambda_trellis_i4_);
|
dqm->lambda_trellis_i4_);
|
||||||
} else {
|
} else {
|
||||||
nz = VP8EncQuantizeBlock(tmp, levels, &dqm->y1_);
|
nz = VP8EncQuantizeBlock(tmp, levels, &dqm->y1_);
|
||||||
@ -927,9 +943,9 @@ static int ReconstructUV(VP8EncIterator* const it, VP8ModeScore* const rd,
|
|||||||
for (y = 0; y < 2; ++y) {
|
for (y = 0; y < 2; ++y) {
|
||||||
for (x = 0; x < 2; ++x, ++n) {
|
for (x = 0; x < 2; ++x, ++n) {
|
||||||
const int ctx = it->top_nz_[4 + ch + x] + it->left_nz_[4 + ch + y];
|
const int ctx = it->top_nz_[4 + ch + x] + it->left_nz_[4 + ch + y];
|
||||||
const int non_zero =
|
const int non_zero = TrellisQuantizeBlock(
|
||||||
TrellisQuantizeBlock(enc, tmp[n], rd->uv_levels[n], ctx, 2,
|
enc, tmp[n], rd->uv_levels[n], ctx, TYPE_CHROMA_A, &dqm->uv_,
|
||||||
&dqm->uv_, dqm->lambda_trellis_uv_);
|
dqm->lambda_trellis_uv_);
|
||||||
it->top_nz_[4 + ch + x] = it->left_nz_[4 + ch + y] = non_zero;
|
it->top_nz_[4 + ch + x] = it->left_nz_[4 + ch + y] = non_zero;
|
||||||
nz |= non_zero << n;
|
nz |= non_zero << n;
|
||||||
}
|
}
|
||||||
|
@ -349,7 +349,7 @@ int VP8EncWrite(VP8Encoder* const enc) {
|
|||||||
(enc->alpha_data_size_ & 1);
|
(enc->alpha_data_size_ & 1);
|
||||||
riff_size += CHUNK_HEADER_SIZE + padded_alpha_size;
|
riff_size += CHUNK_HEADER_SIZE + padded_alpha_size;
|
||||||
}
|
}
|
||||||
// Sanity check.
|
// RIFF size should fit in 32-bits.
|
||||||
if (riff_size > 0xfffffffeU) {
|
if (riff_size > 0xfffffffeU) {
|
||||||
return WebPEncodingSetError(pic, VP8_ENC_ERROR_FILE_TOO_BIG);
|
return WebPEncodingSetError(pic, VP8_ENC_ERROR_FILE_TOO_BIG);
|
||||||
}
|
}
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user