Merge: a histogram that reads the sensor, beside the one that reads the frame

FR-CULL-3's other two bullets. What existed was a display histogram
tagged FR-DSP-7, counting AdjustPass's 8-bit output with r == 255
clipping counters -- it says a highlight is gone precisely where this
requirement needs it to say the highlight is recoverable.

The new reduction runs over the demosaiced scene-linear texture on a
stops-below-saturation axis: camera-native, unbalanced, unmatrixed,
uncurved, normalised by the sensor's own black and white levels, so 1.0
is saturation by construction. Four series, and the fourth is the
brightest channel rather than luma, because a weighted sum of unbalanced
values is a number about nothing. Cached per photograph, not per frame:
nothing downstream of the demosaic can move a count.

Both readings are legitimate and answer different questions, so the
panel offers a choice rather than replacing one with the other.

ARCH 5.5 is amended to match. It specified a pre-demosaic reduction;
retaining the CFA samples costs 48 MB at 24 MP and 120 MB at 60 MP
resident on every photograph opened, whether or not anyone looks at the
histogram, on the platform ARCH 6.2 exists for. The spec now records two
reductions, why the more complete one was not worth its cost, and what
the cheaper one cannot answer: it counts pixels not photosites, it
cannot see above white, and it is measured after the CFA pattern is gone.

Verified: clippy -D warnings clean, 98 dr-gpu tests, 556 dr-ui tests.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-08-30 00:14:34 +02:00
co-authored by Claude Opus 5
10 changed files with 1793 additions and 47 deletions
+11
View File
@@ -72,6 +72,16 @@ export component AppWindow inherits Window {
/// of a draft frame is a histogram of an image nobody is reading.
in property <HistogramView> histogram;
/// The same photograph counted in the raw domain — the demosaiced
/// scene-linear texture, before white balance, the camera matrix or any
/// curve, on an axis of stops below sensor saturation.
///
/// Beside the display histogram rather than instead of it: the two answer
/// different questions and the panel offers both. Unlike the one above it
/// this is a property of the *file* and not of the render, so it survives
/// a crop, a zoom and every slider — see `raw_histogram.rs`.
in property <HistogramView> raw-histogram;
/// TRACES: FR-CULL-3
/// Focus peaking: the marks, whether they describe *this* frame, and the
/// three things the photographer chose. All of them are Rust's, because
@@ -2264,6 +2274,7 @@ in property <bool> panel-visible: true;
// answer than an honest one that is not yet scoped.
HistogramPanel {
data: root.histogram;
raw-data: root.raw-histogram;
}
Rectangle {