Compare commits
	
		
			31 Commits
		
	
	
		
			aff239377d
			...
			preview
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 0b46b891c2 | |||
| d131b5a02f | |||
| 9d9a486537 | |||
| 610ed10011 | |||
| 4edab11616 | |||
| 6df0417667 | |||
| 4d48f9d237 | |||
| bd9bbf67d4 | |||
| 8cab1307ab | |||
| 5bfc429450 | |||
| 7a7b55bebf | |||
| b4eda033c6 | |||
| c9672bf352 | |||
| 5547ff6d2b | |||
| ea8cc85c61 | |||
| 5ecec26731 | |||
| 01fddd19cd | |||
| e362af8271 | |||
| 2dba4f8fbb | |||
| bdfe44399a | |||
| 67653bbe50 | |||
| a144459e8d | |||
| d725ed8cd0 | |||
| 87d7eb69af | |||
| 3cd551098b | |||
| 95b77cb696 | |||
| 2e28ad7bb9 | |||
| 75f78f8c7f | |||
| ef59386e5c | |||
| c0b57c30bd | |||
| 42b3866753 | 
							
								
								
									
										3
									
								
								external/CMakeLists.txt
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								external/CMakeLists.txt
									
									
									
									
										vendored
									
									
								
							| @@ -15,3 +15,6 @@ add_subdirectory(./solanaceae_tox) | |||||||
| add_subdirectory(./sdl) | add_subdirectory(./sdl) | ||||||
| add_subdirectory(./imgui) | add_subdirectory(./imgui) | ||||||
|  |  | ||||||
|  | add_subdirectory(./stb) | ||||||
|  | add_subdirectory(./libwebp) | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										6
									
								
								external/libwebp/CMakeLists.txt
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								external/libwebp/CMakeLists.txt
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,6 @@ | |||||||
|  | cmake_minimum_required(VERSION 3.9 FATAL_ERROR) | ||||||
|  |  | ||||||
|  | set(WEBP_LINK_STATIC ON CACHE INTERNAL "") | ||||||
|  |  | ||||||
|  | add_subdirectory(./libwebp EXCLUDE_FROM_ALL) | ||||||
|  |  | ||||||
							
								
								
									
										240
									
								
								external/libwebp/libwebp/.cmake-format.py
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										240
									
								
								external/libwebp/libwebp/.cmake-format.py
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,240 @@ | |||||||
|  | # ---------------------------------- | ||||||
|  | # Options affecting listfile parsing | ||||||
|  | # ---------------------------------- | ||||||
|  | with section("parse"): | ||||||
|  |  | ||||||
|  |   # Specify structure for custom cmake functions | ||||||
|  |   additional_commands = { 'foo': { 'flags': ['BAR', 'BAZ'], | ||||||
|  |              'kwargs': {'DEPENDS': '*', 'HEADERS': '*', 'SOURCES': '*'}}} | ||||||
|  |  | ||||||
|  |   # Override configurations per-command where available | ||||||
|  |   override_spec = {} | ||||||
|  |  | ||||||
|  |   # Specify variable tags. | ||||||
|  |   vartags = [] | ||||||
|  |  | ||||||
|  |   # Specify property tags. | ||||||
|  |   proptags = [] | ||||||
|  |  | ||||||
|  | # ----------------------------- | ||||||
|  | # Options affecting formatting. | ||||||
|  | # ----------------------------- | ||||||
|  | with section("format"): | ||||||
|  |  | ||||||
|  |   # Disable formatting entirely, making cmake-format a no-op | ||||||
|  |   disable = False | ||||||
|  |  | ||||||
|  |   # How wide to allow formatted cmake files | ||||||
|  |   line_width = 80 | ||||||
|  |  | ||||||
|  |   # How many spaces to tab for indent | ||||||
|  |   tab_size = 2 | ||||||
|  |  | ||||||
|  |   # If true, lines are indented using tab characters (utf-8 0x09) instead of | ||||||
|  |   # <tab_size> space characters (utf-8 0x20). In cases where the layout would | ||||||
|  |   # require a fractional tab character, the behavior of the  fractional | ||||||
|  |   # indentation is governed by <fractional_tab_policy> | ||||||
|  |   use_tabchars = False | ||||||
|  |  | ||||||
|  |   # If <use_tabchars> is True, then the value of this variable indicates how | ||||||
|  |   # fractional indentions are handled during whitespace replacement. If set to | ||||||
|  |   # 'use-space', fractional indentation is left as spaces (utf-8 0x20). If set | ||||||
|  |   # to `round-up` fractional indentation is replaced with a single tab character | ||||||
|  |   # (utf-8 0x09) effectively shifting the column to the next tabstop | ||||||
|  |   fractional_tab_policy = 'use-space' | ||||||
|  |  | ||||||
|  |   # If an argument group contains more than this many sub-groups (parg or kwarg | ||||||
|  |   # groups) then force it to a vertical layout. | ||||||
|  |   max_subgroups_hwrap = 3 | ||||||
|  |  | ||||||
|  |   # If a positional argument group contains more than this many arguments, then | ||||||
|  |   # force it to a vertical layout. | ||||||
|  |   max_pargs_hwrap = 6 | ||||||
|  |  | ||||||
|  |   # If a cmdline positional group consumes more than this many lines without | ||||||
|  |   # nesting, then invalidate the layout (and nest) | ||||||
|  |   max_rows_cmdline = 2 | ||||||
|  |  | ||||||
|  |   # If true, separate flow control names from their parentheses with a space | ||||||
|  |   separate_ctrl_name_with_space = False | ||||||
|  |  | ||||||
|  |   # If true, separate function names from parentheses with a space | ||||||
|  |   separate_fn_name_with_space = False | ||||||
|  |  | ||||||
|  |   # If a statement is wrapped to more than one line, than dangle the closing | ||||||
|  |   # parenthesis on its own line. | ||||||
|  |   dangle_parens = False | ||||||
|  |  | ||||||
|  |   # If the trailing parenthesis must be 'dangled' on its on line, then align it | ||||||
|  |   # to this reference: `prefix`: the start of the statement,  `prefix-indent`: | ||||||
|  |   # the start of the statement, plus one indentation  level, `child`: align to | ||||||
|  |   # the column of the arguments | ||||||
|  |   dangle_align = 'prefix' | ||||||
|  |  | ||||||
|  |   # If the statement spelling length (including space and parenthesis) is | ||||||
|  |   # smaller than this amount, then force reject nested layouts. | ||||||
|  |   min_prefix_chars = 4 | ||||||
|  |  | ||||||
|  |   # If the statement spelling length (including space and parenthesis) is larger | ||||||
|  |   # than the tab width by more than this amount, then force reject un-nested | ||||||
|  |   # layouts. | ||||||
|  |   max_prefix_chars = 10 | ||||||
|  |  | ||||||
|  |   # If a candidate layout is wrapped horizontally but it exceeds this many | ||||||
|  |   # lines, then reject the layout. | ||||||
|  |   max_lines_hwrap = 2 | ||||||
|  |  | ||||||
|  |   # What style line endings to use in the output. | ||||||
|  |   line_ending = 'unix' | ||||||
|  |  | ||||||
|  |   # Format command names consistently as 'lower' or 'upper' case | ||||||
|  |   command_case = 'canonical' | ||||||
|  |  | ||||||
|  |   # Format keywords consistently as 'lower' or 'upper' case | ||||||
|  |   keyword_case = 'unchanged' | ||||||
|  |  | ||||||
|  |   # A list of command names which should always be wrapped | ||||||
|  |   always_wrap = [] | ||||||
|  |  | ||||||
|  |   # If true, the argument lists which are known to be sortable will be sorted | ||||||
|  |   # lexicographicall | ||||||
|  |   enable_sort = True | ||||||
|  |  | ||||||
|  |   # If true, the parsers may infer whether or not an argument list is sortable | ||||||
|  |   # (without annotation). | ||||||
|  |   autosort = False | ||||||
|  |  | ||||||
|  |   # By default, if cmake-format cannot successfully fit everything into the | ||||||
|  |   # desired linewidth it will apply the last, most agressive attempt that it | ||||||
|  |   # made. If this flag is True, however, cmake-format will print error, exit | ||||||
|  |   # with non-zero status code, and write-out nothing | ||||||
|  |   require_valid_layout = False | ||||||
|  |  | ||||||
|  |   # A dictionary mapping layout nodes to a list of wrap decisions. See the | ||||||
|  |   # documentation for more information. | ||||||
|  |   layout_passes = {} | ||||||
|  |  | ||||||
|  | # ------------------------------------------------ | ||||||
|  | # Options affecting comment reflow and formatting. | ||||||
|  | # ------------------------------------------------ | ||||||
|  | with section("markup"): | ||||||
|  |  | ||||||
|  |   # What character to use for bulleted lists | ||||||
|  |   bullet_char = '*' | ||||||
|  |  | ||||||
|  |   # What character to use as punctuation after numerals in an enumerated list | ||||||
|  |   enum_char = '.' | ||||||
|  |  | ||||||
|  |   # If comment markup is enabled, don't reflow the first comment block in each | ||||||
|  |   # listfile. Use this to preserve formatting of your copyright/license | ||||||
|  |   # statements. | ||||||
|  |   first_comment_is_literal = True | ||||||
|  |  | ||||||
|  |   # If comment markup is enabled, don't reflow any comment block which matches | ||||||
|  |   # this (regex) pattern. Default is `None` (disabled). | ||||||
|  |   literal_comment_pattern = None | ||||||
|  |  | ||||||
|  |   # Regular expression to match preformat fences in comments default= | ||||||
|  |   # ``r'^\s*([`~]{3}[`~]*)(.*)$'`` | ||||||
|  |   fence_pattern = '^\\s*([`~]{3}[`~]*)(.*)$' | ||||||
|  |  | ||||||
|  |   # Regular expression to match rulers in comments default= | ||||||
|  |   # ``r'^\s*[^\w\s]{3}.*[^\w\s]{3}$'`` | ||||||
|  |   ruler_pattern = '^\\s*[^\\w\\s]{3}.*[^\\w\\s]{3}$' | ||||||
|  |  | ||||||
|  |   # If a comment line matches starts with this pattern then it is explicitly a | ||||||
|  |   # trailing comment for the preceeding argument. Default is '#<' | ||||||
|  |   explicit_trailing_pattern = '#<' | ||||||
|  |  | ||||||
|  |   # If a comment line starts with at least this many consecutive hash | ||||||
|  |   # characters, then don't lstrip() them off. This allows for lazy hash rulers | ||||||
|  |   # where the first hash char is not separated by space | ||||||
|  |   hashruler_min_length = 10 | ||||||
|  |  | ||||||
|  |   # If true, then insert a space between the first hash char and remaining hash | ||||||
|  |   # chars in a hash ruler, and normalize its length to fill the column | ||||||
|  |   canonicalize_hashrulers = True | ||||||
|  |  | ||||||
|  |   # enable comment markup parsing and reflow | ||||||
|  |   enable_markup = True | ||||||
|  |  | ||||||
|  | # ---------------------------- | ||||||
|  | # Options affecting the linter | ||||||
|  | # ---------------------------- | ||||||
|  | with section("lint"): | ||||||
|  |  | ||||||
|  |   # a list of lint codes to disable | ||||||
|  |   disabled_codes = [] | ||||||
|  |  | ||||||
|  |   # regular expression pattern describing valid function names | ||||||
|  |   function_pattern = '[0-9a-z_]+' | ||||||
|  |  | ||||||
|  |   # regular expression pattern describing valid macro names | ||||||
|  |   macro_pattern = '[0-9A-Z_]+' | ||||||
|  |  | ||||||
|  |   # regular expression pattern describing valid names for variables with global | ||||||
|  |   # (cache) scope | ||||||
|  |   global_var_pattern = '[A-Z][0-9A-Z_]+' | ||||||
|  |  | ||||||
|  |   # regular expression pattern describing valid names for variables with global | ||||||
|  |   # scope (but internal semantic) | ||||||
|  |   internal_var_pattern = '_[A-Z][0-9A-Z_]+' | ||||||
|  |  | ||||||
|  |   # regular expression pattern describing valid names for variables with local | ||||||
|  |   # scope | ||||||
|  |   local_var_pattern = '[a-z][a-z0-9_]+' | ||||||
|  |  | ||||||
|  |   # regular expression pattern describing valid names for privatedirectory | ||||||
|  |   # variables | ||||||
|  |   private_var_pattern = '_[0-9a-z_]+' | ||||||
|  |  | ||||||
|  |   # regular expression pattern describing valid names for public directory | ||||||
|  |   # variables | ||||||
|  |   public_var_pattern = '[A-Z][0-9A-Z_]+' | ||||||
|  |  | ||||||
|  |   # regular expression pattern describing valid names for function/macro | ||||||
|  |   # arguments and loop variables. | ||||||
|  |   argument_var_pattern = '[a-z][a-z0-9_]+' | ||||||
|  |  | ||||||
|  |   # regular expression pattern describing valid names for keywords used in | ||||||
|  |   # functions or macros | ||||||
|  |   keyword_pattern = '[A-Z][0-9A-Z_]+' | ||||||
|  |  | ||||||
|  |   # In the heuristic for C0201, how many conditionals to match within a loop in | ||||||
|  |   # before considering the loop a parser. | ||||||
|  |   max_conditionals_custom_parser = 2 | ||||||
|  |  | ||||||
|  |   # Require at least this many newlines between statements | ||||||
|  |   min_statement_spacing = 1 | ||||||
|  |  | ||||||
|  |   # Require no more than this many newlines between statements | ||||||
|  |   max_statement_spacing = 2 | ||||||
|  |   max_returns = 6 | ||||||
|  |   max_branches = 12 | ||||||
|  |   max_arguments = 5 | ||||||
|  |   max_localvars = 15 | ||||||
|  |   max_statements = 50 | ||||||
|  |  | ||||||
|  | # ------------------------------- | ||||||
|  | # Options affecting file encoding | ||||||
|  | # ------------------------------- | ||||||
|  | with section("encode"): | ||||||
|  |  | ||||||
|  |   # If true, emit the unicode byte-order mark (BOM) at the start of the file | ||||||
|  |   emit_byteorder_mark = False | ||||||
|  |  | ||||||
|  |   # Specify the encoding of the input file. Defaults to utf-8 | ||||||
|  |   input_encoding = 'utf-8' | ||||||
|  |  | ||||||
|  |   # Specify the encoding of the output file. Defaults to utf-8. Note that cmake | ||||||
|  |   # only claims to support utf-8 so be careful when using anything else | ||||||
|  |   output_encoding = 'utf-8' | ||||||
|  |  | ||||||
|  | # ------------------------------------- | ||||||
|  | # Miscellaneous configurations options. | ||||||
|  | # ------------------------------------- | ||||||
|  | with section("misc"): | ||||||
|  |  | ||||||
|  |   # A dictionary containing any per-command configuration overrides. Currently | ||||||
|  |   # only `command_case` is supported. | ||||||
|  |   per_command = {} | ||||||
							
								
								
									
										6
									
								
								external/libwebp/libwebp/.gitattributes
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								external/libwebp/libwebp/.gitattributes
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,6 @@ | |||||||
|  | .gitattributes export-ignore | ||||||
|  | .gitignore export-ignore | ||||||
|  | .mailmap export-ignore | ||||||
|  | *.bat text eol=crlf | ||||||
|  | *.pdf -text -diff | ||||||
|  | *.ppm -text -diff | ||||||
							
								
								
									
										56
									
								
								external/libwebp/libwebp/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								external/libwebp/libwebp/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,56 @@ | |||||||
|  | *.l[ao] | ||||||
|  | *.[ao] | ||||||
|  | *.pc | ||||||
|  | .DS_Store | ||||||
|  | .deps | ||||||
|  | .idea | ||||||
|  | .libs | ||||||
|  | .vscode | ||||||
|  | /aclocal.m4 | ||||||
|  | /ar-lib | ||||||
|  | /autom4te.cache | ||||||
|  | /compile | ||||||
|  | /config.* | ||||||
|  | /configure | ||||||
|  | /depcomp | ||||||
|  | /dist | ||||||
|  | /install-sh | ||||||
|  | /libtool | ||||||
|  | /ltmain.sh | ||||||
|  | /missing | ||||||
|  | /mkinstalldirs | ||||||
|  | /stamp-h1 | ||||||
|  | Makefile | ||||||
|  | Makefile.in | ||||||
|  | examples/anim_diff | ||||||
|  | examples/anim_dump | ||||||
|  | examples/[cdv]webp | ||||||
|  | examples/gif2webp | ||||||
|  | examples/img2webp | ||||||
|  | examples/webpinfo | ||||||
|  | examples/webpmux | ||||||
|  | src/webp/config.h* | ||||||
|  | src/webp/stamp-h1 | ||||||
|  | /output | ||||||
|  | /doc/output | ||||||
|  | *.idb | ||||||
|  | *.pdb | ||||||
|  | /iosbuild | ||||||
|  | /xcframeworkbuild | ||||||
|  | /WebP*.*framework | ||||||
|  | CMakeCache.txt | ||||||
|  | CMakeFiles/ | ||||||
|  | cmake_install.cmake | ||||||
|  | .gradle | ||||||
|  | /build | ||||||
|  | extras/get_disto | ||||||
|  | extras/vwebp_sdl | ||||||
|  | extras/webp_quality | ||||||
|  | tests/fuzzer/advanced_api_fuzzer | ||||||
|  | tests/fuzzer/animation_api_fuzzer | ||||||
|  | tests/fuzzer/animdecoder_fuzzer | ||||||
|  | tests/fuzzer/animencoder_fuzzer | ||||||
|  | tests/fuzzer/demux_api_fuzzer | ||||||
|  | tests/fuzzer/enc_dec_fuzzer | ||||||
|  | tests/fuzzer/mux_demux_api_fuzzer | ||||||
|  | tests/fuzzer/simple_api_fuzzer | ||||||
							
								
								
									
										19
									
								
								external/libwebp/libwebp/.mailmap
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								external/libwebp/libwebp/.mailmap
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,19 @@ | |||||||
|  | Johann Koenig <johann.koenig@duck.com> | ||||||
|  | Johann Koenig <johann.koenig@duck.com> <johannkoenig@google.com> | ||||||
|  | Mikołaj Zalewski <mikolajz@google.com> | ||||||
|  | Pascal Massimino <pascal.massimino@gmail.com> | ||||||
|  | Pascal Massimino <pascal.massimino@gmail.com> <skal@google.com> | ||||||
|  | Vikas Arora <vikasa@google.com> | ||||||
|  | <vikasa@google.com> <vikasa@gmail.com> | ||||||
|  | <vikasa@google.com> <vikaas.arora@gmail.com> | ||||||
|  | <slobodan.prijic@imgtec.com> <Slobodan.Prijic@imgtec.com> | ||||||
|  | <vrabaud@google.com> <vincent.rabaud@gmail.com> | ||||||
|  | Vincent Rabaud <vrabaud@google.com> | ||||||
|  | Tamar Levy <tamar.levy@intel.com> | ||||||
|  | <qrczak@google.com> <qrczak> | ||||||
|  | Hui Su <huisu@google.com> | ||||||
|  | James Zern <jzern@google.com> | ||||||
|  | Roberto Alanis <alanisbaez@google.com> | ||||||
|  | Brian Ledger <brianpl@google.com> | ||||||
|  | Maryla Ustarroz-Calonge <maryla@google.com> | ||||||
|  | Yannis Guyon <yguyon@google.com> | ||||||
							
								
								
									
										441
									
								
								external/libwebp/libwebp/.pylintrc
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										441
									
								
								external/libwebp/libwebp/.pylintrc
									
									
									
									
										vendored
									
									
										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
									
								
								external/libwebp/libwebp/.style.yapf
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								external/libwebp/libwebp/.style.yapf
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,2 @@ | |||||||
|  | [style] | ||||||
|  | based_on_style = yapf | ||||||
							
								
								
									
										60
									
								
								external/libwebp/libwebp/AUTHORS
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								external/libwebp/libwebp/AUTHORS
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,60 @@ | |||||||
|  | Contributors: | ||||||
|  | - Aidan O'Loan (aidanol at gmail dot com) | ||||||
|  | - Alan Browning (browning at google dot com) | ||||||
|  | - Alexandru Ardelean (ardeleanalex at gmail dot com) | ||||||
|  | - Brian Ledger (brianpl at google dot com) | ||||||
|  | - Charles Munger (clm at google dot com) | ||||||
|  | - Cheng Yi (cyi 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) | ||||||
|  | - Frank Barchard (fbarchard at google dot com) | ||||||
|  | - Hui Su (huisu at google dot com) | ||||||
|  | - H. Vetinari (h dot vetinari at gmx dot com) | ||||||
|  | - Ilya Kurdyukov (jpegqs at gmail dot com) | ||||||
|  | - Ingvar Stepanyan (rreverser at google dot com) | ||||||
|  | - James Zern (jzern at google dot com) | ||||||
|  | - Jan Engelhardt (jengelh at medozas dot de) | ||||||
|  | - Jehan (jehan at girinstud dot io) | ||||||
|  | - Jeremy Maitin-Shepard (jbms at google dot com) | ||||||
|  | - Johann Koenig (johann dot koenig at duck dot com) | ||||||
|  | - Jovan Zelincevic (jovan dot zelincevic at imgtec dot com) | ||||||
|  | - Jyrki Alakuijala (jyrki at google dot com) | ||||||
|  | - Konstantin Ivlev (tomskside at gmail dot com) | ||||||
|  | - Lode Vandevenne (lode at google dot com) | ||||||
|  | - Lou Quillio (louquillio at google dot com) | ||||||
|  | - Mans Rullgard (mans at mansr dot com) | ||||||
|  | - Marcin Kowalczyk (qrczak at google dot com) | ||||||
|  | - Martin Olsson (mnemo at minimum dot se) | ||||||
|  | - Maryla Ustarroz-Calonge (maryla at google dot com) | ||||||
|  | - Mikołaj Zalewski (mikolajz at google dot com) | ||||||
|  | - Mislav Bradac (mislavm at google dot com) | ||||||
|  | - Nico Weber (thakis at chromium dot org) | ||||||
|  | - Noel Chromium (noel at chromium dot org) | ||||||
|  | - Nozomi Isozaki (nontan at pixiv dot co dot jp) | ||||||
|  | - Oliver Wolff (oliver dot wolff at qt dot io) | ||||||
|  | - Owen Rodley (orodley at google dot com) | ||||||
|  | - Parag Salasakar (img dot mips1 at gmail dot com) | ||||||
|  | - Pascal Massimino (pascal dot massimino at gmail dot com) | ||||||
|  | - Paweł Hajdan, Jr (phajdan dot jr at chromium dot org) | ||||||
|  | - Pierre Joye (pierre dot php at gmail dot com) | ||||||
|  | - Roberto Alanis (alanisbaez at google dot com) | ||||||
|  | - Sam Clegg (sbc at chromium dot org) | ||||||
|  | - Scott Hancher (seh at google dot com) | ||||||
|  | - Scott LaVarnway (slavarnway at google dot com) | ||||||
|  | - Scott Talbot (s at chikachow dot org) | ||||||
|  | - Slobodan Prijic (slobodan dot prijic at imgtec dot com) | ||||||
|  | - Somnath Banerjee (somnath dot banerjee at gmail dot com) | ||||||
|  | - Sriraman Tallam (tmsriram at google dot com) | ||||||
|  | - Tamar Levy (tamar dot levy at intel dot com) | ||||||
|  | - Thiago Perrotta (tperrotta at google dot com) | ||||||
|  | - Timothy Gu (timothygu99 at gmail dot com) | ||||||
|  | - Urvang Joshi (urvang at google dot com) | ||||||
|  | - Vikas Arora (vikasa at google dot com) | ||||||
|  | - Vincent Rabaud (vrabaud at google dot com) | ||||||
|  | - Vlad Tsyrklevich (vtsyrklevich at chromium dot org) | ||||||
|  | - Wan-Teh Chang (wtc at google dot com) | ||||||
|  | - Yang Zhang (yang dot zhang at arm dot com) | ||||||
|  | - Yannis Guyon (yguyon at google dot com) | ||||||
|  | - Zhi An Ng (zhin at chromium dot org) | ||||||
							
								
								
									
										295
									
								
								external/libwebp/libwebp/Android.mk
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										295
									
								
								external/libwebp/libwebp/Android.mk
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,295 @@ | |||||||
|  | # Ignore this file during non-NDK builds. | ||||||
|  | ifdef NDK_ROOT | ||||||
|  | LOCAL_PATH := $(call my-dir) | ||||||
|  |  | ||||||
|  | WEBP_CFLAGS := -Wall -DANDROID -DHAVE_MALLOC_H -DHAVE_PTHREAD -DWEBP_USE_THREAD | ||||||
|  | WEBP_CFLAGS += -fvisibility=hidden | ||||||
|  |  | ||||||
|  | ifeq ($(APP_OPTIM),release) | ||||||
|  |   WEBP_CFLAGS += -finline-functions -ffast-math \ | ||||||
|  |                  -ffunction-sections -fdata-sections | ||||||
|  |   ifeq ($(findstring clang,$(NDK_TOOLCHAIN_VERSION)),) | ||||||
|  |     WEBP_CFLAGS += -frename-registers -s | ||||||
|  |   endif | ||||||
|  | endif | ||||||
|  |  | ||||||
|  | # mips32 fails to build with clang from r14b | ||||||
|  | # https://bugs.chromium.org/p/webp/issues/detail?id=343 | ||||||
|  | ifeq ($(findstring clang,$(NDK_TOOLCHAIN_VERSION)),clang) | ||||||
|  |   ifeq ($(TARGET_ARCH),mips) | ||||||
|  |     clang_version := $(shell $(TARGET_CC) --version) | ||||||
|  |     ifneq ($(findstring clang version 3,$(clang_version)),) | ||||||
|  |       WEBP_CFLAGS += -no-integrated-as | ||||||
|  |     endif | ||||||
|  |   endif | ||||||
|  | endif | ||||||
|  |  | ||||||
|  | ifneq ($(findstring armeabi-v7a, $(TARGET_ARCH_ABI)),) | ||||||
|  |   # Setting LOCAL_ARM_NEON will enable -mfpu=neon which may cause illegal | ||||||
|  |   # instructions to be generated for armv7a code. Instead target the neon code | ||||||
|  |   # specifically. | ||||||
|  |   NEON := c.neon | ||||||
|  |   USE_CPUFEATURES := yes | ||||||
|  |   WEBP_CFLAGS += -DHAVE_CPU_FEATURES_H | ||||||
|  | else | ||||||
|  |   NEON := c | ||||||
|  | endif | ||||||
|  |  | ||||||
|  | sharpyuv_srcs := \ | ||||||
|  |     sharpyuv/sharpyuv.c \ | ||||||
|  |     sharpyuv/sharpyuv_cpu.c \ | ||||||
|  |     sharpyuv/sharpyuv_csp.c \ | ||||||
|  |     sharpyuv/sharpyuv_dsp.c \ | ||||||
|  |     sharpyuv/sharpyuv_gamma.c \ | ||||||
|  |     sharpyuv/sharpyuv_neon.$(NEON) \ | ||||||
|  |     sharpyuv/sharpyuv_sse2.c \ | ||||||
|  |  | ||||||
|  | dec_srcs := \ | ||||||
|  |     src/dec/alpha_dec.c \ | ||||||
|  |     src/dec/buffer_dec.c \ | ||||||
|  |     src/dec/frame_dec.c \ | ||||||
|  |     src/dec/idec_dec.c \ | ||||||
|  |     src/dec/io_dec.c \ | ||||||
|  |     src/dec/quant_dec.c \ | ||||||
|  |     src/dec/tree_dec.c \ | ||||||
|  |     src/dec/vp8_dec.c \ | ||||||
|  |     src/dec/vp8l_dec.c \ | ||||||
|  |     src/dec/webp_dec.c \ | ||||||
|  |  | ||||||
|  | demux_srcs := \ | ||||||
|  |     src/demux/anim_decode.c \ | ||||||
|  |     src/demux/demux.c \ | ||||||
|  |  | ||||||
|  | dsp_dec_srcs := \ | ||||||
|  |     src/dsp/alpha_processing.c \ | ||||||
|  |     src/dsp/alpha_processing_mips_dsp_r2.c \ | ||||||
|  |     src/dsp/alpha_processing_neon.$(NEON) \ | ||||||
|  |     src/dsp/alpha_processing_sse2.c \ | ||||||
|  |     src/dsp/alpha_processing_sse41.c \ | ||||||
|  |     src/dsp/cpu.c \ | ||||||
|  |     src/dsp/dec.c \ | ||||||
|  |     src/dsp/dec_clip_tables.c \ | ||||||
|  |     src/dsp/dec_mips32.c \ | ||||||
|  |     src/dsp/dec_mips_dsp_r2.c \ | ||||||
|  |     src/dsp/dec_msa.c \ | ||||||
|  |     src/dsp/dec_neon.$(NEON) \ | ||||||
|  |     src/dsp/dec_sse2.c \ | ||||||
|  |     src/dsp/dec_sse41.c \ | ||||||
|  |     src/dsp/filters.c \ | ||||||
|  |     src/dsp/filters_mips_dsp_r2.c \ | ||||||
|  |     src/dsp/filters_msa.c \ | ||||||
|  |     src/dsp/filters_neon.$(NEON) \ | ||||||
|  |     src/dsp/filters_sse2.c \ | ||||||
|  |     src/dsp/lossless.c \ | ||||||
|  |     src/dsp/lossless_mips_dsp_r2.c \ | ||||||
|  |     src/dsp/lossless_msa.c \ | ||||||
|  |     src/dsp/lossless_neon.$(NEON) \ | ||||||
|  |     src/dsp/lossless_sse2.c \ | ||||||
|  |     src/dsp/lossless_sse41.c \ | ||||||
|  |     src/dsp/rescaler.c \ | ||||||
|  |     src/dsp/rescaler_mips32.c \ | ||||||
|  |     src/dsp/rescaler_mips_dsp_r2.c \ | ||||||
|  |     src/dsp/rescaler_msa.c \ | ||||||
|  |     src/dsp/rescaler_neon.$(NEON) \ | ||||||
|  |     src/dsp/rescaler_sse2.c \ | ||||||
|  |     src/dsp/upsampling.c \ | ||||||
|  |     src/dsp/upsampling_mips_dsp_r2.c \ | ||||||
|  |     src/dsp/upsampling_msa.c \ | ||||||
|  |     src/dsp/upsampling_neon.$(NEON) \ | ||||||
|  |     src/dsp/upsampling_sse2.c \ | ||||||
|  |     src/dsp/upsampling_sse41.c \ | ||||||
|  |     src/dsp/yuv.c \ | ||||||
|  |     src/dsp/yuv_mips32.c \ | ||||||
|  |     src/dsp/yuv_mips_dsp_r2.c \ | ||||||
|  |     src/dsp/yuv_neon.$(NEON) \ | ||||||
|  |     src/dsp/yuv_sse2.c \ | ||||||
|  |     src/dsp/yuv_sse41.c \ | ||||||
|  |  | ||||||
|  | dsp_enc_srcs := \ | ||||||
|  |     src/dsp/cost.c \ | ||||||
|  |     src/dsp/cost_mips32.c \ | ||||||
|  |     src/dsp/cost_mips_dsp_r2.c \ | ||||||
|  |     src/dsp/cost_neon.$(NEON) \ | ||||||
|  |     src/dsp/cost_sse2.c \ | ||||||
|  |     src/dsp/enc.c \ | ||||||
|  |     src/dsp/enc_mips32.c \ | ||||||
|  |     src/dsp/enc_mips_dsp_r2.c \ | ||||||
|  |     src/dsp/enc_msa.c \ | ||||||
|  |     src/dsp/enc_neon.$(NEON) \ | ||||||
|  |     src/dsp/enc_sse2.c \ | ||||||
|  |     src/dsp/enc_sse41.c \ | ||||||
|  |     src/dsp/lossless_enc.c \ | ||||||
|  |     src/dsp/lossless_enc_mips32.c \ | ||||||
|  |     src/dsp/lossless_enc_mips_dsp_r2.c \ | ||||||
|  |     src/dsp/lossless_enc_msa.c \ | ||||||
|  |     src/dsp/lossless_enc_neon.$(NEON) \ | ||||||
|  |     src/dsp/lossless_enc_sse2.c \ | ||||||
|  |     src/dsp/lossless_enc_sse41.c \ | ||||||
|  |     src/dsp/ssim.c \ | ||||||
|  |     src/dsp/ssim_sse2.c \ | ||||||
|  |  | ||||||
|  | enc_srcs := \ | ||||||
|  |     src/enc/alpha_enc.c \ | ||||||
|  |     src/enc/analysis_enc.c \ | ||||||
|  |     src/enc/backward_references_cost_enc.c \ | ||||||
|  |     src/enc/backward_references_enc.c \ | ||||||
|  |     src/enc/config_enc.c \ | ||||||
|  |     src/enc/cost_enc.c \ | ||||||
|  |     src/enc/filter_enc.c \ | ||||||
|  |     src/enc/frame_enc.c \ | ||||||
|  |     src/enc/histogram_enc.c \ | ||||||
|  |     src/enc/iterator_enc.c \ | ||||||
|  |     src/enc/near_lossless_enc.c \ | ||||||
|  |     src/enc/picture_enc.c \ | ||||||
|  |     src/enc/picture_csp_enc.c \ | ||||||
|  |     src/enc/picture_psnr_enc.c \ | ||||||
|  |     src/enc/picture_rescale_enc.c \ | ||||||
|  |     src/enc/picture_tools_enc.c \ | ||||||
|  |     src/enc/predictor_enc.c \ | ||||||
|  |     src/enc/quant_enc.c \ | ||||||
|  |     src/enc/syntax_enc.c \ | ||||||
|  |     src/enc/token_enc.c \ | ||||||
|  |     src/enc/tree_enc.c \ | ||||||
|  |     src/enc/vp8l_enc.c \ | ||||||
|  |     src/enc/webp_enc.c \ | ||||||
|  |  | ||||||
|  | mux_srcs := \ | ||||||
|  |     src/mux/anim_encode.c \ | ||||||
|  |     src/mux/muxedit.c \ | ||||||
|  |     src/mux/muxinternal.c \ | ||||||
|  |     src/mux/muxread.c \ | ||||||
|  |  | ||||||
|  | utils_dec_srcs := \ | ||||||
|  |     src/utils/bit_reader_utils.c \ | ||||||
|  |     src/utils/color_cache_utils.c \ | ||||||
|  |     src/utils/filters_utils.c \ | ||||||
|  |     src/utils/huffman_utils.c \ | ||||||
|  |     src/utils/palette.c \ | ||||||
|  |     src/utils/quant_levels_dec_utils.c \ | ||||||
|  |     src/utils/random_utils.c \ | ||||||
|  |     src/utils/rescaler_utils.c \ | ||||||
|  |     src/utils/thread_utils.c \ | ||||||
|  |     src/utils/utils.c \ | ||||||
|  |  | ||||||
|  | utils_enc_srcs := \ | ||||||
|  |     src/utils/bit_writer_utils.c \ | ||||||
|  |     src/utils/huffman_encode_utils.c \ | ||||||
|  |     src/utils/quant_levels_utils.c \ | ||||||
|  |  | ||||||
|  | ################################################################################ | ||||||
|  | # libwebpdecoder | ||||||
|  |  | ||||||
|  | include $(CLEAR_VARS) | ||||||
|  |  | ||||||
|  | LOCAL_SRC_FILES := \ | ||||||
|  |     $(dec_srcs) \ | ||||||
|  |     $(dsp_dec_srcs) \ | ||||||
|  |     $(utils_dec_srcs) \ | ||||||
|  |  | ||||||
|  | LOCAL_CFLAGS := $(WEBP_CFLAGS) | ||||||
|  | LOCAL_EXPORT_C_INCLUDES += $(LOCAL_PATH)/src | ||||||
|  |  | ||||||
|  | # prefer arm over thumb mode for performance gains | ||||||
|  | LOCAL_ARM_MODE := arm | ||||||
|  |  | ||||||
|  | ifeq ($(USE_CPUFEATURES),yes) | ||||||
|  |   LOCAL_STATIC_LIBRARIES := cpufeatures | ||||||
|  | endif | ||||||
|  |  | ||||||
|  | LOCAL_MODULE := webpdecoder_static | ||||||
|  |  | ||||||
|  | include $(BUILD_STATIC_LIBRARY) | ||||||
|  |  | ||||||
|  | ifeq ($(ENABLE_SHARED),1) | ||||||
|  | include $(CLEAR_VARS) | ||||||
|  |  | ||||||
|  | LOCAL_WHOLE_STATIC_LIBRARIES := webpdecoder_static | ||||||
|  |  | ||||||
|  | LOCAL_MODULE := webpdecoder | ||||||
|  |  | ||||||
|  | include $(BUILD_SHARED_LIBRARY) | ||||||
|  | endif  # ENABLE_SHARED=1 | ||||||
|  |  | ||||||
|  | ################################################################################ | ||||||
|  | # libwebp | ||||||
|  |  | ||||||
|  | include $(CLEAR_VARS) | ||||||
|  |  | ||||||
|  | LOCAL_SRC_FILES := \ | ||||||
|  |     $(sharpyuv_srcs) \ | ||||||
|  |     $(dsp_enc_srcs) \ | ||||||
|  |     $(enc_srcs) \ | ||||||
|  |     $(utils_enc_srcs) \ | ||||||
|  |  | ||||||
|  | LOCAL_CFLAGS := $(WEBP_CFLAGS) | ||||||
|  | LOCAL_EXPORT_C_INCLUDES += $(LOCAL_PATH)/src $(LOCAL_PATH) | ||||||
|  |  | ||||||
|  | # prefer arm over thumb mode for performance gains | ||||||
|  | LOCAL_ARM_MODE := arm | ||||||
|  |  | ||||||
|  | LOCAL_WHOLE_STATIC_LIBRARIES := webpdecoder_static | ||||||
|  |  | ||||||
|  | LOCAL_MODULE := webp | ||||||
|  |  | ||||||
|  | ifeq ($(ENABLE_SHARED),1) | ||||||
|  |   include $(BUILD_SHARED_LIBRARY) | ||||||
|  | else | ||||||
|  |   include $(BUILD_STATIC_LIBRARY) | ||||||
|  | endif | ||||||
|  |  | ||||||
|  | ################################################################################ | ||||||
|  | # libwebpdemux | ||||||
|  |  | ||||||
|  | include $(CLEAR_VARS) | ||||||
|  |  | ||||||
|  | LOCAL_SRC_FILES := $(demux_srcs) | ||||||
|  |  | ||||||
|  | LOCAL_CFLAGS := $(WEBP_CFLAGS) | ||||||
|  | LOCAL_EXPORT_C_INCLUDES += $(LOCAL_PATH)/src | ||||||
|  |  | ||||||
|  | # prefer arm over thumb mode for performance gains | ||||||
|  | LOCAL_ARM_MODE := arm | ||||||
|  |  | ||||||
|  | LOCAL_MODULE := webpdemux | ||||||
|  |  | ||||||
|  | ifeq ($(ENABLE_SHARED),1) | ||||||
|  |   LOCAL_SHARED_LIBRARIES := webp | ||||||
|  |   include $(BUILD_SHARED_LIBRARY) | ||||||
|  | else | ||||||
|  |   LOCAL_STATIC_LIBRARIES := webp | ||||||
|  |   include $(BUILD_STATIC_LIBRARY) | ||||||
|  | endif | ||||||
|  |  | ||||||
|  | ################################################################################ | ||||||
|  | # libwebpmux | ||||||
|  |  | ||||||
|  | include $(CLEAR_VARS) | ||||||
|  |  | ||||||
|  | LOCAL_SRC_FILES := $(mux_srcs) | ||||||
|  |  | ||||||
|  | LOCAL_CFLAGS := $(WEBP_CFLAGS) | ||||||
|  | LOCAL_EXPORT_C_INCLUDES += $(LOCAL_PATH)/src | ||||||
|  |  | ||||||
|  | # prefer arm over thumb mode for performance gains | ||||||
|  | LOCAL_ARM_MODE := arm | ||||||
|  |  | ||||||
|  | LOCAL_MODULE := webpmux | ||||||
|  |  | ||||||
|  | ifeq ($(ENABLE_SHARED),1) | ||||||
|  |   LOCAL_SHARED_LIBRARIES := webp | ||||||
|  |   include $(BUILD_SHARED_LIBRARY) | ||||||
|  | else | ||||||
|  |   LOCAL_STATIC_LIBRARIES := webp | ||||||
|  |   include $(BUILD_STATIC_LIBRARY) | ||||||
|  | endif | ||||||
|  |  | ||||||
|  | ################################################################################ | ||||||
|  |  | ||||||
|  | WEBP_SRC_PATH := $(LOCAL_PATH) | ||||||
|  | include $(WEBP_SRC_PATH)/imageio/Android.mk | ||||||
|  | include $(WEBP_SRC_PATH)/examples/Android.mk | ||||||
|  |  | ||||||
|  | ifeq ($(USE_CPUFEATURES),yes) | ||||||
|  |   $(call import-module,android/cpufeatures) | ||||||
|  | endif | ||||||
|  | endif  # NDK_ROOT | ||||||
							
								
								
									
										802
									
								
								external/libwebp/libwebp/CMakeLists.txt
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										802
									
								
								external/libwebp/libwebp/CMakeLists.txt
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,802 @@ | |||||||
|  | #  Copyright (c) 2020 Google LLC. | ||||||
|  | # | ||||||
|  | #  Use of this source code is governed by a BSD-style license | ||||||
|  | #  that can be found in the LICENSE file in the root of the source | ||||||
|  | #  tree. An additional intellectual property rights grant can be found | ||||||
|  | #  in the file PATENTS.  All contributing project authors may | ||||||
|  | #  be found in the AUTHORS file in the root of the source tree. | ||||||
|  |  | ||||||
|  | if(APPLE) | ||||||
|  |   cmake_minimum_required(VERSION 3.17) | ||||||
|  | else() | ||||||
|  |   cmake_minimum_required(VERSION 3.7) | ||||||
|  | endif() | ||||||
|  |  | ||||||
|  | if(POLICY CMP0072) | ||||||
|  |   cmake_policy(SET CMP0072 NEW) | ||||||
|  | endif() | ||||||
|  |  | ||||||
|  | project(WebP C) | ||||||
|  |  | ||||||
|  | # Options for coder / decoder executables. | ||||||
|  | if(BUILD_SHARED_LIBS) | ||||||
|  |   set(WEBP_LINK_STATIC_DEFAULT OFF) | ||||||
|  | else() | ||||||
|  |   set(WEBP_LINK_STATIC_DEFAULT ON) | ||||||
|  | endif() | ||||||
|  | option(WEBP_LINK_STATIC | ||||||
|  |        "Link using static libraries. If OFF, use dynamic libraries." | ||||||
|  |        ${WEBP_LINK_STATIC_DEFAULT}) | ||||||
|  | if(NOT EMSCRIPTEN) | ||||||
|  |   # Disable SIMD on Emscripten by default, as it's a new unstable Wasm feature. | ||||||
|  |   # Users can still explicitly opt-in to make a SIMD-enabled build. | ||||||
|  |   set(WEBP_ENABLE_SIMD_DEFAULT ON) | ||||||
|  | endif() | ||||||
|  | option(WEBP_ENABLE_SIMD "Enable any SIMD optimization." | ||||||
|  |        ${WEBP_ENABLE_SIMD_DEFAULT}) | ||||||
|  | option(WEBP_BUILD_ANIM_UTILS "Build animation utilities." ON) | ||||||
|  | option(WEBP_BUILD_CWEBP "Build the cwebp command line tool." ON) | ||||||
|  | option(WEBP_BUILD_DWEBP "Build the dwebp command line tool." ON) | ||||||
|  | option(WEBP_BUILD_GIF2WEBP "Build the gif2webp conversion tool." ON) | ||||||
|  | option(WEBP_BUILD_IMG2WEBP "Build the img2webp animation tool." ON) | ||||||
|  | option(WEBP_BUILD_VWEBP "Build the vwebp viewer tool." ON) | ||||||
|  | option(WEBP_BUILD_WEBPINFO "Build the webpinfo command line tool." ON) | ||||||
|  | option(WEBP_BUILD_LIBWEBPMUX "Build the libwebpmux library." ON) | ||||||
|  | option(WEBP_BUILD_WEBPMUX "Build the webpmux command line tool." ON) | ||||||
|  | option(WEBP_BUILD_EXTRAS "Build extras." ON) | ||||||
|  | option(WEBP_BUILD_WEBP_JS "Emscripten build of webp.js." OFF) | ||||||
|  | option(WEBP_USE_THREAD "Enable threading support" ON) | ||||||
|  | option(WEBP_NEAR_LOSSLESS "Enable near-lossless encoding" ON) | ||||||
|  | option(WEBP_ENABLE_SWAP_16BIT_CSP "Enable byte swap for 16 bit colorspaces." | ||||||
|  |        OFF) | ||||||
|  | set(WEBP_BITTRACE "0" CACHE STRING "Bit trace mode (0=none, 1=bit, 2=bytes)") | ||||||
|  | set_property(CACHE WEBP_BITTRACE PROPERTY STRINGS 0 1 2) | ||||||
|  |  | ||||||
|  | if(WEBP_LINK_STATIC) | ||||||
|  |   if(WIN32) | ||||||
|  |     set(CMAKE_FIND_LIBRARY_SUFFIXES .lib .a ${CMAKE_FIND_LIBRARY_SUFFIXES}) | ||||||
|  |   else() | ||||||
|  |     set(CMAKE_FIND_LIBRARY_SUFFIXES .a ${CMAKE_FIND_LIBRARY_SUFFIXES}) | ||||||
|  |   endif() | ||||||
|  |   set(CMAKE_POSITION_INDEPENDENT_CODE ON) | ||||||
|  |   # vwebp does not compile on Ubuntu with static libraries so disabling it for | ||||||
|  |   # now. | ||||||
|  |   set(WEBP_BUILD_VWEBP OFF) | ||||||
|  | endif() | ||||||
|  |  | ||||||
|  | # Option needed for handling Unicode file names on Windows. | ||||||
|  | if(WIN32) | ||||||
|  |   option(WEBP_UNICODE "Build Unicode executables." ON) | ||||||
|  | endif() | ||||||
|  |  | ||||||
|  | if(WEBP_BUILD_WEBP_JS) | ||||||
|  |   set(WEBP_BUILD_ANIM_UTILS OFF) | ||||||
|  |   set(WEBP_BUILD_CWEBP OFF) | ||||||
|  |   set(WEBP_BUILD_DWEBP OFF) | ||||||
|  |   set(WEBP_BUILD_GIF2WEBP OFF) | ||||||
|  |   set(WEBP_BUILD_IMG2WEBP OFF) | ||||||
|  |   set(WEBP_BUILD_VWEBP OFF) | ||||||
|  |   set(WEBP_BUILD_WEBPINFO OFF) | ||||||
|  |   set(WEBP_BUILD_WEBPMUX OFF) | ||||||
|  |   set(WEBP_BUILD_EXTRAS OFF) | ||||||
|  |   set(WEBP_USE_THREAD OFF) | ||||||
|  |  | ||||||
|  |   if(WEBP_ENABLE_SIMD) | ||||||
|  |     message(NOTICE | ||||||
|  |             "wasm2js does not support SIMD, disabling webp.js generation.") | ||||||
|  |   endif() | ||||||
|  | endif() | ||||||
|  |  | ||||||
|  | set(SHARPYUV_DEP_LIBRARIES) | ||||||
|  | set(SHARPYUV_DEP_INCLUDE_DIRS) | ||||||
|  | set(WEBP_DEP_LIBRARIES) | ||||||
|  | set(WEBP_DEP_INCLUDE_DIRS) | ||||||
|  |  | ||||||
|  | if(NOT CMAKE_BUILD_TYPE) | ||||||
|  |   set(CMAKE_BUILD_TYPE "Release" | ||||||
|  |       CACHE STRING "Build type: Release, Debug, MinSizeRel or RelWithDebInfo" | ||||||
|  |             FORCE) | ||||||
|  | endif() | ||||||
|  |  | ||||||
|  | # Include dependencies. | ||||||
|  | if(WEBP_BUILD_ANIM_UTILS | ||||||
|  |    OR WEBP_BUILD_CWEBP | ||||||
|  |    OR WEBP_BUILD_DWEBP | ||||||
|  |    OR WEBP_BUILD_EXTRAS | ||||||
|  |    OR WEBP_BUILD_GIF2WEBP | ||||||
|  |    OR WEBP_BUILD_IMG2WEBP) | ||||||
|  |   set(WEBP_FIND_IMG_LIBS TRUE) | ||||||
|  | else() | ||||||
|  |   set(WEBP_FIND_IMG_LIBS FALSE) | ||||||
|  | endif() | ||||||
|  | include(cmake/deps.cmake) | ||||||
|  | include(GNUInstallDirs) | ||||||
|  |  | ||||||
|  | if(BUILD_SHARED_LIBS AND NOT DEFINED CMAKE_INSTALL_RPATH) | ||||||
|  |   # Set the rpath to match autoconf/libtool behavior. Note this must be set | ||||||
|  |   # before target creation. | ||||||
|  |   set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}") | ||||||
|  | endif() | ||||||
|  |  | ||||||
|  | # ############################################################################## | ||||||
|  | # Options. | ||||||
|  | if(WEBP_ENABLE_SWAP_16BIT_CSP) | ||||||
|  |   add_definitions(-DWEBP_SWAP_16BIT_CSP=1) | ||||||
|  | endif() | ||||||
|  |  | ||||||
|  | if(NOT WEBP_BITTRACE STREQUAL "0") | ||||||
|  |   add_definitions(-DBITTRACE=${WEBP_BITTRACE}) | ||||||
|  | endif() | ||||||
|  |  | ||||||
|  | if(WEBP_UNICODE) | ||||||
|  |   # Windows recommends setting both UNICODE and _UNICODE. | ||||||
|  |   add_definitions(-DUNICODE -D_UNICODE) | ||||||
|  | endif() | ||||||
|  |  | ||||||
|  | if(MSVC AND BUILD_SHARED_LIBS) | ||||||
|  |   add_definitions(-DWEBP_DLL) | ||||||
|  | endif() | ||||||
|  |  | ||||||
|  | # pkg-config variables used by *.pc.in. | ||||||
|  | set(prefix ${CMAKE_INSTALL_PREFIX}) | ||||||
|  | set(exec_prefix "\${prefix}") | ||||||
|  | if(IS_ABSOLUTE "${CMAKE_INSTALL_LIBDIR}") | ||||||
|  |   set(libdir "${CMAKE_INSTALL_LIBDIR}") | ||||||
|  | else() | ||||||
|  |   set(libdir "\${exec_prefix}/${CMAKE_INSTALL_LIBDIR}") | ||||||
|  | endif() | ||||||
|  | if(IS_ABSOLUTE "${CMAKE_INSTALL_INCLUDEDIR}") | ||||||
|  |   set(includedir "${CMAKE_INSTALL_INCLUDEDIR}") | ||||||
|  | else() | ||||||
|  |   set(includedir "\${prefix}/${CMAKE_INSTALL_INCLUDEDIR}") | ||||||
|  | endif() | ||||||
|  | set(PTHREAD_LIBS ${CMAKE_THREAD_LIBS_INIT}) | ||||||
|  | set(INSTALLED_LIBRARIES) | ||||||
|  |  | ||||||
|  | if(MSVC) | ||||||
|  |   # match the naming convention used by nmake | ||||||
|  |   set(webp_libname_prefix "lib") | ||||||
|  |   set(CMAKE_SHARED_LIBRARY_PREFIX "${webp_libname_prefix}") | ||||||
|  |   set(CMAKE_IMPORT_LIBRARY_PREFIX "${webp_libname_prefix}") | ||||||
|  |   set(CMAKE_STATIC_LIBRARY_PREFIX "${webp_libname_prefix}") | ||||||
|  | endif() | ||||||
|  |  | ||||||
|  | set(CMAKE_C_VISIBILITY_PRESET hidden) | ||||||
|  |  | ||||||
|  | # ############################################################################## | ||||||
|  | # Android only. | ||||||
|  | if(ANDROID) | ||||||
|  |   include_directories(${ANDROID_NDK}/sources/android/cpufeatures) | ||||||
|  |   add_library(cpufeatures-webp STATIC | ||||||
|  |               ${ANDROID_NDK}/sources/android/cpufeatures/cpu-features.c) | ||||||
|  |   list(APPEND INSTALLED_LIBRARIES cpufeatures-webp) | ||||||
|  |   target_link_libraries(cpufeatures-webp dl) | ||||||
|  |   set(SHARPYUV_DEP_LIBRARIES ${SHARPYUV_DEP_LIBRARIES} cpufeatures-webp) | ||||||
|  |   set(WEBP_DEP_LIBRARIES ${WEBP_DEP_LIBRARIES} cpufeatures-webp) | ||||||
|  |   set(cpufeatures_include_dir ${ANDROID_NDK}/sources/android/cpufeatures) | ||||||
|  |   set(SHARPYUV_DEP_INCLUDE_DIRS ${SHARPYUV_DEP_INCLUDE_DIRS} | ||||||
|  |                                 ${cpufeatures_include_dir}) | ||||||
|  |   set(WEBP_DEP_INCLUDE_DIRS ${WEBP_DEP_INCLUDE_DIRS} ${cpufeatures_include_dir}) | ||||||
|  |   add_definitions(-DHAVE_CPU_FEATURES_H=1) | ||||||
|  |   set(HAVE_CPU_FEATURES_H 1) | ||||||
|  | else() | ||||||
|  |   set(HAVE_CPU_FEATURES_H 0) | ||||||
|  | endif() | ||||||
|  |  | ||||||
|  | function(configure_pkg_config FILE) | ||||||
|  |   configure_file("${CMAKE_CURRENT_SOURCE_DIR}/${FILE}.in" | ||||||
|  |                  "${CMAKE_CURRENT_BINARY_DIR}/${FILE}" @ONLY) | ||||||
|  |  | ||||||
|  |   if(HAVE_MATH_LIBRARY) | ||||||
|  |     # MSVC doesn't have libm | ||||||
|  |     file(READ ${CMAKE_CURRENT_BINARY_DIR}/${FILE} data) | ||||||
|  |     string(REPLACE "-lm" "" data ${data}) | ||||||
|  |     file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/${FILE} ${data}) | ||||||
|  |   endif() | ||||||
|  |  | ||||||
|  |   install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${FILE}" | ||||||
|  |           DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig) | ||||||
|  | endfunction() | ||||||
|  |  | ||||||
|  | # ############################################################################## | ||||||
|  | # WebP source files. Read the Makefile.am to get the source files. | ||||||
|  |  | ||||||
|  | # We expect the Makefiles to define the sources as defined in the first regex. | ||||||
|  | # E.g.: libimagedec_la_SOURCES  = image_dec.c image_dec.h | ||||||
|  | function(parse_Makefile_am FOLDER VAR SRC_REGEX) | ||||||
|  |   file(READ ${FOLDER}/Makefile.am MAKEFILE_AM) | ||||||
|  |   string(REGEX MATCHALL "${SRC_REGEX}_SOURCES[ ]*\\+?=[ ]+[0-9a-z\\._ ]*" | ||||||
|  |                FILES_PER_LINE ${MAKEFILE_AM}) | ||||||
|  |   set(SRCS ${${VAR}}) | ||||||
|  |   foreach(FILES ${FILES_PER_LINE}) | ||||||
|  |     string(FIND ${FILES} "=" OFFSET) | ||||||
|  |     math(EXPR OFFSET "${OFFSET} + 2") | ||||||
|  |     string(SUBSTRING ${FILES} ${OFFSET} -1 FILES) | ||||||
|  |     if(FILES) | ||||||
|  |       string(REGEX MATCHALL "[0-9a-z\\._]+" FILES ${FILES}) | ||||||
|  |       foreach(FILE ${FILES}) | ||||||
|  |         list(APPEND SRCS ${FOLDER}/${FILE}) | ||||||
|  |       endforeach() | ||||||
|  |     endif() | ||||||
|  |   endforeach() | ||||||
|  |   set(${VAR} ${SRCS} PARENT_SCOPE) | ||||||
|  | endfunction() | ||||||
|  |  | ||||||
|  | set(WEBP_SRC_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src) | ||||||
|  | parse_makefile_am(${WEBP_SRC_DIR}/dec "WEBP_DEC_SRCS" "") | ||||||
|  | parse_makefile_am(${WEBP_SRC_DIR}/demux "WEBP_DEMUX_SRCS" "") | ||||||
|  | parse_makefile_am(${WEBP_SRC_DIR}/dsp "WEBP_DSP_COMMON_SRCS" "COMMON") | ||||||
|  | parse_makefile_am(${WEBP_SRC_DIR}/dsp "WEBP_DSP_ENC_SRCS" "ENC") | ||||||
|  | parse_makefile_am(${WEBP_SRC_DIR}/dsp "WEBP_DSP_ENC_SRCS" "dsp_[^ ]*") | ||||||
|  | parse_makefile_am(${WEBP_SRC_DIR}/dsp "WEBP_DSP_DEC_SRCS" "decode_[^ ]*") | ||||||
|  | parse_makefile_am(${WEBP_SRC_DIR}/enc "WEBP_ENC_SRCS" "") | ||||||
|  | parse_makefile_am(${WEBP_SRC_DIR}/utils "WEBP_UTILS_COMMON_SRCS" "COMMON") | ||||||
|  | parse_makefile_am(${WEBP_SRC_DIR}/utils "WEBP_UTILS_ENC_SRCS" "ENC") | ||||||
|  | parse_makefile_am(${WEBP_SRC_DIR}/utils "WEBP_UTILS_DEC_SRCS" "decode_[^ ]*") | ||||||
|  |  | ||||||
|  | # Remove the files specific to SIMD we don't use. | ||||||
|  | foreach(FILE ${WEBP_SIMD_FILES_NOT_TO_INCLUDE}) | ||||||
|  |   list(REMOVE_ITEM WEBP_DSP_ENC_SRCS ${FILE}) | ||||||
|  |   list(REMOVE_ITEM WEBP_DSP_DEC_SRCS ${FILE}) | ||||||
|  | endforeach() | ||||||
|  |  | ||||||
|  | # Generate the config.h file. | ||||||
|  | configure_file(${CMAKE_CURRENT_LIST_DIR}/cmake/config.h.in | ||||||
|  |                ${CMAKE_CURRENT_BINARY_DIR}/src/webp/config.h @ONLY) | ||||||
|  | add_definitions(-DHAVE_CONFIG_H) | ||||||
|  |  | ||||||
|  | # Set the version numbers. | ||||||
|  | macro(set_version FILE TARGET_NAME NAME_IN_MAKEFILE) | ||||||
|  |   file(READ ${CMAKE_CURRENT_SOURCE_DIR}/${FILE} SOURCE_FILE) | ||||||
|  |   string(REGEX MATCH | ||||||
|  |                "${NAME_IN_MAKEFILE}_la_LDFLAGS[^\n]* -version-info [0-9:]+" TMP | ||||||
|  |                ${SOURCE_FILE}) | ||||||
|  |   string(REGEX MATCH "[0-9:]+" TMP ${TMP}) | ||||||
|  |   string(REGEX REPLACE ":" " " LT_VERSION ${TMP}) | ||||||
|  |  | ||||||
|  |   # See the libtool docs for more information: | ||||||
|  |   # https://www.gnu.org/software/libtool/manual/libtool.html#Updating-version-info | ||||||
|  |   # | ||||||
|  |   # c=<current>, a=<age>, r=<revision> | ||||||
|  |   # | ||||||
|  |   # libtool generates a .so file as .so.[c-a].a.r, while -version-info c:r:a is | ||||||
|  |   # passed to libtool. | ||||||
|  |   # | ||||||
|  |   # We set FULL = [c-a].a.r and MAJOR = [c-a]. | ||||||
|  |   separate_arguments(LT_VERSION) | ||||||
|  |   list(GET LT_VERSION 0 LT_CURRENT) | ||||||
|  |   list(GET LT_VERSION 1 LT_REVISION) | ||||||
|  |   list(GET LT_VERSION 2 LT_AGE) | ||||||
|  |   math(EXPR LT_CURRENT_MINUS_AGE "${LT_CURRENT} - ${LT_AGE}") | ||||||
|  |  | ||||||
|  |   set_target_properties( | ||||||
|  |     ${TARGET_NAME} | ||||||
|  |     PROPERTIES VERSION ${LT_CURRENT_MINUS_AGE}.${LT_AGE}.${LT_REVISION} | ||||||
|  |                SOVERSION ${LT_CURRENT_MINUS_AGE}) | ||||||
|  |   if(APPLE) | ||||||
|  |     # For compatibility, set MACHO_COMPATIBILITY_VERSION and | ||||||
|  |     # MACHO_CURRENT_VERSION to match libtool. These properties were introduced | ||||||
|  |     # in 3.17: | ||||||
|  |     # https://cmake.org/cmake/help/latest/prop_tgt/MACHO_COMPATIBILITY_VERSION.html | ||||||
|  |     math(EXPR LIBWEBP_MACHO_COMPATIBILITY_VERSION "${LT_CURRENT} + 1") | ||||||
|  |     set_target_properties( | ||||||
|  |       ${TARGET_NAME} | ||||||
|  |       PROPERTIES MACHO_COMPATIBILITY_VERSION | ||||||
|  |                  ${LIBWEBP_MACHO_COMPATIBILITY_VERSION} | ||||||
|  |                  MACHO_CURRENT_VERSION | ||||||
|  |                  ${LIBWEBP_MACHO_COMPATIBILITY_VERSION}.${LT_REVISION}) | ||||||
|  |   endif() | ||||||
|  | endmacro() | ||||||
|  |  | ||||||
|  | # ############################################################################## | ||||||
|  | # Build the webpdecoder library. | ||||||
|  |  | ||||||
|  | # Creates a source file with an unused stub function in $CMAKE_BINARY_DIR and | ||||||
|  | # adds it to the specified target. Currently used only with Xcode. | ||||||
|  | # | ||||||
|  | # See also: | ||||||
|  | # https://cmake.org/cmake/help/v3.18/command/add_library.html#object-libraries | ||||||
|  | # "Some native build systems (such as Xcode) may not like targets that have only | ||||||
|  | # object files, so consider adding at least one real source file to any target | ||||||
|  | # that references $<TARGET_OBJECTS:objlib>." | ||||||
|  | function(libwebp_add_stub_file TARGET) | ||||||
|  |   set(stub_source_dir "${CMAKE_BINARY_DIR}") | ||||||
|  |   set(stub_source_file "${stub_source_dir}/libwebp_${TARGET}_stub.c") | ||||||
|  |   set(stub_source_code | ||||||
|  |       "// Generated file. DO NOT EDIT!\n" | ||||||
|  |       "// C source file created for target ${TARGET}.\n" | ||||||
|  |       "void libwebp_${TARGET}_stub_function(void)\;\n" | ||||||
|  |       "void libwebp_${TARGET}_stub_function(void) {}\n") | ||||||
|  |   file(WRITE "${stub_source_file}" ${stub_source_code}) | ||||||
|  |  | ||||||
|  |   target_sources(${TARGET} PRIVATE ${stub_source_file}) | ||||||
|  | endfunction() | ||||||
|  |  | ||||||
|  | parse_makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/sharpyuv "WEBP_SHARPYUV_SRCS" "") | ||||||
|  | add_library(sharpyuv ${WEBP_SHARPYUV_SRCS}) | ||||||
|  | target_link_libraries(sharpyuv ${SHARPYUV_DEP_LIBRARIES}) | ||||||
|  | set_version(sharpyuv/Makefile.am sharpyuv sharpyuv) | ||||||
|  | target_include_directories( | ||||||
|  |   sharpyuv PRIVATE ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR} | ||||||
|  |                    ${CMAKE_CURRENT_SOURCE_DIR}/src) | ||||||
|  | set_target_properties( | ||||||
|  |   sharpyuv | ||||||
|  |   PROPERTIES PUBLIC_HEADER "${CMAKE_CURRENT_SOURCE_DIR}/sharpyuv/sharpyuv.h;\ | ||||||
|  | ${CMAKE_CURRENT_SOURCE_DIR}/sharpyuv/sharpyuv_csp.h") | ||||||
|  | configure_pkg_config("sharpyuv/libsharpyuv.pc") | ||||||
|  | install( | ||||||
|  |   TARGETS sharpyuv | ||||||
|  |   EXPORT ${PROJECT_NAME}Targets | ||||||
|  |   PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/webp/sharpyuv | ||||||
|  |   INCLUDES | ||||||
|  |   DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} | ||||||
|  |   ${CMAKE_INSTALL_INCLUDEDIR}/webp | ||||||
|  |   ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} | ||||||
|  |   LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} | ||||||
|  |   RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) | ||||||
|  |  | ||||||
|  | if(MSVC) | ||||||
|  |   # avoid security warnings for e.g., fopen() used in the examples. | ||||||
|  |   add_definitions(-D_CRT_SECURE_NO_WARNINGS) | ||||||
|  | else() | ||||||
|  |   add_compile_options(-Wall) | ||||||
|  | endif() | ||||||
|  | include_directories(${WEBP_DEP_INCLUDE_DIRS}) | ||||||
|  | add_library(webpdecode OBJECT ${WEBP_DEC_SRCS}) | ||||||
|  | target_include_directories(webpdecode PRIVATE ${CMAKE_CURRENT_BINARY_DIR} | ||||||
|  |                                               ${CMAKE_CURRENT_SOURCE_DIR}) | ||||||
|  | add_library(webpdspdecode OBJECT ${WEBP_DSP_COMMON_SRCS} ${WEBP_DSP_DEC_SRCS}) | ||||||
|  | target_include_directories(webpdspdecode PRIVATE ${CMAKE_CURRENT_BINARY_DIR} | ||||||
|  |                                                  ${CMAKE_CURRENT_SOURCE_DIR}) | ||||||
|  | add_library(webputilsdecode OBJECT ${WEBP_UTILS_COMMON_SRCS} | ||||||
|  |                                    ${WEBP_UTILS_DEC_SRCS}) | ||||||
|  | target_include_directories(webputilsdecode PRIVATE ${CMAKE_CURRENT_BINARY_DIR} | ||||||
|  |                                                    ${CMAKE_CURRENT_SOURCE_DIR}) | ||||||
|  | add_library( | ||||||
|  |   webpdecoder $<TARGET_OBJECTS:webpdecode> $<TARGET_OBJECTS:webpdspdecode> | ||||||
|  |               $<TARGET_OBJECTS:webputilsdecode>) | ||||||
|  | if(XCODE) | ||||||
|  |   libwebp_add_stub_file(webpdecoder) | ||||||
|  | endif() | ||||||
|  | target_link_libraries(webpdecoder ${WEBP_DEP_LIBRARIES}) | ||||||
|  | target_include_directories( | ||||||
|  |   webpdecoder PRIVATE ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR} | ||||||
|  |   INTERFACE $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}> | ||||||
|  |             $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>) | ||||||
|  | set_target_properties( | ||||||
|  |   webpdecoder | ||||||
|  |   PROPERTIES PUBLIC_HEADER "${CMAKE_CURRENT_SOURCE_DIR}/src/webp/decode.h;\ | ||||||
|  | ${CMAKE_CURRENT_SOURCE_DIR}/src/webp/types.h") | ||||||
|  |  | ||||||
|  | configure_pkg_config("src/libwebpdecoder.pc") | ||||||
|  |  | ||||||
|  | # Build the webp library. | ||||||
|  | add_library(webpencode OBJECT ${WEBP_ENC_SRCS}) | ||||||
|  | target_include_directories( | ||||||
|  |   webpencode PRIVATE ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR} | ||||||
|  |                      ${CMAKE_CURRENT_SOURCE_DIR}/src) | ||||||
|  | add_library(webpdsp OBJECT ${WEBP_DSP_COMMON_SRCS} ${WEBP_DSP_DEC_SRCS} | ||||||
|  |                            ${WEBP_DSP_ENC_SRCS}) | ||||||
|  | target_include_directories(webpdsp PRIVATE ${CMAKE_CURRENT_BINARY_DIR} | ||||||
|  |                                            ${CMAKE_CURRENT_SOURCE_DIR}) | ||||||
|  | add_library(webputils OBJECT ${WEBP_UTILS_COMMON_SRCS} ${WEBP_UTILS_DEC_SRCS} | ||||||
|  |                              ${WEBP_UTILS_ENC_SRCS}) | ||||||
|  | target_include_directories(webputils PRIVATE ${CMAKE_CURRENT_BINARY_DIR} | ||||||
|  |                                              ${CMAKE_CURRENT_SOURCE_DIR}) | ||||||
|  | add_library(webp $<TARGET_OBJECTS:webpdecode> $<TARGET_OBJECTS:webpdsp> | ||||||
|  |                  $<TARGET_OBJECTS:webpencode> $<TARGET_OBJECTS:webputils>) | ||||||
|  | target_link_libraries(webp sharpyuv) | ||||||
|  | if(XCODE) | ||||||
|  |   libwebp_add_stub_file(webp) | ||||||
|  | endif() | ||||||
|  | target_link_libraries(webp ${WEBP_DEP_LIBRARIES}) | ||||||
|  | target_include_directories( | ||||||
|  |   webp PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} | ||||||
|  |   PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src> | ||||||
|  |          $<INSTALL_INTERFACE:include>) | ||||||
|  | set_target_properties( | ||||||
|  |   webp | ||||||
|  |   PROPERTIES PUBLIC_HEADER "${CMAKE_CURRENT_SOURCE_DIR}/src/webp/decode.h;\ | ||||||
|  | ${CMAKE_CURRENT_SOURCE_DIR}/src/webp/encode.h;\ | ||||||
|  | ${CMAKE_CURRENT_SOURCE_DIR}/src/webp/types.h") | ||||||
|  |  | ||||||
|  | # Make sure the OBJECT libraries are built with position independent code (it is | ||||||
|  | # not ON by default). | ||||||
|  | set_target_properties(webpdecode webpdspdecode webputilsdecode webpencode | ||||||
|  |                       webpdsp webputils PROPERTIES POSITION_INDEPENDENT_CODE ON) | ||||||
|  | configure_pkg_config("src/libwebp.pc") | ||||||
|  |  | ||||||
|  | # Build the webp demux library. | ||||||
|  | add_library(webpdemux ${WEBP_DEMUX_SRCS}) | ||||||
|  | target_link_libraries(webpdemux webp) | ||||||
|  | target_include_directories( | ||||||
|  |   webpdemux PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} | ||||||
|  |   PUBLIC $<INSTALL_INTERFACE:include>) | ||||||
|  | set_target_properties( | ||||||
|  |   webpdemux | ||||||
|  |   PROPERTIES | ||||||
|  |     PUBLIC_HEADER | ||||||
|  |     "${CMAKE_CURRENT_SOURCE_DIR}/src/webp/decode.h;\ | ||||||
|  | ${CMAKE_CURRENT_SOURCE_DIR}/src/webp/demux.h;\ | ||||||
|  | ${CMAKE_CURRENT_SOURCE_DIR}/src/webp/mux_types.h;\ | ||||||
|  | ${CMAKE_CURRENT_SOURCE_DIR}/src/webp/types.h") | ||||||
|  |  | ||||||
|  | configure_pkg_config("src/demux/libwebpdemux.pc") | ||||||
|  |  | ||||||
|  | set_version(src/Makefile.am webp webp) | ||||||
|  | set_version(src/Makefile.am webpdecoder webpdecoder) | ||||||
|  | set_version(src/demux/Makefile.am webpdemux webpdemux) | ||||||
|  | file(READ ${CMAKE_CURRENT_SOURCE_DIR}/configure.ac CONFIGURE_FILE) | ||||||
|  | string(REGEX MATCH "AC_INIT\\([^\n]*\\[[0-9\\.]+\\]" TMP ${CONFIGURE_FILE}) | ||||||
|  | string(REGEX MATCH "[0-9\\.]+" PROJECT_VERSION ${TMP}) | ||||||
|  |  | ||||||
|  | # Define the libraries to install. | ||||||
|  | list(APPEND INSTALLED_LIBRARIES webpdecoder webp webpdemux) | ||||||
|  |  | ||||||
|  | # Deal with SIMD. Change the compile flags for SIMD files we use. | ||||||
|  | list(LENGTH WEBP_SIMD_FILES_TO_INCLUDE WEBP_SIMD_FILES_TO_INCLUDE_LENGTH) | ||||||
|  | math(EXPR WEBP_SIMD_FILES_TO_INCLUDE_RANGE | ||||||
|  |      "${WEBP_SIMD_FILES_TO_INCLUDE_LENGTH}-1") | ||||||
|  |  | ||||||
|  | foreach(I_FILE RANGE ${WEBP_SIMD_FILES_TO_INCLUDE_RANGE}) | ||||||
|  |   list(GET WEBP_SIMD_FILES_TO_INCLUDE ${I_FILE} FILE) | ||||||
|  |   list(GET WEBP_SIMD_FLAGS_TO_INCLUDE ${I_FILE} SIMD_COMPILE_FLAG) | ||||||
|  |   set_source_files_properties(${FILE} PROPERTIES COMPILE_FLAGS | ||||||
|  |                                                  ${SIMD_COMPILE_FLAG}) | ||||||
|  | endforeach() | ||||||
|  |  | ||||||
|  | if(NOT WEBP_BUILD_LIBWEBPMUX) | ||||||
|  |   set(WEBP_BUILD_GIF2WEBP OFF) | ||||||
|  |   set(WEBP_BUILD_IMG2WEBP OFF) | ||||||
|  |   set(WEBP_BUILD_WEBPMUX OFF) | ||||||
|  | endif() | ||||||
|  |  | ||||||
|  | if(WEBP_BUILD_GIF2WEBP AND NOT GIF_FOUND) | ||||||
|  |   set(WEBP_BUILD_GIF2WEBP OFF) | ||||||
|  | endif() | ||||||
|  |  | ||||||
|  | if(WEBP_BUILD_ANIM_UTILS AND NOT GIF_FOUND) | ||||||
|  |   set(WEBP_BUILD_ANIM_UTILS OFF) | ||||||
|  | endif() | ||||||
|  |  | ||||||
|  | # Build the executables if asked for. | ||||||
|  | if(WEBP_BUILD_ANIM_UTILS | ||||||
|  |    OR WEBP_BUILD_CWEBP | ||||||
|  |    OR WEBP_BUILD_DWEBP | ||||||
|  |    OR WEBP_BUILD_GIF2WEBP | ||||||
|  |    OR WEBP_BUILD_IMG2WEBP | ||||||
|  |    OR WEBP_BUILD_VWEBP | ||||||
|  |    OR WEBP_BUILD_WEBPMUX | ||||||
|  |    OR WEBP_BUILD_WEBPINFO) | ||||||
|  |   # Example utility library. | ||||||
|  |   parse_makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/examples "EXAMPLEUTIL_SRCS" | ||||||
|  |                     "example_util_[^ ]*") | ||||||
|  |   list(APPEND EXAMPLEUTIL_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/examples/stopwatch.h) | ||||||
|  |   add_library(exampleutil STATIC ${EXAMPLEUTIL_SRCS}) | ||||||
|  |   target_include_directories( | ||||||
|  |     exampleutil PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>) | ||||||
|  |  | ||||||
|  |   parse_makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/imageio "IMAGEIOUTILS_SRCS" | ||||||
|  |                     "imageio_util_[^ ]*") | ||||||
|  |   add_library(imageioutil STATIC ${IMAGEIOUTILS_SRCS}) | ||||||
|  |   target_link_libraries(imageioutil webp) | ||||||
|  |   target_link_libraries(exampleutil imageioutil) | ||||||
|  |  | ||||||
|  |   # Image-decoding utility library. | ||||||
|  |   parse_makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/imageio "IMAGEDEC_SRCS" | ||||||
|  |                     "imagedec_[^ ]*") | ||||||
|  |   add_library(imagedec STATIC ${IMAGEDEC_SRCS}) | ||||||
|  |   target_link_libraries(imagedec imageioutil webpdemux webp | ||||||
|  |                         ${WEBP_DEP_IMG_LIBRARIES}) | ||||||
|  |  | ||||||
|  |   # Image-encoding utility library. | ||||||
|  |   parse_makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/imageio "IMAGEENC_SRCS" | ||||||
|  |                     "imageenc_[^ ]*") | ||||||
|  |   add_library(imageenc STATIC ${IMAGEENC_SRCS}) | ||||||
|  |   target_link_libraries(imageenc imageioutil webp) | ||||||
|  |  | ||||||
|  |   set_property( | ||||||
|  |     TARGET exampleutil imageioutil imagedec imageenc | ||||||
|  |     PROPERTY INCLUDE_DIRECTORIES ${CMAKE_CURRENT_SOURCE_DIR}/src | ||||||
|  |              ${CMAKE_CURRENT_BINARY_DIR}/src) | ||||||
|  | endif() | ||||||
|  |  | ||||||
|  | if(WEBP_BUILD_DWEBP) | ||||||
|  |   # dwebp | ||||||
|  |   parse_makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/examples "DWEBP_SRCS" "dwebp") | ||||||
|  |   add_executable(dwebp ${DWEBP_SRCS}) | ||||||
|  |   target_link_libraries(dwebp exampleutil imagedec imageenc) | ||||||
|  |   target_include_directories(dwebp PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/src) | ||||||
|  |   install(TARGETS dwebp RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) | ||||||
|  | endif() | ||||||
|  |  | ||||||
|  | if(WEBP_BUILD_CWEBP) | ||||||
|  |   # cwebp | ||||||
|  |   parse_makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/examples "CWEBP_SRCS" "cwebp") | ||||||
|  |   add_executable(cwebp ${CWEBP_SRCS}) | ||||||
|  |   target_link_libraries(cwebp exampleutil imagedec webp) | ||||||
|  |   target_include_directories(cwebp PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/src | ||||||
|  |                                            ${CMAKE_CURRENT_SOURCE_DIR}) | ||||||
|  |   install(TARGETS cwebp RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) | ||||||
|  | endif() | ||||||
|  |  | ||||||
|  | if(WEBP_BUILD_LIBWEBPMUX) | ||||||
|  |   parse_makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/src/mux "WEBP_MUX_SRCS" "") | ||||||
|  |   add_library(libwebpmux ${WEBP_MUX_SRCS}) | ||||||
|  |   target_link_libraries(libwebpmux webp) | ||||||
|  |   target_include_directories(libwebpmux PRIVATE ${CMAKE_CURRENT_BINARY_DIR} | ||||||
|  |                                                 ${CMAKE_CURRENT_SOURCE_DIR}) | ||||||
|  |   set_version(src/mux/Makefile.am libwebpmux webpmux) | ||||||
|  |   set_target_properties( | ||||||
|  |     libwebpmux | ||||||
|  |     PROPERTIES PUBLIC_HEADER "${CMAKE_CURRENT_SOURCE_DIR}/src/webp/mux.h;\ | ||||||
|  | ${CMAKE_CURRENT_SOURCE_DIR}/src/webp/mux_types.h;\ | ||||||
|  | ${CMAKE_CURRENT_SOURCE_DIR}/src/webp/types.h;") | ||||||
|  |   set_target_properties(libwebpmux PROPERTIES OUTPUT_NAME webpmux) | ||||||
|  |   list(APPEND INSTALLED_LIBRARIES libwebpmux) | ||||||
|  |   configure_pkg_config("src/mux/libwebpmux.pc") | ||||||
|  | endif() | ||||||
|  |  | ||||||
|  | if(WEBP_BUILD_GIF2WEBP) | ||||||
|  |   # gif2webp | ||||||
|  |   include_directories(${WEBP_DEP_GIF_INCLUDE_DIRS}) | ||||||
|  |   parse_makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/examples "GIF2WEBP_SRCS" | ||||||
|  |                     "gif2webp") | ||||||
|  |   add_executable(gif2webp ${GIF2WEBP_SRCS}) | ||||||
|  |   target_link_libraries(gif2webp exampleutil imageioutil webp libwebpmux | ||||||
|  |                         ${WEBP_DEP_GIF_LIBRARIES}) | ||||||
|  |   target_include_directories(gif2webp PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/src) | ||||||
|  |   install(TARGETS gif2webp RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) | ||||||
|  | endif() | ||||||
|  |  | ||||||
|  | if(WEBP_BUILD_IMG2WEBP) | ||||||
|  |   # img2webp | ||||||
|  |   include_directories(${WEBP_DEP_IMG_INCLUDE_DIRS}) | ||||||
|  |   parse_makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/examples "IMG2WEBP_SRCS" | ||||||
|  |                     "img2webp") | ||||||
|  |   add_executable(img2webp ${IMG2WEBP_SRCS}) | ||||||
|  |   target_link_libraries(img2webp exampleutil imagedec imageioutil webp | ||||||
|  |                         libwebpmux) | ||||||
|  |   target_include_directories(img2webp PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/src | ||||||
|  |                                               ${CMAKE_CURRENT_SOURCE_DIR}) | ||||||
|  |   install(TARGETS img2webp RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) | ||||||
|  | endif() | ||||||
|  |  | ||||||
|  | if(WEBP_BUILD_VWEBP) | ||||||
|  |   # vwebp | ||||||
|  |   find_package(GLUT) | ||||||
|  |   if(GLUT_FOUND) | ||||||
|  |     include_directories(${WEBP_DEP_IMG_INCLUDE_DIRS}) | ||||||
|  |     parse_makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/examples "VWEBP_SRCS" "vwebp") | ||||||
|  |     add_executable(vwebp ${VWEBP_SRCS}) | ||||||
|  |     target_link_libraries( | ||||||
|  |       vwebp | ||||||
|  |       ${OPENGL_LIBRARIES} | ||||||
|  |       exampleutil | ||||||
|  |       GLUT::GLUT | ||||||
|  |       imageioutil | ||||||
|  |       webp | ||||||
|  |       webpdemux) | ||||||
|  |     target_include_directories( | ||||||
|  |       vwebp PRIVATE ${GLUT_INCLUDE_DIR} ${CMAKE_CURRENT_BINARY_DIR}/src | ||||||
|  |                     ${OPENGL_INCLUDE_DIR}) | ||||||
|  |     install(TARGETS vwebp RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) | ||||||
|  |     if(${CMAKE_SYSTEM_NAME} STREQUAL "Darwin") | ||||||
|  |       check_c_compiler_flag("-Wno-deprecated-declarations" HAS_NO_DEPRECATED) | ||||||
|  |       if(HAS_NO_DEPRECATED) | ||||||
|  |         target_compile_options(vwebp PRIVATE "-Wno-deprecated-declarations") | ||||||
|  |       endif() | ||||||
|  |     endif() | ||||||
|  |   endif() | ||||||
|  | endif() | ||||||
|  |  | ||||||
|  | if(WEBP_BUILD_WEBPINFO) | ||||||
|  |   # webpinfo | ||||||
|  |   include_directories(${WEBP_DEP_IMG_INCLUDE_DIRS}) | ||||||
|  |   parse_makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/examples "WEBPINFO_SRCS" | ||||||
|  |                     "webpinfo") | ||||||
|  |   add_executable(webpinfo ${WEBPINFO_SRCS}) | ||||||
|  |   target_link_libraries(webpinfo exampleutil imageioutil) | ||||||
|  |   target_include_directories(webpinfo PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/src | ||||||
|  |                                               ${CMAKE_CURRENT_SOURCE_DIR}/src) | ||||||
|  |   install(TARGETS webpinfo RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) | ||||||
|  | endif() | ||||||
|  |  | ||||||
|  | if(WEBP_BUILD_WEBPMUX) | ||||||
|  |   # webpmux | ||||||
|  |   parse_makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/examples "WEBPMUX_SRCS" | ||||||
|  |                     "webpmux") | ||||||
|  |   add_executable(webpmux ${WEBPMUX_SRCS}) | ||||||
|  |   target_link_libraries(webpmux exampleutil imageioutil libwebpmux webp) | ||||||
|  |   target_include_directories(webpmux PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/src) | ||||||
|  |   install(TARGETS webpmux RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) | ||||||
|  | endif() | ||||||
|  |  | ||||||
|  | if(WEBP_BUILD_EXTRAS) | ||||||
|  |   set(EXTRAS_MAKEFILE "${CMAKE_CURRENT_SOURCE_DIR}/extras") | ||||||
|  |   parse_makefile_am(${EXTRAS_MAKEFILE} "WEBP_EXTRAS_SRCS" "libwebpextras_la") | ||||||
|  |   parse_makefile_am(${EXTRAS_MAKEFILE} "GET_DISTO_SRCS" "get_disto") | ||||||
|  |   parse_makefile_am(${EXTRAS_MAKEFILE} "WEBP_QUALITY_SRCS" "webp_quality") | ||||||
|  |   parse_makefile_am(${EXTRAS_MAKEFILE} "VWEBP_SDL_SRCS" "vwebp_sdl") | ||||||
|  |  | ||||||
|  |   # libextras | ||||||
|  |   add_library(extras STATIC ${WEBP_EXTRAS_SRCS}) | ||||||
|  |   target_include_directories( | ||||||
|  |     extras PRIVATE ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR} | ||||||
|  |                    ${CMAKE_CURRENT_SOURCE_DIR}/src) | ||||||
|  |  | ||||||
|  |   # get_disto | ||||||
|  |   add_executable(get_disto ${GET_DISTO_SRCS}) | ||||||
|  |   target_link_libraries(get_disto imagedec) | ||||||
|  |   target_include_directories(get_disto PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} | ||||||
|  |                                                ${CMAKE_CURRENT_BINARY_DIR}/src) | ||||||
|  |  | ||||||
|  |   # webp_quality | ||||||
|  |   add_executable(webp_quality ${WEBP_QUALITY_SRCS}) | ||||||
|  |   target_link_libraries(webp_quality exampleutil imagedec extras) | ||||||
|  |   target_include_directories(webp_quality PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} | ||||||
|  |                                                   ${CMAKE_CURRENT_BINARY_DIR}) | ||||||
|  |  | ||||||
|  |   # vwebp_sdl | ||||||
|  |   find_package(SDL) | ||||||
|  |   if(WEBP_BUILD_VWEBP AND SDL_FOUND) | ||||||
|  |     add_executable(vwebp_sdl ${VWEBP_SDL_SRCS}) | ||||||
|  |     target_link_libraries(vwebp_sdl ${SDL_LIBRARY} imageioutil webp) | ||||||
|  |     target_include_directories( | ||||||
|  |       vwebp_sdl PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} | ||||||
|  |                         ${CMAKE_CURRENT_BINARY_DIR}/src ${SDL_INCLUDE_DIR}) | ||||||
|  |     set(WEBP_HAVE_SDL 1) | ||||||
|  |     target_compile_definitions(vwebp_sdl PUBLIC WEBP_HAVE_SDL) | ||||||
|  |   endif() | ||||||
|  | endif() | ||||||
|  |  | ||||||
|  | if(WEBP_BUILD_WEBP_JS) | ||||||
|  |   # The default stack size changed from 5MB to 64KB in 3.1.27. See | ||||||
|  |   # https://crbug.com/webp/614. | ||||||
|  |   if(EMSCRIPTEN_VERSION VERSION_GREATER_EQUAL "3.1.27") | ||||||
|  |     # TOTAL_STACK size was renamed to STACK_SIZE in 3.1.27. The old name was | ||||||
|  |     # kept for compatibility, but prefer the new one in case it is removed in | ||||||
|  |     # the future. | ||||||
|  |     set(emscripten_stack_size "-sSTACK_SIZE=5MB") | ||||||
|  |   else() | ||||||
|  |     set(emscripten_stack_size "-sTOTAL_STACK=5MB") | ||||||
|  |   endif() | ||||||
|  |   # wasm2js does not support SIMD. | ||||||
|  |   if(NOT WEBP_ENABLE_SIMD) | ||||||
|  |     # JavaScript version | ||||||
|  |     add_executable(webp_js ${CMAKE_CURRENT_SOURCE_DIR}/extras/webp_to_sdl.c) | ||||||
|  |     target_link_libraries(webp_js webpdecoder SDL) | ||||||
|  |     target_include_directories(webp_js PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) | ||||||
|  |     set(WEBP_HAVE_SDL 1) | ||||||
|  |     set_target_properties( | ||||||
|  |       webp_js | ||||||
|  |       PROPERTIES LINK_FLAGS "-sWASM=0 ${emscripten_stack_size} \ | ||||||
|  |          -sEXPORTED_FUNCTIONS=_WebPToSDL -sINVOKE_RUN=0 \ | ||||||
|  |          -sEXPORTED_RUNTIME_METHODS=cwrap") | ||||||
|  |     set_target_properties(webp_js PROPERTIES OUTPUT_NAME webp) | ||||||
|  |     target_compile_definitions(webp_js PUBLIC EMSCRIPTEN WEBP_HAVE_SDL) | ||||||
|  |   endif() | ||||||
|  |  | ||||||
|  |   # WASM version | ||||||
|  |   add_executable(webp_wasm ${CMAKE_CURRENT_SOURCE_DIR}/extras/webp_to_sdl.c) | ||||||
|  |   target_link_libraries(webp_wasm webpdecoder SDL) | ||||||
|  |   target_include_directories(webp_wasm PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) | ||||||
|  |   set_target_properties( | ||||||
|  |     webp_wasm | ||||||
|  |     PROPERTIES LINK_FLAGS "-sWASM=1 ${emscripten_stack_size} \ | ||||||
|  |        -sEXPORTED_FUNCTIONS=_WebPToSDL -sINVOKE_RUN=0 \ | ||||||
|  |        -sEXPORTED_RUNTIME_METHODS=cwrap") | ||||||
|  |   target_compile_definitions(webp_wasm PUBLIC EMSCRIPTEN WEBP_HAVE_SDL) | ||||||
|  |  | ||||||
|  |   target_compile_definitions(webpdspdecode PUBLIC EMSCRIPTEN) | ||||||
|  | endif() | ||||||
|  |  | ||||||
|  | if(WEBP_BUILD_ANIM_UTILS) | ||||||
|  |   # anim_diff | ||||||
|  |   include_directories(${WEBP_DEP_IMG_INCLUDE_DIRS} ${WEBP_DEP_GIF_INCLUDE_DIRS}) | ||||||
|  |   parse_makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/examples "ANIM_DIFF_SRCS" | ||||||
|  |                     "anim_diff") | ||||||
|  |   add_executable(anim_diff ${ANIM_DIFF_SRCS}) | ||||||
|  |   target_link_libraries( | ||||||
|  |     anim_diff | ||||||
|  |     exampleutil | ||||||
|  |     imagedec | ||||||
|  |     imageenc | ||||||
|  |     imageioutil | ||||||
|  |     webp | ||||||
|  |     webpdemux | ||||||
|  |     ${WEBP_DEP_GIF_LIBRARIES}) | ||||||
|  |   target_include_directories(anim_diff PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/src) | ||||||
|  |  | ||||||
|  |   # anim_dump | ||||||
|  |   include_directories(${WEBP_DEP_IMG_INCLUDE_DIRS} ${WEBP_DEP_GIF_INCLUDE_DIRS}) | ||||||
|  |   parse_makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/examples "ANIM_DUMP_SRCS" | ||||||
|  |                     "anim_dump") | ||||||
|  |   add_executable(anim_dump ${ANIM_DUMP_SRCS}) | ||||||
|  |   target_link_libraries( | ||||||
|  |     anim_dump | ||||||
|  |     exampleutil | ||||||
|  |     imagedec | ||||||
|  |     imageenc | ||||||
|  |     imageioutil | ||||||
|  |     webp | ||||||
|  |     webpdemux | ||||||
|  |     ${WEBP_DEP_GIF_LIBRARIES}) | ||||||
|  |   target_include_directories(anim_dump PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/src) | ||||||
|  | endif() | ||||||
|  |  | ||||||
|  | # Install the different headers and libraries. | ||||||
|  | install( | ||||||
|  |   TARGETS ${INSTALLED_LIBRARIES} | ||||||
|  |   EXPORT ${PROJECT_NAME}Targets | ||||||
|  |   PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/webp | ||||||
|  |   INCLUDES | ||||||
|  |   DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} | ||||||
|  |   ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} | ||||||
|  |   LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} | ||||||
|  |   RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) | ||||||
|  | set(ConfigPackageLocation ${CMAKE_INSTALL_DATADIR}/${PROJECT_NAME}/cmake/) | ||||||
|  | install(EXPORT ${PROJECT_NAME}Targets NAMESPACE ${PROJECT_NAME}:: | ||||||
|  |         DESTINATION ${ConfigPackageLocation}) | ||||||
|  |  | ||||||
|  | # Create the CMake version file. | ||||||
|  | include(CMakePackageConfigHelpers) | ||||||
|  | write_basic_package_version_file( | ||||||
|  |   "${CMAKE_CURRENT_BINARY_DIR}/WebPConfigVersion.cmake" | ||||||
|  |   VERSION ${PACKAGE_VERSION} COMPATIBILITY AnyNewerVersion) | ||||||
|  |  | ||||||
|  | # Create the Config file. | ||||||
|  | include(CMakePackageConfigHelpers) | ||||||
|  | # Fix libwebpmux reference. The target name libwebpmux is used for compatibility | ||||||
|  | # purposes, but the library mentioned in WebPConfig.cmake should be the | ||||||
|  | # unprefixed version. Note string(...) can be replaced with list(TRANSFORM ...) | ||||||
|  | # if cmake_minimum_required is >= 3.12. | ||||||
|  | string(REGEX REPLACE "libwebpmux" "webpmux" INSTALLED_LIBRARIES | ||||||
|  |                      "${INSTALLED_LIBRARIES}") | ||||||
|  |  | ||||||
|  | if(MSVC) | ||||||
|  |   # For compatibility with nmake, MSVC builds use a custom prefix (lib) that | ||||||
|  |   # needs to be included in the library name. | ||||||
|  |   string(REGEX REPLACE "[A-Za-z0-9_]+" "${CMAKE_STATIC_LIBRARY_PREFIX}\\0" | ||||||
|  |                        INSTALLED_LIBRARIES "${INSTALLED_LIBRARIES}") | ||||||
|  | endif() | ||||||
|  |  | ||||||
|  | configure_package_config_file( | ||||||
|  |   ${CMAKE_CURRENT_SOURCE_DIR}/cmake/WebPConfig.cmake.in | ||||||
|  |   ${CMAKE_CURRENT_BINARY_DIR}/WebPConfig.cmake | ||||||
|  |   INSTALL_DESTINATION ${ConfigPackageLocation} | ||||||
|  |   PATH_VARS CMAKE_INSTALL_INCLUDEDIR) | ||||||
|  |  | ||||||
|  | # Install the generated CMake files. | ||||||
|  | install(FILES "${CMAKE_CURRENT_BINARY_DIR}/WebPConfigVersion.cmake" | ||||||
|  |               "${CMAKE_CURRENT_BINARY_DIR}/WebPConfig.cmake" | ||||||
|  |         DESTINATION ${ConfigPackageLocation}) | ||||||
|  |  | ||||||
|  | # Install the man pages. | ||||||
|  | set(MAN_PAGES | ||||||
|  |     cwebp.1 | ||||||
|  |     dwebp.1 | ||||||
|  |     gif2webp.1 | ||||||
|  |     img2webp.1 | ||||||
|  |     vwebp.1 | ||||||
|  |     webpmux.1 | ||||||
|  |     webpinfo.1) | ||||||
|  | set(EXEC_BUILDS | ||||||
|  |     "CWEBP" | ||||||
|  |     "DWEBP" | ||||||
|  |     "GIF2WEBP" | ||||||
|  |     "IMG2WEBP" | ||||||
|  |     "VWEBP" | ||||||
|  |     "WEBPMUX" | ||||||
|  |     "WEBPINFO") | ||||||
|  | list(LENGTH MAN_PAGES MAN_PAGES_LENGTH) | ||||||
|  | math(EXPR MAN_PAGES_RANGE "${MAN_PAGES_LENGTH} - 1") | ||||||
|  |  | ||||||
|  | foreach(I_MAN RANGE ${MAN_PAGES_RANGE}) | ||||||
|  |   list(GET EXEC_BUILDS ${I_MAN} EXEC_BUILD) | ||||||
|  |   if(WEBP_BUILD_${EXEC_BUILD}) | ||||||
|  |     list(GET MAN_PAGES ${I_MAN} MAN_PAGE) | ||||||
|  |     install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/man/${MAN_PAGE} | ||||||
|  |             DESTINATION ${CMAKE_INSTALL_MANDIR}/man1 COMPONENT doc) | ||||||
|  |   endif() | ||||||
|  | endforeach() | ||||||
							
								
								
									
										78
									
								
								external/libwebp/libwebp/CONTRIBUTING.md
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										78
									
								
								external/libwebp/libwebp/CONTRIBUTING.md
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,78 @@ | |||||||
|  | # 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. | ||||||
|  |  | ||||||
|  | ## Sending patches | ||||||
|  |  | ||||||
|  | The basic git workflow for modifying libwebp code and sending for review is: | ||||||
|  |  | ||||||
|  | 1.  Get the latest version of the repository locally: | ||||||
|  |  | ||||||
|  |     ```sh | ||||||
|  |     git clone https://chromium.googlesource.com/webm/libwebp && cd libwebp | ||||||
|  |     ``` | ||||||
|  |  | ||||||
|  | 2.  Copy the commit-msg script into ./git/hooks (this will add an ID to all of | ||||||
|  |     your commits): | ||||||
|  |  | ||||||
|  |     ```sh | ||||||
|  |     curl -Lo .git/hooks/commit-msg https://chromium-review.googlesource.com/tools/hooks/commit-msg && chmod u+x .git/hooks/commit-msg | ||||||
|  |     ``` | ||||||
|  |  | ||||||
|  | 3.  Modify the local copy of libwebp. Make sure the code | ||||||
|  |     [builds successfully](https://chromium.googlesource.com/webm/libwebp/+/HEAD/doc/building.md#cmake). | ||||||
|  |  | ||||||
|  | 4.  Choose a short and representative commit message: | ||||||
|  |  | ||||||
|  |     ```sh | ||||||
|  |     git commit -a -m "Set commit message here" | ||||||
|  |     ``` | ||||||
|  |  | ||||||
|  | 5.  Send the patch for review: | ||||||
|  |  | ||||||
|  |     ```sh | ||||||
|  |     git push https://chromium-review.googlesource.com/webm/libwebp HEAD:refs/for/main | ||||||
|  |     ``` | ||||||
|  |  | ||||||
|  |     Go to https://chromium-review.googlesource.com to view your patch and | ||||||
|  |     request a review from the maintainers. | ||||||
|  |  | ||||||
|  | See the | ||||||
|  | [WebM Project page](https://www.webmproject.org/code/contribute/submitting-patches/) | ||||||
|  | for additional details. | ||||||
|  |  | ||||||
|  | ## Code Style | ||||||
|  |  | ||||||
|  | The C code style is based on the | ||||||
|  | [Google C++ Style Guide](https://google.github.io/styleguide/cppguide.html) and | ||||||
|  | `clang-format --style=Google`, though this project doesn't use the tool to | ||||||
|  | enforce the formatting. | ||||||
|  |  | ||||||
|  | CMake files are formatted with | ||||||
|  | [cmake-format](https://cmake-format.readthedocs.io/en/latest/). `cmake-format | ||||||
|  | -i` can be used to format individual files, it will use the settings from | ||||||
|  | `.cmake-format.py`. | ||||||
|  |  | ||||||
|  | ## Community Guidelines | ||||||
|  |  | ||||||
|  | This project follows | ||||||
|  | [Google's Open Source Community Guidelines](https://opensource.google.com/conduct/). | ||||||
							
								
								
									
										30
									
								
								external/libwebp/libwebp/COPYING
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								external/libwebp/libwebp/COPYING
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,30 @@ | |||||||
|  | Copyright (c) 2010, 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. | ||||||
|  |  | ||||||
							
								
								
									
										4622
									
								
								external/libwebp/libwebp/ChangeLog
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										4622
									
								
								external/libwebp/libwebp/ChangeLog
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										9
									
								
								external/libwebp/libwebp/Makefile.am
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								external/libwebp/libwebp/Makefile.am
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | |||||||
|  | ACLOCAL_AMFLAGS = -I m4 | ||||||
|  | SUBDIRS = sharpyuv src imageio man | ||||||
|  | EXTRA_DIST = COPYING autogen.sh | ||||||
|  |  | ||||||
|  | if BUILD_EXTRAS | ||||||
|  |   SUBDIRS += extras | ||||||
|  | endif | ||||||
|  |  | ||||||
|  | SUBDIRS += examples | ||||||
							
								
								
									
										528
									
								
								external/libwebp/libwebp/Makefile.vc
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										528
									
								
								external/libwebp/libwebp/Makefile.vc
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,528 @@ | |||||||
|  | # | ||||||
|  | # Stem for static libs and DLLs | ||||||
|  | # | ||||||
|  | LIBWEBPDECODER_BASENAME = libwebpdecoder | ||||||
|  | LIBWEBP_BASENAME = libwebp | ||||||
|  | LIBWEBPMUX_BASENAME = libwebpmux | ||||||
|  | LIBWEBPDEMUX_BASENAME = libwebpdemux | ||||||
|  | LIBSHARPYUV_BASENAME = libsharpyuv | ||||||
|  |  | ||||||
|  | !IFNDEF ARCH | ||||||
|  | !IF ! [ cl 2>&1 | find "x86" > NUL ] | ||||||
|  | ARCH = x86 | ||||||
|  | !ELSE IF ! [ cl 2>&1 | find "x64" > NUL ] | ||||||
|  | ARCH = x64 | ||||||
|  | !ELSE IF ! [ cl 2>&1 | find "ARM" > NUL ] | ||||||
|  | ARCH = ARM | ||||||
|  | !ELSE | ||||||
|  | !ERROR Unable to auto-detect toolchain architecture! \ | ||||||
|  | If cl.exe is in your PATH rerun nmake with ARCH=<arch>. | ||||||
|  | !ENDIF | ||||||
|  | !ENDIF | ||||||
|  |  | ||||||
|  | !IF "$(ARCH)" == "x86" | ||||||
|  | PLATFORM_LDFLAGS = /SAFESEH | ||||||
|  | !ENDIF | ||||||
|  |  | ||||||
|  | ############################################################# | ||||||
|  | ## Nothing more to do below this line! | ||||||
|  |  | ||||||
|  | NOLOGO     = /nologo | ||||||
|  | CCNODBG    = cl.exe $(NOLOGO) /O2 /DNDEBUG | ||||||
|  | CCDEBUG    = cl.exe $(NOLOGO) /Od /Zi /D_DEBUG /RTC1 | ||||||
|  | CFLAGS     = /I. /Isrc $(NOLOGO) /W3 /EHsc /c | ||||||
|  | CFLAGS     = $(CFLAGS) /DWIN32 /D_CRT_SECURE_NO_WARNINGS /DWIN32_LEAN_AND_MEAN | ||||||
|  | LDFLAGS    = /LARGEADDRESSAWARE /MANIFEST:EMBED /NXCOMPAT /DYNAMICBASE | ||||||
|  | LDFLAGS    = $(LDFLAGS) $(PLATFORM_LDFLAGS) | ||||||
|  | LNKDLL     = link.exe /DLL $(NOLOGO) | ||||||
|  | LNKEXE     = link.exe $(NOLOGO) | ||||||
|  | LNKLIB     = lib.exe $(NOLOGO) | ||||||
|  | RCNODBG    = rc.exe $(NOLOGO) /l"0x0409"  # 0x409 = U.S. English | ||||||
|  | RCDEBUG    = $(RCNODBG) /D_DEBUG | ||||||
|  |  | ||||||
|  | !IF "$(ARCH)" == "ARM" | ||||||
|  | CFLAGS = $(CFLAGS) /DWINAPI_FAMILY=WINAPI_FAMILY_PHONE_APP /DWEBP_USE_THREAD | ||||||
|  | !ELSE | ||||||
|  | CFLAGS = $(CFLAGS) /DHAVE_WINCODEC_H /DWEBP_USE_THREAD | ||||||
|  | !ENDIF | ||||||
|  |  | ||||||
|  | CFGSET     = FALSE | ||||||
|  | !IF "$(OBJDIR)" == "" | ||||||
|  | OUTDIR = ..\obj\ | ||||||
|  | !ELSE | ||||||
|  | OUTDIR = $(OBJDIR) | ||||||
|  | !ENDIF | ||||||
|  |  | ||||||
|  | ############################################################## | ||||||
|  | # Runtime library configuration | ||||||
|  | !IF "$(RTLIBCFG)" == "static" | ||||||
|  | RTLIB  = /MT | ||||||
|  | RTLIBD = /MTd | ||||||
|  | !ELSE IF "$(RTLIBCFG)" == "legacy" | ||||||
|  | RTLIBCFG = static | ||||||
|  | RTLIB  = /MT | ||||||
|  | RTLIBD = /MTd | ||||||
|  | CFLAGS = $(CFLAGS) /GS- /arch:IA32 | ||||||
|  | !ELSE | ||||||
|  | RTLIB   = /MD | ||||||
|  | RTLIBD  = /MDd | ||||||
|  | !ENDIF | ||||||
|  | DIRBASE = $(OUTDIR)\$(CFG)\$(ARCH) | ||||||
|  | DIROBJ = $(DIRBASE)\obj | ||||||
|  | DIRLIB = $(DIRBASE)\lib | ||||||
|  | DIRINC = $(DIRBASE)\include | ||||||
|  | DIRBIN = $(DIRBASE)\bin | ||||||
|  | LIBWEBP_PDBNAME = $(DIROBJ)\$(LIBWEBP_BASENAME).pdb | ||||||
|  | OUTPUT_DIRS = $(DIRBIN) $(DIRINC) $(DIRLIB) \ | ||||||
|  |               $(DIROBJ)\dec \ | ||||||
|  |               $(DIROBJ)\demux \ | ||||||
|  |               $(DIROBJ)\dsp \ | ||||||
|  |               $(DIROBJ)\enc \ | ||||||
|  |               $(DIROBJ)\examples \ | ||||||
|  |               $(DIROBJ)\extras \ | ||||||
|  |               $(DIROBJ)\imageio \ | ||||||
|  |               $(DIROBJ)\mux \ | ||||||
|  |               $(DIROBJ)\sharpyuv \ | ||||||
|  |               $(DIROBJ)\utils \ | ||||||
|  |  | ||||||
|  | # Target configuration | ||||||
|  | !IF "$(CFG)" == "release-static" | ||||||
|  | CC             = $(CCNODBG) | ||||||
|  | STATICLIBBUILD = TRUE | ||||||
|  | !ELSE IF "$(CFG)" == "debug-static" | ||||||
|  | CC             = $(CCDEBUG) | ||||||
|  | RTLIB          = $(RTLIBD) | ||||||
|  | STATICLIBBUILD = TRUE | ||||||
|  | LIBWEBPDECODER_BASENAME = $(LIBWEBPDECODER_BASENAME)_debug | ||||||
|  | LIBWEBP_BASENAME = $(LIBWEBP_BASENAME)_debug | ||||||
|  | LIBWEBPMUX_BASENAME = $(LIBWEBPMUX_BASENAME)_debug | ||||||
|  | LIBWEBPDEMUX_BASENAME = $(LIBWEBPDEMUX_BASENAME)_debug | ||||||
|  | LIBSHARPYUV_BASENAME = $(LIBSHARPYUV_BASENAME)_debug | ||||||
|  | !ELSE IF "$(CFG)" == "release-dynamic" | ||||||
|  | CC        = $(CCNODBG) | ||||||
|  | RC        = $(RCNODBG) | ||||||
|  | DLLBUILD  = TRUE | ||||||
|  | !ELSE IF "$(CFG)" == "debug-dynamic" | ||||||
|  | CC        = $(CCDEBUG) | ||||||
|  | RC        = $(RCDEBUG) | ||||||
|  | RTLIB     = $(RTLIBD) | ||||||
|  | DLLBUILD  = TRUE | ||||||
|  | LIBWEBPDECODER_BASENAME = $(LIBWEBPDECODER_BASENAME)_debug | ||||||
|  | LIBWEBP_BASENAME = $(LIBWEBP_BASENAME)_debug | ||||||
|  | LIBWEBPMUX_BASENAME = $(LIBWEBPMUX_BASENAME)_debug | ||||||
|  | LIBWEBPDEMUX_BASENAME = $(LIBWEBPDEMUX_BASENAME)_debug | ||||||
|  | LIBSHARPYUV_BASENAME = $(LIBSHARPYUV_BASENAME)_debug | ||||||
|  | !ENDIF | ||||||
|  |  | ||||||
|  | !IF "$(STATICLIBBUILD)" == "TRUE" | ||||||
|  | CC     = $(CC) $(RTLIB) | ||||||
|  | CFGSET = TRUE | ||||||
|  | LIBWEBPDECODER = $(DIRLIB)\$(LIBWEBPDECODER_BASENAME).lib | ||||||
|  | LIBWEBP = $(DIRLIB)\$(LIBWEBP_BASENAME).lib | ||||||
|  | LIBWEBPMUX = $(DIRLIB)\$(LIBWEBPMUX_BASENAME).lib | ||||||
|  | LIBWEBPDEMUX = $(DIRLIB)\$(LIBWEBPDEMUX_BASENAME).lib | ||||||
|  | LIBSHARPYUV = $(DIRLIB)\$(LIBSHARPYUV_BASENAME).lib | ||||||
|  | !ELSE IF "$(DLLBUILD)" == "TRUE" | ||||||
|  | CC     = $(CC) /I$(DIROBJ) $(RTLIB) /DWEBP_DLL | ||||||
|  | LIBWEBPDECODER = $(DIRLIB)\$(LIBWEBPDECODER_BASENAME)_dll.lib | ||||||
|  | LIBWEBP = $(DIRLIB)\$(LIBWEBP_BASENAME)_dll.lib | ||||||
|  | LIBWEBPMUX = $(DIRLIB)\$(LIBWEBPMUX_BASENAME)_dll.lib | ||||||
|  | LIBWEBPDEMUX = $(DIRLIB)\$(LIBWEBPDEMUX_BASENAME)_dll.lib | ||||||
|  | LIBSHARPYUV = $(DIRLIB)\$(LIBSHARPYUV_BASENAME)_dll.lib | ||||||
|  | LIBWEBP_PDBNAME = $(DIROBJ)\$(LIBWEBP_BASENAME)_dll.pdb | ||||||
|  | CFGSET = TRUE | ||||||
|  | !ENDIF | ||||||
|  |  | ||||||
|  | !IF "$(UNICODE)" == "1" | ||||||
|  | CFLAGS = $(CFLAGS) /D_UNICODE /DUNICODE | ||||||
|  | !ENDIF | ||||||
|  |  | ||||||
|  | ####################### | ||||||
|  | # Usage | ||||||
|  | # | ||||||
|  | !IF "$(CFGSET)" == "FALSE" | ||||||
|  | !MESSAGE Usage: nmake /f Makefile.vc [CFG=<config>] | ||||||
|  | !MESSAGE .          [OBJDIR=<path>] [RTLIBCFG=<rtlib>] [UNICODE=1] [<target>] | ||||||
|  | !MESSAGE | ||||||
|  | !MESSAGE where <config> is one of: | ||||||
|  | !MESSAGE -  release-static                - release static library | ||||||
|  | !MESSAGE -  debug-static                  - debug static library | ||||||
|  | !MESSAGE -  release-dynamic               - release dynamic link library (DLL) | ||||||
|  | !MESSAGE -  debug-dynamic                 - debug dynamic link library (DLL) | ||||||
|  | !MESSAGE | ||||||
|  | !MESSAGE <target> may be: | ||||||
|  | !MESSAGE -  clean                         - perform a clean for CFG | ||||||
|  | !MESSAGE -  experimental                  - build CFG with experimental | ||||||
|  | !MESSAGE .                                  features enabled. | ||||||
|  | !MESSAGE - (empty)                        - build libwebp-based targets for CFG | ||||||
|  | !MESSAGE - all                            - build (de)mux-based targets for CFG | ||||||
|  | !MESSAGE - gif2webp                       - requires libgif & >= VS2013 | ||||||
|  | !MESSAGE - anim_diff                      - requires libgif & >= VS2013 | ||||||
|  | !MESSAGE - anim_dump | ||||||
|  | !MESSAGE | ||||||
|  | !MESSAGE RTLIBCFG controls the runtime library linkage - 'static' or 'dynamic'. | ||||||
|  | !MESSAGE   'legacy' will produce a Windows 2000 compatible library. | ||||||
|  | !MESSAGE OBJDIR is the path where you like to build (obj, bins, etc.), | ||||||
|  | !MESSAGE   defaults to ..\obj | ||||||
|  |  | ||||||
|  | !IF "$(CFG)" != "" | ||||||
|  | !MESSAGE | ||||||
|  | !ERROR please choose a valid configuration instead of "$(CFG)" | ||||||
|  | !ENDIF | ||||||
|  | !ENDIF | ||||||
|  |  | ||||||
|  | ####################### | ||||||
|  | # Rules | ||||||
|  | # | ||||||
|  | !IF "$(CFGSET)" == "TRUE" | ||||||
|  | # A config was provided, so the library can be built. | ||||||
|  | # | ||||||
|  |  | ||||||
|  | SHARPYUV_OBJS = \ | ||||||
|  |     $(DIROBJ)\sharpyuv\sharpyuv.obj \ | ||||||
|  |     $(DIROBJ)\sharpyuv\sharpyuv_cpu.obj \ | ||||||
|  |     $(DIROBJ)\sharpyuv\sharpyuv_csp.obj \ | ||||||
|  |     $(DIROBJ)\sharpyuv\sharpyuv_dsp.obj \ | ||||||
|  |     $(DIROBJ)\sharpyuv\sharpyuv_gamma.obj \ | ||||||
|  |     $(DIROBJ)\sharpyuv\sharpyuv_neon.obj \ | ||||||
|  |     $(DIROBJ)\sharpyuv\sharpyuv_sse2.obj \ | ||||||
|  |  | ||||||
|  | DEC_OBJS = \ | ||||||
|  |     $(DIROBJ)\dec\alpha_dec.obj \ | ||||||
|  |     $(DIROBJ)\dec\buffer_dec.obj \ | ||||||
|  |     $(DIROBJ)\dec\frame_dec.obj \ | ||||||
|  |     $(DIROBJ)\dec\idec_dec.obj \ | ||||||
|  |     $(DIROBJ)\dec\io_dec.obj \ | ||||||
|  |     $(DIROBJ)\dec\quant_dec.obj \ | ||||||
|  |     $(DIROBJ)\dec\tree_dec.obj \ | ||||||
|  |     $(DIROBJ)\dec\vp8_dec.obj \ | ||||||
|  |     $(DIROBJ)\dec\vp8l_dec.obj \ | ||||||
|  |     $(DIROBJ)\dec\webp_dec.obj \ | ||||||
|  |  | ||||||
|  | DEMUX_OBJS = \ | ||||||
|  |     $(DIROBJ)\demux\anim_decode.obj \ | ||||||
|  |     $(DIROBJ)\demux\demux.obj \ | ||||||
|  |  | ||||||
|  | DSP_DEC_OBJS = \ | ||||||
|  |     $(DIROBJ)\dsp\alpha_processing.obj \ | ||||||
|  |     $(DIROBJ)\dsp\alpha_processing_mips_dsp_r2.obj \ | ||||||
|  |     $(DIROBJ)\dsp\alpha_processing_neon.obj \ | ||||||
|  |     $(DIROBJ)\dsp\alpha_processing_sse2.obj \ | ||||||
|  |     $(DIROBJ)\dsp\alpha_processing_sse41.obj \ | ||||||
|  |     $(DIROBJ)\dsp\cpu.obj \ | ||||||
|  |     $(DIROBJ)\dsp\dec.obj \ | ||||||
|  |     $(DIROBJ)\dsp\dec_clip_tables.obj \ | ||||||
|  |     $(DIROBJ)\dsp\dec_mips32.obj \ | ||||||
|  |     $(DIROBJ)\dsp\dec_mips_dsp_r2.obj \ | ||||||
|  |     $(DIROBJ)\dsp\dec_msa.obj \ | ||||||
|  |     $(DIROBJ)\dsp\dec_neon.obj \ | ||||||
|  |     $(DIROBJ)\dsp\dec_sse2.obj \ | ||||||
|  |     $(DIROBJ)\dsp\dec_sse41.obj \ | ||||||
|  |     $(DIROBJ)\dsp\filters.obj \ | ||||||
|  |     $(DIROBJ)\dsp\filters_mips_dsp_r2.obj \ | ||||||
|  |     $(DIROBJ)\dsp\filters_msa.obj \ | ||||||
|  |     $(DIROBJ)\dsp\filters_neon.obj \ | ||||||
|  |     $(DIROBJ)\dsp\filters_sse2.obj \ | ||||||
|  |     $(DIROBJ)\dsp\lossless.obj \ | ||||||
|  |     $(DIROBJ)\dsp\lossless_mips_dsp_r2.obj \ | ||||||
|  |     $(DIROBJ)\dsp\lossless_msa.obj \ | ||||||
|  |     $(DIROBJ)\dsp\lossless_neon.obj \ | ||||||
|  |     $(DIROBJ)\dsp\lossless_sse2.obj \ | ||||||
|  |     $(DIROBJ)\dsp\lossless_sse41.obj \ | ||||||
|  |     $(DIROBJ)\dsp\rescaler.obj \ | ||||||
|  |     $(DIROBJ)\dsp\rescaler_mips32.obj \ | ||||||
|  |     $(DIROBJ)\dsp\rescaler_mips_dsp_r2.obj \ | ||||||
|  |     $(DIROBJ)\dsp\rescaler_msa.obj \ | ||||||
|  |     $(DIROBJ)\dsp\rescaler_neon.obj \ | ||||||
|  |     $(DIROBJ)\dsp\rescaler_sse2.obj \ | ||||||
|  |     $(DIROBJ)\dsp\upsampling.obj \ | ||||||
|  |     $(DIROBJ)\dsp\upsampling_mips_dsp_r2.obj \ | ||||||
|  |     $(DIROBJ)\dsp\upsampling_msa.obj \ | ||||||
|  |     $(DIROBJ)\dsp\upsampling_neon.obj \ | ||||||
|  |     $(DIROBJ)\dsp\upsampling_sse2.obj \ | ||||||
|  |     $(DIROBJ)\dsp\upsampling_sse41.obj \ | ||||||
|  |     $(DIROBJ)\dsp\yuv.obj \ | ||||||
|  |     $(DIROBJ)\dsp\yuv_mips32.obj \ | ||||||
|  |     $(DIROBJ)\dsp\yuv_mips_dsp_r2.obj \ | ||||||
|  |     $(DIROBJ)\dsp\yuv_neon.obj \ | ||||||
|  |     $(DIROBJ)\dsp\yuv_sse2.obj \ | ||||||
|  |     $(DIROBJ)\dsp\yuv_sse41.obj \ | ||||||
|  |  | ||||||
|  | DSP_ENC_OBJS = \ | ||||||
|  |     $(DIROBJ)\dsp\cost.obj \ | ||||||
|  |     $(DIROBJ)\dsp\cost_mips32.obj \ | ||||||
|  |     $(DIROBJ)\dsp\cost_mips_dsp_r2.obj \ | ||||||
|  |     $(DIROBJ)\dsp\cost_neon.obj \ | ||||||
|  |     $(DIROBJ)\dsp\cost_sse2.obj \ | ||||||
|  |     $(DIROBJ)\dsp\enc.obj \ | ||||||
|  |     $(DIROBJ)\dsp\enc_mips32.obj \ | ||||||
|  |     $(DIROBJ)\dsp\enc_mips_dsp_r2.obj \ | ||||||
|  |     $(DIROBJ)\dsp\enc_msa.obj \ | ||||||
|  |     $(DIROBJ)\dsp\enc_neon.obj \ | ||||||
|  |     $(DIROBJ)\dsp\enc_sse2.obj \ | ||||||
|  |     $(DIROBJ)\dsp\enc_sse41.obj \ | ||||||
|  |     $(DIROBJ)\dsp\lossless_enc.obj \ | ||||||
|  |     $(DIROBJ)\dsp\lossless_enc_mips32.obj \ | ||||||
|  |     $(DIROBJ)\dsp\lossless_enc_mips_dsp_r2.obj \ | ||||||
|  |     $(DIROBJ)\dsp\lossless_enc_msa.obj \ | ||||||
|  |     $(DIROBJ)\dsp\lossless_enc_neon.obj \ | ||||||
|  |     $(DIROBJ)\dsp\lossless_enc_sse2.obj \ | ||||||
|  |     $(DIROBJ)\dsp\lossless_enc_sse41.obj \ | ||||||
|  |     $(DIROBJ)\dsp\ssim.obj \ | ||||||
|  |     $(DIROBJ)\dsp\ssim_sse2.obj \ | ||||||
|  |  | ||||||
|  | EX_ANIM_UTIL_OBJS = \ | ||||||
|  |     $(DIROBJ)\examples\anim_util.obj \ | ||||||
|  |  | ||||||
|  | IMAGEIO_DEC_OBJS = \ | ||||||
|  |     $(DIROBJ)\imageio\image_dec.obj \ | ||||||
|  |     $(DIROBJ)\imageio\jpegdec.obj \ | ||||||
|  |     $(DIROBJ)\imageio\metadata.obj \ | ||||||
|  |     $(DIROBJ)\imageio\pngdec.obj \ | ||||||
|  |     $(DIROBJ)\imageio\pnmdec.obj \ | ||||||
|  |     $(DIROBJ)\imageio\tiffdec.obj \ | ||||||
|  |     $(DIROBJ)\imageio\webpdec.obj \ | ||||||
|  |     $(DIROBJ)\imageio\wicdec.obj \ | ||||||
|  |  | ||||||
|  | IMAGEIO_ENC_OBJS = \ | ||||||
|  |     $(DIROBJ)\imageio\image_enc.obj \ | ||||||
|  |  | ||||||
|  | EX_GIF_DEC_OBJS = \ | ||||||
|  |     $(DIROBJ)\examples\gifdec.obj \ | ||||||
|  |  | ||||||
|  | EX_UTIL_OBJS = \ | ||||||
|  |     $(DIROBJ)\examples\example_util.obj \ | ||||||
|  |  | ||||||
|  | ENC_OBJS = \ | ||||||
|  |     $(DIROBJ)\enc\alpha_enc.obj \ | ||||||
|  |     $(DIROBJ)\enc\analysis_enc.obj \ | ||||||
|  |     $(DIROBJ)\enc\backward_references_cost_enc.obj \ | ||||||
|  |     $(DIROBJ)\enc\backward_references_enc.obj \ | ||||||
|  |     $(DIROBJ)\enc\config_enc.obj \ | ||||||
|  |     $(DIROBJ)\enc\cost_enc.obj \ | ||||||
|  |     $(DIROBJ)\enc\filter_enc.obj \ | ||||||
|  |     $(DIROBJ)\enc\frame_enc.obj \ | ||||||
|  |     $(DIROBJ)\enc\histogram_enc.obj \ | ||||||
|  |     $(DIROBJ)\enc\iterator_enc.obj \ | ||||||
|  |     $(DIROBJ)\enc\near_lossless_enc.obj \ | ||||||
|  |     $(DIROBJ)\enc\picture_enc.obj \ | ||||||
|  |     $(DIROBJ)\enc\picture_csp_enc.obj \ | ||||||
|  |     $(DIROBJ)\enc\picture_psnr_enc.obj \ | ||||||
|  |     $(DIROBJ)\enc\picture_rescale_enc.obj \ | ||||||
|  |     $(DIROBJ)\enc\picture_tools_enc.obj \ | ||||||
|  |     $(DIROBJ)\enc\predictor_enc.obj \ | ||||||
|  |     $(DIROBJ)\enc\quant_enc.obj \ | ||||||
|  |     $(DIROBJ)\enc\syntax_enc.obj \ | ||||||
|  |     $(DIROBJ)\enc\token_enc.obj \ | ||||||
|  |     $(DIROBJ)\enc\tree_enc.obj \ | ||||||
|  |     $(DIROBJ)\enc\vp8l_enc.obj \ | ||||||
|  |     $(DIROBJ)\enc\webp_enc.obj \ | ||||||
|  |  | ||||||
|  | EXTRAS_OBJS = \ | ||||||
|  |     $(DIROBJ)\extras\extras.obj \ | ||||||
|  |     $(DIROBJ)\extras\quality_estimate.obj \ | ||||||
|  |  | ||||||
|  | IMAGEIO_UTIL_OBJS = \ | ||||||
|  |     $(DIROBJ)\imageio\imageio_util.obj \ | ||||||
|  |  | ||||||
|  | MUX_OBJS = \ | ||||||
|  |     $(DIROBJ)\mux\anim_encode.obj \ | ||||||
|  |     $(DIROBJ)\mux\muxedit.obj \ | ||||||
|  |     $(DIROBJ)\mux\muxinternal.obj \ | ||||||
|  |     $(DIROBJ)\mux\muxread.obj \ | ||||||
|  |  | ||||||
|  | UTILS_DEC_OBJS = \ | ||||||
|  |     $(DIROBJ)\utils\bit_reader_utils.obj \ | ||||||
|  |     $(DIROBJ)\utils\color_cache_utils.obj \ | ||||||
|  |     $(DIROBJ)\utils\filters_utils.obj \ | ||||||
|  |     $(DIROBJ)\utils\huffman_utils.obj \ | ||||||
|  |     $(DIROBJ)\utils\palette.obj \ | ||||||
|  |     $(DIROBJ)\utils\quant_levels_dec_utils.obj \ | ||||||
|  |     $(DIROBJ)\utils\rescaler_utils.obj \ | ||||||
|  |     $(DIROBJ)\utils\random_utils.obj \ | ||||||
|  |     $(DIROBJ)\utils\thread_utils.obj \ | ||||||
|  |     $(DIROBJ)\utils\utils.obj \ | ||||||
|  |  | ||||||
|  | UTILS_ENC_OBJS = \ | ||||||
|  |     $(DIROBJ)\utils\bit_writer_utils.obj \ | ||||||
|  |     $(DIROBJ)\utils\huffman_encode_utils.obj \ | ||||||
|  |     $(DIROBJ)\utils\quant_levels_utils.obj \ | ||||||
|  |  | ||||||
|  | LIBWEBPDECODER_OBJS = $(DEC_OBJS) $(DSP_DEC_OBJS) $(UTILS_DEC_OBJS) | ||||||
|  | LIBWEBP_OBJS = $(LIBWEBPDECODER_OBJS) $(ENC_OBJS) \ | ||||||
|  |                $(DSP_ENC_OBJS) $(UTILS_ENC_OBJS) $(DLL_OBJS) | ||||||
|  | LIBWEBPMUX_OBJS = $(MUX_OBJS) $(LIBWEBPMUX_OBJS) | ||||||
|  | LIBWEBPDEMUX_OBJS = $(DEMUX_OBJS) $(LIBWEBPDEMUX_OBJS) | ||||||
|  | LIBSHARPYUV_OBJS = $(SHARPYUV_OBJS) | ||||||
|  |  | ||||||
|  | OUT_LIBS = $(LIBWEBPDECODER) $(LIBWEBP) $(LIBSHARPYUV) | ||||||
|  | !IF "$(ARCH)" == "ARM" | ||||||
|  | ex: $(OUT_LIBS) | ||||||
|  | all: ex | ||||||
|  | !ELSE | ||||||
|  | OUT_EXAMPLES = $(DIRBIN)\cwebp.exe $(DIRBIN)\dwebp.exe | ||||||
|  | EXTRA_EXAMPLES = $(DIRBIN)\vwebp.exe $(DIRBIN)\webpmux.exe \ | ||||||
|  |                  $(DIRBIN)\img2webp.exe $(DIRBIN)\get_disto.exe \ | ||||||
|  |                  $(DIRBIN)\webp_quality.exe $(DIRBIN)\vwebp_sdl.exe \ | ||||||
|  |                  $(DIRBIN)\webpinfo.exe | ||||||
|  |  | ||||||
|  | ex: $(OUT_LIBS) $(OUT_EXAMPLES) | ||||||
|  | all: ex $(EXTRA_EXAMPLES) | ||||||
|  | # NB: gif2webp.exe and anim_diff.exe are excluded from 'all' as libgif requires | ||||||
|  | # C99 support which is only available from VS2013 onward. | ||||||
|  | gif2webp: $(DIRBIN)\gif2webp.exe | ||||||
|  | anim_diff: $(DIRBIN)\anim_diff.exe | ||||||
|  | anim_dump: $(DIRBIN)\anim_dump.exe | ||||||
|  |  | ||||||
|  | $(DIRBIN)\anim_diff.exe: $(DIROBJ)\examples\anim_diff.obj $(EX_ANIM_UTIL_OBJS) | ||||||
|  | $(DIRBIN)\anim_diff.exe: $(EX_UTIL_OBJS) $(IMAGEIO_UTIL_OBJS) | ||||||
|  | $(DIRBIN)\anim_diff.exe: $(EX_GIF_DEC_OBJS) $(LIBWEBPDEMUX) $(LIBWEBP) | ||||||
|  | $(DIRBIN)\anim_dump.exe: $(DIROBJ)\examples\anim_dump.obj $(EX_ANIM_UTIL_OBJS) | ||||||
|  | $(DIRBIN)\anim_dump.exe: $(EX_UTIL_OBJS) $(IMAGEIO_UTIL_OBJS) | ||||||
|  | $(DIRBIN)\anim_dump.exe: $(EX_GIF_DEC_OBJS) $(LIBWEBPDEMUX) $(LIBWEBP) | ||||||
|  | $(DIRBIN)\anim_dump.exe: $(IMAGEIO_ENC_OBJS) | ||||||
|  | $(DIRBIN)\cwebp.exe: $(DIROBJ)\examples\cwebp.obj $(IMAGEIO_DEC_OBJS) | ||||||
|  | $(DIRBIN)\cwebp.exe: $(IMAGEIO_UTIL_OBJS) | ||||||
|  | $(DIRBIN)\cwebp.exe: $(LIBWEBPDEMUX) $(LIBSHARPYUV) | ||||||
|  | $(DIRBIN)\dwebp.exe: $(DIROBJ)\examples\dwebp.obj $(IMAGEIO_DEC_OBJS) | ||||||
|  | $(DIRBIN)\dwebp.exe: $(IMAGEIO_ENC_OBJS) | ||||||
|  | $(DIRBIN)\dwebp.exe: $(IMAGEIO_UTIL_OBJS) | ||||||
|  | $(DIRBIN)\dwebp.exe: $(LIBWEBPDEMUX) | ||||||
|  | $(DIRBIN)\gif2webp.exe: $(DIROBJ)\examples\gif2webp.obj $(EX_GIF_DEC_OBJS) | ||||||
|  | $(DIRBIN)\gif2webp.exe: $(EX_UTIL_OBJS) $(IMAGEIO_UTIL_OBJS) $(LIBWEBPMUX) | ||||||
|  | $(DIRBIN)\gif2webp.exe: $(LIBWEBP) | ||||||
|  | $(DIRBIN)\vwebp.exe: $(DIROBJ)\examples\vwebp.obj $(EX_UTIL_OBJS) | ||||||
|  | $(DIRBIN)\vwebp.exe: $(IMAGEIO_UTIL_OBJS) $(LIBWEBPDEMUX) $(LIBWEBP) | ||||||
|  | $(DIRBIN)\vwebp_sdl.exe: $(DIROBJ)\extras\vwebp_sdl.obj | ||||||
|  | $(DIRBIN)\vwebp_sdl.exe: $(DIROBJ)\extras\webp_to_sdl.obj | ||||||
|  | $(DIRBIN)\vwebp_sdl.exe: $(IMAGEIO_UTIL_OBJS) $(LIBWEBP) | ||||||
|  | $(DIRBIN)\webpmux.exe: $(DIROBJ)\examples\webpmux.obj $(LIBWEBPMUX) | ||||||
|  | $(DIRBIN)\webpmux.exe: $(EX_UTIL_OBJS) $(IMAGEIO_UTIL_OBJS) $(LIBWEBP) | ||||||
|  | $(DIRBIN)\img2webp.exe: $(DIROBJ)\examples\img2webp.obj $(LIBWEBPMUX) | ||||||
|  | $(DIRBIN)\img2webp.exe: $(IMAGEIO_DEC_OBJS) | ||||||
|  | $(DIRBIN)\img2webp.exe: $(EX_UTIL_OBJS) $(IMAGEIO_UTIL_OBJS) | ||||||
|  | $(DIRBIN)\img2webp.exe: $(LIBWEBPDEMUX) $(LIBWEBP) $(LIBSHARPYUV) | ||||||
|  | $(DIRBIN)\get_disto.exe: $(DIROBJ)\extras\get_disto.obj | ||||||
|  | $(DIRBIN)\get_disto.exe: $(IMAGEIO_DEC_OBJS) $(IMAGEIO_UTIL_OBJS) | ||||||
|  | $(DIRBIN)\get_disto.exe: $(LIBWEBPDEMUX) $(LIBWEBP) | ||||||
|  | $(DIRBIN)\webp_quality.exe: $(DIROBJ)\extras\webp_quality.obj | ||||||
|  | $(DIRBIN)\webp_quality.exe: $(IMAGEIO_UTIL_OBJS) | ||||||
|  | $(DIRBIN)\webp_quality.exe: $(EXTRAS_OBJS) | ||||||
|  | # EXTRA_OBJS requires private symbols from dsp. Explicitly add those when | ||||||
|  | # building libwebp as a dll. | ||||||
|  | !IF "$(DLLBUILD)" == "TRUE" | ||||||
|  | $(DIRBIN)\webp_quality.exe: $(DSP_DEC_OBJS) | ||||||
|  | !ENDIF | ||||||
|  | $(DIRBIN)\webp_quality.exe: $(LIBWEBP) | ||||||
|  | $(DIRBIN)\webpinfo.exe: $(DIROBJ)\examples\webpinfo.obj | ||||||
|  | $(DIRBIN)\webpinfo.exe: $(IMAGEIO_DEC_OBJS) | ||||||
|  | $(DIRBIN)\webpinfo.exe: $(EX_UTIL_OBJS) $(IMAGEIO_UTIL_OBJS) | ||||||
|  | $(DIRBIN)\webpinfo.exe: $(LIBWEBPDEMUX) $(LIBWEBP) | ||||||
|  |  | ||||||
|  | $(OUT_EXAMPLES): $(EX_UTIL_OBJS) $(LIBWEBP) | ||||||
|  | $(EX_UTIL_OBJS) $(IMAGEIO_UTIL_OBJS): $(OUTPUT_DIRS) | ||||||
|  | $(IMAGEIO_DEC_OBJS) $(IMAGEIO_ENC_OBJS) $(EXTRAS_OBJS): $(OUTPUT_DIRS) | ||||||
|  | !ENDIF  # ARCH == ARM | ||||||
|  |  | ||||||
|  | $(LIBSHARPYUV): $(LIBSHARPYUV_OBJS) | ||||||
|  | $(LIBWEBPDECODER): $(LIBWEBPDECODER_OBJS) | ||||||
|  | $(LIBWEBP): $(LIBWEBP_OBJS) $(LIBSHARPYUV) | ||||||
|  | $(LIBWEBPMUX): $(LIBWEBPMUX_OBJS) | ||||||
|  | $(LIBWEBPDEMUX): $(LIBWEBPDEMUX_OBJS) | ||||||
|  |  | ||||||
|  | $(LIBWEBP_OBJS) $(LIBWEBPMUX_OBJS) $(LIBWEBPDEMUX_OBJS) $(LIBSHARPYUV_OBJS): \ | ||||||
|  |     $(OUTPUT_DIRS) | ||||||
|  |  | ||||||
|  | !IF "$(DLLBUILD)" == "TRUE" | ||||||
|  | {$(DIROBJ)}.c{$(DIROBJ)}.obj: | ||||||
|  | 	$(CC) $(CFLAGS) /Fd$(LIBWEBP_PDBNAME) /Fo$@  $< | ||||||
|  |  | ||||||
|  | {src}.rc{$(DIROBJ)}.res: | ||||||
|  | 	$(RC) /fo$@ $< | ||||||
|  | {src\demux}.rc{$(DIROBJ)\demux}.res: | ||||||
|  | 	$(RC) /fo$@ $< | ||||||
|  | {src\mux}.rc{$(DIROBJ)\mux}.res: | ||||||
|  | 	$(RC) /fo$@ $< | ||||||
|  | {sharpyuv}.rc{$(DIROBJ)\sharpyuv}.res: | ||||||
|  | 	$(RC) /fo$@ $< | ||||||
|  |  | ||||||
|  | $(LIBSHARPYUV): $(DIROBJ)\sharpyuv\$(LIBSHARPYUV_BASENAME:_debug=).res | ||||||
|  | $(LIBWEBP): $(LIBSHARPYUV) $(DIROBJ)\$(LIBWEBP_BASENAME:_debug=).res | ||||||
|  | $(LIBWEBPDECODER): $(DIROBJ)\$(LIBWEBPDECODER_BASENAME:_debug=).res | ||||||
|  | $(LIBWEBPMUX): $(LIBWEBP) $(DIROBJ)\mux\$(LIBWEBPMUX_BASENAME:_debug=).res | ||||||
|  | $(LIBWEBPDEMUX): $(LIBWEBP) $(DIROBJ)\demux\$(LIBWEBPDEMUX_BASENAME:_debug=).res | ||||||
|  |  | ||||||
|  | $(LIBWEBPDECODER) $(LIBWEBP) $(LIBWEBPMUX) $(LIBWEBPDEMUX) $(LIBSHARPYUV): | ||||||
|  | 	$(LNKDLL) /out:$(DIRBIN)\$(@B:_dll=.dll) /implib:$@ $(LFLAGS) $** | ||||||
|  | 	-xcopy $(DIROBJ)\*.pdb $(DIRLIB) /y | ||||||
|  | !ELSE | ||||||
|  | $(LIBWEBPDECODER) $(LIBWEBP) $(LIBWEBPMUX) $(LIBWEBPDEMUX) $(LIBSHARPYUV): | ||||||
|  | 	$(LNKLIB) /out:$@ $** | ||||||
|  | 	-xcopy $(DIROBJ)\*.pdb $(DIRLIB) /y | ||||||
|  | !ENDIF | ||||||
|  |  | ||||||
|  | $(OUTPUT_DIRS): | ||||||
|  | 	@if not exist "$(@)" mkdir "$(@)" | ||||||
|  |  | ||||||
|  | .SUFFIXES: .c .obj .res .exe | ||||||
|  | # File-specific flag builds. Note batch rules take precedence over wildcards, | ||||||
|  | # so for now name each file individually. | ||||||
|  | $(DIROBJ)\examples\anim_diff.obj: examples\anim_diff.c | ||||||
|  | 	$(CC) $(CFLAGS) /DWEBP_HAVE_GIF /Fd$(LIBWEBP_PDBNAME) \ | ||||||
|  | 	  /Fo$(DIROBJ)\examples\ examples\$(@B).c | ||||||
|  | $(DIROBJ)\examples\anim_dump.obj: examples\anim_dump.c | ||||||
|  | 	$(CC) $(CFLAGS) /DWEBP_HAVE_GIF /Fd$(LIBWEBP_PDBNAME) \ | ||||||
|  | 	  /Fo$(DIROBJ)\examples\ examples\$(@B).c | ||||||
|  | $(DIROBJ)\examples\anim_util.obj: examples\anim_util.c | ||||||
|  | 	$(CC) $(CFLAGS) /DWEBP_HAVE_GIF /Fd$(LIBWEBP_PDBNAME) \ | ||||||
|  | 	  /Fo$(DIROBJ)\examples\ examples\$(@B).c | ||||||
|  | $(DIROBJ)\examples\gif2webp.obj: examples\gif2webp.c | ||||||
|  | 	$(CC) $(CFLAGS) /DWEBP_HAVE_GIF /Fd$(LIBWEBP_PDBNAME) \ | ||||||
|  | 	  /Fo$(DIROBJ)\examples\ examples\$(@B).c | ||||||
|  | $(DIROBJ)\examples\gifdec.obj: examples\gifdec.c | ||||||
|  | 	$(CC) $(CFLAGS) /DWEBP_HAVE_GIF /Fd$(LIBWEBP_PDBNAME) \ | ||||||
|  | 	  /Fo$(DIROBJ)\examples\ examples\$(@B).c | ||||||
|  | # Batch rules | ||||||
|  | {examples}.c{$(DIROBJ)\examples}.obj:: | ||||||
|  | 	$(CC) $(CFLAGS) /Fd$(DIROBJ)\examples\ /Fo$(DIROBJ)\examples\ $< | ||||||
|  | {extras}.c{$(DIROBJ)\extras}.obj:: | ||||||
|  | 	$(CC) $(CFLAGS) /Fd$(DIROBJ)\extras\ /Fo$(DIROBJ)\extras\ $< | ||||||
|  | {imageio}.c{$(DIROBJ)\imageio}.obj:: | ||||||
|  | 	$(CC) $(CFLAGS) /Fd$(DIROBJ)\imageio\ /Fo$(DIROBJ)\imageio\ $< | ||||||
|  | {sharpyuv}.c{$(DIROBJ)\sharpyuv}.obj:: | ||||||
|  | 	$(CC) $(CFLAGS) /Fd$(DIROBJ)\sharpyuv\ /Fo$(DIROBJ)\sharpyuv\ $< | ||||||
|  | {src\dec}.c{$(DIROBJ)\dec}.obj:: | ||||||
|  | 	$(CC) $(CFLAGS) /Fd$(LIBWEBP_PDBNAME) /Fo$(DIROBJ)\dec\ $< | ||||||
|  | {src\demux}.c{$(DIROBJ)\demux}.obj:: | ||||||
|  | 	$(CC) $(CFLAGS) /Fd$(LIBWEBP_PDBNAME) /Fo$(DIROBJ)\demux\ $< | ||||||
|  | {src\dsp}.c{$(DIROBJ)\dsp}.obj:: | ||||||
|  | 	$(CC) $(CFLAGS) /Fd$(LIBWEBP_PDBNAME) /Fo$(DIROBJ)\dsp\ $< | ||||||
|  | {src\enc}.c{$(DIROBJ)\enc}.obj:: | ||||||
|  | 	$(CC) $(CFLAGS) /Fd$(LIBWEBP_PDBNAME) /Fo$(DIROBJ)\enc\ $< | ||||||
|  | {src\mux}.c{$(DIROBJ)\mux}.obj:: | ||||||
|  | 	$(CC) $(CFLAGS) /Fd$(LIBWEBP_PDBNAME) /Fo$(DIROBJ)\mux\ $< | ||||||
|  | {src\utils}.c{$(DIROBJ)\utils}.obj:: | ||||||
|  | 	$(CC) $(CFLAGS) /Fd$(LIBWEBP_PDBNAME) /Fo$(DIROBJ)\utils\ $< | ||||||
|  |  | ||||||
|  | LNKLIBS     = ole32.lib windowscodecs.lib shlwapi.lib | ||||||
|  | !IF "$(UNICODE)" == "1" | ||||||
|  | LNKLIBS     = $(LNKLIBS) Shell32.lib | ||||||
|  | !ENDIF | ||||||
|  |  | ||||||
|  | {$(DIROBJ)\examples}.obj{$(DIRBIN)}.exe: | ||||||
|  | 	$(LNKEXE) $(LDFLAGS) /OUT:$@ $** $(LNKLIBS) | ||||||
|  |  | ||||||
|  | {$(DIROBJ)\extras}.obj{$(DIRBIN)}.exe: | ||||||
|  | 	$(LNKEXE) $(LDFLAGS) /OUT:$@ $** $(LNKLIBS) | ||||||
|  |  | ||||||
|  | clean:: | ||||||
|  | 	@-erase /s $(DIROBJ)\*.dll 2> NUL | ||||||
|  | 	@-erase /s $(DIROBJ)\*.exp 2> NUL | ||||||
|  | 	@-erase /s $(DIROBJ)\*.idb 2> NUL | ||||||
|  | 	@-erase /s $(DIROBJ)\*.lib 2> NUL | ||||||
|  | 	@-erase /s $(DIROBJ)\*.obj 2> NUL | ||||||
|  | 	@-erase /s $(DIROBJ)\*.pch 2> NUL | ||||||
|  | 	@-erase /s $(DIROBJ)\*.pdb 2> NUL | ||||||
|  | 	@-erase /s $(DIROBJ)\*.res 2> NUL | ||||||
|  |  | ||||||
|  | !ENDIF  # End of case where a config was provided. | ||||||
							
								
								
									
										311
									
								
								external/libwebp/libwebp/NEWS
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										311
									
								
								external/libwebp/libwebp/NEWS
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,311 @@ | |||||||
|  | - 6/23/2023: version 1.3.1 | ||||||
|  |   This is a binary compatible release. | ||||||
|  |   * security fixes for lossless encoder (#603, chromium: #1420107, #1455619, | ||||||
|  |     CVE-2023-1999) | ||||||
|  |   * improve error reporting through WebPPicture error codes | ||||||
|  |   * fix upsampling for RGB565 and RGBA4444 in NEON builds | ||||||
|  |   * img2webp: add -sharp_yuv & -near_lossless | ||||||
|  |   * Windows builds: | ||||||
|  |     - fix compatibility with clang-cl (#607) | ||||||
|  |     - improve Arm64 performance with cl.exe | ||||||
|  |     - add Arm64EC support | ||||||
|  |   * fix webp_js with emcc >= 3.1.27 (stack size change, #614) | ||||||
|  |   * CMake fixes (#592, #610, #612) | ||||||
|  |   * further updates to the container and lossless bitstream docs (#581, #611) | ||||||
|  |  | ||||||
|  | - 12/16/2022: version 1.3.0 | ||||||
|  |   This is a binary compatible release. | ||||||
|  |   * add libsharpyuv, which exposes -sharp_yuv/config.use_sharp_yuv | ||||||
|  |     functionality to other libraries; libwebp now depends on this library | ||||||
|  |   * major updates to the container and lossless bitstream docs (#448, #546, | ||||||
|  |     #551) | ||||||
|  |   * miscellaneous warning, bug & build fixes (#576, #583, #584) | ||||||
|  |  | ||||||
|  | - 8/4/2022: version 1.2.4 | ||||||
|  |   This is a binary compatible release. | ||||||
|  |   * restore CMake libwebpmux target name for compatibility with 1.2.2 (#575) | ||||||
|  |   * fix lossless crunch mode encoding with WEBP_REDUCE_SIZE | ||||||
|  |     (chromium: #1345547, #1345595, #1345772, #1345804) | ||||||
|  |  | ||||||
|  | - 6/30/2022: version 1.2.3 | ||||||
|  |   This is a binary compatible release. | ||||||
|  |   * security fix for lossless encoder (#565, chromium:1313709) | ||||||
|  |   * improved progress granularity in WebPReportProgress() when using lossless | ||||||
|  |   * improved precision in Sharp YUV (-sharp_yuv) conversion | ||||||
|  |   * many corrections to webp-lossless-bitstream-spec.txt (#551) | ||||||
|  |   * crash/leak fixes on error/OOM and other bug fixes (#558, #563, #569, #573) | ||||||
|  |  | ||||||
|  | - 1/11/2022: version 1.2.2 | ||||||
|  |   This is a binary compatible release. | ||||||
|  |   * webpmux: add "-set bgcolor A,R,G,B" | ||||||
|  |   * add ARM64 NEON support for MSVC builds (#539) | ||||||
|  |   * fix duplicate include error in Xcode when using multiple XCFrameworks in a | ||||||
|  |     project (#542) | ||||||
|  |   * doc updates and bug fixes (#538, #544, #548, #550) | ||||||
|  |  | ||||||
|  | - 7/20/2021: version 1.2.1 | ||||||
|  |   This is a binary compatible release. | ||||||
|  |   * minor lossless encoder improvements and x86 color conversion speed up | ||||||
|  |   * add ARM64 simulator support to xcframeworkbuild.sh (#510) | ||||||
|  |   * further security related hardening in libwebp & examples | ||||||
|  |     (issues: #497, #508, #518) | ||||||
|  |     (chromium: #1196480, #1196773, #1196775, #1196777, #1196778, #1196850) | ||||||
|  |     (oss-fuzz: #28658, #28978) | ||||||
|  |   * toolchain updates and bug fixes (#498, #501, #502, #504, #505, #506, #509, | ||||||
|  |                                      #533) | ||||||
|  |   * use more inclusive language within the source (#507) | ||||||
|  |  | ||||||
|  | - 12/23/2020: version 1.2.0 | ||||||
|  |   * API changes: | ||||||
|  |     - libwebp: | ||||||
|  |       encode.h: add a qmin / qmax range for quality factor (cwebp adds -qrange) | ||||||
|  |   * lossless encoder improvements | ||||||
|  |   * SIMD support for Wasm builds | ||||||
|  |   * add xcframeworkbuild.sh, supports Mac Catalyst builds | ||||||
|  |   * import fuzzers from oss-fuzz & chromium (#409) | ||||||
|  |   * webpmux: add an '-set loop <value>' option (#494) | ||||||
|  |   * toolchain updates and bug fixes (#449, #463, #470, #475, #477, #478, #479, | ||||||
|  |     #488, #491) | ||||||
|  |  | ||||||
|  | - 12/18/2019: version 1.1.0 | ||||||
|  |   * API changes: | ||||||
|  |     - libwebp: | ||||||
|  |       WebPMalloc (issue #442) | ||||||
|  |     - extras: | ||||||
|  |       WebPUnmultiplyARGB | ||||||
|  |   * alpha decode fix (issue #439) | ||||||
|  |   * toolchain updates and bug fixes | ||||||
|  |     (chromium: #1026858, #1027136, #1027409, #1028620, #1028716, #995200) | ||||||
|  |     (oss-fuzz: #19430, #19447) | ||||||
|  |  | ||||||
|  | - 7/4/2019: version 1.0.3 | ||||||
|  |   This is a binary compatible release. | ||||||
|  |   * resize fixes for Nx1 sizes and the addition of non-opaque alpha values for | ||||||
|  |     odd sizes (issues #418, #434) | ||||||
|  |   * lossless encode/decode performance improvements | ||||||
|  |   * lossy compression performance improvement at low quality levels with flat | ||||||
|  |     content (issue #432) | ||||||
|  |   * python swig files updated to support python 3 | ||||||
|  |   Tool updates: | ||||||
|  |     vwebp will now preserve the aspect ratio of images that exceed monitor | ||||||
|  |     resolution by scaling the image to fit (issue #433) | ||||||
|  |  | ||||||
|  | - 1/14/2019: version 1.0.2 | ||||||
|  |   This is a binary compatible release. | ||||||
|  |   * (Windows) unicode file support in the tools (linux and mac already had | ||||||
|  |     support, issue #398) | ||||||
|  |   * lossless encoder speedups | ||||||
|  |   * lossy encoder speedup on ARM | ||||||
|  |   * lossless multi-threaded security fix (chromium:917029) | ||||||
|  |  | ||||||
|  | - 11/2/2018: version 1.0.1 | ||||||
|  |   This is a binary compatible release. | ||||||
|  |   * lossless encoder speedups | ||||||
|  |   * big-endian fix for alpha decoding (issue #393) | ||||||
|  |   * gif2webp fix for loop count=65535 transcode (issue #382) | ||||||
|  |   * further security related hardening in libwebp & libwebpmux | ||||||
|  |     (issues #383, #385, #386, #387, #388, #391) | ||||||
|  |     (oss-fuzz #9099, #9100, #9105, #9106, #9111, #9112, #9119, #9123, #9170, | ||||||
|  |               #9178, #9179, #9183, #9186, #9191, #9364, #9417, #9496, #10349, | ||||||
|  |               #10423, #10634, #10700, #10838, #10922, #11021, #11088, #11152) | ||||||
|  |   * miscellaneous bug & build fixes (issues #381, #394, #396, #397, #400) | ||||||
|  |  | ||||||
|  | - 4/2/2018: version 1.0.0 | ||||||
|  |   This is a binary compatible release. | ||||||
|  |   * lossy encoder improvements to avoid chroma shifts in various circumstances | ||||||
|  |     (issues #308, #340) | ||||||
|  |   * big-endian fixes for decode, RGBA import and WebPPictureDistortion | ||||||
|  |   Tool updates: | ||||||
|  |     gifwebp, anim_diff - default duration behavior (<= 10ms) changed to match | ||||||
|  |                          web browsers, transcoding tools (issue #379) | ||||||
|  |     img2webp, webpmux - allow options to be passed in via a file (issue #355) | ||||||
|  |  | ||||||
|  | - 11/24/2017: version 0.6.1 | ||||||
|  |   This is a binary compatible release. | ||||||
|  |   * lossless performance and compression improvements + a new 'cruncher' mode | ||||||
|  |     (-m 6 -q 100) | ||||||
|  |   * ARM performance improvements with clang (15-20% w/ndk r15c, issue #339) | ||||||
|  |   * webp-js: emscripten/webassembly based javascript decoder | ||||||
|  |   * miscellaneous bug & build fixes (issue #329, #332, #343, #353, #360, #361, | ||||||
|  |     #363) | ||||||
|  |   Tool updates / additions: | ||||||
|  |     added webpinfo - prints file format information (issue #330) | ||||||
|  |     gif2webp - loop behavior modified to match Chrome M63+ (crbug.com/649264); | ||||||
|  |                '-loop_compatibility' can be used for the old behavior | ||||||
|  |  | ||||||
|  | - 1/26/2017: version 0.6.0 | ||||||
|  |   * lossless performance and compression improvements | ||||||
|  |   * miscellaneous performance improvements (SSE2, NEON, MSA) | ||||||
|  |   * webpmux gained a -duration option allowing for frame timing modification | ||||||
|  |   * new img2webp utility allowing a sequence of images to be converted to | ||||||
|  |     animated webp | ||||||
|  |   * API changes: | ||||||
|  |     - libwebp: | ||||||
|  |       WebPPictureSharpARGBToYUVA | ||||||
|  |       WebPPlaneDistortion | ||||||
|  |     - libwebpmux / gif2webp: | ||||||
|  |       WebPAnimEncoderOptions: kmax <= 0 now disables keyframes, kmax == 1 | ||||||
|  |                               forces all keyframes. See mux.h and the gif2webp | ||||||
|  |                               manpage for details. | ||||||
|  |  | ||||||
|  | - 12/13/2016: version 0.5.2 | ||||||
|  |   This is a binary compatible release. | ||||||
|  |   This release covers CVE-2016-8888 and CVE-2016-9085. | ||||||
|  |   * further security related hardening in the tools; fixes to | ||||||
|  |     gif2webp/AnimEncoder (issues #310, #314, #316, #322), cwebp/libwebp (issue | ||||||
|  |     #312) | ||||||
|  |   * full libwebp (encoder & decoder) iOS framework; libwebpdecoder | ||||||
|  |     WebP.framework renamed to WebPDecoder.framework (issue #307) | ||||||
|  |   * CMake support for Android Studio (2.2) | ||||||
|  |   * miscellaneous build related fixes (issue #306, #313) | ||||||
|  |   * miscellaneous documentation improvements (issue #225) | ||||||
|  |   * minor lossy encoder fixes and improvements | ||||||
|  |  | ||||||
|  | - 6/14/2016: version 0.5.1 | ||||||
|  |   This is a binary compatible release. | ||||||
|  |   * miscellaneous bug fixes (issues #280, #289) | ||||||
|  |   * reverted alpha plane encoding with color cache for compatibility with | ||||||
|  |     libwebp 0.4.0->0.4.3 (issues #291, #298) | ||||||
|  |   * lossless encoding performance improvements | ||||||
|  |   * memory reduction in both lossless encoding and decoding | ||||||
|  |   * force mux output to be in the extended format (VP8X) when undefined chunks | ||||||
|  |     are present (issue #294) | ||||||
|  |   * gradle, cmake build support | ||||||
|  |   * workaround for compiler bug causing 64-bit decode failures on android | ||||||
|  |     devices using clang-3.8 in the r11c NDK | ||||||
|  |   * various WebPAnimEncoder improvements | ||||||
|  |  | ||||||
|  | - 12/17/2015: version 0.5.0 | ||||||
|  |   * miscellaneous bug & build fixes (issues #234, #258, #274, #275, #278) | ||||||
|  |   * encoder & decoder speed-ups on x86/ARM/MIPS for lossy & lossless | ||||||
|  |     - note! YUV->RGB conversion was sped-up, but the results will be slightly | ||||||
|  |       different from previous releases | ||||||
|  |   * various lossless encoder improvements | ||||||
|  |   * gif2webp improvements, -min_size option added | ||||||
|  |   * tools fully support input from stdin and output to stdout (issue #168) | ||||||
|  |   * New WebPAnimEncoder API for creating animations | ||||||
|  |   * New WebPAnimDecoder API for decoding animations | ||||||
|  |   * other API changes: | ||||||
|  |     - libwebp: | ||||||
|  |       WebPPictureSmartARGBToYUVA() (-pre 4 in cwebp) | ||||||
|  |       WebPConfig::exact (-exact in cwebp; -alpha_cleanup is now the default) | ||||||
|  |       WebPConfig::near_lossless (-near_lossless in cwebp) | ||||||
|  |       WebPFree() (free'ing webp allocated memory in other languages) | ||||||
|  |       WebPConfigLosslessPreset() | ||||||
|  |       WebPMemoryWriterClear() | ||||||
|  |     - libwebpdemux: removed experimental fragment related fields and functions | ||||||
|  |     - libwebpmux: WebPMuxSetCanvasSize() | ||||||
|  |   * new libwebpextras library with some uncommon import functions: | ||||||
|  |     WebPImportGray/WebPImportRGB565/WebPImportRGB4444 | ||||||
|  |  | ||||||
|  | - 10/15/15: version 0.4.4 | ||||||
|  |   This is a binary compatible release. | ||||||
|  |   * rescaling out-of-bounds read fix (issue #254) | ||||||
|  |   * various build fixes and improvements (issues #253, #259, #262, #267, #268) | ||||||
|  |   * container documentation update | ||||||
|  |   * gif2webp transparency fix (issue #245) | ||||||
|  |  | ||||||
|  | - 3/3/15: version 0.4.3 | ||||||
|  |   This is a binary compatible release. | ||||||
|  |   * Android / gcc / iOS / MSVS build fixes and improvements | ||||||
|  |   * lossless decode fix (issue #239 -- since 0.4.0) | ||||||
|  |   * documentation / vwebp updates for animation | ||||||
|  |   * multi-threading fix (issue #234) | ||||||
|  |  | ||||||
|  | - 10/13/14: version 0.4.2 | ||||||
|  |   This is a binary compatible release. | ||||||
|  |   * Android / gcc build fixes | ||||||
|  |   * (Windows) fix reading from stdin and writing to stdout | ||||||
|  |   * gif2webp: miscellaneous fixes | ||||||
|  |   * fix 'alpha-leak' with lossy compression (issue #220) | ||||||
|  |   * the lossless bitstream spec has been amended to reflect the current code | ||||||
|  |  | ||||||
|  | - 7/24/14: version 0.4.1 | ||||||
|  |   This is a binary compatible release. | ||||||
|  |   * AArch64 (arm64) & MIPS support/optimizations | ||||||
|  |   * NEON assembly additions: | ||||||
|  |     - ~25% faster lossy decode / encode (-m 4) | ||||||
|  |     - ~10% faster lossless decode | ||||||
|  |     - ~5-10% faster lossless encode (-m 3/4) | ||||||
|  |   * dwebp/vwebp can read from stdin | ||||||
|  |   * cwebp/gif2webp can write to stdout | ||||||
|  |   * cwebp can read webp files; useful if storing sources as webp lossless | ||||||
|  |  | ||||||
|  | - 12/19/13: version 0.4.0 | ||||||
|  |   * improved gif2webp tool | ||||||
|  |   * numerous fixes, compression improvement and speed-up | ||||||
|  |   * dither option added to decoder (dwebp -dither 50 ...) | ||||||
|  |   * improved multi-threaded modes (-mt option) | ||||||
|  |   * improved filtering strength determination | ||||||
|  |   * New function: WebPMuxGetCanvasSize | ||||||
|  |   * BMP and TIFF format output added to 'dwebp' | ||||||
|  |   * Significant memory reduction for decoding lossy images with alpha. | ||||||
|  |   * Intertwined decoding of RGB and alpha for a shorter | ||||||
|  |     time-to-first-decoded-pixel. | ||||||
|  |   * WebPIterator has a new member 'has_alpha' denoting whether the frame | ||||||
|  |     contains transparency. | ||||||
|  |   * Container spec amended with new 'blending method' for animation. | ||||||
|  |  | ||||||
|  | - 6/13/13: version 0.3.1 | ||||||
|  |   This is a binary compatible release. | ||||||
|  |   * Add incremental decoding support for images containing ALPH and ICCP chunks. | ||||||
|  |   * Python bindings via swig for the simple encode/decode interfaces similar to | ||||||
|  |     Java. | ||||||
|  |  | ||||||
|  | - 3/20/13: version 0.3.0 | ||||||
|  |   This is a binary compatible release. | ||||||
|  |   * WebPINewRGB/WebPINewYUVA accept being passed a NULL output buffer | ||||||
|  |     and will perform auto-allocation. | ||||||
|  |   * default filter option is now '-strong -f 60' | ||||||
|  |   * encoding speed-up for lossy methods 3 to 6 | ||||||
|  |   * alpha encoding can be done in parallel to lossy using 'cwebp -mt ...' | ||||||
|  |   * color profile, metadata (XMP/EXIF) and animation support finalized in the | ||||||
|  |     container. | ||||||
|  |   * various NEON assembly additions | ||||||
|  |   Tool updates / additions: | ||||||
|  |     * gif2webp added | ||||||
|  |     * vwebp given color profile & animation support | ||||||
|  |     * cwebp can preserve color profile / metadata with '-metadata' | ||||||
|  |  | ||||||
|  | - 10/30/12: version 0.2.1 | ||||||
|  |   * Various security related fixes | ||||||
|  |   * cwebp.exe: fix import errors on Windows XP | ||||||
|  |   * enable DLL builds for mingw targets | ||||||
|  |  | ||||||
|  | - 8/3/12: version 0.2.0 | ||||||
|  |   * Add support for ARGB -> YUVA conversion for lossless decoder | ||||||
|  |     New functions: WebPINewYUVA, WebPIDecGetYUVA | ||||||
|  |   * Add stats for lossless and alpha encoding | ||||||
|  |   * Security related hardening: allocation and size checks | ||||||
|  |   * Add PAM output support to dwebp | ||||||
|  |  | ||||||
|  | - 7/19/12: version 0.1.99 | ||||||
|  |   * This is a pre-release of 0.2.0, not an rc to allow for further | ||||||
|  |     incompatible changes based on user feedback. | ||||||
|  |   * Alpha channel encode/decode support. | ||||||
|  |   * Lossless encoder/decoder. | ||||||
|  |   * Add TIFF input support to cwebp. | ||||||
|  |   Incompatible changes: | ||||||
|  |     * The encode ABI has been modified to support alpha encoding. | ||||||
|  |     * Deprecated function WebPINew() has been removed. | ||||||
|  |     * Decode function signatures have changed to consistently use size_t over | ||||||
|  |       int/uint32_t. | ||||||
|  |     * decode_vp8.h is no longer installed system-wide. | ||||||
|  |     * cwebp will encode the alpha channel if present. | ||||||
|  |  | ||||||
|  | - 9/19/11: version 0.1.3 | ||||||
|  |   * Advanced decoding APIs. | ||||||
|  |   * On-the-fly cropping and rescaling of images. | ||||||
|  |   * SSE2 instructions for decoding performance optimizations on x86 based | ||||||
|  |     platforms. | ||||||
|  |   * Support Multi-threaded decoding. | ||||||
|  |   * 40% improvement in Decoding performance. | ||||||
|  |   * Add support for RGB565, RGBA4444 & ARGB image colorspace. | ||||||
|  |   * Better handling of large picture encoding. | ||||||
|  |  | ||||||
|  | - 3/25/11: version 0.1.2 | ||||||
|  |   * Incremental decoding: picture can be decoded byte-by-byte if needs be. | ||||||
|  |   * lot of bug-fixes, consolidation and stabilization | ||||||
|  |  | ||||||
|  | - 2/23/11: initial release of version 0.1, with the new encoder | ||||||
|  | - 9/30/10: initial release version with only the lightweight decoder | ||||||
							
								
								
									
										23
									
								
								external/libwebp/libwebp/PATENTS
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								external/libwebp/libwebp/PATENTS
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,23 @@ | |||||||
|  | Additional IP Rights Grant (Patents) | ||||||
|  | ------------------------------------ | ||||||
|  |  | ||||||
|  | "These implementations" means the copyrightable works that implement the WebM | ||||||
|  | codecs distributed by Google as part of the WebM Project. | ||||||
|  |  | ||||||
|  | Google hereby grants to you a perpetual, worldwide, non-exclusive, no-charge, | ||||||
|  | royalty-free, irrevocable (except as stated in this section) patent license to | ||||||
|  | make, have made, use, offer to sell, sell, import, transfer, and otherwise | ||||||
|  | run, modify and propagate the contents of these implementations of WebM, where | ||||||
|  | such license applies only to those patent claims, both currently owned by | ||||||
|  | Google and acquired in the future, licensable by Google that are necessarily | ||||||
|  | infringed by these implementations of WebM. This grant does not include claims | ||||||
|  | that would be infringed only as a consequence of further modification of these | ||||||
|  | implementations. If you or your agent or exclusive licensee institute or order | ||||||
|  | or agree to the institution of patent litigation or any other patent | ||||||
|  | enforcement activity against any entity (including a cross-claim or | ||||||
|  | counterclaim in a lawsuit) alleging that any of these implementations of WebM | ||||||
|  | or any code incorporated within any of these implementations of WebM | ||||||
|  | constitute direct or contributory patent infringement, or inducement of | ||||||
|  | patent infringement, then any patent rights granted to you under this License | ||||||
|  | for these implementations of WebM shall terminate as of the date such | ||||||
|  | litigation is filed. | ||||||
							
								
								
									
										245
									
								
								external/libwebp/libwebp/PRESUBMIT.py
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										245
									
								
								external/libwebp/libwebp/PRESUBMIT.py
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,245 @@ | |||||||
|  | # Copyright (c) 2021, Google Inc. All rights reserved. | ||||||
|  | # | ||||||
|  | # Redistribution and use in source and binary forms, with or without | ||||||
|  | # modification, are permitted provided that the following conditions are | ||||||
|  | # met: | ||||||
|  | # | ||||||
|  | #   * Redistributions of source code must retain the above copyright | ||||||
|  | #     notice, this list of conditions and the following disclaimer. | ||||||
|  | # | ||||||
|  | #   * Redistributions in binary form must reproduce the above copyright | ||||||
|  | #     notice, this list of conditions and the following disclaimer in | ||||||
|  | #     the documentation and/or other materials provided with the | ||||||
|  | #     distribution. | ||||||
|  | # | ||||||
|  | #   * Neither the name of Google nor the names of its contributors may | ||||||
|  | #     be used to endorse or promote products derived from this software | ||||||
|  | #     without specific prior written permission. | ||||||
|  | # | ||||||
|  | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||||||
|  | # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||||||
|  | # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||||||
|  | # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||||||
|  | # HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||||||
|  | # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||||||
|  | # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||||||
|  | # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||||||
|  | # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||||||
|  | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||||||
|  | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||||||
|  | """Top-level presubmit script for libwebp. | ||||||
|  |  | ||||||
|  | See https://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts for | ||||||
|  | details on the presubmit API built into depot_tools. | ||||||
|  | """ | ||||||
|  |  | ||||||
|  | import re | ||||||
|  | import subprocess2 | ||||||
|  |  | ||||||
|  | USE_PYTHON3 = True | ||||||
|  | _BASH_INDENTATION = "2" | ||||||
|  | _GIT_COMMIT_SUBJECT_LENGTH = 65 | ||||||
|  | _INCLUDE_BASH_FILES_ONLY = [r".*\.sh$"] | ||||||
|  | _INCLUDE_MAN_FILES_ONLY = [r"man/.+\.1$"] | ||||||
|  | _INCLUDE_SOURCE_FILES_ONLY = [r".*\.[ch]$"] | ||||||
|  | _LIBWEBP_MAX_LINE_LENGTH = 80 | ||||||
|  |  | ||||||
|  |  | ||||||
|  | def _CheckCommitSubjectLength(input_api, output_api): | ||||||
|  |   """Ensures commit's subject length is no longer than 65 chars.""" | ||||||
|  |   name = "git-commit subject" | ||||||
|  |   cmd = ["git", "log", "-1", "--pretty=%s"] | ||||||
|  |   start = input_api.time.time() | ||||||
|  |   proc = subprocess2.Popen( | ||||||
|  |       cmd, | ||||||
|  |       stderr=subprocess2.PIPE, | ||||||
|  |       stdout=subprocess2.PIPE, | ||||||
|  |       universal_newlines=True) | ||||||
|  |  | ||||||
|  |   stdout, _ = proc.communicate() | ||||||
|  |   duration = input_api.time.time() - start | ||||||
|  |  | ||||||
|  |   if not re.match(r"^Revert", | ||||||
|  |                   stdout) and (len(stdout) - 1) > _GIT_COMMIT_SUBJECT_LENGTH: | ||||||
|  |     failure_msg = ( | ||||||
|  |         "The commit subject: %s is too long (%d chars)\n" | ||||||
|  |         "Try to keep this to 50 or less (up to 65 is permitted for " | ||||||
|  |         "non-reverts).\n" | ||||||
|  |         "https://www.git-scm.com/book/en/v2/Distributed-Git-Contributing-to-a-" | ||||||
|  |         "Project#_commit_guidelines") % (stdout, len(stdout) - 1) | ||||||
|  |     return output_api.PresubmitError("%s\n (%4.2fs) failed\n%s" % | ||||||
|  |                                      (name, duration, failure_msg)) | ||||||
|  |  | ||||||
|  |   return output_api.PresubmitResult("%s\n (%4.2fs) success" % (name, duration)) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | def _CheckDuplicateFiles(input_api, output_api): | ||||||
|  |   """Ensures there are not repeated filenames.""" | ||||||
|  |   all_files = [] | ||||||
|  |   for f in input_api.change.AllFiles(): | ||||||
|  |     for include_file in _INCLUDE_SOURCE_FILES_ONLY: | ||||||
|  |       if re.match(include_file, f): | ||||||
|  |         all_files.append(f) | ||||||
|  |         break | ||||||
|  |  | ||||||
|  |   basename_to_path = {} | ||||||
|  |   for f in all_files: | ||||||
|  |     basename_file = input_api.basename(f) | ||||||
|  |     if basename_file in basename_to_path: | ||||||
|  |       basename_to_path[basename_file].append(f) | ||||||
|  |     else: | ||||||
|  |       basename_to_path[basename_file] = [f] | ||||||
|  |  | ||||||
|  |   dupes = [] | ||||||
|  |   for files in basename_to_path.values(): | ||||||
|  |     if len(files) > 1: | ||||||
|  |       dupes.extend(files) | ||||||
|  |  | ||||||
|  |   if dupes: | ||||||
|  |     return output_api.PresubmitError( | ||||||
|  |         "Duplicate source files, rebase or rename some to make them unique:\n%s" | ||||||
|  |         % dupes) | ||||||
|  |   return output_api.PresubmitResult("No duplicates, success\n") | ||||||
|  |  | ||||||
|  |  | ||||||
|  | def _GetFilesToSkip(input_api): | ||||||
|  |   return list(input_api.DEFAULT_FILES_TO_SKIP) + [ | ||||||
|  |       r"swig/.*\.py$", | ||||||
|  |       r"\.pylintrc$", | ||||||
|  |   ] | ||||||
|  |  | ||||||
|  |  | ||||||
|  | def _RunManCmd(input_api, output_api, man_file): | ||||||
|  |   """man command wrapper.""" | ||||||
|  |   cmd = ["man", "--warnings", "-EUTF-8", "-l", "-Tutf8", "-Z", man_file] | ||||||
|  |   name = "Check %s file." % man_file | ||||||
|  |   start = input_api.time.time() | ||||||
|  |   output, _ = subprocess2.communicate( | ||||||
|  |       cmd, stdout=None, stderr=subprocess2.PIPE, universal_newlines=True) | ||||||
|  |   duration = input_api.time.time() - start | ||||||
|  |   if output[1]: | ||||||
|  |     return output_api.PresubmitError("%s\n%s (%4.2fs) failed\n%s" % | ||||||
|  |                                      (name, " ".join(cmd), duration, output[1])) | ||||||
|  |   return output_api.PresubmitResult("%s\n%s (%4.2fs)\n" % | ||||||
|  |                                     (name, " ".join(cmd), duration)) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | def _RunShellCheckCmd(input_api, output_api, bash_file): | ||||||
|  |   """shellcheck command wrapper.""" | ||||||
|  |   cmd = ["shellcheck", "-x", "-oall", "-sbash", bash_file] | ||||||
|  |   name = "Check %s file." % bash_file | ||||||
|  |   start = input_api.time.time() | ||||||
|  |   output, rc = subprocess2.communicate( | ||||||
|  |       cmd, stdout=None, stderr=subprocess2.PIPE, universal_newlines=True) | ||||||
|  |   duration = input_api.time.time() - start | ||||||
|  |   if rc == 0: | ||||||
|  |     return output_api.PresubmitResult("%s\n%s (%4.2fs)\n" % | ||||||
|  |                                       (name, " ".join(cmd), duration)) | ||||||
|  |   return output_api.PresubmitError("%s\n%s (%4.2fs) failed\n%s" % | ||||||
|  |                                    (name, " ".join(cmd), duration, output[1])) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | def _RunShfmtCheckCmd(input_api, output_api, bash_file): | ||||||
|  |   """shfmt command wrapper.""" | ||||||
|  |   cmd = [ | ||||||
|  |       "shfmt", "-i", _BASH_INDENTATION, "-bn", "-ci", "-sr", "-kp", "-d", | ||||||
|  |       bash_file | ||||||
|  |   ] | ||||||
|  |   name = "Check %s file." % bash_file | ||||||
|  |   start = input_api.time.time() | ||||||
|  |   output, rc = subprocess2.communicate( | ||||||
|  |       cmd, stdout=None, stderr=subprocess2.PIPE, universal_newlines=True) | ||||||
|  |   duration = input_api.time.time() - start | ||||||
|  |   if rc == 0: | ||||||
|  |     return output_api.PresubmitResult("%s\n%s (%4.2fs)\n" % | ||||||
|  |                                       (name, " ".join(cmd), duration)) | ||||||
|  |   return output_api.PresubmitError("%s\n%s (%4.2fs) failed\n%s" % | ||||||
|  |                                    (name, " ".join(cmd), duration, output[1])) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | def _RunCmdOnCheckedFiles(input_api, output_api, run_cmd, files_to_check): | ||||||
|  |   """Ensure that libwebp/ files are clean.""" | ||||||
|  |   file_filter = lambda x: input_api.FilterSourceFile( | ||||||
|  |       x, files_to_check=files_to_check, files_to_skip=None) | ||||||
|  |  | ||||||
|  |   affected_files = input_api.change.AffectedFiles(file_filter=file_filter) | ||||||
|  |   results = [ | ||||||
|  |       run_cmd(input_api, output_api, f.AbsoluteLocalPath()) | ||||||
|  |       for f in affected_files | ||||||
|  |   ] | ||||||
|  |   return results | ||||||
|  |  | ||||||
|  |  | ||||||
|  | def _CommonChecks(input_api, output_api): | ||||||
|  |   """Ensures this patch does not have trailing spaces, extra EOLs, | ||||||
|  |      or long lines. | ||||||
|  |   """ | ||||||
|  |   results = [] | ||||||
|  |   results.extend( | ||||||
|  |       input_api.canned_checks.CheckChangeHasNoCrAndHasOnlyOneEol( | ||||||
|  |           input_api, output_api)) | ||||||
|  |   results.extend( | ||||||
|  |       input_api.canned_checks.CheckChangeHasNoTabs(input_api, output_api)) | ||||||
|  |   results.extend( | ||||||
|  |       input_api.canned_checks.CheckChangeHasNoStrayWhitespace( | ||||||
|  |           input_api, output_api)) | ||||||
|  |   results.append(_CheckCommitSubjectLength(input_api, output_api)) | ||||||
|  |   results.append(_CheckDuplicateFiles(input_api, output_api)) | ||||||
|  |  | ||||||
|  |   source_file_filter = lambda x: input_api.FilterSourceFile( | ||||||
|  |       x, files_to_skip=_GetFilesToSkip(input_api)) | ||||||
|  |   results.extend( | ||||||
|  |       input_api.canned_checks.CheckLongLines( | ||||||
|  |           input_api, | ||||||
|  |           output_api, | ||||||
|  |           maxlen=_LIBWEBP_MAX_LINE_LENGTH, | ||||||
|  |           source_file_filter=source_file_filter)) | ||||||
|  |  | ||||||
|  |   results.extend( | ||||||
|  |       input_api.canned_checks.CheckPatchFormatted( | ||||||
|  |           input_api, | ||||||
|  |           output_api, | ||||||
|  |           check_clang_format=False, | ||||||
|  |           check_python=True, | ||||||
|  |           result_factory=output_api.PresubmitError)) | ||||||
|  |   results.extend( | ||||||
|  |       _RunCmdOnCheckedFiles(input_api, output_api, _RunManCmd, | ||||||
|  |                             _INCLUDE_MAN_FILES_ONLY)) | ||||||
|  |   # Run pylint. | ||||||
|  |   results.extend( | ||||||
|  |       input_api.canned_checks.RunPylint( | ||||||
|  |           input_api, | ||||||
|  |           output_api, | ||||||
|  |           files_to_skip=_GetFilesToSkip(input_api), | ||||||
|  |           pylintrc=".pylintrc", | ||||||
|  |           version="2.7")) | ||||||
|  |  | ||||||
|  |   # Binaries shellcheck and shfmt are not installed in depot_tools. | ||||||
|  |   # Installation is needed | ||||||
|  |   try: | ||||||
|  |     subprocess2.communicate(["shellcheck", "--version"]) | ||||||
|  |     results.extend( | ||||||
|  |         _RunCmdOnCheckedFiles(input_api, output_api, _RunShellCheckCmd, | ||||||
|  |                               _INCLUDE_BASH_FILES_ONLY)) | ||||||
|  |     print("shfmt") | ||||||
|  |     subprocess2.communicate(["shfmt", "-version"]) | ||||||
|  |     results.extend( | ||||||
|  |         _RunCmdOnCheckedFiles(input_api, output_api, _RunShfmtCheckCmd, | ||||||
|  |                               _INCLUDE_BASH_FILES_ONLY)) | ||||||
|  |   except OSError as os_error: | ||||||
|  |     results.append( | ||||||
|  |         output_api.PresubmitPromptWarning( | ||||||
|  |             "%s\nPlease install missing binaries locally." % os_error.args[0])) | ||||||
|  |   return results | ||||||
|  |  | ||||||
|  |  | ||||||
|  | def CheckChangeOnUpload(input_api, output_api): | ||||||
|  |   results = [] | ||||||
|  |   results.extend(_CommonChecks(input_api, output_api)) | ||||||
|  |   return results | ||||||
|  |  | ||||||
|  |  | ||||||
|  | def CheckChangeOnCommit(input_api, output_api): | ||||||
|  |   results = [] | ||||||
|  |   results.extend(_CommonChecks(input_api, output_api)) | ||||||
|  |   return results | ||||||
							
								
								
									
										53
									
								
								external/libwebp/libwebp/README.md
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								external/libwebp/libwebp/README.md
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,53 @@ | |||||||
|  | # WebP Codec | ||||||
|  |  | ||||||
|  | ``` | ||||||
|  |       __   __  ____  ____  ____ | ||||||
|  |      /  \\/  \/  _ \/  _ )/  _ \ | ||||||
|  |      \       /   __/  _  \   __/ | ||||||
|  |       \__\__/\____/\_____/__/ ____  ___ | ||||||
|  |             / _/ /    \    \ /  _ \/ _/ | ||||||
|  |            /  \_/   / /   \ \   __/  \__ | ||||||
|  |            \____/____/\_____/_____/____/v1.3.1 | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | WebP codec is a library to encode and decode images in WebP format. This package | ||||||
|  | contains the library that can be used in other programs to add WebP support, as | ||||||
|  | well as the command line tools 'cwebp' and 'dwebp' to compress and decompress | ||||||
|  | images respectively. | ||||||
|  |  | ||||||
|  | See https://developers.google.com/speed/webp for details on the image format. | ||||||
|  |  | ||||||
|  | The latest source tree is available at | ||||||
|  | https://chromium.googlesource.com/webm/libwebp | ||||||
|  |  | ||||||
|  | It is released under the same license as the WebM project. See | ||||||
|  | https://www.webmproject.org/license/software/ or the "COPYING" file for details. | ||||||
|  | An additional intellectual property rights grant can be found in the file | ||||||
|  | PATENTS. | ||||||
|  |  | ||||||
|  | ## Building | ||||||
|  |  | ||||||
|  | See the [building documentation](doc/building.md). | ||||||
|  |  | ||||||
|  | ## Encoding and Decoding Tools | ||||||
|  |  | ||||||
|  | The examples/ directory contains tools to encode and decode images and | ||||||
|  | animations, view information about WebP images, and more. See the | ||||||
|  | [tools documentation](doc/tools.md). | ||||||
|  |  | ||||||
|  | ## APIs | ||||||
|  |  | ||||||
|  | See the [APIs documentation](doc/api.md), and API usage examples in the | ||||||
|  | `examples/` directory. | ||||||
|  |  | ||||||
|  | ## Bugs | ||||||
|  |  | ||||||
|  | Please report all bugs to the issue tracker: https://bugs.chromium.org/p/webp | ||||||
|  |  | ||||||
|  | Patches welcome! See [how to contribute](CONTRIBUTING.md). | ||||||
|  |  | ||||||
|  | ## Discuss | ||||||
|  |  | ||||||
|  | Email: webp-discuss@webmproject.org | ||||||
|  |  | ||||||
|  | Web: https://groups.google.com/a/webmproject.org/group/webp-discuss | ||||||
							
								
								
									
										2
									
								
								external/libwebp/libwebp/autogen.sh
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										2
									
								
								external/libwebp/libwebp/autogen.sh
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,2 @@ | |||||||
|  | #! /bin/sh -e | ||||||
|  | exec autoreconf -fi | ||||||
							
								
								
									
										444
									
								
								external/libwebp/libwebp/build.gradle
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										444
									
								
								external/libwebp/libwebp/build.gradle
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,444 @@ | |||||||
|  | // Define dependencies. | ||||||
|  | buildscript { | ||||||
|  |   repositories { | ||||||
|  |     maven { | ||||||
|  |       url "https://jcenter.bintray.com" | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   dependencies { | ||||||
|  |     classpath "com.android.tools.build:gradle:${ANDROID_GRADLE_PLUGIN_VERSION}" | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Define versions in the project. | ||||||
|  | project.ext { | ||||||
|  |   buildToolsVersion = "${BUILD_TOOLS_VERSION}" | ||||||
|  |   compileSdkVersion = COMPILE_SDK_VERSION.toInteger() | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Core libraries and executables. | ||||||
|  | apply plugin: "c" | ||||||
|  | def NEON | ||||||
|  | model { | ||||||
|  |   buildTypes { | ||||||
|  |     debug | ||||||
|  |     release | ||||||
|  |   } | ||||||
|  |   platforms { | ||||||
|  |     arm { | ||||||
|  |       architecture "arm" | ||||||
|  |     } | ||||||
|  |     arm64 { | ||||||
|  |       architecture "arm64" | ||||||
|  |     } | ||||||
|  |     x86 { | ||||||
|  |       architecture "x86" | ||||||
|  |     } | ||||||
|  |     x64 { | ||||||
|  |       architecture "x86_64" | ||||||
|  |     } | ||||||
|  |     mips32r2 | ||||||
|  |     mips32r5 | ||||||
|  |     mips64r6 | ||||||
|  |   } | ||||||
|  |   toolChains { | ||||||
|  |     gcc(Gcc) { | ||||||
|  |       target("mips32r2") { | ||||||
|  |         cCompiler.args "-mips32r2" | ||||||
|  |       } | ||||||
|  |       target("mips32r5") { | ||||||
|  |         cCompiler.args "-mips32r5" | ||||||
|  |       } | ||||||
|  |       target("mips64r6") { | ||||||
|  |         cCompiler.args "-mips64r6" | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   binaries { | ||||||
|  |     all { | ||||||
|  |       if (toolChain in Gcc) { | ||||||
|  |         cCompiler.args "-fPIC" | ||||||
|  |         cCompiler.args "-Wall" | ||||||
|  |         cCompiler.define "ANDROID" | ||||||
|  |         cCompiler.define "HAVE_MALLOC_H" | ||||||
|  |       } | ||||||
|  |       // Optimizations. | ||||||
|  |       if (buildType == buildTypes.release) { | ||||||
|  |         if (toolChain in Gcc) { | ||||||
|  |           cCompiler.args "-finline-functions" | ||||||
|  |           cCompiler.args "-ffast-math" | ||||||
|  |           cCompiler.args "-ffunction-sections" | ||||||
|  |           cCompiler.args "-fdata-sections" | ||||||
|  |         } | ||||||
|  |         if (toolChain in Clang) { | ||||||
|  |           cCompiler.args "-frename-registers -s" | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |       // mips32 fails to build with clang from r14b | ||||||
|  |       // https://bugs.chromium.org/p/webp/issues/detail?id=343 | ||||||
|  |       if (toolChain in Clang) { | ||||||
|  |         if (getTargetPlatform() == "mips") { | ||||||
|  |           cCompiler.args "-no-integrated-as" | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |       // Check for NEON usage. | ||||||
|  |       if (getTargetPlatform() == "arm") { | ||||||
|  |         NEON = "c.neon" | ||||||
|  |         cCompiler.define "HAVE_CPU_FEATURES_H" | ||||||
|  |       } else { | ||||||
|  |         NEON = "c" | ||||||
|  |       } | ||||||
|  |  | ||||||
|  |       cCompiler.args "-I" + file(".").absolutePath | ||||||
|  |     } | ||||||
|  |     // Link to pthread for shared libraries. | ||||||
|  |     withType(SharedLibraryBinarySpec) { | ||||||
|  |       if (toolChain in Gcc) { | ||||||
|  |         cCompiler.define "HAVE_PTHREAD" | ||||||
|  |         cCompiler.define "WEBP_USE_THREAD" | ||||||
|  |         linker.args "-pthread" | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   components { | ||||||
|  |     webp(NativeLibrarySpec) { | ||||||
|  |       sources { | ||||||
|  |         c { | ||||||
|  |           source { | ||||||
|  |             srcDir "sharpyuv" | ||||||
|  |             include "sharpyuv.c" | ||||||
|  |             include "sharpyuv_cpu.c" | ||||||
|  |             include "sharpyuv_csp.c" | ||||||
|  |             include "sharpyuv_dsp.c" | ||||||
|  |             include "sharpyuv_gamma.c" | ||||||
|  |             include "sharpyuv_neon.c" | ||||||
|  |             include "sharpyuv_sse2.c" | ||||||
|  |             srcDir "src/dec" | ||||||
|  |             include "alpha_dec.c" | ||||||
|  |             include "buffer_dec.c" | ||||||
|  |             include "frame_dec.c" | ||||||
|  |             include "idec_dec.c" | ||||||
|  |             include "io_dec.c" | ||||||
|  |             include "quant_dec.c" | ||||||
|  |             include "tree_dec.c" | ||||||
|  |             include "vp8_dec.c" | ||||||
|  |             include "vp8l_dec.c" | ||||||
|  |             include "webp_dec.c" | ||||||
|  |             srcDir "src/dsp" | ||||||
|  |             include "alpha_processing.c" | ||||||
|  |             include "alpha_processing_mips_dsp_r2.c" | ||||||
|  |             include "alpha_processing_neon.$NEON" | ||||||
|  |             include "alpha_processing_sse2.c" | ||||||
|  |             include "alpha_processing_sse41.c" | ||||||
|  |             include "cpu.c" | ||||||
|  |             include "dec.c" | ||||||
|  |             include "dec_clip_tables.c" | ||||||
|  |             include "dec_mips32.c" | ||||||
|  |             include "dec_mips_dsp_r2.c" | ||||||
|  |             include "dec_msa.c" | ||||||
|  |             include "dec_neon.$NEON" | ||||||
|  |             include "dec_sse2.c" | ||||||
|  |             include "dec_sse41.c" | ||||||
|  |             include "filters.c" | ||||||
|  |             include "filters_mips_dsp_r2.c" | ||||||
|  |             include "filters_msa.c" | ||||||
|  |             include "filters_neon.$NEON" | ||||||
|  |             include "filters_sse2.c" | ||||||
|  |             include "lossless.c" | ||||||
|  |             include "lossless_mips_dsp_r2.c" | ||||||
|  |             include "lossless_msa.c" | ||||||
|  |             include "lossless_neon.$NEON" | ||||||
|  |             include "lossless_sse2.c" | ||||||
|  |             include "lossless_sse41.c" | ||||||
|  |             include "rescaler.c" | ||||||
|  |             include "rescaler_mips32.c" | ||||||
|  |             include "rescaler_mips_dsp_r2.c" | ||||||
|  |             include "rescaler_msa.c" | ||||||
|  |             include "rescaler_neon.$NEON" | ||||||
|  |             include "rescaler_sse2.c" | ||||||
|  |             include "upsampling.c" | ||||||
|  |             include "upsampling_mips_dsp_r2.c" | ||||||
|  |             include "upsampling_msa.c" | ||||||
|  |             include "upsampling_neon.$NEON" | ||||||
|  |             include "upsampling_sse2.c" | ||||||
|  |             include "upsampling_sse41.c" | ||||||
|  |             include "yuv.c" | ||||||
|  |             include "yuv_mips32.c" | ||||||
|  |             include "yuv_mips_dsp_r2.c" | ||||||
|  |             include "yuv_neon.$NEON" | ||||||
|  |             include "yuv_sse2.c" | ||||||
|  |             include "yuv_sse41.c" | ||||||
|  |             srcDir "src/utils" | ||||||
|  |             include "bit_reader_utils.c" | ||||||
|  |             include "color_cache_utils.c" | ||||||
|  |             include "filters_utils.c" | ||||||
|  |             include "huffman_utils.c" | ||||||
|  |             include "palette.c" | ||||||
|  |             include "quant_levels_dec_utils.c" | ||||||
|  |             include "random_utils.c" | ||||||
|  |             include "rescaler_utils.c" | ||||||
|  |             include "thread_utils.c" | ||||||
|  |             include "utils.c" | ||||||
|  |             srcDir "src/dsp" | ||||||
|  |             include "cost.c" | ||||||
|  |             include "cost_mips32.c" | ||||||
|  |             include "cost_mips_dsp_r2.c" | ||||||
|  |             include "cost_neon.$NEON" | ||||||
|  |             include "cost_sse2.c" | ||||||
|  |             include "enc.c" | ||||||
|  |             include "enc_mips32.c" | ||||||
|  |             include "enc_mips_dsp_r2.c" | ||||||
|  |             include "enc_msa.c" | ||||||
|  |             include "enc_neon.$NEON" | ||||||
|  |             include "enc_sse2.c" | ||||||
|  |             include "enc_sse41.c" | ||||||
|  |             include "lossless_enc.c" | ||||||
|  |             include "lossless_enc_mips32.c" | ||||||
|  |             include "lossless_enc_mips_dsp_r2.c" | ||||||
|  |             include "lossless_enc_msa.c" | ||||||
|  |             include "lossless_enc_neon.$NEON" | ||||||
|  |             include "lossless_enc_sse2.c" | ||||||
|  |             include "lossless_enc_sse41.c" | ||||||
|  |             include "ssim.c" | ||||||
|  |             include "ssim_sse2.c" | ||||||
|  |             srcDir "src/enc" | ||||||
|  |             include "alpha_enc.c" | ||||||
|  |             include "analysis_enc.c" | ||||||
|  |             include "backward_references_cost_enc.c" | ||||||
|  |             include "backward_references_enc.c" | ||||||
|  |             include "config_enc.c" | ||||||
|  |             include "cost_enc.c" | ||||||
|  |             include "filter_enc.c" | ||||||
|  |             include "frame_enc.c" | ||||||
|  |             include "histogram_enc.c" | ||||||
|  |             include "iterator_enc.c" | ||||||
|  |             include "near_lossless_enc.c" | ||||||
|  |             include "picture_enc.c" | ||||||
|  |             include "picture_csp_enc.c" | ||||||
|  |             include "picture_psnr_enc.c" | ||||||
|  |             include "picture_rescale_enc.c" | ||||||
|  |             include "picture_tools_enc.c" | ||||||
|  |             include "predictor_enc.c" | ||||||
|  |             include "quant_enc.c" | ||||||
|  |             include "syntax_enc.c" | ||||||
|  |             include "token_enc.c" | ||||||
|  |             include "tree_enc.c" | ||||||
|  |             include "vp8l_enc.c" | ||||||
|  |             include "webp_enc.c" | ||||||
|  |             srcDir "src/utils" | ||||||
|  |             include "bit_writer_utils.c" | ||||||
|  |             include "huffman_encode_utils.c" | ||||||
|  |             include "quant_levels_utils.c" | ||||||
|  |           } | ||||||
|  |           exportedHeaders { | ||||||
|  |             srcDir "src" | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     webpdemux(NativeLibrarySpec) { | ||||||
|  |       sources { | ||||||
|  |         c { | ||||||
|  |           source { | ||||||
|  |             srcDir "src/demux" | ||||||
|  |             include "anim_decode.c" | ||||||
|  |             include "demux.c" | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     webpmux(NativeLibrarySpec) { | ||||||
|  |       sources { | ||||||
|  |         c { | ||||||
|  |           source { | ||||||
|  |             srcDir "src/mux/" | ||||||
|  |             include "anim_encode.c" | ||||||
|  |             include "muxedit.c" | ||||||
|  |             include "muxinternal.c" | ||||||
|  |             include "muxread.c" | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // Executables from examples. | ||||||
|  |     example_util(NativeLibrarySpec) { | ||||||
|  |       binaries { | ||||||
|  |         all { | ||||||
|  |           lib library: "webp", linkage: "static" | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |       sources { | ||||||
|  |         c { | ||||||
|  |           source { | ||||||
|  |             srcDir "./examples" | ||||||
|  |             include "example_util.c" | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     imageio_util(NativeLibrarySpec) { | ||||||
|  |       binaries { | ||||||
|  |         all { | ||||||
|  |           lib library: "webp", linkage: "static" | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |       sources { | ||||||
|  |         c { | ||||||
|  |           source { | ||||||
|  |             srcDir "./imageio" | ||||||
|  |             include "imageio_util.c" | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     imagedec(NativeLibrarySpec) { | ||||||
|  |       binaries { | ||||||
|  |         all { | ||||||
|  |           lib library: "webpdemux", linkage: "static" | ||||||
|  |           lib library: "webp", linkage: "static" | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |       sources { | ||||||
|  |         c { | ||||||
|  |           source { | ||||||
|  |             srcDir "./imageio" | ||||||
|  |             include "image_dec.c" | ||||||
|  |             include "jpegdec.c" | ||||||
|  |             include "metadata.c" | ||||||
|  |             include "pngdec.c" | ||||||
|  |             include "pnmdec.c" | ||||||
|  |             include "tiffdec.c" | ||||||
|  |             include "webpdec.c" | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     imageenc(NativeLibrarySpec) { | ||||||
|  |       binaries { | ||||||
|  |         all { | ||||||
|  |           lib library: "webp", linkage: "static" | ||||||
|  |           lib library: "imageio_util", linkage: "static" | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |       sources { | ||||||
|  |         c { | ||||||
|  |           source { | ||||||
|  |             srcDir "./imageio" | ||||||
|  |             include "image_enc.c" | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     cwebp(NativeExecutableSpec) { | ||||||
|  |       binaries { | ||||||
|  |         all { | ||||||
|  |           lib library: "example_util", linkage: "static" | ||||||
|  |           lib library: "imagedec", linkage: "static" | ||||||
|  |           lib library: "imageio_util", linkage: "static" | ||||||
|  |           lib library: "webpdemux", linkage: "static" | ||||||
|  |           lib library: "webp", linkage: "static" | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |       sources { | ||||||
|  |         c { | ||||||
|  |           source { | ||||||
|  |             srcDir "./examples" | ||||||
|  |             include "cwebp.c" | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     dwebp(NativeExecutableSpec) { | ||||||
|  |       binaries { | ||||||
|  |         all { | ||||||
|  |           lib library: "example_util", linkage: "static" | ||||||
|  |           lib library: "imagedec", linkage: "static" | ||||||
|  |           lib library: "imageenc", linkage: "static" | ||||||
|  |           lib library: "imageio_util", linkage: "static" | ||||||
|  |           lib library: "webpdemux", linkage: "static" | ||||||
|  |           lib library: "webp" | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |       sources { | ||||||
|  |         c { | ||||||
|  |           source { | ||||||
|  |               srcDir "./examples" | ||||||
|  |               include "dwebp.c" | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     webpmux_example(NativeExecutableSpec) { | ||||||
|  |       binaries { | ||||||
|  |         all { | ||||||
|  |           lib library: "example_util", linkage: "static" | ||||||
|  |           lib library: "imageio_util", linkage: "static" | ||||||
|  |           lib library: "webpmux", linkage: "static" | ||||||
|  |           lib library: "webp" | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |       sources { | ||||||
|  |         c { | ||||||
|  |           source { | ||||||
|  |             srcDir "./examples" | ||||||
|  |             include "webpmux.c" | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     img2webp_example(NativeExecutableSpec) { | ||||||
|  |       binaries { | ||||||
|  |         all { | ||||||
|  |           lib library: "example_util", linkage: "static" | ||||||
|  |           lib library: "imagedec", linkage: "static" | ||||||
|  |           lib library: "imageio_util", linkage: "static" | ||||||
|  |           lib library: "webpmux", linkage: "static" | ||||||
|  |           lib library: "webpdemux", linkage: "static" | ||||||
|  |           lib library: "webp" | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |       sources { | ||||||
|  |         c { | ||||||
|  |           source { | ||||||
|  |             srcDir "./examples" | ||||||
|  |             include "img2webp.c" | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     webpinfo_example(NativeExecutableSpec) { | ||||||
|  |       binaries { | ||||||
|  |         all { | ||||||
|  |           lib library: "example_util", linkage: "static" | ||||||
|  |           lib library: "imageio_util", linkage: "static" | ||||||
|  |           lib library: "webp" | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |       sources { | ||||||
|  |         c { | ||||||
|  |           source { | ||||||
|  |             srcDir "./examples" | ||||||
|  |             include "webpinfo.c" | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   tasks { | ||||||
|  |     // Task to test all possible configurations. | ||||||
|  |     buildAllExecutables(Task) { | ||||||
|  |       dependsOn $.binaries.findAll { it.buildable } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										18
									
								
								external/libwebp/libwebp/cmake/WebPConfig.cmake.in
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								external/libwebp/libwebp/cmake/WebPConfig.cmake.in
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,18 @@ | |||||||
|  | set(WebP_VERSION @PROJECT_VERSION@) | ||||||
|  | set(WEBP_VERSION ${WebP_VERSION}) | ||||||
|  |  | ||||||
|  | @PACKAGE_INIT@ | ||||||
|  |  | ||||||
|  | if(@WEBP_USE_THREAD@) | ||||||
|  |   include(CMakeFindDependencyMacro) | ||||||
|  |   find_dependency(Threads REQUIRED) | ||||||
|  | endif() | ||||||
|  |  | ||||||
|  | include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Targets.cmake") | ||||||
|  |  | ||||||
|  | set_and_check(WebP_INCLUDE_DIR "@PACKAGE_CMAKE_INSTALL_INCLUDEDIR@") | ||||||
|  | set(WEBP_INCLUDE_DIRS ${WebP_INCLUDE_DIRS}) | ||||||
|  | set(WebP_LIBRARIES "@INSTALLED_LIBRARIES@") | ||||||
|  | set(WEBP_LIBRARIES "${WebP_LIBRARIES}") | ||||||
|  |  | ||||||
|  | check_required_components(WebP) | ||||||
							
								
								
									
										116
									
								
								external/libwebp/libwebp/cmake/config.h.in
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										116
									
								
								external/libwebp/libwebp/cmake/config.h.in
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,116 @@ | |||||||
|  | /* Adapted from the autotools src/webp/config.h.in.  */ | ||||||
|  |  | ||||||
|  | /* Define if building universal (internal helper macro) */ | ||||||
|  | /* TODO: handle properly in CMake */ | ||||||
|  | #cmakedefine AC_APPLE_UNIVERSAL_BUILD 1 | ||||||
|  |  | ||||||
|  | /* Set to 1 if __builtin_bswap16 is available */ | ||||||
|  | #cmakedefine HAVE_BUILTIN_BSWAP16 1 | ||||||
|  |  | ||||||
|  | /* Set to 1 if __builtin_bswap32 is available */ | ||||||
|  | #cmakedefine HAVE_BUILTIN_BSWAP32 1 | ||||||
|  |  | ||||||
|  | /* Set to 1 if __builtin_bswap64 is available */ | ||||||
|  | #cmakedefine HAVE_BUILTIN_BSWAP64 1 | ||||||
|  |  | ||||||
|  | /* Define to 1 if you have the <cpu-features.h> header file. */ | ||||||
|  | #cmakedefine HAVE_CPU_FEATURES_H 1 | ||||||
|  |  | ||||||
|  | /* Define to 1 if you have the <GLUT/glut.h> header file. */ | ||||||
|  | #cmakedefine HAVE_GLUT_GLUT_H 1 | ||||||
|  |  | ||||||
|  | /* Define to 1 if you have the <GL/glut.h> header file. */ | ||||||
|  | #cmakedefine HAVE_GL_GLUT_H 1 | ||||||
|  |  | ||||||
|  | /* Define to 1 if you have the <OpenGL/glut.h> header file. */ | ||||||
|  | #cmakedefine HAVE_OPENGL_GLUT_H 1 | ||||||
|  |  | ||||||
|  | /* Define to 1 if you have the <shlwapi.h> header file. */ | ||||||
|  | #cmakedefine HAVE_SHLWAPI_H 1 | ||||||
|  |  | ||||||
|  | /* Define to 1 if you have the <unistd.h> header file. */ | ||||||
|  | #cmakedefine HAVE_UNISTD_H 1 | ||||||
|  |  | ||||||
|  | /* Define to 1 if you have the <wincodec.h> header file. */ | ||||||
|  | #cmakedefine HAVE_WINCODEC_H 1 | ||||||
|  |  | ||||||
|  | /* Define to 1 if you have the <windows.h> header file. */ | ||||||
|  | #cmakedefine HAVE_WINDOWS_H 1 | ||||||
|  |  | ||||||
|  | /* Define to the sub-directory in which libtool stores uninstalled libraries. | ||||||
|  |    */ | ||||||
|  | /* TODO: handle properly in CMake */ | ||||||
|  | #cmakedefine LT_OBJDIR "@LT_OBJDIR@" | ||||||
|  |  | ||||||
|  | /* Name of package */ | ||||||
|  | #cmakedefine PACKAGE "@PROJECT_NAME@" | ||||||
|  |  | ||||||
|  | /* Define to the address where bug reports for this package should be sent. */ | ||||||
|  | #cmakedefine PACKAGE_BUGREPORT "@PACKAGE_BUGREPORT@" | ||||||
|  |  | ||||||
|  | /* Define to the full name of this package. */ | ||||||
|  | #cmakedefine PACKAGE_NAME "@PACKAGE_NAME@" | ||||||
|  |  | ||||||
|  | /* Define to the full name and version of this package. */ | ||||||
|  | #cmakedefine PACKAGE_STRING "@PACKAGE_STRING@" | ||||||
|  |  | ||||||
|  | /* Define to the one symbol short name of this package. */ | ||||||
|  | #cmakedefine PACKAGE_TARNAME "@PACKAGE_TARNAME@" | ||||||
|  |  | ||||||
|  | /* Define to the home page for this package. */ | ||||||
|  | #cmakedefine PACKAGE_URL "@PACKAGE_URL@" | ||||||
|  |  | ||||||
|  | /* Define to the version of this package. */ | ||||||
|  | #cmakedefine PACKAGE_VERSION "@PACKAGE_VERSION@" | ||||||
|  |  | ||||||
|  | /* Version number of package */ | ||||||
|  | #cmakedefine VERSION "@VERSION@" | ||||||
|  |  | ||||||
|  | /* Set to 1 if GIF library is installed */ | ||||||
|  | #cmakedefine WEBP_HAVE_GIF 1 | ||||||
|  |  | ||||||
|  | /* Set to 1 if OpenGL is supported */ | ||||||
|  | #cmakedefine WEBP_HAVE_GL 1 | ||||||
|  |  | ||||||
|  | /* Set to 1 if JPEG library is installed */ | ||||||
|  | #cmakedefine WEBP_HAVE_JPEG 1 | ||||||
|  |  | ||||||
|  | /* Set to 1 if NEON is supported */ | ||||||
|  | #cmakedefine WEBP_HAVE_NEON | ||||||
|  |  | ||||||
|  | /* Set to 1 if runtime detection of NEON is enabled */ | ||||||
|  | /* TODO: handle properly in CMake */ | ||||||
|  | #cmakedefine WEBP_HAVE_NEON_RTCD | ||||||
|  |  | ||||||
|  | /* Set to 1 if PNG library is installed */ | ||||||
|  | #cmakedefine WEBP_HAVE_PNG 1 | ||||||
|  |  | ||||||
|  | /* Set to 1 if SDL library is installed */ | ||||||
|  | #cmakedefine WEBP_HAVE_SDL 1 | ||||||
|  |  | ||||||
|  | /* Set to 1 if SSE2 is supported */ | ||||||
|  | #cmakedefine WEBP_HAVE_SSE2 1 | ||||||
|  |  | ||||||
|  | /* Set to 1 if SSE4.1 is supported */ | ||||||
|  | #cmakedefine WEBP_HAVE_SSE41 1 | ||||||
|  |  | ||||||
|  | /* Set to 1 if TIFF library is installed */ | ||||||
|  | #cmakedefine WEBP_HAVE_TIFF 1 | ||||||
|  |  | ||||||
|  | /* Enable near lossless encoding */ | ||||||
|  | #cmakedefine WEBP_NEAR_LOSSLESS 1 | ||||||
|  |  | ||||||
|  | /* Undefine this to disable thread support. */ | ||||||
|  | #cmakedefine WEBP_USE_THREAD 1 | ||||||
|  |  | ||||||
|  | /* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most | ||||||
|  |    significant byte first (like Motorola and SPARC, unlike Intel). */ | ||||||
|  | #if defined AC_APPLE_UNIVERSAL_BUILD | ||||||
|  | # if defined __BIG_ENDIAN__ | ||||||
|  | #  define WORDS_BIGENDIAN 1 | ||||||
|  | # endif | ||||||
|  | #else | ||||||
|  | # ifndef WORDS_BIGENDIAN | ||||||
|  | #  undef WORDS_BIGENDIAN | ||||||
|  | # endif | ||||||
|  | #endif | ||||||
							
								
								
									
										159
									
								
								external/libwebp/libwebp/cmake/cpu.cmake
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										159
									
								
								external/libwebp/libwebp/cmake/cpu.cmake
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,159 @@ | |||||||
|  | #  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. | ||||||
|  | include(CMakePushCheckState) | ||||||
|  |  | ||||||
|  | function(webp_check_compiler_flag WEBP_SIMD_FLAG ENABLE_SIMD) | ||||||
|  |   if(NOT ENABLE_SIMD) | ||||||
|  |     message(STATUS "Disabling ${WEBP_SIMD_FLAG} optimization.") | ||||||
|  |     set(WEBP_HAVE_${WEBP_SIMD_FLAG} 0 PARENT_SCOPE) | ||||||
|  |     return() | ||||||
|  |   endif() | ||||||
|  |   unset(WEBP_HAVE_FLAG_${WEBP_SIMD_FLAG} CACHE) | ||||||
|  |   cmake_push_check_state() | ||||||
|  |   set(CMAKE_REQUIRED_INCLUDES ${CMAKE_CURRENT_SOURCE_DIR}) | ||||||
|  |   check_c_source_compiles( | ||||||
|  |     " | ||||||
|  |       #include \"${CMAKE_CURRENT_LIST_DIR}/../src/dsp/dsp.h\" | ||||||
|  |       int main(void) { | ||||||
|  |         #if !defined(WEBP_USE_${WEBP_SIMD_FLAG}) | ||||||
|  |         this is not valid code | ||||||
|  |         #endif | ||||||
|  |         return 0; | ||||||
|  |       } | ||||||
|  |     " | ||||||
|  |     WEBP_HAVE_FLAG_${WEBP_SIMD_FLAG}) | ||||||
|  |   cmake_pop_check_state() | ||||||
|  |   if(WEBP_HAVE_FLAG_${WEBP_SIMD_FLAG}) | ||||||
|  |     set(WEBP_HAVE_${WEBP_SIMD_FLAG} 1 PARENT_SCOPE) | ||||||
|  |   else() | ||||||
|  |     set(WEBP_HAVE_${WEBP_SIMD_FLAG} 0 PARENT_SCOPE) | ||||||
|  |   endif() | ||||||
|  | endfunction() | ||||||
|  |  | ||||||
|  | # those are included in the names of WEBP_USE_* in c++ code. | ||||||
|  | set(WEBP_SIMD_FLAGS "SSE41;SSE2;MIPS32;MIPS_DSP_R2;NEON;MSA") | ||||||
|  | set(WEBP_SIMD_FILE_EXTENSIONS | ||||||
|  |     "_sse41.c;_sse2.c;_mips32.c;_mips_dsp_r2.c;_neon.c;_msa.c") | ||||||
|  | if(MSVC AND CMAKE_C_COMPILER_ID STREQUAL "MSVC") | ||||||
|  |   # With at least Visual Studio 12 (2013)+ /arch is not necessary to build SSE2 | ||||||
|  |   # or SSE4 code unless a lesser /arch is forced. MSVC does not have a SSE4 | ||||||
|  |   # flag, but an AVX one. Using that with SSE4 code risks generating illegal | ||||||
|  |   # instructions when used on machines with SSE4 only. The flags are left for | ||||||
|  |   # older (untested) versions to avoid any potential compatibility issues. | ||||||
|  |   if(MSVC_VERSION GREATER_EQUAL 1800 AND NOT CMAKE_C_FLAGS MATCHES "/arch:") | ||||||
|  |     set(SIMD_ENABLE_FLAGS) | ||||||
|  |   else() | ||||||
|  |     set(SIMD_ENABLE_FLAGS "/arch:AVX;/arch:SSE2;;;;") | ||||||
|  |   endif() | ||||||
|  |   set(SIMD_DISABLE_FLAGS) | ||||||
|  | else() | ||||||
|  |   set(SIMD_ENABLE_FLAGS "-msse4.1;-msse2;-mips32;-mdspr2;-mfpu=neon;-mmsa") | ||||||
|  |   set(SIMD_DISABLE_FLAGS "-mno-sse4.1;-mno-sse2;;-mno-dspr2;;-mno-msa") | ||||||
|  | endif() | ||||||
|  |  | ||||||
|  | set(WEBP_SIMD_FILES_TO_INCLUDE) | ||||||
|  | set(WEBP_SIMD_FLAGS_TO_INCLUDE) | ||||||
|  |  | ||||||
|  | if(${ANDROID}) | ||||||
|  |   if(${ANDROID_ABI} STREQUAL "armeabi-v7a") | ||||||
|  |     # This is because Android studio uses the configuration "-march=armv7-a | ||||||
|  |     # -mfloat-abi=softfp -mfpu=vfpv3-d16" that does not trigger neon | ||||||
|  |     # optimizations but should (as this configuration does not exist anymore). | ||||||
|  |     set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mfpu=neon ") | ||||||
|  |   endif() | ||||||
|  | endif() | ||||||
|  |  | ||||||
|  | list(LENGTH WEBP_SIMD_FLAGS WEBP_SIMD_FLAGS_LENGTH) | ||||||
|  | math(EXPR WEBP_SIMD_FLAGS_RANGE "${WEBP_SIMD_FLAGS_LENGTH} - 1") | ||||||
|  |  | ||||||
|  | foreach(I_SIMD RANGE ${WEBP_SIMD_FLAGS_RANGE}) | ||||||
|  |   # With Emscripten 2.0.9 -msimd128 -mfpu=neon will enable NEON, but the source | ||||||
|  |   # will fail to compile. | ||||||
|  |   if(EMSCRIPTEN AND ${I_SIMD} GREATER_EQUAL 2) | ||||||
|  |     break() | ||||||
|  |   endif() | ||||||
|  |  | ||||||
|  |   list(GET WEBP_SIMD_FLAGS ${I_SIMD} WEBP_SIMD_FLAG) | ||||||
|  |  | ||||||
|  |   # First try with no extra flag added as the compiler might have default flags | ||||||
|  |   # (especially on Android). | ||||||
|  |   unset(WEBP_HAVE_${WEBP_SIMD_FLAG} CACHE) | ||||||
|  |   cmake_push_check_state() | ||||||
|  |   set(CMAKE_REQUIRED_FLAGS) | ||||||
|  |   webp_check_compiler_flag(${WEBP_SIMD_FLAG} ${WEBP_ENABLE_SIMD}) | ||||||
|  |   if(NOT WEBP_HAVE_${WEBP_SIMD_FLAG}) | ||||||
|  |     list(GET SIMD_ENABLE_FLAGS ${I_SIMD} SIMD_COMPILE_FLAG) | ||||||
|  |     if(EMSCRIPTEN) | ||||||
|  |       set(SIMD_COMPILE_FLAG "-msimd128 ${SIMD_COMPILE_FLAG}") | ||||||
|  |     endif() | ||||||
|  |     set(CMAKE_REQUIRED_FLAGS ${SIMD_COMPILE_FLAG}) | ||||||
|  |     webp_check_compiler_flag(${WEBP_SIMD_FLAG} ${WEBP_ENABLE_SIMD}) | ||||||
|  |   else() | ||||||
|  |     if(MSVC AND SIMD_ENABLE_FLAGS) | ||||||
|  |       # The detection for SSE2/SSE4 support under MSVC is based on the compiler | ||||||
|  |       # version so e.g., clang-cl will require flags to enable the assembly. | ||||||
|  |       list(GET SIMD_ENABLE_FLAGS ${I_SIMD} SIMD_COMPILE_FLAG) | ||||||
|  |     else() | ||||||
|  |       set(SIMD_COMPILE_FLAG " ") | ||||||
|  |     endif() | ||||||
|  |   endif() | ||||||
|  |   # Check which files we should include or not. | ||||||
|  |   list(GET WEBP_SIMD_FILE_EXTENSIONS ${I_SIMD} WEBP_SIMD_FILE_EXTENSION) | ||||||
|  |   file(GLOB SIMD_FILES "${CMAKE_CURRENT_LIST_DIR}/../" | ||||||
|  |        "src/dsp/*${WEBP_SIMD_FILE_EXTENSION}") | ||||||
|  |   if(WEBP_HAVE_${WEBP_SIMD_FLAG}) | ||||||
|  |     # Memorize the file and flags. | ||||||
|  |     foreach(FILE ${SIMD_FILES}) | ||||||
|  |       list(APPEND WEBP_SIMD_FILES_TO_INCLUDE ${FILE}) | ||||||
|  |       list(APPEND WEBP_SIMD_FLAGS_TO_INCLUDE ${SIMD_COMPILE_FLAG}) | ||||||
|  |     endforeach() | ||||||
|  |   else() | ||||||
|  |     # Remove the file from the list. | ||||||
|  |     foreach(FILE ${SIMD_FILES}) | ||||||
|  |       list(APPEND WEBP_SIMD_FILES_NOT_TO_INCLUDE ${FILE}) | ||||||
|  |     endforeach() | ||||||
|  |     # Explicitly disable SIMD. | ||||||
|  |     if(SIMD_DISABLE_FLAGS) | ||||||
|  |       list(GET SIMD_DISABLE_FLAGS ${I_SIMD} SIMD_COMPILE_FLAG) | ||||||
|  |       include(CheckCCompilerFlag) | ||||||
|  |       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) | ||||||
|  |         check_c_compiler_flag(${SIMD_COMPILE_FLAG} HAS_COMPILE_FLAG) | ||||||
|  |         if(HAS_COMPILE_FLAG) | ||||||
|  |           # Do one more check for Clang to circumvent CMake issue 13194. | ||||||
|  |           if(COMMAND check_compiler_flag_common_patterns) | ||||||
|  |             # Only in CMake 3.0 and above. | ||||||
|  |             check_compiler_flag_common_patterns(COMMON_PATTERNS) | ||||||
|  |           else() | ||||||
|  |             set(COMMON_PATTERNS) | ||||||
|  |           endif() | ||||||
|  |           set(CMAKE_REQUIRED_DEFINITIONS ${SIMD_COMPILE_FLAG}) | ||||||
|  |           check_c_source_compiles( | ||||||
|  |             "int main(void) {return 0;}" FLAG_${SIMD_COMPILE_FLAG} FAIL_REGEX | ||||||
|  |             "warning: argument unused during compilation:" ${COMMON_PATTERNS}) | ||||||
|  |           if(NOT FLAG_${SIMD_COMPILE_FLAG}) | ||||||
|  |             unset(HAS_COMPILE_FLAG) | ||||||
|  |             unset(HAS_COMPILE_FLAG CACHE) | ||||||
|  |           endif() | ||||||
|  |         endif() | ||||||
|  |         if(HAS_COMPILE_FLAG) | ||||||
|  |           set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${SIMD_COMPILE_FLAG}") | ||||||
|  |         endif() | ||||||
|  |       endif() | ||||||
|  |     endif() | ||||||
|  |   endif() | ||||||
|  |   cmake_pop_check_state() | ||||||
|  | endforeach() | ||||||
							
								
								
									
										172
									
								
								external/libwebp/libwebp/cmake/deps.cmake
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										172
									
								
								external/libwebp/libwebp/cmake/deps.cmake
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,172 @@ | |||||||
|  | #  Copyright (c) 2021 Google LLC. | ||||||
|  | # | ||||||
|  | #  Use of this source code is governed by a BSD-style license | ||||||
|  | #  that can be found in the LICENSE file in the root of the source | ||||||
|  | #  tree. An additional intellectual property rights grant can be found | ||||||
|  | #  in the file PATENTS.  All contributing project authors may | ||||||
|  | #  be found in the AUTHORS file in the root of the source tree. | ||||||
|  |  | ||||||
|  | # Generate the config.h to compile with specific intrinsics / libs. | ||||||
|  |  | ||||||
|  | # Check for compiler options. | ||||||
|  | include(CheckCSourceCompiles) | ||||||
|  | check_c_source_compiles( | ||||||
|  |   " | ||||||
|  |     int main(void) { | ||||||
|  |       (void)__builtin_bswap16(0); | ||||||
|  |       return 0; | ||||||
|  |     } | ||||||
|  |   " | ||||||
|  |   HAVE_BUILTIN_BSWAP16) | ||||||
|  | check_c_source_compiles( | ||||||
|  |   " | ||||||
|  |     int main(void) { | ||||||
|  |       (void)__builtin_bswap32(0); | ||||||
|  |       return 0; | ||||||
|  |     } | ||||||
|  |   " | ||||||
|  |   HAVE_BUILTIN_BSWAP32) | ||||||
|  | check_c_source_compiles( | ||||||
|  |   " | ||||||
|  |     int main(void) { | ||||||
|  |       (void)__builtin_bswap64(0); | ||||||
|  |       return 0; | ||||||
|  |     } | ||||||
|  |   " | ||||||
|  |   HAVE_BUILTIN_BSWAP64) | ||||||
|  |  | ||||||
|  | # Check for libraries. | ||||||
|  | if(WEBP_USE_THREAD) | ||||||
|  |   find_package(Threads) | ||||||
|  |   if(Threads_FOUND) | ||||||
|  |     # work around cmake bug on QNX (https://cmake.org/Bug/view.php?id=11333) | ||||||
|  |     if(CMAKE_USE_PTHREADS_INIT AND NOT CMAKE_SYSTEM_NAME STREQUAL "QNX") | ||||||
|  |       set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pthread") | ||||||
|  |     endif() | ||||||
|  |     list(APPEND WEBP_DEP_LIBRARIES Threads::Threads) | ||||||
|  |   endif() | ||||||
|  |   set(WEBP_USE_THREAD ${Threads_FOUND}) | ||||||
|  | endif() | ||||||
|  |  | ||||||
|  | # TODO: this seems unused, check with autotools. | ||||||
|  | set(LT_OBJDIR ".libs/") | ||||||
|  |  | ||||||
|  | # Only useful for vwebp, so useless for now. | ||||||
|  | find_package(OpenGL) | ||||||
|  | set(WEBP_HAVE_GL ${OPENGL_FOUND}) | ||||||
|  |  | ||||||
|  | # Check if we need to link to the C math library. We do not look for it as it is | ||||||
|  | # not found when cross-compiling, while it is here. | ||||||
|  | check_c_source_compiles( | ||||||
|  |   " | ||||||
|  |     #include <math.h> | ||||||
|  |     int main(int argc, char** argv) { | ||||||
|  |       return (int)pow(argc, 2.5); | ||||||
|  |     } | ||||||
|  |   " | ||||||
|  |   HAVE_MATH_LIBRARY) | ||||||
|  | if(NOT HAVE_MATH_LIBRARY) | ||||||
|  |   message(STATUS "Adding -lm flag.") | ||||||
|  |   list(APPEND SHARPYUV_DEP_LIBRARIES m) | ||||||
|  |   list(APPEND WEBP_DEP_LIBRARIES m) | ||||||
|  | endif() | ||||||
|  |  | ||||||
|  | # Find the standard image libraries. | ||||||
|  | set(WEBP_DEP_IMG_LIBRARIES) | ||||||
|  | set(WEBP_DEP_IMG_INCLUDE_DIRS) | ||||||
|  | if(WEBP_FIND_IMG_LIBS) | ||||||
|  |   foreach(I_LIB PNG JPEG TIFF) | ||||||
|  |     # Disable tiff when compiling in static mode as it is failing on Ubuntu. | ||||||
|  |     if(WEBP_LINK_STATIC AND ${I_LIB} STREQUAL "TIFF") | ||||||
|  |       message(STATUS "TIFF is disabled when statically linking.") | ||||||
|  |       continue() | ||||||
|  |     endif() | ||||||
|  |     find_package(${I_LIB}) | ||||||
|  |     set(WEBP_HAVE_${I_LIB} ${${I_LIB}_FOUND}) | ||||||
|  |     if(${I_LIB}_FOUND) | ||||||
|  |       list(APPEND WEBP_DEP_IMG_LIBRARIES ${${I_LIB}_LIBRARIES}) | ||||||
|  |       list(APPEND WEBP_DEP_IMG_INCLUDE_DIRS ${${I_LIB}_INCLUDE_DIR} | ||||||
|  |            ${${I_LIB}_INCLUDE_DIRS}) | ||||||
|  |     endif() | ||||||
|  |   endforeach() | ||||||
|  |   if(WEBP_DEP_IMG_INCLUDE_DIRS) | ||||||
|  |     list(REMOVE_DUPLICATES WEBP_DEP_IMG_INCLUDE_DIRS) | ||||||
|  |   endif() | ||||||
|  |  | ||||||
|  |   # GIF detection, gifdec isn't part of the imageio lib. | ||||||
|  |   include(CMakePushCheckState) | ||||||
|  |   set(WEBP_DEP_GIF_LIBRARIES) | ||||||
|  |   set(WEBP_DEP_GIF_INCLUDE_DIRS) | ||||||
|  |   find_package(GIF) | ||||||
|  |   set(WEBP_HAVE_GIF ${GIF_FOUND}) | ||||||
|  |   if(GIF_FOUND) | ||||||
|  |     # GIF find_package only locates the header and library, it doesn't fail | ||||||
|  |     # compile tests when detecting the version, but falls back to 3 (as of at | ||||||
|  |     # least cmake 3.7.2). Make sure the library links to avoid incorrect | ||||||
|  |     # detection when cross compiling. | ||||||
|  |     cmake_push_check_state() | ||||||
|  |     set(CMAKE_REQUIRED_LIBRARIES ${GIF_LIBRARIES}) | ||||||
|  |     set(CMAKE_REQUIRED_INCLUDES ${GIF_INCLUDE_DIR}) | ||||||
|  |     check_c_source_compiles( | ||||||
|  |       " | ||||||
|  |       #include <gif_lib.h> | ||||||
|  |       int main(void) { | ||||||
|  |         (void)DGifOpenFileHandle; | ||||||
|  |         return 0; | ||||||
|  |       } | ||||||
|  |       " | ||||||
|  |       GIF_COMPILES) | ||||||
|  |     cmake_pop_check_state() | ||||||
|  |     if(GIF_COMPILES) | ||||||
|  |       list(APPEND WEBP_DEP_GIF_LIBRARIES ${GIF_LIBRARIES}) | ||||||
|  |       list(APPEND WEBP_DEP_GIF_INCLUDE_DIRS ${GIF_INCLUDE_DIR}) | ||||||
|  |     else() | ||||||
|  |       unset(GIF_FOUND) | ||||||
|  |     endif() | ||||||
|  |   endif() | ||||||
|  | endif() | ||||||
|  |  | ||||||
|  | # Check for specific headers. | ||||||
|  | include(CheckIncludeFiles) | ||||||
|  | check_include_files(GLUT/glut.h HAVE_GLUT_GLUT_H) | ||||||
|  | check_include_files(GL/glut.h HAVE_GL_GLUT_H) | ||||||
|  | check_include_files(OpenGL/glut.h HAVE_OPENGL_GLUT_H) | ||||||
|  | check_include_files(shlwapi.h HAVE_SHLWAPI_H) | ||||||
|  | check_include_files(unistd.h HAVE_UNISTD_H) | ||||||
|  | check_include_files(wincodec.h HAVE_WINCODEC_H) | ||||||
|  | check_include_files(windows.h HAVE_WINDOWS_H) | ||||||
|  |  | ||||||
|  | # Windows specifics | ||||||
|  | if(HAVE_WINCODEC_H) | ||||||
|  |   list(APPEND WEBP_DEP_LIBRARIES shlwapi ole32 windowscodecs) | ||||||
|  | endif() | ||||||
|  |  | ||||||
|  | # Check for SIMD extensions. | ||||||
|  | include(${CMAKE_CURRENT_LIST_DIR}/cpu.cmake) | ||||||
|  |  | ||||||
|  | # Define extra info. | ||||||
|  | set(PACKAGE ${PROJECT_NAME}) | ||||||
|  | set(PACKAGE_NAME ${PROJECT_NAME}) | ||||||
|  |  | ||||||
|  | # Read from configure.ac. | ||||||
|  | file(READ ${CMAKE_CURRENT_SOURCE_DIR}/configure.ac CONFIGURE_AC) | ||||||
|  | string(REGEX MATCHALL "\\[([0-9a-z\\.:/]*)\\]" CONFIGURE_AC_PACKAGE_INFO | ||||||
|  |              ${CONFIGURE_AC}) | ||||||
|  | function(strip_bracket VAR) | ||||||
|  |   string(LENGTH ${${VAR}} TMP_LEN) | ||||||
|  |   math(EXPR TMP_LEN ${TMP_LEN}-2) | ||||||
|  |   string(SUBSTRING ${${VAR}} 1 ${TMP_LEN} TMP_SUB) | ||||||
|  |   set(${VAR} ${TMP_SUB} PARENT_SCOPE) | ||||||
|  | endfunction() | ||||||
|  |  | ||||||
|  | list(GET CONFIGURE_AC_PACKAGE_INFO 1 PACKAGE_VERSION) | ||||||
|  | strip_bracket(PACKAGE_VERSION) | ||||||
|  | list(GET CONFIGURE_AC_PACKAGE_INFO 2 PACKAGE_BUGREPORT) | ||||||
|  | strip_bracket(PACKAGE_BUGREPORT) | ||||||
|  | list(GET CONFIGURE_AC_PACKAGE_INFO 3 PACKAGE_URL) | ||||||
|  | strip_bracket(PACKAGE_URL) | ||||||
|  |  | ||||||
|  | # Build more info. | ||||||
|  | set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}") | ||||||
|  | set(PACKAGE_TARNAME ${PACKAGE_NAME}) | ||||||
|  | set(VERSION ${PACKAGE_VERSION}) | ||||||
							
								
								
									
										4
									
								
								external/libwebp/libwebp/codereview.settings
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								external/libwebp/libwebp/codereview.settings
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,4 @@ | |||||||
|  | # This file is used by git cl to get repository specific information. | ||||||
|  | GERRIT_HOST: True | ||||||
|  | CODE_REVIEW_SERVER: chromium-review.googlesource.com | ||||||
|  | GERRIT_SQUASH_UPLOADS: False | ||||||
							
								
								
									
										803
									
								
								external/libwebp/libwebp/configure.ac
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										803
									
								
								external/libwebp/libwebp/configure.ac
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,803 @@ | |||||||
|  | AC_INIT([libwebp], [1.3.1], | ||||||
|  |         [https://bugs.chromium.org/p/webp],, | ||||||
|  |         [https://developers.google.com/speed/webp]) | ||||||
|  | AC_CANONICAL_HOST | ||||||
|  | AC_PREREQ([2.60]) | ||||||
|  | AM_INIT_AUTOMAKE([-Wall foreign subdir-objects]) | ||||||
|  |  | ||||||
|  | dnl === automake >= 1.12 requires this for 'unusual archivers' support. | ||||||
|  | dnl === it must occur before LT_INIT (AC_PROG_LIBTOOL). | ||||||
|  | m4_ifdef([AM_PROG_AR], [AM_PROG_AR]) | ||||||
|  |  | ||||||
|  | dnl === AC_PROG_LIBTOOL is deprecated. | ||||||
|  | m4_ifdef([LT_INIT], [LT_INIT], [AC_PROG_LIBTOOL]) | ||||||
|  | AC_PROG_SED | ||||||
|  | AM_PROG_CC_C_O | ||||||
|  |  | ||||||
|  | dnl === Enable less verbose output when building. | ||||||
|  | m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) | ||||||
|  |  | ||||||
|  | dnl == test endianness | ||||||
|  | AC_C_BIGENDIAN | ||||||
|  |  | ||||||
|  | dnl === SET_IF_UNSET(shell_var, value) | ||||||
|  | dnl ===   Set the shell variable 'shell_var' to 'value' if it is unset. | ||||||
|  | AC_DEFUN([SET_IF_UNSET], [test "${$1+set}" = "set" || $1=$2]) | ||||||
|  |  | ||||||
|  | AC_ARG_ENABLE([everything], | ||||||
|  |               AS_HELP_STRING([--enable-everything], | ||||||
|  |                              [Enable all optional targets. These can still be | ||||||
|  |                               disabled with --disable-target]), | ||||||
|  |               [SET_IF_UNSET([enable_libsharpyuv], [$enableval]) | ||||||
|  |                SET_IF_UNSET([enable_libwebpdecoder], [$enableval]) | ||||||
|  |                SET_IF_UNSET([enable_libwebpdemux], [$enableval]) | ||||||
|  |                SET_IF_UNSET([enable_libwebpextras], [$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 | ||||||
|  |  | ||||||
|  | AC_MSG_CHECKING(whether asserts are enabled) | ||||||
|  | AC_ARG_ENABLE([asserts], | ||||||
|  |               AS_HELP_STRING([--enable-asserts], | ||||||
|  |                              [Enable assert checks])) | ||||||
|  | if test "x${enable_asserts-no}" = "xno"; then | ||||||
|  |   AM_CPPFLAGS="${AM_CPPFLAGS} -DNDEBUG" | ||||||
|  | fi | ||||||
|  | AC_MSG_RESULT(${enable_asserts-no}) | ||||||
|  | AC_SUBST([AM_CPPFLAGS]) | ||||||
|  |  | ||||||
|  | AC_ARG_WITH([pkgconfigdir], AS_HELP_STRING([--with-pkgconfigdir=DIR], | ||||||
|  |             [Path to the pkgconfig directory @<:@LIBDIR/pkgconfig@:>@]), | ||||||
|  |             [pkgconfigdir="$withval"], [pkgconfigdir='${libdir}/pkgconfig']) | ||||||
|  | AC_SUBST([pkgconfigdir]) | ||||||
|  |  | ||||||
|  | dnl === TEST_AND_ADD_CFLAGS(var, flag) | ||||||
|  | dnl ===   Checks whether $CC supports 'flag' and adds it to 'var' | ||||||
|  | dnl ===   on success. | ||||||
|  | AC_DEFUN([TEST_AND_ADD_CFLAGS], | ||||||
|  |          [SAVED_CFLAGS="$CFLAGS" | ||||||
|  |           CFLAGS="-Werror $2" | ||||||
|  |           AC_MSG_CHECKING([whether $CC supports $2]) | ||||||
|  |           dnl Note AC_LANG_PROGRAM([]) uses an old-style main definition. | ||||||
|  |           AC_COMPILE_IFELSE([AC_LANG_SOURCE([int main(void) { return 0; }])], | ||||||
|  |                             [AC_MSG_RESULT([yes])] | ||||||
|  |                             dnl Simply append the variable avoiding a | ||||||
|  |                             dnl compatibility ifdef for AS_VAR_APPEND as this | ||||||
|  |                             dnl variable shouldn't grow all that large. | ||||||
|  |                             [$1="${$1} $2"], | ||||||
|  |                             [AC_MSG_RESULT([no])]) | ||||||
|  |           CFLAGS="$SAVED_CFLAGS"]) | ||||||
|  | TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-fvisibility=hidden]) | ||||||
|  | TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wall]) | ||||||
|  | TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wconstant-conversion]) | ||||||
|  | TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wdeclaration-after-statement]) | ||||||
|  | TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wextra]) | ||||||
|  | TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wfloat-conversion]) | ||||||
|  | TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wformat -Wformat-nonliteral]) | ||||||
|  | TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wformat -Wformat-security]) | ||||||
|  | TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wmissing-declarations]) | ||||||
|  | TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wmissing-prototypes]) | ||||||
|  | TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wold-style-definition]) | ||||||
|  | TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wparentheses-equality]) | ||||||
|  | TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wshadow]) | ||||||
|  | TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wshorten-64-to-32]) | ||||||
|  | TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wundef]) | ||||||
|  | TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wunreachable-code-aggressive]) | ||||||
|  | TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wunreachable-code]) | ||||||
|  | TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wunused-but-set-variable]) | ||||||
|  | TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wunused]) | ||||||
|  | TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wvla]) | ||||||
|  | # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=62040 | ||||||
|  | # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61622 | ||||||
|  | AS_IF([test "$GCC" = "yes" ], [ | ||||||
|  |        gcc_version=`$CC -dumpversion` | ||||||
|  |        gcc_wht_bug="" | ||||||
|  |        case "$host_cpu" in | ||||||
|  |          aarch64|arm64) | ||||||
|  |           case "$gcc_version" in | ||||||
|  |             4.9|4.9.0|4.9.1) gcc_wht_bug=yes ;; | ||||||
|  |           esac | ||||||
|  |        esac | ||||||
|  |        AS_IF([test "$gcc_wht_bug" = "yes"], [ | ||||||
|  |               TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-frename-registers])])]) | ||||||
|  | # Use -flax-vector-conversions, if available, when building intrinsics with | ||||||
|  | # older versions of gcc. The flag appeared in 4.3.x, but if backported, and | ||||||
|  | # -fno-lax-vector-conversions is set, errors may occur with the intrinsics | ||||||
|  | # files along with the older system includes, e.g., emmintrin.h. | ||||||
|  | # Originally observed with cc (GCC) 4.2.1 20070831 patched [FreeBSD] (9.3). | ||||||
|  | # https://bugs.chromium.org/p/webp/issues/detail?id=274 | ||||||
|  | AS_IF([test "$GCC" = "yes" ], [ | ||||||
|  |        case "$host_cpu" in | ||||||
|  |          amd64|i?86|x86_64) | ||||||
|  |            AC_COMPILE_IFELSE( | ||||||
|  |              dnl only check for -flax-vector-conversions with older gcc, skip | ||||||
|  |              dnl clang as it reports itself as 4.2.1, but the flag isn't needed. | ||||||
|  |              [AC_LANG_SOURCE([#if !defined(__clang__) && defined(__GNUC__) && \ | ||||||
|  |                                   ((__GNUC__ << 8) | __GNUC_MINOR__) < 0x403 | ||||||
|  |                               #error old gcc | ||||||
|  |                               #endif | ||||||
|  |                               int main(void) { return 0; } | ||||||
|  |                              ])],, | ||||||
|  |               [TEST_AND_ADD_CFLAGS([INTRINSICS_CFLAGS], | ||||||
|  |                                    [-flax-vector-conversions])]) | ||||||
|  |            ;; | ||||||
|  |        esac]) | ||||||
|  | AC_SUBST([AM_CFLAGS]) | ||||||
|  |  | ||||||
|  | dnl === Check for machine specific flags | ||||||
|  | AC_ARG_ENABLE([sse4.1], | ||||||
|  |               AS_HELP_STRING([--disable-sse4.1], | ||||||
|  |                              [Disable detection of SSE4.1 support | ||||||
|  |                               @<:@default=auto@:>@])) | ||||||
|  |  | ||||||
|  | AS_IF([test "x$enable_sse4_1" != "xno" -a "x$enable_sse2" != "xno"], [ | ||||||
|  |   SSE41_FLAGS="$INTRINSICS_CFLAGS $SSE41_FLAGS" | ||||||
|  |   TEST_AND_ADD_CFLAGS([SSE41_FLAGS], [-msse4.1]) | ||||||
|  |   AS_IF([test -n "$SSE41_FLAGS"], [ | ||||||
|  |     SAVED_CFLAGS=$CFLAGS | ||||||
|  |     CFLAGS="$CFLAGS $SSE41_FLAGS" | ||||||
|  |     AC_CHECK_HEADER([smmintrin.h], | ||||||
|  |                     [AC_DEFINE(WEBP_HAVE_SSE41, [1], | ||||||
|  |                      [Set to 1 if SSE4.1 is supported])], | ||||||
|  |                     [SSE41_FLAGS=""]) | ||||||
|  |     CFLAGS=$SAVED_CFLAGS]) | ||||||
|  |   AC_SUBST([SSE41_FLAGS])]) | ||||||
|  |  | ||||||
|  | AC_ARG_ENABLE([sse2], | ||||||
|  |               AS_HELP_STRING([--disable-sse2], | ||||||
|  |                              [Disable detection of SSE2 support | ||||||
|  |                               @<:@default=auto@:>@])) | ||||||
|  |  | ||||||
|  | AS_IF([test "x$enable_sse2" != "xno"], [ | ||||||
|  |   SSE2_FLAGS="$INTRINSICS_CFLAGS $SSE2_FLAGS" | ||||||
|  |   TEST_AND_ADD_CFLAGS([SSE2_FLAGS], [-msse2]) | ||||||
|  |   AS_IF([test -n "$SSE2_FLAGS"], [ | ||||||
|  |     SAVED_CFLAGS=$CFLAGS | ||||||
|  |     CFLAGS="$CFLAGS $SSE2_FLAGS" | ||||||
|  |     AC_CHECK_HEADER([emmintrin.h], | ||||||
|  |                     [AC_DEFINE(WEBP_HAVE_SSE2, [1], | ||||||
|  |                      [Set to 1 if SSE2 is supported])], | ||||||
|  |                     [SSE2_FLAGS=""]) | ||||||
|  |     CFLAGS=$SAVED_CFLAGS]) | ||||||
|  |   AC_SUBST([SSE2_FLAGS])]) | ||||||
|  |  | ||||||
|  | AC_ARG_ENABLE([neon], | ||||||
|  |               AS_HELP_STRING([--disable-neon], | ||||||
|  |                              [Disable detection of NEON support | ||||||
|  |                               @<:@default=auto@:>@])) | ||||||
|  |  | ||||||
|  | AC_ARG_ENABLE([neon_rtcd], | ||||||
|  |               AS_HELP_STRING([--disable-neon-rtcd], | ||||||
|  |                              [Disable runtime detection of NEON support via | ||||||
|  |                               /proc/cpuinfo on Linux hosts | ||||||
|  |                               @<:@default=auto@:>@])) | ||||||
|  | # For ARM(7) hosts: | ||||||
|  | # Both NEON flags unset and NEON support detected = build all modules with NEON | ||||||
|  | # NEON detected with the use of -mfpu=neon = build only NEON modules with NEON | ||||||
|  | AS_IF([test "x$enable_neon" != "xno"], [ | ||||||
|  |   case "$host_cpu" in | ||||||
|  |     arm|armv7*) | ||||||
|  |       # Test for NEON support without flags before falling back to -mfpu=neon | ||||||
|  |       for flag in '' '-mfpu=neon'; do | ||||||
|  |         LOCAL_NEON_FLAGS="$INTRINSICS_CFLAGS $NEON_FLAGS" | ||||||
|  |         TEST_AND_ADD_CFLAGS([LOCAL_NEON_FLAGS], [$flag]) | ||||||
|  |         SAVED_CFLAGS=$CFLAGS | ||||||
|  |         CFLAGS="$CFLAGS $LOCAL_NEON_FLAGS" | ||||||
|  |  | ||||||
|  |         dnl Note AC_LANG_PROGRAM([]) uses an old-style main definition. | ||||||
|  |         AC_COMPILE_IFELSE([AC_LANG_SOURCE([ | ||||||
|  |           #include <arm_neon.h> | ||||||
|  |           int main(void) { | ||||||
|  |             int8x8_t v = vdup_n_s8(0); | ||||||
|  |             (void)v; | ||||||
|  |             return 0; | ||||||
|  |           }])], | ||||||
|  |           [NEON_FLAGS="$(echo $LOCAL_NEON_FLAGS | $SED 's/^ *//')" | ||||||
|  |            AS_IF([test -n "$NEON_FLAGS"], [ | ||||||
|  |              AS_IF([test "${host_os%%-*}" = "linux" -o \ | ||||||
|  |                          "x$enable_neon_rtcd" = "xno"], [ | ||||||
|  |                CFLAGS=$SAVED_CFLAGS | ||||||
|  |                AC_DEFINE(WEBP_HAVE_NEON, [1], [Set to 1 if NEON is supported]) | ||||||
|  |                break | ||||||
|  |              ],[ | ||||||
|  |                AC_MSG_WARN(m4_normalize([NEON runtime cpu-detection is | ||||||
|  |                                          unavailable for ${host_os%%-*}. Force | ||||||
|  |                                          with CFLAGS=-mfpu=neon or | ||||||
|  |                                          --disable-neon-rtcd.])) | ||||||
|  |                enable_neon_rtcd=no | ||||||
|  |                NEON_FLAGS="" | ||||||
|  |              ]) | ||||||
|  |            ],[ | ||||||
|  |              CFLAGS=$SAVED_CFLAGS | ||||||
|  |              AC_DEFINE(WEBP_HAVE_NEON, [1], [Set to 1 if NEON is supported]) | ||||||
|  |              break | ||||||
|  |            ])]) | ||||||
|  |         CFLAGS=$SAVED_CFLAGS | ||||||
|  |       done | ||||||
|  |  | ||||||
|  |       AS_IF([test -n "$NEON_FLAGS"], [ | ||||||
|  |         # If NEON is available and rtcd is disabled apply NEON_FLAGS globally. | ||||||
|  |         AS_IF([test "x$enable_neon_rtcd" = "xno"], [ | ||||||
|  |           AM_CFLAGS="$AM_CFLAGS $NEON_FLAGS" | ||||||
|  |           NEON_FLAGS=""], | ||||||
|  |           [AC_DEFINE(WEBP_HAVE_NEON_RTCD, [1], | ||||||
|  |                      [Set to 1 if runtime detection of NEON is enabled])])]) | ||||||
|  |  | ||||||
|  |       case "$host_os" in | ||||||
|  |         *android*) AC_CHECK_HEADERS([cpu-features.h]) ;; | ||||||
|  |       esac | ||||||
|  |       ;; | ||||||
|  |     aarch64*|arm64*) | ||||||
|  |       AC_DEFINE(WEBP_HAVE_NEON, [1], [Set to 1 if NEON is supported]) | ||||||
|  |       ;; | ||||||
|  |   esac | ||||||
|  |   AC_SUBST([NEON_FLAGS])]) | ||||||
|  |  | ||||||
|  | dnl === CLEAR_LIBVARS([var_pfx]) | ||||||
|  | dnl ===   Clears <var_pfx>_{INCLUDES,LIBS}. | ||||||
|  | AC_DEFUN([CLEAR_LIBVARS], [$1_INCLUDES=""; $1_LIBS=""]) | ||||||
|  |  | ||||||
|  | dnl === WITHLIB_OPTION([opt_pfx], [outvar_pfx]) | ||||||
|  | dnl ===   Defines --with-<opt_pfx>{include,lib}dir options which set | ||||||
|  | dnl ===   the variables <outvar_pfx>_{INCLUDES,LIBS}. | ||||||
|  | AC_DEFUN([WITHLIB_OPTION], | ||||||
|  |   [AC_ARG_WITH([$1includedir], | ||||||
|  |                AS_HELP_STRING([--with-$1includedir=DIR], | ||||||
|  |                               [use $2 includes from DIR]), | ||||||
|  |                $2_INCLUDES="-I$withval") | ||||||
|  |    AC_ARG_WITH([$1libdir], | ||||||
|  |                AS_HELP_STRING([--with-$1libdir=DIR], | ||||||
|  |                               [use $2 libraries from DIR]), | ||||||
|  |                [$2_LIBS="-L$withval"])]) | ||||||
|  |  | ||||||
|  | dnl === LIBCHECK_PROLOGUE([var_pfx]) | ||||||
|  | dnl ===   Caches the current values of CPPFLAGS/LIBS in SAVED_* then | ||||||
|  | dnl ===   prepends the current values with <var_pfx>_{INCLUDES,LIBS}. | ||||||
|  | AC_DEFUN([LIBCHECK_PROLOGUE], | ||||||
|  |          [SAVED_CPPFLAGS=$CPPFLAGS | ||||||
|  |           SAVED_LIBS=$LIBS | ||||||
|  |           CPPFLAGS="$$1_INCLUDES $CPPFLAGS" | ||||||
|  |           LIBS="$$1_LIBS $LIBS"]) | ||||||
|  |  | ||||||
|  | dnl === LIBCHECK_EPILOGUE([var_pfx]) | ||||||
|  | dnl ===   Restores the values of CPPFLAGS/LIBS from SAVED_* and exports | ||||||
|  | dnl ===   <var_pfx>_{INCLUDES,LIBS} with AC_SUBST. | ||||||
|  | AC_DEFUN([LIBCHECK_EPILOGUE], | ||||||
|  |          [AC_SUBST($1_LIBS) | ||||||
|  |           AC_SUBST($1_INCLUDES) | ||||||
|  |           CPPFLAGS=$SAVED_CPPFLAGS | ||||||
|  |           LIBS=$SAVED_LIBS]) | ||||||
|  |  | ||||||
|  | dnl === Check for gcc builtins | ||||||
|  |  | ||||||
|  | dnl === CHECK_FOR_BUILTIN([builtin], [param], [define]) | ||||||
|  | dnl ===   links a C AC_LANG_PROGRAM, with <builtin>(<param>) | ||||||
|  | dnl ===   AC_DEFINE'ing <define> if successful. | ||||||
|  | AC_DEFUN([CHECK_FOR_BUILTIN], | ||||||
|  |          [AC_LANG_PUSH([C]) | ||||||
|  |           AC_MSG_CHECKING([for $1]) | ||||||
|  |           AC_LINK_IFELSE([AC_LANG_PROGRAM([], [(void)$1($2)])], | ||||||
|  |                          [AC_MSG_RESULT([yes]) | ||||||
|  |                           AC_DEFINE([$3], [1], | ||||||
|  |                                     [Set to 1 if $1 is available])], | ||||||
|  |                          [AC_MSG_RESULT([no])]), | ||||||
|  |           AC_LANG_POP]) | ||||||
|  |  | ||||||
|  | dnl AC_CHECK_FUNC doesn't work with builtin's. | ||||||
|  | CHECK_FOR_BUILTIN([__builtin_bswap16], [1u << 15], [HAVE_BUILTIN_BSWAP16]) | ||||||
|  | CHECK_FOR_BUILTIN([__builtin_bswap32], [1u << 31], [HAVE_BUILTIN_BSWAP32]) | ||||||
|  | CHECK_FOR_BUILTIN([__builtin_bswap64], [1ull << 63], [HAVE_BUILTIN_BSWAP64]) | ||||||
|  |  | ||||||
|  | dnl === Check for pthread support | ||||||
|  | AC_ARG_ENABLE([threading], | ||||||
|  |               AS_HELP_STRING([--disable-threading], | ||||||
|  |                              [Disable detection of thread support]),, | ||||||
|  |               [enable_threading=yes]) | ||||||
|  | if test "$enable_threading" = "yes"; then | ||||||
|  |   AC_MSG_NOTICE([checking for threading support...]) | ||||||
|  |   AX_PTHREAD([AC_DEFINE([WEBP_USE_THREAD], [1], | ||||||
|  |                         [Undefine this to disable thread support.]) | ||||||
|  |               LIBS="$PTHREAD_LIBS $LIBS" | ||||||
|  |               CFLAGS="$CFLAGS $PTHREAD_CFLAGS" | ||||||
|  |               CC="$PTHREAD_CC" | ||||||
|  |              ], | ||||||
|  |              [AC_CHECK_FUNC([_beginthreadex], | ||||||
|  |                             [AC_DEFINE([WEBP_USE_THREAD], [1], | ||||||
|  |                                        [Undefine this to disable thread | ||||||
|  |                                         support.])], | ||||||
|  |                             [enable_threading=no])]) | ||||||
|  | fi | ||||||
|  | AC_MSG_NOTICE([checking if threading is enabled... ${enable_threading-no}]) | ||||||
|  |  | ||||||
|  | dnl === check for OpenGL/GLUT support === | ||||||
|  |  | ||||||
|  | AC_ARG_ENABLE([gl], AS_HELP_STRING([--disable-gl], | ||||||
|  |                                    [Disable detection of OpenGL support | ||||||
|  |                                     @<:@default=auto@:>@])) | ||||||
|  | AS_IF([test "x$enable_gl" != "xno"], [ | ||||||
|  |   CLEAR_LIBVARS([GL]) | ||||||
|  |   WITHLIB_OPTION([gl], [GL]) | ||||||
|  |  | ||||||
|  |   LIBCHECK_PROLOGUE([GL]) | ||||||
|  |  | ||||||
|  |   glut_cflags="none" | ||||||
|  |   glut_ldflags="none" | ||||||
|  |   case $host_os in | ||||||
|  |     darwin*) | ||||||
|  |       # Special case for OSX builds. Append these to give the user a chance to | ||||||
|  |       # override with --with-gl* | ||||||
|  |       glut_cflags="$glut_cflags|-framework GLUT -framework OpenGL" | ||||||
|  |       glut_ldflags="$glut_ldflags|-framework GLUT -framework OpenGL" | ||||||
|  |       # quiet deprecation warnings for glut | ||||||
|  |       TEST_AND_ADD_CFLAGS([AM_CFLAGS], [-Wno-deprecated-declarations]) | ||||||
|  |       ;; | ||||||
|  |   esac | ||||||
|  |  | ||||||
|  |   GLUT_SAVED_CPPFLAGS="$CPPFLAGS" | ||||||
|  |   SAVED_IFS="$IFS" | ||||||
|  |   IFS="|" | ||||||
|  |   for flag in $glut_cflags; do | ||||||
|  |     # restore IFS immediately as the autoconf macros may need the default. | ||||||
|  |     IFS="$SAVED_IFS" | ||||||
|  |     unset ac_cv_header_GL_glut_h | ||||||
|  |     unset ac_cv_header_OpenGL_glut_h | ||||||
|  |  | ||||||
|  |     case $flag in | ||||||
|  |       none) ;; | ||||||
|  |       *) CPPFLAGS="$flag $CPPFLAGS";; | ||||||
|  |     esac | ||||||
|  |     AC_CHECK_HEADERS([GL/glut.h GLUT/glut.h OpenGL/glut.h], | ||||||
|  |                      [glut_headers=yes; | ||||||
|  |                       test "$flag" = "none" || GL_INCLUDES="$CPPFLAGS"; | ||||||
|  |                       break]) | ||||||
|  |     CPPFLAGS="$GLUT_SAVED_CPPFLAGS" | ||||||
|  |     test "$glut_headers" = "yes" && break | ||||||
|  |   done | ||||||
|  |   IFS="$SAVED_IFS" | ||||||
|  |  | ||||||
|  |   if test "$glut_headers" = "yes"; then | ||||||
|  |     AC_LANG_PUSH([C]) | ||||||
|  |     GLUT_SAVED_LDFLAGS="$LDFLAGS" | ||||||
|  |     SAVED_IFS="$IFS" | ||||||
|  |     IFS="|" | ||||||
|  |     for flag in $glut_ldflags; do | ||||||
|  |       # restore IFS immediately as the autoconf macros may need the default. | ||||||
|  |       IFS="$SAVED_IFS" | ||||||
|  |       unset ac_cv_search_glBegin | ||||||
|  |  | ||||||
|  |       case $flag in | ||||||
|  |         none) ;; | ||||||
|  |         *) LDFLAGS="$flag $LDFLAGS";; | ||||||
|  |       esac | ||||||
|  |  | ||||||
|  |       # find libGL | ||||||
|  |       GL_SAVED_LIBS="$LIBS" | ||||||
|  |       AC_SEARCH_LIBS([glBegin], [GL OpenGL opengl32]) | ||||||
|  |       LIBS="$GL_SAVED_LIBS" | ||||||
|  |  | ||||||
|  |       # A direct link to libGL may not be necessary on e.g., linux. | ||||||
|  |       GLUT_SAVED_LIBS="$LIBS" | ||||||
|  |       for lib in "" "-lglut" "-lglut $ac_cv_search_glBegin"; do | ||||||
|  |         LIBS="$lib" | ||||||
|  |         AC_LINK_IFELSE( | ||||||
|  |           [AC_LANG_PROGRAM([ | ||||||
|  |              #ifdef __cplusplus | ||||||
|  |              # define EXTERN_C extern "C" | ||||||
|  |              #else | ||||||
|  |              # define EXTERN_C | ||||||
|  |              #endif | ||||||
|  |              EXTERN_C char glOrtho(); | ||||||
|  |              EXTERN_C char glutMainLoop(); | ||||||
|  |             ],[ | ||||||
|  |              glOrtho(); | ||||||
|  |              glutMainLoop(); | ||||||
|  |             ]) | ||||||
|  |           ], | ||||||
|  |           AC_DEFINE(WEBP_HAVE_GL, [1], | ||||||
|  |                     [Set to 1 if OpenGL is supported]) | ||||||
|  |           [glut_support=yes], [] | ||||||
|  |         ) | ||||||
|  |         if test "$glut_support" = "yes"; then | ||||||
|  |           GL_LIBS="$LDFLAGS $lib" | ||||||
|  |           break | ||||||
|  |         fi | ||||||
|  |       done | ||||||
|  |       LIBS="$GLUT_SAVED_LIBS" | ||||||
|  |       LDFLAGS="$GLUT_SAVED_LDFLAGS" | ||||||
|  |       test "$glut_support" = "yes" && break | ||||||
|  |     done | ||||||
|  |     IFS="$SAVED_IFS" | ||||||
|  |     AC_LANG_POP | ||||||
|  |   fi | ||||||
|  |  | ||||||
|  |   LIBCHECK_EPILOGUE([GL]) | ||||||
|  |  | ||||||
|  |   if test "$glut_support" = "yes" -a "$enable_libwebpdemux" = "yes"; then | ||||||
|  |     build_vwebp=yes | ||||||
|  |   else | ||||||
|  |     AC_MSG_NOTICE( | ||||||
|  |       m4_normalize([Not building vwebp. | ||||||
|  |                     OpenGL libraries and --enable-libwebpdemux are required.])) | ||||||
|  |   fi | ||||||
|  | ]) | ||||||
|  | AM_CONDITIONAL([BUILD_VWEBP], [test "$build_vwebp" = "yes"]) | ||||||
|  |  | ||||||
|  | dnl === check for SDL support === | ||||||
|  |  | ||||||
|  | AC_ARG_ENABLE([sdl], | ||||||
|  |               AS_HELP_STRING([--disable-sdl], | ||||||
|  |                              [Disable detection of SDL support | ||||||
|  |                               @<:@default=auto@:>@])) | ||||||
|  | AS_IF([test "x$enable_sdl" != "xno"], [ | ||||||
|  |   CLEAR_LIBVARS([SDL]) | ||||||
|  |   AC_PATH_PROGS([LIBSDL_CONFIG], [sdl-config]) | ||||||
|  |   if test -n "$LIBSDL_CONFIG"; then | ||||||
|  |     SDL_INCLUDES=`$LIBSDL_CONFIG --cflags` | ||||||
|  |     SDL_LIBS="`$LIBSDL_CONFIG --libs`" | ||||||
|  |   fi | ||||||
|  |  | ||||||
|  |   WITHLIB_OPTION([sdl], [SDL]) | ||||||
|  |  | ||||||
|  |   sdl_header="no" | ||||||
|  |   LIBCHECK_PROLOGUE([SDL]) | ||||||
|  |   AC_CHECK_HEADER([SDL/SDL.h], [sdl_header="SDL/SDL.h"], | ||||||
|  |                   [AC_CHECK_HEADER([SDL.h], [sdl_header="SDL.h"], | ||||||
|  |                   [AC_MSG_WARN(SDL library not available - no sdl.h)])]) | ||||||
|  |   if test x"$sdl_header" != "xno"; then | ||||||
|  |     AC_LANG_PUSH(C) | ||||||
|  |     SDL_SAVED_LIBS="$LIBS" | ||||||
|  |     for lib in "" "-lSDL" "-lSDLmain -lSDL"; do | ||||||
|  |       LIBS="$SDL_SAVED_LIBS $lib" | ||||||
|  |       # Perform a full link to ensure SDL_main is resolved if needed. | ||||||
|  |       AC_LINK_IFELSE( | ||||||
|  |         [AC_LANG_SOURCE([ | ||||||
|  |            #include <$sdl_header> | ||||||
|  |            int main(int argc, char** argv) { | ||||||
|  |              SDL_Init(0); | ||||||
|  |              return 0; | ||||||
|  |            }])], | ||||||
|  |         [SDL_LIBS="$LDFLAGS $LIBS" | ||||||
|  |          SDL_INCLUDES="$SDL_INCLUDES -DWEBP_HAVE_SDL" | ||||||
|  |          AC_DEFINE(WEBP_HAVE_SDL, [1], | ||||||
|  |                    [Set to 1 if SDL library is installed]) | ||||||
|  |          sdl_support=yes] | ||||||
|  |       ) | ||||||
|  |       if test x"$sdl_support" = "xyes"; then | ||||||
|  |         break | ||||||
|  |       fi | ||||||
|  |     done | ||||||
|  |     # LIBS is restored by LIBCHECK_EPILOGUE | ||||||
|  |     AC_LANG_POP | ||||||
|  |     if test x"$sdl_header" = "xSDL.h"; then | ||||||
|  |       SDL_INCLUDES="$SDL_INCLUDES -DWEBP_HAVE_JUST_SDL_H" | ||||||
|  |     fi | ||||||
|  |   fi | ||||||
|  |   LIBCHECK_EPILOGUE([SDL]) | ||||||
|  |  | ||||||
|  |   if test x"$sdl_support" = "xyes"; then | ||||||
|  |     build_vwebp_sdl=yes | ||||||
|  |   else | ||||||
|  |     AC_MSG_NOTICE([Not building vwebp-sdl. SDL library is required.]) | ||||||
|  |   fi | ||||||
|  | ]) | ||||||
|  |  | ||||||
|  | AM_CONDITIONAL([BUILD_VWEBP_SDL], [test "$build_vwebp_sdl" = "yes"]) | ||||||
|  |  | ||||||
|  | dnl === check for PNG support === | ||||||
|  |  | ||||||
|  | AC_ARG_ENABLE([png], AS_HELP_STRING([--disable-png], | ||||||
|  |                                     [Disable detection of PNG format support | ||||||
|  |                                      @<:@default=auto@:>@])) | ||||||
|  | AS_IF([test "x$enable_png" != "xno"], [ | ||||||
|  |   CLEAR_LIBVARS([PNG]) | ||||||
|  |   AC_PATH_PROGS([LIBPNG_CONFIG], | ||||||
|  |                 [libpng-config libpng16-config libpng15-config libpng14-config \ | ||||||
|  |                  libpng12-config]) | ||||||
|  |   if test -n "$LIBPNG_CONFIG"; then | ||||||
|  |     PNG_INCLUDES=`$LIBPNG_CONFIG --cflags` | ||||||
|  |     PNG_LIBS="`$LIBPNG_CONFIG --ldflags`" | ||||||
|  |   fi | ||||||
|  |  | ||||||
|  |   WITHLIB_OPTION([png], [PNG]) | ||||||
|  |  | ||||||
|  |   LIBCHECK_PROLOGUE([PNG]) | ||||||
|  |   AC_CHECK_HEADER(png.h, | ||||||
|  |     AC_SEARCH_LIBS(png_get_libpng_ver, [png], | ||||||
|  |                    [test "$ac_cv_search_png_get_libpng_ver" = "none required" \ | ||||||
|  |                       || PNG_LIBS="$PNG_LIBS $ac_cv_search_png_get_libpng_ver" | ||||||
|  |                     PNG_INCLUDES="$PNG_INCLUDES -DWEBP_HAVE_PNG" | ||||||
|  |                     AC_DEFINE(WEBP_HAVE_PNG, [1], | ||||||
|  |                               [Set to 1 if PNG library is installed]) | ||||||
|  |                     png_support=yes | ||||||
|  |                    ], | ||||||
|  |                    [AC_MSG_WARN(Optional png library not found) | ||||||
|  |                     PNG_LIBS="" | ||||||
|  |                     PNG_INCLUDES="" | ||||||
|  |                    ], | ||||||
|  |                    [$MATH_LIBS]), | ||||||
|  |     [AC_MSG_WARN(png library not available - no png.h) | ||||||
|  |      PNG_LIBS="" | ||||||
|  |      PNG_INCLUDES="" | ||||||
|  |     ], | ||||||
|  |   ) | ||||||
|  |   LIBCHECK_EPILOGUE([PNG]) | ||||||
|  | ]) | ||||||
|  |  | ||||||
|  | dnl === check for JPEG support === | ||||||
|  |  | ||||||
|  | AC_ARG_ENABLE([jpeg], | ||||||
|  |               AS_HELP_STRING([--disable-jpeg], | ||||||
|  |                              [Disable detection of JPEG format support | ||||||
|  |                               @<:@default=auto@:>@])) | ||||||
|  | AS_IF([test "x$enable_jpeg" != "xno"], [ | ||||||
|  |   CLEAR_LIBVARS([JPEG]) | ||||||
|  |   WITHLIB_OPTION([jpeg], [JPEG]) | ||||||
|  |  | ||||||
|  |   LIBCHECK_PROLOGUE([JPEG]) | ||||||
|  |   AC_CHECK_HEADER(jpeglib.h, | ||||||
|  |     AC_CHECK_LIB(jpeg, jpeg_set_defaults, | ||||||
|  |                  [JPEG_LIBS="$JPEG_LIBS -ljpeg" | ||||||
|  |                   JPEG_INCLUDES="$JPEG_INCLUDES -DWEBP_HAVE_JPEG" | ||||||
|  |                   AC_DEFINE(WEBP_HAVE_JPEG, [1], | ||||||
|  |                             [Set to 1 if JPEG library is installed]) | ||||||
|  |                   jpeg_support=yes | ||||||
|  |                  ], | ||||||
|  |                  AC_MSG_WARN(Optional jpeg library not found), | ||||||
|  |                  [$MATH_LIBS]), | ||||||
|  |     AC_MSG_WARN(jpeg library not available - no jpeglib.h) | ||||||
|  |   ) | ||||||
|  |   LIBCHECK_EPILOGUE([JPEG]) | ||||||
|  | ]) | ||||||
|  |  | ||||||
|  | dnl === check for TIFF support === | ||||||
|  |  | ||||||
|  | AC_ARG_ENABLE([tiff], | ||||||
|  |               AS_HELP_STRING([--disable-tiff], | ||||||
|  |                              [Disable detection of TIFF format support | ||||||
|  |                               @<:@default=auto@:>@])) | ||||||
|  | AS_IF([test "x$enable_tiff" != "xno"], [ | ||||||
|  |   CLEAR_LIBVARS([TIFF]) | ||||||
|  |   WITHLIB_OPTION([tiff], [TIFF]) | ||||||
|  |  | ||||||
|  |   LIBCHECK_PROLOGUE([TIFF]) | ||||||
|  |   AC_CHECK_HEADER(tiffio.h, | ||||||
|  |     AC_CHECK_LIB(tiff, TIFFGetVersion, | ||||||
|  |                  [TIFF_LIBS="$TIFF_LIBS -ltiff" | ||||||
|  |                   TIFF_INCLUDES="$TIFF_INCLUDES -DWEBP_HAVE_TIFF" | ||||||
|  |                   AC_DEFINE(WEBP_HAVE_TIFF, [1], | ||||||
|  |                             [Set to 1 if TIFF library is installed]) | ||||||
|  |                   tiff_support=yes | ||||||
|  |                  ], | ||||||
|  |                  AC_MSG_WARN(Optional tiff library not found), | ||||||
|  |                  [$MATH_LIBS]), | ||||||
|  |     AC_MSG_WARN(tiff library not available - no tiffio.h) | ||||||
|  |   ) | ||||||
|  |   LIBCHECK_EPILOGUE([TIFF]) | ||||||
|  | ]) | ||||||
|  |  | ||||||
|  | dnl === check for GIF support === | ||||||
|  |  | ||||||
|  | AC_ARG_ENABLE([gif], AS_HELP_STRING([--disable-gif], | ||||||
|  |                                     [Disable detection of GIF format support | ||||||
|  |                                      @<:@default=auto@:>@])) | ||||||
|  | AS_IF([test "x$enable_gif" != "xno"], [ | ||||||
|  |   CLEAR_LIBVARS([GIF]) | ||||||
|  |   WITHLIB_OPTION([gif], [GIF]) | ||||||
|  |  | ||||||
|  |   LIBCHECK_PROLOGUE([GIF]) | ||||||
|  |   AC_CHECK_HEADER(gif_lib.h, | ||||||
|  |     AC_CHECK_LIB([gif], [DGifOpenFileHandle], | ||||||
|  |                  [GIF_LIBS="$GIF_LIBS -lgif" | ||||||
|  |                   AC_DEFINE(WEBP_HAVE_GIF, [1], | ||||||
|  |                             [Set to 1 if GIF library is installed]) | ||||||
|  |                   gif_support=yes | ||||||
|  |                  ], | ||||||
|  |                  AC_MSG_WARN(Optional gif library not found), | ||||||
|  |                  [$MATH_LIBS]), | ||||||
|  |     AC_MSG_WARN(gif library not available - no gif_lib.h) | ||||||
|  |   ) | ||||||
|  |   LIBCHECK_EPILOGUE([GIF]) | ||||||
|  |  | ||||||
|  |   if test "$gif_support" = "yes" -a \ | ||||||
|  |           "$enable_libwebpdemux" = "yes"; then | ||||||
|  |     build_anim_diff=yes | ||||||
|  |   else | ||||||
|  |     AC_MSG_NOTICE( | ||||||
|  |       [Not building anim_diff. libgif and --enable-libwebpdemux are required.]) | ||||||
|  |   fi | ||||||
|  |  | ||||||
|  |   if test "$gif_support" = "yes" -a \ | ||||||
|  |           "$enable_libwebpmux" = "yes"; then | ||||||
|  |     build_gif2webp=yes | ||||||
|  |   else | ||||||
|  |     AC_MSG_NOTICE( | ||||||
|  |       [Not building gif2webp. libgif and --enable-libwebpmux are required.]) | ||||||
|  |   fi | ||||||
|  | ]) | ||||||
|  | AM_CONDITIONAL([BUILD_ANIMDIFF], [test "${build_anim_diff}" = "yes"]) | ||||||
|  | AM_CONDITIONAL([BUILD_GIF2WEBP], [test "${build_gif2webp}" = "yes"]) | ||||||
|  |  | ||||||
|  | if test "$enable_libwebpdemux" = "yes" -a "$enable_libwebpmux" = "yes"; then | ||||||
|  |   build_img2webp=yes | ||||||
|  | else | ||||||
|  |   AC_MSG_NOTICE( | ||||||
|  |     m4_normalize([Not building img2webp. | ||||||
|  |                   --enable-libwebpdemux & --enable-libwebpmux are required.])) | ||||||
|  | fi | ||||||
|  | AM_CONDITIONAL([BUILD_IMG2WEBP], [test "${build_img2webp}" = "yes"]) | ||||||
|  |  | ||||||
|  | if test "$enable_libwebpmux" = "yes"; then | ||||||
|  |   build_webpinfo=yes | ||||||
|  | else | ||||||
|  |   AC_MSG_NOTICE([Not building webpinfo. --enable-libwebpdemux is required.]) | ||||||
|  | fi | ||||||
|  | AM_CONDITIONAL([BUILD_WEBPINFO], [test "${build_webpinfo}" = "yes"]) | ||||||
|  |  | ||||||
|  | dnl === check for WIC support === | ||||||
|  |  | ||||||
|  | AC_ARG_ENABLE([wic], | ||||||
|  |               AS_HELP_STRING([--disable-wic], | ||||||
|  |                              [Disable Windows Imaging Component (WIC) detection. | ||||||
|  |                               @<:@default=auto@:>@]),, | ||||||
|  |               [enable_wic=yes]) | ||||||
|  |  | ||||||
|  | case $host_os in | ||||||
|  | mingw*) | ||||||
|  | if test "$enable_wic" = "yes"; then | ||||||
|  |   AC_CHECK_HEADERS([wincodec.h shlwapi.h windows.h]) | ||||||
|  |   if test "$ac_cv_header_wincodec_h" = "yes"; then | ||||||
|  |     AC_MSG_CHECKING(for Windows Imaging Component support) | ||||||
|  |     SAVED_LIBS=$LIBS | ||||||
|  |     LIBS="-lshlwapi -lole32 $LIBS" | ||||||
|  |     # match include structure from [cd]webp.c | ||||||
|  |     wic_headers=" | ||||||
|  |       #define INITGUID | ||||||
|  |       #define CINTERFACE | ||||||
|  |       #define COBJMACROS | ||||||
|  |       #define _WIN32_IE 0x500 | ||||||
|  |  | ||||||
|  |       #include <shlwapi.h> | ||||||
|  |       #include <windows.h> | ||||||
|  |       #include <wincodec.h> | ||||||
|  |       " | ||||||
|  |     # test for functions from each lib and the GUID is created properly | ||||||
|  |     wic_main=" | ||||||
|  |       int main(void) { | ||||||
|  |         CLSID_WICImagingFactory; | ||||||
|  |         CoInitialize(NULL); | ||||||
|  |         SHCreateStreamOnFile(NULL, 0, NULL); | ||||||
|  |         return 0; | ||||||
|  |       } | ||||||
|  |       " | ||||||
|  |     AC_LANG_PUSH(C) | ||||||
|  |     AC_LINK_IFELSE( | ||||||
|  |       [AC_LANG_SOURCE([ | ||||||
|  |          $wic_headers | ||||||
|  |          $wic_main])], | ||||||
|  |       [wic_support=yes], | ||||||
|  |       [wic_support=no] | ||||||
|  |     ) | ||||||
|  |     AC_LANG_POP | ||||||
|  |  | ||||||
|  |     test "$wic_support" = "yes" || LIBS=$SAVED_LIBS | ||||||
|  |     AC_MSG_RESULT(${wic_support-no}) | ||||||
|  |   fi | ||||||
|  | fi | ||||||
|  | esac | ||||||
|  |  | ||||||
|  | dnl === If --enable-swap-16bit-csp is defined, add -DWEBP_SWAP_16BIT_CSP=1 | ||||||
|  |  | ||||||
|  | USE_SWAP_16BIT_CSP="" | ||||||
|  | AC_MSG_CHECKING(if --enable-swap-16bit-csp option is specified) | ||||||
|  | AC_ARG_ENABLE([swap-16bit-csp], | ||||||
|  |               AS_HELP_STRING([--enable-swap-16bit-csp], | ||||||
|  |                              [Enable byte swap for 16 bit colorspaces])) | ||||||
|  | if test "$enable_swap_16bit_csp" = "yes"; then | ||||||
|  |   USE_SWAP_16BIT_CSP="-DWEBP_SWAP_16BIT_CSP=1" | ||||||
|  | fi | ||||||
|  | AC_MSG_RESULT(${enable_swap_16bit_csp-no}) | ||||||
|  | AC_SUBST(USE_SWAP_16BIT_CSP) | ||||||
|  |  | ||||||
|  | dnl === If --disable-near-lossless is defined, add -DWEBP_NEAR_LOSSLESS=0 | ||||||
|  |  | ||||||
|  | AC_DEFINE(WEBP_NEAR_LOSSLESS, [1], [Enable near lossless encoding]) | ||||||
|  | AC_MSG_CHECKING(if --disable-near-lossless option is specified) | ||||||
|  | AC_ARG_ENABLE([near_lossless], | ||||||
|  |               AS_HELP_STRING([--disable-near-lossless], | ||||||
|  |                              [Disable near lossless encoding]), | ||||||
|  |               [], [enable_near_lossless=yes]) | ||||||
|  | if test "$enable_near_lossless" = "no"; then | ||||||
|  |   AC_DEFINE(WEBP_NEAR_LOSSLESS, [0], [Enable near lossless encoding]) | ||||||
|  |   AC_MSG_RESULT([yes]) | ||||||
|  | else | ||||||
|  |   AC_MSG_RESULT([no]) | ||||||
|  | fi | ||||||
|  |  | ||||||
|  | dnl ========================= | ||||||
|  |  | ||||||
|  | dnl Add an empty webp_libname_prefix variable for use in *.pc.in. | ||||||
|  | AC_SUBST([webp_libname_prefix]) | ||||||
|  | AC_CONFIG_MACRO_DIR([m4]) | ||||||
|  | AC_CONFIG_HEADERS([src/webp/config.h]) | ||||||
|  | AC_CONFIG_FILES([Makefile src/Makefile man/Makefile \ | ||||||
|  |                  examples/Makefile extras/Makefile imageio/Makefile \ | ||||||
|  |                  sharpyuv/Makefile sharpyuv/libsharpyuv.pc \ | ||||||
|  |                  src/dec/Makefile src/enc/Makefile src/dsp/Makefile \ | ||||||
|  |                  src/demux/Makefile src/mux/Makefile \ | ||||||
|  |                  src/utils/Makefile \ | ||||||
|  |                  src/libwebp.pc src/libwebpdecoder.pc \ | ||||||
|  |                  src/demux/libwebpdemux.pc src/mux/libwebpmux.pc]) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | AC_OUTPUT | ||||||
|  |  | ||||||
|  | AC_MSG_NOTICE([ | ||||||
|  | WebP Configuration Summary | ||||||
|  | -------------------------- | ||||||
|  |  | ||||||
|  | Shared libraries: ${enable_shared} | ||||||
|  | Static libraries: ${enable_static} | ||||||
|  | Threading support: ${enable_threading-no} | ||||||
|  | libwebp: yes | ||||||
|  | libwebpdecoder: ${enable_libwebpdecoder-no} | ||||||
|  | libwebpdemux: ${enable_libwebpdemux-no} | ||||||
|  | libwebpmux: ${enable_libwebpmux-no} | ||||||
|  | libwebpextras: ${enable_libwebpextras-no} | ||||||
|  |  | ||||||
|  | Tools: | ||||||
|  | cwebp : ${enable_libwebpdemux-no} | ||||||
|  |   Input format support | ||||||
|  |   ==================== | ||||||
|  |   JPEG : ${jpeg_support-no} | ||||||
|  |   PNG  : ${png_support-no} | ||||||
|  |   TIFF : ${tiff_support-no} | ||||||
|  |   WIC  : ${wic_support-no} | ||||||
|  | dwebp : ${enable_libwebpdemux-no} | ||||||
|  |   Output format support | ||||||
|  |   ===================== | ||||||
|  |   PNG  : ${png_support-no} | ||||||
|  |   WIC  : ${wic_support-no} | ||||||
|  | GIF support : ${gif_support-no} | ||||||
|  | anim_diff   : ${build_anim_diff-no} | ||||||
|  | gif2webp    : ${build_gif2webp-no} | ||||||
|  | img2webp    : ${build_img2webp-no} | ||||||
|  | webpmux     : ${enable_libwebpmux-no} | ||||||
|  | vwebp       : ${build_vwebp-no} | ||||||
|  | webpinfo    : ${build_webpinfo-no} | ||||||
|  | SDL support : ${sdl_support-no} | ||||||
|  | vwebp_sdl   : ${build_vwebp_sdl-no} | ||||||
|  | ]) | ||||||
							
								
								
									
										13
									
								
								external/libwebp/libwebp/doc/TODO
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								external/libwebp/libwebp/doc/TODO
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,13 @@ | |||||||
|  | <louquillio@google.com>, 20111004 | ||||||
|  |  | ||||||
|  | * Determine that normative RFC 2119 terms (MUST, SHOULD, MAY, etc.) are | ||||||
|  |   truly intended in all cases where capitalized. | ||||||
|  |  | ||||||
|  | * Several passages could be made clearer. | ||||||
|  |  | ||||||
|  |   * Overall edit for scope.  Portions are phrased as an introduction to | ||||||
|  |     the 0.1.3 RIFF container additions, rather than a holistic guide to | ||||||
|  |     WebP. | ||||||
|  |  | ||||||
|  |   * To wit, suggest s/[spec|specification]/guide/g .  "Spec" can imply a | ||||||
|  |     standards track; in any case it's too formal for a work in progress. | ||||||
							
								
								
									
										385
									
								
								external/libwebp/libwebp/doc/api.md
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										385
									
								
								external/libwebp/libwebp/doc/api.md
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,385 @@ | |||||||
|  | # WebP APIs | ||||||
|  |  | ||||||
|  | ## Encoding API | ||||||
|  |  | ||||||
|  | The main encoding functions are available in the header src/webp/encode.h | ||||||
|  |  | ||||||
|  | The ready-to-use ones are: | ||||||
|  |  | ||||||
|  | ```c | ||||||
|  | size_t WebPEncodeRGB(const uint8_t* rgb, int width, int height, int stride, | ||||||
|  |                      float quality_factor, uint8_t** output); | ||||||
|  | size_t WebPEncodeBGR(const uint8_t* bgr, int width, int height, int stride, | ||||||
|  |                      float quality_factor, uint8_t** output); | ||||||
|  | size_t WebPEncodeRGBA(const uint8_t* rgba, int width, int height, int stride, | ||||||
|  |                       float quality_factor, uint8_t** output); | ||||||
|  | size_t WebPEncodeBGRA(const uint8_t* bgra, int width, int height, int stride, | ||||||
|  |                       float quality_factor, uint8_t** output); | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | They will convert raw RGB samples to a WebP data. The only control supplied is | ||||||
|  | the quality factor. | ||||||
|  |  | ||||||
|  | There are some variants for using the lossless format: | ||||||
|  |  | ||||||
|  | ```c | ||||||
|  | size_t WebPEncodeLosslessRGB(const uint8_t* rgb, int width, int height, | ||||||
|  |                              int stride, uint8_t** output); | ||||||
|  | size_t WebPEncodeLosslessBGR(const uint8_t* bgr, int width, int height, | ||||||
|  |                              int stride, uint8_t** output); | ||||||
|  | size_t WebPEncodeLosslessRGBA(const uint8_t* rgba, int width, int height, | ||||||
|  |                               int stride, uint8_t** output); | ||||||
|  | size_t WebPEncodeLosslessBGRA(const uint8_t* bgra, int width, int height, | ||||||
|  |                               int stride, uint8_t** output); | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | Of course in this case, no quality factor is needed since the compression occurs | ||||||
|  | without loss of the input values, at the expense of larger output sizes. | ||||||
|  |  | ||||||
|  | ### Advanced encoding API | ||||||
|  |  | ||||||
|  | A more advanced API is based on the WebPConfig and WebPPicture structures. | ||||||
|  |  | ||||||
|  | WebPConfig contains the encoding settings and is not tied to a particular | ||||||
|  | picture. WebPPicture contains input data, on which some WebPConfig will be used | ||||||
|  | for compression. The encoding flow looks like: | ||||||
|  |  | ||||||
|  | ```c | ||||||
|  | #include <webp/encode.h> | ||||||
|  |  | ||||||
|  | // Setup a config, starting form a preset and tuning some additional | ||||||
|  | // parameters | ||||||
|  | WebPConfig config; | ||||||
|  | if (!WebPConfigPreset(&config, WEBP_PRESET_PHOTO, quality_factor)) { | ||||||
|  |   return 0;   // version error | ||||||
|  | } | ||||||
|  | // ... additional tuning | ||||||
|  | config.sns_strength = 90; | ||||||
|  | config.filter_sharpness = 6; | ||||||
|  | config_error = WebPValidateConfig(&config);  // not mandatory, but useful | ||||||
|  |  | ||||||
|  | // Setup the input data | ||||||
|  | WebPPicture pic; | ||||||
|  | if (!WebPPictureInit(&pic)) { | ||||||
|  |   return 0;  // version error | ||||||
|  | } | ||||||
|  | pic.width = width; | ||||||
|  | pic.height = height; | ||||||
|  | // allocated picture of dimension width x height | ||||||
|  | if (!WebPPictureAlloc(&pic)) { | ||||||
|  |   return 0;   // memory error | ||||||
|  | } | ||||||
|  | // at this point, 'pic' has been initialized as a container, | ||||||
|  | // and can receive the Y/U/V samples. | ||||||
|  | // Alternatively, one could use ready-made import functions like | ||||||
|  | // WebPPictureImportRGB(), which will take care of memory allocation. | ||||||
|  | // In any case, past this point, one will have to call | ||||||
|  | // WebPPictureFree(&pic) to reclaim memory. | ||||||
|  |  | ||||||
|  | // Set up a byte-output write method. WebPMemoryWriter, for instance. | ||||||
|  | WebPMemoryWriter wrt; | ||||||
|  | WebPMemoryWriterInit(&wrt);     // initialize 'wrt' | ||||||
|  |  | ||||||
|  | pic.writer = MyFileWriter; | ||||||
|  | pic.custom_ptr = my_opaque_structure_to_make_MyFileWriter_work; | ||||||
|  |  | ||||||
|  | // Compress! | ||||||
|  | int ok = WebPEncode(&config, &pic);   // ok = 0 => error occurred! | ||||||
|  | WebPPictureFree(&pic);  // must be called independently of the 'ok' result. | ||||||
|  |  | ||||||
|  | // output data should have been handled by the writer at that point. | ||||||
|  | // -> compressed data is the memory buffer described by wrt.mem / wrt.size | ||||||
|  |  | ||||||
|  | // deallocate the memory used by compressed data | ||||||
|  | WebPMemoryWriterClear(&wrt); | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | ## Decoding API | ||||||
|  |  | ||||||
|  | This is mainly just one function to call: | ||||||
|  |  | ||||||
|  | ```c | ||||||
|  | #include "webp/decode.h" | ||||||
|  | uint8_t* WebPDecodeRGB(const uint8_t* data, size_t data_size, | ||||||
|  |                        int* width, int* height); | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | Please have a look at the file src/webp/decode.h for the details. There are | ||||||
|  | variants for decoding in BGR/RGBA/ARGB/BGRA order, along with decoding to raw | ||||||
|  | Y'CbCr samples. One can also decode the image directly into a pre-allocated | ||||||
|  | buffer. | ||||||
|  |  | ||||||
|  | To detect a WebP file and gather the picture's dimensions, the function: | ||||||
|  |  | ||||||
|  | ```c | ||||||
|  | int WebPGetInfo(const uint8_t* data, size_t data_size, | ||||||
|  |                 int* width, int* height); | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | is supplied. No decoding is involved when using it. | ||||||
|  |  | ||||||
|  | ### Incremental decoding API | ||||||
|  |  | ||||||
|  | In the case when data is being progressively transmitted, pictures can still be | ||||||
|  | incrementally decoded using a slightly more complicated API. Decoder state is | ||||||
|  | stored into an instance of the WebPIDecoder object. This object can be created | ||||||
|  | with the purpose of decoding either RGB or Y'CbCr samples. For instance: | ||||||
|  |  | ||||||
|  | ```c | ||||||
|  | WebPDecBuffer buffer; | ||||||
|  | WebPInitDecBuffer(&buffer); | ||||||
|  | buffer.colorspace = MODE_BGR; | ||||||
|  | ... | ||||||
|  | WebPIDecoder* idec = WebPINewDecoder(&buffer); | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | As data is made progressively available, this incremental-decoder object can be | ||||||
|  | used to decode the picture further. There are two (mutually exclusive) ways to | ||||||
|  | pass freshly arrived data: | ||||||
|  |  | ||||||
|  | either by appending the fresh bytes: | ||||||
|  |  | ||||||
|  | ```c | ||||||
|  | WebPIAppend(idec, fresh_data, size_of_fresh_data); | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | or by just mentioning the new size of the transmitted data: | ||||||
|  |  | ||||||
|  | ```c | ||||||
|  | WebPIUpdate(idec, buffer, size_of_transmitted_buffer); | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | Note that 'buffer' can be modified between each call to WebPIUpdate, in | ||||||
|  | particular when the buffer is resized to accommodate larger data. | ||||||
|  |  | ||||||
|  | These functions will return the decoding status: either VP8_STATUS_SUSPENDED if | ||||||
|  | decoding is not finished yet or VP8_STATUS_OK when decoding is done. Any other | ||||||
|  | status is an error condition. | ||||||
|  |  | ||||||
|  | The 'idec' object must always be released (even upon an error condition) by | ||||||
|  | calling: WebPDelete(idec). | ||||||
|  |  | ||||||
|  | To retrieve partially decoded picture samples, one must use the corresponding | ||||||
|  | method: WebPIDecGetRGB or WebPIDecGetYUVA. It will return the last displayable | ||||||
|  | pixel row. | ||||||
|  |  | ||||||
|  | Lastly, note that decoding can also be performed into a pre-allocated pixel | ||||||
|  | buffer. This buffer must be passed when creating a WebPIDecoder, calling | ||||||
|  | WebPINewRGB() or WebPINewYUVA(). | ||||||
|  |  | ||||||
|  | Please have a look at the src/webp/decode.h header for further details. | ||||||
|  |  | ||||||
|  | ### Advanced Decoding API | ||||||
|  |  | ||||||
|  | WebP decoding supports an advanced API which provides on-the-fly cropping and | ||||||
|  | rescaling, something of great usefulness on memory-constrained environments like | ||||||
|  | mobile phones. Basically, the memory usage will scale with the output's size, | ||||||
|  | not the input's, when one only needs a quick preview or a zoomed in portion of | ||||||
|  | an otherwise too-large picture. Some CPU can be saved too, incidentally. | ||||||
|  |  | ||||||
|  | ```c | ||||||
|  | // A) Init a configuration object | ||||||
|  | WebPDecoderConfig config; | ||||||
|  | CHECK(WebPInitDecoderConfig(&config)); | ||||||
|  |  | ||||||
|  | // B) optional: retrieve the bitstream's features. | ||||||
|  | CHECK(WebPGetFeatures(data, data_size, &config.input) == VP8_STATUS_OK); | ||||||
|  |  | ||||||
|  | // C) Adjust 'config' options, if needed | ||||||
|  | config.options.no_fancy_upsampling = 1; | ||||||
|  | config.options.use_scaling = 1; | ||||||
|  | config.options.scaled_width = scaledWidth(); | ||||||
|  | config.options.scaled_height = scaledHeight(); | ||||||
|  | // etc. | ||||||
|  |  | ||||||
|  | // D) Specify 'config' output options for specifying output colorspace. | ||||||
|  | // Optionally the external image decode buffer can also be specified. | ||||||
|  | config.output.colorspace = MODE_BGRA; | ||||||
|  | // Optionally, the config.output can be pointed to an external buffer as | ||||||
|  | // well for decoding the image. This externally supplied memory buffer | ||||||
|  | // should be big enough to store the decoded picture. | ||||||
|  | config.output.u.RGBA.rgba = (uint8_t*) memory_buffer; | ||||||
|  | config.output.u.RGBA.stride = scanline_stride; | ||||||
|  | config.output.u.RGBA.size = total_size_of_the_memory_buffer; | ||||||
|  | config.output.is_external_memory = 1; | ||||||
|  |  | ||||||
|  | // E) Decode the WebP image. There are two variants w.r.t decoding image. | ||||||
|  | // The first one (E.1) decodes the full image and the second one (E.2) is | ||||||
|  | // used to incrementally decode the image using small input buffers. | ||||||
|  | // Any one of these steps can be used to decode the WebP image. | ||||||
|  |  | ||||||
|  | // E.1) Decode full image. | ||||||
|  | CHECK(WebPDecode(data, data_size, &config) == VP8_STATUS_OK); | ||||||
|  |  | ||||||
|  | // E.2) Decode image incrementally. | ||||||
|  | WebPIDecoder* const idec = WebPIDecode(NULL, NULL, &config); | ||||||
|  | CHECK(idec != NULL); | ||||||
|  | while (bytes_remaining > 0) { | ||||||
|  |   VP8StatusCode status = WebPIAppend(idec, input, bytes_read); | ||||||
|  |   if (status == VP8_STATUS_OK || status == VP8_STATUS_SUSPENDED) { | ||||||
|  |     bytes_remaining -= bytes_read; | ||||||
|  |   } else { | ||||||
|  |     break; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | WebPIDelete(idec); | ||||||
|  |  | ||||||
|  | // F) Decoded image is now in config.output (and config.output.u.RGBA). | ||||||
|  | // It can be saved, displayed or otherwise processed. | ||||||
|  |  | ||||||
|  | // G) Reclaim memory allocated in config's object. It's safe to call | ||||||
|  | // this function even if the memory is external and wasn't allocated | ||||||
|  | // by WebPDecode(). | ||||||
|  | WebPFreeDecBuffer(&config.output); | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | ## WebP Mux | ||||||
|  |  | ||||||
|  | WebPMux is a set of two libraries 'Mux' and 'Demux' for creation, extraction and | ||||||
|  | manipulation of an extended format WebP file, which can have features like color | ||||||
|  | profile, metadata and animation. Reference command-line tools `webpmux` and | ||||||
|  | `vwebp` as well as the WebP container specification | ||||||
|  | 'doc/webp-container-spec.txt' are also provided in this package, see the | ||||||
|  | [tools documentation](tools.md). | ||||||
|  |  | ||||||
|  | ### Mux API | ||||||
|  |  | ||||||
|  | The Mux API contains methods for adding data to and reading data from WebP | ||||||
|  | files. This API currently supports XMP/EXIF metadata, ICC profile and animation. | ||||||
|  | Other features may be added in subsequent releases. | ||||||
|  |  | ||||||
|  | Example#1 (pseudo code): Creating a WebPMux object with image data, color | ||||||
|  | profile and XMP metadata. | ||||||
|  |  | ||||||
|  | ```c | ||||||
|  | int copy_data = 0; | ||||||
|  | WebPMux* mux = WebPMuxNew(); | ||||||
|  | // ... (Prepare image data). | ||||||
|  | WebPMuxSetImage(mux, &image, copy_data); | ||||||
|  | // ... (Prepare ICC profile data). | ||||||
|  | WebPMuxSetChunk(mux, "ICCP", &icc_profile, copy_data); | ||||||
|  | // ... (Prepare XMP metadata). | ||||||
|  | WebPMuxSetChunk(mux, "XMP ", &xmp, copy_data); | ||||||
|  | // Get data from mux in WebP RIFF format. | ||||||
|  | WebPMuxAssemble(mux, &output_data); | ||||||
|  | WebPMuxDelete(mux); | ||||||
|  | // ... (Consume output_data; e.g. write output_data.bytes to file). | ||||||
|  | WebPDataClear(&output_data); | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | Example#2 (pseudo code): Get image and color profile data from a WebP file. | ||||||
|  |  | ||||||
|  | ```c | ||||||
|  | int copy_data = 0; | ||||||
|  | // ... (Read data from file). | ||||||
|  | WebPMux* mux = WebPMuxCreate(&data, copy_data); | ||||||
|  | WebPMuxGetFrame(mux, 1, &image); | ||||||
|  | // ... (Consume image; e.g. call WebPDecode() to decode the data). | ||||||
|  | WebPMuxGetChunk(mux, "ICCP", &icc_profile); | ||||||
|  | // ... (Consume icc_profile). | ||||||
|  | WebPMuxDelete(mux); | ||||||
|  | free(data); | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | For a detailed Mux API reference, please refer to the header file | ||||||
|  | (src/webp/mux.h). | ||||||
|  |  | ||||||
|  | ### Demux API | ||||||
|  |  | ||||||
|  | The Demux API enables extraction of images and extended format data from WebP | ||||||
|  | files. This API currently supports reading of XMP/EXIF metadata, ICC profile and | ||||||
|  | animated images. Other features may be added in subsequent releases. | ||||||
|  |  | ||||||
|  | Code example: Demuxing WebP data to extract all the frames, ICC profile and | ||||||
|  | EXIF/XMP metadata. | ||||||
|  |  | ||||||
|  | ```c | ||||||
|  | WebPDemuxer* demux = WebPDemux(&webp_data); | ||||||
|  | uint32_t width = WebPDemuxGetI(demux, WEBP_FF_CANVAS_WIDTH); | ||||||
|  | uint32_t height = WebPDemuxGetI(demux, WEBP_FF_CANVAS_HEIGHT); | ||||||
|  | // ... (Get information about the features present in the WebP file). | ||||||
|  | uint32_t flags = WebPDemuxGetI(demux, WEBP_FF_FORMAT_FLAGS); | ||||||
|  |  | ||||||
|  | // ... (Iterate over all frames). | ||||||
|  | WebPIterator iter; | ||||||
|  | if (WebPDemuxGetFrame(demux, 1, &iter)) { | ||||||
|  |   do { | ||||||
|  |     // ... (Consume 'iter'; e.g. Decode 'iter.fragment' with WebPDecode(), | ||||||
|  |     // ... and get other frame properties like width, height, offsets etc. | ||||||
|  |     // ... see 'struct WebPIterator' below for more info). | ||||||
|  |   } while (WebPDemuxNextFrame(&iter)); | ||||||
|  |   WebPDemuxReleaseIterator(&iter); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // ... (Extract metadata). | ||||||
|  | WebPChunkIterator chunk_iter; | ||||||
|  | if (flags & ICCP_FLAG) WebPDemuxGetChunk(demux, "ICCP", 1, &chunk_iter); | ||||||
|  | // ... (Consume the ICC profile in 'chunk_iter.chunk'). | ||||||
|  | WebPDemuxReleaseChunkIterator(&chunk_iter); | ||||||
|  | if (flags & EXIF_FLAG) WebPDemuxGetChunk(demux, "EXIF", 1, &chunk_iter); | ||||||
|  | // ... (Consume the EXIF metadata in 'chunk_iter.chunk'). | ||||||
|  | WebPDemuxReleaseChunkIterator(&chunk_iter); | ||||||
|  | if (flags & XMP_FLAG) WebPDemuxGetChunk(demux, "XMP ", 1, &chunk_iter); | ||||||
|  | // ... (Consume the XMP metadata in 'chunk_iter.chunk'). | ||||||
|  | WebPDemuxReleaseChunkIterator(&chunk_iter); | ||||||
|  | WebPDemuxDelete(demux); | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | For a detailed Demux API reference, please refer to the header file | ||||||
|  | (src/webp/demux.h). | ||||||
|  |  | ||||||
|  | ## AnimEncoder API | ||||||
|  |  | ||||||
|  | The AnimEncoder API can be used to create animated WebP images. | ||||||
|  |  | ||||||
|  | Code example: | ||||||
|  |  | ||||||
|  | ```c | ||||||
|  | WebPAnimEncoderOptions enc_options; | ||||||
|  | WebPAnimEncoderOptionsInit(&enc_options); | ||||||
|  | // ... (Tune 'enc_options' as needed). | ||||||
|  | WebPAnimEncoder* enc = WebPAnimEncoderNew(width, height, &enc_options); | ||||||
|  | while(<there are more frames>) { | ||||||
|  |   WebPConfig config; | ||||||
|  |   WebPConfigInit(&config); | ||||||
|  |   // ... (Tune 'config' as needed). | ||||||
|  |   WebPAnimEncoderAdd(enc, frame, duration, &config); | ||||||
|  | } | ||||||
|  | WebPAnimEncoderAssemble(enc, webp_data); | ||||||
|  | WebPAnimEncoderDelete(enc); | ||||||
|  | // ... (Write the 'webp_data' to a file, or re-mux it further). | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | For a detailed AnimEncoder API reference, please refer to the header file | ||||||
|  | (src/webp/mux.h). | ||||||
|  |  | ||||||
|  | ## AnimDecoder API | ||||||
|  |  | ||||||
|  | This AnimDecoder API allows decoding (possibly) animated WebP images. | ||||||
|  |  | ||||||
|  | Code Example: | ||||||
|  |  | ||||||
|  | ```c | ||||||
|  | WebPAnimDecoderOptions dec_options; | ||||||
|  | WebPAnimDecoderOptionsInit(&dec_options); | ||||||
|  | // Tune 'dec_options' as needed. | ||||||
|  | WebPAnimDecoder* dec = WebPAnimDecoderNew(webp_data, &dec_options); | ||||||
|  | WebPAnimInfo anim_info; | ||||||
|  | WebPAnimDecoderGetInfo(dec, &anim_info); | ||||||
|  | for (uint32_t i = 0; i < anim_info.loop_count; ++i) { | ||||||
|  |   while (WebPAnimDecoderHasMoreFrames(dec)) { | ||||||
|  |     uint8_t* buf; | ||||||
|  |     int timestamp; | ||||||
|  |     WebPAnimDecoderGetNext(dec, &buf, ×tamp); | ||||||
|  |     // ... (Render 'buf' based on 'timestamp'). | ||||||
|  |     // ... (Do NOT free 'buf', as it is owned by 'dec'). | ||||||
|  |   } | ||||||
|  |   WebPAnimDecoderReset(dec); | ||||||
|  | } | ||||||
|  | const WebPDemuxer* demuxer = WebPAnimDecoderGetDemuxer(dec); | ||||||
|  | // ... (Do something using 'demuxer'; e.g. get EXIF/XMP/ICC data). | ||||||
|  | WebPAnimDecoderDelete(dec); | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | For a detailed AnimDecoder API reference, please refer to the header file | ||||||
|  | (src/webp/demux.h). | ||||||
							
								
								
									
										213
									
								
								external/libwebp/libwebp/doc/building.md
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										213
									
								
								external/libwebp/libwebp/doc/building.md
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,213 @@ | |||||||
|  | # Building | ||||||
|  |  | ||||||
|  | ## Windows build | ||||||
|  |  | ||||||
|  | By running: | ||||||
|  |  | ||||||
|  | ```batch | ||||||
|  | nmake /f Makefile.vc CFG=release-static RTLIBCFG=static OBJDIR=output | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | the directory `output\release-static\(x64|x86)\bin` will contain the tools | ||||||
|  | cwebp.exe and dwebp.exe. The directory `output\release-static\(x64|x86)\lib` | ||||||
|  | will contain the libwebp static library. The target architecture (x86/x64) is | ||||||
|  | detected by Makefile.vc from the Visual Studio compiler (cl.exe) available in | ||||||
|  | the system path. | ||||||
|  |  | ||||||
|  | ## Unix build using makefile.unix | ||||||
|  |  | ||||||
|  | On platforms with GNU tools installed (gcc and make), running | ||||||
|  |  | ||||||
|  | ```shell | ||||||
|  | make -f makefile.unix | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | will build the binaries examples/cwebp and examples/dwebp, along with the static | ||||||
|  | library src/libwebp.a. No system-wide installation is supplied, as this is a | ||||||
|  | simple alternative to the full installation system based on the autoconf tools | ||||||
|  | (see below). Please refer to makefile.unix for additional details and | ||||||
|  | customizations. | ||||||
|  |  | ||||||
|  | ## Using autoconf tools | ||||||
|  |  | ||||||
|  | Prerequisites: a compiler (e.g., gcc), make, autoconf, automake, libtool. | ||||||
|  |  | ||||||
|  | On a Debian-like system the following should install everything you need for a | ||||||
|  | minimal build: | ||||||
|  |  | ||||||
|  | ```shell | ||||||
|  | $ sudo apt-get install gcc make autoconf automake libtool | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | When building from git sources, you will need to run autogen.sh to generate the | ||||||
|  | configure script. | ||||||
|  |  | ||||||
|  | ```shell | ||||||
|  | ./configure | ||||||
|  | make | ||||||
|  | make install | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | should be all you need to have the following files | ||||||
|  |  | ||||||
|  | ``` | ||||||
|  | /usr/local/include/webp/decode.h | ||||||
|  | /usr/local/include/webp/encode.h | ||||||
|  | /usr/local/include/webp/types.h | ||||||
|  | /usr/local/lib/libwebp.* | ||||||
|  | /usr/local/bin/cwebp | ||||||
|  | /usr/local/bin/dwebp | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | installed. | ||||||
|  |  | ||||||
|  | Note: A decode-only library, libwebpdecoder, is available using the | ||||||
|  | `--enable-libwebpdecoder` flag. The encode library is built separately and can | ||||||
|  | be installed independently using a minor modification in the corresponding | ||||||
|  | Makefile.am configure files (see comments there). See `./configure --help` for | ||||||
|  | more options. | ||||||
|  |  | ||||||
|  | ## Building for MIPS Linux | ||||||
|  |  | ||||||
|  | MIPS Linux toolchain stable available releases can be found at: | ||||||
|  | https://community.imgtec.com/developers/mips/tools/codescape-mips-sdk/available-releases/ | ||||||
|  |  | ||||||
|  | ```shell | ||||||
|  | # Add toolchain to PATH | ||||||
|  | export PATH=$PATH:/path/to/toolchain/bin | ||||||
|  |  | ||||||
|  | # 32-bit build for mips32r5 (p5600) | ||||||
|  | HOST=mips-mti-linux-gnu | ||||||
|  | MIPS_CFLAGS="-O3 -mips32r5 -mabi=32 -mtune=p5600 -mmsa -mfp64 \ | ||||||
|  |   -msched-weight -mload-store-pairs -fPIE" | ||||||
|  | MIPS_LDFLAGS="-mips32r5 -mabi=32 -mmsa -mfp64 -pie" | ||||||
|  |  | ||||||
|  | # 64-bit build for mips64r6 (i6400) | ||||||
|  | HOST=mips-img-linux-gnu | ||||||
|  | MIPS_CFLAGS="-O3 -mips64r6 -mabi=64 -mtune=i6400 -mmsa -mfp64 \ | ||||||
|  |   -msched-weight -mload-store-pairs -fPIE" | ||||||
|  | MIPS_LDFLAGS="-mips64r6 -mabi=64 -mmsa -mfp64 -pie" | ||||||
|  |  | ||||||
|  | ./configure --host=${HOST} --build=`config.guess` \ | ||||||
|  |   CC="${HOST}-gcc -EL" \ | ||||||
|  |   CFLAGS="$MIPS_CFLAGS" \ | ||||||
|  |   LDFLAGS="$MIPS_LDFLAGS" | ||||||
|  | make | ||||||
|  | make install | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | ## CMake | ||||||
|  |  | ||||||
|  | With CMake, you can compile libwebp, cwebp, dwebp, gif2webp, img2webp, webpinfo | ||||||
|  | and the JS bindings. | ||||||
|  |  | ||||||
|  | Prerequisites: a compiler (e.g., gcc with autotools) and CMake. | ||||||
|  |  | ||||||
|  | On a Debian-like system the following should install everything you need for a | ||||||
|  | minimal build: | ||||||
|  |  | ||||||
|  | ```shell | ||||||
|  | $ sudo apt-get install build-essential cmake | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | When building from git sources, you will need to run cmake to generate the | ||||||
|  | makefiles. | ||||||
|  |  | ||||||
|  | ```shell | ||||||
|  | mkdir build && cd build && cmake ../ | ||||||
|  | make | ||||||
|  | make install | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | If you also want any of the executables, you will need to enable them through | ||||||
|  | CMake, e.g.: | ||||||
|  |  | ||||||
|  | ```shell | ||||||
|  | cmake -DWEBP_BUILD_CWEBP=ON -DWEBP_BUILD_DWEBP=ON ../ | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | or through your favorite interface (like ccmake or cmake-qt-gui). | ||||||
|  |  | ||||||
|  | Use option `-DWEBP_UNICODE=ON` for Unicode support on Windows (with chcp 65001). | ||||||
|  |  | ||||||
|  | Finally, once installed, you can also use WebP in your CMake project by doing: | ||||||
|  |  | ||||||
|  | ```cmake | ||||||
|  | find_package(WebP) | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | which will define the CMake variables WebP_INCLUDE_DIRS and WebP_LIBRARIES. | ||||||
|  |  | ||||||
|  | ## Gradle | ||||||
|  |  | ||||||
|  | The support for Gradle is minimal: it only helps you compile libwebp, cwebp and | ||||||
|  | dwebp and webpmux_example. | ||||||
|  |  | ||||||
|  | Prerequisites: a compiler (e.g., gcc with autotools) and gradle. | ||||||
|  |  | ||||||
|  | On a Debian-like system the following should install everything you need for a | ||||||
|  | minimal build: | ||||||
|  |  | ||||||
|  | ```shell | ||||||
|  | $ sudo apt-get install build-essential gradle | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | When building from git sources, you will need to run the Gradle wrapper with the | ||||||
|  | appropriate target, e.g. : | ||||||
|  |  | ||||||
|  | ```shell | ||||||
|  | ./gradlew buildAllExecutables | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | ## SWIG bindings | ||||||
|  |  | ||||||
|  | To generate language bindings from swig/libwebp.swig at least swig-1.3 | ||||||
|  | (http://www.swig.org) is required. | ||||||
|  |  | ||||||
|  | Currently the following functions are mapped: | ||||||
|  |  | ||||||
|  | Decode: | ||||||
|  |  | ||||||
|  | ``` | ||||||
|  | WebPGetDecoderVersion | ||||||
|  | WebPGetInfo | ||||||
|  | WebPDecodeRGBA | ||||||
|  | WebPDecodeARGB | ||||||
|  | WebPDecodeBGRA | ||||||
|  | WebPDecodeBGR | ||||||
|  | WebPDecodeRGB | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | Encode: | ||||||
|  |  | ||||||
|  | ``` | ||||||
|  | WebPGetEncoderVersion | ||||||
|  | WebPEncodeRGBA | ||||||
|  | WebPEncodeBGRA | ||||||
|  | WebPEncodeRGB | ||||||
|  | WebPEncodeBGR | ||||||
|  | WebPEncodeLosslessRGBA | ||||||
|  | WebPEncodeLosslessBGRA | ||||||
|  | WebPEncodeLosslessRGB | ||||||
|  | WebPEncodeLosslessBGR | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | See also the [swig documentation](../swig/README.md) for more detailed build | ||||||
|  | instructions and usage examples. | ||||||
|  |  | ||||||
|  | ### Java bindings | ||||||
|  |  | ||||||
|  | To build the swig-generated JNI wrapper code at least JDK-1.5 (or equivalent) is | ||||||
|  | necessary for enum support. The output is intended to be a shared object / DLL | ||||||
|  | that can be loaded via `System.loadLibrary("webp_jni")`. | ||||||
|  |  | ||||||
|  | ### Python bindings | ||||||
|  |  | ||||||
|  | To build the swig-generated Python extension code at least Python 2.6 is | ||||||
|  | required. Python < 2.6 may build with some minor changes to libwebp.swig or the | ||||||
|  | generated code, but is untested. | ||||||
|  |  | ||||||
|  | ## Javascript decoder | ||||||
|  |  | ||||||
|  | Libwebp can be compiled into a JavaScript decoder using Emscripten and CMake. | ||||||
|  | See the [corresponding documentation](../README.md) | ||||||
							
								
								
									
										26
									
								
								external/libwebp/libwebp/doc/specs_generation.md
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								external/libwebp/libwebp/doc/specs_generation.md
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,26 @@ | |||||||
|  | # Generate libwebp Container Spec Docs from Text Source | ||||||
|  |  | ||||||
|  | HTML generation requires [kramdown](https://kramdown.gettalong.org/), easily | ||||||
|  | installed as a [rubygem](https://rubygems.org/). Rubygems installation should | ||||||
|  | satisfy dependencies automatically. | ||||||
|  |  | ||||||
|  | HTML generation can then be done from the project root: | ||||||
|  |  | ||||||
|  | ```shell | ||||||
|  | $ kramdown doc/webp-container-spec.txt --template doc/template.html > \ | ||||||
|  |   doc/output/webp-container-spec.html | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | kramdown can optionally syntax highlight code blocks, using | ||||||
|  | [CodeRay](https://github.com/rubychan/coderay), a dependency of kramdown that | ||||||
|  | rubygems will install automatically. The following will apply inline CSS | ||||||
|  | styling; an external stylesheet is not needed. | ||||||
|  |  | ||||||
|  | ```shell | ||||||
|  | $ kramdown doc/webp-lossless-bitstream-spec.txt --template \ | ||||||
|  |   doc/template.html --coderay-css style --coderay-line-numbers ' ' \ | ||||||
|  |   --coderay-default-lang c > \ | ||||||
|  |   doc/output/webp-lossless-bitstream-spec.html | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | Optimally, use kramdown 0.13.7 or newer if syntax highlighting desired. | ||||||
							
								
								
									
										94
									
								
								external/libwebp/libwebp/doc/template.html
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										94
									
								
								external/libwebp/libwebp/doc/template.html
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,94 @@ | |||||||
|  | <!DOCTYPE html> | ||||||
|  | <html lang="en"> | ||||||
|  | <head> | ||||||
|  |   <meta charset="utf-8"> | ||||||
|  |   <title>WebP Container Specification</title> | ||||||
|  |   <meta name="generator" content="kramdown <%= ::Kramdown::VERSION %>" /> | ||||||
|  |   <style type="text/css"> | ||||||
|  |   body { | ||||||
|  |     color: #000; | ||||||
|  |     background-color: #fff; | ||||||
|  |     margin: 10%; | ||||||
|  |     font-family: "Liberation Sans", "DejaVu Sans", "Bitstream Vera Sans", Arial, sans-serif; | ||||||
|  |     line-height: 1.4; | ||||||
|  |   } | ||||||
|  |   h2 { | ||||||
|  |     border-bottom: 1px solid #ccc; | ||||||
|  |     padding-bottom: 0; | ||||||
|  |   } | ||||||
|  |   table { | ||||||
|  |     border-collapse: collapse; | ||||||
|  |   } | ||||||
|  |   th, td { | ||||||
|  |     border: 1px solid #999; | ||||||
|  |     padding: .5em .7em;; | ||||||
|  |   } | ||||||
|  |   th { | ||||||
|  |     color: #fff; | ||||||
|  |     background-color: #000; | ||||||
|  |   } | ||||||
|  |   td { | ||||||
|  |   } | ||||||
|  |   hr { | ||||||
|  |   } | ||||||
|  |   code { | ||||||
|  |     color: #000; | ||||||
|  |     background-color: #f7f7f7; | ||||||
|  |     padding: 0 3px; | ||||||
|  |     font-family: "Liberation Mono", "DejaVu Sans Mono", "Bitstream Vera Sans Mono", Consolata, monospace; | ||||||
|  |   } | ||||||
|  |   pre { | ||||||
|  |     background-color: #f7f7f7; | ||||||
|  |     padding: 1em; | ||||||
|  |     border: 1px solid #ccc; | ||||||
|  |     width: 42em; | ||||||
|  |     overflow: auto; | ||||||
|  |     font-family: "Liberation Mono", "DejaVu Sans Mono", "Bitstream Vera Sans Mono", Consolata, monospace; | ||||||
|  |   } | ||||||
|  |   pre code { | ||||||
|  |     background-color: #f7f7f7; | ||||||
|  |     padding: 0; /* Only want padding on inline code, not blocks */ | ||||||
|  |   } | ||||||
|  |   pre.terminal { | ||||||
|  |     color: #fff; | ||||||
|  |     background-color: #000; | ||||||
|  |     border: 1px solid #ccc; | ||||||
|  |     max-height: 30em; | ||||||
|  |   } | ||||||
|  |   pre.terminal code { | ||||||
|  |     color: #fff; | ||||||
|  |     background-color: #000; | ||||||
|  |     font-size: smaller; | ||||||
|  |   } | ||||||
|  |   #markdown-toc ul { | ||||||
|  |     list-style-type: disc; | ||||||
|  |   } | ||||||
|  |   ul#markdown-toc { | ||||||
|  |     margin-top: -1em; | ||||||
|  |     visibility: hidden; | ||||||
|  |     -webkit-padding-start: 0; | ||||||
|  |   } | ||||||
|  |   ul#markdown-toc ul { | ||||||
|  |     visibility: visible; | ||||||
|  |   } | ||||||
|  |   ul#markdown-toc ul ul{ | ||||||
|  |     visibility: visible; | ||||||
|  |   } | ||||||
|  |   ul#markdown-toc + hr { | ||||||
|  |     margin-bottom: 4em; | ||||||
|  |   } | ||||||
|  |   ol ol { /* Format nested ordered lists */ | ||||||
|  |     list-style-type: lower-alpha; | ||||||
|  |   } | ||||||
|  |   dt { | ||||||
|  |     font-style: italic; | ||||||
|  |     font-weight: bold; | ||||||
|  |   } | ||||||
|  |   .caption { | ||||||
|  |   } | ||||||
|  |   </style> | ||||||
|  | </head> | ||||||
|  | <body> | ||||||
|  | <%= @body %> | ||||||
|  | </body> | ||||||
|  | </html> | ||||||
							
								
								
									
										516
									
								
								external/libwebp/libwebp/doc/tools.md
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										516
									
								
								external/libwebp/libwebp/doc/tools.md
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,516 @@ | |||||||
|  | # WebP tools | ||||||
|  |  | ||||||
|  | ## Encoding tool | ||||||
|  |  | ||||||
|  | The examples/ directory contains tools for encoding (cwebp) and decoding (dwebp) | ||||||
|  | images. | ||||||
|  |  | ||||||
|  | The easiest use should look like: | ||||||
|  |  | ||||||
|  | ```shell | ||||||
|  | cwebp input.png -q 80 -o output.webp | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | which will convert the input file to a WebP file using a quality factor of 80 on | ||||||
|  | a 0->100 scale (0 being the lowest quality, 100 being the best. Default value is | ||||||
|  | 75). | ||||||
|  |  | ||||||
|  | You might want to try the `-lossless` flag too, which will compress the source | ||||||
|  | (in RGBA format) without any loss. The `-q` quality parameter will in this case | ||||||
|  | control the amount of processing time spent trying to make the output file as | ||||||
|  | small as possible. | ||||||
|  |  | ||||||
|  | A longer list of options is available using the `-longhelp` command line flag: | ||||||
|  |  | ||||||
|  | ```shell | ||||||
|  | > cwebp -longhelp | ||||||
|  | Usage: | ||||||
|  |  cwebp [-preset <...>] [options] in_file [-o out_file] | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | If input size (-s) for an image is not specified, it is assumed to be a PNG, | ||||||
|  | JPEG, TIFF or WebP file. Note: Animated PNG and WebP files are not supported. | ||||||
|  |  | ||||||
|  | Options: | ||||||
|  |  | ||||||
|  | ``` | ||||||
|  | -h / -help ............. short help | ||||||
|  | -H / -longhelp ......... long help | ||||||
|  | -q <float> ............. quality factor (0:small..100:big), default=75 | ||||||
|  | -alpha_q <int> ......... transparency-compression quality (0..100), | ||||||
|  |                          default=100 | ||||||
|  | -preset <string> ....... preset setting, one of: | ||||||
|  |                           default, photo, picture, | ||||||
|  |                           drawing, icon, text | ||||||
|  |    -preset must come first, as it overwrites other parameters | ||||||
|  | -z <int> ............... activates lossless preset with given | ||||||
|  |                          level in [0:fast, ..., 9:slowest] | ||||||
|  |  | ||||||
|  | -m <int> ............... compression method (0=fast, 6=slowest), default=4 | ||||||
|  | -segments <int> ........ number of segments to use (1..4), default=4 | ||||||
|  | -size <int> ............ target size (in bytes) | ||||||
|  | -psnr <float> .......... target PSNR (in dB. typically: 42) | ||||||
|  |  | ||||||
|  | -s <int> <int> ......... input size (width x height) for YUV | ||||||
|  | -sns <int> ............. spatial noise shaping (0:off, 100:max), default=50 | ||||||
|  | -f <int> ............... filter strength (0=off..100), default=60 | ||||||
|  | -sharpness <int> ....... filter sharpness (0:most .. 7:least sharp), default=0 | ||||||
|  | -strong ................ use strong filter instead of simple (default) | ||||||
|  | -nostrong .............. use simple filter instead of strong | ||||||
|  | -sharp_yuv ............. use sharper (and slower) RGB->YUV conversion | ||||||
|  | -partition_limit <int> . limit quality to fit the 512k limit on | ||||||
|  |                          the first partition (0=no degradation ... 100=full) | ||||||
|  | -pass <int> ............ analysis pass number (1..10) | ||||||
|  | -qrange <min> <max> .... specifies the permissible quality range | ||||||
|  |                          (default: 0 100) | ||||||
|  | -crop <x> <y> <w> <h> .. crop picture with the given rectangle | ||||||
|  | -resize <w> <h> ........ resize picture (*after* any cropping) | ||||||
|  | -mt .................... use multi-threading if available | ||||||
|  | -low_memory ............ reduce memory usage (slower encoding) | ||||||
|  | -map <int> ............. print map of extra info | ||||||
|  | -print_psnr ............ prints averaged PSNR distortion | ||||||
|  | -print_ssim ............ prints averaged SSIM distortion | ||||||
|  | -print_lsim ............ prints local-similarity distortion | ||||||
|  | -d <file.pgm> .......... dump the compressed output (PGM file) | ||||||
|  | -alpha_method <int> .... transparency-compression method (0..1), default=1 | ||||||
|  | -alpha_filter <string> . predictive filtering for alpha plane, | ||||||
|  |                          one of: none, fast (default) or best | ||||||
|  | -exact ................. preserve RGB values in transparent area, default=off | ||||||
|  | -blend_alpha <hex> ..... blend colors against background color | ||||||
|  |                          expressed as RGB values written in | ||||||
|  |                          hexadecimal, e.g. 0xc0e0d0 for red=0xc0 | ||||||
|  |                          green=0xe0 and blue=0xd0 | ||||||
|  | -noalpha ............... discard any transparency information | ||||||
|  | -lossless .............. encode image losslessly, default=off | ||||||
|  | -near_lossless <int> ... use near-lossless image preprocessing | ||||||
|  |                          (0..100=off), default=100 | ||||||
|  | -hint <string> ......... specify image characteristics hint, | ||||||
|  |                          one of: photo, picture or graph | ||||||
|  |  | ||||||
|  | -metadata <string> ..... comma separated list of metadata to | ||||||
|  |                          copy from the input to the output if present. | ||||||
|  |                          Valid values: all, none (default), exif, icc, xmp | ||||||
|  |  | ||||||
|  | -short ................. condense printed message | ||||||
|  | -quiet ................. don't print anything | ||||||
|  | -version ............... print version number and exit | ||||||
|  | -noasm ................. disable all assembly optimizations | ||||||
|  | -v ..................... verbose, e.g. print encoding/decoding times | ||||||
|  | -progress .............. report encoding progress | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | Experimental Options: | ||||||
|  |  | ||||||
|  | ``` | ||||||
|  | -jpeg_like ............. roughly match expected JPEG size | ||||||
|  | -af .................... auto-adjust filter strength | ||||||
|  | -pre <int> ............. pre-processing filter | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | The main options you might want to try in order to further tune the visual | ||||||
|  | quality are: | ||||||
|  |  | ||||||
|  | -preset -sns -f -m | ||||||
|  |  | ||||||
|  | Namely: | ||||||
|  |  | ||||||
|  | *   `preset` will set up a default encoding configuration targeting a particular | ||||||
|  |     type of input. It should appear first in the list of options, so that | ||||||
|  |     subsequent options can take effect on top of this preset. Default value is | ||||||
|  |     'default'. | ||||||
|  | *   `sns` will progressively turn on (when going from 0 to 100) some additional | ||||||
|  |     visual optimizations (like: segmentation map re-enforcement). This option | ||||||
|  |     will balance the bit allocation differently. It tries to take bits from the | ||||||
|  |     "easy" parts of the picture and use them in the "difficult" ones instead. | ||||||
|  |     Usually, raising the sns value (at fixed -q value) leads to larger files, | ||||||
|  |     but with better quality. Typical value is around '75'. | ||||||
|  | *   `f` option directly links to the filtering strength used by the codec's | ||||||
|  |     in-loop processing. The higher the value, the smoother the highly-compressed | ||||||
|  |     area will look. This is particularly useful when aiming at very small files. | ||||||
|  |     Typical values are around 20-30. Note that using the option | ||||||
|  |     -strong/-nostrong will change the type of filtering. Use "-f 0" to turn | ||||||
|  |     filtering off. | ||||||
|  | *   `m` controls the trade-off between encoding speed and quality. Default is 4. | ||||||
|  |     You can try -m 5 or -m 6 to explore more (time-consuming) encoding | ||||||
|  |     possibilities. A lower value will result in faster encoding at the expense | ||||||
|  |     of quality. | ||||||
|  |  | ||||||
|  | ## Decoding tool | ||||||
|  |  | ||||||
|  | There is a decoding sample in examples/dwebp.c which will take a .webp file and | ||||||
|  | decode it to a PNG image file (amongst other formats). This is simply to | ||||||
|  | demonstrate the use of the API. You can verify the file test.webp decodes to | ||||||
|  | exactly the same as test_ref.ppm by using: | ||||||
|  |  | ||||||
|  | ```shell | ||||||
|  | cd examples | ||||||
|  | ./dwebp test.webp -ppm -o test.ppm | ||||||
|  | diff test.ppm test_ref.ppm | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | The full list of options is available using -h: | ||||||
|  |  | ||||||
|  | ```shell | ||||||
|  | > dwebp -h | ||||||
|  | Usage: dwebp in_file [options] [-o out_file] | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | Decodes the WebP image file to PNG format [Default]. Note: Animated WebP files | ||||||
|  | are not supported. | ||||||
|  |  | ||||||
|  | Use following options to convert into alternate image formats: | ||||||
|  |  | ||||||
|  | ``` | ||||||
|  | -pam ......... save the raw RGBA samples as a color PAM | ||||||
|  | -ppm ......... save the raw RGB samples as a color PPM | ||||||
|  | -bmp ......... save as uncompressed BMP format | ||||||
|  | -tiff ........ save as uncompressed TIFF format | ||||||
|  | -pgm ......... save the raw YUV samples as a grayscale PGM | ||||||
|  |                file with IMC4 layout | ||||||
|  | -yuv ......... save the raw YUV samples in flat layout | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | Other options are: | ||||||
|  |  | ||||||
|  | ``` | ||||||
|  | -version ..... print version number and exit | ||||||
|  | -nofancy ..... don't use the fancy YUV420 upscaler | ||||||
|  | -nofilter .... disable in-loop filtering | ||||||
|  | -nodither .... disable dithering | ||||||
|  | -dither <d> .. dithering strength (in 0..100) | ||||||
|  | -alpha_dither  use alpha-plane dithering if needed | ||||||
|  | -mt .......... use multi-threading | ||||||
|  | -crop <x> <y> <w> <h> ... crop output with the given rectangle | ||||||
|  | -resize <w> <h> ......... resize output (*after* any cropping) | ||||||
|  | -flip ........ flip the output vertically | ||||||
|  | -alpha ....... only save the alpha plane | ||||||
|  | -incremental . use incremental decoding (useful for tests) | ||||||
|  | -h ........... this help message | ||||||
|  | -v ........... verbose (e.g. print encoding/decoding times) | ||||||
|  | -quiet ....... quiet mode, don't print anything | ||||||
|  | -noasm ....... disable all assembly optimizations | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | ## WebP file analysis tool | ||||||
|  |  | ||||||
|  | `webpinfo` can be used to print out the chunk level structure and bitstream | ||||||
|  | header information of WebP files. It can also check if the files are of valid | ||||||
|  | WebP format. | ||||||
|  |  | ||||||
|  | Usage: | ||||||
|  |  | ||||||
|  | ```shell | ||||||
|  | webpinfo [options] in_files | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | Note: there could be multiple input files; options must come before input files. | ||||||
|  |  | ||||||
|  | Options: | ||||||
|  |  | ||||||
|  | ``` | ||||||
|  | -version ........... Print version number and exit. | ||||||
|  | -quiet ............. Do not show chunk parsing information. | ||||||
|  | -diag .............. Show parsing error diagnosis. | ||||||
|  | -summary ........... Show chunk stats summary. | ||||||
|  | -bitstream_info .... Parse bitstream header. | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | ## Visualization tool | ||||||
|  |  | ||||||
|  | There's a little self-serve visualization tool called 'vwebp' under the | ||||||
|  | examples/ directory. It uses OpenGL to open a simple drawing window and show a | ||||||
|  | decoded WebP file. It's not yet integrated in the automake build system, but you | ||||||
|  | can try to manually compile it using the recommendations below. | ||||||
|  |  | ||||||
|  | Usage: | ||||||
|  |  | ||||||
|  | ```shell | ||||||
|  | vwebp in_file [options] | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | Decodes the WebP image file and visualize it using OpenGL | ||||||
|  |  | ||||||
|  | Options are: | ||||||
|  |  | ||||||
|  | ``` | ||||||
|  | -version ..... print version number and exit | ||||||
|  | -noicc ....... don't use the icc profile if present | ||||||
|  | -nofancy ..... don't use the fancy YUV420 upscaler | ||||||
|  | -nofilter .... disable in-loop filtering | ||||||
|  | -dither <int>  dithering strength (0..100), default=50 | ||||||
|  | -noalphadither disable alpha plane dithering | ||||||
|  | -usebgcolor .. display background color | ||||||
|  | -mt .......... use multi-threading | ||||||
|  | -info ........ print info | ||||||
|  | -h ........... this help message | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | Keyboard shortcuts: | ||||||
|  |  | ||||||
|  | ``` | ||||||
|  | 'c' ................ toggle use of color profile | ||||||
|  | 'b' ................ toggle background color display | ||||||
|  | 'i' ................ overlay file information | ||||||
|  | 'd' ................ disable blending & disposal (debug) | ||||||
|  | 'q' / 'Q' / ESC .... quit | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | ### Building | ||||||
|  |  | ||||||
|  | Prerequisites: | ||||||
|  |  | ||||||
|  | 1.  OpenGL & OpenGL Utility Toolkit (GLUT) | ||||||
|  |  | ||||||
|  |     Linux: `sudo apt-get install freeglut3-dev mesa-common-dev` | ||||||
|  |  | ||||||
|  |     Mac + Xcode: These libraries should be available in the OpenGL / GLUT | ||||||
|  |     frameworks. | ||||||
|  |  | ||||||
|  |     Windows: http://freeglut.sourceforge.net/index.php#download | ||||||
|  |  | ||||||
|  | 2.  (Optional) qcms (Quick Color Management System) | ||||||
|  |  | ||||||
|  |     1.  Download qcms from Mozilla / Chromium: | ||||||
|  |         https://hg.mozilla.org/mozilla-central/file/0e7639e3bdfb/gfx/qcms | ||||||
|  |         https://source.chromium.org/chromium/chromium/src/+/main:third_party/qcms/;drc=d4a2f8e1ed461d8fc05ed88d1ae2dc94c9773825 | ||||||
|  |     2.  Build and archive the source files as libqcms.a / qcms.lib | ||||||
|  |     3.  Update makefile.unix / Makefile.vc | ||||||
|  |         1.  Define WEBP_HAVE_QCMS | ||||||
|  |         2.  Update include / library paths to reference the qcms directory. | ||||||
|  |  | ||||||
|  | Build using makefile.unix / Makefile.vc: | ||||||
|  |  | ||||||
|  | ```shell | ||||||
|  | $ make -f makefile.unix examples/vwebp | ||||||
|  | > nmake /f Makefile.vc CFG=release-static \ | ||||||
|  |     ../obj/x64/release-static/bin/vwebp.exe | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | ## Animation creation tool | ||||||
|  |  | ||||||
|  | The utility `img2webp` can turn a sequence of input images (PNG, JPEG, ...) into | ||||||
|  | an animated WebP file. It offers fine control over duration, encoding modes, | ||||||
|  | etc. | ||||||
|  |  | ||||||
|  | Usage: | ||||||
|  |  | ||||||
|  | ```shell | ||||||
|  | img2webp [file_options] [[frame_options] frame_file]... [-o webp_file] | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | File-level options (only used at the start of compression): | ||||||
|  |  | ||||||
|  | ``` | ||||||
|  | -min_size ............ minimize size | ||||||
|  | -kmax <int> .......... maximum number of frame between key-frames | ||||||
|  |                         (0=only keyframes) | ||||||
|  | -kmin <int> .......... minimum number of frame between key-frames | ||||||
|  |                         (0=disable key-frames altogether) | ||||||
|  | -mixed ............... use mixed lossy/lossless automatic mode | ||||||
|  | -near_lossless <int> . use near-lossless image preprocessing | ||||||
|  |                        (0..100=off), default=100 | ||||||
|  | -sharp_yuv ........... use sharper (and slower) RGB->YUV conversion | ||||||
|  |                        (lossy only) | ||||||
|  | -loop <int> .......... loop count (default: 0, = infinite loop) | ||||||
|  | -v ................... verbose mode | ||||||
|  | -h ................... this help | ||||||
|  | -version ............. print version number and exit | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | Per-frame options (only used for subsequent images input): | ||||||
|  |  | ||||||
|  | ``` | ||||||
|  | -d <int> ............. frame duration in ms (default: 100) | ||||||
|  | -lossless  ........... use lossless mode (default) | ||||||
|  | -lossy ... ........... use lossy mode | ||||||
|  | -q <float> ........... quality | ||||||
|  | -m <int> ............. method to use | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | example: `img2webp -loop 2 in0.png -lossy in1.jpg -d 80 in2.tiff -o out.webp` | ||||||
|  |  | ||||||
|  | Note: if a single file name is passed as the argument, the arguments will be | ||||||
|  | tokenized from this file. The file name must not start with the character '-'. | ||||||
|  |  | ||||||
|  | ## Animated GIF conversion | ||||||
|  |  | ||||||
|  | Animated GIF files can be converted to WebP files with animation using the | ||||||
|  | gif2webp utility available under examples/. The files can then be viewed using | ||||||
|  | vwebp. | ||||||
|  |  | ||||||
|  | Usage: | ||||||
|  |  | ||||||
|  | ```shell | ||||||
|  | gif2webp [options] gif_file -o webp_file | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | Options: | ||||||
|  |  | ||||||
|  | ``` | ||||||
|  | -h / -help ............. this help | ||||||
|  | -lossy ................. encode image using lossy compression | ||||||
|  | -mixed ................. for each frame in the image, pick lossy | ||||||
|  |                          or lossless compression heuristically | ||||||
|  | -q <float> ............. quality factor (0:small..100:big) | ||||||
|  | -m <int> ............... compression method (0=fast, 6=slowest) | ||||||
|  | -min_size .............. minimize output size (default:off) | ||||||
|  |                          lossless compression by default; can be | ||||||
|  |                          combined with -q, -m, -lossy or -mixed | ||||||
|  |                          options | ||||||
|  | -kmin <int> ............ min distance between key frames | ||||||
|  | -kmax <int> ............ max distance between key frames | ||||||
|  | -f <int> ............... filter strength (0=off..100) | ||||||
|  | -metadata <string> ..... comma separated list of metadata to | ||||||
|  |                          copy from the input to the output if present | ||||||
|  |                          Valid values: all, none, icc, xmp (default) | ||||||
|  | -loop_compatibility .... use compatibility mode for Chrome | ||||||
|  |                          version prior to M62 (inclusive) | ||||||
|  | -mt .................... use multi-threading if available | ||||||
|  |  | ||||||
|  | -version ............... print version number and exit | ||||||
|  | -v ..................... verbose | ||||||
|  | -quiet ................. don't print anything | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | ### Building | ||||||
|  |  | ||||||
|  | With the libgif development files installed, gif2webp can be built using | ||||||
|  | makefile.unix: | ||||||
|  |  | ||||||
|  | ```shell | ||||||
|  | $ make -f makefile.unix examples/gif2webp | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | or using autoconf: | ||||||
|  |  | ||||||
|  | ```shell | ||||||
|  | $ ./configure --enable-everything | ||||||
|  | $ make | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | ## Comparison of animated images | ||||||
|  |  | ||||||
|  | Test utility anim_diff under examples/ can be used to compare two animated | ||||||
|  | images (each can be GIF or WebP). | ||||||
|  |  | ||||||
|  | Usage: | ||||||
|  |  | ||||||
|  | ```shell | ||||||
|  | anim_diff <image1> <image2> [options] | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | Options: | ||||||
|  |  | ||||||
|  | ``` | ||||||
|  | -dump_frames <folder> dump decoded frames in PAM format | ||||||
|  | -min_psnr <float> ... minimum per-frame PSNR | ||||||
|  | -raw_comparison ..... if this flag is not used, RGB is | ||||||
|  |                       premultiplied before comparison | ||||||
|  | -max_diff <int> ..... maximum allowed difference per channel | ||||||
|  |                       between corresponding pixels in subsequent | ||||||
|  |                       frames | ||||||
|  | -h .................. this help | ||||||
|  | -version ............ print version number and exit | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | ### Building | ||||||
|  |  | ||||||
|  | With the libgif development files installed, anim_diff can be built using | ||||||
|  | makefile.unix: | ||||||
|  |  | ||||||
|  | ```shell | ||||||
|  | $ make -f makefile.unix examples/anim_diff | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | or using autoconf: | ||||||
|  |  | ||||||
|  | ```shell | ||||||
|  | $ ./configure --enable-everything | ||||||
|  | $ make | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | ## WebP Mux tool | ||||||
|  |  | ||||||
|  | The examples/ directory contains a tool (webpmux) for manipulating WebP files. | ||||||
|  | The webpmux tool can be used to create an extended format WebP file and also to | ||||||
|  | extract or strip relevant data from such a file. | ||||||
|  |  | ||||||
|  | A list of options is available using the -help command line flag: | ||||||
|  |  | ||||||
|  | ```shell | ||||||
|  | > webpmux -help | ||||||
|  | Usage: webpmux -get GET_OPTIONS INPUT -o OUTPUT | ||||||
|  |        webpmux -set SET_OPTIONS INPUT -o OUTPUT | ||||||
|  |        webpmux -duration DURATION_OPTIONS [-duration ...] | ||||||
|  |                INPUT -o OUTPUT | ||||||
|  |        webpmux -strip STRIP_OPTIONS INPUT -o OUTPUT | ||||||
|  |        webpmux -frame FRAME_OPTIONS [-frame...] [-loop LOOP_COUNT] | ||||||
|  |                [-bgcolor BACKGROUND_COLOR] -o OUTPUT | ||||||
|  |        webpmux -info INPUT | ||||||
|  |        webpmux [-h|-help] | ||||||
|  |        webpmux -version | ||||||
|  |        webpmux argument_file_name | ||||||
|  |  | ||||||
|  | GET_OPTIONS: | ||||||
|  |  Extract relevant data: | ||||||
|  |    icc       get ICC profile | ||||||
|  |    exif      get EXIF metadata | ||||||
|  |    xmp       get XMP metadata | ||||||
|  |    frame n   get nth frame | ||||||
|  |  | ||||||
|  | SET_OPTIONS: | ||||||
|  |  Set color profile/metadata/parameters: | ||||||
|  |    loop LOOP_COUNT            set the loop count | ||||||
|  |    bgcolor BACKGROUND_COLOR   set the animation background color | ||||||
|  |    icc  file.icc              set ICC profile | ||||||
|  |    exif file.exif             set EXIF metadata | ||||||
|  |    xmp  file.xmp              set XMP metadata | ||||||
|  |    where:    'file.icc' contains the ICC profile to be set, | ||||||
|  |              'file.exif' contains the EXIF metadata to be set | ||||||
|  |              'file.xmp' contains the XMP metadata to be set | ||||||
|  |  | ||||||
|  | DURATION_OPTIONS: | ||||||
|  |  Set duration of selected frames: | ||||||
|  |    duration            set duration for all frames | ||||||
|  |    duration,frame      set duration of a particular frame | ||||||
|  |    duration,start,end  set duration of frames in the | ||||||
|  |                         interval [start,end]) | ||||||
|  |    where: 'duration' is the duration in milliseconds | ||||||
|  |           'start' is the start frame index | ||||||
|  |           'end' is the inclusive end frame index | ||||||
|  |            The special 'end' value '0' means: last frame. | ||||||
|  |  | ||||||
|  | STRIP_OPTIONS: | ||||||
|  |  Strip color profile/metadata: | ||||||
|  |    icc       strip ICC profile | ||||||
|  |    exif      strip EXIF metadata | ||||||
|  |    xmp       strip XMP metadata | ||||||
|  |  | ||||||
|  | FRAME_OPTIONS(i): | ||||||
|  |  Create animation: | ||||||
|  |    file_i +di[+xi+yi[+mi[bi]]] | ||||||
|  |    where:    'file_i' is the i'th animation frame (WebP format), | ||||||
|  |              'di' is the pause duration before next frame, | ||||||
|  |              'xi','yi' specify the image offset for this frame, | ||||||
|  |              'mi' is the dispose method for this frame (0 or 1), | ||||||
|  |              'bi' is the blending method for this frame (+b or -b) | ||||||
|  |  | ||||||
|  | LOOP_COUNT: | ||||||
|  |  Number of times to repeat the animation. | ||||||
|  |  Valid range is 0 to 65535 [Default: 0 (infinite)]. | ||||||
|  |  | ||||||
|  | BACKGROUND_COLOR: | ||||||
|  |  Background color of the canvas. | ||||||
|  |   A,R,G,B | ||||||
|  |   where:    'A', 'R', 'G' and 'B' are integers in the range 0 to 255 specifying | ||||||
|  |             the Alpha, Red, Green and Blue component values respectively | ||||||
|  |             [Default: 255,255,255,255] | ||||||
|  |  | ||||||
|  | INPUT & OUTPUT are in WebP format. | ||||||
|  |  | ||||||
|  | Note: The nature of EXIF, XMP and ICC data is not checked and is assumed to be | ||||||
|  | valid. | ||||||
|  |  | ||||||
|  | Note: if a single file name is passed as the argument, the arguments will be | ||||||
|  | tokenized from this file. The file name must not start with the character '-'. | ||||||
|  | ``` | ||||||
							
								
								
									
										870
									
								
								external/libwebp/libwebp/doc/webp-container-spec.txt
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										870
									
								
								external/libwebp/libwebp/doc/webp-container-spec.txt
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,870 @@ | |||||||
|  | <!-- | ||||||
|  |  | ||||||
|  | Although you may be viewing an alternate representation, this document | ||||||
|  | is sourced in Markdown, a light-duty markup scheme, and is optimized for | ||||||
|  | the [kramdown](https://kramdown.gettalong.org/) transformer. | ||||||
|  |  | ||||||
|  | See the accompanying specs_generation.md. External link targets are referenced | ||||||
|  | at the end of this file. | ||||||
|  |  | ||||||
|  | --> | ||||||
|  |  | ||||||
|  |  | ||||||
|  | WebP Container Specification | ||||||
|  | ============================ | ||||||
|  |  | ||||||
|  | * TOC placeholder | ||||||
|  | {:toc} | ||||||
|  |  | ||||||
|  |  | ||||||
|  | Introduction | ||||||
|  | ------------ | ||||||
|  |  | ||||||
|  | WebP is an image format that uses either (i) the VP8 key frame encoding to | ||||||
|  | compress image data in a lossy way or (ii) the WebP lossless encoding. These | ||||||
|  | encoding schemes should make it more efficient than older formats, such as JPEG, | ||||||
|  | GIF, and PNG. It is optimized for fast image transfer over the network (for | ||||||
|  | example, for websites). The WebP format has feature parity (color profile, | ||||||
|  | metadata, animation, etc.) with other formats as well. This document describes | ||||||
|  | the structure of a WebP file. | ||||||
|  |  | ||||||
|  | The WebP container (that is, the RIFF container for WebP) allows feature support | ||||||
|  | over and above the basic use case of WebP (that is, a file containing a single | ||||||
|  | image encoded as a VP8 key frame). The WebP container provides additional | ||||||
|  | support for the following: | ||||||
|  |  | ||||||
|  |   * Lossless Compression: An image can be losslessly compressed, using the | ||||||
|  |     WebP Lossless Format. | ||||||
|  |  | ||||||
|  |   * Metadata: An image may have metadata stored in Exchangeable Image File | ||||||
|  |     Format (Exif) or Extensible Metadata Platform (XMP) format. | ||||||
|  |  | ||||||
|  |   * Transparency: An image may have transparency, that is, an alpha channel. | ||||||
|  |  | ||||||
|  |   * Color Profile: An image may have an embedded ICC profile as described | ||||||
|  |     by the [International Color Consortium][iccspec]. | ||||||
|  |  | ||||||
|  |   * Animation: An image may have multiple frames with pauses between them, | ||||||
|  |     making it an animation. | ||||||
|  |  | ||||||
|  | Terminology & Basics | ||||||
|  | -------------------- | ||||||
|  |  | ||||||
|  | The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", | ||||||
|  | "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this | ||||||
|  | document are to be interpreted as described in BCP 14 [RFC 2119][] [RFC 8174][] | ||||||
|  | when, and only when, they appear in all capitals, as shown here. | ||||||
|  |  | ||||||
|  | A WebP file contains either a still image (that is, an encoded matrix of pixels) | ||||||
|  | or an [animation](#animation). Optionally, it can also contain transparency | ||||||
|  | information, a color profile and metadata. We refer to the matrix of pixels as | ||||||
|  | the _canvas_ of the image. | ||||||
|  |  | ||||||
|  | Bit numbering in chunk diagrams starts at `0` for the most significant bit | ||||||
|  | ('MSB 0'), as described in [RFC 1166][]. | ||||||
|  |  | ||||||
|  | Below are additional terms used throughout this document: | ||||||
|  |  | ||||||
|  | _Reader/Writer_ | ||||||
|  |  | ||||||
|  | : Code that reads WebP files is referred to as a _reader_, while code that | ||||||
|  |   writes them is referred to as a _writer_. | ||||||
|  |  | ||||||
|  | _uint16_ | ||||||
|  |  | ||||||
|  | : A 16-bit, little-endian, unsigned integer. | ||||||
|  |  | ||||||
|  | _uint24_ | ||||||
|  |  | ||||||
|  | : A 24-bit, little-endian, unsigned integer. | ||||||
|  |  | ||||||
|  | _uint32_ | ||||||
|  |  | ||||||
|  | : A 32-bit, little-endian, unsigned integer. | ||||||
|  |  | ||||||
|  | _FourCC_ | ||||||
|  |  | ||||||
|  | : A four-character code (FourCC) is a _uint32_ created by concatenating four | ||||||
|  |   ASCII characters in little-endian order. This means 'aaaa' (0x61616161) and | ||||||
|  |  'AAAA' (0x41414141) are treated as different _FourCCs_. | ||||||
|  |  | ||||||
|  | _1-based_ | ||||||
|  |  | ||||||
|  | : An unsigned integer field storing values offset by `-1`, for example, such a | ||||||
|  |   field would store value _25_ as _24_. | ||||||
|  |  | ||||||
|  | _ChunkHeader('ABCD')_ | ||||||
|  |  | ||||||
|  | : Used to describe the _FourCC_ and _Chunk Size_ header of individual chunks, | ||||||
|  |   where 'ABCD' is the FourCC for the chunk. This element's size is 8 bytes. | ||||||
|  |  | ||||||
|  |  | ||||||
|  | RIFF File Format | ||||||
|  | ---------------- | ||||||
|  |  | ||||||
|  | The WebP file format is based on the RIFF (Resource Interchange File Format) | ||||||
|  | document format. | ||||||
|  |  | ||||||
|  | The basic element of a RIFF file is a _chunk_. It consists of: | ||||||
|  |  | ||||||
|  |      0                   1                   2                   3 | ||||||
|  |      0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | ||||||
|  |     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||||
|  |     |                         Chunk FourCC                          | | ||||||
|  |     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||||
|  |     |                          Chunk Size                           | | ||||||
|  |     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||||
|  |     :                         Chunk Payload                         : | ||||||
|  |     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||||
|  |  | ||||||
|  | Chunk FourCC: 32 bits | ||||||
|  |  | ||||||
|  | : ASCII four-character code used for chunk identification. | ||||||
|  |  | ||||||
|  | Chunk Size: 32 bits (_uint32_) | ||||||
|  |  | ||||||
|  | : The size of the chunk in bytes, not including this field, the chunk | ||||||
|  |   identifier, or padding. | ||||||
|  |  | ||||||
|  | Chunk Payload: _Chunk Size_ bytes | ||||||
|  |  | ||||||
|  | : The data payload. If _Chunk Size_ is odd, a single padding byte -- which MUST | ||||||
|  |   be `0` to conform with RIFF -- is added. | ||||||
|  |  | ||||||
|  | **Note:** RIFF has a convention that all-uppercase chunk FourCCs are standard | ||||||
|  | chunks that apply to any RIFF file format, while FourCCs specific to a file | ||||||
|  | format are all lowercase. WebP does not follow this convention. | ||||||
|  |  | ||||||
|  |  | ||||||
|  | WebP File Header | ||||||
|  | ---------------- | ||||||
|  |  | ||||||
|  |      0                   1                   2                   3 | ||||||
|  |      0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | ||||||
|  |     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||||
|  |     |      'R'      |      'I'      |      'F'      |      'F'      | | ||||||
|  |     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||||
|  |     |                           File Size                           | | ||||||
|  |     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||||
|  |     |      'W'      |      'E'      |      'B'      |      'P'      | | ||||||
|  |     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||||
|  |  | ||||||
|  | 'RIFF': 32 bits | ||||||
|  |  | ||||||
|  | : The ASCII characters 'R', 'I', 'F', 'F'. | ||||||
|  |  | ||||||
|  | File Size: 32 bits (_uint32_) | ||||||
|  |  | ||||||
|  | : The size of the file in bytes, starting at offset 8. The maximum value of | ||||||
|  |   this field is 2^32 minus 10 bytes and thus the size of the whole file is at | ||||||
|  |   most 4 GiB minus 2 bytes. | ||||||
|  |  | ||||||
|  | 'WEBP': 32 bits | ||||||
|  |  | ||||||
|  | : The ASCII characters 'W', 'E', 'B', 'P'. | ||||||
|  |  | ||||||
|  | A WebP file MUST begin with a RIFF header with the FourCC 'WEBP'. The file size | ||||||
|  | in the header is the total size of the chunks that follow plus `4` bytes for | ||||||
|  | the 'WEBP' FourCC. The file SHOULD NOT contain any data after the data | ||||||
|  | specified by _File Size_. Readers MAY parse such files, ignoring the trailing | ||||||
|  | data. As the size of any chunk is even, the size given by the RIFF header is | ||||||
|  | also even. The contents of individual chunks are described in the following | ||||||
|  | sections. | ||||||
|  |  | ||||||
|  |  | ||||||
|  | Simple File Format (Lossy) | ||||||
|  | -------------------------- | ||||||
|  |  | ||||||
|  | This layout SHOULD be used if the image requires _lossy_ encoding and does not | ||||||
|  | require transparency or other advanced features provided by the extended format. | ||||||
|  | Files with this layout are smaller and supported by older software. | ||||||
|  |  | ||||||
|  | Simple WebP (lossy) file format: | ||||||
|  |  | ||||||
|  |      0                   1                   2                   3 | ||||||
|  |      0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | ||||||
|  |     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||||
|  |     |                                                               | | ||||||
|  |     |                    WebP file header (12 bytes)                | | ||||||
|  |     |                                                               | | ||||||
|  |     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||||
|  |     :                        'VP8 ' Chunk                           : | ||||||
|  |     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||||
|  |  | ||||||
|  | 'VP8 ' Chunk: | ||||||
|  |  | ||||||
|  |      0                   1                   2                   3 | ||||||
|  |      0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | ||||||
|  |     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||||
|  |     |                      ChunkHeader('VP8 ')                      | | ||||||
|  |     |                                                               | | ||||||
|  |     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||||
|  |     :                           VP8 data                            : | ||||||
|  |     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||||
|  |  | ||||||
|  | VP8 data: _Chunk Size_ bytes | ||||||
|  |  | ||||||
|  | : VP8 bitstream data. | ||||||
|  |  | ||||||
|  | Note that the fourth character in the 'VP8 ' FourCC is an ASCII space (0x20). | ||||||
|  |  | ||||||
|  | The VP8 bitstream format specification is described in [VP8 Data Format and | ||||||
|  | Decoding Guide][rfc 6386]. Note that the VP8 frame header contains the VP8 frame | ||||||
|  | width and height. That is assumed to be the width and height of the canvas. | ||||||
|  |  | ||||||
|  | The VP8 specification describes how to decode the image into Y'CbCr format. To | ||||||
|  | convert to RGB, [Recommendation BT.601][rec601] SHOULD be used. Applications MAY | ||||||
|  | use another conversion method, but visual results may differ among decoders. | ||||||
|  |  | ||||||
|  |  | ||||||
|  | Simple File Format (Lossless) | ||||||
|  | ----------------------------- | ||||||
|  |  | ||||||
|  | **Note:** Older readers may not support files using the lossless format. | ||||||
|  |  | ||||||
|  | This layout SHOULD be used if the image requires _lossless_ encoding (with an | ||||||
|  | optional transparency channel) and does not require advanced features provided | ||||||
|  | by the extended format. | ||||||
|  |  | ||||||
|  | Simple WebP (lossless) file format: | ||||||
|  |  | ||||||
|  |      0                   1                   2                   3 | ||||||
|  |      0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | ||||||
|  |     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||||
|  |     |                                                               | | ||||||
|  |     |                    WebP file header (12 bytes)                | | ||||||
|  |     |                                                               | | ||||||
|  |     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||||
|  |     :                         'VP8L' Chunk                          : | ||||||
|  |     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||||
|  |  | ||||||
|  | 'VP8L' Chunk: | ||||||
|  |  | ||||||
|  |      0                   1                   2                   3 | ||||||
|  |      0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | ||||||
|  |     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||||
|  |     |                      ChunkHeader('VP8L')                      | | ||||||
|  |     |                                                               | | ||||||
|  |     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||||
|  |     :                           VP8L data                           : | ||||||
|  |     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||||
|  |  | ||||||
|  | VP8L data: _Chunk Size_ bytes | ||||||
|  |  | ||||||
|  | : VP8L bitstream data. | ||||||
|  |  | ||||||
|  | The current specification of the VP8L bitstream can be found at | ||||||
|  | [WebP Lossless Bitstream Format][webpllspec]. Note that the VP8L header | ||||||
|  | contains the VP8L image width and height. That is assumed to be the width | ||||||
|  | and height of the canvas. | ||||||
|  |  | ||||||
|  |  | ||||||
|  | Extended File Format | ||||||
|  | -------------------- | ||||||
|  |  | ||||||
|  | **Note:** Older readers may not support files using the extended format. | ||||||
|  |  | ||||||
|  | An extended format file consists of: | ||||||
|  |  | ||||||
|  |   * A 'VP8X' Chunk with information about features used in the file. | ||||||
|  |  | ||||||
|  |   * An optional 'ICCP' Chunk with a color profile. | ||||||
|  |  | ||||||
|  |   * An optional 'ANIM' Chunk with animation control data. | ||||||
|  |  | ||||||
|  |   * Image data. | ||||||
|  |  | ||||||
|  |   * An optional 'EXIF' Chunk with Exif metadata. | ||||||
|  |  | ||||||
|  |   * An optional 'XMP ' Chunk with XMP metadata. | ||||||
|  |  | ||||||
|  |   * An optional list of [unknown chunks](#unknown-chunks). | ||||||
|  |  | ||||||
|  | For a _still image_, the _image data_ consists of a single frame, which is made | ||||||
|  | up of: | ||||||
|  |  | ||||||
|  |   * An optional [alpha subchunk](#alpha). | ||||||
|  |  | ||||||
|  |   * A [bitstream subchunk](#bitstream-vp8vp8l). | ||||||
|  |  | ||||||
|  | For an _animated image_, the _image data_ consists of multiple frames. More | ||||||
|  | details about frames can be found in the [Animation](#animation) section. | ||||||
|  |  | ||||||
|  | All chunks SHOULD be placed in the same order as listed above. If a chunk | ||||||
|  | appears in the wrong place, the file is invalid, but readers MAY parse the | ||||||
|  | file, ignoring the chunks that are out of order. | ||||||
|  |  | ||||||
|  | **Rationale:** Setting the order of chunks should allow quicker file | ||||||
|  | parsing. For example, if an 'ALPH' Chunk does not appear in its required | ||||||
|  | position, a decoder can choose to stop searching for it. The rule of | ||||||
|  | ignoring late chunks should make programs that need to do a full search | ||||||
|  | give the same results as the ones stopping early. | ||||||
|  |  | ||||||
|  | Extended WebP file header: | ||||||
|  | {:#extended_header} | ||||||
|  |  | ||||||
|  |      0                   1                   2                   3 | ||||||
|  |      0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | ||||||
|  |     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||||
|  |     |                                                               | | ||||||
|  |     |                   WebP file header (12 bytes)                 | | ||||||
|  |     |                                                               | | ||||||
|  |     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||||
|  |     |                      ChunkHeader('VP8X')                      | | ||||||
|  |     |                                                               | | ||||||
|  |     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||||
|  |     |Rsv|I|L|E|X|A|R|                   Reserved                    | | ||||||
|  |     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||||
|  |     |          Canvas Width Minus One               |             ... | ||||||
|  |     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||||
|  |     ...  Canvas Height Minus One    | | ||||||
|  |     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||||
|  |  | ||||||
|  | Reserved (Rsv): 2 bits | ||||||
|  |  | ||||||
|  | : MUST be `0`. Readers MUST ignore this field. | ||||||
|  |  | ||||||
|  | ICC profile (I): 1 bit | ||||||
|  |  | ||||||
|  | : Set if the file contains an 'ICCP' Chunk. | ||||||
|  |  | ||||||
|  | Alpha (L): 1 bit | ||||||
|  |  | ||||||
|  | : Set if any of the frames of the image contain transparency information | ||||||
|  |   ("alpha"). | ||||||
|  |  | ||||||
|  | Exif metadata (E): 1 bit | ||||||
|  |  | ||||||
|  | : Set if the file contains Exif metadata. | ||||||
|  |  | ||||||
|  | XMP metadata (X): 1 bit | ||||||
|  |  | ||||||
|  | : Set if the file contains XMP metadata. | ||||||
|  |  | ||||||
|  | Animation (A): 1 bit | ||||||
|  |  | ||||||
|  | : Set if this is an animated image. Data in 'ANIM' and 'ANMF' Chunks should be | ||||||
|  |   used to control the animation. | ||||||
|  |  | ||||||
|  | Reserved (R): 1 bit | ||||||
|  |  | ||||||
|  | : MUST be `0`. Readers MUST ignore this field. | ||||||
|  |  | ||||||
|  | Reserved: 24 bits | ||||||
|  |  | ||||||
|  | : MUST be `0`. Readers MUST ignore this field. | ||||||
|  |  | ||||||
|  | Canvas Width Minus One: 24 bits | ||||||
|  |  | ||||||
|  | : _1-based_ width of the canvas in pixels. | ||||||
|  |   The actual canvas width is `1 + Canvas Width Minus One`. | ||||||
|  |  | ||||||
|  | Canvas Height Minus One: 24 bits | ||||||
|  |  | ||||||
|  | : _1-based_ height of the canvas in pixels. | ||||||
|  |   The actual canvas height is `1 + Canvas Height Minus One`. | ||||||
|  |  | ||||||
|  | The product of _Canvas Width_ and _Canvas Height_ MUST be at most `2^32 - 1`. | ||||||
|  |  | ||||||
|  | Future specifications may add more fields. Unknown fields MUST be ignored. | ||||||
|  |  | ||||||
|  | ### Chunks | ||||||
|  |  | ||||||
|  | #### Animation | ||||||
|  |  | ||||||
|  | An animation is controlled by 'ANIM' and 'ANMF' Chunks. | ||||||
|  |  | ||||||
|  | 'ANIM' Chunk: | ||||||
|  | {:#anim_chunk} | ||||||
|  |  | ||||||
|  | For an animated image, this chunk contains the _global parameters_ of the | ||||||
|  | animation. | ||||||
|  |  | ||||||
|  |      0                   1                   2                   3 | ||||||
|  |      0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | ||||||
|  |     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||||
|  |     |                      ChunkHeader('ANIM')                      | | ||||||
|  |     |                                                               | | ||||||
|  |     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||||
|  |     |                       Background Color                        | | ||||||
|  |     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||||
|  |     |          Loop Count           | | ||||||
|  |     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||||
|  |  | ||||||
|  | Background Color: 32 bits (_uint32_) | ||||||
|  |  | ||||||
|  | : The default background color of the canvas in \[Blue, Green, Red, Alpha\] | ||||||
|  |   byte order. This color MAY be used to fill the unused space on the canvas | ||||||
|  |   around the frames, as well as the transparent pixels of the first frame. | ||||||
|  |   The background color is also used when the Disposal method is `1`. | ||||||
|  |  | ||||||
|  | **Note**: | ||||||
|  |  | ||||||
|  |   * The background color MAY contain a non-opaque alpha value, even if the | ||||||
|  |     _Alpha_ flag in the ['VP8X' Chunk](#extended_header) is unset. | ||||||
|  |  | ||||||
|  |   * Viewer applications SHOULD treat the background color value as a hint and | ||||||
|  |     are not required to use it. | ||||||
|  |  | ||||||
|  |   * The canvas is cleared at the start of each loop. The background color MAY be | ||||||
|  |     used to achieve this. | ||||||
|  |  | ||||||
|  | Loop Count: 16 bits (_uint16_) | ||||||
|  |  | ||||||
|  | : The number of times to loop the animation. If it is `0`, this means | ||||||
|  |   infinitely. | ||||||
|  |  | ||||||
|  | This chunk MUST appear if the _Animation_ flag in the 'VP8X' Chunk is set. | ||||||
|  | If the _Animation_ flag is not set and this chunk is present, it MUST be | ||||||
|  | ignored. | ||||||
|  |  | ||||||
|  | 'ANMF' Chunk: | ||||||
|  |  | ||||||
|  | For animated images, this chunk contains information about a _single_ frame. | ||||||
|  | If the _Animation flag_ is not set, then this chunk SHOULD NOT be present. | ||||||
|  |  | ||||||
|  |      0                   1                   2                   3 | ||||||
|  |      0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | ||||||
|  |     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||||
|  |     |                      ChunkHeader('ANMF')                      | | ||||||
|  |     |                                                               | | ||||||
|  |     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||||
|  |     |                        Frame X                |             ... | ||||||
|  |     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||||
|  |     ...          Frame Y            |   Frame Width Minus One     ... | ||||||
|  |     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||||
|  |     ...             |           Frame Height Minus One              | | ||||||
|  |     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||||
|  |     |                 Frame Duration                |  Reserved |B|D| | ||||||
|  |     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||||
|  |     :                         Frame Data                            : | ||||||
|  |     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||||
|  |  | ||||||
|  | Frame X: 24 bits (_uint24_) | ||||||
|  |  | ||||||
|  | : The X coordinate of the upper left corner of the frame is `Frame X * 2`. | ||||||
|  |  | ||||||
|  | Frame Y: 24 bits (_uint24_) | ||||||
|  |  | ||||||
|  | : The Y coordinate of the upper left corner of the frame is `Frame Y * 2`. | ||||||
|  |  | ||||||
|  | Frame Width Minus One: 24 bits (_uint24_) | ||||||
|  |  | ||||||
|  | : The _1-based_ width of the frame. | ||||||
|  |   The frame width is `1 + Frame Width Minus One`. | ||||||
|  |  | ||||||
|  | Frame Height Minus One: 24 bits (_uint24_) | ||||||
|  |  | ||||||
|  | : The _1-based_ height of the frame. | ||||||
|  |   The frame height is `1 + Frame Height Minus One`. | ||||||
|  |  | ||||||
|  | Frame Duration: 24 bits (_uint24_) | ||||||
|  |  | ||||||
|  | : The time to wait before displaying the next frame, in 1-millisecond units. | ||||||
|  |   Note that the interpretation of the Frame Duration of 0 (and often <= 10) is | ||||||
|  |   defined by the implementation. Many tools and browsers assign a minimum | ||||||
|  |   duration similar to GIF. | ||||||
|  |  | ||||||
|  | Reserved: 6 bits | ||||||
|  |  | ||||||
|  | : MUST be `0`. Readers MUST ignore this field. | ||||||
|  |  | ||||||
|  | Blending method (B): 1 bit | ||||||
|  |  | ||||||
|  | : Indicates how transparent pixels of _the current frame_ are to be blended | ||||||
|  |   with corresponding pixels of the previous canvas: | ||||||
|  |  | ||||||
|  |     * `0`: Use alpha-blending. After disposing of the previous frame, render the | ||||||
|  |       current frame on the canvas using [alpha-blending](#alpha-blending). If | ||||||
|  |       the current frame does not have an alpha channel, assume the alpha value | ||||||
|  |       is 255, effectively replacing the rectangle. | ||||||
|  |  | ||||||
|  |     * `1`: Do not blend. After disposing of the previous frame, render the | ||||||
|  |       current frame on the canvas by overwriting the rectangle covered by the | ||||||
|  |       current frame. | ||||||
|  |  | ||||||
|  | Disposal method (D): 1 bit | ||||||
|  |  | ||||||
|  | : Indicates how _the current frame_ is to be treated after it has been | ||||||
|  |   displayed (before rendering the next frame) on the canvas: | ||||||
|  |  | ||||||
|  |     * `0`: Do not dispose. Leave the canvas as is. | ||||||
|  |  | ||||||
|  |     * `1`: Dispose to the background color. Fill the _rectangle_ on the canvas | ||||||
|  |       covered by the _current frame_ with the background color specified in the | ||||||
|  |       ['ANIM' Chunk](#anim_chunk). | ||||||
|  |  | ||||||
|  | **Notes**: | ||||||
|  |  | ||||||
|  |   * The frame disposal only applies to the _frame rectangle_, that is, the | ||||||
|  |     rectangle defined by _Frame X_, _Frame Y_, _frame width_, and _frame | ||||||
|  |     height_. It may or may not cover the whole canvas. | ||||||
|  |  | ||||||
|  | {:#alpha-blending} | ||||||
|  |   * Alpha-blending: | ||||||
|  |  | ||||||
|  |     Given that each of the R, G, B, and A channels is 8 bits, and the RGB | ||||||
|  |     channels are _not premultiplied_ by alpha, the formula for blending | ||||||
|  |     'dst' onto 'src' is: | ||||||
|  |  | ||||||
|  | ~~~~~ | ||||||
|  |     blend.A = src.A + dst.A * (1 - src.A / 255) | ||||||
|  |     if blend.A = 0 then | ||||||
|  |       blend.RGB = 0 | ||||||
|  |     else | ||||||
|  |       blend.RGB = | ||||||
|  |           (src.RGB * src.A + | ||||||
|  |            dst.RGB * dst.A * (1 - src.A / 255)) / blend.A | ||||||
|  | ~~~~~ | ||||||
|  |  | ||||||
|  |   * Alpha-blending SHOULD be done in linear color space, by taking into account | ||||||
|  |     the [color profile](#color-profile) of the image. If the color profile is | ||||||
|  |     not present, standard RGB (sRGB) is to be assumed. (Note that sRGB also | ||||||
|  |     needs to be linearized due to a gamma of ~2.2.) | ||||||
|  |  | ||||||
|  | Frame Data: _Chunk Size_ - `16` bytes | ||||||
|  |  | ||||||
|  | : Consists of: | ||||||
|  |  | ||||||
|  |   * An optional [alpha subchunk](#alpha) for the frame. | ||||||
|  |  | ||||||
|  |   * A [bitstream subchunk](#bitstream-vp8vp8l) for the frame. | ||||||
|  |  | ||||||
|  |   * An optional list of [unknown chunks](#unknown-chunks). | ||||||
|  |  | ||||||
|  | **Note**: The 'ANMF' payload, _Frame Data_ above, consists of individual | ||||||
|  | _padded_ chunks, as described by the [RIFF file format](#riff-file-format). | ||||||
|  |  | ||||||
|  | #### Alpha | ||||||
|  |  | ||||||
|  |      0                   1                   2                   3 | ||||||
|  |      0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | ||||||
|  |     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||||
|  |     |                      ChunkHeader('ALPH')                      | | ||||||
|  |     |                                                               | | ||||||
|  |     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||||
|  |     |Rsv| P | F | C |     Alpha Bitstream...                        | | ||||||
|  |     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||||
|  |  | ||||||
|  | Reserved (Rsv): 2 bits | ||||||
|  |  | ||||||
|  | : MUST be `0`. Readers MUST ignore this field. | ||||||
|  |  | ||||||
|  | Preprocessing (P): 2 bits | ||||||
|  |  | ||||||
|  | : These _informative_ bits are used to signal the preprocessing that has | ||||||
|  |   been performed during compression. The decoder can use this information to | ||||||
|  |   for example, dither the values or smooth the gradients prior to display. | ||||||
|  |  | ||||||
|  |     * `0`: No preprocessing. | ||||||
|  |     * `1`: Level reduction. | ||||||
|  |  | ||||||
|  | Decoders are not required to use this information in any specified way. | ||||||
|  |  | ||||||
|  | Filtering method (F): 2 bits | ||||||
|  |  | ||||||
|  | : The filtering methods used are described as follows: | ||||||
|  |  | ||||||
|  |     * `0`: None. | ||||||
|  |     * `1`: Horizontal filter. | ||||||
|  |     * `2`: Vertical filter. | ||||||
|  |     * `3`: Gradient filter. | ||||||
|  |  | ||||||
|  | For each pixel, filtering is performed using the following calculations. | ||||||
|  | Assume the alpha values surrounding the current `X` position are labeled as: | ||||||
|  |  | ||||||
|  |      C | B | | ||||||
|  |     ---+---+ | ||||||
|  |      A | X | | ||||||
|  |  | ||||||
|  | We seek to compute the alpha value at position `X`. First, a prediction is | ||||||
|  | made depending on the filtering method: | ||||||
|  |  | ||||||
|  |   * Method `0`: predictor = 0 | ||||||
|  |   * Method `1`: predictor = A | ||||||
|  |   * Method `2`: predictor = B | ||||||
|  |   * Method `3`: predictor = clip(A + B - C) | ||||||
|  |  | ||||||
|  | where `clip(v)` is equal to: | ||||||
|  |  | ||||||
|  |   * 0    if v < 0, | ||||||
|  |   * 255  if v > 255, or | ||||||
|  |   * v    otherwise | ||||||
|  |  | ||||||
|  | The final value is derived by adding the decompressed value `X` to the | ||||||
|  | predictor and using modulo-256 arithmetic to wrap the \[256..511\] range | ||||||
|  | into the \[0..255\] one: | ||||||
|  |  | ||||||
|  | `alpha = (predictor + X) % 256` | ||||||
|  |  | ||||||
|  | There are special cases for the left-most and top-most pixel positions. For | ||||||
|  | example, the top-left value at location (0, 0) uses 0 as the predictor value. | ||||||
|  | Otherwise: | ||||||
|  |  | ||||||
|  |   * For horizontal or gradient filtering methods, the left-most pixels at | ||||||
|  |     location (0, y) are predicted using the location (0, y-1) just above. | ||||||
|  |   * For vertical or gradient filtering methods, the top-most pixels at | ||||||
|  |     location (x, 0) are predicted using the location (x-1, 0) on the left. | ||||||
|  |  | ||||||
|  | Compression method (C): 2 bits | ||||||
|  |  | ||||||
|  | : The compression method used: | ||||||
|  |  | ||||||
|  |     * `0`: No compression. | ||||||
|  |     * `1`: Compressed using the WebP lossless format. | ||||||
|  |  | ||||||
|  | Alpha bitstream: _Chunk Size_ - `1` bytes | ||||||
|  |  | ||||||
|  | : Encoded alpha bitstream. | ||||||
|  |  | ||||||
|  | This optional chunk contains encoded alpha data for this frame. A frame | ||||||
|  | containing a 'VP8L' Chunk SHOULD NOT contain this chunk. | ||||||
|  |  | ||||||
|  | **Rationale**: The transparency information is already part of the 'VP8L' | ||||||
|  | Chunk. | ||||||
|  |  | ||||||
|  | The alpha channel data is stored as uncompressed raw data (when the | ||||||
|  | compression method is '0') or compressed using the lossless format | ||||||
|  | (when the compression method is '1'). | ||||||
|  |  | ||||||
|  |   * Raw data: This consists of a byte sequence of length = width * height, | ||||||
|  |     containing all the 8-bit transparency values in scan order. | ||||||
|  |  | ||||||
|  |   * Lossless format compression: The byte sequence is a compressed | ||||||
|  |     image-stream (as described in ["WebP Lossless Bitstream Format"] | ||||||
|  |     [webpllspec]) of implicit dimensions width x height. That is, this | ||||||
|  |     image-stream does NOT contain any headers describing the image dimensions. | ||||||
|  |  | ||||||
|  |     **Rationale**: The dimensions are already known from other sources, | ||||||
|  |     so storing them again would be redundant and prone to error. | ||||||
|  |  | ||||||
|  |     Once the image-stream is decoded into Alpha, Red, Green, Blue (ARGB) color | ||||||
|  |     values, following the process described in the lossless format | ||||||
|  |     specification, the transparency information must be extracted from the | ||||||
|  |     *green* channel of the ARGB quadruplet. | ||||||
|  |  | ||||||
|  |     **Rationale**: The green channel is allowed extra transformation | ||||||
|  |     steps in the specification -- unlike the other channels -- that can | ||||||
|  |     improve compression. | ||||||
|  |  | ||||||
|  | #### Bitstream (VP8/VP8L) | ||||||
|  |  | ||||||
|  | This chunk contains compressed bitstream data for a single frame. | ||||||
|  |  | ||||||
|  | A bitstream chunk may be either (i) a 'VP8 ' Chunk, using 'VP8 ' (note the | ||||||
|  | significant fourth-character space) as its FourCC, _or_ (ii) a 'VP8L' Chunk, | ||||||
|  | using 'VP8L' as its FourCC. | ||||||
|  |  | ||||||
|  | The formats of 'VP8 ' and 'VP8L' Chunks are as described in sections | ||||||
|  | [Simple File Format (Lossy)](#simple-file-format-lossy) | ||||||
|  | and [Simple File Format (Lossless)](#simple-file-format-lossless), respectively. | ||||||
|  |  | ||||||
|  | #### Color Profile | ||||||
|  |  | ||||||
|  |      0                   1                   2                   3 | ||||||
|  |      0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | ||||||
|  |     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||||
|  |     |                      ChunkHeader('ICCP')                      | | ||||||
|  |     |                                                               | | ||||||
|  |     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||||
|  |     :                       Color Profile                           : | ||||||
|  |     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||||
|  |  | ||||||
|  | Color Profile: _Chunk Size_ bytes | ||||||
|  |  | ||||||
|  | : ICC profile. | ||||||
|  |  | ||||||
|  | This chunk MUST appear before the image data. | ||||||
|  |  | ||||||
|  | There SHOULD be at most one such chunk. If there are more such chunks, readers | ||||||
|  | MAY ignore all except the first one. | ||||||
|  | See the [ICC Specification][iccspec] for details. | ||||||
|  |  | ||||||
|  | If this chunk is not present, sRGB SHOULD be assumed. | ||||||
|  |  | ||||||
|  | #### Metadata | ||||||
|  |  | ||||||
|  | Metadata can be stored in 'EXIF' or 'XMP ' Chunks. | ||||||
|  |  | ||||||
|  | There SHOULD be at most one chunk of each type ('EXIF' and 'XMP '). If there | ||||||
|  | are more such chunks, readers MAY ignore all except the first one. | ||||||
|  |  | ||||||
|  | The chunks are defined as follows: | ||||||
|  |  | ||||||
|  | 'EXIF' Chunk: | ||||||
|  |  | ||||||
|  |      0                   1                   2                   3 | ||||||
|  |      0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | ||||||
|  |     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||||
|  |     |                      ChunkHeader('EXIF')                      | | ||||||
|  |     |                                                               | | ||||||
|  |     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||||
|  |     :                        Exif Metadata                          : | ||||||
|  |     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||||
|  |  | ||||||
|  | Exif Metadata: _Chunk Size_ bytes | ||||||
|  |  | ||||||
|  | : Image metadata in Exif format. | ||||||
|  |  | ||||||
|  | 'XMP ' Chunk: | ||||||
|  |  | ||||||
|  |      0                   1                   2                   3 | ||||||
|  |      0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | ||||||
|  |     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||||
|  |     |                      ChunkHeader('XMP ')                      | | ||||||
|  |     |                                                               | | ||||||
|  |     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||||
|  |     :                        XMP Metadata                           : | ||||||
|  |     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||||
|  |  | ||||||
|  | XMP Metadata: _Chunk Size_ bytes | ||||||
|  |  | ||||||
|  | : Image metadata in XMP format. | ||||||
|  |  | ||||||
|  | Note that the fourth character in the 'XMP ' FourCC is an ASCII space (0x20). | ||||||
|  |  | ||||||
|  | Additional guidance about handling metadata can be found in the | ||||||
|  | Metadata Working Group's ["Guidelines for Handling Metadata"][metadata]. | ||||||
|  |  | ||||||
|  | #### Unknown Chunks | ||||||
|  |  | ||||||
|  | A RIFF chunk (described in the [RIFF File Format](#riff-file-format) section) | ||||||
|  | whose FourCC is different from any of the chunks described in this document, is | ||||||
|  | considered an _unknown chunk_. | ||||||
|  |  | ||||||
|  | **Rationale**: Allowing unknown chunks gives a provision for future extension | ||||||
|  | of the format and also allows storage of any application-specific data. | ||||||
|  |  | ||||||
|  | A file MAY contain unknown chunks: | ||||||
|  |  | ||||||
|  |   * at the end of the file, as described in [Extended WebP file | ||||||
|  |     header](#extended_header) section, or | ||||||
|  |   * at the end of 'ANMF' Chunks, as described in the | ||||||
|  |     [Animation](#animation) section. | ||||||
|  |  | ||||||
|  | Readers SHOULD ignore these chunks. Writers SHOULD preserve them in their | ||||||
|  | original order (unless they specifically intend to modify these chunks). | ||||||
|  |  | ||||||
|  | ### Canvas Assembly from Frames | ||||||
|  |  | ||||||
|  | Here we provide an overview of how a reader MUST assemble a canvas in the case | ||||||
|  | of an animated image. | ||||||
|  |  | ||||||
|  | The process begins with creating a canvas using the dimensions given in the | ||||||
|  | 'VP8X' Chunk, `Canvas Width Minus One + 1` pixels wide by `Canvas Height Minus | ||||||
|  | One + 1` pixels high. The `Loop Count` field from the 'ANIM' Chunk controls how | ||||||
|  | many times the animation process is repeated. This is `Loop Count - 1` for | ||||||
|  | nonzero `Loop Count` values or infinite if the `Loop Count` is zero. | ||||||
|  |  | ||||||
|  | At the beginning of each loop iteration, the canvas is filled using the | ||||||
|  | background color from the 'ANIM' Chunk or an application-defined color. | ||||||
|  |  | ||||||
|  | 'ANMF' Chunks contain individual frames given in display order. Before rendering | ||||||
|  | each frame, the previous frame's `Disposal method` is applied. | ||||||
|  |  | ||||||
|  | The rendering of the decoded frame begins at the Cartesian coordinates (`2 * | ||||||
|  | Frame X`, `2 * Frame Y`), using the top-left corner of the canvas as the origin. | ||||||
|  | `Frame Width Minus One + 1` pixels wide by `Frame Height Minus One + 1` pixels | ||||||
|  | high are rendered onto the canvas using the `Blending method`. | ||||||
|  |  | ||||||
|  | The canvas is displayed for `Frame Duration` milliseconds. This continues until | ||||||
|  | all frames given by 'ANMF' Chunks have been displayed. A new loop iteration is | ||||||
|  | then begun, or the canvas is left in its final state if all iterations have been | ||||||
|  | completed. | ||||||
|  |  | ||||||
|  | The following pseudocode illustrates the rendering process. The notation | ||||||
|  | _VP8X.field_ means the field in the 'VP8X' Chunk with the same description. | ||||||
|  |  | ||||||
|  | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||||
|  | assert VP8X.flags.hasAnimation | ||||||
|  | canvas ← new image of size VP8X.canvasWidth x VP8X.canvasHeight with | ||||||
|  |          background color ANIM.background_color. | ||||||
|  | loop_count ← ANIM.loopCount | ||||||
|  | dispose_method ← Dispose to background color | ||||||
|  | if loop_count == 0: | ||||||
|  |   loop_count = ∞ | ||||||
|  | frame_params ← nil | ||||||
|  | assert next chunk in image_data is ANMF | ||||||
|  | for loop = 0..loop_count - 1 | ||||||
|  |   clear canvas to ANIM.background_color or application-defined color | ||||||
|  |   until eof or non-ANMF chunk | ||||||
|  |     frame_params.frameX = Frame X | ||||||
|  |     frame_params.frameY = Frame Y | ||||||
|  |     frame_params.frameWidth = Frame Width Minus One + 1 | ||||||
|  |     frame_params.frameHeight = Frame Height Minus One + 1 | ||||||
|  |     frame_params.frameDuration = Frame Duration | ||||||
|  |     frame_right = frame_params.frameX + frame_params.frameWidth | ||||||
|  |     frame_bottom = frame_params.frameY + frame_params.frameHeight | ||||||
|  |     assert VP8X.canvasWidth >= frame_right | ||||||
|  |     assert VP8X.canvasHeight >= frame_bottom | ||||||
|  |     for subchunk in 'Frame Data': | ||||||
|  |       if subchunk.tag == "ALPH": | ||||||
|  |         assert alpha subchunks not found in 'Frame Data' earlier | ||||||
|  |         frame_params.alpha = alpha_data | ||||||
|  |       else if subchunk.tag == "VP8 " OR subchunk.tag == "VP8L": | ||||||
|  |         assert bitstream subchunks not found in 'Frame Data' earlier | ||||||
|  |         frame_params.bitstream = bitstream_data | ||||||
|  |     render frame with frame_params.alpha and frame_params.bitstream | ||||||
|  |       on canvas with top-left corner at (frame_params.frameX, | ||||||
|  |       frame_params.frameY), using Blending method | ||||||
|  |       frame_params.blendingMethod. | ||||||
|  |     canvas contains the decoded image. | ||||||
|  |     Show the contents of the canvas for | ||||||
|  |     frame_params.frameDuration * 1 ms. | ||||||
|  |     dispose_method = frame_params.disposeMethod | ||||||
|  | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||||
|  |  | ||||||
|  |  | ||||||
|  | Example File Layouts | ||||||
|  | -------------------- | ||||||
|  |  | ||||||
|  | A lossy-encoded image with alpha may look as follows: | ||||||
|  |  | ||||||
|  | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||||
|  | RIFF/WEBP | ||||||
|  | +- VP8X (descriptions of features used) | ||||||
|  | +- ALPH (alpha bitstream) | ||||||
|  | +- VP8 (bitstream) | ||||||
|  | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||||
|  |  | ||||||
|  | A lossless-encoded image may look as follows: | ||||||
|  |  | ||||||
|  | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||||
|  | RIFF/WEBP | ||||||
|  | +- VP8X (descriptions of features used) | ||||||
|  | +- XYZW (unknown chunk) | ||||||
|  | +- VP8L (lossless bitstream) | ||||||
|  | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||||
|  |  | ||||||
|  | A lossless image with an ICC profile and XMP metadata may | ||||||
|  | look as follows: | ||||||
|  |  | ||||||
|  | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||||
|  | RIFF/WEBP | ||||||
|  | +- VP8X (descriptions of features used) | ||||||
|  | +- ICCP (color profile) | ||||||
|  | +- VP8L (lossless bitstream) | ||||||
|  | +- XMP  (metadata) | ||||||
|  | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||||
|  |  | ||||||
|  | An animated image with Exif metadata may look as follows: | ||||||
|  |  | ||||||
|  | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||||
|  | RIFF/WEBP | ||||||
|  | +- VP8X (descriptions of features used) | ||||||
|  | +- ANIM (global animation parameters) | ||||||
|  | +- ANMF (frame1 parameters + data) | ||||||
|  | +- ANMF (frame2 parameters + data) | ||||||
|  | +- ANMF (frame3 parameters + data) | ||||||
|  | +- ANMF (frame4 parameters + data) | ||||||
|  | +- EXIF (metadata) | ||||||
|  | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||||
|  |  | ||||||
|  | [webpllspec]: https://chromium.googlesource.com/webm/libwebp/+/HEAD/doc/webp-lossless-bitstream-spec.txt | ||||||
|  | [iccspec]: https://www.color.org/icc_specs2.xalter | ||||||
|  | [metadata]: https://web.archive.org/web/20180919181934/http://www.metadataworkinggroup.org/pdf/mwg_guidance.pdf | ||||||
|  | [rec601]: https://www.itu.int/rec/R-REC-BT.601 | ||||||
|  | [rfc 1166]: https://datatracker.ietf.org/doc/html/rfc1166 | ||||||
|  | [rfc 2119]: https://datatracker.ietf.org/doc/html/rfc2119 | ||||||
|  | [rfc 6386]: https://datatracker.ietf.org/doc/html/rfc6386 | ||||||
|  | [rfc 8174]: https://datatracker.ietf.org/doc/html/rfc8174 | ||||||
							
								
								
									
										1155
									
								
								external/libwebp/libwebp/doc/webp-lossless-bitstream-spec.txt
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1155
									
								
								external/libwebp/libwebp/doc/webp-lossless-bitstream-spec.txt
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										96
									
								
								external/libwebp/libwebp/examples/Android.mk
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										96
									
								
								external/libwebp/libwebp/examples/Android.mk
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,96 @@ | |||||||
|  | # Ignore this file during non-NDK builds. | ||||||
|  | ifdef NDK_ROOT | ||||||
|  | LOCAL_PATH := $(call my-dir) | ||||||
|  |  | ||||||
|  | ################################################################################ | ||||||
|  | # libexample_util | ||||||
|  |  | ||||||
|  | include $(CLEAR_VARS) | ||||||
|  |  | ||||||
|  | LOCAL_SRC_FILES := \ | ||||||
|  |     example_util.c \ | ||||||
|  |  | ||||||
|  | LOCAL_CFLAGS := $(WEBP_CFLAGS) | ||||||
|  | LOCAL_C_INCLUDES := $(LOCAL_PATH)/../src | ||||||
|  |  | ||||||
|  | LOCAL_MODULE := example_util | ||||||
|  |  | ||||||
|  | include $(BUILD_STATIC_LIBRARY) | ||||||
|  |  | ||||||
|  | ################################################################################ | ||||||
|  | # cwebp | ||||||
|  |  | ||||||
|  | include $(CLEAR_VARS) | ||||||
|  |  | ||||||
|  | # Note: to enable jpeg/png encoding the sources from AOSP can be used with | ||||||
|  | # minor modification to their Android.mk files. | ||||||
|  | LOCAL_SRC_FILES := \ | ||||||
|  |     cwebp.c \ | ||||||
|  |  | ||||||
|  | LOCAL_CFLAGS := $(WEBP_CFLAGS) | ||||||
|  | LOCAL_STATIC_LIBRARIES := example_util imageio_util imagedec webpdemux webp | ||||||
|  |  | ||||||
|  | LOCAL_MODULE := cwebp | ||||||
|  |  | ||||||
|  | include $(BUILD_EXECUTABLE) | ||||||
|  |  | ||||||
|  | ################################################################################ | ||||||
|  | # dwebp | ||||||
|  |  | ||||||
|  | include $(CLEAR_VARS) | ||||||
|  |  | ||||||
|  | LOCAL_SRC_FILES := \ | ||||||
|  |     dwebp.c \ | ||||||
|  |  | ||||||
|  | LOCAL_CFLAGS := $(WEBP_CFLAGS) | ||||||
|  | LOCAL_STATIC_LIBRARIES := example_util imagedec imageenc webpdemux webp | ||||||
|  | LOCAL_MODULE := dwebp | ||||||
|  |  | ||||||
|  | include $(BUILD_EXECUTABLE) | ||||||
|  |  | ||||||
|  | ################################################################################ | ||||||
|  | # webpmux | ||||||
|  |  | ||||||
|  | include $(CLEAR_VARS) | ||||||
|  |  | ||||||
|  | LOCAL_SRC_FILES := \ | ||||||
|  |     webpmux.c \ | ||||||
|  |  | ||||||
|  | LOCAL_CFLAGS := $(WEBP_CFLAGS) | ||||||
|  | LOCAL_STATIC_LIBRARIES := example_util imageio_util webpmux webp | ||||||
|  |  | ||||||
|  | LOCAL_MODULE := webpmux_example | ||||||
|  |  | ||||||
|  | include $(BUILD_EXECUTABLE) | ||||||
|  |  | ||||||
|  | ################################################################################ | ||||||
|  | # img2webp | ||||||
|  |  | ||||||
|  | include $(CLEAR_VARS) | ||||||
|  |  | ||||||
|  | LOCAL_SRC_FILES := \ | ||||||
|  |     img2webp.c \ | ||||||
|  |  | ||||||
|  | LOCAL_CFLAGS := $(WEBP_CFLAGS) | ||||||
|  | LOCAL_STATIC_LIBRARIES := example_util imageio_util imagedec webpmux webpdemux \ | ||||||
|  |                           webp | ||||||
|  |  | ||||||
|  | LOCAL_MODULE := img2webp_example | ||||||
|  |  | ||||||
|  | include $(BUILD_EXECUTABLE) | ||||||
|  |  | ||||||
|  | ################################################################################ | ||||||
|  | # webpinfo | ||||||
|  |  | ||||||
|  | include $(CLEAR_VARS) | ||||||
|  |  | ||||||
|  | LOCAL_SRC_FILES := \ | ||||||
|  |     webpinfo.c \ | ||||||
|  |  | ||||||
|  | LOCAL_CFLAGS := $(WEBP_CFLAGS) | ||||||
|  | LOCAL_STATIC_LIBRARIES := example_util imageio_util webp | ||||||
|  |  | ||||||
|  | LOCAL_MODULE := webpinfo_example | ||||||
|  |  | ||||||
|  | include $(BUILD_EXECUTABLE) | ||||||
|  | endif  # NDK_ROOT | ||||||
							
								
								
									
										119
									
								
								external/libwebp/libwebp/examples/Makefile.am
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										119
									
								
								external/libwebp/libwebp/examples/Makefile.am
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,119 @@ | |||||||
|  | AM_CPPFLAGS += -I$(top_builddir)/src -I$(top_srcdir)/src | ||||||
|  |  | ||||||
|  | bin_PROGRAMS = | ||||||
|  | if BUILD_DEMUX | ||||||
|  |   bin_PROGRAMS += dwebp cwebp | ||||||
|  | endif | ||||||
|  | if BUILD_ANIMDIFF | ||||||
|  |   noinst_PROGRAMS = anim_diff anim_dump | ||||||
|  | endif | ||||||
|  | if BUILD_GIF2WEBP | ||||||
|  |   bin_PROGRAMS += gif2webp | ||||||
|  | endif | ||||||
|  | if BUILD_IMG2WEBP | ||||||
|  |   bin_PROGRAMS += img2webp | ||||||
|  | endif | ||||||
|  | if BUILD_MUX | ||||||
|  |   bin_PROGRAMS += webpmux | ||||||
|  | endif | ||||||
|  | if BUILD_VWEBP | ||||||
|  |   bin_PROGRAMS += vwebp | ||||||
|  | endif | ||||||
|  | if BUILD_WEBPINFO | ||||||
|  |   bin_PROGRAMS += webpinfo | ||||||
|  | endif | ||||||
|  |  | ||||||
|  | noinst_LTLIBRARIES = libexample_util.la | ||||||
|  |  | ||||||
|  | libexample_util_la_SOURCES = example_util.c example_util.h | ||||||
|  | libexample_util_la_LIBADD = ../src/libwebp.la | ||||||
|  |  | ||||||
|  | anim_diff_SOURCES = anim_diff.c anim_util.c anim_util.h gifdec.c gifdec.h | ||||||
|  | anim_diff_CPPFLAGS = $(AM_CPPFLAGS) $(GIF_INCLUDES) | ||||||
|  | anim_diff_LDADD  = | ||||||
|  | anim_diff_LDADD += ../src/demux/libwebpdemux.la | ||||||
|  | anim_diff_LDADD += libexample_util.la | ||||||
|  | anim_diff_LDADD += ../imageio/libimageio_util.la | ||||||
|  | anim_diff_LDADD += $(GIF_LIBS) -lm | ||||||
|  |  | ||||||
|  | anim_dump_SOURCES = anim_dump.c anim_util.c anim_util.h gifdec.c gifdec.h | ||||||
|  | anim_dump_CPPFLAGS = $(AM_CPPFLAGS) $(PNG_INCLUDES) | ||||||
|  | anim_dump_CPPFLAGS += $(GIF_INCLUDES) | ||||||
|  | anim_dump_LDADD  = | ||||||
|  | anim_dump_LDADD += ../src/demux/libwebpdemux.la | ||||||
|  | anim_dump_LDADD += libexample_util.la | ||||||
|  | anim_dump_LDADD += ../imageio/libimageio_util.la | ||||||
|  | anim_dump_LDADD += ../imageio/libimageenc.la | ||||||
|  | anim_dump_LDADD += $(PNG_LIBS) $(GIF_LIBS) $(TIFF_LIBS) -lm | ||||||
|  |  | ||||||
|  | cwebp_SOURCES  = cwebp.c stopwatch.h | ||||||
|  | cwebp_CPPFLAGS  = $(AM_CPPFLAGS) -I$(top_srcdir) | ||||||
|  | cwebp_LDADD  = | ||||||
|  | cwebp_LDADD += libexample_util.la | ||||||
|  | cwebp_LDADD += ../imageio/libimageio_util.la | ||||||
|  | cwebp_LDADD += ../imageio/libimagedec.la | ||||||
|  | cwebp_LDADD += ../src/libwebp.la | ||||||
|  | cwebp_LDADD += $(JPEG_LIBS) $(PNG_LIBS) $(TIFF_LIBS) | ||||||
|  |  | ||||||
|  | dwebp_SOURCES = dwebp.c stopwatch.h | ||||||
|  | dwebp_CPPFLAGS  = $(AM_CPPFLAGS) | ||||||
|  | dwebp_CPPFLAGS += $(JPEG_INCLUDES) $(PNG_INCLUDES) | ||||||
|  | dwebp_LDADD  = | ||||||
|  | dwebp_LDADD += libexample_util.la | ||||||
|  | dwebp_LDADD += ../imageio/libimagedec.la | ||||||
|  | dwebp_LDADD += ../imageio/libimageenc.la | ||||||
|  | dwebp_LDADD += ../imageio/libimageio_util.la | ||||||
|  | dwebp_LDADD += ../src/libwebp.la | ||||||
|  | dwebp_LDADD +=$(PNG_LIBS) $(JPEG_LIBS) | ||||||
|  |  | ||||||
|  | gif2webp_SOURCES = gif2webp.c gifdec.c gifdec.h | ||||||
|  | gif2webp_CPPFLAGS = $(AM_CPPFLAGS) $(GIF_INCLUDES) | ||||||
|  | gif2webp_LDADD  = | ||||||
|  | gif2webp_LDADD += libexample_util.la | ||||||
|  | gif2webp_LDADD += ../imageio/libimageio_util.la | ||||||
|  | gif2webp_LDADD += ../src/mux/libwebpmux.la | ||||||
|  | gif2webp_LDADD += ../src/libwebp.la | ||||||
|  | gif2webp_LDADD += $(GIF_LIBS) | ||||||
|  |  | ||||||
|  | vwebp_SOURCES = vwebp.c | ||||||
|  | vwebp_CPPFLAGS = $(AM_CPPFLAGS) $(GL_INCLUDES) | ||||||
|  | vwebp_LDADD  = | ||||||
|  | vwebp_LDADD += libexample_util.la | ||||||
|  | vwebp_LDADD += ../imageio/libimageio_util.la | ||||||
|  | vwebp_LDADD += ../src/demux/libwebpdemux.la | ||||||
|  | vwebp_LDADD += $(GL_LIBS) | ||||||
|  |  | ||||||
|  | webpmux_SOURCES = webpmux.c | ||||||
|  | webpmux_CPPFLAGS = $(AM_CPPFLAGS) | ||||||
|  | webpmux_LDADD  = | ||||||
|  | webpmux_LDADD += libexample_util.la | ||||||
|  | webpmux_LDADD += ../imageio/libimageio_util.la | ||||||
|  | webpmux_LDADD += ../src/mux/libwebpmux.la | ||||||
|  | webpmux_LDADD += ../src/libwebp.la | ||||||
|  |  | ||||||
|  | img2webp_SOURCES = img2webp.c | ||||||
|  | img2webp_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_srcdir) | ||||||
|  | img2webp_LDADD  = | ||||||
|  | img2webp_LDADD += libexample_util.la | ||||||
|  | img2webp_LDADD += ../imageio/libimageio_util.la | ||||||
|  | img2webp_LDADD += ../imageio/libimagedec.la | ||||||
|  | img2webp_LDADD += ../src/mux/libwebpmux.la | ||||||
|  | img2webp_LDADD += ../src/libwebp.la | ||||||
|  | img2webp_LDADD += $(PNG_LIBS) $(JPEG_LIBS) $(TIFF_LIBS) | ||||||
|  |  | ||||||
|  | webpinfo_SOURCES = webpinfo.c | ||||||
|  | webpinfo_CPPFLAGS = $(AM_CPPFLAGS) | ||||||
|  | webpinfo_LDADD  = | ||||||
|  | webpinfo_LDADD += libexample_util.la | ||||||
|  | webpinfo_LDADD += ../imageio/libimageio_util.la | ||||||
|  | webpinfo_LDADD += ../src/libwebp.la | ||||||
|  |  | ||||||
|  | if BUILD_LIBWEBPDECODER | ||||||
|  |   anim_diff_LDADD += ../src/libwebpdecoder.la | ||||||
|  |   anim_dump_LDADD += ../src/libwebpdecoder.la | ||||||
|  |   vwebp_LDADD += ../src/libwebpdecoder.la | ||||||
|  | else | ||||||
|  |   anim_diff_LDADD += ../src/libwebp.la | ||||||
|  |   anim_dump_LDADD += ../src/libwebp.la | ||||||
|  |   vwebp_LDADD += ../src/libwebp.la | ||||||
|  | endif | ||||||
							
								
								
									
										317
									
								
								external/libwebp/libwebp/examples/anim_diff.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										317
									
								
								external/libwebp/libwebp/examples/anim_diff.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,317 @@ | |||||||
|  | // Copyright 2015 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. | ||||||
|  | // ----------------------------------------------------------------------------- | ||||||
|  | // | ||||||
|  | // Checks if given pair of animated GIF/WebP images are identical: | ||||||
|  | // That is: their reconstructed canvases match pixel-by-pixel and their other | ||||||
|  | // animation properties (loop count etc) also match. | ||||||
|  | // | ||||||
|  | // example: anim_diff foo.gif bar.webp | ||||||
|  |  | ||||||
|  | #include <assert.h> | ||||||
|  | #include <limits.h> | ||||||
|  | #include <stdio.h> | ||||||
|  | #include <stdlib.h>  // for 'strtod'. | ||||||
|  | #include <string.h>  // for 'strcmp'. | ||||||
|  |  | ||||||
|  | #include "./anim_util.h" | ||||||
|  | #include "./example_util.h" | ||||||
|  | #include "./unicode.h" | ||||||
|  |  | ||||||
|  | #if defined(_MSC_VER) && _MSC_VER < 1900 | ||||||
|  | #define snprintf _snprintf | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | // Returns true if 'a + b' will overflow. | ||||||
|  | static int AdditionWillOverflow(int a, int b) { | ||||||
|  |   return (b > 0) && (a > INT_MAX - b); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static int FramesAreEqual(const uint8_t* const rgba1, | ||||||
|  |                           const uint8_t* const rgba2, int width, int height) { | ||||||
|  |   const int stride = width * 4;  // Always true for 'DecodedFrame.rgba'. | ||||||
|  |   return !memcmp(rgba1, rgba2, stride * height); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static WEBP_INLINE int PixelsAreSimilar(uint32_t src, uint32_t dst, | ||||||
|  |                                         int max_allowed_diff) { | ||||||
|  |   const int src_a = (src >> 24) & 0xff; | ||||||
|  |   const int src_r = (src >> 16) & 0xff; | ||||||
|  |   const int src_g = (src >> 8) & 0xff; | ||||||
|  |   const int src_b = (src >> 0) & 0xff; | ||||||
|  |   const int dst_a = (dst >> 24) & 0xff; | ||||||
|  |   const int dst_r = (dst >> 16) & 0xff; | ||||||
|  |   const int dst_g = (dst >> 8) & 0xff; | ||||||
|  |   const int dst_b = (dst >> 0) & 0xff; | ||||||
|  |  | ||||||
|  |   return (abs(src_r * src_a - dst_r * dst_a) <= (max_allowed_diff * 255)) && | ||||||
|  |          (abs(src_g * src_a - dst_g * dst_a) <= (max_allowed_diff * 255)) && | ||||||
|  |          (abs(src_b * src_a - dst_b * dst_a) <= (max_allowed_diff * 255)) && | ||||||
|  |          (abs(src_a - dst_a) <= max_allowed_diff); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static int FramesAreSimilar(const uint8_t* const rgba1, | ||||||
|  |                             const uint8_t* const rgba2, | ||||||
|  |                             int width, int height, int max_allowed_diff) { | ||||||
|  |   int i, j; | ||||||
|  |   assert(max_allowed_diff > 0); | ||||||
|  |   for (j = 0; j < height; ++j) { | ||||||
|  |     for (i = 0; i < width; ++i) { | ||||||
|  |       const int stride = width * 4; | ||||||
|  |       const size_t offset = j * stride + i; | ||||||
|  |       if (!PixelsAreSimilar(rgba1[offset], rgba2[offset], max_allowed_diff)) { | ||||||
|  |         return 0; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   return 1; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Minimize number of frames by combining successive frames that have at max | ||||||
|  | // 'max_diff' difference per channel between corresponding pixels. | ||||||
|  | static void MinimizeAnimationFrames(AnimatedImage* const img, int max_diff) { | ||||||
|  |   uint32_t i; | ||||||
|  |   for (i = 1; i < img->num_frames; ++i) { | ||||||
|  |     DecodedFrame* const frame1 = &img->frames[i - 1]; | ||||||
|  |     DecodedFrame* const frame2 = &img->frames[i]; | ||||||
|  |     const uint8_t* const rgba1 = frame1->rgba; | ||||||
|  |     const uint8_t* const rgba2 = frame2->rgba; | ||||||
|  |     int should_merge_frames = 0; | ||||||
|  |     // If merging frames will result in integer overflow for 'duration', | ||||||
|  |     // skip merging. | ||||||
|  |     if (AdditionWillOverflow(frame1->duration, frame2->duration)) continue; | ||||||
|  |     if (max_diff > 0) { | ||||||
|  |       should_merge_frames = FramesAreSimilar(rgba1, rgba2, img->canvas_width, | ||||||
|  |                                              img->canvas_height, max_diff); | ||||||
|  |     } else { | ||||||
|  |       should_merge_frames = | ||||||
|  |           FramesAreEqual(rgba1, rgba2, img->canvas_width, img->canvas_height); | ||||||
|  |     } | ||||||
|  |     if (should_merge_frames) {  // Merge 'i+1'th frame into 'i'th frame. | ||||||
|  |       frame1->duration += frame2->duration; | ||||||
|  |       if (i + 1 < img->num_frames) { | ||||||
|  |         memmove(&img->frames[i], &img->frames[i + 1], | ||||||
|  |                 (img->num_frames - i - 1) * sizeof(*img->frames)); | ||||||
|  |       } | ||||||
|  |       --img->num_frames; | ||||||
|  |       --i; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static int CompareValues(uint32_t a, uint32_t b, const char* output_str) { | ||||||
|  |   if (a != b) { | ||||||
|  |     fprintf(stderr, "%s: %d vs %d\n", output_str, a, b); | ||||||
|  |     return 0; | ||||||
|  |   } | ||||||
|  |   return 1; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static int CompareBackgroundColor(uint32_t bg1, uint32_t bg2, int premultiply) { | ||||||
|  |   if (premultiply) { | ||||||
|  |     const int alpha1 = (bg1 >> 24) & 0xff; | ||||||
|  |     const int alpha2 = (bg2 >> 24) & 0xff; | ||||||
|  |     if (alpha1 == 0 && alpha2 == 0) return 1; | ||||||
|  |   } | ||||||
|  |   if (bg1 != bg2) { | ||||||
|  |     fprintf(stderr, "Background color mismatch: 0x%08x vs 0x%08x\n", | ||||||
|  |             bg1, bg2); | ||||||
|  |     return 0; | ||||||
|  |   } | ||||||
|  |   return 1; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Note: As long as frame durations and reconstructed frames are identical, it | ||||||
|  | // is OK for other aspects like offsets, dispose/blend method to vary. | ||||||
|  | static int CompareAnimatedImagePair(const AnimatedImage* const img1, | ||||||
|  |                                     const AnimatedImage* const img2, | ||||||
|  |                                     int premultiply, | ||||||
|  |                                     double min_psnr) { | ||||||
|  |   int ok = 1; | ||||||
|  |   const int is_multi_frame_image = (img1->num_frames > 1); | ||||||
|  |   uint32_t i; | ||||||
|  |  | ||||||
|  |   ok = CompareValues(img1->canvas_width, img2->canvas_width, | ||||||
|  |                      "Canvas width mismatch") && ok; | ||||||
|  |   ok = CompareValues(img1->canvas_height, img2->canvas_height, | ||||||
|  |                      "Canvas height mismatch") && ok; | ||||||
|  |   ok = CompareValues(img1->num_frames, img2->num_frames, | ||||||
|  |                      "Frame count mismatch") && ok; | ||||||
|  |   if (!ok) return 0;  // These are fatal failures, can't proceed. | ||||||
|  |  | ||||||
|  |   if (is_multi_frame_image) {  // Checks relevant for multi-frame images only. | ||||||
|  |     int max_loop_count_workaround = 0; | ||||||
|  |     // Transcodes to webp increase the gif loop count by 1 for compatibility. | ||||||
|  |     // When the gif has the maximum value the webp value will be off by one. | ||||||
|  |     if ((img1->format == ANIM_GIF && img1->loop_count == 65536 && | ||||||
|  |          img2->format == ANIM_WEBP && img2->loop_count == 65535) || | ||||||
|  |         (img1->format == ANIM_WEBP && img1->loop_count == 65535 && | ||||||
|  |          img2->format == ANIM_GIF && img2->loop_count == 65536)) { | ||||||
|  |       max_loop_count_workaround = 1; | ||||||
|  |     } | ||||||
|  |     ok = (max_loop_count_workaround || | ||||||
|  |           CompareValues(img1->loop_count, img2->loop_count, | ||||||
|  |                         "Loop count mismatch")) && ok; | ||||||
|  |     ok = CompareBackgroundColor(img1->bgcolor, img2->bgcolor, | ||||||
|  |                                 premultiply) && ok; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   for (i = 0; i < img1->num_frames; ++i) { | ||||||
|  |     // Pixel-by-pixel comparison. | ||||||
|  |     const uint8_t* const rgba1 = img1->frames[i].rgba; | ||||||
|  |     const uint8_t* const rgba2 = img2->frames[i].rgba; | ||||||
|  |     int max_diff; | ||||||
|  |     double psnr; | ||||||
|  |     if (is_multi_frame_image) {  // Check relevant for multi-frame images only. | ||||||
|  |       const char format[] = "Frame #%d, duration mismatch"; | ||||||
|  |       char tmp[sizeof(format) + 8]; | ||||||
|  |       ok = ok && (snprintf(tmp, sizeof(tmp), format, i) >= 0); | ||||||
|  |       ok = ok && CompareValues(img1->frames[i].duration, | ||||||
|  |                                img2->frames[i].duration, tmp); | ||||||
|  |     } | ||||||
|  |     GetDiffAndPSNR(rgba1, rgba2, img1->canvas_width, img1->canvas_height, | ||||||
|  |                    premultiply, &max_diff, &psnr); | ||||||
|  |     if (min_psnr > 0.) { | ||||||
|  |       if (psnr < min_psnr) { | ||||||
|  |         fprintf(stderr, "Frame #%d, psnr = %.2lf (min_psnr = %f)\n", i, | ||||||
|  |                 psnr, min_psnr); | ||||||
|  |         ok = 0; | ||||||
|  |       } | ||||||
|  |     } else { | ||||||
|  |       if (max_diff != 0) { | ||||||
|  |         fprintf(stderr, "Frame #%d, max pixel diff: %d\n", i, max_diff); | ||||||
|  |         ok = 0; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   return ok; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static void Help(void) { | ||||||
|  |   printf("Usage: anim_diff <image1> <image2> [options]\n"); | ||||||
|  |   printf("\nOptions:\n"); | ||||||
|  |   printf("  -dump_frames <folder> dump decoded frames in PAM format\n"); | ||||||
|  |   printf("  -min_psnr <float> ... minimum per-frame PSNR\n"); | ||||||
|  |   printf("  -raw_comparison ..... if this flag is not used, RGB is\n"); | ||||||
|  |   printf("                        premultiplied before comparison\n"); | ||||||
|  |   printf("  -max_diff <int> ..... maximum allowed difference per channel\n" | ||||||
|  |          "                        between corresponding pixels in subsequent\n" | ||||||
|  |          "                        frames\n"); | ||||||
|  |   printf("  -h .................. this help\n"); | ||||||
|  |   printf("  -version ............ print version number and exit\n"); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int main(int argc, const char* argv[]) { | ||||||
|  |   int return_code = -1; | ||||||
|  |   int dump_frames = 0; | ||||||
|  |   const char* dump_folder = NULL; | ||||||
|  |   double min_psnr = 0.; | ||||||
|  |   int got_input1 = 0; | ||||||
|  |   int got_input2 = 0; | ||||||
|  |   int premultiply = 1; | ||||||
|  |   int max_diff = 0; | ||||||
|  |   int i, c; | ||||||
|  |   const char* files[2] = { NULL, NULL }; | ||||||
|  |   AnimatedImage images[2]; | ||||||
|  |  | ||||||
|  |   INIT_WARGV(argc, argv); | ||||||
|  |  | ||||||
|  |   for (c = 1; c < argc; ++c) { | ||||||
|  |     int parse_error = 0; | ||||||
|  |     if (!strcmp(argv[c], "-dump_frames")) { | ||||||
|  |       if (c < argc - 1) { | ||||||
|  |         dump_frames = 1; | ||||||
|  |         dump_folder = (const char*)GET_WARGV(argv, ++c); | ||||||
|  |       } else { | ||||||
|  |         parse_error = 1; | ||||||
|  |       } | ||||||
|  |     } else if (!strcmp(argv[c], "-min_psnr")) { | ||||||
|  |       if (c < argc - 1) { | ||||||
|  |         min_psnr = ExUtilGetFloat(argv[++c], &parse_error); | ||||||
|  |       } else { | ||||||
|  |         parse_error = 1; | ||||||
|  |       } | ||||||
|  |     } else if (!strcmp(argv[c], "-raw_comparison")) { | ||||||
|  |       premultiply = 0; | ||||||
|  |     } else if (!strcmp(argv[c], "-max_diff")) { | ||||||
|  |       if (c < argc - 1) { | ||||||
|  |         max_diff = ExUtilGetInt(argv[++c], 0, &parse_error); | ||||||
|  |       } else { | ||||||
|  |         parse_error = 1; | ||||||
|  |       } | ||||||
|  |     } else if (!strcmp(argv[c], "-h") || !strcmp(argv[c], "-help")) { | ||||||
|  |       Help(); | ||||||
|  |       FREE_WARGV_AND_RETURN(0); | ||||||
|  |     } else if (!strcmp(argv[c], "-version")) { | ||||||
|  |       int dec_version, demux_version; | ||||||
|  |       GetAnimatedImageVersions(&dec_version, &demux_version); | ||||||
|  |       printf("WebP Decoder version: %d.%d.%d\nWebP Demux version: %d.%d.%d\n", | ||||||
|  |              (dec_version >> 16) & 0xff, (dec_version >> 8) & 0xff, | ||||||
|  |              (dec_version >> 0) & 0xff, | ||||||
|  |              (demux_version >> 16) & 0xff, (demux_version >> 8) & 0xff, | ||||||
|  |              (demux_version >> 0) & 0xff); | ||||||
|  |       FREE_WARGV_AND_RETURN(0); | ||||||
|  |     } else { | ||||||
|  |       if (!got_input1) { | ||||||
|  |         files[0] = (const char*)GET_WARGV(argv, c); | ||||||
|  |         got_input1 = 1; | ||||||
|  |       } else if (!got_input2) { | ||||||
|  |         files[1] = (const char*)GET_WARGV(argv, c); | ||||||
|  |         got_input2 = 1; | ||||||
|  |       } else { | ||||||
|  |         parse_error = 1; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |     if (parse_error) { | ||||||
|  |       Help(); | ||||||
|  |       FREE_WARGV_AND_RETURN(-1); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   if (argc < 3) { | ||||||
|  |     Help(); | ||||||
|  |     FREE_WARGV_AND_RETURN(-1); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |   if (!got_input2) { | ||||||
|  |     Help(); | ||||||
|  |     FREE_WARGV_AND_RETURN(-1); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   if (dump_frames) { | ||||||
|  |     WPRINTF("Dumping decoded frames in: %s\n", (const W_CHAR*)dump_folder); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   memset(images, 0, sizeof(images)); | ||||||
|  |   for (i = 0; i < 2; ++i) { | ||||||
|  |     WPRINTF("Decoding file: %s\n", (const W_CHAR*)files[i]); | ||||||
|  |     if (!ReadAnimatedImage(files[i], &images[i], dump_frames, dump_folder)) { | ||||||
|  |       WFPRINTF(stderr, "Error decoding file: %s\n Aborting.\n", | ||||||
|  |                (const W_CHAR*)files[i]); | ||||||
|  |       return_code = -2; | ||||||
|  |       goto End; | ||||||
|  |     } else { | ||||||
|  |       MinimizeAnimationFrames(&images[i], max_diff); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   if (!CompareAnimatedImagePair(&images[0], &images[1], | ||||||
|  |                                 premultiply, min_psnr)) { | ||||||
|  |     WFPRINTF(stderr, "\nFiles %s and %s differ.\n", (const W_CHAR*)files[0], | ||||||
|  |              (const W_CHAR*)files[1]); | ||||||
|  |     return_code = -3; | ||||||
|  |   } else { | ||||||
|  |     WPRINTF("\nFiles %s and %s are identical.\n", (const W_CHAR*)files[0], | ||||||
|  |             (const W_CHAR*)files[1]); | ||||||
|  |     return_code = 0; | ||||||
|  |   } | ||||||
|  |  End: | ||||||
|  |   ClearAnimatedImage(&images[0]); | ||||||
|  |   ClearAnimatedImage(&images[1]); | ||||||
|  |   FREE_WARGV_AND_RETURN(return_code); | ||||||
|  | } | ||||||
							
								
								
									
										121
									
								
								external/libwebp/libwebp/examples/anim_dump.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										121
									
								
								external/libwebp/libwebp/examples/anim_dump.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,121 @@ | |||||||
|  | // Copyright 2017 Google Inc. All Rights Reserved. | ||||||
|  | // | ||||||
|  | // Use of this source code is governed by a BSD-style license | ||||||
|  | // that can be found in the COPYING file in the root of the source | ||||||
|  | // tree. An additional intellectual property rights grant can be found | ||||||
|  | // in the file PATENTS. All contributing project authors may | ||||||
|  | // be found in the AUTHORS file in the root of the source tree. | ||||||
|  | // ----------------------------------------------------------------------------- | ||||||
|  | // | ||||||
|  | // Decodes an animated WebP file and dumps the decoded frames as PNG or TIFF. | ||||||
|  | // | ||||||
|  | // Author: Skal (pascal.massimino@gmail.com) | ||||||
|  |  | ||||||
|  | #include <stdio.h> | ||||||
|  | #include <string.h>  // for 'strcmp'. | ||||||
|  |  | ||||||
|  | #include "./anim_util.h" | ||||||
|  | #include "webp/decode.h" | ||||||
|  | #include "../imageio/image_enc.h" | ||||||
|  | #include "./unicode.h" | ||||||
|  |  | ||||||
|  | #if defined(_MSC_VER) && _MSC_VER < 1900 | ||||||
|  | #define snprintf _snprintf | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | static void Help(void) { | ||||||
|  |   printf("Usage: anim_dump [options] files...\n"); | ||||||
|  |   printf("\nOptions:\n"); | ||||||
|  |   printf("  -folder <string> .... dump folder (default: '.')\n"); | ||||||
|  |   printf("  -prefix <string> .... prefix for dumped frames " | ||||||
|  |                                   "(default: 'dump_')\n"); | ||||||
|  |   printf("  -tiff ............... save frames as TIFF\n"); | ||||||
|  |   printf("  -pam ................ save frames as PAM\n"); | ||||||
|  |   printf("  -h .................. this help\n"); | ||||||
|  |   printf("  -version ............ print version number and exit\n"); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int main(int argc, const char* argv[]) { | ||||||
|  |   int error = 0; | ||||||
|  |   const W_CHAR* dump_folder = TO_W_CHAR("."); | ||||||
|  |   const W_CHAR* prefix = TO_W_CHAR("dump_"); | ||||||
|  |   const W_CHAR* suffix = TO_W_CHAR("png"); | ||||||
|  |   WebPOutputFileFormat format = PNG; | ||||||
|  |   int c; | ||||||
|  |  | ||||||
|  |   INIT_WARGV(argc, argv); | ||||||
|  |  | ||||||
|  |   if (argc < 2) { | ||||||
|  |     Help(); | ||||||
|  |     FREE_WARGV_AND_RETURN(-1); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   for (c = 1; !error && c < argc; ++c) { | ||||||
|  |     if (!strcmp(argv[c], "-folder")) { | ||||||
|  |       if (c + 1 == argc) { | ||||||
|  |         fprintf(stderr, "missing argument after option '%s'\n", argv[c]); | ||||||
|  |         error = 1; | ||||||
|  |         break; | ||||||
|  |       } | ||||||
|  |       dump_folder = GET_WARGV(argv, ++c); | ||||||
|  |     } else if (!strcmp(argv[c], "-prefix")) { | ||||||
|  |       if (c + 1 == argc) { | ||||||
|  |         fprintf(stderr, "missing argument after option '%s'\n", argv[c]); | ||||||
|  |         error = 1; | ||||||
|  |         break; | ||||||
|  |       } | ||||||
|  |       prefix = GET_WARGV(argv, ++c); | ||||||
|  |     } else if (!strcmp(argv[c], "-tiff")) { | ||||||
|  |       format = TIFF; | ||||||
|  |       suffix = TO_W_CHAR("tiff"); | ||||||
|  |     } else if (!strcmp(argv[c], "-pam")) { | ||||||
|  |       format = PAM; | ||||||
|  |       suffix = TO_W_CHAR("pam"); | ||||||
|  |     } else if (!strcmp(argv[c], "-h") || !strcmp(argv[c], "-help")) { | ||||||
|  |       Help(); | ||||||
|  |       FREE_WARGV_AND_RETURN(0); | ||||||
|  |     } else if (!strcmp(argv[c], "-version")) { | ||||||
|  |       int dec_version, demux_version; | ||||||
|  |       GetAnimatedImageVersions(&dec_version, &demux_version); | ||||||
|  |       printf("WebP Decoder version: %d.%d.%d\nWebP Demux version: %d.%d.%d\n", | ||||||
|  |              (dec_version >> 16) & 0xff, (dec_version >> 8) & 0xff, | ||||||
|  |              (dec_version >> 0) & 0xff, | ||||||
|  |              (demux_version >> 16) & 0xff, (demux_version >> 8) & 0xff, | ||||||
|  |              (demux_version >> 0) & 0xff); | ||||||
|  |       FREE_WARGV_AND_RETURN(0); | ||||||
|  |     } else { | ||||||
|  |       uint32_t i; | ||||||
|  |       AnimatedImage image; | ||||||
|  |       const W_CHAR* const file = GET_WARGV(argv, c); | ||||||
|  |       memset(&image, 0, sizeof(image)); | ||||||
|  |       WPRINTF("Decoding file: %s as %s/%sxxxx.%s\n", | ||||||
|  |               file, dump_folder, prefix, suffix); | ||||||
|  |       if (!ReadAnimatedImage((const char*)file, &image, 0, NULL)) { | ||||||
|  |         WFPRINTF(stderr, "Error decoding file: %s\n Aborting.\n", file); | ||||||
|  |         error = 1; | ||||||
|  |         break; | ||||||
|  |       } | ||||||
|  |       for (i = 0; !error && i < image.num_frames; ++i) { | ||||||
|  |         W_CHAR out_file[1024]; | ||||||
|  |         WebPDecBuffer buffer; | ||||||
|  |         WebPInitDecBuffer(&buffer); | ||||||
|  |         buffer.colorspace = MODE_RGBA; | ||||||
|  |         buffer.is_external_memory = 1; | ||||||
|  |         buffer.width = image.canvas_width; | ||||||
|  |         buffer.height = image.canvas_height; | ||||||
|  |         buffer.u.RGBA.rgba = image.frames[i].rgba; | ||||||
|  |         buffer.u.RGBA.stride = buffer.width * sizeof(uint32_t); | ||||||
|  |         buffer.u.RGBA.size = buffer.u.RGBA.stride * buffer.height; | ||||||
|  |         WSNPRINTF(out_file, sizeof(out_file), "%s/%s%.4d.%s", | ||||||
|  |                   dump_folder, prefix, i, suffix); | ||||||
|  |         if (!WebPSaveImage(&buffer, format, (const char*)out_file)) { | ||||||
|  |           WFPRINTF(stderr, "Error while saving image '%s'\n", out_file); | ||||||
|  |           error = 1; | ||||||
|  |         } | ||||||
|  |         WebPFreeDecBuffer(&buffer); | ||||||
|  |       } | ||||||
|  |       ClearAnimatedImage(&image); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   FREE_WARGV_AND_RETURN(error ? 1 : 0); | ||||||
|  | } | ||||||
							
								
								
									
										782
									
								
								external/libwebp/libwebp/examples/anim_util.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										782
									
								
								external/libwebp/libwebp/examples/anim_util.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,782 @@ | |||||||
|  | // Copyright 2015 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. | ||||||
|  | // ----------------------------------------------------------------------------- | ||||||
|  | // | ||||||
|  | // Utilities for animated images | ||||||
|  |  | ||||||
|  | #include "./anim_util.h" | ||||||
|  |  | ||||||
|  | #include <assert.h> | ||||||
|  | #include <math.h> | ||||||
|  | #include <stdio.h> | ||||||
|  | #include <string.h> | ||||||
|  |  | ||||||
|  | #if defined(WEBP_HAVE_GIF) | ||||||
|  | #include <gif_lib.h> | ||||||
|  | #endif | ||||||
|  | #include "webp/format_constants.h" | ||||||
|  | #include "webp/decode.h" | ||||||
|  | #include "webp/demux.h" | ||||||
|  | #include "../imageio/imageio_util.h" | ||||||
|  | #include "./gifdec.h" | ||||||
|  | #include "./unicode.h" | ||||||
|  | #include "./unicode_gif.h" | ||||||
|  |  | ||||||
|  | #if defined(_MSC_VER) && _MSC_VER < 1900 | ||||||
|  | #define snprintf _snprintf | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | static const int kNumChannels = 4; | ||||||
|  |  | ||||||
|  | // ----------------------------------------------------------------------------- | ||||||
|  | // Common utilities. | ||||||
|  |  | ||||||
|  | #if defined(WEBP_HAVE_GIF) | ||||||
|  | // Returns true if the frame covers the full canvas. | ||||||
|  | static int IsFullFrame(int width, int height, | ||||||
|  |                        int canvas_width, int canvas_height) { | ||||||
|  |   return (width == canvas_width && height == canvas_height); | ||||||
|  | } | ||||||
|  | #endif // WEBP_HAVE_GIF | ||||||
|  |  | ||||||
|  | static int CheckSizeForOverflow(uint64_t size) { | ||||||
|  |   return (size == (size_t)size); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static int AllocateFrames(AnimatedImage* const image, uint32_t num_frames) { | ||||||
|  |   uint32_t i; | ||||||
|  |   uint8_t* mem = NULL; | ||||||
|  |   DecodedFrame* frames = NULL; | ||||||
|  |   const uint64_t rgba_size = | ||||||
|  |       (uint64_t)image->canvas_width * kNumChannels * image->canvas_height; | ||||||
|  |   const uint64_t total_size = (uint64_t)num_frames * rgba_size * sizeof(*mem); | ||||||
|  |   const uint64_t total_frame_size = (uint64_t)num_frames * sizeof(*frames); | ||||||
|  |   if (!CheckSizeForOverflow(total_size) || | ||||||
|  |       !CheckSizeForOverflow(total_frame_size)) { | ||||||
|  |     return 0; | ||||||
|  |   } | ||||||
|  |   mem = (uint8_t*)WebPMalloc((size_t)total_size); | ||||||
|  |   frames = (DecodedFrame*)WebPMalloc((size_t)total_frame_size); | ||||||
|  |  | ||||||
|  |   if (mem == NULL || frames == NULL) { | ||||||
|  |     WebPFree(mem); | ||||||
|  |     WebPFree(frames); | ||||||
|  |     return 0; | ||||||
|  |   } | ||||||
|  |   WebPFree(image->raw_mem); | ||||||
|  |   image->num_frames = num_frames; | ||||||
|  |   image->frames = frames; | ||||||
|  |   for (i = 0; i < num_frames; ++i) { | ||||||
|  |     frames[i].rgba = mem + i * rgba_size; | ||||||
|  |     frames[i].duration = 0; | ||||||
|  |     frames[i].is_key_frame = 0; | ||||||
|  |   } | ||||||
|  |   image->raw_mem = mem; | ||||||
|  |   return 1; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void ClearAnimatedImage(AnimatedImage* const image) { | ||||||
|  |   if (image != NULL) { | ||||||
|  |     WebPFree(image->raw_mem); | ||||||
|  |     WebPFree(image->frames); | ||||||
|  |     image->num_frames = 0; | ||||||
|  |     image->frames = NULL; | ||||||
|  |     image->raw_mem = NULL; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #if defined(WEBP_HAVE_GIF) | ||||||
|  | // Clear the canvas to transparent. | ||||||
|  | static void ZeroFillCanvas(uint8_t* rgba, | ||||||
|  |                            uint32_t canvas_width, uint32_t canvas_height) { | ||||||
|  |   memset(rgba, 0, canvas_width * kNumChannels * canvas_height); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Clear given frame rectangle to transparent. | ||||||
|  | static void ZeroFillFrameRect(uint8_t* rgba, int rgba_stride, int x_offset, | ||||||
|  |                               int y_offset, int width, int height) { | ||||||
|  |   int j; | ||||||
|  |   assert(width * kNumChannels <= rgba_stride); | ||||||
|  |   rgba += y_offset * rgba_stride + x_offset * kNumChannels; | ||||||
|  |   for (j = 0; j < height; ++j) { | ||||||
|  |     memset(rgba, 0, width * kNumChannels); | ||||||
|  |     rgba += rgba_stride; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Copy width * height pixels from 'src' to 'dst'. | ||||||
|  | static void CopyCanvas(const uint8_t* src, uint8_t* dst, | ||||||
|  |                        uint32_t width, uint32_t height) { | ||||||
|  |   assert(src != NULL && dst != NULL); | ||||||
|  |   memcpy(dst, src, width * kNumChannels * height); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Copy pixels in the given rectangle from 'src' to 'dst' honoring the 'stride'. | ||||||
|  | static void CopyFrameRectangle(const uint8_t* src, uint8_t* dst, int stride, | ||||||
|  |                                int x_offset, int y_offset, | ||||||
|  |                                int width, int height) { | ||||||
|  |   int j; | ||||||
|  |   const int width_in_bytes = width * kNumChannels; | ||||||
|  |   const size_t offset = y_offset * stride + x_offset * kNumChannels; | ||||||
|  |   assert(width_in_bytes <= stride); | ||||||
|  |   src += offset; | ||||||
|  |   dst += offset; | ||||||
|  |   for (j = 0; j < height; ++j) { | ||||||
|  |     memcpy(dst, src, width_in_bytes); | ||||||
|  |     src += stride; | ||||||
|  |     dst += stride; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | #endif // WEBP_HAVE_GIF | ||||||
|  |  | ||||||
|  | // Canonicalize all transparent pixels to transparent black to aid comparison. | ||||||
|  | static void CleanupTransparentPixels(uint32_t* rgba, | ||||||
|  |                                      uint32_t width, uint32_t height) { | ||||||
|  |   const uint32_t* const rgba_end = rgba + width * height; | ||||||
|  |   while (rgba < rgba_end) { | ||||||
|  |     const uint8_t alpha = (*rgba >> 24) & 0xff; | ||||||
|  |     if (alpha == 0) { | ||||||
|  |       *rgba = 0; | ||||||
|  |     } | ||||||
|  |     ++rgba; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Dump frame to a PAM file. Returns true on success. | ||||||
|  | static int DumpFrame(const char filename[], const char dump_folder[], | ||||||
|  |                      uint32_t frame_num, const uint8_t rgba[], | ||||||
|  |                      int canvas_width, int canvas_height) { | ||||||
|  |   int ok = 0; | ||||||
|  |   size_t max_len; | ||||||
|  |   int y; | ||||||
|  |   const W_CHAR* base_name = NULL; | ||||||
|  |   W_CHAR* file_name = NULL; | ||||||
|  |   FILE* f = NULL; | ||||||
|  |   const char* row; | ||||||
|  |  | ||||||
|  |   if (dump_folder == NULL) dump_folder = (const char*)TO_W_CHAR("."); | ||||||
|  |  | ||||||
|  |   base_name = WSTRRCHR(filename, '/'); | ||||||
|  |   base_name = (base_name == NULL) ? (const W_CHAR*)filename : base_name + 1; | ||||||
|  |   max_len = WSTRLEN(dump_folder) + 1 + WSTRLEN(base_name) | ||||||
|  |           + strlen("_frame_") + strlen(".pam") + 8; | ||||||
|  |   file_name = (W_CHAR*)WebPMalloc(max_len * sizeof(*file_name)); | ||||||
|  |   if (file_name == NULL) goto End; | ||||||
|  |  | ||||||
|  |   if (WSNPRINTF(file_name, max_len, "%s/%s_frame_%d.pam", | ||||||
|  |                 (const W_CHAR*)dump_folder, base_name, frame_num) < 0) { | ||||||
|  |     fprintf(stderr, "Error while generating file name\n"); | ||||||
|  |     goto End; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   f = WFOPEN(file_name, "wb"); | ||||||
|  |   if (f == NULL) { | ||||||
|  |     WFPRINTF(stderr, "Error opening file for writing: %s\n", file_name); | ||||||
|  |     ok = 0; | ||||||
|  |     goto End; | ||||||
|  |   } | ||||||
|  |   if (fprintf(f, "P7\nWIDTH %d\nHEIGHT %d\n" | ||||||
|  |               "DEPTH 4\nMAXVAL 255\nTUPLTYPE RGB_ALPHA\nENDHDR\n", | ||||||
|  |               canvas_width, canvas_height) < 0) { | ||||||
|  |     WFPRINTF(stderr, "Write error for file %s\n", file_name); | ||||||
|  |     goto End; | ||||||
|  |   } | ||||||
|  |   row = (const char*)rgba; | ||||||
|  |   for (y = 0; y < canvas_height; ++y) { | ||||||
|  |     if (fwrite(row, canvas_width * kNumChannels, 1, f) != 1) { | ||||||
|  |       WFPRINTF(stderr, "Error writing to file: %s\n", file_name); | ||||||
|  |       goto End; | ||||||
|  |     } | ||||||
|  |     row += canvas_width * kNumChannels; | ||||||
|  |   } | ||||||
|  |   ok = 1; | ||||||
|  |  End: | ||||||
|  |   if (f != NULL) fclose(f); | ||||||
|  |   WebPFree(file_name); | ||||||
|  |   return ok; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // ----------------------------------------------------------------------------- | ||||||
|  | // WebP Decoding. | ||||||
|  |  | ||||||
|  | // Returns true if this is a valid WebP bitstream. | ||||||
|  | static int IsWebP(const WebPData* const webp_data) { | ||||||
|  |   return (WebPGetInfo(webp_data->bytes, webp_data->size, NULL, NULL) != 0); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Read animated WebP bitstream 'webp_data' into 'AnimatedImage' struct. | ||||||
|  | static int ReadAnimatedWebP(const char filename[], | ||||||
|  |                             const WebPData* const webp_data, | ||||||
|  |                             AnimatedImage* const image, int dump_frames, | ||||||
|  |                             const char dump_folder[]) { | ||||||
|  |   int ok = 0; | ||||||
|  |   int dump_ok = 1; | ||||||
|  |   uint32_t frame_index = 0; | ||||||
|  |   int prev_frame_timestamp = 0; | ||||||
|  |   WebPAnimDecoder* dec; | ||||||
|  |   WebPAnimInfo anim_info; | ||||||
|  |  | ||||||
|  |   memset(image, 0, sizeof(*image)); | ||||||
|  |  | ||||||
|  |   dec = WebPAnimDecoderNew(webp_data, NULL); | ||||||
|  |   if (dec == NULL) { | ||||||
|  |     WFPRINTF(stderr, "Error parsing image: %s\n", (const W_CHAR*)filename); | ||||||
|  |     goto End; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   if (!WebPAnimDecoderGetInfo(dec, &anim_info)) { | ||||||
|  |     fprintf(stderr, "Error getting global info about the animation\n"); | ||||||
|  |     goto End; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   // Animation properties. | ||||||
|  |   image->canvas_width = anim_info.canvas_width; | ||||||
|  |   image->canvas_height = anim_info.canvas_height; | ||||||
|  |   image->loop_count = anim_info.loop_count; | ||||||
|  |   image->bgcolor = anim_info.bgcolor; | ||||||
|  |  | ||||||
|  |   // Allocate frames. | ||||||
|  |   if (!AllocateFrames(image, anim_info.frame_count)) goto End; | ||||||
|  |  | ||||||
|  |   // Decode frames. | ||||||
|  |   while (WebPAnimDecoderHasMoreFrames(dec)) { | ||||||
|  |     DecodedFrame* curr_frame; | ||||||
|  |     uint8_t* curr_rgba; | ||||||
|  |     uint8_t* frame_rgba; | ||||||
|  |     int timestamp; | ||||||
|  |  | ||||||
|  |     if (!WebPAnimDecoderGetNext(dec, &frame_rgba, ×tamp)) { | ||||||
|  |       fprintf(stderr, "Error decoding frame #%u\n", frame_index); | ||||||
|  |       goto End; | ||||||
|  |     } | ||||||
|  |     assert(frame_index < anim_info.frame_count); | ||||||
|  |     curr_frame = &image->frames[frame_index]; | ||||||
|  |     curr_rgba = curr_frame->rgba; | ||||||
|  |     curr_frame->duration = timestamp - prev_frame_timestamp; | ||||||
|  |     curr_frame->is_key_frame = 0;  // Unused. | ||||||
|  |     memcpy(curr_rgba, frame_rgba, | ||||||
|  |            image->canvas_width * kNumChannels * image->canvas_height); | ||||||
|  |  | ||||||
|  |     // Needed only because we may want to compare with GIF later. | ||||||
|  |     CleanupTransparentPixels((uint32_t*)curr_rgba, | ||||||
|  |                              image->canvas_width, image->canvas_height); | ||||||
|  |  | ||||||
|  |     if (dump_frames && dump_ok) { | ||||||
|  |       dump_ok = DumpFrame(filename, dump_folder, frame_index, curr_rgba, | ||||||
|  |                           image->canvas_width, image->canvas_height); | ||||||
|  |       if (!dump_ok) {  // Print error once, but continue decode loop. | ||||||
|  |         fprintf(stderr, "Error dumping frames to %s\n", dump_folder); | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     ++frame_index; | ||||||
|  |     prev_frame_timestamp = timestamp; | ||||||
|  |   } | ||||||
|  |   ok = dump_ok; | ||||||
|  |   if (ok) image->format = ANIM_WEBP; | ||||||
|  |  | ||||||
|  |  End: | ||||||
|  |   WebPAnimDecoderDelete(dec); | ||||||
|  |   return ok; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // ----------------------------------------------------------------------------- | ||||||
|  | // GIF Decoding. | ||||||
|  |  | ||||||
|  | #if defined(WEBP_HAVE_GIF) | ||||||
|  |  | ||||||
|  | // Returns true if this is a valid GIF bitstream. | ||||||
|  | static int IsGIF(const WebPData* const data) { | ||||||
|  |   return data->size > GIF_STAMP_LEN && | ||||||
|  |          (!memcmp(GIF_STAMP, data->bytes, GIF_STAMP_LEN) || | ||||||
|  |           !memcmp(GIF87_STAMP, data->bytes, GIF_STAMP_LEN) || | ||||||
|  |           !memcmp(GIF89_STAMP, data->bytes, GIF_STAMP_LEN)); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // GIFLIB_MAJOR is only defined in libgif >= 4.2.0. | ||||||
|  | #if defined(GIFLIB_MAJOR) && defined(GIFLIB_MINOR) | ||||||
|  | # define LOCAL_GIF_VERSION ((GIFLIB_MAJOR << 8) | GIFLIB_MINOR) | ||||||
|  | # define LOCAL_GIF_PREREQ(maj, min) \ | ||||||
|  |     (LOCAL_GIF_VERSION >= (((maj) << 8) | (min))) | ||||||
|  | #else | ||||||
|  | # define LOCAL_GIF_VERSION 0 | ||||||
|  | # define LOCAL_GIF_PREREQ(maj, min) 0 | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | #if !LOCAL_GIF_PREREQ(5, 0) | ||||||
|  |  | ||||||
|  | // Added in v5.0 | ||||||
|  | typedef struct { | ||||||
|  |   int DisposalMode; | ||||||
|  | #define DISPOSAL_UNSPECIFIED      0       // No disposal specified | ||||||
|  | #define DISPOSE_DO_NOT            1       // Leave image in place | ||||||
|  | #define DISPOSE_BACKGROUND        2       // Set area to background color | ||||||
|  | #define DISPOSE_PREVIOUS          3       // Restore to previous content | ||||||
|  |   int UserInputFlag;       // User confirmation required before disposal | ||||||
|  |   int DelayTime;           // Pre-display delay in 0.01sec units | ||||||
|  |   int TransparentColor;    // Palette index for transparency, -1 if none | ||||||
|  | #define NO_TRANSPARENT_COLOR     -1 | ||||||
|  | } GraphicsControlBlock; | ||||||
|  |  | ||||||
|  | static int DGifExtensionToGCB(const size_t GifExtensionLength, | ||||||
|  |                               const GifByteType* GifExtension, | ||||||
|  |                               GraphicsControlBlock* gcb) { | ||||||
|  |   if (GifExtensionLength != 4) { | ||||||
|  |     return GIF_ERROR; | ||||||
|  |   } | ||||||
|  |   gcb->DisposalMode = (GifExtension[0] >> 2) & 0x07; | ||||||
|  |   gcb->UserInputFlag = (GifExtension[0] & 0x02) != 0; | ||||||
|  |   gcb->DelayTime = GifExtension[1] | (GifExtension[2] << 8); | ||||||
|  |   if (GifExtension[0] & 0x01) { | ||||||
|  |     gcb->TransparentColor = (int)GifExtension[3]; | ||||||
|  |   } else { | ||||||
|  |     gcb->TransparentColor = NO_TRANSPARENT_COLOR; | ||||||
|  |   } | ||||||
|  |   return GIF_OK; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static int DGifSavedExtensionToGCB(GifFileType* GifFile, int ImageIndex, | ||||||
|  |                                    GraphicsControlBlock* gcb) { | ||||||
|  |   int i; | ||||||
|  |   if (ImageIndex < 0 || ImageIndex > GifFile->ImageCount - 1) { | ||||||
|  |     return GIF_ERROR; | ||||||
|  |   } | ||||||
|  |   gcb->DisposalMode = DISPOSAL_UNSPECIFIED; | ||||||
|  |   gcb->UserInputFlag = 0; | ||||||
|  |   gcb->DelayTime = 0; | ||||||
|  |   gcb->TransparentColor = NO_TRANSPARENT_COLOR; | ||||||
|  |  | ||||||
|  |   for (i = 0; i < GifFile->SavedImages[ImageIndex].ExtensionBlockCount; i++) { | ||||||
|  |     ExtensionBlock* ep = &GifFile->SavedImages[ImageIndex].ExtensionBlocks[i]; | ||||||
|  |     if (ep->Function == GRAPHICS_EXT_FUNC_CODE) { | ||||||
|  |       return DGifExtensionToGCB( | ||||||
|  |           ep->ByteCount, (const GifByteType*)ep->Bytes, gcb); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   return GIF_ERROR; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #define CONTINUE_EXT_FUNC_CODE 0x00 | ||||||
|  |  | ||||||
|  | // Signature was changed in v5.0 | ||||||
|  | #define DGifOpenFileName(a, b) DGifOpenFileName(a) | ||||||
|  |  | ||||||
|  | #endif  // !LOCAL_GIF_PREREQ(5, 0) | ||||||
|  |  | ||||||
|  | // Signature changed in v5.1 | ||||||
|  | #if !LOCAL_GIF_PREREQ(5, 1) | ||||||
|  | #define DGifCloseFile(a, b) DGifCloseFile(a) | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | static int IsKeyFrameGIF(const GifImageDesc* prev_desc, int prev_dispose, | ||||||
|  |                          const DecodedFrame* const prev_frame, | ||||||
|  |                          int canvas_width, int canvas_height) { | ||||||
|  |   if (prev_frame == NULL) return 1; | ||||||
|  |   if (prev_dispose == DISPOSE_BACKGROUND) { | ||||||
|  |     if (IsFullFrame(prev_desc->Width, prev_desc->Height, | ||||||
|  |                     canvas_width, canvas_height)) { | ||||||
|  |       return 1; | ||||||
|  |     } | ||||||
|  |     if (prev_frame->is_key_frame) return 1; | ||||||
|  |   } | ||||||
|  |   return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static int GetTransparentIndexGIF(GifFileType* gif) { | ||||||
|  |   GraphicsControlBlock first_gcb; | ||||||
|  |   memset(&first_gcb, 0, sizeof(first_gcb)); | ||||||
|  |   DGifSavedExtensionToGCB(gif, 0, &first_gcb); | ||||||
|  |   return first_gcb.TransparentColor; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static uint32_t GetBackgroundColorGIF(GifFileType* gif) { | ||||||
|  |   const int transparent_index = GetTransparentIndexGIF(gif); | ||||||
|  |   const ColorMapObject* const color_map = gif->SColorMap; | ||||||
|  |   if (transparent_index != NO_TRANSPARENT_COLOR && | ||||||
|  |       gif->SBackGroundColor == transparent_index) { | ||||||
|  |     return 0x00000000;  // Special case: transparent black. | ||||||
|  |   } else if (color_map == NULL || color_map->Colors == NULL | ||||||
|  |              || gif->SBackGroundColor >= color_map->ColorCount) { | ||||||
|  |     return 0xffffffff;  // Invalid: assume white. | ||||||
|  |   } else { | ||||||
|  |     const GifColorType color = color_map->Colors[gif->SBackGroundColor]; | ||||||
|  |     return (0xffu << 24) | | ||||||
|  |            (color.Red << 16) | | ||||||
|  |            (color.Green << 8) | | ||||||
|  |            (color.Blue << 0); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Find appropriate app extension and get loop count from the next extension. | ||||||
|  | // We use Chrome's interpretation of the 'loop_count' semantics: | ||||||
|  | //   if not present -> loop once | ||||||
|  | //   if present and loop_count == 0, return 0 ('infinite'). | ||||||
|  | //   if present and loop_count != 0, it's the number of *extra* loops | ||||||
|  | //     so we need to return loop_count + 1 as total loop number. | ||||||
|  | static uint32_t GetLoopCountGIF(const GifFileType* const gif) { | ||||||
|  |   int i; | ||||||
|  |   for (i = 0; i < gif->ImageCount; ++i) { | ||||||
|  |     const SavedImage* const image = &gif->SavedImages[i]; | ||||||
|  |     int j; | ||||||
|  |     for (j = 0; (j + 1) < image->ExtensionBlockCount; ++j) { | ||||||
|  |       const ExtensionBlock* const eb1 = image->ExtensionBlocks + j; | ||||||
|  |       const ExtensionBlock* const eb2 = image->ExtensionBlocks + j + 1; | ||||||
|  |       const char* const signature = (const char*)eb1->Bytes; | ||||||
|  |       const int signature_is_ok = | ||||||
|  |           (eb1->Function == APPLICATION_EXT_FUNC_CODE) && | ||||||
|  |           (eb1->ByteCount == 11) && | ||||||
|  |           (!memcmp(signature, "NETSCAPE2.0", 11) || | ||||||
|  |            !memcmp(signature, "ANIMEXTS1.0", 11)); | ||||||
|  |       if (signature_is_ok && | ||||||
|  |           eb2->Function == CONTINUE_EXT_FUNC_CODE && eb2->ByteCount >= 3 && | ||||||
|  |           eb2->Bytes[0] == 1) { | ||||||
|  |         const uint32_t extra_loop = ((uint32_t)(eb2->Bytes[2]) << 8) + | ||||||
|  |                                     ((uint32_t)(eb2->Bytes[1]) << 0); | ||||||
|  |         return (extra_loop > 0) ? extra_loop + 1 : 0; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   return 1;  // Default. | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Get duration of 'n'th frame in milliseconds. | ||||||
|  | static int GetFrameDurationGIF(GifFileType* gif, int n) { | ||||||
|  |   GraphicsControlBlock gcb; | ||||||
|  |   memset(&gcb, 0, sizeof(gcb)); | ||||||
|  |   DGifSavedExtensionToGCB(gif, n, &gcb); | ||||||
|  |   return gcb.DelayTime * 10; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Returns true if frame 'target' completely covers 'covered'. | ||||||
|  | static int CoversFrameGIF(const GifImageDesc* const target, | ||||||
|  |                           const GifImageDesc* const covered) { | ||||||
|  |   return target->Left <= covered->Left && | ||||||
|  |          covered->Left + covered->Width <= target->Left + target->Width && | ||||||
|  |          target->Top <= covered->Top && | ||||||
|  |          covered->Top + covered->Height <= target->Top + target->Height; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static void RemapPixelsGIF(const uint8_t* const src, | ||||||
|  |                            const ColorMapObject* const cmap, | ||||||
|  |                            int transparent_color, int len, uint8_t* dst) { | ||||||
|  |   int i; | ||||||
|  |   for (i = 0; i < len; ++i) { | ||||||
|  |     if (src[i] != transparent_color) { | ||||||
|  |       // If a pixel in the current frame is transparent, we don't modify it, so | ||||||
|  |       // that we can see-through the corresponding pixel from an earlier frame. | ||||||
|  |       const GifColorType c = cmap->Colors[src[i]]; | ||||||
|  |       dst[4 * i + 0] = c.Red; | ||||||
|  |       dst[4 * i + 1] = c.Green; | ||||||
|  |       dst[4 * i + 2] = c.Blue; | ||||||
|  |       dst[4 * i + 3] = 0xff; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static int ReadFrameGIF(const SavedImage* const gif_image, | ||||||
|  |                         const ColorMapObject* cmap, int transparent_color, | ||||||
|  |                         int out_stride, uint8_t* const dst) { | ||||||
|  |   const GifImageDesc* image_desc = &gif_image->ImageDesc; | ||||||
|  |   const uint8_t* in; | ||||||
|  |   uint8_t* out; | ||||||
|  |   int j; | ||||||
|  |  | ||||||
|  |   if (image_desc->ColorMap) cmap = image_desc->ColorMap; | ||||||
|  |  | ||||||
|  |   if (cmap == NULL || cmap->ColorCount != (1 << cmap->BitsPerPixel)) { | ||||||
|  |     fprintf(stderr, "Potentially corrupt color map.\n"); | ||||||
|  |     return 0; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   in = (const uint8_t*)gif_image->RasterBits; | ||||||
|  |   out = dst + image_desc->Top * out_stride + image_desc->Left * kNumChannels; | ||||||
|  |  | ||||||
|  |   for (j = 0; j < image_desc->Height; ++j) { | ||||||
|  |     RemapPixelsGIF(in, cmap, transparent_color, image_desc->Width, out); | ||||||
|  |     in += image_desc->Width; | ||||||
|  |     out += out_stride; | ||||||
|  |   } | ||||||
|  |   return 1; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Read animated GIF bitstream from 'filename' into 'AnimatedImage' struct. | ||||||
|  | static int ReadAnimatedGIF(const char filename[], AnimatedImage* const image, | ||||||
|  |                            int dump_frames, const char dump_folder[]) { | ||||||
|  |   uint32_t frame_count; | ||||||
|  |   uint32_t canvas_width, canvas_height; | ||||||
|  |   uint32_t i; | ||||||
|  |   int gif_error; | ||||||
|  |   GifFileType* gif; | ||||||
|  |  | ||||||
|  |   gif = DGifOpenFileUnicode((const W_CHAR*)filename, NULL); | ||||||
|  |   if (gif == NULL) { | ||||||
|  |     WFPRINTF(stderr, "Could not read file: %s.\n", (const W_CHAR*)filename); | ||||||
|  |     return 0; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   gif_error = DGifSlurp(gif); | ||||||
|  |   if (gif_error != GIF_OK) { | ||||||
|  |     WFPRINTF(stderr, "Could not parse image: %s.\n", (const W_CHAR*)filename); | ||||||
|  |     GIFDisplayError(gif, gif_error); | ||||||
|  |     DGifCloseFile(gif, NULL); | ||||||
|  |     return 0; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   // Animation properties. | ||||||
|  |   image->canvas_width = (uint32_t)gif->SWidth; | ||||||
|  |   image->canvas_height = (uint32_t)gif->SHeight; | ||||||
|  |   if (image->canvas_width > MAX_CANVAS_SIZE || | ||||||
|  |       image->canvas_height > MAX_CANVAS_SIZE) { | ||||||
|  |     fprintf(stderr, "Invalid canvas dimension: %d x %d\n", | ||||||
|  |             image->canvas_width, image->canvas_height); | ||||||
|  |     DGifCloseFile(gif, NULL); | ||||||
|  |     return 0; | ||||||
|  |   } | ||||||
|  |   image->loop_count = GetLoopCountGIF(gif); | ||||||
|  |   image->bgcolor = GetBackgroundColorGIF(gif); | ||||||
|  |  | ||||||
|  |   frame_count = (uint32_t)gif->ImageCount; | ||||||
|  |   if (frame_count == 0) { | ||||||
|  |     DGifCloseFile(gif, NULL); | ||||||
|  |     return 0; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   if (image->canvas_width == 0 || image->canvas_height == 0) { | ||||||
|  |     image->canvas_width = gif->SavedImages[0].ImageDesc.Width; | ||||||
|  |     image->canvas_height = gif->SavedImages[0].ImageDesc.Height; | ||||||
|  |     gif->SavedImages[0].ImageDesc.Left = 0; | ||||||
|  |     gif->SavedImages[0].ImageDesc.Top = 0; | ||||||
|  |     if (image->canvas_width == 0 || image->canvas_height == 0) { | ||||||
|  |       fprintf(stderr, "Invalid canvas size in GIF.\n"); | ||||||
|  |       DGifCloseFile(gif, NULL); | ||||||
|  |       return 0; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   // Allocate frames. | ||||||
|  |   if (!AllocateFrames(image, frame_count)) { | ||||||
|  |     DGifCloseFile(gif, NULL); | ||||||
|  |     return 0; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   canvas_width = image->canvas_width; | ||||||
|  |   canvas_height = image->canvas_height; | ||||||
|  |  | ||||||
|  |   // Decode and reconstruct frames. | ||||||
|  |   for (i = 0; i < frame_count; ++i) { | ||||||
|  |     const int canvas_width_in_bytes = canvas_width * kNumChannels; | ||||||
|  |     const SavedImage* const curr_gif_image = &gif->SavedImages[i]; | ||||||
|  |     GraphicsControlBlock curr_gcb; | ||||||
|  |     DecodedFrame* curr_frame; | ||||||
|  |     uint8_t* curr_rgba; | ||||||
|  |  | ||||||
|  |     memset(&curr_gcb, 0, sizeof(curr_gcb)); | ||||||
|  |     DGifSavedExtensionToGCB(gif, i, &curr_gcb); | ||||||
|  |  | ||||||
|  |     curr_frame = &image->frames[i]; | ||||||
|  |     curr_rgba = curr_frame->rgba; | ||||||
|  |     curr_frame->duration = GetFrameDurationGIF(gif, i); | ||||||
|  |     // Force frames with a small or no duration to 100ms to be consistent | ||||||
|  |     // with web browsers and other transcoding tools (like gif2webp itself). | ||||||
|  |     if (curr_frame->duration <= 10) curr_frame->duration = 100; | ||||||
|  |  | ||||||
|  |     if (i == 0) {  // Initialize as transparent. | ||||||
|  |       curr_frame->is_key_frame = 1; | ||||||
|  |       ZeroFillCanvas(curr_rgba, canvas_width, canvas_height); | ||||||
|  |     } else { | ||||||
|  |       DecodedFrame* const prev_frame = &image->frames[i - 1]; | ||||||
|  |       const GifImageDesc* const prev_desc = &gif->SavedImages[i - 1].ImageDesc; | ||||||
|  |       GraphicsControlBlock prev_gcb; | ||||||
|  |       memset(&prev_gcb, 0, sizeof(prev_gcb)); | ||||||
|  |       DGifSavedExtensionToGCB(gif, i - 1, &prev_gcb); | ||||||
|  |  | ||||||
|  |       curr_frame->is_key_frame = | ||||||
|  |           IsKeyFrameGIF(prev_desc, prev_gcb.DisposalMode, prev_frame, | ||||||
|  |                         canvas_width, canvas_height); | ||||||
|  |  | ||||||
|  |       if (curr_frame->is_key_frame) {  // Initialize as transparent. | ||||||
|  |         ZeroFillCanvas(curr_rgba, canvas_width, canvas_height); | ||||||
|  |       } else { | ||||||
|  |         int prev_frame_disposed, curr_frame_opaque; | ||||||
|  |         int prev_frame_completely_covered; | ||||||
|  |         // Initialize with previous canvas. | ||||||
|  |         uint8_t* const prev_rgba = image->frames[i - 1].rgba; | ||||||
|  |         CopyCanvas(prev_rgba, curr_rgba, canvas_width, canvas_height); | ||||||
|  |  | ||||||
|  |         // Dispose previous frame rectangle. | ||||||
|  |         prev_frame_disposed = | ||||||
|  |             (prev_gcb.DisposalMode == DISPOSE_BACKGROUND || | ||||||
|  |              prev_gcb.DisposalMode == DISPOSE_PREVIOUS); | ||||||
|  |         curr_frame_opaque = | ||||||
|  |             (curr_gcb.TransparentColor == NO_TRANSPARENT_COLOR); | ||||||
|  |         prev_frame_completely_covered = | ||||||
|  |             curr_frame_opaque && | ||||||
|  |             CoversFrameGIF(&curr_gif_image->ImageDesc, prev_desc); | ||||||
|  |  | ||||||
|  |         if (prev_frame_disposed && !prev_frame_completely_covered) { | ||||||
|  |           switch (prev_gcb.DisposalMode) { | ||||||
|  |             case DISPOSE_BACKGROUND: { | ||||||
|  |               ZeroFillFrameRect(curr_rgba, canvas_width_in_bytes, | ||||||
|  |                                 prev_desc->Left, prev_desc->Top, | ||||||
|  |                                 prev_desc->Width, prev_desc->Height); | ||||||
|  |               break; | ||||||
|  |             } | ||||||
|  |             case DISPOSE_PREVIOUS: { | ||||||
|  |               int src_frame_num = i - 2; | ||||||
|  |               while (src_frame_num >= 0) { | ||||||
|  |                 GraphicsControlBlock src_frame_gcb; | ||||||
|  |                 memset(&src_frame_gcb, 0, sizeof(src_frame_gcb)); | ||||||
|  |                 DGifSavedExtensionToGCB(gif, src_frame_num, &src_frame_gcb); | ||||||
|  |                 if (src_frame_gcb.DisposalMode != DISPOSE_PREVIOUS) break; | ||||||
|  |                 --src_frame_num; | ||||||
|  |               } | ||||||
|  |               if (src_frame_num >= 0) { | ||||||
|  |                 // Restore pixels inside previous frame rectangle to | ||||||
|  |                 // corresponding pixels in source canvas. | ||||||
|  |                 uint8_t* const src_frame_rgba = | ||||||
|  |                     image->frames[src_frame_num].rgba; | ||||||
|  |                 CopyFrameRectangle(src_frame_rgba, curr_rgba, | ||||||
|  |                                    canvas_width_in_bytes, | ||||||
|  |                                    prev_desc->Left, prev_desc->Top, | ||||||
|  |                                    prev_desc->Width, prev_desc->Height); | ||||||
|  |               } else { | ||||||
|  |                 // Source canvas doesn't exist. So clear previous frame | ||||||
|  |                 // rectangle to background. | ||||||
|  |                 ZeroFillFrameRect(curr_rgba, canvas_width_in_bytes, | ||||||
|  |                                   prev_desc->Left, prev_desc->Top, | ||||||
|  |                                   prev_desc->Width, prev_desc->Height); | ||||||
|  |               } | ||||||
|  |               break; | ||||||
|  |             } | ||||||
|  |             default: | ||||||
|  |               break;  // Nothing to do. | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // Decode current frame. | ||||||
|  |     if (!ReadFrameGIF(curr_gif_image, gif->SColorMap, curr_gcb.TransparentColor, | ||||||
|  |                       canvas_width_in_bytes, curr_rgba)) { | ||||||
|  |       DGifCloseFile(gif, NULL); | ||||||
|  |       return 0; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     if (dump_frames) { | ||||||
|  |       if (!DumpFrame(filename, dump_folder, i, curr_rgba, | ||||||
|  |                      canvas_width, canvas_height)) { | ||||||
|  |         DGifCloseFile(gif, NULL); | ||||||
|  |         return 0; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   image->format = ANIM_GIF; | ||||||
|  |   DGifCloseFile(gif, NULL); | ||||||
|  |   return 1; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #else | ||||||
|  |  | ||||||
|  | static int IsGIF(const WebPData* const data) { | ||||||
|  |   (void)data; | ||||||
|  |   return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static int ReadAnimatedGIF(const char filename[], AnimatedImage* const image, | ||||||
|  |                            int dump_frames, const char dump_folder[]) { | ||||||
|  |   (void)filename; | ||||||
|  |   (void)image; | ||||||
|  |   (void)dump_frames; | ||||||
|  |   (void)dump_folder; | ||||||
|  |   fprintf(stderr, "GIF support not compiled. Please install the libgif-dev " | ||||||
|  |           "package before building.\n"); | ||||||
|  |   return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #endif  // WEBP_HAVE_GIF | ||||||
|  |  | ||||||
|  | // ----------------------------------------------------------------------------- | ||||||
|  |  | ||||||
|  | int ReadAnimatedImage(const char filename[], AnimatedImage* const image, | ||||||
|  |                       int dump_frames, const char dump_folder[]) { | ||||||
|  |   int ok = 0; | ||||||
|  |   WebPData webp_data; | ||||||
|  |  | ||||||
|  |   WebPDataInit(&webp_data); | ||||||
|  |   memset(image, 0, sizeof(*image)); | ||||||
|  |  | ||||||
|  |   if (!ImgIoUtilReadFile(filename, &webp_data.bytes, &webp_data.size)) { | ||||||
|  |     WFPRINTF(stderr, "Error reading file: %s\n", (const W_CHAR*)filename); | ||||||
|  |     return 0; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   if (IsWebP(&webp_data)) { | ||||||
|  |     ok = ReadAnimatedWebP(filename, &webp_data, image, dump_frames, | ||||||
|  |                           dump_folder); | ||||||
|  |   } else if (IsGIF(&webp_data)) { | ||||||
|  |     ok = ReadAnimatedGIF(filename, image, dump_frames, dump_folder); | ||||||
|  |   } else { | ||||||
|  |     WFPRINTF(stderr, | ||||||
|  |              "Unknown file type: %s. Supported file types are WebP and GIF\n", | ||||||
|  |              (const W_CHAR*)filename); | ||||||
|  |     ok = 0; | ||||||
|  |   } | ||||||
|  |   if (!ok) ClearAnimatedImage(image); | ||||||
|  |   WebPDataClear(&webp_data); | ||||||
|  |   return ok; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static void Accumulate(double v1, double v2, double* const max_diff, | ||||||
|  |                        double* const sse) { | ||||||
|  |   const double diff = fabs(v1 - v2); | ||||||
|  |   if (diff > *max_diff) *max_diff = diff; | ||||||
|  |   *sse += diff * diff; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void GetDiffAndPSNR(const uint8_t rgba1[], const uint8_t rgba2[], | ||||||
|  |                     uint32_t width, uint32_t height, int premultiply, | ||||||
|  |                     int* const max_diff, double* const psnr) { | ||||||
|  |   const uint32_t stride = width * kNumChannels; | ||||||
|  |   const int kAlphaChannel = kNumChannels - 1; | ||||||
|  |   double f_max_diff = 0.; | ||||||
|  |   double sse = 0.; | ||||||
|  |   uint32_t x, y; | ||||||
|  |   for (y = 0; y < height; ++y) { | ||||||
|  |     for (x = 0; x < stride; x += kNumChannels) { | ||||||
|  |       int k; | ||||||
|  |       const size_t offset = (size_t)y * stride + x; | ||||||
|  |       const int alpha1 = rgba1[offset + kAlphaChannel]; | ||||||
|  |       const int alpha2 = rgba2[offset + kAlphaChannel]; | ||||||
|  |       Accumulate(alpha1, alpha2, &f_max_diff, &sse); | ||||||
|  |       if (!premultiply) { | ||||||
|  |         for (k = 0; k < kAlphaChannel; ++k) { | ||||||
|  |           Accumulate(rgba1[offset + k], rgba2[offset + k], &f_max_diff, &sse); | ||||||
|  |         } | ||||||
|  |       } else { | ||||||
|  |         // premultiply R/G/B channels with alpha value | ||||||
|  |         for (k = 0; k < kAlphaChannel; ++k) { | ||||||
|  |           Accumulate(rgba1[offset + k] * alpha1 / 255., | ||||||
|  |                      rgba2[offset + k] * alpha2 / 255., | ||||||
|  |                      &f_max_diff, &sse); | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   *max_diff = (int)f_max_diff; | ||||||
|  |   if (*max_diff == 0) { | ||||||
|  |     *psnr = 99.;  // PSNR when images are identical. | ||||||
|  |   } else { | ||||||
|  |     sse /= stride * height; | ||||||
|  |     *psnr = 4.3429448 * log(255. * 255. / sse); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void GetAnimatedImageVersions(int* const decoder_version, | ||||||
|  |                               int* const demux_version) { | ||||||
|  |   *decoder_version = WebPGetDecoderVersion(); | ||||||
|  |   *demux_version = WebPGetDemuxVersion(); | ||||||
|  | } | ||||||
							
								
								
									
										73
									
								
								external/libwebp/libwebp/examples/anim_util.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								external/libwebp/libwebp/examples/anim_util.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,73 @@ | |||||||
|  | // Copyright 2015 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. | ||||||
|  | // ----------------------------------------------------------------------------- | ||||||
|  | // | ||||||
|  | // Utilities for animated images | ||||||
|  |  | ||||||
|  | #ifndef WEBP_EXAMPLES_ANIM_UTIL_H_ | ||||||
|  | #define WEBP_EXAMPLES_ANIM_UTIL_H_ | ||||||
|  |  | ||||||
|  | #ifdef HAVE_CONFIG_H | ||||||
|  | #include "webp/config.h" | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | #include "webp/types.h" | ||||||
|  |  | ||||||
|  | #ifdef __cplusplus | ||||||
|  | extern "C" { | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | typedef enum { | ||||||
|  |   ANIM_GIF, | ||||||
|  |   ANIM_WEBP | ||||||
|  | } AnimatedFileFormat; | ||||||
|  |  | ||||||
|  | typedef struct { | ||||||
|  |   uint8_t* rgba;         // Decoded and reconstructed full frame. | ||||||
|  |   int duration;          // Frame duration in milliseconds. | ||||||
|  |   int is_key_frame;      // True if this frame is a key-frame. | ||||||
|  | } DecodedFrame; | ||||||
|  |  | ||||||
|  | typedef struct { | ||||||
|  |   AnimatedFileFormat format; | ||||||
|  |   uint32_t canvas_width; | ||||||
|  |   uint32_t canvas_height; | ||||||
|  |   uint32_t bgcolor; | ||||||
|  |   uint32_t loop_count; | ||||||
|  |   DecodedFrame* frames; | ||||||
|  |   uint32_t num_frames; | ||||||
|  |   void* raw_mem; | ||||||
|  | } AnimatedImage; | ||||||
|  |  | ||||||
|  | // Deallocate everything in 'image' (but not the object itself). | ||||||
|  | void ClearAnimatedImage(AnimatedImage* const image); | ||||||
|  |  | ||||||
|  | // Read animated image file into 'AnimatedImage' struct. | ||||||
|  | // If 'dump_frames' is true, dump frames to 'dump_folder'. | ||||||
|  | // Previous content of 'image' is obliterated. | ||||||
|  | // Upon successful return, content of 'image' must be deleted by | ||||||
|  | // calling 'ClearAnimatedImage'. | ||||||
|  | int ReadAnimatedImage(const char filename[], AnimatedImage* const image, | ||||||
|  |                       int dump_frames, const char dump_folder[]); | ||||||
|  |  | ||||||
|  | // Given two RGBA buffers, calculate max pixel difference and PSNR. | ||||||
|  | // If 'premultiply' is true, R/G/B values will be pre-multiplied by the | ||||||
|  | // transparency before comparison. | ||||||
|  | void GetDiffAndPSNR(const uint8_t rgba1[], const uint8_t rgba2[], | ||||||
|  |                     uint32_t width, uint32_t height, int premultiply, | ||||||
|  |                     int* const max_diff, double* const psnr); | ||||||
|  |  | ||||||
|  | // Return library versions used by anim_util. | ||||||
|  | void GetAnimatedImageVersions(int* const decoder_version, | ||||||
|  |                               int* const demux_version); | ||||||
|  |  | ||||||
|  | #ifdef __cplusplus | ||||||
|  | }    // extern "C" | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | #endif  // WEBP_EXAMPLES_ANIM_UTIL_H_ | ||||||
							
								
								
									
										1245
									
								
								external/libwebp/libwebp/examples/cwebp.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1245
									
								
								external/libwebp/libwebp/examples/cwebp.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										421
									
								
								external/libwebp/libwebp/examples/dwebp.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										421
									
								
								external/libwebp/libwebp/examples/dwebp.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,421 @@ | |||||||
|  | // Copyright 2010 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. | ||||||
|  | // ----------------------------------------------------------------------------- | ||||||
|  | // | ||||||
|  | //  Command-line tool for decoding a WebP image. | ||||||
|  | // | ||||||
|  | // Author: Skal (pascal.massimino@gmail.com) | ||||||
|  |  | ||||||
|  | #include <assert.h> | ||||||
|  | #include <stdio.h> | ||||||
|  | #include <stdlib.h> | ||||||
|  | #include <string.h> | ||||||
|  |  | ||||||
|  | #ifdef HAVE_CONFIG_H | ||||||
|  | #include "webp/config.h" | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | #include "../examples/example_util.h" | ||||||
|  | #include "../imageio/image_enc.h" | ||||||
|  | #include "../imageio/webpdec.h" | ||||||
|  | #include "./stopwatch.h" | ||||||
|  | #include "./unicode.h" | ||||||
|  |  | ||||||
|  | static int verbose = 0; | ||||||
|  | static int quiet = 0; | ||||||
|  | #ifndef WEBP_DLL | ||||||
|  | #ifdef __cplusplus | ||||||
|  | extern "C" { | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | extern void* VP8GetCPUInfo;   // opaque forward declaration. | ||||||
|  |  | ||||||
|  | #ifdef __cplusplus | ||||||
|  | }    // extern "C" | ||||||
|  | #endif | ||||||
|  | #endif  // WEBP_DLL | ||||||
|  |  | ||||||
|  |  | ||||||
|  | static int SaveOutput(const WebPDecBuffer* const buffer, | ||||||
|  |                       WebPOutputFileFormat format, const char* const out_file) { | ||||||
|  |   const int use_stdout = (out_file != NULL) && !WSTRCMP(out_file, "-"); | ||||||
|  |   int ok = 1; | ||||||
|  |   Stopwatch stop_watch; | ||||||
|  |  | ||||||
|  |   if (verbose) { | ||||||
|  |     StopwatchReset(&stop_watch); | ||||||
|  |   } | ||||||
|  |   ok = WebPSaveImage(buffer, format, out_file); | ||||||
|  |  | ||||||
|  |   if (ok) { | ||||||
|  |     if (!quiet) { | ||||||
|  |       if (use_stdout) { | ||||||
|  |         fprintf(stderr, "Saved to stdout\n"); | ||||||
|  |       } else { | ||||||
|  |         WFPRINTF(stderr, "Saved file %s\n", (const W_CHAR*)out_file); | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |     if (verbose) { | ||||||
|  |       const double write_time = StopwatchReadAndReset(&stop_watch); | ||||||
|  |       fprintf(stderr, "Time to write output: %.3fs\n", write_time); | ||||||
|  |     } | ||||||
|  |   } else { | ||||||
|  |     if (use_stdout) { | ||||||
|  |       fprintf(stderr, "Error writing to stdout !!\n"); | ||||||
|  |     } else { | ||||||
|  |       WFPRINTF(stderr, "Error writing file %s !!\n", (const W_CHAR*)out_file); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   return ok; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static void Help(void) { | ||||||
|  |   printf("Usage: dwebp in_file [options] [-o out_file]\n\n" | ||||||
|  |          "Decodes the WebP image file to PNG format [Default].\n" | ||||||
|  |          "Note: Animated WebP files are not supported.\n\n" | ||||||
|  |          "Use following options to convert into alternate image formats:\n" | ||||||
|  |          "  -pam ......... save the raw RGBA samples as a color PAM\n" | ||||||
|  |          "  -ppm ......... save the raw RGB samples as a color PPM\n" | ||||||
|  |          "  -bmp ......... save as uncompressed BMP format\n" | ||||||
|  |          "  -tiff ........ save as uncompressed TIFF format\n" | ||||||
|  |          "  -pgm ......... save the raw YUV samples as a grayscale PGM\n" | ||||||
|  |          "                 file with IMC4 layout\n" | ||||||
|  |          "  -yuv ......... save the raw YUV samples in flat layout\n" | ||||||
|  |          "\n" | ||||||
|  |          " Other options are:\n" | ||||||
|  |          "  -version ..... print version number and exit\n" | ||||||
|  |          "  -nofancy ..... don't use the fancy YUV420 upscaler\n" | ||||||
|  |          "  -nofilter .... disable in-loop filtering\n" | ||||||
|  |          "  -nodither .... disable dithering\n" | ||||||
|  |          "  -dither <d> .. dithering strength (in 0..100)\n" | ||||||
|  |          "  -alpha_dither  use alpha-plane dithering if needed\n" | ||||||
|  |          "  -mt .......... use multi-threading\n" | ||||||
|  |          "  -crop <x> <y> <w> <h> ... crop output with the given rectangle\n" | ||||||
|  |          "  -resize <w> <h> ......... resize output (*after* any cropping)\n" | ||||||
|  |          "  -flip ........ flip the output vertically\n" | ||||||
|  |          "  -alpha ....... only save the alpha plane\n" | ||||||
|  |          "  -incremental . use incremental decoding (useful for tests)\n" | ||||||
|  |          "  -h ........... this help message\n" | ||||||
|  |          "  -v ........... verbose (e.g. print encoding/decoding times)\n" | ||||||
|  |          "  -quiet ....... quiet mode, don't print anything\n" | ||||||
|  | #ifndef WEBP_DLL | ||||||
|  |          "  -noasm ....... disable all assembly optimizations\n" | ||||||
|  | #endif | ||||||
|  |         ); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static const char* const kFormatType[] = { | ||||||
|  |   "unspecified", "lossy", "lossless" | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | static uint8_t* AllocateExternalBuffer(WebPDecoderConfig* config, | ||||||
|  |                                        WebPOutputFileFormat format, | ||||||
|  |                                        int use_external_memory) { | ||||||
|  |   uint8_t* external_buffer = NULL; | ||||||
|  |   WebPDecBuffer* const output_buffer = &config->output; | ||||||
|  |   int w = config->input.width; | ||||||
|  |   int h = config->input.height; | ||||||
|  |   if (config->options.use_scaling) { | ||||||
|  |     w = config->options.scaled_width; | ||||||
|  |     h = config->options.scaled_height; | ||||||
|  |   } else if (config->options.use_cropping) { | ||||||
|  |     w = config->options.crop_width; | ||||||
|  |     h = config->options.crop_height; | ||||||
|  |   } | ||||||
|  |   if (format >= RGB && format <= rgbA_4444) { | ||||||
|  |     const int bpp = (format == RGB || format == BGR) ? 3 | ||||||
|  |                   : (format == RGBA_4444 || format == rgbA_4444 || | ||||||
|  |                      format == RGB_565) ? 2 | ||||||
|  |                   : 4; | ||||||
|  |     uint32_t stride = bpp * w + 7;   // <- just for exercising | ||||||
|  |     external_buffer = (uint8_t*)WebPMalloc(stride * h); | ||||||
|  |     if (external_buffer == NULL) return NULL; | ||||||
|  |     output_buffer->u.RGBA.stride = stride; | ||||||
|  |     output_buffer->u.RGBA.size = stride * h; | ||||||
|  |     output_buffer->u.RGBA.rgba = external_buffer; | ||||||
|  |   } else {    // YUV and YUVA | ||||||
|  |     const int has_alpha = WebPIsAlphaMode(output_buffer->colorspace); | ||||||
|  |     uint8_t* tmp; | ||||||
|  |     uint32_t stride = w + 3; | ||||||
|  |     uint32_t uv_stride = (w + 1) / 2 + 13; | ||||||
|  |     uint32_t total_size = stride * h * (has_alpha ? 2 : 1) | ||||||
|  |                         + 2 * uv_stride * (h + 1) / 2; | ||||||
|  |     assert(format >= YUV && format <= YUVA); | ||||||
|  |     external_buffer = (uint8_t*)WebPMalloc(total_size); | ||||||
|  |     if (external_buffer == NULL) return NULL; | ||||||
|  |     tmp = external_buffer; | ||||||
|  |     output_buffer->u.YUVA.y = tmp; | ||||||
|  |     output_buffer->u.YUVA.y_stride = stride; | ||||||
|  |     output_buffer->u.YUVA.y_size = stride * h; | ||||||
|  |     tmp += output_buffer->u.YUVA.y_size; | ||||||
|  |     if (has_alpha) { | ||||||
|  |       output_buffer->u.YUVA.a = tmp; | ||||||
|  |       output_buffer->u.YUVA.a_stride = stride; | ||||||
|  |       output_buffer->u.YUVA.a_size = stride * h; | ||||||
|  |       tmp += output_buffer->u.YUVA.a_size; | ||||||
|  |     } else { | ||||||
|  |       output_buffer->u.YUVA.a = NULL; | ||||||
|  |       output_buffer->u.YUVA.a_stride = 0; | ||||||
|  |     } | ||||||
|  |     output_buffer->u.YUVA.u = tmp; | ||||||
|  |     output_buffer->u.YUVA.u_stride = uv_stride; | ||||||
|  |     output_buffer->u.YUVA.u_size = uv_stride * (h + 1) / 2; | ||||||
|  |     tmp += output_buffer->u.YUVA.u_size; | ||||||
|  |  | ||||||
|  |     output_buffer->u.YUVA.v = tmp; | ||||||
|  |     output_buffer->u.YUVA.v_stride = uv_stride; | ||||||
|  |     output_buffer->u.YUVA.v_size = uv_stride * (h + 1) / 2; | ||||||
|  |     tmp += output_buffer->u.YUVA.v_size; | ||||||
|  |     assert(tmp <= external_buffer + total_size); | ||||||
|  |   } | ||||||
|  |   output_buffer->is_external_memory = use_external_memory; | ||||||
|  |   return external_buffer; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int main(int argc, const char* argv[]) { | ||||||
|  |   int ok = 0; | ||||||
|  |   const char* in_file = NULL; | ||||||
|  |   const char* out_file = NULL; | ||||||
|  |  | ||||||
|  |   WebPDecoderConfig config; | ||||||
|  |   WebPDecBuffer* const output_buffer = &config.output; | ||||||
|  |   WebPBitstreamFeatures* const bitstream = &config.input; | ||||||
|  |   WebPOutputFileFormat format = PNG; | ||||||
|  |   uint8_t* external_buffer = NULL; | ||||||
|  |   int use_external_memory = 0; | ||||||
|  |   const uint8_t* data = NULL; | ||||||
|  |  | ||||||
|  |   int incremental = 0; | ||||||
|  |   int c; | ||||||
|  |  | ||||||
|  |   INIT_WARGV(argc, argv); | ||||||
|  |  | ||||||
|  |   if (!WebPInitDecoderConfig(&config)) { | ||||||
|  |     fprintf(stderr, "Library version mismatch!\n"); | ||||||
|  |     FREE_WARGV_AND_RETURN(-1); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   for (c = 1; c < argc; ++c) { | ||||||
|  |     int parse_error = 0; | ||||||
|  |     if (!strcmp(argv[c], "-h") || !strcmp(argv[c], "-help")) { | ||||||
|  |       Help(); | ||||||
|  |       FREE_WARGV_AND_RETURN(0); | ||||||
|  |     } else if (!strcmp(argv[c], "-o") && c < argc - 1) { | ||||||
|  |       out_file = (const char*)GET_WARGV(argv, ++c); | ||||||
|  |     } else if (!strcmp(argv[c], "-alpha")) { | ||||||
|  |       format = ALPHA_PLANE_ONLY; | ||||||
|  |     } else if (!strcmp(argv[c], "-nofancy")) { | ||||||
|  |       config.options.no_fancy_upsampling = 1; | ||||||
|  |     } else if (!strcmp(argv[c], "-nofilter")) { | ||||||
|  |       config.options.bypass_filtering = 1; | ||||||
|  |     } else if (!strcmp(argv[c], "-pam")) { | ||||||
|  |       format = PAM; | ||||||
|  |     } else if (!strcmp(argv[c], "-ppm")) { | ||||||
|  |       format = PPM; | ||||||
|  |     } else if (!strcmp(argv[c], "-bmp")) { | ||||||
|  |       format = BMP; | ||||||
|  |     } else if (!strcmp(argv[c], "-tiff")) { | ||||||
|  |       format = TIFF; | ||||||
|  |     } else if (!strcmp(argv[c], "-quiet")) { | ||||||
|  |       quiet = 1; | ||||||
|  |     } else if (!strcmp(argv[c], "-version")) { | ||||||
|  |       const int version = WebPGetDecoderVersion(); | ||||||
|  |       printf("%d.%d.%d\n", | ||||||
|  |              (version >> 16) & 0xff, (version >> 8) & 0xff, version & 0xff); | ||||||
|  |       FREE_WARGV_AND_RETURN(0); | ||||||
|  |     } else if (!strcmp(argv[c], "-pgm")) { | ||||||
|  |       format = PGM; | ||||||
|  |     } else if (!strcmp(argv[c], "-yuv")) { | ||||||
|  |       format = RAW_YUV; | ||||||
|  |     } else if (!strcmp(argv[c], "-pixel_format") && c < argc - 1) { | ||||||
|  |       const char* const fmt = argv[++c]; | ||||||
|  |       if      (!strcmp(fmt, "RGB"))  format = RGB; | ||||||
|  |       else if (!strcmp(fmt, "RGBA")) format = RGBA; | ||||||
|  |       else if (!strcmp(fmt, "BGR"))  format = BGR; | ||||||
|  |       else if (!strcmp(fmt, "BGRA")) format = BGRA; | ||||||
|  |       else if (!strcmp(fmt, "ARGB")) format = ARGB; | ||||||
|  |       else if (!strcmp(fmt, "RGBA_4444")) format = RGBA_4444; | ||||||
|  |       else if (!strcmp(fmt, "RGB_565")) format = RGB_565; | ||||||
|  |       else if (!strcmp(fmt, "rgbA")) format = rgbA; | ||||||
|  |       else if (!strcmp(fmt, "bgrA")) format = bgrA; | ||||||
|  |       else if (!strcmp(fmt, "Argb")) format = Argb; | ||||||
|  |       else if (!strcmp(fmt, "rgbA_4444")) format = rgbA_4444; | ||||||
|  |       else if (!strcmp(fmt, "YUV"))  format = YUV; | ||||||
|  |       else if (!strcmp(fmt, "YUVA")) format = YUVA; | ||||||
|  |       else { | ||||||
|  |         fprintf(stderr, "Can't parse pixel_format %s\n", fmt); | ||||||
|  |         parse_error = 1; | ||||||
|  |       } | ||||||
|  |     } else if (!strcmp(argv[c], "-external_memory") && c < argc - 1) { | ||||||
|  |       use_external_memory = ExUtilGetInt(argv[++c], 0, &parse_error); | ||||||
|  |       parse_error |= (use_external_memory > 2 || use_external_memory < 0); | ||||||
|  |       if (parse_error) { | ||||||
|  |         fprintf(stderr, "Can't parse 'external_memory' value %s\n", argv[c]); | ||||||
|  |       } | ||||||
|  |     } else if (!strcmp(argv[c], "-mt")) { | ||||||
|  |       config.options.use_threads = 1; | ||||||
|  |     } else if (!strcmp(argv[c], "-alpha_dither")) { | ||||||
|  |       config.options.alpha_dithering_strength = 100; | ||||||
|  |     } else if (!strcmp(argv[c], "-nodither")) { | ||||||
|  |       config.options.dithering_strength = 0; | ||||||
|  |     } else if (!strcmp(argv[c], "-dither") && c < argc - 1) { | ||||||
|  |       config.options.dithering_strength = | ||||||
|  |           ExUtilGetInt(argv[++c], 0, &parse_error); | ||||||
|  |     } else if (!strcmp(argv[c], "-crop") && c < argc - 4) { | ||||||
|  |       config.options.use_cropping = 1; | ||||||
|  |       config.options.crop_left   = ExUtilGetInt(argv[++c], 0, &parse_error); | ||||||
|  |       config.options.crop_top    = ExUtilGetInt(argv[++c], 0, &parse_error); | ||||||
|  |       config.options.crop_width  = ExUtilGetInt(argv[++c], 0, &parse_error); | ||||||
|  |       config.options.crop_height = ExUtilGetInt(argv[++c], 0, &parse_error); | ||||||
|  |     } else if ((!strcmp(argv[c], "-scale") || !strcmp(argv[c], "-resize")) && | ||||||
|  |                c < argc - 2) {  // '-scale' is left for compatibility | ||||||
|  |       config.options.use_scaling = 1; | ||||||
|  |       config.options.scaled_width  = ExUtilGetInt(argv[++c], 0, &parse_error); | ||||||
|  |       config.options.scaled_height = ExUtilGetInt(argv[++c], 0, &parse_error); | ||||||
|  |     } else if (!strcmp(argv[c], "-flip")) { | ||||||
|  |       config.options.flip = 1; | ||||||
|  |     } else if (!strcmp(argv[c], "-v")) { | ||||||
|  |       verbose = 1; | ||||||
|  | #ifndef WEBP_DLL | ||||||
|  |     } else if (!strcmp(argv[c], "-noasm")) { | ||||||
|  |       VP8GetCPUInfo = NULL; | ||||||
|  | #endif | ||||||
|  |     } else if (!strcmp(argv[c], "-incremental")) { | ||||||
|  |       incremental = 1; | ||||||
|  |     } else if (!strcmp(argv[c], "--")) { | ||||||
|  |       if (c < argc - 1) in_file = (const char*)GET_WARGV(argv, ++c); | ||||||
|  |       break; | ||||||
|  |     } else if (argv[c][0] == '-') { | ||||||
|  |       fprintf(stderr, "Unknown option '%s'\n", argv[c]); | ||||||
|  |       Help(); | ||||||
|  |       FREE_WARGV_AND_RETURN(-1); | ||||||
|  |     } else { | ||||||
|  |       in_file = (const char*)GET_WARGV(argv, c); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     if (parse_error) { | ||||||
|  |       Help(); | ||||||
|  |       FREE_WARGV_AND_RETURN(-1); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   if (in_file == NULL) { | ||||||
|  |     fprintf(stderr, "missing input file!!\n"); | ||||||
|  |     Help(); | ||||||
|  |     FREE_WARGV_AND_RETURN(-1); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   if (quiet) verbose = 0; | ||||||
|  |  | ||||||
|  |   { | ||||||
|  |     VP8StatusCode status = VP8_STATUS_OK; | ||||||
|  |     size_t data_size = 0; | ||||||
|  |     if (!LoadWebP(in_file, &data, &data_size, bitstream)) { | ||||||
|  |       FREE_WARGV_AND_RETURN(-1); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     switch (format) { | ||||||
|  |       case PNG: | ||||||
|  | #ifdef HAVE_WINCODEC_H | ||||||
|  |         output_buffer->colorspace = bitstream->has_alpha ? MODE_BGRA : MODE_BGR; | ||||||
|  | #else | ||||||
|  |         output_buffer->colorspace = bitstream->has_alpha ? MODE_RGBA : MODE_RGB; | ||||||
|  | #endif | ||||||
|  |         break; | ||||||
|  |       case PAM: | ||||||
|  |         output_buffer->colorspace = MODE_RGBA; | ||||||
|  |         break; | ||||||
|  |       case PPM: | ||||||
|  |         output_buffer->colorspace = MODE_RGB;  // drops alpha for PPM | ||||||
|  |         break; | ||||||
|  |       case BMP: | ||||||
|  |         output_buffer->colorspace = bitstream->has_alpha ? MODE_BGRA : MODE_BGR; | ||||||
|  |         break; | ||||||
|  |       case TIFF: | ||||||
|  |         output_buffer->colorspace = bitstream->has_alpha ? MODE_RGBA : MODE_RGB; | ||||||
|  |         break; | ||||||
|  |       case PGM: | ||||||
|  |       case RAW_YUV: | ||||||
|  |         output_buffer->colorspace = bitstream->has_alpha ? MODE_YUVA : MODE_YUV; | ||||||
|  |         break; | ||||||
|  |       case ALPHA_PLANE_ONLY: | ||||||
|  |         output_buffer->colorspace = MODE_YUVA; | ||||||
|  |         break; | ||||||
|  |       // forced modes: | ||||||
|  |       case RGB: output_buffer->colorspace = MODE_RGB; break; | ||||||
|  |       case RGBA: output_buffer->colorspace = MODE_RGBA; break; | ||||||
|  |       case BGR: output_buffer->colorspace = MODE_BGR; break; | ||||||
|  |       case BGRA: output_buffer->colorspace = MODE_BGRA; break; | ||||||
|  |       case ARGB: output_buffer->colorspace = MODE_ARGB; break; | ||||||
|  |       case RGBA_4444: output_buffer->colorspace = MODE_RGBA_4444; break; | ||||||
|  |       case RGB_565: output_buffer->colorspace = MODE_RGB_565; break; | ||||||
|  |       case rgbA: output_buffer->colorspace = MODE_rgbA; break; | ||||||
|  |       case bgrA: output_buffer->colorspace = MODE_bgrA; break; | ||||||
|  |       case Argb: output_buffer->colorspace = MODE_Argb; break; | ||||||
|  |       case rgbA_4444: output_buffer->colorspace = MODE_rgbA_4444; break; | ||||||
|  |       case YUV: output_buffer->colorspace = MODE_YUV; break; | ||||||
|  |       case YUVA: output_buffer->colorspace = MODE_YUVA; break; | ||||||
|  |       default: goto Exit; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     if (use_external_memory > 0 && format >= RGB) { | ||||||
|  |       external_buffer = AllocateExternalBuffer(&config, format, | ||||||
|  |                                                use_external_memory); | ||||||
|  |       if (external_buffer == NULL) goto Exit; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     { | ||||||
|  |       Stopwatch stop_watch; | ||||||
|  |       if (verbose) StopwatchReset(&stop_watch); | ||||||
|  |  | ||||||
|  |       if (incremental) { | ||||||
|  |         status = DecodeWebPIncremental(data, data_size, &config); | ||||||
|  |       } else { | ||||||
|  |         status = DecodeWebP(data, data_size, &config); | ||||||
|  |       } | ||||||
|  |       if (verbose) { | ||||||
|  |         const double decode_time = StopwatchReadAndReset(&stop_watch); | ||||||
|  |         fprintf(stderr, "Time to decode picture: %.3fs\n", decode_time); | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     ok = (status == VP8_STATUS_OK); | ||||||
|  |     if (!ok) { | ||||||
|  |       PrintWebPError(in_file, status); | ||||||
|  |       goto Exit; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   if (out_file != NULL) { | ||||||
|  |     if (!quiet) { | ||||||
|  |       WFPRINTF(stderr, "Decoded %s.", (const W_CHAR*)in_file); | ||||||
|  |       fprintf(stderr, " Dimensions: %d x %d %s. Format: %s. Now saving...\n", | ||||||
|  |               output_buffer->width, output_buffer->height, | ||||||
|  |               bitstream->has_alpha ? " (with alpha)" : "", | ||||||
|  |               kFormatType[bitstream->format]); | ||||||
|  |     } | ||||||
|  |     ok = SaveOutput(output_buffer, format, out_file); | ||||||
|  |   } else { | ||||||
|  |     if (!quiet) { | ||||||
|  |       WFPRINTF(stderr, "File %s can be decoded ", (const W_CHAR*)in_file); | ||||||
|  |       fprintf(stderr, "(dimensions: %d x %d %s. Format: %s).\n", | ||||||
|  |               output_buffer->width, output_buffer->height, | ||||||
|  |               bitstream->has_alpha ? " (with alpha)" : "", | ||||||
|  |               kFormatType[bitstream->format]); | ||||||
|  |       fprintf(stderr, "Nothing written; " | ||||||
|  |                       "use -o flag to save the result as e.g. PNG.\n"); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  Exit: | ||||||
|  |   WebPFreeDecBuffer(output_buffer); | ||||||
|  |   WebPFree((void*)external_buffer); | ||||||
|  |   WebPFree((void*)data); | ||||||
|  |   FREE_WARGV_AND_RETURN(ok ? 0 : -1); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | //------------------------------------------------------------------------------ | ||||||
							
								
								
									
										139
									
								
								external/libwebp/libwebp/examples/example_util.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										139
									
								
								external/libwebp/libwebp/examples/example_util.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,139 @@ | |||||||
|  | // Copyright 2012 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. | ||||||
|  | // ----------------------------------------------------------------------------- | ||||||
|  | // | ||||||
|  | //  Utility functions used by the example programs. | ||||||
|  | // | ||||||
|  |  | ||||||
|  | #include "./example_util.h" | ||||||
|  |  | ||||||
|  | #include <assert.h> | ||||||
|  | #include <stdio.h> | ||||||
|  | #include <stdlib.h> | ||||||
|  | #include <string.h> | ||||||
|  |  | ||||||
|  | #include "webp/mux_types.h" | ||||||
|  | #include "../imageio/imageio_util.h" | ||||||
|  |  | ||||||
|  | //------------------------------------------------------------------------------ | ||||||
|  | // String parsing | ||||||
|  |  | ||||||
|  | uint32_t ExUtilGetUInt(const char* const v, int base, int* const error) { | ||||||
|  |   char* end = NULL; | ||||||
|  |   const uint32_t n = (v != NULL) ? (uint32_t)strtoul(v, &end, base) : 0u; | ||||||
|  |   if (end == v && error != NULL && !*error) { | ||||||
|  |     *error = 1; | ||||||
|  |     fprintf(stderr, "Error! '%s' is not an integer.\n", | ||||||
|  |             (v != NULL) ? v : "(null)"); | ||||||
|  |   } | ||||||
|  |   return n; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int ExUtilGetInt(const char* const v, int base, int* const error) { | ||||||
|  |   return (int)ExUtilGetUInt(v, base, error); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int ExUtilGetInts(const char* v, int base, int max_output, int output[]) { | ||||||
|  |   int n, error = 0; | ||||||
|  |   for (n = 0; v != NULL && n < max_output; ++n) { | ||||||
|  |     const int value = ExUtilGetInt(v, base, &error); | ||||||
|  |     if (error) return -1; | ||||||
|  |     output[n] = value; | ||||||
|  |     v = strchr(v, ','); | ||||||
|  |     if (v != NULL) ++v;   // skip over the trailing ',' | ||||||
|  |   } | ||||||
|  |   return n; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | float ExUtilGetFloat(const char* const v, int* const error) { | ||||||
|  |   char* end = NULL; | ||||||
|  |   const float f = (v != NULL) ? (float)strtod(v, &end) : 0.f; | ||||||
|  |   if (end == v && error != NULL && !*error) { | ||||||
|  |     *error = 1; | ||||||
|  |     fprintf(stderr, "Error! '%s' is not a floating point number.\n", | ||||||
|  |             (v != NULL) ? v : "(null)"); | ||||||
|  |   } | ||||||
|  |   return f; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | //------------------------------------------------------------------------------ | ||||||
|  |  | ||||||
|  | static void ResetCommandLineArguments(int argc, const char* argv[], | ||||||
|  |                                       CommandLineArguments* const args) { | ||||||
|  |   assert(args != NULL); | ||||||
|  |   args->argc_ = argc; | ||||||
|  |   args->argv_ = argv; | ||||||
|  |   args->own_argv_ = 0; | ||||||
|  |   WebPDataInit(&args->argv_data_); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void ExUtilDeleteCommandLineArguments(CommandLineArguments* const args) { | ||||||
|  |   if (args != NULL) { | ||||||
|  |     if (args->own_argv_) { | ||||||
|  |       WebPFree((void*)args->argv_); | ||||||
|  |       WebPDataClear(&args->argv_data_); | ||||||
|  |     } | ||||||
|  |     ResetCommandLineArguments(0, NULL, args); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #define MAX_ARGC 16384 | ||||||
|  | int ExUtilInitCommandLineArguments(int argc, const char* argv[], | ||||||
|  |                                    CommandLineArguments* const args) { | ||||||
|  |   if (args == NULL || argv == NULL) return 0; | ||||||
|  |   ResetCommandLineArguments(argc, argv, args); | ||||||
|  |   if (argc == 1 && argv[0][0] != '-') { | ||||||
|  |     char* cur; | ||||||
|  |     const char sep[] = " \t\r\n\f\v"; | ||||||
|  |  | ||||||
|  | #if defined(_WIN32) && defined(_UNICODE) | ||||||
|  |     fprintf(stderr, | ||||||
|  |             "Error: Reading arguments from a file is a feature unavailable " | ||||||
|  |             "with Unicode binaries.\n"); | ||||||
|  |     return 0; | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  |     if (!ExUtilReadFileToWebPData(argv[0], &args->argv_data_)) { | ||||||
|  |       return 0; | ||||||
|  |     } | ||||||
|  |     args->own_argv_ = 1; | ||||||
|  |     args->argv_ = (const char**)WebPMalloc(MAX_ARGC * sizeof(*args->argv_)); | ||||||
|  |     if (args->argv_ == NULL) { | ||||||
|  |       ExUtilDeleteCommandLineArguments(args); | ||||||
|  |       return 0; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     argc = 0; | ||||||
|  |     for (cur = strtok((char*)args->argv_data_.bytes, sep); | ||||||
|  |          cur != NULL; | ||||||
|  |          cur = strtok(NULL, sep)) { | ||||||
|  |       if (argc == MAX_ARGC) { | ||||||
|  |         fprintf(stderr, "ERROR: Arguments limit %d reached\n", MAX_ARGC); | ||||||
|  |         ExUtilDeleteCommandLineArguments(args); | ||||||
|  |         return 0; | ||||||
|  |       } | ||||||
|  |       assert(strlen(cur) != 0); | ||||||
|  |       args->argv_[argc++] = cur; | ||||||
|  |     } | ||||||
|  |     args->argc_ = argc; | ||||||
|  |   } | ||||||
|  |   return 1; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | //------------------------------------------------------------------------------ | ||||||
|  |  | ||||||
|  | int ExUtilReadFileToWebPData(const char* const filename, | ||||||
|  |                              WebPData* const webp_data) { | ||||||
|  |   const uint8_t* data; | ||||||
|  |   size_t size; | ||||||
|  |   if (webp_data == NULL) return 0; | ||||||
|  |   if (!ImgIoUtilReadFile(filename, &data, &size)) return 0; | ||||||
|  |   webp_data->bytes = data; | ||||||
|  |   webp_data->size = size; | ||||||
|  |   return 1; | ||||||
|  | } | ||||||
							
								
								
									
										70
									
								
								external/libwebp/libwebp/examples/example_util.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										70
									
								
								external/libwebp/libwebp/examples/example_util.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,70 @@ | |||||||
|  | // Copyright 2012 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. | ||||||
|  | // ----------------------------------------------------------------------------- | ||||||
|  | // | ||||||
|  | //  Utility functions used by the example programs. | ||||||
|  | // | ||||||
|  |  | ||||||
|  | #ifndef WEBP_EXAMPLES_EXAMPLE_UTIL_H_ | ||||||
|  | #define WEBP_EXAMPLES_EXAMPLE_UTIL_H_ | ||||||
|  |  | ||||||
|  | #include "webp/types.h" | ||||||
|  | #include "webp/mux_types.h" | ||||||
|  |  | ||||||
|  | #ifdef __cplusplus | ||||||
|  | extern "C" { | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | //------------------------------------------------------------------------------ | ||||||
|  | // String parsing | ||||||
|  |  | ||||||
|  | // Parses 'v' using strto(ul|l|d)(). If error is non-NULL, '*error' is set to | ||||||
|  | // true on failure while on success it is left unmodified to allow chaining of | ||||||
|  | // calls. An error is only printed on the first occurrence. | ||||||
|  | uint32_t ExUtilGetUInt(const char* const v, int base, int* const error); | ||||||
|  | int ExUtilGetInt(const char* const v, int base, int* const error); | ||||||
|  | float ExUtilGetFloat(const char* const v, int* const error); | ||||||
|  |  | ||||||
|  | // This variant of ExUtilGetInt() will parse multiple integers from a | ||||||
|  | // comma-separated list. Up to 'max_output' integers are parsed. | ||||||
|  | // The result is placed in the output[] array, and the number of integers | ||||||
|  | // actually parsed is returned, or -1 if an error occurred. | ||||||
|  | int ExUtilGetInts(const char* v, int base, int max_output, int output[]); | ||||||
|  |  | ||||||
|  | // Reads a file named 'filename' into a WebPData structure. The content of | ||||||
|  | // webp_data is overwritten. Returns false in case of error. | ||||||
|  | int ExUtilReadFileToWebPData(const char* const filename, | ||||||
|  |                              WebPData* const webp_data); | ||||||
|  |  | ||||||
|  | //------------------------------------------------------------------------------ | ||||||
|  | // Command-line arguments | ||||||
|  |  | ||||||
|  | typedef struct { | ||||||
|  |   int argc_; | ||||||
|  |   const char** argv_; | ||||||
|  |   WebPData argv_data_; | ||||||
|  |   int own_argv_; | ||||||
|  | } CommandLineArguments; | ||||||
|  |  | ||||||
|  | // Initializes the structure from the command-line parameters. If there is | ||||||
|  | // only one parameter and it does not start with a '-', then it is assumed to | ||||||
|  | // be a file name. This file will be read and tokenized into command-line | ||||||
|  | // arguments. The content of 'args' is overwritten. | ||||||
|  | // Returns false in case of error (memory allocation failure, non | ||||||
|  | // existing file, too many arguments, ...). | ||||||
|  | int ExUtilInitCommandLineArguments(int argc, const char* argv[], | ||||||
|  |                                    CommandLineArguments* const args); | ||||||
|  |  | ||||||
|  | // Deallocate all memory and reset 'args'. | ||||||
|  | void ExUtilDeleteCommandLineArguments(CommandLineArguments* const args); | ||||||
|  |  | ||||||
|  | #ifdef __cplusplus | ||||||
|  | }    // extern "C" | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | #endif  // WEBP_EXAMPLES_EXAMPLE_UTIL_H_ | ||||||
							
								
								
									
										609
									
								
								external/libwebp/libwebp/examples/gif2webp.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										609
									
								
								external/libwebp/libwebp/examples/gif2webp.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,609 @@ | |||||||
|  | // Copyright 2012 Google Inc. All Rights Reserved. | ||||||
|  | // | ||||||
|  | // Use of this source code is governed by a BSD-style license | ||||||
|  | // that can be found in the COPYING file in the root of the source | ||||||
|  | // tree. An additional intellectual property rights grant can be found | ||||||
|  | // in the file PATENTS. All contributing project authors may | ||||||
|  | // be found in the AUTHORS file in the root of the source tree. | ||||||
|  | // ----------------------------------------------------------------------------- | ||||||
|  | // | ||||||
|  | //  simple tool to convert animated GIFs to WebP | ||||||
|  | // | ||||||
|  | // Authors: Skal (pascal.massimino@gmail.com) | ||||||
|  | //          Urvang (urvang@google.com) | ||||||
|  |  | ||||||
|  | #include <assert.h> | ||||||
|  | #include <stdio.h> | ||||||
|  | #include <stdlib.h> | ||||||
|  | #include <string.h> | ||||||
|  |  | ||||||
|  | #ifdef HAVE_CONFIG_H | ||||||
|  | #include "webp/config.h" | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | #ifdef WEBP_HAVE_GIF | ||||||
|  |  | ||||||
|  | #if defined(HAVE_UNISTD_H) && HAVE_UNISTD_H | ||||||
|  | #include <unistd.h> | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | #include <gif_lib.h> | ||||||
|  | #include "webp/encode.h" | ||||||
|  | #include "webp/mux.h" | ||||||
|  | #include "../examples/example_util.h" | ||||||
|  | #include "../imageio/imageio_util.h" | ||||||
|  | #include "./gifdec.h" | ||||||
|  | #include "./unicode.h" | ||||||
|  | #include "./unicode_gif.h" | ||||||
|  |  | ||||||
|  | #if !defined(STDIN_FILENO) | ||||||
|  | #define STDIN_FILENO 0 | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | //------------------------------------------------------------------------------ | ||||||
|  |  | ||||||
|  | static int transparent_index = GIF_INDEX_INVALID;  // Opaque by default. | ||||||
|  |  | ||||||
|  | static const char* const kErrorMessages[-WEBP_MUX_NOT_ENOUGH_DATA + 1] = { | ||||||
|  |   "WEBP_MUX_NOT_FOUND", "WEBP_MUX_INVALID_ARGUMENT", "WEBP_MUX_BAD_DATA", | ||||||
|  |   "WEBP_MUX_MEMORY_ERROR", "WEBP_MUX_NOT_ENOUGH_DATA" | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | static const char* ErrorString(WebPMuxError err) { | ||||||
|  |   assert(err <= WEBP_MUX_NOT_FOUND && err >= WEBP_MUX_NOT_ENOUGH_DATA); | ||||||
|  |   return kErrorMessages[-err]; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | enum { | ||||||
|  |   METADATA_ICC  = (1 << 0), | ||||||
|  |   METADATA_XMP  = (1 << 1), | ||||||
|  |   METADATA_ALL  = METADATA_ICC | METADATA_XMP | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | //------------------------------------------------------------------------------ | ||||||
|  |  | ||||||
|  | static void Help(void) { | ||||||
|  |   printf("Usage:\n"); | ||||||
|  |   printf(" gif2webp [options] gif_file -o webp_file\n"); | ||||||
|  |   printf("Options:\n"); | ||||||
|  |   printf("  -h / -help ............. this help\n"); | ||||||
|  |   printf("  -lossy ................. encode image using lossy compression\n"); | ||||||
|  |   printf("  -mixed ................. for each frame in the image, pick lossy\n" | ||||||
|  |          "                           or lossless compression heuristically\n"); | ||||||
|  |   printf("  -q <float> ............. quality factor (0:small..100:big)\n"); | ||||||
|  |   printf("  -m <int> ............... compression method (0=fast, 6=slowest)\n"); | ||||||
|  |   printf("  -min_size .............. minimize output size (default:off)\n" | ||||||
|  |          "                           lossless compression by default; can be\n" | ||||||
|  |          "                           combined with -q, -m, -lossy or -mixed\n" | ||||||
|  |          "                           options\n"); | ||||||
|  |   printf("  -kmin <int> ............ min distance between key frames\n"); | ||||||
|  |   printf("  -kmax <int> ............ max distance between key frames\n"); | ||||||
|  |   printf("  -f <int> ............... filter strength (0=off..100)\n"); | ||||||
|  |   printf("  -metadata <string> ..... comma separated list of metadata to\n"); | ||||||
|  |   printf("                           "); | ||||||
|  |   printf("copy from the input to the output if present\n"); | ||||||
|  |   printf("                           "); | ||||||
|  |   printf("Valid values: all, none, icc, xmp (default)\n"); | ||||||
|  |   printf("  -loop_compatibility .... use compatibility mode for Chrome\n"); | ||||||
|  |   printf("                           version prior to M62 (inclusive)\n"); | ||||||
|  |   printf("  -mt .................... use multi-threading if available\n"); | ||||||
|  |   printf("\n"); | ||||||
|  |   printf("  -version ............... print version number and exit\n"); | ||||||
|  |   printf("  -v ..................... verbose\n"); | ||||||
|  |   printf("  -quiet ................. don't print anything\n"); | ||||||
|  |   printf("\n"); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | //------------------------------------------------------------------------------ | ||||||
|  |  | ||||||
|  | int main(int argc, const char* argv[]) { | ||||||
|  |   int verbose = 0; | ||||||
|  |   int gif_error = GIF_ERROR; | ||||||
|  |   WebPMuxError err = WEBP_MUX_OK; | ||||||
|  |   int ok = 0; | ||||||
|  |   const W_CHAR* in_file = NULL, *out_file = NULL; | ||||||
|  |   GifFileType* gif = NULL; | ||||||
|  |   int frame_duration = 0; | ||||||
|  |   int frame_timestamp = 0; | ||||||
|  |   GIFDisposeMethod orig_dispose = GIF_DISPOSE_NONE; | ||||||
|  |  | ||||||
|  |   WebPPicture frame;                // Frame rectangle only (not disposed). | ||||||
|  |   WebPPicture curr_canvas;          // Not disposed. | ||||||
|  |   WebPPicture prev_canvas;          // Disposed. | ||||||
|  |  | ||||||
|  |   WebPAnimEncoder* enc = NULL; | ||||||
|  |   WebPAnimEncoderOptions enc_options; | ||||||
|  |   WebPConfig config; | ||||||
|  |  | ||||||
|  |   int frame_number = 0;     // Whether we are processing the first frame. | ||||||
|  |   int done; | ||||||
|  |   int c; | ||||||
|  |   int quiet = 0; | ||||||
|  |   WebPData webp_data; | ||||||
|  |  | ||||||
|  |   int keep_metadata = METADATA_XMP;  // ICC not output by default. | ||||||
|  |   WebPData icc_data; | ||||||
|  |   int stored_icc = 0;         // Whether we have already stored an ICC profile. | ||||||
|  |   WebPData xmp_data; | ||||||
|  |   int stored_xmp = 0;         // Whether we have already stored an XMP profile. | ||||||
|  |   int loop_count = 0;         // default: infinite | ||||||
|  |   int stored_loop_count = 0;  // Whether we have found an explicit loop count. | ||||||
|  |   int loop_compatibility = 0; | ||||||
|  |   WebPMux* mux = NULL; | ||||||
|  |  | ||||||
|  |   int default_kmin = 1;  // Whether to use default kmin value. | ||||||
|  |   int default_kmax = 1; | ||||||
|  |  | ||||||
|  |   INIT_WARGV(argc, argv); | ||||||
|  |  | ||||||
|  |   if (!WebPConfigInit(&config) || !WebPAnimEncoderOptionsInit(&enc_options) || | ||||||
|  |       !WebPPictureInit(&frame) || !WebPPictureInit(&curr_canvas) || | ||||||
|  |       !WebPPictureInit(&prev_canvas)) { | ||||||
|  |     fprintf(stderr, "Error! Version mismatch!\n"); | ||||||
|  |     FREE_WARGV_AND_RETURN(-1); | ||||||
|  |   } | ||||||
|  |   config.lossless = 1;  // Use lossless compression by default. | ||||||
|  |  | ||||||
|  |   WebPDataInit(&webp_data); | ||||||
|  |   WebPDataInit(&icc_data); | ||||||
|  |   WebPDataInit(&xmp_data); | ||||||
|  |  | ||||||
|  |   if (argc == 1) { | ||||||
|  |     Help(); | ||||||
|  |     FREE_WARGV_AND_RETURN(0); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   for (c = 1; c < argc; ++c) { | ||||||
|  |     int parse_error = 0; | ||||||
|  |     if (!strcmp(argv[c], "-h") || !strcmp(argv[c], "-help")) { | ||||||
|  |       Help(); | ||||||
|  |       FREE_WARGV_AND_RETURN(0); | ||||||
|  |     } else if (!strcmp(argv[c], "-o") && c < argc - 1) { | ||||||
|  |       out_file = GET_WARGV(argv, ++c); | ||||||
|  |     } else if (!strcmp(argv[c], "-lossy")) { | ||||||
|  |       config.lossless = 0; | ||||||
|  |     } else if (!strcmp(argv[c], "-mixed")) { | ||||||
|  |       enc_options.allow_mixed = 1; | ||||||
|  |       config.lossless = 0; | ||||||
|  |     } else if (!strcmp(argv[c], "-loop_compatibility")) { | ||||||
|  |       loop_compatibility = 1; | ||||||
|  |     } else if (!strcmp(argv[c], "-q") && c < argc - 1) { | ||||||
|  |       config.quality = ExUtilGetFloat(argv[++c], &parse_error); | ||||||
|  |     } else if (!strcmp(argv[c], "-m") && c < argc - 1) { | ||||||
|  |       config.method = ExUtilGetInt(argv[++c], 0, &parse_error); | ||||||
|  |     } else if (!strcmp(argv[c], "-min_size")) { | ||||||
|  |       enc_options.minimize_size = 1; | ||||||
|  |     } else if (!strcmp(argv[c], "-kmax") && c < argc - 1) { | ||||||
|  |       enc_options.kmax = ExUtilGetInt(argv[++c], 0, &parse_error); | ||||||
|  |       default_kmax = 0; | ||||||
|  |     } else if (!strcmp(argv[c], "-kmin") && c < argc - 1) { | ||||||
|  |       enc_options.kmin = ExUtilGetInt(argv[++c], 0, &parse_error); | ||||||
|  |       default_kmin = 0; | ||||||
|  |     } else if (!strcmp(argv[c], "-f") && c < argc - 1) { | ||||||
|  |       config.filter_strength = ExUtilGetInt(argv[++c], 0, &parse_error); | ||||||
|  |     } else if (!strcmp(argv[c], "-metadata") && c < argc - 1) { | ||||||
|  |       static const struct { | ||||||
|  |         const char* option; | ||||||
|  |         int flag; | ||||||
|  |       } kTokens[] = { | ||||||
|  |         { "all",  METADATA_ALL }, | ||||||
|  |         { "none", 0 }, | ||||||
|  |         { "icc",  METADATA_ICC }, | ||||||
|  |         { "xmp",  METADATA_XMP }, | ||||||
|  |       }; | ||||||
|  |       const size_t kNumTokens = sizeof(kTokens) / sizeof(*kTokens); | ||||||
|  |       const char* start = argv[++c]; | ||||||
|  |       const char* const end = start + strlen(start); | ||||||
|  |  | ||||||
|  |       keep_metadata = 0; | ||||||
|  |       while (start < end) { | ||||||
|  |         size_t i; | ||||||
|  |         const char* token = strchr(start, ','); | ||||||
|  |         if (token == NULL) token = end; | ||||||
|  |  | ||||||
|  |         for (i = 0; i < kNumTokens; ++i) { | ||||||
|  |           if ((size_t)(token - start) == strlen(kTokens[i].option) && | ||||||
|  |               !strncmp(start, kTokens[i].option, strlen(kTokens[i].option))) { | ||||||
|  |             if (kTokens[i].flag != 0) { | ||||||
|  |               keep_metadata |= kTokens[i].flag; | ||||||
|  |             } else { | ||||||
|  |               keep_metadata = 0; | ||||||
|  |             } | ||||||
|  |             break; | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |         if (i == kNumTokens) { | ||||||
|  |           fprintf(stderr, "Error! Unknown metadata type '%.*s'\n", | ||||||
|  |                   (int)(token - start), start); | ||||||
|  |           Help(); | ||||||
|  |           FREE_WARGV_AND_RETURN(-1); | ||||||
|  |         } | ||||||
|  |         start = token + 1; | ||||||
|  |       } | ||||||
|  |     } else if (!strcmp(argv[c], "-mt")) { | ||||||
|  |       ++config.thread_level; | ||||||
|  |     } else if (!strcmp(argv[c], "-version")) { | ||||||
|  |       const int enc_version = WebPGetEncoderVersion(); | ||||||
|  |       const int mux_version = WebPGetMuxVersion(); | ||||||
|  |       printf("WebP Encoder version: %d.%d.%d\nWebP Mux version: %d.%d.%d\n", | ||||||
|  |              (enc_version >> 16) & 0xff, (enc_version >> 8) & 0xff, | ||||||
|  |              enc_version & 0xff, (mux_version >> 16) & 0xff, | ||||||
|  |              (mux_version >> 8) & 0xff, mux_version & 0xff); | ||||||
|  |       FREE_WARGV_AND_RETURN(0); | ||||||
|  |     } else if (!strcmp(argv[c], "-quiet")) { | ||||||
|  |       quiet = 1; | ||||||
|  |       enc_options.verbose = 0; | ||||||
|  |     } else if (!strcmp(argv[c], "-v")) { | ||||||
|  |       verbose = 1; | ||||||
|  |       enc_options.verbose = 1; | ||||||
|  |     } else if (!strcmp(argv[c], "--")) { | ||||||
|  |       if (c < argc - 1) in_file = GET_WARGV(argv, ++c); | ||||||
|  |       break; | ||||||
|  |     } else if (argv[c][0] == '-') { | ||||||
|  |       fprintf(stderr, "Error! Unknown option '%s'\n", argv[c]); | ||||||
|  |       Help(); | ||||||
|  |       FREE_WARGV_AND_RETURN(-1); | ||||||
|  |     } else { | ||||||
|  |       in_file = GET_WARGV(argv, c); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     if (parse_error) { | ||||||
|  |       Help(); | ||||||
|  |       FREE_WARGV_AND_RETURN(-1); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   // Appropriate default kmin, kmax values for lossy and lossless. | ||||||
|  |   if (default_kmin) { | ||||||
|  |     enc_options.kmin = config.lossless ? 9 : 3; | ||||||
|  |   } | ||||||
|  |   if (default_kmax) { | ||||||
|  |     enc_options.kmax = config.lossless ? 17 : 5; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   if (!WebPValidateConfig(&config)) { | ||||||
|  |     fprintf(stderr, "Error! Invalid configuration.\n"); | ||||||
|  |     goto End; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   if (in_file == NULL) { | ||||||
|  |     fprintf(stderr, "No input file specified!\n"); | ||||||
|  |     Help(); | ||||||
|  |     goto End; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   // Start the decoder object | ||||||
|  |   gif = DGifOpenFileUnicode(in_file, &gif_error); | ||||||
|  |   if (gif == NULL) goto End; | ||||||
|  |  | ||||||
|  |   // Loop over GIF images | ||||||
|  |   done = 0; | ||||||
|  |   do { | ||||||
|  |     GifRecordType type; | ||||||
|  |     if (DGifGetRecordType(gif, &type) == GIF_ERROR) goto End; | ||||||
|  |  | ||||||
|  |     switch (type) { | ||||||
|  |       case IMAGE_DESC_RECORD_TYPE: { | ||||||
|  |         GIFFrameRect gif_rect; | ||||||
|  |         GifImageDesc* const image_desc = &gif->Image; | ||||||
|  |  | ||||||
|  |         if (!DGifGetImageDesc(gif)) goto End; | ||||||
|  |  | ||||||
|  |         if (frame_number == 0) { | ||||||
|  |           if (verbose) { | ||||||
|  |             printf("Canvas screen: %d x %d\n", gif->SWidth, gif->SHeight); | ||||||
|  |           } | ||||||
|  |           // Fix some broken GIF global headers that report | ||||||
|  |           // 0 x 0 screen dimension. | ||||||
|  |           if (gif->SWidth == 0 || gif->SHeight == 0) { | ||||||
|  |             image_desc->Left = 0; | ||||||
|  |             image_desc->Top = 0; | ||||||
|  |             gif->SWidth = image_desc->Width; | ||||||
|  |             gif->SHeight = image_desc->Height; | ||||||
|  |             if (gif->SWidth <= 0 || gif->SHeight <= 0) { | ||||||
|  |               goto End; | ||||||
|  |             } | ||||||
|  |             if (verbose) { | ||||||
|  |               printf("Fixed canvas screen dimension to: %d x %d\n", | ||||||
|  |                      gif->SWidth, gif->SHeight); | ||||||
|  |             } | ||||||
|  |           } | ||||||
|  |           // Allocate current buffer. | ||||||
|  |           frame.width = gif->SWidth; | ||||||
|  |           frame.height = gif->SHeight; | ||||||
|  |           frame.use_argb = 1; | ||||||
|  |           if (!WebPPictureAlloc(&frame)) goto End; | ||||||
|  |           GIFClearPic(&frame, NULL); | ||||||
|  |           if (!(WebPPictureCopy(&frame, &curr_canvas) && | ||||||
|  |                 WebPPictureCopy(&frame, &prev_canvas))) { | ||||||
|  |             fprintf(stderr, "Error allocating canvas.\n"); | ||||||
|  |             goto End; | ||||||
|  |           } | ||||||
|  |  | ||||||
|  |           // Background color. | ||||||
|  |           GIFGetBackgroundColor(gif->SColorMap, gif->SBackGroundColor, | ||||||
|  |                                 transparent_index, | ||||||
|  |                                 &enc_options.anim_params.bgcolor); | ||||||
|  |  | ||||||
|  |           // Initialize encoder. | ||||||
|  |           enc = WebPAnimEncoderNew(curr_canvas.width, curr_canvas.height, | ||||||
|  |                                    &enc_options); | ||||||
|  |           if (enc == NULL) { | ||||||
|  |             fprintf(stderr, | ||||||
|  |                     "Error! Could not create encoder object. Possibly due to " | ||||||
|  |                     "a memory error.\n"); | ||||||
|  |             goto End; | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         // Some even more broken GIF can have sub-rect with zero width/height. | ||||||
|  |         if (image_desc->Width == 0 || image_desc->Height == 0) { | ||||||
|  |           image_desc->Width = gif->SWidth; | ||||||
|  |           image_desc->Height = gif->SHeight; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         if (!GIFReadFrame(gif, transparent_index, &gif_rect, &frame)) { | ||||||
|  |           goto End; | ||||||
|  |         } | ||||||
|  |         // Blend frame rectangle with previous canvas to compose full canvas. | ||||||
|  |         // Note that 'curr_canvas' is same as 'prev_canvas' at this point. | ||||||
|  |         GIFBlendFrames(&frame, &gif_rect, &curr_canvas); | ||||||
|  |  | ||||||
|  |         if (!WebPAnimEncoderAdd(enc, &curr_canvas, frame_timestamp, &config)) { | ||||||
|  |           fprintf(stderr, "Error while adding frame #%d: %s\n", frame_number, | ||||||
|  |                   WebPAnimEncoderGetError(enc)); | ||||||
|  |           goto End; | ||||||
|  |         } else { | ||||||
|  |           ++frame_number; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         // Update canvases. | ||||||
|  |         GIFDisposeFrame(orig_dispose, &gif_rect, &prev_canvas, &curr_canvas); | ||||||
|  |         GIFCopyPixels(&curr_canvas, &prev_canvas); | ||||||
|  |  | ||||||
|  |         // Force frames with a small or no duration to 100ms to be consistent | ||||||
|  |         // with web browsers and other transcoding tools. This also avoids | ||||||
|  |         // incorrect durations between frames when padding frames are | ||||||
|  |         // discarded. | ||||||
|  |         if (frame_duration <= 10) { | ||||||
|  |           frame_duration = 100; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         // Update timestamp (for next frame). | ||||||
|  |         frame_timestamp += frame_duration; | ||||||
|  |  | ||||||
|  |         // In GIF, graphic control extensions are optional for a frame, so we | ||||||
|  |         // may not get one before reading the next frame. To handle this case, | ||||||
|  |         // we reset frame properties to reasonable defaults for the next frame. | ||||||
|  |         orig_dispose = GIF_DISPOSE_NONE; | ||||||
|  |         frame_duration = 0; | ||||||
|  |         transparent_index = GIF_INDEX_INVALID; | ||||||
|  |         break; | ||||||
|  |       } | ||||||
|  |       case EXTENSION_RECORD_TYPE: { | ||||||
|  |         int extension; | ||||||
|  |         GifByteType* data = NULL; | ||||||
|  |         if (DGifGetExtension(gif, &extension, &data) == GIF_ERROR) { | ||||||
|  |           goto End; | ||||||
|  |         } | ||||||
|  |         if (data == NULL) continue; | ||||||
|  |  | ||||||
|  |         switch (extension) { | ||||||
|  |           case COMMENT_EXT_FUNC_CODE: { | ||||||
|  |             break;  // Do nothing for now. | ||||||
|  |           } | ||||||
|  |           case GRAPHICS_EXT_FUNC_CODE: { | ||||||
|  |             if (!GIFReadGraphicsExtension(data, &frame_duration, &orig_dispose, | ||||||
|  |                                           &transparent_index)) { | ||||||
|  |               goto End; | ||||||
|  |             } | ||||||
|  |             break; | ||||||
|  |           } | ||||||
|  |           case PLAINTEXT_EXT_FUNC_CODE: { | ||||||
|  |             break; | ||||||
|  |           } | ||||||
|  |           case APPLICATION_EXT_FUNC_CODE: { | ||||||
|  |             if (data[0] != 11) break;    // Chunk is too short | ||||||
|  |             if (!memcmp(data + 1, "NETSCAPE2.0", 11) || | ||||||
|  |                 !memcmp(data + 1, "ANIMEXTS1.0", 11)) { | ||||||
|  |               if (!GIFReadLoopCount(gif, &data, &loop_count)) { | ||||||
|  |                 goto End; | ||||||
|  |               } | ||||||
|  |               if (verbose) { | ||||||
|  |                 fprintf(stderr, "Loop count: %d\n", loop_count); | ||||||
|  |               } | ||||||
|  |               stored_loop_count = loop_compatibility ? (loop_count != 0) : 1; | ||||||
|  |             } else {  // An extension containing metadata. | ||||||
|  |               // We only store the first encountered chunk of each type, and | ||||||
|  |               // only if requested by the user. | ||||||
|  |               const int is_xmp = (keep_metadata & METADATA_XMP) && | ||||||
|  |                                  !stored_xmp && | ||||||
|  |                                  !memcmp(data + 1, "XMP DataXMP", 11); | ||||||
|  |               const int is_icc = (keep_metadata & METADATA_ICC) && | ||||||
|  |                                  !stored_icc && | ||||||
|  |                                  !memcmp(data + 1, "ICCRGBG1012", 11); | ||||||
|  |               if (is_xmp || is_icc) { | ||||||
|  |                 if (!GIFReadMetadata(gif, &data, | ||||||
|  |                                      is_xmp ? &xmp_data : &icc_data)) { | ||||||
|  |                   goto End; | ||||||
|  |                 } | ||||||
|  |                 if (is_icc) { | ||||||
|  |                   stored_icc = 1; | ||||||
|  |                 } else if (is_xmp) { | ||||||
|  |                   stored_xmp = 1; | ||||||
|  |                 } | ||||||
|  |               } | ||||||
|  |             } | ||||||
|  |             break; | ||||||
|  |           } | ||||||
|  |           default: { | ||||||
|  |             break;  // skip | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |         while (data != NULL) { | ||||||
|  |           if (DGifGetExtensionNext(gif, &data) == GIF_ERROR) goto End; | ||||||
|  |         } | ||||||
|  |         break; | ||||||
|  |       } | ||||||
|  |       case TERMINATE_RECORD_TYPE: { | ||||||
|  |         done = 1; | ||||||
|  |         break; | ||||||
|  |       } | ||||||
|  |       default: { | ||||||
|  |         if (verbose) { | ||||||
|  |           fprintf(stderr, "Skipping over unknown record type %d\n", type); | ||||||
|  |         } | ||||||
|  |         break; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } while (!done); | ||||||
|  |  | ||||||
|  |   // Last NULL frame. | ||||||
|  |   if (!WebPAnimEncoderAdd(enc, NULL, frame_timestamp, NULL)) { | ||||||
|  |     fprintf(stderr, "Error flushing WebP muxer.\n"); | ||||||
|  |     fprintf(stderr, "%s\n", WebPAnimEncoderGetError(enc)); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   if (!WebPAnimEncoderAssemble(enc, &webp_data)) { | ||||||
|  |     fprintf(stderr, "%s\n", WebPAnimEncoderGetError(enc)); | ||||||
|  |     goto End; | ||||||
|  |   } | ||||||
|  |   // If there's only one frame, we don't need to handle loop count. | ||||||
|  |   if (frame_number == 1) { | ||||||
|  |     loop_count = 0; | ||||||
|  |   } else if (!loop_compatibility) { | ||||||
|  |     if (!stored_loop_count) { | ||||||
|  |       // if no loop-count element is seen, the default is '1' (loop-once) | ||||||
|  |       // and we need to signal it explicitly in WebP. Note however that | ||||||
|  |       // in case there's a single frame, we still don't need to store it. | ||||||
|  |       if (frame_number > 1) { | ||||||
|  |         stored_loop_count = 1; | ||||||
|  |         loop_count = 1; | ||||||
|  |       } | ||||||
|  |     } else if (loop_count > 0 && loop_count < 65535) { | ||||||
|  |       // adapt GIF's semantic to WebP's (except in the infinite-loop case) | ||||||
|  |       loop_count += 1; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   // loop_count of 0 is the default (infinite), so no need to signal it | ||||||
|  |   if (loop_count == 0) stored_loop_count = 0; | ||||||
|  |  | ||||||
|  |   if (stored_loop_count || stored_icc || stored_xmp) { | ||||||
|  |     // Re-mux to add loop count and/or metadata as needed. | ||||||
|  |     mux = WebPMuxCreate(&webp_data, 1); | ||||||
|  |     if (mux == NULL) { | ||||||
|  |       fprintf(stderr, "ERROR: Could not re-mux to add loop count/metadata.\n"); | ||||||
|  |       goto End; | ||||||
|  |     } | ||||||
|  |     WebPDataClear(&webp_data); | ||||||
|  |  | ||||||
|  |     if (stored_loop_count) {  // Update loop count. | ||||||
|  |       WebPMuxAnimParams new_params; | ||||||
|  |       err = WebPMuxGetAnimationParams(mux, &new_params); | ||||||
|  |       if (err != WEBP_MUX_OK) { | ||||||
|  |         fprintf(stderr, "ERROR (%s): Could not fetch loop count.\n", | ||||||
|  |                 ErrorString(err)); | ||||||
|  |         goto End; | ||||||
|  |       } | ||||||
|  |       new_params.loop_count = loop_count; | ||||||
|  |       err = WebPMuxSetAnimationParams(mux, &new_params); | ||||||
|  |       if (err != WEBP_MUX_OK) { | ||||||
|  |         fprintf(stderr, "ERROR (%s): Could not update loop count.\n", | ||||||
|  |                 ErrorString(err)); | ||||||
|  |         goto End; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     if (stored_icc) {   // Add ICCP chunk. | ||||||
|  |       err = WebPMuxSetChunk(mux, "ICCP", &icc_data, 1); | ||||||
|  |       if (verbose) { | ||||||
|  |         fprintf(stderr, "ICC size: %d\n", (int)icc_data.size); | ||||||
|  |       } | ||||||
|  |       if (err != WEBP_MUX_OK) { | ||||||
|  |         fprintf(stderr, "ERROR (%s): Could not set ICC chunk.\n", | ||||||
|  |                 ErrorString(err)); | ||||||
|  |         goto End; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     if (stored_xmp) {   // Add XMP chunk. | ||||||
|  |       err = WebPMuxSetChunk(mux, "XMP ", &xmp_data, 1); | ||||||
|  |       if (verbose) { | ||||||
|  |         fprintf(stderr, "XMP size: %d\n", (int)xmp_data.size); | ||||||
|  |       } | ||||||
|  |       if (err != WEBP_MUX_OK) { | ||||||
|  |         fprintf(stderr, "ERROR (%s): Could not set XMP chunk.\n", | ||||||
|  |                 ErrorString(err)); | ||||||
|  |         goto End; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     err = WebPMuxAssemble(mux, &webp_data); | ||||||
|  |     if (err != WEBP_MUX_OK) { | ||||||
|  |       fprintf(stderr, "ERROR (%s): Could not assemble when re-muxing to add " | ||||||
|  |               "loop count/metadata.\n", ErrorString(err)); | ||||||
|  |       goto End; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   if (out_file != NULL) { | ||||||
|  |     if (!ImgIoUtilWriteFile((const char*)out_file, webp_data.bytes, | ||||||
|  |                             webp_data.size)) { | ||||||
|  |       WFPRINTF(stderr, "Error writing output file: %s\n", out_file); | ||||||
|  |       goto End; | ||||||
|  |     } | ||||||
|  |     if (!quiet) { | ||||||
|  |       if (!WSTRCMP(out_file, "-")) { | ||||||
|  |         fprintf(stderr, "Saved %d bytes to STDIO\n", | ||||||
|  |                 (int)webp_data.size); | ||||||
|  |       } else { | ||||||
|  |         WFPRINTF(stderr, "Saved output file (%d bytes): %s\n", | ||||||
|  |                  (int)webp_data.size, out_file); | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } else { | ||||||
|  |     if (!quiet) { | ||||||
|  |       fprintf(stderr, "Nothing written; use -o flag to save the result " | ||||||
|  |                       "(%d bytes).\n", (int)webp_data.size); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   // All OK. | ||||||
|  |   ok = 1; | ||||||
|  |   gif_error = GIF_OK; | ||||||
|  |  | ||||||
|  |  End: | ||||||
|  |   WebPDataClear(&icc_data); | ||||||
|  |   WebPDataClear(&xmp_data); | ||||||
|  |   WebPMuxDelete(mux); | ||||||
|  |   WebPDataClear(&webp_data); | ||||||
|  |   WebPPictureFree(&frame); | ||||||
|  |   WebPPictureFree(&curr_canvas); | ||||||
|  |   WebPPictureFree(&prev_canvas); | ||||||
|  |   WebPAnimEncoderDelete(enc); | ||||||
|  |  | ||||||
|  |   if (gif_error != GIF_OK) { | ||||||
|  |     GIFDisplayError(gif, gif_error); | ||||||
|  |   } | ||||||
|  |   if (gif != NULL) { | ||||||
|  | #if LOCAL_GIF_PREREQ(5,1) | ||||||
|  |     DGifCloseFile(gif, &gif_error); | ||||||
|  | #else | ||||||
|  |     DGifCloseFile(gif); | ||||||
|  | #endif | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   FREE_WARGV_AND_RETURN(!ok); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #else  // !WEBP_HAVE_GIF | ||||||
|  |  | ||||||
|  | int main(int argc, const char* argv[]) { | ||||||
|  |   fprintf(stderr, "GIF support not enabled in %s.\n", argv[0]); | ||||||
|  |   (void)argc; | ||||||
|  |   return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | //------------------------------------------------------------------------------ | ||||||
							
								
								
									
										416
									
								
								external/libwebp/libwebp/examples/gifdec.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										416
									
								
								external/libwebp/libwebp/examples/gifdec.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,416 @@ | |||||||
|  | // Copyright 2012 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. | ||||||
|  | // ----------------------------------------------------------------------------- | ||||||
|  | // | ||||||
|  | // GIF decode. | ||||||
|  |  | ||||||
|  | #include "./gifdec.h" | ||||||
|  |  | ||||||
|  | #include <stdio.h> | ||||||
|  |  | ||||||
|  | #ifdef WEBP_HAVE_GIF | ||||||
|  | #include <assert.h> | ||||||
|  | #include <stdlib.h> | ||||||
|  | #include <string.h> | ||||||
|  |  | ||||||
|  | #include "webp/encode.h" | ||||||
|  | #include "webp/mux_types.h" | ||||||
|  |  | ||||||
|  | #define GIF_TRANSPARENT_COLOR 0x00000000u | ||||||
|  | #define GIF_WHITE_COLOR       0xffffffffu | ||||||
|  | #define GIF_TRANSPARENT_MASK  0x01 | ||||||
|  | #define GIF_DISPOSE_MASK      0x07 | ||||||
|  | #define GIF_DISPOSE_SHIFT     2 | ||||||
|  |  | ||||||
|  | // from utils/utils.h | ||||||
|  | #ifdef __cplusplus | ||||||
|  | extern "C" { | ||||||
|  | #endif | ||||||
|  | extern void WebPCopyPlane(const uint8_t* src, int src_stride, | ||||||
|  |                           uint8_t* dst, int dst_stride, | ||||||
|  |                           int width, int height); | ||||||
|  | extern void WebPCopyPixels(const WebPPicture* const src, | ||||||
|  |                            WebPPicture* const dst); | ||||||
|  | #ifdef __cplusplus | ||||||
|  | } | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | void GIFGetBackgroundColor(const ColorMapObject* const color_map, | ||||||
|  |                            int bgcolor_index, int transparent_index, | ||||||
|  |                            uint32_t* const bgcolor) { | ||||||
|  |   if (transparent_index != GIF_INDEX_INVALID && | ||||||
|  |       bgcolor_index == transparent_index) { | ||||||
|  |     *bgcolor = GIF_TRANSPARENT_COLOR;  // Special case. | ||||||
|  |   } else if (color_map == NULL || color_map->Colors == NULL | ||||||
|  |              || bgcolor_index >= color_map->ColorCount) { | ||||||
|  |     *bgcolor = GIF_WHITE_COLOR; | ||||||
|  |     fprintf(stderr, | ||||||
|  |             "GIF decode warning: invalid background color index. Assuming " | ||||||
|  |             "white background.\n"); | ||||||
|  |   } else { | ||||||
|  |     const GifColorType color = color_map->Colors[bgcolor_index]; | ||||||
|  |     *bgcolor = (0xffu       << 24) | ||||||
|  |              | (color.Red   << 16) | ||||||
|  |              | (color.Green <<  8) | ||||||
|  |              | (color.Blue  <<  0); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int GIFReadGraphicsExtension(const GifByteType* const buf, int* const duration, | ||||||
|  |                              GIFDisposeMethod* const dispose, | ||||||
|  |                              int* const transparent_index) { | ||||||
|  |   const int flags = buf[1]; | ||||||
|  |   const int dispose_raw = (flags >> GIF_DISPOSE_SHIFT) & GIF_DISPOSE_MASK; | ||||||
|  |   const int duration_raw = buf[2] | (buf[3] << 8);  // In 10 ms units. | ||||||
|  |   if (buf[0] != 4) return 0; | ||||||
|  |   *duration = duration_raw * 10;  // Duration is in 1 ms units. | ||||||
|  |   switch (dispose_raw) { | ||||||
|  |     case 3: | ||||||
|  |       *dispose = GIF_DISPOSE_RESTORE_PREVIOUS; | ||||||
|  |       break; | ||||||
|  |     case 2: | ||||||
|  |       *dispose = GIF_DISPOSE_BACKGROUND; | ||||||
|  |       break; | ||||||
|  |     case 1: | ||||||
|  |     case 0: | ||||||
|  |     default: | ||||||
|  |       *dispose = GIF_DISPOSE_NONE; | ||||||
|  |       break; | ||||||
|  |   } | ||||||
|  |   *transparent_index = | ||||||
|  |       (flags & GIF_TRANSPARENT_MASK) ? buf[4] : GIF_INDEX_INVALID; | ||||||
|  |   return 1; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static int Remap(const GifFileType* const gif, const uint8_t* const src, | ||||||
|  |                  int len, int transparent_index, uint32_t* dst) { | ||||||
|  |   int i; | ||||||
|  |   const GifColorType* colors; | ||||||
|  |   const ColorMapObject* const cmap = | ||||||
|  |       gif->Image.ColorMap ? gif->Image.ColorMap : gif->SColorMap; | ||||||
|  |   if (cmap == NULL) return 1; | ||||||
|  |   if (cmap->Colors == NULL || cmap->ColorCount <= 0) return 0; | ||||||
|  |   colors = cmap->Colors; | ||||||
|  |  | ||||||
|  |   for (i = 0; i < len; ++i) { | ||||||
|  |     if (src[i] == transparent_index) { | ||||||
|  |       dst[i] = GIF_TRANSPARENT_COLOR; | ||||||
|  |     } else if (src[i] < cmap->ColorCount) { | ||||||
|  |       const GifColorType c = colors[src[i]]; | ||||||
|  |       dst[i] = c.Blue | (c.Green << 8) | (c.Red << 16) | (0xffu << 24); | ||||||
|  |     } else { | ||||||
|  |       return 0; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   return 1; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int GIFReadFrame(GifFileType* const gif, int transparent_index, | ||||||
|  |                  GIFFrameRect* const gif_rect, WebPPicture* const picture) { | ||||||
|  |   WebPPicture sub_image; | ||||||
|  |   const GifImageDesc* const image_desc = &gif->Image; | ||||||
|  |   uint32_t* dst = NULL; | ||||||
|  |   uint8_t* tmp = NULL; | ||||||
|  |   const GIFFrameRect rect = { | ||||||
|  |       image_desc->Left, image_desc->Top, image_desc->Width, image_desc->Height | ||||||
|  |   }; | ||||||
|  |   const uint64_t memory_needed = 4 * rect.width * (uint64_t)rect.height; | ||||||
|  |   int ok = 0; | ||||||
|  |   *gif_rect = rect; | ||||||
|  |  | ||||||
|  |   if (memory_needed != (size_t)memory_needed || memory_needed > (4ULL << 32)) { | ||||||
|  |     fprintf(stderr, "Image is too large (%d x %d).", rect.width, rect.height); | ||||||
|  |     return 0; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   // Use a view for the sub-picture: | ||||||
|  |   if (!WebPPictureView(picture, rect.x_offset, rect.y_offset, | ||||||
|  |                        rect.width, rect.height, &sub_image)) { | ||||||
|  |     fprintf(stderr, "Sub-image %dx%d at position %d,%d is invalid!\n", | ||||||
|  |             rect.width, rect.height, rect.x_offset, rect.y_offset); | ||||||
|  |     return 0; | ||||||
|  |   } | ||||||
|  |   dst = sub_image.argb; | ||||||
|  |  | ||||||
|  |   tmp = (uint8_t*)WebPMalloc(rect.width * sizeof(*tmp)); | ||||||
|  |   if (tmp == NULL) goto End; | ||||||
|  |  | ||||||
|  |   if (image_desc->Interlace) {  // Interlaced image. | ||||||
|  |     // We need 4 passes, with the following offsets and jumps. | ||||||
|  |     const int interlace_offsets[] = { 0, 4, 2, 1 }; | ||||||
|  |     const int interlace_jumps[]   = { 8, 8, 4, 2 }; | ||||||
|  |     int pass; | ||||||
|  |     for (pass = 0; pass < 4; ++pass) { | ||||||
|  |       const size_t stride = (size_t)sub_image.argb_stride; | ||||||
|  |       int y = interlace_offsets[pass]; | ||||||
|  |       uint32_t* row = dst + y * stride; | ||||||
|  |       const size_t jump = interlace_jumps[pass] * stride; | ||||||
|  |       for (; y < rect.height; y += interlace_jumps[pass], row += jump) { | ||||||
|  |         if (DGifGetLine(gif, tmp, rect.width) == GIF_ERROR) goto End; | ||||||
|  |         if (!Remap(gif, tmp, rect.width, transparent_index, row)) goto End; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } else {  // Non-interlaced image. | ||||||
|  |     int y; | ||||||
|  |     uint32_t* ptr = dst; | ||||||
|  |     for (y = 0; y < rect.height; ++y, ptr += sub_image.argb_stride) { | ||||||
|  |       if (DGifGetLine(gif, tmp, rect.width) == GIF_ERROR) goto End; | ||||||
|  |       if (!Remap(gif, tmp, rect.width, transparent_index, ptr)) goto End; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   ok = 1; | ||||||
|  |  | ||||||
|  |  End: | ||||||
|  |   if (!ok) picture->error_code = sub_image.error_code; | ||||||
|  |   WebPPictureFree(&sub_image); | ||||||
|  |   WebPFree(tmp); | ||||||
|  |   return ok; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int GIFReadLoopCount(GifFileType* const gif, GifByteType** const buf, | ||||||
|  |                      int* const loop_count) { | ||||||
|  |   assert(!memcmp(*buf + 1, "NETSCAPE2.0", 11) || | ||||||
|  |          !memcmp(*buf + 1, "ANIMEXTS1.0", 11)); | ||||||
|  |   if (DGifGetExtensionNext(gif, buf) == GIF_ERROR) { | ||||||
|  |     return 0; | ||||||
|  |   } | ||||||
|  |   if (*buf == NULL) { | ||||||
|  |     return 0;  // Loop count sub-block missing. | ||||||
|  |   } | ||||||
|  |   if ((*buf)[0] < 3 || (*buf)[1] != 1) { | ||||||
|  |     return 0;   // wrong size/marker | ||||||
|  |   } | ||||||
|  |   *loop_count = (*buf)[2] | ((*buf)[3] << 8); | ||||||
|  |   return 1; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int GIFReadMetadata(GifFileType* const gif, GifByteType** const buf, | ||||||
|  |                     WebPData* const metadata) { | ||||||
|  |   const int is_xmp = !memcmp(*buf + 1, "XMP DataXMP", 11); | ||||||
|  |   const int is_icc = !memcmp(*buf + 1, "ICCRGBG1012", 11); | ||||||
|  |   assert(is_xmp || is_icc); | ||||||
|  |   (void)is_icc;  // silence unused warning. | ||||||
|  |   // Construct metadata from sub-blocks. | ||||||
|  |   // Usual case (including ICC profile): In each sub-block, the | ||||||
|  |   // first byte specifies its size in bytes (0 to 255) and the | ||||||
|  |   // rest of the bytes contain the data. | ||||||
|  |   // Special case for XMP data: In each sub-block, the first byte | ||||||
|  |   // is also part of the XMP payload. XMP in GIF also has a 257 | ||||||
|  |   // byte padding data. See the XMP specification for details. | ||||||
|  |   while (1) { | ||||||
|  |     WebPData subblock; | ||||||
|  |     const uint8_t* tmp; | ||||||
|  |     if (DGifGetExtensionNext(gif, buf) == GIF_ERROR) { | ||||||
|  |       return 0; | ||||||
|  |     } | ||||||
|  |     if (*buf == NULL) break;  // Finished. | ||||||
|  |     subblock.size = is_xmp ? (*buf)[0] + 1 : (*buf)[0]; | ||||||
|  |     assert(subblock.size > 0); | ||||||
|  |     subblock.bytes = is_xmp ? *buf : *buf + 1; | ||||||
|  |     // Note: We store returned value in 'tmp' first, to avoid | ||||||
|  |     // leaking old memory in metadata->bytes on error. | ||||||
|  |     tmp = (uint8_t*)realloc((void*)metadata->bytes, | ||||||
|  |                             metadata->size + subblock.size); | ||||||
|  |     if (tmp == NULL) { | ||||||
|  |       return 0; | ||||||
|  |     } | ||||||
|  |     memcpy((void*)(tmp + metadata->size), | ||||||
|  |            subblock.bytes, subblock.size); | ||||||
|  |     metadata->bytes = tmp; | ||||||
|  |     metadata->size += subblock.size; | ||||||
|  |   } | ||||||
|  |   if (is_xmp) { | ||||||
|  |     // XMP padding data is 0x01, 0xff, 0xfe ... 0x01, 0x00. | ||||||
|  |     const size_t xmp_pading_size = 257; | ||||||
|  |     if (metadata->size > xmp_pading_size) { | ||||||
|  |       metadata->size -= xmp_pading_size; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   return 1; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static void ClearRectangle(WebPPicture* const picture, | ||||||
|  |                            int left, int top, int width, int height) { | ||||||
|  |   int i, j; | ||||||
|  |   const size_t stride = picture->argb_stride; | ||||||
|  |   uint32_t* dst = picture->argb + top * stride + left; | ||||||
|  |   for (j = 0; j < height; ++j, dst += stride) { | ||||||
|  |     for (i = 0; i < width; ++i) dst[i] = GIF_TRANSPARENT_COLOR; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void GIFClearPic(WebPPicture* const pic, const GIFFrameRect* const rect) { | ||||||
|  |   if (rect != NULL) { | ||||||
|  |     ClearRectangle(pic, rect->x_offset, rect->y_offset, | ||||||
|  |                    rect->width, rect->height); | ||||||
|  |   } else { | ||||||
|  |     ClearRectangle(pic, 0, 0, pic->width, pic->height); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void GIFCopyPixels(const WebPPicture* const src, WebPPicture* const dst) { | ||||||
|  |   WebPCopyPixels(src, dst); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void GIFDisposeFrame(GIFDisposeMethod dispose, const GIFFrameRect* const rect, | ||||||
|  |                      const WebPPicture* const prev_canvas, | ||||||
|  |                      WebPPicture* const curr_canvas) { | ||||||
|  |   assert(rect != NULL); | ||||||
|  |   if (dispose == GIF_DISPOSE_BACKGROUND) { | ||||||
|  |     GIFClearPic(curr_canvas, rect); | ||||||
|  |   } else if (dispose == GIF_DISPOSE_RESTORE_PREVIOUS) { | ||||||
|  |     const size_t src_stride = prev_canvas->argb_stride; | ||||||
|  |     const uint32_t* const src = prev_canvas->argb + rect->x_offset | ||||||
|  |                               + rect->y_offset * src_stride; | ||||||
|  |     const size_t dst_stride = curr_canvas->argb_stride; | ||||||
|  |     uint32_t* const dst = curr_canvas->argb + rect->x_offset | ||||||
|  |                         + rect->y_offset * dst_stride; | ||||||
|  |     assert(prev_canvas != NULL); | ||||||
|  |     WebPCopyPlane((uint8_t*)src, (int)(4 * src_stride), | ||||||
|  |                   (uint8_t*)dst, (int)(4 * dst_stride), | ||||||
|  |                   4 * rect->width, rect->height); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void GIFBlendFrames(const WebPPicture* const src, | ||||||
|  |                     const GIFFrameRect* const rect, WebPPicture* const dst) { | ||||||
|  |   int i, j; | ||||||
|  |   const size_t src_stride = src->argb_stride; | ||||||
|  |   const size_t dst_stride = dst->argb_stride; | ||||||
|  |   assert(src->width == dst->width && src->height == dst->height); | ||||||
|  |   for (j = rect->y_offset; j < rect->y_offset + rect->height; ++j) { | ||||||
|  |     for (i = rect->x_offset; i < rect->x_offset + rect->width; ++i) { | ||||||
|  |       const uint32_t src_pixel = src->argb[j * src_stride + i]; | ||||||
|  |       const int src_alpha = src_pixel >> 24; | ||||||
|  |       if (src_alpha != 0) { | ||||||
|  |         dst->argb[j * dst_stride + i] = src_pixel; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void GIFDisplayError(const GifFileType* const gif, int gif_error) { | ||||||
|  |   // libgif 4.2.0 has retired PrintGifError() and added GifErrorString(). | ||||||
|  | #if LOCAL_GIF_PREREQ(4,2) | ||||||
|  | #if LOCAL_GIF_PREREQ(5,0) | ||||||
|  |   // Static string actually, hence the const char* cast. | ||||||
|  |   const char* error_str = (const char*)GifErrorString( | ||||||
|  |       (gif == NULL) ? gif_error : gif->Error); | ||||||
|  | #else | ||||||
|  |   const char* error_str = (const char*)GifErrorString(); | ||||||
|  |   (void)gif; | ||||||
|  | #endif | ||||||
|  |   if (error_str == NULL) error_str = "Unknown error"; | ||||||
|  |   fprintf(stderr, "GIFLib Error %d: %s\n", gif_error, error_str); | ||||||
|  | #else | ||||||
|  |   (void)gif; | ||||||
|  |   fprintf(stderr, "GIFLib Error %d: ", gif_error); | ||||||
|  |   PrintGifError(); | ||||||
|  |   fprintf(stderr, "\n"); | ||||||
|  | #endif | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #else  // !WEBP_HAVE_GIF | ||||||
|  |  | ||||||
|  | static void ErrorGIFNotAvailable() { | ||||||
|  |   fprintf(stderr, "GIF support not compiled. Please install the libgif-dev " | ||||||
|  |           "package before building.\n"); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void GIFGetBackgroundColor(const struct ColorMapObject* const color_map, | ||||||
|  |                            int bgcolor_index, int transparent_index, | ||||||
|  |                            uint32_t* const bgcolor) { | ||||||
|  |   (void)color_map; | ||||||
|  |   (void)bgcolor_index; | ||||||
|  |   (void)transparent_index; | ||||||
|  |   (void)bgcolor; | ||||||
|  |   ErrorGIFNotAvailable(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int GIFReadGraphicsExtension(const GifByteType* const data, int* const duration, | ||||||
|  |                              GIFDisposeMethod* const dispose, | ||||||
|  |                              int* const transparent_index) { | ||||||
|  |   (void)data; | ||||||
|  |   (void)duration; | ||||||
|  |   (void)dispose; | ||||||
|  |   (void)transparent_index; | ||||||
|  |   ErrorGIFNotAvailable(); | ||||||
|  |   return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int GIFReadFrame(struct GifFileType* const gif, int transparent_index, | ||||||
|  |                  GIFFrameRect* const gif_rect, | ||||||
|  |                  struct WebPPicture* const picture) { | ||||||
|  |   (void)gif; | ||||||
|  |   (void)transparent_index; | ||||||
|  |   (void)gif_rect; | ||||||
|  |   (void)picture; | ||||||
|  |   ErrorGIFNotAvailable(); | ||||||
|  |   return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int GIFReadLoopCount(struct GifFileType* const gif, GifByteType** const buf, | ||||||
|  |                      int* const loop_count) { | ||||||
|  |   (void)gif; | ||||||
|  |   (void)buf; | ||||||
|  |   (void)loop_count; | ||||||
|  |   ErrorGIFNotAvailable(); | ||||||
|  |   return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int GIFReadMetadata(struct GifFileType* const gif, GifByteType** const buf, | ||||||
|  |                     struct WebPData* const metadata) { | ||||||
|  |   (void)gif; | ||||||
|  |   (void)buf; | ||||||
|  |   (void)metadata; | ||||||
|  |   ErrorGIFNotAvailable(); | ||||||
|  |   return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void GIFDisposeFrame(GIFDisposeMethod dispose, const GIFFrameRect* const rect, | ||||||
|  |                      const struct WebPPicture* const prev_canvas, | ||||||
|  |                      struct WebPPicture* const curr_canvas) { | ||||||
|  |   (void)dispose; | ||||||
|  |   (void)rect; | ||||||
|  |   (void)prev_canvas; | ||||||
|  |   (void)curr_canvas; | ||||||
|  |   ErrorGIFNotAvailable(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void GIFBlendFrames(const struct WebPPicture* const src, | ||||||
|  |                     const GIFFrameRect* const rect, | ||||||
|  |                     struct WebPPicture* const dst) { | ||||||
|  |   (void)src; | ||||||
|  |   (void)rect; | ||||||
|  |   (void)dst; | ||||||
|  |   ErrorGIFNotAvailable(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void GIFDisplayError(const struct GifFileType* const gif, int gif_error) { | ||||||
|  |   (void)gif; | ||||||
|  |   (void)gif_error; | ||||||
|  |   ErrorGIFNotAvailable(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void GIFClearPic(struct WebPPicture* const pic, | ||||||
|  |                  const GIFFrameRect* const rect) { | ||||||
|  |   (void)pic; | ||||||
|  |   (void)rect; | ||||||
|  |   ErrorGIFNotAvailable(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void GIFCopyPixels(const struct WebPPicture* const src, | ||||||
|  |                    struct WebPPicture* const dst) { | ||||||
|  |   (void)src; | ||||||
|  |   (void)dst; | ||||||
|  |   ErrorGIFNotAvailable(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #endif  // WEBP_HAVE_GIF | ||||||
|  |  | ||||||
|  | // ----------------------------------------------------------------------------- | ||||||
							
								
								
									
										116
									
								
								external/libwebp/libwebp/examples/gifdec.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										116
									
								
								external/libwebp/libwebp/examples/gifdec.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,116 @@ | |||||||
|  | // Copyright 2014 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. | ||||||
|  | // ----------------------------------------------------------------------------- | ||||||
|  | // | ||||||
|  | // GIF decode. | ||||||
|  |  | ||||||
|  | #ifndef WEBP_EXAMPLES_GIFDEC_H_ | ||||||
|  | #define WEBP_EXAMPLES_GIFDEC_H_ | ||||||
|  |  | ||||||
|  | #include <stdio.h> | ||||||
|  | #include "webp/types.h" | ||||||
|  |  | ||||||
|  | #ifdef HAVE_CONFIG_H | ||||||
|  | #include "webp/config.h" | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | #ifdef WEBP_HAVE_GIF | ||||||
|  | #include <gif_lib.h> | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | #ifdef __cplusplus | ||||||
|  | extern "C" { | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | // GIFLIB_MAJOR is only defined in libgif >= 4.2.0. | ||||||
|  | #if defined(GIFLIB_MAJOR) && defined(GIFLIB_MINOR) | ||||||
|  | # define LOCAL_GIF_VERSION ((GIFLIB_MAJOR << 8) | GIFLIB_MINOR) | ||||||
|  | # define LOCAL_GIF_PREREQ(maj, min) \ | ||||||
|  |     (LOCAL_GIF_VERSION >= (((maj) << 8) | (min))) | ||||||
|  | #else | ||||||
|  | # define LOCAL_GIF_VERSION 0 | ||||||
|  | # define LOCAL_GIF_PREREQ(maj, min) 0 | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | #define GIF_INDEX_INVALID (-1) | ||||||
|  |  | ||||||
|  | typedef enum GIFDisposeMethod { | ||||||
|  |   GIF_DISPOSE_NONE, | ||||||
|  |   GIF_DISPOSE_BACKGROUND, | ||||||
|  |   GIF_DISPOSE_RESTORE_PREVIOUS | ||||||
|  | } GIFDisposeMethod; | ||||||
|  |  | ||||||
|  | typedef struct { | ||||||
|  |   int x_offset, y_offset, width, height; | ||||||
|  | } GIFFrameRect; | ||||||
|  |  | ||||||
|  | struct WebPData; | ||||||
|  | struct WebPPicture; | ||||||
|  |  | ||||||
|  | #ifndef WEBP_HAVE_GIF | ||||||
|  | struct ColorMapObject; | ||||||
|  | struct GifFileType; | ||||||
|  | typedef unsigned char GifByteType; | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | // Given the index of background color and transparent color, returns the | ||||||
|  | // corresponding background color (in BGRA format) in 'bgcolor'. | ||||||
|  | void GIFGetBackgroundColor(const struct ColorMapObject* const color_map, | ||||||
|  |                            int bgcolor_index, int transparent_index, | ||||||
|  |                            uint32_t* const bgcolor); | ||||||
|  |  | ||||||
|  | // Parses the given graphics extension data to get frame duration (in 1ms | ||||||
|  | // units), dispose method and transparent color index. | ||||||
|  | // Returns true on success. | ||||||
|  | int GIFReadGraphicsExtension(const GifByteType* const buf, int* const duration, | ||||||
|  |                              GIFDisposeMethod* const dispose, | ||||||
|  |                              int* const transparent_index); | ||||||
|  |  | ||||||
|  | // Reads the next GIF frame from 'gif' into 'picture'. Also, returns the GIF | ||||||
|  | // frame dimensions and offsets in 'rect'. | ||||||
|  | // Returns true on success. | ||||||
|  | int GIFReadFrame(struct GifFileType* const gif, int transparent_index, | ||||||
|  |                  GIFFrameRect* const gif_rect, | ||||||
|  |                  struct WebPPicture* const picture); | ||||||
|  |  | ||||||
|  | // Parses loop count from the given Netscape extension data. | ||||||
|  | int GIFReadLoopCount(struct GifFileType* const gif, GifByteType** const buf, | ||||||
|  |                      int* const loop_count); | ||||||
|  |  | ||||||
|  | // Parses the given ICC or XMP extension data and stores it into 'metadata'. | ||||||
|  | // Returns true on success. | ||||||
|  | int GIFReadMetadata(struct GifFileType* const gif, GifByteType** const buf, | ||||||
|  |                     struct WebPData* const metadata); | ||||||
|  |  | ||||||
|  | // Dispose the pixels within 'rect' of 'curr_canvas' based on 'dispose' method | ||||||
|  | // and 'prev_canvas'. | ||||||
|  | void GIFDisposeFrame(GIFDisposeMethod dispose, const GIFFrameRect* const rect, | ||||||
|  |                      const struct WebPPicture* const prev_canvas, | ||||||
|  |                      struct WebPPicture* const curr_canvas); | ||||||
|  |  | ||||||
|  | // Given 'src' picture and its frame rectangle 'rect', blend it into 'dst'. | ||||||
|  | void GIFBlendFrames(const struct WebPPicture* const src, | ||||||
|  |                     const GIFFrameRect* const rect, | ||||||
|  |                     struct WebPPicture* const dst); | ||||||
|  |  | ||||||
|  | // Prints an error string based on 'gif_error'. | ||||||
|  | void GIFDisplayError(const struct GifFileType* const gif, int gif_error); | ||||||
|  |  | ||||||
|  | // In the given 'pic', clear the pixels in 'rect' to transparent color. | ||||||
|  | void GIFClearPic(struct WebPPicture* const pic, const GIFFrameRect* const rect); | ||||||
|  |  | ||||||
|  | // Copy pixels from 'src' to 'dst' honoring strides. 'src' and 'dst' are assumed | ||||||
|  | // to be already allocated. | ||||||
|  | void GIFCopyPixels(const struct WebPPicture* const src, | ||||||
|  |                    struct WebPPicture* const dst); | ||||||
|  |  | ||||||
|  | #ifdef __cplusplus | ||||||
|  | }    // extern "C" | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | #endif  // WEBP_EXAMPLES_GIFDEC_H_ | ||||||
							
								
								
									
										339
									
								
								external/libwebp/libwebp/examples/img2webp.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										339
									
								
								external/libwebp/libwebp/examples/img2webp.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,339 @@ | |||||||
|  | // Copyright 2016 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. | ||||||
|  | // ----------------------------------------------------------------------------- | ||||||
|  | // | ||||||
|  | //  generate an animated WebP out of a sequence of images | ||||||
|  | //  (PNG, JPEG, ...) | ||||||
|  | // | ||||||
|  | //  Example usage: | ||||||
|  | //     img2webp -o out.webp -q 40 -mixed -duration 40 input??.png | ||||||
|  | // | ||||||
|  | // Author: skal@google.com (Pascal Massimino) | ||||||
|  |  | ||||||
|  | #include <stdio.h> | ||||||
|  | #include <stdlib.h> | ||||||
|  | #include <string.h> | ||||||
|  |  | ||||||
|  | #ifdef HAVE_CONFIG_H | ||||||
|  | #include "webp/config.h" | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | #include "../examples/example_util.h" | ||||||
|  | #include "../imageio/image_dec.h" | ||||||
|  | #include "../imageio/imageio_util.h" | ||||||
|  | #include "./stopwatch.h" | ||||||
|  | #include "./unicode.h" | ||||||
|  | #include "sharpyuv/sharpyuv.h" | ||||||
|  | #include "webp/encode.h" | ||||||
|  | #include "webp/mux.h" | ||||||
|  |  | ||||||
|  | //------------------------------------------------------------------------------ | ||||||
|  |  | ||||||
|  | static void Help(void) { | ||||||
|  |   printf("Usage:\n\n"); | ||||||
|  |   printf("  img2webp [file_options] [[frame_options] frame_file]..."); | ||||||
|  |   printf(" [-o webp_file]\n\n"); | ||||||
|  |  | ||||||
|  |   printf("File-level options (only used at the start of compression):\n"); | ||||||
|  |   printf(" -min_size ............ minimize size\n"); | ||||||
|  |   printf(" -kmax <int> .......... maximum number of frame between key-frames\n" | ||||||
|  |          "                        (0=only keyframes)\n"); | ||||||
|  |   printf(" -kmin <int> .......... minimum number of frame between key-frames\n" | ||||||
|  |          "                        (0=disable key-frames altogether)\n"); | ||||||
|  |   printf(" -mixed ............... use mixed lossy/lossless automatic mode\n"); | ||||||
|  |   printf(" -near_lossless <int> . use near-lossless image preprocessing\n" | ||||||
|  |          "                        (0..100=off), default=100\n"); | ||||||
|  |   printf(" -sharp_yuv ........... use sharper (and slower) RGB->YUV " | ||||||
|  |                                   "conversion\n                        " | ||||||
|  |                                   "(lossy only)\n"); | ||||||
|  |   printf(" -loop <int> .......... loop count (default: 0, = infinite loop)\n"); | ||||||
|  |   printf(" -v ................... verbose mode\n"); | ||||||
|  |   printf(" -h ................... this help\n"); | ||||||
|  |   printf(" -version ............. print version number and exit\n"); | ||||||
|  |   printf("\n"); | ||||||
|  |  | ||||||
|  |   printf("Per-frame options (only used for subsequent images input):\n"); | ||||||
|  |   printf(" -d <int> ............. frame duration in ms (default: 100)\n"); | ||||||
|  |   printf(" -lossless  ........... use lossless mode (default)\n"); | ||||||
|  |   printf(" -lossy ... ........... use lossy mode\n"); | ||||||
|  |   printf(" -q <float> ........... quality\n"); | ||||||
|  |   printf(" -m <int> ............. method to use\n"); | ||||||
|  |  | ||||||
|  |   printf("\n"); | ||||||
|  |   printf("example: img2webp -loop 2 in0.png -lossy in1.jpg\n" | ||||||
|  |          "                  -d 80 in2.tiff -o out.webp\n"); | ||||||
|  |   printf("\nNote: if a single file name is passed as the argument, the " | ||||||
|  |          "arguments will be\n"); | ||||||
|  |   printf("tokenized from this file. The file name must not start with " | ||||||
|  |          "the character '-'.\n"); | ||||||
|  |   printf("\nSupported input formats:\n  %s\n", | ||||||
|  |          WebPGetEnabledInputFileFormats()); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | //------------------------------------------------------------------------------ | ||||||
|  |  | ||||||
|  | static int ReadImage(const char filename[], WebPPicture* const pic) { | ||||||
|  |   const uint8_t* data = NULL; | ||||||
|  |   size_t data_size = 0; | ||||||
|  |   WebPImageReader reader; | ||||||
|  |   int ok; | ||||||
|  | #ifdef HAVE_WINCODEC_H | ||||||
|  |   // Try to decode the file using WIC falling back to the other readers for | ||||||
|  |   // e.g., WebP. | ||||||
|  |   ok = ReadPictureWithWIC(filename, pic, 1, NULL); | ||||||
|  |   if (ok) return 1; | ||||||
|  | #endif | ||||||
|  |   if (!ImgIoUtilReadFile(filename, &data, &data_size)) return 0; | ||||||
|  |   reader = WebPGuessImageReader(data, data_size); | ||||||
|  |   ok = reader(data, data_size, pic, 1, NULL); | ||||||
|  |   WebPFree((void*)data); | ||||||
|  |   return ok; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static int SetLoopCount(int loop_count, WebPData* const webp_data) { | ||||||
|  |   int ok = 1; | ||||||
|  |   WebPMuxError err; | ||||||
|  |   uint32_t features; | ||||||
|  |   WebPMuxAnimParams new_params; | ||||||
|  |   WebPMux* const mux = WebPMuxCreate(webp_data, 1); | ||||||
|  |   if (mux == NULL) return 0; | ||||||
|  |  | ||||||
|  |   err = WebPMuxGetFeatures(mux, &features); | ||||||
|  |   ok = (err == WEBP_MUX_OK); | ||||||
|  |   if (!ok || !(features & ANIMATION_FLAG)) goto End; | ||||||
|  |  | ||||||
|  |   err = WebPMuxGetAnimationParams(mux, &new_params); | ||||||
|  |   ok = (err == WEBP_MUX_OK); | ||||||
|  |   if (ok) { | ||||||
|  |     new_params.loop_count = loop_count; | ||||||
|  |     err = WebPMuxSetAnimationParams(mux, &new_params); | ||||||
|  |     ok = (err == WEBP_MUX_OK); | ||||||
|  |   } | ||||||
|  |   if (ok) { | ||||||
|  |     WebPDataClear(webp_data); | ||||||
|  |     err = WebPMuxAssemble(mux, webp_data); | ||||||
|  |     ok = (err == WEBP_MUX_OK); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |  End: | ||||||
|  |   WebPMuxDelete(mux); | ||||||
|  |   if (!ok) { | ||||||
|  |     fprintf(stderr, "Error during loop-count setting\n"); | ||||||
|  |   } | ||||||
|  |   return ok; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | //------------------------------------------------------------------------------ | ||||||
|  |  | ||||||
|  | int main(int argc, const char* argv[]) { | ||||||
|  |   const char* output = NULL; | ||||||
|  |   WebPAnimEncoder* enc = NULL; | ||||||
|  |   int verbose = 0; | ||||||
|  |   int pic_num = 0; | ||||||
|  |   int duration = 100; | ||||||
|  |   int timestamp_ms = 0; | ||||||
|  |   int loop_count = 0; | ||||||
|  |   int width = 0, height = 0; | ||||||
|  |   WebPAnimEncoderOptions anim_config; | ||||||
|  |   WebPConfig config; | ||||||
|  |   WebPPicture pic; | ||||||
|  |   WebPData webp_data; | ||||||
|  |   int c; | ||||||
|  |   int have_input = 0; | ||||||
|  |   CommandLineArguments cmd_args; | ||||||
|  |   int ok; | ||||||
|  |  | ||||||
|  |   INIT_WARGV(argc, argv); | ||||||
|  |  | ||||||
|  |   ok = ExUtilInitCommandLineArguments(argc - 1, argv + 1, &cmd_args); | ||||||
|  |   if (!ok) FREE_WARGV_AND_RETURN(1); | ||||||
|  |  | ||||||
|  |   argc = cmd_args.argc_; | ||||||
|  |   argv = cmd_args.argv_; | ||||||
|  |  | ||||||
|  |   WebPDataInit(&webp_data); | ||||||
|  |   if (!WebPAnimEncoderOptionsInit(&anim_config) || | ||||||
|  |       !WebPConfigInit(&config) || | ||||||
|  |       !WebPPictureInit(&pic)) { | ||||||
|  |     fprintf(stderr, "Library version mismatch!\n"); | ||||||
|  |     ok = 0; | ||||||
|  |     goto End; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   // 1st pass of option parsing | ||||||
|  |   for (c = 0; ok && c < argc; ++c) { | ||||||
|  |     if (argv[c][0] == '-') { | ||||||
|  |       int parse_error = 0; | ||||||
|  |       if (!strcmp(argv[c], "-o") && c + 1 < argc) { | ||||||
|  |         argv[c] = NULL; | ||||||
|  |         output = (const char*)GET_WARGV_SHIFTED(argv, ++c); | ||||||
|  |       } else if (!strcmp(argv[c], "-kmin") && c + 1 < argc) { | ||||||
|  |         argv[c] = NULL; | ||||||
|  |         anim_config.kmin = ExUtilGetInt(argv[++c], 0, &parse_error); | ||||||
|  |       } else if (!strcmp(argv[c], "-kmax") && c + 1 < argc) { | ||||||
|  |         argv[c] = NULL; | ||||||
|  |         anim_config.kmax = ExUtilGetInt(argv[++c], 0, &parse_error); | ||||||
|  |       } else if (!strcmp(argv[c], "-loop") && c + 1 < argc) { | ||||||
|  |         argv[c] = NULL; | ||||||
|  |         loop_count = ExUtilGetInt(argv[++c], 0, &parse_error); | ||||||
|  |         if (loop_count < 0) { | ||||||
|  |           fprintf(stderr, "Invalid non-positive loop-count (%d)\n", loop_count); | ||||||
|  |           parse_error = 1; | ||||||
|  |         } | ||||||
|  |       } else if (!strcmp(argv[c], "-min_size")) { | ||||||
|  |         anim_config.minimize_size = 1; | ||||||
|  |       } else if (!strcmp(argv[c], "-mixed")) { | ||||||
|  |         anim_config.allow_mixed = 1; | ||||||
|  |         config.lossless = 0; | ||||||
|  |       } else if (!strcmp(argv[c], "-near_lossless") && c + 1 < argc) { | ||||||
|  |         argv[c] = NULL; | ||||||
|  |         config.near_lossless = ExUtilGetInt(argv[++c], 0, &parse_error); | ||||||
|  |       } else if (!strcmp(argv[c], "-sharp_yuv")) { | ||||||
|  |         config.use_sharp_yuv = 1; | ||||||
|  |       } else if (!strcmp(argv[c], "-v")) { | ||||||
|  |         verbose = 1; | ||||||
|  |       } else if (!strcmp(argv[c], "-h") || !strcmp(argv[c], "-help")) { | ||||||
|  |         Help(); | ||||||
|  |         FREE_WARGV_AND_RETURN(0); | ||||||
|  |       } else if (!strcmp(argv[c], "-version")) { | ||||||
|  |         const int enc_version = WebPGetEncoderVersion(); | ||||||
|  |         const int mux_version = WebPGetMuxVersion(); | ||||||
|  |         const int sharpyuv_version = SharpYuvGetVersion(); | ||||||
|  |         printf("WebP Encoder version: %d.%d.%d\nWebP Mux version: %d.%d.%d\n", | ||||||
|  |                (enc_version >> 16) & 0xff, (enc_version >> 8) & 0xff, | ||||||
|  |                enc_version & 0xff, (mux_version >> 16) & 0xff, | ||||||
|  |                (mux_version >> 8) & 0xff, mux_version & 0xff); | ||||||
|  |         printf("libsharpyuv: %d.%d.%d\n", (sharpyuv_version >> 24) & 0xff, | ||||||
|  |                (sharpyuv_version >> 16) & 0xffff, sharpyuv_version & 0xff); | ||||||
|  |         goto End; | ||||||
|  |       } else { | ||||||
|  |         continue; | ||||||
|  |       } | ||||||
|  |       ok = !parse_error; | ||||||
|  |       if (!ok) goto End; | ||||||
|  |       argv[c] = NULL;   // mark option as 'parsed' during 1st pass | ||||||
|  |     } else { | ||||||
|  |       have_input |= 1; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   if (!have_input) { | ||||||
|  |     fprintf(stderr, "No input file(s) for generating animation!\n"); | ||||||
|  |     goto End; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   // image-reading pass | ||||||
|  |   pic_num = 0; | ||||||
|  |   config.lossless = 1; | ||||||
|  |   for (c = 0; ok && c < argc; ++c) { | ||||||
|  |     if (argv[c] == NULL) continue; | ||||||
|  |     if (argv[c][0] == '-') {    // parse local options | ||||||
|  |       int parse_error = 0; | ||||||
|  |       if (!strcmp(argv[c], "-lossy")) { | ||||||
|  |         if (!anim_config.allow_mixed) config.lossless = 0; | ||||||
|  |       } else if (!strcmp(argv[c], "-lossless")) { | ||||||
|  |         if (!anim_config.allow_mixed) config.lossless = 1; | ||||||
|  |       } else if (!strcmp(argv[c], "-q") && c + 1 < argc) { | ||||||
|  |         config.quality = ExUtilGetFloat(argv[++c], &parse_error); | ||||||
|  |       } else if (!strcmp(argv[c], "-m") && c + 1 < argc) { | ||||||
|  |         config.method = ExUtilGetInt(argv[++c], 0, &parse_error); | ||||||
|  |       } else if (!strcmp(argv[c], "-d") && c + 1 < argc) { | ||||||
|  |         duration = ExUtilGetInt(argv[++c], 0, &parse_error); | ||||||
|  |         if (duration <= 0) { | ||||||
|  |           fprintf(stderr, "Invalid negative duration (%d)\n", duration); | ||||||
|  |           parse_error = 1; | ||||||
|  |         } | ||||||
|  |       } else { | ||||||
|  |         parse_error = 1;   // shouldn't be here. | ||||||
|  |         fprintf(stderr, "Unknown option [%s]\n", argv[c]); | ||||||
|  |       } | ||||||
|  |       ok = !parse_error; | ||||||
|  |       if (!ok) goto End; | ||||||
|  |       continue; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     if (ok) { | ||||||
|  |       ok = WebPValidateConfig(&config); | ||||||
|  |       if (!ok) { | ||||||
|  |         fprintf(stderr, "Invalid configuration.\n"); | ||||||
|  |         goto End; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // read next input image | ||||||
|  |     pic.use_argb = 1; | ||||||
|  |     ok = ReadImage((const char*)GET_WARGV_SHIFTED(argv, c), &pic); | ||||||
|  |     if (!ok) goto End; | ||||||
|  |  | ||||||
|  |     if (enc == NULL) { | ||||||
|  |       width  = pic.width; | ||||||
|  |       height = pic.height; | ||||||
|  |       enc = WebPAnimEncoderNew(width, height, &anim_config); | ||||||
|  |       ok = (enc != NULL); | ||||||
|  |       if (!ok) { | ||||||
|  |         fprintf(stderr, "Could not create WebPAnimEncoder object.\n"); | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     if (ok) { | ||||||
|  |       ok = (width == pic.width && height == pic.height); | ||||||
|  |       if (!ok) { | ||||||
|  |         fprintf(stderr, "Frame #%d dimension mismatched! " | ||||||
|  |                         "Got %d x %d. Was expecting %d x %d.\n", | ||||||
|  |                 pic_num, pic.width, pic.height, width, height); | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     if (ok) { | ||||||
|  |       ok = WebPAnimEncoderAdd(enc, &pic, timestamp_ms, &config); | ||||||
|  |       if (!ok) { | ||||||
|  |         fprintf(stderr, "Error while adding frame #%d\n", pic_num); | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |     WebPPictureFree(&pic); | ||||||
|  |     if (!ok) goto End; | ||||||
|  |  | ||||||
|  |     if (verbose) { | ||||||
|  |       WFPRINTF(stderr, "Added frame #%3d at time %4d (file: %s)\n", | ||||||
|  |                pic_num, timestamp_ms, GET_WARGV_SHIFTED(argv, c)); | ||||||
|  |     } | ||||||
|  |     timestamp_ms += duration; | ||||||
|  |     ++pic_num; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   // add a last fake frame to signal the last duration | ||||||
|  |   ok = ok && WebPAnimEncoderAdd(enc, NULL, timestamp_ms, NULL); | ||||||
|  |   ok = ok && WebPAnimEncoderAssemble(enc, &webp_data); | ||||||
|  |   if (!ok) { | ||||||
|  |     fprintf(stderr, "Error during final animation assembly.\n"); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |  End: | ||||||
|  |   // free resources | ||||||
|  |   WebPAnimEncoderDelete(enc); | ||||||
|  |  | ||||||
|  |   if (ok && loop_count > 0) {  // Re-mux to add loop count. | ||||||
|  |     ok = SetLoopCount(loop_count, &webp_data); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   if (ok) { | ||||||
|  |     if (output != NULL) { | ||||||
|  |       ok = ImgIoUtilWriteFile(output, webp_data.bytes, webp_data.size); | ||||||
|  |       if (ok) WFPRINTF(stderr, "output file: %s     ", (const W_CHAR*)output); | ||||||
|  |     } else { | ||||||
|  |       fprintf(stderr, "[no output file specified]   "); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   if (ok) { | ||||||
|  |     fprintf(stderr, "[%d frames, %u bytes].\n", | ||||||
|  |             pic_num, (unsigned int)webp_data.size); | ||||||
|  |   } | ||||||
|  |   WebPDataClear(&webp_data); | ||||||
|  |   ExUtilDeleteCommandLineArguments(&cmd_args); | ||||||
|  |   FREE_WARGV_AND_RETURN(ok ? 0 : 1); | ||||||
|  | } | ||||||
							
								
								
									
										63
									
								
								external/libwebp/libwebp/examples/stopwatch.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								external/libwebp/libwebp/examples/stopwatch.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,63 @@ | |||||||
|  | // Copyright 2011 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. | ||||||
|  | // ----------------------------------------------------------------------------- | ||||||
|  | // | ||||||
|  | //  Helper functions to measure elapsed time. | ||||||
|  | // | ||||||
|  | // Author: Mikolaj Zalewski (mikolajz@google.com) | ||||||
|  |  | ||||||
|  | #ifndef WEBP_EXAMPLES_STOPWATCH_H_ | ||||||
|  | #define WEBP_EXAMPLES_STOPWATCH_H_ | ||||||
|  |  | ||||||
|  | #include "webp/types.h" | ||||||
|  |  | ||||||
|  | #if defined _WIN32 && !defined __GNUC__ | ||||||
|  | #include <windows.h> | ||||||
|  |  | ||||||
|  | typedef LARGE_INTEGER Stopwatch; | ||||||
|  |  | ||||||
|  | static WEBP_INLINE void StopwatchReset(Stopwatch* watch) { | ||||||
|  |   QueryPerformanceCounter(watch); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static WEBP_INLINE double StopwatchReadAndReset(Stopwatch* watch) { | ||||||
|  |   const LARGE_INTEGER old_value = *watch; | ||||||
|  |   LARGE_INTEGER freq; | ||||||
|  |   if (!QueryPerformanceCounter(watch)) | ||||||
|  |     return 0.0; | ||||||
|  |   if (!QueryPerformanceFrequency(&freq)) | ||||||
|  |     return 0.0; | ||||||
|  |   if (freq.QuadPart == 0) | ||||||
|  |     return 0.0; | ||||||
|  |   return (watch->QuadPart - old_value.QuadPart) / (double)freq.QuadPart; | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | #else    /* !_WIN32 */ | ||||||
|  | #include <string.h>  // memcpy | ||||||
|  | #include <sys/time.h> | ||||||
|  |  | ||||||
|  | typedef struct timeval Stopwatch; | ||||||
|  |  | ||||||
|  | static WEBP_INLINE void StopwatchReset(Stopwatch* watch) { | ||||||
|  |   gettimeofday(watch, NULL); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static WEBP_INLINE double StopwatchReadAndReset(Stopwatch* watch) { | ||||||
|  |   struct timeval old_value; | ||||||
|  |   double delta_sec, delta_usec; | ||||||
|  |   memcpy(&old_value, watch, sizeof(old_value)); | ||||||
|  |   gettimeofday(watch, NULL); | ||||||
|  |   delta_sec = (double)watch->tv_sec - old_value.tv_sec; | ||||||
|  |   delta_usec = (double)watch->tv_usec - old_value.tv_usec; | ||||||
|  |   return delta_sec + delta_usec / 1000000.0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #endif   /* _WIN32 */ | ||||||
|  |  | ||||||
|  | #endif  // WEBP_EXAMPLES_STOPWATCH_H_ | ||||||
							
								
								
									
										
											BIN
										
									
								
								external/libwebp/libwebp/examples/test.webp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								external/libwebp/libwebp/examples/test.webp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 4.8 KiB | 
							
								
								
									
										4
									
								
								external/libwebp/libwebp/examples/test_ref.ppm
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								external/libwebp/libwebp/examples/test_ref.ppm
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										116
									
								
								external/libwebp/libwebp/examples/unicode.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										116
									
								
								external/libwebp/libwebp/examples/unicode.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,116 @@ | |||||||
|  | // Copyright 2018 Google Inc. All Rights Reserved. | ||||||
|  | // | ||||||
|  | // Use of this source code is governed by a BSD-style license | ||||||
|  | // that can be found in the COPYING file in the root of the source | ||||||
|  | // tree. An additional intellectual property rights grant can be found | ||||||
|  | // in the file PATENTS. All contributing project authors may | ||||||
|  | // be found in the AUTHORS file in the root of the source tree. | ||||||
|  | // ----------------------------------------------------------------------------- | ||||||
|  | // | ||||||
|  | // Unicode support for Windows. The main idea is to maintain an array of Unicode | ||||||
|  | // arguments (wargv) and use it only for file paths. The regular argv is used | ||||||
|  | // for everything else. | ||||||
|  | // | ||||||
|  | // Author: Yannis Guyon (yguyon@google.com) | ||||||
|  |  | ||||||
|  | #ifndef WEBP_EXAMPLES_UNICODE_H_ | ||||||
|  | #define WEBP_EXAMPLES_UNICODE_H_ | ||||||
|  |  | ||||||
|  | #include <stdio.h> | ||||||
|  |  | ||||||
|  | #if defined(_WIN32) && defined(_UNICODE) | ||||||
|  |  | ||||||
|  | // wchar_t is used instead of TCHAR because we only perform additional work when | ||||||
|  | // Unicode is enabled and because the output of CommandLineToArgvW() is wchar_t. | ||||||
|  |  | ||||||
|  | #include <fcntl.h> | ||||||
|  | #include <io.h> | ||||||
|  | #include <wchar.h> | ||||||
|  | #include <windows.h> | ||||||
|  | #include <shellapi.h> | ||||||
|  |  | ||||||
|  | // Create a wchar_t array containing Unicode parameters. | ||||||
|  | #define INIT_WARGV(ARGC, ARGV)                                                \ | ||||||
|  |   int wargc;                                                                  \ | ||||||
|  |   const W_CHAR** const wargv =                                                \ | ||||||
|  |       (const W_CHAR**)CommandLineToArgvW(GetCommandLineW(), &wargc);          \ | ||||||
|  |   do {                                                                        \ | ||||||
|  |     if (wargv == NULL || wargc != (ARGC)) {                                   \ | ||||||
|  |       fprintf(stderr, "Error: Unable to get Unicode arguments.\n");           \ | ||||||
|  |       FREE_WARGV_AND_RETURN(-1);                                              \ | ||||||
|  |     }                                                                         \ | ||||||
|  |   } while (0) | ||||||
|  |  | ||||||
|  | // Use this to get a Unicode argument (e.g. file path). | ||||||
|  | #define GET_WARGV(UNUSED, C) wargv[C] | ||||||
|  | // For cases where argv is shifted by one compared to wargv. | ||||||
|  | #define GET_WARGV_SHIFTED(UNUSED, C) wargv[(C) + 1] | ||||||
|  | #define GET_WARGV_OR_NULL() wargv | ||||||
|  |  | ||||||
|  | // Release resources. LocalFree() is needed after CommandLineToArgvW(). | ||||||
|  | #define FREE_WARGV() LOCAL_FREE((W_CHAR** const)wargv) | ||||||
|  | #define LOCAL_FREE(WARGV)                  \ | ||||||
|  |   do {                                     \ | ||||||
|  |     if ((WARGV) != NULL) LocalFree(WARGV); \ | ||||||
|  |   } while (0) | ||||||
|  |  | ||||||
|  | #define W_CHAR wchar_t  // WCHAR without underscore might already be defined. | ||||||
|  | #define TO_W_CHAR(STR) (L##STR) | ||||||
|  |  | ||||||
|  | #define WFOPEN(ARG, OPT) _wfopen((const W_CHAR*)ARG, TO_W_CHAR(OPT)) | ||||||
|  |  | ||||||
|  | #define WFPRINTF(STREAM, STR, ...)                    \ | ||||||
|  |   do {                                                \ | ||||||
|  |     int prev_mode;                                    \ | ||||||
|  |     fflush(STREAM);                                   \ | ||||||
|  |     prev_mode = _setmode(_fileno(STREAM), _O_U8TEXT); \ | ||||||
|  |     fwprintf(STREAM, TO_W_CHAR(STR), __VA_ARGS__);    \ | ||||||
|  |     fflush(STREAM);                                   \ | ||||||
|  |     (void)_setmode(_fileno(STREAM), prev_mode);       \ | ||||||
|  |   } while (0) | ||||||
|  | #define WPRINTF(STR, ...) WFPRINTF(stdout, STR, __VA_ARGS__) | ||||||
|  |  | ||||||
|  | #define WSTRLEN(FILENAME) wcslen((const W_CHAR*)FILENAME) | ||||||
|  | #define WSTRCMP(FILENAME, STR) wcscmp((const W_CHAR*)FILENAME, TO_W_CHAR(STR)) | ||||||
|  | #define WSTRRCHR(FILENAME, STR) wcsrchr((const W_CHAR*)FILENAME, TO_W_CHAR(STR)) | ||||||
|  | #define WSNPRINTF(A, B, STR, ...) _snwprintf(A, B, TO_W_CHAR(STR), __VA_ARGS__) | ||||||
|  |  | ||||||
|  | #else | ||||||
|  |  | ||||||
|  | #include <string.h> | ||||||
|  |  | ||||||
|  | // Unicode file paths work as is on Unix platforms, and no extra work is done on | ||||||
|  | // Windows either if Unicode is disabled. | ||||||
|  |  | ||||||
|  | #define INIT_WARGV(ARGC, ARGV) | ||||||
|  |  | ||||||
|  | #define GET_WARGV(ARGV, C) (ARGV)[C] | ||||||
|  | #define GET_WARGV_SHIFTED(ARGV, C) (ARGV)[C] | ||||||
|  | #define GET_WARGV_OR_NULL() NULL | ||||||
|  |  | ||||||
|  | #define FREE_WARGV() | ||||||
|  | #define LOCAL_FREE(WARGV) | ||||||
|  |  | ||||||
|  | #define W_CHAR char | ||||||
|  | #define TO_W_CHAR(STR) (STR) | ||||||
|  |  | ||||||
|  | #define WFOPEN(ARG, OPT) fopen(ARG, OPT) | ||||||
|  |  | ||||||
|  | #define WPRINTF(STR, ...) printf(STR, __VA_ARGS__) | ||||||
|  | #define WFPRINTF(STREAM, STR, ...) fprintf(STREAM, STR, __VA_ARGS__) | ||||||
|  |  | ||||||
|  | #define WSTRLEN(FILENAME) strlen(FILENAME) | ||||||
|  | #define WSTRCMP(FILENAME, STR) strcmp(FILENAME, STR) | ||||||
|  | #define WSTRRCHR(FILENAME, STR) strrchr(FILENAME, STR) | ||||||
|  | #define WSNPRINTF(A, B, STR, ...) snprintf(A, B, STR, __VA_ARGS__) | ||||||
|  |  | ||||||
|  | #endif  // defined(_WIN32) && defined(_UNICODE) | ||||||
|  |  | ||||||
|  | // Don't forget to free wargv before returning (e.g. from main). | ||||||
|  | #define FREE_WARGV_AND_RETURN(VALUE) \ | ||||||
|  |   do {                               \ | ||||||
|  |     FREE_WARGV();                    \ | ||||||
|  |     return (VALUE);                  \ | ||||||
|  |   } while (0) | ||||||
|  |  | ||||||
|  | #endif  // WEBP_EXAMPLES_UNICODE_H_ | ||||||
							
								
								
									
										76
									
								
								external/libwebp/libwebp/examples/unicode_gif.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										76
									
								
								external/libwebp/libwebp/examples/unicode_gif.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,76 @@ | |||||||
|  | // Copyright 2018 Google Inc. All Rights Reserved. | ||||||
|  | // | ||||||
|  | // Use of this source code is governed by a BSD-style license | ||||||
|  | // that can be found in the COPYING file in the root of the source | ||||||
|  | // tree. An additional intellectual property rights grant can be found | ||||||
|  | // in the file PATENTS. All contributing project authors may | ||||||
|  | // be found in the AUTHORS file in the root of the source tree. | ||||||
|  | // ----------------------------------------------------------------------------- | ||||||
|  | // | ||||||
|  | // giflib doesn't have a Unicode DGifOpenFileName(). Let's make one. | ||||||
|  | // | ||||||
|  | // Author: Yannis Guyon (yguyon@google.com) | ||||||
|  |  | ||||||
|  | #ifndef WEBP_EXAMPLES_UNICODE_GIF_H_ | ||||||
|  | #define WEBP_EXAMPLES_UNICODE_GIF_H_ | ||||||
|  |  | ||||||
|  | #include "./unicode.h" | ||||||
|  | #ifdef HAVE_CONFIG_H | ||||||
|  | #include "webp/config.h"  // For WEBP_HAVE_GIF | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | #if defined(WEBP_HAVE_GIF) | ||||||
|  |  | ||||||
|  | #ifdef _WIN32 | ||||||
|  | #include <fcntl.h>  // Not standard, needed for _topen and flags. | ||||||
|  | #include <io.h> | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | #include <gif_lib.h> | ||||||
|  | #include <string.h> | ||||||
|  | #include "./gifdec.h" | ||||||
|  |  | ||||||
|  | #if !defined(STDIN_FILENO) | ||||||
|  | #define STDIN_FILENO 0 | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | static GifFileType* DGifOpenFileUnicode(const W_CHAR* file_name, int* error) { | ||||||
|  |   if (!WSTRCMP(file_name, "-")) { | ||||||
|  | #if LOCAL_GIF_PREREQ(5, 0) | ||||||
|  |     return DGifOpenFileHandle(STDIN_FILENO, error); | ||||||
|  | #else | ||||||
|  |     (void)error; | ||||||
|  |     return DGifOpenFileHandle(STDIN_FILENO); | ||||||
|  | #endif | ||||||
|  |   } | ||||||
|  |  | ||||||
|  | #if defined(_WIN32) && defined(_UNICODE) | ||||||
|  |   { | ||||||
|  |     int file_handle = _wopen(file_name, _O_RDONLY | _O_BINARY); | ||||||
|  |     if (file_handle == -1) { | ||||||
|  |       if (error != NULL) *error = D_GIF_ERR_OPEN_FAILED; | ||||||
|  |       return NULL; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | #if LOCAL_GIF_PREREQ(5, 0) | ||||||
|  |     return DGifOpenFileHandle(file_handle, error); | ||||||
|  | #else | ||||||
|  |     return DGifOpenFileHandle(file_handle); | ||||||
|  | #endif | ||||||
|  |   } | ||||||
|  |  | ||||||
|  | #else | ||||||
|  |  | ||||||
|  | #if LOCAL_GIF_PREREQ(5, 0) | ||||||
|  |   return DGifOpenFileName(file_name, error); | ||||||
|  | #else | ||||||
|  |   return DGifOpenFileName(file_name); | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | #endif  // defined(_WIN32) && defined(_UNICODE) | ||||||
|  |   // DGifCloseFile() is called later. | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #endif  // defined(WEBP_HAVE_GIF) | ||||||
|  |  | ||||||
|  | #endif  // WEBP_EXAMPLES_UNICODE_GIF_H_ | ||||||
							
								
								
									
										654
									
								
								external/libwebp/libwebp/examples/vwebp.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										654
									
								
								external/libwebp/libwebp/examples/vwebp.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,654 @@ | |||||||
|  | // Copyright 2011 Google Inc. All Rights Reserved. | ||||||
|  | // | ||||||
|  | // Use of this source code is governed by a BSD-style license | ||||||
|  | // that can be found in the COPYING file in the root of the source | ||||||
|  | // tree. An additional intellectual property rights grant can be found | ||||||
|  | // in the file PATENTS. All contributing project authors may | ||||||
|  | // be found in the AUTHORS file in the root of the source tree. | ||||||
|  | // ----------------------------------------------------------------------------- | ||||||
|  | // | ||||||
|  | //  Simple OpenGL-based WebP file viewer. | ||||||
|  | // | ||||||
|  | // Author: Skal (pascal.massimino@gmail.com) | ||||||
|  | #ifdef HAVE_CONFIG_H | ||||||
|  | #include "webp/config.h" | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | #if defined(__unix__) || defined(__CYGWIN__) | ||||||
|  | #define _POSIX_C_SOURCE 200112L  // for setenv | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | #include <stdio.h> | ||||||
|  | #include <stdlib.h> | ||||||
|  | #include <string.h> | ||||||
|  |  | ||||||
|  | #if defined(WEBP_HAVE_GL) | ||||||
|  |  | ||||||
|  | #if defined(HAVE_GLUT_GLUT_H) | ||||||
|  | #include <GLUT/glut.h> | ||||||
|  | #else | ||||||
|  | #include <GL/glut.h> | ||||||
|  | #ifdef FREEGLUT | ||||||
|  | #include <GL/freeglut.h> | ||||||
|  | #endif | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | #ifdef WEBP_HAVE_QCMS | ||||||
|  | #include <qcms.h> | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | #include "webp/decode.h" | ||||||
|  | #include "webp/demux.h" | ||||||
|  |  | ||||||
|  | #include "../examples/example_util.h" | ||||||
|  | #include "../imageio/imageio_util.h" | ||||||
|  | #include "./unicode.h" | ||||||
|  |  | ||||||
|  | #if defined(_MSC_VER) && _MSC_VER < 1900 | ||||||
|  | #define snprintf _snprintf | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | // Unfortunate global variables. Gathered into a struct for comfort. | ||||||
|  | static struct { | ||||||
|  |   int has_animation; | ||||||
|  |   int has_color_profile; | ||||||
|  |   int done; | ||||||
|  |   int decoding_error; | ||||||
|  |   int print_info; | ||||||
|  |   int only_deltas; | ||||||
|  |   int use_color_profile; | ||||||
|  |   int draw_anim_background_color; | ||||||
|  |  | ||||||
|  |   int canvas_width, canvas_height; | ||||||
|  |   int loop_count; | ||||||
|  |   uint32_t bg_color; | ||||||
|  |  | ||||||
|  |   const char* file_name; | ||||||
|  |   WebPData data; | ||||||
|  |   WebPDecoderConfig config; | ||||||
|  |   const WebPDecBuffer* pic; | ||||||
|  |   WebPDemuxer* dmux; | ||||||
|  |   WebPIterator curr_frame; | ||||||
|  |   WebPIterator prev_frame; | ||||||
|  |   WebPChunkIterator iccp; | ||||||
|  |   int viewport_width, viewport_height; | ||||||
|  | } kParams; | ||||||
|  |  | ||||||
|  | static void ClearPreviousPic(void) { | ||||||
|  |   WebPFreeDecBuffer((WebPDecBuffer*)kParams.pic); | ||||||
|  |   kParams.pic = NULL; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static void ClearParams(void) { | ||||||
|  |   ClearPreviousPic(); | ||||||
|  |   WebPDataClear(&kParams.data); | ||||||
|  |   WebPDemuxReleaseIterator(&kParams.curr_frame); | ||||||
|  |   WebPDemuxReleaseIterator(&kParams.prev_frame); | ||||||
|  |   WebPDemuxReleaseChunkIterator(&kParams.iccp); | ||||||
|  |   WebPDemuxDelete(kParams.dmux); | ||||||
|  |   kParams.dmux = NULL; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Sets the previous frame to the dimensions of the canvas and has it dispose | ||||||
|  | // to background to cause the canvas to be cleared. | ||||||
|  | static void ClearPreviousFrame(void) { | ||||||
|  |   WebPIterator* const prev = &kParams.prev_frame; | ||||||
|  |   prev->width = kParams.canvas_width; | ||||||
|  |   prev->height = kParams.canvas_height; | ||||||
|  |   prev->x_offset = prev->y_offset = 0; | ||||||
|  |   prev->dispose_method = WEBP_MUX_DISPOSE_BACKGROUND; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // ----------------------------------------------------------------------------- | ||||||
|  | // Color profile handling | ||||||
|  | static int ApplyColorProfile(const WebPData* const profile, | ||||||
|  |                              WebPDecBuffer* const rgba) { | ||||||
|  | #ifdef WEBP_HAVE_QCMS | ||||||
|  |   int i, ok = 0; | ||||||
|  |   uint8_t* line; | ||||||
|  |   uint8_t major_revision; | ||||||
|  |   qcms_profile* input_profile = NULL; | ||||||
|  |   qcms_profile* output_profile = NULL; | ||||||
|  |   qcms_transform* transform = NULL; | ||||||
|  |   const qcms_data_type input_type = QCMS_DATA_RGBA_8; | ||||||
|  |   const qcms_data_type output_type = QCMS_DATA_RGBA_8; | ||||||
|  |   const qcms_intent intent = QCMS_INTENT_DEFAULT; | ||||||
|  |  | ||||||
|  |   if (profile == NULL || rgba == NULL) return 0; | ||||||
|  |   if (profile->bytes == NULL || profile->size < 10) return 1; | ||||||
|  |   major_revision = profile->bytes[8]; | ||||||
|  |  | ||||||
|  |   qcms_enable_iccv4(); | ||||||
|  |   input_profile = qcms_profile_from_memory(profile->bytes, profile->size); | ||||||
|  |   // qcms_profile_is_bogus() is broken with ICCv4. | ||||||
|  |   if (input_profile == NULL || | ||||||
|  |       (major_revision < 4 && qcms_profile_is_bogus(input_profile))) { | ||||||
|  |     fprintf(stderr, "Color profile is bogus!\n"); | ||||||
|  |     goto Error; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   output_profile = qcms_profile_sRGB(); | ||||||
|  |   if (output_profile == NULL) { | ||||||
|  |     fprintf(stderr, "Error creating output color profile!\n"); | ||||||
|  |     goto Error; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   qcms_profile_precache_output_transform(output_profile); | ||||||
|  |   transform = qcms_transform_create(input_profile, input_type, | ||||||
|  |                                     output_profile, output_type, | ||||||
|  |                                     intent); | ||||||
|  |   if (transform == NULL) { | ||||||
|  |     fprintf(stderr, "Error creating color transform!\n"); | ||||||
|  |     goto Error; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   line = rgba->u.RGBA.rgba; | ||||||
|  |   for (i = 0; i < rgba->height; ++i, line += rgba->u.RGBA.stride) { | ||||||
|  |     qcms_transform_data(transform, line, line, rgba->width); | ||||||
|  |   } | ||||||
|  |   ok = 1; | ||||||
|  |  | ||||||
|  |  Error: | ||||||
|  |   if (input_profile != NULL) qcms_profile_release(input_profile); | ||||||
|  |   if (output_profile != NULL) qcms_profile_release(output_profile); | ||||||
|  |   if (transform != NULL) qcms_transform_release(transform); | ||||||
|  |   return ok; | ||||||
|  | #else | ||||||
|  |   (void)profile; | ||||||
|  |   (void)rgba; | ||||||
|  |   return 1; | ||||||
|  | #endif  // WEBP_HAVE_QCMS | ||||||
|  | } | ||||||
|  |  | ||||||
|  | //------------------------------------------------------------------------------ | ||||||
|  | // File decoding | ||||||
|  |  | ||||||
|  | static int Decode(void) {   // Fills kParams.curr_frame | ||||||
|  |   const WebPIterator* const curr = &kParams.curr_frame; | ||||||
|  |   WebPDecoderConfig* const config = &kParams.config; | ||||||
|  |   WebPDecBuffer* const output_buffer = &config->output; | ||||||
|  |   int ok = 0; | ||||||
|  |  | ||||||
|  |   ClearPreviousPic(); | ||||||
|  |   output_buffer->colorspace = MODE_RGBA; | ||||||
|  |   ok = (WebPDecode(curr->fragment.bytes, curr->fragment.size, | ||||||
|  |                    config) == VP8_STATUS_OK); | ||||||
|  |   if (!ok) { | ||||||
|  |     fprintf(stderr, "Decoding of frame #%d failed!\n", curr->frame_num); | ||||||
|  |   } else { | ||||||
|  |     kParams.pic = output_buffer; | ||||||
|  |     if (kParams.use_color_profile) { | ||||||
|  |       ok = ApplyColorProfile(&kParams.iccp.chunk, output_buffer); | ||||||
|  |       if (!ok) { | ||||||
|  |         fprintf(stderr, "Applying color profile to frame #%d failed!\n", | ||||||
|  |                 curr->frame_num); | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   return ok; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static void decode_callback(int what) { | ||||||
|  |   if (what == 0 && !kParams.done) { | ||||||
|  |     int duration = 0; | ||||||
|  |     if (kParams.dmux != NULL) { | ||||||
|  |       WebPIterator* const curr = &kParams.curr_frame; | ||||||
|  |       if (!WebPDemuxNextFrame(curr)) { | ||||||
|  |         WebPDemuxReleaseIterator(curr); | ||||||
|  |         if (WebPDemuxGetFrame(kParams.dmux, 1, curr)) { | ||||||
|  |           --kParams.loop_count; | ||||||
|  |           kParams.done = (kParams.loop_count == 0); | ||||||
|  |           if (kParams.done) return; | ||||||
|  |           ClearPreviousFrame(); | ||||||
|  |         } else { | ||||||
|  |           kParams.decoding_error = 1; | ||||||
|  |           kParams.done = 1; | ||||||
|  |           return; | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |       duration = curr->duration; | ||||||
|  |       // Behavior copied from Chrome, cf: | ||||||
|  |       // https://cs.chromium.org/chromium/src/third_party/WebKit/Source/ | ||||||
|  |       // platform/graphics/DeferredImageDecoder.cpp? | ||||||
|  |       // rcl=b4c33049f096cd283f32be9a58b9a9e768227c26&l=246 | ||||||
|  |       if (duration <= 10) duration = 100; | ||||||
|  |     } | ||||||
|  |     if (!Decode()) { | ||||||
|  |       kParams.decoding_error = 1; | ||||||
|  |       kParams.done = 1; | ||||||
|  |     } else { | ||||||
|  |       glutPostRedisplay(); | ||||||
|  |       glutTimerFunc(duration, decode_callback, what); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | //------------------------------------------------------------------------------ | ||||||
|  | // Callbacks | ||||||
|  |  | ||||||
|  | static void HandleKey(unsigned char key, int pos_x, int pos_y) { | ||||||
|  |   // Note: rescaling the window or toggling some features during an animation | ||||||
|  |   // generates visual artifacts. This is not fixed because refreshing the frame | ||||||
|  |   // may require rendering the whole animation from start till current frame. | ||||||
|  |   (void)pos_x; | ||||||
|  |   (void)pos_y; | ||||||
|  |   if (key == 'q' || key == 'Q' || key == 27 /* Esc */) { | ||||||
|  | #ifdef FREEGLUT | ||||||
|  |     glutLeaveMainLoop(); | ||||||
|  | #else | ||||||
|  |     ClearParams(); | ||||||
|  |     exit(0); | ||||||
|  | #endif | ||||||
|  |   } else if (key == 'c') { | ||||||
|  |     if (kParams.has_color_profile && !kParams.decoding_error) { | ||||||
|  |       kParams.use_color_profile = 1 - kParams.use_color_profile; | ||||||
|  |  | ||||||
|  |       if (kParams.has_animation) { | ||||||
|  |         // Restart the completed animation to pickup the color profile change. | ||||||
|  |         if (kParams.done && kParams.loop_count == 0) { | ||||||
|  |           kParams.loop_count = | ||||||
|  |               (int)WebPDemuxGetI(kParams.dmux, WEBP_FF_LOOP_COUNT) + 1; | ||||||
|  |           kParams.done = 0; | ||||||
|  |           // Start the decode loop immediately. | ||||||
|  |           glutTimerFunc(0, decode_callback, 0); | ||||||
|  |         } | ||||||
|  |       } else { | ||||||
|  |         Decode(); | ||||||
|  |         glutPostRedisplay(); | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } else if (key == 'b') { | ||||||
|  |     kParams.draw_anim_background_color = 1 - kParams.draw_anim_background_color; | ||||||
|  |     if (!kParams.has_animation) ClearPreviousFrame(); | ||||||
|  |     glutPostRedisplay(); | ||||||
|  |   } else if (key == 'i') { | ||||||
|  |     kParams.print_info = 1 - kParams.print_info; | ||||||
|  |     if (!kParams.has_animation) ClearPreviousFrame(); | ||||||
|  |     glutPostRedisplay(); | ||||||
|  |   } else if (key == 'd') { | ||||||
|  |     kParams.only_deltas = 1 - kParams.only_deltas; | ||||||
|  |     glutPostRedisplay(); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static void HandleReshape(int width, int height) { | ||||||
|  |   // Note: reshape doesn't preserve aspect ratio, and might | ||||||
|  |   // be handling larger-than-screen pictures incorrectly. | ||||||
|  |   glViewport(0, 0, width, height); | ||||||
|  |   glMatrixMode(GL_PROJECTION); | ||||||
|  |   glLoadIdentity(); | ||||||
|  |   glMatrixMode(GL_MODELVIEW); | ||||||
|  |   glLoadIdentity(); | ||||||
|  |   kParams.viewport_width = width; | ||||||
|  |   kParams.viewport_height = height; | ||||||
|  |   if (!kParams.has_animation) ClearPreviousFrame(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static void PrintString(const char* const text) { | ||||||
|  |   void* const font = GLUT_BITMAP_9_BY_15; | ||||||
|  |   int i; | ||||||
|  |   for (i = 0; text[i]; ++i) { | ||||||
|  |     glutBitmapCharacter(font, text[i]); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static void PrintStringW(const char* const text) { | ||||||
|  | #if defined(_WIN32) && defined(_UNICODE) | ||||||
|  |   void* const font = GLUT_BITMAP_9_BY_15; | ||||||
|  |   const W_CHAR* const wtext = (const W_CHAR*)text; | ||||||
|  |   int i; | ||||||
|  |   for (i = 0; wtext[i]; ++i) { | ||||||
|  |     glutBitmapCharacter(font, wtext[i]); | ||||||
|  |   } | ||||||
|  | #else | ||||||
|  |   PrintString(text); | ||||||
|  | #endif | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static float GetColorf(uint32_t color, int shift) { | ||||||
|  |   return ((color >> shift) & 0xff) / 255.f; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static void DrawCheckerBoard(void) { | ||||||
|  |   const int square_size = 8;  // must be a power of 2 | ||||||
|  |   int x, y; | ||||||
|  |   GLint viewport[4];  // x, y, width, height | ||||||
|  |  | ||||||
|  |   glPushMatrix(); | ||||||
|  |  | ||||||
|  |   glGetIntegerv(GL_VIEWPORT, viewport); | ||||||
|  |   // shift to integer coordinates with (0,0) being top-left. | ||||||
|  |   glOrtho(0, viewport[2], viewport[3], 0, -1, 1); | ||||||
|  |   for (y = 0; y < viewport[3]; y += square_size) { | ||||||
|  |     for (x = 0; x < viewport[2]; x += square_size) { | ||||||
|  |       const GLubyte color = 128 + 64 * (!((x + y) & square_size)); | ||||||
|  |       glColor3ub(color, color, color); | ||||||
|  |       glRecti(x, y, x + square_size, y + square_size); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   glPopMatrix(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static void DrawBackground(void) { | ||||||
|  |   // Whole window cleared with clear color, checkerboard rendered on top of it. | ||||||
|  |   glClear(GL_COLOR_BUFFER_BIT); | ||||||
|  |   DrawCheckerBoard(); | ||||||
|  |  | ||||||
|  |   // ANIM background color rendered (blend) on top. Default is white for still | ||||||
|  |   // images (without ANIM chunk). glClear() can't be used for that (no blend). | ||||||
|  |   if (kParams.draw_anim_background_color) { | ||||||
|  |     glPushMatrix(); | ||||||
|  |     glLoadIdentity(); | ||||||
|  |     glColor4f(GetColorf(kParams.bg_color, 16),  // BGRA from spec | ||||||
|  |               GetColorf(kParams.bg_color, 8), | ||||||
|  |               GetColorf(kParams.bg_color, 0), | ||||||
|  |               GetColorf(kParams.bg_color, 24)); | ||||||
|  |     glRecti(-1, -1, +1, +1); | ||||||
|  |     glPopMatrix(); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Draw background in a scissored rectangle. | ||||||
|  | static void DrawBackgroundScissored(int window_x, int window_y, int frame_w, | ||||||
|  |                                     int frame_h) { | ||||||
|  |   // Only update the requested area, not the whole canvas. | ||||||
|  |   window_x = window_x * kParams.viewport_width / kParams.canvas_width; | ||||||
|  |   window_y = window_y * kParams.viewport_height / kParams.canvas_height; | ||||||
|  |   frame_w = frame_w * kParams.viewport_width / kParams.canvas_width; | ||||||
|  |   frame_h = frame_h * kParams.viewport_height / kParams.canvas_height; | ||||||
|  |  | ||||||
|  |   // glScissor() takes window coordinates (0,0 at bottom left). | ||||||
|  |   window_y = kParams.viewport_height - window_y - frame_h; | ||||||
|  |  | ||||||
|  |   glEnable(GL_SCISSOR_TEST); | ||||||
|  |   glScissor(window_x, window_y, frame_w, frame_h); | ||||||
|  |   DrawBackground(); | ||||||
|  |   glDisable(GL_SCISSOR_TEST); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static void HandleDisplay(void) { | ||||||
|  |   const WebPDecBuffer* const pic = kParams.pic; | ||||||
|  |   const WebPIterator* const curr = &kParams.curr_frame; | ||||||
|  |   WebPIterator* const prev = &kParams.prev_frame; | ||||||
|  |   GLfloat xoff, yoff; | ||||||
|  |   if (pic == NULL) return; | ||||||
|  |   glPushMatrix(); | ||||||
|  |   glPixelZoom((GLfloat)(+1. / kParams.canvas_width * kParams.viewport_width), | ||||||
|  |               (GLfloat)(-1. / kParams.canvas_height * kParams.viewport_height)); | ||||||
|  |   xoff = (GLfloat)(2. * curr->x_offset / kParams.canvas_width); | ||||||
|  |   yoff = (GLfloat)(2. * curr->y_offset / kParams.canvas_height); | ||||||
|  |   glRasterPos2f(-1.f + xoff, 1.f - yoff); | ||||||
|  |   glPixelStorei(GL_UNPACK_ALIGNMENT, 1); | ||||||
|  |   glPixelStorei(GL_UNPACK_ROW_LENGTH, pic->u.RGBA.stride / 4); | ||||||
|  |  | ||||||
|  |   if (kParams.only_deltas) { | ||||||
|  |     DrawBackground(); | ||||||
|  |   } else { | ||||||
|  |     // The rectangle of the previous frame might be different than the current | ||||||
|  |     // frame, so we may need to DrawBackgroundScissored for both. | ||||||
|  |     if (prev->dispose_method == WEBP_MUX_DISPOSE_BACKGROUND) { | ||||||
|  |       // Clear the previous frame rectangle. | ||||||
|  |       DrawBackgroundScissored(prev->x_offset, prev->y_offset, prev->width, | ||||||
|  |                               prev->height); | ||||||
|  |     } | ||||||
|  |     if (curr->blend_method == WEBP_MUX_NO_BLEND) { | ||||||
|  |       // We simulate no-blending behavior by first clearing the current frame | ||||||
|  |       // rectangle and then alpha-blending against it. | ||||||
|  |       DrawBackgroundScissored(curr->x_offset, curr->y_offset, curr->width, | ||||||
|  |                               curr->height); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   *prev = *curr; | ||||||
|  |  | ||||||
|  |   glDrawPixels(pic->width, pic->height, | ||||||
|  |                GL_RGBA, GL_UNSIGNED_BYTE, | ||||||
|  |                (GLvoid*)pic->u.RGBA.rgba); | ||||||
|  |   if (kParams.print_info) { | ||||||
|  |     char tmp[32]; | ||||||
|  |  | ||||||
|  |     glColor4f(0.90f, 0.0f, 0.90f, 1.0f); | ||||||
|  |     glRasterPos2f(-0.95f, 0.90f); | ||||||
|  |     PrintStringW(kParams.file_name); | ||||||
|  |  | ||||||
|  |     snprintf(tmp, sizeof(tmp), "Dimension:%d x %d", pic->width, pic->height); | ||||||
|  |     glColor4f(0.90f, 0.0f, 0.90f, 1.0f); | ||||||
|  |     glRasterPos2f(-0.95f, 0.80f); | ||||||
|  |     PrintString(tmp); | ||||||
|  |     if (curr->x_offset != 0 || curr->y_offset != 0) { | ||||||
|  |       snprintf(tmp, sizeof(tmp), " (offset:%d,%d)", | ||||||
|  |                curr->x_offset, curr->y_offset); | ||||||
|  |       glRasterPos2f(-0.95f, 0.70f); | ||||||
|  |       PrintString(tmp); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   glPopMatrix(); | ||||||
|  | #if defined(__APPLE__) || defined(_WIN32) | ||||||
|  |   glFlush(); | ||||||
|  | #else | ||||||
|  |   glutSwapBuffers(); | ||||||
|  | #endif | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static void StartDisplay(void) { | ||||||
|  |   int width = kParams.canvas_width; | ||||||
|  |   int height = kParams.canvas_height; | ||||||
|  |   int screen_width, screen_height; | ||||||
|  |   // TODO(webp:365) GLUT_DOUBLE results in flickering / old frames to be | ||||||
|  |   // partially displayed with animated webp + alpha. | ||||||
|  | #if defined(__APPLE__) || defined(_WIN32) | ||||||
|  |   glutInitDisplayMode(GLUT_RGBA); | ||||||
|  | #else | ||||||
|  |   glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA); | ||||||
|  | #endif | ||||||
|  |   screen_width = glutGet(GLUT_SCREEN_WIDTH); | ||||||
|  |   screen_height = glutGet(GLUT_SCREEN_HEIGHT); | ||||||
|  |   if (width > screen_width || height > screen_height) { | ||||||
|  |     if (width > screen_width) { | ||||||
|  |       height = (height * screen_width + width - 1) / width; | ||||||
|  |       width = screen_width; | ||||||
|  |     } | ||||||
|  |     if (height > screen_height) { | ||||||
|  |       width = (width * screen_height + height - 1) / height; | ||||||
|  |       height = screen_height; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   glutInitWindowSize(width, height); | ||||||
|  |   glutCreateWindow("WebP viewer"); | ||||||
|  |   glutDisplayFunc(HandleDisplay); | ||||||
|  |   glutReshapeFunc(HandleReshape); | ||||||
|  |   glutIdleFunc(NULL); | ||||||
|  |   glutKeyboardFunc(HandleKey); | ||||||
|  |   glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | ||||||
|  |   glEnable(GL_BLEND); | ||||||
|  |   glClearColor(0, 0, 0, 0);  // window will be cleared to black (no blend) | ||||||
|  |   DrawBackground(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | //------------------------------------------------------------------------------ | ||||||
|  | // Main | ||||||
|  |  | ||||||
|  | static void Help(void) { | ||||||
|  |   printf( | ||||||
|  |       "Usage: vwebp in_file [options]\n\n" | ||||||
|  |       "Decodes the WebP image file and visualize it using OpenGL\n" | ||||||
|  |       "Options are:\n" | ||||||
|  |       "  -version ..... print version number and exit\n" | ||||||
|  |       "  -noicc ....... don't use the icc profile if present\n" | ||||||
|  |       "  -nofancy ..... don't use the fancy YUV420 upscaler\n" | ||||||
|  |       "  -nofilter .... disable in-loop filtering\n" | ||||||
|  |       "  -dither <int>  dithering strength (0..100), default=50\n" | ||||||
|  |       "  -noalphadither disable alpha plane dithering\n" | ||||||
|  |       "  -usebgcolor .. display background color\n" | ||||||
|  |       "  -mt .......... use multi-threading\n" | ||||||
|  |       "  -info ........ print info\n" | ||||||
|  |       "  -h ........... this help message\n" | ||||||
|  |       "\n" | ||||||
|  |       "Keyboard shortcuts:\n" | ||||||
|  |       "  'c' ................ toggle use of color profile\n" | ||||||
|  |       "  'b' ................ toggle background color display\n" | ||||||
|  |       "  'i' ................ overlay file information\n" | ||||||
|  |       "  'd' ................ disable blending & disposal (debug)\n" | ||||||
|  |       "  'q' / 'Q' / ESC .... quit\n"); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int main(int argc, char* argv[]) { | ||||||
|  |   int c; | ||||||
|  |   WebPDecoderConfig* const config = &kParams.config; | ||||||
|  |   WebPIterator* const curr = &kParams.curr_frame; | ||||||
|  |  | ||||||
|  |   INIT_WARGV(argc, argv); | ||||||
|  |  | ||||||
|  |   if (!WebPInitDecoderConfig(config)) { | ||||||
|  |     fprintf(stderr, "Library version mismatch!\n"); | ||||||
|  |     FREE_WARGV_AND_RETURN(-1); | ||||||
|  |   } | ||||||
|  |   config->options.dithering_strength = 50; | ||||||
|  |   config->options.alpha_dithering_strength = 100; | ||||||
|  |   kParams.use_color_profile = 1; | ||||||
|  |   // Background color hidden by default to see transparent areas. | ||||||
|  |   kParams.draw_anim_background_color = 0; | ||||||
|  |  | ||||||
|  |   for (c = 1; c < argc; ++c) { | ||||||
|  |     int parse_error = 0; | ||||||
|  |     if (!strcmp(argv[c], "-h") || !strcmp(argv[c], "-help")) { | ||||||
|  |       Help(); | ||||||
|  |       FREE_WARGV_AND_RETURN(0); | ||||||
|  |     } else if (!strcmp(argv[c], "-noicc")) { | ||||||
|  |       kParams.use_color_profile = 0; | ||||||
|  |     } else if (!strcmp(argv[c], "-nofancy")) { | ||||||
|  |       config->options.no_fancy_upsampling = 1; | ||||||
|  |     } else if (!strcmp(argv[c], "-nofilter")) { | ||||||
|  |       config->options.bypass_filtering = 1; | ||||||
|  |     } else if (!strcmp(argv[c], "-noalphadither")) { | ||||||
|  |       config->options.alpha_dithering_strength = 0; | ||||||
|  |     } else if (!strcmp(argv[c], "-usebgcolor")) { | ||||||
|  |       kParams.draw_anim_background_color = 1; | ||||||
|  |     } else if (!strcmp(argv[c], "-dither") && c + 1 < argc) { | ||||||
|  |       config->options.dithering_strength = | ||||||
|  |           ExUtilGetInt(argv[++c], 0, &parse_error); | ||||||
|  |     } else if (!strcmp(argv[c], "-info")) { | ||||||
|  |       kParams.print_info = 1; | ||||||
|  |     } else if (!strcmp(argv[c], "-version")) { | ||||||
|  |       const int dec_version = WebPGetDecoderVersion(); | ||||||
|  |       const int dmux_version = WebPGetDemuxVersion(); | ||||||
|  |       printf("WebP Decoder version: %d.%d.%d\nWebP Demux version: %d.%d.%d\n", | ||||||
|  |              (dec_version >> 16) & 0xff, (dec_version >> 8) & 0xff, | ||||||
|  |              dec_version & 0xff, (dmux_version >> 16) & 0xff, | ||||||
|  |              (dmux_version >> 8) & 0xff, dmux_version & 0xff); | ||||||
|  |       FREE_WARGV_AND_RETURN(0); | ||||||
|  |     } else if (!strcmp(argv[c], "-mt")) { | ||||||
|  |       config->options.use_threads = 1; | ||||||
|  |     } else if (!strcmp(argv[c], "--")) { | ||||||
|  |       if (c < argc - 1) kParams.file_name = (const char*)GET_WARGV(argv, ++c); | ||||||
|  |       break; | ||||||
|  |     } else if (argv[c][0] == '-') { | ||||||
|  |       printf("Unknown option '%s'\n", argv[c]); | ||||||
|  |       Help(); | ||||||
|  |       FREE_WARGV_AND_RETURN(-1); | ||||||
|  |     } else { | ||||||
|  |       kParams.file_name = (const char*)GET_WARGV(argv, c); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     if (parse_error) { | ||||||
|  |       Help(); | ||||||
|  |       FREE_WARGV_AND_RETURN(-1); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   if (kParams.file_name == NULL) { | ||||||
|  |     printf("missing input file!!\n"); | ||||||
|  |     Help(); | ||||||
|  |     FREE_WARGV_AND_RETURN(0); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   if (!ImgIoUtilReadFile(kParams.file_name, | ||||||
|  |                          &kParams.data.bytes, &kParams.data.size)) { | ||||||
|  |     goto Error; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   if (!WebPGetInfo(kParams.data.bytes, kParams.data.size, NULL, NULL)) { | ||||||
|  |     fprintf(stderr, "Input file doesn't appear to be WebP format.\n"); | ||||||
|  |     goto Error; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   kParams.dmux = WebPDemux(&kParams.data); | ||||||
|  |   if (kParams.dmux == NULL) { | ||||||
|  |     fprintf(stderr, "Could not create demuxing object!\n"); | ||||||
|  |     goto Error; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   kParams.canvas_width = WebPDemuxGetI(kParams.dmux, WEBP_FF_CANVAS_WIDTH); | ||||||
|  |   kParams.canvas_height = WebPDemuxGetI(kParams.dmux, WEBP_FF_CANVAS_HEIGHT); | ||||||
|  |   if (kParams.print_info) { | ||||||
|  |     printf("Canvas: %d x %d\n", kParams.canvas_width, kParams.canvas_height); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   ClearPreviousFrame(); | ||||||
|  |  | ||||||
|  |   memset(&kParams.iccp, 0, sizeof(kParams.iccp)); | ||||||
|  |   kParams.has_color_profile = | ||||||
|  |       !!(WebPDemuxGetI(kParams.dmux, WEBP_FF_FORMAT_FLAGS) & ICCP_FLAG); | ||||||
|  |   if (kParams.has_color_profile) { | ||||||
|  | #ifdef WEBP_HAVE_QCMS | ||||||
|  |     if (!WebPDemuxGetChunk(kParams.dmux, "ICCP", 1, &kParams.iccp)) goto Error; | ||||||
|  |     printf("VP8X: Found color profile\n"); | ||||||
|  | #else | ||||||
|  |     fprintf(stderr, "Warning: color profile present, but qcms is unavailable!\n" | ||||||
|  |             "Build libqcms from Mozilla or Chromium and define WEBP_HAVE_QCMS " | ||||||
|  |             "before building.\n"); | ||||||
|  | #endif | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   if (!WebPDemuxGetFrame(kParams.dmux, 1, curr)) goto Error; | ||||||
|  |  | ||||||
|  |   kParams.has_animation = (curr->num_frames > 1); | ||||||
|  |   kParams.loop_count = (int)WebPDemuxGetI(kParams.dmux, WEBP_FF_LOOP_COUNT); | ||||||
|  |   kParams.bg_color = WebPDemuxGetI(kParams.dmux, WEBP_FF_BACKGROUND_COLOR); | ||||||
|  |   printf("VP8X: Found %d images in file (loop count = %d)\n", | ||||||
|  |          curr->num_frames, kParams.loop_count); | ||||||
|  |  | ||||||
|  |   // Decode first frame | ||||||
|  |   if (!Decode()) goto Error; | ||||||
|  |  | ||||||
|  |   // Position iterator to last frame. Next call to HandleDisplay will wrap over. | ||||||
|  |   // We take this into account by bumping up loop_count. | ||||||
|  |   WebPDemuxGetFrame(kParams.dmux, 0, curr); | ||||||
|  |   if (kParams.loop_count) ++kParams.loop_count; | ||||||
|  |  | ||||||
|  | #if defined(__unix__) || defined(__CYGWIN__) | ||||||
|  |   // Work around GLUT compositor bug. | ||||||
|  |   // https://bugs.launchpad.net/ubuntu/+source/freeglut/+bug/369891 | ||||||
|  |   setenv("XLIB_SKIP_ARGB_VISUALS", "1", 1); | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  |   // Start display (and timer) | ||||||
|  |   glutInit(&argc, argv); | ||||||
|  | #ifdef FREEGLUT | ||||||
|  |   glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_CONTINUE_EXECUTION); | ||||||
|  | #endif | ||||||
|  |   StartDisplay(); | ||||||
|  |  | ||||||
|  |   if (kParams.has_animation) glutTimerFunc(0, decode_callback, 0); | ||||||
|  |   glutMainLoop(); | ||||||
|  |  | ||||||
|  |   // Should only be reached when using FREEGLUT: | ||||||
|  |   ClearParams(); | ||||||
|  |   FREE_WARGV_AND_RETURN(0); | ||||||
|  |  | ||||||
|  |  Error: | ||||||
|  |   ClearParams(); | ||||||
|  |   FREE_WARGV_AND_RETURN(-1); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #else   // !WEBP_HAVE_GL | ||||||
|  |  | ||||||
|  | int main(int argc, const char* argv[]) { | ||||||
|  |   fprintf(stderr, "OpenGL support not enabled in %s.\n", argv[0]); | ||||||
|  |   (void)argc; | ||||||
|  |   return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | //------------------------------------------------------------------------------ | ||||||
							
								
								
									
										1186
									
								
								external/libwebp/libwebp/examples/webpinfo.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1186
									
								
								external/libwebp/libwebp/examples/webpinfo.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1234
									
								
								external/libwebp/libwebp/examples/webpmux.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1234
									
								
								external/libwebp/libwebp/examples/webpmux.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										44
									
								
								external/libwebp/libwebp/extras/Makefile.am
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								external/libwebp/libwebp/extras/Makefile.am
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,44 @@ | |||||||
|  | AM_CPPFLAGS += -I$(top_builddir) -I$(top_srcdir) | ||||||
|  | AM_CPPFLAGS += -I$(top_builddir)/src -I$(top_srcdir)/src | ||||||
|  | noinst_LTLIBRARIES = libwebpextras.la | ||||||
|  |  | ||||||
|  | noinst_HEADERS = | ||||||
|  | noinst_HEADERS += ../src/webp/types.h | ||||||
|  |  | ||||||
|  | libwebpextras_la_SOURCES = | ||||||
|  | libwebpextras_la_SOURCES += extras.c extras.h quality_estimate.c | ||||||
|  |  | ||||||
|  | libwebpextras_la_CPPFLAGS = $(AM_CPPFLAGS) | ||||||
|  | libwebpextras_la_LDFLAGS = -lm | ||||||
|  | libwebpextras_la_LIBADD = ../src/libwebp.la | ||||||
|  |  | ||||||
|  | noinst_PROGRAMS = | ||||||
|  | noinst_PROGRAMS += webp_quality | ||||||
|  | if BUILD_DEMUX | ||||||
|  |   noinst_PROGRAMS += get_disto | ||||||
|  | endif | ||||||
|  | if BUILD_VWEBP_SDL | ||||||
|  |   noinst_PROGRAMS += vwebp_sdl | ||||||
|  | endif | ||||||
|  |  | ||||||
|  | get_disto_SOURCES  = get_disto.c | ||||||
|  | get_disto_CPPFLAGS = $(AM_CPPFLAGS) | ||||||
|  | get_disto_LDADD = | ||||||
|  | get_disto_LDADD += ../imageio/libimageio_util.la | ||||||
|  | get_disto_LDADD += ../imageio/libimagedec.la | ||||||
|  | get_disto_LDADD += ../src/libwebp.la | ||||||
|  | get_disto_LDADD += $(PNG_LIBS) $(JPEG_LIBS) $(TIFF_LIBS) | ||||||
|  |  | ||||||
|  | webp_quality_SOURCES  = webp_quality.c | ||||||
|  | webp_quality_CPPFLAGS = $(AM_CPPFLAGS) | ||||||
|  | webp_quality_LDADD = | ||||||
|  | webp_quality_LDADD += ../imageio/libimageio_util.la | ||||||
|  | webp_quality_LDADD += libwebpextras.la | ||||||
|  | webp_quality_LDADD += ../src/libwebp.la | ||||||
|  |  | ||||||
|  | vwebp_sdl_SOURCES  = vwebp_sdl.c webp_to_sdl.c webp_to_sdl.h | ||||||
|  | vwebp_sdl_CPPFLAGS = $(AM_CPPFLAGS) $(SDL_INCLUDES) | ||||||
|  | vwebp_sdl_LDADD = | ||||||
|  | vwebp_sdl_LDADD += ../imageio/libimageio_util.la | ||||||
|  | vwebp_sdl_LDADD += ../src/libwebp.la | ||||||
|  | vwebp_sdl_LDADD += $(SDL_LIBS) | ||||||
							
								
								
									
										162
									
								
								external/libwebp/libwebp/extras/extras.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										162
									
								
								external/libwebp/libwebp/extras/extras.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,162 @@ | |||||||
|  | // Copyright 2015 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. | ||||||
|  | // ----------------------------------------------------------------------------- | ||||||
|  | // | ||||||
|  | //  Additional WebP utilities. | ||||||
|  | // | ||||||
|  |  | ||||||
|  | #include "extras/extras.h" | ||||||
|  | #include "webp/format_constants.h" | ||||||
|  | #include "src/dsp/dsp.h" | ||||||
|  |  | ||||||
|  | #include <assert.h> | ||||||
|  | #include <string.h> | ||||||
|  |  | ||||||
|  | #define XTRA_MAJ_VERSION 1 | ||||||
|  | #define XTRA_MIN_VERSION 3 | ||||||
|  | #define XTRA_REV_VERSION 1 | ||||||
|  |  | ||||||
|  | //------------------------------------------------------------------------------ | ||||||
|  |  | ||||||
|  | int WebPGetExtrasVersion(void) { | ||||||
|  |   return (XTRA_MAJ_VERSION << 16) | (XTRA_MIN_VERSION << 8) | XTRA_REV_VERSION; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | //------------------------------------------------------------------------------ | ||||||
|  |  | ||||||
|  | int WebPImportGray(const uint8_t* gray_data, WebPPicture* pic) { | ||||||
|  |   int y, width, uv_width; | ||||||
|  |   if (pic == NULL || gray_data == NULL) return 0; | ||||||
|  |   pic->colorspace = WEBP_YUV420; | ||||||
|  |   if (!WebPPictureAlloc(pic)) return 0; | ||||||
|  |   width = pic->width; | ||||||
|  |   uv_width = (width + 1) >> 1; | ||||||
|  |   for (y = 0; y < pic->height; ++y) { | ||||||
|  |     memcpy(pic->y + y * pic->y_stride, gray_data, width); | ||||||
|  |     gray_data += width;    // <- we could use some 'data_stride' here if needed | ||||||
|  |     if ((y & 1) == 0) { | ||||||
|  |       memset(pic->u + (y >> 1) * pic->uv_stride, 128, uv_width); | ||||||
|  |       memset(pic->v + (y >> 1) * pic->uv_stride, 128, uv_width); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   return 1; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int WebPImportRGB565(const uint8_t* rgb565, WebPPicture* pic) { | ||||||
|  |   int x, y; | ||||||
|  |   uint32_t* dst; | ||||||
|  |   if (pic == NULL || rgb565 == NULL) return 0; | ||||||
|  |   pic->colorspace = WEBP_YUV420; | ||||||
|  |   pic->use_argb = 1; | ||||||
|  |   if (!WebPPictureAlloc(pic)) return 0; | ||||||
|  |   dst = pic->argb; | ||||||
|  |   for (y = 0; y < pic->height; ++y) { | ||||||
|  |     const int width = pic->width; | ||||||
|  |     for (x = 0; x < width; ++x) { | ||||||
|  | #if defined(WEBP_SWAP_16BIT_CSP) && (WEBP_SWAP_16BIT_CSP == 1) | ||||||
|  |       const uint32_t rg = rgb565[2 * x + 1]; | ||||||
|  |       const uint32_t gb = rgb565[2 * x + 0]; | ||||||
|  | #else | ||||||
|  |       const uint32_t rg = rgb565[2 * x + 0]; | ||||||
|  |       const uint32_t gb = rgb565[2 * x + 1]; | ||||||
|  | #endif | ||||||
|  |       uint32_t r = rg & 0xf8; | ||||||
|  |       uint32_t g = ((rg << 5) | (gb >> 3)) & 0xfc; | ||||||
|  |       uint32_t b = (gb << 5); | ||||||
|  |       // dithering | ||||||
|  |       r = r | (r >> 5); | ||||||
|  |       g = g | (g >> 6); | ||||||
|  |       b = b | (b >> 5); | ||||||
|  |       dst[x] = (0xffu << 24) | (r << 16) | (g << 8) | b; | ||||||
|  |     } | ||||||
|  |     rgb565 += 2 * width; | ||||||
|  |     dst += pic->argb_stride; | ||||||
|  |   } | ||||||
|  |   return 1; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int WebPImportRGB4444(const uint8_t* rgb4444, WebPPicture* pic) { | ||||||
|  |   int x, y; | ||||||
|  |   uint32_t* dst; | ||||||
|  |   if (pic == NULL || rgb4444 == NULL) return 0; | ||||||
|  |   pic->colorspace = WEBP_YUV420; | ||||||
|  |   pic->use_argb = 1; | ||||||
|  |   if (!WebPPictureAlloc(pic)) return 0; | ||||||
|  |   dst = pic->argb; | ||||||
|  |   for (y = 0; y < pic->height; ++y) { | ||||||
|  |     const int width = pic->width; | ||||||
|  |     for (x = 0; x < width; ++x) { | ||||||
|  | #if defined(WEBP_SWAP_16BIT_CSP) && (WEBP_SWAP_16BIT_CSP == 1) | ||||||
|  |       const uint32_t rg = rgb4444[2 * x + 1]; | ||||||
|  |       const uint32_t ba = rgb4444[2 * x + 0]; | ||||||
|  | #else | ||||||
|  |       const uint32_t rg = rgb4444[2 * x + 0]; | ||||||
|  |       const uint32_t ba = rgb4444[2 * x + 1]; | ||||||
|  | #endif | ||||||
|  |       uint32_t r = rg & 0xf0; | ||||||
|  |       uint32_t g = (rg << 4); | ||||||
|  |       uint32_t b = (ba & 0xf0); | ||||||
|  |       uint32_t a = (ba << 4); | ||||||
|  |       // dithering | ||||||
|  |       r = r | (r >> 4); | ||||||
|  |       g = g | (g >> 4); | ||||||
|  |       b = b | (b >> 4); | ||||||
|  |       a = a | (a >> 4); | ||||||
|  |       dst[x] = (a << 24) | (r << 16) | (g << 8) | b; | ||||||
|  |     } | ||||||
|  |     rgb4444 += 2 * width; | ||||||
|  |     dst += pic->argb_stride; | ||||||
|  |   } | ||||||
|  |   return 1; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int WebPImportColorMappedARGB(const uint8_t* indexed, int indexed_stride, | ||||||
|  |                               const uint32_t palette[], int palette_size, | ||||||
|  |                               WebPPicture* pic) { | ||||||
|  |   int x, y; | ||||||
|  |   uint32_t* dst; | ||||||
|  |   // 256 as the input buffer is uint8_t. | ||||||
|  |   assert(MAX_PALETTE_SIZE <= 256); | ||||||
|  |   if (pic == NULL || indexed == NULL || indexed_stride < pic->width || | ||||||
|  |       palette == NULL || palette_size > MAX_PALETTE_SIZE || palette_size <= 0) { | ||||||
|  |     return 0; | ||||||
|  |   } | ||||||
|  |   pic->use_argb = 1; | ||||||
|  |   if (!WebPPictureAlloc(pic)) return 0; | ||||||
|  |   dst = pic->argb; | ||||||
|  |   for (y = 0; y < pic->height; ++y) { | ||||||
|  |     for (x = 0; x < pic->width; ++x) { | ||||||
|  |       // Make sure we are within the palette. | ||||||
|  |       if (indexed[x] >= palette_size) { | ||||||
|  |         WebPPictureFree(pic); | ||||||
|  |         return 0; | ||||||
|  |       } | ||||||
|  |       dst[x] = palette[indexed[x]]; | ||||||
|  |     } | ||||||
|  |     indexed += indexed_stride; | ||||||
|  |     dst += pic->argb_stride; | ||||||
|  |   } | ||||||
|  |   return 1; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | //------------------------------------------------------------------------------ | ||||||
|  |  | ||||||
|  | int WebPUnmultiplyARGB(WebPPicture* pic) { | ||||||
|  |   int y; | ||||||
|  |   uint32_t* dst; | ||||||
|  |   if (pic == NULL || pic->use_argb != 1 || pic->argb == NULL) return 0; | ||||||
|  |   WebPInitAlphaProcessing(); | ||||||
|  |   dst = pic->argb; | ||||||
|  |   for (y = 0; y < pic->height; ++y) { | ||||||
|  |     WebPMultARGBRow(dst, pic->width, /*inverse=*/1); | ||||||
|  |     dst += pic->argb_stride; | ||||||
|  |   } | ||||||
|  |   return 1; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | //------------------------------------------------------------------------------ | ||||||
							
								
								
									
										77
									
								
								external/libwebp/libwebp/extras/extras.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										77
									
								
								external/libwebp/libwebp/extras/extras.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,77 @@ | |||||||
|  | // Copyright 2015 Google Inc. All Rights Reserved. | ||||||
|  | // | ||||||
|  | // Use of this source code is governed by a BSD-style license | ||||||
|  | // that can be found in the COPYING file in the root of the source | ||||||
|  | // tree. An additional intellectual property rights grant can be found | ||||||
|  | // in the file PATENTS. All contributing project authors may | ||||||
|  | // be found in the AUTHORS file in the root of the source tree. | ||||||
|  | // ----------------------------------------------------------------------------- | ||||||
|  | // | ||||||
|  |  | ||||||
|  | #ifndef WEBP_EXTRAS_EXTRAS_H_ | ||||||
|  | #define WEBP_EXTRAS_EXTRAS_H_ | ||||||
|  |  | ||||||
|  | #include "webp/types.h" | ||||||
|  |  | ||||||
|  | #ifdef __cplusplus | ||||||
|  | extern "C" { | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | #include "webp/encode.h" | ||||||
|  |  | ||||||
|  | #define WEBP_EXTRAS_ABI_VERSION 0x0002    // MAJOR(8b) + MINOR(8b) | ||||||
|  |  | ||||||
|  | //------------------------------------------------------------------------------ | ||||||
|  |  | ||||||
|  | // Returns the version number of the extras library, packed in hexadecimal using | ||||||
|  | // 8bits for each of major/minor/revision. E.g: v2.5.7 is 0x020507. | ||||||
|  | WEBP_EXTERN int WebPGetExtrasVersion(void); | ||||||
|  |  | ||||||
|  | //------------------------------------------------------------------------------ | ||||||
|  | // Ad-hoc colorspace importers. | ||||||
|  |  | ||||||
|  | // Import luma sample (gray scale image) into 'picture'. The 'picture' | ||||||
|  | // width and height must be set prior to calling this function. | ||||||
|  | WEBP_EXTERN int WebPImportGray(const uint8_t* gray, WebPPicture* picture); | ||||||
|  |  | ||||||
|  | // Import rgb sample in RGB565 packed format into 'picture'. The 'picture' | ||||||
|  | // width and height must be set prior to calling this function. | ||||||
|  | WEBP_EXTERN int WebPImportRGB565(const uint8_t* rgb565, WebPPicture* pic); | ||||||
|  |  | ||||||
|  | // Import rgb sample in RGB4444 packed format into 'picture'. The 'picture' | ||||||
|  | // width and height must be set prior to calling this function. | ||||||
|  | WEBP_EXTERN int WebPImportRGB4444(const uint8_t* rgb4444, WebPPicture* pic); | ||||||
|  |  | ||||||
|  | // Import a color mapped image. The number of colors is less or equal to | ||||||
|  | // MAX_PALETTE_SIZE. 'pic' must have been initialized. Its content, if any, | ||||||
|  | // will be discarded. Returns 'false' in case of error, or if indexed[] contains | ||||||
|  | // invalid indices. | ||||||
|  | WEBP_EXTERN int | ||||||
|  | WebPImportColorMappedARGB(const uint8_t* indexed, int indexed_stride, | ||||||
|  |                           const uint32_t palette[], int palette_size, | ||||||
|  |                           WebPPicture* pic); | ||||||
|  |  | ||||||
|  | // Convert the ARGB content of 'pic' from associated to unassociated. | ||||||
|  | // 'pic' can be for instance the result of calling of some WebPPictureImportXXX | ||||||
|  | // functions, with pic->use_argb set to 'true'. It is assumed (and not checked) | ||||||
|  | // that the pre-multiplied r/g/b values as less or equal than the alpha value. | ||||||
|  | // Return false in case of error (invalid parameter, ...). | ||||||
|  | WEBP_EXTERN int WebPUnmultiplyARGB(WebPPicture* pic); | ||||||
|  |  | ||||||
|  | //------------------------------------------------------------------------------ | ||||||
|  |  | ||||||
|  | // Parse a bitstream, search for VP8 (lossy) header and report a | ||||||
|  | // rough estimation of the quality factor used for compressing the bitstream. | ||||||
|  | // If the bitstream is in lossless format, the special value '101' is returned. | ||||||
|  | // Otherwise (lossy bitstream), the returned value is in the range [0..100]. | ||||||
|  | // Any error (invalid bitstream, animated WebP, incomplete header, etc.) | ||||||
|  | // will return a value of -1. | ||||||
|  | WEBP_EXTERN int VP8EstimateQuality(const uint8_t* const data, size_t size); | ||||||
|  |  | ||||||
|  | //------------------------------------------------------------------------------ | ||||||
|  |  | ||||||
|  | #ifdef __cplusplus | ||||||
|  | }    // extern "C" | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | #endif  // WEBP_EXTRAS_EXTRAS_H_ | ||||||
							
								
								
									
										356
									
								
								external/libwebp/libwebp/extras/get_disto.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										356
									
								
								external/libwebp/libwebp/extras/get_disto.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,356 @@ | |||||||
|  | // Copyright 2016 Google Inc. All Rights Reserved. | ||||||
|  | // | ||||||
|  | // Use of this source code is governed by a BSD-style license | ||||||
|  | // that can be found in the COPYING file in the root of the source | ||||||
|  | // tree. An additional intellectual property rights grant can be found | ||||||
|  | // in the file PATENTS. All contributing project authors may | ||||||
|  | // be found in the AUTHORS file in the root of the source tree. | ||||||
|  | // ----------------------------------------------------------------------------- | ||||||
|  | // | ||||||
|  | // Simple tool to load two webp/png/jpg/tiff files and compute PSNR/SSIM. | ||||||
|  | // This is mostly a wrapper around WebPPictureDistortion(). | ||||||
|  | // | ||||||
|  | /* | ||||||
|  |  gcc -o get_disto get_disto.c -O3 -I../ -L../examples -L../imageio \ | ||||||
|  |     -lexample_util -limageio_util -limagedec -lwebp -L/opt/local/lib \ | ||||||
|  |     -lpng -lz -ljpeg -ltiff -lm -lpthread | ||||||
|  | */ | ||||||
|  | // | ||||||
|  | // Author: Skal (pascal.massimino@gmail.com) | ||||||
|  |  | ||||||
|  | #include <assert.h> | ||||||
|  | #include <stdio.h> | ||||||
|  | #include <stdlib.h> | ||||||
|  | #include <string.h> | ||||||
|  |  | ||||||
|  | #include "webp/encode.h" | ||||||
|  | #include "imageio/image_dec.h" | ||||||
|  | #include "imageio/imageio_util.h" | ||||||
|  | #include "../examples/unicode.h" | ||||||
|  |  | ||||||
|  | static size_t ReadPicture(const char* const filename, WebPPicture* const pic, | ||||||
|  |                           int keep_alpha) { | ||||||
|  |   const uint8_t* data = NULL; | ||||||
|  |   size_t data_size = 0; | ||||||
|  |   WebPImageReader reader = NULL; | ||||||
|  |   int ok = ImgIoUtilReadFile(filename, &data, &data_size); | ||||||
|  |   if (!ok) goto End; | ||||||
|  |  | ||||||
|  |   pic->use_argb = 1;  // force ARGB | ||||||
|  |  | ||||||
|  | #ifdef HAVE_WINCODEC_H | ||||||
|  |   // Try to decode the file using WIC falling back to the other readers for | ||||||
|  |   // e.g., WebP. | ||||||
|  |   ok = ReadPictureWithWIC(filename, pic, keep_alpha, NULL); | ||||||
|  |   if (ok) goto End; | ||||||
|  | #endif | ||||||
|  |   reader = WebPGuessImageReader(data, data_size); | ||||||
|  |   ok = reader(data, data_size, pic, keep_alpha, NULL); | ||||||
|  |  | ||||||
|  |  End: | ||||||
|  |   if (!ok) { | ||||||
|  |     WFPRINTF(stderr, "Error! Could not process file %s\n", | ||||||
|  |              (const W_CHAR*)filename); | ||||||
|  |   } | ||||||
|  |   free((void*)data); | ||||||
|  |   return ok ? data_size : 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static void RescalePlane(uint8_t* plane, int width, int height, | ||||||
|  |                          int x_stride, int y_stride, int max) { | ||||||
|  |   const uint32_t factor = (max > 0) ? (255u << 16) / max : 0; | ||||||
|  |   int x, y; | ||||||
|  |   for (y = 0; y < height; ++y) { | ||||||
|  |     uint8_t* const ptr = plane + y * y_stride; | ||||||
|  |     for (x = 0; x < width * x_stride; x += x_stride) { | ||||||
|  |       const uint32_t diff = (ptr[x] * factor + (1 << 15)) >> 16; | ||||||
|  |       ptr[x] = diff; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Return the max absolute difference. | ||||||
|  | static int DiffScaleChannel(uint8_t* src1, int stride1, | ||||||
|  |                             const uint8_t* src2, int stride2, | ||||||
|  |                             int x_stride, int w, int h, int do_scaling) { | ||||||
|  |   int x, y; | ||||||
|  |   int max = 0; | ||||||
|  |   for (y = 0; y < h; ++y) { | ||||||
|  |     uint8_t* const ptr1 = src1 + y * stride1; | ||||||
|  |     const uint8_t* const ptr2 = src2 + y * stride2; | ||||||
|  |     for (x = 0; x < w * x_stride; x += x_stride) { | ||||||
|  |       const int diff = abs(ptr1[x] - ptr2[x]); | ||||||
|  |       if (diff > max) max = diff; | ||||||
|  |       ptr1[x] = diff; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   if (do_scaling) RescalePlane(src1, w, h, x_stride, stride1, max); | ||||||
|  |   return max; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | //------------------------------------------------------------------------------ | ||||||
|  | // SSIM calculation. We re-implement these functions here, out of dsp/, to avoid | ||||||
|  | // breaking the library's hidden visibility. This code duplication avoids the | ||||||
|  | // bigger annoyance of having to open up internal details of libdsp... | ||||||
|  |  | ||||||
|  | #define SSIM_KERNEL 3   // total size of the kernel: 2 * SSIM_KERNEL + 1 | ||||||
|  |  | ||||||
|  | // struct for accumulating statistical moments | ||||||
|  | typedef struct { | ||||||
|  |   uint32_t w;              // sum(w_i) : sum of weights | ||||||
|  |   uint32_t xm, ym;         // sum(w_i * x_i), sum(w_i * y_i) | ||||||
|  |   uint32_t xxm, xym, yym;  // sum(w_i * x_i * x_i), etc. | ||||||
|  | } DistoStats; | ||||||
|  |  | ||||||
|  | // hat-shaped filter. Sum of coefficients is equal to 16. | ||||||
|  | static const uint32_t kWeight[2 * SSIM_KERNEL + 1] = { 1, 2, 3, 4, 3, 2, 1 }; | ||||||
|  |  | ||||||
|  | static WEBP_INLINE double SSIMCalculation(const DistoStats* const stats) { | ||||||
|  |   const uint32_t N = stats->w; | ||||||
|  |   const uint32_t w2 =  N * N; | ||||||
|  |   const uint32_t C1 = 20 * w2; | ||||||
|  |   const uint32_t C2 = 60 * w2; | ||||||
|  |   const uint32_t C3 = 8 * 8 * w2;   // 'dark' limit ~= 6 | ||||||
|  |   const uint64_t xmxm = (uint64_t)stats->xm * stats->xm; | ||||||
|  |   const uint64_t ymym = (uint64_t)stats->ym * stats->ym; | ||||||
|  |   if (xmxm + ymym >= C3) { | ||||||
|  |     const int64_t xmym = (int64_t)stats->xm * stats->ym; | ||||||
|  |     const int64_t sxy = (int64_t)stats->xym * N - xmym;    // can be negative | ||||||
|  |     const uint64_t sxx = (uint64_t)stats->xxm * N - xmxm; | ||||||
|  |     const uint64_t syy = (uint64_t)stats->yym * N - ymym; | ||||||
|  |     // we descale by 8 to prevent overflow during the fnum/fden multiply. | ||||||
|  |     const uint64_t num_S = (2 * (uint64_t)(sxy < 0 ? 0 : sxy) + C2) >> 8; | ||||||
|  |     const uint64_t den_S = (sxx + syy + C2) >> 8; | ||||||
|  |     const uint64_t fnum = (2 * xmym + C1) * num_S; | ||||||
|  |     const uint64_t fden = (xmxm + ymym + C1) * den_S; | ||||||
|  |     const double r = (double)fnum / fden; | ||||||
|  |     assert(r >= 0. && r <= 1.0); | ||||||
|  |     return r; | ||||||
|  |   } | ||||||
|  |   return 1.;   // area is too dark to contribute meaningfully | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static double SSIMGetClipped(const uint8_t* src1, int stride1, | ||||||
|  |                              const uint8_t* src2, int stride2, | ||||||
|  |                              int xo, int yo, int W, int H) { | ||||||
|  |   DistoStats stats = { 0, 0, 0, 0, 0, 0 }; | ||||||
|  |   const int ymin = (yo - SSIM_KERNEL < 0) ? 0 : yo - SSIM_KERNEL; | ||||||
|  |   const int ymax = (yo + SSIM_KERNEL > H - 1) ? H - 1 : yo + SSIM_KERNEL; | ||||||
|  |   const int xmin = (xo - SSIM_KERNEL < 0) ? 0 : xo - SSIM_KERNEL; | ||||||
|  |   const int xmax = (xo + SSIM_KERNEL > W - 1) ? W - 1 : xo + SSIM_KERNEL; | ||||||
|  |   int x, y; | ||||||
|  |   src1 += ymin * stride1; | ||||||
|  |   src2 += ymin * stride2; | ||||||
|  |   for (y = ymin; y <= ymax; ++y, src1 += stride1, src2 += stride2) { | ||||||
|  |     for (x = xmin; x <= xmax; ++x) { | ||||||
|  |       const uint32_t w = kWeight[SSIM_KERNEL + x - xo] | ||||||
|  |                        * kWeight[SSIM_KERNEL + y - yo]; | ||||||
|  |       const uint32_t s1 = src1[x]; | ||||||
|  |       const uint32_t s2 = src2[x]; | ||||||
|  |       stats.w   += w; | ||||||
|  |       stats.xm  += w * s1; | ||||||
|  |       stats.ym  += w * s2; | ||||||
|  |       stats.xxm += w * s1 * s1; | ||||||
|  |       stats.xym += w * s1 * s2; | ||||||
|  |       stats.yym += w * s2 * s2; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   return SSIMCalculation(&stats); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Compute SSIM-score map. Return -1 in case of error, max diff otherwise. | ||||||
|  | static int SSIMScaleChannel(uint8_t* src1, int stride1, | ||||||
|  |                             const uint8_t* src2, int stride2, | ||||||
|  |                             int x_stride, int w, int h, int do_scaling) { | ||||||
|  |   int x, y; | ||||||
|  |   int max = 0; | ||||||
|  |   uint8_t* const plane1 = (uint8_t*)malloc(2 * w * h * sizeof(*plane1)); | ||||||
|  |   uint8_t* const plane2 = plane1 + w * h; | ||||||
|  |   if (plane1 == NULL) return -1; | ||||||
|  |  | ||||||
|  |   // extract plane | ||||||
|  |   for (y = 0; y < h; ++y) { | ||||||
|  |     for (x = 0; x < w; ++x) { | ||||||
|  |       plane1[x + y * w] = src1[x * x_stride + y * stride1]; | ||||||
|  |       plane2[x + y * w] = src2[x * x_stride + y * stride2]; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   for (y = 0; y < h; ++y) { | ||||||
|  |     for (x = 0; x < w; ++x) { | ||||||
|  |       const double ssim = SSIMGetClipped(plane1, w, plane2, w, x, y, w, h); | ||||||
|  |       int diff = (int)(255 * (1. - ssim)); | ||||||
|  |       if (diff < 0) { | ||||||
|  |         diff = 0; | ||||||
|  |       } else if (diff > max) { | ||||||
|  |         max = diff; | ||||||
|  |       } | ||||||
|  |       src1[x * x_stride + y * stride1] = (diff > 255) ? 255u : (uint8_t)diff; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   free(plane1); | ||||||
|  |  | ||||||
|  |   if (do_scaling) RescalePlane(src1, w, h, x_stride, stride1, max); | ||||||
|  |   return max; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Convert an argb picture to luminance. | ||||||
|  | static void ConvertToGray(WebPPicture* const pic) { | ||||||
|  |   int x, y; | ||||||
|  |   assert(pic != NULL); | ||||||
|  |   assert(pic->use_argb); | ||||||
|  |   for (y = 0; y < pic->height; ++y) { | ||||||
|  |     uint32_t* const row = &pic->argb[y * pic->argb_stride]; | ||||||
|  |     for (x = 0; x < pic->width; ++x) { | ||||||
|  |       const uint32_t argb = row[x]; | ||||||
|  |       const uint32_t r = (argb >> 16) & 0xff; | ||||||
|  |       const uint32_t g = (argb >>  8) & 0xff; | ||||||
|  |       const uint32_t b = (argb >>  0) & 0xff; | ||||||
|  |       // We use BT.709 for converting to luminance. | ||||||
|  |       const uint32_t Y = (uint32_t)(0.2126 * r + 0.7152 * g + 0.0722 * b + .5); | ||||||
|  |       row[x] = (argb & 0xff000000u) | (Y * 0x010101u); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static void Help(void) { | ||||||
|  |   fprintf(stderr, | ||||||
|  |           "Usage: get_disto [-ssim][-psnr][-alpha] compressed.webp orig.webp\n" | ||||||
|  |           "  -ssim ..... print SSIM distortion\n" | ||||||
|  |           "  -psnr ..... print PSNR distortion (default)\n" | ||||||
|  |           "  -alpha .... preserve alpha plane\n" | ||||||
|  |           "  -h ........ this message\n" | ||||||
|  |           "  -o <file> . save the diff map as a WebP lossless file\n" | ||||||
|  |           "  -scale .... scale the difference map to fit [0..255] range\n" | ||||||
|  |           "  -gray ..... use grayscale for difference map (-scale)\n" | ||||||
|  |           "\nSupported input formats:\n  %s\n", | ||||||
|  |           WebPGetEnabledInputFileFormats()); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int main(int argc, const char* argv[]) { | ||||||
|  |   WebPPicture pic1, pic2; | ||||||
|  |   size_t size1 = 0, size2 = 0; | ||||||
|  |   int ret = 1; | ||||||
|  |   float disto[5]; | ||||||
|  |   int type = 0; | ||||||
|  |   int c; | ||||||
|  |   int help = 0; | ||||||
|  |   int keep_alpha = 0; | ||||||
|  |   int scale = 0; | ||||||
|  |   int use_gray = 0; | ||||||
|  |   const char* name1 = NULL; | ||||||
|  |   const char* name2 = NULL; | ||||||
|  |   const char* output = NULL; | ||||||
|  |  | ||||||
|  |   INIT_WARGV(argc, argv); | ||||||
|  |  | ||||||
|  |   if (!WebPPictureInit(&pic1) || !WebPPictureInit(&pic2)) { | ||||||
|  |     fprintf(stderr, "Can't init pictures\n"); | ||||||
|  |     FREE_WARGV_AND_RETURN(1); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   for (c = 1; c < argc; ++c) { | ||||||
|  |     if (!strcmp(argv[c], "-ssim")) { | ||||||
|  |       type = 1; | ||||||
|  |     } else if (!strcmp(argv[c], "-psnr")) { | ||||||
|  |       type = 0; | ||||||
|  |     } else if (!strcmp(argv[c], "-alpha")) { | ||||||
|  |       keep_alpha = 1; | ||||||
|  |     } else if (!strcmp(argv[c], "-scale")) { | ||||||
|  |       scale = 1; | ||||||
|  |     } else if (!strcmp(argv[c], "-gray")) { | ||||||
|  |       use_gray = 1; | ||||||
|  |     } else if (!strcmp(argv[c], "-h")) { | ||||||
|  |       help = 1; | ||||||
|  |       ret = 0; | ||||||
|  |     } else if (!strcmp(argv[c], "-o")) { | ||||||
|  |       if (++c == argc) { | ||||||
|  |         fprintf(stderr, "missing file name after %s option.\n", argv[c - 1]); | ||||||
|  |         goto End; | ||||||
|  |       } | ||||||
|  |       output = (const char*)GET_WARGV(argv, c); | ||||||
|  |     } else if (name1 == NULL) { | ||||||
|  |       name1 = (const char*)GET_WARGV(argv, c); | ||||||
|  |     } else { | ||||||
|  |       name2 = (const char*)GET_WARGV(argv, c); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   if (help || name1 == NULL || name2 == NULL) { | ||||||
|  |     if (!help) { | ||||||
|  |       fprintf(stderr, "Error: missing arguments.\n"); | ||||||
|  |     } | ||||||
|  |     Help(); | ||||||
|  |     goto End; | ||||||
|  |   } | ||||||
|  |   size1 = ReadPicture(name1, &pic1, 1); | ||||||
|  |   size2 = ReadPicture(name2, &pic2, 1); | ||||||
|  |   if (size1 == 0 || size2 == 0) goto End; | ||||||
|  |  | ||||||
|  |   if (!keep_alpha) { | ||||||
|  |     WebPBlendAlpha(&pic1, 0x00000000); | ||||||
|  |     WebPBlendAlpha(&pic2, 0x00000000); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   if (!WebPPictureDistortion(&pic1, &pic2, type, disto)) { | ||||||
|  |     fprintf(stderr, "Error while computing the distortion.\n"); | ||||||
|  |     goto End; | ||||||
|  |   } | ||||||
|  |   printf("%u %.2f    %.2f %.2f %.2f %.2f [ %.2f bpp ]\n", | ||||||
|  |          (unsigned int)size1, | ||||||
|  |          disto[4], disto[0], disto[1], disto[2], disto[3], | ||||||
|  |          8.f * size1 / pic1.width / pic1.height); | ||||||
|  |  | ||||||
|  |   if (output != NULL) { | ||||||
|  |     uint8_t* data = NULL; | ||||||
|  |     size_t data_size = 0; | ||||||
|  |     if (pic1.use_argb != pic2.use_argb) { | ||||||
|  |       fprintf(stderr, "Pictures are not in the same argb format. " | ||||||
|  |                       "Can't save the difference map.\n"); | ||||||
|  |       goto End; | ||||||
|  |     } | ||||||
|  |     if (pic1.use_argb) { | ||||||
|  |       int n; | ||||||
|  |       fprintf(stderr, "max differences per channel: "); | ||||||
|  |       for (n = 0; n < 3; ++n) {    // skip the alpha channel | ||||||
|  |         const int range = (type == 1) ? | ||||||
|  |           SSIMScaleChannel((uint8_t*)pic1.argb + n, pic1.argb_stride * 4, | ||||||
|  |                            (const uint8_t*)pic2.argb + n, pic2.argb_stride * 4, | ||||||
|  |                            4, pic1.width, pic1.height, scale) : | ||||||
|  |           DiffScaleChannel((uint8_t*)pic1.argb + n, pic1.argb_stride * 4, | ||||||
|  |                            (const uint8_t*)pic2.argb + n, pic2.argb_stride * 4, | ||||||
|  |                            4, pic1.width, pic1.height, scale); | ||||||
|  |         if (range < 0) fprintf(stderr, "\nError computing diff map\n"); | ||||||
|  |         fprintf(stderr, "[%d]", range); | ||||||
|  |       } | ||||||
|  |       fprintf(stderr, "\n"); | ||||||
|  |       if (use_gray) ConvertToGray(&pic1); | ||||||
|  |     } else { | ||||||
|  |       fprintf(stderr, "Can only compute the difference map in ARGB format.\n"); | ||||||
|  |       goto End; | ||||||
|  |     } | ||||||
|  | #if !defined(WEBP_REDUCE_CSP) | ||||||
|  |     data_size = WebPEncodeLosslessBGRA((const uint8_t*)pic1.argb, | ||||||
|  |                                        pic1.width, pic1.height, | ||||||
|  |                                        pic1.argb_stride * 4, | ||||||
|  |                                        &data); | ||||||
|  |     if (data_size == 0) { | ||||||
|  |       fprintf(stderr, "Error during lossless encoding.\n"); | ||||||
|  |       goto End; | ||||||
|  |     } | ||||||
|  |     ret = ImgIoUtilWriteFile(output, data, data_size) ? 0 : 1; | ||||||
|  |     WebPFree(data); | ||||||
|  |     if (ret) goto End; | ||||||
|  | #else | ||||||
|  |     (void)data; | ||||||
|  |     (void)data_size; | ||||||
|  |     fprintf(stderr, "Cannot save the difference map. Please recompile " | ||||||
|  |                     "without the WEBP_REDUCE_CSP flag.\n"); | ||||||
|  | #endif  // WEBP_REDUCE_CSP | ||||||
|  |   } | ||||||
|  |   ret = 0; | ||||||
|  |  | ||||||
|  |  End: | ||||||
|  |   WebPPictureFree(&pic1); | ||||||
|  |   WebPPictureFree(&pic2); | ||||||
|  |   FREE_WARGV_AND_RETURN(ret); | ||||||
|  | } | ||||||
							
								
								
									
										129
									
								
								external/libwebp/libwebp/extras/quality_estimate.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										129
									
								
								external/libwebp/libwebp/extras/quality_estimate.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,129 @@ | |||||||
|  | // Copyright 2016 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. | ||||||
|  | // ----------------------------------------------------------------------------- | ||||||
|  | // | ||||||
|  | //  VP8EstimateQuality(): rough encoding quality estimate | ||||||
|  | // | ||||||
|  | // Author: Skal (pascal.massimino@gmail.com) | ||||||
|  |  | ||||||
|  | #include "extras/extras.h" | ||||||
|  | #include "webp/decode.h" | ||||||
|  |  | ||||||
|  | #include <math.h> | ||||||
|  |  | ||||||
|  | //------------------------------------------------------------------------------ | ||||||
|  |  | ||||||
|  | #define INVALID_BIT_POS (1ull << 63) | ||||||
|  |  | ||||||
|  | // In most cases, we don't need to use a full arithmetic decoder, since | ||||||
|  | // all the header's bits are written using a uniform probability of 128. | ||||||
|  | // We can just parse the header as if it was bits (works in 99.999% cases). | ||||||
|  | static WEBP_INLINE uint32_t GetBit(const uint8_t* const data, size_t nb, | ||||||
|  |                                    uint64_t max_size, uint64_t* const bit_pos) { | ||||||
|  |   uint32_t val = 0; | ||||||
|  |   if (*bit_pos + nb <= 8 * max_size) { | ||||||
|  |     while (nb-- > 0) { | ||||||
|  |       const uint64_t p = (*bit_pos)++; | ||||||
|  |       const int bit = !!(data[p >> 3] & (128 >> ((p & 7)))); | ||||||
|  |       val = (val << 1) | bit; | ||||||
|  |     } | ||||||
|  |   } else { | ||||||
|  |     *bit_pos = INVALID_BIT_POS; | ||||||
|  |   } | ||||||
|  |   return val; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #define GET_BIT(n) GetBit(data, (n), size, &bit_pos) | ||||||
|  | #define CONDITIONAL_SKIP(n) (GET_BIT(1) ? GET_BIT((n)) : 0) | ||||||
|  |  | ||||||
|  | int VP8EstimateQuality(const uint8_t* const data, size_t size) { | ||||||
|  |   size_t pos = 0; | ||||||
|  |   uint64_t bit_pos; | ||||||
|  |   uint64_t sig = 0x00; | ||||||
|  |   int ok = 0; | ||||||
|  |   int Q = -1; | ||||||
|  |   WebPBitstreamFeatures features; | ||||||
|  |  | ||||||
|  |   if (data == NULL) return -1; | ||||||
|  |  | ||||||
|  |   if (WebPGetFeatures(data, size, &features) != VP8_STATUS_OK) { | ||||||
|  |     return -1;   // invalid file | ||||||
|  |   } | ||||||
|  |   if (features.format == 2) return 101;  // lossless | ||||||
|  |   if (features.format == 0 || features.has_animation) return -1;   // mixed | ||||||
|  |  | ||||||
|  |   while (pos < size) { | ||||||
|  |     sig = (sig >> 8) | ((uint64_t)data[pos++] << 40); | ||||||
|  |     if ((sig >> 24) == 0x2a019dull) { | ||||||
|  |       ok = 1; | ||||||
|  |       break; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   if (!ok) return -1; | ||||||
|  |   if (pos + 4 > size) return -1; | ||||||
|  |  | ||||||
|  |   // Skip main Header | ||||||
|  |   // width  = (data[pos + 0] | (data[pos + 1] << 8)) & 0x3fff; | ||||||
|  |   // height = (data[pos + 2] | (data[pos + 3] << 8)) & 0x3fff; | ||||||
|  |   pos += 4; | ||||||
|  |   bit_pos = pos * 8; | ||||||
|  |  | ||||||
|  |   GET_BIT(2);  // colorspace + clamp type | ||||||
|  |  | ||||||
|  |   // Segment header | ||||||
|  |   if (GET_BIT(1)) {       // use_segment_ | ||||||
|  |     int s; | ||||||
|  |     const int update_map = GET_BIT(1); | ||||||
|  |     if (GET_BIT(1)) {     // update data | ||||||
|  |       const int absolute_delta = GET_BIT(1); | ||||||
|  |       int q[4]  = { 0, 0, 0, 0 }; | ||||||
|  |       for (s = 0; s < 4; ++s) { | ||||||
|  |         if (GET_BIT(1)) { | ||||||
|  |           q[s] = GET_BIT(7); | ||||||
|  |           if (GET_BIT(1)) q[s] = -q[s];   // sign | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |       if (absolute_delta) Q = q[0];  // just use the first segment's quantizer | ||||||
|  |       for (s = 0; s < 4; ++s) CONDITIONAL_SKIP(7);   //  filter strength | ||||||
|  |     } | ||||||
|  |     if (update_map) { | ||||||
|  |       for (s = 0; s < 3; ++s) CONDITIONAL_SKIP(8); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   // Filter header | ||||||
|  |   GET_BIT(1 + 6 + 3);     // simple + level + sharpness | ||||||
|  |   if (GET_BIT(1)) {       // use_lf_delta | ||||||
|  |     if (GET_BIT(1)) {     // update lf_delta? | ||||||
|  |       int n; | ||||||
|  |       for (n = 0; n < 4 + 4; ++n) CONDITIONAL_SKIP(6); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   // num partitions | ||||||
|  |   GET_BIT(2); | ||||||
|  |  | ||||||
|  |   // ParseQuant | ||||||
|  |   { | ||||||
|  |     const int base_q = GET_BIT(7); | ||||||
|  |     /* dqy1_dc = */ CONDITIONAL_SKIP(5); | ||||||
|  |     /* dqy2_dc = */ CONDITIONAL_SKIP(5); | ||||||
|  |     /* dqy2_ac = */ CONDITIONAL_SKIP(5); | ||||||
|  |     /* dquv_dc = */ CONDITIONAL_SKIP(5); | ||||||
|  |     /* dquv_ac = */ CONDITIONAL_SKIP(5); | ||||||
|  |  | ||||||
|  |     if (Q < 0) Q = base_q; | ||||||
|  |   } | ||||||
|  |   if (bit_pos == INVALID_BIT_POS) return -1; | ||||||
|  |  | ||||||
|  |   // base mapping | ||||||
|  |   Q = (127 - Q) * 100 / 127; | ||||||
|  |   // correction for power-law behavior in low range | ||||||
|  |   if (Q < 80) { | ||||||
|  |     Q = (int)(pow(Q / 80., 1. / 0.38) * 80); | ||||||
|  |   } | ||||||
|  |   return Q; | ||||||
|  | } | ||||||
							
								
								
									
										101
									
								
								external/libwebp/libwebp/extras/vwebp_sdl.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										101
									
								
								external/libwebp/libwebp/extras/vwebp_sdl.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,101 @@ | |||||||
|  | // Copyright 2017 Google Inc. All Rights Reserved. | ||||||
|  | // | ||||||
|  | // Use of this source code is governed by a BSD-style license | ||||||
|  | // that can be found in the COPYING file in the root of the source | ||||||
|  | // tree. An additional intellectual property rights grant can be found | ||||||
|  | // in the file PATENTS. All contributing project authors may | ||||||
|  | // be found in the AUTHORS file in the root of the source tree. | ||||||
|  | // ----------------------------------------------------------------------------- | ||||||
|  | // | ||||||
|  | // Simple SDL-based WebP file viewer. | ||||||
|  | // Does not support animation, just static images. | ||||||
|  | // | ||||||
|  | // Press 'q' to exit. | ||||||
|  | // | ||||||
|  | // Author: James Zern (jzern@google.com) | ||||||
|  |  | ||||||
|  | #include <stdio.h> | ||||||
|  |  | ||||||
|  | #ifdef HAVE_CONFIG_H | ||||||
|  | #include "webp/config.h" | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | #if defined(WEBP_HAVE_SDL) | ||||||
|  |  | ||||||
|  | #include "webp_to_sdl.h" | ||||||
|  | #include "webp/decode.h" | ||||||
|  | #include "imageio/imageio_util.h" | ||||||
|  | #include "../examples/unicode.h" | ||||||
|  |  | ||||||
|  | #if defined(WEBP_HAVE_JUST_SDL_H) | ||||||
|  | #include <SDL.h> | ||||||
|  | #else | ||||||
|  | #include <SDL/SDL.h> | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | static void ProcessEvents(void) { | ||||||
|  |   int done = 0; | ||||||
|  |   SDL_Event event; | ||||||
|  |   while (!done && SDL_WaitEvent(&event)) { | ||||||
|  |     switch (event.type) { | ||||||
|  |       case SDL_KEYUP: | ||||||
|  |         switch (event.key.keysym.sym) { | ||||||
|  |           case SDLK_q: done = 1; break; | ||||||
|  |           default: break; | ||||||
|  |         } | ||||||
|  |         break; | ||||||
|  |       default: break; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int main(int argc, char* argv[]) { | ||||||
|  |   int c; | ||||||
|  |   int ok = 0; | ||||||
|  |  | ||||||
|  |   INIT_WARGV(argc, argv); | ||||||
|  |  | ||||||
|  |   for (c = 1; c < argc; ++c) { | ||||||
|  |     const char* file = NULL; | ||||||
|  |     const uint8_t* webp = NULL; | ||||||
|  |     size_t webp_size = 0; | ||||||
|  |     if (!strcmp(argv[c], "-h")) { | ||||||
|  |       printf("Usage: %s [-h] image.webp [more_files.webp...]\n", argv[0]); | ||||||
|  |       FREE_WARGV_AND_RETURN(0); | ||||||
|  |     } else { | ||||||
|  |       file = (const char*)GET_WARGV(argv, c); | ||||||
|  |     } | ||||||
|  |     if (file == NULL) continue; | ||||||
|  |     if (!ImgIoUtilReadFile(file, &webp, &webp_size)) { | ||||||
|  |       WFPRINTF(stderr, "Error opening file: %s\n", (const W_CHAR*)file); | ||||||
|  |       goto Error; | ||||||
|  |     } | ||||||
|  |     if (webp_size != (size_t)(int)webp_size) { | ||||||
|  |       free((void*)webp); | ||||||
|  |       fprintf(stderr, "File too large.\n"); | ||||||
|  |       goto Error; | ||||||
|  |     } | ||||||
|  |     ok = WebPToSDL((const char*)webp, (int)webp_size); | ||||||
|  |     free((void*)webp); | ||||||
|  |     if (!ok) { | ||||||
|  |       WFPRINTF(stderr, "Error decoding file %s\n", (const W_CHAR*)file); | ||||||
|  |       goto Error; | ||||||
|  |     } | ||||||
|  |     ProcessEvents(); | ||||||
|  |   } | ||||||
|  |   ok = 1; | ||||||
|  |  | ||||||
|  |  Error: | ||||||
|  |   SDL_Quit(); | ||||||
|  |   FREE_WARGV_AND_RETURN(ok ? 0 : 1); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #else  // !WEBP_HAVE_SDL | ||||||
|  |  | ||||||
|  | int main(int argc, const char* argv[]) { | ||||||
|  |   fprintf(stderr, "SDL support not enabled in %s.\n", argv[0]); | ||||||
|  |   (void)argc; | ||||||
|  |   return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #endif | ||||||
							
								
								
									
										54
									
								
								external/libwebp/libwebp/extras/webp_quality.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								external/libwebp/libwebp/extras/webp_quality.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,54 @@ | |||||||
|  | // Simple tool to roughly evaluate the quality encoding of a webp bitstream | ||||||
|  | // | ||||||
|  | // Result is a *rough* estimation of the quality. You should just consider | ||||||
|  | // the bucket it's in (q > 80? > 50? > 20?) and not take it for face value. | ||||||
|  | /* | ||||||
|  |  gcc -o webp_quality webp_quality.c -O3 -I../ -L. -L../imageio \ | ||||||
|  |     -limageio_util -lwebpextras -lwebp -lm -lpthread | ||||||
|  | */ | ||||||
|  |  | ||||||
|  | #include <stdio.h> | ||||||
|  | #include <stdlib.h> | ||||||
|  | #include <string.h> | ||||||
|  |  | ||||||
|  | #include "extras/extras.h" | ||||||
|  | #include "imageio/imageio_util.h" | ||||||
|  | #include "../examples/unicode.h" | ||||||
|  |  | ||||||
|  | int main(int argc, const char* argv[]) { | ||||||
|  |   int c; | ||||||
|  |   int quiet = 0; | ||||||
|  |   int ok = 1; | ||||||
|  |  | ||||||
|  |   INIT_WARGV(argc, argv); | ||||||
|  |  | ||||||
|  |   for (c = 1; ok && c < argc; ++c) { | ||||||
|  |     if (!strcmp(argv[c], "-quiet")) { | ||||||
|  |       quiet = 1; | ||||||
|  |     } else if (!strcmp(argv[c], "-help") || !strcmp(argv[c], "-h")) { | ||||||
|  |       printf("webp_quality [-h][-quiet] webp_files...\n"); | ||||||
|  |       FREE_WARGV_AND_RETURN(0); | ||||||
|  |     } else { | ||||||
|  |       const char* const filename = (const char*)GET_WARGV(argv, c); | ||||||
|  |       const uint8_t* data = NULL; | ||||||
|  |       size_t data_size = 0; | ||||||
|  |       int q; | ||||||
|  |       ok = ImgIoUtilReadFile(filename, &data, &data_size); | ||||||
|  |       if (!ok) break; | ||||||
|  |       q = VP8EstimateQuality(data, data_size); | ||||||
|  |       if (!quiet) WPRINTF("[%s] ", (const W_CHAR*)filename); | ||||||
|  |       if (q < 0) { | ||||||
|  |         fprintf(stderr, "Not a WebP file, or not a lossy WebP file.\n"); | ||||||
|  |         ok = 0; | ||||||
|  |       } else { | ||||||
|  |         if (!quiet) { | ||||||
|  |           printf("Estimated quality factor: %d\n", q); | ||||||
|  |         } else { | ||||||
|  |           printf("%d\n", q);   // just print the number | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |       free((void*)data); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   FREE_WARGV_AND_RETURN(ok ? 0 : 1); | ||||||
|  | } | ||||||
							
								
								
									
										110
									
								
								external/libwebp/libwebp/extras/webp_to_sdl.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										110
									
								
								external/libwebp/libwebp/extras/webp_to_sdl.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,110 @@ | |||||||
|  | // Copyright 2017 Google Inc. All Rights Reserved. | ||||||
|  | // | ||||||
|  | // Use of this source code is governed by a BSD-style license | ||||||
|  | // that can be found in the COPYING file in the root of the source | ||||||
|  | // tree. An additional intellectual property rights grant can be found | ||||||
|  | // in the file PATENTS. All contributing project authors may | ||||||
|  | // be found in the AUTHORS file in the root of the source tree. | ||||||
|  | // ----------------------------------------------------------------------------- | ||||||
|  | // | ||||||
|  | //  Simple WebP-to-SDL wrapper. Useful for emscripten. | ||||||
|  | // | ||||||
|  | // Author: James Zern (jzern@google.com) | ||||||
|  |  | ||||||
|  | #ifdef HAVE_CONFIG_H | ||||||
|  | #include "src/webp/config.h" | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | #if defined(WEBP_HAVE_SDL) | ||||||
|  |  | ||||||
|  | #include "webp_to_sdl.h" | ||||||
|  |  | ||||||
|  | #include <stdio.h> | ||||||
|  | #include "src/webp/decode.h" | ||||||
|  |  | ||||||
|  | #if defined(WEBP_HAVE_JUST_SDL_H) | ||||||
|  | #include <SDL.h> | ||||||
|  | #else | ||||||
|  | #include <SDL/SDL.h> | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | static int init_ok = 0; | ||||||
|  | int WebPToSDL(const char* data, unsigned int data_size) { | ||||||
|  |   int ok = 0; | ||||||
|  |   VP8StatusCode status; | ||||||
|  |   WebPDecoderConfig config; | ||||||
|  |   WebPBitstreamFeatures* const input = &config.input; | ||||||
|  |   WebPDecBuffer* const output = &config.output; | ||||||
|  |   SDL_Surface* screen = NULL; | ||||||
|  |   SDL_Surface* surface = NULL; | ||||||
|  |  | ||||||
|  |   if (!WebPInitDecoderConfig(&config)) { | ||||||
|  |     fprintf(stderr, "Library version mismatch!\n"); | ||||||
|  |     return 0; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   if (!init_ok) { | ||||||
|  |     SDL_Init(SDL_INIT_VIDEO); | ||||||
|  |     init_ok = 1; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   status = WebPGetFeatures((uint8_t*)data, (size_t)data_size, &config.input); | ||||||
|  |   if (status != VP8_STATUS_OK) goto Error; | ||||||
|  |  | ||||||
|  |   screen = SDL_SetVideoMode(input->width, input->height, 32, SDL_SWSURFACE); | ||||||
|  |   if (screen == NULL) { | ||||||
|  |     fprintf(stderr, "Unable to set video mode (32bpp %dx%d)!\n", | ||||||
|  |             input->width, input->height); | ||||||
|  |     goto Error; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   surface = SDL_CreateRGBSurface(SDL_SWSURFACE, | ||||||
|  |                                  input->width, input->height, 32, | ||||||
|  |                                  0x000000ffu,   // R mask | ||||||
|  |                                  0x0000ff00u,   // G mask | ||||||
|  |                                  0x00ff0000u,   // B mask | ||||||
|  |                                  0xff000000u);  // A mask | ||||||
|  |  | ||||||
|  |   if (surface == NULL) { | ||||||
|  |     fprintf(stderr, "Unable to create %dx%d RGBA surface!\n", | ||||||
|  |             input->width, input->height); | ||||||
|  |     goto Error; | ||||||
|  |   } | ||||||
|  |   if (SDL_MUSTLOCK(surface)) SDL_LockSurface(surface); | ||||||
|  |  | ||||||
|  | #if SDL_BYTEORDER == SDL_BIG_ENDIAN | ||||||
|  |   output->colorspace = MODE_BGRA; | ||||||
|  | #else | ||||||
|  |   output->colorspace = MODE_RGBA; | ||||||
|  | #endif | ||||||
|  |   output->width  = surface->w; | ||||||
|  |   output->height = surface->h; | ||||||
|  |   output->u.RGBA.rgba   = surface->pixels; | ||||||
|  |   output->u.RGBA.stride = surface->pitch; | ||||||
|  |   output->u.RGBA.size   = surface->pitch * surface->h; | ||||||
|  |   output->is_external_memory = 1; | ||||||
|  |  | ||||||
|  |   status = WebPDecode((const uint8_t*)data, (size_t)data_size, &config); | ||||||
|  |   if (status != VP8_STATUS_OK) { | ||||||
|  |     fprintf(stderr, "Error decoding image (%d)\n", status); | ||||||
|  |     goto Error; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   if (SDL_MUSTLOCK(surface)) SDL_UnlockSurface(surface); | ||||||
|  |   if (SDL_BlitSurface(surface, NULL, screen, NULL) || | ||||||
|  |       SDL_Flip(screen)) { | ||||||
|  |     goto Error; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   ok = 1; | ||||||
|  |  | ||||||
|  |  Error: | ||||||
|  |   SDL_FreeSurface(surface); | ||||||
|  |   SDL_FreeSurface(screen); | ||||||
|  |   WebPFreeDecBuffer(output); | ||||||
|  |   return ok; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | //------------------------------------------------------------------------------ | ||||||
|  |  | ||||||
|  | #endif  // WEBP_HAVE_SDL | ||||||
							
								
								
									
										22
									
								
								external/libwebp/libwebp/extras/webp_to_sdl.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								external/libwebp/libwebp/extras/webp_to_sdl.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,22 @@ | |||||||
|  | // Copyright 2017 Google Inc. All Rights Reserved. | ||||||
|  | // | ||||||
|  | // Use of this source code is governed by a BSD-style license | ||||||
|  | // that can be found in the COPYING file in the root of the source | ||||||
|  | // tree. An additional intellectual property rights grant can be found | ||||||
|  | // in the file PATENTS. All contributing project authors may | ||||||
|  | // be found in the AUTHORS file in the root of the source tree. | ||||||
|  | // ----------------------------------------------------------------------------- | ||||||
|  | // | ||||||
|  | //  Simple WebP-to-SDL wrapper. Useful for emscripten. | ||||||
|  | // | ||||||
|  | // Author: James Zern (jzern@google.com) | ||||||
|  |  | ||||||
|  | #ifndef WEBP_EXTRAS_WEBP_TO_SDL_H_ | ||||||
|  | #define WEBP_EXTRAS_WEBP_TO_SDL_H_ | ||||||
|  |  | ||||||
|  | // Exports the method WebPToSDL(const char* data, int data_size) which decodes | ||||||
|  | // a WebP bitstream into an RGBA SDL surface. | ||||||
|  | // Return false on failure. | ||||||
|  | extern int WebPToSDL(const char* data, unsigned int data_size); | ||||||
|  |  | ||||||
|  | #endif  // WEBP_EXTRAS_WEBP_TO_SDL_H_ | ||||||
							
								
								
									
										14
									
								
								external/libwebp/libwebp/gradle.properties
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								external/libwebp/libwebp/gradle.properties
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,14 @@ | |||||||
|  | # Project-wide Gradle settings. | ||||||
|  |  | ||||||
|  | # IDE (e.g. Android Studio) users: | ||||||
|  | # Gradle settings configured through the IDE *will override* | ||||||
|  | # any settings specified in this file. | ||||||
|  |  | ||||||
|  | # For more details on how to configure your build environment visit | ||||||
|  | # http://www.gradle.org/docs/current/userguide/build_environment.html | ||||||
|  |  | ||||||
|  | # Versions for gradle | ||||||
|  | BUILD_TOOLS_VERSION=23.0.3 | ||||||
|  | COMPILE_SDK_VERSION=23 | ||||||
|  | ANDROID_GRADLE_PLUGIN_VERSION=1.5.0 | ||||||
|  | GRADLE_DOWNLOAD_TASK_VERSION=2.1.0 | ||||||
							
								
								
									
										
											BIN
										
									
								
								external/libwebp/libwebp/gradle/wrapper/gradle-wrapper.jar
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								external/libwebp/libwebp/gradle/wrapper/gradle-wrapper.jar
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										5
									
								
								external/libwebp/libwebp/gradle/wrapper/gradle-wrapper.properties
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								external/libwebp/libwebp/gradle/wrapper/gradle-wrapper.properties
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,5 @@ | |||||||
|  | distributionBase=GRADLE_USER_HOME | ||||||
|  | distributionPath=wrapper/dists | ||||||
|  | distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-bin.zip | ||||||
|  | zipStoreBase=GRADLE_USER_HOME | ||||||
|  | zipStorePath=wrapper/dists | ||||||
							
								
								
									
										183
									
								
								external/libwebp/libwebp/gradlew
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										183
									
								
								external/libwebp/libwebp/gradlew
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,183 @@ | |||||||
|  | #!/usr/bin/env sh | ||||||
|  |  | ||||||
|  | # | ||||||
|  | # Copyright 2015 the original author or authors. | ||||||
|  | # | ||||||
|  | # Licensed under the Apache License, Version 2.0 (the "License"); | ||||||
|  | # you may not use this file except in compliance with the License. | ||||||
|  | # You may obtain a copy of the License at | ||||||
|  | # | ||||||
|  | #      https://www.apache.org/licenses/LICENSE-2.0 | ||||||
|  | # | ||||||
|  | # Unless required by applicable law or agreed to in writing, software | ||||||
|  | # distributed under the License is distributed on an "AS IS" BASIS, | ||||||
|  | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  | # See the License for the specific language governing permissions and | ||||||
|  | # limitations under the License. | ||||||
|  | # | ||||||
|  |  | ||||||
|  | ############################################################################## | ||||||
|  | ## | ||||||
|  | ##  Gradle start up script for UN*X | ||||||
|  | ## | ||||||
|  | ############################################################################## | ||||||
|  |  | ||||||
|  | # Attempt to set APP_HOME | ||||||
|  | # Resolve links: $0 may be a link | ||||||
|  | PRG="$0" | ||||||
|  | # Need this for relative symlinks. | ||||||
|  | while [ -h "$PRG" ] ; do | ||||||
|  |     ls=`ls -ld "$PRG"` | ||||||
|  |     link=`expr "$ls" : '.*-> \(.*\)$'` | ||||||
|  |     if expr "$link" : '/.*' > /dev/null; then | ||||||
|  |         PRG="$link" | ||||||
|  |     else | ||||||
|  |         PRG=`dirname "$PRG"`"/$link" | ||||||
|  |     fi | ||||||
|  | done | ||||||
|  | SAVED="`pwd`" | ||||||
|  | cd "`dirname \"$PRG\"`/" >/dev/null | ||||||
|  | APP_HOME="`pwd -P`" | ||||||
|  | cd "$SAVED" >/dev/null | ||||||
|  |  | ||||||
|  | APP_NAME="Gradle" | ||||||
|  | APP_BASE_NAME=`basename "$0"` | ||||||
|  |  | ||||||
|  | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. | ||||||
|  | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' | ||||||
|  |  | ||||||
|  | # Use the maximum available, or set MAX_FD != -1 to use that value. | ||||||
|  | MAX_FD="maximum" | ||||||
|  |  | ||||||
|  | warn () { | ||||||
|  |     echo "$*" | ||||||
|  | } | ||||||
|  |  | ||||||
|  | die () { | ||||||
|  |     echo | ||||||
|  |     echo "$*" | ||||||
|  |     echo | ||||||
|  |     exit 1 | ||||||
|  | } | ||||||
|  |  | ||||||
|  | # OS specific support (must be 'true' or 'false'). | ||||||
|  | cygwin=false | ||||||
|  | msys=false | ||||||
|  | darwin=false | ||||||
|  | nonstop=false | ||||||
|  | case "`uname`" in | ||||||
|  |   CYGWIN* ) | ||||||
|  |     cygwin=true | ||||||
|  |     ;; | ||||||
|  |   Darwin* ) | ||||||
|  |     darwin=true | ||||||
|  |     ;; | ||||||
|  |   MINGW* ) | ||||||
|  |     msys=true | ||||||
|  |     ;; | ||||||
|  |   NONSTOP* ) | ||||||
|  |     nonstop=true | ||||||
|  |     ;; | ||||||
|  | esac | ||||||
|  |  | ||||||
|  | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar | ||||||
|  |  | ||||||
|  | # Determine the Java command to use to start the JVM. | ||||||
|  | if [ -n "$JAVA_HOME" ] ; then | ||||||
|  |     if [ -x "$JAVA_HOME/jre/sh/java" ] ; then | ||||||
|  |         # IBM's JDK on AIX uses strange locations for the executables | ||||||
|  |         JAVACMD="$JAVA_HOME/jre/sh/java" | ||||||
|  |     else | ||||||
|  |         JAVACMD="$JAVA_HOME/bin/java" | ||||||
|  |     fi | ||||||
|  |     if [ ! -x "$JAVACMD" ] ; then | ||||||
|  |         die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME | ||||||
|  |  | ||||||
|  | Please set the JAVA_HOME variable in your environment to match the | ||||||
|  | location of your Java installation." | ||||||
|  |     fi | ||||||
|  | else | ||||||
|  |     JAVACMD="java" | ||||||
|  |     which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. | ||||||
|  |  | ||||||
|  | Please set the JAVA_HOME variable in your environment to match the | ||||||
|  | location of your Java installation." | ||||||
|  | fi | ||||||
|  |  | ||||||
|  | # Increase the maximum file descriptors if we can. | ||||||
|  | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then | ||||||
|  |     MAX_FD_LIMIT=`ulimit -H -n` | ||||||
|  |     if [ $? -eq 0 ] ; then | ||||||
|  |         if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then | ||||||
|  |             MAX_FD="$MAX_FD_LIMIT" | ||||||
|  |         fi | ||||||
|  |         ulimit -n $MAX_FD | ||||||
|  |         if [ $? -ne 0 ] ; then | ||||||
|  |             warn "Could not set maximum file descriptor limit: $MAX_FD" | ||||||
|  |         fi | ||||||
|  |     else | ||||||
|  |         warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" | ||||||
|  |     fi | ||||||
|  | fi | ||||||
|  |  | ||||||
|  | # For Darwin, add options to specify how the application appears in the dock | ||||||
|  | if $darwin; then | ||||||
|  |     GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" | ||||||
|  | fi | ||||||
|  |  | ||||||
|  | # For Cygwin or MSYS, switch paths to Windows format before running java | ||||||
|  | if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then | ||||||
|  |     APP_HOME=`cygpath --path --mixed "$APP_HOME"` | ||||||
|  |     CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` | ||||||
|  |     JAVACMD=`cygpath --unix "$JAVACMD"` | ||||||
|  |  | ||||||
|  |     # We build the pattern for arguments to be converted via cygpath | ||||||
|  |     ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` | ||||||
|  |     SEP="" | ||||||
|  |     for dir in $ROOTDIRSRAW ; do | ||||||
|  |         ROOTDIRS="$ROOTDIRS$SEP$dir" | ||||||
|  |         SEP="|" | ||||||
|  |     done | ||||||
|  |     OURCYGPATTERN="(^($ROOTDIRS))" | ||||||
|  |     # Add a user-defined pattern to the cygpath arguments | ||||||
|  |     if [ "$GRADLE_CYGPATTERN" != "" ] ; then | ||||||
|  |         OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" | ||||||
|  |     fi | ||||||
|  |     # Now convert the arguments - kludge to limit ourselves to /bin/sh | ||||||
|  |     i=0 | ||||||
|  |     for arg in "$@" ; do | ||||||
|  |         CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` | ||||||
|  |         CHECK2=`echo "$arg"|egrep -c "^-"`                                 ### Determine if an option | ||||||
|  |  | ||||||
|  |         if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition | ||||||
|  |             eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` | ||||||
|  |         else | ||||||
|  |             eval `echo args$i`="\"$arg\"" | ||||||
|  |         fi | ||||||
|  |         i=`expr $i + 1` | ||||||
|  |     done | ||||||
|  |     case $i in | ||||||
|  |         0) set -- ;; | ||||||
|  |         1) set -- "$args0" ;; | ||||||
|  |         2) set -- "$args0" "$args1" ;; | ||||||
|  |         3) set -- "$args0" "$args1" "$args2" ;; | ||||||
|  |         4) set -- "$args0" "$args1" "$args2" "$args3" ;; | ||||||
|  |         5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; | ||||||
|  |         6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; | ||||||
|  |         7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; | ||||||
|  |         8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; | ||||||
|  |         9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; | ||||||
|  |     esac | ||||||
|  | fi | ||||||
|  |  | ||||||
|  | # Escape application args | ||||||
|  | save () { | ||||||
|  |     for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done | ||||||
|  |     echo " " | ||||||
|  | } | ||||||
|  | APP_ARGS=`save "$@"` | ||||||
|  |  | ||||||
|  | # Collect all arguments for the java command, following the shell quoting and substitution rules | ||||||
|  | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" | ||||||
|  |  | ||||||
|  | exec "$JAVACMD" "$@" | ||||||
							
								
								
									
										100
									
								
								external/libwebp/libwebp/gradlew.bat
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										100
									
								
								external/libwebp/libwebp/gradlew.bat
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,100 @@ | |||||||
|  | @rem | ||||||
|  | @rem Copyright 2015 the original author or authors. | ||||||
|  | @rem | ||||||
|  | @rem Licensed under the Apache License, Version 2.0 (the "License"); | ||||||
|  | @rem you may not use this file except in compliance with the License. | ||||||
|  | @rem You may obtain a copy of the License at | ||||||
|  | @rem | ||||||
|  | @rem      https://www.apache.org/licenses/LICENSE-2.0 | ||||||
|  | @rem | ||||||
|  | @rem Unless required by applicable law or agreed to in writing, software | ||||||
|  | @rem distributed under the License is distributed on an "AS IS" BASIS, | ||||||
|  | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  | @rem See the License for the specific language governing permissions and | ||||||
|  | @rem limitations under the License. | ||||||
|  | @rem | ||||||
|  |  | ||||||
|  | @if "%DEBUG%" == "" @echo off | ||||||
|  | @rem ########################################################################## | ||||||
|  | @rem | ||||||
|  | @rem  Gradle startup script for Windows | ||||||
|  | @rem | ||||||
|  | @rem ########################################################################## | ||||||
|  |  | ||||||
|  | @rem Set local scope for the variables with windows NT shell | ||||||
|  | if "%OS%"=="Windows_NT" setlocal | ||||||
|  |  | ||||||
|  | set DIRNAME=%~dp0 | ||||||
|  | if "%DIRNAME%" == "" set DIRNAME=. | ||||||
|  | set APP_BASE_NAME=%~n0 | ||||||
|  | set APP_HOME=%DIRNAME% | ||||||
|  |  | ||||||
|  | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. | ||||||
|  | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" | ||||||
|  |  | ||||||
|  | @rem Find java.exe | ||||||
|  | if defined JAVA_HOME goto findJavaFromJavaHome | ||||||
|  |  | ||||||
|  | set JAVA_EXE=java.exe | ||||||
|  | %JAVA_EXE% -version >NUL 2>&1 | ||||||
|  | if "%ERRORLEVEL%" == "0" goto init | ||||||
|  |  | ||||||
|  | echo. | ||||||
|  | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. | ||||||
|  | echo. | ||||||
|  | echo Please set the JAVA_HOME variable in your environment to match the | ||||||
|  | echo location of your Java installation. | ||||||
|  |  | ||||||
|  | goto fail | ||||||
|  |  | ||||||
|  | :findJavaFromJavaHome | ||||||
|  | set JAVA_HOME=%JAVA_HOME:"=% | ||||||
|  | set JAVA_EXE=%JAVA_HOME%/bin/java.exe | ||||||
|  |  | ||||||
|  | if exist "%JAVA_EXE%" goto init | ||||||
|  |  | ||||||
|  | echo. | ||||||
|  | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% | ||||||
|  | echo. | ||||||
|  | echo Please set the JAVA_HOME variable in your environment to match the | ||||||
|  | echo location of your Java installation. | ||||||
|  |  | ||||||
|  | goto fail | ||||||
|  |  | ||||||
|  | :init | ||||||
|  | @rem Get command-line arguments, handling Windows variants | ||||||
|  |  | ||||||
|  | if not "%OS%" == "Windows_NT" goto win9xME_args | ||||||
|  |  | ||||||
|  | :win9xME_args | ||||||
|  | @rem Slurp the command line arguments. | ||||||
|  | set CMD_LINE_ARGS= | ||||||
|  | set _SKIP=2 | ||||||
|  |  | ||||||
|  | :win9xME_args_slurp | ||||||
|  | if "x%~1" == "x" goto execute | ||||||
|  |  | ||||||
|  | set CMD_LINE_ARGS=%* | ||||||
|  |  | ||||||
|  | :execute | ||||||
|  | @rem Setup the command line | ||||||
|  |  | ||||||
|  | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar | ||||||
|  |  | ||||||
|  | @rem Execute Gradle | ||||||
|  | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% | ||||||
|  |  | ||||||
|  | :end | ||||||
|  | @rem End local scope for the variables with windows NT shell | ||||||
|  | if "%ERRORLEVEL%"=="0" goto mainEnd | ||||||
|  |  | ||||||
|  | :fail | ||||||
|  | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of | ||||||
|  | rem the _cmd.exe /c_ return code! | ||||||
|  | if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 | ||||||
|  | exit /b 1 | ||||||
|  |  | ||||||
|  | :mainEnd | ||||||
|  | if "%OS%"=="Windows_NT" endlocal | ||||||
|  |  | ||||||
|  | :omega | ||||||
							
								
								
									
										57
									
								
								external/libwebp/libwebp/imageio/Android.mk
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								external/libwebp/libwebp/imageio/Android.mk
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,57 @@ | |||||||
|  | # Ignore this file during non-NDK builds. | ||||||
|  | ifdef NDK_ROOT | ||||||
|  | LOCAL_PATH := $(call my-dir) | ||||||
|  |  | ||||||
|  | ################################################################################ | ||||||
|  | # libimageio_util | ||||||
|  |  | ||||||
|  | include $(CLEAR_VARS) | ||||||
|  |  | ||||||
|  | LOCAL_SRC_FILES := \ | ||||||
|  |     imageio_util.c \ | ||||||
|  |  | ||||||
|  | LOCAL_CFLAGS := $(WEBP_CFLAGS) | ||||||
|  | LOCAL_C_INCLUDES := $(LOCAL_PATH)/../src | ||||||
|  |  | ||||||
|  | LOCAL_MODULE := imageio_util | ||||||
|  |  | ||||||
|  | include $(BUILD_STATIC_LIBRARY) | ||||||
|  |  | ||||||
|  | ################################################################################ | ||||||
|  | # libimagedec | ||||||
|  |  | ||||||
|  | include $(CLEAR_VARS) | ||||||
|  |  | ||||||
|  | LOCAL_SRC_FILES := \ | ||||||
|  |     image_dec.c \ | ||||||
|  |     jpegdec.c \ | ||||||
|  |     metadata.c \ | ||||||
|  |     pngdec.c \ | ||||||
|  |     pnmdec.c \ | ||||||
|  |     tiffdec.c \ | ||||||
|  |     webpdec.c \ | ||||||
|  |  | ||||||
|  | LOCAL_CFLAGS := $(WEBP_CFLAGS) | ||||||
|  | LOCAL_C_INCLUDES := $(LOCAL_PATH)/../src | ||||||
|  | LOCAL_STATIC_LIBRARIES := imageio_util | ||||||
|  |  | ||||||
|  | LOCAL_MODULE := imagedec | ||||||
|  |  | ||||||
|  | include $(BUILD_STATIC_LIBRARY) | ||||||
|  |  | ||||||
|  | ################################################################################ | ||||||
|  | # libimageenc | ||||||
|  |  | ||||||
|  | include $(CLEAR_VARS) | ||||||
|  |  | ||||||
|  | LOCAL_SRC_FILES := \ | ||||||
|  |     image_enc.c \ | ||||||
|  |  | ||||||
|  | LOCAL_CFLAGS := $(WEBP_CFLAGS) | ||||||
|  | LOCAL_C_INCLUDES := $(LOCAL_PATH)/../src | ||||||
|  | LOCAL_STATIC_LIBRARIES := imageio_util | ||||||
|  |  | ||||||
|  | LOCAL_MODULE := imageenc | ||||||
|  |  | ||||||
|  | include $(BUILD_STATIC_LIBRARY) | ||||||
|  | endif  # NDK_ROOT | ||||||
							
								
								
									
										32
									
								
								external/libwebp/libwebp/imageio/Makefile.am
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								external/libwebp/libwebp/imageio/Makefile.am
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,32 @@ | |||||||
|  | AM_CPPFLAGS += -I$(top_builddir)/src -I$(top_srcdir)/src | ||||||
|  | noinst_LTLIBRARIES = | ||||||
|  | noinst_LTLIBRARIES += libimageio_util.la | ||||||
|  | if BUILD_DEMUX | ||||||
|  |   noinst_LTLIBRARIES += libimagedec.la | ||||||
|  | endif | ||||||
|  | noinst_LTLIBRARIES += libimageenc.la | ||||||
|  |  | ||||||
|  | noinst_HEADERS = | ||||||
|  | noinst_HEADERS += ../src/webp/decode.h | ||||||
|  | noinst_HEADERS += ../src/webp/types.h | ||||||
|  |  | ||||||
|  | libimageio_util_la_SOURCES = | ||||||
|  | libimageio_util_la_SOURCES += imageio_util.c imageio_util.h | ||||||
|  |  | ||||||
|  | libimagedec_la_SOURCES  = | ||||||
|  | libimagedec_la_SOURCES += image_dec.c image_dec.h | ||||||
|  | libimagedec_la_SOURCES += jpegdec.c jpegdec.h | ||||||
|  | libimagedec_la_SOURCES += metadata.c metadata.h | ||||||
|  | libimagedec_la_SOURCES += pngdec.c pngdec.h | ||||||
|  | libimagedec_la_SOURCES += pnmdec.c pnmdec.h | ||||||
|  | libimagedec_la_SOURCES += tiffdec.c tiffdec.h | ||||||
|  | libimagedec_la_SOURCES += webpdec.c webpdec.h | ||||||
|  | libimagedec_la_SOURCES += wicdec.c wicdec.h | ||||||
|  | libimagedec_la_CPPFLAGS = $(JPEG_INCLUDES) $(PNG_INCLUDES) $(TIFF_INCLUDES) | ||||||
|  | libimagedec_la_CPPFLAGS += $(AM_CPPFLAGS) | ||||||
|  | libimagedec_la_LIBADD = ../src/demux/libwebpdemux.la | ||||||
|  |  | ||||||
|  | libimageenc_la_SOURCES  = | ||||||
|  | libimageenc_la_SOURCES += image_enc.c image_enc.h | ||||||
|  | libimageenc_la_CPPFLAGS = $(JPEG_INCLUDES) $(PNG_INCLUDES) $(TIFF_INCLUDES) | ||||||
|  | libimageenc_la_CPPFLAGS += $(AM_CPPFLAGS) | ||||||
							
								
								
									
										84
									
								
								external/libwebp/libwebp/imageio/image_dec.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										84
									
								
								external/libwebp/libwebp/imageio/image_dec.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,84 @@ | |||||||
|  | // Copyright 2016 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. | ||||||
|  | // ----------------------------------------------------------------------------- | ||||||
|  | // | ||||||
|  | // Generic image-type guessing. | ||||||
|  |  | ||||||
|  | #include "./image_dec.h" | ||||||
|  |  | ||||||
|  | const char* WebPGetEnabledInputFileFormats(void) { | ||||||
|  |   return "WebP" | ||||||
|  | #ifdef WEBP_HAVE_JPEG | ||||||
|  |          ", JPEG" | ||||||
|  | #endif | ||||||
|  | #ifdef WEBP_HAVE_PNG | ||||||
|  |          ", PNG" | ||||||
|  | #endif | ||||||
|  |          ", PNM (PGM, PPM, PAM)" | ||||||
|  | #ifdef WEBP_HAVE_TIFF | ||||||
|  |          ", TIFF" | ||||||
|  | #endif | ||||||
|  | #ifdef HAVE_WINCODEC_H | ||||||
|  |          ", Windows Imaging Component (WIC)" | ||||||
|  | #endif | ||||||
|  |          ""; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static WEBP_INLINE uint32_t GetBE32(const uint8_t buf[]) { | ||||||
|  |   return ((uint32_t)buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3]; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | WebPInputFileFormat WebPGuessImageType(const uint8_t* const data, | ||||||
|  |                                        size_t data_size) { | ||||||
|  |   WebPInputFileFormat format = WEBP_UNSUPPORTED_FORMAT; | ||||||
|  |   if (data != NULL && data_size >= 12) { | ||||||
|  |     const uint32_t magic1 = GetBE32(data + 0); | ||||||
|  |     const uint32_t magic2 = GetBE32(data + 8); | ||||||
|  |     if (magic1 == 0x89504E47U) { | ||||||
|  |       format = WEBP_PNG_FORMAT; | ||||||
|  |     } else if (magic1 >= 0xFFD8FF00U && magic1 <= 0xFFD8FFFFU) { | ||||||
|  |       format = WEBP_JPEG_FORMAT; | ||||||
|  |     } else if (magic1 == 0x49492A00 || magic1 == 0x4D4D002A) { | ||||||
|  |       format = WEBP_TIFF_FORMAT; | ||||||
|  |     } else if (magic1 == 0x52494646 && magic2 == 0x57454250) { | ||||||
|  |       format = WEBP_WEBP_FORMAT; | ||||||
|  |     } else if (((magic1 >> 24) & 0xff) == 'P') { | ||||||
|  |       const int type = (magic1 >> 16) & 0xff; | ||||||
|  |       // we only support 'P5 -> P7' for now. | ||||||
|  |       if (type >= '5' && type <= '7') format = WEBP_PNM_FORMAT; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   return format; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static int FailReader(const uint8_t* const data, size_t data_size, | ||||||
|  |                       struct WebPPicture* const pic, | ||||||
|  |                       int keep_alpha, struct Metadata* const metadata) { | ||||||
|  |   (void)data; | ||||||
|  |   (void)data_size; | ||||||
|  |   (void)pic; | ||||||
|  |   (void)keep_alpha; | ||||||
|  |   (void)metadata; | ||||||
|  |   return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | WebPImageReader WebPGetImageReader(WebPInputFileFormat format) { | ||||||
|  |   switch (format) { | ||||||
|  |     case WEBP_PNG_FORMAT: return ReadPNG; | ||||||
|  |     case WEBP_JPEG_FORMAT: return ReadJPEG; | ||||||
|  |     case WEBP_TIFF_FORMAT: return ReadTIFF; | ||||||
|  |     case WEBP_WEBP_FORMAT: return ReadWebP; | ||||||
|  |     case WEBP_PNM_FORMAT: return ReadPNM; | ||||||
|  |     default: return FailReader; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | WebPImageReader WebPGuessImageReader(const uint8_t* const data, | ||||||
|  |                                      size_t data_size) { | ||||||
|  |   return WebPGetImageReader(WebPGuessImageType(data, data_size)); | ||||||
|  | } | ||||||
							
								
								
									
										70
									
								
								external/libwebp/libwebp/imageio/image_dec.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										70
									
								
								external/libwebp/libwebp/imageio/image_dec.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,70 @@ | |||||||
|  | // Copyright 2016 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. | ||||||
|  | // ----------------------------------------------------------------------------- | ||||||
|  | // | ||||||
|  | //  All-in-one library to decode PNG/JPEG/WebP/TIFF/WIC input images. | ||||||
|  | // | ||||||
|  | // Author: Skal (pascal.massimino@gmail.com) | ||||||
|  |  | ||||||
|  | #ifndef WEBP_IMAGEIO_IMAGE_DEC_H_ | ||||||
|  | #define WEBP_IMAGEIO_IMAGE_DEC_H_ | ||||||
|  |  | ||||||
|  | #include "webp/types.h" | ||||||
|  |  | ||||||
|  | #ifdef HAVE_CONFIG_H | ||||||
|  | #include "webp/config.h" | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | #include "./metadata.h" | ||||||
|  | #include "./jpegdec.h" | ||||||
|  | #include "./pngdec.h" | ||||||
|  | #include "./pnmdec.h" | ||||||
|  | #include "./tiffdec.h" | ||||||
|  | #include "./webpdec.h" | ||||||
|  | #include "./wicdec.h" | ||||||
|  |  | ||||||
|  | #ifdef __cplusplus | ||||||
|  | extern "C" { | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | typedef enum { | ||||||
|  |   WEBP_PNG_FORMAT = 0, | ||||||
|  |   WEBP_JPEG_FORMAT, | ||||||
|  |   WEBP_TIFF_FORMAT, | ||||||
|  |   WEBP_WEBP_FORMAT, | ||||||
|  |   WEBP_PNM_FORMAT, | ||||||
|  |   WEBP_UNSUPPORTED_FORMAT | ||||||
|  | } WebPInputFileFormat; | ||||||
|  |  | ||||||
|  | // Returns a comma separated list of enabled input formats. | ||||||
|  | const char* WebPGetEnabledInputFileFormats(void); | ||||||
|  |  | ||||||
|  | // Try to infer the image format. 'data_size' should be larger than 12. | ||||||
|  | // Returns WEBP_UNSUPPORTED_FORMAT if format can't be guess safely. | ||||||
|  | WebPInputFileFormat WebPGuessImageType(const uint8_t* const data, | ||||||
|  |                                        size_t data_size); | ||||||
|  |  | ||||||
|  | // Signature for common image-reading functions (ReadPNG, ReadJPEG, ...) | ||||||
|  | typedef int (*WebPImageReader)(const uint8_t* const data, size_t data_size, | ||||||
|  |                                struct WebPPicture* const pic, | ||||||
|  |                                int keep_alpha, struct Metadata* const metadata); | ||||||
|  |  | ||||||
|  | // Return the reader associated to a given file format. | ||||||
|  | WebPImageReader WebPGetImageReader(WebPInputFileFormat format); | ||||||
|  |  | ||||||
|  | // This function is similar to WebPGuessImageType(), but returns a | ||||||
|  | // suitable reader function. The returned reader is never NULL, but | ||||||
|  | // unknown formats will return an always-failing valid reader. | ||||||
|  | WebPImageReader WebPGuessImageReader(const uint8_t* const data, | ||||||
|  |                                      size_t data_size); | ||||||
|  |  | ||||||
|  | #ifdef __cplusplus | ||||||
|  | }    // extern "C" | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | #endif  // WEBP_IMAGEIO_IMAGE_DEC_H_ | ||||||
							
								
								
									
										615
									
								
								external/libwebp/libwebp/imageio/image_enc.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										615
									
								
								external/libwebp/libwebp/imageio/image_enc.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,615 @@ | |||||||
|  | // Copyright 2016 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. | ||||||
|  | // ----------------------------------------------------------------------------- | ||||||
|  | // | ||||||
|  | // Save image | ||||||
|  |  | ||||||
|  | #include "./image_enc.h" | ||||||
|  |  | ||||||
|  | #include <assert.h> | ||||||
|  | #include <string.h> | ||||||
|  |  | ||||||
|  | #ifdef WEBP_HAVE_PNG | ||||||
|  | #include <png.h> | ||||||
|  | #include <setjmp.h>   // note: this must be included *after* png.h | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | #ifdef HAVE_WINCODEC_H | ||||||
|  | #ifdef __MINGW32__ | ||||||
|  | #define INITGUID  // Without this GUIDs are declared extern and fail to link | ||||||
|  | #endif | ||||||
|  | #define CINTERFACE | ||||||
|  | #define COBJMACROS | ||||||
|  | #define _WIN32_IE 0x500  // Workaround bug in shlwapi.h when compiling C++ | ||||||
|  |                          // code with COBJMACROS. | ||||||
|  | #include <ole2.h>  // CreateStreamOnHGlobal() | ||||||
|  | #include <shlwapi.h> | ||||||
|  | #include <tchar.h> | ||||||
|  | #include <windows.h> | ||||||
|  | #include <wincodec.h> | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | #include "./imageio_util.h" | ||||||
|  | #include "../examples/unicode.h" | ||||||
|  |  | ||||||
|  | //------------------------------------------------------------------------------ | ||||||
|  | // PNG | ||||||
|  |  | ||||||
|  | #ifdef HAVE_WINCODEC_H | ||||||
|  |  | ||||||
|  | #define IFS(fn)                                                     \ | ||||||
|  |   do {                                                              \ | ||||||
|  |     if (SUCCEEDED(hr)) {                                            \ | ||||||
|  |       hr = (fn);                                                    \ | ||||||
|  |       if (FAILED(hr)) fprintf(stderr, #fn " failed %08lx\n", hr);   \ | ||||||
|  |     }                                                               \ | ||||||
|  |   } while (0) | ||||||
|  |  | ||||||
|  | #ifdef __cplusplus | ||||||
|  | #define MAKE_REFGUID(x) (x) | ||||||
|  | #else | ||||||
|  | #define MAKE_REFGUID(x) &(x) | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | static HRESULT CreateOutputStream(const char* out_file_name, | ||||||
|  |                                   int write_to_mem, IStream** stream) { | ||||||
|  |   HRESULT hr = S_OK; | ||||||
|  |   if (write_to_mem) { | ||||||
|  |     // Output to a memory buffer. This is freed when 'stream' is released. | ||||||
|  |     IFS(CreateStreamOnHGlobal(NULL, TRUE, stream)); | ||||||
|  |   } else { | ||||||
|  |     IFS(SHCreateStreamOnFile((const LPTSTR)out_file_name, | ||||||
|  |                              STGM_WRITE | STGM_CREATE, stream)); | ||||||
|  |   } | ||||||
|  |   if (FAILED(hr)) { | ||||||
|  |     _ftprintf(stderr, _T("Error opening output file %s (%08lx)\n"), | ||||||
|  |               (const LPTSTR)out_file_name, hr); | ||||||
|  |   } | ||||||
|  |   return hr; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static HRESULT WriteUsingWIC(const char* out_file_name, int use_stdout, | ||||||
|  |                              REFGUID container_guid, | ||||||
|  |                              uint8_t* rgb, int stride, | ||||||
|  |                              uint32_t width, uint32_t height, int has_alpha) { | ||||||
|  |   HRESULT hr = S_OK; | ||||||
|  |   IWICImagingFactory* factory = NULL; | ||||||
|  |   IWICBitmapFrameEncode* frame = NULL; | ||||||
|  |   IWICBitmapEncoder* encoder = NULL; | ||||||
|  |   IStream* stream = NULL; | ||||||
|  |   WICPixelFormatGUID pixel_format = has_alpha ? GUID_WICPixelFormat32bppBGRA | ||||||
|  |                                               : GUID_WICPixelFormat24bppBGR; | ||||||
|  |  | ||||||
|  |   if (out_file_name == NULL || rgb == NULL) return E_INVALIDARG; | ||||||
|  |  | ||||||
|  |   IFS(CoInitialize(NULL)); | ||||||
|  |   IFS(CoCreateInstance(MAKE_REFGUID(CLSID_WICImagingFactory), NULL, | ||||||
|  |                        CLSCTX_INPROC_SERVER, | ||||||
|  |                        MAKE_REFGUID(IID_IWICImagingFactory), | ||||||
|  |                        (LPVOID*)&factory)); | ||||||
|  |   if (hr == REGDB_E_CLASSNOTREG) { | ||||||
|  |     fprintf(stderr, | ||||||
|  |             "Couldn't access Windows Imaging Component (are you running " | ||||||
|  |             "Windows XP SP3 or newer?). PNG support not available. " | ||||||
|  |             "Use -ppm or -pgm for available PPM and PGM formats.\n"); | ||||||
|  |   } | ||||||
|  |   IFS(CreateOutputStream(out_file_name, use_stdout, &stream)); | ||||||
|  |   IFS(IWICImagingFactory_CreateEncoder(factory, container_guid, NULL, | ||||||
|  |                                        &encoder)); | ||||||
|  |   IFS(IWICBitmapEncoder_Initialize(encoder, stream, | ||||||
|  |                                    WICBitmapEncoderNoCache)); | ||||||
|  |   IFS(IWICBitmapEncoder_CreateNewFrame(encoder, &frame, NULL)); | ||||||
|  |   IFS(IWICBitmapFrameEncode_Initialize(frame, NULL)); | ||||||
|  |   IFS(IWICBitmapFrameEncode_SetSize(frame, width, height)); | ||||||
|  |   IFS(IWICBitmapFrameEncode_SetPixelFormat(frame, &pixel_format)); | ||||||
|  |   IFS(IWICBitmapFrameEncode_WritePixels(frame, height, stride, | ||||||
|  |                                         height * stride, rgb)); | ||||||
|  |   IFS(IWICBitmapFrameEncode_Commit(frame)); | ||||||
|  |   IFS(IWICBitmapEncoder_Commit(encoder)); | ||||||
|  |  | ||||||
|  |   if (SUCCEEDED(hr) && use_stdout) { | ||||||
|  |     HGLOBAL image; | ||||||
|  |     IFS(GetHGlobalFromStream(stream, &image)); | ||||||
|  |     if (SUCCEEDED(hr)) { | ||||||
|  |       HANDLE std_output = GetStdHandle(STD_OUTPUT_HANDLE); | ||||||
|  |       DWORD mode; | ||||||
|  |       const BOOL update_mode = GetConsoleMode(std_output, &mode); | ||||||
|  |       const void* const image_mem = GlobalLock(image); | ||||||
|  |       DWORD bytes_written = 0; | ||||||
|  |  | ||||||
|  |       // Clear output processing if necessary, then output the image. | ||||||
|  |       if (update_mode) SetConsoleMode(std_output, 0); | ||||||
|  |       if (!WriteFile(std_output, image_mem, (DWORD)GlobalSize(image), | ||||||
|  |                      &bytes_written, NULL) || | ||||||
|  |           bytes_written != GlobalSize(image)) { | ||||||
|  |         hr = E_FAIL; | ||||||
|  |       } | ||||||
|  |       if (update_mode) SetConsoleMode(std_output, mode); | ||||||
|  |       GlobalUnlock(image); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   if (frame != NULL) IUnknown_Release(frame); | ||||||
|  |   if (encoder != NULL) IUnknown_Release(encoder); | ||||||
|  |   if (factory != NULL) IUnknown_Release(factory); | ||||||
|  |   if (stream != NULL) IUnknown_Release(stream); | ||||||
|  |   return hr; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int WebPWritePNG(const char* out_file_name, int use_stdout, | ||||||
|  |                  const WebPDecBuffer* const buffer) { | ||||||
|  |   const uint32_t width = buffer->width; | ||||||
|  |   const uint32_t height = buffer->height; | ||||||
|  |   uint8_t* const rgb = buffer->u.RGBA.rgba; | ||||||
|  |   const int stride = buffer->u.RGBA.stride; | ||||||
|  |   const int has_alpha = WebPIsAlphaMode(buffer->colorspace); | ||||||
|  |  | ||||||
|  |   return SUCCEEDED(WriteUsingWIC(out_file_name, use_stdout, | ||||||
|  |                                  MAKE_REFGUID(GUID_ContainerFormatPng), | ||||||
|  |                                  rgb, stride, width, height, has_alpha)); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #elif defined(WEBP_HAVE_PNG)    // !HAVE_WINCODEC_H | ||||||
|  | static void PNGAPI PNGErrorFunction(png_structp png, png_const_charp unused) { | ||||||
|  |   (void)unused;  // remove variable-unused warning | ||||||
|  |   longjmp(png_jmpbuf(png), 1); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int WebPWritePNG(FILE* out_file, const WebPDecBuffer* const buffer) { | ||||||
|  |   volatile png_structp png; | ||||||
|  |   volatile png_infop info; | ||||||
|  |  | ||||||
|  |   if (out_file == NULL || buffer == NULL) return 0; | ||||||
|  |  | ||||||
|  |   png = png_create_write_struct(PNG_LIBPNG_VER_STRING, | ||||||
|  |                                 NULL, PNGErrorFunction, NULL); | ||||||
|  |   if (png == NULL) { | ||||||
|  |     return 0; | ||||||
|  |   } | ||||||
|  |   info = png_create_info_struct(png); | ||||||
|  |   if (info == NULL) { | ||||||
|  |     png_destroy_write_struct((png_structpp)&png, NULL); | ||||||
|  |     return 0; | ||||||
|  |   } | ||||||
|  |   if (setjmp(png_jmpbuf(png))) { | ||||||
|  |     png_destroy_write_struct((png_structpp)&png, (png_infopp)&info); | ||||||
|  |     return 0; | ||||||
|  |   } | ||||||
|  |   png_init_io(png, out_file); | ||||||
|  |   { | ||||||
|  |     const uint32_t width = buffer->width; | ||||||
|  |     const uint32_t height = buffer->height; | ||||||
|  |     png_bytep row = buffer->u.RGBA.rgba; | ||||||
|  |     const int stride = buffer->u.RGBA.stride; | ||||||
|  |     const int has_alpha = WebPIsAlphaMode(buffer->colorspace); | ||||||
|  |     uint32_t y; | ||||||
|  |  | ||||||
|  |     png_set_IHDR(png, info, width, height, 8, | ||||||
|  |                  has_alpha ? PNG_COLOR_TYPE_RGBA : PNG_COLOR_TYPE_RGB, | ||||||
|  |                  PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, | ||||||
|  |                  PNG_FILTER_TYPE_DEFAULT); | ||||||
|  |     png_write_info(png, info); | ||||||
|  |     for (y = 0; y < height; ++y) { | ||||||
|  |       png_write_rows(png, &row, 1); | ||||||
|  |       row += stride; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   png_write_end(png, info); | ||||||
|  |   png_destroy_write_struct((png_structpp)&png, (png_infopp)&info); | ||||||
|  |   return 1; | ||||||
|  | } | ||||||
|  | #else    // !HAVE_WINCODEC_H && !WEBP_HAVE_PNG | ||||||
|  | int WebPWritePNG(FILE* fout, const WebPDecBuffer* const buffer) { | ||||||
|  |   if (fout == NULL || buffer == NULL) return 0; | ||||||
|  |  | ||||||
|  |   fprintf(stderr, "PNG support not compiled. Please install the libpng " | ||||||
|  |           "development package before building.\n"); | ||||||
|  |   fprintf(stderr, "You can run with -ppm flag to decode in PPM format.\n"); | ||||||
|  |   return 0; | ||||||
|  | } | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | //------------------------------------------------------------------------------ | ||||||
|  | // PPM / PAM | ||||||
|  |  | ||||||
|  | static int WritePPMPAM(FILE* fout, const WebPDecBuffer* const buffer, | ||||||
|  |                        int alpha) { | ||||||
|  |   if (fout == NULL || buffer == NULL) { | ||||||
|  |     return 0; | ||||||
|  |   } else { | ||||||
|  |     const uint32_t width = buffer->width; | ||||||
|  |     const uint32_t height = buffer->height; | ||||||
|  |     const uint8_t* row = buffer->u.RGBA.rgba; | ||||||
|  |     const int stride = buffer->u.RGBA.stride; | ||||||
|  |     const size_t bytes_per_px = alpha ? 4 : 3; | ||||||
|  |     uint32_t y; | ||||||
|  |  | ||||||
|  |     if (row == NULL) return 0; | ||||||
|  |  | ||||||
|  |     if (alpha) { | ||||||
|  |       fprintf(fout, "P7\nWIDTH %u\nHEIGHT %u\nDEPTH 4\nMAXVAL 255\n" | ||||||
|  |                     "TUPLTYPE RGB_ALPHA\nENDHDR\n", width, height); | ||||||
|  |     } else { | ||||||
|  |       fprintf(fout, "P6\n%u %u\n255\n", width, height); | ||||||
|  |     } | ||||||
|  |     for (y = 0; y < height; ++y) { | ||||||
|  |       if (fwrite(row, width, bytes_per_px, fout) != bytes_per_px) { | ||||||
|  |         return 0; | ||||||
|  |       } | ||||||
|  |       row += stride; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   return 1; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int WebPWritePPM(FILE* fout, const WebPDecBuffer* const buffer) { | ||||||
|  |   return WritePPMPAM(fout, buffer, 0); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int WebPWritePAM(FILE* fout, const WebPDecBuffer* const buffer) { | ||||||
|  |   return WritePPMPAM(fout, buffer, 1); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | //------------------------------------------------------------------------------ | ||||||
|  | // Raw PGM | ||||||
|  |  | ||||||
|  | // Save 16b mode (RGBA4444, RGB565, ...) for debugging purpose. | ||||||
|  | int WebPWrite16bAsPGM(FILE* fout, const WebPDecBuffer* const buffer) { | ||||||
|  |   const uint32_t width = buffer->width; | ||||||
|  |   const uint32_t height = buffer->height; | ||||||
|  |   const uint8_t* rgba = buffer->u.RGBA.rgba; | ||||||
|  |   const int stride = buffer->u.RGBA.stride; | ||||||
|  |   const uint32_t bytes_per_px = 2; | ||||||
|  |   uint32_t y; | ||||||
|  |  | ||||||
|  |   if (fout == NULL || buffer == NULL || rgba == NULL) return 0; | ||||||
|  |  | ||||||
|  |   fprintf(fout, "P5\n%u %u\n255\n", width * bytes_per_px, height); | ||||||
|  |   for (y = 0; y < height; ++y) { | ||||||
|  |     if (fwrite(rgba, width, bytes_per_px, fout) != bytes_per_px) { | ||||||
|  |       return 0; | ||||||
|  |     } | ||||||
|  |     rgba += stride; | ||||||
|  |   } | ||||||
|  |   return 1; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | //------------------------------------------------------------------------------ | ||||||
|  | // BMP (see https://en.wikipedia.org/wiki/BMP_file_format#Pixel_storage) | ||||||
|  |  | ||||||
|  | static void PutLE16(uint8_t* const dst, uint32_t value) { | ||||||
|  |   dst[0] = (value >> 0) & 0xff; | ||||||
|  |   dst[1] = (value >> 8) & 0xff; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static void PutLE32(uint8_t* const dst, uint32_t value) { | ||||||
|  |   PutLE16(dst + 0, (value >>  0) & 0xffff); | ||||||
|  |   PutLE16(dst + 2, (value >> 16) & 0xffff); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #define BMP_HEADER_SIZE 54 | ||||||
|  | #define BMP_HEADER_ALPHA_EXTRA_SIZE 16  // for alpha info | ||||||
|  | int WebPWriteBMP(FILE* fout, const WebPDecBuffer* const buffer) { | ||||||
|  |   const int has_alpha = WebPIsAlphaMode(buffer->colorspace); | ||||||
|  |   const int header_size = | ||||||
|  |       BMP_HEADER_SIZE + (has_alpha ? BMP_HEADER_ALPHA_EXTRA_SIZE : 0); | ||||||
|  |   const uint32_t width = buffer->width; | ||||||
|  |   const uint32_t height = buffer->height; | ||||||
|  |   const uint8_t* rgba = buffer->u.RGBA.rgba; | ||||||
|  |   const int stride = buffer->u.RGBA.stride; | ||||||
|  |   const uint32_t bytes_per_px = has_alpha ? 4 : 3; | ||||||
|  |   uint32_t y; | ||||||
|  |   const uint32_t line_size = bytes_per_px * width; | ||||||
|  |   const uint32_t bmp_stride = (line_size + 3) & ~3;   // pad to 4 | ||||||
|  |   const uint32_t image_size = bmp_stride * height; | ||||||
|  |   const uint32_t total_size =  image_size + header_size; | ||||||
|  |   uint8_t bmp_header[BMP_HEADER_SIZE + BMP_HEADER_ALPHA_EXTRA_SIZE] = { 0 }; | ||||||
|  |  | ||||||
|  |   if (fout == NULL || buffer == NULL || rgba == NULL) return 0; | ||||||
|  |  | ||||||
|  |   // bitmap file header | ||||||
|  |   PutLE16(bmp_header + 0, 0x4d42);                // signature 'BM' | ||||||
|  |   PutLE32(bmp_header + 2, total_size);            // size including header | ||||||
|  |   PutLE32(bmp_header + 6, 0);                     // reserved | ||||||
|  |   PutLE32(bmp_header + 10, header_size);          // offset to pixel array | ||||||
|  |   // bitmap info header | ||||||
|  |   PutLE32(bmp_header + 14, header_size - 14);     // DIB header size | ||||||
|  |   PutLE32(bmp_header + 18, width);                // dimensions | ||||||
|  |   PutLE32(bmp_header + 22, height);               // no vertical flip | ||||||
|  |   PutLE16(bmp_header + 26, 1);                    // number of planes | ||||||
|  |   PutLE16(bmp_header + 28, bytes_per_px * 8);     // bits per pixel | ||||||
|  |   PutLE32(bmp_header + 30, has_alpha ? 3 : 0);    // BI_BITFIELDS or BI_RGB | ||||||
|  |   PutLE32(bmp_header + 34, image_size); | ||||||
|  |   PutLE32(bmp_header + 38, 2400);                 // x pixels/meter | ||||||
|  |   PutLE32(bmp_header + 42, 2400);                 // y pixels/meter | ||||||
|  |   PutLE32(bmp_header + 46, 0);                    // number of palette colors | ||||||
|  |   PutLE32(bmp_header + 50, 0);                    // important color count | ||||||
|  |   if (has_alpha) {  // BITMAPV3INFOHEADER complement | ||||||
|  |     PutLE32(bmp_header + 54, 0x00ff0000);         // red mask | ||||||
|  |     PutLE32(bmp_header + 58, 0x0000ff00);         // green mask | ||||||
|  |     PutLE32(bmp_header + 62, 0x000000ff);         // blue mask | ||||||
|  |     PutLE32(bmp_header + 66, 0xff000000);         // alpha mask | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   // TODO(skal): color profile | ||||||
|  |  | ||||||
|  |   // write header | ||||||
|  |   if (fwrite(bmp_header, header_size, 1, fout) != 1) { | ||||||
|  |     return 0; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   // write pixel array, bottom to top | ||||||
|  |   for (y = 0; y < height; ++y) { | ||||||
|  |     const uint8_t* const src = &rgba[(uint64_t)(height - 1 - y) * stride]; | ||||||
|  |     if (fwrite(src, line_size, 1, fout) != 1) { | ||||||
|  |       return 0; | ||||||
|  |     } | ||||||
|  |     // write padding zeroes | ||||||
|  |     if (bmp_stride != line_size) { | ||||||
|  |       const uint8_t zeroes[3] = { 0 }; | ||||||
|  |       if (fwrite(zeroes, bmp_stride - line_size, 1, fout) != 1) { | ||||||
|  |         return 0; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   return 1; | ||||||
|  | } | ||||||
|  | #undef BMP_HEADER_SIZE | ||||||
|  | #undef BMP_HEADER_ALPHA_EXTRA_SIZE | ||||||
|  |  | ||||||
|  | //------------------------------------------------------------------------------ | ||||||
|  | // TIFF | ||||||
|  |  | ||||||
|  | #define NUM_IFD_ENTRIES 15 | ||||||
|  | #define EXTRA_DATA_SIZE 16 | ||||||
|  | // 10b for signature/header + n * 12b entries + 4b for IFD terminator: | ||||||
|  | #define EXTRA_DATA_OFFSET (10 + 12 * NUM_IFD_ENTRIES + 4) | ||||||
|  | #define TIFF_HEADER_SIZE (EXTRA_DATA_OFFSET + EXTRA_DATA_SIZE) | ||||||
|  |  | ||||||
|  | int WebPWriteTIFF(FILE* fout, const WebPDecBuffer* const buffer) { | ||||||
|  |   const int has_alpha = WebPIsAlphaMode(buffer->colorspace); | ||||||
|  |   const uint32_t width = buffer->width; | ||||||
|  |   const uint32_t height = buffer->height; | ||||||
|  |   const uint8_t* rgba = buffer->u.RGBA.rgba; | ||||||
|  |   const int stride = buffer->u.RGBA.stride; | ||||||
|  |   const uint8_t bytes_per_px = has_alpha ? 4 : 3; | ||||||
|  |   const uint8_t assoc_alpha = | ||||||
|  |       WebPIsPremultipliedMode(buffer->colorspace) ? 1 : 2; | ||||||
|  |   // For non-alpha case, we omit tag 0x152 (ExtraSamples). | ||||||
|  |   const uint8_t num_ifd_entries = has_alpha ? NUM_IFD_ENTRIES | ||||||
|  |                                             : NUM_IFD_ENTRIES - 1; | ||||||
|  |   uint8_t tiff_header[TIFF_HEADER_SIZE] = { | ||||||
|  |     0x49, 0x49, 0x2a, 0x00,   // little endian signature | ||||||
|  |     8, 0, 0, 0,               // offset to the unique IFD that follows | ||||||
|  |     // IFD (offset = 8). Entries must be written in increasing tag order. | ||||||
|  |     num_ifd_entries, 0,       // Number of entries in the IFD (12 bytes each). | ||||||
|  |     0x00, 0x01, 3, 0, 1, 0, 0, 0, 0, 0, 0, 0,    //  10: Width  (TBD) | ||||||
|  |     0x01, 0x01, 3, 0, 1, 0, 0, 0, 0, 0, 0, 0,    //  22: Height (TBD) | ||||||
|  |     0x02, 0x01, 3, 0, bytes_per_px, 0, 0, 0,     //  34: BitsPerSample: 8888 | ||||||
|  |         EXTRA_DATA_OFFSET + 0, 0, 0, 0, | ||||||
|  |     0x03, 0x01, 3, 0, 1, 0, 0, 0, 1, 0, 0, 0,    //  46: Compression: none | ||||||
|  |     0x06, 0x01, 3, 0, 1, 0, 0, 0, 2, 0, 0, 0,    //  58: Photometric: RGB | ||||||
|  |     0x11, 0x01, 4, 0, 1, 0, 0, 0,                //  70: Strips offset: | ||||||
|  |         TIFF_HEADER_SIZE, 0, 0, 0,               //      data follows header | ||||||
|  |     0x12, 0x01, 3, 0, 1, 0, 0, 0, 1, 0, 0, 0,    //  82: Orientation: topleft | ||||||
|  |     0x15, 0x01, 3, 0, 1, 0, 0, 0,                //  94: SamplesPerPixels | ||||||
|  |         bytes_per_px, 0, 0, 0, | ||||||
|  |     0x16, 0x01, 3, 0, 1, 0, 0, 0, 0, 0, 0, 0,    // 106: Rows per strip (TBD) | ||||||
|  |     0x17, 0x01, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0,    // 118: StripByteCount (TBD) | ||||||
|  |     0x1a, 0x01, 5, 0, 1, 0, 0, 0,                // 130: X-resolution | ||||||
|  |         EXTRA_DATA_OFFSET + 8, 0, 0, 0, | ||||||
|  |     0x1b, 0x01, 5, 0, 1, 0, 0, 0,                // 142: Y-resolution | ||||||
|  |         EXTRA_DATA_OFFSET + 8, 0, 0, 0, | ||||||
|  |     0x1c, 0x01, 3, 0, 1, 0, 0, 0, 1, 0, 0, 0,    // 154: PlanarConfiguration | ||||||
|  |     0x28, 0x01, 3, 0, 1, 0, 0, 0, 2, 0, 0, 0,    // 166: ResolutionUnit (inch) | ||||||
|  |     0x52, 0x01, 3, 0, 1, 0, 0, 0, | ||||||
|  |         assoc_alpha, 0, 0, 0,                    // 178: ExtraSamples: rgbA/RGBA | ||||||
|  |     0, 0, 0, 0,                                  // 190: IFD terminator | ||||||
|  |     // EXTRA_DATA_OFFSET: | ||||||
|  |     8, 0, 8, 0, 8, 0, 8, 0,      // BitsPerSample | ||||||
|  |     72, 0, 0, 0, 1, 0, 0, 0      // 72 pixels/inch, for X/Y-resolution | ||||||
|  |   }; | ||||||
|  |   uint32_t y; | ||||||
|  |  | ||||||
|  |   if (fout == NULL || buffer == NULL || rgba == NULL) return 0; | ||||||
|  |  | ||||||
|  |   // Fill placeholders in IFD: | ||||||
|  |   PutLE32(tiff_header + 10 + 8, width); | ||||||
|  |   PutLE32(tiff_header + 22 + 8, height); | ||||||
|  |   PutLE32(tiff_header + 106 + 8, height); | ||||||
|  |   PutLE32(tiff_header + 118 + 8, width * bytes_per_px * height); | ||||||
|  |   if (!has_alpha) PutLE32(tiff_header + 178, 0);  // IFD terminator | ||||||
|  |  | ||||||
|  |   // write header | ||||||
|  |   if (fwrite(tiff_header, sizeof(tiff_header), 1, fout) != 1) { | ||||||
|  |     return 0; | ||||||
|  |   } | ||||||
|  |   // write pixel values | ||||||
|  |   for (y = 0; y < height; ++y) { | ||||||
|  |     if (fwrite(rgba, bytes_per_px, width, fout) != width) { | ||||||
|  |       return 0; | ||||||
|  |     } | ||||||
|  |     rgba += stride; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   return 1; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #undef TIFF_HEADER_SIZE | ||||||
|  | #undef EXTRA_DATA_OFFSET | ||||||
|  | #undef EXTRA_DATA_SIZE | ||||||
|  | #undef NUM_IFD_ENTRIES | ||||||
|  |  | ||||||
|  | //------------------------------------------------------------------------------ | ||||||
|  | // Raw Alpha | ||||||
|  |  | ||||||
|  | int WebPWriteAlphaPlane(FILE* fout, const WebPDecBuffer* const buffer) { | ||||||
|  |   if (fout == NULL || buffer == NULL) { | ||||||
|  |     return 0; | ||||||
|  |   } else { | ||||||
|  |     const uint32_t width = buffer->width; | ||||||
|  |     const uint32_t height = buffer->height; | ||||||
|  |     const uint8_t* a = buffer->u.YUVA.a; | ||||||
|  |     const int a_stride = buffer->u.YUVA.a_stride; | ||||||
|  |     uint32_t y; | ||||||
|  |  | ||||||
|  |     if (a == NULL) return 0; | ||||||
|  |  | ||||||
|  |     fprintf(fout, "P5\n%u %u\n255\n", width, height); | ||||||
|  |     for (y = 0; y < height; ++y) { | ||||||
|  |       if (fwrite(a, width, 1, fout) != 1) return 0; | ||||||
|  |       a += a_stride; | ||||||
|  |     } | ||||||
|  |     return 1; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | //------------------------------------------------------------------------------ | ||||||
|  | // PGM with IMC4 layout | ||||||
|  |  | ||||||
|  | int WebPWritePGM(FILE* fout, const WebPDecBuffer* const buffer) { | ||||||
|  |   if (fout == NULL || buffer == NULL) { | ||||||
|  |     return 0; | ||||||
|  |   } else { | ||||||
|  |     const int width = buffer->width; | ||||||
|  |     const int height = buffer->height; | ||||||
|  |     const WebPYUVABuffer* const yuv = &buffer->u.YUVA; | ||||||
|  |     const uint8_t* src_y = yuv->y; | ||||||
|  |     const uint8_t* src_u = yuv->u; | ||||||
|  |     const uint8_t* src_v = yuv->v; | ||||||
|  |     const uint8_t* src_a = yuv->a; | ||||||
|  |     const int uv_width = (width + 1) / 2; | ||||||
|  |     const int uv_height = (height + 1) / 2; | ||||||
|  |     const int a_height = (src_a != NULL) ? height : 0; | ||||||
|  |     int ok = 1; | ||||||
|  |     int y; | ||||||
|  |  | ||||||
|  |     if (src_y == NULL || src_u == NULL || src_v == NULL) return 0; | ||||||
|  |  | ||||||
|  |     fprintf(fout, "P5\n%d %d\n255\n", | ||||||
|  |             (width + 1) & ~1, height + uv_height + a_height); | ||||||
|  |     for (y = 0; ok && y < height; ++y) { | ||||||
|  |       ok &= (fwrite(src_y, width, 1, fout) == 1); | ||||||
|  |       if (width & 1) fputc(0, fout);    // padding byte | ||||||
|  |       src_y += yuv->y_stride; | ||||||
|  |     } | ||||||
|  |     for (y = 0; ok && y < uv_height; ++y) { | ||||||
|  |       ok &= (fwrite(src_u, uv_width, 1, fout) == 1); | ||||||
|  |       ok &= (fwrite(src_v, uv_width, 1, fout) == 1); | ||||||
|  |       src_u += yuv->u_stride; | ||||||
|  |       src_v += yuv->v_stride; | ||||||
|  |     } | ||||||
|  |     for (y = 0; ok && y < a_height; ++y) { | ||||||
|  |       ok &= (fwrite(src_a, width, 1, fout) == 1); | ||||||
|  |       if (width & 1) fputc(0, fout);    // padding byte | ||||||
|  |       src_a += yuv->a_stride; | ||||||
|  |     } | ||||||
|  |     return ok; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | //------------------------------------------------------------------------------ | ||||||
|  | // Raw YUV(A) planes | ||||||
|  |  | ||||||
|  | int WebPWriteYUV(FILE* fout, const WebPDecBuffer* const buffer) { | ||||||
|  |   if (fout == NULL || buffer == NULL) { | ||||||
|  |     return 0; | ||||||
|  |   } else { | ||||||
|  |     const int width = buffer->width; | ||||||
|  |     const int height = buffer->height; | ||||||
|  |     const WebPYUVABuffer* const yuv = &buffer->u.YUVA; | ||||||
|  |     const uint8_t* src_y = yuv->y; | ||||||
|  |     const uint8_t* src_u = yuv->u; | ||||||
|  |     const uint8_t* src_v = yuv->v; | ||||||
|  |     const uint8_t* src_a = yuv->a; | ||||||
|  |     const int uv_width = (width + 1) / 2; | ||||||
|  |     const int uv_height = (height + 1) / 2; | ||||||
|  |     const int a_height = (src_a != NULL) ? height : 0; | ||||||
|  |     int ok = 1; | ||||||
|  |     int y; | ||||||
|  |  | ||||||
|  |     if (src_y == NULL || src_u == NULL || src_v == NULL) return 0; | ||||||
|  |  | ||||||
|  |     for (y = 0; ok && y < height; ++y) { | ||||||
|  |       ok &= (fwrite(src_y, width, 1, fout) == 1); | ||||||
|  |       src_y += yuv->y_stride; | ||||||
|  |     } | ||||||
|  |     for (y = 0; ok && y < uv_height; ++y) { | ||||||
|  |       ok &= (fwrite(src_u, uv_width, 1, fout) == 1); | ||||||
|  |       src_u += yuv->u_stride; | ||||||
|  |     } | ||||||
|  |     for (y = 0; ok && y < uv_height; ++y) { | ||||||
|  |       ok &= (fwrite(src_v, uv_width, 1, fout) == 1); | ||||||
|  |       src_v += yuv->v_stride; | ||||||
|  |     } | ||||||
|  |     for (y = 0; ok && y < a_height; ++y) { | ||||||
|  |       ok &= (fwrite(src_a, width, 1, fout) == 1); | ||||||
|  |       src_a += yuv->a_stride; | ||||||
|  |     } | ||||||
|  |     return ok; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | //------------------------------------------------------------------------------ | ||||||
|  | // Generic top-level call | ||||||
|  |  | ||||||
|  | int WebPSaveImage(const WebPDecBuffer* const buffer, | ||||||
|  |                   WebPOutputFileFormat format, | ||||||
|  |                   const char* const out_file_name) { | ||||||
|  |   FILE* fout = NULL; | ||||||
|  |   int needs_open_file = 1; | ||||||
|  |   const int use_stdout = | ||||||
|  |       (out_file_name != NULL) && !WSTRCMP(out_file_name, "-"); | ||||||
|  |   int ok = 1; | ||||||
|  |  | ||||||
|  |   if (buffer == NULL || out_file_name == NULL) return 0; | ||||||
|  |  | ||||||
|  | #ifdef HAVE_WINCODEC_H | ||||||
|  |   needs_open_file = (format != PNG); | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  |   if (needs_open_file) { | ||||||
|  |     fout = use_stdout ? ImgIoUtilSetBinaryMode(stdout) | ||||||
|  |                       : WFOPEN(out_file_name, "wb"); | ||||||
|  |     if (fout == NULL) { | ||||||
|  |       WFPRINTF(stderr, "Error opening output file %s\n", | ||||||
|  |                (const W_CHAR*)out_file_name); | ||||||
|  |       return 0; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   if (format == PNG || | ||||||
|  |       format == RGBA || format == BGRA || format == ARGB || | ||||||
|  |       format == rgbA || format == bgrA || format == Argb) { | ||||||
|  | #ifdef HAVE_WINCODEC_H | ||||||
|  |     ok &= WebPWritePNG(out_file_name, use_stdout, buffer); | ||||||
|  | #else | ||||||
|  |     ok &= WebPWritePNG(fout, buffer); | ||||||
|  | #endif | ||||||
|  |   } else if (format == PAM) { | ||||||
|  |     ok &= WebPWritePAM(fout, buffer); | ||||||
|  |   } else if (format == PPM || format == RGB || format == BGR) { | ||||||
|  |     ok &= WebPWritePPM(fout, buffer); | ||||||
|  |   } else if (format == RGBA_4444 || format == RGB_565 || format == rgbA_4444) { | ||||||
|  |     ok &= WebPWrite16bAsPGM(fout, buffer); | ||||||
|  |   } else if (format == BMP) { | ||||||
|  |     ok &= WebPWriteBMP(fout, buffer); | ||||||
|  |   } else if (format == TIFF) { | ||||||
|  |     ok &= WebPWriteTIFF(fout, buffer); | ||||||
|  |   } else if (format == RAW_YUV) { | ||||||
|  |     ok &= WebPWriteYUV(fout, buffer); | ||||||
|  |   } else if (format == PGM || format == YUV || format == YUVA) { | ||||||
|  |     ok &= WebPWritePGM(fout, buffer); | ||||||
|  |   } else if (format == ALPHA_PLANE_ONLY) { | ||||||
|  |     ok &= WebPWriteAlphaPlane(fout, buffer); | ||||||
|  |   } | ||||||
|  |   if (fout != NULL && fout != stdout) { | ||||||
|  |     fclose(fout); | ||||||
|  |   } | ||||||
|  |   return ok; | ||||||
|  | } | ||||||
							
								
								
									
										96
									
								
								external/libwebp/libwebp/imageio/image_enc.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										96
									
								
								external/libwebp/libwebp/imageio/image_enc.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,96 @@ | |||||||
|  | // Copyright 2016 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. | ||||||
|  | // ----------------------------------------------------------------------------- | ||||||
|  | // | ||||||
|  | //  All-in-one library to save PNG/JPEG/WebP/TIFF/WIC images. | ||||||
|  | // | ||||||
|  | // Author: Skal (pascal.massimino@gmail.com) | ||||||
|  |  | ||||||
|  | #ifndef WEBP_IMAGEIO_IMAGE_ENC_H_ | ||||||
|  | #define WEBP_IMAGEIO_IMAGE_ENC_H_ | ||||||
|  |  | ||||||
|  | #include <stdio.h> | ||||||
|  |  | ||||||
|  | #ifdef HAVE_CONFIG_H | ||||||
|  | #include "webp/config.h" | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | #include "webp/types.h" | ||||||
|  | #include "webp/decode.h" | ||||||
|  |  | ||||||
|  | #ifdef __cplusplus | ||||||
|  | extern "C" { | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | // Output types | ||||||
|  | typedef enum { | ||||||
|  |   PNG = 0, | ||||||
|  |   PAM, | ||||||
|  |   PPM, | ||||||
|  |   PGM, | ||||||
|  |   BMP, | ||||||
|  |   TIFF, | ||||||
|  |   RAW_YUV, | ||||||
|  |   ALPHA_PLANE_ONLY,  // this is for experimenting only | ||||||
|  |   // forced colorspace output (for testing, mostly) | ||||||
|  |   RGB, RGBA, BGR, BGRA, ARGB, | ||||||
|  |   RGBA_4444, RGB_565, | ||||||
|  |   rgbA, bgrA, Argb, rgbA_4444, | ||||||
|  |   YUV, YUVA | ||||||
|  | } WebPOutputFileFormat; | ||||||
|  |  | ||||||
|  | // General all-purpose call. | ||||||
|  | // Most formats expect a 'buffer' containing RGBA-like samples, except | ||||||
|  | // RAW_YUV, YUV and YUVA formats. | ||||||
|  | // If 'out_file_name' is "-", data is saved to stdout. | ||||||
|  | // Returns false if an error occurred, true otherwise. | ||||||
|  | int WebPSaveImage(const WebPDecBuffer* const buffer, | ||||||
|  |                   WebPOutputFileFormat format, const char* const out_file_name); | ||||||
|  |  | ||||||
|  | // Save to PNG. | ||||||
|  | #ifdef HAVE_WINCODEC_H | ||||||
|  | int WebPWritePNG(const char* out_file_name, int use_stdout, | ||||||
|  |                  const struct WebPDecBuffer* const buffer); | ||||||
|  | #else | ||||||
|  | int WebPWritePNG(FILE* out_file, const WebPDecBuffer* const buffer); | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | // Save to PPM format (RGB, no alpha) | ||||||
|  | int WebPWritePPM(FILE* fout, const struct WebPDecBuffer* const buffer); | ||||||
|  |  | ||||||
|  | // Save to PAM format (= PPM + alpha) | ||||||
|  | int WebPWritePAM(FILE* fout, const struct WebPDecBuffer* const buffer); | ||||||
|  |  | ||||||
|  | // Save 16b mode (RGBA4444, RGB565, ...) for debugging purposes. | ||||||
|  | int WebPWrite16bAsPGM(FILE* fout, const struct WebPDecBuffer* const buffer); | ||||||
|  |  | ||||||
|  | // Save as BMP | ||||||
|  | int WebPWriteBMP(FILE* fout, const struct WebPDecBuffer* const buffer); | ||||||
|  |  | ||||||
|  | // Save as TIFF | ||||||
|  | int WebPWriteTIFF(FILE* fout, const struct WebPDecBuffer* const buffer); | ||||||
|  |  | ||||||
|  | // Save the ALPHA plane (only) as a PGM | ||||||
|  | int WebPWriteAlphaPlane(FILE* fout, const struct WebPDecBuffer* const buffer); | ||||||
|  |  | ||||||
|  | // Save as YUV samples as PGM format (using IMC4 layout). | ||||||
|  | // See: https://www.fourcc.org/yuv.php#IMC4. | ||||||
|  | // (very convenient format for viewing the samples, esp. for odd dimensions). | ||||||
|  | int WebPWritePGM(FILE* fout, const struct WebPDecBuffer* const buffer); | ||||||
|  |  | ||||||
|  | // Save YUV(A) planes sequentially (raw dump) | ||||||
|  | int WebPWriteYUV(FILE* fout, const struct WebPDecBuffer* const buffer); | ||||||
|  |  | ||||||
|  | // Save 16b mode (RGBA4444, RGB565, ...) as PGM format, for debugging purposes. | ||||||
|  | int WebPWrite16bAsPGM(FILE* fout, const struct WebPDecBuffer* const buffer); | ||||||
|  |  | ||||||
|  | #ifdef __cplusplus | ||||||
|  | }    // extern "C" | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | #endif  // WEBP_IMAGEIO_IMAGE_ENC_H_ | ||||||
							
								
								
									
										162
									
								
								external/libwebp/libwebp/imageio/imageio_util.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										162
									
								
								external/libwebp/libwebp/imageio/imageio_util.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,162 @@ | |||||||
|  | // Copyright 2016 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. | ||||||
|  | // ----------------------------------------------------------------------------- | ||||||
|  | // | ||||||
|  | //  Utility functions used by the image decoders. | ||||||
|  | // | ||||||
|  |  | ||||||
|  | #include "./imageio_util.h" | ||||||
|  |  | ||||||
|  | #if defined(_WIN32) | ||||||
|  | #include <fcntl.h>   // for _O_BINARY | ||||||
|  | #include <io.h>      // for _setmode() | ||||||
|  | #endif | ||||||
|  | #include <stdlib.h> | ||||||
|  | #include <string.h> | ||||||
|  | #include "../examples/unicode.h" | ||||||
|  |  | ||||||
|  | // ----------------------------------------------------------------------------- | ||||||
|  | // File I/O | ||||||
|  |  | ||||||
|  | FILE* ImgIoUtilSetBinaryMode(FILE* file) { | ||||||
|  | #if defined(_WIN32) | ||||||
|  |   if (_setmode(_fileno(file), _O_BINARY) == -1) { | ||||||
|  |     fprintf(stderr, "Failed to reopen file in O_BINARY mode.\n"); | ||||||
|  |     return NULL; | ||||||
|  |   } | ||||||
|  | #endif | ||||||
|  |   return file; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int ImgIoUtilReadFromStdin(const uint8_t** data, size_t* data_size) { | ||||||
|  |   static const size_t kBlockSize = 16384;  // default initial size | ||||||
|  |   size_t max_size = 0; | ||||||
|  |   size_t size = 0; | ||||||
|  |   uint8_t* input = NULL; | ||||||
|  |  | ||||||
|  |   if (data == NULL || data_size == NULL) return 0; | ||||||
|  |   *data = NULL; | ||||||
|  |   *data_size = 0; | ||||||
|  |  | ||||||
|  |   if (!ImgIoUtilSetBinaryMode(stdin)) return 0; | ||||||
|  |  | ||||||
|  |   while (!feof(stdin)) { | ||||||
|  |     // We double the buffer size each time and read as much as possible. | ||||||
|  |     const size_t extra_size = (max_size == 0) ? kBlockSize : max_size; | ||||||
|  |     // we allocate one extra byte for the \0 terminator | ||||||
|  |     void* const new_data = realloc(input, max_size + extra_size + 1); | ||||||
|  |     if (new_data == NULL) goto Error; | ||||||
|  |     input = (uint8_t*)new_data; | ||||||
|  |     max_size += extra_size; | ||||||
|  |     size += fread(input + size, 1, extra_size, stdin); | ||||||
|  |     if (size < max_size) break; | ||||||
|  |   } | ||||||
|  |   if (ferror(stdin)) goto Error; | ||||||
|  |   if (input != NULL) input[size] = '\0';  // convenient 0-terminator | ||||||
|  |   *data = input; | ||||||
|  |   *data_size = size; | ||||||
|  |   return 1; | ||||||
|  |  | ||||||
|  |  Error: | ||||||
|  |   free(input); | ||||||
|  |   fprintf(stderr, "Could not read from stdin\n"); | ||||||
|  |   return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int ImgIoUtilReadFile(const char* const file_name, | ||||||
|  |                       const uint8_t** data, size_t* data_size) { | ||||||
|  |   int ok; | ||||||
|  |   uint8_t* file_data; | ||||||
|  |   size_t file_size; | ||||||
|  |   FILE* in; | ||||||
|  |   const int from_stdin = (file_name == NULL) || !WSTRCMP(file_name, "-"); | ||||||
|  |  | ||||||
|  |   if (from_stdin) return ImgIoUtilReadFromStdin(data, data_size); | ||||||
|  |  | ||||||
|  |   if (data == NULL || data_size == NULL) return 0; | ||||||
|  |   *data = NULL; | ||||||
|  |   *data_size = 0; | ||||||
|  |  | ||||||
|  |   in = WFOPEN(file_name, "rb"); | ||||||
|  |   if (in == NULL) { | ||||||
|  |     WFPRINTF(stderr, "cannot open input file '%s'\n", (const W_CHAR*)file_name); | ||||||
|  |     return 0; | ||||||
|  |   } | ||||||
|  |   fseek(in, 0, SEEK_END); | ||||||
|  |   file_size = ftell(in); | ||||||
|  |   fseek(in, 0, SEEK_SET); | ||||||
|  |   // we allocate one extra byte for the \0 terminator | ||||||
|  |   file_data = (uint8_t*)WebPMalloc(file_size + 1); | ||||||
|  |   if (file_data == NULL) { | ||||||
|  |     fclose(in); | ||||||
|  |     WFPRINTF(stderr, "memory allocation failure when reading file %s\n", | ||||||
|  |              (const W_CHAR*)file_name); | ||||||
|  |     return 0; | ||||||
|  |   } | ||||||
|  |   ok = (fread(file_data, file_size, 1, in) == 1); | ||||||
|  |   fclose(in); | ||||||
|  |  | ||||||
|  |   if (!ok) { | ||||||
|  |     WFPRINTF(stderr, "Could not read %d bytes of data from file %s\n", | ||||||
|  |              (int)file_size, (const W_CHAR*)file_name); | ||||||
|  |     WebPFree(file_data); | ||||||
|  |     return 0; | ||||||
|  |   } | ||||||
|  |   file_data[file_size] = '\0';  // convenient 0-terminator | ||||||
|  |   *data = file_data; | ||||||
|  |   *data_size = file_size; | ||||||
|  |   return 1; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // ----------------------------------------------------------------------------- | ||||||
|  |  | ||||||
|  | int ImgIoUtilWriteFile(const char* const file_name, | ||||||
|  |                        const uint8_t* data, size_t data_size) { | ||||||
|  |   int ok; | ||||||
|  |   FILE* out; | ||||||
|  |   const int to_stdout = (file_name == NULL) || !WSTRCMP(file_name, "-"); | ||||||
|  |  | ||||||
|  |   if (data == NULL) { | ||||||
|  |     return 0; | ||||||
|  |   } | ||||||
|  |   out = to_stdout ? ImgIoUtilSetBinaryMode(stdout) : WFOPEN(file_name, "wb"); | ||||||
|  |   if (out == NULL) { | ||||||
|  |     WFPRINTF(stderr, "Error! Cannot open output file '%s'\n", | ||||||
|  |              (const W_CHAR*)file_name); | ||||||
|  |     return 0; | ||||||
|  |   } | ||||||
|  |   ok = (fwrite(data, data_size, 1, out) == 1); | ||||||
|  |   if (out != stdout) fclose(out); | ||||||
|  |   return ok; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // ----------------------------------------------------------------------------- | ||||||
|  |  | ||||||
|  | void ImgIoUtilCopyPlane(const uint8_t* src, int src_stride, | ||||||
|  |                         uint8_t* dst, int dst_stride, int width, int height) { | ||||||
|  |   while (height-- > 0) { | ||||||
|  |     memcpy(dst, src, width * sizeof(*dst)); | ||||||
|  |     src += src_stride; | ||||||
|  |     dst += dst_stride; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // ----------------------------------------------------------------------------- | ||||||
|  |  | ||||||
|  | int ImgIoUtilCheckSizeArgumentsOverflow(uint64_t stride, size_t height) { | ||||||
|  |   const uint64_t total_size = stride * height; | ||||||
|  |   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) | ||||||
|  |   ok = ok && (total_size <= (uint64_t)WEBP_MAX_IMAGE_SIZE); | ||||||
|  | #endif | ||||||
|  |   return ok; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // ----------------------------------------------------------------------------- | ||||||
							
								
								
									
										64
									
								
								external/libwebp/libwebp/imageio/imageio_util.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								external/libwebp/libwebp/imageio/imageio_util.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,64 @@ | |||||||
|  | // Copyright 2016 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. | ||||||
|  | // ----------------------------------------------------------------------------- | ||||||
|  | // | ||||||
|  | //  Utility functions used by the image decoders. | ||||||
|  | // | ||||||
|  |  | ||||||
|  | #ifndef WEBP_IMAGEIO_IMAGEIO_UTIL_H_ | ||||||
|  | #define WEBP_IMAGEIO_IMAGEIO_UTIL_H_ | ||||||
|  |  | ||||||
|  | #include <stdio.h> | ||||||
|  | #include "webp/types.h" | ||||||
|  |  | ||||||
|  | #ifdef __cplusplus | ||||||
|  | extern "C" { | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | //------------------------------------------------------------------------------ | ||||||
|  | // File I/O | ||||||
|  |  | ||||||
|  | // Reopen file in binary (O_BINARY) mode. | ||||||
|  | // Returns 'file' on success, NULL otherwise. | ||||||
|  | FILE* ImgIoUtilSetBinaryMode(FILE* file); | ||||||
|  |  | ||||||
|  | // Allocates storage for entire file 'file_name' and returns contents and size | ||||||
|  | // in 'data' and 'data_size'. Returns 1 on success, 0 otherwise. '*data' should | ||||||
|  | // be deleted using WebPFree(). | ||||||
|  | // Note: for convenience, the data will be null-terminated with an extra byte | ||||||
|  | // (not accounted for in *data_size), in case the file is text and intended | ||||||
|  | // to be used as a C-string. | ||||||
|  | // If 'file_name' is NULL or equal to "-", input is read from stdin by calling | ||||||
|  | // the function ImgIoUtilReadFromStdin(). | ||||||
|  | int ImgIoUtilReadFile(const char* const file_name, | ||||||
|  |                       const uint8_t** data, size_t* data_size); | ||||||
|  |  | ||||||
|  | // Same as ImgIoUtilReadFile(), but reads until EOF from stdin instead. | ||||||
|  | int ImgIoUtilReadFromStdin(const uint8_t** data, size_t* data_size); | ||||||
|  |  | ||||||
|  | // Write a data segment into a file named 'file_name'. Returns true if ok. | ||||||
|  | // If 'file_name' is NULL or equal to "-", output is written to stdout. | ||||||
|  | int ImgIoUtilWriteFile(const char* const file_name, | ||||||
|  |                        const uint8_t* data, size_t data_size); | ||||||
|  |  | ||||||
|  | //------------------------------------------------------------------------------ | ||||||
|  |  | ||||||
|  | // Copy width x height pixels from 'src' to 'dst' honoring the strides. | ||||||
|  | void ImgIoUtilCopyPlane(const uint8_t* src, int src_stride, | ||||||
|  |                         uint8_t* dst, int dst_stride, int width, int height); | ||||||
|  |  | ||||||
|  | //------------------------------------------------------------------------------ | ||||||
|  |  | ||||||
|  | // Returns 0 in case of overflow, memory over-allocation or excessive dimension. | ||||||
|  | int ImgIoUtilCheckSizeArgumentsOverflow(uint64_t stride, size_t height); | ||||||
|  |  | ||||||
|  | #ifdef __cplusplus | ||||||
|  | }    // extern "C" | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | #endif  // WEBP_IMAGEIO_IMAGEIO_UTIL_H_ | ||||||
							
								
								
									
										364
									
								
								external/libwebp/libwebp/imageio/jpegdec.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										364
									
								
								external/libwebp/libwebp/imageio/jpegdec.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,364 @@ | |||||||
|  | // Copyright 2012 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. | ||||||
|  | // ----------------------------------------------------------------------------- | ||||||
|  | // | ||||||
|  | // JPEG decode. | ||||||
|  |  | ||||||
|  | #include "./jpegdec.h" | ||||||
|  |  | ||||||
|  | #ifdef HAVE_CONFIG_H | ||||||
|  | #include "webp/config.h" | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | #include <stdio.h> | ||||||
|  |  | ||||||
|  | #ifdef WEBP_HAVE_JPEG | ||||||
|  | #include <jpeglib.h> | ||||||
|  | #include <jerror.h> | ||||||
|  | #include <setjmp.h> | ||||||
|  | #include <stdlib.h> | ||||||
|  | #include <string.h> | ||||||
|  |  | ||||||
|  | #include "webp/encode.h" | ||||||
|  | #include "./imageio_util.h" | ||||||
|  | #include "./metadata.h" | ||||||
|  |  | ||||||
|  | // ----------------------------------------------------------------------------- | ||||||
|  | // Metadata processing | ||||||
|  |  | ||||||
|  | #ifndef JPEG_APP1 | ||||||
|  | # define JPEG_APP1 (JPEG_APP0 + 1) | ||||||
|  | #endif | ||||||
|  | #ifndef JPEG_APP2 | ||||||
|  | # define JPEG_APP2 (JPEG_APP0 + 2) | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | typedef struct { | ||||||
|  |   const uint8_t* data; | ||||||
|  |   size_t data_length; | ||||||
|  |   int seq;  // this segment's sequence number [1, 255] for use in reassembly. | ||||||
|  | } ICCPSegment; | ||||||
|  |  | ||||||
|  | static void SaveMetadataMarkers(j_decompress_ptr dinfo) { | ||||||
|  |   const unsigned int max_marker_length = 0xffff; | ||||||
|  |   jpeg_save_markers(dinfo, JPEG_APP1, max_marker_length);  // Exif/XMP | ||||||
|  |   jpeg_save_markers(dinfo, JPEG_APP2, max_marker_length);  // ICC profile | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static int CompareICCPSegments(const void* a, const void* b) { | ||||||
|  |   const ICCPSegment* s1 = (const ICCPSegment*)a; | ||||||
|  |   const ICCPSegment* s2 = (const ICCPSegment*)b; | ||||||
|  |   return s1->seq - s2->seq; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Extract ICC profile segments from the marker list in 'dinfo', reassembling | ||||||
|  | // and storing them in 'iccp'. | ||||||
|  | // Returns true on success and false for memory errors and corrupt profiles. | ||||||
|  | static int StoreICCP(j_decompress_ptr dinfo, MetadataPayload* const iccp) { | ||||||
|  |   // ICC.1:2010-12 (4.3.0.0) Annex B.4 Embedding ICC Profiles in JPEG files | ||||||
|  |   static const char kICCPSignature[] = "ICC_PROFILE"; | ||||||
|  |   static const size_t kICCPSignatureLength = 12;  // signature includes '\0' | ||||||
|  |   static const size_t kICCPSkipLength = 14;  // signature + seq & count | ||||||
|  |   int expected_count = 0; | ||||||
|  |   int actual_count = 0; | ||||||
|  |   int seq_max = 0; | ||||||
|  |   size_t total_size = 0; | ||||||
|  |   ICCPSegment iccp_segments[255]; | ||||||
|  |   jpeg_saved_marker_ptr marker; | ||||||
|  |  | ||||||
|  |   memset(iccp_segments, 0, sizeof(iccp_segments)); | ||||||
|  |   for (marker = dinfo->marker_list; marker != NULL; marker = marker->next) { | ||||||
|  |     if (marker->marker == JPEG_APP2 && | ||||||
|  |         marker->data_length > kICCPSkipLength && | ||||||
|  |         !memcmp(marker->data, kICCPSignature, kICCPSignatureLength)) { | ||||||
|  |       // ICC_PROFILE\0<seq><count>; 'seq' starts at 1. | ||||||
|  |       const int seq = marker->data[kICCPSignatureLength]; | ||||||
|  |       const int count = marker->data[kICCPSignatureLength + 1]; | ||||||
|  |       const size_t segment_size = marker->data_length - kICCPSkipLength; | ||||||
|  |       ICCPSegment* segment; | ||||||
|  |  | ||||||
|  |       if (segment_size == 0 || count == 0 || seq == 0) { | ||||||
|  |         fprintf(stderr, "[ICCP] size (%d) / count (%d) / sequence number (%d)" | ||||||
|  |                         " cannot be 0!\n", | ||||||
|  |                 (int)segment_size, seq, count); | ||||||
|  |         return 0; | ||||||
|  |       } | ||||||
|  |  | ||||||
|  |       if (expected_count == 0) { | ||||||
|  |         expected_count = count; | ||||||
|  |       } else if (expected_count != count) { | ||||||
|  |         fprintf(stderr, "[ICCP] Inconsistent segment count (%d / %d)!\n", | ||||||
|  |                 expected_count, count); | ||||||
|  |         return 0; | ||||||
|  |       } | ||||||
|  |  | ||||||
|  |       segment = iccp_segments + seq - 1; | ||||||
|  |       if (segment->data_length != 0) { | ||||||
|  |         fprintf(stderr, "[ICCP] Duplicate segment number (%d)!\n" , seq); | ||||||
|  |         return 0; | ||||||
|  |       } | ||||||
|  |  | ||||||
|  |       segment->data = marker->data + kICCPSkipLength; | ||||||
|  |       segment->data_length = segment_size; | ||||||
|  |       segment->seq = seq; | ||||||
|  |       total_size += segment_size; | ||||||
|  |       if (seq > seq_max) seq_max = seq; | ||||||
|  |       ++actual_count; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   if (actual_count == 0) return 1; | ||||||
|  |   if (seq_max != actual_count) { | ||||||
|  |     fprintf(stderr, "[ICCP] Discontinuous segments, expected: %d actual: %d!\n", | ||||||
|  |             actual_count, seq_max); | ||||||
|  |     return 0; | ||||||
|  |   } | ||||||
|  |   if (expected_count != actual_count) { | ||||||
|  |     fprintf(stderr, "[ICCP] Segment count: %d does not match expected: %d!\n", | ||||||
|  |             actual_count, expected_count); | ||||||
|  |     return 0; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   // The segments may appear out of order in the file, sort them based on | ||||||
|  |   // sequence number before assembling the payload. | ||||||
|  |   qsort(iccp_segments, actual_count, sizeof(*iccp_segments), | ||||||
|  |         CompareICCPSegments); | ||||||
|  |  | ||||||
|  |   iccp->bytes = (uint8_t*)malloc(total_size); | ||||||
|  |   if (iccp->bytes == NULL) return 0; | ||||||
|  |   iccp->size = total_size; | ||||||
|  |  | ||||||
|  |   { | ||||||
|  |     int i; | ||||||
|  |     size_t offset = 0; | ||||||
|  |     for (i = 0; i < seq_max; ++i) { | ||||||
|  |       memcpy(iccp->bytes + offset, | ||||||
|  |              iccp_segments[i].data, iccp_segments[i].data_length); | ||||||
|  |       offset += iccp_segments[i].data_length; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   return 1; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Returns true on success and false for memory errors and corrupt profiles. | ||||||
|  | // The caller must use MetadataFree() on 'metadata' in all cases. | ||||||
|  | static int ExtractMetadataFromJPEG(j_decompress_ptr dinfo, | ||||||
|  |                                    Metadata* const metadata) { | ||||||
|  |   static const struct { | ||||||
|  |     int marker; | ||||||
|  |     const char* signature; | ||||||
|  |     size_t signature_length; | ||||||
|  |     size_t storage_offset; | ||||||
|  |   } kJPEGMetadataMap[] = { | ||||||
|  |     // Exif 2.2 Section 4.7.2 Interoperability Structure of APP1 ... | ||||||
|  |     { JPEG_APP1, "Exif\0",                        6, METADATA_OFFSET(exif) }, | ||||||
|  |     // XMP Specification Part 3 Section 3 Embedding XMP Metadata ... #JPEG | ||||||
|  |     // TODO(jzern) Add support for 'ExtendedXMP' | ||||||
|  |     { JPEG_APP1, "http://ns.adobe.com/xap/1.0/", 29, METADATA_OFFSET(xmp) }, | ||||||
|  |     { 0, NULL, 0, 0 }, | ||||||
|  |   }; | ||||||
|  |   jpeg_saved_marker_ptr marker; | ||||||
|  |   // Treat ICC profiles separately as they may be segmented and out of order. | ||||||
|  |   if (!StoreICCP(dinfo, &metadata->iccp)) return 0; | ||||||
|  |  | ||||||
|  |   for (marker = dinfo->marker_list; marker != NULL; marker = marker->next) { | ||||||
|  |     int i; | ||||||
|  |     for (i = 0; kJPEGMetadataMap[i].marker != 0; ++i) { | ||||||
|  |       if (marker->marker == kJPEGMetadataMap[i].marker && | ||||||
|  |           marker->data_length > kJPEGMetadataMap[i].signature_length && | ||||||
|  |           !memcmp(marker->data, kJPEGMetadataMap[i].signature, | ||||||
|  |                   kJPEGMetadataMap[i].signature_length)) { | ||||||
|  |         MetadataPayload* const payload = | ||||||
|  |             (MetadataPayload*)((uint8_t*)metadata + | ||||||
|  |                                kJPEGMetadataMap[i].storage_offset); | ||||||
|  |  | ||||||
|  |         if (payload->bytes == NULL) { | ||||||
|  |           const char* marker_data = (const char*)marker->data + | ||||||
|  |                                     kJPEGMetadataMap[i].signature_length; | ||||||
|  |           const size_t marker_data_length = | ||||||
|  |               marker->data_length - kJPEGMetadataMap[i].signature_length; | ||||||
|  |           if (!MetadataCopy(marker_data, marker_data_length, payload)) return 0; | ||||||
|  |         } else { | ||||||
|  |           fprintf(stderr, "Ignoring additional '%s' marker\n", | ||||||
|  |                   kJPEGMetadataMap[i].signature); | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   return 1; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #undef JPEG_APP1 | ||||||
|  | #undef JPEG_APP2 | ||||||
|  |  | ||||||
|  | // ----------------------------------------------------------------------------- | ||||||
|  | // JPEG decoding | ||||||
|  |  | ||||||
|  | struct my_error_mgr { | ||||||
|  |   struct jpeg_error_mgr pub; | ||||||
|  |   jmp_buf setjmp_buffer; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | static void my_error_exit(j_common_ptr dinfo) { | ||||||
|  |   struct my_error_mgr* myerr = (struct my_error_mgr*)dinfo->err; | ||||||
|  |   fprintf(stderr, "libjpeg error: "); | ||||||
|  |   dinfo->err->output_message(dinfo); | ||||||
|  |   longjmp(myerr->setjmp_buffer, 1); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | typedef struct { | ||||||
|  |   struct jpeg_source_mgr pub; | ||||||
|  |   const uint8_t* data; | ||||||
|  |   size_t data_size; | ||||||
|  | } JPEGReadContext; | ||||||
|  |  | ||||||
|  | static void ContextInit(j_decompress_ptr cinfo) { | ||||||
|  |   JPEGReadContext* const ctx = (JPEGReadContext*)cinfo->src; | ||||||
|  |   ctx->pub.next_input_byte = ctx->data; | ||||||
|  |   ctx->pub.bytes_in_buffer = ctx->data_size; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static boolean ContextFill(j_decompress_ptr cinfo) { | ||||||
|  |   // we shouldn't get here. | ||||||
|  |   ERREXIT(cinfo, JERR_FILE_READ); | ||||||
|  |   return FALSE; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static void ContextSkip(j_decompress_ptr cinfo, long jump_size) { | ||||||
|  |   JPEGReadContext* const ctx = (JPEGReadContext*)cinfo->src; | ||||||
|  |   size_t jump = (size_t)jump_size; | ||||||
|  |   if (jump > ctx->pub.bytes_in_buffer) {  // Don't overflow the buffer. | ||||||
|  |     jump = ctx->pub.bytes_in_buffer; | ||||||
|  |   } | ||||||
|  |   ctx->pub.bytes_in_buffer -= jump; | ||||||
|  |   ctx->pub.next_input_byte += jump; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static void ContextTerm(j_decompress_ptr cinfo) { | ||||||
|  |   (void)cinfo; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static void ContextSetup(volatile struct jpeg_decompress_struct* const cinfo, | ||||||
|  |                          JPEGReadContext* const ctx) { | ||||||
|  |   cinfo->src = (struct jpeg_source_mgr*)ctx; | ||||||
|  |   ctx->pub.init_source = ContextInit; | ||||||
|  |   ctx->pub.fill_input_buffer = ContextFill; | ||||||
|  |   ctx->pub.skip_input_data = ContextSkip; | ||||||
|  |   ctx->pub.resync_to_restart = jpeg_resync_to_restart; | ||||||
|  |   ctx->pub.term_source = ContextTerm; | ||||||
|  |   ctx->pub.bytes_in_buffer = 0; | ||||||
|  |   ctx->pub.next_input_byte = NULL; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int ReadJPEG(const uint8_t* const data, size_t data_size, | ||||||
|  |              WebPPicture* const pic, int keep_alpha, | ||||||
|  |              Metadata* const metadata) { | ||||||
|  |   volatile int ok = 0; | ||||||
|  |   int width, height; | ||||||
|  |   int64_t stride; | ||||||
|  |   volatile struct jpeg_decompress_struct dinfo; | ||||||
|  |   struct my_error_mgr jerr; | ||||||
|  |   uint8_t* volatile rgb = NULL; | ||||||
|  |   JSAMPROW buffer[1]; | ||||||
|  |   JPEGReadContext ctx; | ||||||
|  |  | ||||||
|  |   if (data == NULL || data_size == 0 || pic == NULL) return 0; | ||||||
|  |  | ||||||
|  |   (void)keep_alpha; | ||||||
|  |   memset(&ctx, 0, sizeof(ctx)); | ||||||
|  |   ctx.data = data; | ||||||
|  |   ctx.data_size = data_size; | ||||||
|  |  | ||||||
|  |   memset((j_decompress_ptr)&dinfo, 0, sizeof(dinfo));   // for setjmp safety | ||||||
|  |   dinfo.err = jpeg_std_error(&jerr.pub); | ||||||
|  |   jerr.pub.error_exit = my_error_exit; | ||||||
|  |  | ||||||
|  |   if (setjmp(jerr.setjmp_buffer)) { | ||||||
|  |  Error: | ||||||
|  |     MetadataFree(metadata); | ||||||
|  |     jpeg_destroy_decompress((j_decompress_ptr)&dinfo); | ||||||
|  |     goto End; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   jpeg_create_decompress((j_decompress_ptr)&dinfo); | ||||||
|  |   ContextSetup(&dinfo, &ctx); | ||||||
|  |   if (metadata != NULL) SaveMetadataMarkers((j_decompress_ptr)&dinfo); | ||||||
|  |   jpeg_read_header((j_decompress_ptr)&dinfo, TRUE); | ||||||
|  |  | ||||||
|  |   dinfo.out_color_space = JCS_RGB; | ||||||
|  |   dinfo.do_fancy_upsampling = TRUE; | ||||||
|  |  | ||||||
|  |   jpeg_start_decompress((j_decompress_ptr)&dinfo); | ||||||
|  |  | ||||||
|  |   if (dinfo.output_components != 3) { | ||||||
|  |     goto Error; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   width = dinfo.output_width; | ||||||
|  |   height = dinfo.output_height; | ||||||
|  |   stride = (int64_t)dinfo.output_width * dinfo.output_components * sizeof(*rgb); | ||||||
|  |  | ||||||
|  |   if (stride != (int)stride || | ||||||
|  |       !ImgIoUtilCheckSizeArgumentsOverflow(stride, height)) { | ||||||
|  |     goto Error; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   rgb = (uint8_t*)malloc((size_t)stride * height); | ||||||
|  |   if (rgb == NULL) { | ||||||
|  |     goto Error; | ||||||
|  |   } | ||||||
|  |   buffer[0] = (JSAMPLE*)rgb; | ||||||
|  |  | ||||||
|  |   while (dinfo.output_scanline < dinfo.output_height) { | ||||||
|  |     if (jpeg_read_scanlines((j_decompress_ptr)&dinfo, buffer, 1) != 1) { | ||||||
|  |       goto Error; | ||||||
|  |     } | ||||||
|  |     buffer[0] += stride; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   if (metadata != NULL) { | ||||||
|  |     ok = ExtractMetadataFromJPEG((j_decompress_ptr)&dinfo, metadata); | ||||||
|  |     if (!ok) { | ||||||
|  |       fprintf(stderr, "Error extracting JPEG metadata!\n"); | ||||||
|  |       goto Error; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   jpeg_finish_decompress((j_decompress_ptr)&dinfo); | ||||||
|  |   jpeg_destroy_decompress((j_decompress_ptr)&dinfo); | ||||||
|  |  | ||||||
|  |   // WebP conversion. | ||||||
|  |   pic->width = width; | ||||||
|  |   pic->height = height; | ||||||
|  |   ok = WebPPictureImportRGB(pic, rgb, (int)stride); | ||||||
|  |   if (!ok) { | ||||||
|  |     pic->width = 0;   // WebPPictureImportRGB() barely touches 'pic' on failure. | ||||||
|  |     pic->height = 0;  // Just reset dimensions but keep any 'custom_ptr' etc. | ||||||
|  |     MetadataFree(metadata);  // In case the caller forgets to free it on error. | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |  End: | ||||||
|  |   free(rgb); | ||||||
|  |   return ok; | ||||||
|  | } | ||||||
|  | #else  // !WEBP_HAVE_JPEG | ||||||
|  | int ReadJPEG(const uint8_t* const data, size_t data_size, | ||||||
|  |              struct WebPPicture* const pic, int keep_alpha, | ||||||
|  |              struct Metadata* const metadata) { | ||||||
|  |   (void)data; | ||||||
|  |   (void)data_size; | ||||||
|  |   (void)pic; | ||||||
|  |   (void)keep_alpha; | ||||||
|  |   (void)metadata; | ||||||
|  |   fprintf(stderr, "JPEG support not compiled. Please install the libjpeg " | ||||||
|  |           "development package before building.\n"); | ||||||
|  |   return 0; | ||||||
|  | } | ||||||
|  | #endif  // WEBP_HAVE_JPEG | ||||||
|  |  | ||||||
|  | // ----------------------------------------------------------------------------- | ||||||
							
								
								
									
										37
									
								
								external/libwebp/libwebp/imageio/jpegdec.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								external/libwebp/libwebp/imageio/jpegdec.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,37 @@ | |||||||
|  | // Copyright 2012 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. | ||||||
|  | // ----------------------------------------------------------------------------- | ||||||
|  | // | ||||||
|  | // JPEG decode. | ||||||
|  |  | ||||||
|  | #ifndef WEBP_IMAGEIO_JPEGDEC_H_ | ||||||
|  | #define WEBP_IMAGEIO_JPEGDEC_H_ | ||||||
|  |  | ||||||
|  | #include "webp/types.h" | ||||||
|  |  | ||||||
|  | #ifdef __cplusplus | ||||||
|  | extern "C" { | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | struct Metadata; | ||||||
|  | struct WebPPicture; | ||||||
|  |  | ||||||
|  | // Reads a JPEG from 'data', returning the decoded output in 'pic'. | ||||||
|  | // The output is RGB or YUV depending on pic->use_argb value. | ||||||
|  | // Returns true on success. | ||||||
|  | // 'keep_alpha' has no effect, but is kept for coherence with other signatures | ||||||
|  | // for image readers. | ||||||
|  | int ReadJPEG(const uint8_t* const data, size_t data_size, | ||||||
|  |              struct WebPPicture* const pic, int keep_alpha, | ||||||
|  |              struct Metadata* const metadata); | ||||||
|  |  | ||||||
|  | #ifdef __cplusplus | ||||||
|  | }    // extern "C" | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | #endif  // WEBP_IMAGEIO_JPEGDEC_H_ | ||||||
							
								
								
									
										49
									
								
								external/libwebp/libwebp/imageio/metadata.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								external/libwebp/libwebp/imageio/metadata.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,49 @@ | |||||||
|  | // Copyright 2012 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. | ||||||
|  | // ----------------------------------------------------------------------------- | ||||||
|  | // | ||||||
|  | //  Metadata types and functions. | ||||||
|  | // | ||||||
|  |  | ||||||
|  | #include "./metadata.h" | ||||||
|  |  | ||||||
|  | #include <stdlib.h> | ||||||
|  | #include <string.h> | ||||||
|  |  | ||||||
|  | #include "webp/types.h" | ||||||
|  |  | ||||||
|  | void MetadataInit(Metadata* const metadata) { | ||||||
|  |   if (metadata == NULL) return; | ||||||
|  |   memset(metadata, 0, sizeof(*metadata)); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void MetadataPayloadDelete(MetadataPayload* const payload) { | ||||||
|  |   if (payload == NULL) return; | ||||||
|  |   free(payload->bytes); | ||||||
|  |   payload->bytes = NULL; | ||||||
|  |   payload->size = 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void MetadataFree(Metadata* const metadata) { | ||||||
|  |   if (metadata == NULL) return; | ||||||
|  |   MetadataPayloadDelete(&metadata->exif); | ||||||
|  |   MetadataPayloadDelete(&metadata->iccp); | ||||||
|  |   MetadataPayloadDelete(&metadata->xmp); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int MetadataCopy(const char* metadata, size_t metadata_len, | ||||||
|  |                  MetadataPayload* const payload) { | ||||||
|  |   if (metadata == NULL || metadata_len == 0 || payload == NULL) return 0; | ||||||
|  |   payload->bytes = (uint8_t*)malloc(metadata_len); | ||||||
|  |   if (payload->bytes == NULL) return 0; | ||||||
|  |   payload->size = metadata_len; | ||||||
|  |   memcpy(payload->bytes, metadata, metadata_len); | ||||||
|  |   return 1; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // ----------------------------------------------------------------------------- | ||||||
							
								
								
									
										47
									
								
								external/libwebp/libwebp/imageio/metadata.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								external/libwebp/libwebp/imageio/metadata.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,47 @@ | |||||||
|  | // Copyright 2012 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. | ||||||
|  | // ----------------------------------------------------------------------------- | ||||||
|  | // | ||||||
|  | //  Metadata types and functions. | ||||||
|  | // | ||||||
|  |  | ||||||
|  | #ifndef WEBP_IMAGEIO_METADATA_H_ | ||||||
|  | #define WEBP_IMAGEIO_METADATA_H_ | ||||||
|  |  | ||||||
|  | #include "webp/types.h" | ||||||
|  |  | ||||||
|  | #ifdef __cplusplus | ||||||
|  | extern "C" { | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | typedef struct MetadataPayload { | ||||||
|  |   uint8_t* bytes; | ||||||
|  |   size_t size; | ||||||
|  | } MetadataPayload; | ||||||
|  |  | ||||||
|  | typedef struct Metadata { | ||||||
|  |   MetadataPayload exif; | ||||||
|  |   MetadataPayload iccp; | ||||||
|  |   MetadataPayload xmp; | ||||||
|  | } Metadata; | ||||||
|  |  | ||||||
|  | #define METADATA_OFFSET(x) offsetof(Metadata, x) | ||||||
|  |  | ||||||
|  | void MetadataInit(Metadata* const metadata); | ||||||
|  | void MetadataPayloadDelete(MetadataPayload* const payload); | ||||||
|  | void MetadataFree(Metadata* const metadata); | ||||||
|  |  | ||||||
|  | // Stores 'metadata' to 'payload->bytes', returns false on allocation error. | ||||||
|  | int MetadataCopy(const char* metadata, size_t metadata_len, | ||||||
|  |                  MetadataPayload* const payload); | ||||||
|  |  | ||||||
|  | #ifdef __cplusplus | ||||||
|  | }    // extern "C" | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | #endif  // WEBP_IMAGEIO_METADATA_H_ | ||||||
							
								
								
									
										374
									
								
								external/libwebp/libwebp/imageio/pngdec.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										374
									
								
								external/libwebp/libwebp/imageio/pngdec.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,374 @@ | |||||||
|  | // Copyright 2012 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. | ||||||
|  | // ----------------------------------------------------------------------------- | ||||||
|  | // | ||||||
|  | // PNG decode. | ||||||
|  |  | ||||||
|  | #include "./pngdec.h" | ||||||
|  |  | ||||||
|  | #ifdef HAVE_CONFIG_H | ||||||
|  | #include "webp/config.h" | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | #include <stdio.h> | ||||||
|  |  | ||||||
|  | #ifdef WEBP_HAVE_PNG | ||||||
|  | #ifndef PNG_USER_MEM_SUPPORTED | ||||||
|  | #define PNG_USER_MEM_SUPPORTED  // for png_create_read_struct_2 | ||||||
|  | #endif | ||||||
|  | #include <png.h> | ||||||
|  | #include <setjmp.h>   // note: this must be included *after* png.h | ||||||
|  | #include <stdlib.h> | ||||||
|  | #include <string.h> | ||||||
|  |  | ||||||
|  | #include "webp/encode.h" | ||||||
|  | #include "./imageio_util.h" | ||||||
|  | #include "./metadata.h" | ||||||
|  |  | ||||||
|  | #define LOCAL_PNG_VERSION ((PNG_LIBPNG_VER_MAJOR << 8) | PNG_LIBPNG_VER_MINOR) | ||||||
|  | #define LOCAL_PNG_PREREQ(maj, min) \ | ||||||
|  |    (LOCAL_PNG_VERSION >= (((maj) << 8) | (min))) | ||||||
|  |  | ||||||
|  | static void PNGAPI error_function(png_structp png, png_const_charp error) { | ||||||
|  |   if (error != NULL) fprintf(stderr, "libpng error: %s\n", error); | ||||||
|  |   longjmp(png_jmpbuf(png), 1); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #if LOCAL_PNG_PREREQ(1,4) | ||||||
|  | typedef png_alloc_size_t LocalPngAllocSize; | ||||||
|  | #else | ||||||
|  | typedef png_size_t LocalPngAllocSize; | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | static png_voidp MallocFunc(png_structp png_ptr, LocalPngAllocSize size) { | ||||||
|  |   (void)png_ptr; | ||||||
|  |   if (size != (size_t)size) return NULL; | ||||||
|  |   if (!ImgIoUtilCheckSizeArgumentsOverflow(size, 1)) return NULL; | ||||||
|  |   return (png_voidp)malloc((size_t)size); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static void FreeFunc(png_structp png_ptr, png_voidp ptr) { | ||||||
|  |   (void)png_ptr; | ||||||
|  |   free(ptr); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Converts the NULL terminated 'hexstring' which contains 2-byte character | ||||||
|  | // representations of hex values to raw data. | ||||||
|  | // 'hexstring' may contain values consisting of [A-F][a-f][0-9] in pairs, | ||||||
|  | // e.g., 7af2..., separated by any number of newlines. | ||||||
|  | // 'expected_length' is the anticipated processed size. | ||||||
|  | // On success the raw buffer is returned with its length equivalent to | ||||||
|  | // 'expected_length'. NULL is returned if the processed length is less than | ||||||
|  | // 'expected_length' or any character aside from those above is encountered. | ||||||
|  | // The returned buffer must be freed by the caller. | ||||||
|  | static uint8_t* HexStringToBytes(const char* hexstring, | ||||||
|  |                                  size_t expected_length) { | ||||||
|  |   const char* src = hexstring; | ||||||
|  |   size_t actual_length = 0; | ||||||
|  |   uint8_t* const raw_data = (uint8_t*)malloc(expected_length); | ||||||
|  |   uint8_t* dst; | ||||||
|  |  | ||||||
|  |   if (raw_data == NULL) return NULL; | ||||||
|  |  | ||||||
|  |   for (dst = raw_data; actual_length < expected_length && *src != '\0'; ++src) { | ||||||
|  |     char* end; | ||||||
|  |     char val[3]; | ||||||
|  |     if (*src == '\n') continue; | ||||||
|  |     val[0] = *src++; | ||||||
|  |     val[1] = *src; | ||||||
|  |     val[2] = '\0'; | ||||||
|  |     *dst++ = (uint8_t)strtol(val, &end, 16); | ||||||
|  |     if (end != val + 2) break; | ||||||
|  |     ++actual_length; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   if (actual_length != expected_length) { | ||||||
|  |     free(raw_data); | ||||||
|  |     return NULL; | ||||||
|  |   } | ||||||
|  |   return raw_data; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static int ProcessRawProfile(const char* profile, size_t profile_len, | ||||||
|  |                              MetadataPayload* const payload) { | ||||||
|  |   const char* src = profile; | ||||||
|  |   char* end; | ||||||
|  |   int expected_length; | ||||||
|  |  | ||||||
|  |   if (profile == NULL || profile_len == 0) return 0; | ||||||
|  |  | ||||||
|  |   // ImageMagick formats 'raw profiles' as | ||||||
|  |   // '\n<name>\n<length>(%8lu)\n<hex payload>\n'. | ||||||
|  |   if (*src != '\n') { | ||||||
|  |     fprintf(stderr, "Malformed raw profile, expected '\\n' got '\\x%.2X'\n", | ||||||
|  |             *src); | ||||||
|  |     return 0; | ||||||
|  |   } | ||||||
|  |   ++src; | ||||||
|  |   // skip the profile name and extract the length. | ||||||
|  |   while (*src != '\0' && *src++ != '\n') {} | ||||||
|  |   expected_length = (int)strtol(src, &end, 10); | ||||||
|  |   if (*end != '\n') { | ||||||
|  |     fprintf(stderr, "Malformed raw profile, expected '\\n' got '\\x%.2X'\n", | ||||||
|  |             *end); | ||||||
|  |     return 0; | ||||||
|  |   } | ||||||
|  |   ++end; | ||||||
|  |  | ||||||
|  |   // 'end' now points to the profile payload. | ||||||
|  |   payload->bytes = HexStringToBytes(end, expected_length); | ||||||
|  |   if (payload->bytes == NULL) return 0; | ||||||
|  |   payload->size = expected_length; | ||||||
|  |   return 1; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static const struct { | ||||||
|  |   const char* name; | ||||||
|  |   int (*process)(const char* profile, size_t profile_len, | ||||||
|  |                  MetadataPayload* const payload); | ||||||
|  |   size_t storage_offset; | ||||||
|  | } kPNGMetadataMap[] = { | ||||||
|  |   // https://exiftool.org/TagNames/PNG.html#TextualData | ||||||
|  |   // See also: ExifTool on CPAN. | ||||||
|  |   { "Raw profile type exif", ProcessRawProfile, METADATA_OFFSET(exif) }, | ||||||
|  |   { "Raw profile type xmp",  ProcessRawProfile, METADATA_OFFSET(xmp) }, | ||||||
|  |   // Exiftool puts exif data in APP1 chunk, too. | ||||||
|  |   { "Raw profile type APP1", ProcessRawProfile, METADATA_OFFSET(exif) }, | ||||||
|  |   // XMP Specification Part 3, Section 3 #PNG | ||||||
|  |   { "XML:com.adobe.xmp",     MetadataCopy,      METADATA_OFFSET(xmp) }, | ||||||
|  |   { NULL, NULL, 0 }, | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | // Looks for metadata at both the beginning and end of the PNG file, giving | ||||||
|  | // preference to the head. | ||||||
|  | // Returns true on success. The caller must use MetadataFree() on 'metadata' in | ||||||
|  | // all cases. | ||||||
|  | static int ExtractMetadataFromPNG(png_structp png, | ||||||
|  |                                   png_infop const head_info, | ||||||
|  |                                   png_infop const end_info, | ||||||
|  |                                   Metadata* const metadata) { | ||||||
|  |   int p; | ||||||
|  |  | ||||||
|  |   for (p = 0; p < 2; ++p)  { | ||||||
|  |     png_infop const info = (p == 0) ? head_info : end_info; | ||||||
|  |     png_textp text = NULL; | ||||||
|  |     const png_uint_32 num = png_get_text(png, info, &text, NULL); | ||||||
|  |     png_uint_32 i; | ||||||
|  |     // Look for EXIF / XMP metadata. | ||||||
|  |     for (i = 0; i < num; ++i, ++text) { | ||||||
|  |       int j; | ||||||
|  |       for (j = 0; kPNGMetadataMap[j].name != NULL; ++j) { | ||||||
|  |         if (!strcmp(text->key, kPNGMetadataMap[j].name)) { | ||||||
|  |           MetadataPayload* const payload = | ||||||
|  |               (MetadataPayload*)((uint8_t*)metadata + | ||||||
|  |                                  kPNGMetadataMap[j].storage_offset); | ||||||
|  |           png_size_t text_length; | ||||||
|  |           switch (text->compression) { | ||||||
|  | #ifdef PNG_iTXt_SUPPORTED | ||||||
|  |             case PNG_ITXT_COMPRESSION_NONE: | ||||||
|  |             case PNG_ITXT_COMPRESSION_zTXt: | ||||||
|  |               text_length = text->itxt_length; | ||||||
|  |               break; | ||||||
|  | #endif | ||||||
|  |             case PNG_TEXT_COMPRESSION_NONE: | ||||||
|  |             case PNG_TEXT_COMPRESSION_zTXt: | ||||||
|  |             default: | ||||||
|  |               text_length = text->text_length; | ||||||
|  |               break; | ||||||
|  |           } | ||||||
|  |           if (payload->bytes != NULL) { | ||||||
|  |             fprintf(stderr, "Ignoring additional '%s'\n", text->key); | ||||||
|  |           } else if (!kPNGMetadataMap[j].process(text->text, text_length, | ||||||
|  |                                                  payload)) { | ||||||
|  |             fprintf(stderr, "Failed to process: '%s'\n", text->key); | ||||||
|  |             return 0; | ||||||
|  |           } | ||||||
|  |           break; | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |     // Look for an ICC profile. | ||||||
|  |     { | ||||||
|  |       png_charp name; | ||||||
|  |       int comp_type; | ||||||
|  | #if LOCAL_PNG_PREREQ(1,5) | ||||||
|  |       png_bytep profile; | ||||||
|  | #else | ||||||
|  |       png_charp profile; | ||||||
|  | #endif | ||||||
|  |       png_uint_32 len; | ||||||
|  |  | ||||||
|  |       if (png_get_iCCP(png, info, | ||||||
|  |                        &name, &comp_type, &profile, &len) == PNG_INFO_iCCP) { | ||||||
|  |         if (!MetadataCopy((const char*)profile, len, &metadata->iccp)) return 0; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   return 1; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | typedef struct { | ||||||
|  |   const uint8_t* data; | ||||||
|  |   size_t data_size; | ||||||
|  |   png_size_t offset; | ||||||
|  | } PNGReadContext; | ||||||
|  |  | ||||||
|  | static void ReadFunc(png_structp png_ptr, png_bytep data, png_size_t length) { | ||||||
|  |   PNGReadContext* const ctx = (PNGReadContext*)png_get_io_ptr(png_ptr); | ||||||
|  |   if (ctx->data_size - ctx->offset < length) { | ||||||
|  |     png_error(png_ptr, "ReadFunc: invalid read length (overflow)!"); | ||||||
|  |   } | ||||||
|  |   memcpy(data, ctx->data + ctx->offset, length); | ||||||
|  |   ctx->offset += length; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int ReadPNG(const uint8_t* const data, size_t data_size, | ||||||
|  |             struct WebPPicture* const pic, | ||||||
|  |             int keep_alpha, struct Metadata* const metadata) { | ||||||
|  |   volatile png_structp png = NULL; | ||||||
|  |   volatile png_infop info = NULL; | ||||||
|  |   volatile png_infop end_info = NULL; | ||||||
|  |   PNGReadContext context = { NULL, 0, 0 }; | ||||||
|  |   int color_type, bit_depth, interlaced; | ||||||
|  |   int num_channels; | ||||||
|  |   int num_passes; | ||||||
|  |   int p; | ||||||
|  |   volatile int ok = 0; | ||||||
|  |   png_uint_32 width, height, y; | ||||||
|  |   int64_t stride; | ||||||
|  |   uint8_t* volatile rgb = NULL; | ||||||
|  |  | ||||||
|  |   if (data == NULL || data_size == 0 || pic == NULL) return 0; | ||||||
|  |  | ||||||
|  |   context.data = data; | ||||||
|  |   context.data_size = data_size; | ||||||
|  |  | ||||||
|  |   png = png_create_read_struct_2(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL, | ||||||
|  |                                  NULL, MallocFunc, FreeFunc); | ||||||
|  |   if (png == NULL) goto End; | ||||||
|  |  | ||||||
|  |   png_set_error_fn(png, 0, error_function, NULL); | ||||||
|  |   if (setjmp(png_jmpbuf(png))) { | ||||||
|  |  Error: | ||||||
|  |     MetadataFree(metadata); | ||||||
|  |     goto End; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  | #if LOCAL_PNG_PREREQ(1,5) || \ | ||||||
|  |     (LOCAL_PNG_PREREQ(1,4) && PNG_LIBPNG_VER_RELEASE >= 1) | ||||||
|  |   // If it looks like the bitstream is going to need more memory than libpng's | ||||||
|  |   // internal limit (default: 8M), try to (reasonably) raise it. | ||||||
|  |   if (data_size > png_get_chunk_malloc_max(png) && data_size < (1u << 24)) { | ||||||
|  |     png_set_chunk_malloc_max(png, data_size); | ||||||
|  |   } | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  |   info = png_create_info_struct(png); | ||||||
|  |   if (info == NULL) goto Error; | ||||||
|  |   end_info = png_create_info_struct(png); | ||||||
|  |   if (end_info == NULL) goto Error; | ||||||
|  |  | ||||||
|  |   png_set_read_fn(png, &context, ReadFunc); | ||||||
|  |   png_read_info(png, info); | ||||||
|  |   if (!png_get_IHDR(png, info, | ||||||
|  |                     &width, &height, &bit_depth, &color_type, &interlaced, | ||||||
|  |                     NULL, NULL)) goto Error; | ||||||
|  |  | ||||||
|  |   png_set_strip_16(png); | ||||||
|  |   png_set_packing(png); | ||||||
|  |   if (color_type == PNG_COLOR_TYPE_PALETTE) { | ||||||
|  |     png_set_palette_to_rgb(png); | ||||||
|  |   } | ||||||
|  |   if (color_type == PNG_COLOR_TYPE_GRAY || | ||||||
|  |       color_type == PNG_COLOR_TYPE_GRAY_ALPHA) { | ||||||
|  |     if (bit_depth < 8) { | ||||||
|  |       png_set_expand_gray_1_2_4_to_8(png); | ||||||
|  |     } | ||||||
|  |     png_set_gray_to_rgb(png); | ||||||
|  |   } | ||||||
|  |   if (png_get_valid(png, info, PNG_INFO_tRNS)) { | ||||||
|  |     png_set_tRNS_to_alpha(png); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   // Apply gamma correction if needed. | ||||||
|  |   { | ||||||
|  |     double image_gamma = 1 / 2.2, screen_gamma = 2.2; | ||||||
|  |     int srgb_intent; | ||||||
|  |     if (png_get_sRGB(png, info, &srgb_intent) || | ||||||
|  |         png_get_gAMA(png, info, &image_gamma)) { | ||||||
|  |       png_set_gamma(png, screen_gamma, image_gamma); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   if (!keep_alpha) { | ||||||
|  |     png_set_strip_alpha(png); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   num_passes = png_set_interlace_handling(png); | ||||||
|  |   png_read_update_info(png, info); | ||||||
|  |  | ||||||
|  |   num_channels = png_get_channels(png, info); | ||||||
|  |   if (num_channels != 3 && num_channels != 4) { | ||||||
|  |     goto Error; | ||||||
|  |   } | ||||||
|  |   stride = (int64_t)num_channels * width * sizeof(*rgb); | ||||||
|  |   if (stride != (int)stride || | ||||||
|  |       !ImgIoUtilCheckSizeArgumentsOverflow(stride, height)) { | ||||||
|  |     goto Error; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   rgb = (uint8_t*)malloc((size_t)stride * height); | ||||||
|  |   if (rgb == NULL) goto Error; | ||||||
|  |   for (p = 0; p < num_passes; ++p) { | ||||||
|  |     png_bytep row = rgb; | ||||||
|  |     for (y = 0; y < height; ++y) { | ||||||
|  |       png_read_rows(png, &row, NULL, 1); | ||||||
|  |       row += stride; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   png_read_end(png, end_info); | ||||||
|  |  | ||||||
|  |   if (metadata != NULL && | ||||||
|  |       !ExtractMetadataFromPNG(png, info, end_info, metadata)) { | ||||||
|  |     fprintf(stderr, "Error extracting PNG metadata!\n"); | ||||||
|  |     goto Error; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   pic->width = (int)width; | ||||||
|  |   pic->height = (int)height; | ||||||
|  |   ok = (num_channels == 4) ? WebPPictureImportRGBA(pic, rgb, (int)stride) | ||||||
|  |                            : WebPPictureImportRGB(pic, rgb, (int)stride); | ||||||
|  |  | ||||||
|  |   if (!ok) { | ||||||
|  |     goto Error; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |  End: | ||||||
|  |   if (png != NULL) { | ||||||
|  |     png_destroy_read_struct((png_structpp)&png, | ||||||
|  |                             (png_infopp)&info, (png_infopp)&end_info); | ||||||
|  |   } | ||||||
|  |   free(rgb); | ||||||
|  |   return ok; | ||||||
|  | } | ||||||
|  | #else  // !WEBP_HAVE_PNG | ||||||
|  | int ReadPNG(const uint8_t* const data, size_t data_size, | ||||||
|  |             struct WebPPicture* const pic, | ||||||
|  |             int keep_alpha, struct Metadata* const metadata) { | ||||||
|  |   (void)data; | ||||||
|  |   (void)data_size; | ||||||
|  |   (void)pic; | ||||||
|  |   (void)keep_alpha; | ||||||
|  |   (void)metadata; | ||||||
|  |   fprintf(stderr, "PNG support not compiled. Please install the libpng " | ||||||
|  |           "development package before building.\n"); | ||||||
|  |   return 0; | ||||||
|  | } | ||||||
|  | #endif  // WEBP_HAVE_PNG | ||||||
|  |  | ||||||
|  | // ----------------------------------------------------------------------------- | ||||||
							
								
								
									
										37
									
								
								external/libwebp/libwebp/imageio/pngdec.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								external/libwebp/libwebp/imageio/pngdec.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,37 @@ | |||||||
|  | // Copyright 2012 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. | ||||||
|  | // ----------------------------------------------------------------------------- | ||||||
|  | // | ||||||
|  | // PNG decode. | ||||||
|  |  | ||||||
|  | #ifndef WEBP_IMAGEIO_PNGDEC_H_ | ||||||
|  | #define WEBP_IMAGEIO_PNGDEC_H_ | ||||||
|  |  | ||||||
|  | #include "webp/types.h" | ||||||
|  |  | ||||||
|  | #ifdef __cplusplus | ||||||
|  | extern "C" { | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | struct Metadata; | ||||||
|  | struct WebPPicture; | ||||||
|  |  | ||||||
|  | // Reads a PNG from 'data', returning the decoded output in 'pic'. | ||||||
|  | // Output is RGBA or YUVA, depending on pic->use_argb value. | ||||||
|  | // If 'keep_alpha' is true and the PNG has an alpha channel, the output is RGBA | ||||||
|  | // or YUVA. Otherwise, alpha channel is dropped and output is RGB or YUV. | ||||||
|  | // Returns true on success. | ||||||
|  | int ReadPNG(const uint8_t* const data, size_t data_size, | ||||||
|  |             struct WebPPicture* const pic, | ||||||
|  |             int keep_alpha, struct Metadata* const metadata); | ||||||
|  |  | ||||||
|  | #ifdef __cplusplus | ||||||
|  | }    // extern "C" | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | #endif  // WEBP_IMAGEIO_PNGDEC_H_ | ||||||
							
								
								
									
										301
									
								
								external/libwebp/libwebp/imageio/pnmdec.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										301
									
								
								external/libwebp/libwebp/imageio/pnmdec.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,301 @@ | |||||||
|  | // Copyright 2017 Google Inc. All Rights Reserved. | ||||||
|  | // | ||||||
|  | // Use of this source code is governed by a BSD-style license | ||||||
|  | // that can be found in the COPYING file in the root of the source | ||||||
|  | // tree. An additional intellectual property rights grant can be found | ||||||
|  | // in the file PATENTS. All contributing project authors may | ||||||
|  | // be found in the AUTHORS file in the root of the source tree. | ||||||
|  | // ----------------------------------------------------------------------------- | ||||||
|  | // | ||||||
|  | // (limited) PNM decoder | ||||||
|  |  | ||||||
|  | #include "./pnmdec.h" | ||||||
|  |  | ||||||
|  | #include <assert.h> | ||||||
|  | #include <ctype.h> | ||||||
|  | #include <stdio.h> | ||||||
|  | #include <stdlib.h> | ||||||
|  | #include <string.h> | ||||||
|  |  | ||||||
|  | #include "webp/encode.h" | ||||||
|  | #include "./imageio_util.h" | ||||||
|  |  | ||||||
|  | #if defined(_MSC_VER) && _MSC_VER < 1900 | ||||||
|  | #define snprintf _snprintf | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | typedef enum { | ||||||
|  |   WIDTH_FLAG      = 1 << 0, | ||||||
|  |   HEIGHT_FLAG     = 1 << 1, | ||||||
|  |   DEPTH_FLAG      = 1 << 2, | ||||||
|  |   MAXVAL_FLAG     = 1 << 3, | ||||||
|  |   TUPLE_FLAG      = 1 << 4, | ||||||
|  |   ALL_NEEDED_FLAGS = WIDTH_FLAG | HEIGHT_FLAG | DEPTH_FLAG | MAXVAL_FLAG | ||||||
|  | } PNMFlags; | ||||||
|  |  | ||||||
|  | typedef struct { | ||||||
|  |   const uint8_t* data; | ||||||
|  |   size_t data_size; | ||||||
|  |   int width, height; | ||||||
|  |   int bytes_per_px; | ||||||
|  |   int depth;          // 1 (grayscale), 2 (grayscale + alpha), 3 (rgb), 4 (rgba) | ||||||
|  |   int max_value; | ||||||
|  |   int type;           // 5, 6 or 7 | ||||||
|  |   int seen_flags; | ||||||
|  | } PNMInfo; | ||||||
|  |  | ||||||
|  | // ----------------------------------------------------------------------------- | ||||||
|  | // PNM decoding | ||||||
|  |  | ||||||
|  | #define MAX_LINE_SIZE 1024 | ||||||
|  | static const size_t kMinPNMHeaderSize = 3; | ||||||
|  |  | ||||||
|  | static size_t ReadLine(const uint8_t* const data, size_t off, size_t data_size, | ||||||
|  |                        char out[MAX_LINE_SIZE + 1], size_t* const out_size) { | ||||||
|  |   size_t i = 0; | ||||||
|  |   *out_size = 0; | ||||||
|  |  redo: | ||||||
|  |   for (i = 0; i < MAX_LINE_SIZE && off < data_size; ++i) { | ||||||
|  |     out[i] = data[off++]; | ||||||
|  |     if (out[i] == '\n') break; | ||||||
|  |   } | ||||||
|  |   if (off < data_size) { | ||||||
|  |     if (i == 0) goto redo;         // empty line | ||||||
|  |     if (out[0] == '#') goto redo;  // skip comment | ||||||
|  |   } | ||||||
|  |   out[i] = 0;   // safety sentinel | ||||||
|  |   *out_size = i; | ||||||
|  |   return off; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static size_t FlagError(const char flag[]) { | ||||||
|  |   fprintf(stderr, "PAM header error: flags '%s' already seen.\n", flag); | ||||||
|  |   return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // inspired from http://netpbm.sourceforge.net/doc/pam.html | ||||||
|  | static size_t ReadPAMFields(PNMInfo* const info, size_t off) { | ||||||
|  |   char out[MAX_LINE_SIZE + 1]; | ||||||
|  |   size_t out_size; | ||||||
|  |   int tmp; | ||||||
|  |   int expected_depth = -1; | ||||||
|  |   assert(info != NULL); | ||||||
|  |   while (1) { | ||||||
|  |     off = ReadLine(info->data, off, info->data_size, out, &out_size); | ||||||
|  |     if (off == 0) return 0; | ||||||
|  |     if (sscanf(out, "WIDTH %d", &tmp) == 1) { | ||||||
|  |       if (info->seen_flags & WIDTH_FLAG) return FlagError("WIDTH"); | ||||||
|  |       info->seen_flags |= WIDTH_FLAG; | ||||||
|  |       info->width = tmp; | ||||||
|  |     } else if (sscanf(out, "HEIGHT %d", &tmp) == 1) { | ||||||
|  |       if (info->seen_flags & HEIGHT_FLAG) return FlagError("HEIGHT"); | ||||||
|  |       info->seen_flags |= HEIGHT_FLAG; | ||||||
|  |       info->height = tmp; | ||||||
|  |     } else if (sscanf(out, "DEPTH %d", &tmp) == 1) { | ||||||
|  |       if (info->seen_flags & DEPTH_FLAG) return FlagError("DEPTH"); | ||||||
|  |       info->seen_flags |= DEPTH_FLAG; | ||||||
|  |       info->depth = tmp; | ||||||
|  |     } else if (sscanf(out, "MAXVAL %d", &tmp) == 1) { | ||||||
|  |       if (info->seen_flags & MAXVAL_FLAG) return FlagError("MAXVAL"); | ||||||
|  |       info->seen_flags |= MAXVAL_FLAG; | ||||||
|  |       info->max_value = tmp; | ||||||
|  |     } else if (!strcmp(out, "TUPLTYPE RGB_ALPHA")) { | ||||||
|  |       expected_depth = 4; | ||||||
|  |       info->seen_flags |= TUPLE_FLAG; | ||||||
|  |     } else if (!strcmp(out, "TUPLTYPE RGB")) { | ||||||
|  |       expected_depth = 3; | ||||||
|  |       info->seen_flags |= TUPLE_FLAG; | ||||||
|  |     } else if (!strcmp(out, "TUPLTYPE GRAYSCALE_ALPHA")) { | ||||||
|  |       expected_depth = 2; | ||||||
|  |       info->seen_flags |= TUPLE_FLAG; | ||||||
|  |     } else if (!strcmp(out, "TUPLTYPE GRAYSCALE")) { | ||||||
|  |       expected_depth = 1; | ||||||
|  |       info->seen_flags |= TUPLE_FLAG; | ||||||
|  |     } else if (!strcmp(out, "ENDHDR")) { | ||||||
|  |       break; | ||||||
|  |     } else { | ||||||
|  |       static const char kEllipsis[] = " ..."; | ||||||
|  |       const size_t kLen = strlen(kEllipsis) + 1;  // +1 = trailing \0 | ||||||
|  |       int i; | ||||||
|  |       if (out_size > 20) snprintf(out + 20 - kLen, kLen, kEllipsis); | ||||||
|  |       for (i = 0; i < (int)strlen(out); ++i) { | ||||||
|  |         // isprint() might trigger a "char-subscripts" warning if given a char. | ||||||
|  |         if (!isprint((int)out[i])) out[i] = ' '; | ||||||
|  |       } | ||||||
|  |       fprintf(stderr, "PAM header error: unrecognized entry [%s]\n", out); | ||||||
|  |       return 0; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   if (!(info->seen_flags & ALL_NEEDED_FLAGS)) { | ||||||
|  |     fprintf(stderr, "PAM header error: missing tags%s%s%s%s\n", | ||||||
|  |             (info->seen_flags & WIDTH_FLAG) ? "" : " WIDTH", | ||||||
|  |             (info->seen_flags & HEIGHT_FLAG) ? "" : " HEIGHT", | ||||||
|  |             (info->seen_flags & DEPTH_FLAG) ? "" : " DEPTH", | ||||||
|  |             (info->seen_flags & MAXVAL_FLAG) ? "" : " MAXVAL"); | ||||||
|  |     return 0; | ||||||
|  |   } | ||||||
|  |   if (expected_depth != -1 && info->depth != expected_depth) { | ||||||
|  |     fprintf(stderr, "PAM header error: expected DEPTH %d but got DEPTH %d\n", | ||||||
|  |             expected_depth, info->depth); | ||||||
|  |     return 0; | ||||||
|  |   } | ||||||
|  |   return off; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static size_t ReadHeader(PNMInfo* const info) { | ||||||
|  |   size_t off = 0; | ||||||
|  |   char out[MAX_LINE_SIZE + 1]; | ||||||
|  |   size_t out_size; | ||||||
|  |   if (info == NULL) return 0; | ||||||
|  |   if (info->data == NULL || info->data_size < kMinPNMHeaderSize) return 0; | ||||||
|  |  | ||||||
|  |   info->width = info->height = 0; | ||||||
|  |   info->type = -1; | ||||||
|  |   info->seen_flags = 0; | ||||||
|  |   info->bytes_per_px = 0; | ||||||
|  |   info->depth = 0; | ||||||
|  |   info->max_value = 0; | ||||||
|  |  | ||||||
|  |   off = ReadLine(info->data, off, info->data_size, out, &out_size); | ||||||
|  |   if (off == 0 || sscanf(out, "P%d", &info->type) != 1) return 0; | ||||||
|  |   if (info->type == 7) { | ||||||
|  |     off = ReadPAMFields(info, off); | ||||||
|  |   } else { | ||||||
|  |     off = ReadLine(info->data, off, info->data_size, out, &out_size); | ||||||
|  |     if (off == 0 || sscanf(out, "%d %d", &info->width, &info->height) != 2) { | ||||||
|  |       return 0; | ||||||
|  |     } | ||||||
|  |     off = ReadLine(info->data, off, info->data_size, out, &out_size); | ||||||
|  |     if (off == 0 || sscanf(out, "%d", &info->max_value) != 1) return 0; | ||||||
|  |  | ||||||
|  |     // finish initializing missing fields | ||||||
|  |     info->depth = (info->type == 5) ? 1 : 3; | ||||||
|  |   } | ||||||
|  |   // perform some basic numerical validation | ||||||
|  |   if (info->width <= 0 || info->height <= 0 || | ||||||
|  |       info->type <= 0 || info->type >= 9 || | ||||||
|  |       info->depth <= 0 || info->depth > 4 || | ||||||
|  |       info->max_value <= 0 || info->max_value >= 65536) { | ||||||
|  |     return 0; | ||||||
|  |   } | ||||||
|  |   info->bytes_per_px = info->depth * (info->max_value > 255 ? 2 : 1); | ||||||
|  |   return off; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int ReadPNM(const uint8_t* const data, size_t data_size, | ||||||
|  |             WebPPicture* const pic, int keep_alpha, | ||||||
|  |             struct Metadata* const metadata) { | ||||||
|  |   int ok = 0; | ||||||
|  |   int i, j; | ||||||
|  |   uint64_t stride, pixel_bytes, sample_size, depth; | ||||||
|  |   uint8_t* rgb = NULL, *tmp_rgb; | ||||||
|  |   size_t offset; | ||||||
|  |   PNMInfo info; | ||||||
|  |  | ||||||
|  |   info.data = data; | ||||||
|  |   info.data_size = data_size; | ||||||
|  |   offset = ReadHeader(&info); | ||||||
|  |   if (offset == 0) { | ||||||
|  |     fprintf(stderr, "Error parsing PNM header.\n"); | ||||||
|  |     goto End; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   if (info.type < 5 || info.type > 7) { | ||||||
|  |     fprintf(stderr, "Unsupported P%d PNM format.\n", info.type); | ||||||
|  |     goto End; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   // Some basic validations. | ||||||
|  |   if (pic == NULL) goto End; | ||||||
|  |   if (info.width > WEBP_MAX_DIMENSION || info.height > WEBP_MAX_DIMENSION) { | ||||||
|  |     fprintf(stderr, "Invalid %dx%d dimension for PNM\n", | ||||||
|  |                     info.width, info.height); | ||||||
|  |     goto End; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   pixel_bytes = (uint64_t)info.width * info.height * info.bytes_per_px; | ||||||
|  |   if (data_size < offset + pixel_bytes) { | ||||||
|  |     fprintf(stderr, "Truncated PNM file (P%d).\n", info.type); | ||||||
|  |     goto End; | ||||||
|  |   } | ||||||
|  |   sample_size = (info.max_value > 255) ? 2 : 1; | ||||||
|  |   // final depth | ||||||
|  |   depth = (info.depth == 1 || info.depth == 3 || !keep_alpha) ? 3 : 4; | ||||||
|  |   stride = depth * info.width; | ||||||
|  |   if (stride != (size_t)stride || | ||||||
|  |       !ImgIoUtilCheckSizeArgumentsOverflow(stride, info.height)) { | ||||||
|  |     goto End; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   rgb = (uint8_t*)malloc((size_t)stride * info.height); | ||||||
|  |   if (rgb == NULL) goto End; | ||||||
|  |  | ||||||
|  |   // Convert input. | ||||||
|  |   // We only optimize for the sample_size=1, max_value=255, depth=1 case. | ||||||
|  |   tmp_rgb = rgb; | ||||||
|  |   for (j = 0; j < info.height; ++j) { | ||||||
|  |     const uint8_t* in = data + offset; | ||||||
|  |     offset += info.bytes_per_px * info.width; | ||||||
|  |     assert(offset <= data_size); | ||||||
|  |     if (info.max_value == 255 && info.depth >= 3) { | ||||||
|  |       // RGB or RGBA | ||||||
|  |       if (info.depth == 3 || keep_alpha) { | ||||||
|  |         memcpy(tmp_rgb, in, info.depth * info.width * sizeof(*in)); | ||||||
|  |       } else { | ||||||
|  |         assert(info.depth == 4 && !keep_alpha); | ||||||
|  |         for (i = 0; i < info.width; ++i) { | ||||||
|  |           tmp_rgb[3 * i + 0] = in[4 * i + 0]; | ||||||
|  |           tmp_rgb[3 * i + 1] = in[4 * i + 1]; | ||||||
|  |           tmp_rgb[3 * i + 2] = in[4 * i + 2]; | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     } else { | ||||||
|  |       // Unoptimized case, we need to handle non-trivial operations: | ||||||
|  |       //   * convert 16b to 8b (if max_value > 255) | ||||||
|  |       //   * rescale to [0..255] range (if max_value != 255) | ||||||
|  |       //   * drop the alpha channel (if keep_alpha is false) | ||||||
|  |       const uint32_t round = info.max_value / 2; | ||||||
|  |       int k = 0; | ||||||
|  |       for (i = 0; i < info.width * info.depth; ++i) { | ||||||
|  |         uint32_t v = (sample_size == 2) ? 256u * in[2 * i + 0] + in[2 * i + 1] | ||||||
|  |                    : in[i]; | ||||||
|  |         if (info.max_value != 255) v = (v * 255u + round) / info.max_value; | ||||||
|  |         if (v > 255u) v = 255u; | ||||||
|  |         if (info.depth > 2) { | ||||||
|  |           if (!keep_alpha && info.depth == 4 && (i % 4) == 3) { | ||||||
|  |             // skip alpha | ||||||
|  |           } else { | ||||||
|  |             tmp_rgb[k] = v; | ||||||
|  |             k += 1; | ||||||
|  |           } | ||||||
|  |         } else if (info.depth == 1 || (i % 2) == 0) { | ||||||
|  |           tmp_rgb[k + 0] = tmp_rgb[k + 1] = tmp_rgb[k + 2] = v; | ||||||
|  |           k += 3; | ||||||
|  |         } else if (keep_alpha && info.depth == 2) { | ||||||
|  |           tmp_rgb[k] = v; | ||||||
|  |           k += 1; | ||||||
|  |         } else { | ||||||
|  |           // skip alpha | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |     tmp_rgb += stride; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   // WebP conversion. | ||||||
|  |   pic->width = info.width; | ||||||
|  |   pic->height = info.height; | ||||||
|  |   ok = (depth == 4) ? WebPPictureImportRGBA(pic, rgb, (int)stride) | ||||||
|  |                     : WebPPictureImportRGB(pic, rgb, (int)stride); | ||||||
|  |   if (!ok) goto End; | ||||||
|  |  | ||||||
|  |   ok = 1; | ||||||
|  |  End: | ||||||
|  |   free((void*)rgb); | ||||||
|  |  | ||||||
|  |   (void)metadata; | ||||||
|  |   (void)keep_alpha; | ||||||
|  |   return ok; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // ----------------------------------------------------------------------------- | ||||||
							
								
								
									
										37
									
								
								external/libwebp/libwebp/imageio/pnmdec.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								external/libwebp/libwebp/imageio/pnmdec.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,37 @@ | |||||||
|  | // Copyright 2017 Google Inc. All Rights Reserved. | ||||||
|  | // | ||||||
|  | // Use of this source code is governed by a BSD-style license | ||||||
|  | // that can be found in the COPYING file in the root of the source | ||||||
|  | // tree. An additional intellectual property rights grant can be found | ||||||
|  | // in the file PATENTS. All contributing project authors may | ||||||
|  | // be found in the AUTHORS file in the root of the source tree. | ||||||
|  | // ----------------------------------------------------------------------------- | ||||||
|  | // | ||||||
|  | // partial PNM format decoder (ppm/pgm) | ||||||
|  |  | ||||||
|  | #ifndef WEBP_IMAGEIO_PNMDEC_H_ | ||||||
|  | #define WEBP_IMAGEIO_PNMDEC_H_ | ||||||
|  |  | ||||||
|  | #include "webp/types.h" | ||||||
|  |  | ||||||
|  | #ifdef __cplusplus | ||||||
|  | extern "C" { | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | struct Metadata; | ||||||
|  | struct WebPPicture; | ||||||
|  |  | ||||||
|  | // Reads a PNM file from 'data', returning the decoded output in 'pic'. | ||||||
|  | // The output is RGB or YUV depending on pic->use_argb value. | ||||||
|  | // Returns true on success. | ||||||
|  | // 'metadata' has no effect, but is kept for coherence with other signatures | ||||||
|  | // for image readers. | ||||||
|  | int ReadPNM(const uint8_t* const data, size_t data_size, | ||||||
|  |             struct WebPPicture* const pic, int keep_alpha, | ||||||
|  |             struct Metadata* const metadata); | ||||||
|  |  | ||||||
|  | #ifdef __cplusplus | ||||||
|  | }    // extern "C" | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | #endif  // WEBP_IMAGEIO_PNMDEC_H_ | ||||||
							
								
								
									
										293
									
								
								external/libwebp/libwebp/imageio/tiffdec.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										293
									
								
								external/libwebp/libwebp/imageio/tiffdec.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,293 @@ | |||||||
|  | // Copyright 2012 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. | ||||||
|  | // ----------------------------------------------------------------------------- | ||||||
|  | // | ||||||
|  | // TIFF decode. | ||||||
|  |  | ||||||
|  | #include "./tiffdec.h" | ||||||
|  |  | ||||||
|  | #ifdef HAVE_CONFIG_H | ||||||
|  | #include "webp/config.h" | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | #include <limits.h> | ||||||
|  | #include <stdio.h> | ||||||
|  | #include <string.h> | ||||||
|  |  | ||||||
|  | #ifdef WEBP_HAVE_TIFF | ||||||
|  | #include <tiffio.h> | ||||||
|  |  | ||||||
|  | #include "webp/encode.h" | ||||||
|  | #include "./imageio_util.h" | ||||||
|  | #include "./metadata.h" | ||||||
|  |  | ||||||
|  | static const struct { | ||||||
|  |   ttag_t tag; | ||||||
|  |   size_t storage_offset; | ||||||
|  | } kTIFFMetadataMap[] = { | ||||||
|  |   { TIFFTAG_ICCPROFILE, METADATA_OFFSET(iccp) }, | ||||||
|  |   { TIFFTAG_XMLPACKET,  METADATA_OFFSET(xmp) }, | ||||||
|  |   { 0, 0 }, | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | // Returns true on success. The caller must use MetadataFree() on 'metadata' in | ||||||
|  | // all cases. | ||||||
|  | static int ExtractMetadataFromTIFF(TIFF* const tif, Metadata* const metadata) { | ||||||
|  |   int i; | ||||||
|  |   toff_t exif_ifd_offset; | ||||||
|  |  | ||||||
|  |   for (i = 0; kTIFFMetadataMap[i].tag != 0; ++i) { | ||||||
|  |     MetadataPayload* const payload = | ||||||
|  |         (MetadataPayload*)((uint8_t*)metadata + | ||||||
|  |                            kTIFFMetadataMap[i].storage_offset); | ||||||
|  |     void* tag_data; | ||||||
|  |     uint32_t tag_data_len; | ||||||
|  |  | ||||||
|  |     if (TIFFGetField(tif, kTIFFMetadataMap[i].tag, &tag_data_len, &tag_data) && | ||||||
|  |         !MetadataCopy((const char*)tag_data, tag_data_len, payload)) { | ||||||
|  |       return 0; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   // TODO(jzern): To extract the raw EXIF directory some parsing of it would be | ||||||
|  |   // necessary to determine the overall size. In addition, value offsets in | ||||||
|  |   // individual directory entries may need to be updated as, depending on the | ||||||
|  |   // type, they are file based. | ||||||
|  |   // Exif 2.2 Section 4.6.2 Tag Structure | ||||||
|  |   // TIFF Revision 6.0 Part 1 Section 2 TIFF Structure #Image File Directory | ||||||
|  |   if (TIFFGetField(tif, TIFFTAG_EXIFIFD, &exif_ifd_offset)) { | ||||||
|  |     fprintf(stderr, "Warning: EXIF extraction from TIFF is unsupported.\n"); | ||||||
|  |   } | ||||||
|  |   return 1; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Ad-hoc structure to supply read-from-memory functionalities. | ||||||
|  | typedef struct { | ||||||
|  |   const uint8_t* data; | ||||||
|  |   toff_t size; | ||||||
|  |   toff_t pos; | ||||||
|  | } MyData; | ||||||
|  |  | ||||||
|  | static int MyClose(thandle_t opaque) { | ||||||
|  |   (void)opaque; | ||||||
|  |   return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static toff_t MySize(thandle_t opaque) { | ||||||
|  |   const MyData* const my_data = (MyData*)opaque; | ||||||
|  |   return my_data->size; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static toff_t MySeek(thandle_t opaque, toff_t offset, int whence) { | ||||||
|  |   MyData* const my_data = (MyData*)opaque; | ||||||
|  |   offset += (whence == SEEK_CUR) ? my_data->pos | ||||||
|  |           : (whence == SEEK_SET) ? 0 | ||||||
|  |           : my_data->size; | ||||||
|  |   if (offset > my_data->size) return (toff_t)-1; | ||||||
|  |   my_data->pos = offset; | ||||||
|  |   return offset; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static int MyMapFile(thandle_t opaque, void** base, toff_t* size) { | ||||||
|  |   (void)opaque; | ||||||
|  |   (void)base; | ||||||
|  |   (void)size; | ||||||
|  |   return 0; | ||||||
|  | } | ||||||
|  | static void MyUnmapFile(thandle_t opaque, void* base, toff_t size) { | ||||||
|  |   (void)opaque; | ||||||
|  |   (void)base; | ||||||
|  |   (void)size; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static tsize_t MyRead(thandle_t opaque, void* dst, tsize_t size) { | ||||||
|  |   MyData* const my_data = (MyData*)opaque; | ||||||
|  |   if (my_data->pos + size > my_data->size) { | ||||||
|  |     size = (tsize_t)(my_data->size - my_data->pos); | ||||||
|  |   } | ||||||
|  |   if (size > 0) { | ||||||
|  |     memcpy(dst, my_data->data + my_data->pos, size); | ||||||
|  |     my_data->pos += size; | ||||||
|  |   } | ||||||
|  |   return size; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Unmultiply Argb data. Taken from dsp/alpha_processing | ||||||
|  | // (we don't want to force a dependency to a libdspdec library). | ||||||
|  | #define MFIX 24    // 24bit fixed-point arithmetic | ||||||
|  | #define HALF ((1u << MFIX) >> 1) | ||||||
|  |  | ||||||
|  | static uint32_t Unmult(uint8_t x, uint32_t mult) { | ||||||
|  |   const uint32_t v = (x * mult + HALF) >> MFIX; | ||||||
|  |   return (v > 255u) ? 255u : v; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static WEBP_INLINE uint32_t GetScale(uint32_t a) { | ||||||
|  |   return (255u << MFIX) / a; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #undef MFIX | ||||||
|  | #undef HALF | ||||||
|  |  | ||||||
|  | static void MultARGBRow(uint8_t* ptr, int width) { | ||||||
|  |   int x; | ||||||
|  |   for (x = 0; x < width; ++x, ptr += 4) { | ||||||
|  |     const uint32_t alpha = ptr[3]; | ||||||
|  |     if (alpha < 255) { | ||||||
|  |       if (alpha == 0) {   // alpha == 0 | ||||||
|  |         ptr[0] = ptr[1] = ptr[2] = 0; | ||||||
|  |       } else { | ||||||
|  |         const uint32_t scale = GetScale(alpha); | ||||||
|  |         ptr[0] = Unmult(ptr[0], scale); | ||||||
|  |         ptr[1] = Unmult(ptr[1], scale); | ||||||
|  |         ptr[2] = Unmult(ptr[2], scale); | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int ReadTIFF(const uint8_t* const data, size_t data_size, | ||||||
|  |              WebPPicture* const pic, int keep_alpha, | ||||||
|  |              Metadata* const metadata) { | ||||||
|  |   MyData my_data = { data, (toff_t)data_size, 0 }; | ||||||
|  |   TIFF* tif; | ||||||
|  |   uint32_t image_width, image_height, tile_width, tile_height; | ||||||
|  |   uint64_t stride; | ||||||
|  |   uint16_t samples_per_px = 0; | ||||||
|  |   uint16_t extra_samples = 0; | ||||||
|  |   uint16_t* extra_samples_ptr = NULL; | ||||||
|  |   uint32_t* raster; | ||||||
|  |   int64_t alloc_size; | ||||||
|  |   int ok = 0; | ||||||
|  |   tdir_t dircount; | ||||||
|  |  | ||||||
|  |   if (data == NULL || data_size == 0 || data_size > INT_MAX || pic == NULL) { | ||||||
|  |     return 0; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   tif = TIFFClientOpen("Memory", "r", &my_data, | ||||||
|  |                        MyRead, MyRead, MySeek, MyClose, | ||||||
|  |                        MySize, MyMapFile, MyUnmapFile); | ||||||
|  |   if (tif == NULL) { | ||||||
|  |     fprintf(stderr, "Error! Cannot parse TIFF file\n"); | ||||||
|  |     return 0; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   dircount = TIFFNumberOfDirectories(tif); | ||||||
|  |   if (dircount > 1) { | ||||||
|  |     fprintf(stderr, "Warning: multi-directory TIFF files are not supported.\n" | ||||||
|  |                     "Only the first will be used, %d will be ignored.\n", | ||||||
|  |                     dircount - 1); | ||||||
|  |   } | ||||||
|  |   if (!TIFFGetFieldDefaulted(tif, TIFFTAG_SAMPLESPERPIXEL, &samples_per_px)) { | ||||||
|  |     fprintf(stderr, "Error! Cannot retrieve TIFF samples-per-pixel info.\n"); | ||||||
|  |     goto End; | ||||||
|  |   } | ||||||
|  |   if (!(samples_per_px == 1 || samples_per_px == 3 || samples_per_px == 4)) { | ||||||
|  |     goto End;  // not supported | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   if (!(TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &image_width) && | ||||||
|  |         TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &image_height))) { | ||||||
|  |     fprintf(stderr, "Error! Cannot retrieve TIFF image dimensions.\n"); | ||||||
|  |     goto End; | ||||||
|  |   } | ||||||
|  |   stride = (uint64_t)image_width * 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; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   // According to spec, a tile can be bigger than the image. However it should | ||||||
|  |   // be a multiple of 16 and not way too large, so check that it's not more | ||||||
|  |   // than twice the image size, for dimensions above some arbitrary minimum | ||||||
|  |   // 32. We also check that they respect WebP's dimension and memory limit. | ||||||
|  |   // Note that a tile can be 6byte/px in some cases. Here we assume | ||||||
|  |   // 4byte/px with sizeof(*raster), to be conservative. | ||||||
|  |   if (TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tile_width) && | ||||||
|  |       TIFFGetField(tif, TIFFTAG_TILELENGTH, &tile_height)) { | ||||||
|  |     if ((tile_width > 32 && tile_width / 2 > image_width) || | ||||||
|  |         (tile_height > 32 && tile_height / 2 > image_height) || | ||||||
|  |         !ImgIoUtilCheckSizeArgumentsOverflow( | ||||||
|  |             (uint64_t)tile_width * sizeof(*raster), tile_height)) { | ||||||
|  |       fprintf(stderr, "Error! TIFF tile dimension (%d x %d) is too large.\n", | ||||||
|  |               tile_width, tile_height); | ||||||
|  |       goto End; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   if (samples_per_px > 3 && !TIFFGetField(tif, TIFFTAG_EXTRASAMPLES, | ||||||
|  |                                           &extra_samples, &extra_samples_ptr)) { | ||||||
|  |     fprintf(stderr, "Error! Cannot retrieve TIFF ExtraSamples info.\n"); | ||||||
|  |     goto End; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   // _Tiffmalloc uses a signed type for size. | ||||||
|  |   alloc_size = (int64_t)(stride * image_height); | ||||||
|  |   if (alloc_size < 0 || alloc_size != (tsize_t)alloc_size) goto End; | ||||||
|  |  | ||||||
|  |   raster = (uint32_t*)_TIFFmalloc((tsize_t)alloc_size); | ||||||
|  |   if (raster != NULL) { | ||||||
|  |     if (TIFFReadRGBAImageOriented(tif, image_width, image_height, raster, | ||||||
|  |                                   ORIENTATION_TOPLEFT, 1)) { | ||||||
|  |       pic->width = image_width; | ||||||
|  |       pic->height = image_height; | ||||||
|  |       // TIFF data is ABGR | ||||||
|  | #ifdef WORDS_BIGENDIAN | ||||||
|  |       TIFFSwabArrayOfLong(raster, image_width * image_height); | ||||||
|  | #endif | ||||||
|  |       // if we have an alpha channel, we must un-multiply from rgbA to RGBA | ||||||
|  |       if (extra_samples == 1 && extra_samples_ptr != NULL && | ||||||
|  |           extra_samples_ptr[0] == EXTRASAMPLE_ASSOCALPHA) { | ||||||
|  |         uint32_t y; | ||||||
|  |         uint8_t* tmp = (uint8_t*)raster; | ||||||
|  |         for (y = 0; y < image_height; ++y) { | ||||||
|  |           MultARGBRow(tmp, image_width); | ||||||
|  |           tmp += stride; | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |       ok = keep_alpha | ||||||
|  |          ? WebPPictureImportRGBA(pic, (const uint8_t*)raster, (int)stride) | ||||||
|  |          : WebPPictureImportRGBX(pic, (const uint8_t*)raster, (int)stride); | ||||||
|  |     } | ||||||
|  |     _TIFFfree(raster); | ||||||
|  |   } else { | ||||||
|  |     fprintf(stderr, "Error allocating TIFF RGBA memory!\n"); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   if (ok) { | ||||||
|  |     if (metadata != NULL) { | ||||||
|  |       ok = ExtractMetadataFromTIFF(tif, metadata); | ||||||
|  |       if (!ok) { | ||||||
|  |         fprintf(stderr, "Error extracting TIFF metadata!\n"); | ||||||
|  |         MetadataFree(metadata); | ||||||
|  |         WebPPictureFree(pic); | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  End: | ||||||
|  |   TIFFClose(tif); | ||||||
|  |   return ok; | ||||||
|  | } | ||||||
|  | #else  // !WEBP_HAVE_TIFF | ||||||
|  | int ReadTIFF(const uint8_t* const data, size_t data_size, | ||||||
|  |              struct WebPPicture* const pic, int keep_alpha, | ||||||
|  |              struct Metadata* const metadata) { | ||||||
|  |   (void)data; | ||||||
|  |   (void)data_size; | ||||||
|  |   (void)pic; | ||||||
|  |   (void)keep_alpha; | ||||||
|  |   (void)metadata; | ||||||
|  |   fprintf(stderr, "TIFF support not compiled. Please install the libtiff " | ||||||
|  |           "development package before building.\n"); | ||||||
|  |   return 0; | ||||||
|  | } | ||||||
|  | #endif  // WEBP_HAVE_TIFF | ||||||
|  |  | ||||||
|  | // ----------------------------------------------------------------------------- | ||||||
							
								
								
									
										37
									
								
								external/libwebp/libwebp/imageio/tiffdec.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								external/libwebp/libwebp/imageio/tiffdec.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,37 @@ | |||||||
|  | // Copyright 2012 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. | ||||||
|  | // ----------------------------------------------------------------------------- | ||||||
|  | // | ||||||
|  | // TIFF decode. | ||||||
|  |  | ||||||
|  | #ifndef WEBP_IMAGEIO_TIFFDEC_H_ | ||||||
|  | #define WEBP_IMAGEIO_TIFFDEC_H_ | ||||||
|  |  | ||||||
|  | #include "webp/types.h" | ||||||
|  |  | ||||||
|  | #ifdef __cplusplus | ||||||
|  | extern "C" { | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | struct Metadata; | ||||||
|  | struct WebPPicture; | ||||||
|  |  | ||||||
|  | // Reads a TIFF from 'data', returning the decoded output in 'pic'. | ||||||
|  | // Output is RGBA or YUVA, depending on pic->use_argb value. | ||||||
|  | // If 'keep_alpha' is true and the TIFF has an alpha channel, the output is RGBA | ||||||
|  | // or YUVA. Otherwise, alpha channel is dropped and output is RGB or YUV. | ||||||
|  | // Returns true on success. | ||||||
|  | int ReadTIFF(const uint8_t* const data, size_t data_size, | ||||||
|  |              struct WebPPicture* const pic, int keep_alpha, | ||||||
|  |              struct Metadata* const metadata); | ||||||
|  |  | ||||||
|  | #ifdef __cplusplus | ||||||
|  | }    // extern "C" | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | #endif  // WEBP_IMAGEIO_TIFFDEC_H_ | ||||||
							
								
								
									
										244
									
								
								external/libwebp/libwebp/imageio/webpdec.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										244
									
								
								external/libwebp/libwebp/imageio/webpdec.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,244 @@ | |||||||
|  | // Copyright 2014 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. | ||||||
|  | // ----------------------------------------------------------------------------- | ||||||
|  | // | ||||||
|  | // WebP decode. | ||||||
|  |  | ||||||
|  | #ifdef HAVE_CONFIG_H | ||||||
|  | #include "webp/config.h" | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | #include "./webpdec.h" | ||||||
|  |  | ||||||
|  | #include <assert.h> | ||||||
|  | #include <stdio.h> | ||||||
|  | #include <stdlib.h> | ||||||
|  |  | ||||||
|  | #include "webp/decode.h" | ||||||
|  | #include "webp/demux.h" | ||||||
|  | #include "webp/encode.h" | ||||||
|  | #include "../examples/unicode.h" | ||||||
|  | #include "./imageio_util.h" | ||||||
|  | #include "./metadata.h" | ||||||
|  |  | ||||||
|  | //------------------------------------------------------------------------------ | ||||||
|  | // WebP decoding | ||||||
|  |  | ||||||
|  | static const char* const kStatusMessages[VP8_STATUS_NOT_ENOUGH_DATA + 1] = { | ||||||
|  |   "OK", "OUT_OF_MEMORY", "INVALID_PARAM", "BITSTREAM_ERROR", | ||||||
|  |   "UNSUPPORTED_FEATURE", "SUSPENDED", "USER_ABORT", "NOT_ENOUGH_DATA" | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | static void PrintAnimationWarning(const WebPDecoderConfig* const config) { | ||||||
|  |   if (config->input.has_animation) { | ||||||
|  |     fprintf(stderr, | ||||||
|  |             "Error! Decoding of an animated WebP file is not supported.\n" | ||||||
|  |             "       Use webpmux to extract the individual frames or\n" | ||||||
|  |             "       vwebp to view this image.\n"); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void PrintWebPError(const char* const in_file, int status) { | ||||||
|  |   WFPRINTF(stderr, "Decoding of %s failed.\n", (const W_CHAR*)in_file); | ||||||
|  |   fprintf(stderr, "Status: %d", status); | ||||||
|  |   if (status >= VP8_STATUS_OK && status <= VP8_STATUS_NOT_ENOUGH_DATA) { | ||||||
|  |     fprintf(stderr, "(%s)", kStatusMessages[status]); | ||||||
|  |   } | ||||||
|  |   fprintf(stderr, "\n"); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int LoadWebP(const char* const in_file, | ||||||
|  |              const uint8_t** data, size_t* data_size, | ||||||
|  |              WebPBitstreamFeatures* bitstream) { | ||||||
|  |   VP8StatusCode status; | ||||||
|  |   WebPBitstreamFeatures local_features; | ||||||
|  |   if (!ImgIoUtilReadFile(in_file, data, data_size)) return 0; | ||||||
|  |  | ||||||
|  |   if (bitstream == NULL) { | ||||||
|  |     bitstream = &local_features; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   status = WebPGetFeatures(*data, *data_size, bitstream); | ||||||
|  |   if (status != VP8_STATUS_OK) { | ||||||
|  |     WebPFree((void*)*data); | ||||||
|  |     *data = NULL; | ||||||
|  |     *data_size = 0; | ||||||
|  |     PrintWebPError(in_file, status); | ||||||
|  |     return 0; | ||||||
|  |   } | ||||||
|  |   return 1; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | //------------------------------------------------------------------------------ | ||||||
|  |  | ||||||
|  | VP8StatusCode DecodeWebP(const uint8_t* const data, size_t data_size, | ||||||
|  |                          WebPDecoderConfig* const config) { | ||||||
|  |   if (config == NULL) return VP8_STATUS_INVALID_PARAM; | ||||||
|  |   PrintAnimationWarning(config); | ||||||
|  |   return WebPDecode(data, data_size, config); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | VP8StatusCode DecodeWebPIncremental( | ||||||
|  |     const uint8_t* const data, size_t data_size, | ||||||
|  |     WebPDecoderConfig* const config) { | ||||||
|  |   VP8StatusCode status = VP8_STATUS_OK; | ||||||
|  |   if (config == NULL) return VP8_STATUS_INVALID_PARAM; | ||||||
|  |  | ||||||
|  |   PrintAnimationWarning(config); | ||||||
|  |  | ||||||
|  |   // Decoding call. | ||||||
|  |   { | ||||||
|  |     WebPIDecoder* const idec = WebPIDecode(data, data_size, config); | ||||||
|  |     if (idec == NULL) { | ||||||
|  |       fprintf(stderr, "Failed during WebPIDecode().\n"); | ||||||
|  |       return VP8_STATUS_OUT_OF_MEMORY; | ||||||
|  |     } else { | ||||||
|  |       status = WebPIUpdate(idec, data, data_size); | ||||||
|  |       WebPIDelete(idec); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   return status; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // ----------------------------------------------------------------------------- | ||||||
|  | // Metadata | ||||||
|  |  | ||||||
|  | static int ExtractMetadata(const uint8_t* const data, size_t data_size, | ||||||
|  |                            Metadata* const metadata) { | ||||||
|  |   WebPData webp_data = { data, data_size }; | ||||||
|  |   WebPDemuxer* const demux = WebPDemux(&webp_data); | ||||||
|  |   WebPChunkIterator chunk_iter; | ||||||
|  |   uint32_t flags; | ||||||
|  |  | ||||||
|  |   if (demux == NULL) return 0; | ||||||
|  |   assert(metadata != NULL); | ||||||
|  |  | ||||||
|  |   flags = WebPDemuxGetI(demux, WEBP_FF_FORMAT_FLAGS); | ||||||
|  |  | ||||||
|  |   if ((flags & ICCP_FLAG) && WebPDemuxGetChunk(demux, "ICCP", 1, &chunk_iter)) { | ||||||
|  |     MetadataCopy((const char*)chunk_iter.chunk.bytes, chunk_iter.chunk.size, | ||||||
|  |                  &metadata->iccp); | ||||||
|  |     WebPDemuxReleaseChunkIterator(&chunk_iter); | ||||||
|  |   } | ||||||
|  |   if ((flags & EXIF_FLAG) && WebPDemuxGetChunk(demux, "EXIF", 1, &chunk_iter)) { | ||||||
|  |     MetadataCopy((const char*)chunk_iter.chunk.bytes, chunk_iter.chunk.size, | ||||||
|  |                  &metadata->exif); | ||||||
|  |     WebPDemuxReleaseChunkIterator(&chunk_iter); | ||||||
|  |   } | ||||||
|  |   if ((flags & XMP_FLAG) && WebPDemuxGetChunk(demux, "XMP ", 1, &chunk_iter)) { | ||||||
|  |     MetadataCopy((const char*)chunk_iter.chunk.bytes, chunk_iter.chunk.size, | ||||||
|  |                  &metadata->xmp); | ||||||
|  |     WebPDemuxReleaseChunkIterator(&chunk_iter); | ||||||
|  |   } | ||||||
|  |   WebPDemuxDelete(demux); | ||||||
|  |   return 1; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // ----------------------------------------------------------------------------- | ||||||
|  |  | ||||||
|  | int ReadWebP(const uint8_t* const data, size_t data_size, | ||||||
|  |              WebPPicture* const pic, | ||||||
|  |              int keep_alpha, Metadata* const metadata) { | ||||||
|  |   int ok = 0; | ||||||
|  |   VP8StatusCode status = VP8_STATUS_OK; | ||||||
|  |   WebPDecoderConfig config; | ||||||
|  |   WebPDecBuffer* const output_buffer = &config.output; | ||||||
|  |   WebPBitstreamFeatures* const bitstream = &config.input; | ||||||
|  |  | ||||||
|  |   if (data == NULL || data_size == 0 || pic == NULL) return 0; | ||||||
|  |  | ||||||
|  |   if (!WebPInitDecoderConfig(&config)) { | ||||||
|  |     fprintf(stderr, "Library version mismatch!\n"); | ||||||
|  |     return 0; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   status = WebPGetFeatures(data, data_size, bitstream); | ||||||
|  |   if (status != VP8_STATUS_OK) { | ||||||
|  |     PrintWebPError("input data", status); | ||||||
|  |     return 0; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   do { | ||||||
|  |     const int has_alpha = keep_alpha && bitstream->has_alpha; | ||||||
|  |     uint64_t stride; | ||||||
|  |     pic->width = bitstream->width; | ||||||
|  |     pic->height = bitstream->height; | ||||||
|  |     if (pic->use_argb) { | ||||||
|  |       stride = (uint64_t)bitstream->width * 4; | ||||||
|  |     } else { | ||||||
|  |       stride = (uint64_t)bitstream->width * (has_alpha ? 5 : 3) / 2; | ||||||
|  |       pic->colorspace = has_alpha ? WEBP_YUV420A : WEBP_YUV420; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     if (!ImgIoUtilCheckSizeArgumentsOverflow(stride, bitstream->height)) { | ||||||
|  |       status = VP8_STATUS_OUT_OF_MEMORY; | ||||||
|  |       break; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     ok = WebPPictureAlloc(pic); | ||||||
|  |     if (!ok) { | ||||||
|  |       status = VP8_STATUS_OUT_OF_MEMORY; | ||||||
|  |       break; | ||||||
|  |     } | ||||||
|  |     if (pic->use_argb) { | ||||||
|  | #ifdef WORDS_BIGENDIAN | ||||||
|  |       output_buffer->colorspace = MODE_ARGB; | ||||||
|  | #else | ||||||
|  |       output_buffer->colorspace = MODE_BGRA; | ||||||
|  | #endif | ||||||
|  |       output_buffer->u.RGBA.rgba = (uint8_t*)pic->argb; | ||||||
|  |       output_buffer->u.RGBA.stride = pic->argb_stride * sizeof(uint32_t); | ||||||
|  |       output_buffer->u.RGBA.size = output_buffer->u.RGBA.stride * pic->height; | ||||||
|  |     } else { | ||||||
|  |       output_buffer->colorspace = has_alpha ? MODE_YUVA : MODE_YUV; | ||||||
|  |       output_buffer->u.YUVA.y = pic->y; | ||||||
|  |       output_buffer->u.YUVA.u = pic->u; | ||||||
|  |       output_buffer->u.YUVA.v = pic->v; | ||||||
|  |       output_buffer->u.YUVA.a = has_alpha ? pic->a : NULL; | ||||||
|  |       output_buffer->u.YUVA.y_stride = pic->y_stride; | ||||||
|  |       output_buffer->u.YUVA.u_stride = pic->uv_stride; | ||||||
|  |       output_buffer->u.YUVA.v_stride = pic->uv_stride; | ||||||
|  |       output_buffer->u.YUVA.a_stride = has_alpha ? pic->a_stride : 0; | ||||||
|  |       output_buffer->u.YUVA.y_size = pic->height * pic->y_stride; | ||||||
|  |       output_buffer->u.YUVA.u_size = (pic->height + 1) / 2 * pic->uv_stride; | ||||||
|  |       output_buffer->u.YUVA.v_size = (pic->height + 1) / 2 * pic->uv_stride; | ||||||
|  |       output_buffer->u.YUVA.a_size = pic->height * pic->a_stride; | ||||||
|  |     } | ||||||
|  |     output_buffer->is_external_memory = 1; | ||||||
|  |  | ||||||
|  |     status = DecodeWebP(data, data_size, &config); | ||||||
|  |     ok = (status == VP8_STATUS_OK); | ||||||
|  |     if (ok && !keep_alpha && pic->use_argb) { | ||||||
|  |       // Need to wipe out the alpha value, as requested. | ||||||
|  |       int x, y; | ||||||
|  |       uint32_t* argb = pic->argb; | ||||||
|  |       for (y = 0; y < pic->height; ++y) { | ||||||
|  |         for (x = 0; x < pic->width; ++x) argb[x] |= 0xff000000u; | ||||||
|  |         argb += pic->argb_stride; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } while (0);   // <- so we can 'break' out of the loop | ||||||
|  |  | ||||||
|  |   if (status != VP8_STATUS_OK) { | ||||||
|  |     PrintWebPError("input data", status); | ||||||
|  |     ok = 0; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   WebPFreeDecBuffer(output_buffer); | ||||||
|  |  | ||||||
|  |   if (ok && metadata != NULL) { | ||||||
|  |     ok = ExtractMetadata(data, data_size, metadata); | ||||||
|  |     if (!ok) { | ||||||
|  |       PrintWebPError("metadata", VP8_STATUS_BITSTREAM_ERROR); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   if (!ok) WebPPictureFree(pic); | ||||||
|  |   return ok; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // ----------------------------------------------------------------------------- | ||||||
							
								
								
									
										67
									
								
								external/libwebp/libwebp/imageio/webpdec.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								external/libwebp/libwebp/imageio/webpdec.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,67 @@ | |||||||
|  | // Copyright 2014 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. | ||||||
|  | // ----------------------------------------------------------------------------- | ||||||
|  | // | ||||||
|  | // WebP decode. | ||||||
|  |  | ||||||
|  | #ifndef WEBP_IMAGEIO_WEBPDEC_H_ | ||||||
|  | #define WEBP_IMAGEIO_WEBPDEC_H_ | ||||||
|  |  | ||||||
|  | #include "webp/decode.h" | ||||||
|  |  | ||||||
|  | #ifdef __cplusplus | ||||||
|  | extern "C" { | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | struct Metadata; | ||||||
|  | struct WebPPicture; | ||||||
|  |  | ||||||
|  | //------------------------------------------------------------------------------ | ||||||
|  | // WebP decoding | ||||||
|  |  | ||||||
|  | // Prints an informative error message regarding decode failure of 'in_file'. | ||||||
|  | // 'status' is treated as a VP8StatusCode and if valid will be printed as a | ||||||
|  | // text string. | ||||||
|  | void PrintWebPError(const char* const in_file, int status); | ||||||
|  |  | ||||||
|  | // Reads a WebP from 'in_file', returning the contents and size in 'data' and | ||||||
|  | // 'data_size'. If not NULL, 'bitstream' is populated using WebPGetFeatures(). | ||||||
|  | // Returns true on success. | ||||||
|  | int LoadWebP(const char* const in_file, | ||||||
|  |              const uint8_t** data, size_t* data_size, | ||||||
|  |              WebPBitstreamFeatures* bitstream); | ||||||
|  |  | ||||||
|  | // Decodes the WebP contained in 'data'. | ||||||
|  | // 'config' is a structure previously initialized by WebPInitDecoderConfig(). | ||||||
|  | // 'config->output' should have the desired colorspace selected. | ||||||
|  | // Returns the decoder status. On success 'config->output' will contain the | ||||||
|  | // decoded picture. | ||||||
|  | VP8StatusCode DecodeWebP(const uint8_t* const data, size_t data_size, | ||||||
|  |                          WebPDecoderConfig* const config); | ||||||
|  |  | ||||||
|  | // Same as DecodeWebP(), but using the incremental decoder. | ||||||
|  | VP8StatusCode DecodeWebPIncremental( | ||||||
|  |     const uint8_t* const data, size_t data_size, | ||||||
|  |     WebPDecoderConfig* const config); | ||||||
|  |  | ||||||
|  | //------------------------------------------------------------------------------ | ||||||
|  |  | ||||||
|  | // Decodes a WebP contained in 'data', returning the decoded output in 'pic'. | ||||||
|  | // Output is RGBA or YUVA, depending on pic->use_argb value. | ||||||
|  | // If 'keep_alpha' is true and the WebP has an alpha channel, the output is RGBA | ||||||
|  | // or YUVA. Otherwise, alpha channel is dropped and output is RGB or YUV. | ||||||
|  | // Returns true on success. | ||||||
|  | int ReadWebP(const uint8_t* const data, size_t data_size, | ||||||
|  |              struct WebPPicture* const pic, | ||||||
|  |              int keep_alpha, struct Metadata* const metadata); | ||||||
|  |  | ||||||
|  | #ifdef __cplusplus | ||||||
|  | }    // extern "C" | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | #endif  // WEBP_IMAGEIO_WEBPDEC_H_ | ||||||
							
								
								
									
										413
									
								
								external/libwebp/libwebp/imageio/wicdec.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										413
									
								
								external/libwebp/libwebp/imageio/wicdec.c
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,413 @@ | |||||||
|  | // Copyright 2013 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. | ||||||
|  | // ----------------------------------------------------------------------------- | ||||||
|  | // | ||||||
|  | // Windows Imaging Component (WIC) decode. | ||||||
|  |  | ||||||
|  | #include "./wicdec.h" | ||||||
|  |  | ||||||
|  | #ifdef HAVE_CONFIG_H | ||||||
|  | #include "webp/config.h" | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | #include <assert.h> | ||||||
|  | #include <stdio.h> | ||||||
|  | #include <string.h> | ||||||
|  |  | ||||||
|  | #ifdef HAVE_WINCODEC_H | ||||||
|  | #ifdef __MINGW32__ | ||||||
|  | #define INITGUID  // Without this GUIDs are declared extern and fail to link | ||||||
|  | #endif | ||||||
|  | #define CINTERFACE | ||||||
|  | #define COBJMACROS | ||||||
|  | #define _WIN32_IE 0x500  // Workaround bug in shlwapi.h when compiling C++ | ||||||
|  |                          // code with COBJMACROS. | ||||||
|  | #include <ole2.h>  // CreateStreamOnHGlobal() | ||||||
|  | #include <shlwapi.h> | ||||||
|  | #include <tchar.h> | ||||||
|  | #include <windows.h> | ||||||
|  | #include <wincodec.h> | ||||||
|  |  | ||||||
|  | #include "../examples/unicode.h" | ||||||
|  | #include "./imageio_util.h" | ||||||
|  | #include "./metadata.h" | ||||||
|  | #include "webp/encode.h" | ||||||
|  |  | ||||||
|  | #define IFS(fn)                                                     \ | ||||||
|  |   do {                                                              \ | ||||||
|  |     if (SUCCEEDED(hr)) {                                            \ | ||||||
|  |       hr = (fn);                                                    \ | ||||||
|  |       if (FAILED(hr)) fprintf(stderr, #fn " failed %08lx\n", hr);   \ | ||||||
|  |     }                                                               \ | ||||||
|  |   } while (0) | ||||||
|  |  | ||||||
|  | // modified version of DEFINE_GUID from guiddef.h. | ||||||
|  | #define WEBP_DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ | ||||||
|  |   static const GUID name = \ | ||||||
|  |       { l, w1, w2, { b1, b2,  b3,  b4,  b5,  b6,  b7,  b8 } } | ||||||
|  |  | ||||||
|  | #ifdef __cplusplus | ||||||
|  | #define MAKE_REFGUID(x) (x) | ||||||
|  | #else | ||||||
|  | #define MAKE_REFGUID(x) &(x) | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | typedef struct WICFormatImporter { | ||||||
|  |   const GUID* pixel_format; | ||||||
|  |   int bytes_per_pixel; | ||||||
|  |   int (*import)(WebPPicture* const, const uint8_t* const, int); | ||||||
|  | } WICFormatImporter; | ||||||
|  |  | ||||||
|  | // From Microsoft SDK 7.0a -- wincodec.h | ||||||
|  | // Create local copies for compatibility when building against earlier | ||||||
|  | // versions of the SDK. | ||||||
|  | WEBP_DEFINE_GUID(GUID_WICPixelFormat24bppBGR_, | ||||||
|  |                  0x6fddc324, 0x4e03, 0x4bfe, | ||||||
|  |                  0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x0c); | ||||||
|  | WEBP_DEFINE_GUID(GUID_WICPixelFormat24bppRGB_, | ||||||
|  |                  0x6fddc324, 0x4e03, 0x4bfe, | ||||||
|  |                  0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x0d); | ||||||
|  | WEBP_DEFINE_GUID(GUID_WICPixelFormat32bppBGRA_, | ||||||
|  |                  0x6fddc324, 0x4e03, 0x4bfe, | ||||||
|  |                  0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x0f); | ||||||
|  | WEBP_DEFINE_GUID(GUID_WICPixelFormat32bppRGBA_, | ||||||
|  |                  0xf5c7ad2d, 0x6a8d, 0x43dd, | ||||||
|  |                  0xa7, 0xa8, 0xa2, 0x99, 0x35, 0x26, 0x1a, 0xe9); | ||||||
|  | WEBP_DEFINE_GUID(GUID_WICPixelFormat64bppBGRA_, | ||||||
|  |                  0x1562ff7c, 0xd352, 0x46f9, | ||||||
|  |                  0x97, 0x9e, 0x42, 0x97, 0x6b, 0x79, 0x22, 0x46); | ||||||
|  | WEBP_DEFINE_GUID(GUID_WICPixelFormat64bppRGBA_, | ||||||
|  |                  0x6fddc324, 0x4e03, 0x4bfe, | ||||||
|  |                  0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x16); | ||||||
|  |  | ||||||
|  | static HRESULT OpenInputStream(const char* filename, IStream** stream) { | ||||||
|  |   HRESULT hr = S_OK; | ||||||
|  |   if (!WSTRCMP(filename, "-")) { | ||||||
|  |     const uint8_t* data = NULL; | ||||||
|  |     size_t data_size = 0; | ||||||
|  |     const int ok = ImgIoUtilReadFile(filename, &data, &data_size); | ||||||
|  |     if (ok) { | ||||||
|  |       HGLOBAL image = GlobalAlloc(GMEM_MOVEABLE, data_size); | ||||||
|  |       if (image != NULL) { | ||||||
|  |         void* const image_mem = GlobalLock(image); | ||||||
|  |         if (image_mem != NULL) { | ||||||
|  |           memcpy(image_mem, data, data_size); | ||||||
|  |           GlobalUnlock(image); | ||||||
|  |           IFS(CreateStreamOnHGlobal(image, TRUE, stream)); | ||||||
|  |         } else { | ||||||
|  |           hr = E_FAIL; | ||||||
|  |         } | ||||||
|  |       } else { | ||||||
|  |         hr = E_OUTOFMEMORY; | ||||||
|  |       } | ||||||
|  |       free((void*)data); | ||||||
|  |     } else { | ||||||
|  |       hr = E_FAIL; | ||||||
|  |     } | ||||||
|  |   } else { | ||||||
|  |     IFS(SHCreateStreamOnFile((const LPTSTR)filename, STGM_READ, stream)); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   if (FAILED(hr)) { | ||||||
|  |     _ftprintf(stderr, _T("Error opening input file %s (%08lx)\n"), | ||||||
|  |               (const LPTSTR)filename, hr); | ||||||
|  |   } | ||||||
|  |   return hr; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // ----------------------------------------------------------------------------- | ||||||
|  | // Metadata processing | ||||||
|  |  | ||||||
|  | // Stores the first non-zero sized color profile from 'frame' to 'iccp'. | ||||||
|  | // Returns an HRESULT to indicate success or failure. The caller is responsible | ||||||
|  | // for freeing 'iccp->bytes' in either case. | ||||||
|  | static HRESULT ExtractICCP(IWICImagingFactory* const factory, | ||||||
|  |                            IWICBitmapFrameDecode* const frame, | ||||||
|  |                            MetadataPayload* const iccp) { | ||||||
|  |   HRESULT hr = S_OK; | ||||||
|  |   UINT i, count; | ||||||
|  |   IWICColorContext** color_contexts; | ||||||
|  |  | ||||||
|  |   IFS(IWICBitmapFrameDecode_GetColorContexts(frame, 0, NULL, &count)); | ||||||
|  |   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)); | ||||||
|  |   if (color_contexts == NULL) return E_OUTOFMEMORY; | ||||||
|  |   for (i = 0; SUCCEEDED(hr) && i < count; ++i) { | ||||||
|  |     IFS(IWICImagingFactory_CreateColorContext(factory, &color_contexts[i])); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   if (SUCCEEDED(hr)) { | ||||||
|  |     UINT num_color_contexts; | ||||||
|  |     IFS(IWICBitmapFrameDecode_GetColorContexts(frame, | ||||||
|  |                                                count, color_contexts, | ||||||
|  |                                                &num_color_contexts)); | ||||||
|  |     assert(FAILED(hr) || num_color_contexts <= count); | ||||||
|  |     for (i = 0; SUCCEEDED(hr) && i < num_color_contexts; ++i) { | ||||||
|  |       WICColorContextType type; | ||||||
|  |       IFS(IWICColorContext_GetType(color_contexts[i], &type)); | ||||||
|  |       if (SUCCEEDED(hr) && type == WICColorContextProfile) { | ||||||
|  |         UINT size; | ||||||
|  |         IFS(IWICColorContext_GetProfileBytes(color_contexts[i], | ||||||
|  |                                              0, NULL, &size)); | ||||||
|  |         if (SUCCEEDED(hr) && size > 0) { | ||||||
|  |           iccp->bytes = (uint8_t*)malloc(size); | ||||||
|  |           if (iccp->bytes == NULL) { | ||||||
|  |             hr = E_OUTOFMEMORY; | ||||||
|  |             break; | ||||||
|  |           } | ||||||
|  |           iccp->size = size; | ||||||
|  |           IFS(IWICColorContext_GetProfileBytes(color_contexts[i], | ||||||
|  |                                                (UINT)iccp->size, iccp->bytes, | ||||||
|  |                                                &size)); | ||||||
|  |           if (SUCCEEDED(hr) && size != iccp->size) { | ||||||
|  |             fprintf(stderr, "Warning! ICC profile size (%u) != expected (%u)\n", | ||||||
|  |                     size, (uint32_t)iccp->size); | ||||||
|  |             iccp->size = size; | ||||||
|  |           } | ||||||
|  |           break; | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   for (i = 0; i < count; ++i) { | ||||||
|  |     if (color_contexts[i] != NULL) IUnknown_Release(color_contexts[i]); | ||||||
|  |   } | ||||||
|  |   free(color_contexts); | ||||||
|  |   return hr; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static HRESULT ExtractMetadata(IWICImagingFactory* const factory, | ||||||
|  |                                IWICBitmapFrameDecode* const frame, | ||||||
|  |                                Metadata* const metadata) { | ||||||
|  |   // TODO(jzern): add XMP/EXIF extraction. | ||||||
|  |   const HRESULT hr = ExtractICCP(factory, frame, &metadata->iccp); | ||||||
|  |   if (FAILED(hr)) MetadataFree(metadata); | ||||||
|  |   return hr; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // ----------------------------------------------------------------------------- | ||||||
|  |  | ||||||
|  | static int HasPalette(GUID pixel_format) { | ||||||
|  |   return (IsEqualGUID(MAKE_REFGUID(pixel_format), | ||||||
|  |                       MAKE_REFGUID(GUID_WICPixelFormat1bppIndexed)) || | ||||||
|  |           IsEqualGUID(MAKE_REFGUID(pixel_format), | ||||||
|  |                       MAKE_REFGUID(GUID_WICPixelFormat2bppIndexed)) || | ||||||
|  |           IsEqualGUID(MAKE_REFGUID(pixel_format), | ||||||
|  |                       MAKE_REFGUID(GUID_WICPixelFormat4bppIndexed)) || | ||||||
|  |           IsEqualGUID(MAKE_REFGUID(pixel_format), | ||||||
|  |                       MAKE_REFGUID(GUID_WICPixelFormat8bppIndexed))); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static int HasAlpha(IWICImagingFactory* const factory, | ||||||
|  |                     IWICBitmapDecoder* const decoder, | ||||||
|  |                     IWICBitmapFrameDecode* const frame, | ||||||
|  |                     GUID pixel_format) { | ||||||
|  |   int has_alpha; | ||||||
|  |   if (HasPalette(pixel_format)) { | ||||||
|  |     IWICPalette* frame_palette = NULL; | ||||||
|  |     IWICPalette* global_palette = NULL; | ||||||
|  |     BOOL frame_palette_has_alpha = FALSE; | ||||||
|  |     BOOL global_palette_has_alpha = FALSE; | ||||||
|  |  | ||||||
|  |     // A palette may exist at the frame or container level, | ||||||
|  |     // check IWICPalette::HasAlpha() for both if present. | ||||||
|  |     if (SUCCEEDED(IWICImagingFactory_CreatePalette(factory, &frame_palette)) && | ||||||
|  |         SUCCEEDED(IWICBitmapFrameDecode_CopyPalette(frame, frame_palette))) { | ||||||
|  |       IWICPalette_HasAlpha(frame_palette, &frame_palette_has_alpha); | ||||||
|  |     } | ||||||
|  |     if (SUCCEEDED(IWICImagingFactory_CreatePalette(factory, &global_palette)) && | ||||||
|  |         SUCCEEDED(IWICBitmapDecoder_CopyPalette(decoder, global_palette))) { | ||||||
|  |       IWICPalette_HasAlpha(global_palette, &global_palette_has_alpha); | ||||||
|  |     } | ||||||
|  |     has_alpha = frame_palette_has_alpha || global_palette_has_alpha; | ||||||
|  |  | ||||||
|  |     if (frame_palette != NULL) IUnknown_Release(frame_palette); | ||||||
|  |     if (global_palette != NULL) IUnknown_Release(global_palette); | ||||||
|  |   } else { | ||||||
|  |     has_alpha = IsEqualGUID(MAKE_REFGUID(pixel_format), | ||||||
|  |                             MAKE_REFGUID(GUID_WICPixelFormat32bppRGBA_)) || | ||||||
|  |                 IsEqualGUID(MAKE_REFGUID(pixel_format), | ||||||
|  |                             MAKE_REFGUID(GUID_WICPixelFormat32bppBGRA_)) || | ||||||
|  |                 IsEqualGUID(MAKE_REFGUID(pixel_format), | ||||||
|  |                             MAKE_REFGUID(GUID_WICPixelFormat64bppRGBA_)) || | ||||||
|  |                 IsEqualGUID(MAKE_REFGUID(pixel_format), | ||||||
|  |                             MAKE_REFGUID(GUID_WICPixelFormat64bppBGRA_)); | ||||||
|  |   } | ||||||
|  |   return has_alpha; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int ReadPictureWithWIC(const char* const filename, | ||||||
|  |                        WebPPicture* const pic, int keep_alpha, | ||||||
|  |                        Metadata* const metadata) { | ||||||
|  |   // From Microsoft SDK 6.0a -- ks.h | ||||||
|  |   // Define a local copy to avoid link errors under mingw. | ||||||
|  |   WEBP_DEFINE_GUID(GUID_NULL_, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); | ||||||
|  |   static const WICFormatImporter kAlphaFormatImporters[] = { | ||||||
|  |     { &GUID_WICPixelFormat32bppBGRA_, 4, WebPPictureImportBGRA }, | ||||||
|  |     { &GUID_WICPixelFormat32bppRGBA_, 4, WebPPictureImportRGBA }, | ||||||
|  |     { NULL, 0, NULL }, | ||||||
|  |   }; | ||||||
|  |   static const WICFormatImporter kNonAlphaFormatImporters[] = { | ||||||
|  |     { &GUID_WICPixelFormat24bppBGR_, 3, WebPPictureImportBGR }, | ||||||
|  |     { &GUID_WICPixelFormat24bppRGB_, 3, WebPPictureImportRGB }, | ||||||
|  |     { NULL, 0, NULL }, | ||||||
|  |   }; | ||||||
|  |   HRESULT hr = S_OK; | ||||||
|  |   IWICBitmapFrameDecode* frame = NULL; | ||||||
|  |   IWICFormatConverter* converter = NULL; | ||||||
|  |   IWICImagingFactory* factory = NULL; | ||||||
|  |   IWICBitmapDecoder* decoder = NULL; | ||||||
|  |   IStream* stream = NULL; | ||||||
|  |   UINT frame_count = 0; | ||||||
|  |   UINT width = 0, height = 0; | ||||||
|  |   BYTE* rgb = NULL; | ||||||
|  |   WICPixelFormatGUID src_pixel_format = GUID_WICPixelFormatUndefined; | ||||||
|  |   const WICFormatImporter* importer = 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[] = { | ||||||
|  |     &GUID_ContainerFormatBmp, | ||||||
|  |     &GUID_ContainerFormatPng, | ||||||
|  |     &GUID_ContainerFormatTiff, | ||||||
|  |     &GUID_ContainerFormatWebp_, | ||||||
|  |     NULL | ||||||
|  |   }; | ||||||
|  |   int has_alpha = 0; | ||||||
|  |   int64_t stride; | ||||||
|  |  | ||||||
|  |   if (filename == NULL || pic == NULL) return 0; | ||||||
|  |  | ||||||
|  |   IFS(CoInitialize(NULL)); | ||||||
|  |   IFS(CoCreateInstance(MAKE_REFGUID(CLSID_WICImagingFactory), NULL, | ||||||
|  |                        CLSCTX_INPROC_SERVER, | ||||||
|  |                        MAKE_REFGUID(IID_IWICImagingFactory), | ||||||
|  |                        (LPVOID*)&factory)); | ||||||
|  |   if (hr == REGDB_E_CLASSNOTREG) { | ||||||
|  |     fprintf(stderr, | ||||||
|  |             "Couldn't access Windows Imaging Component (are you running " | ||||||
|  |             "Windows XP SP3 or newer?). Most formats not available. " | ||||||
|  |             "Use -s for the available YUV input.\n"); | ||||||
|  |   } | ||||||
|  |   // Prepare for image decoding. | ||||||
|  |   IFS(OpenInputStream(filename, &stream)); | ||||||
|  |   IFS(IWICImagingFactory_CreateDecoderFromStream( | ||||||
|  |           factory, stream, NULL, | ||||||
|  |           WICDecodeMetadataCacheOnDemand, &decoder)); | ||||||
|  |   IFS(IWICBitmapDecoder_GetFrameCount(decoder, &frame_count)); | ||||||
|  |   if (SUCCEEDED(hr)) { | ||||||
|  |     if (frame_count == 0) { | ||||||
|  |       fprintf(stderr, "No frame found in input file.\n"); | ||||||
|  |       hr = E_FAIL; | ||||||
|  |     } else if (frame_count > 1) { | ||||||
|  |       // WIC will be tried before native WebP decoding so avoid duplicating the | ||||||
|  |       // error message. | ||||||
|  |       hr = E_FAIL; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   IFS(IWICBitmapDecoder_GetFrame(decoder, 0, &frame)); | ||||||
|  |   IFS(IWICBitmapFrameDecode_GetPixelFormat(frame, &src_pixel_format)); | ||||||
|  |   IFS(IWICBitmapDecoder_GetContainerFormat(decoder, &src_container_format)); | ||||||
|  |  | ||||||
|  |   if (SUCCEEDED(hr) && keep_alpha) { | ||||||
|  |     const GUID** guid; | ||||||
|  |     for (guid = kAlphaContainers; *guid != NULL; ++guid) { | ||||||
|  |       if (IsEqualGUID(MAKE_REFGUID(src_container_format), | ||||||
|  |                       MAKE_REFGUID(**guid))) { | ||||||
|  |         has_alpha = HasAlpha(factory, decoder, frame, src_pixel_format); | ||||||
|  |         break; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   // Prepare for pixel format conversion (if necessary). | ||||||
|  |   IFS(IWICImagingFactory_CreateFormatConverter(factory, &converter)); | ||||||
|  |  | ||||||
|  |   for (importer = has_alpha ? kAlphaFormatImporters : kNonAlphaFormatImporters; | ||||||
|  |        hr == S_OK && importer->import != NULL; ++importer) { | ||||||
|  |     BOOL can_convert; | ||||||
|  |     const HRESULT cchr = IWICFormatConverter_CanConvert( | ||||||
|  |         converter, | ||||||
|  |         MAKE_REFGUID(src_pixel_format), | ||||||
|  |         MAKE_REFGUID(*importer->pixel_format), | ||||||
|  |         &can_convert); | ||||||
|  |     if (SUCCEEDED(cchr) && can_convert) break; | ||||||
|  |   } | ||||||
|  |   if (importer->import == NULL) hr = E_FAIL; | ||||||
|  |  | ||||||
|  |   IFS(IWICFormatConverter_Initialize(converter, (IWICBitmapSource*)frame, | ||||||
|  |                                      importer->pixel_format, | ||||||
|  |                                      WICBitmapDitherTypeNone, | ||||||
|  |                                      NULL, 0.0, WICBitmapPaletteTypeCustom)); | ||||||
|  |  | ||||||
|  |   // Decode. | ||||||
|  |   IFS(IWICFormatConverter_GetSize(converter, &width, &height)); | ||||||
|  |   stride = (int64_t)importer->bytes_per_pixel * width * sizeof(*rgb); | ||||||
|  |   if (stride != (int)stride || | ||||||
|  |       !ImgIoUtilCheckSizeArgumentsOverflow(stride, height)) { | ||||||
|  |     hr = E_FAIL; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   if (SUCCEEDED(hr)) { | ||||||
|  |     rgb = (BYTE*)malloc((size_t)stride * height); | ||||||
|  |     if (rgb == NULL) | ||||||
|  |       hr = E_OUTOFMEMORY; | ||||||
|  |   } | ||||||
|  |   IFS(IWICFormatConverter_CopyPixels(converter, NULL, | ||||||
|  |                                      (UINT)stride, (UINT)stride * height, rgb)); | ||||||
|  |  | ||||||
|  |   // WebP conversion. | ||||||
|  |   if (SUCCEEDED(hr)) { | ||||||
|  |     int ok; | ||||||
|  |     pic->width = width; | ||||||
|  |     pic->height = height; | ||||||
|  |     pic->use_argb = 1;    // For WIC, we always force to argb | ||||||
|  |     ok = importer->import(pic, rgb, (int)stride); | ||||||
|  |     if (!ok) hr = E_FAIL; | ||||||
|  |   } | ||||||
|  |   if (SUCCEEDED(hr)) { | ||||||
|  |     if (metadata != NULL) { | ||||||
|  |       hr = ExtractMetadata(factory, frame, metadata); | ||||||
|  |       if (FAILED(hr)) { | ||||||
|  |         fprintf(stderr, "Error extracting image metadata using WIC!\n"); | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   // Cleanup. | ||||||
|  |   if (converter != NULL) IUnknown_Release(converter); | ||||||
|  |   if (frame != NULL) IUnknown_Release(frame); | ||||||
|  |   if (decoder != NULL) IUnknown_Release(decoder); | ||||||
|  |   if (factory != NULL) IUnknown_Release(factory); | ||||||
|  |   if (stream != NULL) IUnknown_Release(stream); | ||||||
|  |   free(rgb); | ||||||
|  |   return SUCCEEDED(hr); | ||||||
|  | } | ||||||
|  | #else  // !HAVE_WINCODEC_H | ||||||
|  | int ReadPictureWithWIC(const char* const filename, | ||||||
|  |                        struct WebPPicture* const pic, int keep_alpha, | ||||||
|  |                        struct Metadata* const metadata) { | ||||||
|  |   (void)filename; | ||||||
|  |   (void)pic; | ||||||
|  |   (void)keep_alpha; | ||||||
|  |   (void)metadata; | ||||||
|  |   fprintf(stderr, "Windows Imaging Component (WIC) support not compiled. " | ||||||
|  |                   "Visual Studio and mingw-w64 builds support WIC. Make sure " | ||||||
|  |                   "wincodec.h detection is working correctly if using autoconf " | ||||||
|  |                   "and HAVE_WINCODEC_H is defined before building.\n"); | ||||||
|  |   return 0; | ||||||
|  | } | ||||||
|  | #endif  // HAVE_WINCODEC_H | ||||||
|  |  | ||||||
|  | // ----------------------------------------------------------------------------- | ||||||
							
								
								
									
										34
									
								
								external/libwebp/libwebp/imageio/wicdec.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								external/libwebp/libwebp/imageio/wicdec.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,34 @@ | |||||||
|  | // Copyright 2013 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. | ||||||
|  | // ----------------------------------------------------------------------------- | ||||||
|  | // | ||||||
|  | // Windows Imaging Component (WIC) decode. | ||||||
|  |  | ||||||
|  | #ifndef WEBP_IMAGEIO_WICDEC_H_ | ||||||
|  | #define WEBP_IMAGEIO_WICDEC_H_ | ||||||
|  |  | ||||||
|  | #ifdef __cplusplus | ||||||
|  | extern "C" { | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | struct Metadata; | ||||||
|  | struct WebPPicture; | ||||||
|  |  | ||||||
|  | // Reads an image from 'filename', returning the decoded output in 'pic'. | ||||||
|  | // If 'keep_alpha' is true and the image has an alpha channel, the output is | ||||||
|  | // RGBA otherwise it will be RGB. pic->use_argb is always forced to true. | ||||||
|  | // Returns true on success. | ||||||
|  | int ReadPictureWithWIC(const char* const filename, | ||||||
|  |                        struct WebPPicture* const pic, int keep_alpha, | ||||||
|  |                        struct Metadata* const metadata); | ||||||
|  |  | ||||||
|  | #ifdef __cplusplus | ||||||
|  | }    // extern "C" | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | #endif  // WEBP_IMAGEIO_WICDEC_H_ | ||||||
							
								
								
									
										106
									
								
								external/libwebp/libwebp/infra/common.sh
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										106
									
								
								external/libwebp/libwebp/infra/common.sh
									
									
									
									
										vendored
									
									
										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
									
								
								external/libwebp/libwebp/infra/compile.sh
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										401
									
								
								external/libwebp/libwebp/infra/compile.sh
									
									
									
									
										vendored
									
									
										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
									
								
								external/libwebp/libwebp/infra/compile_android.sh
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										224
									
								
								external/libwebp/libwebp/infra/compile_android.sh
									
									
									
									
										vendored
									
									
										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
									
								
								external/libwebp/libwebp/infra/compile_js.sh
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										75
									
								
								external/libwebp/libwebp/infra/compile_js.sh
									
									
									
									
										vendored
									
									
										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
									
								
								external/libwebp/libwebp/infra/run_static_analysis.sh
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										98
									
								
								external/libwebp/libwebp/infra/run_static_analysis.sh
									
									
									
									
										vendored
									
									
										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}")/"* "${OUTPUT_DIR}" | ||||||
|  | else | ||||||
|  |   # make a empty report to wipe out any old bug reports. | ||||||
|  |   cat << EOT > "${OUTPUT_DIR}/index.html" | ||||||
|  | <html> | ||||||
|  | <body> | ||||||
|  | No bugs reported. | ||||||
|  | </body> | ||||||
|  | </html> | ||||||
|  | EOT | ||||||
|  | fi | ||||||
							
								
								
									
										168
									
								
								external/libwebp/libwebp/iosbuild.sh
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										168
									
								
								external/libwebp/libwebp/iosbuild.sh
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,168 @@ | |||||||
|  | #!/bin/bash | ||||||
|  | # | ||||||
|  | # This script generates 'WebP.framework' and 'WebPDecoder.framework', | ||||||
|  | # 'WebPDemux.framework' and 'WebPMux.framework'. | ||||||
|  | # An iOS app can decode WebP images by including 'WebPDecoder.framework' and | ||||||
|  | # both encode and decode WebP images by including 'WebP.framework'. | ||||||
|  | # | ||||||
|  | # Run ./iosbuild.sh to generate the frameworks under the current directory | ||||||
|  | # (the previous build will be erased if it exists). | ||||||
|  | # | ||||||
|  | # This script is inspired by the build script written by Carson McDonald. | ||||||
|  | # (https://www.ioncannon.net/programming/1483/using-webp-to-reduce-native-ios-app-size/). | ||||||
|  |  | ||||||
|  | set -e | ||||||
|  |  | ||||||
|  | # Set this variable based on the desired minimum deployment target. | ||||||
|  | readonly IOS_MIN_VERSION=6.0 | ||||||
|  |  | ||||||
|  | # Extract the latest SDK version from the final field of the form: iphoneosX.Y | ||||||
|  | readonly SDK=$(xcodebuild -showsdks \ | ||||||
|  |   | grep iphoneos | sort | tail -n 1 | awk '{print substr($NF, 9)}' | ||||||
|  | ) | ||||||
|  | # Extract Xcode version. | ||||||
|  | readonly XCODE=$(xcodebuild -version | grep Xcode | cut -d " " -f2) | ||||||
|  | if [[ -z "${XCODE}" ]]; then | ||||||
|  |   echo "Xcode not available" | ||||||
|  |   exit 1 | ||||||
|  | fi | ||||||
|  |  | ||||||
|  | readonly OLDPATH=${PATH} | ||||||
|  |  | ||||||
|  | # Add iPhoneOS-V6 to the list of platforms below if you need armv6 support. | ||||||
|  | # Note that iPhoneOS-V6 support is not available with the iOS6 SDK. | ||||||
|  | PLATFORMS="iPhoneSimulator iPhoneSimulator64" | ||||||
|  | PLATFORMS+=" iPhoneOS-V7 iPhoneOS-V7s iPhoneOS-V7-arm64" | ||||||
|  | readonly PLATFORMS | ||||||
|  | readonly SRCDIR=$(dirname $0) | ||||||
|  | readonly TOPDIR=$(pwd) | ||||||
|  | readonly BUILDDIR="${TOPDIR}/iosbuild" | ||||||
|  | readonly TARGETDIR="${TOPDIR}/WebP.framework" | ||||||
|  | readonly DECTARGETDIR="${TOPDIR}/WebPDecoder.framework" | ||||||
|  | readonly MUXTARGETDIR="${TOPDIR}/WebPMux.framework" | ||||||
|  | readonly DEMUXTARGETDIR="${TOPDIR}/WebPDemux.framework" | ||||||
|  | readonly DEVELOPER=$(xcode-select --print-path) | ||||||
|  | readonly PLATFORMSROOT="${DEVELOPER}/Platforms" | ||||||
|  | readonly LIPO=$(xcrun -sdk iphoneos${SDK} -find lipo) | ||||||
|  | LIBLIST='' | ||||||
|  | DECLIBLIST='' | ||||||
|  | MUXLIBLIST='' | ||||||
|  | DEMUXLIBLIST='' | ||||||
|  |  | ||||||
|  | if [[ -z "${SDK}" ]]; then | ||||||
|  |   echo "iOS SDK not available" | ||||||
|  |   exit 1 | ||||||
|  | elif [[ ${SDK%%.*} -gt 8 ]]; then | ||||||
|  |   EXTRA_CFLAGS="-fembed-bitcode" | ||||||
|  | elif [[ ${SDK%%.*} -le 6 ]]; then | ||||||
|  |   echo "You need iOS SDK version 6.0 or above" | ||||||
|  |   exit 1 | ||||||
|  | fi | ||||||
|  |  | ||||||
|  | echo "Xcode Version: ${XCODE}" | ||||||
|  | echo "iOS SDK Version: ${SDK}" | ||||||
|  |  | ||||||
|  | if [[ -e "${BUILDDIR}" || -e "${TARGETDIR}" || -e "${DECTARGETDIR}" \ | ||||||
|  |       || -e "${MUXTARGETDIR}" || -e "${DEMUXTARGETDIR}" ]]; then | ||||||
|  |   cat << EOF | ||||||
|  | WARNING: The following directories will be deleted: | ||||||
|  | WARNING:   ${BUILDDIR} | ||||||
|  | WARNING:   ${TARGETDIR} | ||||||
|  | WARNING:   ${DECTARGETDIR} | ||||||
|  | WARNING:   ${MUXTARGETDIR} | ||||||
|  | WARNING:   ${DEMUXTARGETDIR} | ||||||
|  | WARNING: The build will continue in 5 seconds... | ||||||
|  | EOF | ||||||
|  |   sleep 5 | ||||||
|  | fi | ||||||
|  | rm -rf ${BUILDDIR} ${TARGETDIR} ${DECTARGETDIR} \ | ||||||
|  |     ${MUXTARGETDIR} ${DEMUXTARGETDIR} | ||||||
|  | mkdir -p ${BUILDDIR} ${TARGETDIR}/Headers/ ${DECTARGETDIR}/Headers/ \ | ||||||
|  |     ${MUXTARGETDIR}/Headers/ ${DEMUXTARGETDIR}/Headers/ | ||||||
|  |  | ||||||
|  | if [[ ! -e ${SRCDIR}/configure ]]; then | ||||||
|  |   if ! (cd ${SRCDIR} && sh autogen.sh); then | ||||||
|  |     cat << EOF | ||||||
|  | Error creating configure script! | ||||||
|  | This script requires the autoconf/automake and libtool to build. MacPorts can | ||||||
|  | be used to obtain these: | ||||||
|  | https://www.macports.org/install.php | ||||||
|  | EOF | ||||||
|  |     exit 1 | ||||||
|  |   fi | ||||||
|  | fi | ||||||
|  |  | ||||||
|  | for PLATFORM in ${PLATFORMS}; do | ||||||
|  |   ARCH2="" | ||||||
|  |   if [[ "${PLATFORM}" == "iPhoneOS-V7-arm64" ]]; then | ||||||
|  |     PLATFORM="iPhoneOS" | ||||||
|  |     ARCH="aarch64" | ||||||
|  |     ARCH2="arm64" | ||||||
|  |   elif [[ "${PLATFORM}" == "iPhoneOS-V7s" ]]; then | ||||||
|  |     PLATFORM="iPhoneOS" | ||||||
|  |     ARCH="armv7s" | ||||||
|  |   elif [[ "${PLATFORM}" == "iPhoneOS-V7" ]]; then | ||||||
|  |     PLATFORM="iPhoneOS" | ||||||
|  |     ARCH="armv7" | ||||||
|  |   elif [[ "${PLATFORM}" == "iPhoneOS-V6" ]]; then | ||||||
|  |     PLATFORM="iPhoneOS" | ||||||
|  |     ARCH="armv6" | ||||||
|  |   elif [[ "${PLATFORM}" == "iPhoneSimulator64" ]]; then | ||||||
|  |     PLATFORM="iPhoneSimulator" | ||||||
|  |     ARCH="x86_64" | ||||||
|  |   else | ||||||
|  |     ARCH="i386" | ||||||
|  |   fi | ||||||
|  |  | ||||||
|  |   ROOTDIR="${BUILDDIR}/${PLATFORM}-${SDK}-${ARCH}" | ||||||
|  |   mkdir -p "${ROOTDIR}" | ||||||
|  |  | ||||||
|  |   DEVROOT="${DEVELOPER}/Toolchains/XcodeDefault.xctoolchain" | ||||||
|  |   SDKROOT="${PLATFORMSROOT}/" | ||||||
|  |   SDKROOT+="${PLATFORM}.platform/Developer/SDKs/${PLATFORM}${SDK}.sdk/" | ||||||
|  |   CFLAGS="-arch ${ARCH2:-${ARCH}} -pipe -isysroot ${SDKROOT} -O3 -DNDEBUG" | ||||||
|  |   CFLAGS+=" -miphoneos-version-min=${IOS_MIN_VERSION} ${EXTRA_CFLAGS}" | ||||||
|  |  | ||||||
|  |   set -x | ||||||
|  |   export PATH="${DEVROOT}/usr/bin:${OLDPATH}" | ||||||
|  |   ${SRCDIR}/configure --host=${ARCH}-apple-darwin --prefix=${ROOTDIR} \ | ||||||
|  |     --build=$(${SRCDIR}/config.guess) \ | ||||||
|  |     --disable-shared --enable-static \ | ||||||
|  |     --enable-libwebpdecoder --enable-swap-16bit-csp \ | ||||||
|  |     --enable-libwebpmux \ | ||||||
|  |     CFLAGS="${CFLAGS}" | ||||||
|  |   set +x | ||||||
|  |  | ||||||
|  |   # Build only the libraries, skip the examples. | ||||||
|  |   make V=0 -C sharpyuv | ||||||
|  |   make V=0 -C src install | ||||||
|  |  | ||||||
|  |   LIBLIST+=" ${ROOTDIR}/lib/libwebp.a" | ||||||
|  |   DECLIBLIST+=" ${ROOTDIR}/lib/libwebpdecoder.a" | ||||||
|  |   MUXLIBLIST+=" ${ROOTDIR}/lib/libwebpmux.a" | ||||||
|  |   DEMUXLIBLIST+=" ${ROOTDIR}/lib/libwebpdemux.a" | ||||||
|  |  | ||||||
|  |   make clean | ||||||
|  |  | ||||||
|  |   export PATH=${OLDPATH} | ||||||
|  | done | ||||||
|  |  | ||||||
|  | echo "LIBLIST = ${LIBLIST}" | ||||||
|  | cp -a ${SRCDIR}/src/webp/{decode,encode,types}.h ${TARGETDIR}/Headers/ | ||||||
|  | ${LIPO} -create ${LIBLIST} -output ${TARGETDIR}/WebP | ||||||
|  |  | ||||||
|  | echo "DECLIBLIST = ${DECLIBLIST}" | ||||||
|  | cp -a ${SRCDIR}/src/webp/{decode,types}.h ${DECTARGETDIR}/Headers/ | ||||||
|  | ${LIPO} -create ${DECLIBLIST} -output ${DECTARGETDIR}/WebPDecoder | ||||||
|  |  | ||||||
|  | echo "MUXLIBLIST = ${MUXLIBLIST}" | ||||||
|  | cp -a ${SRCDIR}/src/webp/{types,mux,mux_types}.h \ | ||||||
|  |     ${MUXTARGETDIR}/Headers/ | ||||||
|  | ${LIPO} -create ${MUXLIBLIST} -output ${MUXTARGETDIR}/WebPMux | ||||||
|  |  | ||||||
|  | echo "DEMUXLIBLIST = ${DEMUXLIBLIST}" | ||||||
|  | cp -a ${SRCDIR}/src/webp/{decode,types,mux_types,demux}.h \ | ||||||
|  |     ${DEMUXTARGETDIR}/Headers/ | ||||||
|  | ${LIPO} -create ${DEMUXLIBLIST} -output ${DEMUXTARGETDIR}/WebPDemux | ||||||
|  |  | ||||||
|  | echo  "SUCCESS" | ||||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user