Skip to content

HEIC decoder#101

Open
xfalcox wants to merge 2 commits intojamsinclair:mainfrom
xfalcox:claude/add-heic-decoder
Open

HEIC decoder#101
xfalcox wants to merge 2 commits intojamsinclair:mainfrom
xfalcox:claude/add-heic-decoder

Conversation

@xfalcox
Copy link
Copy Markdown

@xfalcox xfalcox commented Mar 30, 2026

Hey, we consume some of your packages on https://github.com/discourse/discourse and we are considering doing HEIC -> JPG conversion on the client going forward, which made me add support for this.

I tested this locally and it works well for all sample HEIC file I could find.

xfalcox and others added 2 commits March 30, 2026 14:02
New decode-only package using libheif + libde265 to decode HEIC/HEIF
images (H.265/HEVC) to ImageData, following the same WASM + Emscripten
pattern as the existing @jsquash/avif package.

Includes: TypeScript wrapper, C++ Emscripten binding, Makefile build
system, and environment polyfills. The WASM binary needs to be built
via Docker (npm run build:codec) before publishing.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Fix libde265 URL to use official strukturag repo
- Copy generated de265-version.h to source tree for FindLIBDE265
- Disable libheif test builds (BUILD_TESTING=OFF)
- Fix typed_memory_view explicit val conversion for Emscripten 3.1.57
- Add compiled heic_dec.js and heic_dec.wasm

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@xfalcox xfalcox changed the title Claude/add heic decoder HEIC decoder Mar 30, 2026
@jamsinclair
Copy link
Copy Markdown
Owner

OH MY! Love your work @xfalcox. This is awesome.

If it's ok, I'll take a look at these this weekend and get back to you with any comments 🙏

@xfalcox
Copy link
Copy Markdown
Author

xfalcox commented Apr 6, 2026

Hey @jamsinclair,

I have this PR waiting on this discourse/discourse#39014 which exemplifies well how to use the new capabilities.

Have you had any chance to look at this?

@xfalcox
Copy link
Copy Markdown
Author

xfalcox commented Apr 28, 2026

Hey @jamsinclair, sorry to ping again, wondering if you had the time to take a look.

xfalcox added a commit to discourse/jSquash that referenced this pull request May 7, 2026
xfalcox added a commit to discourse/discourse that referenced this pull request May 11, 2026
## Summary

- Extends client-side image optimization to convert **JXL → JPEG**,
**HEIC → JPEG**, and **animated GIF → animated WEBP** using jSquash WASM
packages before upload
- Transparent JXL/HEIC images are converted to **WEBP** instead of JPEG,
so transparency is preserved (WEBP compresses much better than PNG for
this case)
- Gated as an **upcoming change** via
`composer_media_optimization_image_convert_enabled` (experimental,
`feature,all_members`, opt-in per group through the upcoming changes
admin UI)
- Sends raw file bytes to Web Worker for formats browsers can't decode
natively (JXL, HEIC), with new `"convert"` and `"convertAnimated"`
worker message types
- Adds JXL to `authorized_extensions` and `supported_images`; adds
HEIC/HEIF to `supported_images` for consistency
- Skips GIF→WEBP when output is larger than input
- Falls back to filename when MIME type is missing (browsers may not
recognize JXL/HEIC)

### Note on jSquash packages

This depends on Discourse-scoped forks of the jSquash packages
(`@discourse/jxl`, `@discourse/heic`, `@discourse/webp`,
`@discourse/gif`, `@discourse/jpeg`, `@discourse/resize`). The following
upstream PRs would let us move back to the canonical `@jsquash/*`
packages, but the upstream maintainer is currently unresponsive:

- jamsinclair/jSquash#101 (`@jsquash/heic`)
- jamsinclair/jSquash#103 (`@jsquash/webp`
animated support)
- jamsinclair/jSquash#104 (`@jsquash/gif`)

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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.

2 participants