//! TRACES: FR-DEV-3g //! The learned denoise's settings: whether to use it, and how much grain to //! keep. //! //! Not an [`crate::operation::Operation`]: the learned stage replaces the //! demosaic and runs once per photograph, off the render path //! (docs/dev/denoise.md §2, §7), and the grain is a blend of its result with //! the classical one, done where the source is chosen. But what a //! photographer sets travels the one road every setting travels — the //! capability list feeds the panel, [`crate::Preset`] captures it, the //! sidecar stores it, the undo stack replays it (FR-DEV-3c) — so it is //! published as a capability, like the lens profile switch. use std::sync::{Arc, LazyLock}; use crate::descriptor::{Attribute, LocalizedKey, OpDescriptor, ParamDescriptor, Scale, Unit}; use crate::{OpId, ParamId}; pub const ID: OpId = OpId("learned_denoise"); pub const APPLY: ParamId = ParamId("apply"); /// TRACES: FR-DEV-3g /// How strongly to denoise, 0–100: 100 is the network's result as it is, and /// lower puts the removed noise's brightness back as grain. pub const STRENGTH: ParamId = ParamId("strength"); /// What 0.21.0 stored instead of [`STRENGTH`]: the grain kept, its inverse. /// Still read, so an edit saved by that release keeps its look; never /// written, and not offered as a control. pub const GRAIN: ParamId = ParamId("grain"); /// On by default, at full strength: every Bayer raw is developed from the /// learned demosaic, and the switch and the slider are there to take it back /// or ease it off. It costs seconds per photograph the first time, while /// the classical demosaic shows; the result is cached, so a photograph /// reopened or exported does not pay again (docs/dev/denoise.md §7). pub(crate) static DESCRIPTOR: LazyLock> = LazyLock::new(|| { Arc::new(OpDescriptor { id: ID, label: LocalizedKey("op.learned_denoise"), params: vec![ ParamDescriptor::switch_on("apply", "param.learned_denoise.apply"), ParamDescriptor::scalar( "strength", "param.learned_denoise.strength", 0.0, 100.0, 100.0, Unit::Percent, Scale::Linear, 0, ), ], // With the classical noise reduction, which is what a photographer // looks for it beside. attributes: vec![Attribute::Detail], }) }); pub fn descriptor() -> Arc { DESCRIPTOR.clone() }