diff --git a/core/dr-gpu/src/adjust.rs b/core/dr-gpu/src/adjust.rs index 26c30c8..41bf934 100644 --- a/core/dr-gpu/src/adjust.rs +++ b/core/dr-gpu/src/adjust.rs @@ -124,6 +124,9 @@ pub struct AdjustPass { /// Cleared by any render that does not write it, so a stale intermediate /// cannot survive a change of image and be handed to a later detail chain. colour_key: Option<(u64, u32, u32)>, + /// The source texels the fused pass read on an earlier frame, kept so a + /// slider drag at fit reads them contiguously. See [`SampleCache`]. + sample: SampleCache, /// Fused dispatches actually encoded. Exposed so a test can see the reuse /// above happening rather than take it on trust. colour_dispatches: usize, @@ -147,6 +150,205 @@ struct Target { const FILM_FORMAT: wgpu::TextureFormat = wgpu::TextureFormat::Rgba32Float; /// TRACES: FR-DEV-3f +/// What a cached sample is valid for: the composer's +/// [`ComposedShader::sample_key`], the source image, and the render size. +type SampleKey = (u64, u64, u32, u32); + +/// The largest render the sample cache is kept for, in pixels. +/// +/// 4K and a little over, which is every develop view there is. An export +/// renders a whole sensor once and gains nothing from a cache it will not +/// read again; without a ceiling, two exports of the same frame in a row +/// would park a full-resolution copy of it on the device. +const SAMPLE_CACHE_MAX_PIXELS: u64 = 3840 * 2400; + +/// How the fused dispatch gets its source colour this frame. +#[derive(Clone, Copy, PartialEq, Eq, Debug)] +enum SampleUse { + /// From the source, as it always did. + Direct, + /// From the source, and stored in the cache for the frames after. + Write, + /// From the cache. + Read, +} + +/// TRACES: NFR-P5 +/// The fused pass's gather from the source, remembered across frames. +/// +/// At fit, each output pixel of the fused pass reads one texel of a source +/// three or four times its width, on a stride, and the memory system fetches +/// the neighbours it skips along with it. On a 60 MP source that gather was +/// most of the fused pass: 10.9 ms of a 2560 x 1600 frame against 3.8 ms for +/// the same work reading contiguously (RTX 3050, clocks held down). But which +/// texel a pixel reads depends on the framing and nothing else, and a slider +/// drag does not move the framing. So the shader writes what it gathered to a +/// render-sized texture on one frame and reads it back contiguously on every +/// frame after, until the framing, the image or the size changes. +/// +/// Bit-for-bit the same picture: the source is `rgba16float` and so is the +/// cache, so the stored texel is the texel. Only the whole-texel sampling path +/// takes part — [`ComposedShader::sample_key`] is `None` when the sample is +/// interpolated. +/// +/// **Written on the second frame with a key, not the first.** A drag of the +/// crop or of a zoom changes the key on every frame, and a cache written then +/// is never read — it would add a write per frame to exactly the gestures that +/// can least afford one. Waiting for the key to repeat once costs a slider drag +/// one uncached frame and costs a crop drag nothing. +struct SampleCache { + /// The cache itself, `rgba16float`, sampled and written as storage. + target: Option, + /// What `target` holds, once a dispatch has written it. + holds: Option, + /// The key the previous fused dispatch had, cached or not. + last: Option, + /// What the most recent plan decided. Read by the tests, which have no + /// other way to tell a cached frame from an uncached one — the point being + /// that the pictures are identical. + last_use: SampleUse, + /// Bound at `@binding(6)` when the cache is not being read. + no_sampled: wgpu::TextureView, + /// Bound at `@binding(7)` when the cache is not being written. + no_sample_out: wgpu::TextureView, +} + +impl SampleCache { + const FORMAT: wgpu::TextureFormat = DemosaicedImage::FORMAT; + + fn new(ctx: &GpuContext) -> Self { + let placeholder = |label, usage| { + ctx.device + .create_texture(&wgpu::TextureDescriptor { + label: Some(label), + size: wgpu::Extent3d { + width: 1, + height: 1, + depth_or_array_layers: 1, + }, + mip_level_count: 1, + sample_count: 1, + dimension: wgpu::TextureDimension::D2, + format: Self::FORMAT, + usage, + view_formats: &[], + }) + .create_view(&Default::default()) + }; + Self { + target: None, + holds: None, + last: None, + last_use: SampleUse::Direct, + no_sampled: placeholder("adjust-no-sampled", wgpu::TextureUsages::TEXTURE_BINDING), + no_sample_out: placeholder( + "adjust-no-sample-out", + wgpu::TextureUsages::STORAGE_BINDING, + ), + } + } + + /// Decide how this dispatch samples, on the assumption that it will be + /// submitted — call it after anything that can still fail. + fn plan( + &mut self, + ctx: &GpuContext, + source: &DemosaicedImage, + shader: &ComposedShader, + width: u32, + height: u32, + ) -> SampleUse { + self.last_use = self.decide(ctx, source, shader, width, height); + self.last_use + } + + fn decide( + &mut self, + ctx: &GpuContext, + source: &DemosaicedImage, + shader: &ComposedShader, + width: u32, + height: u32, + ) -> SampleUse { + let key = shader + .sample_key + .filter(|_| u64::from(width) * u64::from(height) <= SAMPLE_CACHE_MAX_PIXELS) + .map(|k| (k, source.id(), width, height)); + let last = std::mem::replace(&mut self.last, key); + let Some(key) = key else { + return SampleUse::Direct; + }; + if self.holds == Some(key) { + return SampleUse::Read; + } + if last != Some(key) { + return SampleUse::Direct; + } + + if !self + .target + .as_ref() + .is_some_and(|t| t.width == width && t.height == height) + { + let texture = ctx.device.create_texture(&wgpu::TextureDescriptor { + label: Some("adjust-sample-cache"), + size: wgpu::Extent3d { + width, + height, + depth_or_array_layers: 1, + }, + mip_level_count: 1, + sample_count: 1, + dimension: wgpu::TextureDimension::D2, + format: Self::FORMAT, + usage: wgpu::TextureUsages::STORAGE_BINDING | wgpu::TextureUsages::TEXTURE_BINDING, + view_formats: &[], + }); + let view = texture.create_view(&Default::default()); + self.target = Some(Target { + texture, + view, + width, + height, + }); + } + // Marked as held now: the dispatch that writes it is submitted before + // any that could read it, and one queue orders the two. + self.holds = Some(key); + SampleUse::Write + } + + /// Write the flags for `usage` into a fused uniform block. + fn flag(usage: SampleUse, uniforms: &mut [f32]) { + let o = dr_pipeline::SAMPLE_CACHE_UNIFORM_OFFSET; + uniforms[o] = if usage == SampleUse::Read { 1.0 } else { 0.0 }; + uniforms[o + 1] = if usage == SampleUse::Write { 1.0 } else { 0.0 }; + } + + /// The views for `@binding(6)` and `@binding(7)`. + fn views(&self, usage: SampleUse) -> (wgpu::TextureView, wgpu::TextureView) { + let cache = || { + self.target + .as_ref() + .expect("planned with a target") + .view + .clone() + }; + match usage { + SampleUse::Direct => (self.no_sampled.clone(), self.no_sample_out.clone()), + SampleUse::Write => (self.no_sampled.clone(), cache()), + SampleUse::Read => (cache(), self.no_sample_out.clone()), + } + } + + /// Forget everything; the next render starts over. + fn release(&mut self) { + self.target = None; + self.holds = None; + self.last = None; + } +} + /// A baked film stock, resident on the GPU. struct FilmTextures { curves: wgpu::TextureView, @@ -440,6 +642,7 @@ impl AdjustPass { camera_pipeline_layout, camera_target: None, colour_key: None, + sample: SampleCache::new(ctx), colour_dispatches: 0, detail_dispatches: 0, } @@ -537,6 +740,30 @@ impl AdjustPass { }, count: None, }, + // The sample cache, read and written. Present in every + // layout for the reason the masks are, and bound to + // placeholders whenever the flags leave it alone. See + // `SampleCache`. + wgpu::BindGroupLayoutEntry { + binding: 6, + visibility: wgpu::ShaderStages::COMPUTE, + ty: wgpu::BindingType::Texture { + sample_type: wgpu::TextureSampleType::Float { filterable: false }, + view_dimension: wgpu::TextureViewDimension::D2, + multisampled: false, + }, + count: None, + }, + wgpu::BindGroupLayoutEntry { + binding: 7, + visibility: wgpu::ShaderStages::COMPUTE, + ty: wgpu::BindingType::StorageTexture { + access: wgpu::StorageTextureAccess::WriteOnly, + format: SampleCache::FORMAT, + view_dimension: wgpu::TextureViewDimension::D2, + }, + count: None, + }, ], }) } @@ -716,7 +943,15 @@ impl AdjustPass { let (width, height) = (width.max(1), height.max(1)); self.ensure_target(width, height); - let uniforms = Self::fused_uniforms(source, shader); + // Compile first: `pipeline` takes &mut self, and the sample cache's + // plan below assumes the dispatch it plans for is submitted, so nothing + // after it may fail. + let _ = self.pipeline(shader)?; + + let mut uniforms = Self::fused_uniforms(source, shader); + let sampling = self.sample.plan(&self.ctx, source, shader, width, height); + SampleCache::flag(sampling, &mut uniforms); + let (sampled, sample_out) = self.sample.views(sampling); let params_buf = self .ctx @@ -727,8 +962,6 @@ impl AdjustPass { usage: wgpu::BufferUsages::UNIFORM, }); - // Borrow order: compile first, since `pipeline` takes &mut self. - let _ = self.pipeline(shader)?; let pipeline = self .cache .get(&shader.structure_hash) @@ -768,6 +1001,14 @@ impl AdjustPass { binding: 5, resource: wgpu::BindingResource::TextureView(self.film_lut_view()), }, + wgpu::BindGroupEntry { + binding: 6, + resource: wgpu::BindingResource::TextureView(&sampled), + }, + wgpu::BindGroupEntry { + binding: 7, + resource: wgpu::BindingResource::TextureView(&sample_out), + }, ], }); @@ -885,7 +1126,12 @@ impl AdjustPass { label: Some("adjust-detail-encoder"), }); + let mut sampling = SampleUse::Direct; if !reuse { + let mut uniforms = uniforms; + sampling = self.sample.plan(&self.ctx, source, shader, width, height); + SampleCache::flag(sampling, &mut uniforms); + let (sampled, sample_out) = self.sample.views(sampling); let params_buf = self.ctx .device @@ -927,6 +1173,14 @@ impl AdjustPass { binding: 5, resource: wgpu::BindingResource::TextureView(&film_lut), }, + wgpu::BindGroupEntry { + binding: 6, + resource: wgpu::BindingResource::TextureView(&sampled), + }, + wgpu::BindGroupEntry { + binding: 7, + resource: wgpu::BindingResource::TextureView(&sample_out), + }, ], }); let pipeline = self @@ -954,9 +1208,20 @@ impl AdjustPass { .expect("ensured above") .view .clone(); - let ran = self + let ran = match self .detail - .encode(&mut enc, detail, &target_view, width, height)?; + .encode(&mut enc, detail, &target_view, width, height) + { + Ok(ran) => ran, + Err(e) => { + // Nothing is submitted, so a cache this frame was to write + // holds nothing, and must not be read as though it did. + if sampling == SampleUse::Write { + self.sample.release(); + } + return Err(e); + } + }; self.ctx.queue.submit(Some(enc.finish())); self.detail_dispatches += ran; self.colour_key = Some((key, width, height)); @@ -1090,6 +1355,7 @@ impl AdjustPass { self.detail.release_caches(); self.targets = [None, None]; self.colour_key = None; + self.sample.release(); } /// How many distinct pipelines are compiled. Exposed for tests asserting @@ -1244,6 +1510,16 @@ impl AdjustPass { binding: 5, resource: wgpu::BindingResource::TextureView(self.film_lut_view()), }, + // The sample cache is the display's; a camera-space tap + // reads its source directly (its flags are zero). + wgpu::BindGroupEntry { + binding: 6, + resource: wgpu::BindingResource::TextureView(&self.sample.no_sampled), + }, + wgpu::BindGroupEntry { + binding: 7, + resource: wgpu::BindingResource::TextureView(&self.sample.no_sample_out), + }, ], }); @@ -2624,6 +2900,131 @@ mod tests { /// A flat RGBA8 image on the JPEG path — already gamma-encoded, as a /// decoded JPEG is. + /// A frame with a different value at every pixel, several times the size + /// of the renders below, so that a fit view reads it on a stride and a + /// texel read from the wrong place cannot go unnoticed. + fn busy_image(ctx: &GpuContext) -> DemosaicedImage { + let (w, h) = (97u32, 61u32); + let mut data = Vec::with_capacity((w * h * 4) as usize); + for y in 0..h { + for x in 0..w { + let n = (x.wrapping_mul(2_654_435_761) ^ y.wrapping_mul(1_640_531_527)) >> 7; + data.extend_from_slice(&[n as u8, (n >> 8) as u8, (x * 2 + y) as u8, 255]); + } + } + DemosaicedImage::from_rgba8(ctx, &data, w, h).expect("upload") + } + + /// Render `g` with a pass that has never seen it, which reads the source + /// directly by construction: the reference a cached frame must equal. + fn fresh(ctx: &GpuContext, img: &DemosaicedImage, g: &EditGraph) -> Vec { + let mut pass = AdjustPass::new(ctx); + let detail = g.compose_detail(img.size(), (23, 15)); + pass.render_detailed(img, &g.compose(), 23, 15, None, &detail, 1) + .expect("render"); + assert_eq!(pass.sample.last_use, SampleUse::Direct); + pass.export_pixels().expect("read").0 + } + + #[test] + fn a_cached_sample_is_the_same_picture() { + // TRACES: NFR-P5 + // The sample cache's whole claim: a frame that reads the source through + // it is bit-for-bit the frame that reads the source directly. Walked + // through each state — direct, writing, reading, reading after a + // slider moved, and direct again once the framing moves — against a + // fresh pass each time. + let Some(ctx) = ctx() else { return }; + let img = busy_image(&ctx); + let mut pass = AdjustPass::new(&ctx); + let mut g = EditGraph::default_chain(); + + let frame = |pass: &mut AdjustPass, g: &EditGraph, key: u64| { + let detail = g.compose_detail(img.size(), (23, 15)); + pass.render_detailed(&img, &g.compose(), 23, 15, None, &detail, key) + .expect("render"); + (pass.sample.last_use, pass.export_pixels().expect("read").0) + }; + + for (i, (expected, value)) in [ + (SampleUse::Direct, 0.3), + (SampleUse::Write, 0.4), + (SampleUse::Read, 0.5), + (SampleUse::Read, -0.7), + ] + .into_iter() + .enumerate() + { + g.set_param(exposure::ID, exposure::EXPOSURE, value); + let (used, pixels) = frame(&mut pass, &g, i as u64); + assert_eq!(used, expected, "frame {i}"); + assert_eq!(pixels, fresh(&ctx, &img, &g), "frame {i} ({used:?})"); + } + + // A neighbourhood operation: the fused pass writes the linear + // intermediate instead, through the same sampling. + g.set_param( + dr_pipeline::ops::noise_reduction::ID, + dr_pipeline::ops::noise_reduction::CHROMA, + 60.0, + ); + for i in 10..13 { + g.set_param(exposure::ID, exposure::EXPOSURE, i as f32 * 0.01); + let (used, pixels) = frame(&mut pass, &g, i); + assert_eq!(used, SampleUse::Read, "detail frame {i}"); + assert_eq!(pixels, fresh(&ctx, &img, &g), "detail frame {i}"); + } + + // The framing moves: what was cached is for the old framing. + g.set_param(dr_pipeline::framing::ID, dr_pipeline::framing::CROP_W, 0.6); + let (used, pixels) = frame(&mut pass, &g, 20); + assert_eq!(used, SampleUse::Direct, "a new framing reads directly"); + assert_eq!(pixels, fresh(&ctx, &img, &g)); + let (used, _) = frame(&mut pass, &g, 21); + assert_eq!(used, SampleUse::Write, "and caches once it holds still"); + let (used, pixels) = frame(&mut pass, &g, 22); + assert_eq!(used, SampleUse::Read); + assert_eq!(pixels, fresh(&ctx, &img, &g)); + } + + #[test] + fn a_cache_is_not_read_for_another_image_or_size() { + // The key is the composer's half plus the two things only this side + // knows. A second photograph with the same edit and the same framing + // must not be shown the first one's texels. + let Some(ctx) = ctx() else { return }; + let (a, b) = (busy_image(&ctx), grey_image(&ctx, 8000)); + let mut pass = AdjustPass::new(&ctx); + let shader = EditGraph::default_chain().compose(); + for _ in 0..3 { + pass.render(&a, &shader, 23, 15).expect("render"); + } + assert_eq!(pass.sample.last_use, SampleUse::Read); + + pass.render(&b, &shader, 23, 15).expect("render"); + assert_eq!(pass.sample.last_use, SampleUse::Direct, "another image"); + pass.render(&b, &shader, 23, 15).expect("render"); + pass.render(&b, &shader, 24, 15).expect("render"); + assert_eq!(pass.sample.last_use, SampleUse::Direct, "another size"); + } + + #[test] + fn a_straightened_frame_samples_directly() { + // Interpolated: the sample is a blend of four texels, which the cache's + // format could not hold exactly, so the composer offers no key. + let Some(ctx) = ctx() else { return }; + let img = busy_image(&ctx); + let mut pass = AdjustPass::new(&ctx); + let mut g = EditGraph::default_chain(); + g.set_param(dr_pipeline::framing::ID, dr_pipeline::framing::ANGLE, 3.0); + let shader = g.compose(); + assert!(shader.sample_key.is_none()); + for _ in 0..3 { + pass.render(&img, &shader, 23, 15).expect("render"); + assert_eq!(pass.sample.last_use, SampleUse::Direct); + } + } + fn jpeg_image(ctx: &GpuContext, rgb: [u8; 3]) -> DemosaicedImage { let size = 16u32; let mut data = Vec::with_capacity((size * size) as usize * 4); diff --git a/core/dr-gpu/src/demosaic.rs b/core/dr-gpu/src/demosaic.rs index f4cc2a6..9e15f1a 100644 --- a/core/dr-gpu/src/demosaic.rs +++ b/core/dr-gpu/src/demosaic.rs @@ -95,6 +95,15 @@ pub struct DemosaicedImage { base_curve: BaseCurve, /// Whether the texture holds gamma-encoded rather than linear values. non_linear: bool, + /// Which upload this is, unique for the life of the process. See + /// [`Self::id`]. + id: u64, +} + +/// The next [`DemosaicedImage::id`]. +fn next_image_id() -> u64 { + static NEXT: std::sync::atomic::AtomicU64 = std::sync::atomic::AtomicU64::new(1); + NEXT.fetch_add(1, std::sync::atomic::Ordering::Relaxed) } impl DemosaicedImage { @@ -112,6 +121,18 @@ impl DemosaicedImage { (self.width, self.height) } + /// Which texture this is, as a number that is never reused. + /// + /// For a cache that has to know it is still looking at the same pixels + /// (`AdjustPass`'s sample cache) without holding the texture alive to find + /// out: keeping a handle would keep half a gigabyte of a closed photograph + /// on the device, and comparing addresses would mistake a new upload for an + /// old one the moment the allocator reused the slot. A texture here is + /// never written after it is built, so the same id is the same pixels. + pub(crate) fn id(&self) -> u64 { + self.id + } + /// Camera RGB → linear sRGB, row-major. Identity where the body is /// uncalibrated, so the image renders uncalibrated rather than black. pub fn color_matrix(&self) -> [f32; 9] { @@ -246,6 +267,7 @@ impl DemosaicedImage { // the highlights of an image that was already finished. base_curve: BaseCurve::IDENTITY, non_linear: true, + id: next_image_id(), }) } } @@ -322,6 +344,7 @@ impl DemosaicedImage { as_shot_wb: [raw.wb_coeffs[0], raw.wb_coeffs[1], raw.wb_coeffs[2]], base_curve: raw.base_curve, non_linear: false, + id: next_image_id(), }) } } @@ -660,6 +683,7 @@ impl Demosaicer { // normalises against black and white levels and applies no // transfer function. non_linear: false, + id: next_image_id(), }) } } diff --git a/core/dr-pipeline/src/lib.rs b/core/dr-pipeline/src/lib.rs index 0d78e25..b408e02 100644 --- a/core/dr-pipeline/src/lib.rs +++ b/core/dr-pipeline/src/lib.rs @@ -67,7 +67,7 @@ pub use lens::{compose_warps, ComposedWarp, LensProfile, Tca, Warp}; pub use operation::{ compose, compose_with_framing, Affects, ComposedShader, Helper, Invalidation, Operation, OutputMode, Uniform, BASE_CURVE_POINTS, BASE_CURVE_UNIFORM_OFFSET, CLIP_ONSET, - RESERVED_UNIFORM_FIELDS, + RESERVED_UNIFORM_FIELDS, SAMPLE_CACHE_UNIFORM_OFFSET, }; pub use preset::{LibraryParseError, NameError, Preset, PresetLibrary, Scope}; pub use sidecar::{Sidecar, Version}; diff --git a/core/dr-pipeline/src/operation.rs b/core/dr-pipeline/src/operation.rs index 0a9c978..6b3db36 100644 --- a/core/dr-pipeline/src/operation.rs +++ b/core/dr-pipeline/src/operation.rs @@ -456,6 +456,25 @@ pub struct ComposedShader { pub structure_hash: u64, /// What this shader writes. See [`OutputMode`]. pub output_mode: OutputMode, + /// What decides which source texel each output pixel reads, when that + /// texel is read whole — `None` when it is interpolated. + /// + /// A fit view reads one texel in every three or four of a 60 MP source, + /// on a stride, and that gather is most of what the fused pass costs + /// there: the texel it wants shares a cache line with neighbours nobody + /// reads. But the gather depends on the framing and nothing else, so it + /// is the same on every frame of a slider drag. The shader can therefore + /// write what it gathered to a viewport-sized texture once and read it + /// back contiguously thereafter; the flags in the uniform block at + /// [`SAMPLE_CACHE_UNIFORM_OFFSET`] say which, and `dr-gpu` decides. + /// + /// This key is the half of that decision only the composer can make: a + /// hash of the generated prologue and the framing and warp uniforms, which + /// together are everything that maps an output pixel to a source texel. + /// The caller mixes in the source image and the render size. `None` for + /// the interpolating paths, whose sample is a blend of four texels and + /// not representable exactly in the source's own format. + pub sample_key: Option, } /// Fields the generated uniform struct always carries, before op uniforms. @@ -466,7 +485,19 @@ pub struct ComposedShader { /// Twelve of the twenty-eight are the camera profile's base curve /// ([`BASE_CURVE_UNIFORM_FIELDS`]); the rest are the matrix, the as-shot /// balance and framing's own block. -const BASE_UNIFORM_FIELDS: usize = 16 + BASE_CURVE_UNIFORM_FIELDS; +const BASE_UNIFORM_FIELDS: usize = 16 + SAMPLE_CACHE_UNIFORM_FIELDS + BASE_CURVE_UNIFORM_FIELDS; + +/// Slots the sample cache's two flags occupy: read, write, and two spare to +/// keep the block a whole `vec4`. See [`ComposedShader::sample_key`]. +const SAMPLE_CACHE_UNIFORM_FIELDS: usize = 4; + +/// Where the sample cache's flags sit in the generated uniform block: `x` says +/// read the source colour from the cache, `y` says write it there. +/// +/// Exported for the reason [`BASE_CURVE_UNIFORM_OFFSET`] is — `dr-gpu` writes +/// these by index — and zero in every block the composer hands out, so a +/// caller that never heard of the cache gets the direct read it always had. +pub const SAMPLE_CACHE_UNIFORM_OFFSET: usize = 16; /// TRACES: FR-DEV-3e /// Slots the base curve occupies: five `(x, y)` points and an active flag. @@ -484,7 +515,8 @@ const BASE_CURVE_UNIFORM_FIELDS: usize = 12; /// Exported for the same reason [`RESERVED_UNIFORM_FIELDS`] is: `dr-gpu` /// writes these by index, and an offset computed independently at both ends is /// an offset that will eventually disagree with itself. -pub const BASE_CURVE_UNIFORM_OFFSET: usize = 16; +pub const BASE_CURVE_UNIFORM_OFFSET: usize = + SAMPLE_CACHE_UNIFORM_OFFSET + SAMPLE_CACHE_UNIFORM_FIELDS; /// How many control points a base curve carries. /// @@ -756,6 +788,10 @@ fn compose_inner( \x20 // gamma-encoded JPEG, 0.0 for demosaiced sensor data), which the\n\ \x20 // prologue reads to decide whether to linearise.\n\ \x20 as_shot_wb: vec4,\n\ + \x20 // The sample cache (see `ComposedShader::sample_key`): `.x` reads\n\ + \x20 // the source colour from `sampled`, `.y` writes it to\n\ + \x20 // `sample_out`. Zero for both is the direct read.\n\ + \x20 sample_cache: vec4,\n\ \x20 // The camera profile's base curve (FR-DEV-3e): five points on a\n\ \x20 // monotone spline, packed as x0..x3, y0..y3, then (x4, y4, on).\n\ \x20 // `.z` of the last is the flag, not padding — it is 0 for a\n\ @@ -936,6 +972,19 @@ fn compose_inner( ); let sampler_helper = if interpolate { BILINEAR_HELPER } else { "" }; + // Everything that decides which texel an output pixel reads: the code that + // computes `coord`, and the uniforms that code reads. Only on the path that + // reads a texel whole — see `ComposedShader::sample_key`. + let sample_key = (!interpolate && !warp.splits_channels).then(|| { + framing + .uniforms() + .iter() + .chain(&warp.uniforms) + .fold(hash_source(&prologue), |h, v| { + mix(h, u64::from(v.to_bits())) + }) + }); + // The tail, and it is the whole of the difference between the two output // modes. Everything above — the prologue, the fragments, the mask layers, // the camera matrix — is emitted identically either way, so an operation @@ -1087,6 +1136,12 @@ struct Params {{ // stock is loaded, which costs eight bytes and no branch. @group(0) @binding(4) var film_curves: texture_2d; @group(0) @binding(5) var film_lut_texture: texture_3d; +// The sample cache: the source texel each output pixel read on an earlier +// frame with this framing, and where this frame writes it when asked. See +// `ComposedShader::sample_key`. Declared unconditionally, like the masks, and +// bound to 1x1 placeholders whenever the flags say not to touch them. +@group(0) @binding(6) var sampled: texture_2d; +@group(0) @binding(7) var sample_out: texture_storage_2d; {sampler_helper}{helper_src}{encode_output} // Display-encoded sRGB back to linear, for sources that arrive that way. @@ -1196,6 +1251,7 @@ fn main(@builtin(global_invocation_id) gid: vec3) {{ uniforms: uniform_values, structure_hash, output_mode, + sample_key, } } @@ -1415,7 +1471,19 @@ pub(crate) fn sample_source(interpolate: bool, splits_channels: bool) -> &'stati // amount that changes with the aspect ratio. It reads as a correction that // is simply too weak, which is indistinguishable from a bad profile. let radius = length(p) / (0.5 * length(aspect)); - var c = textureLoad(source, coord, 0).rgb; + // The texel itself, from the source or from the cache of it an earlier + // frame wrote (see `ComposedShader::sample_key`). Both branches yield the + // same bits: the source is `rgba16float` and so is the cache. The flags + // are uniforms, so the whole dispatch takes one branch. + var c: vec3; + if (u.sample_cache.x > 0.5) { + c = textureLoad(sampled, vec2(gid.xy), 0).rgb; + } else { + c = textureLoad(source, coord, 0).rgb; + if (u.sample_cache.y > 0.5) { + textureStore(sample_out, vec2(gid.xy), vec4(c, 1.0)); + } + } " } } diff --git a/docs/dev/traceability.md b/docs/dev/traceability.md index 5a7f322..76a1b9f 100644 --- a/docs/dev/traceability.md +++ b/docs/dev/traceability.md @@ -10,7 +10,7 @@ Denominators are parsed from [`requirements.md`](requirements.md) at run time, n | Metric | Value | |---|---| | Source files scanned | 448 | -| TRACES tags found | 1800 | +| TRACES tags found | 1802 | | Requirements defined | 190 | | Requirements deferred (post-v1) | 24 | | Requirements covered | 159 | @@ -70,45 +70,45 @@ _None._ | FR-DEV-19 | [`core/dr-pipeline/src/mask.rs:1341`](../../core/dr-pipeline/src/mask.rs#L1341) | | FR-DEV-19a | [`core/dr-gpu/src/mask.rs:655`](../../core/dr-gpu/src/mask.rs#L655), [`core/dr-gpu/src/mask.rs:773`](../../core/dr-gpu/src/mask.rs#L773), [`core/dr-gpu/tests/local_adjustments.rs:793`](../../core/dr-gpu/tests/local_adjustments.rs#L793), [`core/dr-gpu/tests/local_adjustments.rs:841`](../../core/dr-gpu/tests/local_adjustments.rs#L841), [`core/dr-pipeline/src/mask.rs:1022`](../../core/dr-pipeline/src/mask.rs#L1022), [`core/dr-pipeline/src/mask.rs:1633`](../../core/dr-pipeline/src/mask.rs#L1633), [`core/dr-pipeline/src/mask.rs:2964`](../../core/dr-pipeline/src/mask.rs#L2964), [`core/dr-pipeline/src/mask.rs:3085`](../../core/dr-pipeline/src/mask.rs#L3085), [`core/dr-pipeline/src/mask.rs:3120`](../../core/dr-pipeline/src/mask.rs#L3120), [`core/dr-pipeline/src/mask.rs:929`](../../core/dr-pipeline/src/mask.rs#L929), [`core/dr-pipeline/src/mask.rs:964`](../../core/dr-pipeline/src/mask.rs#L964), [`core/dr-pipeline/src/sidecar.rs:1259`](../../core/dr-pipeline/src/sidecar.rs#L1259), [`core/dr-pipeline/tests/mask_sidecar.rs:1347`](../../core/dr-pipeline/tests/mask_sidecar.rs#L1347), [`core/dr-pipeline/tests/mask_sidecar.rs:1369`](../../core/dr-pipeline/tests/mask_sidecar.rs#L1369), [`core/dr-pipeline/tests/mask_sidecar.rs:1395`](../../core/dr-pipeline/tests/mask_sidecar.rs#L1395), [`ui/dr-ui/src/develop/masks.rs:432`](../../ui/dr-ui/src/develop/masks.rs#L432), [`ui/dr-ui/src/develop/masks.rs:493`](../../ui/dr-ui/src/develop/masks.rs#L493), [`ui/dr-ui/src/develop/masks.rs:512`](../../ui/dr-ui/src/develop/masks.rs#L512), [`ui/dr-ui/src/develop/masks.rs:547`](../../ui/dr-ui/src/develop/masks.rs#L547), [`ui/dr-ui/src/develop/session.rs:192`](../../ui/dr-ui/src/develop/session.rs#L192), [`ui/dr-ui/src/labels.rs:73`](../../ui/dr-ui/src/labels.rs#L73), [`ui/dr-ui/src/masks_ui.rs:1083`](../../ui/dr-ui/src/masks_ui.rs#L1083), [`ui/dr-ui/src/masks_ui.rs:1140`](../../ui/dr-ui/src/masks_ui.rs#L1140), [`ui/dr-ui/src/masks_ui.rs:1196`](../../ui/dr-ui/src/masks_ui.rs#L1196), [`ui/dr-ui/src/masks_ui.rs:1555`](../../ui/dr-ui/src/masks_ui.rs#L1555), [`ui/dr-ui/src/masks_ui.rs:1578`](../../ui/dr-ui/src/masks_ui.rs#L1578), [`ui/dr-ui/src/masks_ui.rs:270`](../../ui/dr-ui/src/masks_ui.rs#L270), [`ui/dr-ui/ui/app.slint:2560`](../../ui/dr-ui/ui/app.slint#L2560), [`ui/dr-ui/ui/masks.slint:151`](../../ui/dr-ui/ui/masks.slint#L151), [`ui/dr-ui/ui/masks.slint:176`](../../ui/dr-ui/ui/masks.slint#L176), [`ui/dr-ui/ui/masks.slint:339`](../../ui/dr-ui/ui/masks.slint#L339), [`ui/dr-ui/ui/masks.slint:379`](../../ui/dr-ui/ui/masks.slint#L379), [`ui/dr-ui/ui/masks.slint:422`](../../ui/dr-ui/ui/masks.slint#L422), [`ui/dr-ui/ui/masks.slint:468`](../../ui/dr-ui/ui/masks.slint#L468), [`ui/dr-ui/ui/masks.slint:796`](../../ui/dr-ui/ui/masks.slint#L796), [`ui/dr-ui/ui/masks.slint:881`](../../ui/dr-ui/ui/masks.slint#L881) | | FR-DEV-19b | [`ui/dr-ui/src/develop/mask_ops.rs:606`](../../ui/dr-ui/src/develop/mask_ops.rs#L606), [`ui/dr-ui/src/develop/masks.rs:595`](../../ui/dr-ui/src/develop/masks.rs#L595), [`ui/dr-ui/src/develop/session.rs:201`](../../ui/dr-ui/src/develop/session.rs#L201), [`ui/dr-ui/src/develop/session.rs:208`](../../ui/dr-ui/src/develop/session.rs#L208), [`ui/dr-ui/src/labels.rs:67`](../../ui/dr-ui/src/labels.rs#L67), [`ui/dr-ui/src/masks_ui.rs:1229`](../../ui/dr-ui/src/masks_ui.rs#L1229), [`ui/dr-ui/src/masks_ui.rs:1448`](../../ui/dr-ui/src/masks_ui.rs#L1448), [`ui/dr-ui/src/masks_ui.rs:1476`](../../ui/dr-ui/src/masks_ui.rs#L1476), [`ui/dr-ui/src/masks_ui.rs:1849`](../../ui/dr-ui/src/masks_ui.rs#L1849), [`ui/dr-ui/src/masks_ui.rs:908`](../../ui/dr-ui/src/masks_ui.rs#L908), [`ui/dr-ui/ui/app.slint:2095`](../../ui/dr-ui/ui/app.slint#L2095), [`ui/dr-ui/ui/app.slint:816`](../../ui/dr-ui/ui/app.slint#L816), [`ui/dr-ui/ui/masks.slint:1156`](../../ui/dr-ui/ui/masks.slint#L1156), [`ui/dr-ui/ui/masks.slint:479`](../../ui/dr-ui/ui/masks.slint#L479), [`ui/dr-ui/ui/masks.slint:800`](../../ui/dr-ui/ui/masks.slint#L800), [`ui/dr-ui/ui/masks.slint:874`](../../ui/dr-ui/ui/masks.slint#L874), [`ui/dr-ui/ui/masks.slint:894`](../../ui/dr-ui/ui/masks.slint#L894) | -| FR-DEV-19c | [`core/dr-gpu/src/mask.rs:727`](../../core/dr-gpu/src/mask.rs#L727), [`core/dr-gpu/tests/local_adjustments.rs:1000`](../../core/dr-gpu/tests/local_adjustments.rs#L1000), [`core/dr-gpu/tests/local_adjustments.rs:1035`](../../core/dr-gpu/tests/local_adjustments.rs#L1035), [`core/dr-gpu/tests/local_adjustments.rs:1080`](../../core/dr-gpu/tests/local_adjustments.rs#L1080), [`core/dr-gpu/tests/local_adjustments.rs:943`](../../core/dr-gpu/tests/local_adjustments.rs#L943), [`core/dr-pipeline/src/graph.rs:893`](../../core/dr-pipeline/src/graph.rs#L893), [`core/dr-pipeline/src/mask.rs:1841`](../../core/dr-pipeline/src/mask.rs#L1841), [`core/dr-pipeline/src/mask.rs:1867`](../../core/dr-pipeline/src/mask.rs#L1867), [`core/dr-pipeline/src/mask.rs:1882`](../../core/dr-pipeline/src/mask.rs#L1882), [`core/dr-pipeline/src/mask.rs:2002`](../../core/dr-pipeline/src/mask.rs#L2002), [`core/dr-pipeline/src/mask.rs:2050`](../../core/dr-pipeline/src/mask.rs#L2050), [`core/dr-pipeline/src/mask.rs:2194`](../../core/dr-pipeline/src/mask.rs#L2194), [`core/dr-pipeline/src/mask.rs:2431`](../../core/dr-pipeline/src/mask.rs#L2431), [`core/dr-pipeline/src/operation.rs:1752`](../../core/dr-pipeline/src/operation.rs#L1752), [`core/dr-pipeline/src/operation.rs:588`](../../core/dr-pipeline/src/operation.rs#L588), [`core/dr-pipeline/src/operation.rs:867`](../../core/dr-pipeline/src/operation.rs#L867), [`ui/dr-ui/src/develop/mask_ops.rs:1199`](../../ui/dr-ui/src/develop/mask_ops.rs#L1199), [`ui/dr-ui/src/develop/mask_ops.rs:1235`](../../ui/dr-ui/src/develop/mask_ops.rs#L1235), [`ui/dr-ui/src/develop/mask_ops.rs:318`](../../ui/dr-ui/src/develop/mask_ops.rs#L318), [`ui/dr-ui/src/develop/mask_ops.rs:58`](../../ui/dr-ui/src/develop/mask_ops.rs#L58), [`ui/dr-ui/src/develop/masks.rs:12`](../../ui/dr-ui/src/develop/masks.rs#L12), [`ui/dr-ui/src/develop/masks.rs:176`](../../ui/dr-ui/src/develop/masks.rs#L176), [`ui/dr-ui/src/develop/masks.rs:21`](../../ui/dr-ui/src/develop/masks.rs#L21), [`ui/dr-ui/src/develop/masks.rs:43`](../../ui/dr-ui/src/develop/masks.rs#L43), [`ui/dr-ui/src/develop/render.rs:260`](../../ui/dr-ui/src/develop/render.rs#L260), [`ui/dr-ui/src/develop/session.rs:227`](../../ui/dr-ui/src/develop/session.rs#L227), [`ui/dr-ui/src/develop/session.rs:236`](../../ui/dr-ui/src/develop/session.rs#L236), [`ui/dr-ui/src/masks_ui.rs:1024`](../../ui/dr-ui/src/masks_ui.rs#L1024), [`ui/dr-ui/src/masks_ui.rs:1448`](../../ui/dr-ui/src/masks_ui.rs#L1448), [`ui/dr-ui/src/masks_ui.rs:152`](../../ui/dr-ui/src/masks_ui.rs#L152), [`ui/dr-ui/src/masks_ui.rs:1849`](../../ui/dr-ui/src/masks_ui.rs#L1849), [`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:677`](../../ui/dr-ui/src/masks_ui.rs#L677), [`ui/dr-ui/src/masks_ui.rs:996`](../../ui/dr-ui/src/masks_ui.rs#L996), [`ui/dr-ui/ui/icons.slint:340`](../../ui/dr-ui/ui/icons.slint#L340), [`ui/dr-ui/ui/masks.slint:1121`](../../ui/dr-ui/ui/masks.slint#L1121), [`ui/dr-ui/ui/masks.slint:184`](../../ui/dr-ui/ui/masks.slint#L184), [`ui/dr-ui/ui/masks.slint:294`](../../ui/dr-ui/ui/masks.slint#L294), [`ui/dr-ui/ui/masks.slint:543`](../../ui/dr-ui/ui/masks.slint#L543), [`ui/dr-ui/ui/masks.slint:70`](../../ui/dr-ui/ui/masks.slint#L70), [`ui/dr-ui/ui/masks.slint:808`](../../ui/dr-ui/ui/masks.slint#L808), [`ui/dr-ui/ui/masks.slint:876`](../../ui/dr-ui/ui/masks.slint#L876), [`ui/dr-ui/ui/masks.slint:968`](../../ui/dr-ui/ui/masks.slint#L968) | +| FR-DEV-19c | [`core/dr-gpu/src/mask.rs:727`](../../core/dr-gpu/src/mask.rs#L727), [`core/dr-gpu/tests/local_adjustments.rs:1000`](../../core/dr-gpu/tests/local_adjustments.rs#L1000), [`core/dr-gpu/tests/local_adjustments.rs:1035`](../../core/dr-gpu/tests/local_adjustments.rs#L1035), [`core/dr-gpu/tests/local_adjustments.rs:1080`](../../core/dr-gpu/tests/local_adjustments.rs#L1080), [`core/dr-gpu/tests/local_adjustments.rs:943`](../../core/dr-gpu/tests/local_adjustments.rs#L943), [`core/dr-pipeline/src/graph.rs:893`](../../core/dr-pipeline/src/graph.rs#L893), [`core/dr-pipeline/src/mask.rs:1841`](../../core/dr-pipeline/src/mask.rs#L1841), [`core/dr-pipeline/src/mask.rs:1867`](../../core/dr-pipeline/src/mask.rs#L1867), [`core/dr-pipeline/src/mask.rs:1882`](../../core/dr-pipeline/src/mask.rs#L1882), [`core/dr-pipeline/src/mask.rs:2002`](../../core/dr-pipeline/src/mask.rs#L2002), [`core/dr-pipeline/src/mask.rs:2050`](../../core/dr-pipeline/src/mask.rs#L2050), [`core/dr-pipeline/src/mask.rs:2194`](../../core/dr-pipeline/src/mask.rs#L2194), [`core/dr-pipeline/src/mask.rs:2431`](../../core/dr-pipeline/src/mask.rs#L2431), [`core/dr-pipeline/src/operation.rs:1820`](../../core/dr-pipeline/src/operation.rs#L1820), [`core/dr-pipeline/src/operation.rs:620`](../../core/dr-pipeline/src/operation.rs#L620), [`core/dr-pipeline/src/operation.rs:903`](../../core/dr-pipeline/src/operation.rs#L903), [`ui/dr-ui/src/develop/mask_ops.rs:1199`](../../ui/dr-ui/src/develop/mask_ops.rs#L1199), [`ui/dr-ui/src/develop/mask_ops.rs:1235`](../../ui/dr-ui/src/develop/mask_ops.rs#L1235), [`ui/dr-ui/src/develop/mask_ops.rs:318`](../../ui/dr-ui/src/develop/mask_ops.rs#L318), [`ui/dr-ui/src/develop/mask_ops.rs:58`](../../ui/dr-ui/src/develop/mask_ops.rs#L58), [`ui/dr-ui/src/develop/masks.rs:12`](../../ui/dr-ui/src/develop/masks.rs#L12), [`ui/dr-ui/src/develop/masks.rs:176`](../../ui/dr-ui/src/develop/masks.rs#L176), [`ui/dr-ui/src/develop/masks.rs:21`](../../ui/dr-ui/src/develop/masks.rs#L21), [`ui/dr-ui/src/develop/masks.rs:43`](../../ui/dr-ui/src/develop/masks.rs#L43), [`ui/dr-ui/src/develop/render.rs:260`](../../ui/dr-ui/src/develop/render.rs#L260), [`ui/dr-ui/src/develop/session.rs:227`](../../ui/dr-ui/src/develop/session.rs#L227), [`ui/dr-ui/src/develop/session.rs:236`](../../ui/dr-ui/src/develop/session.rs#L236), [`ui/dr-ui/src/masks_ui.rs:1024`](../../ui/dr-ui/src/masks_ui.rs#L1024), [`ui/dr-ui/src/masks_ui.rs:1448`](../../ui/dr-ui/src/masks_ui.rs#L1448), [`ui/dr-ui/src/masks_ui.rs:152`](../../ui/dr-ui/src/masks_ui.rs#L152), [`ui/dr-ui/src/masks_ui.rs:1849`](../../ui/dr-ui/src/masks_ui.rs#L1849), [`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:677`](../../ui/dr-ui/src/masks_ui.rs#L677), [`ui/dr-ui/src/masks_ui.rs:996`](../../ui/dr-ui/src/masks_ui.rs#L996), [`ui/dr-ui/ui/icons.slint:340`](../../ui/dr-ui/ui/icons.slint#L340), [`ui/dr-ui/ui/masks.slint:1121`](../../ui/dr-ui/ui/masks.slint#L1121), [`ui/dr-ui/ui/masks.slint:184`](../../ui/dr-ui/ui/masks.slint#L184), [`ui/dr-ui/ui/masks.slint:294`](../../ui/dr-ui/ui/masks.slint#L294), [`ui/dr-ui/ui/masks.slint:543`](../../ui/dr-ui/ui/masks.slint#L543), [`ui/dr-ui/ui/masks.slint:70`](../../ui/dr-ui/ui/masks.slint#L70), [`ui/dr-ui/ui/masks.slint:808`](../../ui/dr-ui/ui/masks.slint#L808), [`ui/dr-ui/ui/masks.slint:876`](../../ui/dr-ui/ui/masks.slint#L876), [`ui/dr-ui/ui/masks.slint:968`](../../ui/dr-ui/ui/masks.slint#L968) | | FR-DEV-2 | [`core/dr-pipeline/src/operation.rs:403`](../../core/dr-pipeline/src/operation.rs#L403) | -| FR-DEV-20 | [`core/dr-gpu/src/adjust.rs:1901`](../../core/dr-gpu/src/adjust.rs#L1901), [`core/dr-pipeline/src/framing.rs:1362`](../../core/dr-pipeline/src/framing.rs#L1362), [`core/dr-pipeline/src/framing.rs:170`](../../core/dr-pipeline/src/framing.rs#L170), [`core/dr-pipeline/src/framing.rs:388`](../../core/dr-pipeline/src/framing.rs#L388), [`core/dr-pipeline/src/framing.rs:482`](../../core/dr-pipeline/src/framing.rs#L482), [`core/dr-pipeline/src/framing.rs:639`](../../core/dr-pipeline/src/framing.rs#L639), [`core/dr-pipeline/src/framing.rs:650`](../../core/dr-pipeline/src/framing.rs#L650), [`core/dr-pipeline/src/framing.rs:88`](../../core/dr-pipeline/src/framing.rs#L88), [`core/dr-pipeline/src/framing.rs:925`](../../core/dr-pipeline/src/framing.rs#L925), [`core/dr-pipeline/src/framing.rs:92`](../../core/dr-pipeline/src/framing.rs#L92), [`core/dr-pipeline/src/framing.rs:981`](../../core/dr-pipeline/src/framing.rs#L981), [`core/dr-pipeline/src/preset.rs:824`](../../core/dr-pipeline/src/preset.rs#L824), [`core/dr-pipeline/src/sidecar.rs:2195`](../../core/dr-pipeline/src/sidecar.rs#L2195), [`ui/dr-ui/src/develop/framing.rs:1035`](../../ui/dr-ui/src/develop/framing.rs#L1035), [`ui/dr-ui/src/develop/framing.rs:418`](../../ui/dr-ui/src/develop/framing.rs#L418), [`ui/dr-ui/src/develop/framing.rs:474`](../../ui/dr-ui/src/develop/framing.rs#L474), [`ui/dr-ui/src/develop/framing.rs:480`](../../ui/dr-ui/src/develop/framing.rs#L480), [`ui/dr-ui/src/develop/framing.rs:489`](../../ui/dr-ui/src/develop/framing.rs#L489), [`ui/dr-ui/src/develop_ui.rs:1240`](../../ui/dr-ui/src/develop_ui.rs#L1240), [`ui/dr-ui/src/develop_ui.rs:1273`](../../ui/dr-ui/src/develop_ui.rs#L1273), [`ui/dr-ui/src/labels.rs:277`](../../ui/dr-ui/src/labels.rs#L277), [`ui/dr-ui/ui/adjust.slint:645`](../../ui/dr-ui/ui/adjust.slint#L645), [`ui/dr-ui/ui/adjust.slint:687`](../../ui/dr-ui/ui/adjust.slint#L687), [`ui/dr-ui/ui/adjust.slint:830`](../../ui/dr-ui/ui/adjust.slint#L830), [`ui/dr-ui/ui/app.slint:2584`](../../ui/dr-ui/ui/app.slint#L2584), [`ui/dr-ui/ui/app.slint:682`](../../ui/dr-ui/ui/app.slint#L682), [`ui/dr-ui/ui/app.slint:705`](../../ui/dr-ui/ui/app.slint#L705) | -| FR-DEV-3 | [`core/dr-gpu/src/adjust.rs:2499`](../../core/dr-gpu/src/adjust.rs#L2499), [`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:1098`](../../core/dr-pipeline/src/framing.rs#L1098), [`core/dr-pipeline/src/framing.rs:251`](../../core/dr-pipeline/src/framing.rs#L251), [`core/dr-pipeline/src/framing.rs:308`](../../core/dr-pipeline/src/framing.rs#L308), [`core/dr-pipeline/src/framing.rs:468`](../../core/dr-pipeline/src/framing.rs#L468), [`core/dr-pipeline/src/framing.rs:704`](../../core/dr-pipeline/src/framing.rs#L704), [`core/dr-pipeline/src/graph.rs:1348`](../../core/dr-pipeline/src/graph.rs#L1348), [`core/dr-pipeline/src/graph.rs:1379`](../../core/dr-pipeline/src/graph.rs#L1379), [`core/dr-pipeline/src/graph.rs:1402`](../../core/dr-pipeline/src/graph.rs#L1402), [`core/dr-pipeline/src/graph.rs:1440`](../../core/dr-pipeline/src/graph.rs#L1440), [`core/dr-pipeline/src/graph.rs:1471`](../../core/dr-pipeline/src/graph.rs#L1471), [`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:860`](../../core/dr-pipeline/src/graph.rs#L860), [`core/dr-pipeline/src/graph.rs:952`](../../core/dr-pipeline/src/graph.rs#L952), [`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:306`](../../core/dr-pipeline/src/neutral.rs#L306), [`core/dr-pipeline/src/neutral.rs:322`](../../core/dr-pipeline/src/neutral.rs#L322), [`core/dr-pipeline/src/neutral.rs:338`](../../core/dr-pipeline/src/neutral.rs#L338), [`core/dr-pipeline/src/neutral.rs:360`](../../core/dr-pipeline/src/neutral.rs#L360), [`core/dr-pipeline/src/neutral.rs:81`](../../core/dr-pipeline/src/neutral.rs#L81), [`core/dr-pipeline/src/operation.rs:330`](../../core/dr-pipeline/src/operation.rs#L330), [`core/dr-pipeline/src/operation.rs:565`](../../core/dr-pipeline/src/operation.rs#L565), [`core/dr-pipeline/src/operation.rs:637`](../../core/dr-pipeline/src/operation.rs#L637), [`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:752`](../../core/dr-pipeline/src/preset.rs#L752), [`core/dr-pipeline/src/sidecar.rs:1433`](../../core/dr-pipeline/src/sidecar.rs#L1433), [`core/dr-pipeline/src/sidecar.rs:206`](../../core/dr-pipeline/src/sidecar.rs#L206), [`core/dr-pipeline/src/sidecar.rs:2273`](../../core/dr-pipeline/src/sidecar.rs#L2273), [`core/dr-pipeline/src/sidecar.rs:2353`](../../core/dr-pipeline/src/sidecar.rs#L2353), [`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/curves.rs:163`](../../ui/dr-ui/src/develop/curves.rs#L163), [`ui/dr-ui/src/develop/framing.rs:10`](../../ui/dr-ui/src/develop/framing.rs#L10), [`ui/dr-ui/src/develop/framing.rs:298`](../../ui/dr-ui/src/develop/framing.rs#L298), [`ui/dr-ui/src/develop/framing.rs:328`](../../ui/dr-ui/src/develop/framing.rs#L328), [`ui/dr-ui/src/develop/framing.rs:394`](../../ui/dr-ui/src/develop/framing.rs#L394), [`ui/dr-ui/src/develop/framing.rs:408`](../../ui/dr-ui/src/develop/framing.rs#L408), [`ui/dr-ui/src/develop/framing.rs:644`](../../ui/dr-ui/src/develop/framing.rs#L644), [`ui/dr-ui/src/develop/framing.rs:71`](../../ui/dr-ui/src/develop/framing.rs#L71), [`ui/dr-ui/src/develop/mask_ops.rs:1076`](../../ui/dr-ui/src/develop/mask_ops.rs#L1076), [`ui/dr-ui/src/develop/mask_ops.rs:1340`](../../ui/dr-ui/src/develop/mask_ops.rs#L1340), [`ui/dr-ui/src/develop/mask_ops.rs:178`](../../ui/dr-ui/src/develop/mask_ops.rs#L178), [`ui/dr-ui/src/develop/mask_ops.rs:969`](../../ui/dr-ui/src/develop/mask_ops.rs#L969), [`ui/dr-ui/src/develop/masks.rs:263`](../../ui/dr-ui/src/develop/masks.rs#L263), [`ui/dr-ui/src/develop/masks.rs:361`](../../ui/dr-ui/src/develop/masks.rs#L361), [`ui/dr-ui/src/develop/masks.rs:743`](../../ui/dr-ui/src/develop/masks.rs#L743), [`ui/dr-ui/src/develop/masks.rs:773`](../../ui/dr-ui/src/develop/masks.rs#L773), [`ui/dr-ui/src/develop/render.rs:1198`](../../ui/dr-ui/src/develop/render.rs#L1198), [`ui/dr-ui/src/develop/rows.rs:106`](../../ui/dr-ui/src/develop/rows.rs#L106), [`ui/dr-ui/src/develop/rows.rs:195`](../../ui/dr-ui/src/develop/rows.rs#L195), [`ui/dr-ui/src/develop/rows.rs:231`](../../ui/dr-ui/src/develop/rows.rs#L231), [`ui/dr-ui/src/develop/rows.rs:679`](../../ui/dr-ui/src/develop/rows.rs#L679), [`ui/dr-ui/src/develop/segmentation.rs:139`](../../ui/dr-ui/src/develop/segmentation.rs#L139), [`ui/dr-ui/src/develop/segmentation.rs:302`](../../ui/dr-ui/src/develop/segmentation.rs#L302), [`ui/dr-ui/src/develop/segmentation.rs:339`](../../ui/dr-ui/src/develop/segmentation.rs#L339), [`ui/dr-ui/src/develop/segmentation.rs:572`](../../ui/dr-ui/src/develop/segmentation.rs#L572), [`ui/dr-ui/src/develop/segmentation.rs:590`](../../ui/dr-ui/src/develop/segmentation.rs#L590), [`ui/dr-ui/src/develop/segmentation.rs:604`](../../ui/dr-ui/src/develop/segmentation.rs#L604), [`ui/dr-ui/src/develop/segmentation.rs:626`](../../ui/dr-ui/src/develop/segmentation.rs#L626), [`ui/dr-ui/src/develop/segmentation.rs:77`](../../ui/dr-ui/src/develop/segmentation.rs#L77), [`ui/dr-ui/src/develop/segmentation.rs:806`](../../ui/dr-ui/src/develop/segmentation.rs#L806), [`ui/dr-ui/src/develop/session.rs:162`](../../ui/dr-ui/src/develop/session.rs#L162), [`ui/dr-ui/src/develop/session.rs:255`](../../ui/dr-ui/src/develop/session.rs#L255), [`ui/dr-ui/src/develop/session.rs:284`](../../ui/dr-ui/src/develop/session.rs#L284), [`ui/dr-ui/src/develop/session.rs:434`](../../ui/dr-ui/src/develop/session.rs#L434), [`ui/dr-ui/src/develop/session.rs:494`](../../ui/dr-ui/src/develop/session.rs#L494), [`ui/dr-ui/src/develop/session.rs:566`](../../ui/dr-ui/src/develop/session.rs#L566), [`ui/dr-ui/src/develop/session.rs:716`](../../ui/dr-ui/src/develop/session.rs#L716), [`ui/dr-ui/src/develop/white_balance.rs:11`](../../ui/dr-ui/src/develop/white_balance.rs#L11), [`ui/dr-ui/src/develop/white_balance.rs:162`](../../ui/dr-ui/src/develop/white_balance.rs#L162), [`ui/dr-ui/src/develop/white_balance.rs:193`](../../ui/dr-ui/src/develop/white_balance.rs#L193), [`ui/dr-ui/src/develop/white_balance.rs:276`](../../ui/dr-ui/src/develop/white_balance.rs#L276), [`ui/dr-ui/src/develop/white_balance.rs:338`](../../ui/dr-ui/src/develop/white_balance.rs#L338), [`ui/dr-ui/src/develop_ui.rs:1053`](../../ui/dr-ui/src/develop_ui.rs#L1053), [`ui/dr-ui/src/develop_ui.rs:1150`](../../ui/dr-ui/src/develop_ui.rs#L1150), [`ui/dr-ui/src/develop_ui.rs:117`](../../ui/dr-ui/src/develop_ui.rs#L117), [`ui/dr-ui/src/develop_ui.rs:1204`](../../ui/dr-ui/src/develop_ui.rs#L1204), [`ui/dr-ui/src/develop_ui.rs:454`](../../ui/dr-ui/src/develop_ui.rs#L454), [`ui/dr-ui/src/develop_ui.rs:674`](../../ui/dr-ui/src/develop_ui.rs#L674), [`ui/dr-ui/src/labels.rs:35`](../../ui/dr-ui/src/labels.rs#L35), [`ui/dr-ui/src/lib.rs:2199`](../../ui/dr-ui/src/lib.rs#L2199), [`ui/dr-ui/src/lib.rs:442`](../../ui/dr-ui/src/lib.rs#L442), [`ui/dr-ui/src/lib.rs:472`](../../ui/dr-ui/src/lib.rs#L472), [`ui/dr-ui/src/lib.rs:580`](../../ui/dr-ui/src/lib.rs#L580), [`ui/dr-ui/src/lib.rs:604`](../../ui/dr-ui/src/lib.rs#L604), [`ui/dr-ui/src/library/sidecar.rs:63`](../../ui/dr-ui/src/library/sidecar.rs#L63), [`ui/dr-ui/src/masks_ui.rs:1608`](../../ui/dr-ui/src/masks_ui.rs#L1608), [`ui/dr-ui/src/masks_ui.rs:1722`](../../ui/dr-ui/src/masks_ui.rs#L1722), [`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:1049`](../../ui/dr-ui/ui/adjust.slint#L1049), [`ui/dr-ui/ui/adjust.slint:126`](../../ui/dr-ui/ui/adjust.slint#L126), [`ui/dr-ui/ui/adjust.slint:1532`](../../ui/dr-ui/ui/adjust.slint#L1532), [`ui/dr-ui/ui/adjust.slint:172`](../../ui/dr-ui/ui/adjust.slint#L172), [`ui/dr-ui/ui/adjust.slint:46`](../../ui/dr-ui/ui/adjust.slint#L46), [`ui/dr-ui/ui/adjust.slint:625`](../../ui/dr-ui/ui/adjust.slint#L625), [`ui/dr-ui/ui/adjust.slint:661`](../../ui/dr-ui/ui/adjust.slint#L661), [`ui/dr-ui/ui/adjust.slint:680`](../../ui/dr-ui/ui/adjust.slint#L680), [`ui/dr-ui/ui/adjust.slint:873`](../../ui/dr-ui/ui/adjust.slint#L873), [`ui/dr-ui/ui/adjust.slint:972`](../../ui/dr-ui/ui/adjust.slint#L972), [`ui/dr-ui/ui/app.slint:207`](../../ui/dr-ui/ui/app.slint#L207), [`ui/dr-ui/ui/app.slint:2160`](../../ui/dr-ui/ui/app.slint#L2160), [`ui/dr-ui/ui/app.slint:2222`](../../ui/dr-ui/ui/app.slint#L2222), [`ui/dr-ui/ui/develop.slint:379`](../../ui/dr-ui/ui/develop.slint#L379), [`ui/dr-ui/ui/masks.slint:1246`](../../ui/dr-ui/ui/masks.slint#L1246), [`ui/dr-ui/ui/masks.slint:779`](../../ui/dr-ui/ui/masks.slint#L779), [`ui/dr-ui/ui/masks.slint:838`](../../ui/dr-ui/ui/masks.slint#L838) | +| FR-DEV-20 | [`core/dr-gpu/src/adjust.rs:2177`](../../core/dr-gpu/src/adjust.rs#L2177), [`core/dr-pipeline/src/framing.rs:1362`](../../core/dr-pipeline/src/framing.rs#L1362), [`core/dr-pipeline/src/framing.rs:170`](../../core/dr-pipeline/src/framing.rs#L170), [`core/dr-pipeline/src/framing.rs:388`](../../core/dr-pipeline/src/framing.rs#L388), [`core/dr-pipeline/src/framing.rs:482`](../../core/dr-pipeline/src/framing.rs#L482), [`core/dr-pipeline/src/framing.rs:639`](../../core/dr-pipeline/src/framing.rs#L639), [`core/dr-pipeline/src/framing.rs:650`](../../core/dr-pipeline/src/framing.rs#L650), [`core/dr-pipeline/src/framing.rs:88`](../../core/dr-pipeline/src/framing.rs#L88), [`core/dr-pipeline/src/framing.rs:925`](../../core/dr-pipeline/src/framing.rs#L925), [`core/dr-pipeline/src/framing.rs:92`](../../core/dr-pipeline/src/framing.rs#L92), [`core/dr-pipeline/src/framing.rs:981`](../../core/dr-pipeline/src/framing.rs#L981), [`core/dr-pipeline/src/preset.rs:824`](../../core/dr-pipeline/src/preset.rs#L824), [`core/dr-pipeline/src/sidecar.rs:2195`](../../core/dr-pipeline/src/sidecar.rs#L2195), [`ui/dr-ui/src/develop/framing.rs:1035`](../../ui/dr-ui/src/develop/framing.rs#L1035), [`ui/dr-ui/src/develop/framing.rs:418`](../../ui/dr-ui/src/develop/framing.rs#L418), [`ui/dr-ui/src/develop/framing.rs:474`](../../ui/dr-ui/src/develop/framing.rs#L474), [`ui/dr-ui/src/develop/framing.rs:480`](../../ui/dr-ui/src/develop/framing.rs#L480), [`ui/dr-ui/src/develop/framing.rs:489`](../../ui/dr-ui/src/develop/framing.rs#L489), [`ui/dr-ui/src/develop_ui.rs:1240`](../../ui/dr-ui/src/develop_ui.rs#L1240), [`ui/dr-ui/src/develop_ui.rs:1273`](../../ui/dr-ui/src/develop_ui.rs#L1273), [`ui/dr-ui/src/labels.rs:277`](../../ui/dr-ui/src/labels.rs#L277), [`ui/dr-ui/ui/adjust.slint:645`](../../ui/dr-ui/ui/adjust.slint#L645), [`ui/dr-ui/ui/adjust.slint:687`](../../ui/dr-ui/ui/adjust.slint#L687), [`ui/dr-ui/ui/adjust.slint:830`](../../ui/dr-ui/ui/adjust.slint#L830), [`ui/dr-ui/ui/app.slint:2584`](../../ui/dr-ui/ui/app.slint#L2584), [`ui/dr-ui/ui/app.slint:682`](../../ui/dr-ui/ui/app.slint#L682), [`ui/dr-ui/ui/app.slint:705`](../../ui/dr-ui/ui/app.slint#L705) | +| FR-DEV-3 | [`core/dr-gpu/src/adjust.rs:1039`](../../core/dr-gpu/src/adjust.rs#L1039), [`core/dr-gpu/src/adjust.rs:2775`](../../core/dr-gpu/src/adjust.rs#L2775), [`core/dr-gpu/src/adjust.rs:84`](../../core/dr-gpu/src/adjust.rs#L84), [`core/dr-gpu/src/adjust.rs:906`](../../core/dr-gpu/src/adjust.rs#L906), [`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:1098`](../../core/dr-pipeline/src/framing.rs#L1098), [`core/dr-pipeline/src/framing.rs:251`](../../core/dr-pipeline/src/framing.rs#L251), [`core/dr-pipeline/src/framing.rs:308`](../../core/dr-pipeline/src/framing.rs#L308), [`core/dr-pipeline/src/framing.rs:468`](../../core/dr-pipeline/src/framing.rs#L468), [`core/dr-pipeline/src/framing.rs:704`](../../core/dr-pipeline/src/framing.rs#L704), [`core/dr-pipeline/src/graph.rs:1348`](../../core/dr-pipeline/src/graph.rs#L1348), [`core/dr-pipeline/src/graph.rs:1379`](../../core/dr-pipeline/src/graph.rs#L1379), [`core/dr-pipeline/src/graph.rs:1402`](../../core/dr-pipeline/src/graph.rs#L1402), [`core/dr-pipeline/src/graph.rs:1440`](../../core/dr-pipeline/src/graph.rs#L1440), [`core/dr-pipeline/src/graph.rs:1471`](../../core/dr-pipeline/src/graph.rs#L1471), [`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:860`](../../core/dr-pipeline/src/graph.rs#L860), [`core/dr-pipeline/src/graph.rs:952`](../../core/dr-pipeline/src/graph.rs#L952), [`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:306`](../../core/dr-pipeline/src/neutral.rs#L306), [`core/dr-pipeline/src/neutral.rs:322`](../../core/dr-pipeline/src/neutral.rs#L322), [`core/dr-pipeline/src/neutral.rs:338`](../../core/dr-pipeline/src/neutral.rs#L338), [`core/dr-pipeline/src/neutral.rs:360`](../../core/dr-pipeline/src/neutral.rs#L360), [`core/dr-pipeline/src/neutral.rs:81`](../../core/dr-pipeline/src/neutral.rs#L81), [`core/dr-pipeline/src/operation.rs:330`](../../core/dr-pipeline/src/operation.rs#L330), [`core/dr-pipeline/src/operation.rs:597`](../../core/dr-pipeline/src/operation.rs#L597), [`core/dr-pipeline/src/operation.rs:669`](../../core/dr-pipeline/src/operation.rs#L669), [`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:752`](../../core/dr-pipeline/src/preset.rs#L752), [`core/dr-pipeline/src/sidecar.rs:1433`](../../core/dr-pipeline/src/sidecar.rs#L1433), [`core/dr-pipeline/src/sidecar.rs:206`](../../core/dr-pipeline/src/sidecar.rs#L206), [`core/dr-pipeline/src/sidecar.rs:2273`](../../core/dr-pipeline/src/sidecar.rs#L2273), [`core/dr-pipeline/src/sidecar.rs:2353`](../../core/dr-pipeline/src/sidecar.rs#L2353), [`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/curves.rs:163`](../../ui/dr-ui/src/develop/curves.rs#L163), [`ui/dr-ui/src/develop/framing.rs:10`](../../ui/dr-ui/src/develop/framing.rs#L10), [`ui/dr-ui/src/develop/framing.rs:298`](../../ui/dr-ui/src/develop/framing.rs#L298), [`ui/dr-ui/src/develop/framing.rs:328`](../../ui/dr-ui/src/develop/framing.rs#L328), [`ui/dr-ui/src/develop/framing.rs:394`](../../ui/dr-ui/src/develop/framing.rs#L394), [`ui/dr-ui/src/develop/framing.rs:408`](../../ui/dr-ui/src/develop/framing.rs#L408), [`ui/dr-ui/src/develop/framing.rs:644`](../../ui/dr-ui/src/develop/framing.rs#L644), [`ui/dr-ui/src/develop/framing.rs:71`](../../ui/dr-ui/src/develop/framing.rs#L71), [`ui/dr-ui/src/develop/mask_ops.rs:1076`](../../ui/dr-ui/src/develop/mask_ops.rs#L1076), [`ui/dr-ui/src/develop/mask_ops.rs:1340`](../../ui/dr-ui/src/develop/mask_ops.rs#L1340), [`ui/dr-ui/src/develop/mask_ops.rs:178`](../../ui/dr-ui/src/develop/mask_ops.rs#L178), [`ui/dr-ui/src/develop/mask_ops.rs:969`](../../ui/dr-ui/src/develop/mask_ops.rs#L969), [`ui/dr-ui/src/develop/masks.rs:263`](../../ui/dr-ui/src/develop/masks.rs#L263), [`ui/dr-ui/src/develop/masks.rs:361`](../../ui/dr-ui/src/develop/masks.rs#L361), [`ui/dr-ui/src/develop/masks.rs:743`](../../ui/dr-ui/src/develop/masks.rs#L743), [`ui/dr-ui/src/develop/masks.rs:773`](../../ui/dr-ui/src/develop/masks.rs#L773), [`ui/dr-ui/src/develop/render.rs:1198`](../../ui/dr-ui/src/develop/render.rs#L1198), [`ui/dr-ui/src/develop/rows.rs:106`](../../ui/dr-ui/src/develop/rows.rs#L106), [`ui/dr-ui/src/develop/rows.rs:195`](../../ui/dr-ui/src/develop/rows.rs#L195), [`ui/dr-ui/src/develop/rows.rs:231`](../../ui/dr-ui/src/develop/rows.rs#L231), [`ui/dr-ui/src/develop/rows.rs:679`](../../ui/dr-ui/src/develop/rows.rs#L679), [`ui/dr-ui/src/develop/segmentation.rs:139`](../../ui/dr-ui/src/develop/segmentation.rs#L139), [`ui/dr-ui/src/develop/segmentation.rs:302`](../../ui/dr-ui/src/develop/segmentation.rs#L302), [`ui/dr-ui/src/develop/segmentation.rs:339`](../../ui/dr-ui/src/develop/segmentation.rs#L339), [`ui/dr-ui/src/develop/segmentation.rs:572`](../../ui/dr-ui/src/develop/segmentation.rs#L572), [`ui/dr-ui/src/develop/segmentation.rs:590`](../../ui/dr-ui/src/develop/segmentation.rs#L590), [`ui/dr-ui/src/develop/segmentation.rs:604`](../../ui/dr-ui/src/develop/segmentation.rs#L604), [`ui/dr-ui/src/develop/segmentation.rs:626`](../../ui/dr-ui/src/develop/segmentation.rs#L626), [`ui/dr-ui/src/develop/segmentation.rs:77`](../../ui/dr-ui/src/develop/segmentation.rs#L77), [`ui/dr-ui/src/develop/segmentation.rs:806`](../../ui/dr-ui/src/develop/segmentation.rs#L806), [`ui/dr-ui/src/develop/session.rs:162`](../../ui/dr-ui/src/develop/session.rs#L162), [`ui/dr-ui/src/develop/session.rs:255`](../../ui/dr-ui/src/develop/session.rs#L255), [`ui/dr-ui/src/develop/session.rs:284`](../../ui/dr-ui/src/develop/session.rs#L284), [`ui/dr-ui/src/develop/session.rs:434`](../../ui/dr-ui/src/develop/session.rs#L434), [`ui/dr-ui/src/develop/session.rs:494`](../../ui/dr-ui/src/develop/session.rs#L494), [`ui/dr-ui/src/develop/session.rs:566`](../../ui/dr-ui/src/develop/session.rs#L566), [`ui/dr-ui/src/develop/session.rs:716`](../../ui/dr-ui/src/develop/session.rs#L716), [`ui/dr-ui/src/develop/white_balance.rs:11`](../../ui/dr-ui/src/develop/white_balance.rs#L11), [`ui/dr-ui/src/develop/white_balance.rs:162`](../../ui/dr-ui/src/develop/white_balance.rs#L162), [`ui/dr-ui/src/develop/white_balance.rs:193`](../../ui/dr-ui/src/develop/white_balance.rs#L193), [`ui/dr-ui/src/develop/white_balance.rs:276`](../../ui/dr-ui/src/develop/white_balance.rs#L276), [`ui/dr-ui/src/develop/white_balance.rs:338`](../../ui/dr-ui/src/develop/white_balance.rs#L338), [`ui/dr-ui/src/develop_ui.rs:1053`](../../ui/dr-ui/src/develop_ui.rs#L1053), [`ui/dr-ui/src/develop_ui.rs:1150`](../../ui/dr-ui/src/develop_ui.rs#L1150), [`ui/dr-ui/src/develop_ui.rs:117`](../../ui/dr-ui/src/develop_ui.rs#L117), [`ui/dr-ui/src/develop_ui.rs:1204`](../../ui/dr-ui/src/develop_ui.rs#L1204), [`ui/dr-ui/src/develop_ui.rs:454`](../../ui/dr-ui/src/develop_ui.rs#L454), [`ui/dr-ui/src/develop_ui.rs:674`](../../ui/dr-ui/src/develop_ui.rs#L674), [`ui/dr-ui/src/labels.rs:35`](../../ui/dr-ui/src/labels.rs#L35), [`ui/dr-ui/src/lib.rs:2199`](../../ui/dr-ui/src/lib.rs#L2199), [`ui/dr-ui/src/lib.rs:442`](../../ui/dr-ui/src/lib.rs#L442), [`ui/dr-ui/src/lib.rs:472`](../../ui/dr-ui/src/lib.rs#L472), [`ui/dr-ui/src/lib.rs:580`](../../ui/dr-ui/src/lib.rs#L580), [`ui/dr-ui/src/lib.rs:604`](../../ui/dr-ui/src/lib.rs#L604), [`ui/dr-ui/src/library/sidecar.rs:63`](../../ui/dr-ui/src/library/sidecar.rs#L63), [`ui/dr-ui/src/masks_ui.rs:1608`](../../ui/dr-ui/src/masks_ui.rs#L1608), [`ui/dr-ui/src/masks_ui.rs:1722`](../../ui/dr-ui/src/masks_ui.rs#L1722), [`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:1049`](../../ui/dr-ui/ui/adjust.slint#L1049), [`ui/dr-ui/ui/adjust.slint:126`](../../ui/dr-ui/ui/adjust.slint#L126), [`ui/dr-ui/ui/adjust.slint:1532`](../../ui/dr-ui/ui/adjust.slint#L1532), [`ui/dr-ui/ui/adjust.slint:172`](../../ui/dr-ui/ui/adjust.slint#L172), [`ui/dr-ui/ui/adjust.slint:46`](../../ui/dr-ui/ui/adjust.slint#L46), [`ui/dr-ui/ui/adjust.slint:625`](../../ui/dr-ui/ui/adjust.slint#L625), [`ui/dr-ui/ui/adjust.slint:661`](../../ui/dr-ui/ui/adjust.slint#L661), [`ui/dr-ui/ui/adjust.slint:680`](../../ui/dr-ui/ui/adjust.slint#L680), [`ui/dr-ui/ui/adjust.slint:873`](../../ui/dr-ui/ui/adjust.slint#L873), [`ui/dr-ui/ui/adjust.slint:972`](../../ui/dr-ui/ui/adjust.slint#L972), [`ui/dr-ui/ui/app.slint:207`](../../ui/dr-ui/ui/app.slint#L207), [`ui/dr-ui/ui/app.slint:2160`](../../ui/dr-ui/ui/app.slint#L2160), [`ui/dr-ui/ui/app.slint:2222`](../../ui/dr-ui/ui/app.slint#L2222), [`ui/dr-ui/ui/develop.slint:379`](../../ui/dr-ui/ui/develop.slint#L379), [`ui/dr-ui/ui/masks.slint:1246`](../../ui/dr-ui/ui/masks.slint#L1246), [`ui/dr-ui/ui/masks.slint:779`](../../ui/dr-ui/ui/masks.slint#L779), [`ui/dr-ui/ui/masks.slint:838`](../../ui/dr-ui/ui/masks.slint#L838) | | 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:555`](../../core/dr-pipeline/src/framing.rs#L555), [`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:1744`](../../core/dr-pipeline/src/mask.rs#L1744), [`core/dr-pipeline/src/neutral.rs:1`](../../core/dr-pipeline/src/neutral.rs#L1), [`core/dr-pipeline/src/neutral.rs:378`](../../core/dr-pipeline/src/neutral.rs#L378), [`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/curves.rs:36`](../../ui/dr-ui/src/develop/curves.rs#L36), [`ui/dr-ui/src/develop/rows.rs:118`](../../ui/dr-ui/src/develop/rows.rs#L118), [`ui/dr-ui/src/develop/rows.rs:679`](../../ui/dr-ui/src/develop/rows.rs#L679), [`ui/dr-ui/src/develop/rows.rs:877`](../../ui/dr-ui/src/develop/rows.rs#L877), [`ui/dr-ui/src/lib.rs:911`](../../ui/dr-ui/src/lib.rs#L911), [`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:2614`](../../ui/dr-ui/ui/app.slint#L2614) | | FR-DEV-3b | [`core/dr-pipeline/src/descriptor.rs:276`](../../core/dr-pipeline/src/descriptor.rs#L276), [`core/dr-pipeline/src/framing.rs:555`](../../core/dr-pipeline/src/framing.rs#L555), [`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:2898`](../../ui/dr-ui/ui/app.slint#L2898) | | 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:1744`](../../core/dr-pipeline/src/mask.rs#L1744), [`core/dr-pipeline/src/preset.rs:752`](../../core/dr-pipeline/src/preset.rs#L752), [`ui/dr-ui/src/develop/rows.rs:928`](../../ui/dr-ui/src/develop/rows.rs#L928) | -| 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:468`](../../core/dr-pipeline/src/framing.rs#L468), [`core/dr-pipeline/src/graph.rs:991`](../../core/dr-pipeline/src/graph.rs#L991), [`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:127`](../../core/dr-decode/src/lib.rs#L127), [`core/dr-decode/src/lib.rs:777`](../../core/dr-decode/src/lib.rs#L777), [`core/dr-decode/src/lib.rs:817`](../../core/dr-decode/src/lib.rs#L817), [`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:473`](../../core/dr-decode/src/profile.rs#L473), [`core/dr-decode/src/profile.rs:507`](../../core/dr-decode/src/profile.rs#L507), [`core/dr-decode/src/profile.rs:678`](../../core/dr-decode/src/profile.rs#L678), [`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:1989`](../../core/dr-pipeline/src/operation.rs#L1989), [`core/dr-pipeline/src/operation.rs:2070`](../../core/dr-pipeline/src/operation.rs#L2070), [`core/dr-pipeline/src/operation.rs:2095`](../../core/dr-pipeline/src/operation.rs#L2095), [`core/dr-pipeline/src/operation.rs:2110`](../../core/dr-pipeline/src/operation.rs#L2110), [`core/dr-pipeline/src/operation.rs:2134`](../../core/dr-pipeline/src/operation.rs#L2134), [`core/dr-pipeline/src/operation.rs:310`](../../core/dr-pipeline/src/operation.rs#L310), [`core/dr-pipeline/src/operation.rs:471`](../../core/dr-pipeline/src/operation.rs#L471), [`core/dr-pipeline/src/operation.rs:481`](../../core/dr-pipeline/src/operation.rs#L481), [`core/dr-pipeline/src/operation.rs:769`](../../core/dr-pipeline/src/operation.rs#L769) | -| 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:195`](../../core/dr-gpu/tests/film_sim.rs#L195), [`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:1317`](../../core/dr-pipeline/src/operation.rs#L1317), [`core/dr-pipeline/src/operation.rs:1345`](../../core/dr-pipeline/src/operation.rs#L1345), [`core/dr-pipeline/src/operation.rs:1391`](../../core/dr-pipeline/src/operation.rs#L1391), [`core/dr-pipeline/src/operation.rs:1989`](../../core/dr-pipeline/src/operation.rs#L1989), [`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:1077`](../../core/dr-pipeline/src/sidecar.rs#L1077), [`core/dr-pipeline/src/sidecar.rs:133`](../../core/dr-pipeline/src/sidecar.rs#L133), [`core/dr-pipeline/src/sidecar.rs:217`](../../core/dr-pipeline/src/sidecar.rs#L217), [`core/dr-pipeline/src/sidecar.rs:2722`](../../core/dr-pipeline/src/sidecar.rs#L2722), [`core/dr-pipeline/src/sidecar.rs:2798`](../../core/dr-pipeline/src/sidecar.rs#L2798), [`core/dr-pipeline/src/sidecar.rs:595`](../../core/dr-pipeline/src/sidecar.rs#L595), [`core/dr-pipeline/src/sidecar.rs:898`](../../core/dr-pipeline/src/sidecar.rs#L898), [`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/render.rs:1210`](../../ui/dr-ui/src/develop/render.rs#L1210), [`ui/dr-ui/src/develop/render.rs:682`](../../ui/dr-ui/src/develop/render.rs#L682), [`ui/dr-ui/src/develop/render.rs:699`](../../ui/dr-ui/src/develop/render.rs#L699), [`ui/dr-ui/src/develop/render.rs:711`](../../ui/dr-ui/src/develop/render.rs#L711), [`ui/dr-ui/src/develop/render.rs:749`](../../ui/dr-ui/src/develop/render.rs#L749), [`ui/dr-ui/src/develop/render.rs:758`](../../ui/dr-ui/src/develop/render.rs#L758), [`ui/dr-ui/src/develop/render.rs:861`](../../ui/dr-ui/src/develop/render.rs#L861), [`ui/dr-ui/src/develop/render.rs:887`](../../ui/dr-ui/src/develop/render.rs#L887), [`ui/dr-ui/src/develop/session.rs:603`](../../ui/dr-ui/src/develop/session.rs#L603), [`ui/dr-ui/src/develop/tabs.rs:80`](../../ui/dr-ui/src/develop/tabs.rs#L80), [`ui/dr-ui/src/develop_ui.rs:386`](../../ui/dr-ui/src/develop_ui.rs#L386), [`ui/dr-ui/src/lib.rs:837`](../../ui/dr-ui/src/lib.rs#L837), [`ui/dr-ui/src/lib.rs:902`](../../ui/dr-ui/src/lib.rs#L902), [`ui/dr-ui/src/library/sidecar.rs:322`](../../ui/dr-ui/src/library/sidecar.rs#L322), [`ui/dr-ui/src/library/sidecar.rs:49`](../../ui/dr-ui/src/library/sidecar.rs#L49), [`ui/dr-ui/src/presets.rs:422`](../../ui/dr-ui/src/presets.rs#L422), [`ui/dr-ui/ui/adjust.slint:1070`](../../ui/dr-ui/ui/adjust.slint#L1070), [`ui/dr-ui/ui/adjust.slint:1080`](../../ui/dr-ui/ui/adjust.slint#L1080), [`ui/dr-ui/ui/adjust.slint:1304`](../../ui/dr-ui/ui/adjust.slint#L1304) | +| FR-DEV-3d | [`core/dr-gpu/src/adjust.rs:1039`](../../core/dr-gpu/src/adjust.rs#L1039), [`core/dr-gpu/src/adjust.rs:114`](../../core/dr-gpu/src/adjust.rs#L114), [`core/dr-gpu/src/adjust.rs:1279`](../../core/dr-gpu/src/adjust.rs#L1279), [`core/dr-gpu/src/adjust.rs:1373`](../../core/dr-gpu/src/adjust.rs#L1373), [`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:468`](../../core/dr-pipeline/src/framing.rs#L468), [`core/dr-pipeline/src/graph.rs:991`](../../core/dr-pipeline/src/graph.rs#L991), [`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:127`](../../core/dr-decode/src/lib.rs#L127), [`core/dr-decode/src/lib.rs:777`](../../core/dr-decode/src/lib.rs#L777), [`core/dr-decode/src/lib.rs:817`](../../core/dr-decode/src/lib.rs#L817), [`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:473`](../../core/dr-decode/src/profile.rs#L473), [`core/dr-decode/src/profile.rs:507`](../../core/dr-decode/src/profile.rs#L507), [`core/dr-decode/src/profile.rs:678`](../../core/dr-decode/src/profile.rs#L678), [`core/dr-gpu/src/adjust.rs:1260`](../../core/dr-gpu/src/adjust.rs#L1260), [`core/dr-gpu/src/adjust.rs:37`](../../core/dr-gpu/src/adjust.rs#L37), [`core/dr-gpu/src/demosaic.rs:142`](../../core/dr-gpu/src/demosaic.rs#L142), [`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:2057`](../../core/dr-pipeline/src/operation.rs#L2057), [`core/dr-pipeline/src/operation.rs:2138`](../../core/dr-pipeline/src/operation.rs#L2138), [`core/dr-pipeline/src/operation.rs:2163`](../../core/dr-pipeline/src/operation.rs#L2163), [`core/dr-pipeline/src/operation.rs:2178`](../../core/dr-pipeline/src/operation.rs#L2178), [`core/dr-pipeline/src/operation.rs:2202`](../../core/dr-pipeline/src/operation.rs#L2202), [`core/dr-pipeline/src/operation.rs:310`](../../core/dr-pipeline/src/operation.rs#L310), [`core/dr-pipeline/src/operation.rs:502`](../../core/dr-pipeline/src/operation.rs#L502), [`core/dr-pipeline/src/operation.rs:512`](../../core/dr-pipeline/src/operation.rs#L512), [`core/dr-pipeline/src/operation.rs:805`](../../core/dr-pipeline/src/operation.rs#L805) | +| 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:152`](../../core/dr-gpu/src/adjust.rs#L152), [`core/dr-gpu/src/adjust.rs:408`](../../core/dr-gpu/src/adjust.rs#L408), [`core/dr-gpu/src/adjust.rs:583`](../../core/dr-gpu/src/adjust.rs#L583), [`core/dr-gpu/src/adjust.rs:713`](../../core/dr-gpu/src/adjust.rs#L713), [`core/dr-gpu/src/adjust.rs:77`](../../core/dr-gpu/src/adjust.rs#L77), [`core/dr-gpu/tests/film_sim.rs:195`](../../core/dr-gpu/tests/film_sim.rs#L195), [`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:1373`](../../core/dr-pipeline/src/operation.rs#L1373), [`core/dr-pipeline/src/operation.rs:1401`](../../core/dr-pipeline/src/operation.rs#L1401), [`core/dr-pipeline/src/operation.rs:1447`](../../core/dr-pipeline/src/operation.rs#L1447), [`core/dr-pipeline/src/operation.rs:2057`](../../core/dr-pipeline/src/operation.rs#L2057), [`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:1077`](../../core/dr-pipeline/src/sidecar.rs#L1077), [`core/dr-pipeline/src/sidecar.rs:133`](../../core/dr-pipeline/src/sidecar.rs#L133), [`core/dr-pipeline/src/sidecar.rs:217`](../../core/dr-pipeline/src/sidecar.rs#L217), [`core/dr-pipeline/src/sidecar.rs:2722`](../../core/dr-pipeline/src/sidecar.rs#L2722), [`core/dr-pipeline/src/sidecar.rs:2798`](../../core/dr-pipeline/src/sidecar.rs#L2798), [`core/dr-pipeline/src/sidecar.rs:595`](../../core/dr-pipeline/src/sidecar.rs#L595), [`core/dr-pipeline/src/sidecar.rs:898`](../../core/dr-pipeline/src/sidecar.rs#L898), [`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/render.rs:1210`](../../ui/dr-ui/src/develop/render.rs#L1210), [`ui/dr-ui/src/develop/render.rs:682`](../../ui/dr-ui/src/develop/render.rs#L682), [`ui/dr-ui/src/develop/render.rs:699`](../../ui/dr-ui/src/develop/render.rs#L699), [`ui/dr-ui/src/develop/render.rs:711`](../../ui/dr-ui/src/develop/render.rs#L711), [`ui/dr-ui/src/develop/render.rs:749`](../../ui/dr-ui/src/develop/render.rs#L749), [`ui/dr-ui/src/develop/render.rs:758`](../../ui/dr-ui/src/develop/render.rs#L758), [`ui/dr-ui/src/develop/render.rs:861`](../../ui/dr-ui/src/develop/render.rs#L861), [`ui/dr-ui/src/develop/render.rs:887`](../../ui/dr-ui/src/develop/render.rs#L887), [`ui/dr-ui/src/develop/session.rs:603`](../../ui/dr-ui/src/develop/session.rs#L603), [`ui/dr-ui/src/develop/tabs.rs:80`](../../ui/dr-ui/src/develop/tabs.rs#L80), [`ui/dr-ui/src/develop_ui.rs:386`](../../ui/dr-ui/src/develop_ui.rs#L386), [`ui/dr-ui/src/lib.rs:837`](../../ui/dr-ui/src/lib.rs#L837), [`ui/dr-ui/src/lib.rs:902`](../../ui/dr-ui/src/lib.rs#L902), [`ui/dr-ui/src/library/sidecar.rs:322`](../../ui/dr-ui/src/library/sidecar.rs#L322), [`ui/dr-ui/src/library/sidecar.rs:49`](../../ui/dr-ui/src/library/sidecar.rs#L49), [`ui/dr-ui/src/presets.rs:422`](../../ui/dr-ui/src/presets.rs#L422), [`ui/dr-ui/ui/adjust.slint:1070`](../../ui/dr-ui/ui/adjust.slint#L1070), [`ui/dr-ui/ui/adjust.slint:1080`](../../ui/dr-ui/ui/adjust.slint#L1080), [`ui/dr-ui/ui/adjust.slint:1304`](../../ui/dr-ui/ui/adjust.slint#L1304) | | FR-DEV-3h | [`core/dr-decode/src/lib.rs:450`](../../core/dr-decode/src/lib.rs#L450), [`core/dr-decode/src/preview.rs:29`](../../core/dr-decode/src/preview.rs#L29), [`core/dr-pipeline/src/framing.rs:1477`](../../core/dr-pipeline/src/framing.rs#L1477), [`core/dr-pipeline/src/framing.rs:486`](../../core/dr-pipeline/src/framing.rs#L486), [`core/dr-pipeline/src/framing.rs:704`](../../core/dr-pipeline/src/framing.rs#L704), [`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/masks.rs:280`](../../ui/dr-ui/src/develop/masks.rs#L280), [`ui/dr-ui/src/develop/segmentation.rs:114`](../../ui/dr-ui/src/develop/segmentation.rs#L114), [`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:798`](../../core/dr-gpu/src/adjust.rs#L798), [`core/dr-gpu/src/lib.rs:368`](../../core/dr-gpu/src/lib.rs#L368), [`ui/dr-ui/ui/crop.slint:1`](../../ui/dr-ui/ui/crop.slint#L1) | +| FR-DEV-4 | [`core/dr-gpu/src/adjust.rs:1039`](../../core/dr-gpu/src/adjust.rs#L1039), [`core/dr-gpu/src/lib.rs:368`](../../core/dr-gpu/src/lib.rs#L368), [`ui/dr-ui/ui/crop.slint:1`](../../ui/dr-ui/ui/crop.slint#L1) | | FR-DEV-5 | [`core/dr-pipeline/src/graph.rs:1440`](../../core/dr-pipeline/src/graph.rs#L1440), [`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:1067`](../../core/dr-pipeline/src/sidecar.rs#L1067), [`core/dr-pipeline/src/sidecar.rs:147`](../../core/dr-pipeline/src/sidecar.rs#L147), [`core/dr-pipeline/src/sidecar.rs:2513`](../../core/dr-pipeline/src/sidecar.rs#L2513), [`core/dr-pipeline/src/sidecar.rs:2549`](../../core/dr-pipeline/src/sidecar.rs#L2549), [`core/dr-pipeline/src/sidecar.rs:2561`](../../core/dr-pipeline/src/sidecar.rs#L2561), [`core/dr-pipeline/src/sidecar.rs:318`](../../core/dr-pipeline/src/sidecar.rs#L318), [`core/dr-pipeline/src/sidecar.rs:713`](../../core/dr-pipeline/src/sidecar.rs#L713), [`core/dr-pipeline/src/sidecar.rs:729`](../../core/dr-pipeline/src/sidecar.rs#L729), [`core/dr-pipeline/src/sidecar.rs:876`](../../core/dr-pipeline/src/sidecar.rs#L876), [`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/framing.rs:870`](../../ui/dr-ui/src/develop/framing.rs#L870), [`ui/dr-ui/src/develop/history.rs:11`](../../ui/dr-ui/src/develop/history.rs#L11), [`ui/dr-ui/src/develop/history.rs:152`](../../ui/dr-ui/src/develop/history.rs#L152), [`ui/dr-ui/src/develop/history.rs:165`](../../ui/dr-ui/src/develop/history.rs#L165), [`ui/dr-ui/src/develop/history.rs:178`](../../ui/dr-ui/src/develop/history.rs#L178), [`ui/dr-ui/src/develop/history.rs:190`](../../ui/dr-ui/src/develop/history.rs#L190), [`ui/dr-ui/src/develop/history.rs:206`](../../ui/dr-ui/src/develop/history.rs#L206), [`ui/dr-ui/src/develop/history.rs:238`](../../ui/dr-ui/src/develop/history.rs#L238), [`ui/dr-ui/src/develop/history.rs:242`](../../ui/dr-ui/src/develop/history.rs#L242), [`ui/dr-ui/src/develop/history.rs:261`](../../ui/dr-ui/src/develop/history.rs#L261), [`ui/dr-ui/src/develop/history.rs:277`](../../ui/dr-ui/src/develop/history.rs#L277), [`ui/dr-ui/src/develop/history.rs:299`](../../ui/dr-ui/src/develop/history.rs#L299), [`ui/dr-ui/src/develop/history.rs:29`](../../ui/dr-ui/src/develop/history.rs#L29), [`ui/dr-ui/src/develop/history.rs:359`](../../ui/dr-ui/src/develop/history.rs#L359), [`ui/dr-ui/src/develop/history.rs:68`](../../ui/dr-ui/src/develop/history.rs#L68), [`ui/dr-ui/src/develop/history.rs:82`](../../ui/dr-ui/src/develop/history.rs#L82), [`ui/dr-ui/src/develop/history.rs:93`](../../ui/dr-ui/src/develop/history.rs#L93), [`ui/dr-ui/src/develop/render.rs:711`](../../ui/dr-ui/src/develop/render.rs#L711), [`ui/dr-ui/src/develop/render.rs:887`](../../ui/dr-ui/src/develop/render.rs#L887), [`ui/dr-ui/src/develop/render.rs:923`](../../ui/dr-ui/src/develop/render.rs#L923), [`ui/dr-ui/src/develop/session.rs:80`](../../ui/dr-ui/src/develop/session.rs#L80), [`ui/dr-ui/src/develop/session.rs:89`](../../ui/dr-ui/src/develop/session.rs#L89), [`ui/dr-ui/src/develop/white_balance.rs:11`](../../ui/dr-ui/src/develop/white_balance.rs#L11), [`ui/dr-ui/src/develop/white_balance.rs:162`](../../ui/dr-ui/src/develop/white_balance.rs#L162), [`ui/dr-ui/src/develop_ui.rs:705`](../../ui/dr-ui/src/develop_ui.rs#L705), [`ui/dr-ui/src/develop_ui.rs:725`](../../ui/dr-ui/src/develop_ui.rs#L725), [`ui/dr-ui/src/labels.rs:12`](../../ui/dr-ui/src/labels.rs#L12), [`ui/dr-ui/src/labels.rs:284`](../../ui/dr-ui/src/labels.rs#L284), [`ui/dr-ui/src/labels.rs:31`](../../ui/dr-ui/src/labels.rs#L31), [`ui/dr-ui/src/lib.rs:2125`](../../ui/dr-ui/src/lib.rs#L2125), [`ui/dr-ui/src/lib.rs:2130`](../../ui/dr-ui/src/lib.rs#L2130), [`ui/dr-ui/src/lib.rs:2162`](../../ui/dr-ui/src/lib.rs#L2162), [`ui/dr-ui/src/lib.rs:2171`](../../ui/dr-ui/src/lib.rs#L2171), [`ui/dr-ui/src/lib.rs:2188`](../../ui/dr-ui/src/lib.rs#L2188), [`ui/dr-ui/src/library/sidecar.rs:348`](../../ui/dr-ui/src/library/sidecar.rs#L348), [`ui/dr-ui/src/library/sidecar.rs:58`](../../ui/dr-ui/src/library/sidecar.rs#L58), [`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:192`](../../ui/dr-ui/ui/history.slint#L192), [`ui/dr-ui/ui/history.slint:1`](../../ui/dr-ui/ui/history.slint#L1), [`ui/dr-ui/ui/history.slint:219`](../../ui/dr-ui/ui/history.slint#L219), [`ui/dr-ui/ui/history.slint:304`](../../ui/dr-ui/ui/history.slint#L304), [`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:443`](../../core/dr-types/src/settings.rs#L443), [`ui/dr-ui/src/develop/session.rs:560`](../../ui/dr-ui/src/develop/session.rs#L560), [`ui/dr-ui/src/develop/session.rs:581`](../../ui/dr-ui/src/develop/session.rs#L581), [`ui/dr-ui/src/develop_ui.rs:167`](../../ui/dr-ui/src/develop_ui.rs#L167), [`ui/dr-ui/src/develop_ui.rs:196`](../../ui/dr-ui/src/develop_ui.rs#L196), [`ui/dr-ui/src/lib.rs:1238`](../../ui/dr-ui/src/lib.rs#L1238), [`ui/dr-ui/src/library/sidecar.rs:11`](../../ui/dr-ui/src/library/sidecar.rs#L11), [`ui/dr-ui/src/library/sidecar.rs:39`](../../ui/dr-ui/src/library/sidecar.rs#L39), [`ui/dr-ui/src/library/thumbnails_fetch.rs:413`](../../ui/dr-ui/src/library/thumbnails_fetch.rs#L413), [`ui/dr-ui/src/library_ui/controller.rs:643`](../../ui/dr-ui/src/library_ui/controller.rs#L643), [`ui/dr-ui/src/library_ui/ratings_keywords.rs:488`](../../ui/dr-ui/src/library_ui/ratings_keywords.rs#L488), [`ui/dr-ui/src/library_ui/window.rs:659`](../../ui/dr-ui/src/library_ui/window.rs#L659), [`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:936`](../../ui/dr-ui/ui/adjust.slint#L936), [`ui/dr-ui/ui/adjust.slint:961`](../../ui/dr-ui/ui/adjust.slint#L961), [`ui/dr-ui/ui/app.slint:1049`](../../ui/dr-ui/ui/app.slint#L1049), [`ui/dr-ui/ui/app.slint:1458`](../../ui/dr-ui/ui/app.slint#L1458), [`ui/dr-ui/ui/app.slint:2416`](../../ui/dr-ui/ui/app.slint#L2416), [`ui/dr-ui/ui/app.slint:3337`](../../ui/dr-ui/ui/app.slint#L3337), [`ui/dr-ui/ui/app.slint:3381`](../../ui/dr-ui/ui/app.slint#L3381), [`ui/dr-ui/ui/app.slint:488`](../../ui/dr-ui/ui/app.slint#L488), [`ui/dr-ui/ui/app.slint:499`](../../ui/dr-ui/ui/app.slint#L499), [`ui/dr-ui/ui/app.slint:653`](../../ui/dr-ui/ui/app.slint#L653), [`ui/dr-ui/ui/develop.slint:257`](../../ui/dr-ui/ui/develop.slint#L257), [`ui/dr-ui/ui/library.slint:1995`](../../ui/dr-ui/ui/library.slint#L1995), [`ui/dr-ui/ui/library.slint:2001`](../../ui/dr-ui/ui/library.slint#L2001), [`ui/dr-ui/ui/library.slint:3190`](../../ui/dr-ui/ui/library.slint#L3190), [`ui/dr-ui/ui/library.slint:5108`](../../ui/dr-ui/ui/library.slint#L5108), [`ui/dr-ui/ui/library.slint:5126`](../../ui/dr-ui/ui/library.slint#L5126), [`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:332`](../../ui/dr-ui/ui/presets.slint#L332), [`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:120`](../../ui/dr-ui/ui/settings.slint#L120), [`ui/dr-ui/ui/settings.slint:642`](../../ui/dr-ui/ui/settings.slint#L642) | | 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/history.rs:107`](../../ui/dr-ui/src/develop/history.rs#L107), [`ui/dr-ui/src/develop/history.rs:124`](../../ui/dr-ui/src/develop/history.rs#L124), [`ui/dr-ui/src/develop/history.rs:206`](../../ui/dr-ui/src/develop/history.rs#L206), [`ui/dr-ui/src/develop/history.rs:238`](../../ui/dr-ui/src/develop/history.rs#L238), [`ui/dr-ui/src/develop/history.rs:359`](../../ui/dr-ui/src/develop/history.rs#L359), [`ui/dr-ui/src/develop/render.rs:493`](../../ui/dr-ui/src/develop/render.rs#L493), [`ui/dr-ui/src/develop/render.rs:534`](../../ui/dr-ui/src/develop/render.rs#L534), [`ui/dr-ui/src/develop/render.rs:923`](../../ui/dr-ui/src/develop/render.rs#L923), [`ui/dr-ui/src/develop/session.rs:105`](../../ui/dr-ui/src/develop/session.rs#L105), [`ui/dr-ui/src/develop_ui.rs:646`](../../ui/dr-ui/src/develop_ui.rs#L646), [`ui/dr-ui/src/develop_ui.rs:705`](../../ui/dr-ui/src/develop_ui.rs#L705), [`ui/dr-ui/src/develop_ui.rs:777`](../../ui/dr-ui/src/develop_ui.rs#L777), [`ui/dr-ui/src/lib.rs:2171`](../../ui/dr-ui/src/lib.rs#L2171), [`ui/dr-ui/src/lib.rs:2248`](../../ui/dr-ui/src/lib.rs#L2248), [`ui/dr-ui/src/lib.rs:2262`](../../ui/dr-ui/src/lib.rs#L2262), [`ui/dr-ui/src/lib.rs:434`](../../ui/dr-ui/src/lib.rs#L434), [`ui/dr-ui/ui/app.slint:189`](../../ui/dr-ui/ui/app.slint#L189), [`ui/dr-ui/ui/app.slint:2283`](../../ui/dr-ui/ui/app.slint#L2283), [`ui/dr-ui/ui/app.slint:2329`](../../ui/dr-ui/ui/app.slint#L2329), [`ui/dr-ui/ui/app.slint:2898`](../../ui/dr-ui/ui/app.slint#L2898), [`ui/dr-ui/ui/history.slint:103`](../../ui/dr-ui/ui/history.slint#L103), [`ui/dr-ui/ui/history.slint:1`](../../ui/dr-ui/ui/history.slint#L1), [`ui/dr-ui/ui/history.slint:227`](../../ui/dr-ui/ui/history.slint#L227), [`ui/dr-ui/ui/history.slint:53`](../../ui/dr-ui/ui/history.slint#L53), [`ui/dr-ui/ui/widgets.slint:72`](../../ui/dr-ui/ui/widgets.slint#L72) | -| 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:1092`](../../core/dr-pipeline/src/graph.rs#L1092), [`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:717`](../../core/dr-pipeline/src/operation.rs#L717), [`core/dr-pipeline/src/sidecar.rs:1104`](../../core/dr-pipeline/src/sidecar.rs#L1104), [`core/dr-pipeline/src/sidecar.rs:1158`](../../core/dr-pipeline/src/sidecar.rs#L1158), [`core/dr-pipeline/src/sidecar.rs:1188`](../../core/dr-pipeline/src/sidecar.rs#L1188), [`core/dr-pipeline/src/sidecar.rs:233`](../../core/dr-pipeline/src/sidecar.rs#L233), [`core/dr-pipeline/src/sidecar.rs:410`](../../core/dr-pipeline/src/sidecar.rs#L410), [`core/dr-pipeline/src/sidecar.rs:910`](../../core/dr-pipeline/src/sidecar.rs#L910), [`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/repairs.rs:114`](../../ui/dr-ui/src/develop/repairs.rs#L114), [`ui/dr-ui/src/develop/repairs.rs:11`](../../ui/dr-ui/src/develop/repairs.rs#L11), [`ui/dr-ui/src/develop/repairs.rs:197`](../../ui/dr-ui/src/develop/repairs.rs#L197), [`ui/dr-ui/src/develop/repairs.rs:211`](../../ui/dr-ui/src/develop/repairs.rs#L211), [`ui/dr-ui/src/develop/repairs.rs:49`](../../ui/dr-ui/src/develop/repairs.rs#L49), [`ui/dr-ui/src/develop/session.rs:216`](../../ui/dr-ui/src/develop/session.rs#L216), [`ui/dr-ui/src/develop_ui.rs:932`](../../ui/dr-ui/src/develop_ui.rs#L932), [`ui/dr-ui/src/labels.rs:80`](../../ui/dr-ui/src/labels.rs#L80), [`ui/dr-ui/src/lib.rs:2206`](../../ui/dr-ui/src/lib.rs#L2206), [`ui/dr-ui/src/lib.rs:477`](../../ui/dr-ui/src/lib.rs#L477), [`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:2136`](../../ui/dr-ui/ui/app.slint#L2136), [`ui/dr-ui/ui/app.slint:2379`](../../ui/dr-ui/ui/app.slint#L2379), [`ui/dr-ui/ui/app.slint:3243`](../../ui/dr-ui/ui/app.slint#L3243), [`ui/dr-ui/ui/icons.slint:378`](../../ui/dr-ui/ui/icons.slint#L378), [`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:2422`](../../core/dr-gpu/src/adjust.rs#L2422), [`core/dr-gpu/src/adjust.rs:2499`](../../core/dr-gpu/src/adjust.rs#L2499), [`core/dr-gpu/src/adjust.rs:2584`](../../core/dr-gpu/src/adjust.rs#L2584), [`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:174`](../../core/dr-gpu/src/lib.rs#L174), [`core/dr-gpu/src/lib.rs:194`](../../core/dr-gpu/src/lib.rs#L194), [`core/dr-gpu/src/lib.rs:72`](../../core/dr-gpu/src/lib.rs#L72), [`core/dr-gpu/src/lib.rs:95`](../../core/dr-gpu/src/lib.rs#L95), [`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:922`](../../core/dr-pipeline/src/graph.rs#L922), [`core/dr-pipeline/src/graph.rs:952`](../../core/dr-pipeline/src/graph.rs#L952), [`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/framing.rs:594`](../../ui/dr-ui/src/develop/framing.rs#L594), [`ui/dr-ui/src/develop/mod.rs:55`](../../ui/dr-ui/src/develop/mod.rs#L55), [`ui/dr-ui/src/develop/render.rs:1014`](../../ui/dr-ui/src/develop/render.rs#L1014), [`ui/dr-ui/src/develop/render.rs:1152`](../../ui/dr-ui/src/develop/render.rs#L1152), [`ui/dr-ui/src/develop/render.rs:217`](../../ui/dr-ui/src/develop/render.rs#L217), [`ui/dr-ui/src/develop/render.rs:79`](../../ui/dr-ui/src/develop/render.rs#L79), [`ui/dr-ui/src/develop/render.rs:980`](../../ui/dr-ui/src/develop/render.rs#L980), [`ui/dr-ui/src/lib.rs:1058`](../../ui/dr-ui/src/lib.rs#L1058), [`ui/dr-ui/src/lib.rs:108`](../../ui/dr-ui/src/lib.rs#L108) | +| 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:1092`](../../core/dr-pipeline/src/graph.rs#L1092), [`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:749`](../../core/dr-pipeline/src/operation.rs#L749), [`core/dr-pipeline/src/sidecar.rs:1104`](../../core/dr-pipeline/src/sidecar.rs#L1104), [`core/dr-pipeline/src/sidecar.rs:1158`](../../core/dr-pipeline/src/sidecar.rs#L1158), [`core/dr-pipeline/src/sidecar.rs:1188`](../../core/dr-pipeline/src/sidecar.rs#L1188), [`core/dr-pipeline/src/sidecar.rs:233`](../../core/dr-pipeline/src/sidecar.rs#L233), [`core/dr-pipeline/src/sidecar.rs:410`](../../core/dr-pipeline/src/sidecar.rs#L410), [`core/dr-pipeline/src/sidecar.rs:910`](../../core/dr-pipeline/src/sidecar.rs#L910), [`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/repairs.rs:114`](../../ui/dr-ui/src/develop/repairs.rs#L114), [`ui/dr-ui/src/develop/repairs.rs:11`](../../ui/dr-ui/src/develop/repairs.rs#L11), [`ui/dr-ui/src/develop/repairs.rs:197`](../../ui/dr-ui/src/develop/repairs.rs#L197), [`ui/dr-ui/src/develop/repairs.rs:211`](../../ui/dr-ui/src/develop/repairs.rs#L211), [`ui/dr-ui/src/develop/repairs.rs:49`](../../ui/dr-ui/src/develop/repairs.rs#L49), [`ui/dr-ui/src/develop/session.rs:216`](../../ui/dr-ui/src/develop/session.rs#L216), [`ui/dr-ui/src/develop_ui.rs:932`](../../ui/dr-ui/src/develop_ui.rs#L932), [`ui/dr-ui/src/labels.rs:80`](../../ui/dr-ui/src/labels.rs#L80), [`ui/dr-ui/src/lib.rs:2206`](../../ui/dr-ui/src/lib.rs#L2206), [`ui/dr-ui/src/lib.rs:477`](../../ui/dr-ui/src/lib.rs#L477), [`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:2136`](../../ui/dr-ui/ui/app.slint#L2136), [`ui/dr-ui/ui/app.slint:2379`](../../ui/dr-ui/ui/app.slint#L2379), [`ui/dr-ui/ui/app.slint:3243`](../../ui/dr-ui/ui/app.slint#L3243), [`ui/dr-ui/ui/icons.slint:378`](../../ui/dr-ui/ui/icons.slint#L378), [`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:1039`](../../core/dr-gpu/src/adjust.rs#L1039), [`core/dr-gpu/src/adjust.rs:2698`](../../core/dr-gpu/src/adjust.rs#L2698), [`core/dr-gpu/src/adjust.rs:2775`](../../core/dr-gpu/src/adjust.rs#L2775), [`core/dr-gpu/src/adjust.rs:2860`](../../core/dr-gpu/src/adjust.rs#L2860), [`core/dr-gpu/src/adjust.rs:54`](../../core/dr-gpu/src/adjust.rs#L54), [`core/dr-gpu/src/lib.rs:174`](../../core/dr-gpu/src/lib.rs#L174), [`core/dr-gpu/src/lib.rs:194`](../../core/dr-gpu/src/lib.rs#L194), [`core/dr-gpu/src/lib.rs:72`](../../core/dr-gpu/src/lib.rs#L72), [`core/dr-gpu/src/lib.rs:95`](../../core/dr-gpu/src/lib.rs#L95), [`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:922`](../../core/dr-pipeline/src/graph.rs#L922), [`core/dr-pipeline/src/graph.rs:952`](../../core/dr-pipeline/src/graph.rs#L952), [`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/framing.rs:594`](../../ui/dr-ui/src/develop/framing.rs#L594), [`ui/dr-ui/src/develop/mod.rs:55`](../../ui/dr-ui/src/develop/mod.rs#L55), [`ui/dr-ui/src/develop/render.rs:1014`](../../ui/dr-ui/src/develop/render.rs#L1014), [`ui/dr-ui/src/develop/render.rs:1152`](../../ui/dr-ui/src/develop/render.rs#L1152), [`ui/dr-ui/src/develop/render.rs:217`](../../ui/dr-ui/src/develop/render.rs#L217), [`ui/dr-ui/src/develop/render.rs:79`](../../ui/dr-ui/src/develop/render.rs#L79), [`ui/dr-ui/src/develop/render.rs:980`](../../ui/dr-ui/src/develop/render.rs#L980), [`ui/dr-ui/src/lib.rs:1058`](../../ui/dr-ui/src/lib.rs#L1058), [`ui/dr-ui/src/lib.rs:108`](../../ui/dr-ui/src/lib.rs#L108) | | 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-4 | [`ui/dr-ui/src/lib.rs:2271`](../../ui/dr-ui/src/lib.rs#L2271), [`ui/dr-ui/src/lib.rs:2450`](../../ui/dr-ui/src/lib.rs#L2450), [`ui/dr-ui/src/refine.rs:1`](../../ui/dr-ui/src/refine.rs#L1), [`ui/dr-ui/ui/app.slint:103`](../../ui/dr-ui/ui/app.slint#L103), [`ui/dr-ui/ui/app.slint:1785`](../../ui/dr-ui/ui/app.slint#L1785), [`ui/dr-ui/ui/histogram.slint:182`](../../ui/dr-ui/ui/histogram.slint#L182), [`ui/dr-ui/ui/histogram.slint:250`](../../ui/dr-ui/ui/histogram.slint#L250) | | 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:527`](../../core/dr-pipeline/src/operation.rs#L527), [`core/dr-types/src/colour.rs:1`](../../core/dr-types/src/colour.rs#L1), [`ui/dr-ui/src/develop/render.rs:1475`](../../ui/dr-ui/src/develop/render.rs#L1475), [`ui/dr-ui/src/develop/render.rs:252`](../../ui/dr-ui/src/develop/render.rs#L252), [`ui/dr-ui/src/lib.rs:2147`](../../ui/dr-ui/src/lib.rs#L2147), [`ui/dr-ui/src/lib.rs:2922`](../../ui/dr-ui/src/lib.rs#L2922) | +| FR-DSP-6 | [`core/dr-pipeline/src/operation.rs:559`](../../core/dr-pipeline/src/operation.rs#L559), [`core/dr-types/src/colour.rs:1`](../../core/dr-types/src/colour.rs#L1), [`ui/dr-ui/src/develop/render.rs:1475`](../../ui/dr-ui/src/develop/render.rs#L1475), [`ui/dr-ui/src/develop/render.rs:252`](../../ui/dr-ui/src/develop/render.rs#L252), [`ui/dr-ui/src/lib.rs:2147`](../../ui/dr-ui/src/lib.rs#L2147), [`ui/dr-ui/src/lib.rs:2922`](../../ui/dr-ui/src/lib.rs#L2922) | | 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/render.rs:1265`](../../ui/dr-ui/src/develop/render.rs#L1265), [`ui/dr-ui/src/develop/render.rs:1297`](../../ui/dr-ui/src/develop/render.rs#L1297), [`ui/dr-ui/src/develop/render.rs:285`](../../ui/dr-ui/src/develop/render.rs#L285), [`ui/dr-ui/src/develop/session.rs:116`](../../ui/dr-ui/src/develop/session.rs#L116), [`ui/dr-ui/src/histogram.rs:1`](../../ui/dr-ui/src/histogram.rs#L1), [`ui/dr-ui/src/lib.rs:2303`](../../ui/dr-ui/src/lib.rs#L2303), [`ui/dr-ui/src/lib.rs:454`](../../ui/dr-ui/src/lib.rs#L454), [`ui/dr-ui/ui/histogram.slint:191`](../../ui/dr-ui/ui/histogram.slint#L191), [`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/render.rs:1113`](../../ui/dr-ui/src/develop/render.rs#L1113), [`ui/dr-ui/src/develop/render.rs:1475`](../../ui/dr-ui/src/develop/render.rs#L1475), [`ui/dr-ui/src/develop/render.rs:1521`](../../ui/dr-ui/src/develop/render.rs#L1521), [`ui/dr-ui/src/develop/render.rs:1540`](../../ui/dr-ui/src/develop/render.rs#L1540), [`ui/dr-ui/src/develop/render.rs:193`](../../ui/dr-ui/src/develop/render.rs#L193), [`ui/dr-ui/src/develop/render.rs:252`](../../ui/dr-ui/src/develop/render.rs#L252), [`ui/dr-ui/src/develop/render.rs:47`](../../ui/dr-ui/src/develop/render.rs#L47), [`ui/dr-ui/src/develop/session.rs:269`](../../ui/dr-ui/src/develop/session.rs#L269), [`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:1260`](../../ui/dr-ui/src/lib.rs#L1260), [`ui/dr-ui/src/lib.rs:2147`](../../ui/dr-ui/src/lib.rs#L2147), [`ui/dr-ui/src/lib.rs:2899`](../../ui/dr-ui/src/lib.rs#L2899), [`ui/dr-ui/src/lib.rs:2922`](../../ui/dr-ui/src/lib.rs#L2922), [`ui/dr-ui/ui/app.slint:121`](../../ui/dr-ui/ui/app.slint#L121), [`ui/dr-ui/ui/app.slint:1771`](../../ui/dr-ui/ui/app.slint#L1771), [`ui/dr-ui/ui/settings.slint:170`](../../ui/dr-ui/ui/settings.slint#L170), [`ui/dr-ui/ui/settings.slint:816`](../../ui/dr-ui/ui/settings.slint#L816) | | 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:157`](../../core/dr-export/src/lib.rs#L157), [`core/dr-export/src/lib.rs:1`](../../core/dr-export/src/lib.rs#L1), [`core/dr-export/src/lib.rs:57`](../../core/dr-export/src/lib.rs#L57), [`core/dr-gpu/src/adjust.rs:2732`](../../core/dr-gpu/src/adjust.rs#L2732), [`core/dr-pipeline/src/graph.rs:835`](../../core/dr-pipeline/src/graph.rs#L835), [`core/dr-pipeline/src/graph.rs:966`](../../core/dr-pipeline/src/graph.rs#L966), [`core/dr-pipeline/src/operation.rs:527`](../../core/dr-pipeline/src/operation.rs#L527), [`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:963`](../../core/dr-types/src/settings.rs#L963), [`ui/dr-ui/src/develop/render.rs:1540`](../../ui/dr-ui/src/develop/render.rs#L1540), [`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:157`](../../core/dr-export/src/lib.rs#L157), [`core/dr-export/src/lib.rs:1`](../../core/dr-export/src/lib.rs#L1), [`core/dr-export/src/lib.rs:57`](../../core/dr-export/src/lib.rs#L57), [`core/dr-gpu/src/adjust.rs:3133`](../../core/dr-gpu/src/adjust.rs#L3133), [`core/dr-pipeline/src/graph.rs:835`](../../core/dr-pipeline/src/graph.rs#L835), [`core/dr-pipeline/src/graph.rs:966`](../../core/dr-pipeline/src/graph.rs#L966), [`core/dr-pipeline/src/operation.rs:559`](../../core/dr-pipeline/src/operation.rs#L559), [`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:963`](../../core/dr-types/src/settings.rs#L963), [`ui/dr-ui/src/develop/render.rs:1540`](../../ui/dr-ui/src/develop/render.rs#L1540), [`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:186`](../../core/dr-export/src/lib.rs#L186), [`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:1008`](../../core/dr-types/src/settings.rs#L1008), [`core/dr-types/src/settings.rs:1016`](../../core/dr-types/src/settings.rs#L1016), [`core/dr-types/src/settings.rs:1032`](../../core/dr-types/src/settings.rs#L1032), [`core/dr-types/src/settings.rs:1101`](../../core/dr-types/src/settings.rs#L1101), [`core/dr-types/src/settings.rs:1129`](../../core/dr-types/src/settings.rs#L1129), [`core/dr-types/src/settings.rs:1140`](../../core/dr-types/src/settings.rs#L1140), [`core/dr-types/src/settings.rs:1146`](../../core/dr-types/src/settings.rs#L1146), [`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), [`ui/dr-ui/src/settings_ui.rs:292`](../../ui/dr-ui/src/settings_ui.rs#L292), [`ui/dr-ui/src/settings_ui.rs:305`](../../ui/dr-ui/src/settings_ui.rs#L305), [`ui/dr-ui/src/settings_ui.rs:324`](../../ui/dr-ui/src/settings_ui.rs#L324), [`ui/dr-ui/src/settings_ui.rs:809`](../../ui/dr-ui/src/settings_ui.rs#L809), [`ui/dr-ui/ui/export.slint:159`](../../ui/dr-ui/ui/export.slint#L159), [`ui/dr-ui/ui/export.slint:169`](../../ui/dr-ui/ui/export.slint#L169) | | 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:638`](../../ui/dr-ui/src/lib.rs#L638), [`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:941`](../../ui/dr-ui/src/settings_ui.rs#L941) | | FR-EXP-7 | [`ui/dr-ui/src/activity.rs:83`](../../ui/dr-ui/src/activity.rs#L83), [`ui/dr-ui/src/develop_ui.rs:309`](../../ui/dr-ui/src/develop_ui.rs#L309), [`ui/dr-ui/src/export.rs:1024`](../../ui/dr-ui/src/export.rs#L1024), [`ui/dr-ui/src/export.rs:1`](../../ui/dr-ui/src/export.rs#L1), [`ui/dr-ui/src/lib.rs:285`](../../ui/dr-ui/src/lib.rs#L285), [`ui/dr-ui/src/lib.rs:638`](../../ui/dr-ui/src/lib.rs#L638), [`ui/dr-ui/src/lib.rs:684`](../../ui/dr-ui/src/lib.rs#L684), [`ui/dr-ui/src/lib.rs:712`](../../ui/dr-ui/src/lib.rs#L712), [`ui/dr-ui/src/library_ui/controller.rs:1022`](../../ui/dr-ui/src/library_ui/controller.rs#L1022), [`ui/dr-ui/src/library_ui/controller.rs:1034`](../../ui/dr-ui/src/library_ui/controller.rs#L1034), [`ui/dr-ui/src/library_ui/controller.rs:1046`](../../ui/dr-ui/src/library_ui/controller.rs#L1046), [`ui/dr-ui/src/library_ui/controller.rs:734`](../../ui/dr-ui/src/library_ui/controller.rs#L734), [`ui/dr-ui/src/library_ui/controller.rs:834`](../../ui/dr-ui/src/library_ui/controller.rs#L834), [`ui/dr-ui/src/library_ui/controller.rs:891`](../../ui/dr-ui/src/library_ui/controller.rs#L891), [`ui/dr-ui/src/library_ui/sync.rs:100`](../../ui/dr-ui/src/library_ui/sync.rs#L100), [`ui/dr-ui/src/settings_ui.rs:502`](../../ui/dr-ui/src/settings_ui.rs#L502), [`ui/dr-ui/ui/app.slint:1049`](../../ui/dr-ui/ui/app.slint#L1049), [`ui/dr-ui/ui/app.slint:1468`](../../ui/dr-ui/ui/app.slint#L1468), [`ui/dr-ui/ui/app.slint:2472`](../../ui/dr-ui/ui/app.slint#L2472), [`ui/dr-ui/ui/app.slint:3362`](../../ui/dr-ui/ui/app.slint#L3362), [`ui/dr-ui/ui/app.slint:646`](../../ui/dr-ui/ui/app.slint#L646), [`ui/dr-ui/ui/app.slint:663`](../../ui/dr-ui/ui/app.slint#L663), [`ui/dr-ui/ui/app.slint:899`](../../ui/dr-ui/ui/app.slint#L899), [`ui/dr-ui/ui/export.slint:1`](../../ui/dr-ui/ui/export.slint#L1), [`ui/dr-ui/ui/export.slint:384`](../../ui/dr-ui/ui/export.slint#L384), [`ui/dr-ui/ui/library.slint:2004`](../../ui/dr-ui/ui/library.slint#L2004), [`ui/dr-ui/ui/library.slint:2012`](../../ui/dr-ui/ui/library.slint#L2012), [`ui/dr-ui/ui/library.slint:3171`](../../ui/dr-ui/ui/library.slint#L3171), [`ui/dr-ui/ui/library.slint:5181`](../../ui/dr-ui/ui/library.slint#L5181) | | FR-EXP-8 | [`core/dr-decode/src/lib.rs:372`](../../core/dr-decode/src/lib.rs#L372), [`core/dr-decode/src/lib.rs:396`](../../core/dr-decode/src/lib.rs#L396), [`core/dr-decode/src/lib.rs:410`](../../core/dr-decode/src/lib.rs#L410), [`core/dr-decode/src/lib.rs:77`](../../core/dr-decode/src/lib.rs#L77), [`core/dr-decode/src/lib.rs:85`](../../core/dr-decode/src/lib.rs#L85), [`core/dr-decode/src/lib.rs:88`](../../core/dr-decode/src/lib.rs#L88), [`core/dr-decode/src/locate.rs:1233`](../../core/dr-decode/src/locate.rs#L1233), [`core/dr-decode/src/locate.rs:1292`](../../core/dr-decode/src/locate.rs#L1292), [`core/dr-decode/src/locate.rs:359`](../../core/dr-decode/src/locate.rs#L359), [`core/dr-decode/src/locate.rs:556`](../../core/dr-decode/src/locate.rs#L556), [`core/dr-decode/src/locate.rs:640`](../../core/dr-decode/src/locate.rs#L640), [`core/dr-decode/src/locate.rs:653`](../../core/dr-decode/src/locate.rs#L653), [`core/dr-decode/src/locate.rs:736`](../../core/dr-decode/src/locate.rs#L736), [`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:140`](../../core/dr-export/src/lib.rs#L140), [`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:671`](../../core/dr-types/src/settings.rs#L671), [`ui/dr-ui/src/decoder_seam.rs:256`](../../ui/dr-ui/src/decoder_seam.rs#L256), [`ui/dr-ui/src/develop/session.rs:37`](../../ui/dr-ui/src/develop/session.rs#L37), [`ui/dr-ui/src/develop/session.rs:417`](../../ui/dr-ui/src/develop/session.rs#L417), [`ui/dr-ui/src/develop/session.rs:529`](../../ui/dr-ui/src/develop/session.rs#L529), [`ui/dr-ui/src/export.rs:475`](../../ui/dr-ui/src/export.rs#L475), [`ui/dr-ui/src/export.rs:646`](../../ui/dr-ui/src/export.rs#L646), [`ui/dr-ui/src/export.rs:692`](../../ui/dr-ui/src/export.rs#L692), [`ui/dr-ui/src/export.rs:720`](../../ui/dr-ui/src/export.rs#L720), [`ui/dr-ui/src/export.rs:757`](../../ui/dr-ui/src/export.rs#L757), [`ui/dr-ui/src/export.rs:858`](../../ui/dr-ui/src/export.rs#L858), [`ui/dr-ui/src/export.rs:876`](../../ui/dr-ui/src/export.rs#L876), [`ui/dr-ui/src/lib.rs:285`](../../ui/dr-ui/src/lib.rs#L285), [`ui/dr-ui/src/lib.rs:309`](../../ui/dr-ui/src/lib.rs#L309), [`ui/dr-ui/src/lib.rs:670`](../../ui/dr-ui/src/lib.rs#L670), [`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:552`](../../core/dr-decode/src/lib.rs#L552), [`core/dr-export/src/lib.rs:132`](../../core/dr-export/src/lib.rs#L132), [`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/decoder_seam.rs:256`](../../ui/dr-ui/src/decoder_seam.rs#L256), [`ui/dr-ui/src/develop/mask_ops.rs:1130`](../../ui/dr-ui/src/develop/mask_ops.rs#L1130), [`ui/dr-ui/src/develop/render.rs:586`](../../ui/dr-ui/src/develop/render.rs#L586), [`ui/dr-ui/src/develop/render.rs:624`](../../ui/dr-ui/src/develop/render.rs#L624), [`ui/dr-ui/src/lib.rs:638`](../../ui/dr-ui/src/lib.rs#L638), [`ui/dr-ui/src/library/sweep.rs:510`](../../ui/dr-ui/src/library/sweep.rs#L510), [`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:552`](../../core/dr-decode/src/lib.rs#L552), [`core/dr-export/src/lib.rs:132`](../../core/dr-export/src/lib.rs#L132), [`core/dr-export/src/lib.rs:1`](../../core/dr-export/src/lib.rs#L1), [`core/dr-gpu/src/adjust.rs:1400`](../../core/dr-gpu/src/adjust.rs#L1400), [`ui/dr-ui/examples/face_native.rs:1`](../../ui/dr-ui/examples/face_native.rs#L1), [`ui/dr-ui/src/decoder_seam.rs:256`](../../ui/dr-ui/src/decoder_seam.rs#L256), [`ui/dr-ui/src/develop/mask_ops.rs:1130`](../../ui/dr-ui/src/develop/mask_ops.rs#L1130), [`ui/dr-ui/src/develop/render.rs:586`](../../ui/dr-ui/src/develop/render.rs#L586), [`ui/dr-ui/src/develop/render.rs:624`](../../ui/dr-ui/src/develop/render.rs#L624), [`ui/dr-ui/src/lib.rs:638`](../../ui/dr-ui/src/lib.rs#L638), [`ui/dr-ui/src/library/sweep.rs:510`](../../ui/dr-ui/src/library/sweep.rs#L510), [`ui/dr-ui/tests/export_ignores_the_viewport.rs:1`](../../ui/dr-ui/tests/export_ignores_the_viewport.rs#L1) | | FR-INF-1 | [`ui/dr-ui/src/lib.rs:1434`](../../ui/dr-ui/src/lib.rs#L1434), [`ui/dr-ui/ui/settings.slint:776`](../../ui/dr-ui/ui/settings.slint#L776) | | 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), [`ui/dr-ui/src/lib.rs:1818`](../../ui/dr-ui/src/lib.rs#L1818), [`ui/dr-ui/src/merge.rs:1`](../../ui/dr-ui/src/merge.rs#L1), [`ui/dr-ui/src/merge_ui.rs:1`](../../ui/dr-ui/src/merge_ui.rs#L1), [`ui/dr-ui/ui/app.slint:1473`](../../ui/dr-ui/ui/app.slint#L1473), [`ui/dr-ui/ui/app.slint:551`](../../ui/dr-ui/ui/app.slint#L551), [`ui/dr-ui/ui/library.slint:2017`](../../ui/dr-ui/ui/library.slint#L2017), [`ui/dr-ui/ui/library.slint:5138`](../../ui/dr-ui/ui/library.slint#L5138), [`ui/dr-ui/ui/merge.slint:1`](../../ui/dr-ui/ui/merge.slint#L1) | | FR-MRG-10 | [`core/dr-gpu/src/merge.rs:1`](../../core/dr-gpu/src/merge.rs#L1), [`core/dr-gpu/src/shaders/merge.wgsl:1`](../../core/dr-gpu/src/shaders/merge.wgsl#L1), [`core/dr-pano/src/lib.rs:1`](../../core/dr-pano/src/lib.rs#L1) | | FR-MRG-11 | [`core/dr-gpu/src/merge.rs:1`](../../core/dr-gpu/src/merge.rs#L1), [`core/dr-gpu/src/shaders/merge.wgsl:1`](../../core/dr-gpu/src/shaders/merge.wgsl#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:2187`](../../core/dr-pipeline/src/operation.rs#L2187), [`core/dr-pipeline/src/operation.rs:427`](../../core/dr-pipeline/src/operation.rs#L427), [`core/dr-pipeline/src/operation.rs:612`](../../core/dr-pipeline/src/operation.rs#L612), [`core/dr-pipeline/src/operation.rs:920`](../../core/dr-pipeline/src/operation.rs#L920), [`ui/dr-ui/src/merge.rs:1`](../../ui/dr-ui/src/merge.rs#L1) | -| FR-MRG-3 | [`core/dr-decode/examples/linear_dng.rs:1`](../../core/dr-decode/examples/linear_dng.rs#L1), [`core/dr-decode/src/lib.rs:143`](../../core/dr-decode/src/lib.rs#L143), [`core/dr-decode/src/lib.rs:150`](../../core/dr-decode/src/lib.rs#L150), [`core/dr-decode/src/lib.rs:604`](../../core/dr-decode/src/lib.rs#L604), [`core/dr-decode/src/profile.rs:395`](../../core/dr-decode/src/profile.rs#L395), [`core/dr-export/src/dng.rs:1`](../../core/dr-export/src/dng.rs#L1), [`core/dr-gpu/src/demosaic.rs:254`](../../core/dr-gpu/src/demosaic.rs#L254), [`ui/dr-ui/src/merge.rs:1`](../../ui/dr-ui/src/merge.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:1423`](../../core/dr-gpu/src/adjust.rs#L1423), [`core/dr-gpu/src/adjust.rs:1552`](../../core/dr-gpu/src/adjust.rs#L1552), [`core/dr-gpu/src/adjust.rs:518`](../../core/dr-gpu/src/adjust.rs#L518), [`core/dr-pipeline/src/graph.rs:852`](../../core/dr-pipeline/src/graph.rs#L852), [`core/dr-pipeline/src/operation.rs:2255`](../../core/dr-pipeline/src/operation.rs#L2255), [`core/dr-pipeline/src/operation.rs:427`](../../core/dr-pipeline/src/operation.rs#L427), [`core/dr-pipeline/src/operation.rs:644`](../../core/dr-pipeline/src/operation.rs#L644), [`core/dr-pipeline/src/operation.rs:956`](../../core/dr-pipeline/src/operation.rs#L956), [`ui/dr-ui/src/merge.rs:1`](../../ui/dr-ui/src/merge.rs#L1) | +| FR-MRG-3 | [`core/dr-decode/examples/linear_dng.rs:1`](../../core/dr-decode/examples/linear_dng.rs#L1), [`core/dr-decode/src/lib.rs:143`](../../core/dr-decode/src/lib.rs#L143), [`core/dr-decode/src/lib.rs:150`](../../core/dr-decode/src/lib.rs#L150), [`core/dr-decode/src/lib.rs:604`](../../core/dr-decode/src/lib.rs#L604), [`core/dr-decode/src/profile.rs:395`](../../core/dr-decode/src/profile.rs#L395), [`core/dr-export/src/dng.rs:1`](../../core/dr-export/src/dng.rs#L1), [`core/dr-gpu/src/demosaic.rs:276`](../../core/dr-gpu/src/demosaic.rs#L276), [`ui/dr-ui/src/merge.rs:1`](../../ui/dr-ui/src/merge.rs#L1) | | FR-MRG-4 | [`core/dr-export/src/inscribed.rs:1`](../../core/dr-export/src/inscribed.rs#L1), [`core/dr-pano/src/fill.rs:1`](../../core/dr-pano/src/fill.rs#L1), [`core/dr-pano/src/migan.rs:1`](../../core/dr-pano/src/migan.rs#L1), [`core/dr-pano/src/projection.rs:1`](../../core/dr-pano/src/projection.rs#L1), [`ui/dr-ui/src/library/paths.rs:365`](../../ui/dr-ui/src/library/paths.rs#L365), [`ui/dr-ui/src/library/paths.rs:369`](../../ui/dr-ui/src/library/paths.rs#L369), [`ui/dr-ui/src/merge.rs:147`](../../ui/dr-ui/src/merge.rs#L147), [`ui/dr-ui/src/merge_ui.rs:1`](../../ui/dr-ui/src/merge_ui.rs#L1), [`ui/dr-ui/ui/merge.slint:1`](../../ui/dr-ui/ui/merge.slint#L1), [`ui/dr-ui/ui/merge.slint:46`](../../ui/dr-ui/ui/merge.slint#L46) | | FR-MRG-5 | [`core/dr-pano/src/align.rs:1`](../../core/dr-pano/src/align.rs#L1), [`ui/dr-ui/src/merge.rs:1`](../../ui/dr-ui/src/merge.rs#L1), [`ui/dr-ui/src/merge_ui.rs:1`](../../ui/dr-ui/src/merge_ui.rs#L1), [`ui/dr-ui/ui/merge.slint:1`](../../ui/dr-ui/ui/merge.slint#L1) | | FR-MRG-6 | [`core/dr-pipeline/src/sidecar.rs:1055`](../../core/dr-pipeline/src/sidecar.rs#L1055), [`core/dr-pipeline/src/sidecar.rs:116`](../../core/dr-pipeline/src/sidecar.rs#L116), [`core/dr-pipeline/src/sidecar.rs:126`](../../core/dr-pipeline/src/sidecar.rs#L126), [`core/dr-pipeline/src/sidecar.rs:2282`](../../core/dr-pipeline/src/sidecar.rs#L2282), [`core/dr-pipeline/src/sidecar.rs:860`](../../core/dr-pipeline/src/sidecar.rs#L860), [`ui/dr-ui/src/merge.rs:849`](../../ui/dr-ui/src/merge.rs#L849) | @@ -135,7 +135,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/scan.rs:126`](../../ui/dr-ui/src/library/scan.rs#L126), [`ui/dr-ui/src/library/scan.rs:179`](../../ui/dr-ui/src/library/scan.rs#L179), [`ui/dr-ui/src/library/scan.rs:210`](../../ui/dr-ui/src/library/scan.rs#L210), [`ui/dr-ui/src/library/scan.rs:629`](../../ui/dr-ui/src/library/scan.rs#L629), [`ui/dr-ui/src/library_ui/controller.rs:339`](../../ui/dr-ui/src/library_ui/controller.rs#L339), [`ui/dr-ui/src/library_ui/controller.rs:586`](../../ui/dr-ui/src/library_ui/controller.rs#L586), [`ui/dr-ui/src/library_ui/offline.rs:569`](../../ui/dr-ui/src/library_ui/offline.rs#L569), [`ui/dr-ui/src/library_ui/open.rs:426`](../../ui/dr-ui/src/library_ui/open.rs#L426), [`ui/dr-ui/src/library_ui/open.rs:533`](../../ui/dr-ui/src/library_ui/open.rs#L533) | | 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: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/render.rs:559`](../../ui/dr-ui/src/develop/render.rs#L559), [`ui/dr-ui/src/identity_ui.rs:125`](../../ui/dr-ui/src/identity_ui.rs#L125), [`ui/dr-ui/src/lib.rs:1212`](../../ui/dr-ui/src/lib.rs#L1212), [`ui/dr-ui/src/lib.rs:1597`](../../ui/dr-ui/src/lib.rs#L1597), [`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:1322`](../../core/dr-gpu/src/adjust.rs#L1322), [`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/render.rs:559`](../../ui/dr-ui/src/develop/render.rs#L559), [`ui/dr-ui/src/identity_ui.rs:125`](../../ui/dr-ui/src/identity_ui.rs#L125), [`ui/dr-ui/src/lib.rs:1212`](../../ui/dr-ui/src/lib.rs#L1212), [`ui/dr-ui/src/lib.rs:1597`](../../ui/dr-ui/src/lib.rs#L1597), [`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:441`](../../apps/darkroom-android/src/lib.rs#L441) | | 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:1383`](../../ui/dr-ui/src/lib.rs#L1383), [`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) | @@ -146,7 +146,7 @@ _None._ | FR-RAW-2 | [`core/dr-decode/src/decoder.rs:1`](../../core/dr-decode/src/decoder.rs#L1), [`core/dr-decode/src/decoder.rs:26`](../../core/dr-decode/src/decoder.rs#L26), [`core/dr-decode/src/decoder.rs:59`](../../core/dr-decode/src/decoder.rs#L59), [`core/dr-decode/src/decoder.rs:95`](../../core/dr-decode/src/decoder.rs#L95), [`ui/dr-ui/src/decoder_seam.rs:184`](../../ui/dr-ui/src/decoder_seam.rs#L184), [`ui/dr-ui/src/decoder_seam.rs:1`](../../ui/dr-ui/src/decoder_seam.rs#L1), [`ui/dr-ui/src/decoder_seam.rs:215`](../../ui/dr-ui/src/decoder_seam.rs#L215), [`ui/dr-ui/src/decoder_seam.rs:256`](../../ui/dr-ui/src/decoder_seam.rs#L256), [`ui/dr-ui/src/export.rs:520`](../../ui/dr-ui/src/export.rs#L520), [`ui/dr-ui/src/export.rs:757`](../../ui/dr-ui/src/export.rs#L757), [`ui/dr-ui/src/import.rs:95`](../../ui/dr-ui/src/import.rs#L95), [`ui/dr-ui/src/library/sweep.rs:279`](../../ui/dr-ui/src/library/sweep.rs#L279), [`ui/dr-ui/src/library/sweep.rs:601`](../../ui/dr-ui/src/library/sweep.rs#L601), [`ui/dr-ui/src/library/thumbnails_gen.rs:100`](../../ui/dr-ui/src/library/thumbnails_gen.rs#L100), [`ui/dr-ui/src/merge.rs:105`](../../ui/dr-ui/src/merge.rs#L105), [`ui/dr-ui/src/repairs.rs:242`](../../ui/dr-ui/src/repairs.rs#L242) | | FR-RAW-3 | [`core/dr-decode/src/lib.rs:161`](../../core/dr-decode/src/lib.rs#L161), [`core/dr-decode/src/lib.rs:552`](../../core/dr-decode/src/lib.rs#L552), [`core/dr-decode/src/locate.rs:1435`](../../core/dr-decode/src/locate.rs#L1435) | | FR-RAW-4 | [`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), [`ui/dr-ui/src/lib.rs:285`](../../ui/dr-ui/src/lib.rs#L285) | -| FR-RAW-5 | [`core/dr-decode/src/lib.rs:189`](../../core/dr-decode/src/lib.rs#L189), [`core/dr-gpu/src/demosaic.rs:34`](../../core/dr-gpu/src/demosaic.rs#L34), [`core/dr-gpu/src/demosaic.rs:734`](../../core/dr-gpu/src/demosaic.rs#L734), [`core/dr-gpu/src/demosaic.rs:813`](../../core/dr-gpu/src/demosaic.rs#L813), [`core/dr-gpu/src/demosaic.rs:937`](../../core/dr-gpu/src/demosaic.rs#L937) | +| FR-RAW-5 | [`core/dr-decode/src/lib.rs:189`](../../core/dr-decode/src/lib.rs#L189), [`core/dr-gpu/src/demosaic.rs:34`](../../core/dr-gpu/src/demosaic.rs#L34), [`core/dr-gpu/src/demosaic.rs:758`](../../core/dr-gpu/src/demosaic.rs#L758), [`core/dr-gpu/src/demosaic.rs:837`](../../core/dr-gpu/src/demosaic.rs#L837), [`core/dr-gpu/src/demosaic.rs:961`](../../core/dr-gpu/src/demosaic.rs#L961) | | FR-UI-1 | [`core/dr-types/src/settings.rs:1377`](../../core/dr-types/src/settings.rs#L1377), [`core/dr-types/src/settings.rs:492`](../../core/dr-types/src/settings.rs#L492), [`core/dr-types/src/settings.rs:512`](../../core/dr-types/src/settings.rs#L512), [`ui/dr-ui/src/develop_ui.rs:204`](../../ui/dr-ui/src/develop_ui.rs#L204), [`ui/dr-ui/src/lib.rs:116`](../../ui/dr-ui/src/lib.rs#L116), [`ui/dr-ui/src/lib.rs:131`](../../ui/dr-ui/src/lib.rs#L131), [`ui/dr-ui/src/lib.rs:153`](../../ui/dr-ui/src/lib.rs#L153), [`ui/dr-ui/src/lib.rs:3194`](../../ui/dr-ui/src/lib.rs#L3194), [`ui/dr-ui/src/lib.rs:3213`](../../ui/dr-ui/src/lib.rs#L3213), [`ui/dr-ui/src/lib.rs:3240`](../../ui/dr-ui/src/lib.rs#L3240), [`ui/dr-ui/src/lib.rs:3291`](../../ui/dr-ui/src/lib.rs#L3291), [`ui/dr-ui/src/lib.rs:3324`](../../ui/dr-ui/src/lib.rs#L3324), [`ui/dr-ui/src/masks_ui.rs:1608`](../../ui/dr-ui/src/masks_ui.rs#L1608), [`ui/dr-ui/src/settings_ui.rs:179`](../../ui/dr-ui/src/settings_ui.rs#L179), [`ui/dr-ui/ui/adjust.slint:999`](../../ui/dr-ui/ui/adjust.slint#L999), [`ui/dr-ui/ui/app.slint:3018`](../../ui/dr-ui/ui/app.slint#L3018), [`ui/dr-ui/ui/app.slint:625`](../../ui/dr-ui/ui/app.slint#L625), [`ui/dr-ui/ui/app.slint:770`](../../ui/dr-ui/ui/app.slint#L770), [`ui/dr-ui/ui/identity.slint:249`](../../ui/dr-ui/ui/identity.slint#L249), [`ui/dr-ui/ui/library.slint:1442`](../../ui/dr-ui/ui/library.slint#L1442), [`ui/dr-ui/ui/settings.slint:123`](../../ui/dr-ui/ui/settings.slint#L123), [`ui/dr-ui/ui/settings.slint:612`](../../ui/dr-ui/ui/settings.slint#L612), [`ui/dr-ui/ui/toolrail.slint:156`](../../ui/dr-ui/ui/toolrail.slint#L156), [`ui/dr-ui/ui/toolrail.slint:89`](../../ui/dr-ui/ui/toolrail.slint#L89) | | FR-UI-2 | [`ui/dr-ui/src/collections_ui/controller.rs:45`](../../ui/dr-ui/src/collections_ui/controller.rs#L45), [`ui/dr-ui/src/collections_ui/controller.rs:83`](../../ui/dr-ui/src/collections_ui/controller.rs#L83), [`ui/dr-ui/src/collections_ui/drag.rs:246`](../../ui/dr-ui/src/collections_ui/drag.rs#L246), [`ui/dr-ui/src/collections_ui/drag.rs:256`](../../ui/dr-ui/src/collections_ui/drag.rs#L256), [`ui/dr-ui/src/collections_ui/press.rs:453`](../../ui/dr-ui/src/collections_ui/press.rs#L453), [`ui/dr-ui/src/collections_ui/wiring_grid.rs:121`](../../ui/dr-ui/src/collections_ui/wiring_grid.rs#L121), [`ui/dr-ui/src/collections_ui/wiring_grid.rs:138`](../../ui/dr-ui/src/collections_ui/wiring_grid.rs#L138), [`ui/dr-ui/src/collections_ui/wiring_grid.rs:415`](../../ui/dr-ui/src/collections_ui/wiring_grid.rs#L415), [`ui/dr-ui/src/collections_ui/wiring_tree.rs:287`](../../ui/dr-ui/src/collections_ui/wiring_tree.rs#L287), [`ui/dr-ui/src/gestures.rs:1`](../../ui/dr-ui/src/gestures.rs#L1), [`ui/dr-ui/src/lib.rs:116`](../../ui/dr-ui/src/lib.rs#L116), [`ui/dr-ui/src/library_ui/filter_bar.rs:351`](../../ui/dr-ui/src/library_ui/filter_bar.rs#L351), [`ui/dr-ui/src/library_ui/window.rs:981`](../../ui/dr-ui/src/library_ui/window.rs#L981), [`ui/dr-ui/ui/app.slint:128`](../../ui/dr-ui/ui/app.slint#L128), [`ui/dr-ui/ui/app.slint:3397`](../../ui/dr-ui/ui/app.slint#L3397), [`ui/dr-ui/ui/app.slint:754`](../../ui/dr-ui/ui/app.slint#L754), [`ui/dr-ui/ui/collections.slint:1281`](../../ui/dr-ui/ui/collections.slint#L1281), [`ui/dr-ui/ui/controls.slint:626`](../../ui/dr-ui/ui/controls.slint#L626), [`ui/dr-ui/ui/gestures.slint:1`](../../ui/dr-ui/ui/gestures.slint#L1), [`ui/dr-ui/ui/library.slint:1329`](../../ui/dr-ui/ui/library.slint#L1329), [`ui/dr-ui/ui/library.slint:1362`](../../ui/dr-ui/ui/library.slint#L1362), [`ui/dr-ui/ui/library.slint:1686`](../../ui/dr-ui/ui/library.slint#L1686), [`ui/dr-ui/ui/library.slint:1693`](../../ui/dr-ui/ui/library.slint#L1693), [`ui/dr-ui/ui/library.slint:1794`](../../ui/dr-ui/ui/library.slint#L1794), [`ui/dr-ui/ui/library.slint:3129`](../../ui/dr-ui/ui/library.slint#L3129), [`ui/dr-ui/ui/library.slint:567`](../../ui/dr-ui/ui/library.slint#L567), [`ui/dr-ui/ui/presets.slint:19`](../../ui/dr-ui/ui/presets.slint#L19), [`ui/dr-ui/ui/settings.slint:137`](../../ui/dr-ui/ui/settings.slint#L137) | | FR-UI-3 | [`ui/dr-ui/src/collections_ui/controller.rs:138`](../../ui/dr-ui/src/collections_ui/controller.rs#L138), [`ui/dr-ui/src/collections_ui/controller.rs:343`](../../ui/dr-ui/src/collections_ui/controller.rs#L343), [`ui/dr-ui/src/collections_ui/controller.rs:356`](../../ui/dr-ui/src/collections_ui/controller.rs#L356), [`ui/dr-ui/src/collections_ui/wiring_tree.rs:287`](../../ui/dr-ui/src/collections_ui/wiring_tree.rs#L287), [`ui/dr-ui/src/develop/masks.rs:361`](../../ui/dr-ui/src/develop/masks.rs#L361), [`ui/dr-ui/src/develop/repairs.rs:49`](../../ui/dr-ui/src/develop/repairs.rs#L49), [`ui/dr-ui/src/library_ui/grid.rs:218`](../../ui/dr-ui/src/library_ui/grid.rs#L218), [`ui/dr-ui/src/masks_ui.rs:1700`](../../ui/dr-ui/src/masks_ui.rs#L1700), [`ui/dr-ui/src/masks_ui.rs:1722`](../../ui/dr-ui/src/masks_ui.rs#L1722), [`ui/dr-ui/src/masks_ui.rs:339`](../../ui/dr-ui/src/masks_ui.rs#L339), [`ui/dr-ui/src/spots_ui.rs:19`](../../ui/dr-ui/src/spots_ui.rs#L19), [`ui/dr-ui/ui/app.slint:2222`](../../ui/dr-ui/ui/app.slint#L2222), [`ui/dr-ui/ui/collections.slint:1155`](../../ui/dr-ui/ui/collections.slint#L1155), [`ui/dr-ui/ui/collections.slint:4`](../../ui/dr-ui/ui/collections.slint#L4), [`ui/dr-ui/ui/collections.slint:76`](../../ui/dr-ui/ui/collections.slint#L76), [`ui/dr-ui/ui/collections.slint:905`](../../ui/dr-ui/ui/collections.slint#L905), [`ui/dr-ui/ui/masks.slint:1246`](../../ui/dr-ui/ui/masks.slint#L1246), [`ui/dr-ui/ui/widgets.slint:72`](../../ui/dr-ui/ui/widgets.slint#L72) | @@ -168,7 +168,7 @@ _None._ | NFR-P13 | [`core/dr-decode/src/preview.rs:121`](../../core/dr-decode/src/preview.rs#L121) | | NFR-P14 | [`core/dr-gpu/src/focus.rs:186`](../../core/dr-gpu/src/focus.rs#L186), [`core/dr-gpu/src/focus.rs:1`](../../core/dr-gpu/src/focus.rs#L1), [`core/dr-gpu/src/focus.rs:317`](../../core/dr-gpu/src/focus.rs#L317), [`core/dr-gpu/src/shaders/focus_peak.wgsl:1`](../../core/dr-gpu/src/shaders/focus_peak.wgsl#L1), [`ui/dr-ui/src/develop/render.rs:409`](../../ui/dr-ui/src/develop/render.rs#L409), [`ui/dr-ui/src/lib.rs:2348`](../../ui/dr-ui/src/lib.rs#L2348) | | NFR-P3 | [`tools/bench/src/thumbnails.rs:1`](../../tools/bench/src/thumbnails.rs#L1) | -| NFR-P5 | [`core/dr-catalog/src/schema.rs:591`](../../core/dr-catalog/src/schema.rs#L591), [`ui/dr-ui/src/library/cells.rs:382`](../../ui/dr-ui/src/library/cells.rs#L382), [`ui/dr-ui/src/library/cells.rs:708`](../../ui/dr-ui/src/library/cells.rs#L708), [`ui/dr-ui/src/library_ui/controller.rs:58`](../../ui/dr-ui/src/library_ui/controller.rs#L58), [`ui/dr-ui/src/library_ui/timeline.rs:382`](../../ui/dr-ui/src/library_ui/timeline.rs#L382) | +| NFR-P5 | [`core/dr-catalog/src/schema.rs:591`](../../core/dr-catalog/src/schema.rs#L591), [`core/dr-gpu/src/adjust.rs:176`](../../core/dr-gpu/src/adjust.rs#L176), [`core/dr-gpu/src/adjust.rs:2931`](../../core/dr-gpu/src/adjust.rs#L2931), [`ui/dr-ui/src/library/cells.rs:382`](../../ui/dr-ui/src/library/cells.rs#L382), [`ui/dr-ui/src/library/cells.rs:708`](../../ui/dr-ui/src/library/cells.rs#L708), [`ui/dr-ui/src/library_ui/controller.rs:58`](../../ui/dr-ui/src/library_ui/controller.rs#L58), [`ui/dr-ui/src/library_ui/timeline.rs:382`](../../ui/dr-ui/src/library_ui/timeline.rs#L382) | | NFR-P9 | [`core/dr-catalog/src/schema.rs:944`](../../core/dr-catalog/src/schema.rs#L944), [`core/dr-face/src/references.rs:1`](../../core/dr-face/src/references.rs#L1), [`ui/dr-ui/src/collections_ui/mod.rs:1`](../../ui/dr-ui/src/collections_ui/mod.rs#L1), [`ui/dr-ui/src/export.rs:1024`](../../ui/dr-ui/src/export.rs#L1024), [`ui/dr-ui/src/library/mod.rs:1`](../../ui/dr-ui/src/library/mod.rs#L1), [`ui/dr-ui/src/library_ui/mod.rs:1`](../../ui/dr-ui/src/library_ui/mod.rs#L1), [`ui/dr-ui/src/trash.rs:1`](../../ui/dr-ui/src/trash.rs#L1) | | NFR-PORT-1 | [`core/dr-catalog/src/walk.rs:1`](../../core/dr-catalog/src/walk.rs#L1), [`core/dr-types/src/lib.rs:272`](../../core/dr-types/src/lib.rs#L272), [`core/dr-types/src/lib.rs:305`](../../core/dr-types/src/lib.rs#L305), [`platform/dr-plat/src/dirs.rs:1`](../../platform/dr-plat/src/dirs.rs#L1), [`platform/dr-plat/src/display.rs:1`](../../platform/dr-plat/src/display.rs#L1), [`platform/dr-plat/src/storage.rs:1`](../../platform/dr-plat/src/storage.rs#L1), [`platform/dr-plat/src/storage.rs:216`](../../platform/dr-plat/src/storage.rs#L216), [`platform/dr-plat/src/storage.rs:287`](../../platform/dr-plat/src/storage.rs#L287), [`platform/dr-plat/src/storage.rs:344`](../../platform/dr-plat/src/storage.rs#L344), [`platform/dr-plat/src/volumes.rs:1`](../../platform/dr-plat/src/volumes.rs#L1), [`platform/dr-plat/src/volumes.rs:62`](../../platform/dr-plat/src/volumes.rs#L62) | | NFR-PORT-2 | [`core/dr-gpu/src/lib.rs:1`](../../core/dr-gpu/src/lib.rs#L1) | @@ -181,7 +181,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: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/render.rs:559`](../../ui/dr-ui/src/develop/render.rs#L559), [`ui/dr-ui/src/identity_ui.rs:125`](../../ui/dr-ui/src/identity_ui.rs#L125), [`ui/dr-ui/src/lib.rs:108`](../../ui/dr-ui/src/lib.rs#L108), [`ui/dr-ui/src/memory.rs:1`](../../ui/dr-ui/src/memory.rs#L1) | +| NFR-RES-1 | [`core/dr-gpu/src/adjust.rs:1322`](../../core/dr-gpu/src/adjust.rs#L1322), [`core/dr-pipeline/src/history.rs:86`](../../core/dr-pipeline/src/history.rs#L86), [`ui/dr-ui/src/develop/render.rs:559`](../../ui/dr-ui/src/develop/render.rs#L559), [`ui/dr-ui/src/identity_ui.rs:125`](../../ui/dr-ui/src/identity_ui.rs#L125), [`ui/dr-ui/src/lib.rs:108`](../../ui/dr-ui/src/lib.rs#L108), [`ui/dr-ui/src/memory.rs:1`](../../ui/dr-ui/src/memory.rs#L1) | | NFR-RES-2 | [`ui/dr-ui/src/faces.rs:462`](../../ui/dr-ui/src/faces.rs#L462), [`ui/dr-ui/src/library/sweep.rs:242`](../../ui/dr-ui/src/library/sweep.rs#L242), [`ui/dr-ui/src/repairs.rs:1149`](../../ui/dr-ui/src/repairs.rs#L1149), [`ui/dr-ui/src/repairs.rs:1`](../../ui/dr-ui/src/repairs.rs#L1) | | 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:1209`](../../core/dr-catalog/src/schema.rs#L1209), [`core/dr-gpu/src/lib.rs:95`](../../core/dr-gpu/src/lib.rs#L95), [`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:393`](../../core/dr-thumbs/src/lib.rs#L393) | | 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) |