Let the develop example render the profile off, the look doubled, or a preset

Diagnostic only. "matrix" switches the camera profile off and
"look200" doubles its look, so a DNG's tables can be judged against
the matrix render; "preset:<name>" applies a shipped preset as the
menu does. The example now renders through render_detailed, the path
every frontend takes, because a preset with clarity in it composes a
detail stage that plain render refuses.
This commit is contained in:
2026-10-02 22:38:07 -04:00
parent cb7ad0bbe7
commit 65c1f1a468
+39 -3
View File
@@ -24,7 +24,7 @@ fn main() {
let mut args = std::env::args().skip(1);
let Some(input) = args.next() else {
eprintln!("usage: develop <file.cr2> [out.ppm] [preset]");
eprintln!(" preset: neutral (default) | punchy | recover");
eprintln!(" preset: neutral (default) | matrix | look200 | punchy | recover | …");
std::process::exit(2);
};
let output = args.next().unwrap_or_else(|| "develop.ppm".into());
@@ -78,6 +78,24 @@ fn main() {
graph.set_param(brilliance::ID, brilliance::BRILLIANCE, 40.0);
graph.set_param(white_balance::ID, white_balance::TEMPERATURE, 15.0);
}
// The camera profile switched off: the matrix alone, as every
// photograph rendered before D20. Beside "neutral" on a DNG that
// embeds a profile, the difference is the profile's tables.
"matrix" => {
graph.set_param(
dr_pipeline::ops::camera_profile::ID,
dr_pipeline::ops::camera_profile::APPLY,
0.0,
);
}
// The profile's look table at twice its strength.
"look200" => {
graph.set_param(
dr_pipeline::ops::camera_profile::ID,
dr_pipeline::ops::camera_profile::LOOK,
200.0,
);
}
// Contrast alone, so its effect can be judged without anything else
// moving.
"contrast" => {
@@ -109,6 +127,14 @@ fn main() {
graph.set_param(curve::ID, curve::P0_Y, 0.12);
graph.set_param(curve::ID, curve::P1_Y, 0.32);
}
// A shipped preset by name — `preset:Vivid landscape` — applied as
// the presets menu applies it, so a look can be judged on a real file.
named if named.starts_with("preset:") => {
let name = &named["preset:".len()..];
let preset = dr_pipeline::bundled::lookup(&Default::default(), name)
.unwrap_or_else(|| panic!("no shipped preset called {name:?}"));
let _ = preset.apply(&mut graph, dr_pipeline::Scope::adjustments());
}
_ => {}
}
@@ -123,8 +149,15 @@ fn main() {
let mut adjust = AdjustPass::new(&ctx);
let (w, h) = image.size();
// Through the detail stage when the edit has one — clarity, sharpening
// — which is the path every frontend takes; `render` alone refuses such
// a shader.
let t2 = std::time::Instant::now();
adjust.render(&image, &shader, w, h).expect("adjust");
let detail = graph.compose_detail(image.size(), (w, h));
let key = graph.invalidation().through(dr_pipeline::Affects::Colour);
adjust
.render_detailed(&image, &shader, w, h, None, &detail, key)
.expect("adjust");
ctx.device
.poll(wgpu::PollType::wait_indefinitely())
.expect("poll");
@@ -134,8 +167,11 @@ fn main() {
// path, and it must not recompile.
graph.set_param(exposure::ID, exposure::EXPOSURE, 0.31);
let again = graph.compose();
let key = graph.invalidation().through(dr_pipeline::Affects::Colour);
let t3 = std::time::Instant::now();
adjust.render(&image, &again, w, h).expect("adjust");
adjust
.render_detailed(&image, &again, w, h, None, &detail, key)
.expect("adjust");
ctx.device
.poll(wgpu::PollType::wait_indefinitely())
.expect("poll");