diff --git a/README.md b/README.md index 9da4692..e27ad7a 100644 --- a/README.md +++ b/README.md @@ -1,85 +1,134 @@ # DarkRoom -A cross-platform, non-destructive RAW photo editor for Linux and Android. +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. -**Status:** 0.9.0, and no longer a spike. A library opens, culls, develops and -exports on both platforms, across eight tagged releases. What is *not* -built is written down rather than merely absent — see -[docs/outstanding.md](docs/outstanding.md) for the requirements that have no -implementation and why, and [docs/technical-debt.md](docs/technical-debt.md) -for the compromises that were chosen. +[![The library: seventy frames, the timeline beside them, the filter bar above](docs/manual/media/library.png)](docs/manual/README.md) -## Documentation +**[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. -| Document | Contents | -|---|---| -| [manual](docs/manual/README.md) | What it looks like — every feature, pictured from the application itself | -| [CONTRIBUTING.md](CONTRIBUTING.md) | How to land a first change without reading the rest | -| [requirements.md](docs/requirements.md) | What the software must do — 179 numbered requirements | -| [architecture.md](docs/architecture.md) | How it is built — crates, GPU pipeline, data model, sync | -| [technical-debt.md](docs/technical-debt.md) | Compromises taken deliberately, each with the condition that retires it | -| [outstanding.md](docs/outstanding.md) | What is not built, and whether that is a decision or a gap | -| [code-health.md](docs/code-health.md) | What a contribution costs, per seam, measured | -| [traceability.md](docs/traceability.md) | Generated: which requirement is claimed by which file | -| [faces.md](docs/faces.md) | Face detection and identity — the models, the licence problem, and what S14 measured | +## What it does -## Building +**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. The grid is virtualised, ordered by capture +time with a timeline beside it, and filtered by rating, flag, keyword, +person and whether the file is here. Ratings, keywords, collections and a +trash that survives a crash mid-operation. Card ingest. Bursts fold. Face +detection and identity, with the index syncing between devices. -Desktop: +**Developing.** Fifteen 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 and straighten, spot repair, and local adjustments over +masks the model draws — click a subject or a category, then paint, subtract +a gradient, grow or shrink the edge. Focus peaking and a raw histogram for +judging what is recoverable. Named presets; 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 the merge as the first step in its history. + +[![Twelve hand-held frames aligned on a cylinder](docs/manual/media/panorama-aligned.png)](docs/manual/README.md#merging-a-panorama) + +**Export.** JPEG, PNG, AVIF, 8- and 16-bit TIFF, with resize, output +sharpening, a naming template and a colour space — to a folder here or back +into the library. + +**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 desktop 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/windows.md)) | Verified under Wine only; unsigned | +| Flatpak | [`packaging/flatpak/`](packaging/flatpak/) | Manifest in tree; choosing a library does not yet work in the sandbox | + +Or build it. Git LFS is required for the model weights, and the toolchain +pins itself to 1.92.0: ```bash -cargo run -p darkroom-desktop +git lfs install && git lfs pull +cargo run --release -p darkroom-desktop ``` -Android (containerised toolchain, see [docker/android](docker/android/README.md)): +Android, through the containerised toolchain ([docker/android](docker/android/README.md)): ```bash ./docker/android/build.sh cargo ndk -t arm64-v8a build --release ``` -Git LFS is required for the model weights, and the toolchain pins itself. -[CONTRIBUTING.md](CONTRIBUTING.md) has the details and the four commands CI -will run against what you send. +[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. -## Current state +## Where it stands -**Working.** A catalog over a local folder, a Nextcloud account, or a folder a -sync client keeps in virtual-files mode — where a placeholder is treated as the -photograph rather than as a one-byte file. A virtualised library grid with a -capture-time timeline, ratings, labels, keywords, collections and a trash that -survives a crash mid-operation. Card ingest. Face detection and identity, with -the index syncing between devices. A develop pipeline of fifteen declared -operations fused into a single compute dispatch, plus the neighbourhood -operations that cannot be — clarity, texture, capture sharpening, noise -reduction, lens correction, spectral film simulation. Crop, straighten, spot -removal, gradient and subject-segmentation masks, named presets, and a -generated panel that no operation in `ui/` is allowed to name. Export to JPEG, -PNG and 8- or 16-bit TIFF with resize and output sharpening. +**0.13.1**, fifteen tagged releases in. 184 numbered requirements in +scope, 84% of them claimed by code and [traced to it](docs/traceability.md); +the rest are written down rather than merely absent. -**The zero-copy display path works on desktop.** The compute pass writes a -texture that Slint composites directly, which is what -[ARCH §6.1](docs/architecture.md) requires; the readback it forbids costs 96% -of frame time at 4K, and +**Not built:** plugins (post-v1, [D12](docs/requirements.md)), compare and +survey culling, AI denoise, tiled and progressive rendering, HDR merge and +focus stacking, most of the Android platform integration beyond running, +and the Flatpak's library chooser. 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/outstanding.md) is the list, with the reasoning for +each. -```bash -cargo run -p dr-gpu --example bench --features readback -``` +**The one deliberate compromise worth knowing about before reading +anything else:** the Android develop view reads its frame back through the +CPU, because zero-copy there needs wgpu's Vulkan swapchain and that tears a +portrait window on a tablet whose panel is mounted landscape. It is debt, +not a revision of the rule — [technical-debt.md TD-1](docs/technical-debt.md) +has the measurements and the three things any one of which would remove it. -still reproduces that measurement. **The one exception is the Android develop -view**, which reads the frame back through the CPU because zero-copy there -needs wgpu's Vulkan swapchain, and that tears a portrait window on a tablet -whose panel is mounted landscape. It is debt, not a revision of the rule: the -reasoning, the on-device measurements that forced it, and the three separate -things any one of which would remove it are in -[technical-debt.md TD-1](docs/technical-debt.md). +## Documentation -**Not built.** Plugins, compare and survey culling, focus peaking, burst -grouping, AI denoise, tiled and progressive rendering, and most of the Android -platform integration beyond running. The performance targets in §4.1 are -unverified rather than unmet — the per-commit benchmark suite §8 requires does -not exist, so nothing fails a build on a regression. -[docs/outstanding.md](docs/outstanding.md) is the list, with the reasoning. +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/requirements.md) | What the software must do — the numbered register, and the decisions | +| [architecture.md](docs/architecture.md) | How it is built — crates, the GPU pipeline, the data model, sync | +| [technical-debt.md](docs/technical-debt.md) | Compromises taken deliberately, each with the condition that retires it | +| [outstanding.md](docs/outstanding.md) | What is not built, and whether that is a decision or a gap | +| [code-health.md](docs/code-health.md) | What a contribution costs, per seam, measured | +| [traceability.md](docs/traceability.md) | Generated: which requirement is claimed by which file | + +Designs, one per subsystem: +[segmentation](docs/segmentation.md) and [mask editing](docs/mask-editing.md) · +[spot removal](docs/spot-removal.md) · [panorama](docs/panorama.md) · +[faces](docs/faces.md) · [inference](docs/inference.md) · +[storage and sync](docs/storage.md) · [catalog](docs/catalog.md) · +[display and extension](docs/display-and-extension.md) · +[navigation](docs/ui-navigation.md) · [distribution](docs/distribution.md) · +[windows](docs/windows.md) · [benchmarks](docs/benchmarks.md). ## Licence -GPL-3.0-or-later. +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).