diff --git a/core/dr-pano/build.rs b/core/dr-pano/build.rs index 4d7de34..2d03f8f 100644 --- a/core/dr-pano/build.rs +++ b/core/dr-pano/build.rs @@ -8,20 +8,31 @@ use std::path::Path; -const MODEL: &str = "../../models/keypoints/xfeat-1024.onnx"; +const MODELS: &[&str] = &[ + "../../models/keypoints/xfeat-1024.onnx", + "../../models/keypoints/xfeat-768.onnx", +]; fn main() { - println!("cargo:rerun-if-changed={MODEL}"); + for m in MODELS { + println!("cargo:rerun-if-changed={m}"); + } println!("cargo:rerun-if-changed=build.rs"); if std::env::var_os("CARGO_FEATURE_EMBEDDED_MODEL").is_none() { return; } - let path = Path::new(MODEL); + for model in MODELS.iter().copied() { + check(model); + } +} + +fn check(model: &str) { + let path = Path::new(model); let Ok(bytes) = std::fs::read(path) else { panic!( - "\n\n{MODEL} is missing.\n\ + "\n\n{model} is missing.\n\ It ships in Git LFS. Run `git lfs install && git lfs pull`, or build \ with `--no-default-features` for a geometry-only build.\n" ); @@ -29,7 +40,7 @@ fn main() { if bytes.starts_with(b"version https://git-lfs.github.com/spec/") { panic!( - "\n\n{MODEL} is a Git LFS pointer, not the model.\n\ + "\n\n{model} is a Git LFS pointer, not the model.\n\ Run `git lfs install && git lfs pull`, or build with \ `--no-default-features` for a geometry-only build.\n" ); diff --git a/core/dr-pano/examples/align.rs b/core/dr-pano/examples/align.rs new file mode 100644 index 0000000..5cf8184 --- /dev/null +++ b/core/dr-pano/examples/align.rs @@ -0,0 +1,172 @@ +//! Align real frames from their embedded previews and draw the result. +//! +//! ```sh +//! cargo run -p dr-pano --example align --release -- fixtures/pano/2025-08-05/*.CR2 +//! cargo run -p dr-pano --example align --release -- out-prefix frame1.CR2 frame2.CR2 … +//! ``` +//! +//! The point of looking rather than asserting: a rotation solve that is +//! numerically converged and geometrically wrong — a mirrored axis, a +//! transposed homography, an orientation applied the wrong way — produces +//! perfectly plausible residuals and a picture that is obviously broken. +//! This writes `-cyl.ppm`: every frame's preview warped onto a +//! cylinder and averaged where they overlap, at a size that fits on a +//! screen. Ghosting in the overlaps is the alignment error, made visible. +//! +//! Previews, not RAW: the alignment runs on proxies in the application too +//! (FR-MRG-7), and a camera's embedded JPEG is a proxy the decoder already +//! extracts in milliseconds. What is different from the real path is only +//! that the pixels are the camera's rendering rather than ours, which the +//! geometry does not care about. + +use std::path::PathBuf; +use std::time::Instant; + +use dr_pano::bundle::Cameras; +use dr_pano::{align, xfeat::XFeat, AlignOptions, Gray, Projection}; + +fn main() { + env_logger::init(); + let mut args: Vec = std::env::args().skip(1).collect(); + if args.is_empty() { + eprintln!("usage: align [out-prefix] ..."); + std::process::exit(2); + } + let prefix = if args[0].ends_with(".CR2") || args[0].ends_with(".dng") || args[0].ends_with(".jpg") { + "align".to_string() + } else { + args.remove(0) + }; + let paths: Vec = args.iter().map(PathBuf::from).collect(); + + // Previews, oriented, at proxy size. + let t = Instant::now(); + let mut proxies: Vec = Vec::new(); + for p in &paths { + let bytes = std::fs::read(p).expect("read"); + let preview = dr_decode::extract_preview(&bytes, dr_decode::PreviewSize::Full) + .expect("embedded preview"); + let orientation = dr_decode::orientation(&bytes[..bytes.len().min(dr_decode::HEADER_BYTES as usize)]) + .unwrap_or(dr_types::Orientation::NORMAL); + let tag = match orientation.quarter_turns { + 1 => 6, + 2 => 3, + 3 => 8, + _ => 1, + }; + let gray = Gray::from_rgba8(&preview.rgba, preview.width as usize, preview.height as usize) + .oriented(tag); + let (fitted, _) = gray.fitted(dr_pano::xfeat::INPUT_LONG_EDGE, dr_pano::xfeat::INPUT_LONG_EDGE); + println!( + "{:<14} preview {}×{} orientation {} → proxy {}×{}", + p.file_name().unwrap().to_string_lossy(), + preview.width, + preview.height, + tag, + fitted.width, + fitted.height + ); + proxies.push(fitted); + } + println!("previews in {:?}", t.elapsed()); + + // Keypoints. + let t = Instant::now(); + let mut detector = XFeat::embedded().expect("model"); + let features: Vec<_> = proxies + .iter() + .map(|g| detector.detect(g).expect("detect")) + .collect(); + for (i, f) in features.iter().enumerate() { + println!("frame {i}: {} keypoints", f.len()); + } + println!("detection in {:?} ({:?} per frame)", t.elapsed(), t.elapsed() / proxies.len() as u32); + + // Alignment. + let t = Instant::now(); + let opts = AlignOptions::default(); + let alignment = align(&features, &opts).expect("align"); + println!("alignment in {:?}", t.elapsed()); + println!( + "focal {:.1} px, long edge {} px ({:.1} mm on full frame), rms {:.3} px", + alignment.focal, + proxies[0].width.max(proxies[0].height), + alignment.focal * 36.0 / proxies[0].width.max(proxies[0].height) as f64, + alignment.rms_px + ); + for l in &alignment.links { + println!(" link {}–{}: {} inliers of {} matches", l.i, l.j, l.inliers, l.matches); + } + for (k, why) in &alignment.unaligned { + println!(" UNALIGNED frame {k}: {why}"); + } + let root = alignment + .rotations + .iter() + .position(|r| *r == Some(dr_pano::linalg::Mat3::IDENTITY)) + .unwrap_or(0); + for (k, r) in alignment.rotations.iter().enumerate() { + if let Some(r) = r { + // Yaw about y, pitch about x, roll about z, from the matrix's + // columns — enough to read a sweep by eye. + let yaw = r.0[0][2].atan2(r.0[2][2]).to_degrees(); + let pitch = (-r.0[1][2]).asin().to_degrees(); + let roll = r.0[1][0].atan2(r.0[1][1]).to_degrees(); + println!( + " frame {k}: yaw {yaw:7.2}° pitch {pitch:6.2}° roll {roll:6.2}°{}", + if k == root { " (reference)" } else { "" } + ); + } + } + + if !alignment.is_complete() { + eprintln!("not drawing: the set is not fully aligned"); + std::process::exit(1); + } + + // Draw: a cylinder, averaged where frames overlap. + let t = Instant::now(); + let cameras: Cameras = alignment.cameras(); + let (fw, fh) = (proxies[0].width as f64, proxies[0].height as f64); + let scale = alignment.focal; + let bounds = dr_pano::projection::bounds(Projection::Cylindrical, scale, &cameras, (fw, fh)) + .expect("bounds"); + // Fit to 3000 px wide. + let out_w = 3000usize; + let px = bounds.width() / out_w as f64; + let out_h = (bounds.height() / px).ceil() as usize; + let mut sum = vec![0.0f32; out_w * out_h]; + let mut count = vec![0u16; out_w * out_h]; + for oy in 0..out_h { + for ox in 0..out_w { + let u = bounds.min_u + (ox as f64 + 0.5) * px; + let v = bounds.min_v + (oy as f64 + 0.5) * px; + let d = Projection::Cylindrical.to_direction(scale, u, v); + for (k, g) in proxies.iter().enumerate() { + let Some((x, y)) = cameras.project(k, d) else { continue }; + let (x, y) = (x + g.width as f64 / 2.0, y + g.height as f64 / 2.0); + if x < 0.0 || y < 0.0 || x >= g.width as f64 - 1.0 || y >= g.height as f64 - 1.0 { + continue; + } + let (x0, y0) = (x as usize, y as usize); + let (tx, ty) = ((x - x0 as f64) as f32, (y - y0 as f64) as f32); + let p = |xx: usize, yy: usize| g.data[yy * g.width + xx]; + let val = (p(x0, y0) * (1.0 - tx) + p(x0 + 1, y0) * tx) * (1.0 - ty) + + (p(x0, y0 + 1) * (1.0 - tx) + p(x0 + 1, y0 + 1) * tx) * ty; + sum[oy * out_w + ox] += val; + count[oy * out_w + ox] += 1; + } + } + } + let mut ppm = format!("P5\n{out_w} {out_h}\n255\n").into_bytes(); + ppm.extend(sum.iter().zip(&count).map(|(s, c)| { + if *c == 0 { + 0u8 + } else { + ((s / f32::from(*c)).clamp(0.0, 1.0) * 255.0) as u8 + } + })); + let out = format!("{prefix}-cyl.pgm"); + std::fs::write(&out, ppm).expect("write"); + println!("wrote {out} ({out_w}×{out_h}) in {:?}", t.elapsed()); +} diff --git a/core/dr-pano/src/align.rs b/core/dr-pano/src/align.rs index e00b8b2..02a2b3a 100644 --- a/core/dr-pano/src/align.rs +++ b/core/dr-pano/src/align.rs @@ -151,9 +151,11 @@ pub fn align(frames: &[Features], opts: &AlignOptions) -> Result = Vec::new(); let mut matched_any = vec![false; n]; + let t_match = std::time::Instant::now(); for i in 0..n { for j in i + 1..n { let matches: Vec = match_features(&frames[i], &frames[j], opts.min_similarity); + log::debug!("pair {i}-{j}: {} matches", matches.len()); if matches.len() < 4 { continue; } @@ -175,6 +177,10 @@ pub fn align(frames: &[Features], opts: &AlignOptions) -> Result Result = links .iter() @@ -304,7 +312,14 @@ pub fn align(frames: &[Features], opts: &AlignOptions) -> Result Vec = sim + .chunks_exact(nb) + .map(|row| { + row.iter() + .enumerate() + .fold((0usize, f32::MIN), |acc, (j, &s)| if s > acc.1 { (j, s) } else { acc }) + }) + .collect(); + let mut best_ba = vec![(0usize, f32::MIN); nb]; + for (i, row) in sim.chunks_exact(nb).enumerate() { + for (j, &s) in row.iter().enumerate() { + if s > best_ba[j].1 { + best_ba[j] = (i, s); + } + } + } + best_ab .iter() .enumerate() - .filter_map(|(ia, &(ib, sim))| { - (best_ba[ib].0 == ia && sim >= min_similarity).then_some(Match { + .filter_map(|(ia, &(ib, s))| { + (best_ba[ib].0 == ia && s >= min_similarity).then_some(Match { a: ia, b: ib, - similarity: sim, + similarity: s, }) }) .collect() } -/// For each descriptor in `from`, the index of its nearest in `to` and the -/// similarity. -fn nearest(from: &Features, to: &Features) -> Vec<(usize, f32)> { - (0..from.len()) - .map(|i| { - let d = from.descriptor(i); - let mut best = (0usize, f32::MIN); - for j in 0..to.len() { - let s = dot(d, to.descriptor(j)); - if s > best.1 { - best = (j, s); - } - } - best - }) - .collect() -} - #[inline] fn dot(a: &[f32], b: &[f32]) -> f32 { - // Written as a plain loop over a fixed length so the compiler - // vectorises it; the length is a constant and the slices are exact. - let mut s = 0.0f32; - for k in 0..DESCRIPTOR_LEN { - s += a[k] * b[k]; + // Eight independent accumulators over exact 8-lane chunks: the shape + // the compiler turns into one vector multiply-add per chunk, and no + // bounds checks inside the loop. `DESCRIPTOR_LEN` is a multiple of 8. + let (a, b) = (&a[..DESCRIPTOR_LEN], &b[..DESCRIPTOR_LEN]); + let mut acc = [0.0f32; 8]; + for (ca, cb) in a.chunks_exact(8).zip(b.chunks_exact(8)) { + for k in 0..8 { + acc[k] += ca[k] * cb[k]; + } } - s + acc.iter().sum() } #[cfg(test)] diff --git a/core/dr-pano/src/xfeat.rs b/core/dr-pano/src/xfeat.rs index 3cb8b49..7acb07f 100644 --- a/core/dr-pano/src/xfeat.rs +++ b/core/dr-pano/src/xfeat.rs @@ -11,17 +11,27 @@ use crate::features::{decode_xfeat, DecodeOptions, Features, XFeatMaps, DESCRIPT use crate::image::Gray; use crate::PanoError; -/// The input shape the shipped export was made for. A different size is a -/// different file (`tools/export-xfeat.sh`). -pub const INPUT_WIDTH: usize = 1024; -pub const INPUT_HEIGHT: usize = 768; +/// The two input shapes the shipped exports were made for: one landscape, +/// one portrait, the same weights. A frame is fitted into whichever +/// matches its aspect, so a portrait set does not spend half the +/// detector's width on padding — which is what the 6D fixture did before +/// the second export existed (512 × 768 of a 1024 × 768 input). A +/// different size is a different file (`tools/export-xfeat.sh`). +pub const INPUT_LANDSCAPE: (usize, usize) = (1024, 768); +pub const INPUT_PORTRAIT: (usize, usize) = (768, 1024); + +/// The long edge of the detector's input, for callers sizing a proxy. +pub const INPUT_LONG_EDGE: usize = 1024; #[cfg(feature = "embedded-model")] -const EMBEDDED_MODEL: &[u8] = include_bytes!("../../../models/keypoints/xfeat-1024.onnx"); +const EMBEDDED_LANDSCAPE: &[u8] = include_bytes!("../../../models/keypoints/xfeat-1024.onnx"); +#[cfg(feature = "embedded-model")] +const EMBEDDED_PORTRAIT: &[u8] = include_bytes!("../../../models/keypoints/xfeat-768.onnx"); -/// A loaded detector. +/// A loaded detector: the network at both shapes. pub struct XFeat { - session: ort::session::Session, + landscape: ort::session::Session, + portrait: ort::session::Session, pub options: DecodeOptions, } @@ -29,49 +39,55 @@ impl XFeat { /// The weights compiled into the binary. #[cfg(feature = "embedded-model")] pub fn embedded() -> Result { - Self::from_bytes(EMBEDDED_MODEL) + Self::from_bytes(EMBEDDED_LANDSCAPE, EMBEDDED_PORTRAIT) } - pub fn from_path(path: &std::path::Path) -> Result { - let bytes = std::fs::read(path).map_err(PanoError::ModelRead)?; - Self::from_bytes(&bytes) + /// From the two exports on disk. + pub fn from_paths(landscape: &std::path::Path, portrait: &std::path::Path) -> Result { + let l = std::fs::read(landscape).map_err(PanoError::ModelRead)?; + let p = std::fs::read(portrait).map_err(PanoError::ModelRead)?; + Self::from_bytes(&l, &p) } - pub fn from_bytes(bytes: &[u8]) -> Result { + pub fn from_bytes(landscape: &[u8], portrait: &[u8]) -> Result { install_backend(); - let session = ort::session::Session::builder() - .map_err(PanoError::Inference)? - .commit_from_memory(bytes) - .map_err(PanoError::Inference)?; + let session = |bytes: &[u8]| { + ort::session::Session::builder() + .map_err(PanoError::Inference)? + .commit_from_memory(bytes) + .map_err(PanoError::Inference) + }; Ok(XFeat { - session, + landscape: session(landscape)?, + portrait: session(portrait)?, options: DecodeOptions::default(), }) } /// Detect keypoints in an upright grayscale image. /// - /// The image is fitted into the network's fixed input — scaled down if - /// larger, never up, and padded to the right and bottom — and the - /// keypoints come back in the coordinates of `image` itself, so a - /// caller that already scaled a frame to a proxy maps them on with the - /// scale it used and nothing else. + /// The image is fitted into the network's input of matching aspect — + /// scaled down if larger, never up, and padded to the right and bottom + /// — and the keypoints come back in the coordinates of `image` itself, + /// so a caller that already scaled a frame to a proxy maps them on with + /// the scale it used and nothing else. pub fn detect(&mut self, image: &Gray) -> Result { - let (fitted, scale) = image.fitted(INPUT_WIDTH, INPUT_HEIGHT); - let padded = fitted.padded(INPUT_WIDTH, INPUT_HEIGHT); + let ((in_w, in_h), session) = if image.height > image.width { + (INPUT_PORTRAIT, &mut self.portrait) + } else { + (INPUT_LANDSCAPE, &mut self.landscape) + }; + let (fitted, scale) = image.fitted(in_w, in_h); + let padded = fitted.padded(in_w, in_h); - let input = ndarray::Array::from_shape_vec( - ndarray::IxDyn(&[1, 1, INPUT_HEIGHT, INPUT_WIDTH]), - padded.data, - ) - .expect("shape matches the buffer by construction"); + let input = ndarray::Array::from_shape_vec(ndarray::IxDyn(&[1, 1, in_h, in_w]), padded.data) + .expect("shape matches the buffer by construction"); let tensor = ort::value::Tensor::from_array(input).map_err(PanoError::Inference)?; - let outputs = self - .session + let outputs = session .run(ort::inputs![tensor]) .map_err(PanoError::Inference)?; - let (w8, h8) = (INPUT_WIDTH / 8, INPUT_HEIGHT / 8); + let (w8, h8) = (in_w / 8, in_h / 8); let expect = |i: usize, channels: usize| -> Result, PanoError> { let (shape, data) = outputs[i] .try_extract_tensor::() diff --git a/docs/traceability.md b/docs/traceability.md index 4daa791..0e0f0bd 100644 --- a/docs/traceability.md +++ b/docs/traceability.md @@ -10,17 +10,17 @@ Denominators are parsed from [`requirements.md`](requirements.md) at run time, n | Metric | Value | |---|---| | Source files scanned | 368 | -| TRACES tags found | 1508 | +| TRACES tags found | 1515 | | Requirements defined | 184 | | Requirements deferred (post-v1) | 24 | -| Requirements covered | 148 | -| **Coverage** | **80.4%** (148/184) | +| Requirements covered | 149 | +| **Coverage** | **81.0%** (149/184) | ### By type | Type | Covered | Defined | |---|---|---| -| FR | 110 | 127 | +| FR | 111 | 127 | | NFR | 34 | 50 | | R | 4 | 7 | @@ -67,39 +67,40 @@ _None._ | FR-DEV-19 | [`core/dr-pipeline/src/mask.rs:1307`](../core/dr-pipeline/src/mask.rs#L1307) | | FR-DEV-19a | [`core/dr-gpu/src/mask.rs:761`](../core/dr-gpu/src/mask.rs#L761), [`core/dr-pipeline/src/mask.rs:1588`](../core/dr-pipeline/src/mask.rs#L1588), [`core/dr-pipeline/src/mask.rs:2919`](../core/dr-pipeline/src/mask.rs#L2919), [`core/dr-pipeline/src/mask.rs:988`](../core/dr-pipeline/src/mask.rs#L988), [`core/dr-pipeline/src/sidecar.rs:1199`](../core/dr-pipeline/src/sidecar.rs#L1199), [`core/dr-pipeline/tests/mask_sidecar.rs:1347`](../core/dr-pipeline/tests/mask_sidecar.rs#L1347), [`core/dr-pipeline/tests/mask_sidecar.rs:1373`](../core/dr-pipeline/tests/mask_sidecar.rs#L1373), [`ui/dr-ui/src/develop.rs:2921`](../ui/dr-ui/src/develop.rs#L2921), [`ui/dr-ui/src/develop.rs:2982`](../ui/dr-ui/src/develop.rs#L2982), [`ui/dr-ui/src/develop.rs:3001`](../ui/dr-ui/src/develop.rs#L3001), [`ui/dr-ui/src/develop.rs:880`](../ui/dr-ui/src/develop.rs#L880), [`ui/dr-ui/src/labels.rs:73`](../ui/dr-ui/src/labels.rs#L73), [`ui/dr-ui/src/masks_ui.rs:1017`](../ui/dr-ui/src/masks_ui.rs#L1017), [`ui/dr-ui/src/masks_ui.rs:1089`](../ui/dr-ui/src/masks_ui.rs#L1089), [`ui/dr-ui/src/masks_ui.rs:1448`](../ui/dr-ui/src/masks_ui.rs#L1448), [`ui/dr-ui/src/masks_ui.rs:270`](../ui/dr-ui/src/masks_ui.rs#L270), [`ui/dr-ui/ui/masks.slint:150`](../ui/dr-ui/ui/masks.slint#L150), [`ui/dr-ui/ui/masks.slint:175`](../ui/dr-ui/ui/masks.slint#L175), [`ui/dr-ui/ui/masks.slint:337`](../ui/dr-ui/ui/masks.slint#L337), [`ui/dr-ui/ui/masks.slint:406`](../ui/dr-ui/ui/masks.slint#L406), [`ui/dr-ui/ui/masks.slint:762`](../ui/dr-ui/ui/masks.slint#L762), [`ui/dr-ui/ui/masks.slint:847`](../ui/dr-ui/ui/masks.slint#L847) | | FR-DEV-19b | [`ui/dr-ui/src/develop.rs:3082`](../ui/dr-ui/src/develop.rs#L3082), [`ui/dr-ui/src/develop.rs:3625`](../ui/dr-ui/src/develop.rs#L3625), [`ui/dr-ui/src/develop.rs:889`](../ui/dr-ui/src/develop.rs#L889), [`ui/dr-ui/src/develop.rs:896`](../ui/dr-ui/src/develop.rs#L896), [`ui/dr-ui/src/labels.rs:67`](../ui/dr-ui/src/labels.rs#L67), [`ui/dr-ui/src/masks_ui.rs:1122`](../ui/dr-ui/src/masks_ui.rs#L1122), [`ui/dr-ui/src/masks_ui.rs:1341`](../ui/dr-ui/src/masks_ui.rs#L1341), [`ui/dr-ui/src/masks_ui.rs:1369`](../ui/dr-ui/src/masks_ui.rs#L1369), [`ui/dr-ui/src/masks_ui.rs:1712`](../ui/dr-ui/src/masks_ui.rs#L1712), [`ui/dr-ui/src/masks_ui.rs:858`](../ui/dr-ui/src/masks_ui.rs#L858), [`ui/dr-ui/ui/app.slint:1008`](../ui/dr-ui/ui/app.slint#L1008), [`ui/dr-ui/ui/app.slint:2170`](../ui/dr-ui/ui/app.slint#L2170), [`ui/dr-ui/ui/masks.slint:1118`](../ui/dr-ui/ui/masks.slint#L1118), [`ui/dr-ui/ui/masks.slint:453`](../ui/dr-ui/ui/masks.slint#L453), [`ui/dr-ui/ui/masks.slint:766`](../ui/dr-ui/ui/masks.slint#L766), [`ui/dr-ui/ui/masks.slint:840`](../ui/dr-ui/ui/masks.slint#L840), [`ui/dr-ui/ui/masks.slint:856`](../ui/dr-ui/ui/masks.slint#L856) | -| FR-DEV-19c | [`core/dr-gpu/src/mask.rs:715`](../core/dr-gpu/src/mask.rs#L715), [`core/dr-gpu/tests/local_adjustments.rs:830`](../core/dr-gpu/tests/local_adjustments.rs#L830), [`core/dr-gpu/tests/local_adjustments.rs:887`](../core/dr-gpu/tests/local_adjustments.rs#L887), [`core/dr-gpu/tests/local_adjustments.rs:922`](../core/dr-gpu/tests/local_adjustments.rs#L922), [`core/dr-gpu/tests/local_adjustments.rs:967`](../core/dr-gpu/tests/local_adjustments.rs#L967), [`core/dr-pipeline/src/graph.rs:852`](../core/dr-pipeline/src/graph.rs#L852), [`core/dr-pipeline/src/mask.rs:1796`](../core/dr-pipeline/src/mask.rs#L1796), [`core/dr-pipeline/src/mask.rs:1822`](../core/dr-pipeline/src/mask.rs#L1822), [`core/dr-pipeline/src/mask.rs:1837`](../core/dr-pipeline/src/mask.rs#L1837), [`core/dr-pipeline/src/mask.rs:1957`](../core/dr-pipeline/src/mask.rs#L1957), [`core/dr-pipeline/src/mask.rs:2005`](../core/dr-pipeline/src/mask.rs#L2005), [`core/dr-pipeline/src/mask.rs:2149`](../core/dr-pipeline/src/mask.rs#L2149), [`core/dr-pipeline/src/mask.rs:2386`](../core/dr-pipeline/src/mask.rs#L2386), [`core/dr-pipeline/src/operation.rs:1600`](../core/dr-pipeline/src/operation.rs#L1600), [`core/dr-pipeline/src/operation.rs:558`](../core/dr-pipeline/src/operation.rs#L558), [`core/dr-pipeline/src/operation.rs:741`](../core/dr-pipeline/src/operation.rs#L741), [`ui/dr-ui/src/develop.rs:2035`](../ui/dr-ui/src/develop.rs#L2035), [`ui/dr-ui/src/develop.rs:2295`](../ui/dr-ui/src/develop.rs#L2295), [`ui/dr-ui/src/develop.rs:2542`](../ui/dr-ui/src/develop.rs#L2542), [`ui/dr-ui/src/develop.rs:2666`](../ui/dr-ui/src/develop.rs#L2666), [`ui/dr-ui/src/develop.rs:4059`](../ui/dr-ui/src/develop.rs#L4059), [`ui/dr-ui/src/develop.rs:686`](../ui/dr-ui/src/develop.rs#L686), [`ui/dr-ui/src/develop.rs:695`](../ui/dr-ui/src/develop.rs#L695), [`ui/dr-ui/src/develop.rs:6995`](../ui/dr-ui/src/develop.rs#L6995), [`ui/dr-ui/src/develop.rs:7031`](../ui/dr-ui/src/develop.rs#L7031), [`ui/dr-ui/src/develop.rs:915`](../ui/dr-ui/src/develop.rs#L915), [`ui/dr-ui/src/develop.rs:924`](../ui/dr-ui/src/develop.rs#L924), [`ui/dr-ui/src/masks_ui.rs:1341`](../ui/dr-ui/src/masks_ui.rs#L1341), [`ui/dr-ui/src/masks_ui.rs:152`](../ui/dr-ui/src/masks_ui.rs#L152), [`ui/dr-ui/src/masks_ui.rs:1712`](../ui/dr-ui/src/masks_ui.rs#L1712), [`ui/dr-ui/src/masks_ui.rs:291`](../ui/dr-ui/src/masks_ui.rs#L291), [`ui/dr-ui/src/masks_ui.rs:317`](../ui/dr-ui/src/masks_ui.rs#L317), [`ui/dr-ui/src/masks_ui.rs:634`](../ui/dr-ui/src/masks_ui.rs#L634), [`ui/dr-ui/src/masks_ui.rs:940`](../ui/dr-ui/src/masks_ui.rs#L940), [`ui/dr-ui/src/masks_ui.rs:968`](../ui/dr-ui/src/masks_ui.rs#L968), [`ui/dr-ui/ui/icons.slint:339`](../ui/dr-ui/ui/icons.slint#L339), [`ui/dr-ui/ui/masks.slint:1083`](../ui/dr-ui/ui/masks.slint#L1083), [`ui/dr-ui/ui/masks.slint:183`](../ui/dr-ui/ui/masks.slint#L183), [`ui/dr-ui/ui/masks.slint:292`](../ui/dr-ui/ui/masks.slint#L292), [`ui/dr-ui/ui/masks.slint:517`](../ui/dr-ui/ui/masks.slint#L517), [`ui/dr-ui/ui/masks.slint:70`](../ui/dr-ui/ui/masks.slint#L70), [`ui/dr-ui/ui/masks.slint:774`](../ui/dr-ui/ui/masks.slint#L774), [`ui/dr-ui/ui/masks.slint:842`](../ui/dr-ui/ui/masks.slint#L842), [`ui/dr-ui/ui/masks.slint:930`](../ui/dr-ui/ui/masks.slint#L930) | +| FR-DEV-19c | [`core/dr-gpu/src/mask.rs:715`](../core/dr-gpu/src/mask.rs#L715), [`core/dr-gpu/tests/local_adjustments.rs:830`](../core/dr-gpu/tests/local_adjustments.rs#L830), [`core/dr-gpu/tests/local_adjustments.rs:887`](../core/dr-gpu/tests/local_adjustments.rs#L887), [`core/dr-gpu/tests/local_adjustments.rs:922`](../core/dr-gpu/tests/local_adjustments.rs#L922), [`core/dr-gpu/tests/local_adjustments.rs:967`](../core/dr-gpu/tests/local_adjustments.rs#L967), [`core/dr-pipeline/src/graph.rs:860`](../core/dr-pipeline/src/graph.rs#L860), [`core/dr-pipeline/src/mask.rs:1796`](../core/dr-pipeline/src/mask.rs#L1796), [`core/dr-pipeline/src/mask.rs:1822`](../core/dr-pipeline/src/mask.rs#L1822), [`core/dr-pipeline/src/mask.rs:1837`](../core/dr-pipeline/src/mask.rs#L1837), [`core/dr-pipeline/src/mask.rs:1957`](../core/dr-pipeline/src/mask.rs#L1957), [`core/dr-pipeline/src/mask.rs:2005`](../core/dr-pipeline/src/mask.rs#L2005), [`core/dr-pipeline/src/mask.rs:2149`](../core/dr-pipeline/src/mask.rs#L2149), [`core/dr-pipeline/src/mask.rs:2386`](../core/dr-pipeline/src/mask.rs#L2386), [`core/dr-pipeline/src/operation.rs:1667`](../core/dr-pipeline/src/operation.rs#L1667), [`core/dr-pipeline/src/operation.rs:573`](../core/dr-pipeline/src/operation.rs#L573), [`core/dr-pipeline/src/operation.rs:798`](../core/dr-pipeline/src/operation.rs#L798), [`ui/dr-ui/src/develop.rs:2035`](../ui/dr-ui/src/develop.rs#L2035), [`ui/dr-ui/src/develop.rs:2295`](../ui/dr-ui/src/develop.rs#L2295), [`ui/dr-ui/src/develop.rs:2542`](../ui/dr-ui/src/develop.rs#L2542), [`ui/dr-ui/src/develop.rs:2666`](../ui/dr-ui/src/develop.rs#L2666), [`ui/dr-ui/src/develop.rs:4059`](../ui/dr-ui/src/develop.rs#L4059), [`ui/dr-ui/src/develop.rs:686`](../ui/dr-ui/src/develop.rs#L686), [`ui/dr-ui/src/develop.rs:695`](../ui/dr-ui/src/develop.rs#L695), [`ui/dr-ui/src/develop.rs:6995`](../ui/dr-ui/src/develop.rs#L6995), [`ui/dr-ui/src/develop.rs:7031`](../ui/dr-ui/src/develop.rs#L7031), [`ui/dr-ui/src/develop.rs:915`](../ui/dr-ui/src/develop.rs#L915), [`ui/dr-ui/src/develop.rs:924`](../ui/dr-ui/src/develop.rs#L924), [`ui/dr-ui/src/masks_ui.rs:1341`](../ui/dr-ui/src/masks_ui.rs#L1341), [`ui/dr-ui/src/masks_ui.rs:152`](../ui/dr-ui/src/masks_ui.rs#L152), [`ui/dr-ui/src/masks_ui.rs:1712`](../ui/dr-ui/src/masks_ui.rs#L1712), [`ui/dr-ui/src/masks_ui.rs:291`](../ui/dr-ui/src/masks_ui.rs#L291), [`ui/dr-ui/src/masks_ui.rs:317`](../ui/dr-ui/src/masks_ui.rs#L317), [`ui/dr-ui/src/masks_ui.rs:634`](../ui/dr-ui/src/masks_ui.rs#L634), [`ui/dr-ui/src/masks_ui.rs:940`](../ui/dr-ui/src/masks_ui.rs#L940), [`ui/dr-ui/src/masks_ui.rs:968`](../ui/dr-ui/src/masks_ui.rs#L968), [`ui/dr-ui/ui/icons.slint:339`](../ui/dr-ui/ui/icons.slint#L339), [`ui/dr-ui/ui/masks.slint:1083`](../ui/dr-ui/ui/masks.slint#L1083), [`ui/dr-ui/ui/masks.slint:183`](../ui/dr-ui/ui/masks.slint#L183), [`ui/dr-ui/ui/masks.slint:292`](../ui/dr-ui/ui/masks.slint#L292), [`ui/dr-ui/ui/masks.slint:517`](../ui/dr-ui/ui/masks.slint#L517), [`ui/dr-ui/ui/masks.slint:70`](../ui/dr-ui/ui/masks.slint#L70), [`ui/dr-ui/ui/masks.slint:774`](../ui/dr-ui/ui/masks.slint#L774), [`ui/dr-ui/ui/masks.slint:842`](../ui/dr-ui/ui/masks.slint#L842), [`ui/dr-ui/ui/masks.slint:930`](../ui/dr-ui/ui/masks.slint#L930) | | FR-DEV-2 | [`core/dr-pipeline/src/operation.rs:403`](../core/dr-pipeline/src/operation.rs#L403) | -| FR-DEV-3 | [`core/dr-gpu/src/adjust.rs:2217`](../core/dr-gpu/src/adjust.rs#L2217), [`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/coverage.rs:122`](../core/dr-pipeline/src/coverage.rs#L122), [`core/dr-pipeline/src/coverage.rs:1`](../core/dr-pipeline/src/coverage.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:1307`](../core/dr-pipeline/src/graph.rs#L1307), [`core/dr-pipeline/src/graph.rs:1338`](../core/dr-pipeline/src/graph.rs#L1338), [`core/dr-pipeline/src/graph.rs:1361`](../core/dr-pipeline/src/graph.rs#L1361), [`core/dr-pipeline/src/graph.rs:1399`](../core/dr-pipeline/src/graph.rs#L1399), [`core/dr-pipeline/src/graph.rs:1430`](../core/dr-pipeline/src/graph.rs#L1430), [`core/dr-pipeline/src/graph.rs:225`](../core/dr-pipeline/src/graph.rs#L225), [`core/dr-pipeline/src/graph.rs:306`](../core/dr-pipeline/src/graph.rs#L306), [`core/dr-pipeline/src/graph.rs:344`](../core/dr-pipeline/src/graph.rs#L344), [`core/dr-pipeline/src/graph.rs:350`](../core/dr-pipeline/src/graph.rs#L350), [`core/dr-pipeline/src/graph.rs:911`](../core/dr-pipeline/src/graph.rs#L911), [`core/dr-pipeline/src/lens.rs:93`](../core/dr-pipeline/src/lens.rs#L93), [`core/dr-pipeline/src/mask.rs:205`](../core/dr-pipeline/src/mask.rs#L205), [`core/dr-pipeline/src/mask.rs:558`](../core/dr-pipeline/src/mask.rs#L558), [`core/dr-pipeline/src/neutral.rs:1`](../core/dr-pipeline/src/neutral.rs#L1), [`core/dr-pipeline/src/neutral.rs:300`](../core/dr-pipeline/src/neutral.rs#L300), [`core/dr-pipeline/src/neutral.rs:316`](../core/dr-pipeline/src/neutral.rs#L316), [`core/dr-pipeline/src/neutral.rs:332`](../core/dr-pipeline/src/neutral.rs#L332), [`core/dr-pipeline/src/neutral.rs:354`](../core/dr-pipeline/src/neutral.rs#L354), [`core/dr-pipeline/src/neutral.rs:79`](../core/dr-pipeline/src/neutral.rs#L79), [`core/dr-pipeline/src/operation.rs:330`](../core/dr-pipeline/src/operation.rs#L330), [`core/dr-pipeline/src/operation.rs:535`](../core/dr-pipeline/src/operation.rs#L535), [`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/preset.rs:751`](../core/dr-pipeline/src/preset.rs#L751), [`core/dr-pipeline/src/sidecar.rs:1373`](../core/dr-pipeline/src/sidecar.rs#L1373), [`core/dr-pipeline/src/sidecar.rs:177`](../core/dr-pipeline/src/sidecar.rs#L177), [`core/dr-pipeline/src/sidecar.rs:2205`](../core/dr-pipeline/src/sidecar.rs#L2205), [`core/dr-pipeline/src/sidecar.rs:2265`](../core/dr-pipeline/src/sidecar.rs#L2265), [`core/dr-pipeline/tests/tone_curve.rs:1`](../core/dr-pipeline/tests/tone_curve.rs#L1), [`core/dr-segment/src/refine.rs:937`](../core/dr-segment/src/refine.rs#L937), [`ui/dr-ui/src/develop.rs:103`](../ui/dr-ui/src/develop.rs#L103), [`ui/dr-ui/src/develop.rs:1318`](../ui/dr-ui/src/develop.rs#L1318), [`ui/dr-ui/src/develop.rs:1407`](../ui/dr-ui/src/develop.rs#L1407), [`ui/dr-ui/src/develop.rs:1443`](../ui/dr-ui/src/develop.rs#L1443), [`ui/dr-ui/src/develop.rs:165`](../ui/dr-ui/src/develop.rs#L165), [`ui/dr-ui/src/develop.rs:1714`](../ui/dr-ui/src/develop.rs#L1714), [`ui/dr-ui/src/develop.rs:2155`](../ui/dr-ui/src/develop.rs#L2155), [`ui/dr-ui/src/develop.rs:2398`](../ui/dr-ui/src/develop.rs#L2398), [`ui/dr-ui/src/develop.rs:2416`](../ui/dr-ui/src/develop.rs#L2416), [`ui/dr-ui/src/develop.rs:2430`](../ui/dr-ui/src/develop.rs#L2430), [`ui/dr-ui/src/develop.rs:2452`](../ui/dr-ui/src/develop.rs#L2452), [`ui/dr-ui/src/develop.rs:2752`](../ui/dr-ui/src/develop.rs#L2752), [`ui/dr-ui/src/develop.rs:2850`](../ui/dr-ui/src/develop.rs#L2850), [`ui/dr-ui/src/develop.rs:328`](../ui/dr-ui/src/develop.rs#L328), [`ui/dr-ui/src/develop.rs:365`](../ui/dr-ui/src/develop.rs#L365), [`ui/dr-ui/src/develop.rs:4400`](../ui/dr-ui/src/develop.rs#L4400), [`ui/dr-ui/src/develop.rs:4556`](../ui/dr-ui/src/develop.rs#L4556), [`ui/dr-ui/src/develop.rs:4616`](../ui/dr-ui/src/develop.rs#L4616), [`ui/dr-ui/src/develop.rs:5021`](../ui/dr-ui/src/develop.rs#L5021), [`ui/dr-ui/src/develop.rs:5051`](../ui/dr-ui/src/develop.rs#L5051), [`ui/dr-ui/src/develop.rs:5117`](../ui/dr-ui/src/develop.rs#L5117), [`ui/dr-ui/src/develop.rs:5131`](../ui/dr-ui/src/develop.rs#L5131), [`ui/dr-ui/src/develop.rs:5333`](../ui/dr-ui/src/develop.rs#L5333), [`ui/dr-ui/src/develop.rs:5421`](../ui/dr-ui/src/develop.rs#L5421), [`ui/dr-ui/src/develop.rs:588`](../ui/dr-ui/src/develop.rs#L588), [`ui/dr-ui/src/develop.rs:6367`](../ui/dr-ui/src/develop.rs#L6367), [`ui/dr-ui/src/develop.rs:6440`](../ui/dr-ui/src/develop.rs#L6440), [`ui/dr-ui/src/develop.rs:649`](../ui/dr-ui/src/develop.rs#L649), [`ui/dr-ui/src/develop.rs:6633`](../ui/dr-ui/src/develop.rs#L6633), [`ui/dr-ui/src/develop.rs:6824`](../ui/dr-ui/src/develop.rs#L6824), [`ui/dr-ui/src/develop.rs:6980`](../ui/dr-ui/src/develop.rs#L6980), [`ui/dr-ui/src/develop.rs:7136`](../ui/dr-ui/src/develop.rs#L7136), [`ui/dr-ui/src/develop.rs:7180`](../ui/dr-ui/src/develop.rs#L7180), [`ui/dr-ui/src/develop.rs:7230`](../ui/dr-ui/src/develop.rs#L7230), [`ui/dr-ui/src/develop.rs:7655`](../ui/dr-ui/src/develop.rs#L7655), [`ui/dr-ui/src/develop.rs:8383`](../ui/dr-ui/src/develop.rs#L8383), [`ui/dr-ui/src/develop.rs:850`](../ui/dr-ui/src/develop.rs#L850), [`ui/dr-ui/src/develop.rs:943`](../ui/dr-ui/src/develop.rs#L943), [`ui/dr-ui/src/develop.rs:972`](../ui/dr-ui/src/develop.rs#L972), [`ui/dr-ui/src/labels.rs:35`](../ui/dr-ui/src/labels.rs#L35), [`ui/dr-ui/src/lib.rs:1960`](../ui/dr-ui/src/lib.rs#L1960), [`ui/dr-ui/src/lib.rs:2840`](../ui/dr-ui/src/lib.rs#L2840), [`ui/dr-ui/src/lib.rs:3047`](../ui/dr-ui/src/lib.rs#L3047), [`ui/dr-ui/src/lib.rs:3180`](../ui/dr-ui/src/lib.rs#L3180), [`ui/dr-ui/src/lib.rs:3385`](../ui/dr-ui/src/lib.rs#L3385), [`ui/dr-ui/src/lib.rs:3449`](../ui/dr-ui/src/lib.rs#L3449), [`ui/dr-ui/src/lib.rs:3503`](../ui/dr-ui/src/lib.rs#L3503), [`ui/dr-ui/src/lib.rs:413`](../ui/dr-ui/src/lib.rs#L413), [`ui/dr-ui/src/lib.rs:442`](../ui/dr-ui/src/lib.rs#L442), [`ui/dr-ui/src/lib.rs:548`](../ui/dr-ui/src/lib.rs#L548), [`ui/dr-ui/src/lib.rs:572`](../ui/dr-ui/src/lib.rs#L572), [`ui/dr-ui/src/library.rs:552`](../ui/dr-ui/src/library.rs#L552), [`ui/dr-ui/src/masks_ui.rs:1471`](../ui/dr-ui/src/masks_ui.rs#L1471), [`ui/dr-ui/src/masks_ui.rs:1585`](../ui/dr-ui/src/masks_ui.rs#L1585), [`ui/dr-ui/src/masks_ui.rs:339`](../ui/dr-ui/src/masks_ui.rs#L339), [`ui/dr-ui/src/masks_ui.rs:44`](../ui/dr-ui/src/masks_ui.rs#L44), [`ui/dr-ui/src/presets.rs:414`](../ui/dr-ui/src/presets.rs#L414), [`ui/dr-ui/src/segmentation.rs:117`](../ui/dr-ui/src/segmentation.rs#L117), [`ui/dr-ui/src/segmentation.rs:353`](../ui/dr-ui/src/segmentation.rs#L353), [`ui/dr-ui/src/segmentation.rs:369`](../ui/dr-ui/src/segmentation.rs#L369), [`ui/dr-ui/src/segmentation.rs:499`](../ui/dr-ui/src/segmentation.rs#L499), [`ui/dr-ui/src/segmentation.rs:527`](../ui/dr-ui/src/segmentation.rs#L527), [`ui/dr-ui/ui/adjust.slint:1019`](../ui/dr-ui/ui/adjust.slint#L1019), [`ui/dr-ui/ui/adjust.slint:126`](../ui/dr-ui/ui/adjust.slint#L126), [`ui/dr-ui/ui/adjust.slint:1496`](../ui/dr-ui/ui/adjust.slint#L1496), [`ui/dr-ui/ui/adjust.slint:171`](../ui/dr-ui/ui/adjust.slint#L171), [`ui/dr-ui/ui/adjust.slint:46`](../ui/dr-ui/ui/adjust.slint#L46), [`ui/dr-ui/ui/adjust.slint:624`](../ui/dr-ui/ui/adjust.slint#L624), [`ui/dr-ui/ui/adjust.slint:650`](../ui/dr-ui/ui/adjust.slint#L650), [`ui/dr-ui/ui/adjust.slint:669`](../ui/dr-ui/ui/adjust.slint#L669), [`ui/dr-ui/ui/adjust.slint:790`](../ui/dr-ui/ui/adjust.slint#L790), [`ui/dr-ui/ui/adjust.slint:947`](../ui/dr-ui/ui/adjust.slint#L947), [`ui/dr-ui/ui/app.slint:146`](../ui/dr-ui/ui/app.slint#L146), [`ui/dr-ui/ui/app.slint:2235`](../ui/dr-ui/ui/app.slint#L2235), [`ui/dr-ui/ui/app.slint:2295`](../ui/dr-ui/ui/app.slint#L2295), [`ui/dr-ui/ui/develop.slint:223`](../ui/dr-ui/ui/develop.slint#L223), [`ui/dr-ui/ui/masks.slint:1208`](../ui/dr-ui/ui/masks.slint#L1208), [`ui/dr-ui/ui/masks.slint:745`](../ui/dr-ui/ui/masks.slint#L745), [`ui/dr-ui/ui/masks.slint:804`](../ui/dr-ui/ui/masks.slint#L804) | +| FR-DEV-3 | [`core/dr-gpu/src/adjust.rs:2427`](../core/dr-gpu/src/adjust.rs#L2427), [`core/dr-gpu/src/adjust.rs:679`](../core/dr-gpu/src/adjust.rs#L679), [`core/dr-gpu/src/adjust.rs:798`](../core/dr-gpu/src/adjust.rs#L798), [`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/coverage.rs:122`](../core/dr-pipeline/src/coverage.rs#L122), [`core/dr-pipeline/src/coverage.rs:1`](../core/dr-pipeline/src/coverage.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:1315`](../core/dr-pipeline/src/graph.rs#L1315), [`core/dr-pipeline/src/graph.rs:1346`](../core/dr-pipeline/src/graph.rs#L1346), [`core/dr-pipeline/src/graph.rs:1369`](../core/dr-pipeline/src/graph.rs#L1369), [`core/dr-pipeline/src/graph.rs:1407`](../core/dr-pipeline/src/graph.rs#L1407), [`core/dr-pipeline/src/graph.rs:1438`](../core/dr-pipeline/src/graph.rs#L1438), [`core/dr-pipeline/src/graph.rs:225`](../core/dr-pipeline/src/graph.rs#L225), [`core/dr-pipeline/src/graph.rs:306`](../core/dr-pipeline/src/graph.rs#L306), [`core/dr-pipeline/src/graph.rs:344`](../core/dr-pipeline/src/graph.rs#L344), [`core/dr-pipeline/src/graph.rs:350`](../core/dr-pipeline/src/graph.rs#L350), [`core/dr-pipeline/src/graph.rs:919`](../core/dr-pipeline/src/graph.rs#L919), [`core/dr-pipeline/src/lens.rs:93`](../core/dr-pipeline/src/lens.rs#L93), [`core/dr-pipeline/src/mask.rs:205`](../core/dr-pipeline/src/mask.rs#L205), [`core/dr-pipeline/src/mask.rs:558`](../core/dr-pipeline/src/mask.rs#L558), [`core/dr-pipeline/src/neutral.rs:1`](../core/dr-pipeline/src/neutral.rs#L1), [`core/dr-pipeline/src/neutral.rs:300`](../core/dr-pipeline/src/neutral.rs#L300), [`core/dr-pipeline/src/neutral.rs:316`](../core/dr-pipeline/src/neutral.rs#L316), [`core/dr-pipeline/src/neutral.rs:332`](../core/dr-pipeline/src/neutral.rs#L332), [`core/dr-pipeline/src/neutral.rs:354`](../core/dr-pipeline/src/neutral.rs#L354), [`core/dr-pipeline/src/neutral.rs:79`](../core/dr-pipeline/src/neutral.rs#L79), [`core/dr-pipeline/src/operation.rs:330`](../core/dr-pipeline/src/operation.rs#L330), [`core/dr-pipeline/src/operation.rs:550`](../core/dr-pipeline/src/operation.rs#L550), [`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/preset.rs:751`](../core/dr-pipeline/src/preset.rs#L751), [`core/dr-pipeline/src/sidecar.rs:1373`](../core/dr-pipeline/src/sidecar.rs#L1373), [`core/dr-pipeline/src/sidecar.rs:177`](../core/dr-pipeline/src/sidecar.rs#L177), [`core/dr-pipeline/src/sidecar.rs:2205`](../core/dr-pipeline/src/sidecar.rs#L2205), [`core/dr-pipeline/src/sidecar.rs:2265`](../core/dr-pipeline/src/sidecar.rs#L2265), [`core/dr-pipeline/tests/tone_curve.rs:1`](../core/dr-pipeline/tests/tone_curve.rs#L1), [`core/dr-segment/src/refine.rs:937`](../core/dr-segment/src/refine.rs#L937), [`ui/dr-ui/src/develop.rs:103`](../ui/dr-ui/src/develop.rs#L103), [`ui/dr-ui/src/develop.rs:1318`](../ui/dr-ui/src/develop.rs#L1318), [`ui/dr-ui/src/develop.rs:1407`](../ui/dr-ui/src/develop.rs#L1407), [`ui/dr-ui/src/develop.rs:1443`](../ui/dr-ui/src/develop.rs#L1443), [`ui/dr-ui/src/develop.rs:165`](../ui/dr-ui/src/develop.rs#L165), [`ui/dr-ui/src/develop.rs:1714`](../ui/dr-ui/src/develop.rs#L1714), [`ui/dr-ui/src/develop.rs:2155`](../ui/dr-ui/src/develop.rs#L2155), [`ui/dr-ui/src/develop.rs:2398`](../ui/dr-ui/src/develop.rs#L2398), [`ui/dr-ui/src/develop.rs:2416`](../ui/dr-ui/src/develop.rs#L2416), [`ui/dr-ui/src/develop.rs:2430`](../ui/dr-ui/src/develop.rs#L2430), [`ui/dr-ui/src/develop.rs:2452`](../ui/dr-ui/src/develop.rs#L2452), [`ui/dr-ui/src/develop.rs:2752`](../ui/dr-ui/src/develop.rs#L2752), [`ui/dr-ui/src/develop.rs:2850`](../ui/dr-ui/src/develop.rs#L2850), [`ui/dr-ui/src/develop.rs:328`](../ui/dr-ui/src/develop.rs#L328), [`ui/dr-ui/src/develop.rs:365`](../ui/dr-ui/src/develop.rs#L365), [`ui/dr-ui/src/develop.rs:4400`](../ui/dr-ui/src/develop.rs#L4400), [`ui/dr-ui/src/develop.rs:4556`](../ui/dr-ui/src/develop.rs#L4556), [`ui/dr-ui/src/develop.rs:4616`](../ui/dr-ui/src/develop.rs#L4616), [`ui/dr-ui/src/develop.rs:5021`](../ui/dr-ui/src/develop.rs#L5021), [`ui/dr-ui/src/develop.rs:5051`](../ui/dr-ui/src/develop.rs#L5051), [`ui/dr-ui/src/develop.rs:5117`](../ui/dr-ui/src/develop.rs#L5117), [`ui/dr-ui/src/develop.rs:5131`](../ui/dr-ui/src/develop.rs#L5131), [`ui/dr-ui/src/develop.rs:5333`](../ui/dr-ui/src/develop.rs#L5333), [`ui/dr-ui/src/develop.rs:5421`](../ui/dr-ui/src/develop.rs#L5421), [`ui/dr-ui/src/develop.rs:588`](../ui/dr-ui/src/develop.rs#L588), [`ui/dr-ui/src/develop.rs:6367`](../ui/dr-ui/src/develop.rs#L6367), [`ui/dr-ui/src/develop.rs:6440`](../ui/dr-ui/src/develop.rs#L6440), [`ui/dr-ui/src/develop.rs:649`](../ui/dr-ui/src/develop.rs#L649), [`ui/dr-ui/src/develop.rs:6633`](../ui/dr-ui/src/develop.rs#L6633), [`ui/dr-ui/src/develop.rs:6824`](../ui/dr-ui/src/develop.rs#L6824), [`ui/dr-ui/src/develop.rs:6980`](../ui/dr-ui/src/develop.rs#L6980), [`ui/dr-ui/src/develop.rs:7136`](../ui/dr-ui/src/develop.rs#L7136), [`ui/dr-ui/src/develop.rs:7180`](../ui/dr-ui/src/develop.rs#L7180), [`ui/dr-ui/src/develop.rs:7230`](../ui/dr-ui/src/develop.rs#L7230), [`ui/dr-ui/src/develop.rs:7655`](../ui/dr-ui/src/develop.rs#L7655), [`ui/dr-ui/src/develop.rs:8383`](../ui/dr-ui/src/develop.rs#L8383), [`ui/dr-ui/src/develop.rs:850`](../ui/dr-ui/src/develop.rs#L850), [`ui/dr-ui/src/develop.rs:943`](../ui/dr-ui/src/develop.rs#L943), [`ui/dr-ui/src/develop.rs:972`](../ui/dr-ui/src/develop.rs#L972), [`ui/dr-ui/src/labels.rs:35`](../ui/dr-ui/src/labels.rs#L35), [`ui/dr-ui/src/lib.rs:1960`](../ui/dr-ui/src/lib.rs#L1960), [`ui/dr-ui/src/lib.rs:2840`](../ui/dr-ui/src/lib.rs#L2840), [`ui/dr-ui/src/lib.rs:3047`](../ui/dr-ui/src/lib.rs#L3047), [`ui/dr-ui/src/lib.rs:3180`](../ui/dr-ui/src/lib.rs#L3180), [`ui/dr-ui/src/lib.rs:3385`](../ui/dr-ui/src/lib.rs#L3385), [`ui/dr-ui/src/lib.rs:3449`](../ui/dr-ui/src/lib.rs#L3449), [`ui/dr-ui/src/lib.rs:3503`](../ui/dr-ui/src/lib.rs#L3503), [`ui/dr-ui/src/lib.rs:413`](../ui/dr-ui/src/lib.rs#L413), [`ui/dr-ui/src/lib.rs:442`](../ui/dr-ui/src/lib.rs#L442), [`ui/dr-ui/src/lib.rs:548`](../ui/dr-ui/src/lib.rs#L548), [`ui/dr-ui/src/lib.rs:572`](../ui/dr-ui/src/lib.rs#L572), [`ui/dr-ui/src/library.rs:552`](../ui/dr-ui/src/library.rs#L552), [`ui/dr-ui/src/masks_ui.rs:1471`](../ui/dr-ui/src/masks_ui.rs#L1471), [`ui/dr-ui/src/masks_ui.rs:1585`](../ui/dr-ui/src/masks_ui.rs#L1585), [`ui/dr-ui/src/masks_ui.rs:339`](../ui/dr-ui/src/masks_ui.rs#L339), [`ui/dr-ui/src/masks_ui.rs:44`](../ui/dr-ui/src/masks_ui.rs#L44), [`ui/dr-ui/src/presets.rs:414`](../ui/dr-ui/src/presets.rs#L414), [`ui/dr-ui/src/segmentation.rs:117`](../ui/dr-ui/src/segmentation.rs#L117), [`ui/dr-ui/src/segmentation.rs:353`](../ui/dr-ui/src/segmentation.rs#L353), [`ui/dr-ui/src/segmentation.rs:369`](../ui/dr-ui/src/segmentation.rs#L369), [`ui/dr-ui/src/segmentation.rs:499`](../ui/dr-ui/src/segmentation.rs#L499), [`ui/dr-ui/src/segmentation.rs:527`](../ui/dr-ui/src/segmentation.rs#L527), [`ui/dr-ui/ui/adjust.slint:1019`](../ui/dr-ui/ui/adjust.slint#L1019), [`ui/dr-ui/ui/adjust.slint:126`](../ui/dr-ui/ui/adjust.slint#L126), [`ui/dr-ui/ui/adjust.slint:1496`](../ui/dr-ui/ui/adjust.slint#L1496), [`ui/dr-ui/ui/adjust.slint:171`](../ui/dr-ui/ui/adjust.slint#L171), [`ui/dr-ui/ui/adjust.slint:46`](../ui/dr-ui/ui/adjust.slint#L46), [`ui/dr-ui/ui/adjust.slint:624`](../ui/dr-ui/ui/adjust.slint#L624), [`ui/dr-ui/ui/adjust.slint:650`](../ui/dr-ui/ui/adjust.slint#L650), [`ui/dr-ui/ui/adjust.slint:669`](../ui/dr-ui/ui/adjust.slint#L669), [`ui/dr-ui/ui/adjust.slint:790`](../ui/dr-ui/ui/adjust.slint#L790), [`ui/dr-ui/ui/adjust.slint:947`](../ui/dr-ui/ui/adjust.slint#L947), [`ui/dr-ui/ui/app.slint:146`](../ui/dr-ui/ui/app.slint#L146), [`ui/dr-ui/ui/app.slint:2235`](../ui/dr-ui/ui/app.slint#L2235), [`ui/dr-ui/ui/app.slint:2295`](../ui/dr-ui/ui/app.slint#L2295), [`ui/dr-ui/ui/develop.slint:223`](../ui/dr-ui/ui/develop.slint#L223), [`ui/dr-ui/ui/masks.slint:1208`](../ui/dr-ui/ui/masks.slint#L1208), [`ui/dr-ui/ui/masks.slint:745`](../ui/dr-ui/ui/masks.slint#L745), [`ui/dr-ui/ui/masks.slint:804`](../ui/dr-ui/ui/masks.slint#L804) | | FR-DEV-3a | [`core/dr-pipeline/ops/exposure.yaml:1`](../core/dr-pipeline/ops/exposure.yaml#L1), [`core/dr-pipeline/src/descriptor.rs:212`](../core/dr-pipeline/src/descriptor.rs#L212), [`core/dr-pipeline/src/descriptor.rs:252`](../core/dr-pipeline/src/descriptor.rs#L252), [`core/dr-pipeline/src/descriptor.rs:276`](../core/dr-pipeline/src/descriptor.rs#L276), [`core/dr-pipeline/src/descriptor.rs:331`](../core/dr-pipeline/src/descriptor.rs#L331), [`core/dr-pipeline/src/framing.rs:395`](../core/dr-pipeline/src/framing.rs#L395), [`core/dr-pipeline/src/graph.rs:25`](../core/dr-pipeline/src/graph.rs#L25), [`core/dr-pipeline/src/graph.rs:393`](../core/dr-pipeline/src/graph.rs#L393), [`core/dr-pipeline/src/graph.rs:47`](../core/dr-pipeline/src/graph.rs#L47), [`core/dr-pipeline/src/graph.rs:534`](../core/dr-pipeline/src/graph.rs#L534), [`core/dr-pipeline/src/graph.rs:60`](../core/dr-pipeline/src/graph.rs#L60), [`core/dr-pipeline/src/mask.rs:1699`](../core/dr-pipeline/src/mask.rs#L1699), [`core/dr-pipeline/src/neutral.rs:1`](../core/dr-pipeline/src/neutral.rs#L1), [`core/dr-pipeline/src/neutral.rs:372`](../core/dr-pipeline/src/neutral.rs#L372), [`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:1330`](../ui/dr-ui/src/develop.rs#L1330), [`ui/dr-ui/src/develop.rs:1609`](../ui/dr-ui/src/develop.rs#L1609), [`ui/dr-ui/src/develop.rs:7655`](../ui/dr-ui/src/develop.rs#L7655), [`ui/dr-ui/src/develop.rs:7853`](../ui/dr-ui/src/develop.rs#L7853), [`ui/dr-ui/src/lib.rs:873`](../ui/dr-ui/src/lib.rs#L873), [`ui/dr-ui/tests/ui_names_no_operation.rs:1`](../ui/dr-ui/tests/ui_names_no_operation.rs#L1), [`ui/dr-ui/ui/app.slint:2479`](../ui/dr-ui/ui/app.slint#L2479) | | FR-DEV-3b | [`core/dr-pipeline/src/descriptor.rs:276`](../core/dr-pipeline/src/descriptor.rs#L276), [`core/dr-pipeline/src/framing.rs:395`](../core/dr-pipeline/src/framing.rs#L395), [`core/dr-pipeline/src/graph.rs:60`](../core/dr-pipeline/src/graph.rs#L60), [`core/dr-pipeline/src/operation.rs:365`](../core/dr-pipeline/src/operation.rs#L365), [`ui/dr-ui/ui/app.slint:2690`](../ui/dr-ui/ui/app.slint#L2690) | | FR-DEV-3c | [`core/dr-pipeline/ops/exposure.yaml:1`](../core/dr-pipeline/ops/exposure.yaml#L1), [`core/dr-pipeline/src/graph.rs:393`](../core/dr-pipeline/src/graph.rs#L393), [`core/dr-pipeline/src/graph.rs:47`](../core/dr-pipeline/src/graph.rs#L47), [`core/dr-pipeline/src/mask.rs:1699`](../core/dr-pipeline/src/mask.rs#L1699), [`core/dr-pipeline/src/preset.rs:751`](../core/dr-pipeline/src/preset.rs#L751), [`ui/dr-ui/src/develop.rs:7904`](../ui/dr-ui/src/develop.rs#L7904) | -| 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:950`](../core/dr-pipeline/src/graph.rs#L950), [`core/dr-pipeline/src/operation.rs:32`](../core/dr-pipeline/src/operation.rs#L32), [`core/dr-pipeline/src/operation.rs:403`](../core/dr-pipeline/src/operation.rs#L403), [`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:716`](../core/dr-decode/src/lib.rs#L716), [`core/dr-decode/src/lib.rs:756`](../core/dr-decode/src/lib.rs#L756), [`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:1837`](../core/dr-pipeline/src/operation.rs#L1837), [`core/dr-pipeline/src/operation.rs:1918`](../core/dr-pipeline/src/operation.rs#L1918), [`core/dr-pipeline/src/operation.rs:1943`](../core/dr-pipeline/src/operation.rs#L1943), [`core/dr-pipeline/src/operation.rs:1958`](../core/dr-pipeline/src/operation.rs#L1958), [`core/dr-pipeline/src/operation.rs:1982`](../core/dr-pipeline/src/operation.rs#L1982), [`core/dr-pipeline/src/operation.rs:310`](../core/dr-pipeline/src/operation.rs#L310), [`core/dr-pipeline/src/operation.rs:454`](../core/dr-pipeline/src/operation.rs#L454), [`core/dr-pipeline/src/operation.rs:464`](../core/dr-pipeline/src/operation.rs#L464), [`core/dr-pipeline/src/operation.rs:647`](../core/dr-pipeline/src/operation.rs#L647) | -| 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:103`](../core/dr-pipeline/src/graph.rs#L103), [`core/dr-pipeline/src/graph.rs:168`](../core/dr-pipeline/src/graph.rs#L168), [`core/dr-pipeline/src/graph.rs:566`](../core/dr-pipeline/src/graph.rs#L566), [`core/dr-pipeline/src/operation.rs:1165`](../core/dr-pipeline/src/operation.rs#L1165), [`core/dr-pipeline/src/operation.rs:1193`](../core/dr-pipeline/src/operation.rs#L1193), [`core/dr-pipeline/src/operation.rs:1239`](../core/dr-pipeline/src/operation.rs#L1239), [`core/dr-pipeline/src/operation.rs:1837`](../core/dr-pipeline/src/operation.rs#L1837), [`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:102`](../core/dr-pipeline/src/ops/film_sim.rs#L102), [`core/dr-pipeline/src/ops/film_sim.rs:139`](../core/dr-pipeline/src/ops/film_sim.rs#L139), [`core/dr-pipeline/src/ops/film_sim.rs:163`](../core/dr-pipeline/src/ops/film_sim.rs#L163), [`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:341`](../core/dr-pipeline/src/ops/film_sim.rs#L341), [`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:97`](../core/dr-pipeline/src/ops/film_sim.rs#L97), [`core/dr-pipeline/src/sidecar.rs:1028`](../core/dr-pipeline/src/sidecar.rs#L1028), [`core/dr-pipeline/src/sidecar.rs:115`](../core/dr-pipeline/src/sidecar.rs#L115), [`core/dr-pipeline/src/sidecar.rs:188`](../core/dr-pipeline/src/sidecar.rs#L188), [`core/dr-pipeline/src/sidecar.rs:2634`](../core/dr-pipeline/src/sidecar.rs#L2634), [`core/dr-pipeline/src/sidecar.rs:2710`](../core/dr-pipeline/src/sidecar.rs#L2710), [`core/dr-pipeline/src/sidecar.rs:561`](../core/dr-pipeline/src/sidecar.rs#L561), [`core/dr-pipeline/src/sidecar.rs:854`](../core/dr-pipeline/src/sidecar.rs#L854), [`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:1170`](../ui/dr-ui/src/develop.rs#L1170), [`ui/dr-ui/src/develop.rs:4768`](../ui/dr-ui/src/develop.rs#L4768), [`ui/dr-ui/src/develop.rs:4785`](../ui/dr-ui/src/develop.rs#L4785), [`ui/dr-ui/src/develop.rs:4797`](../ui/dr-ui/src/develop.rs#L4797), [`ui/dr-ui/src/develop.rs:4835`](../ui/dr-ui/src/develop.rs#L4835), [`ui/dr-ui/src/develop.rs:4844`](../ui/dr-ui/src/develop.rs#L4844), [`ui/dr-ui/src/develop.rs:4947`](../ui/dr-ui/src/develop.rs#L4947), [`ui/dr-ui/src/develop.rs:5458`](../ui/dr-ui/src/develop.rs#L5458), [`ui/dr-ui/src/develop.rs:5629`](../ui/dr-ui/src/develop.rs#L5629), [`ui/dr-ui/src/develop.rs:8395`](../ui/dr-ui/src/develop.rs#L8395), [`ui/dr-ui/src/lib.rs:2812`](../ui/dr-ui/src/lib.rs#L2812), [`ui/dr-ui/src/lib.rs:799`](../ui/dr-ui/src/lib.rs#L799), [`ui/dr-ui/src/lib.rs:864`](../ui/dr-ui/src/lib.rs#L864), [`ui/dr-ui/src/library.rs:538`](../ui/dr-ui/src/library.rs#L538), [`ui/dr-ui/src/library.rs:806`](../ui/dr-ui/src/library.rs#L806), [`ui/dr-ui/src/presets.rs:422`](../ui/dr-ui/src/presets.rs#L422), [`ui/dr-ui/ui/adjust.slint:1040`](../ui/dr-ui/ui/adjust.slint#L1040), [`ui/dr-ui/ui/adjust.slint:1050`](../ui/dr-ui/ui/adjust.slint#L1050), [`ui/dr-ui/ui/adjust.slint:1268`](../ui/dr-ui/ui/adjust.slint#L1268) | +| FR-DEV-3d | [`core/dr-gpu/src/adjust.rs:1014`](../core/dr-gpu/src/adjust.rs#L1014), [`core/dr-gpu/src/adjust.rs:1107`](../core/dr-gpu/src/adjust.rs#L1107), [`core/dr-gpu/src/adjust.rs:114`](../core/dr-gpu/src/adjust.rs#L114), [`core/dr-gpu/src/adjust.rs:798`](../core/dr-gpu/src/adjust.rs#L798), [`core/dr-gpu/src/adjust.rs:84`](../core/dr-gpu/src/adjust.rs#L84), [`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:958`](../core/dr-pipeline/src/graph.rs#L958), [`core/dr-pipeline/src/operation.rs:32`](../core/dr-pipeline/src/operation.rs#L32), [`core/dr-pipeline/src/operation.rs:403`](../core/dr-pipeline/src/operation.rs#L403), [`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:716`](../core/dr-decode/src/lib.rs#L716), [`core/dr-decode/src/lib.rs:756`](../core/dr-decode/src/lib.rs#L756), [`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:995`](../core/dr-gpu/src/adjust.rs#L995), [`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:1904`](../core/dr-pipeline/src/operation.rs#L1904), [`core/dr-pipeline/src/operation.rs:1985`](../core/dr-pipeline/src/operation.rs#L1985), [`core/dr-pipeline/src/operation.rs:2010`](../core/dr-pipeline/src/operation.rs#L2010), [`core/dr-pipeline/src/operation.rs:2025`](../core/dr-pipeline/src/operation.rs#L2025), [`core/dr-pipeline/src/operation.rs:2049`](../core/dr-pipeline/src/operation.rs#L2049), [`core/dr-pipeline/src/operation.rs:310`](../core/dr-pipeline/src/operation.rs#L310), [`core/dr-pipeline/src/operation.rs:469`](../core/dr-pipeline/src/operation.rs#L469), [`core/dr-pipeline/src/operation.rs:479`](../core/dr-pipeline/src/operation.rs#L479), [`core/dr-pipeline/src/operation.rs:704`](../core/dr-pipeline/src/operation.rs#L704) | +| 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:149`](../core/dr-gpu/src/adjust.rs#L149), [`core/dr-gpu/src/adjust.rs:206`](../core/dr-gpu/src/adjust.rs#L206), [`core/dr-gpu/src/adjust.rs:381`](../core/dr-gpu/src/adjust.rs#L381), [`core/dr-gpu/src/adjust.rs:510`](../core/dr-gpu/src/adjust.rs#L510), [`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:103`](../core/dr-pipeline/src/graph.rs#L103), [`core/dr-pipeline/src/graph.rs:168`](../core/dr-pipeline/src/graph.rs#L168), [`core/dr-pipeline/src/graph.rs:566`](../core/dr-pipeline/src/graph.rs#L566), [`core/dr-pipeline/src/operation.rs:1232`](../core/dr-pipeline/src/operation.rs#L1232), [`core/dr-pipeline/src/operation.rs:1260`](../core/dr-pipeline/src/operation.rs#L1260), [`core/dr-pipeline/src/operation.rs:1306`](../core/dr-pipeline/src/operation.rs#L1306), [`core/dr-pipeline/src/operation.rs:1904`](../core/dr-pipeline/src/operation.rs#L1904), [`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:102`](../core/dr-pipeline/src/ops/film_sim.rs#L102), [`core/dr-pipeline/src/ops/film_sim.rs:139`](../core/dr-pipeline/src/ops/film_sim.rs#L139), [`core/dr-pipeline/src/ops/film_sim.rs:163`](../core/dr-pipeline/src/ops/film_sim.rs#L163), [`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:341`](../core/dr-pipeline/src/ops/film_sim.rs#L341), [`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:97`](../core/dr-pipeline/src/ops/film_sim.rs#L97), [`core/dr-pipeline/src/sidecar.rs:1028`](../core/dr-pipeline/src/sidecar.rs#L1028), [`core/dr-pipeline/src/sidecar.rs:115`](../core/dr-pipeline/src/sidecar.rs#L115), [`core/dr-pipeline/src/sidecar.rs:188`](../core/dr-pipeline/src/sidecar.rs#L188), [`core/dr-pipeline/src/sidecar.rs:2634`](../core/dr-pipeline/src/sidecar.rs#L2634), [`core/dr-pipeline/src/sidecar.rs:2710`](../core/dr-pipeline/src/sidecar.rs#L2710), [`core/dr-pipeline/src/sidecar.rs:561`](../core/dr-pipeline/src/sidecar.rs#L561), [`core/dr-pipeline/src/sidecar.rs:854`](../core/dr-pipeline/src/sidecar.rs#L854), [`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:1170`](../ui/dr-ui/src/develop.rs#L1170), [`ui/dr-ui/src/develop.rs:4768`](../ui/dr-ui/src/develop.rs#L4768), [`ui/dr-ui/src/develop.rs:4785`](../ui/dr-ui/src/develop.rs#L4785), [`ui/dr-ui/src/develop.rs:4797`](../ui/dr-ui/src/develop.rs#L4797), [`ui/dr-ui/src/develop.rs:4835`](../ui/dr-ui/src/develop.rs#L4835), [`ui/dr-ui/src/develop.rs:4844`](../ui/dr-ui/src/develop.rs#L4844), [`ui/dr-ui/src/develop.rs:4947`](../ui/dr-ui/src/develop.rs#L4947), [`ui/dr-ui/src/develop.rs:5458`](../ui/dr-ui/src/develop.rs#L5458), [`ui/dr-ui/src/develop.rs:5629`](../ui/dr-ui/src/develop.rs#L5629), [`ui/dr-ui/src/develop.rs:8395`](../ui/dr-ui/src/develop.rs#L8395), [`ui/dr-ui/src/lib.rs:2812`](../ui/dr-ui/src/lib.rs#L2812), [`ui/dr-ui/src/lib.rs:799`](../ui/dr-ui/src/lib.rs#L799), [`ui/dr-ui/src/lib.rs:864`](../ui/dr-ui/src/lib.rs#L864), [`ui/dr-ui/src/library.rs:538`](../ui/dr-ui/src/library.rs#L538), [`ui/dr-ui/src/library.rs:806`](../ui/dr-ui/src/library.rs#L806), [`ui/dr-ui/src/presets.rs:422`](../ui/dr-ui/src/presets.rs#L422), [`ui/dr-ui/ui/adjust.slint:1040`](../ui/dr-ui/ui/adjust.slint#L1040), [`ui/dr-ui/ui/adjust.slint:1050`](../ui/dr-ui/ui/adjust.slint#L1050), [`ui/dr-ui/ui/adjust.slint:1268`](../ui/dr-ui/ui/adjust.slint#L1268) | | FR-DEV-3h | [`core/dr-decode/src/lib.rs:408`](../core/dr-decode/src/lib.rs#L408), [`core/dr-decode/src/preview.rs:29`](../core/dr-decode/src/preview.rs#L29), [`core/dr-pipeline/src/framing.rs:1067`](../core/dr-pipeline/src/framing.rs#L1067), [`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:339`](../core/dr-types/src/lib.rs#L339), [`core/dr-types/src/lib.rs:447`](../core/dr-types/src/lib.rs#L447), [`core/dr-types/src/lib.rs:459`](../core/dr-types/src/lib.rs#L459), [`core/dr-types/src/lib.rs:475`](../core/dr-types/src/lib.rs#L475), [`ui/dr-ui/src/develop.rs:140`](../ui/dr-ui/src/develop.rs#L140), [`ui/dr-ui/src/develop.rs:2769`](../ui/dr-ui/src/develop.rs#L2769), [`ui/dr-ui/src/segmentation.rs:499`](../ui/dr-ui/src/segmentation.rs#L499) | | FR-DEV-3i | [`core/dr-pipeline/src/mask.rs:558`](../core/dr-pipeline/src/mask.rs#L558), [`core/dr-segment/src/lib.rs:1`](../core/dr-segment/src/lib.rs#L1), [`ui/dr-ui/src/segmentation.rs:1`](../ui/dr-ui/src/segmentation.rs#L1) | -| FR-DEV-4 | [`core/dr-gpu/src/adjust.rs:770`](../core/dr-gpu/src/adjust.rs#L770), [`core/dr-gpu/src/lib.rs:366`](../core/dr-gpu/src/lib.rs#L366), [`ui/dr-ui/ui/crop.slint:1`](../ui/dr-ui/ui/crop.slint#L1) | -| FR-DEV-5 | [`core/dr-pipeline/src/graph.rs:1399`](../core/dr-pipeline/src/graph.rs#L1399), [`core/dr-pipeline/src/graph.rs:587`](../core/dr-pipeline/src/graph.rs#L587), [`core/dr-pipeline/src/graph.rs:640`](../core/dr-pipeline/src/graph.rs#L640), [`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/sidecar.rs:1018`](../core/dr-pipeline/src/sidecar.rs#L1018), [`core/dr-pipeline/src/sidecar.rs:129`](../core/dr-pipeline/src/sidecar.rs#L129), [`core/dr-pipeline/src/sidecar.rs:2425`](../core/dr-pipeline/src/sidecar.rs#L2425), [`core/dr-pipeline/src/sidecar.rs:2461`](../core/dr-pipeline/src/sidecar.rs#L2461), [`core/dr-pipeline/src/sidecar.rs:2473`](../core/dr-pipeline/src/sidecar.rs#L2473), [`core/dr-pipeline/src/sidecar.rs:288`](../core/dr-pipeline/src/sidecar.rs#L288), [`core/dr-pipeline/src/sidecar.rs:679`](../core/dr-pipeline/src/sidecar.rs#L679), [`core/dr-pipeline/src/sidecar.rs:695`](../core/dr-pipeline/src/sidecar.rs#L695), [`core/dr-pipeline/src/sidecar.rs:835`](../core/dr-pipeline/src/sidecar.rs#L835), [`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:4400`](../ui/dr-ui/src/develop.rs#L4400), [`ui/dr-ui/src/develop.rs:4797`](../ui/dr-ui/src/develop.rs#L4797), [`ui/dr-ui/src/develop.rs:5475`](../ui/dr-ui/src/develop.rs#L5475), [`ui/dr-ui/src/develop.rs:5493`](../ui/dr-ui/src/develop.rs#L5493), [`ui/dr-ui/src/develop.rs:5532`](../ui/dr-ui/src/develop.rs#L5532), [`ui/dr-ui/src/develop.rs:5546`](../ui/dr-ui/src/develop.rs#L5546), [`ui/dr-ui/src/develop.rs:5557`](../ui/dr-ui/src/develop.rs#L5557), [`ui/dr-ui/src/develop.rs:5616`](../ui/dr-ui/src/develop.rs#L5616), [`ui/dr-ui/src/develop.rs:5629`](../ui/dr-ui/src/develop.rs#L5629), [`ui/dr-ui/src/develop.rs:5659`](../ui/dr-ui/src/develop.rs#L5659), [`ui/dr-ui/src/develop.rs:5672`](../ui/dr-ui/src/develop.rs#L5672), [`ui/dr-ui/src/develop.rs:5684`](../ui/dr-ui/src/develop.rs#L5684), [`ui/dr-ui/src/develop.rs:5700`](../ui/dr-ui/src/develop.rs#L5700), [`ui/dr-ui/src/develop.rs:5732`](../ui/dr-ui/src/develop.rs#L5732), [`ui/dr-ui/src/develop.rs:5736`](../ui/dr-ui/src/develop.rs#L5736), [`ui/dr-ui/src/develop.rs:5755`](../ui/dr-ui/src/develop.rs#L5755), [`ui/dr-ui/src/develop.rs:5771`](../ui/dr-ui/src/develop.rs#L5771), [`ui/dr-ui/src/develop.rs:6613`](../ui/dr-ui/src/develop.rs#L6613), [`ui/dr-ui/src/develop.rs:6633`](../ui/dr-ui/src/develop.rs#L6633), [`ui/dr-ui/src/develop.rs:6664`](../ui/dr-ui/src/develop.rs#L6664), [`ui/dr-ui/src/develop.rs:6721`](../ui/dr-ui/src/develop.rs#L6721), [`ui/dr-ui/src/develop.rs:6781`](../ui/dr-ui/src/develop.rs#L6781), [`ui/dr-ui/src/develop.rs:772`](../ui/dr-ui/src/develop.rs#L772), [`ui/dr-ui/src/develop.rs:781`](../ui/dr-ui/src/develop.rs#L781), [`ui/dr-ui/src/labels.rs:12`](../ui/dr-ui/src/labels.rs#L12), [`ui/dr-ui/src/labels.rs:278`](../ui/dr-ui/src/labels.rs#L278), [`ui/dr-ui/src/labels.rs:31`](../ui/dr-ui/src/labels.rs#L31), [`ui/dr-ui/src/lib.rs:1860`](../ui/dr-ui/src/lib.rs#L1860), [`ui/dr-ui/src/lib.rs:1865`](../ui/dr-ui/src/lib.rs#L1865), [`ui/dr-ui/src/lib.rs:1928`](../ui/dr-ui/src/lib.rs#L1928), [`ui/dr-ui/src/lib.rs:1937`](../ui/dr-ui/src/lib.rs#L1937), [`ui/dr-ui/src/lib.rs:1949`](../ui/dr-ui/src/lib.rs#L1949), [`ui/dr-ui/src/lib.rs:3080`](../ui/dr-ui/src/lib.rs#L3080), [`ui/dr-ui/src/lib.rs:3100`](../ui/dr-ui/src/lib.rs#L3100), [`ui/dr-ui/src/library.rs:547`](../ui/dr-ui/src/library.rs#L547), [`ui/dr-ui/src/library.rs:832`](../ui/dr-ui/src/library.rs#L832), [`ui/dr-ui/src/presets.rs:1678`](../ui/dr-ui/src/presets.rs#L1678), [`ui/dr-ui/src/presets.rs:373`](../ui/dr-ui/src/presets.rs#L373), [`ui/dr-ui/src/presets.rs:437`](../ui/dr-ui/src/presets.rs#L437), [`ui/dr-ui/src/presets.rs:557`](../ui/dr-ui/src/presets.rs#L557), [`ui/dr-ui/ui/history.slint:191`](../ui/dr-ui/ui/history.slint#L191), [`ui/dr-ui/ui/history.slint:1`](../ui/dr-ui/ui/history.slint#L1), [`ui/dr-ui/ui/history.slint:218`](../ui/dr-ui/ui/history.slint#L218), [`ui/dr-ui/ui/history.slint:303`](../ui/dr-ui/ui/history.slint#L303), [`ui/dr-ui/ui/history.slint:43`](../ui/dr-ui/ui/history.slint#L43), [`ui/dr-ui/ui/history.slint:53`](../ui/dr-ui/ui/history.slint#L53) | +| FR-DEV-4 | [`core/dr-gpu/src/adjust.rs:798`](../core/dr-gpu/src/adjust.rs#L798), [`core/dr-gpu/src/lib.rs:366`](../core/dr-gpu/src/lib.rs#L366), [`ui/dr-ui/ui/crop.slint:1`](../ui/dr-ui/ui/crop.slint#L1) | +| FR-DEV-5 | [`core/dr-pipeline/src/graph.rs:1407`](../core/dr-pipeline/src/graph.rs#L1407), [`core/dr-pipeline/src/graph.rs:587`](../core/dr-pipeline/src/graph.rs#L587), [`core/dr-pipeline/src/graph.rs:640`](../core/dr-pipeline/src/graph.rs#L640), [`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/sidecar.rs:1018`](../core/dr-pipeline/src/sidecar.rs#L1018), [`core/dr-pipeline/src/sidecar.rs:129`](../core/dr-pipeline/src/sidecar.rs#L129), [`core/dr-pipeline/src/sidecar.rs:2425`](../core/dr-pipeline/src/sidecar.rs#L2425), [`core/dr-pipeline/src/sidecar.rs:2461`](../core/dr-pipeline/src/sidecar.rs#L2461), [`core/dr-pipeline/src/sidecar.rs:2473`](../core/dr-pipeline/src/sidecar.rs#L2473), [`core/dr-pipeline/src/sidecar.rs:288`](../core/dr-pipeline/src/sidecar.rs#L288), [`core/dr-pipeline/src/sidecar.rs:679`](../core/dr-pipeline/src/sidecar.rs#L679), [`core/dr-pipeline/src/sidecar.rs:695`](../core/dr-pipeline/src/sidecar.rs#L695), [`core/dr-pipeline/src/sidecar.rs:835`](../core/dr-pipeline/src/sidecar.rs#L835), [`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:4400`](../ui/dr-ui/src/develop.rs#L4400), [`ui/dr-ui/src/develop.rs:4797`](../ui/dr-ui/src/develop.rs#L4797), [`ui/dr-ui/src/develop.rs:5475`](../ui/dr-ui/src/develop.rs#L5475), [`ui/dr-ui/src/develop.rs:5493`](../ui/dr-ui/src/develop.rs#L5493), [`ui/dr-ui/src/develop.rs:5532`](../ui/dr-ui/src/develop.rs#L5532), [`ui/dr-ui/src/develop.rs:5546`](../ui/dr-ui/src/develop.rs#L5546), [`ui/dr-ui/src/develop.rs:5557`](../ui/dr-ui/src/develop.rs#L5557), [`ui/dr-ui/src/develop.rs:5616`](../ui/dr-ui/src/develop.rs#L5616), [`ui/dr-ui/src/develop.rs:5629`](../ui/dr-ui/src/develop.rs#L5629), [`ui/dr-ui/src/develop.rs:5659`](../ui/dr-ui/src/develop.rs#L5659), [`ui/dr-ui/src/develop.rs:5672`](../ui/dr-ui/src/develop.rs#L5672), [`ui/dr-ui/src/develop.rs:5684`](../ui/dr-ui/src/develop.rs#L5684), [`ui/dr-ui/src/develop.rs:5700`](../ui/dr-ui/src/develop.rs#L5700), [`ui/dr-ui/src/develop.rs:5732`](../ui/dr-ui/src/develop.rs#L5732), [`ui/dr-ui/src/develop.rs:5736`](../ui/dr-ui/src/develop.rs#L5736), [`ui/dr-ui/src/develop.rs:5755`](../ui/dr-ui/src/develop.rs#L5755), [`ui/dr-ui/src/develop.rs:5771`](../ui/dr-ui/src/develop.rs#L5771), [`ui/dr-ui/src/develop.rs:6613`](../ui/dr-ui/src/develop.rs#L6613), [`ui/dr-ui/src/develop.rs:6633`](../ui/dr-ui/src/develop.rs#L6633), [`ui/dr-ui/src/develop.rs:6664`](../ui/dr-ui/src/develop.rs#L6664), [`ui/dr-ui/src/develop.rs:6721`](../ui/dr-ui/src/develop.rs#L6721), [`ui/dr-ui/src/develop.rs:6781`](../ui/dr-ui/src/develop.rs#L6781), [`ui/dr-ui/src/develop.rs:772`](../ui/dr-ui/src/develop.rs#L772), [`ui/dr-ui/src/develop.rs:781`](../ui/dr-ui/src/develop.rs#L781), [`ui/dr-ui/src/labels.rs:12`](../ui/dr-ui/src/labels.rs#L12), [`ui/dr-ui/src/labels.rs:278`](../ui/dr-ui/src/labels.rs#L278), [`ui/dr-ui/src/labels.rs:31`](../ui/dr-ui/src/labels.rs#L31), [`ui/dr-ui/src/lib.rs:1860`](../ui/dr-ui/src/lib.rs#L1860), [`ui/dr-ui/src/lib.rs:1865`](../ui/dr-ui/src/lib.rs#L1865), [`ui/dr-ui/src/lib.rs:1928`](../ui/dr-ui/src/lib.rs#L1928), [`ui/dr-ui/src/lib.rs:1937`](../ui/dr-ui/src/lib.rs#L1937), [`ui/dr-ui/src/lib.rs:1949`](../ui/dr-ui/src/lib.rs#L1949), [`ui/dr-ui/src/lib.rs:3080`](../ui/dr-ui/src/lib.rs#L3080), [`ui/dr-ui/src/lib.rs:3100`](../ui/dr-ui/src/lib.rs#L3100), [`ui/dr-ui/src/library.rs:547`](../ui/dr-ui/src/library.rs#L547), [`ui/dr-ui/src/library.rs:832`](../ui/dr-ui/src/library.rs#L832), [`ui/dr-ui/src/presets.rs:1678`](../ui/dr-ui/src/presets.rs#L1678), [`ui/dr-ui/src/presets.rs:373`](../ui/dr-ui/src/presets.rs#L373), [`ui/dr-ui/src/presets.rs:437`](../ui/dr-ui/src/presets.rs#L437), [`ui/dr-ui/src/presets.rs:557`](../ui/dr-ui/src/presets.rs#L557), [`ui/dr-ui/ui/history.slint:191`](../ui/dr-ui/ui/history.slint#L191), [`ui/dr-ui/ui/history.slint:1`](../ui/dr-ui/ui/history.slint#L1), [`ui/dr-ui/ui/history.slint:218`](../ui/dr-ui/ui/history.slint#L218), [`ui/dr-ui/ui/history.slint:303`](../ui/dr-ui/ui/history.slint#L303), [`ui/dr-ui/ui/history.slint:43`](../ui/dr-ui/ui/history.slint#L43), [`ui/dr-ui/ui/history.slint:53`](../ui/dr-ui/ui/history.slint#L53) | | FR-DEV-6 | [`core/dr-pipeline/src/preset.rs:1`](../core/dr-pipeline/src/preset.rs#L1), [`core/dr-pipeline/src/preset.rs:390`](../core/dr-pipeline/src/preset.rs#L390), [`core/dr-pipeline/src/preset.rs:423`](../core/dr-pipeline/src/preset.rs#L423), [`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:419`](../core/dr-types/src/settings.rs#L419), [`ui/dr-ui/src/develop.rs:5415`](../ui/dr-ui/src/develop.rs#L5415), [`ui/dr-ui/src/develop.rs:5436`](../ui/dr-ui/src/develop.rs#L5436), [`ui/dr-ui/src/lib.rs:1827`](../ui/dr-ui/src/lib.rs#L1827), [`ui/dr-ui/src/lib.rs:2613`](../ui/dr-ui/src/lib.rs#L2613), [`ui/dr-ui/src/lib.rs:2642`](../ui/dr-ui/src/lib.rs#L2642), [`ui/dr-ui/src/library.rs:2427`](../ui/dr-ui/src/library.rs#L2427), [`ui/dr-ui/src/library.rs:500`](../ui/dr-ui/src/library.rs#L500), [`ui/dr-ui/src/library.rs:528`](../ui/dr-ui/src/library.rs#L528), [`ui/dr-ui/src/library_ui.rs:3281`](../ui/dr-ui/src/library_ui.rs#L3281), [`ui/dr-ui/src/library_ui.rs:3864`](../ui/dr-ui/src/library_ui.rs#L3864), [`ui/dr-ui/src/library_ui.rs:628`](../ui/dr-ui/src/library_ui.rs#L628), [`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:707`](../ui/dr-ui/src/presets.rs#L707), [`ui/dr-ui/src/presets.rs:741`](../ui/dr-ui/src/presets.rs#L741), [`ui/dr-ui/ui/adjust.slint:853`](../ui/dr-ui/ui/adjust.slint#L853), [`ui/dr-ui/ui/adjust.slint:878`](../ui/dr-ui/ui/adjust.slint#L878), [`ui/dr-ui/ui/adjust.slint:889`](../ui/dr-ui/ui/adjust.slint#L889), [`ui/dr-ui/ui/adjust.slint:932`](../ui/dr-ui/ui/adjust.slint#L932), [`ui/dr-ui/ui/app.slint:1620`](../ui/dr-ui/ui/app.slint#L1620), [`ui/dr-ui/ui/app.slint:2448`](../ui/dr-ui/ui/app.slint#L2448), [`ui/dr-ui/ui/app.slint:3083`](../ui/dr-ui/ui/app.slint#L3083), [`ui/dr-ui/ui/app.slint:755`](../ui/dr-ui/ui/app.slint#L755), [`ui/dr-ui/ui/app.slint:766`](../ui/dr-ui/ui/app.slint#L766), [`ui/dr-ui/ui/library.slint:1574`](../ui/dr-ui/ui/library.slint#L1574), [`ui/dr-ui/ui/library.slint:1580`](../ui/dr-ui/ui/library.slint#L1580), [`ui/dr-ui/ui/library.slint:4217`](../ui/dr-ui/ui/library.slint#L4217), [`ui/dr-ui/ui/library.slint:4232`](../ui/dr-ui/ui/library.slint#L4232), [`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:113`](../ui/dr-ui/ui/settings.slint#L113), [`ui/dr-ui/ui/settings.slint:658`](../ui/dr-ui/ui/settings.slint#L658) | | 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:4334`](../ui/dr-ui/src/develop.rs#L4334), [`ui/dr-ui/src/develop.rs:4375`](../ui/dr-ui/src/develop.rs#L4375), [`ui/dr-ui/src/develop.rs:5571`](../ui/dr-ui/src/develop.rs#L5571), [`ui/dr-ui/src/develop.rs:5588`](../ui/dr-ui/src/develop.rs#L5588), [`ui/dr-ui/src/develop.rs:5700`](../ui/dr-ui/src/develop.rs#L5700), [`ui/dr-ui/src/develop.rs:5732`](../ui/dr-ui/src/develop.rs#L5732), [`ui/dr-ui/src/develop.rs:6664`](../ui/dr-ui/src/develop.rs#L6664), [`ui/dr-ui/src/develop.rs:6781`](../ui/dr-ui/src/develop.rs#L6781), [`ui/dr-ui/src/develop.rs:797`](../ui/dr-ui/src/develop.rs#L797), [`ui/dr-ui/src/lib.rs:1937`](../ui/dr-ui/src/lib.rs#L1937), [`ui/dr-ui/src/lib.rs:2009`](../ui/dr-ui/src/lib.rs#L2009), [`ui/dr-ui/src/lib.rs:2023`](../ui/dr-ui/src/lib.rs#L2023), [`ui/dr-ui/src/lib.rs:3019`](../ui/dr-ui/src/lib.rs#L3019), [`ui/dr-ui/src/lib.rs:3080`](../ui/dr-ui/src/lib.rs#L3080), [`ui/dr-ui/src/lib.rs:3152`](../ui/dr-ui/src/lib.rs#L3152), [`ui/dr-ui/src/lib.rs:405`](../ui/dr-ui/src/lib.rs#L405), [`ui/dr-ui/ui/app.slint:128`](../ui/dr-ui/ui/app.slint#L128), [`ui/dr-ui/ui/app.slint:2355`](../ui/dr-ui/ui/app.slint#L2355), [`ui/dr-ui/ui/app.slint:2370`](../ui/dr-ui/ui/app.slint#L2370), [`ui/dr-ui/ui/app.slint:2690`](../ui/dr-ui/ui/app.slint#L2690), [`ui/dr-ui/ui/history.slint:102`](../ui/dr-ui/ui/history.slint#L102), [`ui/dr-ui/ui/history.slint:1`](../ui/dr-ui/ui/history.slint#L1), [`ui/dr-ui/ui/history.slint:226`](../ui/dr-ui/ui/history.slint#L226), [`ui/dr-ui/ui/history.slint:53`](../ui/dr-ui/ui/history.slint#L53), [`ui/dr-ui/ui/widgets.slint:71`](../ui/dr-ui/ui/widgets.slint#L71) | -| 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:1051`](../core/dr-pipeline/src/graph.rs#L1051), [`core/dr-pipeline/src/graph.rs:115`](../core/dr-pipeline/src/graph.rs#L115), [`core/dr-pipeline/src/graph.rs:247`](../core/dr-pipeline/src/graph.rs#L247), [`core/dr-pipeline/src/operation.rs:330`](../core/dr-pipeline/src/operation.rs#L330), [`core/dr-pipeline/src/operation.rs:601`](../core/dr-pipeline/src/operation.rs#L601), [`core/dr-pipeline/src/sidecar.rs:1044`](../core/dr-pipeline/src/sidecar.rs#L1044), [`core/dr-pipeline/src/sidecar.rs:1098`](../core/dr-pipeline/src/sidecar.rs#L1098), [`core/dr-pipeline/src/sidecar.rs:1128`](../core/dr-pipeline/src/sidecar.rs#L1128), [`core/dr-pipeline/src/sidecar.rs:204`](../core/dr-pipeline/src/sidecar.rs#L204), [`core/dr-pipeline/src/sidecar.rs:380`](../core/dr-pipeline/src/sidecar.rs#L380), [`core/dr-pipeline/src/sidecar.rs:866`](../core/dr-pipeline/src/sidecar.rs#L866), [`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:3200`](../ui/dr-ui/src/develop.rs#L3200), [`ui/dr-ui/src/develop.rs:3238`](../ui/dr-ui/src/develop.rs#L3238), [`ui/dr-ui/src/develop.rs:3303`](../ui/dr-ui/src/develop.rs#L3303), [`ui/dr-ui/src/develop.rs:3386`](../ui/dr-ui/src/develop.rs#L3386), [`ui/dr-ui/src/develop.rs:3400`](../ui/dr-ui/src/develop.rs#L3400), [`ui/dr-ui/src/develop.rs:904`](../ui/dr-ui/src/develop.rs#L904), [`ui/dr-ui/src/labels.rs:80`](../ui/dr-ui/src/labels.rs#L80), [`ui/dr-ui/src/lib.rs:1967`](../ui/dr-ui/src/lib.rs#L1967), [`ui/dr-ui/src/lib.rs:3305`](../ui/dr-ui/src/lib.rs#L3305), [`ui/dr-ui/src/lib.rs:447`](../ui/dr-ui/src/lib.rs#L447), [`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/app.slint:2211`](../ui/dr-ui/ui/app.slint#L2211), [`ui/dr-ui/ui/app.slint:2413`](../ui/dr-ui/ui/app.slint#L2413), [`ui/dr-ui/ui/app.slint:2989`](../ui/dr-ui/ui/app.slint#L2989), [`ui/dr-ui/ui/icons.slint:366`](../ui/dr-ui/ui/icons.slint#L366), [`ui/dr-ui/ui/session.slint:102`](../ui/dr-ui/ui/session.slint#L102), [`ui/dr-ui/ui/session.slint:52`](../ui/dr-ui/ui/session.slint#L52), [`ui/dr-ui/ui/spots.slint:191`](../ui/dr-ui/ui/spots.slint#L191), [`ui/dr-ui/ui/spots.slint:49`](../ui/dr-ui/ui/spots.slint#L49), [`ui/dr-ui/ui/spots.slint:6`](../ui/dr-ui/ui/spots.slint#L6), [`ui/dr-ui/ui/spots.slint:91`](../ui/dr-ui/ui/spots.slint#L91) | -| FR-DSP-1 | [`core/dr-gpu/src/adjust.rs:2140`](../core/dr-gpu/src/adjust.rs#L2140), [`core/dr-gpu/src/adjust.rs:2217`](../core/dr-gpu/src/adjust.rs#L2217), [`core/dr-gpu/src/adjust.rs:2302`](../core/dr-gpu/src/adjust.rs#L2302), [`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:881`](../core/dr-pipeline/src/graph.rs#L881), [`core/dr-pipeline/src/graph.rs:911`](../core/dr-pipeline/src/graph.rs#L911), [`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/dehaze.rs:1`](../core/dr-pipeline/src/ops/dehaze.rs#L1), [`core/dr-pipeline/src/ops/dehaze.rs:592`](../core/dr-pipeline/src/ops/dehaze.rs#L592), [`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:4021`](../ui/dr-ui/src/develop.rs#L4021), [`ui/dr-ui/src/develop.rs:5283`](../ui/dr-ui/src/develop.rs#L5283), [`ui/dr-ui/src/develop.rs:6026`](../ui/dr-ui/src/develop.rs#L6026), [`ui/dr-ui/src/develop.rs:7354`](../ui/dr-ui/src/develop.rs#L7354), [`ui/dr-ui/src/develop.rs:7388`](../ui/dr-ui/src/develop.rs#L7388), [`ui/dr-ui/src/lib.rs:1020`](../ui/dr-ui/src/lib.rs#L1020), [`ui/dr-ui/src/lib.rs:1079`](../ui/dr-ui/src/lib.rs#L1079), [`ui/dr-ui/src/lib.rs:94`](../ui/dr-ui/src/lib.rs#L94) | +| 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:1059`](../core/dr-pipeline/src/graph.rs#L1059), [`core/dr-pipeline/src/graph.rs:115`](../core/dr-pipeline/src/graph.rs#L115), [`core/dr-pipeline/src/graph.rs:247`](../core/dr-pipeline/src/graph.rs#L247), [`core/dr-pipeline/src/operation.rs:330`](../core/dr-pipeline/src/operation.rs#L330), [`core/dr-pipeline/src/operation.rs:652`](../core/dr-pipeline/src/operation.rs#L652), [`core/dr-pipeline/src/sidecar.rs:1044`](../core/dr-pipeline/src/sidecar.rs#L1044), [`core/dr-pipeline/src/sidecar.rs:1098`](../core/dr-pipeline/src/sidecar.rs#L1098), [`core/dr-pipeline/src/sidecar.rs:1128`](../core/dr-pipeline/src/sidecar.rs#L1128), [`core/dr-pipeline/src/sidecar.rs:204`](../core/dr-pipeline/src/sidecar.rs#L204), [`core/dr-pipeline/src/sidecar.rs:380`](../core/dr-pipeline/src/sidecar.rs#L380), [`core/dr-pipeline/src/sidecar.rs:866`](../core/dr-pipeline/src/sidecar.rs#L866), [`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:3200`](../ui/dr-ui/src/develop.rs#L3200), [`ui/dr-ui/src/develop.rs:3238`](../ui/dr-ui/src/develop.rs#L3238), [`ui/dr-ui/src/develop.rs:3303`](../ui/dr-ui/src/develop.rs#L3303), [`ui/dr-ui/src/develop.rs:3386`](../ui/dr-ui/src/develop.rs#L3386), [`ui/dr-ui/src/develop.rs:3400`](../ui/dr-ui/src/develop.rs#L3400), [`ui/dr-ui/src/develop.rs:904`](../ui/dr-ui/src/develop.rs#L904), [`ui/dr-ui/src/labels.rs:80`](../ui/dr-ui/src/labels.rs#L80), [`ui/dr-ui/src/lib.rs:1967`](../ui/dr-ui/src/lib.rs#L1967), [`ui/dr-ui/src/lib.rs:3305`](../ui/dr-ui/src/lib.rs#L3305), [`ui/dr-ui/src/lib.rs:447`](../ui/dr-ui/src/lib.rs#L447), [`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/app.slint:2211`](../ui/dr-ui/ui/app.slint#L2211), [`ui/dr-ui/ui/app.slint:2413`](../ui/dr-ui/ui/app.slint#L2413), [`ui/dr-ui/ui/app.slint:2989`](../ui/dr-ui/ui/app.slint#L2989), [`ui/dr-ui/ui/icons.slint:366`](../ui/dr-ui/ui/icons.slint#L366), [`ui/dr-ui/ui/session.slint:102`](../ui/dr-ui/ui/session.slint#L102), [`ui/dr-ui/ui/session.slint:52`](../ui/dr-ui/ui/session.slint#L52), [`ui/dr-ui/ui/spots.slint:191`](../ui/dr-ui/ui/spots.slint#L191), [`ui/dr-ui/ui/spots.slint:49`](../ui/dr-ui/ui/spots.slint#L49), [`ui/dr-ui/ui/spots.slint:6`](../ui/dr-ui/ui/spots.slint#L6), [`ui/dr-ui/ui/spots.slint:91`](../ui/dr-ui/ui/spots.slint#L91) | +| FR-DSP-1 | [`core/dr-gpu/src/adjust.rs:2350`](../core/dr-gpu/src/adjust.rs#L2350), [`core/dr-gpu/src/adjust.rs:2427`](../core/dr-gpu/src/adjust.rs#L2427), [`core/dr-gpu/src/adjust.rs:2512`](../core/dr-gpu/src/adjust.rs#L2512), [`core/dr-gpu/src/adjust.rs:54`](../core/dr-gpu/src/adjust.rs#L54), [`core/dr-gpu/src/adjust.rs:798`](../core/dr-gpu/src/adjust.rs#L798), [`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:889`](../core/dr-pipeline/src/graph.rs#L889), [`core/dr-pipeline/src/graph.rs:919`](../core/dr-pipeline/src/graph.rs#L919), [`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/dehaze.rs:1`](../core/dr-pipeline/src/ops/dehaze.rs#L1), [`core/dr-pipeline/src/ops/dehaze.rs:592`](../core/dr-pipeline/src/ops/dehaze.rs#L592), [`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:4021`](../ui/dr-ui/src/develop.rs#L4021), [`ui/dr-ui/src/develop.rs:5283`](../ui/dr-ui/src/develop.rs#L5283), [`ui/dr-ui/src/develop.rs:6026`](../ui/dr-ui/src/develop.rs#L6026), [`ui/dr-ui/src/develop.rs:7354`](../ui/dr-ui/src/develop.rs#L7354), [`ui/dr-ui/src/develop.rs:7388`](../ui/dr-ui/src/develop.rs#L7388), [`ui/dr-ui/src/lib.rs:1020`](../ui/dr-ui/src/lib.rs#L1020), [`ui/dr-ui/src/lib.rs:1079`](../ui/dr-ui/src/lib.rs#L1079), [`ui/dr-ui/src/lib.rs:94`](../ui/dr-ui/src/lib.rs#L94) | | 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:497`](../core/dr-pipeline/src/operation.rs#L497), [`core/dr-types/src/colour.rs:1`](../core/dr-types/src/colour.rs#L1), [`ui/dr-ui/src/develop.rs:4051`](../ui/dr-ui/src/develop.rs#L4051), [`ui/dr-ui/src/develop.rs:8967`](../ui/dr-ui/src/develop.rs#L8967), [`ui/dr-ui/src/lib.rs:1913`](../ui/dr-ui/src/lib.rs#L1913), [`ui/dr-ui/src/lib.rs:3696`](../ui/dr-ui/src/lib.rs#L3696) | +| FR-DSP-6 | [`core/dr-pipeline/src/operation.rs:512`](../core/dr-pipeline/src/operation.rs#L512), [`core/dr-types/src/colour.rs:1`](../core/dr-types/src/colour.rs#L1), [`ui/dr-ui/src/develop.rs:4051`](../ui/dr-ui/src/develop.rs#L4051), [`ui/dr-ui/src/develop.rs:8967`](../ui/dr-ui/src/develop.rs#L8967), [`ui/dr-ui/src/lib.rs:1913`](../ui/dr-ui/src/lib.rs#L1913), [`ui/dr-ui/src/lib.rs:3696`](../ui/dr-ui/src/lib.rs#L3696) | | 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:4105`](../ui/dr-ui/src/develop.rs#L4105), [`ui/dr-ui/src/develop.rs:804`](../ui/dr-ui/src/develop.rs#L804), [`ui/dr-ui/src/develop.rs:8641`](../ui/dr-ui/src/develop.rs#L8641), [`ui/dr-ui/src/develop.rs:8673`](../ui/dr-ui/src/develop.rs#L8673), [`ui/dr-ui/src/histogram.rs:1`](../ui/dr-ui/src/histogram.rs#L1), [`ui/dr-ui/src/lib.rs:2047`](../ui/dr-ui/src/lib.rs#L2047), [`ui/dr-ui/src/lib.rs:424`](../ui/dr-ui/src/lib.rs#L424), [`ui/dr-ui/ui/histogram.slint:184`](../ui/dr-ui/ui/histogram.slint#L184), [`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:3997`](../ui/dr-ui/src/develop.rs#L3997), [`ui/dr-ui/src/develop.rs:4051`](../ui/dr-ui/src/develop.rs#L4051), [`ui/dr-ui/src/develop.rs:8967`](../ui/dr-ui/src/develop.rs#L8967), [`ui/dr-ui/src/develop.rs:9013`](../ui/dr-ui/src/develop.rs#L9013), [`ui/dr-ui/src/develop.rs:9032`](../ui/dr-ui/src/develop.rs#L9032), [`ui/dr-ui/src/develop.rs:957`](../ui/dr-ui/src/develop.rs#L957), [`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:1849`](../ui/dr-ui/src/lib.rs#L1849), [`ui/dr-ui/src/lib.rs:1913`](../ui/dr-ui/src/lib.rs#L1913), [`ui/dr-ui/src/lib.rs:3603`](../ui/dr-ui/src/lib.rs#L3603), [`ui/dr-ui/src/lib.rs:3696`](../ui/dr-ui/src/lib.rs#L3696), [`ui/dr-ui/ui/app.slint:1891`](../ui/dr-ui/ui/app.slint#L1891), [`ui/dr-ui/ui/app.slint:61`](../ui/dr-ui/ui/app.slint#L61), [`ui/dr-ui/ui/settings.slint:155`](../ui/dr-ui/ui/settings.slint#L155), [`ui/dr-ui/ui/settings.slint:895`](../ui/dr-ui/ui/settings.slint#L895) | | 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:2450`](../core/dr-gpu/src/adjust.rs#L2450), [`core/dr-pipeline/src/graph.rs:835`](../core/dr-pipeline/src/graph.rs#L835), [`core/dr-pipeline/src/graph.rs:925`](../core/dr-pipeline/src/graph.rs#L925), [`core/dr-pipeline/src/operation.rs:497`](../core/dr-pipeline/src/operation.rs#L497), [`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:934`](../core/dr-types/src/settings.rs#L934), [`ui/dr-ui/src/develop.rs:9032`](../ui/dr-ui/src/develop.rs#L9032), [`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:2660`](../core/dr-gpu/src/adjust.rs#L2660), [`core/dr-pipeline/src/graph.rs:835`](../core/dr-pipeline/src/graph.rs#L835), [`core/dr-pipeline/src/graph.rs:933`](../core/dr-pipeline/src/graph.rs#L933), [`core/dr-pipeline/src/operation.rs:512`](../core/dr-pipeline/src/operation.rs#L512), [`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:934`](../core/dr-types/src/settings.rs#L934), [`ui/dr-ui/src/develop.rs:9032`](../ui/dr-ui/src/develop.rs#L9032), [`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:1003`](../core/dr-types/src/settings.rs#L1003), [`core/dr-types/src/settings.rs:1072`](../core/dr-types/src/settings.rs#L1072), [`core/dr-types/src/settings.rs:1100`](../core/dr-types/src/settings.rs#L1100), [`core/dr-types/src/settings.rs:1111`](../core/dr-types/src/settings.rs#L1111), [`core/dr-types/src/settings.rs:1117`](../core/dr-types/src/settings.rs#L1117), [`core/dr-types/src/settings.rs:1`](../core/dr-types/src/settings.rs#L1), [`core/dr-types/src/settings.rs:979`](../core/dr-types/src/settings.rs#L979), [`core/dr-types/src/settings.rs:987`](../core/dr-types/src/settings.rs#L987), [`ui/dr-ui/src/settings_ui.rs:1`](../ui/dr-ui/src/settings_ui.rs#L1), [`ui/dr-ui/src/settings_ui.rs:274`](../ui/dr-ui/src/settings_ui.rs#L274), [`ui/dr-ui/src/settings_ui.rs:287`](../ui/dr-ui/src/settings_ui.rs#L287), [`ui/dr-ui/src/settings_ui.rs:302`](../ui/dr-ui/src/settings_ui.rs#L302), [`ui/dr-ui/src/settings_ui.rs:701`](../ui/dr-ui/src/settings_ui.rs#L701), [`ui/dr-ui/ui/settings.slint:798`](../ui/dr-ui/ui/settings.slint#L798), [`ui/dr-ui/ui/settings.slint:808`](../ui/dr-ui/ui/settings.slint#L808) | | 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:601`](../ui/dr-ui/src/lib.rs#L601), [`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:815`](../ui/dr-ui/src/settings_ui.rs#L815) | | 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:992`](../ui/dr-ui/src/export.rs#L992), [`ui/dr-ui/src/lib.rs:262`](../ui/dr-ui/src/lib.rs#L262), [`ui/dr-ui/src/lib.rs:2752`](../ui/dr-ui/src/lib.rs#L2752), [`ui/dr-ui/src/lib.rs:601`](../ui/dr-ui/src/lib.rs#L601), [`ui/dr-ui/src/lib.rs:647`](../ui/dr-ui/src/lib.rs#L647), [`ui/dr-ui/src/lib.rs:674`](../ui/dr-ui/src/lib.rs#L674), [`ui/dr-ui/src/library_ui.rs:4275`](../ui/dr-ui/src/library_ui.rs#L4275), [`ui/dr-ui/src/library_ui.rs:719`](../ui/dr-ui/src/library_ui.rs#L719), [`ui/dr-ui/src/library_ui.rs:8026`](../ui/dr-ui/src/library_ui.rs#L8026), [`ui/dr-ui/src/library_ui.rs:8103`](../ui/dr-ui/src/library_ui.rs#L8103), [`ui/dr-ui/src/library_ui.rs:8115`](../ui/dr-ui/src/library_ui.rs#L8115), [`ui/dr-ui/src/library_ui.rs:819`](../ui/dr-ui/src/library_ui.rs#L819), [`ui/dr-ui/src/library_ui.rs:876`](../ui/dr-ui/src/library_ui.rs#L876), [`ui/dr-ui/ui/app.slint:1091`](../ui/dr-ui/ui/app.slint#L1091), [`ui/dr-ui/ui/app.slint:1630`](../ui/dr-ui/ui/app.slint#L1630), [`ui/dr-ui/ui/library.slint:1583`](../ui/dr-ui/ui/library.slint#L1583), [`ui/dr-ui/ui/library.slint:4278`](../ui/dr-ui/ui/library.slint#L4278) | | FR-EXP-8 | [`core/dr-decode/src/lib.rs:330`](../core/dr-decode/src/lib.rs#L330), [`core/dr-decode/src/lib.rs:354`](../core/dr-decode/src/lib.rs#L354), [`core/dr-decode/src/lib.rs:368`](../core/dr-decode/src/lib.rs#L368), [`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:655`](../core/dr-types/src/lib.rs#L655), [`core/dr-types/src/settings.rs:647`](../core/dr-types/src/settings.rs#L647), [`ui/dr-ui/src/develop.rs:4539`](../ui/dr-ui/src/develop.rs#L4539), [`ui/dr-ui/src/develop.rs:4651`](../ui/dr-ui/src/develop.rs#L4651), [`ui/dr-ui/src/develop.rs:729`](../ui/dr-ui/src/develop.rs#L729), [`ui/dr-ui/src/export.rs:467`](../ui/dr-ui/src/export.rs#L467), [`ui/dr-ui/src/export.rs:634`](../ui/dr-ui/src/export.rs#L634), [`ui/dr-ui/src/export.rs:680`](../ui/dr-ui/src/export.rs#L680), [`ui/dr-ui/src/export.rs:702`](../ui/dr-ui/src/export.rs#L702), [`ui/dr-ui/src/export.rs:826`](../ui/dr-ui/src/export.rs#L826), [`ui/dr-ui/src/export.rs:844`](../ui/dr-ui/src/export.rs#L844), [`ui/dr-ui/src/lib.rs:262`](../ui/dr-ui/src/lib.rs#L262), [`ui/dr-ui/src/lib.rs:285`](../ui/dr-ui/src/lib.rs#L285), [`ui/dr-ui/src/lib.rs:633`](../ui/dr-ui/src/lib.rs#L633), [`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:510`](../core/dr-decode/src/lib.rs#L510), [`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:4672`](../ui/dr-ui/src/develop.rs#L4672), [`ui/dr-ui/src/develop.rs:4710`](../ui/dr-ui/src/develop.rs#L4710), [`ui/dr-ui/src/develop.rs:6878`](../ui/dr-ui/src/develop.rs#L6878), [`ui/dr-ui/src/lib.rs:601`](../ui/dr-ui/src/lib.rs#L601), [`ui/dr-ui/src/library.rs:4052`](../ui/dr-ui/src/library.rs#L4052), [`ui/dr-ui/src/library.rs:4522`](../ui/dr-ui/src/library.rs#L4522), [`ui/dr-ui/src/library.rs:4558`](../ui/dr-ui/src/library.rs#L4558), [`ui/dr-ui/tests/export_ignores_the_viewport.rs:1`](../ui/dr-ui/tests/export_ignores_the_viewport.rs#L1) | +| FR-EXP-9 | [`core/dr-decode/src/lib.rs:510`](../core/dr-decode/src/lib.rs#L510), [`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:1134`](../core/dr-gpu/src/adjust.rs#L1134), [`ui/dr-ui/examples/face_native.rs:1`](../ui/dr-ui/examples/face_native.rs#L1), [`ui/dr-ui/src/develop.rs:4672`](../ui/dr-ui/src/develop.rs#L4672), [`ui/dr-ui/src/develop.rs:4710`](../ui/dr-ui/src/develop.rs#L4710), [`ui/dr-ui/src/develop.rs:6878`](../ui/dr-ui/src/develop.rs#L6878), [`ui/dr-ui/src/lib.rs:601`](../ui/dr-ui/src/lib.rs#L601), [`ui/dr-ui/src/library.rs:4052`](../ui/dr-ui/src/library.rs#L4052), [`ui/dr-ui/src/library.rs:4522`](../ui/dr-ui/src/library.rs#L4522), [`ui/dr-ui/src/library.rs:4558`](../ui/dr-ui/src/library.rs#L4558), [`ui/dr-ui/tests/export_ignores_the_viewport.rs:1`](../ui/dr-ui/tests/export_ignores_the_viewport.rs#L1) | | FR-MRG-1 | [`core/dr-pano/src/align.rs:1`](../core/dr-pano/src/align.rs#L1), [`core/dr-pano/src/lib.rs:1`](../core/dr-pano/src/lib.rs#L1) | | FR-MRG-10 | [`core/dr-pano/src/lib.rs:1`](../core/dr-pano/src/lib.rs#L1) | +| FR-MRG-2 | [`core/dr-gpu/src/adjust.rs:104`](../core/dr-gpu/src/adjust.rs#L104), [`core/dr-gpu/src/adjust.rs:1157`](../core/dr-gpu/src/adjust.rs#L1157), [`core/dr-gpu/src/adjust.rs:1276`](../core/dr-gpu/src/adjust.rs#L1276), [`core/dr-gpu/src/adjust.rs:316`](../core/dr-gpu/src/adjust.rs#L316), [`core/dr-pipeline/src/graph.rs:852`](../core/dr-pipeline/src/graph.rs#L852), [`core/dr-pipeline/src/operation.rs:427`](../core/dr-pipeline/src/operation.rs#L427), [`core/dr-pipeline/src/operation.rs:595`](../core/dr-pipeline/src/operation.rs#L595) | | FR-MRG-3 | [`core/dr-decode/examples/linear_dng.rs:1`](../core/dr-decode/examples/linear_dng.rs#L1) | | FR-MRG-4 | [`core/dr-pano/src/projection.rs:1`](../core/dr-pano/src/projection.rs#L1) | | FR-MRG-5 | [`core/dr-pano/src/align.rs:1`](../core/dr-pano/src/align.rs#L1) | @@ -125,7 +126,7 @@ _None._ | FR-PLAT-AND-2 | [`core/dr-catalog/src/walk.rs:1022`](../core/dr-catalog/src/walk.rs#L1022), [`core/dr-catalog/src/walk.rs:435`](../core/dr-catalog/src/walk.rs#L435), [`core/dr-sync-folder/src/lib.rs:242`](../core/dr-sync-folder/src/lib.rs#L242), [`core/dr-sync-folder/src/tests.rs:51`](../core/dr-sync-folder/src/tests.rs#L51), [`core/dr-sync/src/error.rs:113`](../core/dr-sync/src/error.rs#L113), [`core/dr-sync/src/error.rs:195`](../core/dr-sync/src/error.rs#L195), [`core/dr-sync/src/scan.rs:211`](../core/dr-sync/src/scan.rs#L211), [`core/dr-sync/src/scan.rs:519`](../core/dr-sync/src/scan.rs#L519), [`core/dr-sync/src/scan.rs:545`](../core/dr-sync/src/scan.rs#L545), [`core/dr-sync/src/scan.rs:574`](../core/dr-sync/src/scan.rs#L574), [`ui/dr-ui/src/library.rs:1291`](../ui/dr-ui/src/library.rs#L1291), [`ui/dr-ui/src/library.rs:1344`](../ui/dr-ui/src/library.rs#L1344), [`ui/dr-ui/src/library.rs:1375`](../ui/dr-ui/src/library.rs#L1375), [`ui/dr-ui/src/library.rs:1955`](../ui/dr-ui/src/library.rs#L1955), [`ui/dr-ui/src/library_ui.rs:1315`](../ui/dr-ui/src/library_ui.rs#L1315), [`ui/dr-ui/src/library_ui.rs:1411`](../ui/dr-ui/src/library_ui.rs#L1411), [`ui/dr-ui/src/library_ui.rs:2010`](../ui/dr-ui/src/library_ui.rs#L2010), [`ui/dr-ui/src/library_ui.rs:328`](../ui/dr-ui/src/library_ui.rs#L328), [`ui/dr-ui/src/library_ui.rs:571`](../ui/dr-ui/src/library_ui.rs#L571) | | FR-PLAT-AND-3 | [`core/dr-catalog/src/jobs.rs:1`](../core/dr-catalog/src/jobs.rs#L1), [`core/dr-catalog/src/runner.rs:1`](../core/dr-catalog/src/runner.rs#L1) | | FR-PLAT-AND-4 | [`core/dr-catalog/src/runner.rs:1`](../core/dr-catalog/src/runner.rs#L1) | -| FR-PLAT-AND-5 | [`apps/darkroom-android/src/lib.rs:166`](../apps/darkroom-android/src/lib.rs#L166), [`core/dr-gpu/src/adjust.rs:1029`](../core/dr-gpu/src/adjust.rs#L1029), [`core/dr-gpu/src/detail.rs:161`](../core/dr-gpu/src/detail.rs#L161), [`core/dr-gpu/src/detail.rs:547`](../core/dr-gpu/src/detail.rs#L547), [`core/dr-gpu/tests/detail_stage.rs:417`](../core/dr-gpu/tests/detail_stage.rs#L417), [`ui/dr-ui/src/develop.rs:4512`](../ui/dr-ui/src/develop.rs#L4512), [`ui/dr-ui/src/identity_ui.rs:125`](../ui/dr-ui/src/identity_ui.rs#L125), [`ui/dr-ui/src/lib.rs:1345`](../ui/dr-ui/src/lib.rs#L1345), [`ui/dr-ui/src/lib.rs:1801`](../ui/dr-ui/src/lib.rs#L1801), [`ui/dr-ui/src/memory.rs:163`](../ui/dr-ui/src/memory.rs#L163), [`ui/dr-ui/src/memory.rs:1`](../ui/dr-ui/src/memory.rs#L1) | +| FR-PLAT-AND-5 | [`apps/darkroom-android/src/lib.rs:166`](../apps/darkroom-android/src/lib.rs#L166), [`core/dr-gpu/src/adjust.rs:1057`](../core/dr-gpu/src/adjust.rs#L1057), [`core/dr-gpu/src/detail.rs:161`](../core/dr-gpu/src/detail.rs#L161), [`core/dr-gpu/src/detail.rs:547`](../core/dr-gpu/src/detail.rs#L547), [`core/dr-gpu/tests/detail_stage.rs:417`](../core/dr-gpu/tests/detail_stage.rs#L417), [`ui/dr-ui/src/develop.rs:4512`](../ui/dr-ui/src/develop.rs#L4512), [`ui/dr-ui/src/identity_ui.rs:125`](../ui/dr-ui/src/identity_ui.rs#L125), [`ui/dr-ui/src/lib.rs:1345`](../ui/dr-ui/src/lib.rs#L1345), [`ui/dr-ui/src/lib.rs:1801`](../ui/dr-ui/src/lib.rs#L1801), [`ui/dr-ui/src/memory.rs:163`](../ui/dr-ui/src/memory.rs#L163), [`ui/dr-ui/src/memory.rs:1`](../ui/dr-ui/src/memory.rs#L1) | | FR-PLAT-AND-6 | [`apps/darkroom-android/src/lib.rs:397`](../apps/darkroom-android/src/lib.rs#L397) | | FR-PLAT-LIN-1 | [`core/dr-types/src/settings.rs:1`](../core/dr-types/src/settings.rs#L1), [`platform/dr-plat/src/dirs.rs:1`](../platform/dr-plat/src/dirs.rs#L1), [`platform/dr-plat/src/storage.rs:344`](../platform/dr-plat/src/storage.rs#L344), [`ui/dr-ui/src/lib.rs:1160`](../ui/dr-ui/src/lib.rs#L1160), [`ui/dr-ui/src/preset_store.rs:1`](../ui/dr-ui/src/preset_store.rs#L1), [`ui/dr-ui/src/settings_store.rs:1`](../ui/dr-ui/src/settings_store.rs#L1) | | FR-PLAT-LIN-2 | [`platform/dr-plat/src/display.rs:1`](../platform/dr-plat/src/display.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) | @@ -170,7 +171,7 @@ _None._ | NFR-R6 | [`core/dr-catalog/src/error.rs:1`](../core/dr-catalog/src/error.rs#L1), [`core/dr-catalog/src/lib.rs:255`](../core/dr-catalog/src/lib.rs#L255), [`core/dr-catalog/src/recovery.rs:1`](../core/dr-catalog/src/recovery.rs#L1) | | NFR-R7 | [`core/dr-gpu/src/error.rs:1`](../core/dr-gpu/src/error.rs#L1) | | NFR-R8 | [`core/dr-gpu/src/error.rs:1`](../core/dr-gpu/src/error.rs#L1) | -| NFR-RES-1 | [`core/dr-gpu/src/adjust.rs:1029`](../core/dr-gpu/src/adjust.rs#L1029), [`core/dr-pipeline/src/history.rs:86`](../core/dr-pipeline/src/history.rs#L86), [`ui/dr-ui/src/develop.rs:4512`](../ui/dr-ui/src/develop.rs#L4512), [`ui/dr-ui/src/identity_ui.rs:125`](../ui/dr-ui/src/identity_ui.rs#L125), [`ui/dr-ui/src/lib.rs:94`](../ui/dr-ui/src/lib.rs#L94), [`ui/dr-ui/src/memory.rs:1`](../ui/dr-ui/src/memory.rs#L1) | +| NFR-RES-1 | [`core/dr-gpu/src/adjust.rs:1057`](../core/dr-gpu/src/adjust.rs#L1057), [`core/dr-pipeline/src/history.rs:86`](../core/dr-pipeline/src/history.rs#L86), [`ui/dr-ui/src/develop.rs:4512`](../ui/dr-ui/src/develop.rs#L4512), [`ui/dr-ui/src/identity_ui.rs:125`](../ui/dr-ui/src/identity_ui.rs#L125), [`ui/dr-ui/src/lib.rs:94`](../ui/dr-ui/src/lib.rs#L94), [`ui/dr-ui/src/memory.rs:1`](../ui/dr-ui/src/memory.rs#L1) | | NFR-RES-2 | [`ui/dr-ui/src/faces.rs:350`](../ui/dr-ui/src/faces.rs#L350), [`ui/dr-ui/src/library.rs:3531`](../ui/dr-ui/src/library.rs#L3531), [`ui/dr-ui/src/library.rs:4052`](../ui/dr-ui/src/library.rs#L4052), [`ui/dr-ui/src/library.rs:4303`](../ui/dr-ui/src/library.rs#L4303), [`ui/dr-ui/src/library.rs:6855`](../ui/dr-ui/src/library.rs#L6855) | | NFR-RES-4 | [`core/dr-catalog/src/cache.rs:1`](../core/dr-catalog/src/cache.rs#L1), [`core/dr-catalog/src/face_shard.rs:1`](../core/dr-catalog/src/face_shard.rs#L1), [`core/dr-catalog/src/schema.rs:922`](../core/dr-catalog/src/schema.rs#L922), [`core/dr-gpu/src/lib.rs:93`](../core/dr-gpu/src/lib.rs#L93), [`core/dr-thumbs/src/codec.rs:1`](../core/dr-thumbs/src/codec.rs#L1), [`core/dr-thumbs/src/lib.rs:1`](../core/dr-thumbs/src/lib.rs#L1), [`core/dr-thumbs/src/lib.rs:376`](../core/dr-thumbs/src/lib.rs#L376), [`ui/dr-ui/src/library.rs:3796`](../ui/dr-ui/src/library.rs#L3796) | | NFR-SEC-1 | [`core/dr-decode/src/error.rs:1`](../core/dr-decode/src/error.rs#L1), [`core/dr-decode/src/error.rs:30`](../core/dr-decode/src/error.rs#L30) | @@ -214,7 +215,7 @@ Defined in `requirements.md` and marked `(post-v1)` on the defining line. Not in ## Not yet tagged -36 of 184 requirements have no implementation tag. Expected while the codebase is young; each should gain one as it is built. +35 of 184 requirements have no implementation tag. Expected while the codebase is young; each should gain one as it is built.
Show untagged requirements @@ -227,7 +228,6 @@ Defined in `requirements.md` and marked `(post-v1)` on the defining line. Not in - FR-DSP-2 - FR-DSP-4 - FR-MRG-11 -- FR-MRG-2 - FR-MRG-6 - FR-MRG-7 - FR-MRG-9 diff --git a/models/LICENCE.md b/models/LICENCE.md index d3a6e29..265ec1b 100644 --- a/models/LICENCE.md +++ b/models/LICENCE.md @@ -76,10 +76,13 @@ rather than a code change — as this document predicted it would be. | File | Source | Trained on | Used by | |---|---|---|---| -| `keypoints/xfeat-1024.onnx` | `weights/xfeat.pt` from `https://github.com/verlab/accelerated_features` | MegaDepth + synthetic warps, by the authors | panorama alignment (FR-MRG-8) | +| `keypoints/xfeat-1024.onnx` | `weights/xfeat.pt` from `https://github.com/verlab/accelerated_features` | MegaDepth + synthetic warps, by the authors | panorama alignment (FR-MRG-8), landscape frames | +| `keypoints/xfeat-768.onnx` | the same weights | — | the same, portrait frames | -Exported by `tools/export-xfeat.sh` at a fixed 768×1024 grayscale input. -Only the convolutional network is in the file; the keypoint decoding is Rust. +Exported by `tools/export-xfeat.sh` at fixed grayscale inputs of 1024×768 +and 768×1024 — the same weights twice, because tract needs a static shape +and a portrait frame in a landscape input wastes half of it. Only the +convolutional network is in each file; the keypoint decoding is Rust. **The repository and its weights are Apache-2.0**, read on 2026-09-19 from the `LICENSE` at its root, with no separate grant on the checkpoint and no diff --git a/models/keypoints/xfeat-768.onnx b/models/keypoints/xfeat-768.onnx new file mode 100644 index 0000000..96b64b6 --- /dev/null +++ b/models/keypoints/xfeat-768.onnx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:956f765f2912420df95632e89815c085067c10f6d39670f40e99d723200de7cf +size 2827922 diff --git a/tools/export-xfeat.sh b/tools/export-xfeat.sh index e91fba2..c242ee2 100755 --- a/tools/export-xfeat.sh +++ b/tools/export-xfeat.sh @@ -6,8 +6,12 @@ # someone once produced and nobody can regenerate. Run it when bumping the # model or changing its input size. # -# ./tools/export-xfeat.sh # 768×1024 -> models/keypoints/xfeat-1024.onnx -# ./tools/export-xfeat.sh 576 768 # another fixed size +# ./tools/export-xfeat.sh # both shapes -> models/keypoints/xfeat-{1024,768}.onnx +# +# Two files from one set of weights: 1024 wide × 768 tall for landscape +# frames and 768 × 1024 for portrait, chosen by the frame's aspect at run +# time. One landscape file would fit a portrait frame at half the width and +# waste half the detector on padding, which is what the 6D fixture did. # # Requires `uv`. Everything else is fetched into a throwaway venv, including # a CPU-only torch — the export needs no GPU and the CUDA wheels are 2 GB. @@ -37,23 +41,25 @@ set -euo pipefail HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" REPO="$(cd "${HERE}/.." && pwd)" -H="${1:-768}" -W="${2:-1024}" OUT="${REPO}/models/keypoints" -NAME="xfeat-${W}" # Not `mktemp -d` under /tmp: a tmpfs, and torch is a gigabyte. WORK="$(mktemp -d -p "${TMPDIR:-/var/tmp}")" trap 'rm -rf "${WORK}"' EXIT -echo "==> exporting XFeat at ${H}×${W} in ${WORK}" +echo "==> exporting XFeat in ${WORK}" cd "${WORK}" git clone -q --depth 1 https://github.com/verlab/accelerated_features.git xfeat uv venv -q --python 3.12 venv VIRTUAL_ENV="${WORK}/venv" uv pip install -q --index-url https://download.pytorch.org/whl/cpu torch VIRTUAL_ENV="${WORK}/venv" uv pip install -q onnx onnxslim -VIRTUAL_ENV="${WORK}/venv" "${WORK}/venv/bin/python" - "${WORK}/xfeat" "${WORK}/${NAME}.onnx" "${H}" "${W}" <<'PY' +mkdir -p "${OUT}" +for shape in "768 1024" "1024 768"; do + set -- $shape + H="$1"; W="$2" + NAME="xfeat-${W}" + VIRTUAL_ENV="${WORK}/venv" "${WORK}/venv/bin/python" - "${WORK}/xfeat" "${WORK}/${NAME}.onnx" "${H}" "${W}" <<'PY' import sys, torch, onnx, onnxslim sys.path.insert(0, sys.argv[1]) from modules.model import XFeatModel @@ -72,7 +78,6 @@ print("ops:", sorted({n.op_type for n in m.graph.node})) for o in m.graph.output: print("out", o.name, [d.dim_value for d in o.type.tensor_type.shape.dim]) PY - -mkdir -p "${OUT}" -cp "${WORK}/${NAME}.onnx" "${OUT}/${NAME}.onnx" -echo "==> ${OUT}/${NAME}.onnx" + cp "${WORK}/${NAME}.onnx" "${OUT}/${NAME}.onnx" + echo "==> ${OUT}/${NAME}.onnx" +done