RSTRust-First Site ToolkitA Rust-first static site generator with typed collections, explicit routes, and a format-agnostic asset pipeline.

Blog

HDR Capabilities in the Asset Pipeline

The asset pipeline preserves HDR semantics across supported AVIF, PNG, and JPEG paths while keeping the site-facing API format-agnostic.

HDR is an internal capability, not a site-level switch

The site-facing API does not ask route code to decide whether an image is SDR or HDR.

That is deliberate.

Route code should say what output it wants:

  • a responsive AVIF image

  • an OpenGraph JPEG

  • a preserved original asset

The pipeline then preserves HDR semantics when the source and destination make that possible.

The public API surface

The important part of this feature is actually what the public API does not expose.

Site code still uses the ordinary image API:

  • RenderContext::image_url(...)

  • RenderContext::responsive_image(...)

  • ImageOutput

  • ResponsiveImageOutput

There is no site-level "HDR mode" switch. HDR behavior is inferred from the authored source and the requested destination format.

What is exercised in this repository

The docs site includes a checked-in HDR AVIF source named hello-hdr.avif.

That sample is useful for two reasons:

  • it exercises both frontmatter-authored media and markdown-authored media

  • it proves that ordinary site code can stay format-agnostic while the engine keeps the HDR details internally

HDR sample gradientChecked-in HDR AVIF sample

What currently works

The current tested HDR slice covers several source and destination combinations.

HDR AVIF stays HDR when re-encoded to AVIF

When the source AVIF already carries HDR signaling, AVIF output preserves that HDR state across resize and crop operations.

The current tests cover:

  • 10-bit HDR AVIF input

  • 12-bit HDR AVIF input

  • preserved HDR signaling

  • preserved gain maps

HDR PNG can be promoted to HDR AVIF

HDR-capable PNG input can be turned into HDR AVIF output when the source provides enough color information to preserve the semantics correctly.

The current tests cover:

  • 8-bit HDR PNG input promoted to HDR AVIF with a gain map

  • HLG signaling preserved through that promotion path

  • 16-bit HDR PNG input preserved as HDR AVIF

HDR AVIF and HDR PNG can emit HDR JPEG outputs

For JPEG output, the current implementation uses gain-map-capable HDR JPEG output rather than quietly flattening everything to SDR.

The current tests cover:

  • HDR AVIF to HDR JPEG with a gain map

  • HDR PNG to HDR JPEG with a gain map

  • preserved HDR JPEG passthrough when the source is already HDR JPEG

HDR JPEG can round-trip back into AVIF

The pipeline also understands HDR JPEG input strongly enough to preserve HDR semantics when AVIF is the requested destination.

That means an authored HDR JPEG does not have to be treated as a dead end.

What the pipeline refuses to guess

The HDR slice is intentionally strict about color semantics.

If the source metadata does not map cleanly into a supported destination model, the pipeline fails instead of manufacturing a plausible-looking but wrong image.

The current tests cover rejection cases such as:

  • HDR PNG with unmapped HDR signaling when AVIF is requested

  • HDR PNG with insufficient HDR metadata when JPEG is requested

  • HDR AVIF with unsupported signaling when HDR JPEG is requested

  • SDR PNG with unmapped CICP values when JPEG is requested

That is an important part of the feature, not a limitation hidden in small print.

Why the public API stays small

The point of this design is not to hide HDR support. It is to keep HDR decisions out of the site code when they belong in the media engine.

Most route code should not be littered with branches such as:

  • if source is HDR, do X

  • if source is SDR, do Y

  • if source is SVG, do Z

Instead, route code asks for a destination and the pipeline does the format-specific work.

Where to go next