Command-line HEIC/HEIF converter using Ente's image raster pipeline (main-branch-only mirror of forge.ejuarezg.com/ejuarezg/heic2img)
README.md

heic2img #

A command-line HEIC/HEIF converter that uses Ente's current image raster pipeline:

  1. Ente's pinned pure-Rust HEIC decoder
  2. Embedded ICC-profile conversion to sRGB via moxcms
  3. HEIF EXIF-orientation handling
  4. fast_image_resize 5.5.0 with the Lanczos3 convolution filter
  5. JPEG, PNG, or WebP encoding, with optional JPEG XL encoding through libjxl's cjxl tool

The pre-encoding pixel pipeline is adapted from Ente and this project is licensed under AGPL-3.0-only. See NOTICE and LICENSE.

Build #

Enter the pinned Guix development environment, then build:

guix shell -m guix-manifest.scm -- cargo build --release

The manifest provides Rust/Cargo, the C toolchain, Git, certificates, and cjxl from libjxl. The compiled binary is target/release/heic2img.

Usage #

# WebP is the default output format.
./heic2img IMG_2951.HEIC --max-long-edge 1200

# JPEG or PNG output.
./heic2img IMG_2951.HEIC -w 1200 --format jpeg
./heic2img IMG_2951.HEIC -w 1200 --format png

# JPEG XL output (requires cjxl from libjxl on PATH).
./heic2img IMG_2951.HEIC -w 1200 --format jxl --jxl-distance 1.5

# Create the WebP fallback and JPEG XL preferred rendition from the same
# decoded, color-managed, resized RGB buffer.
./heic2img IMG_2951.HEIC -w 1200 --format paired \
  --jxl-distance 1.5 --jxl-effort 7

# Process every .heic or .heif file in a directory.
./heic2img photos/ -o converted/ -w 2048 --format webp -q 85

-w is an alias for --max-long-edge. It caps the long edge, preserves aspect ratio, uses Ente's integer rounding behavior, and never upscales an image.

Options #

<INPUT>                           Input HEIC/HEIF file or directory
-o, --output <DIRECTORY>        Destination directory; defaults to the input directory
-w, --max-long-edge <PIXELS>    Maximum output long edge [default: 1920]
-f, --format <FORMAT>           webp, jpeg, png, jxl, or paired [default: webp]
-q, --quality <1-100>           JPEG/WebP quality [default: 80]
    --cjxl <PATH>              JPEG XL encoder executable [default: cjxl]
    --jxl-distance <NUMBER>    Butteraugli distance [default: 1.5]
    --jxl-effort <1-10>        JPEG XL encoder effort [default: 7]

PNG is lossless; --quality does not affect PNG output. JPEG XL uses its own Butteraugli distance, not the JPEG/WebP quality scale. paired writes <stem>.webp and <stem>.jxl; both are published only after both encoders succeed, and an existing output is never overwritten. The JPEG XL output requires the external cjxl executable; the RGB pixels passed to it are written as a metadata-free temporary PNG.

Development disclosure #

This project has been developed with substantial assistance from large language models (LLMs), a form of probabilistic automation. Such tools can produce plausible but incorrect code or explanations; their output does not establish that behavior is correct. The human maintainer is responsible for reviewing changes and validating them with tests.

This wording follows GNOME's “Probabilistically Automated” label and its focus on describing how work was produced without treating a model as a human-like agent. For more on precise, non-anthropomorphic language, see “We Need to Talk About How We Talk About ‘AI’”.