Compare commits
	
		
			45 Commits
		
	
	
		
			4d09e1fd4a
			...
			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 | |||
| aff239377d | |||
| 3aaa1b0350 | |||
| 823a4ae189 | |||
| 40cd04f9dd | |||
| 6a979d31a0 | |||
| 56f7db9ae6 | |||
| d5e2dd2e1f | |||
| 93e5bb867b | |||
| 4cd295065b | |||
| 5a9aacc603 | |||
| 082c4febdf | |||
| a848a01527 | |||
| 3a1c15f313 | |||
| e92c7cbfa0 | 
							
								
								
									
										3
									
								
								external/CMakeLists.txt
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								external/CMakeLists.txt
									
									
									
									
										vendored
									
									
								
							| @@ -15,3 +15,6 @@ add_subdirectory(./solanaceae_tox) | ||||
| add_subdirectory(./sdl) | ||||
| 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 | ||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user