dotCMS / dotCMS/core

feat(image): optional libvips (vips-ffm) image processing engine behind a feature flag

Open
#35,989 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Team : Platform
Dominant language
Java
Stars
970
Forks
486
Avg merge
3d 33m
Merged PRs (30d)
170

Description

Problem / Opportunity

dotCMS image processing (com.dotmarketing.image.filter) is a pure-JVM stack (TwelveMonkeys, PDFBox, Batik, webp-imageio, jhlabs). It works, but:

  • The ImageFilterAPI Javadoc itself warns that resizing large images "can cause garbage collections and OOM exceptions" because the whole image is decompressed into heap.
  • No modern output formats (AVIF/JXL), no content-aware crop, per-filter temp-file round-trips in multi-filter chains.

libvips is a streaming, demand-driven image library that is dramatically faster and lower-memory, and — via the vips-ffm Panama FFM bindings — is a natural fit now that dotCMS runs on Java 25.

Proposal

Add a feature-flagged, drop-in alternative image engine backed by libvips, alongside the existing pure-JVM engine (which stays the default and is untouched).

  • Flag IMAGE_API_USE_LIBVIPS (default false) selects the engine; IMAGE_API_LIBVIPS_FALLBACK (default true) degrades to the legacy engine if a native op fails (corrupt input, missing delegate).
  • Every libvips filter subclasses the legacy ImageFilter, reusing its caching, unique-naming and overwrite() logic, so the URL parameter contract is identical (crop_w, resize_w, filter=resize,jpeg, …). Only the pixels change.

Scope

  • 16 libvips filters at parity (crop, resize, scale, thumbnail, rotate, flip, gamma, grayscale, hsb, exposure, subsample, jpeg, png, webp, gif, pdf)
  • VipsImageFilterApiImpl implements ImageFilterAPI; engine selected via ImageEngine.resolve() in the exporter, metadata generator and binary view tool
  • Graceful fallback to the legacy engine on libvips failure
  • New capabilities: content-aware smartcrop, AVIF output
  • libvips42 added to the Ubuntu 24.04 runtime Dockerfile (bundles pdf/heif/svg/webp/jxl delegates — no custom build needed)
  • CI installs libvips on the JVM unit-test runner so parity tests run
  • Tests: VipsParityTest + ImageFilterExporterEngineSelectionTest (30 green; legacy suite unchanged)

Parity definition

Not pixel-identical (different engines). Parity = deterministic geometry exact (shared ResizeCalc), encoding correct (container/alpha/animation preserved), and visual delta under threshold vs the legacy output. exposure and hsb are documented approximations.

Out of scope / follow-ups

  • Pixel-exact exposure/hsb curves
  • Single-pass VipsPipeline to collapse multi-filter chains
  • BlurHash / dominant-colour derived metadata
  • Animated WebP/AVIF transcode, ICC handling

See dotCMS/src/main/java/com/dotmarketing/image/vips/README.md and NEW-FEATURES.md for details.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with dotCMS/src/main/java/com/dotmarketing/image/vips/README.md and NEW-FEATURES.md, then inspect ImageEngine.resolve() and the listed VipsParityTest and ImageFilterExporterEngineSelectionTest. Confirm which scoped items remain beyond the checked filters, fallback, runtime, CI, and format work; done means the remaining feature behavior is covered without changing the legacy default.

Written by the indexing model from the issue text.

Assessment

Tech stack
docker, java
Domain
backend, build-system, performance
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.