Benchmarks / CPU and I/O (per commit) (push) Successful in 5m27s
Benchmarks / Frame budget (on demand) (push) Skipped
Traceability / Requirement traces (push) Successful in 1m2s
Build and test / Android (aarch64) (push) Successful in 29m53s
Build and test / android-image (push) Successful in 2s
🐳 Android image / Build and push (push) Successful in 2s
Build and test / Desktop (Linux) (push) Successful in 50m11s
Build and test / windows-image (push) Successful in 2s
🐳 Windows image / Build and push (push) Successful in 1s
Build and test / Layer separation (push) Successful in 38s
Build and test / Windows (x86_64, cross) (push) Successful in 35m28s
Build and test / Publish the release (push) Successful in 1m10s
158 lines
8.4 KiB
Markdown
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.
|
|
|
|
[](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.
|
|
|
|
[](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.
|
|
|
|
[](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.19.0**, twenty-nine 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).
|