BoxLang 🚀 A New JVM Dynamic Language Learn More...

avif

v1.0.0 Modules

avif

AVIF Logo

AVIF is a ColdBox module that provides a simple API for converting images into AVIF format, decoding AVIF images back into PNG/JPEG, and inspecting AVIF files. It uses the precompiled libavif command-line binaries (avifenc / avifdec).

It is a hot-swap sister module to webp : the API mirrors the webp module's methods and shared argument names, so a consuming app (like a CMS) can switch webp@webp for avif@avif with no call-site changes — only the output file extension changes.

Why AVIF?

AVIF is a modern, royalty-free image format based on the AV1 video codec. It typically achieves smaller files than both JPEG and WebP at comparable quality, supports alpha transparency, wide color gamut, and high bit depth. It is supported by all major modern browsers.

AVIF support in ColdFusion

Neither Adobe ColdFusion nor Lucee ship native AVIF encoding. This module fills that gap by driving the official libavif binaries, so both engines can produce and consume AVIF without built-in image support.

Requirements

  • Lucee 5+, Adobe ColdFusion 2023+, Boxlang 1.0+
  • ColdBox 8+
  • Windows x64 (for now — see Known Limitations)
  • Permission for the CFML runtime to launch child processes

Installation

box install avif

The module detects your platform and points at the bundled binaries. To override (e.g. to use your own libavif build), set module settings in your Coldbox.cfc:

moduleSettings = {
    avif = {
        avifencPath  : "C:\tools\libavif\avifenc.exe", // explicit encoder path
        avifdecPath  : "C:\tools\libavif\avifdec.exe", // explicit decoder path
        timeout      : 90,     // default seconds before a conversion is killed
        maxDimension : 16384   // decode guard (avifdec --dimension-limit); 0 = off
    }
};

Alternatively, override just the folder that contains the binaries via binPath.

Usage

Inject the model with WireBox:

property name="avif" inject="avif@avif";

Encode an image into AVIF:

avif.encode(
    source      = "path/to/image.jpg",
    destination = "path/to/image.avif"
);

Decode an AVIF image into another format (PNG or JPEG — unlike WebP, JPEG is supported directly):

avif.decode(
    source      = "path/to/image.avif",
    destination = "path/to/image.png"
);

Get information about an AVIF image:

var meta = avif.info( source = "path/to/image.avif" );
// meta.width, meta.height, meta.depth, meta.alpha, meta.chroma, ...

Supported decode output formats: PNG, JPEG, Y4M (inferred from the destination extension).

Hot-swapping with the webp module

Because the shared argument names match, the same call site works against either module:

// Works identically whether `img` is webp@webp or avif@avif:
img.encode( source = upload, destination = target, quality = 80, resizeWidth = 800 );

avifenc/avifdec cannot crop or resize raster pixels themselves, so this module performs cropX/Y/Width/Height and resizeWidth/resizeHeight (and flipImage on decode) using ColdFusion's native cfimage functions — giving you the same behavior a CMS expects from the webp module.

Encode arguments

Argument Type Default Description
source stringFull path to the source file (JPEG/PNG/Y4M)
destination stringFull path to the .avif output
quality int (0-100)80Color quality; 100 ≈ lossless (avifenc -q)
lossless booleanfalseEncode losslessly (avifenc -l)
alphaQuality int (0-100)Alpha channel quality (avifenc --qalpha)
cropX/Y/Width/Height intPixel crop (all four together; via cfimage)
resizeWidth int0Resize width; 0 preserves aspect ratio (via cfimage)
resizeHeight int0Resize height; 0 preserves aspect ratio (via cfimage)
multiThreaded booleantrueUse all worker threads (avifenc -j all)
metadata string"none" strips EXIF/XMP/ICC; otherwise preserved
overwrite booleantrueReplace an existing destination
verbose booleanfalseAccepted for parity; output is always captured
timeout int0Seconds before the process is killed (0 = module setting)
speed int (0-10)6Encoder speed/effort; 0 slowest/best (avifenc -s)
depth int (8/10/12)Output bit depth (avifenc -d)
chroma stringauto/444/422/420/400 (avifenc -y)

Hot-swap note: WebP-specific options (nearLossless, preset, compressionMethod, filterStrength, jpegLike, sourceHint, …) have no AVIF equivalent. You can leave them in a hot-swapped call — CFML simply ignores arguments this module doesn't declare, so nothing breaks; they just have no effect.

