Merge remote-tracking branch 'origin/master' into worktree-spot-removal
🐳 Android image / Build and push (push) Successful in 2s
Build and test / android-image (push) Successful in 2s
Build and test / Desktop (Linux) (push) Successful in 20m9s
Build and test / Layer separation (push) Successful in 39s
Traceability / Requirement traces (push) Successful in 26s
Build and test / Android (aarch64) (push) Failing after 33m10s

# Conflicts:
#	docs/traceability.md
This commit is contained in:
2026-08-26 21:56:32 +02:00
7 changed files with 582 additions and 24 deletions
+28
View File
@@ -37,6 +37,23 @@ pub const ID: OpId = OpId("film_sim");
pub const EXPOSURE: ParamId = ParamId("exposure");
pub const PRINT_EXPOSURE: ParamId = ParamId("print_exposure");
pub const PUSH: ParamId = ParamId("push");
pub const FORMAT: ParamId = ParamId("format");
/// TRACES: FR-DEV-3f
/// The frames a photograph can be simulated on, smallest first.
///
/// A genuinely fixed list, unlike the stocks: nobody invents a film format, so
/// this is a declared `enum` parameter and gets its control, its place in the
/// sidecar and its undo step for free. The *sizes* live in `dr_film::Format`;
/// this crate carries only the names, in the same order.
static FORMATS: [LocalizedKey; 6] = [
LocalizedKey("param.film_sim.format.35mm"),
LocalizedKey("param.film_sim.format.645"),
LocalizedKey("param.film_sim.format.6x6"),
LocalizedKey("param.film_sim.format.6x7"),
LocalizedKey("param.film_sim.format.4x5"),
LocalizedKey("param.film_sim.format.8x10"),
];
/// How many samples a characteristic curve carries.
///
@@ -70,6 +87,13 @@ static DESCRIPTOR: OpDescriptor = OpDescriptor {
// actually published: Double-X's measured axis spans about -1 to +2,
// and beyond a range like that a curve would have to be invented.
ParamDescriptor::stops("push", "param.film_sim.push", -1.0, 3.0),
// TRACES: FR-DEV-3f
// Which frame this was taken on — the half of the enlargement a
// photograph cannot supply. A crystal is a fixed size in micrometres,
// so how grainy a picture looks is film size against output size, and
// the same emulsion on 4x5 renders about three times smoother than on
// 35mm at the same print.
ParamDescriptor::choice("format", "param.film_sim.format", &FORMATS),
],
};
@@ -129,6 +153,8 @@ pub struct FilmSim {
exposure: f32,
print_exposure: f32,
push: f32,
/// Index into `FORMATS`. Zero is 35 mm, which is the neutral choice.
format: f32,
tables: Option<FilmTables>,
}
@@ -173,6 +199,7 @@ impl Operation for FilmSim {
EXPOSURE => self.exposure = value,
PRINT_EXPOSURE => self.print_exposure = value,
PUSH => self.push = value,
FORMAT => self.format = value,
_ => log::warn!("film_sim: unknown parameter {id}"),
}
}
@@ -182,6 +209,7 @@ impl Operation for FilmSim {
EXPOSURE => self.exposure,
PRINT_EXPOSURE => self.print_exposure,
PUSH => self.push,
FORMAT => self.format,
_ => 0.0,
}
}