// Where the develop's white level comes from (src/engine/sensorWhite.ts). The // probe reads the frame instead of trusting a constant: the plane's ceiling is // 1.89-2.00x `maximum - black` and which one depends on the body, and a frame // that sat below the desaturation's 0.95 start came out tinted (Fuji X-Trans, // measured 1.892). These pin the two states it has to tell apart — a blown // plateau (spike plus gap) and a bright smooth sky (a top bin no bigger than the // ones under it) — and the fall-backs on frames with nothing to measure. // // node scripts/white-level-check.mjs import assert from 'node:assert/strict'; import { readFileSync } from 'node:fs'; import ts from 'typescript'; const src = readFileSync(new URL('../src/engine/sensorWhite.ts', import.meta.url), 'utf8'); const js = ts.transpileModule(src, { compilerOptions: { module: ts.ModuleKind.ESNext, target: ts.ScriptTarget.ES2022 }, }).outputText; const { sensorWhite } = await import(`data:text/javascript,${encodeURIComponent(js)}`); const N = 1_000_000; const MAXIMUM = 16383; const BLACK = 512; const LEGACY = 2 * (MAXIMUM - BLACK); const FLOOR = 8192; // an unremarkable mid-tone the frame is mostly made of // A frame of `N` mid-tone samples plus `counts` of them sitting in the nine bins // from top-8 up to top: counts[8] is the top bin, counts[0] the one eight below. function plane(top, counts) { const data = new Uint16Array(N); data.fill(FLOOR); let i = 0; for (let d = 0; d < 9; d++) for (let k = 0; k < counts[d]; k++) data[i++] = top - 8 + d; return data; } // The sensor's own plateau: a pile at the top with nine near-empty bins under it. assert.equal(sensorWhite(plane(30995, [1, 1, 1, 1, 1, 1, 1, 1, 3000]), MAXIMUM, BLACK), 30995, 'X-Trans plateau missed'); assert.equal(sensorWhite(plane(31779, [1, 1, 1, 1, 1, 1, 1, 1, 3000]), MAXIMUM, BLACK), 31779, 'Sony plateau missed'); // ...and the body that really does sit at twice the white level is read as such, // not as the constant it used to be. Same answer either way, which is the point: // the probe does not need to know which body it has. assert.equal(sensorWhite(plane(LEGACY, [1, 1, 1, 1, 1, 1, 1, 1, 3000]), MAXIMUM, BLACK), LEGACY); // A smooth sky fills the bins around the top far more than a clipped one does, // and its top bin is a tail, not a step: no gap, no clip, no move of the white. assert.equal( sensorWhite(plane(30995, [400, 900, 1500, 2000, 2400, 2600, 2600, 2400, 2000]), MAXIMUM, BLACK), LEGACY, 'a smooth top read as a clip' ); // A bright flat wall sits exactly on one value with a big pile — but the bins // under it are empty too, so that one IS a clip and is meant to move the white. assert.equal(sensorWhite(plane(30995, [0, 0, 0, 0, 0, 0, 0, 0, 5000]), MAXIMUM, BLACK), 30995); // Nothing to measure: a frame that never reached the plane's ceiling, and one // whose only pile is a handful of hot pixels, both stay on the fixed factor two. assert.equal(sensorWhite(plane(9000, [1, 1, 1, 1, 1, 1, 1, 1, 3000]), MAXIMUM, BLACK), LEGACY, 'an unblown frame moved the white'); assert.equal(sensorWhite(plane(30995, [0, 0, 0, 0, 0, 0, 0, 0, 5]), MAXIMUM, BLACK), LEGACY, 'hot pixels moved the white'); // A hot pixel above the plateau is not the ceiling: the window is hung off the // pile, not off the frame's largest sample. Measured on a Panasonic DMC-LX10 RW2 // — a pile of 3.1M at 13855 with one sample at 15993 over it — reading the stray // as the top left the nine bins under it empty, the frame fell back on the factor // two (7908 against its own 13855) and opened 0.8 of a stop bright with its // highlights clipped flat. const strayed = new Uint16Array(N); strayed.fill(FLOOR); for (let i = 0; i < 400_000; i++) strayed[i] = 30995; strayed[600_000] = 34000; strayed[700_000] = 32400; assert.equal(sensorWhite(strayed, MAXIMUM, BLACK), 30995, 'a stray sample above the plateau moved the white'); // The pile is a fraction of the plane, not a fixed count, so a small sensor with // the same clipping is read the same way as a large one. const small = new Uint16Array(100_000); small.fill(FLOOR); for (let i = 0; i < 40; i++) small[i] = 30995; assert.equal(sensorWhite(small, MAXIMUM, BLACK), 30995, 'a small plane moved the threshold'); console.log('white-level-check ok');