@wasmedia/wenblend
v0.2.0
Published
Enblend and Enfuse compiled to WebAssembly for browsers
Maintainers
Readme
wenblend
Enblend and Enfuse cross-compiled to WebAssembly, so
panorama blending and exposure fusion run in a browser. enblend joins overlapping images into one
image with a multi-resolution spline; enfuse merges a bracketed exposure stack into a single fused
image. Both are C++ command-line tools from the Hugin ecosystem.
Part of the wasmedia family.
Status
The native layer and the TypeScript wrapper are both built. blend/fuse and the CLI-style
enblend/enfuse are documented in docs/api.md. The wasm build is tested by a smoke suite and by a
differential comparison against native enblend/enfuse; the wrapper by unit and integration tests. All
of it passes locally and in GitLab CI, which runs it on every pipeline — the first green run was
pipeline 2868936176, on real amd64 runners. The browser playground is built; see below.
Install
npm install @wasmedia/wenblendimport { blend, fuse } from "@wasmedia/wenblend";
const panorama = await blend([left, right]); // positioned RGBA TIFFs, as Uint8ArrayESM only; browsers and Node. Read the first section of docs/api.md before blending anything: enblend
places images by their TIFF position tags and aligns nothing. The wasm in the package is
GPLv3-or-later (see Licensing below), so anything that ships it inherits GPL obligations.
Playground
npm run build && npm run playground serves a browser playground at http://localhost:8000/ (set
PORT= to change it). On main it deploys to GitLab Pages at
enblend.wasmedia.org. It runs enblend and enfuse on built-in sample
sets or on your own positioned RGBA TIFFs, in a worker, and nothing leaves the browser. Each input's
position tags are shown before you run, 16-bit and predictor-compressed TIFFs (Hugin nona output)
included; previews are downsampled, and only 8-bit images get one. Where the browser has OPFS, runs
store their files there, and runs in several tabs of the page take turns rather than overlap.
Artifacts
One WebAssembly module per tool, not one module with a dispatcher — the two programs cannot share a
symbol space (see docs/building.md).
| Artifact | Emscripten export | Size |
|---|---|---|
| dist/wenblend.{js,wasm} | WEnblend | ~3 MB wasm |
| dist/wenfuse.{js,wasm} | WEnfuse | ~3 MB wasm |
Each module takes its tool's own argv, passed straight to Emscripten's callMain with no tool-name
prefix. There is no C wrapper API to call instead.
Build
Docker is the only prerequisite; never install a local emsdk.
make -C native # full pipeline -> the four artifacts in dist/
make -C native smoke # fixtures, both modules under Node, 42 image invariants
npm install && npm run build:ts && npm test # the TypeScript wrapper and its testsA cold build is about 7 minutes. Other targets (verify, differential, measure-ceiling, shell,
clean, distclean) are listed in docs/building.md.
Documentation
docs/api.md— the TypeScript API. Read its first section before blending anything.docs/building.md— read this before touchingnative/. Dependency order, sentinels, source integrity, and the gotchas that cost this build real time.CLAUDE.md— project overview, architecture, and the constraints the wrapper inherits.docs/superpowers/specs/2026-09-20-wenblend-design.md— the design of record.
File mode
Inputs and outputs can stay in files (OPFS handles in a worker, host paths under Node) instead of
passing through memory; see docs/api.md § File mode. It uses
@wasmedia/wopfs, installed from npm like any other
dependency.
Licensing
wenblend's own source is GPL-2.0. LICENSE in the repository root is the GPLv2 text and covers the
code here.
The built artifacts in dist/ are GPLv3-or-later. Enblend and Enfuse are "GPL version 2, or (at
your option) any later version", and GNU GSL — linked into both modules for the Mersenne Twister on the
output-dither path — is GPLv3-or-later. The combination is legal precisely because of that "or later"
clause, which permits the upgrade; the effect is that redistributing dist/wenblend.{js,wasm} or
dist/wenfuse.{js,wasm} binds you to GPLv3-or-later terms, not GPLv2. GSL is the only copyleft
dependency in the stack — VIGRA, libtiff, libpng, zlib-ng, mozjpeg, lcms2 and Boost are all permissive.
File mode loads wopfs (MIT), a runtime dependency that is loaded only on the first file-mode call and is not part of the wasm artifacts.
Anything that links these modules inherits GPL obligations. This section is a documentation of fact about the licences in the source tree, not legal advice; a real licence review is warranted before any public release.
