Skip to content

feat(sharp): AVIF encode (.avif) + quality-aware JPEG/AVIF encoding#5456

Merged
proggeramlug merged 1 commit into
mainfrom
feat/sharp-avif
Jun 19, 2026
Merged

feat(sharp): AVIF encode (.avif) + quality-aware JPEG/AVIF encoding#5456
proggeramlug merged 1 commit into
mainfrom
feat/sharp-avif

Conversation

@proggeramlug

@proggeramlug proggeramlug commented Jun 19, 2026

Copy link
Copy Markdown
Contributor

PR 2 of 2 in the sharp batch. Stacked on #5455 (base is that branch, so this diff shows only the AVIF changes; it'll retarget to main once #5455 merges).

Pure-Rust, keeps the static-binary model.

.avif(quality) — AVIF output

Via the image crate's avif feature (the pure-Rust ravif/rav1e encoder). sharp(input).resize(…).avif(50).toBuffer() yields a real AVIF Buffer (ftyp/avif box); .toFile('out.avif') writes a valid AVIF and reports format: "avif".

Encode-only — AVIF decode is intentionally out (it needs the C dav1d library, which would break the no-system-deps model). sharp('x.avif') input isn't supported.

Quality now honoured for JPEG + AVIF

Encoding routes through a new encode_to_vec helper using JpegEncoder::new_with_quality / AvifEncoder::new_with_speed_quality. This also fixes a pre-existing gap: .jpeg(q) stored a quality the default write_to path ignored — now .jpeg(20) really is smaller than .jpeg(95). toFile encodes by the output path's extension (so .toFile('x.avif') works) and honours quality.

Validation

  • .avif().toBuffer() → AVIF ftyp/avif box; .toFile('x.avif')file(1) reports ISO Media, AVIF Image.
  • JPEG quality affects output size (lo < hi).
  • perry-ext-sharp unit suite 9/9; API docs regenerated (+avif).

Size note

Enabling AVIF pulls rav1e (a large pure-Rust AV1 encoder) into sharp binaries — a deliberate trade for AVIF output. SVG rasterization (resvg) was deferred to a separate opt-in PR (per discussion) to avoid bloating every sharp binary with its dependency tree.

Animated WebP

Still out — the image crate has no animated-WebP encoder; a separate codec path would be needed.

Summary by CodeRabbit

New Features

  • Added AVIF image encoding format support to the sharp module
  • Introduced quality-aware encoding for JPEG and AVIF formats with configurable quality settings
  • Enhanced image output pipeline with optimized compression options

Documentation

  • Updated API reference documentation with the new sharp.avif() method and available options

@coderabbitai

coderabbitai Bot commented Jun 19, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 6067425b-1466-4c59-95dd-6bbb7712da82

📥 Commits

Reviewing files that changed from the base of the PR and between 4a73b0e and 2331e24.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (10)
  • CHANGELOG.md
  • CLAUDE.md
  • Cargo.toml
  • crates/perry-api-manifest/src/entries.rs
  • crates/perry-codegen/src/lower_call/early_branches.rs
  • crates/perry-codegen/src/lower_call/native_table/media.rs
  • crates/perry-codegen/src/runtime_decls/stdlib_ffi.rs
  • crates/perry-ext-sharp/Cargo.toml
  • crates/perry-ext-sharp/src/lib.rs
  • docs/src/api/reference.md

📝 Walkthrough

Walkthrough

Adds AVIF output format to the sharp pipeline by enabling the avif feature on the image crate, introducing a js_sharp_avif export and a quality-aware encode_to_vec helper, updating toFile/toBuffer to use it, and wiring the new method through FFI declarations, native dispatch tables, fluent chain allowlist, and the API manifest.

Changes

Sharp AVIF Encoding

Layer / File(s) Summary
AVIF encoder implementation and dependency
crates/perry-ext-sharp/Cargo.toml, crates/perry-ext-sharp/src/lib.rs
Enables the avif feature on the image crate. Adds ImageFormat::Avif"avif" mapping to fmt_name, introduces the exported js_sharp_avif(handle, quality) transform, adds an internal encode_to_vec helper dispatching JPEG quality, AVIF quality+speed, and default encoding, and updates toFile/toBuffer to encode through encode_to_vec.
FFI declaration, native table, fluent allowlist, and manifest
crates/perry-codegen/src/runtime_decls/stdlib_ffi.rs, crates/perry-codegen/src/lower_call/native_table/media.rs, crates/perry-codegen/src/lower_call/early_branches.rs, crates/perry-api-manifest/src/entries.rs
Declares js_sharp_avif (I64, [I64, DOUBLE]) in the stdlib FFI module, registers a NativeModSig for sharp().avif(...) in MEDIA_ROWS, adds "avif" to the native_method_returns_self_instance fluent allowlist, and adds the avif instance-method entry to the API manifest.
Version bump and documentation
Cargo.toml, CLAUDE.md, CHANGELOG.md, docs/src/api/reference.md
Bumps workspace version to 0.5.1195, adds the changelog entry for AVIF/quality-aware encoding, and updates the API reference to include the avif method entry (total: 2815).

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • PerryTS/perry#5444: Modifies the same toBuffer encoding path in crates/perry-ext-sharp/src/lib.rs, switching from base64 to a real Node Buffer—the base that this PR's encode_to_vec-based toBuffer rewrite builds on.
  • PerryTS/perry#5445: Extends the same crates/perry-codegen/src/lower_call/early_branches.rs fluent native-module allowlist that this PR further extends with "avif".
  • PerryTS/perry#5448: Touches the same toFile info-payload fields (channels, size) in crates/perry-ext-sharp/src/lib.rs that this PR also modifies when switching to encode_to_vec.

Poem

🐇 A bunny hops through pixel fields so bright,
Now AVIF joins the image format night,
With encode_to_vec and quality in tow,
The sharp pipeline gains a brand-new glow—
No dav1d needed, just rav1e's might! 🎨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description violates the repository's explicit guidelines by modifying CHANGELOG.md, Cargo.toml version, and CLAUDE.md despite template instructions prohibiting this. Remove version bumps from Cargo.toml and CLAUDE.md, and CHANGELOG.md edits. The maintainer will handle these at merge time as stated in the template instructions.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the two main changes: AVIF encoding support and quality-aware JPEG/AVIF encoding implementation.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/sharp-avif

Comment @coderabbitai help to get the list of available commands and usage tips.

Base automatically changed from feat/sharp-orient-composite-extend-trim to main June 19, 2026 13:42
- .avif(quality): AVIF output via image's `avif` feature (pure-Rust ravif/rav1e).
  Encode-only — AVIF decode needs C dav1d, kept out for the static-binary model.
- encode_to_vec helper honours quality for JPEG (JpegEncoder::new_with_quality)
  and AVIF (AvifEncoder::new_with_speed_quality); fixes the pre-existing gap where
  .jpeg(q) quality was ignored by the default write_to path. toFile encodes by the
  output path extension (so .toFile('x.avif') works) and honours quality.

Wired end-to-end (media.rs row, stdlib_ffi decl, entries.rs manifest, fluent
allowlist) + docs regen. Validated: .avif().toBuffer() -> AVIF ftyp/avif box;
.toFile('x.avif') -> valid AVIF (ISO Media); jpeg quality affects size; 9/9 tests.

Stacked on the EXIF/extend/trim/composite branch (#5455).
@proggeramlug proggeramlug merged commit b3ff10c into main Jun 19, 2026
15 checks passed
@proggeramlug proggeramlug deleted the feat/sharp-avif branch June 19, 2026 13:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant