From 3d248cfb7953d74bc377bdae84850608136390ea Mon Sep 17 00:00:00 2001 From: Duncan Tourolle Date: Sun, 30 Aug 2026 19:33:44 +0200 Subject: [PATCH] Export the photograph, not the canvas MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Zooming the develop view changed the exported file. `Framing::view` is kept out of the sidecar, out of `is_active` and out of `output_size` precisely so that it cannot — but those exclusions keep it out of the *edit*, and an export is a *render*. `visible_rect` deliberately folds the view into the single rect the fused shader's prologue samples, so `render_for_export` inherited it: at 4:1 it wrote the middle of the frame, magnified to fill the file at the full output size, with the detail kernels scaled four times over because `render_scale` folds the view in as well. `render_thumbnail` did the same to the grid. `render_uncropped` already suspends the view for this exact reason, so the fix is its pattern: one `render_the_file` that both file-producing paths go through, composing inside the suspension since the view reaches the shader as a uniform baked at composition time. Restored whatever happens — leaving the graph un-zoomed after a failed export would throw away where the photographer was looking. Nothing caught it because the guard checked the wrong things. `zooming_does_not_change_the_exported_image` asserted the output size and the crop; both held perfectly throughout. Renamed to `zooming_does_not_change_the_size_or_the_crop`, which is what it tests, and the pixels are now guarded where pixels exist. The new test uses a ramp rather than quadrants deliberately: a four-quadrant frame is self-similar under a centred zoom, and the first version of this test passed against the bug because of it. Traces FR-EXP-9, which asks for the full-quality pipeline "regardless of what the display was showing". Co-Authored-By: Claude Opus 5 (1M context) --- core/dr-pipeline/src/framing.rs | 30 ++++- docs/traceability.md | 42 +++--- ui/dr-ui/src/develop.rs | 53 ++++++-- ui/dr-ui/tests/export_ignores_the_viewport.rs | 123 ++++++++++++++++++ 4 files changed, 213 insertions(+), 35 deletions(-) create mode 100644 ui/dr-ui/tests/export_ignores_the_viewport.rs diff --git a/core/dr-pipeline/src/framing.rs b/core/dr-pipeline/src/framing.rs index 841a08c..0758dcd 100644 --- a/core/dr-pipeline/src/framing.rs +++ b/core/dr-pipeline/src/framing.rs @@ -348,9 +348,19 @@ pub struct Framing { /// Which part of the framed image the viewport is looking at. /// /// **Not an edit.** Zooming changes what you are inspecting, never what - /// the file becomes: it is excluded from [`Self::is_active`], from the - /// structure hash, and from the sidecar, so a zoomed view exports exactly - /// as an unzoomed one does. + /// the file becomes, so it is excluded from [`Self::is_active`], from the + /// structure hash, and from the sidecar. + /// + /// **That is not on its own enough to make an export ignore it**, and + /// this doc comment used to claim it was. The exclusions keep the view out + /// of the *edit* — out of what is saved, out of the output size, out of + /// the crop. They cannot keep it out of a *render*, because + /// [`Self::visible_rect`] deliberately folds it into the one rect the + /// shader samples. Anything composing this framing and rendering it gets + /// the zoom; a caller that wants the photograph rather than the canvas + /// has to suspend the view first, as `DevelopSession::render_the_file` + /// and `render_uncropped` both do. Exporting at 4:1 wrote the middle of + /// the frame, magnified, until it did. /// /// It lives here rather than in the UI because it composes with the crop /// in the same normalised space — nesting one rect inside the other is a @@ -1252,10 +1262,18 @@ mod tests { } #[test] - fn zooming_does_not_change_the_exported_image() { + fn zooming_does_not_change_the_size_or_the_crop() { // The property that makes zoom a viewing tool rather than an edit: it - // must not reach the output size or the crop. If it did, exporting - // while zoomed would write the zoomed view. + // must not reach the output size or the crop. + // + // **Renamed, because the old name promised more than the body checks + // and the gap was where a real bug lived.** "Does not change the + // exported image" was read as a guarantee about pixels; it is a + // guarantee about two numbers. Both held perfectly while + // `render_for_export` was writing the zoomed view at full size, + // because the view reaches the render through `visible_rect` and + // never through either of these. The pixels are guarded where pixels + // exist — `dr-ui`'s `export_ignores_the_viewport`. // // The structure key is deliberately not asserted here — see // `zooming_from_neutral_changes_the_structure_key` for why it must diff --git a/docs/traceability.md b/docs/traceability.md index 1cfb58e..0fa1fe9 100644 --- a/docs/traceability.md +++ b/docs/traceability.md @@ -9,8 +9,8 @@ Denominators are parsed from [`requirements.md`](requirements.md) at run time, n | Metric | Value | |---|---| -| Source files scanned | 330 | -| TRACES tags found | 1039 | +| Source files scanned | 331 | +| TRACES tags found | 1041 | | Requirements defined | 179 | | Requirements covered | 126 | | **Coverage** | **70.4%** (126/179) | @@ -45,48 +45,48 @@ _None._ | FR-CAT-5 | [`core/dr-catalog/src/keywords.rs:1`](../core/dr-catalog/src/keywords.rs#L1), [`core/dr-catalog/src/merge.rs:1`](../core/dr-catalog/src/merge.rs#L1), [`core/dr-catalog/src/rating.rs:1`](../core/dr-catalog/src/rating.rs#L1), [`core/dr-catalog/src/schema.rs:1171`](../core/dr-catalog/src/schema.rs#L1171), [`core/dr-catalog/src/schema.rs:668`](../core/dr-catalog/src/schema.rs#L668), [`core/dr-decode/src/lib.rs:285`](../core/dr-decode/src/lib.rs#L285), [`core/dr-decode/src/lib.rs:404`](../core/dr-decode/src/lib.rs#L404), [`core/dr-pipeline/src/sidecar.rs:136`](../core/dr-pipeline/src/sidecar.rs#L136), [`ui/dr-ui/src/collections_ui.rs:1579`](../ui/dr-ui/src/collections_ui.rs#L1579), [`ui/dr-ui/src/collections_ui.rs:1685`](../ui/dr-ui/src/collections_ui.rs#L1685), [`ui/dr-ui/src/collections_ui.rs:1734`](../ui/dr-ui/src/collections_ui.rs#L1734), [`ui/dr-ui/src/collections_ui.rs:238`](../ui/dr-ui/src/collections_ui.rs#L238), [`ui/dr-ui/src/collections_ui.rs:335`](../ui/dr-ui/src/collections_ui.rs#L335), [`ui/dr-ui/src/collections_ui.rs:87`](../ui/dr-ui/src/collections_ui.rs#L87), [`ui/dr-ui/src/library.rs:4165`](../ui/dr-ui/src/library.rs#L4165), [`ui/dr-ui/src/library_ui.rs:659`](../ui/dr-ui/src/library_ui.rs#L659), [`ui/dr-ui/src/library_ui.rs:6953`](../ui/dr-ui/src/library_ui.rs#L6953), [`ui/dr-ui/src/library_ui.rs:6964`](../ui/dr-ui/src/library_ui.rs#L6964), [`ui/dr-ui/src/library_ui.rs:6977`](../ui/dr-ui/src/library_ui.rs#L6977), [`ui/dr-ui/src/library_ui.rs:6992`](../ui/dr-ui/src/library_ui.rs#L6992), [`ui/dr-ui/src/library_ui.rs:7001`](../ui/dr-ui/src/library_ui.rs#L7001), [`ui/dr-ui/ui/app.slint:333`](../ui/dr-ui/ui/app.slint#L333), [`ui/dr-ui/ui/app.slint:547`](../ui/dr-ui/ui/app.slint#L547), [`ui/dr-ui/ui/library.slint:1246`](../ui/dr-ui/ui/library.slint#L1246), [`ui/dr-ui/ui/library.slint:1270`](../ui/dr-ui/ui/library.slint#L1270), [`ui/dr-ui/ui/library.slint:1323`](../ui/dr-ui/ui/library.slint#L1323), [`ui/dr-ui/ui/library.slint:19`](../ui/dr-ui/ui/library.slint#L19), [`ui/dr-ui/ui/library.slint:3963`](../ui/dr-ui/ui/library.slint#L3963) | | FR-CAT-6 | [`core/dr-catalog/src/collections.rs:1`](../core/dr-catalog/src/collections.rs#L1), [`core/dr-catalog/src/keywords.rs:1`](../core/dr-catalog/src/keywords.rs#L1), [`core/dr-catalog/src/lib.rs:1`](../core/dr-catalog/src/lib.rs#L1), [`core/dr-catalog/src/query.rs:1`](../core/dr-catalog/src/query.rs#L1), [`core/dr-catalog/src/rating.rs:1`](../core/dr-catalog/src/rating.rs#L1), [`core/dr-catalog/src/schema.rs:668`](../core/dr-catalog/src/schema.rs#L668), [`core/dr-types/src/selector.rs:1`](../core/dr-types/src/selector.rs#L1), [`core/dr-types/src/settings.rs:64`](../core/dr-types/src/settings.rs#L64), [`core/dr-types/src/time.rs:67`](../core/dr-types/src/time.rs#L67), [`core/dr-types/src/time.rs:90`](../core/dr-types/src/time.rs#L90), [`ui/dr-ui/src/library.rs:246`](../ui/dr-ui/src/library.rs#L246), [`ui/dr-ui/src/library.rs:4558`](../ui/dr-ui/src/library.rs#L4558), [`ui/dr-ui/src/library_ui.rs:342`](../ui/dr-ui/src/library_ui.rs#L342), [`ui/dr-ui/src/library_ui.rs:416`](../ui/dr-ui/src/library_ui.rs#L416), [`ui/dr-ui/src/library_ui.rs:5688`](../ui/dr-ui/src/library_ui.rs#L5688), [`ui/dr-ui/src/library_ui.rs:5741`](../ui/dr-ui/src/library_ui.rs#L5741), [`ui/dr-ui/src/library_ui.rs:7093`](../ui/dr-ui/src/library_ui.rs#L7093), [`ui/dr-ui/ui/app.slint:345`](../ui/dr-ui/ui/app.slint#L345), [`ui/dr-ui/ui/app.slint:547`](../ui/dr-ui/ui/app.slint#L547), [`ui/dr-ui/ui/app.slint:850`](../ui/dr-ui/ui/app.slint#L850), [`ui/dr-ui/ui/library.slint:110`](../ui/dr-ui/ui/library.slint#L110), [`ui/dr-ui/ui/library.slint:1433`](../ui/dr-ui/ui/library.slint#L1433), [`ui/dr-ui/ui/library.slint:3963`](../ui/dr-ui/ui/library.slint#L3963), [`ui/dr-ui/ui/settings.slint:150`](../ui/dr-ui/ui/settings.slint#L150) | | FR-CAT-7 | [`core/dr-catalog/src/collections.rs:1`](../core/dr-catalog/src/collections.rs#L1), [`core/dr-catalog/src/merge.rs:1`](../core/dr-catalog/src/merge.rs#L1), [`core/dr-catalog/src/sync.rs:1`](../core/dr-catalog/src/sync.rs#L1), [`core/dr-types/src/selector.rs:1`](../core/dr-types/src/selector.rs#L1), [`ui/dr-ui/src/collections_ui.rs:1073`](../ui/dr-ui/src/collections_ui.rs#L1073), [`ui/dr-ui/src/collections_ui.rs:117`](../ui/dr-ui/src/collections_ui.rs#L117), [`ui/dr-ui/src/collections_ui.rs:1552`](../ui/dr-ui/src/collections_ui.rs#L1552), [`ui/dr-ui/src/collections_ui.rs:1598`](../ui/dr-ui/src/collections_ui.rs#L1598), [`ui/dr-ui/src/collections_ui.rs:1848`](../ui/dr-ui/src/collections_ui.rs#L1848), [`ui/dr-ui/src/collections_ui.rs:1913`](../ui/dr-ui/src/collections_ui.rs#L1913), [`ui/dr-ui/src/collections_ui.rs:1973`](../ui/dr-ui/src/collections_ui.rs#L1973), [`ui/dr-ui/src/collections_ui.rs:1`](../ui/dr-ui/src/collections_ui.rs#L1), [`ui/dr-ui/src/collections_ui.rs:2963`](../ui/dr-ui/src/collections_ui.rs#L2963), [`ui/dr-ui/src/collections_ui.rs:365`](../ui/dr-ui/src/collections_ui.rs#L365), [`ui/dr-ui/src/collections_ui.rs:569`](../ui/dr-ui/src/collections_ui.rs#L569), [`ui/dr-ui/src/collections_ui.rs:965`](../ui/dr-ui/src/collections_ui.rs#L965), [`ui/dr-ui/src/derived_sync.rs:1`](../ui/dr-ui/src/derived_sync.rs#L1), [`ui/dr-ui/src/library.rs:4363`](../ui/dr-ui/src/library.rs#L4363), [`ui/dr-ui/src/library.rs:4389`](../ui/dr-ui/src/library.rs#L4389), [`ui/dr-ui/src/library.rs:4444`](../ui/dr-ui/src/library.rs#L4444), [`ui/dr-ui/src/library_ui.rs:2467`](../ui/dr-ui/src/library_ui.rs#L2467), [`ui/dr-ui/src/library_ui.rs:3863`](../ui/dr-ui/src/library_ui.rs#L3863), [`ui/dr-ui/src/library_ui.rs:4590`](../ui/dr-ui/src/library_ui.rs#L4590), [`ui/dr-ui/ui/app.slint:336`](../ui/dr-ui/ui/app.slint#L336), [`ui/dr-ui/ui/app.slint:542`](../ui/dr-ui/ui/app.slint#L542), [`ui/dr-ui/ui/app.slint:571`](../ui/dr-ui/ui/app.slint#L571), [`ui/dr-ui/ui/collections.slint:4`](../ui/dr-ui/ui/collections.slint#L4), [`ui/dr-ui/ui/library.slint:1213`](../ui/dr-ui/ui/library.slint#L1213), [`ui/dr-ui/ui/library.slint:2748`](../ui/dr-ui/ui/library.slint#L2748), [`ui/dr-ui/ui/library.slint:3941`](../ui/dr-ui/ui/library.slint#L3941), [`ui/dr-ui/ui/library.slint:889`](../ui/dr-ui/ui/library.slint#L889) | -| FR-CAT-8 | [`core/dr-pipeline/src/graph.rs:346`](../core/dr-pipeline/src/graph.rs#L346), [`core/dr-pipeline/src/graph.rs:385`](../core/dr-pipeline/src/graph.rs#L385), [`core/dr-pipeline/src/ops/curve.rs:137`](../core/dr-pipeline/src/ops/curve.rs#L137), [`core/dr-pipeline/src/ops/curve.rs:656`](../core/dr-pipeline/src/ops/curve.rs#L656), [`core/dr-pipeline/src/sidecar.rs:1669`](../core/dr-pipeline/src/sidecar.rs#L1669), [`core/dr-pipeline/src/sidecar.rs:93`](../core/dr-pipeline/src/sidecar.rs#L93), [`core/dr-pipeline/src/state.rs:1`](../core/dr-pipeline/src/state.rs#L1), [`core/dr-pipeline/src/state.rs:75`](../core/dr-pipeline/src/state.rs#L75), [`core/dr-pipeline/tests/tone_curve.rs:34`](../core/dr-pipeline/tests/tone_curve.rs#L34), [`ui/dr-ui/src/develop.rs:3954`](../ui/dr-ui/src/develop.rs#L3954), [`ui/dr-ui/src/develop.rs:3983`](../ui/dr-ui/src/develop.rs#L3983), [`ui/dr-ui/src/export.rs:750`](../ui/dr-ui/src/export.rs#L750), [`ui/dr-ui/src/lib.rs:1038`](../ui/dr-ui/src/lib.rs#L1038), [`ui/dr-ui/src/lib.rs:1554`](../ui/dr-ui/src/lib.rs#L1554), [`ui/dr-ui/src/lib.rs:2044`](../ui/dr-ui/src/lib.rs#L2044), [`ui/dr-ui/src/lib.rs:2179`](../ui/dr-ui/src/lib.rs#L2179), [`ui/dr-ui/src/lib.rs:590`](../ui/dr-ui/src/lib.rs#L590), [`ui/dr-ui/src/library.rs:1903`](../ui/dr-ui/src/library.rs#L1903), [`ui/dr-ui/src/library.rs:492`](../ui/dr-ui/src/library.rs#L492), [`ui/dr-ui/src/library.rs:539`](../ui/dr-ui/src/library.rs#L539), [`ui/dr-ui/src/library.rs:576`](../ui/dr-ui/src/library.rs#L576), [`ui/dr-ui/src/library.rs:823`](../ui/dr-ui/src/library.rs#L823), [`ui/dr-ui/src/library_ui.rs:5313`](../ui/dr-ui/src/library_ui.rs#L5313), [`ui/dr-ui/src/sidecar_cache.rs:1`](../ui/dr-ui/src/sidecar_cache.rs#L1) | -| FR-CAT-9 | [`core/dr-catalog/src/cache.rs:1`](../core/dr-catalog/src/cache.rs#L1), [`core/dr-catalog/src/scan.rs:1`](../core/dr-catalog/src/scan.rs#L1), [`core/dr-catalog/src/schema.rs:725`](../core/dr-catalog/src/schema.rs#L725), [`core/dr-catalog/src/walk.rs:1022`](../core/dr-catalog/src/walk.rs#L1022), [`core/dr-catalog/src/walk.rs:162`](../core/dr-catalog/src/walk.rs#L162), [`core/dr-catalog/src/walk.rs:1`](../core/dr-catalog/src/walk.rs#L1), [`core/dr-catalog/src/walk.rs:435`](../core/dr-catalog/src/walk.rs#L435), [`core/dr-catalog/src/walk.rs:728`](../core/dr-catalog/src/walk.rs#L728), [`core/dr-sync-nextcloud/src/desktop_client.rs:30`](../core/dr-sync-nextcloud/src/desktop_client.rs#L30), [`core/dr-sync/src/error.rs:113`](../core/dr-sync/src/error.rs#L113), [`core/dr-sync/src/reachability.rs:1`](../core/dr-sync/src/reachability.rs#L1), [`core/dr-sync/src/scan.rs:175`](../core/dr-sync/src/scan.rs#L175), [`core/dr-sync/src/scan.rs:464`](../core/dr-sync/src/scan.rs#L464), [`core/dr-types/src/lib.rs:120`](../core/dr-types/src/lib.rs#L120), [`ui/dr-ui/src/develop.rs:3381`](../ui/dr-ui/src/develop.rs#L3381), [`ui/dr-ui/src/library.rs:1222`](../ui/dr-ui/src/library.rs#L1222), [`ui/dr-ui/src/library.rs:1275`](../ui/dr-ui/src/library.rs#L1275), [`ui/dr-ui/src/library.rs:1306`](../ui/dr-ui/src/library.rs#L1306), [`ui/dr-ui/src/library.rs:1411`](../ui/dr-ui/src/library.rs#L1411), [`ui/dr-ui/src/library.rs:161`](../ui/dr-ui/src/library.rs#L161), [`ui/dr-ui/src/library.rs:1863`](../ui/dr-ui/src/library.rs#L1863), [`ui/dr-ui/src/library.rs:1939`](../ui/dr-ui/src/library.rs#L1939), [`ui/dr-ui/src/library.rs:266`](../ui/dr-ui/src/library.rs#L266), [`ui/dr-ui/src/library.rs:4666`](../ui/dr-ui/src/library.rs#L4666), [`ui/dr-ui/src/library.rs:576`](../ui/dr-ui/src/library.rs#L576), [`ui/dr-ui/src/library.rs:807`](../ui/dr-ui/src/library.rs#L807), [`ui/dr-ui/src/library.rs:823`](../ui/dr-ui/src/library.rs#L823), [`ui/dr-ui/src/library.rs:877`](../ui/dr-ui/src/library.rs#L877), [`ui/dr-ui/src/library_ui.rs:1241`](../ui/dr-ui/src/library_ui.rs#L1241), [`ui/dr-ui/src/library_ui.rs:1832`](../ui/dr-ui/src/library_ui.rs#L1832), [`ui/dr-ui/src/library_ui.rs:1876`](../ui/dr-ui/src/library_ui.rs#L1876), [`ui/dr-ui/src/library_ui.rs:1892`](../ui/dr-ui/src/library_ui.rs#L1892), [`ui/dr-ui/src/library_ui.rs:1986`](../ui/dr-ui/src/library_ui.rs#L1986), [`ui/dr-ui/src/library_ui.rs:237`](../ui/dr-ui/src/library_ui.rs#L237), [`ui/dr-ui/src/library_ui.rs:2706`](../ui/dr-ui/src/library_ui.rs#L2706), [`ui/dr-ui/src/library_ui.rs:270`](../ui/dr-ui/src/library_ui.rs#L270), [`ui/dr-ui/src/library_ui.rs:278`](../ui/dr-ui/src/library_ui.rs#L278), [`ui/dr-ui/src/library_ui.rs:3144`](../ui/dr-ui/src/library_ui.rs#L3144), [`ui/dr-ui/src/library_ui.rs:3366`](../ui/dr-ui/src/library_ui.rs#L3366), [`ui/dr-ui/src/library_ui.rs:3644`](../ui/dr-ui/src/library_ui.rs#L3644), [`ui/dr-ui/src/library_ui.rs:3732`](../ui/dr-ui/src/library_ui.rs#L3732), [`ui/dr-ui/src/library_ui.rs:3914`](../ui/dr-ui/src/library_ui.rs#L3914), [`ui/dr-ui/src/library_ui.rs:4028`](../ui/dr-ui/src/library_ui.rs#L4028), [`ui/dr-ui/src/library_ui.rs:469`](../ui/dr-ui/src/library_ui.rs#L469), [`ui/dr-ui/src/library_ui.rs:532`](../ui/dr-ui/src/library_ui.rs#L532), [`ui/dr-ui/src/library_ui.rs:5786`](../ui/dr-ui/src/library_ui.rs#L5786), [`ui/dr-ui/src/library_ui.rs:5901`](../ui/dr-ui/src/library_ui.rs#L5901), [`ui/dr-ui/src/presets.rs:446`](../ui/dr-ui/src/presets.rs#L446), [`ui/dr-ui/src/presets.rs:458`](../ui/dr-ui/src/presets.rs#L458), [`ui/dr-ui/src/sidecar_cache.rs:1`](../ui/dr-ui/src/sidecar_cache.rs#L1) | +| FR-CAT-8 | [`core/dr-pipeline/src/graph.rs:346`](../core/dr-pipeline/src/graph.rs#L346), [`core/dr-pipeline/src/graph.rs:385`](../core/dr-pipeline/src/graph.rs#L385), [`core/dr-pipeline/src/ops/curve.rs:137`](../core/dr-pipeline/src/ops/curve.rs#L137), [`core/dr-pipeline/src/ops/curve.rs:656`](../core/dr-pipeline/src/ops/curve.rs#L656), [`core/dr-pipeline/src/sidecar.rs:1669`](../core/dr-pipeline/src/sidecar.rs#L1669), [`core/dr-pipeline/src/sidecar.rs:93`](../core/dr-pipeline/src/sidecar.rs#L93), [`core/dr-pipeline/src/state.rs:1`](../core/dr-pipeline/src/state.rs#L1), [`core/dr-pipeline/src/state.rs:75`](../core/dr-pipeline/src/state.rs#L75), [`core/dr-pipeline/tests/tone_curve.rs:34`](../core/dr-pipeline/tests/tone_curve.rs#L34), [`ui/dr-ui/src/develop.rs:3991`](../ui/dr-ui/src/develop.rs#L3991), [`ui/dr-ui/src/develop.rs:4020`](../ui/dr-ui/src/develop.rs#L4020), [`ui/dr-ui/src/export.rs:750`](../ui/dr-ui/src/export.rs#L750), [`ui/dr-ui/src/lib.rs:1038`](../ui/dr-ui/src/lib.rs#L1038), [`ui/dr-ui/src/lib.rs:1554`](../ui/dr-ui/src/lib.rs#L1554), [`ui/dr-ui/src/lib.rs:2044`](../ui/dr-ui/src/lib.rs#L2044), [`ui/dr-ui/src/lib.rs:2179`](../ui/dr-ui/src/lib.rs#L2179), [`ui/dr-ui/src/lib.rs:590`](../ui/dr-ui/src/lib.rs#L590), [`ui/dr-ui/src/library.rs:1903`](../ui/dr-ui/src/library.rs#L1903), [`ui/dr-ui/src/library.rs:492`](../ui/dr-ui/src/library.rs#L492), [`ui/dr-ui/src/library.rs:539`](../ui/dr-ui/src/library.rs#L539), [`ui/dr-ui/src/library.rs:576`](../ui/dr-ui/src/library.rs#L576), [`ui/dr-ui/src/library.rs:823`](../ui/dr-ui/src/library.rs#L823), [`ui/dr-ui/src/library_ui.rs:5313`](../ui/dr-ui/src/library_ui.rs#L5313), [`ui/dr-ui/src/sidecar_cache.rs:1`](../ui/dr-ui/src/sidecar_cache.rs#L1) | +| FR-CAT-9 | [`core/dr-catalog/src/cache.rs:1`](../core/dr-catalog/src/cache.rs#L1), [`core/dr-catalog/src/scan.rs:1`](../core/dr-catalog/src/scan.rs#L1), [`core/dr-catalog/src/schema.rs:725`](../core/dr-catalog/src/schema.rs#L725), [`core/dr-catalog/src/walk.rs:1022`](../core/dr-catalog/src/walk.rs#L1022), [`core/dr-catalog/src/walk.rs:162`](../core/dr-catalog/src/walk.rs#L162), [`core/dr-catalog/src/walk.rs:1`](../core/dr-catalog/src/walk.rs#L1), [`core/dr-catalog/src/walk.rs:435`](../core/dr-catalog/src/walk.rs#L435), [`core/dr-catalog/src/walk.rs:728`](../core/dr-catalog/src/walk.rs#L728), [`core/dr-sync-nextcloud/src/desktop_client.rs:30`](../core/dr-sync-nextcloud/src/desktop_client.rs#L30), [`core/dr-sync/src/error.rs:113`](../core/dr-sync/src/error.rs#L113), [`core/dr-sync/src/reachability.rs:1`](../core/dr-sync/src/reachability.rs#L1), [`core/dr-sync/src/scan.rs:175`](../core/dr-sync/src/scan.rs#L175), [`core/dr-sync/src/scan.rs:464`](../core/dr-sync/src/scan.rs#L464), [`core/dr-types/src/lib.rs:120`](../core/dr-types/src/lib.rs#L120), [`ui/dr-ui/src/develop.rs:3378`](../ui/dr-ui/src/develop.rs#L3378), [`ui/dr-ui/src/develop.rs:3421`](../ui/dr-ui/src/develop.rs#L3421), [`ui/dr-ui/src/library.rs:1222`](../ui/dr-ui/src/library.rs#L1222), [`ui/dr-ui/src/library.rs:1275`](../ui/dr-ui/src/library.rs#L1275), [`ui/dr-ui/src/library.rs:1306`](../ui/dr-ui/src/library.rs#L1306), [`ui/dr-ui/src/library.rs:1411`](../ui/dr-ui/src/library.rs#L1411), [`ui/dr-ui/src/library.rs:161`](../ui/dr-ui/src/library.rs#L161), [`ui/dr-ui/src/library.rs:1863`](../ui/dr-ui/src/library.rs#L1863), [`ui/dr-ui/src/library.rs:1939`](../ui/dr-ui/src/library.rs#L1939), [`ui/dr-ui/src/library.rs:266`](../ui/dr-ui/src/library.rs#L266), [`ui/dr-ui/src/library.rs:4666`](../ui/dr-ui/src/library.rs#L4666), [`ui/dr-ui/src/library.rs:576`](../ui/dr-ui/src/library.rs#L576), [`ui/dr-ui/src/library.rs:807`](../ui/dr-ui/src/library.rs#L807), [`ui/dr-ui/src/library.rs:823`](../ui/dr-ui/src/library.rs#L823), [`ui/dr-ui/src/library.rs:877`](../ui/dr-ui/src/library.rs#L877), [`ui/dr-ui/src/library_ui.rs:1241`](../ui/dr-ui/src/library_ui.rs#L1241), [`ui/dr-ui/src/library_ui.rs:1832`](../ui/dr-ui/src/library_ui.rs#L1832), [`ui/dr-ui/src/library_ui.rs:1876`](../ui/dr-ui/src/library_ui.rs#L1876), [`ui/dr-ui/src/library_ui.rs:1892`](../ui/dr-ui/src/library_ui.rs#L1892), [`ui/dr-ui/src/library_ui.rs:1986`](../ui/dr-ui/src/library_ui.rs#L1986), [`ui/dr-ui/src/library_ui.rs:237`](../ui/dr-ui/src/library_ui.rs#L237), [`ui/dr-ui/src/library_ui.rs:2706`](../ui/dr-ui/src/library_ui.rs#L2706), [`ui/dr-ui/src/library_ui.rs:270`](../ui/dr-ui/src/library_ui.rs#L270), [`ui/dr-ui/src/library_ui.rs:278`](../ui/dr-ui/src/library_ui.rs#L278), [`ui/dr-ui/src/library_ui.rs:3144`](../ui/dr-ui/src/library_ui.rs#L3144), [`ui/dr-ui/src/library_ui.rs:3366`](../ui/dr-ui/src/library_ui.rs#L3366), [`ui/dr-ui/src/library_ui.rs:3644`](../ui/dr-ui/src/library_ui.rs#L3644), [`ui/dr-ui/src/library_ui.rs:3732`](../ui/dr-ui/src/library_ui.rs#L3732), [`ui/dr-ui/src/library_ui.rs:3914`](../ui/dr-ui/src/library_ui.rs#L3914), [`ui/dr-ui/src/library_ui.rs:4028`](../ui/dr-ui/src/library_ui.rs#L4028), [`ui/dr-ui/src/library_ui.rs:469`](../ui/dr-ui/src/library_ui.rs#L469), [`ui/dr-ui/src/library_ui.rs:532`](../ui/dr-ui/src/library_ui.rs#L532), [`ui/dr-ui/src/library_ui.rs:5786`](../ui/dr-ui/src/library_ui.rs#L5786), [`ui/dr-ui/src/library_ui.rs:5901`](../ui/dr-ui/src/library_ui.rs#L5901), [`ui/dr-ui/src/presets.rs:446`](../ui/dr-ui/src/presets.rs#L446), [`ui/dr-ui/src/presets.rs:458`](../ui/dr-ui/src/presets.rs#L458), [`ui/dr-ui/src/sidecar_cache.rs:1`](../ui/dr-ui/src/sidecar_cache.rs#L1), [`ui/dr-ui/tests/export_ignores_the_viewport.rs:1`](../ui/dr-ui/tests/export_ignores_the_viewport.rs#L1) | | FR-CULL-1 | [`core/dr-decode/src/preview.rs:121`](../core/dr-decode/src/preview.rs#L121) | | FR-CULL-10 | [`core/dr-catalog/src/faces.rs:1`](../core/dr-catalog/src/faces.rs#L1), [`core/dr-catalog/src/schema.rs:376`](../core/dr-catalog/src/schema.rs#L376), [`core/dr-catalog/src/schema.rs:554`](../core/dr-catalog/src/schema.rs#L554), [`core/dr-face/src/assign.rs:1`](../core/dr-face/src/assign.rs#L1), [`core/dr-face/src/neighbours.rs:1`](../core/dr-face/src/neighbours.rs#L1), [`core/dr-types/src/settings.rs:117`](../core/dr-types/src/settings.rs#L117), [`ui/dr-ui/src/develop.rs:120`](../ui/dr-ui/src/develop.rs#L120), [`ui/dr-ui/src/develop.rs:129`](../ui/dr-ui/src/develop.rs#L129), [`ui/dr-ui/src/develop.rs:195`](../ui/dr-ui/src/develop.rs#L195), [`ui/dr-ui/src/develop.rs:2011`](../ui/dr-ui/src/develop.rs#L2011), [`ui/dr-ui/src/develop.rs:688`](../ui/dr-ui/src/develop.rs#L688), [`ui/dr-ui/src/faces.rs:1`](../ui/dr-ui/src/faces.rs#L1), [`ui/dr-ui/src/identity.rs:1`](../ui/dr-ui/src/identity.rs#L1), [`ui/dr-ui/src/identity_ui.rs:1`](../ui/dr-ui/src/identity_ui.rs#L1), [`ui/dr-ui/src/lib.rs:2151`](../ui/dr-ui/src/lib.rs#L2151), [`ui/dr-ui/ui/identity.slint:1`](../ui/dr-ui/ui/identity.slint#L1) | | FR-CULL-11 | [`core/dr-catalog/src/faces.rs:1`](../core/dr-catalog/src/faces.rs#L1), [`core/dr-catalog/src/schema.rs:554`](../core/dr-catalog/src/schema.rs#L554), [`ui/dr-ui/src/identity.rs:1`](../ui/dr-ui/src/identity.rs#L1), [`ui/dr-ui/src/identity_ui.rs:1`](../ui/dr-ui/src/identity_ui.rs#L1), [`ui/dr-ui/src/library.rs:287`](../ui/dr-ui/src/library.rs#L287), [`ui/dr-ui/src/library.rs:317`](../ui/dr-ui/src/library.rs#L317), [`ui/dr-ui/ui/identity.slint:1`](../ui/dr-ui/ui/identity.slint#L1) | | FR-CULL-12 | [`core/dr-catalog/src/faces.rs:1`](../core/dr-catalog/src/faces.rs#L1), [`core/dr-catalog/src/schema.rs:376`](../core/dr-catalog/src/schema.rs#L376), [`core/dr-catalog/src/schema.rs:554`](../core/dr-catalog/src/schema.rs#L554), [`ui/dr-ui/src/identity.rs:1`](../ui/dr-ui/src/identity.rs#L1), [`ui/dr-ui/ui/identity.slint:1`](../ui/dr-ui/ui/identity.slint#L1) | | FR-CULL-2 | [`core/dr-decode/src/locate.rs:1`](../core/dr-decode/src/locate.rs#L1), [`core/dr-decode/src/preview.rs:148`](../core/dr-decode/src/preview.rs#L148), [`ui/dr-ui/src/import.rs:463`](../ui/dr-ui/src/import.rs#L463) | -| FR-CULL-3 | [`core/dr-gpu/src/focus.rs:154`](../core/dr-gpu/src/focus.rs#L154), [`core/dr-gpu/src/focus.rs:186`](../core/dr-gpu/src/focus.rs#L186), [`core/dr-gpu/src/focus.rs:1`](../core/dr-gpu/src/focus.rs#L1), [`core/dr-gpu/src/focus.rs:317`](../core/dr-gpu/src/focus.rs#L317), [`core/dr-gpu/src/raw_histogram.rs:129`](../core/dr-gpu/src/raw_histogram.rs#L129), [`core/dr-gpu/src/raw_histogram.rs:1`](../core/dr-gpu/src/raw_histogram.rs#L1), [`core/dr-gpu/src/raw_histogram.rs:272`](../core/dr-gpu/src/raw_histogram.rs#L272), [`core/dr-gpu/src/raw_histogram.rs:407`](../core/dr-gpu/src/raw_histogram.rs#L407), [`core/dr-gpu/src/shaders/focus_peak.wgsl:1`](../core/dr-gpu/src/shaders/focus_peak.wgsl#L1), [`core/dr-gpu/src/shaders/raw_histogram.wgsl:1`](../core/dr-gpu/src/shaders/raw_histogram.wgsl#L1), [`ui/dr-ui/src/develop.rs:3106`](../ui/dr-ui/src/develop.rs#L3106), [`ui/dr-ui/src/develop.rs:3119`](../ui/dr-ui/src/develop.rs#L3119), [`ui/dr-ui/src/develop.rs:3164`](../ui/dr-ui/src/develop.rs#L3164), [`ui/dr-ui/src/develop.rs:3175`](../ui/dr-ui/src/develop.rs#L3175), [`ui/dr-ui/src/develop.rs:3181`](../ui/dr-ui/src/develop.rs#L3181), [`ui/dr-ui/src/develop.rs:3198`](../ui/dr-ui/src/develop.rs#L3198), [`ui/dr-ui/src/develop.rs:6081`](../ui/dr-ui/src/develop.rs#L6081), [`ui/dr-ui/src/develop.rs:6145`](../ui/dr-ui/src/develop.rs#L6145), [`ui/dr-ui/src/develop.rs:6168`](../ui/dr-ui/src/develop.rs#L6168), [`ui/dr-ui/src/develop.rs:726`](../ui/dr-ui/src/develop.rs#L726), [`ui/dr-ui/src/develop.rs:746`](../ui/dr-ui/src/develop.rs#L746), [`ui/dr-ui/src/develop.rs:752`](../ui/dr-ui/src/develop.rs#L752), [`ui/dr-ui/src/histogram.rs:1`](../ui/dr-ui/src/histogram.rs#L1), [`ui/dr-ui/src/histogram.rs:208`](../ui/dr-ui/src/histogram.rs#L208), [`ui/dr-ui/src/histogram.rs:228`](../ui/dr-ui/src/histogram.rs#L228), [`ui/dr-ui/src/histogram.rs:272`](../ui/dr-ui/src/histogram.rs#L272), [`ui/dr-ui/src/histogram.rs:544`](../ui/dr-ui/src/histogram.rs#L544), [`ui/dr-ui/src/histogram.rs:565`](../ui/dr-ui/src/histogram.rs#L565), [`ui/dr-ui/src/histogram.rs:593`](../ui/dr-ui/src/histogram.rs#L593), [`ui/dr-ui/src/histogram.rs:621`](../ui/dr-ui/src/histogram.rs#L621), [`ui/dr-ui/src/histogram.rs:658`](../ui/dr-ui/src/histogram.rs#L658), [`ui/dr-ui/src/lib.rs:1593`](../ui/dr-ui/src/lib.rs#L1593), [`ui/dr-ui/src/lib.rs:1671`](../ui/dr-ui/src/lib.rs#L1671), [`ui/dr-ui/src/lib.rs:1770`](../ui/dr-ui/src/lib.rs#L1770), [`ui/dr-ui/src/lib.rs:1811`](../ui/dr-ui/src/lib.rs#L1811), [`ui/dr-ui/src/lib.rs:3061`](../ui/dr-ui/src/lib.rs#L3061), [`ui/dr-ui/src/lib.rs:350`](../ui/dr-ui/src/lib.rs#L350), [`ui/dr-ui/src/peaking.rs:1`](../ui/dr-ui/src/peaking.rs#L1), [`ui/dr-ui/ui/app.slint:1820`](../ui/dr-ui/ui/app.slint#L1820), [`ui/dr-ui/ui/app.slint:2398`](../ui/dr-ui/ui/app.slint#L2398), [`ui/dr-ui/ui/app.slint:89`](../ui/dr-ui/ui/app.slint#L89), [`ui/dr-ui/ui/peaking.slint:1`](../ui/dr-ui/ui/peaking.slint#L1), [`ui/dr-ui/ui/peaking.slint:25`](../ui/dr-ui/ui/peaking.slint#L25), [`ui/dr-ui/ui/peaking.slint:56`](../ui/dr-ui/ui/peaking.slint#L56) | +| FR-CULL-3 | [`core/dr-gpu/src/focus.rs:154`](../core/dr-gpu/src/focus.rs#L154), [`core/dr-gpu/src/focus.rs:186`](../core/dr-gpu/src/focus.rs#L186), [`core/dr-gpu/src/focus.rs:1`](../core/dr-gpu/src/focus.rs#L1), [`core/dr-gpu/src/focus.rs:317`](../core/dr-gpu/src/focus.rs#L317), [`core/dr-gpu/src/raw_histogram.rs:129`](../core/dr-gpu/src/raw_histogram.rs#L129), [`core/dr-gpu/src/raw_histogram.rs:1`](../core/dr-gpu/src/raw_histogram.rs#L1), [`core/dr-gpu/src/raw_histogram.rs:272`](../core/dr-gpu/src/raw_histogram.rs#L272), [`core/dr-gpu/src/raw_histogram.rs:407`](../core/dr-gpu/src/raw_histogram.rs#L407), [`core/dr-gpu/src/shaders/focus_peak.wgsl:1`](../core/dr-gpu/src/shaders/focus_peak.wgsl#L1), [`core/dr-gpu/src/shaders/raw_histogram.wgsl:1`](../core/dr-gpu/src/shaders/raw_histogram.wgsl#L1), [`ui/dr-ui/src/develop.rs:3106`](../ui/dr-ui/src/develop.rs#L3106), [`ui/dr-ui/src/develop.rs:3119`](../ui/dr-ui/src/develop.rs#L3119), [`ui/dr-ui/src/develop.rs:3164`](../ui/dr-ui/src/develop.rs#L3164), [`ui/dr-ui/src/develop.rs:3175`](../ui/dr-ui/src/develop.rs#L3175), [`ui/dr-ui/src/develop.rs:3181`](../ui/dr-ui/src/develop.rs#L3181), [`ui/dr-ui/src/develop.rs:3198`](../ui/dr-ui/src/develop.rs#L3198), [`ui/dr-ui/src/develop.rs:6118`](../ui/dr-ui/src/develop.rs#L6118), [`ui/dr-ui/src/develop.rs:6182`](../ui/dr-ui/src/develop.rs#L6182), [`ui/dr-ui/src/develop.rs:6205`](../ui/dr-ui/src/develop.rs#L6205), [`ui/dr-ui/src/develop.rs:726`](../ui/dr-ui/src/develop.rs#L726), [`ui/dr-ui/src/develop.rs:746`](../ui/dr-ui/src/develop.rs#L746), [`ui/dr-ui/src/develop.rs:752`](../ui/dr-ui/src/develop.rs#L752), [`ui/dr-ui/src/histogram.rs:1`](../ui/dr-ui/src/histogram.rs#L1), [`ui/dr-ui/src/histogram.rs:208`](../ui/dr-ui/src/histogram.rs#L208), [`ui/dr-ui/src/histogram.rs:228`](../ui/dr-ui/src/histogram.rs#L228), [`ui/dr-ui/src/histogram.rs:272`](../ui/dr-ui/src/histogram.rs#L272), [`ui/dr-ui/src/histogram.rs:544`](../ui/dr-ui/src/histogram.rs#L544), [`ui/dr-ui/src/histogram.rs:565`](../ui/dr-ui/src/histogram.rs#L565), [`ui/dr-ui/src/histogram.rs:593`](../ui/dr-ui/src/histogram.rs#L593), [`ui/dr-ui/src/histogram.rs:621`](../ui/dr-ui/src/histogram.rs#L621), [`ui/dr-ui/src/histogram.rs:658`](../ui/dr-ui/src/histogram.rs#L658), [`ui/dr-ui/src/lib.rs:1593`](../ui/dr-ui/src/lib.rs#L1593), [`ui/dr-ui/src/lib.rs:1671`](../ui/dr-ui/src/lib.rs#L1671), [`ui/dr-ui/src/lib.rs:1770`](../ui/dr-ui/src/lib.rs#L1770), [`ui/dr-ui/src/lib.rs:1811`](../ui/dr-ui/src/lib.rs#L1811), [`ui/dr-ui/src/lib.rs:3061`](../ui/dr-ui/src/lib.rs#L3061), [`ui/dr-ui/src/lib.rs:350`](../ui/dr-ui/src/lib.rs#L350), [`ui/dr-ui/src/peaking.rs:1`](../ui/dr-ui/src/peaking.rs#L1), [`ui/dr-ui/ui/app.slint:1820`](../ui/dr-ui/ui/app.slint#L1820), [`ui/dr-ui/ui/app.slint:2398`](../ui/dr-ui/ui/app.slint#L2398), [`ui/dr-ui/ui/app.slint:89`](../ui/dr-ui/ui/app.slint#L89), [`ui/dr-ui/ui/peaking.slint:1`](../ui/dr-ui/ui/peaking.slint#L1), [`ui/dr-ui/ui/peaking.slint:25`](../ui/dr-ui/ui/peaking.slint#L25), [`ui/dr-ui/ui/peaking.slint:56`](../ui/dr-ui/ui/peaking.slint#L56) | | FR-CULL-4 | [`core/dr-catalog/src/rating.rs:1`](../core/dr-catalog/src/rating.rs#L1), [`core/dr-pipeline/src/sidecar.rs:136`](../core/dr-pipeline/src/sidecar.rs#L136), [`ui/dr-ui/src/library.rs:246`](../ui/dr-ui/src/library.rs#L246), [`ui/dr-ui/src/library.rs:492`](../ui/dr-ui/src/library.rs#L492) | | FR-CULL-5 | [`core/dr-catalog/src/bursts.rs:1`](../core/dr-catalog/src/bursts.rs#L1), [`core/dr-catalog/src/schema.rs:419`](../core/dr-catalog/src/schema.rs#L419), [`ui/dr-ui/src/bursts.rs:1`](../ui/dr-ui/src/bursts.rs#L1), [`ui/dr-ui/src/library.rs:202`](../ui/dr-ui/src/library.rs#L202), [`ui/dr-ui/src/library.rs:5267`](../ui/dr-ui/src/library.rs#L5267) | | FR-CULL-8 | [`core/dr-catalog/src/face_shard.rs:1`](../core/dr-catalog/src/face_shard.rs#L1), [`core/dr-catalog/src/faces.rs:1`](../core/dr-catalog/src/faces.rs#L1), [`core/dr-catalog/src/schema.rs:487`](../core/dr-catalog/src/schema.rs#L487), [`core/dr-catalog/src/schema.rs:513`](../core/dr-catalog/src/schema.rs#L513), [`core/dr-catalog/src/schema.rs:554`](../core/dr-catalog/src/schema.rs#L554), [`core/dr-face/src/align.rs:291`](../core/dr-face/src/align.rs#L291), [`ui/dr-ui/examples/face_native.rs:1`](../ui/dr-ui/examples/face_native.rs#L1), [`ui/dr-ui/src/faces.rs:1`](../ui/dr-ui/src/faces.rs#L1), [`ui/dr-ui/src/faces.rs:330`](../ui/dr-ui/src/faces.rs#L330), [`ui/dr-ui/src/faces.rs:346`](../ui/dr-ui/src/faces.rs#L346), [`ui/dr-ui/src/identity_ui.rs:540`](../ui/dr-ui/src/identity_ui.rs#L540), [`ui/dr-ui/src/lib.rs:1212`](../ui/dr-ui/src/lib.rs#L1212), [`ui/dr-ui/src/library.rs:2965`](../ui/dr-ui/src/library.rs#L2965), [`ui/dr-ui/src/library.rs:3058`](../ui/dr-ui/src/library.rs#L3058), [`ui/dr-ui/src/library.rs:3279`](../ui/dr-ui/src/library.rs#L3279), [`ui/dr-ui/src/library.rs:3423`](../ui/dr-ui/src/library.rs#L3423), [`ui/dr-ui/src/library.rs:3462`](../ui/dr-ui/src/library.rs#L3462), [`ui/dr-ui/ui/settings.slint:419`](../ui/dr-ui/ui/settings.slint#L419), [`ui/dr-ui/ui/settings.slint:82`](../ui/dr-ui/ui/settings.slint#L82) | | FR-CULL-9 | [`core/dr-catalog/src/faces.rs:1`](../core/dr-catalog/src/faces.rs#L1), [`core/dr-catalog/src/schema.rs:554`](../core/dr-catalog/src/schema.rs#L554), [`core/dr-face/src/assign.rs:1`](../core/dr-face/src/assign.rs#L1), [`core/dr-face/src/neighbours.rs:1`](../core/dr-face/src/neighbours.rs#L1), [`core/dr-types/src/settings.rs:117`](../core/dr-types/src/settings.rs#L117), [`ui/dr-ui/src/faces.rs:1`](../ui/dr-ui/src/faces.rs#L1), [`ui/dr-ui/src/identity_ui.rs:1`](../ui/dr-ui/src/identity_ui.rs#L1), [`ui/dr-ui/ui/identity.slint:283`](../ui/dr-ui/ui/identity.slint#L283) | | FR-DEV-1 | [`core/dr-pipeline/src/graph.rs:1`](../core/dr-pipeline/src/graph.rs#L1), [`core/dr-pipeline/src/sidecar.rs:1`](../core/dr-pipeline/src/sidecar.rs#L1) | | FR-DEV-2 | [`core/dr-pipeline/src/operation.rs:389`](../core/dr-pipeline/src/operation.rs#L389) | -| FR-DEV-3 | [`core/dr-gpu/src/adjust.rs:2203`](../core/dr-gpu/src/adjust.rs#L2203), [`core/dr-gpu/src/adjust.rs:651`](../core/dr-gpu/src/adjust.rs#L651), [`core/dr-gpu/src/adjust.rs:770`](../core/dr-gpu/src/adjust.rs#L770), [`core/dr-gpu/src/adjust.rs:84`](../core/dr-gpu/src/adjust.rs#L84), [`core/dr-gpu/tests/tone_curve.rs:1`](../core/dr-gpu/tests/tone_curve.rs#L1), [`core/dr-pipeline/src/detail.rs:434`](../core/dr-pipeline/src/detail.rs#L434), [`core/dr-pipeline/src/detail.rs:524`](../core/dr-pipeline/src/detail.rs#L524), [`core/dr-pipeline/src/framing.rs:177`](../core/dr-pipeline/src/framing.rs#L177), [`core/dr-pipeline/src/framing.rs:234`](../core/dr-pipeline/src/framing.rs#L234), [`core/dr-pipeline/src/framing.rs:314`](../core/dr-pipeline/src/framing.rs#L314), [`core/dr-pipeline/src/framing.rs:488`](../core/dr-pipeline/src/framing.rs#L488), [`core/dr-pipeline/src/framing.rs:743`](../core/dr-pipeline/src/framing.rs#L743), [`core/dr-pipeline/src/graph.rs:170`](../core/dr-pipeline/src/graph.rs#L170), [`core/dr-pipeline/src/graph.rs:578`](../core/dr-pipeline/src/graph.rs#L578), [`core/dr-pipeline/src/mask.rs:134`](../core/dr-pipeline/src/mask.rs#L134), [`core/dr-pipeline/src/operation.rs:330`](../core/dr-pipeline/src/operation.rs#L330), [`core/dr-pipeline/src/operation.rs:516`](../core/dr-pipeline/src/operation.rs#L516), [`core/dr-pipeline/src/ops/capture_sharpen.rs:1`](../core/dr-pipeline/src/ops/capture_sharpen.rs#L1), [`core/dr-pipeline/src/ops/capture_sharpen.rs:210`](../core/dr-pipeline/src/ops/capture_sharpen.rs#L210), [`core/dr-pipeline/src/ops/curve.rs:100`](../core/dr-pipeline/src/ops/curve.rs#L100), [`core/dr-pipeline/src/ops/curve.rs:1`](../core/dr-pipeline/src/ops/curve.rs#L1), [`core/dr-pipeline/src/ops/curve.rs:219`](../core/dr-pipeline/src/ops/curve.rs#L219), [`core/dr-pipeline/src/ops/curve.rs:635`](../core/dr-pipeline/src/ops/curve.rs#L635), [`core/dr-pipeline/src/ops/local_contrast.rs:1`](../core/dr-pipeline/src/ops/local_contrast.rs#L1), [`core/dr-pipeline/src/ops/noise_reduction.rs:1`](../core/dr-pipeline/src/ops/noise_reduction.rs#L1), [`core/dr-pipeline/src/ops/noise_reduction.rs:273`](../core/dr-pipeline/src/ops/noise_reduction.rs#L273), [`core/dr-pipeline/src/sidecar.rs:157`](../core/dr-pipeline/src/sidecar.rs#L157), [`core/dr-pipeline/src/sidecar.rs:1669`](../core/dr-pipeline/src/sidecar.rs#L1669), [`core/dr-pipeline/src/sidecar.rs:1729`](../core/dr-pipeline/src/sidecar.rs#L1729), [`core/dr-pipeline/tests/tone_curve.rs:1`](../core/dr-pipeline/tests/tone_curve.rs#L1), [`core/dr-segment/src/refine.rs:442`](../core/dr-segment/src/refine.rs#L442), [`ui/dr-ui/src/develop.rs:102`](../ui/dr-ui/src/develop.rs#L102), [`ui/dr-ui/src/develop.rs:1472`](../ui/dr-ui/src/develop.rs#L1472), [`ui/dr-ui/src/develop.rs:164`](../ui/dr-ui/src/develop.rs#L164), [`ui/dr-ui/src/develop.rs:1993`](../ui/dr-ui/src/develop.rs#L1993), [`ui/dr-ui/src/develop.rs:2011`](../ui/dr-ui/src/develop.rs#L2011), [`ui/dr-ui/src/develop.rs:2025`](../ui/dr-ui/src/develop.rs#L2025), [`ui/dr-ui/src/develop.rs:2047`](../ui/dr-ui/src/develop.rs#L2047), [`ui/dr-ui/src/develop.rs:2193`](../ui/dr-ui/src/develop.rs#L2193), [`ui/dr-ui/src/develop.rs:2291`](../ui/dr-ui/src/develop.rs#L2291), [`ui/dr-ui/src/develop.rs:327`](../ui/dr-ui/src/develop.rs#L327), [`ui/dr-ui/src/develop.rs:364`](../ui/dr-ui/src/develop.rs#L364), [`ui/dr-ui/src/develop.rs:3652`](../ui/dr-ui/src/develop.rs#L3652), [`ui/dr-ui/src/develop.rs:3682`](../ui/dr-ui/src/develop.rs#L3682), [`ui/dr-ui/src/develop.rs:3748`](../ui/dr-ui/src/develop.rs#L3748), [`ui/dr-ui/src/develop.rs:3762`](../ui/dr-ui/src/develop.rs#L3762), [`ui/dr-ui/src/develop.rs:3954`](../ui/dr-ui/src/develop.rs#L3954), [`ui/dr-ui/src/develop.rs:4614`](../ui/dr-ui/src/develop.rs#L4614), [`ui/dr-ui/src/develop.rs:4668`](../ui/dr-ui/src/develop.rs#L4668), [`ui/dr-ui/src/develop.rs:4712`](../ui/dr-ui/src/develop.rs#L4712), [`ui/dr-ui/src/develop.rs:4762`](../ui/dr-ui/src/develop.rs#L4762), [`ui/dr-ui/src/develop.rs:587`](../ui/dr-ui/src/develop.rs#L587), [`ui/dr-ui/src/develop.rs:648`](../ui/dr-ui/src/develop.rs#L648), [`ui/dr-ui/src/develop.rs:766`](../ui/dr-ui/src/develop.rs#L766), [`ui/dr-ui/src/develop.rs:813`](../ui/dr-ui/src/develop.rs#L813), [`ui/dr-ui/src/develop.rs:842`](../ui/dr-ui/src/develop.rs#L842), [`ui/dr-ui/src/lib.rs:1652`](../ui/dr-ui/src/lib.rs#L1652), [`ui/dr-ui/src/lib.rs:2454`](../ui/dr-ui/src/lib.rs#L2454), [`ui/dr-ui/src/lib.rs:2650`](../ui/dr-ui/src/lib.rs#L2650), [`ui/dr-ui/src/lib.rs:2822`](../ui/dr-ui/src/lib.rs#L2822), [`ui/dr-ui/src/lib.rs:2886`](../ui/dr-ui/src/lib.rs#L2886), [`ui/dr-ui/src/lib.rs:2940`](../ui/dr-ui/src/lib.rs#L2940), [`ui/dr-ui/src/lib.rs:356`](../ui/dr-ui/src/lib.rs#L356), [`ui/dr-ui/src/lib.rs:399`](../ui/dr-ui/src/lib.rs#L399), [`ui/dr-ui/src/lib.rs:422`](../ui/dr-ui/src/lib.rs#L422), [`ui/dr-ui/src/library.rs:539`](../ui/dr-ui/src/library.rs#L539), [`ui/dr-ui/src/masks_ui.rs:249`](../ui/dr-ui/src/masks_ui.rs#L249), [`ui/dr-ui/src/masks_ui.rs:41`](../ui/dr-ui/src/masks_ui.rs#L41), [`ui/dr-ui/src/masks_ui.rs:884`](../ui/dr-ui/src/masks_ui.rs#L884), [`ui/dr-ui/src/masks_ui.rs:998`](../ui/dr-ui/src/masks_ui.rs#L998), [`ui/dr-ui/src/segmentation.rs:305`](../ui/dr-ui/src/segmentation.rs#L305), [`ui/dr-ui/src/segmentation.rs:321`](../ui/dr-ui/src/segmentation.rs#L321), [`ui/dr-ui/src/segmentation.rs:451`](../ui/dr-ui/src/segmentation.rs#L451), [`ui/dr-ui/src/segmentation.rs:479`](../ui/dr-ui/src/segmentation.rs#L479), [`ui/dr-ui/ui/adjust.slint:547`](../ui/dr-ui/ui/adjust.slint#L547), [`ui/dr-ui/ui/adjust.slint:666`](../ui/dr-ui/ui/adjust.slint#L666), [`ui/dr-ui/ui/app.slint:150`](../ui/dr-ui/ui/app.slint#L150), [`ui/dr-ui/ui/app.slint:196`](../ui/dr-ui/ui/app.slint#L196), [`ui/dr-ui/ui/app.slint:2022`](../ui/dr-ui/ui/app.slint#L2022), [`ui/dr-ui/ui/app.slint:960`](../ui/dr-ui/ui/app.slint#L960), [`ui/dr-ui/ui/masks.slint:611`](../ui/dr-ui/ui/masks.slint#L611) | -| FR-DEV-3a | [`core/dr-pipeline/ops/exposure.yaml:1`](../core/dr-pipeline/ops/exposure.yaml#L1), [`core/dr-pipeline/src/descriptor.rs:194`](../core/dr-pipeline/src/descriptor.rs#L194), [`core/dr-pipeline/src/descriptor.rs:234`](../core/dr-pipeline/src/descriptor.rs#L234), [`core/dr-pipeline/src/descriptor.rs:258`](../core/dr-pipeline/src/descriptor.rs#L258), [`core/dr-pipeline/src/descriptor.rs:313`](../core/dr-pipeline/src/descriptor.rs#L313), [`core/dr-pipeline/src/framing.rs:385`](../core/dr-pipeline/src/framing.rs#L385), [`core/dr-pipeline/src/graph.rs:24`](../core/dr-pipeline/src/graph.rs#L24), [`core/dr-pipeline/src/graph.rs:251`](../core/dr-pipeline/src/graph.rs#L251), [`core/dr-pipeline/src/graph.rs:46`](../core/dr-pipeline/src/graph.rs#L46), [`core/dr-pipeline/src/graph.rs:59`](../core/dr-pipeline/src/graph.rs#L59), [`core/dr-pipeline/src/mask.rs:1024`](../core/dr-pipeline/src/mask.rs#L1024), [`core/dr-pipeline/src/operation.rs:232`](../core/dr-pipeline/src/operation.rs#L232), [`core/dr-pipeline/src/operation.rs:365`](../core/dr-pipeline/src/operation.rs#L365), [`core/dr-pipeline/src/ops/curve.rs:319`](../core/dr-pipeline/src/ops/curve.rs#L319), [`ui/dr-ui/src/develop.rs:1369`](../ui/dr-ui/src/develop.rs#L1369), [`ui/dr-ui/src/lib.rs:705`](../ui/dr-ui/src/lib.rs#L705), [`ui/dr-ui/tests/ui_names_no_operation.rs:1`](../ui/dr-ui/tests/ui_names_no_operation.rs#L1) | -| FR-DEV-3b | [`core/dr-pipeline/src/descriptor.rs:258`](../core/dr-pipeline/src/descriptor.rs#L258), [`core/dr-pipeline/src/framing.rs:385`](../core/dr-pipeline/src/framing.rs#L385), [`core/dr-pipeline/src/graph.rs:59`](../core/dr-pipeline/src/graph.rs#L59), [`core/dr-pipeline/src/operation.rs:365`](../core/dr-pipeline/src/operation.rs#L365) | -| FR-DEV-3c | [`core/dr-pipeline/ops/exposure.yaml:1`](../core/dr-pipeline/ops/exposure.yaml#L1), [`core/dr-pipeline/src/graph.rs:251`](../core/dr-pipeline/src/graph.rs#L251), [`core/dr-pipeline/src/graph.rs:46`](../core/dr-pipeline/src/graph.rs#L46), [`core/dr-pipeline/src/mask.rs:1024`](../core/dr-pipeline/src/mask.rs#L1024), [`ui/dr-ui/src/develop.rs:5341`](../ui/dr-ui/src/develop.rs#L5341) | +| FR-DEV-3 | [`core/dr-gpu/src/adjust.rs:2203`](../core/dr-gpu/src/adjust.rs#L2203), [`core/dr-gpu/src/adjust.rs:651`](../core/dr-gpu/src/adjust.rs#L651), [`core/dr-gpu/src/adjust.rs:770`](../core/dr-gpu/src/adjust.rs#L770), [`core/dr-gpu/src/adjust.rs:84`](../core/dr-gpu/src/adjust.rs#L84), [`core/dr-gpu/tests/tone_curve.rs:1`](../core/dr-gpu/tests/tone_curve.rs#L1), [`core/dr-pipeline/src/detail.rs:434`](../core/dr-pipeline/src/detail.rs#L434), [`core/dr-pipeline/src/detail.rs:524`](../core/dr-pipeline/src/detail.rs#L524), [`core/dr-pipeline/src/framing.rs:177`](../core/dr-pipeline/src/framing.rs#L177), [`core/dr-pipeline/src/framing.rs:234`](../core/dr-pipeline/src/framing.rs#L234), [`core/dr-pipeline/src/framing.rs:314`](../core/dr-pipeline/src/framing.rs#L314), [`core/dr-pipeline/src/framing.rs:498`](../core/dr-pipeline/src/framing.rs#L498), [`core/dr-pipeline/src/framing.rs:753`](../core/dr-pipeline/src/framing.rs#L753), [`core/dr-pipeline/src/graph.rs:170`](../core/dr-pipeline/src/graph.rs#L170), [`core/dr-pipeline/src/graph.rs:578`](../core/dr-pipeline/src/graph.rs#L578), [`core/dr-pipeline/src/mask.rs:134`](../core/dr-pipeline/src/mask.rs#L134), [`core/dr-pipeline/src/operation.rs:330`](../core/dr-pipeline/src/operation.rs#L330), [`core/dr-pipeline/src/operation.rs:516`](../core/dr-pipeline/src/operation.rs#L516), [`core/dr-pipeline/src/ops/capture_sharpen.rs:1`](../core/dr-pipeline/src/ops/capture_sharpen.rs#L1), [`core/dr-pipeline/src/ops/capture_sharpen.rs:210`](../core/dr-pipeline/src/ops/capture_sharpen.rs#L210), [`core/dr-pipeline/src/ops/curve.rs:100`](../core/dr-pipeline/src/ops/curve.rs#L100), [`core/dr-pipeline/src/ops/curve.rs:1`](../core/dr-pipeline/src/ops/curve.rs#L1), [`core/dr-pipeline/src/ops/curve.rs:219`](../core/dr-pipeline/src/ops/curve.rs#L219), [`core/dr-pipeline/src/ops/curve.rs:635`](../core/dr-pipeline/src/ops/curve.rs#L635), [`core/dr-pipeline/src/ops/local_contrast.rs:1`](../core/dr-pipeline/src/ops/local_contrast.rs#L1), [`core/dr-pipeline/src/ops/noise_reduction.rs:1`](../core/dr-pipeline/src/ops/noise_reduction.rs#L1), [`core/dr-pipeline/src/ops/noise_reduction.rs:273`](../core/dr-pipeline/src/ops/noise_reduction.rs#L273), [`core/dr-pipeline/src/sidecar.rs:157`](../core/dr-pipeline/src/sidecar.rs#L157), [`core/dr-pipeline/src/sidecar.rs:1669`](../core/dr-pipeline/src/sidecar.rs#L1669), [`core/dr-pipeline/src/sidecar.rs:1729`](../core/dr-pipeline/src/sidecar.rs#L1729), [`core/dr-pipeline/tests/tone_curve.rs:1`](../core/dr-pipeline/tests/tone_curve.rs#L1), [`core/dr-segment/src/refine.rs:442`](../core/dr-segment/src/refine.rs#L442), [`ui/dr-ui/src/develop.rs:102`](../ui/dr-ui/src/develop.rs#L102), [`ui/dr-ui/src/develop.rs:1472`](../ui/dr-ui/src/develop.rs#L1472), [`ui/dr-ui/src/develop.rs:164`](../ui/dr-ui/src/develop.rs#L164), [`ui/dr-ui/src/develop.rs:1993`](../ui/dr-ui/src/develop.rs#L1993), [`ui/dr-ui/src/develop.rs:2011`](../ui/dr-ui/src/develop.rs#L2011), [`ui/dr-ui/src/develop.rs:2025`](../ui/dr-ui/src/develop.rs#L2025), [`ui/dr-ui/src/develop.rs:2047`](../ui/dr-ui/src/develop.rs#L2047), [`ui/dr-ui/src/develop.rs:2193`](../ui/dr-ui/src/develop.rs#L2193), [`ui/dr-ui/src/develop.rs:2291`](../ui/dr-ui/src/develop.rs#L2291), [`ui/dr-ui/src/develop.rs:327`](../ui/dr-ui/src/develop.rs#L327), [`ui/dr-ui/src/develop.rs:364`](../ui/dr-ui/src/develop.rs#L364), [`ui/dr-ui/src/develop.rs:3689`](../ui/dr-ui/src/develop.rs#L3689), [`ui/dr-ui/src/develop.rs:3719`](../ui/dr-ui/src/develop.rs#L3719), [`ui/dr-ui/src/develop.rs:3785`](../ui/dr-ui/src/develop.rs#L3785), [`ui/dr-ui/src/develop.rs:3799`](../ui/dr-ui/src/develop.rs#L3799), [`ui/dr-ui/src/develop.rs:3991`](../ui/dr-ui/src/develop.rs#L3991), [`ui/dr-ui/src/develop.rs:4651`](../ui/dr-ui/src/develop.rs#L4651), [`ui/dr-ui/src/develop.rs:4705`](../ui/dr-ui/src/develop.rs#L4705), [`ui/dr-ui/src/develop.rs:4749`](../ui/dr-ui/src/develop.rs#L4749), [`ui/dr-ui/src/develop.rs:4799`](../ui/dr-ui/src/develop.rs#L4799), [`ui/dr-ui/src/develop.rs:587`](../ui/dr-ui/src/develop.rs#L587), [`ui/dr-ui/src/develop.rs:648`](../ui/dr-ui/src/develop.rs#L648), [`ui/dr-ui/src/develop.rs:766`](../ui/dr-ui/src/develop.rs#L766), [`ui/dr-ui/src/develop.rs:813`](../ui/dr-ui/src/develop.rs#L813), [`ui/dr-ui/src/develop.rs:842`](../ui/dr-ui/src/develop.rs#L842), [`ui/dr-ui/src/lib.rs:1652`](../ui/dr-ui/src/lib.rs#L1652), [`ui/dr-ui/src/lib.rs:2454`](../ui/dr-ui/src/lib.rs#L2454), [`ui/dr-ui/src/lib.rs:2650`](../ui/dr-ui/src/lib.rs#L2650), [`ui/dr-ui/src/lib.rs:2822`](../ui/dr-ui/src/lib.rs#L2822), [`ui/dr-ui/src/lib.rs:2886`](../ui/dr-ui/src/lib.rs#L2886), [`ui/dr-ui/src/lib.rs:2940`](../ui/dr-ui/src/lib.rs#L2940), [`ui/dr-ui/src/lib.rs:356`](../ui/dr-ui/src/lib.rs#L356), [`ui/dr-ui/src/lib.rs:399`](../ui/dr-ui/src/lib.rs#L399), [`ui/dr-ui/src/lib.rs:422`](../ui/dr-ui/src/lib.rs#L422), [`ui/dr-ui/src/library.rs:539`](../ui/dr-ui/src/library.rs#L539), [`ui/dr-ui/src/masks_ui.rs:249`](../ui/dr-ui/src/masks_ui.rs#L249), [`ui/dr-ui/src/masks_ui.rs:41`](../ui/dr-ui/src/masks_ui.rs#L41), [`ui/dr-ui/src/masks_ui.rs:884`](../ui/dr-ui/src/masks_ui.rs#L884), [`ui/dr-ui/src/masks_ui.rs:998`](../ui/dr-ui/src/masks_ui.rs#L998), [`ui/dr-ui/src/segmentation.rs:305`](../ui/dr-ui/src/segmentation.rs#L305), [`ui/dr-ui/src/segmentation.rs:321`](../ui/dr-ui/src/segmentation.rs#L321), [`ui/dr-ui/src/segmentation.rs:451`](../ui/dr-ui/src/segmentation.rs#L451), [`ui/dr-ui/src/segmentation.rs:479`](../ui/dr-ui/src/segmentation.rs#L479), [`ui/dr-ui/ui/adjust.slint:547`](../ui/dr-ui/ui/adjust.slint#L547), [`ui/dr-ui/ui/adjust.slint:666`](../ui/dr-ui/ui/adjust.slint#L666), [`ui/dr-ui/ui/app.slint:150`](../ui/dr-ui/ui/app.slint#L150), [`ui/dr-ui/ui/app.slint:196`](../ui/dr-ui/ui/app.slint#L196), [`ui/dr-ui/ui/app.slint:2022`](../ui/dr-ui/ui/app.slint#L2022), [`ui/dr-ui/ui/app.slint:960`](../ui/dr-ui/ui/app.slint#L960), [`ui/dr-ui/ui/masks.slint:611`](../ui/dr-ui/ui/masks.slint#L611) | +| FR-DEV-3a | [`core/dr-pipeline/ops/exposure.yaml:1`](../core/dr-pipeline/ops/exposure.yaml#L1), [`core/dr-pipeline/src/descriptor.rs:194`](../core/dr-pipeline/src/descriptor.rs#L194), [`core/dr-pipeline/src/descriptor.rs:234`](../core/dr-pipeline/src/descriptor.rs#L234), [`core/dr-pipeline/src/descriptor.rs:258`](../core/dr-pipeline/src/descriptor.rs#L258), [`core/dr-pipeline/src/descriptor.rs:313`](../core/dr-pipeline/src/descriptor.rs#L313), [`core/dr-pipeline/src/framing.rs:395`](../core/dr-pipeline/src/framing.rs#L395), [`core/dr-pipeline/src/graph.rs:24`](../core/dr-pipeline/src/graph.rs#L24), [`core/dr-pipeline/src/graph.rs:251`](../core/dr-pipeline/src/graph.rs#L251), [`core/dr-pipeline/src/graph.rs:46`](../core/dr-pipeline/src/graph.rs#L46), [`core/dr-pipeline/src/graph.rs:59`](../core/dr-pipeline/src/graph.rs#L59), [`core/dr-pipeline/src/mask.rs:1024`](../core/dr-pipeline/src/mask.rs#L1024), [`core/dr-pipeline/src/operation.rs:232`](../core/dr-pipeline/src/operation.rs#L232), [`core/dr-pipeline/src/operation.rs:365`](../core/dr-pipeline/src/operation.rs#L365), [`core/dr-pipeline/src/ops/curve.rs:319`](../core/dr-pipeline/src/ops/curve.rs#L319), [`ui/dr-ui/src/develop.rs:1369`](../ui/dr-ui/src/develop.rs#L1369), [`ui/dr-ui/src/lib.rs:705`](../ui/dr-ui/src/lib.rs#L705), [`ui/dr-ui/tests/ui_names_no_operation.rs:1`](../ui/dr-ui/tests/ui_names_no_operation.rs#L1) | +| FR-DEV-3b | [`core/dr-pipeline/src/descriptor.rs:258`](../core/dr-pipeline/src/descriptor.rs#L258), [`core/dr-pipeline/src/framing.rs:395`](../core/dr-pipeline/src/framing.rs#L395), [`core/dr-pipeline/src/graph.rs:59`](../core/dr-pipeline/src/graph.rs#L59), [`core/dr-pipeline/src/operation.rs:365`](../core/dr-pipeline/src/operation.rs#L365) | +| FR-DEV-3c | [`core/dr-pipeline/ops/exposure.yaml:1`](../core/dr-pipeline/ops/exposure.yaml#L1), [`core/dr-pipeline/src/graph.rs:251`](../core/dr-pipeline/src/graph.rs#L251), [`core/dr-pipeline/src/graph.rs:46`](../core/dr-pipeline/src/graph.rs#L46), [`core/dr-pipeline/src/mask.rs:1024`](../core/dr-pipeline/src/mask.rs#L1024), [`ui/dr-ui/src/develop.rs:5378`](../ui/dr-ui/src/develop.rs#L5378) | | FR-DEV-3d | [`core/dr-gpu/src/adjust.rs:104`](../core/dr-gpu/src/adjust.rs#L104), [`core/dr-gpu/src/adjust.rs:1079`](../core/dr-gpu/src/adjust.rs#L1079), [`core/dr-gpu/src/adjust.rs:770`](../core/dr-gpu/src/adjust.rs#L770), [`core/dr-gpu/src/adjust.rs:84`](../core/dr-gpu/src/adjust.rs#L84), [`core/dr-gpu/src/adjust.rs:986`](../core/dr-gpu/src/adjust.rs#L986), [`core/dr-gpu/tests/capture_sharpen.rs:434`](../core/dr-gpu/tests/capture_sharpen.rs#L434), [`core/dr-gpu/tests/detail_stage.rs:242`](../core/dr-gpu/tests/detail_stage.rs#L242), [`core/dr-gpu/tests/local_contrast.rs:558`](../core/dr-gpu/tests/local_contrast.rs#L558), [`core/dr-gpu/tests/noise_reduction.rs:556`](../core/dr-gpu/tests/noise_reduction.rs#L556), [`core/dr-pipeline/src/framing.rs:314`](../core/dr-pipeline/src/framing.rs#L314), [`core/dr-pipeline/src/graph.rs:617`](../core/dr-pipeline/src/graph.rs#L617), [`core/dr-pipeline/src/operation.rs:32`](../core/dr-pipeline/src/operation.rs#L32), [`core/dr-pipeline/src/operation.rs:389`](../core/dr-pipeline/src/operation.rs#L389), [`core/dr-pipeline/src/operation.rs:53`](../core/dr-pipeline/src/operation.rs#L53), [`core/dr-pipeline/src/operation.rs:71`](../core/dr-pipeline/src/operation.rs#L71) | | FR-DEV-3e | [`core/dr-decode/src/base_curve.rs:145`](../core/dr-decode/src/base_curve.rs#L145), [`core/dr-decode/src/base_curve.rs:158`](../core/dr-decode/src/base_curve.rs#L158), [`core/dr-decode/src/base_curve.rs:1`](../core/dr-decode/src/base_curve.rs#L1), [`core/dr-decode/src/base_curve.rs:267`](../core/dr-decode/src/base_curve.rs#L267), [`core/dr-decode/src/base_curve.rs:347`](../core/dr-decode/src/base_curve.rs#L347), [`core/dr-decode/src/base_curve.rs:55`](../core/dr-decode/src/base_curve.rs#L55), [`core/dr-decode/src/lib.rs:121`](../core/dr-decode/src/lib.rs#L121), [`core/dr-decode/src/lib.rs:708`](../core/dr-decode/src/lib.rs#L708), [`core/dr-decode/src/lib.rs:748`](../core/dr-decode/src/lib.rs#L748), [`core/dr-decode/src/profile.rs:102`](../core/dr-decode/src/profile.rs#L102), [`core/dr-decode/src/profile.rs:151`](../core/dr-decode/src/profile.rs#L151), [`core/dr-decode/src/profile.rs:1`](../core/dr-decode/src/profile.rs#L1), [`core/dr-decode/src/profile.rs:235`](../core/dr-decode/src/profile.rs#L235), [`core/dr-decode/src/profile.rs:286`](../core/dr-decode/src/profile.rs#L286), [`core/dr-decode/src/profile.rs:343`](../core/dr-decode/src/profile.rs#L343), [`core/dr-decode/src/profile.rs:458`](../core/dr-decode/src/profile.rs#L458), [`core/dr-decode/src/profile.rs:492`](../core/dr-decode/src/profile.rs#L492), [`core/dr-decode/src/profile.rs:630`](../core/dr-decode/src/profile.rs#L630), [`core/dr-gpu/src/adjust.rs:37`](../core/dr-gpu/src/adjust.rs#L37), [`core/dr-gpu/src/adjust.rs:967`](../core/dr-gpu/src/adjust.rs#L967), [`core/dr-gpu/src/demosaic.rs:121`](../core/dr-gpu/src/demosaic.rs#L121), [`core/dr-gpu/src/demosaic.rs:86`](../core/dr-gpu/src/demosaic.rs#L86), [`core/dr-gpu/tests/base_curve.rs:1`](../core/dr-gpu/tests/base_curve.rs#L1), [`core/dr-pipeline/src/operation.rs:1495`](../core/dr-pipeline/src/operation.rs#L1495), [`core/dr-pipeline/src/operation.rs:1576`](../core/dr-pipeline/src/operation.rs#L1576), [`core/dr-pipeline/src/operation.rs:1601`](../core/dr-pipeline/src/operation.rs#L1601), [`core/dr-pipeline/src/operation.rs:1616`](../core/dr-pipeline/src/operation.rs#L1616), [`core/dr-pipeline/src/operation.rs:1640`](../core/dr-pipeline/src/operation.rs#L1640), [`core/dr-pipeline/src/operation.rs:310`](../core/dr-pipeline/src/operation.rs#L310), [`core/dr-pipeline/src/operation.rs:440`](../core/dr-pipeline/src/operation.rs#L440), [`core/dr-pipeline/src/operation.rs:450`](../core/dr-pipeline/src/operation.rs#L450), [`core/dr-pipeline/src/operation.rs:600`](../core/dr-pipeline/src/operation.rs#L600) | -| FR-DEV-3f | [`core/dr-film/src/bake.rs:271`](../core/dr-film/src/bake.rs#L271), [`core/dr-film/src/bake.rs:62`](../core/dr-film/src/bake.rs#L62), [`core/dr-film/src/boolean_grain.rs:1`](../core/dr-film/src/boolean_grain.rs#L1), [`core/dr-film/src/boolean_grain.rs:78`](../core/dr-film/src/boolean_grain.rs#L78), [`core/dr-film/src/grain.rs:140`](../core/dr-film/src/grain.rs#L140), [`core/dr-film/src/grain.rs:1`](../core/dr-film/src/grain.rs#L1), [`core/dr-film/src/grain.rs:302`](../core/dr-film/src/grain.rs#L302), [`core/dr-film/src/grain.rs:79`](../core/dr-film/src/grain.rs#L79), [`core/dr-film/src/lib.rs:160`](../core/dr-film/src/lib.rs#L160), [`core/dr-film/src/lib.rs:1`](../core/dr-film/src/lib.rs#L1), [`core/dr-film/src/profile.rs:100`](../core/dr-film/src/profile.rs#L100), [`core/dr-film/src/profile.rs:142`](../core/dr-film/src/profile.rs#L142), [`core/dr-film/src/profile.rs:182`](../core/dr-film/src/profile.rs#L182), [`core/dr-film/src/profile.rs:259`](../core/dr-film/src/profile.rs#L259), [`core/dr-film/src/profile.rs:502`](../core/dr-film/src/profile.rs#L502), [`core/dr-film/src/profile.rs:73`](../core/dr-film/src/profile.rs#L73), [`core/dr-gpu/src/adjust.rs:139`](../core/dr-gpu/src/adjust.rs#L139), [`core/dr-gpu/src/adjust.rs:196`](../core/dr-gpu/src/adjust.rs#L196), [`core/dr-gpu/src/adjust.rs:357`](../core/dr-gpu/src/adjust.rs#L357), [`core/dr-gpu/src/adjust.rs:483`](../core/dr-gpu/src/adjust.rs#L483), [`core/dr-gpu/src/adjust.rs:77`](../core/dr-gpu/src/adjust.rs#L77), [`core/dr-gpu/tests/film_sim.rs:191`](../core/dr-gpu/tests/film_sim.rs#L191), [`core/dr-gpu/tests/film_sim.rs:1`](../core/dr-gpu/tests/film_sim.rs#L1), [`core/dr-pipeline/src/graph.rs:102`](../core/dr-pipeline/src/graph.rs#L102), [`core/dr-pipeline/src/graph.rs:125`](../core/dr-pipeline/src/graph.rs#L125), [`core/dr-pipeline/src/graph.rs:325`](../core/dr-pipeline/src/graph.rs#L325), [`core/dr-pipeline/src/operation.rs:1065`](../core/dr-pipeline/src/operation.rs#L1065), [`core/dr-pipeline/src/operation.rs:1094`](../core/dr-pipeline/src/operation.rs#L1094), [`core/dr-pipeline/src/operation.rs:1495`](../core/dr-pipeline/src/operation.rs#L1495), [`core/dr-pipeline/src/operation.rs:296`](../core/dr-pipeline/src/operation.rs#L296), [`core/dr-pipeline/src/operation.rs:310`](../core/dr-pipeline/src/operation.rs#L310), [`core/dr-pipeline/src/ops/film_sim.rs:129`](../core/dr-pipeline/src/ops/film_sim.rs#L129), [`core/dr-pipeline/src/ops/film_sim.rs:153`](../core/dr-pipeline/src/ops/film_sim.rs#L153), [`core/dr-pipeline/src/ops/film_sim.rs:1`](../core/dr-pipeline/src/ops/film_sim.rs#L1), [`core/dr-pipeline/src/ops/film_sim.rs:331`](../core/dr-pipeline/src/ops/film_sim.rs#L331), [`core/dr-pipeline/src/ops/film_sim.rs:43`](../core/dr-pipeline/src/ops/film_sim.rs#L43), [`core/dr-pipeline/src/ops/film_sim.rs:87`](../core/dr-pipeline/src/ops/film_sim.rs#L87), [`core/dr-pipeline/src/ops/film_sim.rs:92`](../core/dr-pipeline/src/ops/film_sim.rs#L92), [`core/dr-pipeline/src/sidecar.rs:112`](../core/dr-pipeline/src/sidecar.rs#L112), [`core/dr-pipeline/src/sidecar.rs:168`](../core/dr-pipeline/src/sidecar.rs#L168), [`core/dr-pipeline/src/sidecar.rs:2015`](../core/dr-pipeline/src/sidecar.rs#L2015), [`core/dr-pipeline/src/sidecar.rs:2091`](../core/dr-pipeline/src/sidecar.rs#L2091), [`core/dr-pipeline/src/sidecar.rs:534`](../core/dr-pipeline/src/sidecar.rs#L534), [`core/dr-pipeline/src/sidecar.rs:661`](../core/dr-pipeline/src/sidecar.rs#L661), [`core/dr-pipeline/src/sidecar.rs:793`](../core/dr-pipeline/src/sidecar.rs#L793), [`core/dr-pipeline/src/state.rs:100`](../core/dr-pipeline/src/state.rs#L100), [`core/dr-pipeline/src/state.rs:115`](../core/dr-pipeline/src/state.rs#L115), [`core/dr-pipeline/src/state.rs:60`](../core/dr-pipeline/src/state.rs#L60), [`ui/dr-ui/src/develop.rs:3396`](../ui/dr-ui/src/develop.rs#L3396), [`ui/dr-ui/src/develop.rs:3413`](../ui/dr-ui/src/develop.rs#L3413), [`ui/dr-ui/src/develop.rs:3425`](../ui/dr-ui/src/develop.rs#L3425), [`ui/dr-ui/src/develop.rs:3463`](../ui/dr-ui/src/develop.rs#L3463), [`ui/dr-ui/src/develop.rs:3472`](../ui/dr-ui/src/develop.rs#L3472), [`ui/dr-ui/src/develop.rs:3575`](../ui/dr-ui/src/develop.rs#L3575), [`ui/dr-ui/src/develop.rs:3991`](../ui/dr-ui/src/develop.rs#L3991), [`ui/dr-ui/src/develop.rs:4006`](../ui/dr-ui/src/develop.rs#L4006), [`ui/dr-ui/src/lib.rs:2428`](../ui/dr-ui/src/lib.rs#L2428), [`ui/dr-ui/src/lib.rs:638`](../ui/dr-ui/src/lib.rs#L638), [`ui/dr-ui/src/lib.rs:696`](../ui/dr-ui/src/lib.rs#L696), [`ui/dr-ui/src/library.rs:530`](../ui/dr-ui/src/library.rs#L530), [`ui/dr-ui/src/library.rs:778`](../ui/dr-ui/src/library.rs#L778), [`ui/dr-ui/src/presets.rs:395`](../ui/dr-ui/src/presets.rs#L395), [`ui/dr-ui/ui/adjust.slint:1072`](../ui/dr-ui/ui/adjust.slint#L1072), [`ui/dr-ui/ui/adjust.slint:996`](../ui/dr-ui/ui/adjust.slint#L996), [`ui/dr-ui/ui/app.slint:2595`](../ui/dr-ui/ui/app.slint#L2595), [`ui/dr-ui/ui/app.slint:688`](../ui/dr-ui/ui/app.slint#L688) | -| FR-DEV-3h | [`core/dr-decode/src/lib.rs:404`](../core/dr-decode/src/lib.rs#L404), [`core/dr-decode/src/preview.rs:29`](../core/dr-decode/src/preview.rs#L29), [`core/dr-pipeline/src/framing.rs:1050`](../core/dr-pipeline/src/framing.rs#L1050), [`core/dr-pipeline/src/framing.rs:328`](../core/dr-pipeline/src/framing.rs#L328), [`core/dr-pipeline/src/framing.rs:488`](../core/dr-pipeline/src/framing.rs#L488), [`core/dr-types/src/lib.rs:337`](../core/dr-types/src/lib.rs#L337), [`core/dr-types/src/lib.rs:445`](../core/dr-types/src/lib.rs#L445), [`core/dr-types/src/lib.rs:457`](../core/dr-types/src/lib.rs#L457), [`core/dr-types/src/lib.rs:473`](../core/dr-types/src/lib.rs#L473), [`ui/dr-ui/src/develop.rs:139`](../ui/dr-ui/src/develop.rs#L139), [`ui/dr-ui/src/develop.rs:2210`](../ui/dr-ui/src/develop.rs#L2210), [`ui/dr-ui/src/segmentation.rs:451`](../ui/dr-ui/src/segmentation.rs#L451) | +| FR-DEV-3f | [`core/dr-film/src/bake.rs:271`](../core/dr-film/src/bake.rs#L271), [`core/dr-film/src/bake.rs:62`](../core/dr-film/src/bake.rs#L62), [`core/dr-film/src/boolean_grain.rs:1`](../core/dr-film/src/boolean_grain.rs#L1), [`core/dr-film/src/boolean_grain.rs:78`](../core/dr-film/src/boolean_grain.rs#L78), [`core/dr-film/src/grain.rs:140`](../core/dr-film/src/grain.rs#L140), [`core/dr-film/src/grain.rs:1`](../core/dr-film/src/grain.rs#L1), [`core/dr-film/src/grain.rs:302`](../core/dr-film/src/grain.rs#L302), [`core/dr-film/src/grain.rs:79`](../core/dr-film/src/grain.rs#L79), [`core/dr-film/src/lib.rs:160`](../core/dr-film/src/lib.rs#L160), [`core/dr-film/src/lib.rs:1`](../core/dr-film/src/lib.rs#L1), [`core/dr-film/src/profile.rs:100`](../core/dr-film/src/profile.rs#L100), [`core/dr-film/src/profile.rs:142`](../core/dr-film/src/profile.rs#L142), [`core/dr-film/src/profile.rs:182`](../core/dr-film/src/profile.rs#L182), [`core/dr-film/src/profile.rs:259`](../core/dr-film/src/profile.rs#L259), [`core/dr-film/src/profile.rs:502`](../core/dr-film/src/profile.rs#L502), [`core/dr-film/src/profile.rs:73`](../core/dr-film/src/profile.rs#L73), [`core/dr-gpu/src/adjust.rs:139`](../core/dr-gpu/src/adjust.rs#L139), [`core/dr-gpu/src/adjust.rs:196`](../core/dr-gpu/src/adjust.rs#L196), [`core/dr-gpu/src/adjust.rs:357`](../core/dr-gpu/src/adjust.rs#L357), [`core/dr-gpu/src/adjust.rs:483`](../core/dr-gpu/src/adjust.rs#L483), [`core/dr-gpu/src/adjust.rs:77`](../core/dr-gpu/src/adjust.rs#L77), [`core/dr-gpu/tests/film_sim.rs:191`](../core/dr-gpu/tests/film_sim.rs#L191), [`core/dr-gpu/tests/film_sim.rs:1`](../core/dr-gpu/tests/film_sim.rs#L1), [`core/dr-pipeline/src/graph.rs:102`](../core/dr-pipeline/src/graph.rs#L102), [`core/dr-pipeline/src/graph.rs:125`](../core/dr-pipeline/src/graph.rs#L125), [`core/dr-pipeline/src/graph.rs:325`](../core/dr-pipeline/src/graph.rs#L325), [`core/dr-pipeline/src/operation.rs:1065`](../core/dr-pipeline/src/operation.rs#L1065), [`core/dr-pipeline/src/operation.rs:1094`](../core/dr-pipeline/src/operation.rs#L1094), [`core/dr-pipeline/src/operation.rs:1495`](../core/dr-pipeline/src/operation.rs#L1495), [`core/dr-pipeline/src/operation.rs:296`](../core/dr-pipeline/src/operation.rs#L296), [`core/dr-pipeline/src/operation.rs:310`](../core/dr-pipeline/src/operation.rs#L310), [`core/dr-pipeline/src/ops/film_sim.rs:129`](../core/dr-pipeline/src/ops/film_sim.rs#L129), [`core/dr-pipeline/src/ops/film_sim.rs:153`](../core/dr-pipeline/src/ops/film_sim.rs#L153), [`core/dr-pipeline/src/ops/film_sim.rs:1`](../core/dr-pipeline/src/ops/film_sim.rs#L1), [`core/dr-pipeline/src/ops/film_sim.rs:331`](../core/dr-pipeline/src/ops/film_sim.rs#L331), [`core/dr-pipeline/src/ops/film_sim.rs:43`](../core/dr-pipeline/src/ops/film_sim.rs#L43), [`core/dr-pipeline/src/ops/film_sim.rs:87`](../core/dr-pipeline/src/ops/film_sim.rs#L87), [`core/dr-pipeline/src/ops/film_sim.rs:92`](../core/dr-pipeline/src/ops/film_sim.rs#L92), [`core/dr-pipeline/src/sidecar.rs:112`](../core/dr-pipeline/src/sidecar.rs#L112), [`core/dr-pipeline/src/sidecar.rs:168`](../core/dr-pipeline/src/sidecar.rs#L168), [`core/dr-pipeline/src/sidecar.rs:2015`](../core/dr-pipeline/src/sidecar.rs#L2015), [`core/dr-pipeline/src/sidecar.rs:2091`](../core/dr-pipeline/src/sidecar.rs#L2091), [`core/dr-pipeline/src/sidecar.rs:534`](../core/dr-pipeline/src/sidecar.rs#L534), [`core/dr-pipeline/src/sidecar.rs:661`](../core/dr-pipeline/src/sidecar.rs#L661), [`core/dr-pipeline/src/sidecar.rs:793`](../core/dr-pipeline/src/sidecar.rs#L793), [`core/dr-pipeline/src/state.rs:100`](../core/dr-pipeline/src/state.rs#L100), [`core/dr-pipeline/src/state.rs:115`](../core/dr-pipeline/src/state.rs#L115), [`core/dr-pipeline/src/state.rs:60`](../core/dr-pipeline/src/state.rs#L60), [`ui/dr-ui/src/develop.rs:3436`](../ui/dr-ui/src/develop.rs#L3436), [`ui/dr-ui/src/develop.rs:3453`](../ui/dr-ui/src/develop.rs#L3453), [`ui/dr-ui/src/develop.rs:3465`](../ui/dr-ui/src/develop.rs#L3465), [`ui/dr-ui/src/develop.rs:3503`](../ui/dr-ui/src/develop.rs#L3503), [`ui/dr-ui/src/develop.rs:3512`](../ui/dr-ui/src/develop.rs#L3512), [`ui/dr-ui/src/develop.rs:3615`](../ui/dr-ui/src/develop.rs#L3615), [`ui/dr-ui/src/develop.rs:4028`](../ui/dr-ui/src/develop.rs#L4028), [`ui/dr-ui/src/develop.rs:4043`](../ui/dr-ui/src/develop.rs#L4043), [`ui/dr-ui/src/lib.rs:2428`](../ui/dr-ui/src/lib.rs#L2428), [`ui/dr-ui/src/lib.rs:638`](../ui/dr-ui/src/lib.rs#L638), [`ui/dr-ui/src/lib.rs:696`](../ui/dr-ui/src/lib.rs#L696), [`ui/dr-ui/src/library.rs:530`](../ui/dr-ui/src/library.rs#L530), [`ui/dr-ui/src/library.rs:778`](../ui/dr-ui/src/library.rs#L778), [`ui/dr-ui/src/presets.rs:395`](../ui/dr-ui/src/presets.rs#L395), [`ui/dr-ui/ui/adjust.slint:1072`](../ui/dr-ui/ui/adjust.slint#L1072), [`ui/dr-ui/ui/adjust.slint:996`](../ui/dr-ui/ui/adjust.slint#L996), [`ui/dr-ui/ui/app.slint:2595`](../ui/dr-ui/ui/app.slint#L2595), [`ui/dr-ui/ui/app.slint:688`](../ui/dr-ui/ui/app.slint#L688) | +| FR-DEV-3h | [`core/dr-decode/src/lib.rs:404`](../core/dr-decode/src/lib.rs#L404), [`core/dr-decode/src/preview.rs:29`](../core/dr-decode/src/preview.rs#L29), [`core/dr-pipeline/src/framing.rs:1060`](../core/dr-pipeline/src/framing.rs#L1060), [`core/dr-pipeline/src/framing.rs:328`](../core/dr-pipeline/src/framing.rs#L328), [`core/dr-pipeline/src/framing.rs:498`](../core/dr-pipeline/src/framing.rs#L498), [`core/dr-types/src/lib.rs:337`](../core/dr-types/src/lib.rs#L337), [`core/dr-types/src/lib.rs:445`](../core/dr-types/src/lib.rs#L445), [`core/dr-types/src/lib.rs:457`](../core/dr-types/src/lib.rs#L457), [`core/dr-types/src/lib.rs:473`](../core/dr-types/src/lib.rs#L473), [`ui/dr-ui/src/develop.rs:139`](../ui/dr-ui/src/develop.rs#L139), [`ui/dr-ui/src/develop.rs:2210`](../ui/dr-ui/src/develop.rs#L2210), [`ui/dr-ui/src/segmentation.rs:451`](../ui/dr-ui/src/segmentation.rs#L451) | | FR-DEV-4 | [`core/dr-gpu/src/adjust.rs:770`](../core/dr-gpu/src/adjust.rs#L770), [`core/dr-gpu/src/lib.rs:351`](../core/dr-gpu/src/lib.rs#L351), [`ui/dr-ui/ui/crop.slint:1`](../ui/dr-ui/ui/crop.slint#L1) | -| FR-DEV-5 | [`core/dr-pipeline/src/graph.rs:346`](../core/dr-pipeline/src/graph.rs#L346), [`core/dr-pipeline/src/graph.rs:385`](../core/dr-pipeline/src/graph.rs#L385), [`core/dr-pipeline/src/history.rs:102`](../core/dr-pipeline/src/history.rs#L102), [`core/dr-pipeline/src/history.rs:110`](../core/dr-pipeline/src/history.rs#L110), [`core/dr-pipeline/src/history.rs:127`](../core/dr-pipeline/src/history.rs#L127), [`core/dr-pipeline/src/history.rs:184`](../core/dr-pipeline/src/history.rs#L184), [`core/dr-pipeline/src/history.rs:1`](../core/dr-pipeline/src/history.rs#L1), [`core/dr-pipeline/src/history.rs:214`](../core/dr-pipeline/src/history.rs#L214), [`core/dr-pipeline/src/history.rs:234`](../core/dr-pipeline/src/history.rs#L234), [`core/dr-pipeline/src/history.rs:293`](../core/dr-pipeline/src/history.rs#L293), [`core/dr-pipeline/src/history.rs:479`](../core/dr-pipeline/src/history.rs#L479), [`core/dr-pipeline/src/history.rs:489`](../core/dr-pipeline/src/history.rs#L489), [`core/dr-pipeline/src/history.rs:499`](../core/dr-pipeline/src/history.rs#L499), [`core/dr-pipeline/src/history.rs:526`](../core/dr-pipeline/src/history.rs#L526), [`core/dr-pipeline/src/history.rs:86`](../core/dr-pipeline/src/history.rs#L86), [`core/dr-pipeline/src/state.rs:1`](../core/dr-pipeline/src/state.rs#L1), [`core/dr-pipeline/src/state.rs:75`](../core/dr-pipeline/src/state.rs#L75), [`ui/dr-ui/src/develop.rs:3425`](../ui/dr-ui/src/develop.rs#L3425), [`ui/dr-ui/src/develop.rs:4006`](../ui/dr-ui/src/develop.rs#L4006), [`ui/dr-ui/src/develop.rs:4036`](../ui/dr-ui/src/develop.rs#L4036), [`ui/dr-ui/src/develop.rs:4049`](../ui/dr-ui/src/develop.rs#L4049), [`ui/dr-ui/src/develop.rs:4061`](../ui/dr-ui/src/develop.rs#L4061), [`ui/dr-ui/src/develop.rs:4077`](../ui/dr-ui/src/develop.rs#L4077), [`ui/dr-ui/src/develop.rs:4109`](../ui/dr-ui/src/develop.rs#L4109), [`ui/dr-ui/src/develop.rs:4113`](../ui/dr-ui/src/develop.rs#L4113), [`ui/dr-ui/src/develop.rs:4132`](../ui/dr-ui/src/develop.rs#L4132), [`ui/dr-ui/src/develop.rs:4148`](../ui/dr-ui/src/develop.rs#L4148), [`ui/dr-ui/src/develop.rs:709`](../ui/dr-ui/src/develop.rs#L709), [`ui/dr-ui/src/labels.rs:12`](../ui/dr-ui/src/labels.rs#L12), [`ui/dr-ui/src/labels.rs:217`](../ui/dr-ui/src/labels.rs#L217), [`ui/dr-ui/src/lib.rs:1587`](../ui/dr-ui/src/lib.rs#L1587), [`ui/dr-ui/src/lib.rs:1630`](../ui/dr-ui/src/lib.rs#L1630), [`ui/dr-ui/src/lib.rs:1638`](../ui/dr-ui/src/lib.rs#L1638), [`ui/dr-ui/src/lib.rs:2624`](../ui/dr-ui/src/lib.rs#L2624), [`ui/dr-ui/ui/history.slint:1`](../ui/dr-ui/ui/history.slint#L1) | -| FR-DEV-6 | [`core/dr-pipeline/src/preset.rs:1`](../core/dr-pipeline/src/preset.rs#L1), [`core/dr-pipeline/src/preset.rs:381`](../core/dr-pipeline/src/preset.rs#L381), [`core/dr-pipeline/src/preset.rs:414`](../core/dr-pipeline/src/preset.rs#L414), [`core/dr-pipeline/src/starter.rs:1`](../core/dr-pipeline/src/starter.rs#L1), [`core/dr-preset-xmp/src/lib.rs:1`](../core/dr-preset-xmp/src/lib.rs#L1), [`core/dr-types/src/settings.rs:272`](../core/dr-types/src/settings.rs#L272), [`ui/dr-ui/src/develop.rs:3948`](../ui/dr-ui/src/develop.rs#L3948), [`ui/dr-ui/src/develop.rs:3969`](../ui/dr-ui/src/develop.rs#L3969), [`ui/dr-ui/src/lib.rs:1554`](../ui/dr-ui/src/lib.rs#L1554), [`ui/dr-ui/src/lib.rs:2239`](../ui/dr-ui/src/lib.rs#L2239), [`ui/dr-ui/src/lib.rs:2268`](../ui/dr-ui/src/lib.rs#L2268), [`ui/dr-ui/src/library.rs:1903`](../ui/dr-ui/src/library.rs#L1903), [`ui/dr-ui/src/library.rs:492`](../ui/dr-ui/src/library.rs#L492), [`ui/dr-ui/src/library.rs:520`](../ui/dr-ui/src/library.rs#L520), [`ui/dr-ui/src/library_ui.rs:2966`](../ui/dr-ui/src/library_ui.rs#L2966), [`ui/dr-ui/src/library_ui.rs:3366`](../ui/dr-ui/src/library_ui.rs#L3366), [`ui/dr-ui/src/library_ui.rs:500`](../ui/dr-ui/src/library_ui.rs#L500), [`ui/dr-ui/src/preset_store.rs:1`](../ui/dr-ui/src/preset_store.rs#L1), [`ui/dr-ui/src/presets.rs:1`](../ui/dr-ui/src/presets.rs#L1), [`ui/dr-ui/src/presets.rs:657`](../ui/dr-ui/src/presets.rs#L657), [`ui/dr-ui/src/presets.rs:691`](../ui/dr-ui/src/presets.rs#L691), [`ui/dr-ui/ui/adjust.slint:740`](../ui/dr-ui/ui/adjust.slint#L740), [`ui/dr-ui/ui/adjust.slint:767`](../ui/dr-ui/ui/adjust.slint#L767), [`ui/dr-ui/ui/adjust.slint:801`](../ui/dr-ui/ui/adjust.slint#L801), [`ui/dr-ui/ui/app.slint:1575`](../ui/dr-ui/ui/app.slint#L1575), [`ui/dr-ui/ui/app.slint:2684`](../ui/dr-ui/ui/app.slint#L2684), [`ui/dr-ui/ui/app.slint:760`](../ui/dr-ui/ui/app.slint#L760), [`ui/dr-ui/ui/app.slint:771`](../ui/dr-ui/ui/app.slint#L771), [`ui/dr-ui/ui/library.slint:1460`](../ui/dr-ui/ui/library.slint#L1460), [`ui/dr-ui/ui/library.slint:1466`](../ui/dr-ui/ui/library.slint#L1466), [`ui/dr-ui/ui/library.slint:3979`](../ui/dr-ui/ui/library.slint#L3979), [`ui/dr-ui/ui/library.slint:3994`](../ui/dr-ui/ui/library.slint#L3994), [`ui/dr-ui/ui/presets.slint:105`](../ui/dr-ui/ui/presets.slint#L105), [`ui/dr-ui/ui/presets.slint:113`](../ui/dr-ui/ui/presets.slint#L113), [`ui/dr-ui/ui/presets.slint:19`](../ui/dr-ui/ui/presets.slint#L19), [`ui/dr-ui/ui/presets.slint:276`](../ui/dr-ui/ui/presets.slint#L276), [`ui/dr-ui/ui/presets.slint:297`](../ui/dr-ui/ui/presets.slint#L297), [`ui/dr-ui/ui/presets.slint:5`](../ui/dr-ui/ui/presets.slint#L5), [`ui/dr-ui/ui/presets.slint:60`](../ui/dr-ui/ui/presets.slint#L60), [`ui/dr-ui/ui/settings.slint:101`](../ui/dr-ui/ui/settings.slint#L101), [`ui/dr-ui/ui/settings.slint:557`](../ui/dr-ui/ui/settings.slint#L557) | -| FR-DEV-7 | [`core/dr-pipeline/src/history.rs:214`](../core/dr-pipeline/src/history.rs#L214), [`core/dr-pipeline/src/history.rs:499`](../core/dr-pipeline/src/history.rs#L499), [`core/dr-pipeline/src/history.rs:526`](../core/dr-pipeline/src/history.rs#L526), [`ui/dr-ui/src/develop.rs:4077`](../ui/dr-ui/src/develop.rs#L4077), [`ui/dr-ui/src/develop.rs:4109`](../ui/dr-ui/src/develop.rs#L4109), [`ui/dr-ui/src/lib.rs:1638`](../ui/dr-ui/src/lib.rs#L1638), [`ui/dr-ui/src/lib.rs:2624`](../ui/dr-ui/src/lib.rs#L2624), [`ui/dr-ui/ui/history.slint:1`](../ui/dr-ui/ui/history.slint#L1) | +| FR-DEV-5 | [`core/dr-pipeline/src/graph.rs:346`](../core/dr-pipeline/src/graph.rs#L346), [`core/dr-pipeline/src/graph.rs:385`](../core/dr-pipeline/src/graph.rs#L385), [`core/dr-pipeline/src/history.rs:102`](../core/dr-pipeline/src/history.rs#L102), [`core/dr-pipeline/src/history.rs:110`](../core/dr-pipeline/src/history.rs#L110), [`core/dr-pipeline/src/history.rs:127`](../core/dr-pipeline/src/history.rs#L127), [`core/dr-pipeline/src/history.rs:184`](../core/dr-pipeline/src/history.rs#L184), [`core/dr-pipeline/src/history.rs:1`](../core/dr-pipeline/src/history.rs#L1), [`core/dr-pipeline/src/history.rs:214`](../core/dr-pipeline/src/history.rs#L214), [`core/dr-pipeline/src/history.rs:234`](../core/dr-pipeline/src/history.rs#L234), [`core/dr-pipeline/src/history.rs:293`](../core/dr-pipeline/src/history.rs#L293), [`core/dr-pipeline/src/history.rs:479`](../core/dr-pipeline/src/history.rs#L479), [`core/dr-pipeline/src/history.rs:489`](../core/dr-pipeline/src/history.rs#L489), [`core/dr-pipeline/src/history.rs:499`](../core/dr-pipeline/src/history.rs#L499), [`core/dr-pipeline/src/history.rs:526`](../core/dr-pipeline/src/history.rs#L526), [`core/dr-pipeline/src/history.rs:86`](../core/dr-pipeline/src/history.rs#L86), [`core/dr-pipeline/src/state.rs:1`](../core/dr-pipeline/src/state.rs#L1), [`core/dr-pipeline/src/state.rs:75`](../core/dr-pipeline/src/state.rs#L75), [`ui/dr-ui/src/develop.rs:3465`](../ui/dr-ui/src/develop.rs#L3465), [`ui/dr-ui/src/develop.rs:4043`](../ui/dr-ui/src/develop.rs#L4043), [`ui/dr-ui/src/develop.rs:4073`](../ui/dr-ui/src/develop.rs#L4073), [`ui/dr-ui/src/develop.rs:4086`](../ui/dr-ui/src/develop.rs#L4086), [`ui/dr-ui/src/develop.rs:4098`](../ui/dr-ui/src/develop.rs#L4098), [`ui/dr-ui/src/develop.rs:4114`](../ui/dr-ui/src/develop.rs#L4114), [`ui/dr-ui/src/develop.rs:4146`](../ui/dr-ui/src/develop.rs#L4146), [`ui/dr-ui/src/develop.rs:4150`](../ui/dr-ui/src/develop.rs#L4150), [`ui/dr-ui/src/develop.rs:4169`](../ui/dr-ui/src/develop.rs#L4169), [`ui/dr-ui/src/develop.rs:4185`](../ui/dr-ui/src/develop.rs#L4185), [`ui/dr-ui/src/develop.rs:709`](../ui/dr-ui/src/develop.rs#L709), [`ui/dr-ui/src/labels.rs:12`](../ui/dr-ui/src/labels.rs#L12), [`ui/dr-ui/src/labels.rs:217`](../ui/dr-ui/src/labels.rs#L217), [`ui/dr-ui/src/lib.rs:1587`](../ui/dr-ui/src/lib.rs#L1587), [`ui/dr-ui/src/lib.rs:1630`](../ui/dr-ui/src/lib.rs#L1630), [`ui/dr-ui/src/lib.rs:1638`](../ui/dr-ui/src/lib.rs#L1638), [`ui/dr-ui/src/lib.rs:2624`](../ui/dr-ui/src/lib.rs#L2624), [`ui/dr-ui/ui/history.slint:1`](../ui/dr-ui/ui/history.slint#L1) | +| FR-DEV-6 | [`core/dr-pipeline/src/preset.rs:1`](../core/dr-pipeline/src/preset.rs#L1), [`core/dr-pipeline/src/preset.rs:381`](../core/dr-pipeline/src/preset.rs#L381), [`core/dr-pipeline/src/preset.rs:414`](../core/dr-pipeline/src/preset.rs#L414), [`core/dr-pipeline/src/starter.rs:1`](../core/dr-pipeline/src/starter.rs#L1), [`core/dr-preset-xmp/src/lib.rs:1`](../core/dr-preset-xmp/src/lib.rs#L1), [`core/dr-types/src/settings.rs:272`](../core/dr-types/src/settings.rs#L272), [`ui/dr-ui/src/develop.rs:3985`](../ui/dr-ui/src/develop.rs#L3985), [`ui/dr-ui/src/develop.rs:4006`](../ui/dr-ui/src/develop.rs#L4006), [`ui/dr-ui/src/lib.rs:1554`](../ui/dr-ui/src/lib.rs#L1554), [`ui/dr-ui/src/lib.rs:2239`](../ui/dr-ui/src/lib.rs#L2239), [`ui/dr-ui/src/lib.rs:2268`](../ui/dr-ui/src/lib.rs#L2268), [`ui/dr-ui/src/library.rs:1903`](../ui/dr-ui/src/library.rs#L1903), [`ui/dr-ui/src/library.rs:492`](../ui/dr-ui/src/library.rs#L492), [`ui/dr-ui/src/library.rs:520`](../ui/dr-ui/src/library.rs#L520), [`ui/dr-ui/src/library_ui.rs:2966`](../ui/dr-ui/src/library_ui.rs#L2966), [`ui/dr-ui/src/library_ui.rs:3366`](../ui/dr-ui/src/library_ui.rs#L3366), [`ui/dr-ui/src/library_ui.rs:500`](../ui/dr-ui/src/library_ui.rs#L500), [`ui/dr-ui/src/preset_store.rs:1`](../ui/dr-ui/src/preset_store.rs#L1), [`ui/dr-ui/src/presets.rs:1`](../ui/dr-ui/src/presets.rs#L1), [`ui/dr-ui/src/presets.rs:657`](../ui/dr-ui/src/presets.rs#L657), [`ui/dr-ui/src/presets.rs:691`](../ui/dr-ui/src/presets.rs#L691), [`ui/dr-ui/ui/adjust.slint:740`](../ui/dr-ui/ui/adjust.slint#L740), [`ui/dr-ui/ui/adjust.slint:767`](../ui/dr-ui/ui/adjust.slint#L767), [`ui/dr-ui/ui/adjust.slint:801`](../ui/dr-ui/ui/adjust.slint#L801), [`ui/dr-ui/ui/app.slint:1575`](../ui/dr-ui/ui/app.slint#L1575), [`ui/dr-ui/ui/app.slint:2684`](../ui/dr-ui/ui/app.slint#L2684), [`ui/dr-ui/ui/app.slint:760`](../ui/dr-ui/ui/app.slint#L760), [`ui/dr-ui/ui/app.slint:771`](../ui/dr-ui/ui/app.slint#L771), [`ui/dr-ui/ui/library.slint:1460`](../ui/dr-ui/ui/library.slint#L1460), [`ui/dr-ui/ui/library.slint:1466`](../ui/dr-ui/ui/library.slint#L1466), [`ui/dr-ui/ui/library.slint:3979`](../ui/dr-ui/ui/library.slint#L3979), [`ui/dr-ui/ui/library.slint:3994`](../ui/dr-ui/ui/library.slint#L3994), [`ui/dr-ui/ui/presets.slint:105`](../ui/dr-ui/ui/presets.slint#L105), [`ui/dr-ui/ui/presets.slint:113`](../ui/dr-ui/ui/presets.slint#L113), [`ui/dr-ui/ui/presets.slint:19`](../ui/dr-ui/ui/presets.slint#L19), [`ui/dr-ui/ui/presets.slint:276`](../ui/dr-ui/ui/presets.slint#L276), [`ui/dr-ui/ui/presets.slint:297`](../ui/dr-ui/ui/presets.slint#L297), [`ui/dr-ui/ui/presets.slint:5`](../ui/dr-ui/ui/presets.slint#L5), [`ui/dr-ui/ui/presets.slint:60`](../ui/dr-ui/ui/presets.slint#L60), [`ui/dr-ui/ui/settings.slint:101`](../ui/dr-ui/ui/settings.slint#L101), [`ui/dr-ui/ui/settings.slint:557`](../ui/dr-ui/ui/settings.slint#L557) | +| FR-DEV-7 | [`core/dr-pipeline/src/history.rs:214`](../core/dr-pipeline/src/history.rs#L214), [`core/dr-pipeline/src/history.rs:499`](../core/dr-pipeline/src/history.rs#L499), [`core/dr-pipeline/src/history.rs:526`](../core/dr-pipeline/src/history.rs#L526), [`ui/dr-ui/src/develop.rs:4114`](../ui/dr-ui/src/develop.rs#L4114), [`ui/dr-ui/src/develop.rs:4146`](../ui/dr-ui/src/develop.rs#L4146), [`ui/dr-ui/src/lib.rs:1638`](../ui/dr-ui/src/lib.rs#L1638), [`ui/dr-ui/src/lib.rs:2624`](../ui/dr-ui/src/lib.rs#L2624), [`ui/dr-ui/ui/history.slint:1`](../ui/dr-ui/ui/history.slint#L1) | | FR-DEV-8 | [`core/dr-gpu/src/detail.rs:405`](../core/dr-gpu/src/detail.rs#L405), [`core/dr-gpu/src/detail.rs:623`](../core/dr-gpu/src/detail.rs#L623), [`core/dr-gpu/tests/detail_instances.rs:1`](../core/dr-gpu/tests/detail_instances.rs#L1), [`core/dr-gpu/tests/spot_removal.rs:1`](../core/dr-gpu/tests/spot_removal.rs#L1), [`core/dr-pipeline/src/detail.rs:410`](../core/dr-pipeline/src/detail.rs#L410), [`core/dr-pipeline/src/detail.rs:434`](../core/dr-pipeline/src/detail.rs#L434), [`core/dr-pipeline/src/detail.rs:469`](../core/dr-pipeline/src/detail.rs#L469), [`core/dr-pipeline/src/detail.rs:555`](../core/dr-pipeline/src/detail.rs#L555), [`core/dr-pipeline/src/graph.rs:114`](../core/dr-pipeline/src/graph.rs#L114), [`core/dr-pipeline/src/graph.rs:192`](../core/dr-pipeline/src/graph.rs#L192), [`core/dr-pipeline/src/graph.rs:686`](../core/dr-pipeline/src/graph.rs#L686), [`core/dr-pipeline/src/operation.rs:330`](../core/dr-pipeline/src/operation.rs#L330), [`core/dr-pipeline/src/operation.rs:554`](../core/dr-pipeline/src/operation.rs#L554), [`core/dr-pipeline/src/sidecar.rs:184`](../core/dr-pipeline/src/sidecar.rs#L184), [`core/dr-pipeline/src/sidecar.rs:353`](../core/dr-pipeline/src/sidecar.rs#L353), [`core/dr-pipeline/src/sidecar.rs:673`](../core/dr-pipeline/src/sidecar.rs#L673), [`core/dr-pipeline/src/sidecar.rs:809`](../core/dr-pipeline/src/sidecar.rs#L809), [`core/dr-pipeline/src/sidecar.rs:863`](../core/dr-pipeline/src/sidecar.rs#L863), [`core/dr-pipeline/src/sidecar.rs:893`](../core/dr-pipeline/src/sidecar.rs#L893), [`core/dr-pipeline/src/spot.rs:115`](../core/dr-pipeline/src/spot.rs#L115), [`core/dr-pipeline/src/spot.rs:151`](../core/dr-pipeline/src/spot.rs#L151), [`core/dr-pipeline/src/spot.rs:1`](../core/dr-pipeline/src/spot.rs#L1), [`core/dr-pipeline/src/spot.rs:207`](../core/dr-pipeline/src/spot.rs#L207), [`core/dr-pipeline/src/spot.rs:387`](../core/dr-pipeline/src/spot.rs#L387), [`core/dr-pipeline/src/spot.rs:472`](../core/dr-pipeline/src/spot.rs#L472), [`core/dr-pipeline/src/spot.rs:582`](../core/dr-pipeline/src/spot.rs#L582), [`core/dr-pipeline/src/spot.rs:673`](../core/dr-pipeline/src/spot.rs#L673), [`core/dr-pipeline/src/state.rs:103`](../core/dr-pipeline/src/state.rs#L103), [`core/dr-pipeline/tests/spot_sidecar.rs:1`](../core/dr-pipeline/tests/spot_sidecar.rs#L1), [`core/dr-pipeline/tests/spots.rs:1`](../core/dr-pipeline/tests/spots.rs#L1), [`ui/dr-ui/src/develop.rs:2362`](../ui/dr-ui/src/develop.rs#L2362), [`ui/dr-ui/src/develop.rs:2400`](../ui/dr-ui/src/develop.rs#L2400), [`ui/dr-ui/src/develop.rs:2465`](../ui/dr-ui/src/develop.rs#L2465), [`ui/dr-ui/src/develop.rs:2548`](../ui/dr-ui/src/develop.rs#L2548), [`ui/dr-ui/src/develop.rs:2562`](../ui/dr-ui/src/develop.rs#L2562), [`ui/dr-ui/src/develop.rs:796`](../ui/dr-ui/src/develop.rs#L796), [`ui/dr-ui/src/labels.rs:53`](../ui/dr-ui/src/labels.rs#L53), [`ui/dr-ui/src/lib.rs:1659`](../ui/dr-ui/src/lib.rs#L1659), [`ui/dr-ui/src/lib.rs:2742`](../ui/dr-ui/src/lib.rs#L2742), [`ui/dr-ui/src/lib.rs:361`](../ui/dr-ui/src/lib.rs#L361), [`ui/dr-ui/src/spots_ui.rs:19`](../ui/dr-ui/src/spots_ui.rs#L19), [`ui/dr-ui/src/spots_ui.rs:1`](../ui/dr-ui/src/spots_ui.rs#L1), [`ui/dr-ui/src/spots_ui.rs:265`](../ui/dr-ui/src/spots_ui.rs#L265), [`ui/dr-ui/ui/adjust.slint:832`](../ui/dr-ui/ui/adjust.slint#L832), [`ui/dr-ui/ui/app.slint:140`](../ui/dr-ui/ui/app.slint#L140), [`ui/dr-ui/ui/app.slint:1925`](../ui/dr-ui/ui/app.slint#L1925), [`ui/dr-ui/ui/app.slint:2100`](../ui/dr-ui/ui/app.slint#L2100), [`ui/dr-ui/ui/app.slint:2496`](../ui/dr-ui/ui/app.slint#L2496), [`ui/dr-ui/ui/icons.slint:338`](../ui/dr-ui/ui/icons.slint#L338), [`ui/dr-ui/ui/spots.slint:172`](../ui/dr-ui/ui/spots.slint#L172), [`ui/dr-ui/ui/spots.slint:48`](../ui/dr-ui/ui/spots.slint#L48), [`ui/dr-ui/ui/spots.slint:5`](../ui/dr-ui/ui/spots.slint#L5) | -| FR-DSP-1 | [`core/dr-gpu/src/adjust.rs:2126`](../core/dr-gpu/src/adjust.rs#L2126), [`core/dr-gpu/src/adjust.rs:2203`](../core/dr-gpu/src/adjust.rs#L2203), [`core/dr-gpu/src/adjust.rs:2288`](../core/dr-gpu/src/adjust.rs#L2288), [`core/dr-gpu/src/adjust.rs:54`](../core/dr-gpu/src/adjust.rs#L54), [`core/dr-gpu/src/adjust.rs:770`](../core/dr-gpu/src/adjust.rs#L770), [`core/dr-gpu/src/lib.rs:172`](../core/dr-gpu/src/lib.rs#L172), [`core/dr-gpu/src/lib.rs:192`](../core/dr-gpu/src/lib.rs#L192), [`core/dr-gpu/src/lib.rs:70`](../core/dr-gpu/src/lib.rs#L70), [`core/dr-gpu/src/lib.rs:93`](../core/dr-gpu/src/lib.rs#L93), [`core/dr-gpu/tests/capture_sharpen.rs:200`](../core/dr-gpu/tests/capture_sharpen.rs#L200), [`core/dr-gpu/tests/detail_stage.rs:328`](../core/dr-gpu/tests/detail_stage.rs#L328), [`core/dr-gpu/tests/local_contrast.rs:264`](../core/dr-gpu/tests/local_contrast.rs#L264), [`core/dr-gpu/tests/noise_reduction.rs:378`](../core/dr-gpu/tests/noise_reduction.rs#L378), [`core/dr-pipeline/src/detail.rs:136`](../core/dr-pipeline/src/detail.rs#L136), [`core/dr-pipeline/src/detail.rs:524`](../core/dr-pipeline/src/detail.rs#L524), [`core/dr-pipeline/src/graph.rs:548`](../core/dr-pipeline/src/graph.rs#L548), [`core/dr-pipeline/src/graph.rs:578`](../core/dr-pipeline/src/graph.rs#L578), [`core/dr-pipeline/src/ops/capture_sharpen.rs:1`](../core/dr-pipeline/src/ops/capture_sharpen.rs#L1), [`core/dr-pipeline/src/ops/capture_sharpen.rs:659`](../core/dr-pipeline/src/ops/capture_sharpen.rs#L659), [`core/dr-pipeline/src/ops/local_contrast.rs:1`](../core/dr-pipeline/src/ops/local_contrast.rs#L1), [`core/dr-pipeline/src/ops/local_contrast.rs:971`](../core/dr-pipeline/src/ops/local_contrast.rs#L971), [`core/dr-pipeline/src/ops/noise_reduction.rs:700`](../core/dr-pipeline/src/ops/noise_reduction.rs#L700), [`core/dr-pipeline/src/spot.rs:673`](../core/dr-pipeline/src/spot.rs#L673), [`ui/dr-ui/src/develop.rs:2995`](../ui/dr-ui/src/develop.rs#L2995), [`ui/dr-ui/src/develop.rs:4403`](../ui/dr-ui/src/develop.rs#L4403), [`ui/dr-ui/src/develop.rs:4886`](../ui/dr-ui/src/develop.rs#L4886), [`ui/dr-ui/src/develop.rs:4920`](../ui/dr-ui/src/develop.rs#L4920), [`ui/dr-ui/src/lib.rs:846`](../ui/dr-ui/src/lib.rs#L846), [`ui/dr-ui/src/lib.rs:905`](../ui/dr-ui/src/lib.rs#L905), [`ui/dr-ui/src/lib.rs:92`](../ui/dr-ui/src/lib.rs#L92) | +| FR-DSP-1 | [`core/dr-gpu/src/adjust.rs:2126`](../core/dr-gpu/src/adjust.rs#L2126), [`core/dr-gpu/src/adjust.rs:2203`](../core/dr-gpu/src/adjust.rs#L2203), [`core/dr-gpu/src/adjust.rs:2288`](../core/dr-gpu/src/adjust.rs#L2288), [`core/dr-gpu/src/adjust.rs:54`](../core/dr-gpu/src/adjust.rs#L54), [`core/dr-gpu/src/adjust.rs:770`](../core/dr-gpu/src/adjust.rs#L770), [`core/dr-gpu/src/lib.rs:172`](../core/dr-gpu/src/lib.rs#L172), [`core/dr-gpu/src/lib.rs:192`](../core/dr-gpu/src/lib.rs#L192), [`core/dr-gpu/src/lib.rs:70`](../core/dr-gpu/src/lib.rs#L70), [`core/dr-gpu/src/lib.rs:93`](../core/dr-gpu/src/lib.rs#L93), [`core/dr-gpu/tests/capture_sharpen.rs:200`](../core/dr-gpu/tests/capture_sharpen.rs#L200), [`core/dr-gpu/tests/detail_stage.rs:328`](../core/dr-gpu/tests/detail_stage.rs#L328), [`core/dr-gpu/tests/local_contrast.rs:264`](../core/dr-gpu/tests/local_contrast.rs#L264), [`core/dr-gpu/tests/noise_reduction.rs:378`](../core/dr-gpu/tests/noise_reduction.rs#L378), [`core/dr-pipeline/src/detail.rs:136`](../core/dr-pipeline/src/detail.rs#L136), [`core/dr-pipeline/src/detail.rs:524`](../core/dr-pipeline/src/detail.rs#L524), [`core/dr-pipeline/src/graph.rs:548`](../core/dr-pipeline/src/graph.rs#L548), [`core/dr-pipeline/src/graph.rs:578`](../core/dr-pipeline/src/graph.rs#L578), [`core/dr-pipeline/src/ops/capture_sharpen.rs:1`](../core/dr-pipeline/src/ops/capture_sharpen.rs#L1), [`core/dr-pipeline/src/ops/capture_sharpen.rs:659`](../core/dr-pipeline/src/ops/capture_sharpen.rs#L659), [`core/dr-pipeline/src/ops/local_contrast.rs:1`](../core/dr-pipeline/src/ops/local_contrast.rs#L1), [`core/dr-pipeline/src/ops/local_contrast.rs:971`](../core/dr-pipeline/src/ops/local_contrast.rs#L971), [`core/dr-pipeline/src/ops/noise_reduction.rs:700`](../core/dr-pipeline/src/ops/noise_reduction.rs#L700), [`core/dr-pipeline/src/spot.rs:673`](../core/dr-pipeline/src/spot.rs#L673), [`ui/dr-ui/src/develop.rs:2995`](../ui/dr-ui/src/develop.rs#L2995), [`ui/dr-ui/src/develop.rs:4440`](../ui/dr-ui/src/develop.rs#L4440), [`ui/dr-ui/src/develop.rs:4923`](../ui/dr-ui/src/develop.rs#L4923), [`ui/dr-ui/src/develop.rs:4957`](../ui/dr-ui/src/develop.rs#L4957), [`ui/dr-ui/src/lib.rs:846`](../ui/dr-ui/src/lib.rs#L846), [`ui/dr-ui/src/lib.rs:905`](../ui/dr-ui/src/lib.rs#L905), [`ui/dr-ui/src/lib.rs:92`](../ui/dr-ui/src/lib.rs#L92) | | FR-DSP-3 | [`core/dr-gpu/tests/frame_budget.rs:101`](../core/dr-gpu/tests/frame_budget.rs#L101), [`core/dr-gpu/tests/local_contrast.rs:329`](../core/dr-gpu/tests/local_contrast.rs#L329), [`core/dr-pipeline/src/ops/local_contrast.rs:447`](../core/dr-pipeline/src/ops/local_contrast.rs#L447) | | FR-DSP-5 | [`core/dr-gpu/tests/frame_budget.rs:101`](../core/dr-gpu/tests/frame_budget.rs#L101), [`core/dr-gpu/tests/zoom_resolution.rs:135`](../core/dr-gpu/tests/zoom_resolution.rs#L135), [`core/dr-gpu/tests/zoom_resolution.rs:166`](../core/dr-gpu/tests/zoom_resolution.rs#L166), [`core/dr-gpu/tests/zoom_resolution.rs:1`](../core/dr-gpu/tests/zoom_resolution.rs#L1), [`core/dr-gpu/tests/zoom_resolution.rs:216`](../core/dr-gpu/tests/zoom_resolution.rs#L216) | -| FR-DSP-6 | [`core/dr-pipeline/src/operation.rs:483`](../core/dr-pipeline/src/operation.rs#L483), [`core/dr-types/src/colour.rs:1`](../core/dr-types/src/colour.rs#L1), [`ui/dr-ui/src/develop.rs:3025`](../ui/dr-ui/src/develop.rs#L3025), [`ui/dr-ui/src/develop.rs:6314`](../ui/dr-ui/src/develop.rs#L6314), [`ui/dr-ui/src/lib.rs:1615`](../ui/dr-ui/src/lib.rs#L1615), [`ui/dr-ui/src/lib.rs:3125`](../ui/dr-ui/src/lib.rs#L3125) | -| FR-DSP-7 | [`core/dr-gpu/src/histogram.rs:147`](../core/dr-gpu/src/histogram.rs#L147), [`core/dr-gpu/src/histogram.rs:1`](../core/dr-gpu/src/histogram.rs#L1), [`core/dr-gpu/src/histogram.rs:281`](../core/dr-gpu/src/histogram.rs#L281), [`core/dr-gpu/src/histogram.rs:50`](../core/dr-gpu/src/histogram.rs#L50), [`core/dr-gpu/src/shaders/histogram.wgsl:1`](../core/dr-gpu/src/shaders/histogram.wgsl#L1), [`ui/dr-ui/src/develop.rs:3074`](../ui/dr-ui/src/develop.rs#L3074), [`ui/dr-ui/src/develop.rs:5988`](../ui/dr-ui/src/develop.rs#L5988), [`ui/dr-ui/src/develop.rs:6020`](../ui/dr-ui/src/develop.rs#L6020), [`ui/dr-ui/src/develop.rs:720`](../ui/dr-ui/src/develop.rs#L720), [`ui/dr-ui/src/histogram.rs:1`](../ui/dr-ui/src/histogram.rs#L1), [`ui/dr-ui/src/lib.rs:1725`](../ui/dr-ui/src/lib.rs#L1725), [`ui/dr-ui/src/lib.rs:340`](../ui/dr-ui/src/lib.rs#L340), [`ui/dr-ui/ui/app.slint:74`](../ui/dr-ui/ui/app.slint#L74), [`ui/dr-ui/ui/histogram.slint:168`](../ui/dr-ui/ui/histogram.slint#L168), [`ui/dr-ui/ui/histogram.slint:1`](../ui/dr-ui/ui/histogram.slint#L1) | -| FR-DSP-8 | [`platform/dr-plat/src/display.rs:1`](../platform/dr-plat/src/display.rs#L1), [`platform/dr-plat/src/display/icc.rs:1`](../platform/dr-plat/src/display/icc.rs#L1), [`platform/dr-plat/src/display/wayland.rs:1`](../platform/dr-plat/src/display/wayland.rs#L1), [`platform/dr-plat/src/display/x11.rs:1`](../platform/dr-plat/src/display/x11.rs#L1), [`ui/dr-ui/src/develop.rs:2971`](../ui/dr-ui/src/develop.rs#L2971), [`ui/dr-ui/src/develop.rs:3025`](../ui/dr-ui/src/develop.rs#L3025), [`ui/dr-ui/src/develop.rs:6314`](../ui/dr-ui/src/develop.rs#L6314), [`ui/dr-ui/src/develop.rs:6360`](../ui/dr-ui/src/develop.rs#L6360), [`ui/dr-ui/src/develop.rs:6379`](../ui/dr-ui/src/develop.rs#L6379), [`ui/dr-ui/src/develop.rs:827`](../ui/dr-ui/src/develop.rs#L827), [`ui/dr-ui/src/display_ui.rs:192`](../ui/dr-ui/src/display_ui.rs#L192), [`ui/dr-ui/src/display_ui.rs:1`](../ui/dr-ui/src/display_ui.rs#L1), [`ui/dr-ui/src/display_ui.rs:325`](../ui/dr-ui/src/display_ui.rs#L325), [`ui/dr-ui/src/display_ui.rs:346`](../ui/dr-ui/src/display_ui.rs#L346), [`ui/dr-ui/src/display_ui.rs:379`](../ui/dr-ui/src/display_ui.rs#L379), [`ui/dr-ui/src/lib.rs:1576`](../ui/dr-ui/src/lib.rs#L1576), [`ui/dr-ui/src/lib.rs:1615`](../ui/dr-ui/src/lib.rs#L1615), [`ui/dr-ui/src/lib.rs:3038`](../ui/dr-ui/src/lib.rs#L3038), [`ui/dr-ui/src/lib.rs:3125`](../ui/dr-ui/src/lib.rs#L3125), [`ui/dr-ui/ui/app.slint:1773`](../ui/dr-ui/ui/app.slint#L1773), [`ui/dr-ui/ui/app.slint:53`](../ui/dr-ui/ui/app.slint#L53), [`ui/dr-ui/ui/settings.slint:124`](../ui/dr-ui/ui/settings.slint#L124), [`ui/dr-ui/ui/settings.slint:794`](../ui/dr-ui/ui/settings.slint#L794) | +| FR-DSP-6 | [`core/dr-pipeline/src/operation.rs:483`](../core/dr-pipeline/src/operation.rs#L483), [`core/dr-types/src/colour.rs:1`](../core/dr-types/src/colour.rs#L1), [`ui/dr-ui/src/develop.rs:3025`](../ui/dr-ui/src/develop.rs#L3025), [`ui/dr-ui/src/develop.rs:6351`](../ui/dr-ui/src/develop.rs#L6351), [`ui/dr-ui/src/lib.rs:1615`](../ui/dr-ui/src/lib.rs#L1615), [`ui/dr-ui/src/lib.rs:3125`](../ui/dr-ui/src/lib.rs#L3125) | +| FR-DSP-7 | [`core/dr-gpu/src/histogram.rs:147`](../core/dr-gpu/src/histogram.rs#L147), [`core/dr-gpu/src/histogram.rs:1`](../core/dr-gpu/src/histogram.rs#L1), [`core/dr-gpu/src/histogram.rs:281`](../core/dr-gpu/src/histogram.rs#L281), [`core/dr-gpu/src/histogram.rs:50`](../core/dr-gpu/src/histogram.rs#L50), [`core/dr-gpu/src/shaders/histogram.wgsl:1`](../core/dr-gpu/src/shaders/histogram.wgsl#L1), [`ui/dr-ui/src/develop.rs:3074`](../ui/dr-ui/src/develop.rs#L3074), [`ui/dr-ui/src/develop.rs:6025`](../ui/dr-ui/src/develop.rs#L6025), [`ui/dr-ui/src/develop.rs:6057`](../ui/dr-ui/src/develop.rs#L6057), [`ui/dr-ui/src/develop.rs:720`](../ui/dr-ui/src/develop.rs#L720), [`ui/dr-ui/src/histogram.rs:1`](../ui/dr-ui/src/histogram.rs#L1), [`ui/dr-ui/src/lib.rs:1725`](../ui/dr-ui/src/lib.rs#L1725), [`ui/dr-ui/src/lib.rs:340`](../ui/dr-ui/src/lib.rs#L340), [`ui/dr-ui/ui/app.slint:74`](../ui/dr-ui/ui/app.slint#L74), [`ui/dr-ui/ui/histogram.slint:168`](../ui/dr-ui/ui/histogram.slint#L168), [`ui/dr-ui/ui/histogram.slint:1`](../ui/dr-ui/ui/histogram.slint#L1) | +| FR-DSP-8 | [`platform/dr-plat/src/display.rs:1`](../platform/dr-plat/src/display.rs#L1), [`platform/dr-plat/src/display/icc.rs:1`](../platform/dr-plat/src/display/icc.rs#L1), [`platform/dr-plat/src/display/wayland.rs:1`](../platform/dr-plat/src/display/wayland.rs#L1), [`platform/dr-plat/src/display/x11.rs:1`](../platform/dr-plat/src/display/x11.rs#L1), [`ui/dr-ui/src/develop.rs:2971`](../ui/dr-ui/src/develop.rs#L2971), [`ui/dr-ui/src/develop.rs:3025`](../ui/dr-ui/src/develop.rs#L3025), [`ui/dr-ui/src/develop.rs:6351`](../ui/dr-ui/src/develop.rs#L6351), [`ui/dr-ui/src/develop.rs:6397`](../ui/dr-ui/src/develop.rs#L6397), [`ui/dr-ui/src/develop.rs:6416`](../ui/dr-ui/src/develop.rs#L6416), [`ui/dr-ui/src/develop.rs:827`](../ui/dr-ui/src/develop.rs#L827), [`ui/dr-ui/src/display_ui.rs:192`](../ui/dr-ui/src/display_ui.rs#L192), [`ui/dr-ui/src/display_ui.rs:1`](../ui/dr-ui/src/display_ui.rs#L1), [`ui/dr-ui/src/display_ui.rs:325`](../ui/dr-ui/src/display_ui.rs#L325), [`ui/dr-ui/src/display_ui.rs:346`](../ui/dr-ui/src/display_ui.rs#L346), [`ui/dr-ui/src/display_ui.rs:379`](../ui/dr-ui/src/display_ui.rs#L379), [`ui/dr-ui/src/lib.rs:1576`](../ui/dr-ui/src/lib.rs#L1576), [`ui/dr-ui/src/lib.rs:1615`](../ui/dr-ui/src/lib.rs#L1615), [`ui/dr-ui/src/lib.rs:3038`](../ui/dr-ui/src/lib.rs#L3038), [`ui/dr-ui/src/lib.rs:3125`](../ui/dr-ui/src/lib.rs#L3125), [`ui/dr-ui/ui/app.slint:1773`](../ui/dr-ui/ui/app.slint#L1773), [`ui/dr-ui/ui/app.slint:53`](../ui/dr-ui/ui/app.slint#L53), [`ui/dr-ui/ui/settings.slint:124`](../ui/dr-ui/ui/settings.slint#L124), [`ui/dr-ui/ui/settings.slint:794`](../ui/dr-ui/ui/settings.slint#L794) | | FR-EXP-1 | [`core/dr-export/src/encode.rs:1`](../core/dr-export/src/encode.rs#L1), [`core/dr-export/src/lib.rs:1`](../core/dr-export/src/lib.rs#L1), [`core/dr-types/src/settings.rs:1`](../core/dr-types/src/settings.rs#L1), [`ui/dr-ui/src/settings_ui.rs:1`](../ui/dr-ui/src/settings_ui.rs#L1) | -| FR-EXP-2 | [`core/dr-export/src/encode.rs:1`](../core/dr-export/src/encode.rs#L1), [`core/dr-export/src/error.rs:26`](../core/dr-export/src/error.rs#L26), [`core/dr-export/src/icc.rs:1`](../core/dr-export/src/icc.rs#L1), [`core/dr-export/src/lib.rs:153`](../core/dr-export/src/lib.rs#L153), [`core/dr-export/src/lib.rs:1`](../core/dr-export/src/lib.rs#L1), [`core/dr-export/src/lib.rs:53`](../core/dr-export/src/lib.rs#L53), [`core/dr-gpu/src/adjust.rs:2436`](../core/dr-gpu/src/adjust.rs#L2436), [`core/dr-pipeline/src/graph.rs:538`](../core/dr-pipeline/src/graph.rs#L538), [`core/dr-pipeline/src/graph.rs:592`](../core/dr-pipeline/src/graph.rs#L592), [`core/dr-pipeline/src/operation.rs:483`](../core/dr-pipeline/src/operation.rs#L483), [`core/dr-types/src/colour.rs:1`](../core/dr-types/src/colour.rs#L1), [`core/dr-types/src/settings.rs:1`](../core/dr-types/src/settings.rs#L1), [`core/dr-types/src/settings.rs:713`](../core/dr-types/src/settings.rs#L713), [`ui/dr-ui/src/develop.rs:6379`](../ui/dr-ui/src/develop.rs#L6379), [`ui/dr-ui/src/settings_ui.rs:1`](../ui/dr-ui/src/settings_ui.rs#L1) | +| FR-EXP-2 | [`core/dr-export/src/encode.rs:1`](../core/dr-export/src/encode.rs#L1), [`core/dr-export/src/error.rs:26`](../core/dr-export/src/error.rs#L26), [`core/dr-export/src/icc.rs:1`](../core/dr-export/src/icc.rs#L1), [`core/dr-export/src/lib.rs:153`](../core/dr-export/src/lib.rs#L153), [`core/dr-export/src/lib.rs:1`](../core/dr-export/src/lib.rs#L1), [`core/dr-export/src/lib.rs:53`](../core/dr-export/src/lib.rs#L53), [`core/dr-gpu/src/adjust.rs:2436`](../core/dr-gpu/src/adjust.rs#L2436), [`core/dr-pipeline/src/graph.rs:538`](../core/dr-pipeline/src/graph.rs#L538), [`core/dr-pipeline/src/graph.rs:592`](../core/dr-pipeline/src/graph.rs#L592), [`core/dr-pipeline/src/operation.rs:483`](../core/dr-pipeline/src/operation.rs#L483), [`core/dr-types/src/colour.rs:1`](../core/dr-types/src/colour.rs#L1), [`core/dr-types/src/settings.rs:1`](../core/dr-types/src/settings.rs#L1), [`core/dr-types/src/settings.rs:713`](../core/dr-types/src/settings.rs#L713), [`ui/dr-ui/src/develop.rs:6416`](../ui/dr-ui/src/develop.rs#L6416), [`ui/dr-ui/src/settings_ui.rs:1`](../ui/dr-ui/src/settings_ui.rs#L1) | | FR-EXP-3 | [`core/dr-export/src/lib.rs:182`](../core/dr-export/src/lib.rs#L182), [`core/dr-export/src/lib.rs:1`](../core/dr-export/src/lib.rs#L1), [`core/dr-export/src/size.rs:136`](../core/dr-export/src/size.rs#L136), [`core/dr-export/src/size.rs:1`](../core/dr-export/src/size.rs#L1), [`core/dr-export/src/size.rs:25`](../core/dr-export/src/size.rs#L25), [`core/dr-export/src/size.rs:84`](../core/dr-export/src/size.rs#L84), [`core/dr-types/src/settings.rs:1`](../core/dr-types/src/settings.rs#L1), [`core/dr-types/src/settings.rs:758`](../core/dr-types/src/settings.rs#L758), [`core/dr-types/src/settings.rs:766`](../core/dr-types/src/settings.rs#L766), [`core/dr-types/src/settings.rs:782`](../core/dr-types/src/settings.rs#L782), [`core/dr-types/src/settings.rs:851`](../core/dr-types/src/settings.rs#L851), [`core/dr-types/src/settings.rs:879`](../core/dr-types/src/settings.rs#L879), [`core/dr-types/src/settings.rs:890`](../core/dr-types/src/settings.rs#L890), [`core/dr-types/src/settings.rs:896`](../core/dr-types/src/settings.rs#L896), [`ui/dr-ui/src/settings_ui.rs:1`](../ui/dr-ui/src/settings_ui.rs#L1), [`ui/dr-ui/src/settings_ui.rs:207`](../ui/dr-ui/src/settings_ui.rs#L207), [`ui/dr-ui/src/settings_ui.rs:220`](../ui/dr-ui/src/settings_ui.rs#L220), [`ui/dr-ui/src/settings_ui.rs:235`](../ui/dr-ui/src/settings_ui.rs#L235), [`ui/dr-ui/src/settings_ui.rs:565`](../ui/dr-ui/src/settings_ui.rs#L565), [`ui/dr-ui/ui/settings.slint:697`](../ui/dr-ui/ui/settings.slint#L697), [`ui/dr-ui/ui/settings.slint:707`](../ui/dr-ui/ui/settings.slint#L707) | | FR-EXP-4 | [`core/dr-export/src/lib.rs:1`](../core/dr-export/src/lib.rs#L1), [`core/dr-export/src/sharpen.rs:1`](../core/dr-export/src/sharpen.rs#L1), [`core/dr-export/src/size.rs:1`](../core/dr-export/src/size.rs#L1), [`ui/dr-ui/src/settings_ui.rs:1`](../ui/dr-ui/src/settings_ui.rs#L1) | | FR-EXP-5 | [`ui/dr-ui/src/settings_store.rs:1`](../ui/dr-ui/src/settings_store.rs#L1) | | FR-EXP-6 | [`core/dr-export/src/lib.rs:1`](../core/dr-export/src/lib.rs#L1), [`core/dr-export/src/name.rs:1`](../core/dr-export/src/name.rs#L1), [`core/dr-types/src/settings.rs:1`](../core/dr-types/src/settings.rs#L1), [`ui/dr-ui/src/export.rs:1`](../ui/dr-ui/src/export.rs#L1), [`ui/dr-ui/src/lib.rs:451`](../ui/dr-ui/src/lib.rs#L451), [`ui/dr-ui/src/settings_ui.rs:1`](../ui/dr-ui/src/settings_ui.rs#L1), [`ui/dr-ui/src/settings_ui.rs:49`](../ui/dr-ui/src/settings_ui.rs#L49), [`ui/dr-ui/src/settings_ui.rs:679`](../ui/dr-ui/src/settings_ui.rs#L679) | | FR-EXP-7 | [`ui/dr-ui/src/activity.rs:83`](../ui/dr-ui/src/activity.rs#L83), [`ui/dr-ui/src/export.rs:1`](../ui/dr-ui/src/export.rs#L1), [`ui/dr-ui/src/export.rs:942`](../ui/dr-ui/src/export.rs#L942), [`ui/dr-ui/src/lib.rs:230`](../ui/dr-ui/src/lib.rs#L230), [`ui/dr-ui/src/lib.rs:2370`](../ui/dr-ui/src/lib.rs#L2370), [`ui/dr-ui/src/lib.rs:451`](../ui/dr-ui/src/lib.rs#L451), [`ui/dr-ui/src/lib.rs:486`](../ui/dr-ui/src/lib.rs#L486), [`ui/dr-ui/src/lib.rs:513`](../ui/dr-ui/src/lib.rs#L513), [`ui/dr-ui/src/library_ui.rs:3749`](../ui/dr-ui/src/library_ui.rs#L3749), [`ui/dr-ui/src/library_ui.rs:591`](../ui/dr-ui/src/library_ui.rs#L591), [`ui/dr-ui/src/library_ui.rs:691`](../ui/dr-ui/src/library_ui.rs#L691), [`ui/dr-ui/src/library_ui.rs:6935`](../ui/dr-ui/src/library_ui.rs#L6935), [`ui/dr-ui/src/library_ui.rs:7012`](../ui/dr-ui/src/library_ui.rs#L7012), [`ui/dr-ui/src/library_ui.rs:7024`](../ui/dr-ui/src/library_ui.rs#L7024), [`ui/dr-ui/src/library_ui.rs:748`](../ui/dr-ui/src/library_ui.rs#L748), [`ui/dr-ui/ui/app.slint:1099`](../ui/dr-ui/ui/app.slint#L1099), [`ui/dr-ui/ui/app.slint:1585`](../ui/dr-ui/ui/app.slint#L1585), [`ui/dr-ui/ui/library.slint:1469`](../ui/dr-ui/ui/library.slint#L1469), [`ui/dr-ui/ui/library.slint:4019`](../ui/dr-ui/ui/library.slint#L4019) | | FR-EXP-8 | [`core/dr-decode/src/lib.rs:326`](../core/dr-decode/src/lib.rs#L326), [`core/dr-decode/src/lib.rs:350`](../core/dr-decode/src/lib.rs#L350), [`core/dr-decode/src/lib.rs:364`](../core/dr-decode/src/lib.rs#L364), [`core/dr-decode/src/lib.rs:71`](../core/dr-decode/src/lib.rs#L71), [`core/dr-decode/src/lib.rs:79`](../core/dr-decode/src/lib.rs#L79), [`core/dr-decode/src/lib.rs:82`](../core/dr-decode/src/lib.rs#L82), [`core/dr-decode/src/locate.rs:1164`](../core/dr-decode/src/locate.rs#L1164), [`core/dr-decode/src/locate.rs:1223`](../core/dr-decode/src/locate.rs#L1223), [`core/dr-decode/src/locate.rs:316`](../core/dr-decode/src/locate.rs#L316), [`core/dr-decode/src/locate.rs:487`](../core/dr-decode/src/locate.rs#L487), [`core/dr-decode/src/locate.rs:571`](../core/dr-decode/src/locate.rs#L571), [`core/dr-decode/src/locate.rs:584`](../core/dr-decode/src/locate.rs#L584), [`core/dr-decode/src/locate.rs:667`](../core/dr-decode/src/locate.rs#L667), [`core/dr-export/examples/export.rs:99`](../core/dr-export/examples/export.rs#L99), [`core/dr-export/src/encode.rs:117`](../core/dr-export/src/encode.rs#L117), [`core/dr-export/src/encode.rs:161`](../core/dr-export/src/encode.rs#L161), [`core/dr-export/src/encode.rs:1`](../core/dr-export/src/encode.rs#L1), [`core/dr-export/src/encode.rs:206`](../core/dr-export/src/encode.rs#L206), [`core/dr-export/src/encode.rs:235`](../core/dr-export/src/encode.rs#L235), [`core/dr-export/src/encode.rs:311`](../core/dr-export/src/encode.rs#L311), [`core/dr-export/src/encode.rs:325`](../core/dr-export/src/encode.rs#L325), [`core/dr-export/src/encode.rs:408`](../core/dr-export/src/encode.rs#L408), [`core/dr-export/src/encode.rs:456`](../core/dr-export/src/encode.rs#L456), [`core/dr-export/src/encode.rs:70`](../core/dr-export/src/encode.rs#L70), [`core/dr-export/src/encode.rs:795`](../core/dr-export/src/encode.rs#L795), [`core/dr-export/src/encode.rs:809`](../core/dr-export/src/encode.rs#L809), [`core/dr-export/src/encode.rs:850`](../core/dr-export/src/encode.rs#L850), [`core/dr-export/src/encode.rs:898`](../core/dr-export/src/encode.rs#L898), [`core/dr-export/src/exif.rs:1`](../core/dr-export/src/exif.rs#L1), [`core/dr-export/src/lib.rs:136`](../core/dr-export/src/lib.rs#L136), [`core/dr-export/src/metadata.rs:1`](../core/dr-export/src/metadata.rs#L1), [`core/dr-export/src/metadata.rs:41`](../core/dr-export/src/metadata.rs#L41), [`core/dr-export/src/metadata.rs:74`](../core/dr-export/src/metadata.rs#L74), [`core/dr-types/src/lib.rs:653`](../core/dr-types/src/lib.rs#L653), [`core/dr-types/src/settings.rs:426`](../core/dr-types/src/settings.rs#L426), [`ui/dr-ui/src/export.rs:619`](../ui/dr-ui/src/export.rs#L619), [`ui/dr-ui/src/export.rs:647`](../ui/dr-ui/src/export.rs#L647), [`ui/dr-ui/src/export.rs:777`](../ui/dr-ui/src/export.rs#L777), [`ui/dr-ui/src/export.rs:794`](../ui/dr-ui/src/export.rs#L794), [`ui/dr-ui/src/settings_ui.rs:1`](../ui/dr-ui/src/settings_ui.rs#L1) | -| FR-EXP-9 | [`core/dr-decode/src/lib.rs:506`](../core/dr-decode/src/lib.rs#L506), [`core/dr-export/src/lib.rs:128`](../core/dr-export/src/lib.rs#L128), [`core/dr-export/src/lib.rs:1`](../core/dr-export/src/lib.rs#L1), [`core/dr-gpu/src/adjust.rs:1106`](../core/dr-gpu/src/adjust.rs#L1106), [`ui/dr-ui/examples/face_native.rs:1`](../ui/dr-ui/examples/face_native.rs#L1), [`ui/dr-ui/src/develop.rs:3340`](../ui/dr-ui/src/develop.rs#L3340), [`ui/dr-ui/src/lib.rs:451`](../ui/dr-ui/src/lib.rs#L451), [`ui/dr-ui/src/library.rs:3058`](../ui/dr-ui/src/library.rs#L3058), [`ui/dr-ui/src/library.rs:3423`](../ui/dr-ui/src/library.rs#L3423), [`ui/dr-ui/src/library.rs:3462`](../ui/dr-ui/src/library.rs#L3462) | +| FR-EXP-9 | [`core/dr-decode/src/lib.rs:506`](../core/dr-decode/src/lib.rs#L506), [`core/dr-export/src/lib.rs:128`](../core/dr-export/src/lib.rs#L128), [`core/dr-export/src/lib.rs:1`](../core/dr-export/src/lib.rs#L1), [`core/dr-gpu/src/adjust.rs:1106`](../core/dr-gpu/src/adjust.rs#L1106), [`ui/dr-ui/examples/face_native.rs:1`](../ui/dr-ui/examples/face_native.rs#L1), [`ui/dr-ui/src/develop.rs:3340`](../ui/dr-ui/src/develop.rs#L3340), [`ui/dr-ui/src/develop.rs:3378`](../ui/dr-ui/src/develop.rs#L3378), [`ui/dr-ui/src/lib.rs:451`](../ui/dr-ui/src/lib.rs#L451), [`ui/dr-ui/src/library.rs:3058`](../ui/dr-ui/src/library.rs#L3058), [`ui/dr-ui/src/library.rs:3423`](../ui/dr-ui/src/library.rs#L3423), [`ui/dr-ui/src/library.rs:3462`](../ui/dr-ui/src/library.rs#L3462), [`ui/dr-ui/tests/export_ignores_the_viewport.rs:1`](../ui/dr-ui/tests/export_ignores_the_viewport.rs#L1) | | FR-NC-1 | [`core/dr-sync-nextcloud/src/auth.rs:132`](../core/dr-sync-nextcloud/src/auth.rs#L132), [`core/dr-sync-nextcloud/src/auth.rs:44`](../core/dr-sync-nextcloud/src/auth.rs#L44), [`core/dr-sync-nextcloud/src/provider.rs:1`](../core/dr-sync-nextcloud/src/provider.rs#L1), [`core/dr-sync/src/account.rs:355`](../core/dr-sync/src/account.rs#L355), [`ui/dr-ui/src/launch.rs:277`](../ui/dr-ui/src/launch.rs#L277), [`ui/dr-ui/src/launch.rs:61`](../ui/dr-ui/src/launch.rs#L61), [`ui/dr-ui/src/launch_ui.rs:417`](../ui/dr-ui/src/launch_ui.rs#L417) | | FR-NC-10 | [`core/dr-sync/src/account.rs:220`](../core/dr-sync/src/account.rs#L220), [`ui/dr-ui/src/export.rs:1`](../ui/dr-ui/src/export.rs#L1), [`ui/dr-ui/src/lib.rs:513`](../ui/dr-ui/src/lib.rs#L513), [`ui/dr-ui/src/library.rs:1101`](../ui/dr-ui/src/library.rs#L1101), [`ui/dr-ui/src/library.rs:1939`](../ui/dr-ui/src/library.rs#L1939), [`ui/dr-ui/src/library.rs:576`](../ui/dr-ui/src/library.rs#L576), [`ui/dr-ui/src/library.rs:877`](../ui/dr-ui/src/library.rs#L877), [`ui/dr-ui/src/library_ui.rs:1892`](../ui/dr-ui/src/library_ui.rs#L1892), [`ui/dr-ui/src/library_ui.rs:3749`](../ui/dr-ui/src/library_ui.rs#L3749), [`ui/dr-ui/src/library_ui.rs:532`](../ui/dr-ui/src/library_ui.rs#L532), [`ui/dr-ui/src/sidecar_cache.rs:1`](../ui/dr-ui/src/sidecar_cache.rs#L1) | | FR-NC-12 | [`core/dr-sync-folder/src/lib.rs:1`](../core/dr-sync-folder/src/lib.rs#L1), [`core/dr-sync-nextcloud/src/lib.rs:40`](../core/dr-sync-nextcloud/src/lib.rs#L40), [`core/dr-sync-nextcloud/src/lib.rs:914`](../core/dr-sync-nextcloud/src/lib.rs#L914), [`core/dr-sync-nextcloud/src/provider.rs:1`](../core/dr-sync-nextcloud/src/provider.rs#L1), [`core/dr-sync/src/account.rs:1`](../core/dr-sync/src/account.rs#L1), [`core/dr-sync/src/account.rs:81`](../core/dr-sync/src/account.rs#L81), [`core/dr-sync/src/lib.rs:218`](../core/dr-sync/src/lib.rs#L218), [`core/dr-sync/src/lib.rs:51`](../core/dr-sync/src/lib.rs#L51), [`core/dr-sync/src/provider.rs:106`](../core/dr-sync/src/provider.rs#L106), [`core/dr-sync/src/provider.rs:1`](../core/dr-sync/src/provider.rs#L1), [`core/dr-sync/src/provider.rs:53`](../core/dr-sync/src/provider.rs#L53), [`core/dr-sync/src/reachability.rs:1`](../core/dr-sync/src/reachability.rs#L1), [`ui/dr-ui/src/remote.rs:1`](../ui/dr-ui/src/remote.rs#L1) | @@ -125,7 +125,7 @@ _None._ | FR-UI-4 | [`tools/traceability/src/gestures.rs:1`](../tools/traceability/src/gestures.rs#L1), [`ui/dr-ui/src/collections_ui.rs:1045`](../ui/dr-ui/src/collections_ui.rs#L1045), [`ui/dr-ui/src/collections_ui.rs:1055`](../ui/dr-ui/src/collections_ui.rs#L1055), [`ui/dr-ui/src/collections_ui.rs:116`](../ui/dr-ui/src/collections_ui.rs#L116), [`ui/dr-ui/src/collections_ui.rs:117`](../ui/dr-ui/src/collections_ui.rs#L117), [`ui/dr-ui/src/collections_ui.rs:126`](../ui/dr-ui/src/collections_ui.rs#L126), [`ui/dr-ui/src/collections_ui.rs:154`](../ui/dr-ui/src/collections_ui.rs#L154), [`ui/dr-ui/src/collections_ui.rs:1552`](../ui/dr-ui/src/collections_ui.rs#L1552), [`ui/dr-ui/src/collections_ui.rs:1569`](../ui/dr-ui/src/collections_ui.rs#L1569), [`ui/dr-ui/src/collections_ui.rs:1685`](../ui/dr-ui/src/collections_ui.rs#L1685), [`ui/dr-ui/src/collections_ui.rs:1821`](../ui/dr-ui/src/collections_ui.rs#L1821), [`ui/dr-ui/src/collections_ui.rs:1848`](../ui/dr-ui/src/collections_ui.rs#L1848), [`ui/dr-ui/src/collections_ui.rs:1964`](../ui/dr-ui/src/collections_ui.rs#L1964), [`ui/dr-ui/src/collections_ui.rs:2926`](../ui/dr-ui/src/collections_ui.rs#L2926), [`ui/dr-ui/src/collections_ui.rs:2963`](../ui/dr-ui/src/collections_ui.rs#L2963), [`ui/dr-ui/src/collections_ui.rs:365`](../ui/dr-ui/src/collections_ui.rs#L365), [`ui/dr-ui/src/collections_ui.rs:569`](../ui/dr-ui/src/collections_ui.rs#L569), [`ui/dr-ui/src/collections_ui.rs:589`](../ui/dr-ui/src/collections_ui.rs#L589), [`ui/dr-ui/src/gesture_book.rs:3`](../ui/dr-ui/src/gesture_book.rs#L3), [`ui/dr-ui/src/gestures.rs:1`](../ui/dr-ui/src/gestures.rs#L1), [`ui/dr-ui/src/library_ui.rs:4795`](../ui/dr-ui/src/library_ui.rs#L4795), [`ui/dr-ui/src/library_ui.rs:4807`](../ui/dr-ui/src/library_ui.rs#L4807), [`ui/dr-ui/src/library_ui.rs:4861`](../ui/dr-ui/src/library_ui.rs#L4861), [`ui/dr-ui/src/library_ui.rs:4964`](../ui/dr-ui/src/library_ui.rs#L4964), [`ui/dr-ui/src/library_ui.rs:4992`](../ui/dr-ui/src/library_ui.rs#L4992), [`ui/dr-ui/src/library_ui.rs:5821`](../ui/dr-ui/src/library_ui.rs#L5821), [`ui/dr-ui/src/library_ui.rs:5833`](../ui/dr-ui/src/library_ui.rs#L5833), [`ui/dr-ui/ui/app.slint:1862`](../ui/dr-ui/ui/app.slint#L1862), [`ui/dr-ui/ui/app.slint:542`](../ui/dr-ui/ui/app.slint#L542), [`ui/dr-ui/ui/app.slint:571`](../ui/dr-ui/ui/app.slint#L571), [`ui/dr-ui/ui/app.slint:580`](../ui/dr-ui/ui/app.slint#L580), [`ui/dr-ui/ui/app.slint:665`](../ui/dr-ui/ui/app.slint#L665), [`ui/dr-ui/ui/gestures.slint:1`](../ui/dr-ui/ui/gestures.slint#L1), [`ui/dr-ui/ui/library.slint:1148`](../ui/dr-ui/ui/library.slint#L1148), [`ui/dr-ui/ui/library.slint:1173`](../ui/dr-ui/ui/library.slint#L1173), [`ui/dr-ui/ui/library.slint:1180`](../ui/dr-ui/ui/library.slint#L1180), [`ui/dr-ui/ui/library.slint:1213`](../ui/dr-ui/ui/library.slint#L1213), [`ui/dr-ui/ui/library.slint:1270`](../ui/dr-ui/ui/library.slint#L1270), [`ui/dr-ui/ui/library.slint:1277`](../ui/dr-ui/ui/library.slint#L1277), [`ui/dr-ui/ui/library.slint:2461`](../ui/dr-ui/ui/library.slint#L2461), [`ui/dr-ui/ui/library.slint:3941`](../ui/dr-ui/ui/library.slint#L3941), [`ui/dr-ui/ui/library.slint:4057`](../ui/dr-ui/ui/library.slint#L4057), [`ui/dr-ui/ui/library.slint:856`](../ui/dr-ui/ui/library.slint#L856), [`ui/dr-ui/ui/library.slint:883`](../ui/dr-ui/ui/library.slint#L883), [`ui/dr-ui/ui/library.slint:889`](../ui/dr-ui/ui/library.slint#L889), [`ui/dr-ui/ui/library.slint:944`](../ui/dr-ui/ui/library.slint#L944) | | FR-UI-5 | [`ui/dr-ui/src/collections_ui.rs:1`](../ui/dr-ui/src/collections_ui.rs#L1), [`ui/dr-ui/src/lib.rs:2707`](../ui/dr-ui/src/lib.rs#L2707), [`ui/dr-ui/src/lib.rs:3318`](../ui/dr-ui/src/lib.rs#L3318), [`ui/dr-ui/src/lib.rs:3503`](../ui/dr-ui/src/lib.rs#L3503), [`ui/dr-ui/src/masks_ui.rs:931`](../ui/dr-ui/src/masks_ui.rs#L931), [`ui/dr-ui/ui/app.slint:121`](../ui/dr-ui/ui/app.slint#L121), [`ui/dr-ui/ui/collections.slint:4`](../ui/dr-ui/ui/collections.slint#L4) | | FR-UI-6 | [`ui/dr-ui/ui/widgets.slint:1`](../ui/dr-ui/ui/widgets.slint#L1) | -| FR-UI-7 | [`core/dr-pipeline/src/descriptor.rs:177`](../core/dr-pipeline/src/descriptor.rs#L177), [`core/dr-pipeline/src/framing.rs:385`](../core/dr-pipeline/src/framing.rs#L385) | +| FR-UI-7 | [`core/dr-pipeline/src/descriptor.rs:177`](../core/dr-pipeline/src/descriptor.rs#L177), [`core/dr-pipeline/src/framing.rs:395`](../core/dr-pipeline/src/framing.rs#L395) | | NFR-A11Y-2 | [`ui/dr-ui/tests/ui_controls_are_accessible.rs:1`](../ui/dr-ui/tests/ui_controls_are_accessible.rs#L1) | | NFR-A11Y-3 | [`ui/dr-ui/src/histogram.rs:356`](../ui/dr-ui/src/histogram.rs#L356), [`ui/dr-ui/ui/histogram.slint:137`](../ui/dr-ui/ui/histogram.slint#L137), [`ui/dr-ui/ui/library.slint:652`](../ui/dr-ui/ui/library.slint#L652), [`ui/dr-ui/ui/library.slint:800`](../ui/dr-ui/ui/library.slint#L800), [`ui/dr-ui/ui/peaking.slint:1`](../ui/dr-ui/ui/peaking.slint#L1) | | NFR-ARCH-2 | [`core/dr-catalog/src/jobs.rs:1`](../core/dr-catalog/src/jobs.rs#L1), [`ui/dr-ui/src/faces.rs:1`](../ui/dr-ui/src/faces.rs#L1), [`ui/dr-ui/src/library.rs:3058`](../ui/dr-ui/src/library.rs#L3058) | diff --git a/ui/dr-ui/src/develop.rs b/ui/dr-ui/src/develop.rs index 199655a..13b2bbb 100644 --- a/ui/dr-ui/src/develop.rs +++ b/ui/dr-ui/src/develop.rs @@ -3371,13 +3371,53 @@ impl DevelopSession { let (sw, sh) = self.demosaiced.size(); let (w, h) = self.graph.output_size(sw, sh); - let shader = self.graph.compose_for(space); - self.render_with_masks(&shader, w, h, space)?; - - let (pixels, rw, rh) = self.adjust.export_pixels().map_err(|e| e.to_string())?; + let (pixels, rw, rh) = self.render_the_file(w, h, space)?; dr_export::Frame::in_space(rw, rh, pixels, space).map_err(|e| e.to_string()) } + /// TRACES: FR-EXP-9 | FR-CAT-9 + /// Render the *photograph*, with the viewport suspended, and read it back. + /// + /// **The one thing separating a file from a frame on screen**, and the + /// reason both file-producing paths go through here rather than composing + /// for themselves. [`Framing::view`](../dr_pipeline/framing/struct.Framing.html#method.view) + /// is not an edit — it is kept out of the sidecar, out of `is_active` and + /// out of `output_size` precisely so that zooming cannot change what the + /// file becomes. But it is folded into `visible_rect`, which is the rect + /// the fused shader's prologue samples, so a path that composes the graph + /// and renders it inherits the zoom whether or not it wanted it. Exporting + /// at 4:1 wrote the middle of the frame magnified to fill the file, at the + /// full output size, with the detail kernels scaled four times over — + /// silently, since every dimension the old guard checked still held. + /// + /// Suspended rather than refused: an export is a thing the photographer + /// asks for *while* inspecting a highlight at 4×, and demanding they zoom + /// out first would be answering a question nobody asked. + /// + /// Restored whatever happens, for the reason [`Self::render_uncropped`] + /// restores it: leaving the graph un-zoomed after a failed export would + /// throw away where the photographer was looking. + fn render_the_file( + &mut self, + w: u32, + h: u32, + space: dr_types::ColourSpace, + ) -> Result<(Vec, u32, u32), String> { + let saved_view = self.graph.framing().view(); + self.graph.framing_mut().set_view(CropRect::default()); + + // Composed *inside* the suspension: the view reaches the shader as a + // uniform baked at composition, so composing before this point would + // restore the framing and export the zoom anyway. + let shader = self.graph.compose_for(space); + let rendered = self.render_with_masks(&shader, w, h, space); + + self.graph.framing_mut().set_view(saved_view); + rendered?; + + self.adjust.export_pixels().map_err(|e| e.to_string()) + } + /// TRACES: FR-CAT-9 /// Render this edit small, for the grid's thumbnail. /// @@ -3594,10 +3634,7 @@ impl DevelopSession { let (fw, fh) = self.graph.output_size(sw, sh); let (w, h) = fit(fw, fh, edge.max(1), edge.max(1)); - let shader = self.graph.compose_for(dr_types::ColourSpace::Srgb); - self.render_with_masks(&shader, w, h, dr_types::ColourSpace::Srgb)?; - - let (pixels, rw, rh) = self.adjust.export_pixels().map_err(|e| e.to_string())?; + let (pixels, rw, rh) = self.render_the_file(w, h, dr_types::ColourSpace::Srgb)?; Ok((rw, rh, pixels)) } diff --git a/ui/dr-ui/tests/export_ignores_the_viewport.rs b/ui/dr-ui/tests/export_ignores_the_viewport.rs new file mode 100644 index 0000000..14cac1c --- /dev/null +++ b/ui/dr-ui/tests/export_ignores_the_viewport.rs @@ -0,0 +1,123 @@ +//! TRACES: FR-EXP-9 | FR-CAT-9 +//! Does an export render what the file is, or what the canvas is showing? +//! +//! FR-EXP-9 says an export uses the full-quality pipeline "regardless of what +//! the display was showing", and `Framing::view` is documented as "not an +//! edit" — kept out of the sidecar, out of `is_active`, out of the output +//! size, "so a zoomed view exports exactly as an unzoomed one does". +//! +//! It is folded into `visible_rect()` all the same, and that is the rect the +//! fused shader's prologue samples. So anything that composes the graph and +//! renders it inherits the zoom whether or not it wanted it. +//! `DevelopSession::render_uncropped` saves and restores the view for exactly +//! this reason; `render_for_export` and `render_thumbnail` do not. +//! +//! The framing crate's own guard, `zooming_does_not_change_the_exported +//! _image`, asserts only that the output *size* and the crop are untouched. +//! Both survive; the pixels do not, which is why this test is at the session +//! level where a render actually happens. + +use dr_gpu::GpuContext; +use dr_types::{ColourSpace, Orientation}; +use dr_ui::DevelopSession; + +fn headless() -> Option { + pollster::block_on(GpuContext::new_headless()).ok() +} + +/// A ramp, not a pattern of quadrants. +/// +/// Worth stating because the first version of this test used quadrants and +/// passed: a four-quadrant frame is self-similar under a centred zoom — the +/// middle quarter of it is four quadrants again — so it cannot tell a zoomed +/// render from an unzoomed one. A monotonic ramp can. The centre quarter of +/// it spans a narrow band of values, magnified across the whole target. +fn ramp(w: u32, h: u32) -> Vec { + let mut rgba = Vec::with_capacity((w * h * 4) as usize); + for y in 0..h { + for x in 0..w { + rgba.extend_from_slice(&[ + (x * 255 / w.max(1)) as u8, + (y * 255 / h.max(1)) as u8, + // A fine stripe, so a magnification shows as well as a shift. + if x % 4 < 2 { 200 } else { 40 }, + 255, + ]); + } + } + rgba +} + +/// The span of the red channel across the top row — the ramp's full sweep on +/// an unzoomed frame, and a narrow slice of it on a zoomed one. +/// +/// Compared instead of the buffers themselves because a failure that prints +/// 16 KB of pixels says nothing a reader can act on, and this says which part +/// of the photograph came out. +fn top_row_span(rgba: &[u8], width: u32) -> (u8, u8) { + let row = &rgba[..(width as usize) * 4]; + let reds = row.iter().step_by(4); + ( + reds.clone().copied().min().unwrap_or(0), + reds.copied().max().unwrap_or(0), + ) +} + +#[test] +fn an_export_is_the_same_frame_whether_or_not_the_canvas_is_zoomed() { + let Some(ctx) = headless() else { return }; + let mut session = DevelopSession::open_rgb(&ctx, &ramp(64, 64), 64, 64, Orientation::NORMAL) + .expect("session"); + + let unzoomed = session + .render_for_export(ColourSpace::Srgb) + .expect("export"); + let before = top_row_span(&unzoomed.rgba, unzoomed.width); + + // What a scroll wheel over the middle of the canvas does. + session.zoom_about(4.0, 0.5, 0.5); + assert!(session.is_zoomed(), "the session did not take the zoom"); + + let zoomed = session + .render_for_export(ColourSpace::Srgb) + .expect("export"); + let after = top_row_span(&zoomed.rgba, zoomed.width); + + assert_eq!( + (unzoomed.width, unzoomed.height), + (zoomed.width, zoomed.height), + "the export changed size with the zoom" + ); + assert_eq!( + before, after, + "the export followed the viewport: unzoomed it swept the ramp {before:?}, \ + zoomed it wrote {after:?} — the middle of the frame, magnified to fill the file" + ); + assert_eq!( + unzoomed.rgba, zoomed.rgba, + "the exported pixels changed when only the viewport moved" + ); +} + +#[test] +fn a_thumbnail_is_the_same_frame_whether_or_not_the_canvas_is_zoomed() { + let Some(ctx) = headless() else { return }; + let mut session = DevelopSession::open_rgb(&ctx, &ramp(64, 64), 64, 64, Orientation::NORMAL) + .expect("session"); + + let (w, _, unzoomed) = session.render_thumbnail(32).expect("thumbnail"); + let before = top_row_span(&unzoomed, w); + + session.zoom_about(4.0, 0.5, 0.5); + let (_, _, zoomed) = session.render_thumbnail(32).expect("thumbnail"); + let after = top_row_span(&zoomed, w); + + assert_eq!( + before, after, + "the grid's thumbnail followed the viewport: {before:?} unzoomed against {after:?} zoomed" + ); + assert_eq!( + unzoomed, zoomed, + "the thumbnail's pixels moved with the view" + ); +}