Decode arguments

Argument Type Default Description
source stringFull path to the .avif source
destination stringOutput path (.png, .jpg, .jpeg, .y4m)
quality int (0-100)90JPEG output quality (JPEG destinations only, avifdec -q)
depth int (8/16)PNG output depth (PNG destinations only, avifdec -d)
upsampling stringautomaticChroma upsampling (avifdec -u)
cropX/Y/Width/Height intPixel crop (via cfimage)
resizeWidth/resizeHeight int0Resize; 0 preserves aspect ratio (via cfimage)
flipImage booleanfalseFlip vertically (via cfimage)
multiThreaded booleantrueUse all worker threads (avifdec -j all)
overwrite booleantrueReplace an existing destination
verbose booleanfalseAccepted for parity; output is always captured
timeout int0Seconds before the process is killed (0 = module setting)

info() / version() / capabilities()

  • info( source ) → struct guaranteed to include numeric width and height, plus depth, alpha, chroma, and the raw parsed keys (Resolution, BitDepth, Format, Range, …). Pass verbose=true to include rawOutput.
  • version() → struct with backend, binary paths, avifencVersion, avifdecVersion, platform, bundled.
  • capabilities() → struct describing supported formats and features.

Error handling

Failures throw typed exceptions you can catch by type:

try {
    avif.encode( source = src, destination = dest );
} catch ( "avif.binaryExecutionFailed" e ) {
    // e.detail contains the tool output
} catch ( "avif.timeout" e ) {
    // conversion exceeded the timeout
}

Types: avif.unsupportedPlatform, avif.binaryNotFound, avif.binaryExecutionFailed, avif.timeout, avif.invalidSource, avif.invalidDestination, avif.unsupportedFormat. Output is written atomically (to a temp file, then moved on success), so a failed conversion never leaves a partial destination file behind.

Security notes

Binaries are executed directly with Java ProcessBuilder — no shell is invoked — and every argument is passed as a discrete value, so filenames containing spaces, &, (, ) etc. are handled safely and cannot be interpreted as flags or shell metacharacters. For untrusted uploads, keep the maxDimension decode guard enabled.

Known limitations

  • Windows x64 only for now. On other platforms the module throws avif.unsupportedPlatform at load. macOS/Linux support is a matter of bundling the corresponding libavif binaries and extending the resolver.
  • Animated AVIF is not supported.
  • Crop/resize/flip are performed with cfimage (native ColdFusion image functions), not by the AVIF tools.

Roadmap

  • macOS (Apple Silicon, then Intel) and Linux (x64, then ARM64) support.
  • 10-bit / HDR encode tests.
  • Optional target-size encoding.

Third-party binaries

This module bundles the libavif command-line tools. See THIRD-PARTY-NOTICES.md for libavif / aom / dav1d license and attribution details.

License

Apache-2.0. See LICENSE.

About the author

Developed by Angry Sam Productions, a freelance web design and development company. We contribute to open source to strengthen the development community. Get in touch to learn more or to hire us for your next project.

Changelog

All notable changes to this project will be documented in this file.

The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.

Unreleased

0.1.0 - 2026-07-07

Added

  • Initial beta release. Windows x64 only.
  • encode() — JPEG/PNG/Y4M → AVIF via bundled avifenc (libavif 1.4.2).
  • decode() — AVIF → PNG/JPEG/Y4M via bundled avifdec (JPEG output supported directly, an improvement over the webp sister module).
  • info() — normalized metadata struct guaranteeing width/height.
  • version() and capabilities() helper methods.
  • Hot-swap compatible interface with the webp module: shared argument names for the options both formats support.
  • Crop/resize (encode) and crop/resize/flip (decode) implemented with native cfimage, since libavif tools do not perform raster transforms.
  • AVIF-native options: speed, depth, chroma, alphaQuality, upsampling.
  • Binaries executed via Java ProcessBuilder (no shell) for safe handling of paths with spaces/special characters.
  • Typed errors, atomic temp-file output with cleanup, configurable timeout, and a decode dimension guard.
  • TestBox integration suite exercising the real binaries.

$ box install avif

No collaborators yet.
     
  • {{ getFullDate("2026-07-08T22:45:58Z") }}
  • {{ getFullDate("2026-07-08T22:49:10Z") }}
  • 32
  • 4