mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-23 12:51:06 +00:00
Bug 1788119 - Part 4 - Update mp4parse-rust for AVIS support. r=kinetik,glandium,supply-chain-reviewers
Depends on D156652 Differential Revision: https://phabricator.services.mozilla.com/D156653
This commit is contained in:
parent
5c801c6e9e
commit
6e1edc99bb
@ -102,7 +102,7 @@ replace-with = "vendored-sources"
|
||||
|
||||
[source."https://github.com/mozilla/mp4parse-rust"]
|
||||
git = "https://github.com/mozilla/mp4parse-rust"
|
||||
rev = "3bfc47d9a571d0842676043ba60716318e946c06"
|
||||
rev = "eb0b625bd7e888d05ebcfc7685e2501b34c3b374"
|
||||
replace-with = "vendored-sources"
|
||||
|
||||
[source."https://github.com/mozilla/neqo"]
|
||||
|
38
Cargo.lock
generated
38
Cargo.lock
generated
@ -71,7 +71,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b5e9dd62f37dea550caf48c77591dc50bd1a378ce08855be1a0c42a97b7550fb"
|
||||
dependencies = [
|
||||
"android_log-sys",
|
||||
"env_logger 0.9.3",
|
||||
"env_logger",
|
||||
"log",
|
||||
"once_cell",
|
||||
]
|
||||
@ -1564,24 +1564,13 @@ dependencies = [
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "env_logger"
|
||||
version = "0.8.999"
|
||||
dependencies = [
|
||||
"env_logger 0.9.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "env_logger"
|
||||
version = "0.9.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a12e6657c4c97ebab115a42dcee77225f7f482cdd841cf7088c657a42e9e00e7"
|
||||
dependencies = [
|
||||
"atty",
|
||||
"humantime",
|
||||
"log",
|
||||
"regex",
|
||||
"termcolor",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2068,7 +2057,7 @@ name = "gecko_logger"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"app_services_logger",
|
||||
"env_logger 0.9.3",
|
||||
"env_logger",
|
||||
"lazy_static",
|
||||
"log",
|
||||
]
|
||||
@ -2327,7 +2316,7 @@ dependencies = [
|
||||
"bincode",
|
||||
"chrono",
|
||||
"crossbeam-channel",
|
||||
"env_logger 0.9.3",
|
||||
"env_logger",
|
||||
"flate2",
|
||||
"log",
|
||||
"once_cell",
|
||||
@ -2623,12 +2612,6 @@ version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421"
|
||||
|
||||
[[package]]
|
||||
name = "humantime"
|
||||
version = "2.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
|
||||
|
||||
[[package]]
|
||||
name = "hyper"
|
||||
version = "0.14.23"
|
||||
@ -3599,12 +3582,11 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "mp4parse"
|
||||
version = "0.13.0"
|
||||
source = "git+https://github.com/mozilla/mp4parse-rust?rev=3bfc47d9a571d0842676043ba60716318e946c06#3bfc47d9a571d0842676043ba60716318e946c06"
|
||||
version = "0.16.0"
|
||||
source = "git+https://github.com/mozilla/mp4parse-rust?rev=eb0b625bd7e888d05ebcfc7685e2501b34c3b374#eb0b625bd7e888d05ebcfc7685e2501b34c3b374"
|
||||
dependencies = [
|
||||
"bitreader",
|
||||
"byteorder",
|
||||
"env_logger 0.8.999",
|
||||
"fallible_collections",
|
||||
"log",
|
||||
"num-traits",
|
||||
@ -3617,8 +3599,8 @@ version = "0.1.0"
|
||||
|
||||
[[package]]
|
||||
name = "mp4parse_capi"
|
||||
version = "0.13.0"
|
||||
source = "git+https://github.com/mozilla/mp4parse-rust?rev=3bfc47d9a571d0842676043ba60716318e946c06#3bfc47d9a571d0842676043ba60716318e946c06"
|
||||
version = "0.16.0"
|
||||
source = "git+https://github.com/mozilla/mp4parse-rust?rev=eb0b625bd7e888d05ebcfc7685e2501b34c3b374#eb0b625bd7e888d05ebcfc7685e2501b34c3b374"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"fallible_collections",
|
||||
@ -3659,7 +3641,7 @@ version = "0.6.3"
|
||||
source = "git+https://github.com/mozilla/neqo?tag=v0.6.3#4fe628bb911e4437169d974baa628c159e96f879"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"env_logger 0.9.3",
|
||||
"env_logger",
|
||||
"lazy_static",
|
||||
"log",
|
||||
"qlog",
|
||||
@ -4000,7 +3982,7 @@ version = "0.1.4"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"core-foundation",
|
||||
"env_logger 0.9.3",
|
||||
"env_logger",
|
||||
"lazy_static",
|
||||
"libloading",
|
||||
"log",
|
||||
@ -5020,7 +5002,7 @@ name = "smoosh"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"env_logger 0.9.3",
|
||||
"env_logger",
|
||||
"jsparagus",
|
||||
"log",
|
||||
]
|
||||
|
@ -104,9 +104,6 @@ memmap2 = { path = "build/rust/memmap2" }
|
||||
# Patch getrandom 0.7 to 0.8
|
||||
rand = { path = "build/rust/rand" }
|
||||
|
||||
# Patch env_logger 0.8 to 0.9
|
||||
env_logger = { path = "build/rust/env_logger" }
|
||||
|
||||
# Patch parking_lot 0.12 down to 0.11, which is compatible for most crates that use it, to avoid
|
||||
# dependencies on windows-sys.
|
||||
parking_lot = { path = "build/rust/parking_lot" }
|
||||
|
@ -1,19 +0,0 @@
|
||||
[package]
|
||||
name = "env_logger"
|
||||
version = "0.8.999"
|
||||
edition = "2018"
|
||||
license = "MPL-2.0"
|
||||
|
||||
[lib]
|
||||
path = "lib.rs"
|
||||
|
||||
[dependencies.env_logger]
|
||||
version = "0.9"
|
||||
default-features = false
|
||||
|
||||
[features]
|
||||
default = ["env_logger/default"]
|
||||
termcolor = ["env_logger/termcolor"]
|
||||
atty = ["env_logger/atty"]
|
||||
humantime = ["env_logger/humantime"]
|
||||
regex = ["env_logger/regex"]
|
@ -1,5 +0,0 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
pub use env_logger::*;
|
@ -671,10 +671,6 @@ criteria = "safe-to-run"
|
||||
version = "1.0.2"
|
||||
criteria = "safe-to-run"
|
||||
|
||||
[[exemptions.humantime]]
|
||||
version = "2.1.0"
|
||||
criteria = "safe-to-deploy"
|
||||
|
||||
[[exemptions.hyper]]
|
||||
version = "0.14.19"
|
||||
criteria = "safe-to-run"
|
||||
|
@ -1 +0,0 @@
|
||||
{"files":{"Cargo.toml":"c0d1443ae237dee3c09cb70185fa947d8d8cb660acfbcb8f650798bd4e0c019e","LICENSE-APACHE":"c6596eb7be8581c18be736c846fb9173b69eccf6ef94c5135893ec56bd92ba08","LICENSE-MIT":"f6deca8261a8f4a3403dc74c725c46051157fd36c27cd4b100277eb1f303ad11","README.md":"e4bb65f28ddffb11d7eb337e9585947651f2fc11a5e4290f0ca126e21c582c1e","benches/datetime_format.rs":"ffe2e459e9b48e8fdbfb3686f6297257d66b29369ecd6750ae9fbba527ccc681","benches/datetime_parse.rs":"8039c4bd5f1795dbb54e1e39da5988f1d2df6c86c42d8fd378094fc78074d31e","bulk.yaml":"17c2548388e0cd3a63473021a2f1e4ddedee082d79d9167cb31ad06a1890d3fc","src/date.rs":"a8159494372ba8ec8a3a0a5b69c9b185f3e7ab007f283188bf96a6f071151f20","src/duration.rs":"4939ae2d1c3056424de421c4b124d0fb387e058d9abc82a21b83b38d66a40753","src/lib.rs":"ad4dbed28080d9a64ef0100c96b20ff4988d9dde908f56e28ece7252f5932990","src/wrapper.rs":"badc640e77379a42b2fcb728337d60a764b7f00a1b5b1d50c7372ddc20941967","vagga.yaml":"8396fe1510117c1c7bc3e896b62290dcf2dd300346071297018b0077ad9e45ce"},"package":"9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"}
|
37
third_party/rust/humantime/Cargo.toml
vendored
37
third_party/rust/humantime/Cargo.toml
vendored
@ -1,37 +0,0 @@
|
||||
# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
|
||||
#
|
||||
# When uploading crates to the registry Cargo will automatically
|
||||
# "normalize" Cargo.toml files for maximal compatibility
|
||||
# with all versions of Cargo and also rewrite `path` dependencies
|
||||
# to registry (e.g., crates.io) dependencies
|
||||
#
|
||||
# If you believe there's an error in this file please file an
|
||||
# issue against the rust-lang/cargo repository. If you're
|
||||
# editing this file be aware that the upstream Cargo.toml
|
||||
# will likely look very different (and much more reasonable)
|
||||
|
||||
[package]
|
||||
edition = "2018"
|
||||
name = "humantime"
|
||||
version = "2.1.0"
|
||||
authors = ["Paul Colomiets <paul@colomiets.name>"]
|
||||
description = " A parser and formatter for std::time::{Duration, SystemTime}\n"
|
||||
homepage = "https://github.com/tailhook/humantime"
|
||||
documentation = "https://docs.rs/humantime"
|
||||
readme = "README.md"
|
||||
keywords = ["time", "human", "human-friendly", "parser", "duration"]
|
||||
categories = ["date-and-time"]
|
||||
license = "MIT/Apache-2.0"
|
||||
repository = "https://github.com/tailhook/humantime"
|
||||
|
||||
[lib]
|
||||
name = "humantime"
|
||||
path = "src/lib.rs"
|
||||
[dev-dependencies.chrono]
|
||||
version = "0.4"
|
||||
|
||||
[dev-dependencies.rand]
|
||||
version = "0.6"
|
||||
|
||||
[dev-dependencies.time]
|
||||
version = "0.1"
|
202
third_party/rust/humantime/LICENSE-APACHE
vendored
202
third_party/rust/humantime/LICENSE-APACHE
vendored
@ -1,202 +0,0 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor 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, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "{}"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright {yyyy} {name of copyright owner}
|
||||
|
||||
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
|
||||
|
||||
http://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.
|
||||
|
26
third_party/rust/humantime/LICENSE-MIT
vendored
26
third_party/rust/humantime/LICENSE-MIT
vendored
@ -1,26 +0,0 @@
|
||||
Copyright (c) 2016 The humantime Developers
|
||||
|
||||
Includes parts of http date with the following copyright:
|
||||
Copyright (c) 2016 Pyfisch
|
||||
|
||||
Includes portions of musl libc with the following copyright:
|
||||
Copyright © 2005-2013 Rich Felker
|
||||
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
68
third_party/rust/humantime/README.md
vendored
68
third_party/rust/humantime/README.md
vendored
@ -1,68 +0,0 @@
|
||||
Human Time
|
||||
==========
|
||||
|
||||
**Status: stable**
|
||||
|
||||
[Documentation](https://docs.rs/humantime) |
|
||||
[Github](https://github.com/tailhook/humantime) |
|
||||
[Crate](https://crates.io/crates/humantime)
|
||||
|
||||
|
||||
Features:
|
||||
|
||||
* Parses durations in free form like `15days 2min 2s`
|
||||
* Formats durations in similar form `2years 2min 12us`
|
||||
* Parses and formats timestamp in `rfc3339` format: `2018-01-01T12:53:00Z`
|
||||
* Parses timestamps in a weaker format: `2018-01-01 12:53:00`
|
||||
|
||||
Timestamp parsing/formatting is super-fast because format is basically
|
||||
fixed.
|
||||
|
||||
Here are some micro-benchmarks:
|
||||
|
||||
```
|
||||
test result: ok. 0 passed; 0 failed; 26 ignored; 0 measured; 0 filtered out
|
||||
|
||||
Running target/release/deps/datetime_format-8facb4ac832d9770
|
||||
|
||||
running 2 tests
|
||||
test rfc3339_chrono ... bench: 737 ns/iter (+/- 37)
|
||||
test rfc3339_humantime_seconds ... bench: 73 ns/iter (+/- 2)
|
||||
|
||||
test result: ok. 0 passed; 0 failed; 0 ignored; 2 measured; 0 filtered out
|
||||
|
||||
Running target/release/deps/datetime_parse-342628f877d7867c
|
||||
|
||||
running 6 tests
|
||||
test datetime_utc_parse_millis ... bench: 228 ns/iter (+/- 11)
|
||||
test datetime_utc_parse_nanos ... bench: 236 ns/iter (+/- 10)
|
||||
test datetime_utc_parse_seconds ... bench: 204 ns/iter (+/- 18)
|
||||
test rfc3339_humantime_millis ... bench: 28 ns/iter (+/- 1)
|
||||
test rfc3339_humantime_nanos ... bench: 36 ns/iter (+/- 2)
|
||||
test rfc3339_humantime_seconds ... bench: 24 ns/iter (+/- 1)
|
||||
|
||||
test result: ok. 0 passed; 0 failed; 0 ignored; 6 measured; 0 filtered out
|
||||
```
|
||||
|
||||
See [humantime-serde] for serde integration (previous crate [serde-humantime] looks unmaintained).
|
||||
|
||||
[serde-humantime]: https://docs.rs/serde-humantime/0.1.1/serde_humantime/
|
||||
[humantime-serde]: https://docs.rs/humantime-serde
|
||||
|
||||
License
|
||||
=======
|
||||
|
||||
Licensed under either of
|
||||
|
||||
* Apache License, Version 2.0, (./LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
|
||||
* MIT license (./LICENSE-MIT or http://opensource.org/licenses/MIT)
|
||||
|
||||
at your option.
|
||||
|
||||
Contribution
|
||||
------------
|
||||
|
||||
Unless you explicitly state otherwise, any contribution intentionally
|
||||
submitted for inclusion in the work by you, as defined in the Apache-2.0
|
||||
license, shall be dual licensed as above, without any additional terms or
|
||||
conditions.
|
@ -1,56 +0,0 @@
|
||||
#![feature(test)]
|
||||
extern crate test;
|
||||
|
||||
use std::io::Write;
|
||||
use std::time::{Duration, UNIX_EPOCH};
|
||||
|
||||
use humantime::format_rfc3339;
|
||||
|
||||
#[bench]
|
||||
fn rfc3339_humantime_seconds(b: &mut test::Bencher) {
|
||||
let time = UNIX_EPOCH + Duration::new(1_483_228_799, 0);
|
||||
let mut buf = Vec::with_capacity(100);
|
||||
b.iter(|| {
|
||||
buf.truncate(0);
|
||||
write!(&mut buf, "{}", format_rfc3339(time)).unwrap()
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn rfc3339_chrono(b: &mut test::Bencher) {
|
||||
use chrono::{DateTime, NaiveDateTime, Utc};
|
||||
use chrono::format::Item;
|
||||
use chrono::format::Item::*;
|
||||
use chrono::format::Numeric::*;
|
||||
use chrono::format::Fixed::*;
|
||||
use chrono::format::Pad::*;
|
||||
|
||||
let time = DateTime::<Utc>::from_utc(
|
||||
NaiveDateTime::from_timestamp(1_483_228_799, 0), Utc);
|
||||
let mut buf = Vec::with_capacity(100);
|
||||
|
||||
// formatting code from env_logger
|
||||
const ITEMS: &[Item<'static>] = {
|
||||
&[
|
||||
Numeric(Year, Zero),
|
||||
Literal("-"),
|
||||
Numeric(Month, Zero),
|
||||
Literal("-"),
|
||||
Numeric(Day, Zero),
|
||||
Literal("T"),
|
||||
Numeric(Hour, Zero),
|
||||
Literal(":"),
|
||||
Numeric(Minute, Zero),
|
||||
Literal(":"),
|
||||
Numeric(Second, Zero),
|
||||
Fixed(TimezoneOffsetZ),
|
||||
]
|
||||
};
|
||||
|
||||
|
||||
b.iter(|| {
|
||||
buf.truncate(0);
|
||||
write!(&mut buf, "{}", time.format_with_items(ITEMS.iter().cloned()))
|
||||
.unwrap()
|
||||
});
|
||||
}
|
@ -1,47 +0,0 @@
|
||||
#![feature(test)]
|
||||
extern crate test;
|
||||
|
||||
use chrono::{DateTime};
|
||||
use humantime::parse_rfc3339;
|
||||
|
||||
#[bench]
|
||||
fn rfc3339_humantime_seconds(b: &mut test::Bencher) {
|
||||
b.iter(|| {
|
||||
parse_rfc3339("2018-02-13T23:08:32Z").unwrap()
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn datetime_utc_parse_seconds(b: &mut test::Bencher) {
|
||||
b.iter(|| {
|
||||
DateTime::parse_from_rfc3339("2018-02-13T23:08:32Z").unwrap()
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn rfc3339_humantime_millis(b: &mut test::Bencher) {
|
||||
b.iter(|| {
|
||||
parse_rfc3339("2018-02-13T23:08:32.123Z").unwrap()
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn datetime_utc_parse_millis(b: &mut test::Bencher) {
|
||||
b.iter(|| {
|
||||
DateTime::parse_from_rfc3339("2018-02-13T23:08:32.123Z").unwrap()
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn rfc3339_humantime_nanos(b: &mut test::Bencher) {
|
||||
b.iter(|| {
|
||||
parse_rfc3339("2018-02-13T23:08:32.123456983Z").unwrap()
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn datetime_utc_parse_nanos(b: &mut test::Bencher) {
|
||||
b.iter(|| {
|
||||
DateTime::parse_from_rfc3339("2018-02-13T23:08:32.123456983Z").unwrap()
|
||||
});
|
||||
}
|
8
third_party/rust/humantime/bulk.yaml
vendored
8
third_party/rust/humantime/bulk.yaml
vendored
@ -1,8 +0,0 @@
|
||||
minimum-bulk: v0.4.5
|
||||
|
||||
versions:
|
||||
|
||||
- file: Cargo.toml
|
||||
block-start: ^\[package\]
|
||||
block-end: ^\[.*\]
|
||||
regex: ^version\s*=\s*"(\S+)"
|
623
third_party/rust/humantime/src/date.rs
vendored
623
third_party/rust/humantime/src/date.rs
vendored
@ -1,623 +0,0 @@
|
||||
use std::error::Error as StdError;
|
||||
use std::fmt;
|
||||
use std::str;
|
||||
use std::time::{SystemTime, Duration, UNIX_EPOCH};
|
||||
|
||||
#[cfg(target_os="cloudabi")]
|
||||
mod max {
|
||||
pub const SECONDS: u64 = ::std::u64::MAX / 1_000_000_000;
|
||||
#[allow(unused)]
|
||||
pub const TIMESTAMP: &'static str = "2554-07-21T23:34:33Z";
|
||||
}
|
||||
#[cfg(all(
|
||||
target_pointer_width="32",
|
||||
not(target_os="cloudabi"),
|
||||
not(target_os="windows"),
|
||||
not(all(target_arch="wasm32", not(target_os="emscripten")))
|
||||
))]
|
||||
mod max {
|
||||
pub const SECONDS: u64 = ::std::i32::MAX as u64;
|
||||
#[allow(unused)]
|
||||
pub const TIMESTAMP: &'static str = "2038-01-19T03:14:07Z";
|
||||
}
|
||||
|
||||
#[cfg(any(
|
||||
target_pointer_width="64",
|
||||
target_os="windows",
|
||||
all(target_arch="wasm32", not(target_os="emscripten")),
|
||||
))]
|
||||
mod max {
|
||||
pub const SECONDS: u64 = 253_402_300_800-1; // last second of year 9999
|
||||
#[allow(unused)]
|
||||
pub const TIMESTAMP: &str = "9999-12-31T23:59:59Z";
|
||||
}
|
||||
|
||||
/// Error parsing datetime (timestamp)
|
||||
#[derive(Debug, PartialEq, Clone, Copy)]
|
||||
pub enum Error {
|
||||
/// Numeric component is out of range
|
||||
OutOfRange,
|
||||
/// Bad character where digit is expected
|
||||
InvalidDigit,
|
||||
/// Other formatting errors
|
||||
InvalidFormat,
|
||||
}
|
||||
|
||||
impl StdError for Error {}
|
||||
|
||||
impl fmt::Display for Error {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
Error::OutOfRange => write!(f, "numeric component is out of range"),
|
||||
Error::InvalidDigit => write!(f, "bad character where digit is expected"),
|
||||
Error::InvalidFormat => write!(f, "timestamp format is invalid"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
enum Precision {
|
||||
Smart,
|
||||
Seconds,
|
||||
Millis,
|
||||
Micros,
|
||||
Nanos,
|
||||
}
|
||||
|
||||
/// A wrapper type that allows you to Display a SystemTime
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Rfc3339Timestamp(SystemTime, Precision);
|
||||
|
||||
#[inline]
|
||||
fn two_digits(b1: u8, b2: u8) -> Result<u64, Error> {
|
||||
if b1 < b'0' || b2 < b'0' || b1 > b'9' || b2 > b'9' {
|
||||
return Err(Error::InvalidDigit);
|
||||
}
|
||||
Ok(((b1 - b'0')*10 + (b2 - b'0')) as u64)
|
||||
}
|
||||
|
||||
/// Parse RFC3339 timestamp `2018-02-14T00:28:07Z`
|
||||
///
|
||||
/// Supported feature: any precision of fractional
|
||||
/// digits `2018-02-14T00:28:07.133Z`.
|
||||
///
|
||||
/// Unsupported feature: localized timestamps. Only UTC is supported.
|
||||
pub fn parse_rfc3339(s: &str) -> Result<SystemTime, Error> {
|
||||
if s.len() < "2018-02-14T00:28:07Z".len() {
|
||||
return Err(Error::InvalidFormat);
|
||||
}
|
||||
let b = s.as_bytes();
|
||||
if b[10] != b'T' || b[b.len()-1] != b'Z' {
|
||||
return Err(Error::InvalidFormat);
|
||||
}
|
||||
parse_rfc3339_weak(s)
|
||||
}
|
||||
|
||||
/// Parse RFC3339-like timestamp `2018-02-14 00:28:07`
|
||||
///
|
||||
/// Supported features:
|
||||
///
|
||||
/// 1. Any precision of fractional digits `2018-02-14 00:28:07.133`.
|
||||
/// 2. Supports timestamp with or without either of `T` or `Z`
|
||||
/// 3. Anything valid for `parse_3339` is valid for this function
|
||||
///
|
||||
/// Unsupported feature: localized timestamps. Only UTC is supported, even if
|
||||
/// `Z` is not specified.
|
||||
///
|
||||
/// This function is intended to use for parsing human input. Whereas
|
||||
/// `parse_rfc3339` is for strings generated programmatically.
|
||||
pub fn parse_rfc3339_weak(s: &str) -> Result<SystemTime, Error> {
|
||||
if s.len() < "2018-02-14T00:28:07".len() {
|
||||
return Err(Error::InvalidFormat);
|
||||
}
|
||||
let b = s.as_bytes(); // for careless slicing
|
||||
if b[4] != b'-' || b[7] != b'-' || (b[10] != b'T' && b[10] != b' ') ||
|
||||
b[13] != b':' || b[16] != b':'
|
||||
{
|
||||
return Err(Error::InvalidFormat);
|
||||
}
|
||||
let year = two_digits(b[0], b[1])? * 100 + two_digits(b[2], b[3])?;
|
||||
let month = two_digits(b[5], b[6])?;
|
||||
let day = two_digits(b[8], b[9])?;
|
||||
let hour = two_digits(b[11], b[12])?;
|
||||
let minute = two_digits(b[14], b[15])?;
|
||||
let mut second = two_digits(b[17], b[18])?;
|
||||
|
||||
if year < 1970 || hour > 23 || minute > 59 || second > 60 {
|
||||
return Err(Error::OutOfRange);
|
||||
}
|
||||
// TODO(tailhook) should we check that leaps second is only on midnight ?
|
||||
if second == 60 {
|
||||
second = 59
|
||||
};
|
||||
let leap_years = ((year - 1) - 1968) / 4 - ((year - 1) - 1900) / 100 +
|
||||
((year - 1) - 1600) / 400;
|
||||
let leap = is_leap_year(year);
|
||||
let (mut ydays, mdays) = match month {
|
||||
1 => (0, 31),
|
||||
2 if leap => (31, 29),
|
||||
2 => (31, 28),
|
||||
3 => (59, 31),
|
||||
4 => (90, 30),
|
||||
5 => (120, 31),
|
||||
6 => (151, 30),
|
||||
7 => (181, 31),
|
||||
8 => (212, 31),
|
||||
9 => (243, 30),
|
||||
10 => (273, 31),
|
||||
11 => (304, 30),
|
||||
12 => (334, 31),
|
||||
_ => return Err(Error::OutOfRange),
|
||||
};
|
||||
if day > mdays || day == 0 {
|
||||
return Err(Error::OutOfRange);
|
||||
}
|
||||
ydays += day - 1;
|
||||
if leap && month > 2 {
|
||||
ydays += 1;
|
||||
}
|
||||
let days = (year - 1970) * 365 + leap_years + ydays;
|
||||
|
||||
let time = second + minute * 60 + hour * 3600;
|
||||
|
||||
let mut nanos = 0;
|
||||
let mut mult = 100_000_000;
|
||||
if b.get(19) == Some(&b'.') {
|
||||
for idx in 20..b.len() {
|
||||
if b[idx] == b'Z' {
|
||||
if idx == b.len()-1 {
|
||||
break;
|
||||
} else {
|
||||
return Err(Error::InvalidDigit);
|
||||
}
|
||||
}
|
||||
if b[idx] < b'0' || b[idx] > b'9' {
|
||||
return Err(Error::InvalidDigit);
|
||||
}
|
||||
nanos += mult * (b[idx] - b'0') as u32;
|
||||
mult /= 10;
|
||||
}
|
||||
} else if b.len() != 19 && (b.len() > 20 || b[19] != b'Z') {
|
||||
return Err(Error::InvalidFormat);
|
||||
}
|
||||
|
||||
let total_seconds = time + days * 86400;
|
||||
if total_seconds > max::SECONDS {
|
||||
return Err(Error::OutOfRange);
|
||||
}
|
||||
|
||||
Ok(UNIX_EPOCH + Duration::new(total_seconds, nanos))
|
||||
}
|
||||
|
||||
fn is_leap_year(y: u64) -> bool {
|
||||
y % 4 == 0 && (y % 100 != 0 || y % 400 == 0)
|
||||
}
|
||||
|
||||
/// Format an RFC3339 timestamp `2018-02-14T00:28:07Z`
|
||||
///
|
||||
/// This function formats timestamp with smart precision: i.e. if it has no
|
||||
/// fractional seconds, they aren't written at all. And up to nine digits if
|
||||
/// they are.
|
||||
///
|
||||
/// The value is always UTC and ignores system timezone.
|
||||
pub fn format_rfc3339(system_time: SystemTime) -> Rfc3339Timestamp {
|
||||
Rfc3339Timestamp(system_time, Precision::Smart)
|
||||
}
|
||||
|
||||
/// Format an RFC3339 timestamp `2018-02-14T00:28:07Z`
|
||||
///
|
||||
/// This format always shows timestamp without fractional seconds.
|
||||
///
|
||||
/// The value is always UTC and ignores system timezone.
|
||||
pub fn format_rfc3339_seconds(system_time: SystemTime) -> Rfc3339Timestamp {
|
||||
Rfc3339Timestamp(system_time, Precision::Seconds)
|
||||
}
|
||||
|
||||
/// Format an RFC3339 timestamp `2018-02-14T00:28:07.000Z`
|
||||
///
|
||||
/// This format always shows milliseconds even if millisecond value is zero.
|
||||
///
|
||||
/// The value is always UTC and ignores system timezone.
|
||||
pub fn format_rfc3339_millis(system_time: SystemTime) -> Rfc3339Timestamp {
|
||||
Rfc3339Timestamp(system_time, Precision::Millis)
|
||||
}
|
||||
|
||||
/// Format an RFC3339 timestamp `2018-02-14T00:28:07.000000Z`
|
||||
///
|
||||
/// This format always shows microseconds even if microsecond value is zero.
|
||||
///
|
||||
/// The value is always UTC and ignores system timezone.
|
||||
pub fn format_rfc3339_micros(system_time: SystemTime) -> Rfc3339Timestamp {
|
||||
Rfc3339Timestamp(system_time, Precision::Micros)
|
||||
}
|
||||
|
||||
/// Format an RFC3339 timestamp `2018-02-14T00:28:07.000000000Z`
|
||||
///
|
||||
/// This format always shows nanoseconds even if nanosecond value is zero.
|
||||
///
|
||||
/// The value is always UTC and ignores system timezone.
|
||||
pub fn format_rfc3339_nanos(system_time: SystemTime) -> Rfc3339Timestamp {
|
||||
Rfc3339Timestamp(system_time, Precision::Nanos)
|
||||
}
|
||||
|
||||
impl Rfc3339Timestamp {
|
||||
/// Returns a reference to the [`SystemTime`][] that is being formatted.
|
||||
pub fn get_ref(&self) -> &SystemTime {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Rfc3339Timestamp {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
use self::Precision::*;
|
||||
|
||||
let dur = self.0.duration_since(UNIX_EPOCH)
|
||||
.expect("all times should be after the epoch");
|
||||
let secs_since_epoch = dur.as_secs();
|
||||
let nanos = dur.subsec_nanos();
|
||||
|
||||
if secs_since_epoch >= 253_402_300_800 { // year 9999
|
||||
return Err(fmt::Error);
|
||||
}
|
||||
|
||||
/* 2000-03-01 (mod 400 year, immediately after feb29 */
|
||||
const LEAPOCH: i64 = 11017;
|
||||
const DAYS_PER_400Y: i64 = 365*400 + 97;
|
||||
const DAYS_PER_100Y: i64 = 365*100 + 24;
|
||||
const DAYS_PER_4Y: i64 = 365*4 + 1;
|
||||
|
||||
let days = (secs_since_epoch / 86400) as i64 - LEAPOCH;
|
||||
let secs_of_day = secs_since_epoch % 86400;
|
||||
|
||||
let mut qc_cycles = days / DAYS_PER_400Y;
|
||||
let mut remdays = days % DAYS_PER_400Y;
|
||||
|
||||
if remdays < 0 {
|
||||
remdays += DAYS_PER_400Y;
|
||||
qc_cycles -= 1;
|
||||
}
|
||||
|
||||
let mut c_cycles = remdays / DAYS_PER_100Y;
|
||||
if c_cycles == 4 { c_cycles -= 1; }
|
||||
remdays -= c_cycles * DAYS_PER_100Y;
|
||||
|
||||
let mut q_cycles = remdays / DAYS_PER_4Y;
|
||||
if q_cycles == 25 { q_cycles -= 1; }
|
||||
remdays -= q_cycles * DAYS_PER_4Y;
|
||||
|
||||
let mut remyears = remdays / 365;
|
||||
if remyears == 4 { remyears -= 1; }
|
||||
remdays -= remyears * 365;
|
||||
|
||||
let mut year = 2000 +
|
||||
remyears + 4*q_cycles + 100*c_cycles + 400*qc_cycles;
|
||||
|
||||
let months = [31,30,31,30,31,31,30,31,30,31,31,29];
|
||||
let mut mon = 0;
|
||||
for mon_len in months.iter() {
|
||||
mon += 1;
|
||||
if remdays < *mon_len {
|
||||
break;
|
||||
}
|
||||
remdays -= *mon_len;
|
||||
}
|
||||
let mday = remdays+1;
|
||||
let mon = if mon + 2 > 12 {
|
||||
year += 1;
|
||||
mon - 10
|
||||
} else {
|
||||
mon + 2
|
||||
};
|
||||
|
||||
let mut buf: [u8; 30] = [
|
||||
// Too long to write as: b"0000-00-00T00:00:00.000000000Z"
|
||||
b'0', b'0', b'0', b'0', b'-', b'0', b'0', b'-', b'0', b'0', b'T',
|
||||
b'0', b'0', b':', b'0', b'0', b':', b'0', b'0',
|
||||
b'.', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'0', b'Z',
|
||||
];
|
||||
buf[0] = b'0' + (year / 1000) as u8;
|
||||
buf[1] = b'0' + (year / 100 % 10) as u8;
|
||||
buf[2] = b'0' + (year / 10 % 10) as u8;
|
||||
buf[3] = b'0' + (year % 10) as u8;
|
||||
buf[5] = b'0' + (mon / 10) as u8;
|
||||
buf[6] = b'0' + (mon % 10) as u8;
|
||||
buf[8] = b'0' + (mday / 10) as u8;
|
||||
buf[9] = b'0' + (mday % 10) as u8;
|
||||
buf[11] = b'0' + (secs_of_day / 3600 / 10) as u8;
|
||||
buf[12] = b'0' + (secs_of_day / 3600 % 10) as u8;
|
||||
buf[14] = b'0' + (secs_of_day / 60 / 10 % 6) as u8;
|
||||
buf[15] = b'0' + (secs_of_day / 60 % 10) as u8;
|
||||
buf[17] = b'0' + (secs_of_day / 10 % 6) as u8;
|
||||
buf[18] = b'0' + (secs_of_day % 10) as u8;
|
||||
|
||||
let offset = if self.1 == Seconds || nanos == 0 && self.1 == Smart {
|
||||
buf[19] = b'Z';
|
||||
19
|
||||
} else if self.1 == Millis {
|
||||
buf[20] = b'0' + (nanos / 100_000_000) as u8;
|
||||
buf[21] = b'0' + (nanos / 10_000_000 % 10) as u8;
|
||||
buf[22] = b'0' + (nanos / 1_000_000 % 10) as u8;
|
||||
buf[23] = b'Z';
|
||||
23
|
||||
} else if self.1 == Micros {
|
||||
buf[20] = b'0' + (nanos / 100_000_000) as u8;
|
||||
buf[21] = b'0' + (nanos / 10_000_000 % 10) as u8;
|
||||
buf[22] = b'0' + (nanos / 1_000_000 % 10) as u8;
|
||||
buf[23] = b'0' + (nanos / 100_000 % 10) as u8;
|
||||
buf[24] = b'0' + (nanos / 10_000 % 10) as u8;
|
||||
buf[25] = b'0' + (nanos / 1_000 % 10) as u8;
|
||||
buf[26] = b'Z';
|
||||
26
|
||||
} else {
|
||||
buf[20] = b'0' + (nanos / 100_000_000) as u8;
|
||||
buf[21] = b'0' + (nanos / 10_000_000 % 10) as u8;
|
||||
buf[22] = b'0' + (nanos / 1_000_000 % 10) as u8;
|
||||
buf[23] = b'0' + (nanos / 100_000 % 10) as u8;
|
||||
buf[24] = b'0' + (nanos / 10_000 % 10) as u8;
|
||||
buf[25] = b'0' + (nanos / 1_000 % 10) as u8;
|
||||
buf[26] = b'0' + (nanos / 100 % 10) as u8;
|
||||
buf[27] = b'0' + (nanos / 10 % 10) as u8;
|
||||
buf[28] = b'0' + (nanos / 1 % 10) as u8;
|
||||
// 29th is 'Z'
|
||||
29
|
||||
};
|
||||
|
||||
// we know our chars are all ascii
|
||||
f.write_str(str::from_utf8(&buf[..=offset]).expect("Conversion to utf8 failed"))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use std::str::from_utf8;
|
||||
use std::time::{UNIX_EPOCH, SystemTime, Duration};
|
||||
|
||||
use rand::Rng;
|
||||
|
||||
use super::{parse_rfc3339, parse_rfc3339_weak, format_rfc3339};
|
||||
use super::{format_rfc3339_millis, format_rfc3339_micros};
|
||||
use super::{format_rfc3339_nanos};
|
||||
use super::max;
|
||||
|
||||
fn from_sec(sec: u64) -> (String, SystemTime) {
|
||||
let s = time::at_utc(time::Timespec { sec: sec as i64, nsec: 0 })
|
||||
.rfc3339().to_string();
|
||||
let time = UNIX_EPOCH + Duration::new(sec, 0);
|
||||
(s, time)
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(all(target_pointer_width="32", target_os="linux"))]
|
||||
fn year_after_2038_fails_gracefully() {
|
||||
// next second
|
||||
assert_eq!(parse_rfc3339("2038-01-19T03:14:08Z").unwrap_err(),
|
||||
super::Error::OutOfRange);
|
||||
assert_eq!(parse_rfc3339("9999-12-31T23:59:59Z").unwrap_err(),
|
||||
super::Error::OutOfRange);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn smoke_tests_parse() {
|
||||
assert_eq!(parse_rfc3339("1970-01-01T00:00:00Z").unwrap(),
|
||||
UNIX_EPOCH + Duration::new(0, 0));
|
||||
assert_eq!(parse_rfc3339("1970-01-01T00:00:01Z").unwrap(),
|
||||
UNIX_EPOCH + Duration::new(1, 0));
|
||||
assert_eq!(parse_rfc3339("2018-02-13T23:08:32Z").unwrap(),
|
||||
UNIX_EPOCH + Duration::new(1_518_563_312, 0));
|
||||
assert_eq!(parse_rfc3339("2012-01-01T00:00:00Z").unwrap(),
|
||||
UNIX_EPOCH + Duration::new(1_325_376_000, 0));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn smoke_tests_format() {
|
||||
assert_eq!(
|
||||
format_rfc3339(UNIX_EPOCH + Duration::new(0, 0)).to_string(),
|
||||
"1970-01-01T00:00:00Z");
|
||||
assert_eq!(
|
||||
format_rfc3339(UNIX_EPOCH + Duration::new(1, 0)).to_string(),
|
||||
"1970-01-01T00:00:01Z");
|
||||
assert_eq!(
|
||||
format_rfc3339(UNIX_EPOCH + Duration::new(1_518_563_312, 0)).to_string(),
|
||||
"2018-02-13T23:08:32Z");
|
||||
assert_eq!(
|
||||
format_rfc3339(UNIX_EPOCH + Duration::new(1_325_376_000, 0)).to_string(),
|
||||
"2012-01-01T00:00:00Z");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn smoke_tests_format_millis() {
|
||||
assert_eq!(
|
||||
format_rfc3339_millis(UNIX_EPOCH +
|
||||
Duration::new(0, 0)).to_string(),
|
||||
"1970-01-01T00:00:00.000Z");
|
||||
assert_eq!(
|
||||
format_rfc3339_millis(UNIX_EPOCH +
|
||||
Duration::new(1_518_563_312, 123_000_000)).to_string(),
|
||||
"2018-02-13T23:08:32.123Z");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn smoke_tests_format_micros() {
|
||||
assert_eq!(
|
||||
format_rfc3339_micros(UNIX_EPOCH +
|
||||
Duration::new(0, 0)).to_string(),
|
||||
"1970-01-01T00:00:00.000000Z");
|
||||
assert_eq!(
|
||||
format_rfc3339_micros(UNIX_EPOCH +
|
||||
Duration::new(1_518_563_312, 123_000_000)).to_string(),
|
||||
"2018-02-13T23:08:32.123000Z");
|
||||
assert_eq!(
|
||||
format_rfc3339_micros(UNIX_EPOCH +
|
||||
Duration::new(1_518_563_312, 456_123_000)).to_string(),
|
||||
"2018-02-13T23:08:32.456123Z");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn smoke_tests_format_nanos() {
|
||||
assert_eq!(
|
||||
format_rfc3339_nanos(UNIX_EPOCH +
|
||||
Duration::new(0, 0)).to_string(),
|
||||
"1970-01-01T00:00:00.000000000Z");
|
||||
assert_eq!(
|
||||
format_rfc3339_nanos(UNIX_EPOCH +
|
||||
Duration::new(1_518_563_312, 123_000_000)).to_string(),
|
||||
"2018-02-13T23:08:32.123000000Z");
|
||||
assert_eq!(
|
||||
format_rfc3339_nanos(UNIX_EPOCH +
|
||||
Duration::new(1_518_563_312, 789_456_123)).to_string(),
|
||||
"2018-02-13T23:08:32.789456123Z");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn upper_bound() {
|
||||
let max = UNIX_EPOCH + Duration::new(max::SECONDS, 0);
|
||||
assert_eq!(parse_rfc3339(&max::TIMESTAMP).unwrap(), max);
|
||||
assert_eq!(format_rfc3339(max).to_string(), max::TIMESTAMP);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn leap_second() {
|
||||
assert_eq!(parse_rfc3339("2016-12-31T23:59:60Z").unwrap(),
|
||||
UNIX_EPOCH + Duration::new(1_483_228_799, 0));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn first_731_days() {
|
||||
let year_start = 0; // 1970
|
||||
for day in 0..= 365 * 2 { // scan leap year and non-leap year
|
||||
let (s, time) = from_sec(year_start + day * 86400);
|
||||
assert_eq!(parse_rfc3339(&s).unwrap(), time);
|
||||
assert_eq!(format_rfc3339(time).to_string(), s);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn the_731_consecutive_days() {
|
||||
let year_start = 1_325_376_000; // 2012
|
||||
for day in 0..= 365 * 2 { // scan leap year and non-leap year
|
||||
let (s, time) = from_sec(year_start + day * 86400);
|
||||
assert_eq!(parse_rfc3339(&s).unwrap(), time);
|
||||
assert_eq!(format_rfc3339(time).to_string(), s);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn all_86400_seconds() {
|
||||
let day_start = 1_325_376_000;
|
||||
for second in 0..86400 { // scan leap year and non-leap year
|
||||
let (s, time) = from_sec(day_start + second);
|
||||
assert_eq!(parse_rfc3339(&s).unwrap(), time);
|
||||
assert_eq!(format_rfc3339(time).to_string(), s);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn random_past() {
|
||||
let upper = SystemTime::now().duration_since(UNIX_EPOCH).unwrap()
|
||||
.as_secs();
|
||||
for _ in 0..10000 {
|
||||
let sec = rand::thread_rng().gen_range(0, upper);
|
||||
let (s, time) = from_sec(sec);
|
||||
assert_eq!(parse_rfc3339(&s).unwrap(), time);
|
||||
assert_eq!(format_rfc3339(time).to_string(), s);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn random_wide_range() {
|
||||
for _ in 0..100_000 {
|
||||
let sec = rand::thread_rng().gen_range(0, max::SECONDS);
|
||||
let (s, time) = from_sec(sec);
|
||||
assert_eq!(parse_rfc3339(&s).unwrap(), time);
|
||||
assert_eq!(format_rfc3339(time).to_string(), s);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn milliseconds() {
|
||||
assert_eq!(parse_rfc3339("1970-01-01T00:00:00.123Z").unwrap(),
|
||||
UNIX_EPOCH + Duration::new(0, 123_000_000));
|
||||
assert_eq!(format_rfc3339(UNIX_EPOCH + Duration::new(0, 123_000_000))
|
||||
.to_string(), "1970-01-01T00:00:00.123000000Z");
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic(expected="OutOfRange")]
|
||||
fn zero_month() {
|
||||
parse_rfc3339("1970-00-01T00:00:00Z").unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic(expected="OutOfRange")]
|
||||
fn big_month() {
|
||||
parse_rfc3339("1970-32-01T00:00:00Z").unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic(expected="OutOfRange")]
|
||||
fn zero_day() {
|
||||
parse_rfc3339("1970-01-00T00:00:00Z").unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic(expected="OutOfRange")]
|
||||
fn big_day() {
|
||||
parse_rfc3339("1970-12-35T00:00:00Z").unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic(expected="OutOfRange")]
|
||||
fn big_day2() {
|
||||
parse_rfc3339("1970-02-30T00:00:00Z").unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic(expected="OutOfRange")]
|
||||
fn big_second() {
|
||||
parse_rfc3339("1970-12-30T00:00:78Z").unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic(expected="OutOfRange")]
|
||||
fn big_minute() {
|
||||
parse_rfc3339("1970-12-30T00:78:00Z").unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic(expected="OutOfRange")]
|
||||
fn big_hour() {
|
||||
parse_rfc3339("1970-12-30T24:00:00Z").unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn break_data() {
|
||||
for pos in 0.."2016-12-31T23:59:60Z".len() {
|
||||
let mut s = b"2016-12-31T23:59:60Z".to_vec();
|
||||
s[pos] = b'x';
|
||||
parse_rfc3339(from_utf8(&s).unwrap()).unwrap_err();
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn weak_smoke_tests() {
|
||||
assert_eq!(parse_rfc3339_weak("1970-01-01 00:00:00").unwrap(),
|
||||
UNIX_EPOCH + Duration::new(0, 0));
|
||||
parse_rfc3339("1970-01-01 00:00:00").unwrap_err();
|
||||
|
||||
assert_eq!(parse_rfc3339_weak("1970-01-01 00:00:00.000123").unwrap(),
|
||||
UNIX_EPOCH + Duration::new(0, 123_000));
|
||||
parse_rfc3339("1970-01-01 00:00:00.000123").unwrap_err();
|
||||
|
||||
assert_eq!(parse_rfc3339_weak("1970-01-01T00:00:00.000123").unwrap(),
|
||||
UNIX_EPOCH + Duration::new(0, 123_000));
|
||||
parse_rfc3339("1970-01-01T00:00:00.000123").unwrap_err();
|
||||
|
||||
assert_eq!(parse_rfc3339_weak("1970-01-01 00:00:00.000123Z").unwrap(),
|
||||
UNIX_EPOCH + Duration::new(0, 123_000));
|
||||
parse_rfc3339("1970-01-01 00:00:00.000123Z").unwrap_err();
|
||||
|
||||
assert_eq!(parse_rfc3339_weak("1970-01-01 00:00:00Z").unwrap(),
|
||||
UNIX_EPOCH + Duration::new(0, 0));
|
||||
parse_rfc3339("1970-01-01 00:00:00Z").unwrap_err();
|
||||
}
|
||||
}
|
456
third_party/rust/humantime/src/duration.rs
vendored
456
third_party/rust/humantime/src/duration.rs
vendored
@ -1,456 +0,0 @@
|
||||
use std::error::Error as StdError;
|
||||
use std::fmt;
|
||||
use std::str::Chars;
|
||||
use std::time::Duration;
|
||||
|
||||
/// Error parsing human-friendly duration
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
pub enum Error {
|
||||
/// Invalid character during parsing
|
||||
///
|
||||
/// More specifically anything that is not alphanumeric is prohibited
|
||||
///
|
||||
/// The field is an byte offset of the character in the string.
|
||||
InvalidCharacter(usize),
|
||||
/// Non-numeric value where number is expected
|
||||
///
|
||||
/// This usually means that either time unit is broken into words,
|
||||
/// e.g. `m sec` instead of `msec`, or just number is omitted,
|
||||
/// for example `2 hours min` instead of `2 hours 1 min`
|
||||
///
|
||||
/// The field is an byte offset of the errorneous character
|
||||
/// in the string.
|
||||
NumberExpected(usize),
|
||||
/// Unit in the number is not one of allowed units
|
||||
///
|
||||
/// See documentation of `parse_duration` for the list of supported
|
||||
/// time units.
|
||||
///
|
||||
/// The two fields are start and end (exclusive) of the slice from
|
||||
/// the original string, containing errorneous value
|
||||
UnknownUnit {
|
||||
/// Start of the invalid unit inside the original string
|
||||
start: usize,
|
||||
/// End of the invalid unit inside the original string
|
||||
end: usize,
|
||||
/// The unit verbatim
|
||||
unit: String,
|
||||
/// A number associated with the unit
|
||||
value: u64,
|
||||
},
|
||||
/// The numeric value is too large
|
||||
///
|
||||
/// Usually this means value is too large to be useful. If user writes
|
||||
/// data in subsecond units, then the maximum is about 3k years. When
|
||||
/// using seconds, or larger units, the limit is even larger.
|
||||
NumberOverflow,
|
||||
/// The value was an empty string (or consists only whitespace)
|
||||
Empty,
|
||||
}
|
||||
|
||||
impl StdError for Error {}
|
||||
|
||||
impl fmt::Display for Error {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
Error::InvalidCharacter(offset) => write!(f, "invalid character at {}", offset),
|
||||
Error::NumberExpected(offset) => write!(f, "expected number at {}", offset),
|
||||
Error::UnknownUnit { unit, value, .. } if &unit == &"" => {
|
||||
write!(f,
|
||||
"time unit needed, for example {0}sec or {0}ms",
|
||||
value,
|
||||
)
|
||||
}
|
||||
Error::UnknownUnit { unit, .. } => {
|
||||
write!(
|
||||
f,
|
||||
"unknown time unit {:?}, \
|
||||
supported units: ns, us, ms, sec, min, hours, days, \
|
||||
weeks, months, years (and few variations)",
|
||||
unit
|
||||
)
|
||||
}
|
||||
Error::NumberOverflow => write!(f, "number is too large"),
|
||||
Error::Empty => write!(f, "value was empty"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A wrapper type that allows you to Display a Duration
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct FormattedDuration(Duration);
|
||||
|
||||
trait OverflowOp: Sized {
|
||||
fn mul(self, other: Self) -> Result<Self, Error>;
|
||||
fn add(self, other: Self) -> Result<Self, Error>;
|
||||
}
|
||||
|
||||
impl OverflowOp for u64 {
|
||||
fn mul(self, other: Self) -> Result<Self, Error> {
|
||||
self.checked_mul(other).ok_or(Error::NumberOverflow)
|
||||
}
|
||||
fn add(self, other: Self) -> Result<Self, Error> {
|
||||
self.checked_add(other).ok_or(Error::NumberOverflow)
|
||||
}
|
||||
}
|
||||
|
||||
struct Parser<'a> {
|
||||
iter: Chars<'a>,
|
||||
src: &'a str,
|
||||
current: (u64, u64),
|
||||
}
|
||||
|
||||
impl<'a> Parser<'a> {
|
||||
fn off(&self) -> usize {
|
||||
self.src.len() - self.iter.as_str().len()
|
||||
}
|
||||
|
||||
fn parse_first_char(&mut self) -> Result<Option<u64>, Error> {
|
||||
let off = self.off();
|
||||
for c in self.iter.by_ref() {
|
||||
match c {
|
||||
'0'..='9' => {
|
||||
return Ok(Some(c as u64 - '0' as u64));
|
||||
}
|
||||
c if c.is_whitespace() => continue,
|
||||
_ => {
|
||||
return Err(Error::NumberExpected(off));
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(None)
|
||||
}
|
||||
fn parse_unit(&mut self, n: u64, start: usize, end: usize)
|
||||
-> Result<(), Error>
|
||||
{
|
||||
let (mut sec, nsec) = match &self.src[start..end] {
|
||||
"nanos" | "nsec" | "ns" => (0u64, n),
|
||||
"usec" | "us" => (0u64, n.mul(1000)?),
|
||||
"millis" | "msec" | "ms" => (0u64, n.mul(1_000_000)?),
|
||||
"seconds" | "second" | "secs" | "sec" | "s" => (n, 0),
|
||||
"minutes" | "minute" | "min" | "mins" | "m"
|
||||
=> (n.mul(60)?, 0),
|
||||
"hours" | "hour" | "hr" | "hrs" | "h" => (n.mul(3600)?, 0),
|
||||
"days" | "day" | "d" => (n.mul(86400)?, 0),
|
||||
"weeks" | "week" | "w" => (n.mul(86400*7)?, 0),
|
||||
"months" | "month" | "M" => (n.mul(2_630_016)?, 0), // 30.44d
|
||||
"years" | "year" | "y" => (n.mul(31_557_600)?, 0), // 365.25d
|
||||
_ => {
|
||||
return Err(Error::UnknownUnit {
|
||||
start, end,
|
||||
unit: self.src[start..end].to_string(),
|
||||
value: n,
|
||||
});
|
||||
}
|
||||
};
|
||||
let mut nsec = self.current.1.add(nsec)?;
|
||||
if nsec > 1_000_000_000 {
|
||||
sec = sec.add(nsec / 1_000_000_000)?;
|
||||
nsec %= 1_000_000_000;
|
||||
}
|
||||
sec = self.current.0.add(sec)?;
|
||||
self.current = (sec, nsec);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn parse(mut self) -> Result<Duration, Error> {
|
||||
let mut n = self.parse_first_char()?.ok_or(Error::Empty)?;
|
||||
'outer: loop {
|
||||
let mut off = self.off();
|
||||
while let Some(c) = self.iter.next() {
|
||||
match c {
|
||||
'0'..='9' => {
|
||||
n = n.checked_mul(10)
|
||||
.and_then(|x| x.checked_add(c as u64 - '0' as u64))
|
||||
.ok_or(Error::NumberOverflow)?;
|
||||
}
|
||||
c if c.is_whitespace() => {}
|
||||
'a'..='z' | 'A'..='Z' => {
|
||||
break;
|
||||
}
|
||||
_ => {
|
||||
return Err(Error::InvalidCharacter(off));
|
||||
}
|
||||
}
|
||||
off = self.off();
|
||||
}
|
||||
let start = off;
|
||||
let mut off = self.off();
|
||||
while let Some(c) = self.iter.next() {
|
||||
match c {
|
||||
'0'..='9' => {
|
||||
self.parse_unit(n, start, off)?;
|
||||
n = c as u64 - '0' as u64;
|
||||
continue 'outer;
|
||||
}
|
||||
c if c.is_whitespace() => break,
|
||||
'a'..='z' | 'A'..='Z' => {}
|
||||
_ => {
|
||||
return Err(Error::InvalidCharacter(off));
|
||||
}
|
||||
}
|
||||
off = self.off();
|
||||
}
|
||||
self.parse_unit(n, start, off)?;
|
||||
n = match self.parse_first_char()? {
|
||||
Some(n) => n,
|
||||
None => return Ok(
|
||||
Duration::new(self.current.0, self.current.1 as u32)),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// Parse duration object `1hour 12min 5s`
|
||||
///
|
||||
/// The duration object is a concatenation of time spans. Where each time
|
||||
/// span is an integer number and a suffix. Supported suffixes:
|
||||
///
|
||||
/// * `nsec`, `ns` -- nanoseconds
|
||||
/// * `usec`, `us` -- microseconds
|
||||
/// * `msec`, `ms` -- milliseconds
|
||||
/// * `seconds`, `second`, `sec`, `s`
|
||||
/// * `minutes`, `minute`, `min`, `m`
|
||||
/// * `hours`, `hour`, `hr`, `h`
|
||||
/// * `days`, `day`, `d`
|
||||
/// * `weeks`, `week`, `w`
|
||||
/// * `months`, `month`, `M` -- defined as 30.44 days
|
||||
/// * `years`, `year`, `y` -- defined as 365.25 days
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::time::Duration;
|
||||
/// use humantime::parse_duration;
|
||||
///
|
||||
/// assert_eq!(parse_duration("2h 37min"), Ok(Duration::new(9420, 0)));
|
||||
/// assert_eq!(parse_duration("32ms"), Ok(Duration::new(0, 32_000_000)));
|
||||
/// ```
|
||||
pub fn parse_duration(s: &str) -> Result<Duration, Error> {
|
||||
Parser {
|
||||
iter: s.chars(),
|
||||
src: s,
|
||||
current: (0, 0),
|
||||
}.parse()
|
||||
}
|
||||
|
||||
/// Formats duration into a human-readable string
|
||||
///
|
||||
/// Note: this format is guaranteed to have same value when using
|
||||
/// parse_duration, but we can change some details of the exact composition
|
||||
/// of the value.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::time::Duration;
|
||||
/// use humantime::format_duration;
|
||||
///
|
||||
/// let val1 = Duration::new(9420, 0);
|
||||
/// assert_eq!(format_duration(val1).to_string(), "2h 37m");
|
||||
/// let val2 = Duration::new(0, 32_000_000);
|
||||
/// assert_eq!(format_duration(val2).to_string(), "32ms");
|
||||
/// ```
|
||||
pub fn format_duration(val: Duration) -> FormattedDuration {
|
||||
FormattedDuration(val)
|
||||
}
|
||||
|
||||
fn item_plural(f: &mut fmt::Formatter, started: &mut bool,
|
||||
name: &str, value: u64)
|
||||
-> fmt::Result
|
||||
{
|
||||
if value > 0 {
|
||||
if *started {
|
||||
f.write_str(" ")?;
|
||||
}
|
||||
write!(f, "{}{}", value, name)?;
|
||||
if value > 1 {
|
||||
f.write_str("s")?;
|
||||
}
|
||||
*started = true;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
fn item(f: &mut fmt::Formatter, started: &mut bool, name: &str, value: u32)
|
||||
-> fmt::Result
|
||||
{
|
||||
if value > 0 {
|
||||
if *started {
|
||||
f.write_str(" ")?;
|
||||
}
|
||||
write!(f, "{}{}", value, name)?;
|
||||
*started = true;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
impl FormattedDuration {
|
||||
/// Returns a reference to the [`Duration`][] that is being formatted.
|
||||
pub fn get_ref(&self) -> &Duration {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for FormattedDuration {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
let secs = self.0.as_secs();
|
||||
let nanos = self.0.subsec_nanos();
|
||||
|
||||
if secs == 0 && nanos == 0 {
|
||||
f.write_str("0s")?;
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let years = secs / 31_557_600; // 365.25d
|
||||
let ydays = secs % 31_557_600;
|
||||
let months = ydays / 2_630_016; // 30.44d
|
||||
let mdays = ydays % 2_630_016;
|
||||
let days = mdays / 86400;
|
||||
let day_secs = mdays % 86400;
|
||||
let hours = day_secs / 3600;
|
||||
let minutes = day_secs % 3600 / 60;
|
||||
let seconds = day_secs % 60;
|
||||
|
||||
let millis = nanos / 1_000_000;
|
||||
let micros = nanos / 1000 % 1000;
|
||||
let nanosec = nanos % 1000;
|
||||
|
||||
let ref mut started = false;
|
||||
item_plural(f, started, "year", years)?;
|
||||
item_plural(f, started, "month", months)?;
|
||||
item_plural(f, started, "day", days)?;
|
||||
item(f, started, "h", hours as u32)?;
|
||||
item(f, started, "m", minutes as u32)?;
|
||||
item(f, started, "s", seconds as u32)?;
|
||||
item(f, started, "ms", millis)?;
|
||||
item(f, started, "us", micros)?;
|
||||
item(f, started, "ns", nanosec)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use std::time::Duration;
|
||||
|
||||
use rand::Rng;
|
||||
|
||||
use super::{parse_duration, format_duration};
|
||||
use super::Error;
|
||||
|
||||
#[test]
|
||||
#[allow(clippy::cognitive_complexity)]
|
||||
fn test_units() {
|
||||
assert_eq!(parse_duration("17nsec"), Ok(Duration::new(0, 17)));
|
||||
assert_eq!(parse_duration("17nanos"), Ok(Duration::new(0, 17)));
|
||||
assert_eq!(parse_duration("33ns"), Ok(Duration::new(0, 33)));
|
||||
assert_eq!(parse_duration("3usec"), Ok(Duration::new(0, 3000)));
|
||||
assert_eq!(parse_duration("78us"), Ok(Duration::new(0, 78000)));
|
||||
assert_eq!(parse_duration("31msec"), Ok(Duration::new(0, 31_000_000)));
|
||||
assert_eq!(parse_duration("31millis"), Ok(Duration::new(0, 31_000_000)));
|
||||
assert_eq!(parse_duration("6ms"), Ok(Duration::new(0, 6_000_000)));
|
||||
assert_eq!(parse_duration("3000s"), Ok(Duration::new(3000, 0)));
|
||||
assert_eq!(parse_duration("300sec"), Ok(Duration::new(300, 0)));
|
||||
assert_eq!(parse_duration("300secs"), Ok(Duration::new(300, 0)));
|
||||
assert_eq!(parse_duration("50seconds"), Ok(Duration::new(50, 0)));
|
||||
assert_eq!(parse_duration("1second"), Ok(Duration::new(1, 0)));
|
||||
assert_eq!(parse_duration("100m"), Ok(Duration::new(6000, 0)));
|
||||
assert_eq!(parse_duration("12min"), Ok(Duration::new(720, 0)));
|
||||
assert_eq!(parse_duration("12mins"), Ok(Duration::new(720, 0)));
|
||||
assert_eq!(parse_duration("1minute"), Ok(Duration::new(60, 0)));
|
||||
assert_eq!(parse_duration("7minutes"), Ok(Duration::new(420, 0)));
|
||||
assert_eq!(parse_duration("2h"), Ok(Duration::new(7200, 0)));
|
||||
assert_eq!(parse_duration("7hr"), Ok(Duration::new(25200, 0)));
|
||||
assert_eq!(parse_duration("7hrs"), Ok(Duration::new(25200, 0)));
|
||||
assert_eq!(parse_duration("1hour"), Ok(Duration::new(3600, 0)));
|
||||
assert_eq!(parse_duration("24hours"), Ok(Duration::new(86400, 0)));
|
||||
assert_eq!(parse_duration("1day"), Ok(Duration::new(86400, 0)));
|
||||
assert_eq!(parse_duration("2days"), Ok(Duration::new(172_800, 0)));
|
||||
assert_eq!(parse_duration("365d"), Ok(Duration::new(31_536_000, 0)));
|
||||
assert_eq!(parse_duration("1week"), Ok(Duration::new(604_800, 0)));
|
||||
assert_eq!(parse_duration("7weeks"), Ok(Duration::new(4_233_600, 0)));
|
||||
assert_eq!(parse_duration("52w"), Ok(Duration::new(31_449_600, 0)));
|
||||
assert_eq!(parse_duration("1month"), Ok(Duration::new(2_630_016, 0)));
|
||||
assert_eq!(parse_duration("3months"), Ok(Duration::new(3*2_630_016, 0)));
|
||||
assert_eq!(parse_duration("12M"), Ok(Duration::new(31_560_192, 0)));
|
||||
assert_eq!(parse_duration("1year"), Ok(Duration::new(31_557_600, 0)));
|
||||
assert_eq!(parse_duration("7years"), Ok(Duration::new(7*31_557_600, 0)));
|
||||
assert_eq!(parse_duration("17y"), Ok(Duration::new(536_479_200, 0)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_combo() {
|
||||
assert_eq!(parse_duration("20 min 17 nsec "), Ok(Duration::new(1200, 17)));
|
||||
assert_eq!(parse_duration("2h 15m"), Ok(Duration::new(8100, 0)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn all_86400_seconds() {
|
||||
for second in 0..86400 { // scan leap year and non-leap year
|
||||
let d = Duration::new(second, 0);
|
||||
assert_eq!(d,
|
||||
parse_duration(&format_duration(d).to_string()).unwrap());
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn random_second() {
|
||||
for _ in 0..10000 {
|
||||
let sec = rand::thread_rng().gen_range(0, 253_370_764_800);
|
||||
let d = Duration::new(sec, 0);
|
||||
assert_eq!(d,
|
||||
parse_duration(&format_duration(d).to_string()).unwrap());
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn random_any() {
|
||||
for _ in 0..10000 {
|
||||
let sec = rand::thread_rng().gen_range(0, 253_370_764_800);
|
||||
let nanos = rand::thread_rng().gen_range(0, 1_000_000_000);
|
||||
let d = Duration::new(sec, nanos);
|
||||
assert_eq!(d,
|
||||
parse_duration(&format_duration(d).to_string()).unwrap());
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_overlow() {
|
||||
// Overflow on subseconds is earlier because of how we do conversion
|
||||
// we could fix it, but I don't see any good reason for this
|
||||
assert_eq!(parse_duration("100000000000000000000ns"),
|
||||
Err(Error::NumberOverflow));
|
||||
assert_eq!(parse_duration("100000000000000000us"),
|
||||
Err(Error::NumberOverflow));
|
||||
assert_eq!(parse_duration("100000000000000ms"),
|
||||
Err(Error::NumberOverflow));
|
||||
|
||||
assert_eq!(parse_duration("100000000000000000000s"),
|
||||
Err(Error::NumberOverflow));
|
||||
assert_eq!(parse_duration("10000000000000000000m"),
|
||||
Err(Error::NumberOverflow));
|
||||
assert_eq!(parse_duration("1000000000000000000h"),
|
||||
Err(Error::NumberOverflow));
|
||||
assert_eq!(parse_duration("100000000000000000d"),
|
||||
Err(Error::NumberOverflow));
|
||||
assert_eq!(parse_duration("10000000000000000w"),
|
||||
Err(Error::NumberOverflow));
|
||||
assert_eq!(parse_duration("1000000000000000M"),
|
||||
Err(Error::NumberOverflow));
|
||||
assert_eq!(parse_duration("10000000000000y"),
|
||||
Err(Error::NumberOverflow));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_nice_error_message() {
|
||||
assert_eq!(parse_duration("123").unwrap_err().to_string(),
|
||||
"time unit needed, for example 123sec or 123ms");
|
||||
assert_eq!(parse_duration("10 months 1").unwrap_err().to_string(),
|
||||
"time unit needed, for example 1sec or 1ms");
|
||||
assert_eq!(parse_duration("10nights").unwrap_err().to_string(),
|
||||
"unknown time unit \"nights\", supported units: \
|
||||
ns, us, ms, sec, min, hours, days, weeks, months, \
|
||||
years (and few variations)");
|
||||
}
|
||||
}
|
34
third_party/rust/humantime/src/lib.rs
vendored
34
third_party/rust/humantime/src/lib.rs
vendored
@ -1,34 +0,0 @@
|
||||
//! Human-friendly time parser and formatter
|
||||
//!
|
||||
//! Features:
|
||||
//!
|
||||
//! * Parses durations in free form like `15days 2min 2s`
|
||||
//! * Formats durations in similar form `2years 2min 12us`
|
||||
//! * Parses and formats timestamp in `rfc3339` format: `2018-01-01T12:53:00Z`
|
||||
//! * Parses timestamps in a weaker format: `2018-01-01 12:53:00`
|
||||
//!
|
||||
//! Timestamp parsing/formatting is super-fast because format is basically
|
||||
//! fixed.
|
||||
//!
|
||||
//! See [humantime-serde] for serde integration (previous crate [serde-humantime] looks unmaintained).
|
||||
//!
|
||||
//! [serde-humantime]: https://docs.rs/serde-humantime/0.1.1/serde_humantime/
|
||||
//! [humantime-serde]: https://docs.rs/humantime-serde
|
||||
|
||||
#![forbid(unsafe_code)]
|
||||
#![warn(missing_debug_implementations)]
|
||||
#![warn(missing_docs)]
|
||||
|
||||
mod duration;
|
||||
mod wrapper;
|
||||
mod date;
|
||||
|
||||
pub use self::duration::{parse_duration, Error as DurationError};
|
||||
pub use self::duration::{format_duration, FormattedDuration};
|
||||
pub use self::wrapper::{Duration, Timestamp};
|
||||
pub use self::date::{parse_rfc3339, parse_rfc3339_weak, Error as TimestampError};
|
||||
pub use self::date::{
|
||||
format_rfc3339, format_rfc3339_micros, format_rfc3339_millis, format_rfc3339_nanos,
|
||||
format_rfc3339_seconds,
|
||||
};
|
||||
pub use self::date::{Rfc3339Timestamp};
|
107
third_party/rust/humantime/src/wrapper.rs
vendored
107
third_party/rust/humantime/src/wrapper.rs
vendored
@ -1,107 +0,0 @@
|
||||
use std::str::FromStr;
|
||||
use std::ops::Deref;
|
||||
use std::fmt;
|
||||
use std::time::{Duration as StdDuration, SystemTime};
|
||||
|
||||
use crate::duration::{self, parse_duration, format_duration};
|
||||
use crate::date::{self, parse_rfc3339_weak, format_rfc3339};
|
||||
|
||||
/// A wrapper for duration that has `FromStr` implementation
|
||||
///
|
||||
/// This is useful if you want to use it somewhere where `FromStr` is
|
||||
/// expected.
|
||||
///
|
||||
/// See `parse_duration` for the description of the format.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// use std::time::Duration;
|
||||
/// let x: Duration;
|
||||
/// x = "12h 5min 2ns".parse::<humantime::Duration>().unwrap().into();
|
||||
/// assert_eq!(x, Duration::new(12*3600 + 5*60, 2))
|
||||
/// ```
|
||||
///
|
||||
#[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)]
|
||||
pub struct Duration(StdDuration);
|
||||
|
||||
/// A wrapper for SystemTime that has `FromStr` implementation
|
||||
///
|
||||
/// This is useful if you want to use it somewhere where `FromStr` is
|
||||
/// expected.
|
||||
///
|
||||
/// See `parse_rfc3339_weak` for the description of the format. The "weak"
|
||||
/// format is used as it's more pemissive for human input as this is the
|
||||
/// expected use of the type (e.g. command-line parsing).
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// use std::time::SystemTime;
|
||||
/// let x: SystemTime;
|
||||
/// x = "2018-02-16T00:31:37Z".parse::<humantime::Timestamp>().unwrap().into();
|
||||
/// assert_eq!(humantime::format_rfc3339(x).to_string(), "2018-02-16T00:31:37Z");
|
||||
/// ```
|
||||
///
|
||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||
pub struct Timestamp(SystemTime);
|
||||
|
||||
impl AsRef<StdDuration> for Duration {
|
||||
fn as_ref(&self) -> &StdDuration { &self.0 }
|
||||
}
|
||||
|
||||
impl Deref for Duration {
|
||||
type Target = StdDuration;
|
||||
fn deref(&self) -> &StdDuration { &self.0 }
|
||||
}
|
||||
|
||||
impl Into<StdDuration> for Duration {
|
||||
fn into(self) -> StdDuration { self.0 }
|
||||
}
|
||||
|
||||
impl From<StdDuration> for Duration {
|
||||
fn from(dur: StdDuration) -> Duration { Duration(dur) }
|
||||
}
|
||||
|
||||
impl FromStr for Duration {
|
||||
type Err = duration::Error;
|
||||
fn from_str(s: &str) -> Result<Duration, Self::Err> {
|
||||
parse_duration(s).map(Duration)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Duration {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
format_duration(self.0).fmt(f)
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRef<SystemTime> for Timestamp {
|
||||
fn as_ref(&self) -> &SystemTime { &self.0 }
|
||||
}
|
||||
|
||||
impl Deref for Timestamp {
|
||||
type Target = SystemTime;
|
||||
fn deref(&self) -> &SystemTime { &self.0 }
|
||||
}
|
||||
|
||||
impl Into<SystemTime> for Timestamp {
|
||||
fn into(self) -> SystemTime { self.0 }
|
||||
}
|
||||
|
||||
impl From<SystemTime> for Timestamp {
|
||||
fn from(dur: SystemTime) -> Timestamp { Timestamp(dur) }
|
||||
}
|
||||
|
||||
impl FromStr for Timestamp {
|
||||
type Err = date::Error;
|
||||
fn from_str(s: &str) -> Result<Timestamp, Self::Err> {
|
||||
parse_rfc3339_weak(s).map(Timestamp)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Timestamp {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
format_rfc3339(self.0).fmt(f)
|
||||
}
|
||||
}
|
92
third_party/rust/humantime/vagga.yaml
vendored
92
third_party/rust/humantime/vagga.yaml
vendored
@ -1,92 +0,0 @@
|
||||
commands:
|
||||
|
||||
cargo: !Command
|
||||
description: Run any cargo command
|
||||
container: ubuntu
|
||||
run: [cargo]
|
||||
|
||||
make: !Command
|
||||
description: Build the library
|
||||
container: ubuntu
|
||||
run: [cargo, build]
|
||||
|
||||
test64: !Command
|
||||
description: Test the 64bit library
|
||||
container: ubuntu
|
||||
environ: { RUST_BACKTRACE: 1 }
|
||||
run: [cargo, test]
|
||||
|
||||
test32: !Command
|
||||
description: Test the 32bit library
|
||||
container: ubuntu32
|
||||
environ: { RUST_BACKTRACE: 1 }
|
||||
run: [cargo, test]
|
||||
|
||||
test: !Command
|
||||
description: Test the 64bit library
|
||||
container: ubuntu
|
||||
environ: { RUST_BACKTRACE: 1 }
|
||||
prerequisites: [test64, test32]
|
||||
run: [echo, okay]
|
||||
|
||||
bench: !Command
|
||||
description: Run benchmarks
|
||||
container: bench
|
||||
environ: { RUST_BACKTRACE: 1 }
|
||||
run: [cargo, bench]
|
||||
|
||||
_bulk: !Command
|
||||
description: Run `bulk` command (for version bookkeeping)
|
||||
container: ubuntu
|
||||
run: [bulk]
|
||||
|
||||
containers:
|
||||
|
||||
ubuntu:
|
||||
setup:
|
||||
- !Ubuntu xenial
|
||||
- !UbuntuUniverse
|
||||
- !Install [ca-certificates, build-essential, vim]
|
||||
|
||||
- !TarInstall
|
||||
url: "https://static.rust-lang.org/dist/rust-1.31.0-x86_64-unknown-linux-gnu.tar.gz"
|
||||
script: "./install.sh --prefix=/usr \
|
||||
--components=rustc,rust-std-x86_64-unknown-linux-gnu,cargo"
|
||||
- &bulk !Tar
|
||||
url: "https://github.com/tailhook/bulk/releases/download/v0.4.10/bulk-v0.4.10.tar.gz"
|
||||
sha256: 481513f8a0306a9857d045497fb5b50b50a51e9ff748909ecf7d2bda1de275ab
|
||||
path: /
|
||||
|
||||
environ:
|
||||
HOME: /work/target
|
||||
USER: pc
|
||||
|
||||
ubuntu32:
|
||||
setup:
|
||||
- !UbuntuRelease
|
||||
codename: xenial
|
||||
arch: i386
|
||||
- !UbuntuUniverse
|
||||
- !Install [ca-certificates, build-essential, vim]
|
||||
|
||||
- !TarInstall
|
||||
url: "https://static.rust-lang.org/dist/rust-1.31.0-i686-unknown-linux-gnu.tar.gz"
|
||||
script: "./install.sh --prefix=/usr \
|
||||
--components=rustc,rust-std-i686-unknown-linux-gnu,cargo"
|
||||
|
||||
environ:
|
||||
HOME: /work/target
|
||||
USER: pc
|
||||
|
||||
bench:
|
||||
setup:
|
||||
- !Ubuntu xenial
|
||||
- !Install [ca-certificates, wget, build-essential]
|
||||
- !TarInstall
|
||||
url: https://static.rust-lang.org/dist/rust-nightly-x86_64-unknown-linux-gnu.tar.gz
|
||||
script: |
|
||||
./install.sh --prefix=/usr \
|
||||
--components=rustc,rust-std-x86_64-unknown-linux-gnu,cargo
|
||||
environ:
|
||||
HOME: /work/target
|
||||
USER: pc
|
File diff suppressed because one or more lines are too long
5
third_party/rust/mp4parse/Cargo.toml
vendored
5
third_party/rust/mp4parse/Cargo.toml
vendored
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "mp4parse"
|
||||
version = "0.13.0"
|
||||
version = "0.16.0"
|
||||
authors = [
|
||||
"Ralph Giles <giles@mozilla.com>",
|
||||
"Matthew Gregan <kinetik@flim.org>",
|
||||
@ -13,7 +13,7 @@ description = "Parser for ISO base media file format (mp4)"
|
||||
documentation = "https://docs.rs/mp4parse/"
|
||||
license = "MPL-2.0"
|
||||
categories = ["multimedia::video"]
|
||||
|
||||
edition = "2018"
|
||||
repository = "https://github.com/mozilla/mp4parse-rust"
|
||||
|
||||
# Avoid complaints about trying to package test files.
|
||||
@ -28,7 +28,6 @@ travis-ci = { repository = "https://github.com/mozilla/mp4parse-rust" }
|
||||
[dependencies]
|
||||
byteorder = "1.2.1"
|
||||
bitreader = { version = "0.3.2" }
|
||||
env_logger = "0.8"
|
||||
fallible_collections = { version = "0.4", features = ["std_io"] }
|
||||
num-traits = "0.2.14"
|
||||
log = "0.4"
|
||||
|
@ -1,8 +1,6 @@
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
extern crate criterion;
|
||||
extern crate mp4parse as mp4;
|
||||
|
||||
use criterion::{criterion_group, criterion_main, Criterion};
|
||||
use std::fs::File;
|
||||
@ -19,5 +17,5 @@ fn avif_largest() {
|
||||
"av1-avif/testFiles/Netflix/avif/cosmos_frame05000_yuv444_12bpc_bt2020_pq_qlossless.avif",
|
||||
)
|
||||
.expect("Unknown file");
|
||||
assert!(mp4::read_avif(input, mp4::ParseStrictness::Normal).is_ok());
|
||||
assert!(mp4parse::read_avif(input, mp4parse::ParseStrictness::Normal).is_ok());
|
||||
}
|
||||
|
@ -1,146 +1,146 @@
|
||||
name: Encode all images and decode them again weekly.
|
||||
|
||||
on:
|
||||
push:
|
||||
schedule:
|
||||
- cron: '0 20 * * 0' # https://crontab.guru/#0_2_*_*_0
|
||||
|
||||
jobs:
|
||||
check-on-ubuntu:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-18.04, ubuntu-20.04]
|
||||
include:
|
||||
- os: ubuntu-18.04
|
||||
codename: 'bionic'
|
||||
cavif-flag: ''
|
||||
- os: ubuntu-20.04
|
||||
codename: 'focal'
|
||||
cavif-flag: ''
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Install required tools
|
||||
run: sudo apt install -y curl jq unzip coreutils imagemagick
|
||||
- name: Download latest cavif
|
||||
shell: bash
|
||||
run: |
|
||||
runId=$(curl https://api.github.com/repos/link-u/cavif/actions/workflows/${WORKFLOW_ID}/runs | jq '[.workflow_runs[] | select( .conclusion == "success")][0].id')
|
||||
artifactId=$(curl https://api.github.com/repos/link-u/cavif/actions/runs/${runId}/artifacts | jq '[.artifacts[] | select( .name == "${{ matrix.codename }}")][0].id')
|
||||
curl --header 'authorization: Bearer ${{ secrets.GITHUB_TOKEN }}' -o cavif.zip -L https://api.github.com/repos/link-u/cavif/actions/artifacts/${artifactId}/zip
|
||||
unzip cavif.zip
|
||||
env:
|
||||
#id of https://github.com/link-u/cavif/actions?query=workflow%3A%22Build+debian+package+on+push+or+release-tags.%22
|
||||
# curl https://api.github.com/repos/link-u/cavif/actions/workflows
|
||||
WORKFLOW_ID: '4521995'
|
||||
- name: Download latest davif
|
||||
shell: bash
|
||||
run: |
|
||||
runId=$(curl https://api.github.com/repos/link-u/davif/actions/workflows/${WORKFLOW_ID}/runs | jq '[.workflow_runs[] | select( .conclusion == "success")][0].id')
|
||||
artifactId=$(curl https://api.github.com/repos/link-u/davif/actions/runs/${runId}/artifacts | jq '[.artifacts[] | select( .name == "${{ matrix.codename }}")][0].id')
|
||||
curl --header 'authorization: Bearer ${{ secrets.GITHUB_TOKEN }}' -o davif.zip -L https://api.github.com/repos/link-u/davif/actions/artifacts/${artifactId}/zip
|
||||
unzip davif.zip
|
||||
env:
|
||||
#id of https://github.com/link-u/davif/actions?query=workflow%3A%22Build+debian+package+on+push+or+release-tags.%22
|
||||
# curl https://api.github.com/repos/link-u/davif/actions/workflows
|
||||
WORKFLOW_ID: '452394'
|
||||
- name: Install davif and cavif
|
||||
run: sudo dpkg -i *.deb
|
||||
- name: Use installed cavif and davif
|
||||
run: |
|
||||
sed -i -e 's/^CAVIF=.*$/CAVIF=cavif ${{ matrix.cavif-flag }}/' Makefile
|
||||
sed -i -e 's/^DAVIF=.*$/DAVIF=davif/' Makefile
|
||||
- name: Clean all images.
|
||||
run: make clean
|
||||
- name: Encode them all.
|
||||
run: make all -j $(nproc)
|
||||
- name: Decode them all.
|
||||
run: make decode -j $(nproc)
|
||||
- name: Copy images to upload.
|
||||
run: |
|
||||
mkdir -p ${{ matrix.codename }}/decoded
|
||||
mkdir -p ${{ matrix.codename }}/encoded
|
||||
cp decoded/* ${{ matrix.codename }}/decoded
|
||||
cp *.avif ${{ matrix.codename }}/encoded
|
||||
- name: Upload result
|
||||
uses: actions/upload-artifact@v1
|
||||
with:
|
||||
name: ${{ matrix.codename }}
|
||||
path: ${{ matrix.codename }}
|
||||
- name: Compare the result
|
||||
run: make compare -j $(nproc)
|
||||
check-on-windows:
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Install msys2
|
||||
uses: msys2/setup-msys2@v2
|
||||
with:
|
||||
msystem: MINGW64
|
||||
update: true
|
||||
path-type: inherit
|
||||
- name: Install dependencies
|
||||
shell: msys2 {0}
|
||||
run: |
|
||||
set -eux
|
||||
pacman --noconfirm -S make
|
||||
pacman --noconfirm -S bc
|
||||
pacman --noconfirm -S mingw-w64-x86_64-imagemagick
|
||||
pacman --noconfirm -S mingw-w64-x86_64-curl
|
||||
pacman --noconfirm -S mingw-w64-x86_64-jq
|
||||
make --version
|
||||
echo '2+2' | bc
|
||||
magick -version
|
||||
- name: Download latest cavif
|
||||
shell: bash
|
||||
run: |
|
||||
runId=$(curl https://api.github.com/repos/link-u/cavif/actions/workflows/${WORKFLOW_ID}/runs | jq '[.workflow_runs[] | select( .conclusion == "success")][0].id')
|
||||
artifactId=$(curl https://api.github.com/repos/link-u/cavif/actions/runs/${runId}/artifacts | jq '[.artifacts[] | select( .name == "cavif-win64")][0].id')
|
||||
curl --header 'authorization: Bearer ${{ secrets.GITHUB_TOKEN }}' -o cavif.zip -L https://api.github.com/repos/link-u/cavif/actions/artifacts/${artifactId}/zip
|
||||
unzip cavif.zip
|
||||
rm cavif.zip
|
||||
./cavif.exe -h
|
||||
env:
|
||||
WORKFLOW_ID: '4517759'
|
||||
- name: Download latest davif
|
||||
shell: bash
|
||||
run: |
|
||||
runId=$(curl https://api.github.com/repos/link-u/davif/actions/workflows/${WORKFLOW_ID}/runs | jq '[.workflow_runs[] | select( .conclusion == "success")][0].id')
|
||||
artifactId=$(curl https://api.github.com/repos/link-u/davif/actions/runs/${runId}/artifacts | jq '[.artifacts[] | select( .name == "davif-win64")][0].id')
|
||||
curl --header 'authorization: Bearer ${{ secrets.GITHUB_TOKEN }}' -o davif.zip -L https://api.github.com/repos/link-u/davif/actions/artifacts/${artifactId}/zip
|
||||
unzip davif.zip
|
||||
rm davif.zip
|
||||
./davif.exe -h
|
||||
env:
|
||||
WORKFLOW_ID: '4521970'
|
||||
- name: Rewrite Makefile to installed cavif and davif
|
||||
shell: msys2 {0}
|
||||
run: |
|
||||
sed -i -e 's/^CAVIF=.*$/CAVIF=.\/cavif.exe/' Makefile
|
||||
sed -i -e 's/^DAVIF=.*$/DAVIF=.\/davif.exe/' Makefile
|
||||
- name: Clean all images.
|
||||
shell: msys2 {0}
|
||||
run: make clean
|
||||
- name: Encode them all
|
||||
shell: msys2 {0}
|
||||
run: make all -j $(nproc)
|
||||
- name: Decode them all
|
||||
shell: msys2 {0}
|
||||
run: make decode -j $(nproc)
|
||||
- name: Copy images to upload.
|
||||
shell: msys2 {0}
|
||||
run: |
|
||||
mkdir -p win64/decoded
|
||||
mkdir -p win64/encoded
|
||||
cp decoded/* win64/decoded
|
||||
cp *.avif win64/encoded
|
||||
- name: Upload result
|
||||
uses: actions/upload-artifact@v1
|
||||
with:
|
||||
name: win64
|
||||
path: win64
|
||||
- name: Compare the result
|
||||
shell: msys2 {0}
|
||||
run: |
|
||||
export PATH="/mingw64/bin:${PATH}"
|
||||
make compare -j $(nproc)
|
||||
name: Encode all images and decode them again weekly.
|
||||
|
||||
on:
|
||||
push:
|
||||
schedule:
|
||||
- cron: '0 20 * * 0' # https://crontab.guru/#0_2_*_*_0
|
||||
|
||||
jobs:
|
||||
check-on-ubuntu:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-18.04, ubuntu-20.04]
|
||||
include:
|
||||
- os: ubuntu-18.04
|
||||
codename: 'bionic'
|
||||
cavif-flag: ''
|
||||
- os: ubuntu-20.04
|
||||
codename: 'focal'
|
||||
cavif-flag: ''
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Install required tools
|
||||
run: sudo apt install -y curl jq unzip coreutils imagemagick
|
||||
- name: Download latest cavif
|
||||
shell: bash
|
||||
run: |
|
||||
runId=$(curl https://api.github.com/repos/link-u/cavif/actions/workflows/${WORKFLOW_ID}/runs | jq '[.workflow_runs[] | select( .conclusion == "success")][0].id')
|
||||
artifactId=$(curl https://api.github.com/repos/link-u/cavif/actions/runs/${runId}/artifacts | jq '[.artifacts[] | select( .name == "${{ matrix.codename }}")][0].id')
|
||||
curl --header 'authorization: Bearer ${{ secrets.GITHUB_TOKEN }}' -o cavif.zip -L https://api.github.com/repos/link-u/cavif/actions/artifacts/${artifactId}/zip
|
||||
unzip cavif.zip
|
||||
env:
|
||||
#id of https://github.com/link-u/cavif/actions?query=workflow%3A%22Build+debian+package+on+push+or+release-tags.%22
|
||||
# curl https://api.github.com/repos/link-u/cavif/actions/workflows
|
||||
WORKFLOW_ID: '4521995'
|
||||
- name: Download latest davif
|
||||
shell: bash
|
||||
run: |
|
||||
runId=$(curl https://api.github.com/repos/link-u/davif/actions/workflows/${WORKFLOW_ID}/runs | jq '[.workflow_runs[] | select( .conclusion == "success")][0].id')
|
||||
artifactId=$(curl https://api.github.com/repos/link-u/davif/actions/runs/${runId}/artifacts | jq '[.artifacts[] | select( .name == "${{ matrix.codename }}")][0].id')
|
||||
curl --header 'authorization: Bearer ${{ secrets.GITHUB_TOKEN }}' -o davif.zip -L https://api.github.com/repos/link-u/davif/actions/artifacts/${artifactId}/zip
|
||||
unzip davif.zip
|
||||
env:
|
||||
#id of https://github.com/link-u/davif/actions?query=workflow%3A%22Build+debian+package+on+push+or+release-tags.%22
|
||||
# curl https://api.github.com/repos/link-u/davif/actions/workflows
|
||||
WORKFLOW_ID: '452394'
|
||||
- name: Install davif and cavif
|
||||
run: sudo dpkg -i *.deb
|
||||
- name: Use installed cavif and davif
|
||||
run: |
|
||||
sed -i -e 's/^CAVIF=.*$/CAVIF=cavif ${{ matrix.cavif-flag }}/' Makefile
|
||||
sed -i -e 's/^DAVIF=.*$/DAVIF=davif/' Makefile
|
||||
- name: Clean all images.
|
||||
run: make clean
|
||||
- name: Encode them all.
|
||||
run: make all -j $(nproc)
|
||||
- name: Decode them all.
|
||||
run: make decode -j $(nproc)
|
||||
- name: Copy images to upload.
|
||||
run: |
|
||||
mkdir -p ${{ matrix.codename }}/decoded
|
||||
mkdir -p ${{ matrix.codename }}/encoded
|
||||
cp decoded/* ${{ matrix.codename }}/decoded
|
||||
cp *.avif ${{ matrix.codename }}/encoded
|
||||
- name: Upload result
|
||||
uses: actions/upload-artifact@v1
|
||||
with:
|
||||
name: ${{ matrix.codename }}
|
||||
path: ${{ matrix.codename }}
|
||||
- name: Compare the result
|
||||
run: make compare -j $(nproc)
|
||||
check-on-windows:
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Install msys2
|
||||
uses: msys2/setup-msys2@v2
|
||||
with:
|
||||
msystem: MINGW64
|
||||
update: true
|
||||
path-type: inherit
|
||||
- name: Install dependencies
|
||||
shell: msys2 {0}
|
||||
run: |
|
||||
set -eux
|
||||
pacman --noconfirm -S make
|
||||
pacman --noconfirm -S bc
|
||||
pacman --noconfirm -S mingw-w64-x86_64-imagemagick
|
||||
pacman --noconfirm -S mingw-w64-x86_64-curl
|
||||
pacman --noconfirm -S mingw-w64-x86_64-jq
|
||||
make --version
|
||||
echo '2+2' | bc
|
||||
magick -version
|
||||
- name: Download latest cavif
|
||||
shell: bash
|
||||
run: |
|
||||
runId=$(curl https://api.github.com/repos/link-u/cavif/actions/workflows/${WORKFLOW_ID}/runs | jq '[.workflow_runs[] | select( .conclusion == "success")][0].id')
|
||||
artifactId=$(curl https://api.github.com/repos/link-u/cavif/actions/runs/${runId}/artifacts | jq '[.artifacts[] | select( .name == "cavif-win64")][0].id')
|
||||
curl --header 'authorization: Bearer ${{ secrets.GITHUB_TOKEN }}' -o cavif.zip -L https://api.github.com/repos/link-u/cavif/actions/artifacts/${artifactId}/zip
|
||||
unzip cavif.zip
|
||||
rm cavif.zip
|
||||
./cavif.exe -h
|
||||
env:
|
||||
WORKFLOW_ID: '4517759'
|
||||
- name: Download latest davif
|
||||
shell: bash
|
||||
run: |
|
||||
runId=$(curl https://api.github.com/repos/link-u/davif/actions/workflows/${WORKFLOW_ID}/runs | jq '[.workflow_runs[] | select( .conclusion == "success")][0].id')
|
||||
artifactId=$(curl https://api.github.com/repos/link-u/davif/actions/runs/${runId}/artifacts | jq '[.artifacts[] | select( .name == "davif-win64")][0].id')
|
||||
curl --header 'authorization: Bearer ${{ secrets.GITHUB_TOKEN }}' -o davif.zip -L https://api.github.com/repos/link-u/davif/actions/artifacts/${artifactId}/zip
|
||||
unzip davif.zip
|
||||
rm davif.zip
|
||||
./davif.exe -h
|
||||
env:
|
||||
WORKFLOW_ID: '4521970'
|
||||
- name: Rewrite Makefile to installed cavif and davif
|
||||
shell: msys2 {0}
|
||||
run: |
|
||||
sed -i -e 's/^CAVIF=.*$/CAVIF=.\/cavif.exe/' Makefile
|
||||
sed -i -e 's/^DAVIF=.*$/DAVIF=.\/davif.exe/' Makefile
|
||||
- name: Clean all images.
|
||||
shell: msys2 {0}
|
||||
run: make clean
|
||||
- name: Encode them all
|
||||
shell: msys2 {0}
|
||||
run: make all -j $(nproc)
|
||||
- name: Decode them all
|
||||
shell: msys2 {0}
|
||||
run: make decode -j $(nproc)
|
||||
- name: Copy images to upload.
|
||||
shell: msys2 {0}
|
||||
run: |
|
||||
mkdir -p win64/decoded
|
||||
mkdir -p win64/encoded
|
||||
cp decoded/* win64/decoded
|
||||
cp *.avif win64/encoded
|
||||
- name: Upload result
|
||||
uses: actions/upload-artifact@v1
|
||||
with:
|
||||
name: win64
|
||||
path: win64
|
||||
- name: Compare the result
|
||||
shell: msys2 {0}
|
||||
run: |
|
||||
export PATH="/mingw64/bin:${PATH}"
|
||||
make compare -j $(nproc)
|
||||
|
@ -1,4 +1,4 @@
|
||||
*.avif.png
|
||||
/core
|
||||
/decoded/
|
||||
/.alpha-masks/
|
||||
*.avif.png
|
||||
/core
|
||||
/decoded/
|
||||
/.alpha-masks/
|
||||
|
@ -1,427 +1,427 @@
|
||||
Attribution-ShareAlike 4.0 International
|
||||
|
||||
=======================================================================
|
||||
|
||||
Creative Commons Corporation ("Creative Commons") is not a law firm and
|
||||
does not provide legal services or legal advice. Distribution of
|
||||
Creative Commons public licenses does not create a lawyer-client or
|
||||
other relationship. Creative Commons makes its licenses and related
|
||||
information available on an "as-is" basis. Creative Commons gives no
|
||||
warranties regarding its licenses, any material licensed under their
|
||||
terms and conditions, or any related information. Creative Commons
|
||||
disclaims all liability for damages resulting from their use to the
|
||||
fullest extent possible.
|
||||
|
||||
Using Creative Commons Public Licenses
|
||||
|
||||
Creative Commons public licenses provide a standard set of terms and
|
||||
conditions that creators and other rights holders may use to share
|
||||
original works of authorship and other material subject to copyright
|
||||
and certain other rights specified in the public license below. The
|
||||
following considerations are for informational purposes only, are not
|
||||
exhaustive, and do not form part of our licenses.
|
||||
|
||||
Considerations for licensors: Our public licenses are
|
||||
intended for use by those authorized to give the public
|
||||
permission to use material in ways otherwise restricted by
|
||||
copyright and certain other rights. Our licenses are
|
||||
irrevocable. Licensors should read and understand the terms
|
||||
and conditions of the license they choose before applying it.
|
||||
Licensors should also secure all rights necessary before
|
||||
applying our licenses so that the public can reuse the
|
||||
material as expected. Licensors should clearly mark any
|
||||
material not subject to the license. This includes other CC-
|
||||
licensed material, or material used under an exception or
|
||||
limitation to copyright. More considerations for licensors:
|
||||
wiki.creativecommons.org/Considerations_for_licensors
|
||||
|
||||
Considerations for the public: By using one of our public
|
||||
licenses, a licensor grants the public permission to use the
|
||||
licensed material under specified terms and conditions. If
|
||||
the licensor's permission is not necessary for any reason--for
|
||||
example, because of any applicable exception or limitation to
|
||||
copyright--then that use is not regulated by the license. Our
|
||||
licenses grant only permissions under copyright and certain
|
||||
other rights that a licensor has authority to grant. Use of
|
||||
the licensed material may still be restricted for other
|
||||
reasons, including because others have copyright or other
|
||||
rights in the material. A licensor may make special requests,
|
||||
such as asking that all changes be marked or described.
|
||||
Although not required by our licenses, you are encouraged to
|
||||
respect those requests where reasonable. More_considerations
|
||||
for the public:
|
||||
wiki.creativecommons.org/Considerations_for_licensees
|
||||
|
||||
=======================================================================
|
||||
|
||||
Creative Commons Attribution-ShareAlike 4.0 International Public
|
||||
License
|
||||
|
||||
By exercising the Licensed Rights (defined below), You accept and agree
|
||||
to be bound by the terms and conditions of this Creative Commons
|
||||
Attribution-ShareAlike 4.0 International Public License ("Public
|
||||
License"). To the extent this Public License may be interpreted as a
|
||||
contract, You are granted the Licensed Rights in consideration of Your
|
||||
acceptance of these terms and conditions, and the Licensor grants You
|
||||
such rights in consideration of benefits the Licensor receives from
|
||||
making the Licensed Material available under these terms and
|
||||
conditions.
|
||||
|
||||
|
||||
Section 1 -- Definitions.
|
||||
|
||||
a. Adapted Material means material subject to Copyright and Similar
|
||||
Rights that is derived from or based upon the Licensed Material
|
||||
and in which the Licensed Material is translated, altered,
|
||||
arranged, transformed, or otherwise modified in a manner requiring
|
||||
permission under the Copyright and Similar Rights held by the
|
||||
Licensor. For purposes of this Public License, where the Licensed
|
||||
Material is a musical work, performance, or sound recording,
|
||||
Adapted Material is always produced where the Licensed Material is
|
||||
synched in timed relation with a moving image.
|
||||
|
||||
b. Adapter's License means the license You apply to Your Copyright
|
||||
and Similar Rights in Your contributions to Adapted Material in
|
||||
accordance with the terms and conditions of this Public License.
|
||||
|
||||
c. BY-SA Compatible License means a license listed at
|
||||
creativecommons.org/compatiblelicenses, approved by Creative
|
||||
Commons as essentially the equivalent of this Public License.
|
||||
|
||||
d. Copyright and Similar Rights means copyright and/or similar rights
|
||||
closely related to copyright including, without limitation,
|
||||
performance, broadcast, sound recording, and Sui Generis Database
|
||||
Rights, without regard to how the rights are labeled or
|
||||
categorized. For purposes of this Public License, the rights
|
||||
specified in Section 2(b)(1)-(2) are not Copyright and Similar
|
||||
Rights.
|
||||
|
||||
e. Effective Technological Measures means those measures that, in the
|
||||
absence of proper authority, may not be circumvented under laws
|
||||
fulfilling obligations under Article 11 of the WIPO Copyright
|
||||
Treaty adopted on December 20, 1996, and/or similar international
|
||||
agreements.
|
||||
|
||||
f. Exceptions and Limitations means fair use, fair dealing, and/or
|
||||
any other exception or limitation to Copyright and Similar Rights
|
||||
that applies to Your use of the Licensed Material.
|
||||
|
||||
g. License Elements means the license attributes listed in the name
|
||||
of a Creative Commons Public License. The License Elements of this
|
||||
Public License are Attribution and ShareAlike.
|
||||
|
||||
h. Licensed Material means the artistic or literary work, database,
|
||||
or other material to which the Licensor applied this Public
|
||||
License.
|
||||
|
||||
i. Licensed Rights means the rights granted to You subject to the
|
||||
terms and conditions of this Public License, which are limited to
|
||||
all Copyright and Similar Rights that apply to Your use of the
|
||||
Licensed Material and that the Licensor has authority to license.
|
||||
|
||||
j. Licensor means the individual(s) or entity(ies) granting rights
|
||||
under this Public License.
|
||||
|
||||
k. Share means to provide material to the public by any means or
|
||||
process that requires permission under the Licensed Rights, such
|
||||
as reproduction, public display, public performance, distribution,
|
||||
dissemination, communication, or importation, and to make material
|
||||
available to the public including in ways that members of the
|
||||
public may access the material from a place and at a time
|
||||
individually chosen by them.
|
||||
|
||||
l. Sui Generis Database Rights means rights other than copyright
|
||||
resulting from Directive 96/9/EC of the European Parliament and of
|
||||
the Council of 11 March 1996 on the legal protection of databases,
|
||||
as amended and/or succeeded, as well as other essentially
|
||||
equivalent rights anywhere in the world.
|
||||
|
||||
m. You means the individual or entity exercising the Licensed Rights
|
||||
under this Public License. Your has a corresponding meaning.
|
||||
|
||||
|
||||
Section 2 -- Scope.
|
||||
|
||||
a. License grant.
|
||||
|
||||
1. Subject to the terms and conditions of this Public License,
|
||||
the Licensor hereby grants You a worldwide, royalty-free,
|
||||
non-sublicensable, non-exclusive, irrevocable license to
|
||||
exercise the Licensed Rights in the Licensed Material to:
|
||||
|
||||
a. reproduce and Share the Licensed Material, in whole or
|
||||
in part; and
|
||||
|
||||
b. produce, reproduce, and Share Adapted Material.
|
||||
|
||||
2. Exceptions and Limitations. For the avoidance of doubt, where
|
||||
Exceptions and Limitations apply to Your use, this Public
|
||||
License does not apply, and You do not need to comply with
|
||||
its terms and conditions.
|
||||
|
||||
3. Term. The term of this Public License is specified in Section
|
||||
6(a).
|
||||
|
||||
4. Media and formats; technical modifications allowed. The
|
||||
Licensor authorizes You to exercise the Licensed Rights in
|
||||
all media and formats whether now known or hereafter created,
|
||||
and to make technical modifications necessary to do so. The
|
||||
Licensor waives and/or agrees not to assert any right or
|
||||
authority to forbid You from making technical modifications
|
||||
necessary to exercise the Licensed Rights, including
|
||||
technical modifications necessary to circumvent Effective
|
||||
Technological Measures. For purposes of this Public License,
|
||||
simply making modifications authorized by this Section 2(a)
|
||||
(4) never produces Adapted Material.
|
||||
|
||||
5. Downstream recipients.
|
||||
|
||||
a. Offer from the Licensor -- Licensed Material. Every
|
||||
recipient of the Licensed Material automatically
|
||||
receives an offer from the Licensor to exercise the
|
||||
Licensed Rights under the terms and conditions of this
|
||||
Public License.
|
||||
|
||||
b. Additional offer from the Licensor -- Adapted Material.
|
||||
Every recipient of Adapted Material from You
|
||||
automatically receives an offer from the Licensor to
|
||||
exercise the Licensed Rights in the Adapted Material
|
||||
under the conditions of the Adapter's License You apply.
|
||||
|
||||
c. No downstream restrictions. You may not offer or impose
|
||||
any additional or different terms or conditions on, or
|
||||
apply any Effective Technological Measures to, the
|
||||
Licensed Material if doing so restricts exercise of the
|
||||
Licensed Rights by any recipient of the Licensed
|
||||
Material.
|
||||
|
||||
6. No endorsement. Nothing in this Public License constitutes or
|
||||
may be construed as permission to assert or imply that You
|
||||
are, or that Your use of the Licensed Material is, connected
|
||||
with, or sponsored, endorsed, or granted official status by,
|
||||
the Licensor or others designated to receive attribution as
|
||||
provided in Section 3(a)(1)(A)(i).
|
||||
|
||||
b. Other rights.
|
||||
|
||||
1. Moral rights, such as the right of integrity, are not
|
||||
licensed under this Public License, nor are publicity,
|
||||
privacy, and/or other similar personality rights; however, to
|
||||
the extent possible, the Licensor waives and/or agrees not to
|
||||
assert any such rights held by the Licensor to the limited
|
||||
extent necessary to allow You to exercise the Licensed
|
||||
Rights, but not otherwise.
|
||||
|
||||
2. Patent and trademark rights are not licensed under this
|
||||
Public License.
|
||||
|
||||
3. To the extent possible, the Licensor waives any right to
|
||||
collect royalties from You for the exercise of the Licensed
|
||||
Rights, whether directly or through a collecting society
|
||||
under any voluntary or waivable statutory or compulsory
|
||||
licensing scheme. In all other cases the Licensor expressly
|
||||
reserves any right to collect such royalties.
|
||||
|
||||
|
||||
Section 3 -- License Conditions.
|
||||
|
||||
Your exercise of the Licensed Rights is expressly made subject to the
|
||||
following conditions.
|
||||
|
||||
a. Attribution.
|
||||
|
||||
1. If You Share the Licensed Material (including in modified
|
||||
form), You must:
|
||||
|
||||
a. retain the following if it is supplied by the Licensor
|
||||
with the Licensed Material:
|
||||
|
||||
i. identification of the creator(s) of the Licensed
|
||||
Material and any others designated to receive
|
||||
attribution, in any reasonable manner requested by
|
||||
the Licensor (including by pseudonym if
|
||||
designated);
|
||||
|
||||
ii. a copyright notice;
|
||||
|
||||
iii. a notice that refers to this Public License;
|
||||
|
||||
iv. a notice that refers to the disclaimer of
|
||||
warranties;
|
||||
|
||||
v. a URI or hyperlink to the Licensed Material to the
|
||||
extent reasonably practicable;
|
||||
|
||||
b. indicate if You modified the Licensed Material and
|
||||
retain an indication of any previous modifications; and
|
||||
|
||||
c. indicate the Licensed Material is licensed under this
|
||||
Public License, and include the text of, or the URI or
|
||||
hyperlink to, this Public License.
|
||||
|
||||
2. You may satisfy the conditions in Section 3(a)(1) in any
|
||||
reasonable manner based on the medium, means, and context in
|
||||
which You Share the Licensed Material. For example, it may be
|
||||
reasonable to satisfy the conditions by providing a URI or
|
||||
hyperlink to a resource that includes the required
|
||||
information.
|
||||
|
||||
3. If requested by the Licensor, You must remove any of the
|
||||
information required by Section 3(a)(1)(A) to the extent
|
||||
reasonably practicable.
|
||||
|
||||
b. ShareAlike.
|
||||
|
||||
In addition to the conditions in Section 3(a), if You Share
|
||||
Adapted Material You produce, the following conditions also apply.
|
||||
|
||||
1. The Adapter's License You apply must be a Creative Commons
|
||||
license with the same License Elements, this version or
|
||||
later, or a BY-SA Compatible License.
|
||||
|
||||
2. You must include the text of, or the URI or hyperlink to, the
|
||||
Adapter's License You apply. You may satisfy this condition
|
||||
in any reasonable manner based on the medium, means, and
|
||||
context in which You Share Adapted Material.
|
||||
|
||||
3. You may not offer or impose any additional or different terms
|
||||
or conditions on, or apply any Effective Technological
|
||||
Measures to, Adapted Material that restrict exercise of the
|
||||
rights granted under the Adapter's License You apply.
|
||||
|
||||
|
||||
Section 4 -- Sui Generis Database Rights.
|
||||
|
||||
Where the Licensed Rights include Sui Generis Database Rights that
|
||||
apply to Your use of the Licensed Material:
|
||||
|
||||
a. for the avoidance of doubt, Section 2(a)(1) grants You the right
|
||||
to extract, reuse, reproduce, and Share all or a substantial
|
||||
portion of the contents of the database;
|
||||
|
||||
b. if You include all or a substantial portion of the database
|
||||
contents in a database in which You have Sui Generis Database
|
||||
Rights, then the database in which You have Sui Generis Database
|
||||
Rights (but not its individual contents) is Adapted Material,
|
||||
|
||||
including for purposes of Section 3(b); and
|
||||
c. You must comply with the conditions in Section 3(a) if You Share
|
||||
all or a substantial portion of the contents of the database.
|
||||
|
||||
For the avoidance of doubt, this Section 4 supplements and does not
|
||||
replace Your obligations under this Public License where the Licensed
|
||||
Rights include other Copyright and Similar Rights.
|
||||
|
||||
|
||||
Section 5 -- Disclaimer of Warranties and Limitation of Liability.
|
||||
|
||||
a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE
|
||||
EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS
|
||||
AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF
|
||||
ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS,
|
||||
IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION,
|
||||
WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS,
|
||||
ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT
|
||||
KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT
|
||||
ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU.
|
||||
|
||||
b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE
|
||||
TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION,
|
||||
NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT,
|
||||
INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES,
|
||||
COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR
|
||||
USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN
|
||||
ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR
|
||||
DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR
|
||||
IN PART, THIS LIMITATION MAY NOT APPLY TO YOU.
|
||||
|
||||
c. The disclaimer of warranties and limitation of liability provided
|
||||
above shall be interpreted in a manner that, to the extent
|
||||
possible, most closely approximates an absolute disclaimer and
|
||||
waiver of all liability.
|
||||
|
||||
|
||||
Section 6 -- Term and Termination.
|
||||
|
||||
a. This Public License applies for the term of the Copyright and
|
||||
Similar Rights licensed here. However, if You fail to comply with
|
||||
this Public License, then Your rights under this Public License
|
||||
terminate automatically.
|
||||
|
||||
b. Where Your right to use the Licensed Material has terminated under
|
||||
Section 6(a), it reinstates:
|
||||
|
||||
1. automatically as of the date the violation is cured, provided
|
||||
it is cured within 30 days of Your discovery of the
|
||||
violation; or
|
||||
|
||||
2. upon express reinstatement by the Licensor.
|
||||
|
||||
For the avoidance of doubt, this Section 6(b) does not affect any
|
||||
right the Licensor may have to seek remedies for Your violations
|
||||
of this Public License.
|
||||
|
||||
c. For the avoidance of doubt, the Licensor may also offer the
|
||||
Licensed Material under separate terms or conditions or stop
|
||||
distributing the Licensed Material at any time; however, doing so
|
||||
will not terminate this Public License.
|
||||
|
||||
d. Sections 1, 5, 6, 7, and 8 survive termination of this Public
|
||||
License.
|
||||
|
||||
|
||||
Section 7 -- Other Terms and Conditions.
|
||||
|
||||
a. The Licensor shall not be bound by any additional or different
|
||||
terms or conditions communicated by You unless expressly agreed.
|
||||
|
||||
b. Any arrangements, understandings, or agreements regarding the
|
||||
Licensed Material not stated herein are separate from and
|
||||
independent of the terms and conditions of this Public License.
|
||||
|
||||
|
||||
Section 8 -- Interpretation.
|
||||
|
||||
a. For the avoidance of doubt, this Public License does not, and
|
||||
shall not be interpreted to, reduce, limit, restrict, or impose
|
||||
conditions on any use of the Licensed Material that could lawfully
|
||||
be made without permission under this Public License.
|
||||
|
||||
b. To the extent possible, if any provision of this Public License is
|
||||
deemed unenforceable, it shall be automatically reformed to the
|
||||
minimum extent necessary to make it enforceable. If the provision
|
||||
cannot be reformed, it shall be severed from this Public License
|
||||
without affecting the enforceability of the remaining terms and
|
||||
conditions.
|
||||
|
||||
c. No term or condition of this Public License will be waived and no
|
||||
failure to comply consented to unless expressly agreed to by the
|
||||
Licensor.
|
||||
|
||||
d. Nothing in this Public License constitutes or may be interpreted
|
||||
as a limitation upon, or waiver of, any privileges and immunities
|
||||
that apply to the Licensor or You, including from the legal
|
||||
processes of any jurisdiction or authority.
|
||||
|
||||
|
||||
=======================================================================
|
||||
|
||||
Creative Commons is not a party to its public
|
||||
licenses. Notwithstanding, Creative Commons may elect to apply one of
|
||||
its public licenses to material it publishes and in those instances
|
||||
will be considered the “Licensor.” The text of the Creative Commons
|
||||
public licenses is dedicated to the public domain under the CC0 Public
|
||||
Domain Dedication. Except for the limited purpose of indicating that
|
||||
material is shared under a Creative Commons public license or as
|
||||
otherwise permitted by the Creative Commons policies published at
|
||||
creativecommons.org/policies, Creative Commons does not authorize the
|
||||
use of the trademark "Creative Commons" or any other trademark or logo
|
||||
of Creative Commons without its prior written consent including,
|
||||
without limitation, in connection with any unauthorized modifications
|
||||
to any of its public licenses or any other arrangements,
|
||||
understandings, or agreements concerning use of licensed material. For
|
||||
the avoidance of doubt, this paragraph does not form part of the
|
||||
public licenses.
|
||||
|
||||
Attribution-ShareAlike 4.0 International
|
||||
|
||||
=======================================================================
|
||||
|
||||
Creative Commons Corporation ("Creative Commons") is not a law firm and
|
||||
does not provide legal services or legal advice. Distribution of
|
||||
Creative Commons public licenses does not create a lawyer-client or
|
||||
other relationship. Creative Commons makes its licenses and related
|
||||
information available on an "as-is" basis. Creative Commons gives no
|
||||
warranties regarding its licenses, any material licensed under their
|
||||
terms and conditions, or any related information. Creative Commons
|
||||
disclaims all liability for damages resulting from their use to the
|
||||
fullest extent possible.
|
||||
|
||||
Using Creative Commons Public Licenses
|
||||
|
||||
Creative Commons public licenses provide a standard set of terms and
|
||||
conditions that creators and other rights holders may use to share
|
||||
original works of authorship and other material subject to copyright
|
||||
and certain other rights specified in the public license below. The
|
||||
following considerations are for informational purposes only, are not
|
||||
exhaustive, and do not form part of our licenses.
|
||||
|
||||
Considerations for licensors: Our public licenses are
|
||||
intended for use by those authorized to give the public
|
||||
permission to use material in ways otherwise restricted by
|
||||
copyright and certain other rights. Our licenses are
|
||||
irrevocable. Licensors should read and understand the terms
|
||||
and conditions of the license they choose before applying it.
|
||||
Licensors should also secure all rights necessary before
|
||||
applying our licenses so that the public can reuse the
|
||||
material as expected. Licensors should clearly mark any
|
||||
material not subject to the license. This includes other CC-
|
||||
licensed material, or material used under an exception or
|
||||
limitation to copyright. More considerations for licensors:
|
||||
wiki.creativecommons.org/Considerations_for_licensors
|
||||
|
||||
Considerations for the public: By using one of our public
|
||||
licenses, a licensor grants the public permission to use the
|
||||
licensed material under specified terms and conditions. If
|
||||
the licensor's permission is not necessary for any reason--for
|
||||
example, because of any applicable exception or limitation to
|
||||
copyright--then that use is not regulated by the license. Our
|
||||
licenses grant only permissions under copyright and certain
|
||||
other rights that a licensor has authority to grant. Use of
|
||||
the licensed material may still be restricted for other
|
||||
reasons, including because others have copyright or other
|
||||
rights in the material. A licensor may make special requests,
|
||||
such as asking that all changes be marked or described.
|
||||
Although not required by our licenses, you are encouraged to
|
||||
respect those requests where reasonable. More_considerations
|
||||
for the public:
|
||||
wiki.creativecommons.org/Considerations_for_licensees
|
||||
|
||||
=======================================================================
|
||||
|
||||
Creative Commons Attribution-ShareAlike 4.0 International Public
|
||||
License
|
||||
|
||||
By exercising the Licensed Rights (defined below), You accept and agree
|
||||
to be bound by the terms and conditions of this Creative Commons
|
||||
Attribution-ShareAlike 4.0 International Public License ("Public
|
||||
License"). To the extent this Public License may be interpreted as a
|
||||
contract, You are granted the Licensed Rights in consideration of Your
|
||||
acceptance of these terms and conditions, and the Licensor grants You
|
||||
such rights in consideration of benefits the Licensor receives from
|
||||
making the Licensed Material available under these terms and
|
||||
conditions.
|
||||
|
||||
|
||||
Section 1 -- Definitions.
|
||||
|
||||
a. Adapted Material means material subject to Copyright and Similar
|
||||
Rights that is derived from or based upon the Licensed Material
|
||||
and in which the Licensed Material is translated, altered,
|
||||
arranged, transformed, or otherwise modified in a manner requiring
|
||||
permission under the Copyright and Similar Rights held by the
|
||||
Licensor. For purposes of this Public License, where the Licensed
|
||||
Material is a musical work, performance, or sound recording,
|
||||
Adapted Material is always produced where the Licensed Material is
|
||||
synched in timed relation with a moving image.
|
||||
|
||||
b. Adapter's License means the license You apply to Your Copyright
|
||||
and Similar Rights in Your contributions to Adapted Material in
|
||||
accordance with the terms and conditions of this Public License.
|
||||
|
||||
c. BY-SA Compatible License means a license listed at
|
||||
creativecommons.org/compatiblelicenses, approved by Creative
|
||||
Commons as essentially the equivalent of this Public License.
|
||||
|
||||
d. Copyright and Similar Rights means copyright and/or similar rights
|
||||
closely related to copyright including, without limitation,
|
||||
performance, broadcast, sound recording, and Sui Generis Database
|
||||
Rights, without regard to how the rights are labeled or
|
||||
categorized. For purposes of this Public License, the rights
|
||||
specified in Section 2(b)(1)-(2) are not Copyright and Similar
|
||||
Rights.
|
||||
|
||||
e. Effective Technological Measures means those measures that, in the
|
||||
absence of proper authority, may not be circumvented under laws
|
||||
fulfilling obligations under Article 11 of the WIPO Copyright
|
||||
Treaty adopted on December 20, 1996, and/or similar international
|
||||
agreements.
|
||||
|
||||
f. Exceptions and Limitations means fair use, fair dealing, and/or
|
||||
any other exception or limitation to Copyright and Similar Rights
|
||||
that applies to Your use of the Licensed Material.
|
||||
|
||||
g. License Elements means the license attributes listed in the name
|
||||
of a Creative Commons Public License. The License Elements of this
|
||||
Public License are Attribution and ShareAlike.
|
||||
|
||||
h. Licensed Material means the artistic or literary work, database,
|
||||
or other material to which the Licensor applied this Public
|
||||
License.
|
||||
|
||||
i. Licensed Rights means the rights granted to You subject to the
|
||||
terms and conditions of this Public License, which are limited to
|
||||
all Copyright and Similar Rights that apply to Your use of the
|
||||
Licensed Material and that the Licensor has authority to license.
|
||||
|
||||
j. Licensor means the individual(s) or entity(ies) granting rights
|
||||
under this Public License.
|
||||
|
||||
k. Share means to provide material to the public by any means or
|
||||
process that requires permission under the Licensed Rights, such
|
||||
as reproduction, public display, public performance, distribution,
|
||||
dissemination, communication, or importation, and to make material
|
||||
available to the public including in ways that members of the
|
||||
public may access the material from a place and at a time
|
||||
individually chosen by them.
|
||||
|
||||
l. Sui Generis Database Rights means rights other than copyright
|
||||
resulting from Directive 96/9/EC of the European Parliament and of
|
||||
the Council of 11 March 1996 on the legal protection of databases,
|
||||
as amended and/or succeeded, as well as other essentially
|
||||
equivalent rights anywhere in the world.
|
||||
|
||||
m. You means the individual or entity exercising the Licensed Rights
|
||||
under this Public License. Your has a corresponding meaning.
|
||||
|
||||
|
||||
Section 2 -- Scope.
|
||||
|
||||
a. License grant.
|
||||
|
||||
1. Subject to the terms and conditions of this Public License,
|
||||
the Licensor hereby grants You a worldwide, royalty-free,
|
||||
non-sublicensable, non-exclusive, irrevocable license to
|
||||
exercise the Licensed Rights in the Licensed Material to:
|
||||
|
||||
a. reproduce and Share the Licensed Material, in whole or
|
||||
in part; and
|
||||
|
||||
b. produce, reproduce, and Share Adapted Material.
|
||||
|
||||
2. Exceptions and Limitations. For the avoidance of doubt, where
|
||||
Exceptions and Limitations apply to Your use, this Public
|
||||
License does not apply, and You do not need to comply with
|
||||
its terms and conditions.
|
||||
|
||||
3. Term. The term of this Public License is specified in Section
|
||||
6(a).
|
||||
|
||||
4. Media and formats; technical modifications allowed. The
|
||||
Licensor authorizes You to exercise the Licensed Rights in
|
||||
all media and formats whether now known or hereafter created,
|
||||
and to make technical modifications necessary to do so. The
|
||||
Licensor waives and/or agrees not to assert any right or
|
||||
authority to forbid You from making technical modifications
|
||||
necessary to exercise the Licensed Rights, including
|
||||
technical modifications necessary to circumvent Effective
|
||||
Technological Measures. For purposes of this Public License,
|
||||
simply making modifications authorized by this Section 2(a)
|
||||
(4) never produces Adapted Material.
|
||||
|
||||
5. Downstream recipients.
|
||||
|
||||
a. Offer from the Licensor -- Licensed Material. Every
|
||||
recipient of the Licensed Material automatically
|
||||
receives an offer from the Licensor to exercise the
|
||||
Licensed Rights under the terms and conditions of this
|
||||
Public License.
|
||||
|
||||
b. Additional offer from the Licensor -- Adapted Material.
|
||||
Every recipient of Adapted Material from You
|
||||
automatically receives an offer from the Licensor to
|
||||
exercise the Licensed Rights in the Adapted Material
|
||||
under the conditions of the Adapter's License You apply.
|
||||
|
||||
c. No downstream restrictions. You may not offer or impose
|
||||
any additional or different terms or conditions on, or
|
||||
apply any Effective Technological Measures to, the
|
||||
Licensed Material if doing so restricts exercise of the
|
||||
Licensed Rights by any recipient of the Licensed
|
||||
Material.
|
||||
|
||||
6. No endorsement. Nothing in this Public License constitutes or
|
||||
may be construed as permission to assert or imply that You
|
||||
are, or that Your use of the Licensed Material is, connected
|
||||
with, or sponsored, endorsed, or granted official status by,
|
||||
the Licensor or others designated to receive attribution as
|
||||
provided in Section 3(a)(1)(A)(i).
|
||||
|
||||
b. Other rights.
|
||||
|
||||
1. Moral rights, such as the right of integrity, are not
|
||||
licensed under this Public License, nor are publicity,
|
||||
privacy, and/or other similar personality rights; however, to
|
||||
the extent possible, the Licensor waives and/or agrees not to
|
||||
assert any such rights held by the Licensor to the limited
|
||||
extent necessary to allow You to exercise the Licensed
|
||||
Rights, but not otherwise.
|
||||
|
||||
2. Patent and trademark rights are not licensed under this
|
||||
Public License.
|
||||
|
||||
3. To the extent possible, the Licensor waives any right to
|
||||
collect royalties from You for the exercise of the Licensed
|
||||
Rights, whether directly or through a collecting society
|
||||
under any voluntary or waivable statutory or compulsory
|
||||
licensing scheme. In all other cases the Licensor expressly
|
||||
reserves any right to collect such royalties.
|
||||
|
||||
|
||||
Section 3 -- License Conditions.
|
||||
|
||||
Your exercise of the Licensed Rights is expressly made subject to the
|
||||
following conditions.
|
||||
|
||||
a. Attribution.
|
||||
|
||||
1. If You Share the Licensed Material (including in modified
|
||||
form), You must:
|
||||
|
||||
a. retain the following if it is supplied by the Licensor
|
||||
with the Licensed Material:
|
||||
|
||||
i. identification of the creator(s) of the Licensed
|
||||
Material and any others designated to receive
|
||||
attribution, in any reasonable manner requested by
|
||||
the Licensor (including by pseudonym if
|
||||
designated);
|
||||
|
||||
ii. a copyright notice;
|
||||
|
||||
iii. a notice that refers to this Public License;
|
||||
|
||||
iv. a notice that refers to the disclaimer of
|
||||
warranties;
|
||||
|
||||
v. a URI or hyperlink to the Licensed Material to the
|
||||
extent reasonably practicable;
|
||||
|
||||
b. indicate if You modified the Licensed Material and
|
||||
retain an indication of any previous modifications; and
|
||||
|
||||
c. indicate the Licensed Material is licensed under this
|
||||
Public License, and include the text of, or the URI or
|
||||
hyperlink to, this Public License.
|
||||
|
||||
2. You may satisfy the conditions in Section 3(a)(1) in any
|
||||
reasonable manner based on the medium, means, and context in
|
||||
which You Share the Licensed Material. For example, it may be
|
||||
reasonable to satisfy the conditions by providing a URI or
|
||||
hyperlink to a resource that includes the required
|
||||
information.
|
||||
|
||||
3. If requested by the Licensor, You must remove any of the
|
||||
information required by Section 3(a)(1)(A) to the extent
|
||||
reasonably practicable.
|
||||
|
||||
b. ShareAlike.
|
||||
|
||||
In addition to the conditions in Section 3(a), if You Share
|
||||
Adapted Material You produce, the following conditions also apply.
|
||||
|
||||
1. The Adapter's License You apply must be a Creative Commons
|
||||
license with the same License Elements, this version or
|
||||
later, or a BY-SA Compatible License.
|
||||
|
||||
2. You must include the text of, or the URI or hyperlink to, the
|
||||
Adapter's License You apply. You may satisfy this condition
|
||||
in any reasonable manner based on the medium, means, and
|
||||
context in which You Share Adapted Material.
|
||||
|
||||
3. You may not offer or impose any additional or different terms
|
||||
or conditions on, or apply any Effective Technological
|
||||
Measures to, Adapted Material that restrict exercise of the
|
||||
rights granted under the Adapter's License You apply.
|
||||
|
||||
|
||||
Section 4 -- Sui Generis Database Rights.
|
||||
|
||||
Where the Licensed Rights include Sui Generis Database Rights that
|
||||
apply to Your use of the Licensed Material:
|
||||
|
||||
a. for the avoidance of doubt, Section 2(a)(1) grants You the right
|
||||
to extract, reuse, reproduce, and Share all or a substantial
|
||||
portion of the contents of the database;
|
||||
|
||||
b. if You include all or a substantial portion of the database
|
||||
contents in a database in which You have Sui Generis Database
|
||||
Rights, then the database in which You have Sui Generis Database
|
||||
Rights (but not its individual contents) is Adapted Material,
|
||||
|
||||
including for purposes of Section 3(b); and
|
||||
c. You must comply with the conditions in Section 3(a) if You Share
|
||||
all or a substantial portion of the contents of the database.
|
||||
|
||||
For the avoidance of doubt, this Section 4 supplements and does not
|
||||
replace Your obligations under this Public License where the Licensed
|
||||
Rights include other Copyright and Similar Rights.
|
||||
|
||||
|
||||
Section 5 -- Disclaimer of Warranties and Limitation of Liability.
|
||||
|
||||
a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE
|
||||
EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS
|
||||
AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF
|
||||
ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS,
|
||||
IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION,
|
||||
WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS,
|
||||
ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT
|
||||
KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT
|
||||
ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU.
|
||||
|
||||
b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE
|
||||
TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION,
|
||||
NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT,
|
||||
INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES,
|
||||
COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR
|
||||
USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN
|
||||
ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR
|
||||
DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR
|
||||
IN PART, THIS LIMITATION MAY NOT APPLY TO YOU.
|
||||
|
||||
c. The disclaimer of warranties and limitation of liability provided
|
||||
above shall be interpreted in a manner that, to the extent
|
||||
possible, most closely approximates an absolute disclaimer and
|
||||
waiver of all liability.
|
||||
|
||||
|
||||
Section 6 -- Term and Termination.
|
||||
|
||||
a. This Public License applies for the term of the Copyright and
|
||||
Similar Rights licensed here. However, if You fail to comply with
|
||||
this Public License, then Your rights under this Public License
|
||||
terminate automatically.
|
||||
|
||||
b. Where Your right to use the Licensed Material has terminated under
|
||||
Section 6(a), it reinstates:
|
||||
|
||||
1. automatically as of the date the violation is cured, provided
|
||||
it is cured within 30 days of Your discovery of the
|
||||
violation; or
|
||||
|
||||
2. upon express reinstatement by the Licensor.
|
||||
|
||||
For the avoidance of doubt, this Section 6(b) does not affect any
|
||||
right the Licensor may have to seek remedies for Your violations
|
||||
of this Public License.
|
||||
|
||||
c. For the avoidance of doubt, the Licensor may also offer the
|
||||
Licensed Material under separate terms or conditions or stop
|
||||
distributing the Licensed Material at any time; however, doing so
|
||||
will not terminate this Public License.
|
||||
|
||||
d. Sections 1, 5, 6, 7, and 8 survive termination of this Public
|
||||
License.
|
||||
|
||||
|
||||
Section 7 -- Other Terms and Conditions.
|
||||
|
||||
a. The Licensor shall not be bound by any additional or different
|
||||
terms or conditions communicated by You unless expressly agreed.
|
||||
|
||||
b. Any arrangements, understandings, or agreements regarding the
|
||||
Licensed Material not stated herein are separate from and
|
||||
independent of the terms and conditions of this Public License.
|
||||
|
||||
|
||||
Section 8 -- Interpretation.
|
||||
|
||||
a. For the avoidance of doubt, this Public License does not, and
|
||||
shall not be interpreted to, reduce, limit, restrict, or impose
|
||||
conditions on any use of the Licensed Material that could lawfully
|
||||
be made without permission under this Public License.
|
||||
|
||||
b. To the extent possible, if any provision of this Public License is
|
||||
deemed unenforceable, it shall be automatically reformed to the
|
||||
minimum extent necessary to make it enforceable. If the provision
|
||||
cannot be reformed, it shall be severed from this Public License
|
||||
without affecting the enforceability of the remaining terms and
|
||||
conditions.
|
||||
|
||||
c. No term or condition of this Public License will be waived and no
|
||||
failure to comply consented to unless expressly agreed to by the
|
||||
Licensor.
|
||||
|
||||
d. Nothing in this Public License constitutes or may be interpreted
|
||||
as a limitation upon, or waiver of, any privileges and immunities
|
||||
that apply to the Licensor or You, including from the legal
|
||||
processes of any jurisdiction or authority.
|
||||
|
||||
|
||||
=======================================================================
|
||||
|
||||
Creative Commons is not a party to its public
|
||||
licenses. Notwithstanding, Creative Commons may elect to apply one of
|
||||
its public licenses to material it publishes and in those instances
|
||||
will be considered the “Licensor.” The text of the Creative Commons
|
||||
public licenses is dedicated to the public domain under the CC0 Public
|
||||
Domain Dedication. Except for the limited purpose of indicating that
|
||||
material is shared under a Creative Commons public license or as
|
||||
otherwise permitted by the Creative Commons policies published at
|
||||
creativecommons.org/policies, Creative Commons does not authorize the
|
||||
use of the trademark "Creative Commons" or any other trademark or logo
|
||||
of Creative Commons without its prior written consent including,
|
||||
without limitation, in connection with any unauthorized modifications
|
||||
to any of its public licenses or any other arrangements,
|
||||
understandings, or agreements concerning use of licensed material. For
|
||||
the avoidance of doubt, this paragraph does not form part of the
|
||||
public licenses.
|
||||
|
||||
Creative Commons may be contacted at creativecommons.org.
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,176 +1,176 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="1000mm"
|
||||
height="1000mm"
|
||||
viewBox="0 0 1000 1000"
|
||||
version="1.1"
|
||||
id="svg8"
|
||||
inkscape:version="0.92.4 (5da689c313, 2019-01-14)"
|
||||
sodipodi:docname="plum-blossom.svg"
|
||||
inkscape:export-filename="/home/psi/src/github.com/link-u/avif-sample-images/plum-blossom-small.png"
|
||||
inkscape:export-xdpi="13.0048"
|
||||
inkscape:export-ydpi="13.0048">
|
||||
<defs
|
||||
id="defs2" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="0.35"
|
||||
inkscape:cx="1367.1429"
|
||||
inkscape:cy="2035.7143"
|
||||
inkscape:document-units="mm"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
inkscape:window-width="2560"
|
||||
inkscape:window-height="1403"
|
||||
inkscape:window-x="2560"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1" />
|
||||
<metadata
|
||||
id="metadata5">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(0,703)">
|
||||
<circle
|
||||
id="path10"
|
||||
cx="500"
|
||||
cy="-453"
|
||||
style="fill:#ffd5d5;stroke-width:0.24955437"
|
||||
r="200" />
|
||||
<circle
|
||||
id="path10-9"
|
||||
cx="262.2359"
|
||||
cy="-280.25427"
|
||||
style="fill:#ffd5d5;stroke-width:0.24955437"
|
||||
r="200" />
|
||||
<circle
|
||||
id="path10-9-1"
|
||||
cx="737.76416"
|
||||
cy="-280.25427"
|
||||
style="fill:#ffd5d5;stroke-width:0.24955437"
|
||||
r="200" />
|
||||
<circle
|
||||
id="path10-9-2"
|
||||
cx="353.05371"
|
||||
cy="-0.74575806"
|
||||
style="fill:#ffd5d5;stroke-width:0.24955437"
|
||||
r="200" />
|
||||
<circle
|
||||
id="path10-9-2-7"
|
||||
cx="646.94629"
|
||||
cy="-0.74575806"
|
||||
style="fill:#ffd5d5;stroke-width:0.24955437"
|
||||
r="200" />
|
||||
<rect
|
||||
style="fill:#ffffff;stroke-width:0.23664318"
|
||||
id="rect215"
|
||||
width="20"
|
||||
height="160"
|
||||
x="493.0238"
|
||||
y="-430.27975" />
|
||||
<rect
|
||||
style="fill:#ffffff;stroke-width:0.26458332"
|
||||
id="rect217"
|
||||
width="2.2678571"
|
||||
height="10.583333"
|
||||
x="495.46429"
|
||||
y="-374.6012" />
|
||||
<circle
|
||||
style="fill:#ffeeaa;stroke-width:0.22826084"
|
||||
id="path221"
|
||||
cx="503.0238"
|
||||
cy="-437.10715"
|
||||
r="30" />
|
||||
<rect
|
||||
style="fill:#ffffff;stroke-width:0.23664318"
|
||||
id="rect215-0"
|
||||
width="20"
|
||||
height="160"
|
||||
x="336.11542"
|
||||
y="186.29741"
|
||||
transform="rotate(-72.000001)" />
|
||||
<circle
|
||||
style="fill:#ffeeaa;stroke-width:0.22826084"
|
||||
id="path221-9"
|
||||
cx="346.11542"
|
||||
cy="179.47002"
|
||||
r="30.000002"
|
||||
transform="rotate(-72.000001)" />
|
||||
<rect
|
||||
style="fill:#ffffff;stroke-width:0.23664318"
|
||||
id="rect215-0-3"
|
||||
width="20"
|
||||
height="160"
|
||||
x="-49.702778"
|
||||
y="-764.44379"
|
||||
transform="rotate(72)" />
|
||||
<circle
|
||||
style="fill:#ffeeaa;stroke-width:0.22826084"
|
||||
id="path221-9-6"
|
||||
cx="-39.702778"
|
||||
cy="-771.27118"
|
||||
r="30.000002"
|
||||
transform="rotate(72)" />
|
||||
<rect
|
||||
style="fill:#ffffff;stroke-width:0.23664318"
|
||||
id="rect215-0-3-0"
|
||||
width="20"
|
||||
height="160"
|
||||
x="-539.49518"
|
||||
y="-358.71228"
|
||||
transform="rotate(144)" />
|
||||
<circle
|
||||
style="fill:#ffeeaa;stroke-width:0.22826084"
|
||||
id="path221-9-6-6"
|
||||
cx="-529.49518"
|
||||
cy="-365.53967"
|
||||
r="30.000002"
|
||||
transform="rotate(144)" />
|
||||
<rect
|
||||
style="fill:#ffffff;stroke-width:0.23664318"
|
||||
id="rect215-0-3-0-2"
|
||||
width="20"
|
||||
height="160"
|
||||
x="-292.17621"
|
||||
y="228.38646"
|
||||
transform="rotate(-144)" />
|
||||
<circle
|
||||
style="fill:#ffeeaa;stroke-width:0.22826084"
|
||||
id="path221-9-6-6-6"
|
||||
cx="-282.17621"
|
||||
cy="221.55907"
|
||||
r="30.000002"
|
||||
transform="rotate(-144)" />
|
||||
<circle
|
||||
style="fill:#ffeeaa;stroke-width:0.31818181"
|
||||
id="path4004"
|
||||
cx="500"
|
||||
cy="-203"
|
||||
r="70" />
|
||||
</g>
|
||||
</svg>
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="1000mm"
|
||||
height="1000mm"
|
||||
viewBox="0 0 1000 1000"
|
||||
version="1.1"
|
||||
id="svg8"
|
||||
inkscape:version="0.92.4 (5da689c313, 2019-01-14)"
|
||||
sodipodi:docname="plum-blossom.svg"
|
||||
inkscape:export-filename="/home/psi/src/github.com/link-u/avif-sample-images/plum-blossom-small.png"
|
||||
inkscape:export-xdpi="13.0048"
|
||||
inkscape:export-ydpi="13.0048">
|
||||
<defs
|
||||
id="defs2" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="0.35"
|
||||
inkscape:cx="1367.1429"
|
||||
inkscape:cy="2035.7143"
|
||||
inkscape:document-units="mm"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
inkscape:window-width="2560"
|
||||
inkscape:window-height="1403"
|
||||
inkscape:window-x="2560"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1" />
|
||||
<metadata
|
||||
id="metadata5">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(0,703)">
|
||||
<circle
|
||||
id="path10"
|
||||
cx="500"
|
||||
cy="-453"
|
||||
style="fill:#ffd5d5;stroke-width:0.24955437"
|
||||
r="200" />
|
||||
<circle
|
||||
id="path10-9"
|
||||
cx="262.2359"
|
||||
cy="-280.25427"
|
||||
style="fill:#ffd5d5;stroke-width:0.24955437"
|
||||
r="200" />
|
||||
<circle
|
||||
id="path10-9-1"
|
||||
cx="737.76416"
|
||||
cy="-280.25427"
|
||||
style="fill:#ffd5d5;stroke-width:0.24955437"
|
||||
r="200" />
|
||||
<circle
|
||||
id="path10-9-2"
|
||||
cx="353.05371"
|
||||
cy="-0.74575806"
|
||||
style="fill:#ffd5d5;stroke-width:0.24955437"
|
||||
r="200" />
|
||||
<circle
|
||||
id="path10-9-2-7"
|
||||
cx="646.94629"
|
||||
cy="-0.74575806"
|
||||
style="fill:#ffd5d5;stroke-width:0.24955437"
|
||||
r="200" />
|
||||
<rect
|
||||
style="fill:#ffffff;stroke-width:0.23664318"
|
||||
id="rect215"
|
||||
width="20"
|
||||
height="160"
|
||||
x="493.0238"
|
||||
y="-430.27975" />
|
||||
<rect
|
||||
style="fill:#ffffff;stroke-width:0.26458332"
|
||||
id="rect217"
|
||||
width="2.2678571"
|
||||
height="10.583333"
|
||||
x="495.46429"
|
||||
y="-374.6012" />
|
||||
<circle
|
||||
style="fill:#ffeeaa;stroke-width:0.22826084"
|
||||
id="path221"
|
||||
cx="503.0238"
|
||||
cy="-437.10715"
|
||||
r="30" />
|
||||
<rect
|
||||
style="fill:#ffffff;stroke-width:0.23664318"
|
||||
id="rect215-0"
|
||||
width="20"
|
||||
height="160"
|
||||
x="336.11542"
|
||||
y="186.29741"
|
||||
transform="rotate(-72.000001)" />
|
||||
<circle
|
||||
style="fill:#ffeeaa;stroke-width:0.22826084"
|
||||
id="path221-9"
|
||||
cx="346.11542"
|
||||
cy="179.47002"
|
||||
r="30.000002"
|
||||
transform="rotate(-72.000001)" />
|
||||
<rect
|
||||
style="fill:#ffffff;stroke-width:0.23664318"
|
||||
id="rect215-0-3"
|
||||
width="20"
|
||||
height="160"
|
||||
x="-49.702778"
|
||||
y="-764.44379"
|
||||
transform="rotate(72)" />
|
||||
<circle
|
||||
style="fill:#ffeeaa;stroke-width:0.22826084"
|
||||
id="path221-9-6"
|
||||
cx="-39.702778"
|
||||
cy="-771.27118"
|
||||
r="30.000002"
|
||||
transform="rotate(72)" />
|
||||
<rect
|
||||
style="fill:#ffffff;stroke-width:0.23664318"
|
||||
id="rect215-0-3-0"
|
||||
width="20"
|
||||
height="160"
|
||||
x="-539.49518"
|
||||
y="-358.71228"
|
||||
transform="rotate(144)" />
|
||||
<circle
|
||||
style="fill:#ffeeaa;stroke-width:0.22826084"
|
||||
id="path221-9-6-6"
|
||||
cx="-529.49518"
|
||||
cy="-365.53967"
|
||||
r="30.000002"
|
||||
transform="rotate(144)" />
|
||||
<rect
|
||||
style="fill:#ffffff;stroke-width:0.23664318"
|
||||
id="rect215-0-3-0-2"
|
||||
width="20"
|
||||
height="160"
|
||||
x="-292.17621"
|
||||
y="228.38646"
|
||||
transform="rotate(-144)" />
|
||||
<circle
|
||||
style="fill:#ffeeaa;stroke-width:0.22826084"
|
||||
id="path221-9-6-6-6"
|
||||
cx="-282.17621"
|
||||
cy="221.55907"
|
||||
r="30.000002"
|
||||
transform="rotate(-144)" />
|
||||
<circle
|
||||
style="fill:#ffeeaa;stroke-width:0.31818181"
|
||||
id="path4004"
|
||||
cx="500"
|
||||
cy="-203"
|
||||
r="70" />
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 4.6 KiB After Width: | Height: | Size: 4.8 KiB |
@ -1,23 +1,23 @@
|
||||
##!/usr/bin/env bash
|
||||
|
||||
avif=$2
|
||||
decoded=$3
|
||||
|
||||
orig=$(cat Makefile | grep "^${avif}" | sed "s/^${avif}: \(.*\)$/\1/")
|
||||
|
||||
if (echo ${avif} | grep "monochrome"); then
|
||||
# FIMXE(ledyba-z): compare monochrome images.
|
||||
score="100.0"
|
||||
elif (echo ${avif} | grep "\(rotate\|mirror\|crop\)"); then
|
||||
# FIMXE(ledyba-z): compare transformed images
|
||||
score="100.0"
|
||||
else
|
||||
score=$(compare -metric PSNR ${orig} ${decoded} NULL: 2>&1 || true)
|
||||
fi
|
||||
if test $(echo "${score} >= 35.0" | bc -l) -eq 1; then
|
||||
echo "Passing: ${decoded}: ${score}"
|
||||
exit 0
|
||||
else
|
||||
echo "Failed: ${decoded}: ${score} (vs ${orig})"
|
||||
exit -1
|
||||
fi
|
||||
##!/usr/bin/env bash
|
||||
|
||||
avif=$2
|
||||
decoded=$3
|
||||
|
||||
orig=$(cat Makefile | grep "^${avif}" | sed "s/^${avif}: \(.*\)$/\1/")
|
||||
|
||||
if (echo ${avif} | grep "monochrome"); then
|
||||
# FIMXE(ledyba-z): compare monochrome images.
|
||||
score="100.0"
|
||||
elif (echo ${avif} | grep "\(rotate\|mirror\|crop\)"); then
|
||||
# FIMXE(ledyba-z): compare transformed images
|
||||
score="100.0"
|
||||
else
|
||||
score=$(compare -metric PSNR ${orig} ${decoded} NULL: 2>&1 || true)
|
||||
fi
|
||||
if test $(echo "${score} >= 35.0" | bc -l) -eq 1; then
|
||||
echo "Passing: ${decoded}: ${score}"
|
||||
exit 0
|
||||
else
|
||||
echo "Failed: ${decoded}: ${score} (vs ${orig})"
|
||||
exit -1
|
||||
fi
|
||||
|
@ -1,9 +1,9 @@
|
||||
file 'star.png'
|
||||
duration 0.1
|
||||
file 'star90.png'
|
||||
duration 0.1
|
||||
file 'star180.png'
|
||||
duration 0.1
|
||||
file 'star270.png'
|
||||
duration 0.1
|
||||
file 'star.png'
|
||||
file 'star.png'
|
||||
duration 0.1
|
||||
file 'star90.png'
|
||||
duration 0.1
|
||||
file 'star180.png'
|
||||
duration 0.1
|
||||
file 'star270.png'
|
||||
duration 0.1
|
||||
file 'star.png'
|
||||
|
@ -1,83 +1,83 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="310.57089mm"
|
||||
height="310.57089mm"
|
||||
viewBox="0 0 310.57089 310.57089"
|
||||
version="1.1"
|
||||
id="svg8"
|
||||
inkscape:version="0.92.4 (5da689c313, 2019-01-14)"
|
||||
sodipodi:docname="star.svg"
|
||||
inkscape:export-filename="/home/psi/g/lu/avif-sample-images/star.png"
|
||||
inkscape:export-xdpi="13.0048"
|
||||
inkscape:export-ydpi="13.0048">
|
||||
<defs
|
||||
id="defs2" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="0.35"
|
||||
inkscape:cx="-377.14283"
|
||||
inkscape:cy="435.7143"
|
||||
inkscape:document-units="mm"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
fit-margin-top="0"
|
||||
fit-margin-left="0"
|
||||
fit-margin-right="0"
|
||||
fit-margin-bottom="0"
|
||||
inkscape:window-width="2560"
|
||||
inkscape:window-height="1369"
|
||||
inkscape:window-x="2560"
|
||||
inkscape:window-y="1474"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:snap-others="true" />
|
||||
<metadata
|
||||
id="metadata5">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="レイヤー 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(7.4768269e-6,13.570917)">
|
||||
<path
|
||||
sodipodi:type="star"
|
||||
style="fill:#ffeeaa;stroke-width:0.26458332"
|
||||
id="path10"
|
||||
sodipodi:sides="5"
|
||||
sodipodi:cx="155.28574"
|
||||
sodipodi:cy="141.64303"
|
||||
sodipodi:r1="154.21428"
|
||||
sodipodi:r2="77.10714"
|
||||
sodipodi:arg1="-1.5707963"
|
||||
sodipodi:arg2="-0.9424778"
|
||||
inkscape:flatsided="false"
|
||||
inkscape:rounded="0.05"
|
||||
inkscape:randomized="0"
|
||||
d="m 155.28574,-12.571243 c 5.12042,0 41.17993,88.823585 45.32244,91.833292 4.1425,3.009707 99.76176,9.85635 101.34405,14.726158 1.5823,4.869808 -71.75095,66.612433 -73.33325,71.482243 -1.58229,4.86981 21.45414,97.92485 17.31163,100.93456 -4.1425,3.00971 -85.52445,-47.65483 -90.64487,-47.65483 -5.12042,0 -86.50238,50.66453 -90.644886,47.65483 C 60.498348,263.3953 83.534785,170.34026 81.952489,165.47045 80.370192,160.60064 7.0369457,98.858007 8.6192422,93.988199 10.201539,89.118391 105.82079,82.271756 109.9633,79.26205 c 4.1425,-3.009707 40.20202,-91.833293 45.32244,-91.833293 z"
|
||||
inkscape:export-xdpi="13.0048"
|
||||
inkscape:export-ydpi="13.0048"
|
||||
inkscape:transform-center-y="-14.661668" />
|
||||
</g>
|
||||
</svg>
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="310.57089mm"
|
||||
height="310.57089mm"
|
||||
viewBox="0 0 310.57089 310.57089"
|
||||
version="1.1"
|
||||
id="svg8"
|
||||
inkscape:version="0.92.4 (5da689c313, 2019-01-14)"
|
||||
sodipodi:docname="star.svg"
|
||||
inkscape:export-filename="/home/psi/g/lu/avif-sample-images/star.png"
|
||||
inkscape:export-xdpi="13.0048"
|
||||
inkscape:export-ydpi="13.0048">
|
||||
<defs
|
||||
id="defs2" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="0.35"
|
||||
inkscape:cx="-377.14283"
|
||||
inkscape:cy="435.7143"
|
||||
inkscape:document-units="mm"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
fit-margin-top="0"
|
||||
fit-margin-left="0"
|
||||
fit-margin-right="0"
|
||||
fit-margin-bottom="0"
|
||||
inkscape:window-width="2560"
|
||||
inkscape:window-height="1369"
|
||||
inkscape:window-x="2560"
|
||||
inkscape:window-y="1474"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:snap-others="true" />
|
||||
<metadata
|
||||
id="metadata5">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="レイヤー 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(7.4768269e-6,13.570917)">
|
||||
<path
|
||||
sodipodi:type="star"
|
||||
style="fill:#ffeeaa;stroke-width:0.26458332"
|
||||
id="path10"
|
||||
sodipodi:sides="5"
|
||||
sodipodi:cx="155.28574"
|
||||
sodipodi:cy="141.64303"
|
||||
sodipodi:r1="154.21428"
|
||||
sodipodi:r2="77.10714"
|
||||
sodipodi:arg1="-1.5707963"
|
||||
sodipodi:arg2="-0.9424778"
|
||||
inkscape:flatsided="false"
|
||||
inkscape:rounded="0.05"
|
||||
inkscape:randomized="0"
|
||||
d="m 155.28574,-12.571243 c 5.12042,0 41.17993,88.823585 45.32244,91.833292 4.1425,3.009707 99.76176,9.85635 101.34405,14.726158 1.5823,4.869808 -71.75095,66.612433 -73.33325,71.482243 -1.58229,4.86981 21.45414,97.92485 17.31163,100.93456 -4.1425,3.00971 -85.52445,-47.65483 -90.64487,-47.65483 -5.12042,0 -86.50238,50.66453 -90.644886,47.65483 C 60.498348,263.3953 83.534785,170.34026 81.952489,165.47045 80.370192,160.60064 7.0369457,98.858007 8.6192422,93.988199 10.201539,89.118391 105.82079,82.271756 109.9633,79.26205 c 4.1425,-3.009707 40.20202,-91.833293 45.32244,-91.833293 z"
|
||||
inkscape:export-xdpi="13.0048"
|
||||
inkscape:export-ydpi="13.0048"
|
||||
inkscape:transform-center-y="-14.661668" />
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 3.1 KiB |
4
third_party/rust/mp4parse/src/boxes.rs
vendored
4
third_party/rust/mp4parse/src/boxes.rs
vendored
@ -15,7 +15,7 @@ struct String;
|
||||
|
||||
macro_rules! box_database {
|
||||
($($(#[$attr:meta])* $boxenum:ident $boxtype:expr),*,) => {
|
||||
#[derive(Clone, Copy, PartialEq)]
|
||||
#[derive(Clone, Copy, PartialEq, Eq)]
|
||||
pub enum BoxType {
|
||||
$($(#[$attr])* $boxenum),*,
|
||||
UnknownBox(u32),
|
||||
@ -110,6 +110,8 @@ box_database!(
|
||||
MovieHeaderBox 0x6d76_6864, // "mvhd"
|
||||
TrackBox 0x7472_616b, // "trak"
|
||||
TrackHeaderBox 0x746b_6864, // "tkhd"
|
||||
TrackReferenceBox 0x7472_6566, // "tref"
|
||||
AuxiliaryBox 0x6175_786C, // "auxl"
|
||||
EditBox 0x6564_7473, // "edts"
|
||||
MediaBox 0x6d64_6961, // "mdia"
|
||||
EditListBox 0x656c_7374, // "elst"
|
||||
|
1296
third_party/rust/mp4parse/src/lib.rs
vendored
1296
third_party/rust/mp4parse/src/lib.rs
vendored
File diff suppressed because it is too large
Load Diff
2
third_party/rust/mp4parse/src/macros.rs
vendored
2
third_party/rust/mp4parse/src/macros.rs
vendored
@ -6,7 +6,7 @@ macro_rules! check_parser_state {
|
||||
( $src:expr ) => {
|
||||
if $src.limit() > 0 {
|
||||
debug!("bad parser state: {} content bytes left", $src.limit());
|
||||
return Err(Error::InvalidData("unread box content or bad parser sync"));
|
||||
return Status::CheckParserStateErr.into();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
74
third_party/rust/mp4parse/src/tests.rs
vendored
74
third_party/rust/mp4parse/src/tests.rs
vendored
@ -6,17 +6,16 @@
|
||||
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
use super::read_mp4;
|
||||
use super::Error;
|
||||
use super::ParseStrictness;
|
||||
use super::{Error, Status};
|
||||
use fallible_collections::TryRead as _;
|
||||
|
||||
use std::convert::TryInto as _;
|
||||
use std::io::Cursor;
|
||||
use std::io::Read as _;
|
||||
extern crate test_assembler;
|
||||
use self::test_assembler::*;
|
||||
use test_assembler::*;
|
||||
|
||||
use boxes::BoxType;
|
||||
use crate::boxes::BoxType;
|
||||
|
||||
enum BoxSize {
|
||||
Short(u32),
|
||||
@ -122,7 +121,7 @@ fn read_box_header_short_unknown_size() {
|
||||
fn read_box_header_short_invalid_size() {
|
||||
let mut stream = make_box(BoxSize::UncheckedShort(2), b"test", |s| s);
|
||||
match super::read_box_header(&mut stream) {
|
||||
Err(Error::InvalidData(s)) => assert_eq!(s, "malformed size"),
|
||||
Err(Error::InvalidData(s)) => assert_eq!(s, Status::BoxBadSize),
|
||||
_ => panic!("unexpected result reading box with invalid size"),
|
||||
};
|
||||
}
|
||||
@ -131,7 +130,7 @@ fn read_box_header_short_invalid_size() {
|
||||
fn read_box_header_long_invalid_size() {
|
||||
let mut stream = make_box(BoxSize::UncheckedLong(2), b"test", |s| s);
|
||||
match super::read_box_header(&mut stream) {
|
||||
Err(Error::InvalidData(s)) => assert_eq!(s, "malformed wide size"),
|
||||
Err(Error::InvalidData(s)) => assert_eq!(s, Status::BoxBadWideSize),
|
||||
_ => panic!("unexpected result reading box with invalid size"),
|
||||
};
|
||||
}
|
||||
@ -490,7 +489,10 @@ fn read_hdlr_multiple_nul_in_name() {
|
||||
let mut stream = iter.next_box().unwrap().unwrap();
|
||||
assert_eq!(stream.head.name, BoxType::HandlerBox);
|
||||
assert_eq!(stream.head.size, 45);
|
||||
assert!(super::read_hdlr(&mut stream, ParseStrictness::Strict).is_err());
|
||||
assert_eq!(
|
||||
super::Status::from(super::read_hdlr(&mut stream, ParseStrictness::Strict)),
|
||||
super::Status::HdlrNameMultipleNul,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -515,13 +517,10 @@ fn read_hdlr_unsupported_version() {
|
||||
let mut stream = iter.next_box().unwrap().unwrap();
|
||||
assert_eq!(stream.head.name, BoxType::HandlerBox);
|
||||
assert_eq!(stream.head.size, 32);
|
||||
match super::read_hdlr(&mut stream, ParseStrictness::Normal) {
|
||||
Err(Error::Unsupported(msg)) => assert_eq!("hdlr version", msg),
|
||||
result => {
|
||||
eprintln!("{:?}", result);
|
||||
panic!("expected Error::Unsupported")
|
||||
}
|
||||
}
|
||||
assert_eq!(
|
||||
super::Status::from(super::read_hdlr(&mut stream, ParseStrictness::Normal)),
|
||||
super::Status::HdlrUnsupportedVersion,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -533,17 +532,10 @@ fn read_hdlr_invalid_pre_defined_field() {
|
||||
let mut stream = iter.next_box().unwrap().unwrap();
|
||||
assert_eq!(stream.head.name, BoxType::HandlerBox);
|
||||
assert_eq!(stream.head.size, 32);
|
||||
match super::read_hdlr(&mut stream, ParseStrictness::Strict) {
|
||||
Err(Error::InvalidData(msg)) => assert_eq!(
|
||||
"The HandlerBox 'pre_defined' field shall be 0 \
|
||||
per ISOBMFF (ISO 14496-12:2020) § 8.4.3.2",
|
||||
msg
|
||||
),
|
||||
result => {
|
||||
eprintln!("{:?}", result);
|
||||
panic!("expected Error::InvalidData")
|
||||
}
|
||||
}
|
||||
assert_eq!(
|
||||
super::Status::from(super::read_hdlr(&mut stream, ParseStrictness::Strict)),
|
||||
super::Status::HdlrPredefinedNonzero,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -555,17 +547,10 @@ fn read_hdlr_invalid_reserved_field() {
|
||||
let mut stream = iter.next_box().unwrap().unwrap();
|
||||
assert_eq!(stream.head.name, BoxType::HandlerBox);
|
||||
assert_eq!(stream.head.size, 32);
|
||||
match super::read_hdlr(&mut stream, ParseStrictness::Strict) {
|
||||
Err(Error::InvalidData(msg)) => assert_eq!(
|
||||
"The HandlerBox 'reserved' fields shall be 0 \
|
||||
per ISOBMFF (ISO 14496-12:2020) § 8.4.3.2",
|
||||
msg
|
||||
),
|
||||
result => {
|
||||
eprintln!("{:?}", result);
|
||||
panic!("expected Error::InvalidData")
|
||||
}
|
||||
}
|
||||
assert_eq!(
|
||||
super::Status::from(super::read_hdlr(&mut stream, ParseStrictness::Strict)),
|
||||
super::Status::HdlrReservedNonzero,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -577,17 +562,10 @@ fn read_hdlr_zero_length_name() {
|
||||
let mut stream = iter.next_box().unwrap().unwrap();
|
||||
assert_eq!(stream.head.name, BoxType::HandlerBox);
|
||||
assert_eq!(stream.head.size, 32);
|
||||
match super::read_hdlr(&mut stream, ParseStrictness::Normal) {
|
||||
Err(Error::InvalidData(msg)) => assert_eq!(
|
||||
"The HandlerBox 'name' field shall be null-terminated \
|
||||
per ISOBMFF (ISO 14496-12:2020) § 8.4.3.2",
|
||||
msg
|
||||
),
|
||||
result => {
|
||||
eprintln!("{:?}", result);
|
||||
panic!("expected Error::InvalidData")
|
||||
}
|
||||
}
|
||||
assert_eq!(
|
||||
super::Status::from(super::read_hdlr(&mut stream, ParseStrictness::Normal)),
|
||||
super::Status::HdlrNameNoNul,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -1278,7 +1256,7 @@ fn read_esds_invalid_descriptor() {
|
||||
let mut stream = iter.next_box().unwrap().unwrap();
|
||||
|
||||
match super::read_esds(&mut stream) {
|
||||
Err(Error::InvalidData(s)) => assert_eq!(s, "Invalid descriptor."),
|
||||
Err(Error::InvalidData(s)) => assert_eq!(s, Status::EsdsBadDescriptor),
|
||||
_ => panic!("unexpected result with invalid descriptor"),
|
||||
}
|
||||
}
|
||||
|
4
third_party/rust/mp4parse/src/unstable.rs
vendored
4
third_party/rust/mp4parse/src/unstable.rs
vendored
@ -106,7 +106,7 @@ impl<T: std::cmp::PartialEq> PartialEq<T> for CheckedInteger<T> {
|
||||
/// sample data offset (start and end), composition time in microseconds
|
||||
/// (start and end) and whether it is a sync sample
|
||||
#[repr(C)]
|
||||
#[derive(Default, Debug, PartialEq)]
|
||||
#[derive(Default, Debug, PartialEq, Eq)]
|
||||
pub struct Indice {
|
||||
/// The byte offset in the file where the indexed sample begins.
|
||||
pub start_offset: CheckedInteger<u64>,
|
||||
@ -489,7 +489,7 @@ where
|
||||
})
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub struct Microseconds<T>(pub T);
|
||||
|
||||
/// Convert `time` in media's global (mvhd) timescale to microseconds,
|
||||
|
BIN
third_party/rust/mp4parse/tests/corrupt/invalid-transformation-order.avif
vendored
Normal file
BIN
third_party/rust/mp4parse/tests/corrupt/invalid-transformation-order.avif
vendored
Normal file
Binary file not shown.
BIN
third_party/rust/mp4parse/tests/corrupt/no-alpha-ispe.avif
vendored
Normal file
BIN
third_party/rust/mp4parse/tests/corrupt/no-alpha-ispe.avif
vendored
Normal file
Binary file not shown.
BIN
third_party/rust/mp4parse/tests/corrupt/transformation-before-ispe.avif
vendored
Normal file
BIN
third_party/rust/mp4parse/tests/corrupt/transformation-before-ispe.avif
vendored
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
185
third_party/rust/mp4parse/tests/public.rs
vendored
185
third_party/rust/mp4parse/tests/public.rs
vendored
@ -2,9 +2,9 @@
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
extern crate mp4parse as mp4;
|
||||
use mp4parse as mp4;
|
||||
|
||||
use mp4::{Error, ParseStrictness, Status};
|
||||
use crate::mp4::{ParseStrictness, Status};
|
||||
use std::convert::TryInto;
|
||||
use std::fs::File;
|
||||
use std::io::{Cursor, Read, Seek, SeekFrom};
|
||||
@ -53,6 +53,9 @@ static IMAGE_AVIF_NO_PITM: &str = "tests/corrupt/no-pitm.avif";
|
||||
static IMAGE_AVIF_NO_PIXI: &str = "tests/corrupt/no-pixi.avif";
|
||||
static IMAGE_AVIF_NO_AV1C: &str = "tests/corrupt/no-av1C.avif";
|
||||
static IMAGE_AVIF_NO_ISPE: &str = "tests/corrupt/no-ispe.avif";
|
||||
static IMAGE_AVIF_NO_ALPHA_ISPE: &str = "tests/corrupt/no-alpha-ispe.avif";
|
||||
static IMAGE_AVIF_TRANSFORM_ORDER: &str = "tests/corrupt/invalid-transformation-order.avif";
|
||||
static IMAGE_AVIF_TRANSFORM_BEFORE_ISPE: &str = "tests/corrupt/transformation-before-ispe.avif";
|
||||
static IMAGE_AVIF_NO_ALPHA_AV1C: &str = "tests/corrupt/no-alpha-av1C.avif";
|
||||
static IMAGE_AVIF_NO_ALPHA_PIXI: &str = "tests/corrupt/no-pixi-for-alpha.avif";
|
||||
static IMAGE_AVIF_AV1C_MISSING_ESSENTIAL: &str = "tests/av1C-missing-essential.avif";
|
||||
@ -92,8 +95,6 @@ static AVIF_UNSUPPORTED_IMAGES: &[&str] = &[
|
||||
AVIF_GRID,
|
||||
AVIF_GRID_A1LX,
|
||||
AVIF_LSEL,
|
||||
AVIF_AVIS_MAJOR_NO_PITM,
|
||||
AVIF_AVIS_MAJOR_WITH_PITM_AND_ALPHA,
|
||||
"av1-avif/testFiles/Apple/multilayer_examples/animals_00_multilayer_a1lx.avif",
|
||||
"av1-avif/testFiles/Apple/multilayer_examples/animals_00_multilayer_a1op.avif",
|
||||
"av1-avif/testFiles/Apple/multilayer_examples/animals_00_multilayer_a1op_lsel.avif",
|
||||
@ -104,7 +105,6 @@ static AVIF_UNSUPPORTED_IMAGES: &[&str] = &[
|
||||
"av1-avif/testFiles/Microsoft/Chimera_10bit_cropped_to_1920x1008.avif",
|
||||
"av1-avif/testFiles/Microsoft/Chimera_10bit_cropped_to_1920x1008_with_HDR_metadata.avif",
|
||||
"av1-avif/testFiles/Microsoft/Chimera_8bit_cropped_480x256.avif",
|
||||
"av1-avif/testFiles/Netflix/avis/alpha_video.avif",
|
||||
"av1-avif/testFiles/Xiph/abandoned_filmgrain.avif",
|
||||
"av1-avif/testFiles/Xiph/fruits_2layer_thumbsize.avif",
|
||||
"av1-avif/testFiles/Xiph/quebec_3layer_op2.avif",
|
||||
@ -112,18 +112,27 @@ static AVIF_UNSUPPORTED_IMAGES: &[&str] = &[
|
||||
"av1-avif/testFiles/Xiph/tiger_3layer_3res.avif",
|
||||
"link-u-avif-sample-images/kimono.crop.avif",
|
||||
"link-u-avif-sample-images/kimono.mirror-vertical.rotate270.crop.avif",
|
||||
"link-u-avif-sample-images/star-10bpc-with-alpha.avifs",
|
||||
"link-u-avif-sample-images/star-10bpc.avifs",
|
||||
"link-u-avif-sample-images/star-12bpc-with-alpha.avifs",
|
||||
"link-u-avif-sample-images/star-12bpc.avifs",
|
||||
"link-u-avif-sample-images/star-8bpc-with-alpha.avifs",
|
||||
"link-u-avif-sample-images/star-8bpc.avifs",
|
||||
];
|
||||
/// See https://github.com/AOMediaCodec/av1-avif/issues/150
|
||||
/// https://github.com/AOMediaCodec/av1-avif/issues/174
|
||||
/// and https://github.com/AOMediaCodec/av1-avif/issues/177
|
||||
/// https://github.com/AOMediaCodec/av1-avif/issues/177
|
||||
/// and https://github.com/AOMediaCodec/av1-avif/issues/178
|
||||
// TODO: make this into a map of expected errors?
|
||||
static AV1_AVIF_CORRUPT_IMAGES: &[&str] = &[
|
||||
"av1-avif/testFiles/Link-U/kimono.crop.avif",
|
||||
"av1-avif/testFiles/Link-U/kimono.mirror-horizontal.avif",
|
||||
"av1-avif/testFiles/Link-U/kimono.mirror-vertical.avif",
|
||||
"av1-avif/testFiles/Link-U/kimono.mirror-vertical.rotate270.avif",
|
||||
"av1-avif/testFiles/Link-U/kimono.mirror-vertical.rotate270.crop.avif",
|
||||
"av1-avif/testFiles/Link-U/kimono.rotate90.avif",
|
||||
"av1-avif/testFiles/Link-U/kimono.rotate270.avif",
|
||||
"link-u-avif-sample-images/kimono.crop.avif",
|
||||
"link-u-avif-sample-images/kimono.mirror-horizontal.avif",
|
||||
"link-u-avif-sample-images/kimono.mirror-vertical.avif",
|
||||
"link-u-avif-sample-images/kimono.mirror-vertical.rotate270.avif",
|
||||
"link-u-avif-sample-images/kimono.mirror-vertical.rotate270.crop.avif",
|
||||
"link-u-avif-sample-images/kimono.rotate90.avif",
|
||||
"link-u-avif-sample-images/kimono.rotate270.avif",
|
||||
"link-u-avif-sample-images/plum-blossom-large.profile0.10bpc.yuv420.alpha-full.avif",
|
||||
"link-u-avif-sample-images/plum-blossom-large.profile0.10bpc.yuv420.alpha-full.monochrome.avif",
|
||||
"link-u-avif-sample-images/plum-blossom-large.profile0.10bpc.yuv420.alpha-limited.avif",
|
||||
@ -328,7 +337,7 @@ fn public_api() {
|
||||
assert!(a.samplesize > 0);
|
||||
assert!(a.samplerate > 0.0);
|
||||
}
|
||||
mp4::TrackType::Metadata | mp4::TrackType::Unknown => {}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -849,7 +858,7 @@ fn public_mp4_bug_1185230() {
|
||||
fn public_mp4_ctts_overflow() {
|
||||
let input = &mut File::open("tests/clusterfuzz-testcase-minimized-mp4-6093954524250112")
|
||||
.expect("Unknown file");
|
||||
assert_invalid_data(mp4::read_mp4(input), "insufficient data in 'ctts' box");
|
||||
assert_eq!(Status::from(mp4::read_mp4(input)), Status::CttsBadSize);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -911,22 +920,6 @@ fn public_avif_bug_1661347() {
|
||||
assert!(mp4::read_avif(input, ParseStrictness::Normal).is_err());
|
||||
}
|
||||
|
||||
fn assert_invalid_data<T: std::fmt::Debug>(result: mp4::Result<T>, expected_msg: &str) {
|
||||
match result {
|
||||
Err(Error::InvalidData(msg)) if msg == expected_msg => {}
|
||||
Err(Error::InvalidData(msg)) if msg != expected_msg => {
|
||||
panic!(
|
||||
"Error message mismatch\nExpected: {}\nFound: {}",
|
||||
expected_msg, msg
|
||||
);
|
||||
}
|
||||
r => panic!(
|
||||
"Expected Err(Error::InvalidData({:?}), found {:?}",
|
||||
expected_msg, r
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
fn for_strictness_result(
|
||||
path: &str,
|
||||
check: impl Fn(ParseStrictness, mp4::Result<mp4::AvifContext>),
|
||||
@ -944,18 +937,7 @@ fn for_strictness_result(
|
||||
}
|
||||
|
||||
/// Check that input generates the expected error only in strict parsing mode
|
||||
fn assert_avif_should(path: &str, expected_msg: &str) {
|
||||
let input = &mut File::open(path).expect("Unknown file");
|
||||
assert_invalid_data(mp4::read_avif(input, ParseStrictness::Strict), expected_msg);
|
||||
input.seek(SeekFrom::Start(0)).expect("rewind failed");
|
||||
mp4::read_avif(input, ParseStrictness::Normal).expect("ParseStrictness::Normal failed");
|
||||
input.seek(SeekFrom::Start(0)).expect("rewind failed");
|
||||
mp4::read_avif(input, ParseStrictness::Permissive).expect("ParseStrictness::Permissive failed");
|
||||
}
|
||||
|
||||
/// Check that input generates the expected error only in strict parsing mode
|
||||
// TODO: replace assert_avif_should
|
||||
fn assert_avif_should2(path: &str, expected: Status) {
|
||||
fn assert_avif_should(path: &str, expected: Status) {
|
||||
for_strictness_result(path, |strictness, result| {
|
||||
if strictness == ParseStrictness::Strict {
|
||||
assert_eq!(expected, Status::from(result));
|
||||
@ -966,17 +948,7 @@ fn assert_avif_should2(path: &str, expected: Status) {
|
||||
}
|
||||
|
||||
/// Check that input generates the expected error unless in permissive parsing mode
|
||||
fn assert_avif_shall(path: &str, expected_msg: &str) {
|
||||
let input = &mut File::open(path).expect("Unknown file");
|
||||
assert_invalid_data(mp4::read_avif(input, ParseStrictness::Strict), expected_msg);
|
||||
input.seek(SeekFrom::Start(0)).expect("rewind failed");
|
||||
assert_invalid_data(mp4::read_avif(input, ParseStrictness::Normal), expected_msg);
|
||||
input.seek(SeekFrom::Start(0)).expect("rewind failed");
|
||||
mp4::read_avif(input, ParseStrictness::Permissive).expect("ParseStrictness::Permissive failed");
|
||||
}
|
||||
|
||||
// TODO: replace assert_avif_shall
|
||||
fn assert_avif_shall2(path: &str, expected: Status) {
|
||||
fn assert_avif_shall(path: &str, expected: Status) {
|
||||
for_strictness_result(path, |strictness, result| {
|
||||
if strictness == ParseStrictness::Permissive {
|
||||
assert!(result.is_ok());
|
||||
@ -992,7 +964,7 @@ fn assert_avif_shall2(path: &str, expected: Status) {
|
||||
|
||||
#[test]
|
||||
fn public_avif_av1c_missing_essential() {
|
||||
assert_avif_should2(IMAGE_AVIF_AV1C_MISSING_ESSENTIAL, Status::TxformNoEssential);
|
||||
assert_avif_should(IMAGE_AVIF_AV1C_MISSING_ESSENTIAL, Status::TxformNoEssential);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -1008,36 +980,30 @@ fn public_avif_clap_missing_essential() {
|
||||
|
||||
#[test]
|
||||
fn public_avif_imir_missing_essential() {
|
||||
assert_avif_should2(IMAGE_AVIF_IMIR_MISSING_ESSENTIAL, Status::TxformNoEssential);
|
||||
assert_avif_should(IMAGE_AVIF_IMIR_MISSING_ESSENTIAL, Status::TxformNoEssential);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn public_avif_irot_missing_essential() {
|
||||
assert_avif_should2(IMAGE_AVIF_IROT_MISSING_ESSENTIAL, Status::TxformNoEssential);
|
||||
assert_avif_should(IMAGE_AVIF_IROT_MISSING_ESSENTIAL, Status::TxformNoEssential);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn public_avif_ipma_bad_version() {
|
||||
let expected_msg = "The ipma version 0 should be used unless 32-bit \
|
||||
item_ID values are needed \
|
||||
per ISOBMFF (ISO 14496-12:2020 § 8.11.14.1";
|
||||
assert_avif_should(IMAGE_AVIF_IPMA_BAD_VERSION, expected_msg);
|
||||
assert_avif_should(IMAGE_AVIF_IPMA_BAD_VERSION, Status::IpmaBadVersion);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn public_avif_ipma_bad_flags() {
|
||||
let expected_msg = "Unless there are more than 127 properties in the \
|
||||
ItemPropertyContainerBox, flags should be equal to 0 \
|
||||
per ISOBMFF (ISO 14496-12:2020 § 8.11.14.1";
|
||||
assert_avif_should(IMAGE_AVIF_IPMA_BAD_FLAGS, expected_msg);
|
||||
assert_avif_should(IMAGE_AVIF_IPMA_BAD_FLAGS, Status::IpmaFlagsNonzero);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn public_avif_ipma_duplicate_version_and_flags() {
|
||||
let expected_msg = "There shall be at most one ItemPropertyAssociationbox \
|
||||
with a given pair of values of version and flags \
|
||||
per ISOBMFF (ISO 14496-12:2020 § 8.11.14.1";
|
||||
assert_avif_shall(IMAGE_AVIF_IPMA_DUPLICATE_VERSION_AND_FLAGS, expected_msg);
|
||||
assert_avif_shall(
|
||||
IMAGE_AVIF_IPMA_DUPLICATE_VERSION_AND_FLAGS,
|
||||
Status::IpmaBadQuantity,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -1046,101 +1012,90 @@ fn public_avif_ipma_duplicate_version_and_flags() {
|
||||
// which is kind of annoying to make pass the "should" requirements on flags and version
|
||||
// as well as the "shall" requirement on duplicate version and flags
|
||||
fn public_avif_ipma_duplicate_item_id() {
|
||||
let expected_msg = "There shall be at most one occurrence of a given item_ID, \
|
||||
in the set of ItemPropertyAssociationBox boxes \
|
||||
per ISOBMFF (ISO 14496-12:2020) § 8.11.14.1";
|
||||
let input = &mut File::open(IMAGE_AVIF_IPMA_DUPLICATE_ITEM_ID).expect("Unknown file");
|
||||
assert_invalid_data(
|
||||
mp4::read_avif(input, ParseStrictness::Permissive),
|
||||
expected_msg,
|
||||
assert_eq!(
|
||||
Status::from(mp4::read_avif(input, ParseStrictness::Permissive)),
|
||||
Status::IpmaDuplicateItemId
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn public_avif_ipma_invalid_property_index() {
|
||||
let expected_msg = "Invalid property index in ipma";
|
||||
assert_avif_shall(IMAGE_AVIF_IPMA_INVALID_PROPERTY_INDEX, expected_msg);
|
||||
assert_avif_shall(IMAGE_AVIF_IPMA_INVALID_PROPERTY_INDEX, Status::IpmaBadIndex);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn public_avif_hdlr_first_in_meta() {
|
||||
let expected_msg = "The HandlerBox shall be the first contained box within \
|
||||
the MetaBox \
|
||||
per MIAF (ISO 23000-22:2019) § 7.2.1.5";
|
||||
assert_avif_shall(IMAGE_AVIF_NO_HDLR, expected_msg);
|
||||
assert_avif_shall(IMAGE_AVIF_HDLR_NOT_FIRST, expected_msg);
|
||||
assert_avif_shall(IMAGE_AVIF_NO_HDLR, Status::HdlrNotFirst);
|
||||
assert_avif_shall(IMAGE_AVIF_HDLR_NOT_FIRST, Status::HdlrNotFirst);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn public_avif_hdlr_is_pict() {
|
||||
let expected_msg = "The HandlerBox handler_type must be 'pict' \
|
||||
per MIAF (ISO 23000-22:2019) § 7.2.1.5";
|
||||
assert_avif_shall(IMAGE_AVIF_HDLR_NOT_PICT, expected_msg);
|
||||
assert_avif_shall(IMAGE_AVIF_HDLR_NOT_PICT, Status::HdlrTypeNotPict);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn public_avif_hdlr_nonzero_reserved() {
|
||||
let expected_msg = "The HandlerBox 'reserved' fields shall be 0 \
|
||||
per ISOBMFF (ISO 14496-12:2020) § 8.4.3.2";
|
||||
// This is a "should" despite the spec indicating a (somewhat ambiguous)
|
||||
// requirement that this field is set to zero.
|
||||
// See comments in read_hdlr
|
||||
assert_avif_should(IMAGE_AVIF_HDLR_NONZERO_RESERVED, expected_msg);
|
||||
assert_avif_should(
|
||||
IMAGE_AVIF_HDLR_NONZERO_RESERVED,
|
||||
Status::HdlrReservedNonzero,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn public_avif_hdlr_multiple_nul() {
|
||||
let expected_msg = "The HandlerBox 'name' field shall have a NUL byte \
|
||||
only in the final position \
|
||||
per ISOBMFF (ISO 14496-12:2020) § 8.4.3.2";
|
||||
|
||||
// This is a "should" despite the spec indicating a (somewhat ambiguous)
|
||||
// requirement about extra data in boxes
|
||||
// See comments in read_hdlr
|
||||
assert_avif_should(IMAGE_AVIF_HDLR_MULTIPLE_NUL, expected_msg);
|
||||
assert_avif_should(IMAGE_AVIF_HDLR_MULTIPLE_NUL, Status::HdlrNameMultipleNul);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn public_avif_no_mif1() {
|
||||
let expected_msg = "The FileTypeBox should contain 'mif1' in the compatible_brands list \
|
||||
per MIAF (ISO 23000-22:2019) § 7.2.1.2";
|
||||
assert_avif_should(IMAGE_AVIF_NO_MIF1, expected_msg);
|
||||
assert_avif_should(IMAGE_AVIF_NO_MIF1, Status::MissingMif1Brand);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn public_avif_no_pitm() {
|
||||
assert_avif_shall2(IMAGE_AVIF_NO_PITM, Status::NoPrimaryItem);
|
||||
assert_avif_shall(IMAGE_AVIF_NO_PITM, Status::PitmMissing);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn public_avif_pixi_present_for_displayable_images() {
|
||||
let expected_msg = "The pixel information property shall be associated with every image \
|
||||
that is displayable (not hidden) \
|
||||
per MIAF (ISO/IEC 23000-22:2019) specification § 7.3.6.6";
|
||||
let pixi_test = if cfg!(feature = "missing-pixi-permitted") {
|
||||
assert_avif_should
|
||||
} else {
|
||||
assert_avif_shall
|
||||
};
|
||||
|
||||
pixi_test(IMAGE_AVIF_NO_PIXI, expected_msg);
|
||||
pixi_test(IMAGE_AVIF_NO_ALPHA_PIXI, expected_msg);
|
||||
pixi_test(IMAGE_AVIF_NO_PIXI, Status::PixiMissing);
|
||||
pixi_test(IMAGE_AVIF_NO_ALPHA_PIXI, Status::PixiMissing);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn public_avif_av1c_present_for_av01() {
|
||||
let expected_msg = "One AV1 Item Configuration Property (av1C) \
|
||||
is mandatory for an image item of type 'av01' \
|
||||
per AVIF specification § 2.2.1";
|
||||
assert_avif_shall(IMAGE_AVIF_NO_AV1C, expected_msg);
|
||||
assert_avif_shall(IMAGE_AVIF_NO_ALPHA_AV1C, expected_msg);
|
||||
assert_avif_shall(IMAGE_AVIF_NO_AV1C, Status::Av1cMissing);
|
||||
assert_avif_shall(IMAGE_AVIF_NO_ALPHA_AV1C, Status::Av1cMissing);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn public_avif_ispe_present() {
|
||||
let expected_msg = "Missing 'ispe' property for primary item, required \
|
||||
per HEIF (ISO/IEC 23008-12:2017) § 6.5.3.1";
|
||||
assert_avif_shall(IMAGE_AVIF_NO_ISPE, expected_msg);
|
||||
assert_avif_shall(IMAGE_AVIF_NO_ISPE, Status::IspeMissing);
|
||||
assert_avif_shall(IMAGE_AVIF_NO_ALPHA_ISPE, Status::IspeMissing);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn public_avif_transform_before_ispe() {
|
||||
assert_avif_shall(IMAGE_AVIF_TRANSFORM_BEFORE_ISPE, Status::TxformBeforeIspe);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn public_avif_transform_order() {
|
||||
assert_avif_shall(IMAGE_AVIF_TRANSFORM_ORDER, Status::TxformOrder);
|
||||
}
|
||||
|
||||
fn assert_unsupported_nonfatal(result: &mp4::Result<mp4::AvifContext>, feature: mp4::Feature) {
|
||||
@ -1192,7 +1147,7 @@ fn public_avif_a1lx() {
|
||||
|
||||
#[test]
|
||||
fn public_avif_a1lx_marked_essential() {
|
||||
assert_avif_shall2(IMAGE_AVIF_A1LX_MARKED_ESSENTIAL, Status::A1lxEssential);
|
||||
assert_avif_shall(IMAGE_AVIF_A1LX_MARKED_ESSENTIAL, Status::A1lxEssential);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -1202,7 +1157,7 @@ fn public_avif_a1op() {
|
||||
|
||||
#[test]
|
||||
fn public_avif_a1op_missing_essential() {
|
||||
assert_avif_shall2(IMAGE_AVIF_A1OP_MISSING_ESSENTIAL, Status::A1opNoEssential);
|
||||
assert_avif_shall(IMAGE_AVIF_A1OP_MISSING_ESSENTIAL, Status::A1opNoEssential);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -1212,7 +1167,7 @@ fn public_avif_lsel() {
|
||||
|
||||
#[test]
|
||||
fn public_avif_lsel_missing_essential() {
|
||||
assert_avif_shall2(IMAGE_AVIF_LSEL_MISSING_ESSENTIAL, Status::LselNoEssential);
|
||||
assert_avif_shall(IMAGE_AVIF_LSEL_MISSING_ESSENTIAL, Status::LselNoEssential);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -1237,8 +1192,8 @@ fn public_avis_major_no_pitm() {
|
||||
match mp4::read_avif(input, ParseStrictness::Normal) {
|
||||
Ok(context) => {
|
||||
assert_eq!(context.major_brand, mp4::AVIS_BRAND);
|
||||
assert!(context.unsupported_features.contains(mp4::Feature::Avis));
|
||||
assert!(context.primary_item_coded_data().is_none());
|
||||
assert!(context.sequence.is_some());
|
||||
}
|
||||
Err(e) => panic!("Expected Ok(_), found {:?}", e),
|
||||
}
|
||||
@ -1250,9 +1205,9 @@ fn public_avis_major_with_pitm_and_alpha() {
|
||||
match mp4::read_avif(input, ParseStrictness::Normal) {
|
||||
Ok(context) => {
|
||||
assert_eq!(context.major_brand, mp4::AVIS_BRAND);
|
||||
assert!(context.unsupported_features.contains(mp4::Feature::Avis));
|
||||
assert!(context.primary_item_coded_data().is_some());
|
||||
assert!(context.alpha_item_coded_data().is_some());
|
||||
assert!(context.sequence.is_some());
|
||||
}
|
||||
Err(e) => panic!("Expected Ok(_), found {:?}", e),
|
||||
}
|
||||
@ -1260,7 +1215,7 @@ fn public_avis_major_with_pitm_and_alpha() {
|
||||
|
||||
#[test]
|
||||
fn public_avif_avis_major_no_moov() {
|
||||
assert_avif_shall2(AVIF_AVIS_MAJOR_NO_MOOV, Status::NoMoov);
|
||||
assert_avif_shall(AVIF_AVIS_MAJOR_NO_MOOV, Status::MoovMissing);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -1 +1 @@
|
||||
{"files":{"Cargo.toml":"5074d01f075fd3c870f6e7f864e5a9b1ac7eb2af671110b58d9b1f3b830f72df","LICENSE":"fab3dd6bdab226f1c08630b1dd917e11fcb4ec5e1e020e2c16f83a0a13863e85","README.md":"f776ed4bbb7b58a5684402a9c5c28dfe1fa02b6b184139b2c2c49384cc1e3723","cbindgen.toml":"62066cd34285ab9e7f1cc5db8950a51e9e080f5a85bd55ad43d7022e4eae2758","examples/dump.rs":"a22630f5f1434d4832f9113dcb18161c0248465e8844d470da3c76bb9910677a","src/lib.rs":"21d0b024037be9ced0f4647925bde55ca5e3fd4272a89847a4431235244b2e34","tests/test_chunk_out_of_range.rs":"73ffb5b60e826f6136d22142c030d17d0f72b85c675ccbf1300c84f9deb73131","tests/test_encryption.rs":"196ba22efc3e693c940bcc1e45d29bec9cf290b81cf77a68c1d254f6b38e6ae3","tests/test_fragment.rs":"a4b275d7159c50b265db583a1cc8255bd0a141e3a44432355713b895a7970d37","tests/test_rotation.rs":"a5aa6cc88a327ec90d6898b2c4f5ac397667ce349d829deae1af46c230be9cb6","tests/test_sample_table.rs":"d191fe5836c58d4bdffd7390da029bb5371f8afb5b1a8d636e15ae0dd6b5f4c8","tests/test_workaround_stsc.rs":"85cd2546224b5c4891a60d86e2d302a56e0c0798c2636ad241603a00ebfa46b5"},"package":null}
|
||||
{"files":{"Cargo.toml":"31d4cece36ac4235873bc71953c450805290ddc7277e834d4d56fc7571dac4ed","LICENSE":"fab3dd6bdab226f1c08630b1dd917e11fcb4ec5e1e020e2c16f83a0a13863e85","README.md":"f776ed4bbb7b58a5684402a9c5c28dfe1fa02b6b184139b2c2c49384cc1e3723","cbindgen.toml":"62066cd34285ab9e7f1cc5db8950a51e9e080f5a85bd55ad43d7022e4eae2758","examples/dump.rs":"7bc2898bc52b2f7feb5e0ddbe13bd93270dfc71b871067c35011902e5a8f4477","src/lib.rs":"0f4e5cf85a2c784d47bf13e4e720aca6efc86520e49835a0deea42025c5be120","tests/test_chunk_out_of_range.rs":"4039d0db0ee5973787e4ca14cea510fd958ae5d21856a79240a5e7b826caa18d","tests/test_encryption.rs":"f62131a36b0516caf9e2c48f8aea060d300b0f5c8a32bc54d31cbc97aa25b4e6","tests/test_fragment.rs":"b87fe0a967c5a3184f9264955b08209e64769e6358ff670665fc719380f22157","tests/test_rotation.rs":"23fa4898eca2e17255bc1ba2f538707a6554fb4644bb75f80548ae56a7cd2d44","tests/test_sample_table.rs":"6e2f5eaadede1e37a5ced722bc071506fd0eecf3cd17310479d3c9692632a2cd","tests/test_workaround_stsc.rs":"1d17a394f55e1524c30888bfe1e57e2b0457444b79c23eb91b02d2edf859c9ad"},"package":null}
|
8
third_party/rust/mp4parse_capi/Cargo.toml
vendored
8
third_party/rust/mp4parse_capi/Cargo.toml
vendored
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "mp4parse_capi"
|
||||
version = "0.13.0"
|
||||
version = "0.16.0"
|
||||
authors = [
|
||||
"Ralph Giles <giles@mozilla.com>",
|
||||
"Matthew Gregan <kinetik@flim.org>",
|
||||
@ -12,7 +12,7 @@ authors = [
|
||||
description = "Parser for ISO base media file format (mp4)"
|
||||
documentation = "https://docs.rs/mp4parse_capi/"
|
||||
license = "MPL-2.0"
|
||||
|
||||
edition = "2018"
|
||||
repository = "https://github.com/mozilla/mp4parse-rust"
|
||||
|
||||
# Avoid complaints about trying to package test files.
|
||||
@ -27,11 +27,11 @@ travis-ci = { repository = "https://github.com/mozilla/mp4parse-rust" }
|
||||
byteorder = "1.2.1"
|
||||
fallible_collections = { version = "0.4", features = ["std_io"] }
|
||||
log = "0.4"
|
||||
mp4parse = { version = "0.13.0", path = "../mp4parse", features = ["unstable-api"] }
|
||||
mp4parse = { version = "0.16.0", path = "../mp4parse", features = ["unstable-api"] }
|
||||
num-traits = "0.2.14"
|
||||
|
||||
[dev-dependencies]
|
||||
env_logger = "0.8"
|
||||
env_logger = "0.9"
|
||||
|
||||
[features]
|
||||
missing-pixi-permitted = ["mp4parse/missing-pixi-permitted"]
|
||||
|
13
third_party/rust/mp4parse_capi/examples/dump.rs
vendored
13
third_party/rust/mp4parse_capi/examples/dump.rs
vendored
@ -1,11 +1,4 @@
|
||||
extern crate mp4parse;
|
||||
extern crate mp4parse_capi;
|
||||
|
||||
#[macro_use]
|
||||
extern crate log;
|
||||
|
||||
extern crate env_logger;
|
||||
|
||||
use log::info;
|
||||
use mp4parse::ParseStrictness;
|
||||
use mp4parse_capi::*;
|
||||
use std::env;
|
||||
@ -119,7 +112,9 @@ fn dump_file(filename: &str, strictness: ParseStrictness) {
|
||||
}
|
||||
}
|
||||
}
|
||||
Mp4parseTrackType::Video => {
|
||||
Mp4parseTrackType::Video
|
||||
| Mp4parseTrackType::Picture
|
||||
| Mp4parseTrackType::AuxiliaryVideo => {
|
||||
let mut video_info = Mp4parseTrackVideoInfo::default();
|
||||
match mp4parse_get_track_video_info(parser, i, &mut video_info) {
|
||||
Mp4parseStatus::Ok => {
|
||||
|
319
third_party/rust/mp4parse_capi/src/lib.rs
vendored
319
third_party/rust/mp4parse_capi/src/lib.rs
vendored
@ -5,7 +5,6 @@
|
||||
//! # Examples
|
||||
//!
|
||||
//! ```rust
|
||||
//! extern crate mp4parse_capi;
|
||||
//! use std::io::Read;
|
||||
//!
|
||||
//! extern fn buf_read(buf: *mut u8, size: usize, userdata: *mut std::os::raw::c_void) -> isize {
|
||||
@ -35,11 +34,6 @@
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
extern crate byteorder;
|
||||
extern crate log;
|
||||
extern crate mp4parse;
|
||||
extern crate num_traits;
|
||||
|
||||
use byteorder::WriteBytesExt;
|
||||
use std::convert::TryFrom;
|
||||
use std::convert::TryInto;
|
||||
@ -51,6 +45,7 @@ use mp4parse::serialize_opus_header;
|
||||
use mp4parse::unstable::{
|
||||
create_sample_table, media_time_to_us, track_time_to_us, CheckedInteger, Indice, Microseconds,
|
||||
};
|
||||
use mp4parse::AV1ConfigBox;
|
||||
use mp4parse::AudioCodecSpecific;
|
||||
use mp4parse::AvifContext;
|
||||
use mp4parse::CodecType;
|
||||
@ -59,6 +54,7 @@ use mp4parse::MediaContext;
|
||||
pub use mp4parse::ParseStrictness;
|
||||
use mp4parse::SampleEntry;
|
||||
pub use mp4parse::Status as Mp4parseStatus;
|
||||
use mp4parse::Track;
|
||||
use mp4parse::TrackType;
|
||||
use mp4parse::TryBox;
|
||||
use mp4parse::TryHashMap;
|
||||
@ -76,11 +72,13 @@ struct HashMap;
|
||||
struct String;
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(PartialEq, Debug)]
|
||||
#[derive(PartialEq, Eq, Debug)]
|
||||
pub enum Mp4parseTrackType {
|
||||
Video = 0,
|
||||
Audio = 1,
|
||||
Metadata = 2,
|
||||
Picture = 1,
|
||||
AuxiliaryVideo = 2,
|
||||
Audio = 3,
|
||||
Metadata = 4,
|
||||
}
|
||||
|
||||
impl Default for Mp4parseTrackType {
|
||||
@ -91,7 +89,7 @@ impl Default for Mp4parseTrackType {
|
||||
|
||||
#[allow(non_camel_case_types, clippy::upper_case_acronyms)]
|
||||
#[repr(C)]
|
||||
#[derive(PartialEq, Debug)]
|
||||
#[derive(PartialEq, Eq, Debug)]
|
||||
pub enum Mp4parseCodec {
|
||||
Unknown,
|
||||
Aac,
|
||||
@ -120,7 +118,7 @@ impl Default for Mp4parseCodec {
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(PartialEq, Debug)]
|
||||
#[derive(PartialEq, Eq, Debug)]
|
||||
pub enum Mp4ParseEncryptionSchemeType {
|
||||
None,
|
||||
Cenc,
|
||||
@ -202,7 +200,7 @@ pub struct Mp4parsePsshInfo {
|
||||
}
|
||||
|
||||
#[repr(u8)]
|
||||
#[derive(Debug, PartialEq)]
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub enum OptionalFourCc {
|
||||
None,
|
||||
Some([u8; 4]),
|
||||
@ -316,15 +314,10 @@ pub struct Mp4parseParser {
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Debug)]
|
||||
pub struct Mp4parseAvifImageItem {
|
||||
pub coded_data: Mp4parseByteData,
|
||||
pub bits_per_channel: Mp4parseByteData,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Debug)]
|
||||
pub struct Mp4parseAvifImage {
|
||||
pub primary_image: Mp4parseAvifImageItem,
|
||||
pub struct Mp4parseAvifInfo {
|
||||
pub premultiplied_alpha: bool,
|
||||
pub major_brand: [u8; 4],
|
||||
pub unsupported_features_bitfield: u32,
|
||||
/// The size of the image; should never be null unless using permissive parsing
|
||||
pub spatial_extents: *const mp4parse::ImageSpatialExtentsProperty,
|
||||
pub nclx_colour_information: *const mp4parse::NclxColourInformation,
|
||||
@ -332,12 +325,33 @@ pub struct Mp4parseAvifImage {
|
||||
pub image_rotation: mp4parse::ImageRotation,
|
||||
pub image_mirror: *const mp4parse::ImageMirror,
|
||||
pub pixel_aspect_ratio: *const mp4parse::PixelAspectRatio,
|
||||
/// If no alpha item exists, members' `.length` will be 0 and `.data` will be null
|
||||
pub alpha_image: Mp4parseAvifImageItem,
|
||||
pub premultiplied_alpha: bool,
|
||||
pub major_brand: [u8; 4],
|
||||
|
||||
/// Whether there is a `pitm` reference to the color image present.
|
||||
pub has_primary_item: bool,
|
||||
/// Bit depth for the item referenced by `pitm`, or 0 if values are inconsistent.
|
||||
pub primary_item_bit_depth: u8,
|
||||
/// Whether there is an `auxl` reference to the `pitm`-accompanying
|
||||
/// alpha image present.
|
||||
pub has_alpha_item: bool,
|
||||
/// Bit depth for the alpha item used by the `pitm`, or 0 if values are inconsistent.
|
||||
pub alpha_item_bit_depth: u8,
|
||||
|
||||
/// Whether there is a sequence. Can be true with no primary image.
|
||||
pub has_sequence: bool,
|
||||
pub unsupported_features_bitfield: u32,
|
||||
/// The color track's ID, which must be valid if has_sequence is true.
|
||||
pub color_track_id: u32,
|
||||
pub color_track_bit_depth: u8,
|
||||
/// The track ID of the alpha track, will be 0 if no alpha track is present.
|
||||
pub alpha_track_id: u32,
|
||||
pub alpha_track_bit_depth: u8,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Debug)]
|
||||
pub struct Mp4parseAvifImage {
|
||||
pub primary_image: Mp4parseByteData,
|
||||
/// If no alpha item exists, members' `.length` will be 0 and `.data` will be null
|
||||
pub alpha_image: Mp4parseByteData,
|
||||
}
|
||||
|
||||
/// A unified interface for the parsers which have different contexts, but
|
||||
@ -381,8 +395,10 @@ impl ContextParser for Mp4parseParser {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct Mp4parseAvifParser {
|
||||
context: AvifContext,
|
||||
sample_table: TryHashMap<u32, TryVec<Indice>>,
|
||||
}
|
||||
|
||||
impl Mp4parseAvifParser {
|
||||
@ -395,7 +411,10 @@ impl ContextParser for Mp4parseAvifParser {
|
||||
type Context = AvifContext;
|
||||
|
||||
fn with_context(context: Self::Context) -> Self {
|
||||
Self { context }
|
||||
Self {
|
||||
context,
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
fn read<T: Read>(io: &mut T, strictness: ParseStrictness) -> mp4parse::Result<Self::Context> {
|
||||
@ -601,6 +620,8 @@ pub unsafe extern "C" fn mp4parse_get_track_info(
|
||||
|
||||
info.track_type = match context.tracks[track_index].track_type {
|
||||
TrackType::Video => Mp4parseTrackType::Video,
|
||||
TrackType::Picture => Mp4parseTrackType::Picture,
|
||||
TrackType::AuxiliaryVideo => Mp4parseTrackType::AuxiliaryVideo,
|
||||
TrackType::Audio => Mp4parseTrackType::Audio,
|
||||
TrackType::Metadata => Mp4parseTrackType::Metadata,
|
||||
TrackType::Unknown => return Mp4parseStatus::Unsupported,
|
||||
@ -1024,6 +1045,158 @@ fn mp4parse_get_track_video_info_safe(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Return a struct containing meta information read by previous
|
||||
/// `mp4parse_avif_new()` call.
|
||||
///
|
||||
/// `color_track_id`and `alpha_track_id` will be 0 if has_sequence is false.
|
||||
/// `alpha_track_id` will be 0 if no alpha aux track is present.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// This function is unsafe because it dereferences both the parser and
|
||||
/// avif_info raw pointers passed into it. Callers should ensure the parser
|
||||
/// pointer points to a valid `Mp4parseAvifParser`, and that the avif_info
|
||||
/// pointer points to a valid `Mp4parseAvifInfo`.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn mp4parse_avif_get_info(
|
||||
parser: *const Mp4parseAvifParser,
|
||||
avif_info: *mut Mp4parseAvifInfo,
|
||||
) -> Mp4parseStatus {
|
||||
if parser.is_null() || avif_info.is_null() {
|
||||
return Mp4parseStatus::BadArg;
|
||||
}
|
||||
|
||||
if let Ok(info) = mp4parse_avif_get_info_safe((*parser).context()) {
|
||||
*avif_info = info;
|
||||
Mp4parseStatus::Ok
|
||||
} else {
|
||||
Mp4parseStatus::Invalid
|
||||
}
|
||||
}
|
||||
|
||||
fn mp4parse_avif_get_info_safe(context: &AvifContext) -> mp4parse::Result<Mp4parseAvifInfo> {
|
||||
let info = Mp4parseAvifInfo {
|
||||
premultiplied_alpha: context.premultiplied_alpha,
|
||||
major_brand: context.major_brand.value,
|
||||
unsupported_features_bitfield: context.unsupported_features.into_bitfield(),
|
||||
spatial_extents: context.spatial_extents_ptr()?,
|
||||
nclx_colour_information: context
|
||||
.nclx_colour_information_ptr()
|
||||
.unwrap_or(Ok(std::ptr::null()))?,
|
||||
icc_colour_information: Mp4parseByteData::with_data(
|
||||
context.icc_colour_information().unwrap_or(Ok(&[]))?,
|
||||
),
|
||||
image_rotation: context.image_rotation()?,
|
||||
image_mirror: context.image_mirror_ptr()?,
|
||||
pixel_aspect_ratio: context.pixel_aspect_ratio_ptr()?,
|
||||
|
||||
has_primary_item: context.primary_item_is_present(),
|
||||
primary_item_bit_depth: 0,
|
||||
has_alpha_item: context.alpha_item_is_present(),
|
||||
alpha_item_bit_depth: 0,
|
||||
|
||||
has_sequence: false,
|
||||
color_track_id: 0,
|
||||
color_track_bit_depth: 0,
|
||||
alpha_track_id: 0,
|
||||
alpha_track_bit_depth: 0,
|
||||
};
|
||||
|
||||
fn get_bit_depth(data: &[u8]) -> u8 {
|
||||
if !data.is_empty() && data.iter().all(|v| *v == data[0]) {
|
||||
data[0]
|
||||
} else {
|
||||
0
|
||||
}
|
||||
}
|
||||
let primary_item_bit_depth =
|
||||
get_bit_depth(context.primary_item_bits_per_channel().unwrap_or(Ok(&[]))?);
|
||||
let alpha_item_bit_depth =
|
||||
get_bit_depth(context.primary_item_bits_per_channel().unwrap_or(Ok(&[]))?);
|
||||
|
||||
if let Some(sequence) = &context.sequence {
|
||||
// Tracks must have track_id and samples
|
||||
fn get_track<T>(tracks: &TryVec<Track>, pred: T) -> Option<&Track>
|
||||
where
|
||||
T: Fn(&Track) -> bool,
|
||||
{
|
||||
tracks.iter().find(|track| {
|
||||
if track.track_id.is_none() {
|
||||
return false;
|
||||
}
|
||||
match &track.stsc {
|
||||
Some(stsc) => {
|
||||
if stsc.samples.is_empty() {
|
||||
return false;
|
||||
}
|
||||
if !pred(track) {
|
||||
return false;
|
||||
}
|
||||
stsc.samples.iter().any(|chunk| chunk.samples_per_chunk > 0)
|
||||
}
|
||||
_ => false,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// Color track will be the first track found
|
||||
let color_track = match get_track(&sequence.tracks, |_| true) {
|
||||
Some(v) => v,
|
||||
_ => return Ok(info),
|
||||
};
|
||||
|
||||
// Alpha track will be the first track found with auxl.aux_for_track_id set to color_track's id
|
||||
let alpha_track = get_track(&sequence.tracks, |track| match &track.tref {
|
||||
Some(tref) => tref.has_auxl_reference(color_track.track_id.unwrap()),
|
||||
_ => false,
|
||||
});
|
||||
|
||||
fn get_av1c(track: &Track) -> Option<&AV1ConfigBox> {
|
||||
if let Some(stsd) = &track.stsd {
|
||||
for entry in &stsd.descriptions {
|
||||
if let SampleEntry::Video(video_entry) = entry {
|
||||
if let VideoCodecSpecific::AV1Config(av1c) = &video_entry.codec_specific {
|
||||
return Some(av1c);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
let color_track_id = color_track.track_id.unwrap();
|
||||
let color_track_bit_depth = match get_av1c(color_track) {
|
||||
Some(av1c) => av1c.bit_depth,
|
||||
_ => return Ok(info),
|
||||
};
|
||||
|
||||
let (alpha_track_id, alpha_track_bit_depth) = match alpha_track {
|
||||
Some(track) => (
|
||||
track.track_id.unwrap(),
|
||||
match get_av1c(track) {
|
||||
Some(av1c) => av1c.bit_depth,
|
||||
_ => return Ok(info),
|
||||
},
|
||||
),
|
||||
_ => (0, 0),
|
||||
};
|
||||
|
||||
return Ok(Mp4parseAvifInfo {
|
||||
primary_item_bit_depth,
|
||||
alpha_item_bit_depth,
|
||||
has_sequence: true,
|
||||
color_track_id,
|
||||
color_track_bit_depth,
|
||||
alpha_track_id,
|
||||
alpha_track_bit_depth,
|
||||
..info
|
||||
});
|
||||
}
|
||||
|
||||
Ok(info)
|
||||
}
|
||||
|
||||
/// Return a pointer to the primary item parsed by previous `mp4parse_avif_new()` call.
|
||||
///
|
||||
/// # Safety
|
||||
@ -1057,39 +1230,11 @@ pub fn mp4parse_avif_get_image_safe(
|
||||
parser: &Mp4parseAvifParser,
|
||||
) -> mp4parse::Result<Mp4parseAvifImage> {
|
||||
let context = parser.context();
|
||||
|
||||
let primary_image = Mp4parseAvifImageItem {
|
||||
coded_data: Mp4parseByteData::with_data(context.primary_item_coded_data().unwrap_or(&[])),
|
||||
bits_per_channel: Mp4parseByteData::with_data(
|
||||
context.primary_item_bits_per_channel().unwrap_or(Ok(&[]))?,
|
||||
),
|
||||
};
|
||||
|
||||
// If there is no alpha present, all the `Mp4parseByteData`s will be zero length
|
||||
let alpha_image = Mp4parseAvifImageItem {
|
||||
coded_data: Mp4parseByteData::with_data(context.alpha_item_coded_data().unwrap_or(&[])),
|
||||
bits_per_channel: Mp4parseByteData::with_data(
|
||||
context.alpha_item_bits_per_channel().unwrap_or(Ok(&[]))?,
|
||||
),
|
||||
};
|
||||
|
||||
Ok(Mp4parseAvifImage {
|
||||
primary_image,
|
||||
spatial_extents: context.spatial_extents_ptr()?,
|
||||
nclx_colour_information: context
|
||||
.nclx_colour_information_ptr()
|
||||
.unwrap_or(Ok(std::ptr::null()))?,
|
||||
icc_colour_information: Mp4parseByteData::with_data(
|
||||
context.icc_colour_information().unwrap_or(Ok(&[]))?,
|
||||
primary_image: Mp4parseByteData::with_data(
|
||||
context.primary_item_coded_data().unwrap_or(&[]),
|
||||
),
|
||||
image_rotation: context.image_rotation()?,
|
||||
image_mirror: context.image_mirror_ptr()?,
|
||||
pixel_aspect_ratio: context.pixel_aspect_ratio_ptr()?,
|
||||
alpha_image,
|
||||
premultiplied_alpha: context.premultiplied_alpha,
|
||||
major_brand: context.major_brand.value,
|
||||
has_sequence: context.has_sequence,
|
||||
unsupported_features_bitfield: context.unsupported_features.into_bitfield(),
|
||||
alpha_image: Mp4parseByteData::with_data(context.alpha_item_coded_data().unwrap_or(&[])),
|
||||
})
|
||||
}
|
||||
|
||||
@ -1114,26 +1259,66 @@ pub unsafe extern "C" fn mp4parse_get_indice_table(
|
||||
// Initialize fields to default values to ensure all fields are always valid.
|
||||
*indices = Default::default();
|
||||
|
||||
get_indice_table(&mut *parser, track_id, &mut *indices).into()
|
||||
get_indice_table(
|
||||
&(*parser).context,
|
||||
&mut (*parser).sample_table,
|
||||
track_id,
|
||||
&mut *indices,
|
||||
)
|
||||
.into()
|
||||
}
|
||||
|
||||
/// Fill the supplied `Mp4parseByteData` with index information from `track`.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// This function is unsafe because it dereferences both the parser and
|
||||
/// indices raw pointers passed to it. Callers should ensure the parser
|
||||
/// points to a valid `Mp4parseAvifParser` and indices points to a valid
|
||||
/// `Mp4parseByteData`.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn mp4parse_avif_get_indice_table(
|
||||
parser: *mut Mp4parseAvifParser,
|
||||
track_id: u32,
|
||||
indices: *mut Mp4parseByteData,
|
||||
) -> Mp4parseStatus {
|
||||
if parser.is_null() {
|
||||
return Mp4parseStatus::BadArg;
|
||||
}
|
||||
|
||||
if indices.is_null() {
|
||||
return Mp4parseStatus::BadArg;
|
||||
}
|
||||
|
||||
// Initialize fields to default values to ensure all fields are always valid.
|
||||
*indices = Default::default();
|
||||
|
||||
if let Some(sequence) = &(*parser).context.sequence {
|
||||
return get_indice_table(
|
||||
sequence,
|
||||
&mut (*parser).sample_table,
|
||||
track_id,
|
||||
&mut *indices,
|
||||
)
|
||||
.into();
|
||||
}
|
||||
|
||||
Mp4parseStatus::BadArg
|
||||
}
|
||||
|
||||
fn get_indice_table(
|
||||
parser: &mut Mp4parseParser,
|
||||
context: &MediaContext,
|
||||
sample_table_cache: &mut TryHashMap<u32, TryVec<Indice>>,
|
||||
track_id: u32,
|
||||
indices: &mut Mp4parseByteData,
|
||||
) -> Result<(), Mp4parseStatus> {
|
||||
let Mp4parseParser {
|
||||
context,
|
||||
sample_table: index_table,
|
||||
..
|
||||
} = parser;
|
||||
let tracks = &context.tracks;
|
||||
let track = match tracks.iter().find(|track| track.track_id == Some(track_id)) {
|
||||
Some(t) => t,
|
||||
_ => return Err(Mp4parseStatus::Invalid),
|
||||
};
|
||||
|
||||
if let Some(v) = index_table.get(&track_id) {
|
||||
if let Some(v) = sample_table_cache.get(&track_id) {
|
||||
indices.set_indices(v);
|
||||
return Ok(());
|
||||
}
|
||||
@ -1165,7 +1350,7 @@ fn get_indice_table(
|
||||
|
||||
if let Some(v) = create_sample_table(track, offset_time) {
|
||||
indices.set_indices(&v);
|
||||
index_table.insert(track_id, v)?;
|
||||
sample_table_cache.insert(track_id, v)?;
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
extern crate mp4parse_capi;
|
||||
use mp4parse_capi::*;
|
||||
use std::io::Read;
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
extern crate mp4parse_capi;
|
||||
use mp4parse_capi::*;
|
||||
use std::io::Read;
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
extern crate mp4parse_capi;
|
||||
use mp4parse_capi::*;
|
||||
use std::io::Read;
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
extern crate mp4parse_capi;
|
||||
use mp4parse_capi::*;
|
||||
use std::io::Read;
|
||||
|
||||
|
@ -1,5 +1,3 @@
|
||||
extern crate mp4parse;
|
||||
extern crate mp4parse_capi;
|
||||
use mp4parse::unstable::Indice;
|
||||
use mp4parse_capi::*;
|
||||
use std::io::Read;
|
||||
|
@ -1,4 +1,3 @@
|
||||
extern crate mp4parse_capi;
|
||||
use mp4parse_capi::*;
|
||||
use std::io::Read;
|
||||
|
||||
|
@ -12,7 +12,7 @@ mozglue-static = { path = "../../../../mozglue/static/rust" }
|
||||
geckoservo = { path = "../../../../servo/ports/geckolib" }
|
||||
kvstore = { path = "../../../components/kvstore" }
|
||||
lmdb-rkv-sys = { version = "0.11", features = ["mdb_idl_logn_9"] }
|
||||
mp4parse_capi = { git = "https://github.com/mozilla/mp4parse-rust", rev = "3bfc47d9a571d0842676043ba60716318e946c06", features = ["missing-pixi-permitted"] }
|
||||
mp4parse_capi = { git = "https://github.com/mozilla/mp4parse-rust", rev = "eb0b625bd7e888d05ebcfc7685e2501b34c3b374", features = ["missing-pixi-permitted"] }
|
||||
nserror = { path = "../../../../xpcom/rust/nserror" }
|
||||
nsstring = { path = "../../../../xpcom/rust/nsstring" }
|
||||
netwerk_helper = { path = "../../../../netwerk/base/rust-helper" }
|
||||
|
Loading…
Reference in New Issue
Block a user