@photivra/engine 2.18.0 → 2.20.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 +179 -1
- package/CITATION.cff +1 -1
- package/NODE_SUPPORT.md +7 -5
- package/README.md +6 -6
- package/SECURITY.md +1 -1
- package/THIRD_PARTY.md +14 -10
- package/dist/capture/dng-lens-correction-opcodes.d.ts +32 -0
- package/dist/capture/dng-lens-correction-opcodes.js +119 -0
- package/dist/capture/dng-lens-correction-opcodes.js.map +1 -0
- package/dist/capture/focus-control.js +2 -75
- package/dist/capture/focus-control.js.map +1 -1
- package/dist/capture/native-environment-lean.d.ts +1 -0
- package/dist/capture/native-environment-lean.js +2 -6
- package/dist/capture/native-environment-lean.js.map +1 -1
- package/dist/capture/native-environment-optical-stage.d.ts +1 -0
- package/dist/capture/native-environment-optical-stage.js +2 -5
- package/dist/capture/native-environment-optical-stage.js.map +1 -1
- package/dist/capture/native-environment-raw.js +1 -5
- package/dist/capture/native-environment-raw.js.map +1 -1
- package/dist/capture/native-raw-dng.d.ts +6 -0
- package/dist/capture/native-raw-dng.js +16 -2
- package/dist/capture/native-raw-dng.js.map +1 -1
- package/dist/capture/release-sequence.js +2 -47
- package/dist/capture/release-sequence.js.map +1 -1
- package/dist/capture/sensor-raw-producer.js +3 -5
- package/dist/capture/sensor-raw-producer.js.map +1 -1
- package/dist/color/white-balance.d.ts +2 -0
- package/dist/color/white-balance.js +3 -56
- package/dist/color/white-balance.js.map +1 -1
- package/dist/composition/image-formation-plan.d.ts +1 -0
- package/dist/composition/image-formation-plan.js +3 -49
- package/dist/composition/image-formation-plan.js.map +1 -1
- package/dist/core/evidence-provenance.js +1 -16
- package/dist/core/evidence-provenance.js.map +1 -1
- package/dist/core/record-validation.d.ts +54 -0
- package/dist/core/record-validation.js +176 -0
- package/dist/core/record-validation.js.map +1 -1
- package/dist/core/scientific-assurance.js +1 -18
- package/dist/core/scientific-assurance.js.map +1 -1
- package/dist/core/shared-helpers.d.ts +35 -0
- package/dist/core/shared-helpers.js +38 -0
- package/dist/core/shared-helpers.js.map +1 -0
- package/dist/core/spectral-composition.js +1 -36
- package/dist/core/spectral-composition.js.map +1 -1
- package/dist/core/spectral.js +1 -19
- package/dist/core/spectral.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/equipment/exposure-capabilities.d.ts +1 -0
- package/dist/equipment/exposure-capabilities.js +2 -36
- package/dist/equipment/exposure-capabilities.js.map +1 -1
- package/dist/equipment/generic-lens-catalogue.d.ts +8 -2
- package/dist/equipment/generic-lens-catalogue.js +31 -2
- package/dist/equipment/generic-lens-catalogue.js.map +1 -1
- package/dist/equipment/generic-tier-assets.js +2 -3
- package/dist/equipment/generic-tier-assets.js.map +1 -1
- package/dist/equipment/generic-tier-presets.js +2 -3
- package/dist/equipment/generic-tier-presets.js.map +1 -1
- package/dist/equipment/iso-capabilities.js +2 -49
- package/dist/equipment/iso-capabilities.js.map +1 -1
- package/dist/equipment/metering-capabilities.js +1 -26
- package/dist/equipment/metering-capabilities.js.map +1 -1
- package/dist/equipment/release-capabilities.js +1 -53
- package/dist/equipment/release-capabilities.js.map +1 -1
- package/dist/exposure/auto-iso-slowest-shutter.js +1 -7
- package/dist/exposure/auto-iso-slowest-shutter.js.map +1 -1
- package/dist/exposure/exposure-duration-control.js +1 -16
- package/dist/exposure/exposure-duration-control.js.map +1 -1
- package/dist/exposure/exposure-mode-resolver.js +1 -17
- package/dist/exposure/exposure-mode-resolver.js.map +1 -1
- package/dist/exposure/filtered-exposure-time.d.ts +93 -0
- package/dist/exposure/filtered-exposure-time.js +129 -0
- package/dist/exposure/filtered-exposure-time.js.map +1 -0
- package/dist/exposure/flash-ttl.d.ts +1 -0
- package/dist/exposure/flash-ttl.js +1 -1
- package/dist/exposure/flash-ttl.js.map +1 -1
- package/dist/exposure/flash.js +1 -49
- package/dist/exposure/flash.js.map +1 -1
- package/dist/exposure/metering-scene-radiance.js +1 -25
- package/dist/exposure/metering-scene-radiance.js.map +1 -1
- package/dist/exposure/metering-target.js +1 -30
- package/dist/exposure/metering-target.js.map +1 -1
- package/dist/exposure/metering-temporal.js +1 -8
- package/dist/exposure/metering-temporal.js.map +1 -1
- package/dist/exposure/metering.js +1 -72
- package/dist/exposure/metering.js.map +1 -1
- package/dist/exposure/program-line.js +1 -45
- package/dist/exposure/program-line.js.map +1 -1
- package/dist/facade/develop-joined-parts.d.ts +29 -0
- package/dist/facade/develop-joined-parts.js +33 -0
- package/dist/facade/develop-joined-parts.js.map +1 -0
- package/dist/facade/display-view-gpu.d.ts +7 -4
- package/dist/facade/display-view-gpu.js +4 -4
- package/dist/facade/display-view-gpu.js.map +1 -1
- package/dist/facade/display-view-lens-signal.d.ts +1 -1
- package/dist/facade/display-view-lens-signal.js +5 -3
- package/dist/facade/display-view-lens-signal.js.map +1 -1
- package/dist/facade/display-view.d.ts +3 -1
- package/dist/facade/display-view.js +1 -1
- package/dist/facade/display-view.js.map +1 -1
- package/dist/facade/fast-methods.d.ts +50 -0
- package/dist/facade/fast-methods.js +50 -0
- package/dist/facade/fast-methods.js.map +1 -0
- package/dist/facade/fast-resolution.d.ts +12 -0
- package/dist/facade/fast-resolution.js +18 -0
- package/dist/facade/fast-resolution.js.map +1 -0
- package/dist/facade/generic-lens-capture.d.ts +6 -3
- package/dist/facade/generic-lens-capture.js +6 -3
- package/dist/facade/generic-lens-capture.js.map +1 -1
- package/dist/facade/simulate-capture.d.ts +88 -16
- package/dist/facade/simulate-capture.js +279 -153
- package/dist/facade/simulate-capture.js.map +1 -1
- package/dist/facade/simulate-display-view.d.ts +3 -2
- package/dist/facade/simulate-display-view.js +22 -12
- package/dist/facade/simulate-display-view.js.map +1 -1
- package/dist/gpu/chart-composite-gpu.js +1 -3
- package/dist/gpu/chart-composite-gpu.js.map +1 -1
- package/dist/gpu/chart-radiance-gpu.js +1 -5
- package/dist/gpu/chart-radiance-gpu.js.map +1 -1
- package/dist/gpu/display-view-quality-gpu.d.ts +13 -1
- package/dist/gpu/display-view-quality-gpu.js +4 -8
- package/dist/gpu/display-view-quality-gpu.js.map +1 -1
- package/dist/gpu/display-view-speed-gpu.js +3 -25
- package/dist/gpu/display-view-speed-gpu.js.map +1 -1
- package/dist/gpu/sensor-stage-gpu.js +1 -5
- package/dist/gpu/sensor-stage-gpu.js.map +1 -1
- package/dist/gpu/webgpu-runtime.d.ts +2 -0
- package/dist/gpu/webgpu-runtime.js +3 -0
- package/dist/gpu/webgpu-runtime.js.map +1 -1
- package/dist/index.d.ts +11 -1
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -1
- package/dist/motion/camera-rotation.js +1 -6
- package/dist/motion/camera-rotation.js.map +1 -1
- package/dist/motion/capture-rotation-inverse-mapping.d.ts +12 -0
- package/dist/motion/capture-rotation-inverse-mapping.js +2 -2
- package/dist/motion/capture-rotation-inverse-mapping.js.map +1 -1
- package/dist/motion/capture-rotation-temporal-quadrature.d.ts +1 -0
- package/dist/motion/capture-rotation-temporal-quadrature.js +1 -1
- package/dist/motion/capture-rotation-temporal-quadrature.js.map +1 -1
- package/dist/motion/capture-rotation-trajectory.js +2 -17
- package/dist/motion/capture-rotation-trajectory.js.map +1 -1
- package/dist/motion/capture-translation-parallax-temporal-quadrature.d.ts +1 -0
- package/dist/motion/capture-translation-parallax-temporal-quadrature.js +3 -14
- package/dist/motion/capture-translation-parallax-temporal-quadrature.js.map +1 -1
- package/dist/motion/extended-object-projection.js +5 -40
- package/dist/motion/extended-object-projection.js.map +1 -1
- package/dist/optics/aperture-diameter.d.ts +47 -0
- package/dist/optics/aperture-diameter.js +50 -0
- package/dist/optics/aperture-diameter.js.map +1 -0
- package/dist/optics/atmospheric-haze.js +1 -7
- package/dist/optics/atmospheric-haze.js.map +1 -1
- package/dist/optics/brown-conrady-distortion.js +1 -7
- package/dist/optics/brown-conrady-distortion.js.map +1 -1
- package/dist/optics/complex-pupil-psf.d.ts +1 -0
- package/dist/optics/complex-pupil-psf.js +2 -84
- package/dist/optics/complex-pupil-psf.js.map +1 -1
- package/dist/optics/detail-limit.d.ts +182 -0
- package/dist/optics/detail-limit.js +336 -0
- package/dist/optics/detail-limit.js.map +1 -0
- package/dist/optics/focus-state.js +1 -11
- package/dist/optics/focus-state.js.map +1 -1
- package/dist/optics/front-of-lens-filter.d.ts +5 -0
- package/dist/optics/front-of-lens-filter.js +3 -65
- package/dist/optics/front-of-lens-filter.js.map +1 -1
- package/dist/optics/generic-lens-psf.d.ts +18 -2
- package/dist/optics/generic-lens-psf.js +25 -2
- package/dist/optics/generic-lens-psf.js.map +1 -1
- package/dist/optics/generic-nd-filter-presets.d.ts +12 -0
- package/dist/optics/generic-nd-filter-presets.js +48 -0
- package/dist/optics/generic-nd-filter-presets.js.map +1 -0
- package/dist/optics/illumination-vignetting.js +1 -6
- package/dist/optics/illumination-vignetting.js.map +1 -1
- package/dist/optics/lens-psf-profile.d.ts +4 -1
- package/dist/optics/lens-psf-profile.js +12 -111
- package/dist/optics/lens-psf-profile.js.map +1 -1
- package/dist/optics/longitudinal-chromatic-aberration.js +1 -7
- package/dist/optics/longitudinal-chromatic-aberration.js.map +1 -1
- package/dist/optics/pupil-vignetting.js +1 -7
- package/dist/optics/pupil-vignetting.js.map +1 -1
- package/dist/optics/radial-distortion.js +1 -6
- package/dist/optics/radial-distortion.js.map +1 -1
- package/dist/optics/scene-to-sensor-irradiance.d.ts +13 -0
- package/dist/optics/scene-to-sensor-irradiance.js +11 -96
- package/dist/optics/scene-to-sensor-irradiance.js.map +1 -1
- package/dist/optics/stray-light.d.ts +1 -0
- package/dist/optics/stray-light.js +1 -1
- package/dist/optics/stray-light.js.map +1 -1
- package/dist/optics/zernike-wavefront.js +1 -7
- package/dist/optics/zernike-wavefront.js.map +1 -1
- package/dist/output/capture-geometry.js +1 -8
- package/dist/output/capture-geometry.js.map +1 -1
- package/dist/output/crop-to-match-focal-length.d.ts +62 -0
- package/dist/output/crop-to-match-focal-length.js +63 -0
- package/dist/output/crop-to-match-focal-length.js.map +1 -0
- package/dist/output/developed-lens-corrections.d.ts +62 -0
- package/dist/output/developed-lens-corrections.js +135 -0
- package/dist/output/developed-lens-corrections.js.map +1 -0
- package/dist/output/generic-lens-corrections.d.ts +5 -7
- package/dist/output/generic-lens-corrections.js +11 -10
- package/dist/output/generic-lens-corrections.js.map +1 -1
- package/dist/output/geometric-transforms.js +1 -4
- package/dist/output/geometric-transforms.js.map +1 -1
- package/dist/output/lens-corrections.d.ts +12 -2
- package/dist/output/lens-corrections.js +22 -7
- package/dist/output/lens-corrections.js.map +1 -1
- package/dist/output/native-capture-sdr.d.ts +2 -2
- package/dist/output/native-capture-sdr.js +3 -2
- package/dist/output/native-capture-sdr.js.map +1 -1
- package/dist/output/print-contrast-reference.js +1 -1
- package/dist/output/print-contrast-reference.js.map +1 -1
- package/dist/output/print-size-blur-noise.d.ts +110 -0
- package/dist/output/print-size-blur-noise.js +138 -0
- package/dist/output/print-size-blur-noise.js.map +1 -0
- package/dist/processing/development-detail.d.ts +29 -0
- package/dist/processing/development-detail.js +128 -107
- package/dist/processing/development-detail.js.map +1 -1
- package/dist/schema/illumination-temporal.js +3 -72
- package/dist/schema/illumination-temporal.js.map +1 -1
- package/dist/schema/illumination.d.ts +1 -0
- package/dist/schema/illumination.js +2 -65
- package/dist/schema/illumination.js.map +1 -1
- package/dist/schema/scene-radiance-temporal.js +2 -14
- package/dist/schema/scene-radiance-temporal.js.map +1 -1
- package/dist/schema/scene-radiance.js +2 -60
- package/dist/schema/scene-radiance.js.map +1 -1
- package/dist/schema/validation.d.ts +2 -0
- package/dist/schema/validation.js +2 -17
- package/dist/schema/validation.js.map +1 -1
- package/dist/sensor/accumulated-charge.js +2 -59
- package/dist/sensor/accumulated-charge.js.map +1 -1
- package/dist/sensor/architecture.js +1 -16
- package/dist/sensor/architecture.js.map +1 -1
- package/dist/sensor/camera-saturation-capacity.d.ts +1 -0
- package/dist/sensor/camera-saturation-capacity.js +3 -55
- package/dist/sensor/camera-saturation-capacity.js.map +1 -1
- package/dist/sensor/capture-color-sampling-binding.js +1 -26
- package/dist/sensor/capture-color-sampling-binding.js.map +1 -1
- package/dist/sensor/capture-mode-timing.js +1 -39
- package/dist/sensor/capture-mode-timing.js.map +1 -1
- package/dist/sensor/capture-mode.js +1 -23
- package/dist/sensor/capture-mode.js.map +1 -1
- package/dist/sensor/color-sampling.js +1 -26
- package/dist/sensor/color-sampling.js.map +1 -1
- package/dist/sensor/constant-rate-temporal-integration.js +2 -46
- package/dist/sensor/constant-rate-temporal-integration.js.map +1 -1
- package/dist/sensor/dark-current.js +2 -45
- package/dist/sensor/dark-current.js.map +1 -1
- package/dist/sensor/eqe-electron-rate.js +2 -41
- package/dist/sensor/eqe-electron-rate.js.map +1 -1
- package/dist/sensor/exposure-window.d.ts +7 -0
- package/dist/sensor/exposure-window.js +9 -24
- package/dist/sensor/exposure-window.js.map +1 -1
- package/dist/sensor/iso-gain.js +1 -7
- package/dist/sensor/iso-gain.js.map +1 -1
- package/dist/sensor/iso-signal-chain.js +1 -43
- package/dist/sensor/iso-signal-chain.js.map +1 -1
- package/dist/sensor/optical-stack.js +1 -25
- package/dist/sensor/optical-stack.js.map +1 -1
- package/dist/sensor/photon-energy.js +1 -26
- package/dist/sensor/photon-energy.js.map +1 -1
- package/dist/sensor/physical-charge-capacity.js +3 -77
- package/dist/sensor/physical-charge-capacity.js.map +1 -1
- package/dist/sensor/radiometry-readiness.js +2 -23
- package/dist/sensor/radiometry-readiness.js.map +1 -1
- package/dist/sensor/raw-readout.d.ts +3 -0
- package/dist/sensor/raw-readout.js +4 -66
- package/dist/sensor/raw-readout.js.map +1 -1
- package/dist/sensor/raw-reconstruction.js +2 -64
- package/dist/sensor/raw-reconstruction.js.map +1 -1
- package/dist/sensor/readout-exposure-linkage.js +1 -9
- package/dist/sensor/readout-exposure-linkage.js.map +1 -1
- package/dist/sensor/readout-timing.js +4 -79
- package/dist/sensor/readout-timing.js.map +1 -1
- package/dist/sensor/response-application-compatibility.d.ts +2 -0
- package/dist/sensor/response-application-compatibility.js +4 -35
- package/dist/sensor/response-application-compatibility.js.map +1 -1
- package/dist/sensor/response-operating-range.d.ts +1 -0
- package/dist/sensor/response-operating-range.js +3 -79
- package/dist/sensor/response-operating-range.js.map +1 -1
- package/dist/sensor/responsivity-photocurrent.js +4 -114
- package/dist/sensor/responsivity-photocurrent.js.map +1 -1
- package/dist/sensor/sampling-aperture.js +1 -25
- package/dist/sensor/sampling-aperture.js.map +1 -1
- package/dist/sensor/sensor-characteristics.d.ts +137 -0
- package/dist/sensor/sensor-characteristics.js +115 -0
- package/dist/sensor/sensor-characteristics.js.map +1 -0
- package/dist/sensor/spatial-sample-reduction.js +3 -24
- package/dist/sensor/spatial-sample-reduction.js.map +1 -1
- package/dist/sensor/spatial-sampling-quadrature.js +1 -3
- package/dist/sensor/spatial-sampling-quadrature.js.map +1 -1
- package/dist/sensor/spatio-spectral-reduction.js +1 -18
- package/dist/sensor/spatio-spectral-reduction.js.map +1 -1
- package/dist/sensor/spectral-coverage.d.ts +10 -1
- package/dist/sensor/spectral-coverage.js +1 -1
- package/dist/sensor/spectral-coverage.js.map +1 -1
- package/dist/sensor/spectral-quadrature.js +3 -41
- package/dist/sensor/spectral-quadrature.js.map +1 -1
- package/dist/sensor/spectral-response.js +1 -47
- package/dist/sensor/spectral-response.js.map +1 -1
- package/dist/sensor/temporal-photo-signal.d.ts +3 -0
- package/dist/sensor/temporal-photo-signal.js +5 -2
- package/dist/sensor/temporal-photo-signal.js.map +1 -1
- package/dist/stabilization/camera-shake.js +1 -6
- package/dist/stabilization/camera-shake.js.map +1 -1
- package/dist/stabilization/system.d.ts +9 -0
- package/dist/stabilization/system.js +7 -86
- package/dist/stabilization/system.js.map +1 -1
- package/docs/AGENT_GUIDE.md +5 -0
- package/docs/API_REFERENCE.md +116 -3
- package/docs/QUICK_START.md +178 -14
- package/docs/USAGE.md +111 -3
- package/docs/api/capture-native-raw-dng.md +6 -0
- package/docs/api/core-version.md +1 -1
- package/docs/api/equipment-generic-lens-catalogue.md +7 -2
- package/docs/api/exports.json +203 -3
- package/docs/api/exposure-filtered-exposure-time.md +105 -0
- package/docs/api/facade-develop-joined-parts.md +32 -0
- package/docs/api/facade-display-view-gpu.md +5 -2
- package/docs/api/facade-fast-methods.md +91 -0
- package/docs/api/facade-simulate-capture.md +72 -16
- package/docs/api/facade-simulate-display-view.md +3 -2
- package/docs/api/optics-aperture-diameter.md +51 -0
- package/docs/api/optics-detail-limit.md +203 -0
- package/docs/api/optics-generic-nd-filter-presets.md +34 -0
- package/docs/api/optics-lens-psf-profile.md +3 -1
- package/docs/api/output-crop-to-match-focal-length.md +67 -0
- package/docs/api/output-developed-lens-corrections.md +12 -0
- package/docs/api/output-generic-lens-corrections.md +3 -10
- package/docs/api/output-lens-corrections.md +11 -1
- package/docs/api/output-print-size-blur-noise.md +115 -0
- package/docs/api/sensor-sensor-characteristics.md +105 -0
- package/llms.txt +5 -0
- package/package.json +1 -1
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# exposure/filtered-exposure-time.ts public contracts
|
|
2
|
+
|
|
3
|
+
The package and root API versions are recorded once in [Navigation](../API_REFERENCE.md) · [Developer guide](https://github.com/Photivra/photivra/blob/main/docs/DEVELOPERS.md). Generated signatures retain independent schema/model versions. Only the exports listed here are root-package contracts; module-local helpers are not supported deep imports.
|
|
4
|
+
|
|
5
|
+
## calculateFilteredExposureTime
|
|
6
|
+
|
|
7
|
+
Shutter time that keeps the same exposure after adding front-of-lens filters, such as a
|
|
8
|
+
neutral-density (ND) filter: t / T, with T the combined transmittance of the filter profiles.
|
|
9
|
+
Aperture and ISO are unchanged.
|
|
10
|
+
|
|
11
|
+
Exact under the linear sensor model (exposure H = E·t); film reciprocity failure is not modelled.
|
|
12
|
+
Nominal filters vary: a "10-stop" or ND1000 (OD 3.0, 9.97 stops) filter transmits roughly, not
|
|
13
|
+
exactly, its rating, so the result is only as good as the profile. The envelope is an
|
|
14
|
+
approximation whenever any profile's `scientificStatus` is `"approximation"`.
|
|
15
|
+
|
|
16
|
+
Example: 1/125 s with `GENERIC_ND_FILTER_PROFILES[10]` (exactly 2^-10) gives 1024/125 = 8.192 s;
|
|
17
|
+
on a third-stop dial, 8 s.
|
|
18
|
+
|
|
19
|
+
```ts
|
|
20
|
+
export function calculateFilteredExposureTime(
|
|
21
|
+
input: CalculateFilteredExposureTimeInput
|
|
22
|
+
): CalculationResult<FilteredExposureTime>;
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
This call is synchronous; any supplied provider must follow its explicit synchronous contract.
|
|
26
|
+
|
|
27
|
+
## CalculateFilteredExposureTimeInput
|
|
28
|
+
|
|
29
|
+
The exact contract is declared below; use the domain guide for assumptions and staged integration.
|
|
30
|
+
|
|
31
|
+
```ts
|
|
32
|
+
export interface CalculateFilteredExposureTimeInput {
|
|
33
|
+
/** Shutter time without the filter, in seconds. */
|
|
34
|
+
shutterSeconds: number;
|
|
35
|
+
/**
|
|
36
|
+
* One front-of-lens filter profile, or several in light-path order (scene side first), as
|
|
37
|
+
* accepted by `composeFrontOfLensFilterTransmission`.
|
|
38
|
+
*/
|
|
39
|
+
filter: FrontOfLensFilterProfile | readonly FrontOfLensFilterProfile[];
|
|
40
|
+
/**
|
|
41
|
+
* Optional shutter dial, in seconds (for example `GENERIC_THIRD_STOP_SHUTTER_SECONDS`). When
|
|
42
|
+
* given, the result also reports the nearest dial value (nearest in stops, the shorter on a tie).
|
|
43
|
+
*/
|
|
44
|
+
shutterDialSeconds?: readonly number[];
|
|
45
|
+
/** Wavelength at which the filters are resolved. Defaults to 550 nm. Neutral filters do not depend on it. */
|
|
46
|
+
wavelengthNanometers?: number;
|
|
47
|
+
/** Wavelength basis; defaults to the first filter profile's basis and must match every profile. */
|
|
48
|
+
wavelengthBasis?: Exclude<SpectralWavelengthBasis, "unspecified">;
|
|
49
|
+
/** Incident polarization, which matters only when a polarizer is in the stack. Omitted means unpolarized. */
|
|
50
|
+
incidentPolarization?: LinearPolarizationState;
|
|
51
|
+
}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## FILTERED_EXPOSURE_DEFAULT_WAVELENGTH_NANOMETERS
|
|
55
|
+
|
|
56
|
+
Wavelength used when the caller gives none: 550 nm, near the photopic peak. Neutral filters do not depend on it.
|
|
57
|
+
|
|
58
|
+
```ts
|
|
59
|
+
FILTERED_EXPOSURE_DEFAULT_WAVELENGTH_NANOMETERS = 550 as const
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## FilteredExposureDialSetting
|
|
63
|
+
|
|
64
|
+
The dial value nearest the exact filtered shutter time.
|
|
65
|
+
|
|
66
|
+
```ts
|
|
67
|
+
export interface FilteredExposureDialSetting {
|
|
68
|
+
/** Nearest dial value in seconds. */
|
|
69
|
+
shutterSeconds: number;
|
|
70
|
+
/**
|
|
71
|
+
* log2(dial / exact filtered time): exposure of the dial setting relative to the unfiltered
|
|
72
|
+
* exposure, in stops. Positive is brighter (longer), negative darker.
|
|
73
|
+
*/
|
|
74
|
+
exposureErrorStops: number;
|
|
75
|
+
/** `"maximum"` when the exact time is longer than every dial value (use bulb for the exact time), `"minimum"` when shorter than every one. */
|
|
76
|
+
clamped: false | "minimum" | "maximum";
|
|
77
|
+
/** How the dial value was chosen. */
|
|
78
|
+
quantizationPolicy: "nearest-log2-shorter-on-tie";
|
|
79
|
+
}
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## FilteredExposureTime
|
|
83
|
+
|
|
84
|
+
The exact contract is declared below; use the domain guide for assumptions and staged integration.
|
|
85
|
+
|
|
86
|
+
```ts
|
|
87
|
+
export interface FilteredExposureTime {
|
|
88
|
+
/** Shutter time without the filter, in seconds. */
|
|
89
|
+
shutterSeconds: number;
|
|
90
|
+
/** Shutter time that gives the same exposure with the filter: shutterSeconds / linearTransmissionFactor. */
|
|
91
|
+
filteredShutterSeconds: number;
|
|
92
|
+
/** Combined intensity transmittance T of the filter stack, in (0, 1]. */
|
|
93
|
+
linearTransmissionFactor: number;
|
|
94
|
+
/** Combined attenuation −log2 T, in stops. */
|
|
95
|
+
attenuationStops: number;
|
|
96
|
+
/** Shutter multiplier 1/T = 2^attenuationStops. */
|
|
97
|
+
exposureFactor: number;
|
|
98
|
+
/** Wavelength at which the filters were resolved, in nanometres. */
|
|
99
|
+
wavelengthNanometers: number;
|
|
100
|
+
/** The filter-stack transmission this result is based on, with each filter's identity and evidence. */
|
|
101
|
+
filterTransmission: ComposedFrontOfLensFilterTransmission;
|
|
102
|
+
/** Nearest shutter-dial value; present only when `shutterDialSeconds` was given. */
|
|
103
|
+
dial?: FilteredExposureDialSetting;
|
|
104
|
+
}
|
|
105
|
+
```
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# facade/develop-joined-parts.ts public contracts
|
|
2
|
+
|
|
3
|
+
The package and root API versions are recorded once in [Navigation](../API_REFERENCE.md) · [Developer guide](https://github.com/Photivra/photivra/blob/main/docs/DEVELOPERS.md). Generated signatures retain independent schema/model versions. Only the exports listed here are root-package contracts; module-local helpers are not supported deep imports.
|
|
4
|
+
|
|
5
|
+
## simulateCaptureFromParts
|
|
6
|
+
|
|
7
|
+
Develops the whole frame of `options` from the packed RAW of region renders of the same request (#571), so a capture can
|
|
8
|
+
render its RAW in parallel parts and still take the development steps that filter across the whole image:
|
|
9
|
+
`output.diffractionCorrection` and `output.sharpening`, which a region render refuses, and `output.lensCorrections` (#570), which
|
|
10
|
+
runs on the whole developed frame here exactly as in `simulateCapture(options)`. The parts are joined exactly as
|
|
11
|
+
{@link serializeSimulatedCaptureDngFromParts } joins them (they must cover every native site and agree where they overlap),
|
|
12
|
+
and the joined RAW is the whole render's RAW, so the result's `image` (samples and JPEG or PNG bytes), `raw` codes and
|
|
13
|
+
`plan` are those of `simulateCapture(options)`, bit for bit.
|
|
14
|
+
|
|
15
|
+
`options` is the whole request (no `output.region`), with the development options it should have; render the parts with
|
|
16
|
+
the same request plus `output.region`, without `output.diffractionCorrection`, `output.sharpening` and `output.dng`, and with a
|
|
17
|
+
fixed white balance in place of `"auto"` (none of these change the RAW codes; auto white balance is measured here over the
|
|
18
|
+
joined frame). A part may keep or drop `output.lensCorrections` (a corrected region only widens its `region.nativeRect`).
|
|
19
|
+
Any `output.format` serves for a part.
|
|
20
|
+
|
|
21
|
+
`onProgress` reports the `white-balance` (with auto white balance), `development`, `diffraction-correction`, `sharpening` and
|
|
22
|
+
`jpeg` stages, the detail stages once per output row, so a host can show "Applying sharpening to the whole image". The lens
|
|
23
|
+
corrections report no stage of their own: they run between `diffraction-correction` and `sharpening`.
|
|
24
|
+
No `raw` stage is reported: no RAW is rendered. What differs from the whole render's result: `diagnostics.providerEvaluationCount`
|
|
25
|
+
is 0, `diagnostics.timingsMs` are this call's, `diagnostics.fast` and the `raw.*` assumptions of how the RAW was rendered are
|
|
26
|
+
not repeated (they are in the parts' results), and a `parts` assumption records the join.
|
|
27
|
+
|
|
28
|
+
```ts
|
|
29
|
+
export async function simulateCaptureFromParts(options: SimulateCaptureOptions, parts: readonly SimulateCaptureDngPart[]): Promise<SimulateCaptureResult>;
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
This call is asynchronous; byte hashing uses the caller runtime's Web Crypto.
|
|
@@ -81,13 +81,16 @@ export type DisplayViewGpuMode = "off" | "auto" | "require";
|
|
|
81
81
|
|
|
82
82
|
```ts
|
|
83
83
|
export interface PrepareDisplayViewOptions {
|
|
84
|
-
/**
|
|
84
|
+
/**
|
|
85
|
+
* See {@link DisplayViewGpuMode}. 2.20.0: default `"auto"` when the request resolves to fast (`fast` omitted or true: the
|
|
86
|
+
* display view's default) and `"off"` when it is exact (`fast: false`); an explicit value wins.
|
|
87
|
+
*/
|
|
85
88
|
gpu?: DisplayViewGpuMode;
|
|
86
89
|
/**
|
|
87
90
|
* Where the device comes from, with `gpu: "auto"` or `"require"`: a WebGPU entry point (a worker's `navigator.gpu`), or an
|
|
88
91
|
* `ImageKernelAccelerator` whose device the view shares (the accelerator keeps ownership; `dispose()` of the prepared view
|
|
89
92
|
* leaves it alone). Without it the engine acquires a device from `globalThis.navigator.gpu` and owns it until `dispose()`.
|
|
90
|
-
* Refused
|
|
93
|
+
* Refused when `gpu` is or defaults to `"off"`.
|
|
91
94
|
*/
|
|
92
95
|
gpuDevice?: unknown;
|
|
93
96
|
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# facade/fast-methods.ts public contracts
|
|
2
|
+
|
|
3
|
+
The package and root API versions are recorded once in [Navigation](../API_REFERENCE.md) · [Developer guide](https://github.com/Photivra/photivra/blob/main/docs/DEVELOPERS.md). Generated signatures retain independent schema/model versions. Only the exports listed here are root-package contracts; module-local helpers are not supported deep imports.
|
|
4
|
+
|
|
5
|
+
## SIMULATE_CAPTURE_FAST_METHODS
|
|
6
|
+
|
|
7
|
+
2.20.0: every speed-versus-accuracy choice of the capture facade and the display view (see the module comment).
|
|
8
|
+
|
|
9
|
+
```ts
|
|
10
|
+
SIMULATE_CAPTURE_FAST_METHODS: readonly SimulateCaptureFastMethod[] = Object.freeze([
|
|
11
|
+
{ id: "lens.catalogue/field-grid", override: "lens.catalogue", methods: "fast-and-exact", runs: ["simulateCapture"],
|
|
12
|
+
fast: "#568: the PSF blended over a field grid and tabulated expected electrons, verified per CFA phase against the exact chain",
|
|
13
|
+
exact: "the environment PSF quadrature with the PSF resolved at each query point", followsFormatDefault: true,
|
|
14
|
+
resolver: { file: CAPTURE, call: "resolveFast(catalogueFast, fastTop)" }, report: { applied: "lens.catalogue", assumption: "fast.lens.catalogue" } },
|
|
15
|
+
{ id: "lens.catalogue/cats-eye", override: "lens.catalogue", methods: "fast-and-exact", runs: ["simulateCapture", "simulateDisplayView", "prepareDisplayView"],
|
|
16
|
+
fast: "#567: with lens.defocus, the lens's bokeh without its cat's eye (the axis kernel everywhere)",
|
|
17
|
+
exact: "the cat's eye shaped at each field point (fast wides and normals)", followsFormatDefault: true,
|
|
18
|
+
resolver: { file: CAPTURE, call: "resolveFast(catalogueFast, fastTop)" }, report: { applied: "lens.catalogue", assumption: "fast.lens.catalogue.catsEye" } },
|
|
19
|
+
{ id: "lens.catalogue/view-psf-zones", override: "lens.catalogue", methods: "fast-and-exact", runs: ["simulateDisplayView", "prepareDisplayView"],
|
|
20
|
+
fast: "#569 (H1): 64 field zones along the longer side, each with the PSF at its centre",
|
|
21
|
+
exact: "one zone per site: the PSF at each site centre", followsFormatDefault: true,
|
|
22
|
+
resolver: { file: CAPTURE, call: "resolveFast(catalogueFast, fastTop)" }, report: { applied: "lens.catalogue", assumption: "view.lensPsf" } },
|
|
23
|
+
{ id: "lens.diffraction/rolling-shutter-taps", override: "lens.diffraction", methods: "fast-and-exact", runs: ["simulateCapture"],
|
|
24
|
+
fast: "#565: under rolling-shutter rotation, each PSF tap reads the scene at its own source point",
|
|
25
|
+
exact: "each tap reads the scene at its site-lattice point (ties on chart boundaries resolve as on the lattice)", followsFormatDefault: true,
|
|
26
|
+
resolver: { file: CAPTURE, call: "resolveFast(diffractionFast, fastTop)" }, report: { applied: "lens.diffraction", assumption: "fast.lens.diffraction" } },
|
|
27
|
+
{ id: "output.demosaic.ahd/view-low-signal-correction", override: "output.demosaic", methods: "fast-and-exact", runs: ["simulateDisplayView", "prepareDisplayView"],
|
|
28
|
+
fast: "(H3) 2048 draws per correction state, applied where a pixel's linear noise exceeds 0.01",
|
|
29
|
+
exact: "8192 draws per state, at the same 0.01 threshold", followsFormatDefault: true,
|
|
30
|
+
resolver: { file: CAPTURE, call: "resolveFast(demosaicFast, fastTop)" }, report: { applied: "output.demosaic.ahd", assumption: "view.demosaic" } },
|
|
31
|
+
{ id: "view.uniform-pixel-sampling", override: "fast", methods: "fast-and-exact", runs: ["simulateDisplayView", "prepareDisplayView"],
|
|
32
|
+
fast: "(H2) a quarter of the samples per axis in display pixels whose pilot finds no detail",
|
|
33
|
+
exact: "the full samples per axis in every display pixel", followsFormatDefault: true,
|
|
34
|
+
resolver: { file: CAPTURE, call: "uniformSampling: fastTop" }, report: { assumption: "view.estimation" } },
|
|
35
|
+
{ id: "prepareDisplayView.gpu", override: "fast", methods: "fast-and-exact", runs: ["prepareDisplayView"],
|
|
36
|
+
fast: "gpu \"auto\": WebGPU float32 where a conforming device supports the request (a bounded approximation), else the CPU reference",
|
|
37
|
+
exact: "gpu \"off\": the CPU reference; an explicit gpu wins", followsFormatDefault: true,
|
|
38
|
+
resolver: { file: VIEW, call: "parsePrepareDisplayViewOptions(prepareOptions, (options as { fast?: unknown } | null | undefined)?.fast !== false)" },
|
|
39
|
+
report: { field: "diagnostics.fast.execution" } },
|
|
40
|
+
{ id: "sensor.midGrey", override: "fast", methods: "fast-and-exact", runs: ["simulateCapture", "simulateDisplayView", "prepareDisplayView"],
|
|
41
|
+
fast: "#535: the mid-gray noise figure is not computed (about 0.3 ms)", exact: "result.sensor.midGrey is computed", followsFormatDefault: true,
|
|
42
|
+
resolver: { file: CAPTURE, call: "fastTop ? undefined : 0" }, report: { field: "sensor.midGrey" } },
|
|
43
|
+
{ id: "lens.diffraction", override: "lens.diffraction", methods: "exact-only", runs: ["simulateCapture", "simulateDisplayView", "prepareDisplayView"],
|
|
44
|
+
fast: "", exact: "the diffraction kernels (a fast method only under rolling-shutter rotation, above)", followsFormatDefault: true,
|
|
45
|
+
resolver: { file: CAPTURE, call: "resolveFast(diffractionFast, fastTop)" }, report: { applied: "lens.diffraction" } },
|
|
46
|
+
{ id: "sensor.antiAliasing", override: "sensor.antiAliasing", methods: "exact-only", runs: ["simulateCapture", "simulateDisplayView", "prepareDisplayView"],
|
|
47
|
+
fast: "", exact: "the point-splitting filter", followsFormatDefault: true,
|
|
48
|
+
resolver: { file: CAPTURE, call: "fastInUse" }, report: { applied: "sensor.antiAliasing" } },
|
|
49
|
+
{ id: "sensor.pixelAperture.box", override: "sensor.pixelAperture", methods: "exact-only", runs: ["simulateCapture", "simulateDisplayView", "prepareDisplayView"],
|
|
50
|
+
fast: "", exact: "the N × N midpoint rule", followsFormatDefault: true,
|
|
51
|
+
resolver: { file: CAPTURE, call: "fastInUse" }, report: { applied: "sensor.pixelAperture.box" } },
|
|
52
|
+
{ id: "output.demosaic.ahd", override: "output.demosaic", methods: "exact-only", runs: ["simulateCapture"],
|
|
53
|
+
fast: "", exact: "the AHD demosaic of the capture (a fast method only in the display view's correction, above)", followsFormatDefault: true,
|
|
54
|
+
resolver: { file: CAPTURE, call: "resolveFast(demosaicFast, fastTop)" }, report: { applied: "output.demosaic.ahd" } }
|
|
55
|
+
] as const satisfies readonly SimulateCaptureFastMethod[])
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## SimulateCaptureFastMethod
|
|
59
|
+
|
|
60
|
+
One speed-versus-accuracy choice of {@link SIMULATE_CAPTURE_FAST_METHODS} (2.20.0).
|
|
61
|
+
|
|
62
|
+
```ts
|
|
63
|
+
export interface SimulateCaptureFastMethod {
|
|
64
|
+
/** A short id: the option path and, where one option has several fast methods, the method. */
|
|
65
|
+
id: string;
|
|
66
|
+
/**
|
|
67
|
+
* The request path whose record takes the `fast` override (`allowKeys` path in simulate-capture.ts), or "fast" when only the
|
|
68
|
+
* top-level flag sets it (a choice with no option record of its own).
|
|
69
|
+
*/
|
|
70
|
+
override: string;
|
|
71
|
+
/** "fast-and-exact": both methods exist; "exact-only": the record takes `fast`, but there is no fast method yet (reports false). */
|
|
72
|
+
methods: "fast-and-exact" | "exact-only";
|
|
73
|
+
/** Where it applies. */
|
|
74
|
+
runs: readonly ("simulateCapture" | "simulateDisplayView" | "prepareDisplayView")[];
|
|
75
|
+
/** The fast method and the exact one, in words (empty for exact-only). */
|
|
76
|
+
fast: string;
|
|
77
|
+
exact: string;
|
|
78
|
+
/** Always true: no choice keeps its own default (the test checks it). */
|
|
79
|
+
followsFormatDefault: true;
|
|
80
|
+
/**
|
|
81
|
+
* The resolver call in the source (`resolveFast(<record flag>, fastTop)`, or `fastTop` itself for a top-level choice), which the
|
|
82
|
+
* test finds in the named file.
|
|
83
|
+
*/
|
|
84
|
+
resolver: { file: string; call: string };
|
|
85
|
+
/**
|
|
86
|
+
* How the result reports it: the `diagnostics.fast.applied` key (true where the fast method ran), an assumption id the fast
|
|
87
|
+
* method adds, or another result field. At least one; the test finds each assumption id in the source.
|
|
88
|
+
*/
|
|
89
|
+
report: { applied?: string; assumption?: string; field?: string };
|
|
90
|
+
}
|
|
91
|
+
```
|
|
@@ -66,6 +66,8 @@ export interface DisplayViewResult {
|
|
|
66
66
|
/** #516: as in the capture result. */
|
|
67
67
|
isoControl: "manual" | "automatic"; autoIso?: SimulateCaptureAutoIsoReport };
|
|
68
68
|
scene: SimulateCaptureResult["scene"];
|
|
69
|
+
/** #555, #535: as in the capture result. */
|
|
70
|
+
sensor: SimulateCaptureSensorReport;
|
|
69
71
|
/**
|
|
70
72
|
* Work done: real pixels sampled, real-site expectations evaluated, scene queries, display pixels sampled in full (detail) or with
|
|
71
73
|
* a quarter of the samples per axis (uniform), display pixels whose value includes the AHD low-signal correction, and wall-clock
|
|
@@ -144,7 +146,7 @@ a capture does. `motion.rotation` is a non-zero angular velocity; `sensor.tempor
|
|
|
144
146
|
SIMULATE_CAPTURE_COST_OPTIONS = Object.freeze(["lens.pupilSampling", "lens.projection", "lens.distortion", "lens.vignetting", "lens.psf",
|
|
145
147
|
"lens.diffraction", "lens.defocus", "lens.catalogue", "sensor.antiAliasing", "sensor.pixelAperture.box", "sensor.temporalSampleCount", "motion.rotation", "motion.shutter.rolling", "output.borderHandling.mirror", "output.region",
|
|
146
148
|
"output.whiteBalance.auto", "output.demosaic.ahd", "output.highlightMode.reconstruct", "output.colorEncoding.wide-gamut", "output.gamutMapping.perceptual",
|
|
147
|
-
"output.diffractionCorrection", "output.sharpening", "output.format.jpeg", "output.format.png", "output.format.dng"] as const)
|
|
149
|
+
"output.diffractionCorrection", "output.sharpening", "output.lensCorrections", "output.format.jpeg", "output.format.png", "output.format.dng"] as const)
|
|
148
150
|
```
|
|
149
151
|
|
|
150
152
|
## SIMULATE_CAPTURE_DEFAULT_ILLUMINANCE_LUX
|
|
@@ -425,6 +427,12 @@ One part of a whole-frame DNG (#391): a region render's packed RAW and where its
|
|
|
425
427
|
export interface SimulateCaptureDngPart {
|
|
426
428
|
raw: Pick<NativeRawOutput, "codes" | "blackLevels" | "digitalSaturationCodes" | "saturationFlags" | "effectiveSaturationCodes">;
|
|
427
429
|
region: { nativeRect: { x: number; y: number; width: number; height: number } };
|
|
430
|
+
/**
|
|
431
|
+
* 2.20.0: true when a fast method ran for this part (`Object.values(result.diagnostics.fast.applied).includes(true)`). The join
|
|
432
|
+
* refuses such a part unless its own request resolves to fast too (a DNG, JPEG or PNG is exact by default): render the parts with
|
|
433
|
+
* the same `fast` as the join, or with `fast: false`.
|
|
434
|
+
*/
|
|
435
|
+
fast?: boolean;
|
|
428
436
|
}
|
|
429
437
|
```
|
|
430
438
|
|
|
@@ -450,8 +458,10 @@ export type SimulateCaptureFastOption = typeof SIMULATE_CAPTURE_FAST_OPTIONS[num
|
|
|
450
458
|
|
|
451
459
|
```ts
|
|
452
460
|
export interface SimulateCaptureFastReport {
|
|
453
|
-
/**
|
|
461
|
+
/** 2.20.0: the resolved top-level value (`fast`, else the format default), or true when any option's record sets `fast: true`. */
|
|
454
462
|
requested: boolean;
|
|
463
|
+
/** 2.20.0: where the top-level value came from: the request's `fast`, or the format default (see {@link SimulateCaptureOptions.fast}). */
|
|
464
|
+
defaultedFrom: "request" | "format";
|
|
455
465
|
/** Each fast-capable option that ran, in {@link SIMULATE_CAPTURE_FAST_OPTIONS} order: true where its fast method ran. */
|
|
456
466
|
applied: Readonly<Partial<Record<SimulateCaptureFastOption, boolean>>>;
|
|
457
467
|
/** `engine-reference` when every option ran exact; `approximation-with-a-priori-bound` when any fast method ran (the WebGPU execution record's values). */
|
|
@@ -462,11 +472,30 @@ export interface SimulateCaptureFastReport {
|
|
|
462
472
|
## SimulateCaptureLensCatalogueRecord
|
|
463
473
|
|
|
464
474
|
`lens.catalogue` as a record (#568): the lens id as `kind` and the `fast` override (see {@link SimulateCaptureOptions.fast}).
|
|
475
|
+
Fast: the tabulated fast method (#568), and with `lens.defocus` the lens's bokeh without its cat's eye (#567; fast wides and
|
|
476
|
+
normals only), whose field-varying PSF needs a finer fast grid (measured 2.2–3.4× slower). Exact: the per-site PSF with the
|
|
477
|
+
cat's eye. Blades and spherical aberration always apply (they cost nothing).
|
|
465
478
|
|
|
466
479
|
```ts
|
|
467
480
|
export interface SimulateCaptureLensCatalogueRecord { kind: string; fast?: boolean }
|
|
468
481
|
```
|
|
469
482
|
|
|
483
|
+
## SimulateCaptureLensCorrections
|
|
484
|
+
|
|
485
|
+
`output.lensCorrections` (#570): which of the catalogue lens's generic corrections (`createGenericLensCorrectionProfile`) the
|
|
486
|
+
development applies. Each is off unless set to true.
|
|
487
|
+
|
|
488
|
+
```ts
|
|
489
|
+
export interface SimulateCaptureLensCorrections {
|
|
490
|
+
/** Radial distortion r_d = r(1 + k1ρ²), inverted by resampling: it stretches the corners and lowers their resolution. */
|
|
491
|
+
distortion?: boolean;
|
|
492
|
+
/** Lateral colour: each channel rescaled by 1/(1 + L·D(λ_c)) into register; axial (longitudinal) colour stays. */
|
|
493
|
+
lateralColor?: boolean;
|
|
494
|
+
/** Vignetting: a gain 1/E(ρ) at each pixel's source point; corner noise rises with the signal, the SNR does not. */
|
|
495
|
+
vignetting?: boolean;
|
|
496
|
+
}
|
|
497
|
+
```
|
|
498
|
+
|
|
470
499
|
## SimulateCaptureLensDistortion
|
|
471
500
|
|
|
472
501
|
The exact contract is declared below; use the domain guide for assumptions and staged integration.
|
|
@@ -531,7 +560,8 @@ export interface SimulateCaptureOptions {
|
|
|
531
560
|
* distance beyond the focal length (no minimum focus distance; `subjectDistanceM` must be at least twice the focal length, as for
|
|
532
561
|
* every lens). Works in `simulateCapture` and the display view. Not combinable with `prime`, `catalogue` or `focalLengthMm`.
|
|
533
562
|
* Optional `widestFNumber` and `narrowestFNumber` (within `IDEAL_LENS_LIMITS`, widest ≤ narrowest; each defaults to its bound)
|
|
534
|
-
* narrow the range: `fNumber` must lie in it, and shutter priority and program choose apertures only in it
|
|
563
|
+
* narrow the range: `fNumber` must lie in it, and shutter priority and program choose apertures only in it (program limits its
|
|
564
|
+
* line to a range that does not hold f/4–f/16, #583). Default off.
|
|
535
565
|
*/
|
|
536
566
|
ideal?: { focalLengthMm: number; widestFNumber?: number; narrowestFNumber?: number };
|
|
537
567
|
/**
|
|
@@ -540,9 +570,9 @@ export interface SimulateCaptureOptions {
|
|
|
540
570
|
* factor and it replaces the tier lens's focal length and f-number range (the transmission is kept). The capture renders the
|
|
541
571
|
* lens's character, all labelled approximations: its PSF (diffraction with the lens's Seidel aberrations, axial and lateral
|
|
542
572
|
* colour, at the resolved f-number and focus) through the environment PSF quadrature, its radial distortion, its vignetting
|
|
543
|
-
* and, for the fisheyes, the equisolid projection. Flare
|
|
573
|
+
* and, for the fisheyes, the equisolid projection. Flare and focus breathing are not rendered. Not combinable
|
|
544
574
|
* with `prime`, `focalLengthMm`, `projection`, `distortion`, `vignetting`, `psf`, `diffraction` or `pupilSampling` (the
|
|
545
|
-
* lens sets them); `defocus` convolves the
|
|
575
|
+
* lens sets them); `defocus` convolves the lens's bokeh kernel (#567) into its PSF. The display view renders it with the PSF taken per field zone (#569; docs/DISPLAY_VIEW.md). Default off.
|
|
546
576
|
* #568: the record form `{ kind: <lens id>, fast }` overrides the top-level `fast` flag for this option; the fast method
|
|
547
577
|
* blends the PSF between exactly resolved kernels on a field grid and tabulates each site's expected signal
|
|
548
578
|
* (docs/LENS_CATALOGUE.md, "Fast method").
|
|
@@ -683,7 +713,7 @@ export interface SimulateCaptureOptions {
|
|
|
683
713
|
exposureCompensationStops?: number;
|
|
684
714
|
/** Default "scene-illuminant". */
|
|
685
715
|
whiteBalance?: SimulateCaptureWhiteBalance;
|
|
686
|
-
/** JPEG constant quantization step 1-255 (not a manufacturer 'quality'). Default 2. */
|
|
716
|
+
/** JPEG constant quantization step 1-255 (not a manufacturer 'quality'). Default 1 (2.20.0; 2 before), the full-quality export. */
|
|
687
717
|
jpegQuantizationStep?: number;
|
|
688
718
|
/** PNG only. Default "srgb". */
|
|
689
719
|
colorEncoding?: SimulateCaptureColorEncoding;
|
|
@@ -698,8 +728,13 @@ export interface SimulateCaptureOptions {
|
|
|
698
728
|
demosaic?: SimulateCaptureDemosaic | SimulateCaptureDemosaicRecord;
|
|
699
729
|
/** Default "margin". */
|
|
700
730
|
borderHandling?: SimulateCaptureBorderHandling;
|
|
701
|
-
/**
|
|
702
|
-
|
|
731
|
+
/**
|
|
732
|
+
* DNG only: optional capture-event time (YYYY-MM-DDTHH:mm:ss.sssZ); without it no date tags are written. Opt-in (#587), with
|
|
733
|
+
* `lens.catalogue`: `lensCorrectionOpcodes` writes the selected corrections of {@link SimulateCaptureLensCorrections} into the DNG as
|
|
734
|
+
* optional DNG opcodes in OpcodeList3 (FixVignetteRadial, WarpRectilinear with the zoom-to-fill; docs/NATIVE_RAW_AND_PRINT.md), for RAW editors
|
|
735
|
+
* that apply them; the RAW codes are unchanged. Whole frame only (no `region`). All off (or omitted): the same DNG bytes as without it.
|
|
736
|
+
*/
|
|
737
|
+
dng?: { capturedAtUtc?: string; lensCorrectionOpcodes?: SimulateCaptureLensCorrections };
|
|
703
738
|
/**
|
|
704
739
|
* Opt-in (2.4) text written into the file for formats "jpeg", "png" and "dng": the caller's description,
|
|
705
740
|
* software, copyright and comment, unchanged (JPEG XMP + COM, PNG tEXt/iTXt, DNG TIFF tags + XMP; see the
|
|
@@ -738,10 +773,21 @@ export interface SimulateCaptureOptions {
|
|
|
738
773
|
* (not the wide-gamut or perceptual PNG paths); not combinable with `region`. The DNG's RAW codes are not changed. Default off.
|
|
739
774
|
*/
|
|
740
775
|
sharpening?: SimulateCaptureSharpening;
|
|
776
|
+
/**
|
|
777
|
+
* Opt-in (#570), with `lens.catalogue`: the lens's generic corrections (see {@link SimulateCaptureLensCorrections}) on the
|
|
778
|
+
* developed linear colour, after demosaic, colour, white balance and `diffractionCorrection`, before the tone curve; for the JPEG,
|
|
779
|
+
* PNG and samples. The RAW and the DNG are never corrected. To keep the output size with no missing pixels, the corrected image is
|
|
780
|
+
* magnified by the smallest factor 1/m ≥ 1 that keeps every pixel's source inside the frame (recorded in the
|
|
781
|
+
* `output.lensCorrections` assumption). Works with `region`: a region develops the frame pixels its corrected pixels read
|
|
782
|
+
* (`region.nativeRect`, `raw` and `plan` describe that rectangle) and its pixels are the whole render's. All off (or omitted):
|
|
783
|
+
* the development is unchanged.
|
|
784
|
+
*/
|
|
785
|
+
lensCorrections?: SimulateCaptureLensCorrections;
|
|
741
786
|
};
|
|
742
787
|
/** Camera motion and shutter type. Default: still camera, global electronic shutter. */
|
|
743
788
|
motion?: SimulateCaptureMotion;
|
|
744
|
-
sensor
|
|
789
|
+
/** #555: plus the sensor characteristics ({@link SimulateCaptureSensorCharacteristics}), each off by default. */
|
|
790
|
+
sensor?: SimulateCaptureSensorCharacteristics & {
|
|
745
791
|
/**
|
|
746
792
|
* Pixel pitch in micrometres, 0.5–1000. Default 6. The simulated sensor is output width × pitch wide. 2.5: above 100 µm the
|
|
747
793
|
* capture is a downsized view of a whole frame (for example 36 mm / 48 pixels = 750 µm), recorded in the assumption
|
|
@@ -768,15 +814,19 @@ export interface SimulateCaptureOptions {
|
|
|
768
814
|
pixelAperture?: SimulateCapturePixelAperture;
|
|
769
815
|
};
|
|
770
816
|
/**
|
|
771
|
-
* Exact or fast (#395). `false
|
|
772
|
-
*
|
|
773
|
-
*
|
|
774
|
-
*
|
|
817
|
+
* Exact or fast (#395). `false`: every option runs its exact method, the engine reference. `true`: each option listed in
|
|
818
|
+
* {@link SIMULATE_CAPTURE_FAST_OPTIONS} runs its fast method where it has one, a measured, bounded approximation of the exact
|
|
819
|
+
* one; an option without a fast method runs exact. An option's own record `fast` overrides this for that option only.
|
|
820
|
+
* Omitted (2.20.0), the format decides: fast for `output.format` "srgb-8" and "srgb-16" and for the display view, exact for
|
|
821
|
+
* "dng", "jpeg" and "png" (exports) and for `simulateIdealReference`. `diagnostics.fast` reports the resolved value, where it
|
|
822
|
+
* came from and what ran. Fast methods: `lens.catalogue` (#568, #567) and `lens.diffraction` under rolling-shutter rotation
|
|
823
|
+
* (#565); in the display view also its catalogue PSF zones, its sampling of uniform pixels and its AHD low-signal correction
|
|
824
|
+
* (docs/DISPLAY_VIEW.md). The exact result also carries `result.sensor.midGrey` (#535). Calculators should pass `fast: false`.
|
|
775
825
|
*/
|
|
776
826
|
fast?: boolean;
|
|
777
827
|
/** Aborting cancels the running task; the promise rejects with a domain error and returns no partial image. */
|
|
778
828
|
signal?: AbortSignal;
|
|
779
|
-
/** Called after each committed RAW, development or JPEG tile. Cannot change output. */
|
|
829
|
+
/** Called after each committed RAW, development, detail or JPEG tile (see {@link SimulateCaptureProgress}). Cannot change output. */
|
|
780
830
|
onProgress?: (progress: SimulateCaptureProgress) => void;
|
|
781
831
|
}
|
|
782
832
|
```
|
|
@@ -799,11 +849,15 @@ export type SimulateCapturePixelAperture = "point" | "box" | { kind: "box"; samp
|
|
|
799
849
|
|
|
800
850
|
## SimulateCaptureProgress
|
|
801
851
|
|
|
802
|
-
|
|
852
|
+
One progress event of `onProgress`. Stages run in this order: `raw`, `white-balance` (with auto white balance), `development`
|
|
853
|
+
(rows), then, when requested, `diffraction-correction` and `sharpening` (#571: one event per output row of the whole image;
|
|
854
|
+
each stage's last event has `completedTileCount === totalTileCount`), then `jpeg`. `output.lensCorrections` (#570) runs between
|
|
855
|
+
`diffraction-correction` and `sharpening` and reports no stage of its own. {@link simulateCaptureFromParts }
|
|
856
|
+
reports no `raw` stage: its RAW comes from the parts.
|
|
803
857
|
|
|
804
858
|
```ts
|
|
805
859
|
export interface SimulateCaptureProgress {
|
|
806
|
-
stage: "raw" | "white-balance" | "development" | "jpeg";
|
|
860
|
+
stage: "raw" | "white-balance" | "development" | "diffraction-correction" | "sharpening" | "jpeg";
|
|
807
861
|
completedTileCount: number;
|
|
808
862
|
totalTileCount: number;
|
|
809
863
|
}
|
|
@@ -963,6 +1017,8 @@ export interface SimulateCaptureResult {
|
|
|
963
1017
|
limitations: readonly string[];
|
|
964
1018
|
};
|
|
965
1019
|
assumptions: readonly SimulateCaptureAssumption[];
|
|
1020
|
+
/** #555, #535: the sensor characteristics used, the calculated dynamic range and (when the request resolves to exact) the mid-grey noise figure. */
|
|
1021
|
+
sensor: SimulateCaptureSensorReport;
|
|
966
1022
|
}
|
|
967
1023
|
```
|
|
968
1024
|
|
|
@@ -65,9 +65,10 @@ responses through the environment chain, the diffraction kernels, readout moment
|
|
|
65
65
|
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;
|
|
66
66
|
errors in the view by `render`.
|
|
67
67
|
|
|
68
|
-
2.11 (#481): `prepareOptions.gpu` chooses the renderer: `"off"`
|
|
68
|
+
2.11 (#481): `prepareOptions.gpu` chooses the renderer: `"off"` is the CPU reference, today's bytes; `"auto"` renders
|
|
69
69
|
on WebGPU when a conforming device is available and the request is supported, else on the CPU, labelled; `"require"` fails
|
|
70
|
-
instead of falling back (`ImageKernelExecutionError`, acquisition failures here, later ones from `render`).
|
|
70
|
+
instead of falling back (`ImageKernelExecutionError`, acquisition failures here, later ones from `render`). 2.20.0: the default is
|
|
71
|
+
`"auto"` when the request resolves to fast (the view's default) and `"off"` with `fast: false`. `gpuDevice` is a
|
|
71
72
|
WebGPU entry point or an `ImageKernelAccelerator` whose device the view shares; without it the engine acquires one device
|
|
72
73
|
for the prepared view (the request's `signal` aborts the acquisition) and `dispose()` releases it. The realm's
|
|
73
74
|
`setWebGpuEnabled(false)` vetoes both GPU modes (`webgpu-disabled`). See docs/DISPLAY_VIEW.md, "Rendering on the GPU".
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# optics/aperture-diameter.ts public contracts
|
|
2
|
+
|
|
3
|
+
The package and root API versions are recorded once in [Navigation](../API_REFERENCE.md) · [Developer guide](https://github.com/Photivra/photivra/blob/main/docs/DEVELOPERS.md). Generated signatures retain independent schema/model versions. Only the exports listed here are root-package contracts; module-local helpers are not supported deep imports.
|
|
4
|
+
|
|
5
|
+
## ApertureDiameter
|
|
6
|
+
|
|
7
|
+
The exact contract is declared below; use the domain guide for assumptions and staged integration.
|
|
8
|
+
|
|
9
|
+
```ts
|
|
10
|
+
export interface ApertureDiameter {
|
|
11
|
+
/** Focal length supplied by the caller, in millimetres. */
|
|
12
|
+
focalLengthMm: number;
|
|
13
|
+
/** f-number supplied by the caller. */
|
|
14
|
+
fNumber: number;
|
|
15
|
+
/** Entrance-pupil diameter D = focalLengthMm / fNumber, in millimetres. */
|
|
16
|
+
entrancePupilDiameterMm: number;
|
|
17
|
+
}
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## calculateApertureDiameter
|
|
21
|
+
|
|
22
|
+
Entrance-pupil (aperture) diameter in millimetres: focal length ÷ f-number.
|
|
23
|
+
|
|
24
|
+
Exact by the definition of the f-number for an ideal lens focused at infinity. It is the
|
|
25
|
+
entrance pupil (the aperture stop as seen from the front), not the diaphragm's physical
|
|
26
|
+
opening. Close focus (working f-number N·(1 + m/P) with pupil magnification P) and focal-length
|
|
27
|
+
changes while focusing are not modelled.
|
|
28
|
+
|
|
29
|
+
Example: 50 mm at f/2 gives 25 mm; at f/4, 12.5 mm (half the diameter, a quarter of the area:
|
|
30
|
+
two stops).
|
|
31
|
+
|
|
32
|
+
```ts
|
|
33
|
+
export function calculateApertureDiameter(
|
|
34
|
+
input: CalculateApertureDiameterInput
|
|
35
|
+
): CalculationResult<ApertureDiameter>;
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
This call is synchronous; any supplied provider must follow its explicit synchronous contract.
|
|
39
|
+
|
|
40
|
+
## CalculateApertureDiameterInput
|
|
41
|
+
|
|
42
|
+
The exact contract is declared below; use the domain guide for assumptions and staged integration.
|
|
43
|
+
|
|
44
|
+
```ts
|
|
45
|
+
export interface CalculateApertureDiameterInput {
|
|
46
|
+
/** Focal length of the lens in millimetres (the physical focal length, not a 35 mm equivalent). */
|
|
47
|
+
focalLengthMm: number;
|
|
48
|
+
/** f-number set on the lens (N = focal length / entrance-pupil diameter). */
|
|
49
|
+
fNumber: number;
|
|
50
|
+
}
|
|
51
|
+
```
|