Installing and running
lapstack is a single native binary. Compared with the browser app it has no stack-size
ceiling, streams frames from disk so memory stays flat however long the stack, takes an optional
CUDA build, and scripts.
Getting it
Each release on GitHub carries an
archive per platform — Linux x86-64, Windows x86-64, macOS on Apple silicon and on Intel —
with the lapstack binary, the raw decoder beside it, the license, the third-party notices
and the decoder's source. Unpack it anywhere and put the directory on your PATH, or run
the binary from there. The Linux and Windows builds have the CUDA path; every build has the
wgpu one. See the download page.
Or build from source, from a checkout of the repository:
cargo build --release
# the binary lands at target/release/lapstack, and next to it
# liblapstack_raw.so (.dylib on macOS, lapstack_raw.dll on Windows)The second file is the camera raw decoder, a component of its own that
lapstack loads when it meets a raw file: keep the two together, or point
LAPSTACK_RAW_LIB at the library. Without it every other input still works
and a raw is refused with a message saying what is missing. The decoder is
free software under the LGPL (it is built on rawler);
its source ships with lapstack, and a build of your own dropped in its place
is what lapstack will use.
With the GPU paths — CUDA, and the browser app's own kernels on any other GPU through Vulkan, Metal or Direct3D 12:
cargo build --release --features gpu,wgpu -p lapstack-cliBoth are loaded at run time, so no CUDA toolkit is needed at build time and a binary built
with the features still runs on a machine without a GPU — --gpu says what it looked for and
the CPU does the work. See GPU acceleration.
The shape of a command
lapstack [options] frame1 frame2 ...A directory among the inputs stands for the image files in it, in natural order (f2
before f10). So both of these work:
lapstack -o stacked.tif frames/*.tif
lapstack -o stacked.tif frames/The command you will actually type
lapstack --align-coarsen 2 --save-depth -o stacked.tif frames/*.tifThat aligns the frames, fuses them, runs the depth pass, writes stacked.tif cropped to the
area every frame covers, and writes the depth map beside it.
With CUDA:
lapstack --gpu --gpu-align --align-coarsen 2 --save-depth -o stacked.tif frames/*.tifOn frames that are already registered — a microscope stack, or frames you aligned elsewhere —
--no-align streams them straight from disk:
lapstack --no-align -o stacked.tif aligned/*.pngRaws work directly, and a .dng output writes a linear DNG:
lapstack --align-coarsen 2 -o stacked.dng shoot/*.NEFInput and output
Input is PNG, JPEG or TIFF (eight- or sixteen-bit), or a camera raw — NEF, CR2, CR3, ARW, DNG, RAF, ORF, RW2, PEF, IIQ, 3FR and the rest. Raws are developed as shot, with no exposure adjustment.
Output keeps the input's bit depth; sixteen bits need PNG or TIFF, and a raw counts as
sixteen-bit. The output carries the first frame's metadata — EXIF, ICC profile and XMP —
unless --no-metadata says otherwise. See formats and metadata.
TIFF output is written by lapstack's own uncompressed writer, which is why it can put EXIF and GPS sub-IFDs where they belong.
The options worth knowing first
| Option | Why |
|---|---|
--draft N | Run everything at 1/2^N the size. The fastest way to check settings before committing |
--align-coarsen 2 | The CLI defaults to 0 (full resolution). Passing 2 is a large speed-up at sub-pixel accuracy, and is what the app does |
--no-align | Frames already registered — skips most of the work |
--save-depth | Write the depth map beside the output |
--halo-control P | Turn on when you can see a rim beside a bright object |
--wav | Also write the weighted average |
--split RULE + --dry-run | Batch, and check the batch before running it |
--gpu --gpu-align | The GPU paths — CUDA, or any GPU through wgpu — when the build has them |
lapstack --help lists every option; the option reference groups them.
Drafts
lapstack --draft 2 --save-depth -o check.tif frames/*.tifEvery frame is block-averaged by 2^N as it is decoded, so the whole run — alignment, fusion,
depth pass, every output — happens at 1/2^N the size. Five 45-megapixel raws at --draft 2
align, fuse and run the depth pass in about four seconds, raw development included.
--crop and the scale bar's calibration follow the frame's own pixels, so a draft's output is
exactly the full run's output, shrunk.
What the log tells you
The run reports, as it goes:
- Each frame decoded, its registration (shift, scale, rotation) and its brightness gain
- Frames resampled because they were not frame 0's size
- The crop window the automatic crop settled on
- The dust spots found, if a dust map was given
- What the scale bar came to, if one was asked for
- Which cue decided the near end, for the stereo and 3D outputs
- The frames' scale trend over the stack, as a hint
Exit status
0 on success. 1 if a run failed, or if any stack of a --split batch failed — the batch
continues past a failure and summarizes at the end.