The encode/decode is implemented in a WebAssembly module built from a
small C wrapper around libavif. Bundled libraries (statically linked,
compiled with the WASI SDK):
* libavif v1.4.1 (container + codec glue)
* libaom v3.14.1 (AV1 encoder + decoder)
* dav1d 1.5.3 (AV1 decoder)
* libyuv (Chromium pin) for color conversion
* parson for JSON message passing across the wasm boundary
HDR handling on the encoder:
* SDR images are written as BT.709 / sRGB / BT.601 (8-bit).
* 10-bit and up are written as BT.2020 primaries with PQ (SMPTE
ST 2084) transfer and BT.2020-NCL matrix coefficients, signalled
via CICP.
* Adobe-style SDR+gainmap inputs (e.g. Lightroom HDR exports) are
baked into a single true-HDR image in BT.2020/PQ at 10-bit, with
the CLLI (Content Light Level Information) box carried through so
HDR-capable clients can tone-map correctly.
Limitations:
* Animated input (animated WebP/GIF) is collapsed to its first frame
when re-encoded as AVIF; animated AVIF output is not yet supported.
Fixes#7837
* Add AVIF, HEIF and HEIC partial support
* Add them as media types.
* Support reading metadata (Width, Height, Exif, etc.) from these formats.
* Add a new template function IsImageResourceMeta to check if a resource supports image metadata operations, which will return true for AVIF, HEIF and HEIC resources even if they don't support full image operations yet.
Fixes#14549
* Always include the content hash in the cache key for unprocessed images.
* Always include the image config hash in the cache key.
This is also a major cleanup/simplification of the implementation in this area.
Note that this, unfortunately, forces new hashes/filenames for generated images.
Fixes#13273Fixes#13272
Keep this as a separate commit as this isn't because the files have changed. The filenames have changed due to cache busting of PNG and Webp images.
See #8729
The root cause of issue #8079 was a non-breaking space (U+0160).
`unicode.IsPrint` only allows the ASCII space (U+0020). Be more lenient
by using `unicode.IsGraphic` instead.
Fixes#8079
This allows for constructs ala:
```
{{ $overlay := $img.Filter (images.Overlay $logo 50 50 )}}
```
Or:
```
{{ $logoFilter := (images.Overlay $logo 50 50 ) }}
{{ $overlay := $img | images.Filter $logoFilter }}
```
Which will overlay the logo in the top left corner (x=50, y=50) of `$img`.
Fixes#8057Fixes#4595
Updates #6731