Canonicalize integer/hex/octal IPv4 hosts to dotted-decimal before
applying the security.http.urls policy so all encodings of an address
are treated alike.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
IsNode's meaning was murky. Add IsBranch, defined as the set of branch
node kinds (home, section, taxonomy, term), and make IsNode a deprecated
alias for it.
Fixes#11574
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The hint setting controls WebP encoding (preset) and AVIF encoding
(chroma subsampling), but only lived on imaging.webp. Add imaging.avif.hint
so it shows up under the AVIF section in the docs, with the same root-level
backwards compatibility as imaging.webp.hint. Per-image hint now resolves
from the target format.
Fixes#14992
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Encode photo/picture hints (and the default) as YUV420 instead of YUV444,
keeping 444 for text/icon/drawing. Lossless stays 444.
This roughly halves the encoder's peak memory (42 -> 27 MiB/MP) and the
output size, while 444 remains available for sharp-edged content. A
3000x3000 image now needs ~239 MiB to encode, down from ~381 MiB (which
sat right at the 384 MiB WASM cap).
Closes#14987
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Before this commit, lossy compression with 100 quality meant lossless compression, leading to a big gap between 99 and 100.
This commit caps the lossy quality at 99, ensuring that lossy compression is always lossy.
Fixes#14981
AVIF's quality scale is not perceptually comparable to JPEG/WebP:
libavif anchors its "good" default at 60, where Hugo's universal 75
produced visibly higher quality and larger files. AVIF now defaults to
60 while JPEG and WebP keep 75. An explicit imaging.quality,
imaging.avif.quality or a per-image qNN still wins.
Fixes#14979
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Allow setting quality per output format via imaging.jpeg.quality,
imaging.webp.quality and imaging.avif.quality. Each falls back to the
global imaging.quality when unset, and a per-image qNN still wins.
Fixes#14957
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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
With renderSegments only a subset of pages is rendered, so the resulting
hugo_stats.json would no longer contain elements from the excluded pages,
causing tools like Tailwind to strip classes that are actually in use.
Fixes#14939