Skip to content

Add JPEG XL (jxl) image filter backed by libvips #36223

Description

@wezell

Description

Now that libvips (vips-ffm) is integrated into core, we should expose a JPEG XL encoder as a libvips-backed image filter, mirroring the existing AVIF filter.

JPEG XL (.jxl) is a modern image format that the legacy pure-JVM (AWT/TwelveMonkeys) engine cannot produce. It typically yields smaller files than JPEG at equal quality and supports mathematically lossless encoding. libvips encodes it via its libjxl delegate, inferred from the .jxl output extension.

URL contract: filter=jxl&jxl_q=75 (also aliased as filter=jpegxl), with optional jxl_lossless and jxl_effort (1-9) parameters - matching the parameter convention of the other libvips filters.

This is a libvips-only capability with no legacy equivalent - exactly like avif and smartcrop. It is registered only in VipsImageFilterApiImpl, so it is selectable only when the libvips engine is active (IMAGE_API_USE_LIBVIPS=true and native libvips is present, resolved via ImageEngine.resolve()). When libvips is disabled the legacy engine has no knowledge of the jxl/jpegxl keys, so the filter is simply unavailable (no error). Because there is no JVM fallback for JPEG XL, no VipsLegacyFilters entry is added.

Acceptance Criteria

  • New VipsJpegXlImageFilter encodes images to .jxl via the libvips libjxl delegate
  • Supports q (0-100 quality, default 75), lossless (present = lossless), and effort (1-9, default 7) parameters under the jxl_ prefix
  • Registered under both jxl and jpegxl keys in VipsImageFilterApiImpl (libvips-only block)
  • Filter is available only when libvips is enabled and available; legacy engine does not expose it
  • No legacy/AWT fallback is wired (JPEG XL has no pure-JVM equivalent)
  • Parity test validates JPEG XL output magic bytes and skips cleanly when the host libvips lacks the libjxl delegate

Priority

Medium

Additional Context

Mirrors VipsAvifImageFilter (dotCMS/src/main/java/com/dotmarketing/image/vips/). Requires the host libvips build to include the libjxl delegate; if absent the request fails like AVIF when libheif/AV1 is missing.

Metadata

Metadata

Assignees

No one assigned

    Type

    No fields configured for Task.

    Projects

    Status
    New

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions