@photivra/engine 2.8.1 → 2.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +144 -1
- package/CITATION.cff +1 -1
- package/README.md +8 -6
- package/SECURITY.md +1 -1
- package/THIRD_PARTY.md +2 -0
- package/dist/capture/export-jpeg.d.ts +19 -0
- package/dist/capture/export-jpeg.js +190 -108
- package/dist/capture/export-jpeg.js.map +1 -1
- package/dist/capture/native-environment-lean.js +106 -12
- package/dist/capture/native-environment-lean.js.map +1 -1
- package/dist/capture/native-environment-tabulated.d.ts +37 -0
- package/dist/capture/native-environment-tabulated.js +42 -6
- package/dist/capture/native-environment-tabulated.js.map +1 -1
- package/dist/core/portable-math.d.ts +13 -0
- package/dist/core/portable-math.js +43 -0
- package/dist/core/portable-math.js.map +1 -1
- package/dist/core/version.d.ts +1 -1
- package/dist/core/version.js +1 -1
- package/dist/core/version.js.map +1 -1
- package/dist/facade/channel-response.d.ts +15 -0
- package/dist/facade/channel-response.js +33 -0
- package/dist/facade/channel-response.js.map +1 -0
- package/dist/facade/diffraction-provider.js +50 -15
- package/dist/facade/diffraction-provider.js.map +1 -1
- package/dist/facade/display-view.d.ts +75 -0
- package/dist/facade/display-view.js +471 -109
- package/dist/facade/display-view.js.map +1 -1
- package/dist/facade/expected-signal-setup.js +2 -1
- package/dist/facade/expected-signal-setup.js.map +1 -1
- package/dist/facade/expected-signal.d.ts +36 -4
- package/dist/facade/expected-signal.js +331 -43
- package/dist/facade/expected-signal.js.map +1 -1
- package/dist/facade/scene-radiance.d.ts +4 -1
- package/dist/facade/scene-radiance.js +4 -4
- package/dist/facade/scene-radiance.js.map +1 -1
- package/dist/facade/simulate-capture.d.ts +77 -5
- package/dist/facade/simulate-capture.js +232 -40
- package/dist/facade/simulate-capture.js.map +1 -1
- package/dist/facade/simulate-display-view.d.ts +25 -2
- package/dist/facade/simulate-display-view.js +55 -21
- package/dist/facade/simulate-display-view.js.map +1 -1
- package/dist/gpu/image-kernel-execution.d.ts +5 -0
- package/dist/gpu/image-kernel-execution.js +2 -2
- package/dist/gpu/image-kernel-execution.js.map +1 -1
- package/dist/index.d.ts +5 -4
- package/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/dist/optics/diffraction-psf-profile.d.ts +19 -17
- package/dist/optics/diffraction-psf-profile.js +49 -18
- package/dist/optics/diffraction-psf-profile.js.map +1 -1
- package/dist/optics/irradiance-convolution.d.ts +11 -0
- package/dist/optics/irradiance-convolution.js +64 -24
- package/dist/optics/irradiance-convolution.js.map +1 -1
- package/dist/optics/scene-to-sensor-irradiance.d.ts +13 -0
- package/dist/optics/scene-to-sensor-irradiance.js +58 -24
- package/dist/optics/scene-to-sensor-irradiance.js.map +1 -1
- package/dist/optics/sensor-aperture-rays.js +2 -1
- package/dist/optics/sensor-aperture-rays.js.map +1 -1
- package/dist/optics/sensor-environment-query.js +4 -3
- package/dist/optics/sensor-environment-query.js.map +1 -1
- package/dist/optics/site-diffraction-kernel.d.ts +16 -0
- package/dist/optics/site-diffraction-kernel.js +60 -8
- package/dist/optics/site-diffraction-kernel.js.map +1 -1
- package/dist/output/print-jpeg.d.ts +28 -1
- package/dist/output/print-jpeg.js +79 -7
- package/dist/output/print-jpeg.js.map +1 -1
- package/dist/processing/demosaic.js +114 -37
- package/dist/processing/demosaic.js.map +1 -1
- package/dist/schema/scene-radiance.d.ts +8 -0
- package/dist/schema/scene-radiance.js +28 -17
- package/dist/schema/scene-radiance.js.map +1 -1
- package/dist/sensor/environment-photo-signal.d.ts +21 -0
- package/dist/sensor/environment-photo-signal.js +68 -2
- package/dist/sensor/environment-photo-signal.js.map +1 -1
- package/dist/sensor/stochastic-seed.d.ts +12 -0
- package/dist/sensor/stochastic-seed.js +25 -0
- package/dist/sensor/stochastic-seed.js.map +1 -1
- package/docs/API_REFERENCE.md +23 -1
- package/docs/QUICK_START.md +77 -8
- package/docs/USAGE.md +30 -0
- package/docs/api/capture-export-jpeg.md +10 -0
- package/docs/api/core-version.md +1 -1
- package/docs/api/exports.json +77 -2
- package/docs/api/facade-display-view.md +50 -0
- package/docs/api/facade-scene-radiance.md +2 -1
- package/docs/api/facade-simulate-capture.md +88 -8
- package/docs/api/facade-simulate-display-view.md +23 -1
- package/docs/api/gpu-image-kernel-execution.md +5 -0
- package/docs/api/optics-diffraction-psf-profile.md +1 -1
- package/docs/api/output-print-jpeg.md +41 -0
- package/package.json +1 -1
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { type DisplayViewExpectedSignal, type DisplayViewRenderResult } from "./display-view.js";
|
|
1
|
+
import { type DisplayViewCorrectionStateKeys, type DisplayViewCorrectionStateSet, type DisplayViewExpectedSignal, type DisplayViewRenderResult } from "./display-view.js";
|
|
2
2
|
import { type DisplayViewResult, type SimulateCaptureOptions, type SimulateDisplayViewOptions } from "./simulate-capture.js";
|
|
3
|
+
export { serializeDisplayViewCorrectionStates, bindDisplayViewCorrectionStates, type DisplayViewCorrectionStateKeys, type DisplayViewCorrectionStateSet } from "./display-view.js";
|
|
3
4
|
/**
|
|
4
5
|
* The display view of a capture request: the image the real full-resolution capture (`simulateCapture(options)`) would
|
|
5
6
|
* give after it is resized to `view.width` × `view.height` by area averaging in linear light, estimated at a cost that
|
|
@@ -22,8 +23,30 @@ export interface PreparedDisplayViewRenderOptions {
|
|
|
22
23
|
* setup: use it to render one view in many regions, for example on each worker of a progressive display.
|
|
23
24
|
*/
|
|
24
25
|
export interface PreparedDisplayView {
|
|
25
|
-
/**
|
|
26
|
+
/**
|
|
27
|
+
* Renders a view of the prepared request. Renders may run concurrently; they share no state except read-only setup and the
|
|
28
|
+
* realm's AHD correction states, which never change a byte (docs/DISPLAY_VIEW.md, "AHD at low signal").
|
|
29
|
+
*/
|
|
26
30
|
render(view: SimulateDisplayViewOptions, renderOptions?: PreparedDisplayViewRenderOptions): Promise<DisplayViewResult>;
|
|
31
|
+
/**
|
|
32
|
+
* 2.10 (#447): the key of this request's AHD low-signal correction states, or null when the request has no AHD
|
|
33
|
+
* (`output.demosaic` other than "ahd"). Every input of the key is fixed when the request is prepared; two prepared views
|
|
34
|
+
* with the same key read the same states.
|
|
35
|
+
*/
|
|
36
|
+
correctionKey(): string | null;
|
|
37
|
+
/**
|
|
38
|
+
* 2.10 (#447): the grid keys of every correction state a render of `view` reads (ascending, whether or not this realm holds
|
|
39
|
+
* them), found by a render of the view's region that records the states instead of computing them. No image is returned;
|
|
40
|
+
* it costs about one render whose states are all held. Fails with an InvalidConfigurationError when the request has no AHD.
|
|
41
|
+
*/
|
|
42
|
+
collectCorrectionStates(view: SimulateDisplayViewOptions, renderOptions?: PreparedDisplayViewRenderOptions): Promise<DisplayViewCorrectionStateKeys>;
|
|
43
|
+
/**
|
|
44
|
+
* 2.10 (#447): computes the correction states of `gridKeys` (from `collectCorrectionStates`, or a share of them) as a render
|
|
45
|
+
* would, stores them in this realm's cache and returns their values, for {@link bindDisplayViewCorrectionStates} in
|
|
46
|
+
* another realm. States this realm holds are read, not computed. Yields and honours `signal` like `render`. Fails with an
|
|
47
|
+
* InvalidConfigurationError when the request has no AHD or a grid key is out of range.
|
|
48
|
+
*/
|
|
49
|
+
computeCorrectionStates(gridKeys: Int32Array, renderOptions?: PreparedDisplayViewRenderOptions): Promise<DisplayViewCorrectionStateSet>;
|
|
27
50
|
}
|
|
28
51
|
/**
|
|
29
52
|
* 2.7 (#387): resolves a {@link simulateDisplayView} request once, without a view, and returns a handle whose `render(view)`
|
|
@@ -13,9 +13,10 @@ import { buildExpectedSignalInput } from "./expected-signal-setup.js";
|
|
|
13
13
|
import { resolveSensorReadoutRegime } from "../sensor/raw-readout.js";
|
|
14
14
|
import { resolvePortableChartScene } from "./chart-scenes.js";
|
|
15
15
|
import { resolvePortableCaptureIlluminant, calculateIlluminantIrradianceScale } from "./scene-radiance.js";
|
|
16
|
-
import { ahdCandidateKernels, createDisplayViewExpectedSignal, renderDisplayView, EXACT_AREA_MEAN_MAX_PIXELS } from "./display-view.js";
|
|
16
|
+
import { ahdCandidateKernels, computeDisplayViewCorrectionStates, createDisplayViewExpectedSignal, displayViewCorrectionKey, renderDisplayView, EXACT_AREA_MEAN_MAX_PIXELS } from "./display-view.js";
|
|
17
17
|
import { runCapture, apertureNodeOffsets, bilinearPhaseProfiles, clockMs, fail, sceneIlluminantWhiteBalance, CAMERA_TO_XYZ, CHANNELS, DARK_CURRENT_ELECTRONS_PER_SECOND, FACADE_EVIDENCE, SIMULATE_CAPTURE_FACADE_VERSION, DISPLAY_VIEW_WITHOUT_VIEW, allowKeys, parseDisplayViewOption } from "./simulate-capture.js";
|
|
18
18
|
import { createHostYield } from "./host-yield.js";
|
|
19
|
+
export { serializeDisplayViewCorrectionStates, bindDisplayViewCorrectionStates } from "./display-view.js";
|
|
19
20
|
/**
|
|
20
21
|
* The display view of a capture request: the image the real full-resolution capture (`simulateCapture(options)`) would
|
|
21
22
|
* give after it is resized to `view.width` × `view.height` by area averaging in linear light, estimated at a cost that
|
|
@@ -38,22 +39,39 @@ export async function simulateDisplayView(options, view) {
|
|
|
38
39
|
*/
|
|
39
40
|
export async function prepareDisplayView(options) {
|
|
40
41
|
let frameWidth = 0, frameHeight = 0;
|
|
41
|
-
const
|
|
42
|
+
const prepared = await runCapture(options, "display-view", DISPLAY_VIEW_WITHOUT_VIEW, (context) => {
|
|
42
43
|
frameWidth = context.width;
|
|
43
44
|
frameHeight = context.height;
|
|
44
45
|
return Promise.resolve(prepareView(context));
|
|
45
46
|
});
|
|
47
|
+
/** One call's start times, cancellation (its own signal) and yielding. */
|
|
48
|
+
const runOf = (renderOptions) => {
|
|
49
|
+
const started = Date.now(), viewStarted = clockMs();
|
|
50
|
+
const signal = renderOptions === undefined ? undefined : allowKeys(renderOptions, "render options", ["signal"]).signal;
|
|
51
|
+
if (signal !== undefined && (typeof signal !== "object" || signal === null || typeof signal.aborted !== "boolean"))
|
|
52
|
+
fail("signal must be an AbortSignal.");
|
|
53
|
+
const checkAbort = () => { if (signal?.aborted)
|
|
54
|
+
fail("simulateCapture aborted."); };
|
|
55
|
+
checkAbort();
|
|
56
|
+
return { started, viewStarted, checkAbort, yieldControl: createHostYield().yieldControl };
|
|
57
|
+
};
|
|
58
|
+
const correctionOf = (caller) => prepared.correction ??
|
|
59
|
+
fail(caller + ": the prepared request has no AHD low-signal correction (it applies with output.demosaic \"ahd\").");
|
|
46
60
|
return Object.freeze({
|
|
47
61
|
async render(view, renderOptions) {
|
|
48
|
-
const
|
|
49
|
-
const
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
62
|
+
const run = runOf(renderOptions);
|
|
63
|
+
const parsed = parseDisplayViewOption(view, frameWidth, frameHeight);
|
|
64
|
+
return await prepared.render(parsed, run);
|
|
65
|
+
},
|
|
66
|
+
correctionKey() { return prepared.correction ? displayViewCorrectionKey(prepared.correction) : null; },
|
|
67
|
+
async collectCorrectionStates(view, renderOptions) {
|
|
68
|
+
const run = runOf(renderOptions), correction = correctionOf("collectCorrectionStates");
|
|
55
69
|
const parsed = parseDisplayViewOption(view, frameWidth, frameHeight);
|
|
56
|
-
return
|
|
70
|
+
return { key: displayViewCorrectionKey(correction), gridKeys: await prepared.collect(parsed, run) };
|
|
71
|
+
},
|
|
72
|
+
async computeCorrectionStates(gridKeys, renderOptions) {
|
|
73
|
+
const run = runOf(renderOptions), correction = correctionOf("computeCorrectionStates");
|
|
74
|
+
return await computeDisplayViewCorrectionStates({ ...correction, yieldControl: run.yieldControl, checkAbort: run.checkAbort }, gridKeys);
|
|
57
75
|
}
|
|
58
76
|
});
|
|
59
77
|
}
|
|
@@ -71,7 +89,7 @@ const DISPLAY_VIEW_AHD_CORRECTION_DRAWS = 2048, DISPLAY_VIEW_AHD_CORRECTION_THRE
|
|
|
71
89
|
/** Renders the display view of a resolved request (the last step of `runCapture` for "display-view"). */
|
|
72
90
|
async function renderDisplayViewResult(context, viewInternals) {
|
|
73
91
|
const viewStarted = clockMs();
|
|
74
|
-
return await prepareView(context)(context.parsedView, { started: context.started, viewStarted, checkAbort: context.checkAbort, yieldControl: context.yieldControl }, viewInternals);
|
|
92
|
+
return await prepareView(context).render(context.parsedView, { started: context.started, viewStarted, checkAbort: context.checkAbort, yieldControl: context.yieldControl }, viewInternals);
|
|
75
93
|
}
|
|
76
94
|
/**
|
|
77
95
|
* Internal (#387): the part of a display view that depends only on the request, done once (the portable illuminant, chart and
|
|
@@ -124,18 +142,33 @@ function prepareView(context) {
|
|
|
124
142
|
const matrix = [0, 1, 2].map((r) => [0, 1, 2].map((c) => toSrgb[r][0] * m[0][c] + toSrgb[r][1] * m[1][c] + toSrgb[r][2] * m[2][c]));
|
|
125
143
|
// Reach of a footprint's pixels into the scene, in sites: the demosaic (1), the largest query offset and the kernel radius.
|
|
126
144
|
const reachSites = (ahd ? 3 : 1) + Math.ceil(Math.max(0, ...offsets.map((o) => Math.max(Math.abs(o.x), Math.abs(o.y))))) + (kernels ? kernels.radius : 0);
|
|
127
|
-
|
|
145
|
+
// The inputs of the AHD correction states (fixed here, so the correction key is too; #447).
|
|
146
|
+
const gains = colour.appliedGains, clipLevel = Math.min(...colour.appliedGains), viewToneCurve = toneCurve;
|
|
147
|
+
const ahdCorrection = ahd ? { labMatrix: CAMERA_TO_XYZ.map((row) => row.map((value, c) => value * (viewGains ? viewGains[c] : 1))), drawsPerState: DISPLAY_VIEW_AHD_CORRECTION_DRAWS,
|
|
148
|
+
thresholdVariance: DISPLAY_VIEW_AHD_CORRECTION_THRESHOLD * DISPLAY_VIEW_AHD_CORRECTION_THRESHOLD } : undefined;
|
|
149
|
+
const ahdCandidates = ahd ? [0, 1, 2, 3].map((p) => ahdCandidateKernels(p % 2, Math.floor(p / 2))) : undefined;
|
|
150
|
+
/** The renderer's setup of one view (with `ahdCollect`, a collect pass), and its expected signal. */
|
|
151
|
+
const setupOf = (v, viewRegion, { checkAbort, yieldControl }, ahdCollect) => {
|
|
152
|
+
// The native columns the region's windows span, beyond one window's width: a filled band need not be wider (a speed hint).
|
|
153
|
+
const signal = createDisplayViewExpectedSignal(signalInput, Math.ceil((viewRegion.width + 2) * nativeWidth / v.width));
|
|
154
|
+
return { signal, setup: { frameWidth: width, frameHeight: height, margin, nativeWidth, nativeHeight, viewWidth: v.width, viewHeight: v.height,
|
|
155
|
+
region: viewRegion, samplesPerAxis: v.samplesPerAxis, reachSites, bitDepth: v.bitDepth, seed: noiseSeed, signal, readout, demosaic: demosaicTable,
|
|
156
|
+
...(ahdCandidates && ahdCorrection ? { candidates: ahdCandidates, ahdCorrection } : {}), ...(ahdCollect ? { ahdCollect } : {}),
|
|
157
|
+
gains, clipLevel, matrix, toneCurve: viewToneCurve, yieldControl, checkAbort } };
|
|
158
|
+
};
|
|
159
|
+
const correction = ahdCorrection ? { seed: noiseSeed, readout, gains, clipLevel, matrix, toneCurve: viewToneCurve, ahdCorrection } : undefined;
|
|
160
|
+
const collect = async (v, run) => {
|
|
161
|
+
const keys = new Set();
|
|
162
|
+
await renderDisplayView(setupOf(v, v.region ?? { x: 0, y: 0, width: v.width, height: v.height }, run, keys).setup);
|
|
163
|
+
return Int32Array.from(keys).sort();
|
|
164
|
+
};
|
|
165
|
+
const render = async (v, run, viewInternals) => {
|
|
166
|
+
const { started, viewStarted } = run;
|
|
128
167
|
const assumptions = [...context.assumptions];
|
|
129
168
|
const assume = (id, kind, value, explanation) => { assumptions.push({ id, kind, value, explanation }); };
|
|
130
|
-
const signal = createDisplayViewExpectedSignal(signalInput);
|
|
131
169
|
const viewRegion = v.region ?? { x: 0, y: 0, width: v.width, height: v.height };
|
|
132
|
-
const
|
|
133
|
-
|
|
134
|
-
...(ahd ? { candidates: [0, 1, 2, 3].map((p) => ahdCandidateKernels(p % 2, Math.floor(p / 2))),
|
|
135
|
-
ahdCorrection: { labMatrix: CAMERA_TO_XYZ.map((row) => row.map((value, c) => value * (viewGains ? viewGains[c] : 1))), drawsPerState: DISPLAY_VIEW_AHD_CORRECTION_DRAWS,
|
|
136
|
-
thresholdVariance: DISPLAY_VIEW_AHD_CORRECTION_THRESHOLD * DISPLAY_VIEW_AHD_CORRECTION_THRESHOLD } } : {}),
|
|
137
|
-
gains: colour.appliedGains, clipLevel: Math.min(...colour.appliedGains), matrix, toneCurve: toneCurve,
|
|
138
|
-
yieldControl, checkAbort });
|
|
170
|
+
const { setup, signal } = setupOf(v, viewRegion, run);
|
|
171
|
+
const rendered = await renderDisplayView(setup);
|
|
139
172
|
if (viewInternals) {
|
|
140
173
|
viewInternals.value = rendered;
|
|
141
174
|
viewInternals.signal = signal;
|
|
@@ -180,12 +213,13 @@ function prepareView(context) {
|
|
|
180
213
|
illuminant: { id: illuminant.id, description: illuminant.description, illuminanceLux }, distanceM: subjectDistanceM,
|
|
181
214
|
framedWidthM: 2 * metresPerFrameUnit, framedHeightM: 2 * metresPerFrameUnit * aspect, ...(chartReport ? { chart: chartReport } : {}), sourceSha256 },
|
|
182
215
|
diagnostics: { sampleCount: rendered.sampleCount, siteEvaluations: rendered.siteCount, sceneLookups: signal.lookups, detailPixelCount: rendered.detailPixelCount,
|
|
183
|
-
uniformPixelCount: rendered.uniformPixelCount, ahdCorrectedPixelCount: rendered.ahdCorrectedPixelCount, timingsMs: { view: viewMs, total: Date.now() - started } },
|
|
216
|
+
uniformPixelCount: rendered.uniformPixelCount, ahdCorrectedPixelCount: rendered.ahdCorrectedPixelCount, timingsMs: { view: viewMs, total: Date.now() - started }, fast: context.fastReport },
|
|
184
217
|
provenance: { scientificStatus: "approximation", cameraPresetId: preset.presetId, cameraPresetVersion: preset.presetVersion, evidence: [...FACADE_EVIDENCE, ...preset.evidence],
|
|
185
218
|
composedContracts: ["calculateEnvironmentSensorPhotoSignal", "resolveSensorReadoutRegime", "calculateSiteEffectiveSaturationCode", ...(diffraction ? ["createDiffractionLimitedPsfProfile", "resolveLensPsfConvolutionKernels"] : []),
|
|
186
219
|
...(antiAliasing ? ["resolveAntiAliasingSpatialKernel"] : []), "prepareSensorColorDevelopment", "display view estimator"],
|
|
187
220
|
limitations: ["Estimated display view of the full-resolution capture: its expected value is a stratified Monte Carlo estimate and its noise is drawn from the variance of the area mean, so it has the resized capture's statistics, not its exact pixels; not a capture and not a measurement."] },
|
|
188
221
|
assumptions: Object.freeze(assumptions.map((a) => Object.freeze(a))) });
|
|
189
222
|
};
|
|
223
|
+
return { render, collect, correction };
|
|
190
224
|
}
|
|
191
225
|
//# sourceMappingURL=simulate-display-view.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"simulate-display-view.js","sourceRoot":"","sources":["../../src/facade/simulate-display-view.ts"],"names":[],"mappings":"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","sourcesContent":["// SPDX-License-Identifier: Apache-2.0\n\n/**\n * The public entry point of the display view (`simulateDisplayView`) and its renderer. `simulate-capture.ts` resolves the\n * request (`runCapture`) and calls the renderer it is given, so a bundle that imports only `simulateCapture` or\n * `simulateIdealReference` does not contain the display view (`display-view.ts`) or the portable evaluations it uses.\n * The design and its error analysis are in docs/DISPLAY_VIEW.md.\n */\n\nimport { ENGINE_API_VERSION } from \"../core/version.js\";\nimport { resolvePortableColorTemperatureWhiteBalance, type ResolvedWhiteBalanceState } from \"../color/white-balance.js\";\nimport { resolveCaptureColorModel } from \"../color/capture-color.js\";\nimport { prepareSensorColorDevelopment } from \"../color/sensor-color-development.js\";\nimport { buildExpectedSignalInput } from \"./expected-signal-setup.js\";\nimport { resolveSensorReadoutRegime } from \"../sensor/raw-readout.js\";\nimport { resolvePortableChartScene, type ChartScene } from \"./chart-scenes.js\";\nimport { resolvePortableCaptureIlluminant, calculateIlluminantIrradianceScale } from \"./scene-radiance.js\";\nimport { ahdCandidateKernels, createDisplayViewExpectedSignal, renderDisplayView, type DisplayViewChannelReadout, type DisplayViewExpectedSignal, type DisplayViewRenderResult,\n EXACT_AREA_MEAN_MAX_PIXELS } from \"./display-view.js\";\nimport { runCapture, apertureNodeOffsets, bilinearPhaseProfiles, clockMs, fail, sceneIlluminantWhiteBalance, CAMERA_TO_XYZ, CHANNELS, DARK_CURRENT_ELECTRONS_PER_SECOND, FACADE_EVIDENCE,\n SIMULATE_CAPTURE_FACADE_VERSION, DISPLAY_VIEW_WITHOUT_VIEW, allowKeys, parseDisplayViewOption, type DisplayViewResult, type DisplayViewRunContext, type ParsedDisplayView,\n type SimulateCaptureAssumption, type SimulateCaptureOptions, type SimulateDisplayViewOptions } from \"./simulate-capture.js\";\nimport { createHostYield } from \"./host-yield.js\";\n\n/**\n * The display view of a capture request: the image the real full-resolution capture (`simulateCapture(options)`) would\n * give after it is resized to `view.width` × `view.height` by area averaging in linear light, estimated at a cost that\n * follows the display pixels, not the capture's. Optics (lens diffraction, the anti-aliasing filter, the pixel aperture)\n * act at the real pixel pitch; the colour mosaic, demosaic and development are those of the real pixels; the noise is\n * that of the average of the real pixels, demosaic correlation included; exposure, white balance and tone are the\n * capture's. The result is labelled `kind: \"display-view\"`; it is not a capture.\n * @see docs/DISPLAY_VIEW.md and docs/QUICK_START.md, \"Display view\".\n */\nexport async function simulateDisplayView(options: SimulateCaptureOptions, view: SimulateDisplayViewOptions): Promise<DisplayViewResult> {\n return await runCapture(options, \"display-view\", view, (context) => renderDisplayViewResult(context)) as DisplayViewResult;\n}\n/** Options of one {@link PreparedDisplayView} render. */\nexport interface PreparedDisplayViewRenderOptions {\n /** Aborting cancels this render only; the promise rejects with a domain error. The request's own `signal` applies to preparing only. */\n signal?: AbortSignal;\n}\n/**\n * 2.7: a display-view request resolved once (`prepareDisplayView`). `render(view)` gives the same result as\n * `simulateDisplayView(options, view)` for the prepared options, byte for byte (samples, view, exposure, scene, diagnostics\n * and assumptions; only `diagnostics.timingsMs` differ, and they cover the render only), without repeating the request's\n * setup: use it to render one view in many regions, for example on each worker of a progressive display.\n */\nexport interface PreparedDisplayView {\n /** Renders a view of the prepared request. Renders may run concurrently; they share no state except read-only setup. */\n render(view: SimulateDisplayViewOptions, renderOptions?: PreparedDisplayViewRenderOptions): Promise<DisplayViewResult>;\n}\n/**\n * 2.7 (#387): resolves a {@link simulateDisplayView} request once, without a view, and returns a handle whose `render(view)`\n * renders its views. The setup it does once (request validation, the camera, lens, scene, chart and illuminant, the channel\n * responses through the environment chain, the diffraction kernels, readout moments, demosaic tables and colour matrix) costs\n * about 0.3–1.3 s per call on a 24 MP request; a region costs only its own pixels. Errors in the request are raised here;\n * errors in the view by `render`.\n * @see docs/QUICK_START.md, \"Display view\".\n */\nexport async function prepareDisplayView(options: SimulateCaptureOptions): Promise<PreparedDisplayView> {\n let frameWidth = 0, frameHeight = 0;\n const renderPrepared = await runCapture(options, \"display-view\", DISPLAY_VIEW_WITHOUT_VIEW, (context) => {\n frameWidth = context.width; frameHeight = context.height;\n return Promise.resolve(prepareView(context));\n }) as RenderPreparedView;\n return Object.freeze({\n async render(view: SimulateDisplayViewOptions, renderOptions?: PreparedDisplayViewRenderOptions): Promise<DisplayViewResult> {\n const started = Date.now(), viewStarted = clockMs();\n const signal = renderOptions === undefined ? undefined : allowKeys(renderOptions, \"render options\", [\"signal\"]).signal as AbortSignal | undefined;\n if (signal !== undefined && (typeof signal !== \"object\" || signal === null || typeof signal.aborted !== \"boolean\")) fail(\"signal must be an AbortSignal.\");\n const checkAbort = (): void => { if (signal?.aborted) fail(\"simulateCapture aborted.\"); };\n checkAbort();\n const parsed = parseDisplayViewOption(view, frameWidth, frameHeight);\n return await renderPrepared(parsed, { started, viewStarted, checkAbort, yieldControl: createHostYield().yieldControl });\n }\n });\n}\n/**\n * Internal (not exported from the package): the display view plus its noise-free expected linear values and noise standard\n * deviations, for the validation scripts and tests.\n */\nexport async function simulateDisplayViewWithInternals(options: SimulateCaptureOptions, view: SimulateDisplayViewOptions):\n Promise<{ result: DisplayViewResult; internals: DisplayViewRenderResult; signal: DisplayViewExpectedSignal }> {\n const internals: { value?: DisplayViewRenderResult; signal?: DisplayViewExpectedSignal } = {};\n const result = await runCapture(options, \"display-view\", view, (context) => renderDisplayViewResult(context, internals)) as DisplayViewResult;\n return { result, internals: internals.value!, signal: internals.signal! };\n}\n\n/** AHD low-signal correction (display view): draws per flat-neighbourhood state, and the pixel noise (linear light) above which it applies. */\nconst DISPLAY_VIEW_AHD_CORRECTION_DRAWS = 2048, DISPLAY_VIEW_AHD_CORRECTION_THRESHOLD = 0.01;\n\ntype ViewInternals = { value?: DisplayViewRenderResult; signal?: DisplayViewExpectedSignal };\n/** What one render of a prepared view needs from its call: its start times, cancellation and yielding. */\ninterface ViewRun { started: number; viewStarted: number; checkAbort: () => void; yieldControl: () => Promise<void> }\ntype RenderPreparedView = (view: ParsedDisplayView, run: ViewRun, viewInternals?: ViewInternals) => Promise<DisplayViewResult>;\n\n/** Renders the display view of a resolved request (the last step of `runCapture` for \"display-view\"). */\nasync function renderDisplayViewResult(context: DisplayViewRunContext, viewInternals?: ViewInternals): Promise<DisplayViewResult> {\n const viewStarted = clockMs();\n return await prepareView(context)(context.parsedView!, { started: context.started, viewStarted, checkAbort: context.checkAbort, yieldControl: context.yieldControl }, viewInternals);\n}\n\n/**\n * Internal (#387): the part of a display view that depends only on the request, done once (the portable illuminant, chart and\n * white balance, the channel responses, query offsets, diffraction kernels, readout moments, demosaic tables and colour\n * matrix). The returned function renders one view from it; it keeps no state between renders (each has its own expected-\n * signal caches, lookup count and assumptions), so its results are those of separate calls.\n */\nfunction prepareView(context: DisplayViewRunContext): RenderPreparedView {\n const { ahd, antiAliasing, aspect, axisChannelResponse, boxSamples, buildProvider, callerScene, chart, chartReport, chartSize, diffraction, diffractionPsf, fNumber, focalLengthMm, focusDistanceM, height, highlightMode, illuminanceLux, illuminant, illuminantOption, imagingArea, intentOf, metresPerFrameUnit, noiseSeed, outputOptions, pitch, preset, provider, regimeByChannel, resolvedIso, sceneOption, scenePreset, shutterSeconds, subjectDistanceM, toneCurve, whiteBalanceOption, whiteBalanceState, width, margin, mode, nativeHeight, nativeWidth, sourceSha256 } = context;\n const kelvinInput = context.kelvinWhiteBalanceInput;\n const portableKelvinWhiteBalance = kelvinInput ? (): ResolvedWhiteBalanceState => resolvePortableColorTemperatureWhiteBalance(kelvinInput) : undefined;\n // The engine's illuminant formulas (Planckian, CIE A, daylight locus) evaluated with the portable power and e^x − 1, so\n // the view's radiances, irradiance scale and scene-illuminant white balance have the same bits in every JavaScript\n // engine; they differ from the capture's own by at most a few ulps (docs/DISPLAY_VIEW.md, \"Same bytes in every engine\").\n const viewIlluminant = resolvePortableCaptureIlluminant(illuminantOption), viewIrradianceScale = calculateIlluminantIrradianceScale(viewIlluminant.shape, illuminanceLux);\n const viewProvider = buildProvider(viewIlluminant, viewIrradianceScale);\n const viewWhiteBalanceState = whiteBalanceOption === \"scene-illuminant\" ? sceneIlluminantWhiteBalance(viewIlluminant) : portableKelvinWhiteBalance ? portableKelvinWhiteBalance() : whiteBalanceState;\n // The chart's materials likewise (a step wedge's geometric levels use the portable power); same geometry and order.\n const viewChart = chart ? resolvePortableChartScene({ scene: sceneOption as ChartScene, aspect: chartSize ? chartSize.heightM / chartSize.widthM : aspect }) : undefined;\n if (chart && viewChart!.materials.length !== chart.materials.length) fail(\"simulateDisplayView: the chart's materials could not be resolved portably.\");\n const { electronsPerRadiance, wavelengths, relativePerElectron } = axisChannelResponse(\"simulateDisplayView\");\n const perNode = CHANNELS.map((c) => Float64Array.from(wavelengths, (nm) => electronsPerRadiance[c].get(nm) ?? 0)) as [Float64Array, Float64Array, Float64Array];\n // The tabulated expected signal's input (#394: shared with the capture's tabulated RAW path).\n const sceneMaterials = viewChart ? viewChart.materials : callerScene?.kind === \"material-function\" ? callerScene.materials : undefined;\n const { offsets, signalInput } = buildExpectedSignalInput({ nativeWidth, nativeHeight, width, wavelengths, perNode, apertureNodes: apertureNodeOffsets(boxSamples), boxSamples,\n antiAliasing, pitch, diffraction: diffraction ? { radius: diffraction.kernelRadiusSamples, psf: diffractionPsf!.configuration.psf, profileWavelengths: diffraction.profile.axes.wavelengthNm } : undefined,\n materials: sceneMaterials && provider.chartMaterialAt ? { materialAt: provider.chartMaterialAt,\n list: [...sceneMaterials.map((m, index) => (m.kind === \"neutral\" ? { neutral: m.reflectance } : { radiance: (nm: number): number => viewProvider.materialRadiance!(index, nm) })),\n ...(chartSize ? [{ neutral: chartSize.surroundReflectance }] : [])],\n whiteRadiance: (nm: number): number => viewIrradianceScale * viewIlluminant.shape.evaluate(nm) / Math.PI } : undefined,\n radianceAt: viewProvider.radianceAt, imagingArea, focalLengthMm, focusDistanceM, subjectDistanceM, metresPerFrameUnit, caller: \"simulateDisplayView\" });\n const kernels = signalInput.kernels;\n // Readout moments per channel: normalized value k·e with variance k²·(e + σ_read²) plus the ADC quantization (1/12 code², times d² before a digital gain d).\n const readout = CHANNELS.map((channel): DisplayViewChannelReadout => {\n const { readoutProfile, regimeId } = regimeByChannel[channel];\n const resolved = resolveSensorReadoutRegime({ profile: readoutProfile as Parameters<typeof resolveSensorReadoutRegime>[0][\"profile\"], regimeId });\n const k = relativePerElectron[channel], digitalGain = resolved.regime.adc.digitalGain ?? 1, gain = resolved.regime.systemConversionGainElectronsPerCode.value;\n const codeSpan = digitalGain / (gain * k), read = resolved.combinedReadNoiseRmsElectrons;\n const quantizationCodes = digitalGain * digitalGain / 12 + (digitalGain === 1 ? 0 : 1 / 12);\n return { perElectron: k, darkElectrons: DARK_CURRENT_ELECTRONS_PER_SECOND * shutterSeconds, constantVariance: k * k * read * read + quantizationCodes / (codeSpan * codeSpan) };\n }) as [DisplayViewChannelReadout, DisplayViewChannelReadout, DisplayViewChannelReadout];\n const phases = bilinearPhaseProfiles(), demosaicTable: { dx: number; dy: number; weight: number }[][][] = [];\n for (const phase of phases) demosaicTable[phase.phaseY * 2 + phase.phaseX] = CHANNELS.map((c) => phase.profile.kernels.find((k) => k.outputChannelId === c)!.contributions\n .map((t) => ({ dx: t.offsetX, dy: t.offsetY, weight: t.weight })));\n const viewIntent = intentOf(viewWhiteBalanceState), viewGains = viewIntent ? [viewIntent.channelGains.red, viewIntent.channelGains.green, viewIntent.channelGains.blue] : null;\n const colour = prepareSensorColorDevelopment(CAMERA_TO_XYZ as unknown as Parameters<typeof prepareSensorColorDevelopment>[0], viewGains, highlightMode);\n const toSrgb = resolveCaptureColorModel().xyzToCameraRgb, m = colour.cameraToXyz;\n const matrix = [0, 1, 2].map((r) => [0, 1, 2].map((c) => toSrgb[r]![0]! * m[0]![c]! + toSrgb[r]![1]! * m[1]![c]! + toSrgb[r]![2]! * m[2]![c]!));\n // Reach of a footprint's pixels into the scene, in sites: the demosaic (1), the largest query offset and the kernel radius.\n const reachSites = (ahd ? 3 : 1) + Math.ceil(Math.max(0, ...offsets.map((o) => Math.max(Math.abs(o.x), Math.abs(o.y))))) + (kernels ? kernels.radius : 0);\n return async (v, { started, viewStarted, checkAbort, yieldControl }, viewInternals) => {\n const assumptions: SimulateCaptureAssumption[] = [...context.assumptions];\n const assume = (id: string, kind: SimulateCaptureAssumption[\"kind\"], value: unknown, explanation: string): void => { assumptions.push({ id, kind, value, explanation }); };\n const signal = createDisplayViewExpectedSignal(signalInput);\n const viewRegion = v.region ?? { x: 0, y: 0, width: v.width, height: v.height };\n const rendered = await renderDisplayView({ frameWidth: width, frameHeight: height, margin, nativeWidth, nativeHeight, viewWidth: v.width, viewHeight: v.height,\n region: viewRegion, samplesPerAxis: v.samplesPerAxis, reachSites, bitDepth: v.bitDepth, seed: noiseSeed, signal, readout, demosaic: demosaicTable,\n ...(ahd ? { candidates: [0, 1, 2, 3].map((p) => ahdCandidateKernels(p % 2, Math.floor(p / 2))),\n ahdCorrection: { labMatrix: CAMERA_TO_XYZ.map((row) => row.map((value, c) => value * (viewGains ? viewGains[c]! : 1))), drawsPerState: DISPLAY_VIEW_AHD_CORRECTION_DRAWS,\n thresholdVariance: DISPLAY_VIEW_AHD_CORRECTION_THRESHOLD * DISPLAY_VIEW_AHD_CORRECTION_THRESHOLD } } : {}),\n gains: colour.appliedGains as [number, number, number], clipLevel: Math.min(...colour.appliedGains), matrix, toneCurve: toneCurve as \"identity\" | \"positive-reinhard-per-channel\",\n yieldControl, checkAbort });\n if (viewInternals) { viewInternals.value = rendered; viewInternals.signal = signal; }\n const viewMs = clockMs() - viewStarted, scaleX = width / v.width, scaleY = height / v.height;\n assume(\"view.definition\", \"model\", { resampling: \"area-average-linear-light\", width: v.width, height: v.height, frameWidth: width, frameHeight: height, scaleX, scaleY },\n \"The image the full-resolution capture of this request would give after resizing to \" + v.width + \" × \" + v.height + \": each display pixel is the area-weighted mean, in linear light (sRGB samples decoded with the sRGB EOTF), \" +\n \"of the real output pixels its rectangle covers (\" + scaleX + \" × \" + scaleY + \" real pixels), then sRGB-encoded and rounded. The real capture's own samples are rounded to the view's bit depth before averaging.\");\n const uniformSamplesPerAxis = Math.max(1, Math.round(v.samplesPerAxis / 4));\n const siteSentence = \"the expected electrons of the real sites its demosaic reads are exact at the real pitch (the scene sampled at those sites through the pixel aperture, \" +\n \"anti-aliasing filter and diffraction kernels, with the capture's own query arithmetic, so the colour mosaic and its aliasing are the real sensor's), and the per-site clip at white, the highlight clip, the tone curve \" +\n \"and the clip to [0, 1] act on the pixel's own noise distribution, approximated as normal.\";\n // 2.8 (#393): where a footprint holds at most 25 real pixels (and at most K²), every real pixel of it is evaluated once with its exact weight.\n if (rendered.estimation === \"exact-area-mean\") {\n assume(\"view.estimation\", \"model\", { method: \"exact-area-mean-over-real-pixels\", samplesPerAxis: v.samplesPerAxis, realPixelsPerDisplayPixel: scaleX * scaleY,\n evaluatedRealPixels: rendered.sampleCount },\n \"Each display pixel's expected value is the exact area mean of the real pixels its rectangle covers: every real pixel it touches is evaluated once and weighted by its overlap with the rectangle \" +\n \"(w_j / A, summing to 1), so there is no sampling error. This applies because each rectangle holds \" + scaleX * scaleY + \" real pixels (\" + scaleX + \" × \" + scaleY + \"), at most \" + EXACT_AREA_MEAN_MAX_PIXELS + \" and at most K² = \" + v.samplesPerAxis * v.samplesPerAxis + \"; coarser views use a stratified estimate, which costs less there. \" +\n \"For each real pixel \" + siteSentence);\n } else {\n assume(\"view.estimation\", \"model\", { method: \"stratified-monte-carlo-over-real-pixels\", samplesPerAxis: v.samplesPerAxis, uniformSamplesPerAxis,\n detailPixels: rendered.detailPixelCount, uniformPixels: rendered.uniformPixelCount },\n \"Each display pixel's expected value is the mean over K × K strata of its rectangle, one seeded uniformly jittered real pixel in each, so it is unbiased; the error is zero where the rectangle is uniform \" +\n \"and falls as K^-3/2 at an edge. K = \" + v.samplesPerAxis + \" where a fixed pilot grid over the rectangle (widened by the demosaic, filter and kernel reach) or a neighbouring pixel's grid finds more than one scene value, \" +\n \"K = \" + uniformSamplesPerAxis + \" elsewhere. For each sampled pixel \" + siteSentence);\n }\n assume(\"view.noise\", \"model\", { method: \"variance-of-the-area-mean\", distribution: \"normal\" },\n \"Noise of the mean of the real pixels: the covariance of the weighted sum of independent site noises (shot, dark, read and ADC), with the demosaic correlation (B_c = Σ β², in closed form from the rectangle) and the \" +\n \"expected slopes of the clips and the tone curve (Stein's lemma); the variance the linearization misses and the real pixels' output rounding are added per pixel. One correlated normal draw per display pixel, seeded \" +\n \"by sensor.noiseSeed: the same statistics as the resized capture, not the same realization.\");\n assume(\"view.demosaic\", \"model\", ahd ? { capture: \"ahd\", view: \"ahd-candidates-with-low-signal-correction\", correctedPixels: rendered.ahdCorrectedPixelCount,\n correctionDrawsPerState: DISPLAY_VIEW_AHD_CORRECTION_DRAWS, correctionThresholdLinearStd: DISPLAY_VIEW_AHD_CORRECTION_THRESHOLD } : { capture: \"bilinear\", view: \"bilinear\" },\n ahd ? \"AHD is non-linear only in its choice between two linear candidates (green along the rows or the columns, red and blue from colour differences). The view propagates both candidates' exact linear statistics \" +\n \"and averages them. Where a sampled pixel's noise exceeds \" + DISPLAY_VIEW_AHD_CORRECTION_THRESHOLD + \" (linear light), the choice reacts to the noise and shifts the colour, so the pixel adds the mean \" +\n \"difference between the engine's AHD steps and the two candidates on \" + DISPLAY_VIEW_AHD_CORRECTION_DRAWS + \" drawn noisy flat neighbourhoods (Poisson electrons plus read and ADC noise) with its channel means, \" +\n \"computed once per state of a logarithmic grid (8 steps per octave of the channel means) and interpolated trilinearly, a control variate with no per-pixel sampling noise; \" +\n \"the flat-neighbourhood state is an approximation at edges (docs/DISPLAY_VIEW.md, validation).\" :\n \"The bilinear demosaic's linear kernels, exactly.\");\n assume(\"view.source\", \"model\", { rendering: \"srgb\", format: v.format, ignoredCaptureOutput: [\"format\", \"colorEncoding\", \"bitDepth\", \"gamutMapping\", \"jpegQuantizationStep\", \"dng\", \"metadata\", \"maximumPixels\"].filter((k) => outputOptions[k] !== undefined) },\n \"The view shows the capture's sRGB rendering (its tone curve, white balance and highlight mode); the capture's file-format options do not apply to it.\");\n return Object.freeze({ kind: \"display-view\" as const, label: \"Display view: the full-resolution capture resized to \" + v.width + \" × \" + v.height + \" (estimated); not a capture.\",\n facadeVersion: SIMULATE_CAPTURE_FACADE_VERSION, engineApiVersion: ENGINE_API_VERSION,\n image: { width: viewRegion.width, height: viewRegion.height, format: v.format, samples: rendered.samples },\n view: { width: v.width, height: v.height, frameWidth: width, frameHeight: height, scaleX, scaleY, samplesPerAxis: v.samplesPerAxis, ...(v.region ? { region: { ...v.region } } : {}) },\n exposure: { mode, settings: { fNumber, shutterSeconds, iso: resolvedIso }, ev100: Math.log2(fNumber ** 2 / shutterSeconds) },\n scene: { sceneId: chart ? \"chart:\" + chart.preset : callerScene!.sceneId, preset: scenePreset, parameters: chart ? chart.parameters : {},\n illuminant: { id: illuminant.id, description: illuminant.description, illuminanceLux }, distanceM: subjectDistanceM,\n framedWidthM: 2 * metresPerFrameUnit, framedHeightM: 2 * metresPerFrameUnit * aspect, ...(chartReport ? { chart: chartReport } : {}), sourceSha256 },\n diagnostics: { sampleCount: rendered.sampleCount, siteEvaluations: rendered.siteCount, sceneLookups: signal.lookups, detailPixelCount: rendered.detailPixelCount,\n uniformPixelCount: rendered.uniformPixelCount, ahdCorrectedPixelCount: rendered.ahdCorrectedPixelCount, timingsMs: { view: viewMs, total: Date.now() - started } },\n provenance: { scientificStatus: \"approximation\" as const, cameraPresetId: preset.presetId, cameraPresetVersion: preset.presetVersion, evidence: [...FACADE_EVIDENCE, ...preset.evidence],\n composedContracts: [\"calculateEnvironmentSensorPhotoSignal\", \"resolveSensorReadoutRegime\", \"calculateSiteEffectiveSaturationCode\", ...(diffraction ? [\"createDiffractionLimitedPsfProfile\", \"resolveLensPsfConvolutionKernels\"] : []),\n ...(antiAliasing ? [\"resolveAntiAliasingSpatialKernel\"] : []), \"prepareSensorColorDevelopment\", \"display view estimator\"],\n limitations: [\"Estimated display view of the full-resolution capture: its expected value is a stratified Monte Carlo estimate and its noise is drawn from the variance of the area mean, so it has the resized capture's statistics, not its exact pixels; not a capture and not a measurement.\"] },\n assumptions: Object.freeze(assumptions.map((a) => Object.freeze(a))) });\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"simulate-display-view.js","sourceRoot":"","sources":["../../src/facade/simulate-display-view.ts"],"names":[],"mappings":"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","sourcesContent":["// SPDX-License-Identifier: Apache-2.0\n\n/**\n * The public entry point of the display view (`simulateDisplayView`) and its renderer. `simulate-capture.ts` resolves the\n * request (`runCapture`) and calls the renderer it is given, so a bundle that imports only `simulateCapture` or\n * `simulateIdealReference` does not contain the display view (`display-view.ts`) or the portable evaluations it uses.\n * The design and its error analysis are in docs/DISPLAY_VIEW.md.\n */\n\nimport { ENGINE_API_VERSION } from \"../core/version.js\";\nimport { resolvePortableColorTemperatureWhiteBalance, type ResolvedWhiteBalanceState } from \"../color/white-balance.js\";\nimport { resolveCaptureColorModel } from \"../color/capture-color.js\";\nimport { prepareSensorColorDevelopment } from \"../color/sensor-color-development.js\";\nimport { buildExpectedSignalInput } from \"./expected-signal-setup.js\";\nimport { resolveSensorReadoutRegime } from \"../sensor/raw-readout.js\";\nimport { resolvePortableChartScene, type ChartScene } from \"./chart-scenes.js\";\nimport { resolvePortableCaptureIlluminant, calculateIlluminantIrradianceScale } from \"./scene-radiance.js\";\nimport { ahdCandidateKernels, computeDisplayViewCorrectionStates, createDisplayViewExpectedSignal, displayViewCorrectionKey, renderDisplayView, type DisplayViewChannelReadout,\n type DisplayViewCorrectionSetup, type DisplayViewCorrectionStateKeys, type DisplayViewCorrectionStateSet, type DisplayViewExpectedSignal, type DisplayViewRenderResult, type DisplayViewSetup,\n EXACT_AREA_MEAN_MAX_PIXELS } from \"./display-view.js\";\nimport { runCapture, apertureNodeOffsets, bilinearPhaseProfiles, clockMs, fail, sceneIlluminantWhiteBalance, CAMERA_TO_XYZ, CHANNELS, DARK_CURRENT_ELECTRONS_PER_SECOND, FACADE_EVIDENCE,\n SIMULATE_CAPTURE_FACADE_VERSION, DISPLAY_VIEW_WITHOUT_VIEW, allowKeys, parseDisplayViewOption, type DisplayViewResult, type DisplayViewRunContext, type ParsedDisplayView,\n type SimulateCaptureAssumption, type SimulateCaptureOptions, type SimulateDisplayViewOptions } from \"./simulate-capture.js\";\nimport { createHostYield } from \"./host-yield.js\";\n\nexport { serializeDisplayViewCorrectionStates, bindDisplayViewCorrectionStates, type DisplayViewCorrectionStateKeys, type DisplayViewCorrectionStateSet } from \"./display-view.js\";\n\n/**\n * The display view of a capture request: the image the real full-resolution capture (`simulateCapture(options)`) would\n * give after it is resized to `view.width` × `view.height` by area averaging in linear light, estimated at a cost that\n * follows the display pixels, not the capture's. Optics (lens diffraction, the anti-aliasing filter, the pixel aperture)\n * act at the real pixel pitch; the colour mosaic, demosaic and development are those of the real pixels; the noise is\n * that of the average of the real pixels, demosaic correlation included; exposure, white balance and tone are the\n * capture's. The result is labelled `kind: \"display-view\"`; it is not a capture.\n * @see docs/DISPLAY_VIEW.md and docs/QUICK_START.md, \"Display view\".\n */\nexport async function simulateDisplayView(options: SimulateCaptureOptions, view: SimulateDisplayViewOptions): Promise<DisplayViewResult> {\n return await runCapture(options, \"display-view\", view, (context) => renderDisplayViewResult(context)) as DisplayViewResult;\n}\n/** Options of one {@link PreparedDisplayView} render. */\nexport interface PreparedDisplayViewRenderOptions {\n /** Aborting cancels this render only; the promise rejects with a domain error. The request's own `signal` applies to preparing only. */\n signal?: AbortSignal;\n}\n/**\n * 2.7: a display-view request resolved once (`prepareDisplayView`). `render(view)` gives the same result as\n * `simulateDisplayView(options, view)` for the prepared options, byte for byte (samples, view, exposure, scene, diagnostics\n * and assumptions; only `diagnostics.timingsMs` differ, and they cover the render only), without repeating the request's\n * setup: use it to render one view in many regions, for example on each worker of a progressive display.\n */\nexport interface PreparedDisplayView {\n /**\n * Renders a view of the prepared request. Renders may run concurrently; they share no state except read-only setup and the\n * realm's AHD correction states, which never change a byte (docs/DISPLAY_VIEW.md, \"AHD at low signal\").\n */\n render(view: SimulateDisplayViewOptions, renderOptions?: PreparedDisplayViewRenderOptions): Promise<DisplayViewResult>;\n /**\n * 2.10 (#447): the key of this request's AHD low-signal correction states, or null when the request has no AHD\n * (`output.demosaic` other than \"ahd\"). Every input of the key is fixed when the request is prepared; two prepared views\n * with the same key read the same states.\n */\n correctionKey(): string | null;\n /**\n * 2.10 (#447): the grid keys of every correction state a render of `view` reads (ascending, whether or not this realm holds\n * them), found by a render of the view's region that records the states instead of computing them. No image is returned;\n * it costs about one render whose states are all held. Fails with an InvalidConfigurationError when the request has no AHD.\n */\n collectCorrectionStates(view: SimulateDisplayViewOptions, renderOptions?: PreparedDisplayViewRenderOptions): Promise<DisplayViewCorrectionStateKeys>;\n /**\n * 2.10 (#447): computes the correction states of `gridKeys` (from `collectCorrectionStates`, or a share of them) as a render\n * would, stores them in this realm's cache and returns their values, for {@link bindDisplayViewCorrectionStates} in\n * another realm. States this realm holds are read, not computed. Yields and honours `signal` like `render`. Fails with an\n * InvalidConfigurationError when the request has no AHD or a grid key is out of range.\n */\n computeCorrectionStates(gridKeys: Int32Array, renderOptions?: PreparedDisplayViewRenderOptions): Promise<DisplayViewCorrectionStateSet>;\n}\n/**\n * 2.7 (#387): resolves a {@link simulateDisplayView} request once, without a view, and returns a handle whose `render(view)`\n * renders its views. The setup it does once (request validation, the camera, lens, scene, chart and illuminant, the channel\n * responses through the environment chain, the diffraction kernels, readout moments, demosaic tables and colour matrix) costs\n * about 0.3–1.3 s per call on a 24 MP request; a region costs only its own pixels. Errors in the request are raised here;\n * errors in the view by `render`.\n * @see docs/QUICK_START.md, \"Display view\".\n */\nexport async function prepareDisplayView(options: SimulateCaptureOptions): Promise<PreparedDisplayView> {\n let frameWidth = 0, frameHeight = 0;\n const prepared = await runCapture(options, \"display-view\", DISPLAY_VIEW_WITHOUT_VIEW, (context) => {\n frameWidth = context.width; frameHeight = context.height;\n return Promise.resolve(prepareView(context));\n }) as PreparedViewParts;\n /** One call's start times, cancellation (its own signal) and yielding. */\n const runOf = (renderOptions: PreparedDisplayViewRenderOptions | undefined): ViewRun => {\n const started = Date.now(), viewStarted = clockMs();\n const signal = renderOptions === undefined ? undefined : allowKeys(renderOptions, \"render options\", [\"signal\"]).signal as AbortSignal | undefined;\n if (signal !== undefined && (typeof signal !== \"object\" || signal === null || typeof signal.aborted !== \"boolean\")) fail(\"signal must be an AbortSignal.\");\n const checkAbort = (): void => { if (signal?.aborted) fail(\"simulateCapture aborted.\"); };\n checkAbort();\n return { started, viewStarted, checkAbort, yieldControl: createHostYield().yieldControl };\n };\n const correctionOf = (caller: string): DisplayViewCorrectionSetup => prepared.correction ??\n fail(caller + \": the prepared request has no AHD low-signal correction (it applies with output.demosaic \\\"ahd\\\").\");\n return Object.freeze({\n async render(view: SimulateDisplayViewOptions, renderOptions?: PreparedDisplayViewRenderOptions): Promise<DisplayViewResult> {\n const run = runOf(renderOptions);\n const parsed = parseDisplayViewOption(view, frameWidth, frameHeight);\n return await prepared.render(parsed, run);\n },\n correctionKey(): string | null { return prepared.correction ? displayViewCorrectionKey(prepared.correction) : null; },\n async collectCorrectionStates(view: SimulateDisplayViewOptions, renderOptions?: PreparedDisplayViewRenderOptions): Promise<DisplayViewCorrectionStateKeys> {\n const run = runOf(renderOptions), correction = correctionOf(\"collectCorrectionStates\");\n const parsed = parseDisplayViewOption(view, frameWidth, frameHeight);\n return { key: displayViewCorrectionKey(correction)!, gridKeys: await prepared.collect(parsed, run) };\n },\n async computeCorrectionStates(gridKeys: Int32Array, renderOptions?: PreparedDisplayViewRenderOptions): Promise<DisplayViewCorrectionStateSet> {\n const run = runOf(renderOptions), correction = correctionOf(\"computeCorrectionStates\");\n return await computeDisplayViewCorrectionStates({ ...correction, yieldControl: run.yieldControl, checkAbort: run.checkAbort }, gridKeys);\n }\n });\n}\n/**\n * Internal (not exported from the package): the display view plus its noise-free expected linear values and noise standard\n * deviations, for the validation scripts and tests.\n */\nexport async function simulateDisplayViewWithInternals(options: SimulateCaptureOptions, view: SimulateDisplayViewOptions):\n Promise<{ result: DisplayViewResult; internals: DisplayViewRenderResult; signal: DisplayViewExpectedSignal }> {\n const internals: { value?: DisplayViewRenderResult; signal?: DisplayViewExpectedSignal } = {};\n const result = await runCapture(options, \"display-view\", view, (context) => renderDisplayViewResult(context, internals)) as DisplayViewResult;\n return { result, internals: internals.value!, signal: internals.signal! };\n}\n\n/** AHD low-signal correction (display view): draws per flat-neighbourhood state, and the pixel noise (linear light) above which it applies. */\nconst DISPLAY_VIEW_AHD_CORRECTION_DRAWS = 2048, DISPLAY_VIEW_AHD_CORRECTION_THRESHOLD = 0.01;\n\ntype ViewInternals = { value?: DisplayViewRenderResult; signal?: DisplayViewExpectedSignal };\n/** What one render of a prepared view needs from its call: its start times, cancellation and yielding. */\ninterface ViewRun { started: number; viewStarted: number; checkAbort: () => void; yieldControl: () => Promise<void> }\ntype RenderPreparedView = (view: ParsedDisplayView, run: ViewRun, viewInternals?: ViewInternals) => Promise<DisplayViewResult>;\n/**\n * A prepared request: its render, its collect pass (#447: the grid keys of the correction states a view's region reads) and\n * the inputs of its correction states (undefined without AHD).\n */\ninterface PreparedViewParts {\n render: RenderPreparedView;\n collect(view: ParsedDisplayView, run: ViewRun): Promise<Int32Array>;\n correction: DisplayViewCorrectionSetup | undefined;\n}\n\n/** Renders the display view of a resolved request (the last step of `runCapture` for \"display-view\"). */\nasync function renderDisplayViewResult(context: DisplayViewRunContext, viewInternals?: ViewInternals): Promise<DisplayViewResult> {\n const viewStarted = clockMs();\n return await prepareView(context).render(context.parsedView!, { started: context.started, viewStarted, checkAbort: context.checkAbort, yieldControl: context.yieldControl }, viewInternals);\n}\n\n/**\n * Internal (#387): the part of a display view that depends only on the request, done once (the portable illuminant, chart and\n * white balance, the channel responses, query offsets, diffraction kernels, readout moments, demosaic tables and colour\n * matrix). The returned function renders one view from it; it keeps no state between renders (each has its own expected-\n * signal caches, lookup count and assumptions), so its results are those of separate calls.\n */\nfunction prepareView(context: DisplayViewRunContext): PreparedViewParts {\n const { ahd, antiAliasing, aspect, axisChannelResponse, boxSamples, buildProvider, callerScene, chart, chartReport, chartSize, diffraction, diffractionPsf, fNumber, focalLengthMm, focusDistanceM, height, highlightMode, illuminanceLux, illuminant, illuminantOption, imagingArea, intentOf, metresPerFrameUnit, noiseSeed, outputOptions, pitch, preset, provider, regimeByChannel, resolvedIso, sceneOption, scenePreset, shutterSeconds, subjectDistanceM, toneCurve, whiteBalanceOption, whiteBalanceState, width, margin, mode, nativeHeight, nativeWidth, sourceSha256 } = context;\n const kelvinInput = context.kelvinWhiteBalanceInput;\n const portableKelvinWhiteBalance = kelvinInput ? (): ResolvedWhiteBalanceState => resolvePortableColorTemperatureWhiteBalance(kelvinInput) : undefined;\n // The engine's illuminant formulas (Planckian, CIE A, daylight locus) evaluated with the portable power and e^x − 1, so\n // the view's radiances, irradiance scale and scene-illuminant white balance have the same bits in every JavaScript\n // engine; they differ from the capture's own by at most a few ulps (docs/DISPLAY_VIEW.md, \"Same bytes in every engine\").\n const viewIlluminant = resolvePortableCaptureIlluminant(illuminantOption), viewIrradianceScale = calculateIlluminantIrradianceScale(viewIlluminant.shape, illuminanceLux);\n const viewProvider = buildProvider(viewIlluminant, viewIrradianceScale);\n const viewWhiteBalanceState = whiteBalanceOption === \"scene-illuminant\" ? sceneIlluminantWhiteBalance(viewIlluminant) : portableKelvinWhiteBalance ? portableKelvinWhiteBalance() : whiteBalanceState;\n // The chart's materials likewise (a step wedge's geometric levels use the portable power); same geometry and order.\n const viewChart = chart ? resolvePortableChartScene({ scene: sceneOption as ChartScene, aspect: chartSize ? chartSize.heightM / chartSize.widthM : aspect }) : undefined;\n if (chart && viewChart!.materials.length !== chart.materials.length) fail(\"simulateDisplayView: the chart's materials could not be resolved portably.\");\n const { electronsPerRadiance, wavelengths, relativePerElectron } = axisChannelResponse(\"simulateDisplayView\");\n const perNode = CHANNELS.map((c) => Float64Array.from(wavelengths, (nm) => electronsPerRadiance[c].get(nm) ?? 0)) as [Float64Array, Float64Array, Float64Array];\n // The tabulated expected signal's input (#394: shared with the capture's tabulated RAW path).\n const sceneMaterials = viewChart ? viewChart.materials : callerScene?.kind === \"material-function\" ? callerScene.materials : undefined;\n const { offsets, signalInput } = buildExpectedSignalInput({ nativeWidth, nativeHeight, width, wavelengths, perNode, apertureNodes: apertureNodeOffsets(boxSamples), boxSamples,\n antiAliasing, pitch, diffraction: diffraction ? { radius: diffraction.kernelRadiusSamples, psf: diffractionPsf!.configuration.psf, profileWavelengths: diffraction.profile.axes.wavelengthNm } : undefined,\n materials: sceneMaterials && provider.chartMaterialAt ? { materialAt: provider.chartMaterialAt,\n list: [...sceneMaterials.map((m, index) => (m.kind === \"neutral\" ? { neutral: m.reflectance } : { radiance: (nm: number): number => viewProvider.materialRadiance!(index, nm) })),\n ...(chartSize ? [{ neutral: chartSize.surroundReflectance }] : [])],\n whiteRadiance: (nm: number): number => viewIrradianceScale * viewIlluminant.shape.evaluate(nm) / Math.PI } : undefined,\n radianceAt: viewProvider.radianceAt, imagingArea, focalLengthMm, focusDistanceM, subjectDistanceM, metresPerFrameUnit, caller: \"simulateDisplayView\" });\n const kernels = signalInput.kernels;\n // Readout moments per channel: normalized value k·e with variance k²·(e + σ_read²) plus the ADC quantization (1/12 code², times d² before a digital gain d).\n const readout = CHANNELS.map((channel): DisplayViewChannelReadout => {\n const { readoutProfile, regimeId } = regimeByChannel[channel];\n const resolved = resolveSensorReadoutRegime({ profile: readoutProfile as Parameters<typeof resolveSensorReadoutRegime>[0][\"profile\"], regimeId });\n const k = relativePerElectron[channel], digitalGain = resolved.regime.adc.digitalGain ?? 1, gain = resolved.regime.systemConversionGainElectronsPerCode.value;\n const codeSpan = digitalGain / (gain * k), read = resolved.combinedReadNoiseRmsElectrons;\n const quantizationCodes = digitalGain * digitalGain / 12 + (digitalGain === 1 ? 0 : 1 / 12);\n return { perElectron: k, darkElectrons: DARK_CURRENT_ELECTRONS_PER_SECOND * shutterSeconds, constantVariance: k * k * read * read + quantizationCodes / (codeSpan * codeSpan) };\n }) as [DisplayViewChannelReadout, DisplayViewChannelReadout, DisplayViewChannelReadout];\n const phases = bilinearPhaseProfiles(), demosaicTable: { dx: number; dy: number; weight: number }[][][] = [];\n for (const phase of phases) demosaicTable[phase.phaseY * 2 + phase.phaseX] = CHANNELS.map((c) => phase.profile.kernels.find((k) => k.outputChannelId === c)!.contributions\n .map((t) => ({ dx: t.offsetX, dy: t.offsetY, weight: t.weight })));\n const viewIntent = intentOf(viewWhiteBalanceState), viewGains = viewIntent ? [viewIntent.channelGains.red, viewIntent.channelGains.green, viewIntent.channelGains.blue] : null;\n const colour = prepareSensorColorDevelopment(CAMERA_TO_XYZ as unknown as Parameters<typeof prepareSensorColorDevelopment>[0], viewGains, highlightMode);\n const toSrgb = resolveCaptureColorModel().xyzToCameraRgb, m = colour.cameraToXyz;\n const matrix = [0, 1, 2].map((r) => [0, 1, 2].map((c) => toSrgb[r]![0]! * m[0]![c]! + toSrgb[r]![1]! * m[1]![c]! + toSrgb[r]![2]! * m[2]![c]!));\n // Reach of a footprint's pixels into the scene, in sites: the demosaic (1), the largest query offset and the kernel radius.\n const reachSites = (ahd ? 3 : 1) + Math.ceil(Math.max(0, ...offsets.map((o) => Math.max(Math.abs(o.x), Math.abs(o.y))))) + (kernels ? kernels.radius : 0);\n // The inputs of the AHD correction states (fixed here, so the correction key is too; #447).\n const gains = colour.appliedGains as [number, number, number], clipLevel = Math.min(...colour.appliedGains), viewToneCurve = toneCurve as \"identity\" | \"positive-reinhard-per-channel\";\n const ahdCorrection = ahd ? { labMatrix: CAMERA_TO_XYZ.map((row) => row.map((value, c) => value * (viewGains ? viewGains[c]! : 1))), drawsPerState: DISPLAY_VIEW_AHD_CORRECTION_DRAWS,\n thresholdVariance: DISPLAY_VIEW_AHD_CORRECTION_THRESHOLD * DISPLAY_VIEW_AHD_CORRECTION_THRESHOLD } : undefined;\n const ahdCandidates = ahd ? [0, 1, 2, 3].map((p) => ahdCandidateKernels(p % 2, Math.floor(p / 2))) : undefined;\n /** The renderer's setup of one view (with `ahdCollect`, a collect pass), and its expected signal. */\n const setupOf = (v: ParsedDisplayView, viewRegion: { x: number; y: number; width: number; height: number }, { checkAbort, yieldControl }: ViewRun,\n ahdCollect?: Set<number>): { setup: DisplayViewSetup; signal: DisplayViewExpectedSignal } => {\n // The native columns the region's windows span, beyond one window's width: a filled band need not be wider (a speed hint).\n const signal = createDisplayViewExpectedSignal(signalInput, Math.ceil((viewRegion.width + 2) * nativeWidth / v.width));\n return { signal, setup: { frameWidth: width, frameHeight: height, margin, nativeWidth, nativeHeight, viewWidth: v.width, viewHeight: v.height,\n region: viewRegion, samplesPerAxis: v.samplesPerAxis, reachSites, bitDepth: v.bitDepth, seed: noiseSeed, signal, readout, demosaic: demosaicTable,\n ...(ahdCandidates && ahdCorrection ? { candidates: ahdCandidates, ahdCorrection } : {}), ...(ahdCollect ? { ahdCollect } : {}),\n gains, clipLevel, matrix, toneCurve: viewToneCurve, yieldControl, checkAbort } };\n };\n const correction: DisplayViewCorrectionSetup | undefined = ahdCorrection ? { seed: noiseSeed, readout, gains, clipLevel, matrix, toneCurve: viewToneCurve, ahdCorrection } : undefined;\n const collect = async (v: ParsedDisplayView, run: ViewRun): Promise<Int32Array> => {\n const keys = new Set<number>();\n await renderDisplayView(setupOf(v, v.region ?? { x: 0, y: 0, width: v.width, height: v.height }, run, keys).setup);\n return Int32Array.from(keys).sort();\n };\n const render: RenderPreparedView = async (v, run, viewInternals) => {\n const { started, viewStarted } = run;\n const assumptions: SimulateCaptureAssumption[] = [...context.assumptions];\n const assume = (id: string, kind: SimulateCaptureAssumption[\"kind\"], value: unknown, explanation: string): void => { assumptions.push({ id, kind, value, explanation }); };\n const viewRegion = v.region ?? { x: 0, y: 0, width: v.width, height: v.height };\n const { setup, signal } = setupOf(v, viewRegion, run);\n const rendered = await renderDisplayView(setup);\n if (viewInternals) { viewInternals.value = rendered; viewInternals.signal = signal; }\n const viewMs = clockMs() - viewStarted, scaleX = width / v.width, scaleY = height / v.height;\n assume(\"view.definition\", \"model\", { resampling: \"area-average-linear-light\", width: v.width, height: v.height, frameWidth: width, frameHeight: height, scaleX, scaleY },\n \"The image the full-resolution capture of this request would give after resizing to \" + v.width + \" × \" + v.height + \": each display pixel is the area-weighted mean, in linear light (sRGB samples decoded with the sRGB EOTF), \" +\n \"of the real output pixels its rectangle covers (\" + scaleX + \" × \" + scaleY + \" real pixels), then sRGB-encoded and rounded. The real capture's own samples are rounded to the view's bit depth before averaging.\");\n const uniformSamplesPerAxis = Math.max(1, Math.round(v.samplesPerAxis / 4));\n const siteSentence = \"the expected electrons of the real sites its demosaic reads are exact at the real pitch (the scene sampled at those sites through the pixel aperture, \" +\n \"anti-aliasing filter and diffraction kernels, with the capture's own query arithmetic, so the colour mosaic and its aliasing are the real sensor's), and the per-site clip at white, the highlight clip, the tone curve \" +\n \"and the clip to [0, 1] act on the pixel's own noise distribution, approximated as normal.\";\n // 2.8 (#393): where a footprint holds at most 25 real pixels (and at most K²), every real pixel of it is evaluated once with its exact weight.\n if (rendered.estimation === \"exact-area-mean\") {\n assume(\"view.estimation\", \"model\", { method: \"exact-area-mean-over-real-pixels\", samplesPerAxis: v.samplesPerAxis, realPixelsPerDisplayPixel: scaleX * scaleY,\n evaluatedRealPixels: rendered.sampleCount },\n \"Each display pixel's expected value is the exact area mean of the real pixels its rectangle covers: every real pixel it touches is evaluated once and weighted by its overlap with the rectangle \" +\n \"(w_j / A, summing to 1), so there is no sampling error. This applies because each rectangle holds \" + scaleX * scaleY + \" real pixels (\" + scaleX + \" × \" + scaleY + \"), at most \" + EXACT_AREA_MEAN_MAX_PIXELS + \" and at most K² = \" + v.samplesPerAxis * v.samplesPerAxis + \"; coarser views use a stratified estimate, which costs less there. \" +\n \"For each real pixel \" + siteSentence);\n } else {\n assume(\"view.estimation\", \"model\", { method: \"stratified-monte-carlo-over-real-pixels\", samplesPerAxis: v.samplesPerAxis, uniformSamplesPerAxis,\n detailPixels: rendered.detailPixelCount, uniformPixels: rendered.uniformPixelCount },\n \"Each display pixel's expected value is the mean over K × K strata of its rectangle, one seeded uniformly jittered real pixel in each, so it is unbiased; the error is zero where the rectangle is uniform \" +\n \"and falls as K^-3/2 at an edge. K = \" + v.samplesPerAxis + \" where a fixed pilot grid over the rectangle (widened by the demosaic, filter and kernel reach) or a neighbouring pixel's grid finds more than one scene value, \" +\n \"K = \" + uniformSamplesPerAxis + \" elsewhere. For each sampled pixel \" + siteSentence);\n }\n assume(\"view.noise\", \"model\", { method: \"variance-of-the-area-mean\", distribution: \"normal\" },\n \"Noise of the mean of the real pixels: the covariance of the weighted sum of independent site noises (shot, dark, read and ADC), with the demosaic correlation (B_c = Σ β², in closed form from the rectangle) and the \" +\n \"expected slopes of the clips and the tone curve (Stein's lemma); the variance the linearization misses and the real pixels' output rounding are added per pixel. One correlated normal draw per display pixel, seeded \" +\n \"by sensor.noiseSeed: the same statistics as the resized capture, not the same realization.\");\n assume(\"view.demosaic\", \"model\", ahd ? { capture: \"ahd\", view: \"ahd-candidates-with-low-signal-correction\", correctedPixels: rendered.ahdCorrectedPixelCount,\n correctionDrawsPerState: DISPLAY_VIEW_AHD_CORRECTION_DRAWS, correctionThresholdLinearStd: DISPLAY_VIEW_AHD_CORRECTION_THRESHOLD } : { capture: \"bilinear\", view: \"bilinear\" },\n ahd ? \"AHD is non-linear only in its choice between two linear candidates (green along the rows or the columns, red and blue from colour differences). The view propagates both candidates' exact linear statistics \" +\n \"and averages them. Where a sampled pixel's noise exceeds \" + DISPLAY_VIEW_AHD_CORRECTION_THRESHOLD + \" (linear light), the choice reacts to the noise and shifts the colour, so the pixel adds the mean \" +\n \"difference between the engine's AHD steps and the two candidates on \" + DISPLAY_VIEW_AHD_CORRECTION_DRAWS + \" drawn noisy flat neighbourhoods (Poisson electrons plus read and ADC noise) with its channel means, \" +\n \"computed once per state of a logarithmic grid (8 steps per octave of the channel means) and interpolated trilinearly, a control variate with no per-pixel sampling noise; \" +\n \"the flat-neighbourhood state is an approximation at edges (docs/DISPLAY_VIEW.md, validation).\" :\n \"The bilinear demosaic's linear kernels, exactly.\");\n assume(\"view.source\", \"model\", { rendering: \"srgb\", format: v.format, ignoredCaptureOutput: [\"format\", \"colorEncoding\", \"bitDepth\", \"gamutMapping\", \"jpegQuantizationStep\", \"dng\", \"metadata\", \"maximumPixels\"].filter((k) => outputOptions[k] !== undefined) },\n \"The view shows the capture's sRGB rendering (its tone curve, white balance and highlight mode); the capture's file-format options do not apply to it.\");\n return Object.freeze({ kind: \"display-view\" as const, label: \"Display view: the full-resolution capture resized to \" + v.width + \" × \" + v.height + \" (estimated); not a capture.\",\n facadeVersion: SIMULATE_CAPTURE_FACADE_VERSION, engineApiVersion: ENGINE_API_VERSION,\n image: { width: viewRegion.width, height: viewRegion.height, format: v.format, samples: rendered.samples },\n view: { width: v.width, height: v.height, frameWidth: width, frameHeight: height, scaleX, scaleY, samplesPerAxis: v.samplesPerAxis, ...(v.region ? { region: { ...v.region } } : {}) },\n exposure: { mode, settings: { fNumber, shutterSeconds, iso: resolvedIso }, ev100: Math.log2(fNumber ** 2 / shutterSeconds) },\n scene: { sceneId: chart ? \"chart:\" + chart.preset : callerScene!.sceneId, preset: scenePreset, parameters: chart ? chart.parameters : {},\n illuminant: { id: illuminant.id, description: illuminant.description, illuminanceLux }, distanceM: subjectDistanceM,\n framedWidthM: 2 * metresPerFrameUnit, framedHeightM: 2 * metresPerFrameUnit * aspect, ...(chartReport ? { chart: chartReport } : {}), sourceSha256 },\n diagnostics: { sampleCount: rendered.sampleCount, siteEvaluations: rendered.siteCount, sceneLookups: signal.lookups, detailPixelCount: rendered.detailPixelCount,\n uniformPixelCount: rendered.uniformPixelCount, ahdCorrectedPixelCount: rendered.ahdCorrectedPixelCount, timingsMs: { view: viewMs, total: Date.now() - started }, fast: context.fastReport },\n provenance: { scientificStatus: \"approximation\" as const, cameraPresetId: preset.presetId, cameraPresetVersion: preset.presetVersion, evidence: [...FACADE_EVIDENCE, ...preset.evidence],\n composedContracts: [\"calculateEnvironmentSensorPhotoSignal\", \"resolveSensorReadoutRegime\", \"calculateSiteEffectiveSaturationCode\", ...(diffraction ? [\"createDiffractionLimitedPsfProfile\", \"resolveLensPsfConvolutionKernels\"] : []),\n ...(antiAliasing ? [\"resolveAntiAliasingSpatialKernel\"] : []), \"prepareSensorColorDevelopment\", \"display view estimator\"],\n limitations: [\"Estimated display view of the full-resolution capture: its expected value is a stratified Monte Carlo estimate and its noise is drawn from the variance of the area mean, so it has the resized capture's statistics, not its exact pixels; not a capture and not a measurement.\"] },\n assumptions: Object.freeze(assumptions.map((a) => Object.freeze(a))) });\n };\n return { render, collect, correction };\n}\n"]}
|
|
@@ -48,6 +48,11 @@ export interface ImageKernelExecution {
|
|
|
48
48
|
fallbackReason: ImageKernelFallbackReason | null;
|
|
49
49
|
arithmetic: "float64" | "float32";
|
|
50
50
|
assurance: "engine-reference" | "approximation-with-a-priori-bound";
|
|
51
|
+
/**
|
|
52
|
+
* The exact-or-fast flag in the facade's words (#395): false for `cpu-reference` (the engine reference), true for
|
|
53
|
+
* `webgpu-f32` (a bounded approximation). `backend` still names where the work ran.
|
|
54
|
+
*/
|
|
55
|
+
fast: boolean;
|
|
51
56
|
/**
|
|
52
57
|
* True only for `cpu-reference`. Bit-exact identities (SHA-256 artifact bindings, byte-parity fixtures,
|
|
53
58
|
* cross-engine determinism hashes) are CPU-only and must never be computed from a `webgpu-f32` result.
|
|
@@ -73,12 +73,12 @@ export const WEBGPU_F32_LIMITATIONS = Object.freeze([
|
|
|
73
73
|
"Execution speed depends on the adapter; software adapters do not represent GPU performance"
|
|
74
74
|
]);
|
|
75
75
|
export function cpuExecution(requestedBackend, fallbackReason) {
|
|
76
|
-
return { backend: "cpu-reference", requestedBackend, fallbackReason, arithmetic: "float64", assurance: "engine-reference",
|
|
76
|
+
return { backend: "cpu-reference", requestedBackend, fallbackReason, arithmetic: "float64", assurance: "engine-reference", fast: false,
|
|
77
77
|
bitIdenticalToReference: true, errorBound: null, diagnosticsExact: true, diagnosticUncertaintySampleCount: 0, limitations: CPU_REFERENCE_LIMITATIONS };
|
|
78
78
|
}
|
|
79
79
|
export function webGpuExecution(errorBound, uncertainty) {
|
|
80
80
|
return { backend: "webgpu-f32", requestedBackend: "webgpu-f32", fallbackReason: null, arithmetic: "float32",
|
|
81
|
-
assurance: "approximation-with-a-priori-bound", bitIdenticalToReference: false, errorBound, diagnosticsExact: uncertainty === 0,
|
|
81
|
+
assurance: "approximation-with-a-priori-bound", fast: true, bitIdenticalToReference: false, errorBound, diagnosticsExact: uncertainty === 0,
|
|
82
82
|
diagnosticUncertaintySampleCount: uncertainty, limitations: WEBGPU_F32_LIMITATIONS };
|
|
83
83
|
}
|
|
84
84
|
//# sourceMappingURL=image-kernel-execution.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"image-kernel-execution.js","sourceRoot":"","sources":["../../src/gpu/image-kernel-execution.ts"],"names":[],"mappings":"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","sourcesContent":["// SPDX-License-Identifier: Apache-2.0\n\n/**\n * Execution-backend labels, error bounds and domain errors for the optional image-kernel accelerator.\n *\n * `cpu-reference` is the float64 engine reference and the default. `webgpu-f32` is a separate float32\n * approximation backend. Every one of its results carries a forward-error bound worked out in advance\n * from:\n * - IEEE 754 binary32 rounding (unit roundoff u = 2^-24; γ_k = k·u/(1 − k·u), the classical factor\n * in error bounds for floating-point sums and inner products: Rump & Jeannerod, SIAM J. Matrix\n * Anal. Appl. 35(2), 2014, sec. 1, free author copy. Also see: Higham, Accuracy and Stability of\n * Numerical Algorithms, 2nd ed., SIAM 2002, §2–§3);\n * - the WGSL built-in accuracy table (W3C WebGPU Shading Language, §\"Floating Point Accuracy\").\n * See docs/WEBGPU.md.\n */\n\nimport { requireInputObject } from \"../core/record-validation.js\";\nimport { InvalidScientificInputError } from \"../core/validation.js\";\n\n/** Requested or actual execution backend. */\nexport type ImageKernelBackend = \"cpu-reference\" | \"webgpu-f32\";\n\n/** Why a requested WebGPU backend was not used (only with `fallback: \"cpu-reference\"`). */\nexport type ImageKernelFallbackReason = \"webgpu-unavailable\" | \"adapter-unavailable\" | \"device-request-failed\" |\n \"insufficient-limits\" | \"unsupported-platform-endianness\";\n\n/** Failure classes reported by {@link ImageKernelExecutionError}. */\nexport type ImageKernelFailureReason = ImageKernelFallbackReason | \"device-lost\" | \"out-of-memory\" | \"gpu-validation\" |\n \"aborted\" | \"disposed\" | \"busy\" | \"unsupported-on-backend\" | \"unsupported-float32-domain\" | \"indeterminate-float32-classification\";\n\n/** Domain error for getting and running a backend. Input validation still throws the engine's existing errors. */\nexport class ImageKernelExecutionError extends Error {\n readonly code = \"IMAGE_KERNEL_EXECUTION\";\n readonly reason: ImageKernelFailureReason;\n\n constructor(reason: ImageKernelFailureReason, message: string) {\n super(message);\n this.name = \"ImageKernelExecutionError\";\n this.reason = reason;\n }\n}\n\n/** Integer output codes: |code_webgpu − code_reference| ≤ maximumAbsoluteCodeDifference for every sample. */\nexport interface ImageKernelCodeErrorBound {\n kind: \"integer-code-difference\";\n maximumAbsoluteCodeDifference: number;\n /** Bound on the float32 linear value entering the sRGB transfer, after tone and gamut handling. */\n linearAbsoluteBound: number;\n /** Declared bound on the WGSL sRGB transfer evaluation (pow), see WEBGPU_F32_TRANSFER_ABSOLUTE_BOUND. */\n transferAbsoluteBound: number;\n}\n\n/** Non-negative linear sums: |v_webgpu − v_reference| ≤ relative·v_reference + absolute for every sample. */\nexport interface ImageKernelRelativeErrorBound {\n kind: \"relative-to-reference\";\n relative: number;\n absolute: number;\n}\n\n/**\n * Seeded stochastic stages (the sensor stage). Random states are integer arithmetic and bit-identical to\n * the reference. A site is flagged when any float32 decision (sampling test, saturation limit, rounding)\n * fell inside its a-priori bound. Every unflagged site has exactly the reference code and flags; only\n * flagged sites may differ, and the statistical-equivalence tests cover them (docs/WEBGPU.md).\n */\nexport interface ImageKernelSeededRealizationBound {\n kind: \"exact-except-flagged-sites\";\n /** Number of flagged sites; equal to the execution's `diagnosticUncertaintySampleCount`. */\n flaggedSiteCount: number;\n noiseModel: { id: string; version: string };\n seedSchedule: string;\n}\n\n/** Label attached to every accelerated result. */\nexport interface ImageKernelExecution {\n backend: ImageKernelBackend;\n requestedBackend: ImageKernelBackend;\n fallbackReason: ImageKernelFallbackReason | null;\n arithmetic: \"float64\" | \"float32\";\n assurance: \"engine-reference\" | \"approximation-with-a-priori-bound\";\n /**\n * True only for `cpu-reference`. Bit-exact identities (SHA-256 artifact bindings, byte-parity fixtures,\n * cross-engine determinism hashes) are CPU-only and must never be computed from a `webgpu-f32` result.\n */\n bitIdenticalToReference: boolean;\n errorBound: ImageKernelCodeErrorBound | ImageKernelRelativeErrorBound | ImageKernelSeededRealizationBound | null;\n /**\n * Diagnostic counts equal the reference when no sample fell inside a float32 classification band\n * (`diagnosticUncertaintySampleCount === 0`). Otherwise each count differs by at most that many\n * samples.\n */\n diagnosticsExact: boolean;\n diagnosticUncertaintySampleCount: number;\n limitations: readonly string[];\n}\n\n/** IEEE 754 binary32 unit roundoff. */\nexport const WEBGPU_F32_UNIT_ROUNDOFF = 2 ** -24;\n/**\n * Declared absolute error bound for the WGSL sRGB encode on [0, 1]: `1.055·pow(x, 1/2.4) − 0.055`. pow\n * takes its accuracy from exp2(y·log2 x) (log2: 3 ULP, or 2^-21 absolute on [0.5, 2]; exp2: 3 + 2|x|\n * ULP). The worst case over [0.0031308, 1] is about 2.5e-6. The bound 2^-17 ≈ 7.6e-6 keeps a 3× margin,\n * and also covers the small jump where the sRGB segments join (< 1e-7).\n */\nexport const WEBGPU_F32_TRANSFER_ABSOLUTE_BOUND = 2 ** -17;\n/** Largest slope of the sRGB encode on [0, 1] (the linear segment, 12.92). */\nexport const SRGB_ENCODE_LIPSCHITZ = 12.92;\n\n/** Higham's γ_k for binary32. */\nexport function float32Gamma(k: number): number {\n const ku = k * WEBGPU_F32_UNIT_ROUNDOFF;\n return ku < 1 ? ku / (1 - ku) : Number.POSITIVE_INFINITY;\n}\n\n/** Integer-code bound from a bound on the linear value: |Δcode| ≤ ⌊maximum·(12.92·δ_L + δ_E)⌋ + 1, capped at maximum. */\nexport function integerCodeBound(maximum: number, linearAbsoluteBound: number): ImageKernelCodeErrorBound {\n const linear = Math.min(1, linearAbsoluteBound);\n const real = maximum * (SRGB_ENCODE_LIPSCHITZ * linear + WEBGPU_F32_TRANSFER_ABSOLUTE_BOUND);\n return { kind: \"integer-code-difference\", maximumAbsoluteCodeDifference: Math.min(maximum, Math.floor(real) + 1),\n linearAbsoluteBound: linear, transferAbsoluteBound: WEBGPU_F32_TRANSFER_ABSOLUTE_BOUND };\n}\n\n/**\n * Composes two `relative-to-reference` bounds through a pipeline `second ∘ first`, where the second\n * stage is linear with non-negative weights summing to at most `secondWeightSum` per output (convolution,\n * temporal sums). With |ã − a| ≤ r₁a + a₁ elementwise and |B̃x − Bx| ≤ r₂Bx + a₂:\n * |B̃ã − Ba| ≤ |B̃ã − Bã| + |B(ã − a)| ≤ r₂(1 + r₁)Ba + r₂W·a₁ + a₂ + r₁Ba + W·a₁,\n * so r = r₁ + r₂ + r₁r₂ and a = a₂ + W·a₁·(1 + r₂). See docs/WEBGPU.md, \"Accuracy contract\".\n */\nexport function composeRelativeErrorBounds(first: ImageKernelRelativeErrorBound, second: ImageKernelRelativeErrorBound,\n secondWeightSum: number): ImageKernelRelativeErrorBound {\n requireInputObject(first, \"composeRelativeErrorBounds first bound\");\n requireInputObject(second, \"composeRelativeErrorBounds second bound\");\n for (const v of [first.relative, first.absolute, second.relative, second.absolute, secondWeightSum]) {\n if (!(typeof v === \"number\" && v >= 0 && v <= Number.MAX_VALUE)) {\n throw new InvalidScientificInputError(\"Error bounds and weight sums must be finite and non-negative.\");\n }\n }\n return { kind: \"relative-to-reference\", relative: first.relative + second.relative + first.relative * second.relative,\n absolute: second.absolute + secondWeightSum * first.absolute * (1 + second.relative) };\n}\n\nexport const CPU_REFERENCE_LIMITATIONS = Object.freeze([\"Float64 engine reference execution; results are the reference by definition\"]);\nexport const WEBGPU_F32_LIMITATIONS = Object.freeze([\n \"Float32 WebGPU execution is an approximation of the float64 reference within the reported a-priori bound\",\n \"Not bit-identical to the reference: never use for SHA-256 artifact identities, byte-parity evidence or determinism hashes\",\n \"Bound assumes a conforming WebGPU implementation (correctly rounded f32 add/multiply/divide, WGSL accuracy table)\",\n \"Execution speed depends on the adapter; software adapters do not represent GPU performance\"\n]);\n\nexport function cpuExecution(requestedBackend: ImageKernelBackend, fallbackReason: ImageKernelFallbackReason | null): ImageKernelExecution {\n return { backend: \"cpu-reference\", requestedBackend, fallbackReason, arithmetic: \"float64\", assurance: \"engine-reference\",\n bitIdenticalToReference: true, errorBound: null, diagnosticsExact: true, diagnosticUncertaintySampleCount: 0, limitations: CPU_REFERENCE_LIMITATIONS };\n}\n\nexport function webGpuExecution(errorBound: ImageKernelExecution[\"errorBound\"], uncertainty: number): ImageKernelExecution {\n return { backend: \"webgpu-f32\", requestedBackend: \"webgpu-f32\", fallbackReason: null, arithmetic: \"float32\",\n assurance: \"approximation-with-a-priori-bound\", bitIdenticalToReference: false, errorBound, diagnosticsExact: uncertainty === 0,\n diagnosticUncertaintySampleCount: uncertainty, limitations: WEBGPU_F32_LIMITATIONS };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"image-kernel-execution.js","sourceRoot":"","sources":["../../src/gpu/image-kernel-execution.ts"],"names":[],"mappings":"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","sourcesContent":["// SPDX-License-Identifier: Apache-2.0\n\n/**\n * Execution-backend labels, error bounds and domain errors for the optional image-kernel accelerator.\n *\n * `cpu-reference` is the float64 engine reference and the default. `webgpu-f32` is a separate float32\n * approximation backend. Every one of its results carries a forward-error bound worked out in advance\n * from:\n * - IEEE 754 binary32 rounding (unit roundoff u = 2^-24; γ_k = k·u/(1 − k·u), the classical factor\n * in error bounds for floating-point sums and inner products: Rump & Jeannerod, SIAM J. Matrix\n * Anal. Appl. 35(2), 2014, sec. 1, free author copy. Also see: Higham, Accuracy and Stability of\n * Numerical Algorithms, 2nd ed., SIAM 2002, §2–§3);\n * - the WGSL built-in accuracy table (W3C WebGPU Shading Language, §\"Floating Point Accuracy\").\n * See docs/WEBGPU.md.\n */\n\nimport { requireInputObject } from \"../core/record-validation.js\";\nimport { InvalidScientificInputError } from \"../core/validation.js\";\n\n/** Requested or actual execution backend. */\nexport type ImageKernelBackend = \"cpu-reference\" | \"webgpu-f32\";\n\n/** Why a requested WebGPU backend was not used (only with `fallback: \"cpu-reference\"`). */\nexport type ImageKernelFallbackReason = \"webgpu-unavailable\" | \"adapter-unavailable\" | \"device-request-failed\" |\n \"insufficient-limits\" | \"unsupported-platform-endianness\";\n\n/** Failure classes reported by {@link ImageKernelExecutionError}. */\nexport type ImageKernelFailureReason = ImageKernelFallbackReason | \"device-lost\" | \"out-of-memory\" | \"gpu-validation\" |\n \"aborted\" | \"disposed\" | \"busy\" | \"unsupported-on-backend\" | \"unsupported-float32-domain\" | \"indeterminate-float32-classification\";\n\n/** Domain error for getting and running a backend. Input validation still throws the engine's existing errors. */\nexport class ImageKernelExecutionError extends Error {\n readonly code = \"IMAGE_KERNEL_EXECUTION\";\n readonly reason: ImageKernelFailureReason;\n\n constructor(reason: ImageKernelFailureReason, message: string) {\n super(message);\n this.name = \"ImageKernelExecutionError\";\n this.reason = reason;\n }\n}\n\n/** Integer output codes: |code_webgpu − code_reference| ≤ maximumAbsoluteCodeDifference for every sample. */\nexport interface ImageKernelCodeErrorBound {\n kind: \"integer-code-difference\";\n maximumAbsoluteCodeDifference: number;\n /** Bound on the float32 linear value entering the sRGB transfer, after tone and gamut handling. */\n linearAbsoluteBound: number;\n /** Declared bound on the WGSL sRGB transfer evaluation (pow), see WEBGPU_F32_TRANSFER_ABSOLUTE_BOUND. */\n transferAbsoluteBound: number;\n}\n\n/** Non-negative linear sums: |v_webgpu − v_reference| ≤ relative·v_reference + absolute for every sample. */\nexport interface ImageKernelRelativeErrorBound {\n kind: \"relative-to-reference\";\n relative: number;\n absolute: number;\n}\n\n/**\n * Seeded stochastic stages (the sensor stage). Random states are integer arithmetic and bit-identical to\n * the reference. A site is flagged when any float32 decision (sampling test, saturation limit, rounding)\n * fell inside its a-priori bound. Every unflagged site has exactly the reference code and flags; only\n * flagged sites may differ, and the statistical-equivalence tests cover them (docs/WEBGPU.md).\n */\nexport interface ImageKernelSeededRealizationBound {\n kind: \"exact-except-flagged-sites\";\n /** Number of flagged sites; equal to the execution's `diagnosticUncertaintySampleCount`. */\n flaggedSiteCount: number;\n noiseModel: { id: string; version: string };\n seedSchedule: string;\n}\n\n/** Label attached to every accelerated result. */\nexport interface ImageKernelExecution {\n backend: ImageKernelBackend;\n requestedBackend: ImageKernelBackend;\n fallbackReason: ImageKernelFallbackReason | null;\n arithmetic: \"float64\" | \"float32\";\n assurance: \"engine-reference\" | \"approximation-with-a-priori-bound\";\n /**\n * The exact-or-fast flag in the facade's words (#395): false for `cpu-reference` (the engine reference), true for\n * `webgpu-f32` (a bounded approximation). `backend` still names where the work ran.\n */\n fast: boolean;\n /**\n * True only for `cpu-reference`. Bit-exact identities (SHA-256 artifact bindings, byte-parity fixtures,\n * cross-engine determinism hashes) are CPU-only and must never be computed from a `webgpu-f32` result.\n */\n bitIdenticalToReference: boolean;\n errorBound: ImageKernelCodeErrorBound | ImageKernelRelativeErrorBound | ImageKernelSeededRealizationBound | null;\n /**\n * Diagnostic counts equal the reference when no sample fell inside a float32 classification band\n * (`diagnosticUncertaintySampleCount === 0`). Otherwise each count differs by at most that many\n * samples.\n */\n diagnosticsExact: boolean;\n diagnosticUncertaintySampleCount: number;\n limitations: readonly string[];\n}\n\n/** IEEE 754 binary32 unit roundoff. */\nexport const WEBGPU_F32_UNIT_ROUNDOFF = 2 ** -24;\n/**\n * Declared absolute error bound for the WGSL sRGB encode on [0, 1]: `1.055·pow(x, 1/2.4) − 0.055`. pow\n * takes its accuracy from exp2(y·log2 x) (log2: 3 ULP, or 2^-21 absolute on [0.5, 2]; exp2: 3 + 2|x|\n * ULP). The worst case over [0.0031308, 1] is about 2.5e-6. The bound 2^-17 ≈ 7.6e-6 keeps a 3× margin,\n * and also covers the small jump where the sRGB segments join (< 1e-7).\n */\nexport const WEBGPU_F32_TRANSFER_ABSOLUTE_BOUND = 2 ** -17;\n/** Largest slope of the sRGB encode on [0, 1] (the linear segment, 12.92). */\nexport const SRGB_ENCODE_LIPSCHITZ = 12.92;\n\n/** Higham's γ_k for binary32. */\nexport function float32Gamma(k: number): number {\n const ku = k * WEBGPU_F32_UNIT_ROUNDOFF;\n return ku < 1 ? ku / (1 - ku) : Number.POSITIVE_INFINITY;\n}\n\n/** Integer-code bound from a bound on the linear value: |Δcode| ≤ ⌊maximum·(12.92·δ_L + δ_E)⌋ + 1, capped at maximum. */\nexport function integerCodeBound(maximum: number, linearAbsoluteBound: number): ImageKernelCodeErrorBound {\n const linear = Math.min(1, linearAbsoluteBound);\n const real = maximum * (SRGB_ENCODE_LIPSCHITZ * linear + WEBGPU_F32_TRANSFER_ABSOLUTE_BOUND);\n return { kind: \"integer-code-difference\", maximumAbsoluteCodeDifference: Math.min(maximum, Math.floor(real) + 1),\n linearAbsoluteBound: linear, transferAbsoluteBound: WEBGPU_F32_TRANSFER_ABSOLUTE_BOUND };\n}\n\n/**\n * Composes two `relative-to-reference` bounds through a pipeline `second ∘ first`, where the second\n * stage is linear with non-negative weights summing to at most `secondWeightSum` per output (convolution,\n * temporal sums). With |ã − a| ≤ r₁a + a₁ elementwise and |B̃x − Bx| ≤ r₂Bx + a₂:\n * |B̃ã − Ba| ≤ |B̃ã − Bã| + |B(ã − a)| ≤ r₂(1 + r₁)Ba + r₂W·a₁ + a₂ + r₁Ba + W·a₁,\n * so r = r₁ + r₂ + r₁r₂ and a = a₂ + W·a₁·(1 + r₂). See docs/WEBGPU.md, \"Accuracy contract\".\n */\nexport function composeRelativeErrorBounds(first: ImageKernelRelativeErrorBound, second: ImageKernelRelativeErrorBound,\n secondWeightSum: number): ImageKernelRelativeErrorBound {\n requireInputObject(first, \"composeRelativeErrorBounds first bound\");\n requireInputObject(second, \"composeRelativeErrorBounds second bound\");\n for (const v of [first.relative, first.absolute, second.relative, second.absolute, secondWeightSum]) {\n if (!(typeof v === \"number\" && v >= 0 && v <= Number.MAX_VALUE)) {\n throw new InvalidScientificInputError(\"Error bounds and weight sums must be finite and non-negative.\");\n }\n }\n return { kind: \"relative-to-reference\", relative: first.relative + second.relative + first.relative * second.relative,\n absolute: second.absolute + secondWeightSum * first.absolute * (1 + second.relative) };\n}\n\nexport const CPU_REFERENCE_LIMITATIONS = Object.freeze([\"Float64 engine reference execution; results are the reference by definition\"]);\nexport const WEBGPU_F32_LIMITATIONS = Object.freeze([\n \"Float32 WebGPU execution is an approximation of the float64 reference within the reported a-priori bound\",\n \"Not bit-identical to the reference: never use for SHA-256 artifact identities, byte-parity evidence or determinism hashes\",\n \"Bound assumes a conforming WebGPU implementation (correctly rounded f32 add/multiply/divide, WGSL accuracy table)\",\n \"Execution speed depends on the adapter; software adapters do not represent GPU performance\"\n]);\n\nexport function cpuExecution(requestedBackend: ImageKernelBackend, fallbackReason: ImageKernelFallbackReason | null): ImageKernelExecution {\n return { backend: \"cpu-reference\", requestedBackend, fallbackReason, arithmetic: \"float64\", assurance: \"engine-reference\", fast: false,\n bitIdenticalToReference: true, errorBound: null, diagnosticsExact: true, diagnosticUncertaintySampleCount: 0, limitations: CPU_REFERENCE_LIMITATIONS };\n}\n\nexport function webGpuExecution(errorBound: ImageKernelExecution[\"errorBound\"], uncertainty: number): ImageKernelExecution {\n return { backend: \"webgpu-f32\", requestedBackend: \"webgpu-f32\", fallbackReason: null, arithmetic: \"float32\",\n assurance: \"approximation-with-a-priori-bound\", fast: true, bitIdenticalToReference: false, errorBound, diagnosticsExact: uncertainty === 0,\n diagnosticUncertaintySampleCount: uncertainty, limitations: WEBGPU_F32_LIMITATIONS };\n}\n"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -162,8 +162,9 @@ export type { PrintRegionRaster, PrintRegionDifferenceInput, PrintRegionNoiseInp
|
|
|
162
162
|
export { PRINT_CONTRAST_REFERENCE_MODEL_VERSION, PRINT_CONTRAST_REFERENCE_UPSTREAM_REVISION, calculatePrintContrastReference, parsePrintContrastReferenceInput } from "./output/print-contrast-reference.js";
|
|
163
163
|
export type { PrintContrastReferenceInput, PrintContrastReference } from "./output/print-contrast-reference.js";
|
|
164
164
|
export { NATIVE_RAW_SCHEMA_VERSION, NATIVE_RAW_LIMITS, calculateNativeRawPlan, createNativeRawTask } from "./capture/native-raw.js";
|
|
165
|
-
export { PRINT_JPEG_SCHEMA_VERSION, PRINT_JPEG_LIMITS, parsePrintJpegInput, createPrintJpegTask } from "./output/print-jpeg.js";
|
|
166
|
-
export type { PrintJpegSource, PrintJpegInput, PrintJpegTileRequest, PrintJpegTile, PrintJpegProvider, PrintJpegOutput, PrintJpegTask } from "./output/print-jpeg.js";
|
|
165
|
+
export { PRINT_JPEG_SCHEMA_VERSION, PRINT_JPEG_LIMITS, parsePrintJpegInput, createPrintJpegTask, createPrintJpegStrip, composePrintJpegStrips } from "./output/print-jpeg.js";
|
|
166
|
+
export type { PrintJpegSource, PrintJpegInput, PrintJpegTileRequest, PrintJpegTile, PrintJpegProvider, PrintJpegOutput, PrintJpegTask, PrintJpegStripInput, PrintJpegStrip } from "./output/print-jpeg.js";
|
|
167
|
+
export type { JpegStripBits } from "./capture/export-jpeg.js";
|
|
167
168
|
export { SRGB_ICC_PROFILE_VERSION, createSrgbIccProfile } from "./color/srgb-icc.js";
|
|
168
169
|
export { createNativeEnvironmentRawTask, createNativeEnvironmentSensorStageTask, calculateNativeRawRowBands, createNativeEnvironmentRawPartitionTask, composeNativeEnvironmentRawPartitions } from "./capture/native-environment-raw.js";
|
|
169
170
|
export type { NativeEnvironmentRawInput, NativeEnvironmentRawTile, NativeEnvironmentPhotoTile, NativeEnvironmentRawProvider, NativeEnvironmentRawOutput, NativeEnvironmentRawTask, NativeRawRowBand, NativeEnvironmentRawPartition, NativeEnvironmentRawPartitionTask, NativeEnvironmentRadianceQuery } from "./capture/native-environment-raw.js";
|
|
@@ -197,8 +198,8 @@ export { createFocusStackTask, type FocusStackInput, type FocusStackOutput } fro
|
|
|
197
198
|
export { createPanoramaTask, type PanoramaFrame, type PanoramaCanvas, type PanoramaInput, type PanoramaOutput } from "./processing/panorama.js";
|
|
198
199
|
export { SYNTHETIC_FILM_GRAIN_STREAM_ID, createBilateralFilterTask, createNonLocalMeansTask, createUnsharpMaskTask, createSyntheticFilmGrainTask, type ProcessedRgbImage, type BilateralFilterInput, type NonLocalMeansInput, type UnsharpMaskInput, type SyntheticFilmGrainInput, type SyntheticFilmGrainOutput } from "./processing/denoise.js";
|
|
199
200
|
export { calculateSensorApertureRays, type CalculateSensorApertureRaysInput, type IdealCircularPupil, type SensorApertureRay, type SensorApertureRays } from "./optics/sensor-aperture-rays.js";
|
|
200
|
-
export { SIMULATE_CAPTURE_FACADE_VERSION, SIMULATE_CAPTURE_DEFAULT_ILLUMINANCE_LUX, SIMULATE_CAPTURE_COST_OPTIONS, simulateCapture, type SimulateCaptureOptions, type SimulateCaptureResult, type SimulateCaptureAssumption, type SimulateCaptureProgress, type SimulateCaptureExposureMode, type SimulateCaptureOutputFormat, type SimulateCaptureWhiteBalance, type SimulateCaptureColorEncoding, type SimulateCaptureDemosaic, type SimulateCaptureBorderHandling, type SimulateCaptureLensDistortion, type SimulateCaptureMotion, type SimulateCaptureSensorAntiAliasing, type SimulateCaptureCostOption, type SimulateCapturePixelAperture, SIMULATE_CAPTURE_BOX_APERTURE_DEFAULT_SAMPLES, simulateIdealReference, type IdealReferenceResult, type SimulateDisplayViewOptions, type DisplayViewResult, SIMULATE_DISPLAY_VIEW_DEFAULT_SAMPLES_PER_AXIS } from "./facade/simulate-capture.js";
|
|
201
|
-
export { simulateDisplayView, prepareDisplayView, type PreparedDisplayView, type PreparedDisplayViewRenderOptions } from "./facade/simulate-display-view.js";
|
|
201
|
+
export { SIMULATE_CAPTURE_FACADE_VERSION, SIMULATE_CAPTURE_DEFAULT_ILLUMINANCE_LUX, SIMULATE_CAPTURE_COST_OPTIONS, simulateCapture, type SimulateCaptureOptions, type SimulateCaptureResult, type SimulateCaptureAssumption, type SimulateCaptureProgress, type SimulateCaptureExposureMode, type SimulateCaptureOutputFormat, type SimulateCaptureWhiteBalance, type SimulateCaptureColorEncoding, type SimulateCaptureDemosaic, type SimulateCaptureBorderHandling, type SimulateCaptureLensDistortion, type SimulateCaptureMotion, type SimulateCaptureSensorAntiAliasing, type SimulateCaptureCostOption, type SimulateCapturePixelAperture, SIMULATE_CAPTURE_BOX_APERTURE_DEFAULT_SAMPLES, SIMULATE_CAPTURE_FAST_OPTIONS, type SimulateCaptureFastOption, type SimulateCaptureFastReport, type SimulateCaptureDemosaicRecord, simulateIdealReference, type IdealReferenceResult, serializeSimulatedCaptureDngFromParts, type SimulateCaptureDngPart, type SimulateDisplayViewOptions, type DisplayViewResult, SIMULATE_DISPLAY_VIEW_DEFAULT_SAMPLES_PER_AXIS } from "./facade/simulate-capture.js";
|
|
202
|
+
export { simulateDisplayView, prepareDisplayView, type PreparedDisplayView, type PreparedDisplayViewRenderOptions, serializeDisplayViewCorrectionStates, bindDisplayViewCorrectionStates, type DisplayViewCorrectionStateKeys, type DisplayViewCorrectionStateSet } from "./facade/simulate-display-view.js";
|
|
202
203
|
export { type OutputTextMetadata } from "./output/text-metadata.js";
|
|
203
204
|
export { GENERIC_PRIME_EQUIVALENT_FOCAL_LENGTHS_MM, GENERIC_PRIME_THIRD_STOP_F_NUMBERS, GENERIC_PRIME_MINIMUM_FOCUS, resolveGenericPrimeLens, calculateGenericPrimeMinimumFocusDistanceM, type GenericPrimeLens, type GenericPrimeEquivalentFocalLengthMm } from "./equipment/generic-prime-lenses.js";
|
|
204
205
|
export { calculateChartFraming, calculateSubjectDistanceForFraming, type CalculateChartFramingInput, type CalculateSubjectDistanceForFramingInput, type ChartFraming, type SubjectFraming, type SubjectFramingFit } from "./facade/subject-framing.js";
|
package/dist/index.js
CHANGED
|
@@ -154,7 +154,7 @@ export { PRINT_REGION_DETAIL_MODEL_VERSION, MAX_PRINT_DETAIL_REGION_SAMPLES, cal
|
|
|
154
154
|
export { PRINT_REGION_STATISTICS_MODEL_VERSION, MAX_PRINT_REGION_STATISTICS_SAMPLES, calculatePrintRegionDifference, calculatePrintRegionNoise, parsePrintRegionDifferenceInput, parsePrintRegionNoiseInput } from "./output/print-region-statistics.js";
|
|
155
155
|
export { PRINT_CONTRAST_REFERENCE_MODEL_VERSION, PRINT_CONTRAST_REFERENCE_UPSTREAM_REVISION, calculatePrintContrastReference, parsePrintContrastReferenceInput } from "./output/print-contrast-reference.js";
|
|
156
156
|
export { NATIVE_RAW_SCHEMA_VERSION, NATIVE_RAW_LIMITS, calculateNativeRawPlan, createNativeRawTask } from "./capture/native-raw.js";
|
|
157
|
-
export { PRINT_JPEG_SCHEMA_VERSION, PRINT_JPEG_LIMITS, parsePrintJpegInput, createPrintJpegTask } from "./output/print-jpeg.js";
|
|
157
|
+
export { PRINT_JPEG_SCHEMA_VERSION, PRINT_JPEG_LIMITS, parsePrintJpegInput, createPrintJpegTask, createPrintJpegStrip, composePrintJpegStrips } from "./output/print-jpeg.js";
|
|
158
158
|
export { SRGB_ICC_PROFILE_VERSION, createSrgbIccProfile } from "./color/srgb-icc.js";
|
|
159
159
|
export { createNativeEnvironmentRawTask, createNativeEnvironmentSensorStageTask, calculateNativeRawRowBands, createNativeEnvironmentRawPartitionTask, composeNativeEnvironmentRawPartitions } from "./capture/native-environment-raw.js";
|
|
160
160
|
export { NATIVE_ENVIRONMENT_OPTICAL_STAGE_LIMITS } from "./capture/native-environment-optical-stage.js";
|
|
@@ -176,8 +176,8 @@ export { createFocusStackTask } from "./processing/focus-stacking.js";
|
|
|
176
176
|
export { createPanoramaTask } from "./processing/panorama.js";
|
|
177
177
|
export { SYNTHETIC_FILM_GRAIN_STREAM_ID, createBilateralFilterTask, createNonLocalMeansTask, createUnsharpMaskTask, createSyntheticFilmGrainTask } from "./processing/denoise.js";
|
|
178
178
|
export { calculateSensorApertureRays } from "./optics/sensor-aperture-rays.js";
|
|
179
|
-
export { SIMULATE_CAPTURE_FACADE_VERSION, SIMULATE_CAPTURE_DEFAULT_ILLUMINANCE_LUX, SIMULATE_CAPTURE_COST_OPTIONS, simulateCapture, SIMULATE_CAPTURE_BOX_APERTURE_DEFAULT_SAMPLES, simulateIdealReference, SIMULATE_DISPLAY_VIEW_DEFAULT_SAMPLES_PER_AXIS } from "./facade/simulate-capture.js";
|
|
180
|
-
export { simulateDisplayView, prepareDisplayView } from "./facade/simulate-display-view.js";
|
|
179
|
+
export { SIMULATE_CAPTURE_FACADE_VERSION, SIMULATE_CAPTURE_DEFAULT_ILLUMINANCE_LUX, SIMULATE_CAPTURE_COST_OPTIONS, simulateCapture, SIMULATE_CAPTURE_BOX_APERTURE_DEFAULT_SAMPLES, SIMULATE_CAPTURE_FAST_OPTIONS, simulateIdealReference, serializeSimulatedCaptureDngFromParts, SIMULATE_DISPLAY_VIEW_DEFAULT_SAMPLES_PER_AXIS } from "./facade/simulate-capture.js";
|
|
180
|
+
export { simulateDisplayView, prepareDisplayView, serializeDisplayViewCorrectionStates, bindDisplayViewCorrectionStates } from "./facade/simulate-display-view.js";
|
|
181
181
|
export {} from "./output/text-metadata.js";
|
|
182
182
|
export { GENERIC_PRIME_EQUIVALENT_FOCAL_LENGTHS_MM, GENERIC_PRIME_THIRD_STOP_F_NUMBERS, GENERIC_PRIME_MINIMUM_FOCUS, resolveGenericPrimeLens, calculateGenericPrimeMinimumFocusDistanceM } from "./equipment/generic-prime-lenses.js";
|
|
183
183
|
export { calculateChartFraming, calculateSubjectDistanceForFraming } from "./facade/subject-framing.js";
|