# 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.** Eighteen declared operations fused into one compute dispatch, plus the neighbourhood work that cannot be: clarity, texture, capture sharpening, noise reduction, lens correction, spectral film simulation. 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. Focus peaking and a raw histogram for judging what is recoverable. Presets, 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. [![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, 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--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.17.0**, twenty-five tagged releases in. 192 numbered requirements in scope, 84% 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, 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).