Look the lens up and say plainly whether one was found
`dr-lens` has held a complete Lensfun lookup — distortion, TCA and vignetting coefficients from a lens name, a focal length and an aperture — with no dependents anywhere in the workspace. The three corrections it feeds now exist in the graph, so this connects the two and finishes the chain. The coefficient structs stay duplicated. `dr-pipeline` is organised around having no dependencies so its codegen is testable without a device or a database (ARCH §6.5a), and `dr-lens` carries an XML parser and 5.5 MB of profile data. Neither crate can convert to the other, so the conversion goes above both, in `develop.rs`, which is the only place that sees them together. Both traits grow the same defaulted door. The optical corrections do not sit on the same side of the fetch — distortion and CA rewrite coordinates and are `Warp`s, vignetting applies a gain to the pixel already there and is an ordinary node — and fanning a profile out by which trait each happens to implement would make the caller reason about that distinction. Each correction takes its own share of the whole profile instead, and `set_lens_profile` walks both lists identically. The lookup happens in `set_source_metadata` rather than in its caller, because that is the one place a session is told which file it came from. Doing it there makes it unforgettable, in the shape `FilmRebake` already uses for the other derived thing — and, more to the point, makes *clearing* unforgettable: a session that opened a second photograph while still holding the first one's profile would correct it for the wrong optics, invisibly, in a way that looks exactly like the lens. It needs the whole shot and not just a name. Distortion is interpolated across a zoom's focal range and vignetting depends strongly on aperture — a fast prime can be two stops down in the corners wide open and clean by f/8 — so a lookup missing either returns coefficients measured for a shot nobody took. Missing any of the three refuses rather than guesses. A profile is derived, not persisted: it comes from the file's EXIF and a database, so it is not a parameter, not in the sidecar and not undoable. What is an edit is the manual trim beside it, which each correction composes with the measurement — so a photographer can lean on it, override it, or work without one. `InfoPanel` gains a lens line, and it distinguishes three cases rather than two. `dr-lens` states the rule it exists for: an automatic correction that silently did nothing is worse than one the user can see is unavailable. A session with no header draws nothing, a header naming no lens reads "Lens not recorded", and a lens the database has never heard of reads "· no profile". Collapsing the last two would send somebody hunting for a profile that was never missing — which, for third-party and adapted glass, is the ordinary case. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -65,6 +65,12 @@ export component AppWindow inherits Window {
|
||||
// Current image, for the status strip and empty state.
|
||||
in property <string> filename: "";
|
||||
in property <string> camera: "";
|
||||
/// TRACES: FR-DEV-3
|
||||
/// The lens the file names, and whether a correction profile was found for
|
||||
/// it. Composed in Rust because the sentence depends on a database lookup
|
||||
/// this file cannot see, and because "not recorded" and "no profile" are
|
||||
/// different facts that must not be collapsed into one.
|
||||
in property <string> lens: "";
|
||||
in property <string> exposure: "";
|
||||
in property <string> dimensions: "";
|
||||
in property <int> index: 0;
|
||||
@@ -2416,6 +2422,7 @@ in property <bool> panel-visible: true;
|
||||
column := VerticalLayout {
|
||||
if !root.local-mode && !root.repairing: InfoPanel {
|
||||
camera: root.camera;
|
||||
lens: root.lens;
|
||||
exposure: root.exposure;
|
||||
dimensions: root.dimensions;
|
||||
}
|
||||
|
||||
@@ -217,6 +217,17 @@ export component StatusBar inherits Rectangle {
|
||||
// wanted, and the per-group lids only stood between the user and the controls.
|
||||
export component InfoPanel inherits Rectangle {
|
||||
in property <string> camera;
|
||||
/// TRACES: FR-DEV-3
|
||||
/// The lens, and whether it matched a correction profile.
|
||||
///
|
||||
/// Here rather than beside the optical sliders, and the reason is what the
|
||||
/// line is *for*. `dr-lens` states the rule — an automatic correction that
|
||||
/// silently did nothing is worse than one the user can see is unavailable
|
||||
/// — and the fact it reports is a fact about the file: which lens took
|
||||
/// this photograph, and whether the database has heard of it. That is the
|
||||
/// same kind of thing as the body and the exposure, and it wants reading
|
||||
/// once on opening rather than hunting for under a group filter.
|
||||
in property <string> lens;
|
||||
in property <string> exposure;
|
||||
in property <string> dimensions;
|
||||
|
||||
@@ -239,6 +250,16 @@ export component InfoPanel inherits Rectangle {
|
||||
|
||||
Label { text: root.exposure; }
|
||||
|
||||
// Dim, like the dimensions below it: this is something the file says,
|
||||
// not something the photographer chose. An empty string draws nothing
|
||||
// — a session built from pixels with no header has no lens to report,
|
||||
// and an empty row is honest where "Unknown" would be noise.
|
||||
Caption {
|
||||
text: root.lens;
|
||||
visible: root.lens != "";
|
||||
wrap: word-wrap;
|
||||
}
|
||||
|
||||
Caption { text: root.dimensions; }
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user