Files
DarkRoom/README.md
T
dtourolle 330ece0abe Bring the README's features and standing up to 0.19.0
The develop paragraph counted eighteen operations fused into one
dispatch, before the view transform made nineteen and a detail stage
made the fusion two passes, and said nothing of editing on the scene
with Tone Mapping last. Presets are now a menu on the tool rail, a
panorama frame can be left out, and a linear DNG larger than one
texture develops. The requirement count and coverage are
traceability.md's (193, 85.5%), and tiled rendering is no longer
wholly unbuilt. outstanding.md gains its sweep note for 0.19.0 and
says in §11 what the frame choice changed.
2026-09-27 19:42:42 -04:00

158 lines
8.4 KiB
Markdown

# DarkRoom
A non-destructive RAW photo editor and library for Linux and Android, with a
GPU develop pipeline, a catalog that syncs between devices, and no account,
no telemetry and no cloud of its own.
[![The library: seventy frames, the timeline beside them, the filter bar above](docs/manual/media/library.png)](docs/manual/README.md)
**[The manual](docs/manual/README.md)** shows every feature, pictured from
the application itself. This page says what it is, how to get it, and what
is still missing.
## What it does
**A library.** Point it at a folder — on this machine, on a network mount,
or one a Nextcloud client keeps in virtual-files mode, where a placeholder
is treated as the photograph rather than as a one-byte file — or at a
Nextcloud account directly; a photograph that is only on the server opens on
its thumbnail with the download's progress over it. The grid is virtualised,
ordered by capture time with a timeline beside it, and filtered by rating,
flag, colour label, person and whether the file is here. Ratings, colour
labels, keywords, collections and a trash that survives a crash
mid-operation. Card ingest. Bursts fold. The same RAW catalogued twice — a
dated folder and a backup beside it — is found, proved the same, and folded
onto one copy with the spares in the trash. Face detection and identity,
with the index syncing between devices.
**Developing.** Nineteen declared operations, those that read one pixel
fused into a generated shader rather than run a pass each, plus the
neighbourhood work that cannot be: clarity, texture, dehaze, capture
sharpening, noise reduction, lens correction. Every edit works on the scene
as the camera recorded it — linear, highlights beyond white included — and
one `Tone Mapping` step, last, after sharpening and noise reduction, fits it
to the screen, with a contrast and a white point of its own; a spectral film
stock takes its place when one is chosen. Crop, straighten and correct
converging verticals, spot repair, and local adjustments over masks the
model draws — click a subject or a category, then paint, subtract a gradient
or keep only where two selections agree, grow or shrink the edge. A mask's
sliders add to the photograph's, the film's among them, so a sky can be
burned in on the print as a darkroom printer would. Hot and dead photosites
are mended before the demosaic, with nothing to set. Focus peaking and a raw
histogram for judging what is recoverable. Presets, a click away in a menu
at the foot of the tool rail, with a collection shipped in the application —
everyday corrections, and a look for each measured colour, cinema and
black-and-white stock — and Lightroom presets imported as looks that leave a
photograph's own corrections alone. XMP sidecars other editors read. A
linear DNG larger than one GPU texture — a stitched panorama twenty thousand
pixels wide — opens, develops and exports at full size.
[![Segmenting an urban scene and choosing the sky as a mask](docs/manual/media/local-segment.png)](docs/manual/README.md#local-adjustments)
**Panoramas.** Select the frames, align, untick any frame to leave it out
and the rest re-align at once, choose a projection, fill the ragged border
rather than crop it, and the composite lands beside its sources as a DNG,
with a sidecar recording what it was merged from.
[![Twelve hand-held frames aligned on a cylinder](docs/manual/media/panorama-aligned.png)](docs/manual/README.md#merging-a-panorama)
**From the keyboard, and with its manual.** Rating, flagging and labelling
have keys in the grid and in develop, as do zoom, undo and stepping through a
shoot in develop, and none of them is keyboard-only. The help sheet (`F1`, or
`?` in develop) lists every key and gesture, generated from the code that
binds it, and links them to the sections of the manual that show them — the
manual ships with the application and opens offline.
**Export.** JPEG, PNG, AVIF, JPEG XL, 8- and 16-bit TIFF, with resize, output
sharpening, a naming template and a colour space — into albums: named export
folders on this machine or on the server, never inside the library, which
remember the photograph behind each file and sync between devices as
collections do.
**On both platforms.** The same core runs on a desktop and a 12-inch
tablet; the interface is one layout, tuned for a wide viewport with touch
targets throughout. On both, the develop view draws the compute pass's
texture directly — no readback between the GPU and the screen.
## Getting it
| Platform | How | State |
|---|---|---|
| Arch Linux | [`packaging/PKGBUILD`](packaging/PKGBUILD) — `makepkg -si` | Built from every release |
| Android | The APK from each CI run, or `./docker/android/package.sh --install` | Runs on a tablet; F-Droid not yet submitted |
| Windows | `DarkRoom-<version>-x86_64-setup.exe`, cross-built by CI ([windows.md](docs/dev/windows.md)) | Verified under Wine only; unsigned |
| Flatpak | [`packaging/flatpak/`](packaging/flatpak/) | Manifest in tree; folders are chosen through the portal, but no Flatpak has been built to prove it |
Or build it. Git LFS is required for the model weights, and the toolchain
pins itself to 1.92.0:
```bash
git lfs install && git lfs pull
cargo run --release -p darkroom-desktop
```
Android, through the containerised toolchain ([docker/android](docker/android/README.md)):
```bash
./docker/android/build.sh cargo ndk -t arm64-v8a build --release
```
[CONTRIBUTING.md](CONTRIBUTING.md) has the system packages, the four
commands CI runs against what you send, and the shortest useful
contribution — a develop operation is one YAML file, and it arrives with its
controls, its place in the chain and its tests.
## Where it stands
**0.18.2**, twenty-eight tagged releases in. 193 numbered requirements in
scope, 85% of them claimed by code and [traced to it](docs/dev/traceability.md);
the rest are written down rather than merely absent.
**Not built:** plugins (post-v1, [D12](docs/dev/requirements.md)), compare and
survey culling, AI denoise, tiled rendering beyond the export of an oversized
DNG, HDR merge and focus stacking, importing a Lightroom or darktable catalog,
translations beyond the launch screen, most of the Android platform
integration beyond running, and a Flatpak actually built and run in its
sandbox. The performance targets are half verified: the per-commit benchmark
suite §8 requires exists for everything that does not need a frame — the
catalog, the scan, the thumbnails — and not yet for the render path, so a
regression there fails nothing.
[outstanding.md](docs/dev/outstanding.md) is the list, with the reasoning for
each.
## Documentation
[docs/README.md](docs/README.md) is the index. The short version, for someone using it:
| | |
|---|---|
| [manual](docs/manual/README.md) | Every feature, pictured |
| [gestures.md](docs/gestures.md) | How it is driven — generated from the code, so it cannot describe a gesture that does not exist |
For someone changing it:
| | |
|---|---|
| [CONTRIBUTING.md](CONTRIBUTING.md) | How to land a first change without reading the rest |
| [requirements.md](docs/dev/requirements.md) | What the software must do — the numbered register, and the decisions |
| [architecture.md](docs/dev/architecture.md) | How it is built — crates, the GPU pipeline, the data model, sync |
| [technical-debt.md](docs/dev/technical-debt.md) | Compromises taken deliberately, each with the condition that retires it |
| [outstanding.md](docs/dev/outstanding.md) | What is not built, and whether that is a decision or a gap |
| [code-health.md](docs/dev/code-health.md) | What a contribution costs, per seam, measured |
| [traceability.md](docs/dev/traceability.md) | Generated: which requirement is claimed by which file |
Designs, one per subsystem:
[segmentation](docs/dev/segmentation.md) and [mask editing](docs/dev/mask-editing.md) ·
[spot removal](docs/dev/spot-removal.md) · [panorama](docs/dev/panorama.md) ·
[faces](docs/dev/faces.md) · [inference](docs/dev/inference.md) ·
[storage and sync](docs/dev/storage.md) · [catalog](docs/dev/catalog.md) ·
[display and extension](docs/dev/display-and-extension.md) ·
[navigation](docs/dev/ui-navigation.md) · [distribution](docs/dev/distribution.md) ·
[windows](docs/dev/windows.md) · [benchmarks](docs/dev/benchmarks.md).
## Licence
GPL-3.0-or-later. The photographs in the manual and the test fixtures are
the author's and are there to show and test this project, nothing else.
The model weights carry their own licences — [models/LICENCE.md](models/LICENCE.md).