@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
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"geometric-transforms.js","sourceRoot":"","sources":["../../src/output/geometric-transforms.ts"],"names":[],"mappings":"AAAA,sCAAsC;AAEtC;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,mBAAmB,EAA0B,MAAM,+BAA+B,CAAC;AAC5F,OAAO,EAAE,2BAA2B,EAAE,MAAM,uBAAuB,CAAC;AACpE,OAAO,EACL,gCAAgC,EAAE,uCAAuC,EACzE,+BAA+B,EAChC,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,+BAA+B,CAAC;AAClG,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AACpF,OAAO,EACL,wBAAwB,EAAE,wBAAwB,EAAE,qCAAqC,EAE1F,MAAM,uCAAuC,CAAC;AAC/C,OAAO,EACL,wBAAwB,EAAE,6BAA6B,EAAE,wBAAwB,EAElF,MAAM,8BAA8B,CAAC;AAgGtC,SAAS,KAAK,CAAC,KAAc;IAC3B,MAAM,CAAC,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC;IACpC,OAAO,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC;AACtD,CAAC;AACD,SAAS,QAAQ,CAAC,CAAoB,EAAE,CAAoB;IAC1D,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,GAAC,CAAC,CAAC,CAAC,CAAC,GAAC,CAAC,CAAC,CAAC,CAAC,GAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAC,CAAC,CAAC,CAAC,CAAC,GAAC,CAAC,CAAC,CAAC,CAAC,GAAC,CAAC,CAAC,CAAC,CAAC;QAC9C,CAAC,CAAC,CAAC,CAAC,GAAC,CAAC,CAAC,CAAC,CAAC,GAAC,CAAC,CAAC,CAAC,CAAC,GAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAC,CAAC,CAAC,CAAC,CAAC,GAAC,CAAC,CAAC,CAAC,CAAC,GAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC9C,CAAC;AACD,SAAS,WAAW,CAAC,CAAoB,IAAY,OAAO,CAAC,CAAC,CAAC,CAAC,GAAC,CAAC,CAAC,CAAC,CAAC,GAAC,CAAC,CAAC,CAAC,CAAC,GAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAClF,SAAS,OAAO,CAAC,CAAoB;IACnC,MAAM,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC;IACzB,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,KAAK;QAAE,MAAM,IAAI,2BAA2B,CAAC,yCAAyC,CAAC,CAAC;IACjI,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,GAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAC,CAAC,CAAC,CAAC;AAC5C,CAAC;AACD,SAAS,MAAM,CAAC,CAAmB,EAAE,CAAoB,EAAE,CAAmB;IAC5E,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAC,CAAC,CAAC,CAAC,GAAC,CAAC,CAAC,CAAC,CAAC,GAAC,CAAC,CAAC,CAAC,GAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAC,CAAC,CAAC,CAAC,GAAC,CAAC,CAAC,CAAC,CAAC,GAAC,CAAC,CAAC,CAAC,GAAC,CAAC,CAAC,CAAC,EAAE,CAAC;AAChE,CAAC;AACD,iHAAiH;AACjH,MAAM,UAAU,8BAA8B,CAAC,KAAc;IAC3D,MAAM,CAAC,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,SAAS;QACpG,uBAAuB,EAAE,kBAAkB,CAAC,CAAC,CAAC;IAChD,MAAM,QAAQ,GAAG;QACf,EAAE,EAAE,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC;QAClD,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,aAAa,EAAE,sBAAsB,EAAE,kBAAkB,CAAC,CAAC;QACrF,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,YAAY,EAAE,WAAW,EAAE,uBAAuB,EAAE,kBAAkB,EAAE,YAAY,EAAE,YAAY,CAAC,CAAC;KACjI,CAAC;IACF,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,QAAQ,EAAE,QAAQ,EAAE,eAAe,EAAE,kBAAkB,CAAC,CAAC,CAAC;IACvF,IAAI,CAAC,IAAI,KAAK,kBAAkB,CAAC,KAAK,CAAC,QAAQ,CAAC,OAAO,KAAK,YAAY,CAAC,EAAE,CAAC;QAC1E,MAAM,IAAI,2BAA2B,CAAC,wEAAwE,CAAC,CAAC;IAClH,CAAC;IACD,IAAI,IAAI,KAAK,kBAAkB,IAAI,CAAC,CAAC,CAAC,qBAAqB,KAAK,SAAS,IAAI,CAAC,CAAC,gBAAgB,KAAK,SAAS,CAAC,EAAE,CAAC;QAC/G,MAAM,IAAI,2BAA2B,CAAC,iEAAiE,CAAC,CAAC;IAC3G,CAAC;IACD,IAAI,IAAI,KAAK,kBAAkB,EAAE,CAAC;QAChC,IAAI,CAAC,CAAC,MAAM,KAAK,SAAS,IAAI,CAAC,CAAC,QAAQ,KAAK,SAAS,IAAI,CAAC,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;YAClF,MAAM,IAAI,2BAA2B,CAAC,8DAA8D,CAAC,CAAC;QACxG,CAAC;QACD,MAAM,UAAU,GAAG,CAAC,CAAU,EAAkC,EAAE;YAChE,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,EAAE,CAAC,iBAAiB,EAAE,eAAe,CAAC,CAAC,CAAC;YAC1D,OAAO,EAAE,eAAe,EAAE,wBAAwB,CAAC,CAAC,CAAC,eAAe,CAAC,EAAE,aAAa,EAAE,QAAQ,CAAC,CAAC,CAAC,aAAa,EAAE,eAAe,CAAC,EAAE,CAAC;QACrI,CAAC,CAAC;QACF,OAAO,EAAE,GAAG,QAAQ,EAAE,IAAI,EAAE,qBAAqB,EAAE,UAAU,CAAC,CAAC,CAAC,qBAAqB,CAAC,EAAE,gBAAgB,EAAE,UAAU,CAAC,CAAC,CAAC,gBAAgB,CAAC,EAAE,CAAC;IAC7I,CAAC;IACD,IAAI,IAAI,KAAK,eAAe,EAAE,CAAC;QAC7B,IAAI,CAAC,CAAC,MAAM,KAAK,SAAS,IAAI,CAAC,CAAC,QAAQ,KAAK,SAAS;YAAE,MAAM,IAAI,2BAA2B,CAAC,iDAAiD,CAAC,CAAC;QACjJ,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,uBAAuB,EAAE,yBAAyB,EAAE,cAAc,CAAC,CAAC,CAAC;QAClG,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,YAAY,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;QACjE,MAAM,OAAO,GAAG,EAAE,qBAAqB,EAAE,QAAQ,CAAC,CAAC,CAAC,qBAAqB,EAAE,uBAAuB,CAAC;YACjG,uBAAuB,EAAE,QAAQ,CAAC,CAAC,CAAC,uBAAuB,EAAE,yBAAyB,CAAC;YACvF,YAAY,EAAE,EAAE,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC;QAC7I,qCAAqC,CAAC,OAAO,CAAC,CAAC;QAC/C,OAAO,EAAE,GAAG,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;IACxC,CAAC;IACD,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;QACtB,IAAI,CAAC,CAAC,OAAO,KAAK,SAAS;YAAE,MAAM,IAAI,2BAA2B,CAAC,2CAA2C,CAAC,CAAC;QAChH,MAAM,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC;QAClE,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;YAAE,MAAM,IAAI,2BAA2B,CAAC,gCAAgC,CAAC,CAAC;QAClG,MAAM,MAAM,GAAG,OAA2C,CAAC;QAC3D,OAAO,CAAC,MAAM,CAAC,CAAC;QAChB,OAAO,EAAE,GAAG,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC;IACpE,CAAC;IACD,IAAI,CAAC,CAAC,MAAM,KAAK,SAAS,IAAI,CAAC,CAAC,QAAQ,KAAK,SAAS;QAAE,MAAM,IAAI,2BAA2B,CAAC,0CAA0C,CAAC,CAAC;IAC1I,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,uBAAuB,EAAE,yBAAyB,EAAE,cAAc,CAAC,CAAC,CAAC;IAClG,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,YAAY,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;IACrD,MAAM,OAAO,GAAG,EAAE,qBAAqB,EAAE,QAAQ,CAAC,CAAC,CAAC,qBAAqB,EAAE,uBAAuB,CAAC;QACjG,uBAAuB,EAAE,QAAQ,CAAC,CAAC,CAAC,uBAAuB,EAAE,yBAAyB,CAAC;QACvF,YAAY,EAAE,EAAE,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC;IAC7F,+BAA+B,CAAC,OAAO,CAAC,CAAC;IACzC,OAAO,EAAE,GAAG,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;AACxC,CAAC;AAED,yGAAyG;AACzG,MAAM,UAAU,uBAAuB,CAAC,KAEvC;IACC,gBAAgB,CAAC,KAAK,EAAE,yBAAyB,EAAE,CAAC,YAAY,EAAE,kBAAkB,CAAC,CAAC,CAAC;IACvF,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,gBAAgB,EAAE,kBAAkB,CAAC,CAAC;IAChE,IAAI,IAAI,GAAG,CAAC;QAAE,MAAM,IAAI,2BAA2B,CAAC,sCAAsC,CAAC,CAAC;IAC5F,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,8BAA8B,CAAC,CAAC;IAClF,IAAI,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,UAAU,CAAC,MAAM;QAAE,MAAM,IAAI,2BAA2B,CAAC,0BAA0B,CAAC,CAAC;IACvI,MAAM,MAAM,GAA+D,EAAE,CAAC;IAC9E,KAAK,MAAM,CAAC,IAAI,UAAU,EAAE,CAAC;QAC3B,MAAM,IAAI,GAAG,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QAC3B,IAAI,IAAI,EAAE,MAAM,KAAK,CAAC,CAAC,MAAM;YAAE,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;;YACvD,MAAM,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;IAC/D,CAAC;IACD,MAAM,OAAO,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,eAAe,IAAI,CAAC,CAAC,IAAI,KAAK,kBAAkB,CAAC,CAAC,CAAC,CAAC,OAAgB,CAAC,CAAC,CAAC,OAAgB,CAAC;IAC1I,OAAO,mBAAmB,CAAC,EAAE,aAAa,EAAE,OAAO,EAAE,gBAAgB,EAAE,IAAI,EAAE,UAAU;QACrF,WAAW,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,gBAAgB,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,EAAE,MAAM,EAAE,EAC/E,2BAA2B,EAAE,OAAO,EAAE,CAAC,2EAA2E,EAAE,wDAAwD,CAAC,CAAC,CAAC;AACjL,CAAC;AAED;;;GAGG;AACH,SAAS,yBAAyB,CAAC,OAAiC;IAClE,kBAAkB,CAAC,OAAO,EAAE,+BAA+B,CAAC,CAAC;IAC7D,OAAO,uBAAuB,CAAC,EAAE,UAAU,EAAE,OAAO,CAAC,UAAU,EAAE,gBAAgB,EAAE,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAAC,KAAK,CAAC;AACvH,CAAC;AAED,8FAA8F;AAC9F,MAAM,UAAU,iCAAiC,CAAC,KAEjD;IACC,gBAAgB,CAAC,KAAK,EAAE,mCAAmC,EAAE,CAAC,SAAS,EAAE,oBAAoB,CAAC,CAAC,CAAC;IAChG,MAAM,OAAO,GAAG,yBAAyB,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IACzD,OAAO,sCAAsC,CAAC,OAAO,EAAE,KAAK,CAAC,kBAAkB,CAAC,CAAC;AACnF,CAAC;AAED,wGAAwG;AACxG,MAAM,uBAAuB,GAAG,IAAI,OAAO,EAA0E,CAAC;AACtH,6GAA6G;AAC7G,SAAS,qBAAqB,CAAC,CAAiC;IAC9D,IAAI,CAAC,GAAG,uBAAuB,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IACvC,IAAI,CAAC,KAAK,SAAS,EAAE,CAAC;QAAC,CAAC,GAAG,qCAAqC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;QAAC,uBAAuB,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAAC,CAAC;IACjH,OAAO,CAAC,CAAC;AACX,CAAC;AAED,SAAS,sCAAsC,CAC7C,OAAiC,EACjC,kBAAoC;IAEpC,IAAI,CAAC,GAAG,KAAK,CAAC,kBAAkB,CAAC,CAAC;IAClC,IAAI,CAAC,GAAsB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IACxC,MAAM,UAAU,GAAkD,EAAE,CAAC;IACrE,KAAK,MAAM,CAAC,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC;QACnC,IAAI,KAAwB,CAAC;QAC7B,IAAI,CAAC,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YACxB,6EAA6E;YAC7E,KAAK,GAAG,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC;YACtB,CAAC,GAAG,MAAM,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC;QACnC,CAAC;aAAM,IAAI,CAAC,CAAC,IAAI,KAAK,eAAe,EAAE,CAAC;YACtC,MAAM,MAAM,GAAG,wBAAwB,CAAC,qBAAqB,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YACrE,KAAK,GAAG,CAAC,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;YAC7B,CAAC,GAAG,MAAM,CAAC,kBAAkB,CAAC;QAChC,CAAC;aAAM,IAAI,CAAC,CAAC,IAAI,KAAK,kBAAkB,EAAE,CAAC;YACzC,MAAM,MAAM,GAAG,wBAAwB,CAAC,CAAC,CAAC,qBAAqB,CAAC,eAAe,EAAE,CAAC,CAAC,qBAAqB,CAAC,aAAa,EACpH,CAAC,CAAC,gBAAgB,CAAC,eAAe,EAAE,CAAC,CAAC,gBAAgB,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;YAClF,KAAK,GAAG,CAAC,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;YAC7B,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC,aAAa,EAAE,CAAC;QAClC,CAAC;aAAM,CAAC;YACN,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,YAAY,CAAC;YAC9C,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,GAAC,CAAC,CAAC,CAAC,GAAC,CAAC,CAAC,CAAC,GAAC,CAAC,CAAC,CAAC,CAAC,GAAC,CAAC,CAAC,OAAO,CAAC,qBAAqB,IAAE,CAAC,CAAC;YAChE,MAAM,CAAC,GAAG,CAAC,GAAC,EAAE,GAAC,EAAE,GAAC,EAAE,GAAC,EAAE,GAAC,EAAE,GAAC,EAAE,GAAC,EAAE,GAAC,EAAE,GAAC,EAAE,CAAC;YACvC,MAAM,CAAC,GAAG,CAAC,GAAC,CAAC,EAAE,GAAC,CAAC,GAAC,EAAE,GAAC,EAAE,GAAC,CAAC,GAAC,EAAE,GAAC,EAAE,GAAC,EAAE,CAAC,GAAC,CAAC,CAAC,OAAO,CAAC,qBAAqB,IAAE,CAAC,CAAC;YACvE,KAAK,GAAG,CAAC,CAAC,GAAC,CAAC,GAAC,CAAC,CAAC,CAAC,GAAC,CAAC,CAAC,CAAC,EAAE,CAAC,GAAC,CAAC,CAAC,CAAC,GAAC,CAAC,CAAC,CAAC,EAAE,CAAC,GAAC,CAAC,CAAC,CAAC,GAAC,CAAC,CAAC,CAAC,EAAE,CAAC,GAAC,CAAC,GAAC,CAAC,CAAC,CAAC,GAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YACzD,CAAC,GAAG,gCAAgC,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,kBAAkB,CAAC;QACzG,CAAC;QACD,CAAC,GAAG,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;QACvB,UAAU,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,aAAa,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC;IAC1E,CAAC;IACD,iGAAiG;IACjG,sCAAsC;IACtC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAC,CAAC,CAAC,CAAC,CAAC,GAAC,CAAC,CAAC,CAAC,CAAC,GAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAC,CAAC,CAAC,CAAC,CAAC,GAAC,CAAC,CAAC,CAAC,CAAC,GAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAC,CAAC,CAAC,CAAC,CAAC,GAAC,CAAC,CAAC,CAAC,CAAC,GAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAChF,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,GAAC,CAAC,GAAC,IAAI,CAAC,KAAK,CAAC,CAAC,GAAC,CAAC,EAAE,CAAC,GAAC,CAAC,CAAC,CAAC,GAAC,CAAC,CAAC,CAAC;IACxD,MAAM,GAAG,GAAG,WAAW,CAAC,CAAC,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,GAAC,OAAO,CAAC;IAC5D,OAAO,mBAAmB,CAAC,EAAE,aAAa,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,WAAW,EAAE,GAAG;QAC1E,kBAAkB,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,EAAE,UAAU,EAAE,OAAO,GAAC,OAAO,EAAE,UAAU,EAAE,EACnF,iCAAiC,EAAE,OAAO,EAAE,CAAC,6EAA6E,CAAC,CAAC,CAAC;AAC/H,CAAC;AAED,uGAAuG;AACvG,MAAM,UAAU,gCAAgC,CAAC,KAEhD;IACC,gBAAgB,CAAC,KAAK,EAAE,kCAAkC,EAAE,CAAC,SAAS,EAAE,eAAe,CAAC,CAAC,CAAC;IAC1F,IAAI,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;IACnC,MAAM,OAAO,GAAG,yBAAyB,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IACzD,KAAK,MAAM,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC;QAClD,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK,QAAQ;YACrB,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC;YACzF,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,eAAe;gBAC1B,CAAC,CAAC,wBAAwB,CAAC,qBAAqB,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;gBACvD,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,kBAAkB;oBAC7B,CAAC,CAAC,wBAAwB,CAAC,CAAC,CAAC,gBAAgB,CAAC,eAAe,EAAE,CAAC,CAAC,gBAAgB,CAAC,aAAa,EAC7F,CAAC,CAAC,qBAAqB,CAAC,eAAe,EAAE,CAAC,CAAC,qBAAqB,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa;oBACzG,CAAC,CAAC,uCAAuC,CAAC,EAAE,qBAAqB,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,kBAAkB,CAAC;IAC7H,CAAC;IACD,OAAO,mBAAmB,CAAC,CAAC,EAAE,iCAAiC,EAAE,OAAO,EAAE,CAAC,6DAA6D,CAAC,CAAC,CAAC;AAC7I,CAAC;AAED,+EAA+E;AAC/E,MAAM,UAAU,oBAAoB,CAAC,KAAc;IACjD,MAAM,CAAC,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,SAAS,CAAC,CAAC,CAAC;IACpE,MAAM,KAAK,GAAG,QAAQ,CAAC,CAAC,CAAC,KAAK,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAC,CAAC,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IAChF,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,KAAK,GAAC,MAAM,GAAG,KAAK,EAAE,CAAC;QAC1F,MAAM,IAAI,2BAA2B,CAAC,kDAAkD,CAAC,CAAC;IAC5F,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC,OAAO,EAAE,SAAS,CAAC,EAAE,CAAC;AACjG,CAAC;AACD,SAAS,UAAU,CAAC,CAAkB,EAAE,CAAS,EAAE,CAAS;IAC1D,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,GAAC,CAAC,CAAC,GAAC,EAAE,GAAC,CAAC,CAAC,KAAK,GAAC,CAAC,CAAC,GAAC,CAAC,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,GAAC,CAAC,CAAC,GAAC,EAAE,GAAC,CAAC,CAAC,MAAM,GAAC,CAAC,CAAC,GAAC,CAAC,CAAC,OAAO,EAAE,CAAC;AACrG,CAAC;AACD,SAAS,eAAe,CAAC,CAAkB,EAAE,CAAmB;IAC9D,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAC,CAAC,CAAC,OAAO,GAAC,CAAC,CAAC,KAAK,GAAC,CAAC,GAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,GAAC,CAAC,CAAC,CAAC,CAAC,GAAC,CAAC,CAAC,OAAO,GAAC,CAAC,CAAC,MAAM,GAAC,CAAC,GAAC,EAAE,EAAE,CAAC;AACzG,CAAC;AACD,SAAS,SAAS,CAAC,CAAkB,EAAE,CAAmB,EAAE,MAAoC;IAC9F,MAAM,CAAC,GAAG,eAAe,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAChC,OAAO,MAAM,KAAK,SAAS;QACzB,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM;QACzG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,GAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,GAAC,CAAC,CAAC;AACpE,CAAC;AACD,sEAAsE;AACtE,MAAM,UAAU,wBAAwB,CAAC,IAAwB,EAAE,KAAa,EAAE,MAAc;IAC9F,MAAM,OAAO,GAAG,KAAK,CAAS,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC7C,IAAI,IAAI,GAAuC,IAAI,EAAE,IAAI,GAAG,CAAC,CAAC;IAC9D,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAChC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE;YAAE,OAAO,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,GAAC,KAAK,GAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAE,GAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACjF,MAAM,KAAK,GAAa,EAAE,CAAC;QAC3B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC;YAChC,MAAM,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAE,CAAC;YACxC,OAAO,KAAK,CAAC,MAAM,IAAI,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAE,CAAE,GAAG,CAAC,EAAE,CAAC;gBACnD,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,EAAG,EAAE,eAAe,GAAG,OAAO,CAAC,KAAK,CAAE,CAAC;gBAC9D,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAE,GAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,cAAc,GAAG,CAAC,GAAC,IAAI,CAAC;gBACzE,IAAI,eAAe,GAAC,cAAc,GAAG,IAAI,EAAE,CAAC;oBAC1C,IAAI,GAAG,eAAe,GAAC,cAAc,CAAC;oBACtC,IAAI,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,GAAC,eAAe,GAAC,CAAC,EAAE,KAAK,EAAE,cAAc,EAAE,MAAM,EAAE,eAAe,EAAE,CAAC;gBAC7F,CAAC;YACH,CAAC;YACD,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAChB,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,iHAAiH;AACjH,MAAM,UAAU,8BAA8B,CAAC,KAQ9C;IACC,gBAAgB,CAAC,KAAK,EAAE,gCAAgC,EAAE,CAAC,SAAS,EAAE,cAAc,EAAE,mBAAmB,EAAE,WAAW,EAAE,8BAA8B,EAAE,uBAAuB,CAAC,CAAC,CAAC;IAClL,MAAM,OAAO,GAAG,yBAAyB,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IACzD,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC;QAAE,MAAM,IAAI,2BAA2B,CAAC,wDAAwD,CAAC,CAAC;IAC/H,MAAM,MAAM,GAAG,oBAAoB,CAAC,KAAK,CAAC,YAAY,CAAC,EAAE,WAAW,GAAG,oBAAoB,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;IACrH,MAAM,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,WAAW,CAAC,CAAC,CAAC;IAC5E,MAAM,SAAS,GAAuB,EAAE,EAAE,EAAE,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC;QACxF,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC,EAAE,CAAC;IACtH,MAAM,UAAU,GAAG,QAAQ,CAAC,KAAK,CAAC,4BAA4B,EAAE,8BAA8B,CAAC,CAAC;IAChG,MAAM,MAAM,GAA4B,EAAE,EAAE,IAAI,GAAc,EAAE,CAAC;IACjE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,WAAW,CAAC,MAAM,EAAE,CAAC,EAAE;QAAE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,WAAW,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC;YACxF,MAAM,MAAM,GAAG,sCAAsC,CAAC,OAAO,EAAE,UAAU,CAAC,WAAW,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;YACpG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,aAAa,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC;QAC5F,CAAC;IACD,MAAM,iBAAiB,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,GAAC,WAAW,CAAC,OAAO,GAAC,MAAM,CAAC,OAAO,GAAG,CAAC,GAAC,KAAK,CAAC,CAAC;IACnH,MAAM,IAAI,GAAG,wBAAwB,CAAC,IAAI,EAAE,WAAW,CAAC,KAAK,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACnF,MAAM,WAAW,GAAG,KAAK,CAAC,qBAAqB,KAAK,SAAS,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,wBAAwB,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC;IACtI,MAAM,KAAK,GAAG,WAAW,KAAK,aAAa;QACzC,CAAC,CAAC,CAAC,EAAU,EAAU,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,GAAC,UAAU,CAAC,GAAC,GAAG,GAAC,IAAI,CAAC,EAAE;QAC9D,CAAC,CAAC,CAAC,EAAU,EAAU,EAAE,CAAC,6BAA6B,CAAC,WAAW,EAAE,UAAU,EAAE,EAAE,CAAC,GAAC,GAAG,GAAC,IAAI,CAAC,EAAE,CAAC;IACnG,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,KAAK,IAAI,IAAI,CAAC,GAAC,WAAW,CAAC,KAAK,IAAI,IAAI,CAAC,CAAC;QACrF,CAAC,GAAC,WAAW,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC,GAAC,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,GAAC,WAAW,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,CAAC;QACpF,IAAI,CAAC,KAAK,CAAC,CAAC,GAAC,WAAW,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,CAAC,GAAC,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC;IACpF,MAAM,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACrF,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACtG,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;IAC9D,OAAO,mBAAmB,CAAC,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,iBAAiB,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM;QAC3G,eAAe,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,iBAAiB;QACzD,WAAW,EAAE,CAAC,iBAAiB,IAAI,SAAS,CAAC,SAAS,KAAK,oBAAoB;QAC/E,0BAA0B,EAAE;YAC1B,UAAU,EAAE,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,GAAC,MAAM,CAAC,KAAK,GAAC,MAAM,CAAC,OAAO,GAAC,CAAC,CAAC,GAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,GAAC,MAAM,CAAC,KAAK,GAAC,MAAM,CAAC,OAAO,GAAC,CAAC,CAAC;YACzH,QAAQ,EAAE,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,GAAC,MAAM,CAAC,MAAM,GAAC,MAAM,CAAC,OAAO,GAAC,CAAC,CAAC,GAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,GAAC,MAAM,CAAC,MAAM,GAAC,MAAM,CAAC,OAAO,GAAC,CAAC,CAAC;SAC1H,EAAE,gCAAgC,EAAE,QAAQ,EAAE,EACjD,+BAA+B,EAAE,OAAO,EAAE,CAAC,oGAAoG,EAAE,qGAAqG,EAAE,uCAAuC,CAAC,CAAC,CAAC;AACpS,CAAC;AAED,6GAA6G;AAC7G,MAAM,UAAU,4BAA4B,CAAC,KAE5C;IACC,gBAAgB,CAAC,KAAK,EAAE,8BAA8B,EAAE,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC,CAAC;IACnF,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC;IACzB,kBAAkB,CAAC,KAAK,EAAE,mCAAmC,CAAC,CAAC;IAC/D,2FAA2F;IAC3F,MAAM,IAAI,GAAG,8BAA8B,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,YAAY,EAAE,KAAK,CAAC,YAAY;QACpG,iBAAiB,EAAE,KAAK,CAAC,iBAAiB,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,4BAA4B,EAAE,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC;IACnH,IAAI,CAAC,IAAI,CAAC,WAAW;QAAE,MAAM,IAAI,2BAA2B,CAAC,+CAA+C,CAAC,CAAC;IAC9G,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,aAAa,EAAE,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,EAAE,eAAe,CAAC,CAAC,CAAC;IACvF,IAAI,MAAM,CAAC,MAAM,KAAK,IAAI,CAAC,YAAY,CAAC,KAAK,GAAC,IAAI,CAAC,YAAY,CAAC,MAAM;QAAE,MAAM,IAAI,2BAA2B,CAAC,+BAA+B,CAAC,CAAC;IAC/I,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,KAAK,EAAiB,EAAE;QAC1D,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC;QAC9C,MAAM,CAAC,GAAG,eAAe,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC,CAAC,aAAa,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC;QAC/F,IAAI,IAAI,CAAC,SAAS,CAAC,MAAM,KAAK,SAAS;YAAE,OAAO,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,GAAC,KAAK,GAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAE,CAAC;QAC/F,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,GAAC,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,GAAC,CAAC,CAAC;QACvE,6FAA6F;QAC7F,MAAM,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAC,CAAC,EAAE,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAC,CAAC,CAAC;QACvD,OAAO,CAAC,CAAC,GAAC,EAAE,CAAC,GAAC,CAAC,CAAC,CAAC,GAAC,EAAE,CAAC,GAAC,MAAM,CAAC,CAAC,GAAC,KAAK,GAAC,CAAC,CAAE,GAAC,EAAE,GAAC,MAAM,CAAC,CAAC,GAAC,KAAK,GAAC,EAAE,CAAE,CAAC;YAC9D,EAAE,GAAC,CAAC,CAAC,CAAC,GAAC,EAAE,CAAC,GAAC,MAAM,CAAC,EAAE,GAAC,KAAK,GAAC,CAAC,CAAE,GAAC,EAAE,GAAC,MAAM,CAAC,EAAE,GAAC,KAAK,GAAC,EAAE,CAAE,CAAC,CAAC;IAC5D,CAAC,CAAC,CAAC;IACH,OAAO,mBAAmB,CAAC,EAAE,OAAO,EAAE,cAAc,EAAE,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,EAClF,kCAAkC,EAAE,OAAO,EAAE,CAAC,iEAAiE,CAAC,CAAC,CAAC;AACtH,CAAC","sourcesContent":["// SPDX-License-Identifier: Apache-2.0\n\n/**\n * Geometric image transforms (warps) such as distortion correction and projection changes, and\n * a resampler that applies them.\n *\n * A mapping goes from destination (output) points to source (captured) points. Preparing a\n * mapping fixes it for one still or frame; a change in time needs a new preparation.\n *\n * Transform kinds:\n * - `affine` and `radial` (schema 0.1.0, unchanged).\n * - From mapping schema 0.2.0: `brown-conrady` (radial plus tangential lens distortion) and\n * `projection-remap` (a change of ideal projection, for example fisheye capture to a\n * rectilinear or equirectangular view).\n *\n * A mapping that uses only 0.1.0 kinds keeps schema and model version 0.1.0 and gives identical output.\n * @see docs/DIGITAL_OPTICS_FOUNDATION.md for equations, coordinate/unit conventions, blockers and\n * support limits.\n */\n\nimport { approximationResult, type CalculationResult } from \"../core/calculation-result.js\";\nimport { InvalidScientificInputError } from \"../core/validation.js\";\nimport {\n calculateRadialDistortionMapping, calculateInverseRadialDistortionMapping,\n validateRadialDistortionProfile, type RadialDistortionProfile, type LensFieldPointMm\n} from \"../optics/radial-distortion.js\";\nimport { choice, finite, list, positive, record, textValue } from \"../optics/profile-contract.js\";\nimport { requireInputObject, requireInputKeys } from \"../core/record-validation.js\";\nimport {\n brownConradyForwardValue, brownConradyInverseValue, validateBrownConradyDistortionProfile,\n type BrownConradyDistortionProfile, type ValidatedBrownConradyDistortionProfile\n} from \"../optics/brown-conrady-distortion.js\";\nimport {\n lensProjectionRemapValue, lensProjectionSignedAxisAngle, parseLensProjectionModel,\n type LensProjectionModel\n} from \"../camera/lens-projection.js\";\n\n/** A domain change separates maps: only adjacent maps in the same domain share one resampling pass. */\nexport type GeometricImageDomain = \"raw-channel\" | \"reconstructed-linear\" | \"processed-output\";\n/** Jacobian (derivative) d(source mm)/d(destination mm), in row-major order. */\nexport type GeometricJacobian = readonly [number, number, number, number];\ninterface TransformIdentity {\n id: string;\n version: string;\n domain: GeometricImageDomain;\n purpose: \"distortion\" | \"breathing\" | \"digital-stabilization\" | \"orientation-crop\" | \"lateral-ca\" | \"projection\";\n}\n/** Explicit destination-to-source affine map, which can include rotation, shear and offset. */\nexport interface AffineGeometricTransform extends TransformIdentity {\n kind: \"affine\";\n matrix: GeometricJacobian;\n offsetMm: LensFieldPointMm;\n}\n/** Radial distortion. A correction reads the physically distorted data at the position mapped from each ideal (undistorted) destination point. */\nexport interface RadialGeometricTransform extends TransformIdentity {\n kind: \"radial\";\n profile: RadialDistortionProfile;\n}\n/** Schema 0.2.0: Brown-Conrady distortion. A correction reads the distorted data at the position mapped from each ideal destination point. */\nexport interface BrownConradyGeometricTransform extends TransformIdentity {\n kind: \"brown-conrady\";\n profile: BrownConradyDistortionProfile;\n}\n/** One ideal projection and its mapping scale (focal length, or mm per radian for equirectangular). */\nexport interface GeometricProjectionDeclaration {\n projectionModel: LensProjectionModel;\n focalLengthMm: number;\n}\n/**\n * Schema 0.2.0: change of projection. Each destination point becomes a scene direction (using\n * the destination projection), then a source point (using the source projection). Purpose must\n * be \"projection\".\n */\nexport interface ProjectionRemapGeometricTransform extends TransformIdentity {\n kind: \"projection-remap\";\n destinationProjection: GeometricProjectionDeclaration;\n sourceProjection: GeometricProjectionDeclaration;\n}\nexport type DigitalGeometricTransform =\n | AffineGeometricTransform\n | RadialGeometricTransform\n | BrownConradyGeometricTransform\n | ProjectionRemapGeometricTransform;\n/** Serializable prepared mapping. Maps are applied in the listed order, from destination towards source. */\nexport interface PreparedGeometricMapping {\n /** 0.1.0 when only affine and radial kinds are used; 0.2.0 when a kind added in 2.0 is present. */\n schemaVersion: \"0.1.0\" | \"0.2.0\";\n frameTimeSeconds: number;\n transforms: readonly DigitalGeometricTransform[];\n semanticKey: string;\n groups: readonly { domain: GeometricImageDomain; componentIds: readonly string[] }[];\n}\n/** A regular grid of pixel centres on the optical plane: +X right, +Y up; rows run top to bottom. */\nexport interface GeometricRaster {\n width: number;\n height: number;\n centerMm: LensFieldPointMm;\n pitchMm: number;\n}\n/** The resampling filter, chosen independently of the mapping. Any prefiltering (anti-aliasing) is the caller's job. */\nexport interface GeometricResampler {\n id: string;\n version: string;\n filter: \"nearest\" | \"bilinear\";\n antialias: \"none\" | \"source-prefiltered\";\n}\nexport interface GeometricMappingPoint {\n sourcePointMm: LensFieldPointMm;\n jacobian: GeometricJacobian;\n determinant: number;\n principalStretches: readonly [number, number];\n anisotropy: number;\n components: readonly { id: string; sourcePointMm: LensFieldPointMm; jacobian: GeometricJacobian }[];\n}\nexport interface GeometricSamplingPlan {\n mapping: PreparedGeometricMapping;\n sourceRaster: GeometricRaster;\n destinationRaster: GeometricRaster;\n resampler: GeometricResampler;\n points: readonly GeometricMappingPoint[];\n /** True where the selected filter has full source support around the pixel centre. Edges are not extended. */\n validSourceMask: readonly boolean[];\n /** Largest axis-aligned rectangle of valid pixels (half-open). Null if there is none. */\n jointCrop: { x: number; y: number; width: number; height: number } | null;\n requiresPrefilter: boolean;\n canResample: boolean;\n physicalCapturedFovDegrees: { horizontal: number; vertical: number };\n /** Angular extent of the mapped pixel-centre rays kept by the joint crop. It is not the edge-to-edge FOV. */\n retainedSampleRayEnvelopeDegrees: { minX: number; maxX: number; minY: number; maxY: number } | null;\n}\n\nfunction point(value: unknown): LensFieldPointMm {\n const p = record(value, [\"x\", \"y\"]);\n return { x: finite(p.x, \"x\"), y: finite(p.y, \"y\") };\n}\nfunction multiply(a: GeometricJacobian, b: GeometricJacobian): GeometricJacobian {\n return [a[0]*b[0]+a[1]*b[2], a[0]*b[1]+a[1]*b[3],\n a[2]*b[0]+a[3]*b[2], a[2]*b[1]+a[3]*b[3]];\n}\nfunction determinant(m: GeometricJacobian): number { return m[0]*m[3]-m[1]*m[2]; }\nfunction inverse(m: GeometricJacobian): GeometricJacobian {\n const d = determinant(m);\n if (!Number.isFinite(d) || Math.abs(d) < 1e-12) throw new InvalidScientificInputError(\"Singular or ill-conditioned affine map.\");\n return [m[3]/d, -m[1]/d, -m[2]/d, m[0]/d];\n}\nfunction affine(p: LensFieldPointMm, m: GeometricJacobian, o: LensFieldPointMm): LensFieldPointMm {\n return { x: m[0]*p.x+m[1]*p.y+o.x, y: m[2]*p.x+m[3]*p.y+o.y };\n}\n/** Strictly parses transform data. Unknown kinds or fields and profiles that cannot be inverted are rejected. */\nexport function parseDigitalGeometricTransform(value: unknown): DigitalGeometricTransform {\n const r = record(value, [\"id\", \"version\", \"domain\", \"purpose\", \"kind\", \"matrix\", \"offsetMm\", \"profile\",\n \"destinationProjection\", \"sourceProjection\"]);\n const identity = {\n id: textValue(r.id), version: textValue(r.version),\n domain: choice(r.domain, [\"raw-channel\", \"reconstructed-linear\", \"processed-output\"]),\n purpose: choice(r.purpose, [\"distortion\", \"breathing\", \"digital-stabilization\", \"orientation-crop\", \"lateral-ca\", \"projection\"])\n };\n const kind = choice(r.kind, [\"affine\", \"radial\", \"brown-conrady\", \"projection-remap\"]);\n if ((kind === \"projection-remap\") !== (identity.purpose === \"projection\")) {\n throw new InvalidScientificInputError(\"Purpose \\\"projection\\\" is used exactly by projection-remap transforms.\");\n }\n if (kind !== \"projection-remap\" && (r.destinationProjection !== undefined || r.sourceProjection !== undefined)) {\n throw new InvalidScientificInputError(\"Only projection-remap transforms carry projection declarations.\");\n }\n if (kind === \"projection-remap\") {\n if (r.matrix !== undefined || r.offsetMm !== undefined || r.profile !== undefined) {\n throw new InvalidScientificInputError(\"Projection remap cannot contain affine or distortion fields.\");\n }\n const projection = (v: unknown): GeometricProjectionDeclaration => {\n const d = record(v, [\"projectionModel\", \"focalLengthMm\"]);\n return { projectionModel: parseLensProjectionModel(d.projectionModel), focalLengthMm: positive(d.focalLengthMm, \"focalLengthMm\") };\n };\n return { ...identity, kind, destinationProjection: projection(r.destinationProjection), sourceProjection: projection(r.sourceProjection) };\n }\n if (kind === \"brown-conrady\") {\n if (r.matrix !== undefined || r.offsetMm !== undefined) throw new InvalidScientificInputError(\"Brown-Conrady map cannot contain affine fields.\");\n const p = record(r.profile, [\"normalizationRadiusMm\", \"maximumNormalizedRadius\", \"coefficients\"]);\n const c = record(p.coefficients, [\"k1\", \"k2\", \"k3\", \"p1\", \"p2\"]);\n const profile = { normalizationRadiusMm: positive(p.normalizationRadiusMm, \"normalizationRadiusMm\"),\n maximumNormalizedRadius: positive(p.maximumNormalizedRadius, \"maximumNormalizedRadius\"),\n coefficients: { k1: finite(c.k1, \"k1\"), k2: finite(c.k2, \"k2\"), k3: finite(c.k3, \"k3\"), p1: finite(c.p1, \"p1\"), p2: finite(c.p2, \"p2\") } };\n validateBrownConradyDistortionProfile(profile);\n return { ...identity, kind, profile };\n }\n if (kind === \"affine\") {\n if (r.profile !== undefined) throw new InvalidScientificInputError(\"Affine map cannot contain radial profile.\");\n const entries = list(r.matrix, 4).map((v) => finite(v, \"matrix\"));\n if (entries.length !== 4) throw new InvalidScientificInputError(\"Matrix must have four entries.\");\n const matrix = entries as [number, number, number, number];\n inverse(matrix);\n return { ...identity, kind, matrix, offsetMm: point(r.offsetMm) };\n }\n if (r.matrix !== undefined || r.offsetMm !== undefined) throw new InvalidScientificInputError(\"Radial map cannot contain affine fields.\");\n const p = record(r.profile, [\"normalizationRadiusMm\", \"maximumNormalizedRadius\", \"coefficients\"]);\n const c = record(p.coefficients, [\"k1\", \"k2\", \"k3\"]);\n const profile = { normalizationRadiusMm: positive(p.normalizationRadiusMm, \"normalizationRadiusMm\"),\n maximumNormalizedRadius: positive(p.maximumNormalizedRadius, \"maximumNormalizedRadius\"),\n coefficients: { k1: finite(c.k1, \"k1\"), k2: finite(c.k2, \"k2\"), k3: finite(c.k3, \"k3\") } };\n validateRadialDistortionProfile(profile);\n return { ...identity, kind, profile };\n}\n\n/** Prepares a deterministic mapping for one still or frame. A change in time needs a new preparation. */\nexport function prepareGeometricMapping(input: {\n transforms: readonly DigitalGeometricTransform[]; frameTimeSeconds: number;\n}): CalculationResult<PreparedGeometricMapping> {\n requireInputKeys(input, \"prepareGeometricMapping\", [\"transforms\", \"frameTimeSeconds\"]);\n const time = finite(input.frameTimeSeconds, \"frameTimeSeconds\");\n if (time < 0) throw new InvalidScientificInputError(\"Time is seconds from exposure start.\");\n const transforms = list(input.transforms, 32).map(parseDigitalGeometricTransform);\n if (new Set(transforms.map((t) => t.id)).size !== transforms.length) throw new InvalidScientificInputError(\"Duplicate transform IDs.\");\n const groups: { domain: GeometricImageDomain; componentIds: string[] }[] = [];\n for (const t of transforms) {\n const last = groups.at(-1);\n if (last?.domain === t.domain) last.componentIds.push(t.id);\n else groups.push({ domain: t.domain, componentIds: [t.id] });\n }\n const version = transforms.some((t) => t.kind === \"brown-conrady\" || t.kind === \"projection-remap\") ? \"0.2.0\" as const : \"0.1.0\" as const;\n return approximationResult({ schemaVersion: version, frameTimeSeconds: time, transforms,\n semanticKey: JSON.stringify({ frameTimeSeconds: time, transforms }), groups },\n \"composed-digital-geometry\", version, [\"Explicit inverse maps; incompatible domains require separate image stages\", \"No physical PSF, photon or noise-history recalculation\"]);\n}\n\n/**\n * Re-validates a prepared mapping from its defining fields (transforms and frame time). Its derived\n * fields (schema version, semantic key, groups) are recomputed, never trusted.\n */\nfunction reprepareGeometricMapping(mapping: PreparedGeometricMapping): PreparedGeometricMapping {\n requireInputObject(mapping, \"prepareGeometricMapping input\");\n return prepareGeometricMapping({ transforms: mapping.transforms, frameTimeSeconds: mapping.frameTimeSeconds }).value;\n}\n\n/** Maps a display point to the capture, with the full local derivatives in each direction. */\nexport function calculateComposedGeometricMapping(input: {\n mapping: PreparedGeometricMapping; destinationPointMm: LensFieldPointMm;\n}): CalculationResult<GeometricMappingPoint> {\n requireInputKeys(input, \"calculateComposedGeometricMapping\", [\"mapping\", \"destinationPointMm\"]);\n const mapping = reprepareGeometricMapping(input.mapping);\n return calculatePreparedGeometricMappingPoint(mapping, input.destinationPointMm);\n}\n\n/** Only a mapping parsed and copied within this call; prepared state from outside is never accepted. */\nconst VALIDATED_BROWN_CONRADY = new WeakMap<BrownConradyGeometricTransform, ValidatedBrownConradyDistortionProfile>();\n/** Validates a parsed transform's profile once per prepared mapping (the transform object is call-local). */\nfunction validatedBrownConrady(t: BrownConradyGeometricTransform): ValidatedBrownConradyDistortionProfile {\n let v = VALIDATED_BROWN_CONRADY.get(t);\n if (v === undefined) { v = validateBrownConradyDistortionProfile(t.profile); VALIDATED_BROWN_CONRADY.set(t, v); }\n return v;\n}\n\nfunction calculatePreparedGeometricMappingPoint(\n mapping: PreparedGeometricMapping,\n destinationPointMm: LensFieldPointMm\n): CalculationResult<GeometricMappingPoint> {\n let p = point(destinationPointMm);\n let j: GeometricJacobian = [1, 0, 0, 1];\n const components: GeometricMappingPoint[\"components\"][number][] = [];\n for (const t of mapping.transforms) {\n let local: GeometricJacobian;\n if (t.kind === \"affine\") {\n // Give each point its own result arrays when one mapping serves many points.\n local = [...t.matrix];\n p = affine(p, local, t.offsetMm);\n } else if (t.kind === \"brown-conrady\") {\n const mapped = brownConradyForwardValue(validatedBrownConrady(t), p);\n local = [...mapped.jacobian];\n p = mapped.mappedImagePointMm;\n } else if (t.kind === \"projection-remap\") {\n const mapped = lensProjectionRemapValue(t.destinationProjection.projectionModel, t.destinationProjection.focalLengthMm,\n t.sourceProjection.projectionModel, t.sourceProjection.focalLengthMm, p.x, p.y);\n local = [...mapped.jacobian];\n p = { ...mapped.sourcePointMm };\n } else {\n const { k1, k2, k3 } = t.profile.coefficients;\n const r2 = (p.x*p.x+p.y*p.y)/t.profile.normalizationRadiusMm**2;\n const s = 1+k1*r2+k2*r2*r2+k3*r2*r2*r2;\n const d = 2*(k1+2*k2*r2+3*k3*r2*r2)/t.profile.normalizationRadiusMm**2;\n local = [s+d*p.x*p.x, d*p.x*p.y, d*p.x*p.y, s+d*p.y*p.y];\n p = calculateRadialDistortionMapping({ imagePointMm: p, profile: t.profile }).value.mappedImagePointMm;\n }\n j = multiply(local, j);\n components.push({ id: t.id, sourcePointMm: { ...p }, jacobian: local });\n }\n // Singular values from the eigenvalues of the symmetric matrix JᵀJ. Computing the smaller one as\n // det/smax avoids cancellation error.\n const a = j[0]*j[0]+j[2]*j[2], b = j[0]*j[1]+j[2]*j[3], c = j[1]*j[1]+j[3]*j[3];\n const maximum = Math.sqrt((a+c+Math.hypot(a-c, 2*b))/2);\n const det = determinant(j), minimum = Math.abs(det)/maximum;\n return approximationResult({ sourcePointMm: p, jacobian: j, determinant: det,\n principalStretches: [maximum, minimum], anisotropy: maximum/minimum, components },\n \"composed-digital-geometry-point\", \"0.1.0\", [\"Jacobian warps already-formed blur and noise; it creates no captured detail\"]);\n}\n\n/** Maps a capture point to the display, for focus, metering and overlays. It inverts the same maps. */\nexport function calculateForwardGeometricMapping(input: {\n mapping: PreparedGeometricMapping; sourcePointMm: LensFieldPointMm;\n}): CalculationResult<LensFieldPointMm> {\n requireInputKeys(input, \"calculateForwardGeometricMapping\", [\"mapping\", \"sourcePointMm\"]);\n let p = point(input.sourcePointMm);\n const mapping = reprepareGeometricMapping(input.mapping);\n for (const t of [...mapping.transforms].reverse()) {\n p = t.kind === \"affine\"\n ? affine({ x: p.x-t.offsetMm.x, y: p.y-t.offsetMm.y }, inverse(t.matrix), { x: 0, y: 0 })\n : t.kind === \"brown-conrady\"\n ? brownConradyInverseValue(validatedBrownConrady(t), p)\n : t.kind === \"projection-remap\"\n ? lensProjectionRemapValue(t.sourceProjection.projectionModel, t.sourceProjection.focalLengthMm,\n t.destinationProjection.projectionModel, t.destinationProjection.focalLengthMm, p.x, p.y).sourcePointMm\n : calculateInverseRadialDistortionMapping({ distortedImagePointMm: p, profile: t.profile }).value.sourceImagePointMm;\n }\n return approximationResult(p, \"forward-digital-geometry-bridge\", \"0.1.0\", [\"Inverse of the authoritative destination-to-source geometry\"]);\n}\n\n/** @internal Shared lattice validation for downstream correction consumers. */\nexport function parseGeometricRaster(value: unknown): GeometricRaster {\n const r = record(value, [\"width\", \"height\", \"centerMm\", \"pitchMm\"]);\n const width = positive(r.width, \"width\"), height = positive(r.height, \"height\");\n if (!Number.isSafeInteger(width) || !Number.isSafeInteger(height) || width*height > 65536) {\n throw new InvalidScientificInputError(\"Raster must have at most 65536 integral samples.\");\n }\n return { width, height, centerMm: point(r.centerMm), pitchMm: positive(r.pitchMm, \"pitchMm\") };\n}\nfunction pixelPoint(r: GeometricRaster, x: number, y: number): LensFieldPointMm {\n return { x: r.centerMm.x+(x+.5-r.width/2)*r.pitchMm, y: r.centerMm.y-(y+.5-r.height/2)*r.pitchMm };\n}\nfunction pixelCoordinate(r: GeometricRaster, p: LensFieldPointMm): LensFieldPointMm {\n return { x: (p.x-r.centerMm.x)/r.pitchMm+r.width/2-.5, y: (r.centerMm.y-p.y)/r.pitchMm+r.height/2-.5 };\n}\nfunction supported(r: GeometricRaster, p: LensFieldPointMm, filter: GeometricResampler[\"filter\"]): boolean {\n const q = pixelCoordinate(r, p);\n return filter === \"nearest\"\n ? Math.round(q.x) >= 0 && Math.round(q.x) < r.width && Math.round(q.y) >= 0 && Math.round(q.y) < r.height\n : q.x >= 0 && q.x <= r.width-1 && q.y >= 0 && q.y <= r.height-1;\n}\n/** @internal Shared deterministic crop for a validated pixel mask. */\nexport function calculateValidSourceCrop(mask: readonly boolean[], width: number, height: number): GeometricSamplingPlan[\"jointCrop\"] {\n const heights = Array<number>(width).fill(0);\n let best: GeometricSamplingPlan[\"jointCrop\"] = null, area = 0;\n for (let y = 0; y < height; y++) {\n for (let x = 0; x < width; x++) heights[x] = mask[y*width+x] ? heights[x]!+1 : 0;\n const stack: number[] = [];\n for (let x = 0; x <= width; x++) {\n const h = x === width ? 0 : heights[x]!;\n while (stack.length && heights[stack.at(-1)!]! > h) {\n const index = stack.pop()!, rectangleHeight = heights[index]!;\n const left = stack.length ? stack.at(-1)!+1 : 0, rectangleWidth = x-left;\n if (rectangleHeight*rectangleWidth > area) {\n area = rectangleHeight*rectangleWidth;\n best = { x: left, y: y-rectangleHeight+1, width: rectangleWidth, height: rectangleHeight };\n }\n }\n stack.push(x);\n }\n }\n return best;\n}\n\n/** Composes compatible inverse maps, then resolves one shared plan for validity, crop and anti-aliasing (AA). */\nexport function calculateGeometricSamplingPlan(input: {\n mapping: PreparedGeometricMapping; sourceRaster: GeometricRaster; destinationRaster: GeometricRaster;\n resampler: GeometricResampler; physicalProjectionDistanceMm: number;\n /**\n * Ideal projection of the captured (source) image, used for the reported angles. Omitted or\n * \"rectilinear\" keeps the existing atan(mm / projection distance) angles exactly.\n */\n sourceProjectionModel?: LensProjectionModel;\n}): CalculationResult<GeometricSamplingPlan> {\n requireInputKeys(input, \"calculateGeometricSamplingPlan\", [\"mapping\", \"sourceRaster\", \"destinationRaster\", \"resampler\", \"physicalProjectionDistanceMm\", \"sourceProjectionModel\"]);\n const mapping = reprepareGeometricMapping(input.mapping);\n if (mapping.groups.length > 1) throw new InvalidScientificInputError(\"Separate incompatible-domain groups before resampling.\");\n const source = parseGeometricRaster(input.sourceRaster), destination = parseGeometricRaster(input.destinationRaster);\n const r = record(input.resampler, [\"id\", \"version\", \"filter\", \"antialias\"]);\n const resampler: GeometricResampler = { id: textValue(r.id), version: textValue(r.version),\n filter: choice(r.filter, [\"nearest\", \"bilinear\"]), antialias: choice(r.antialias, [\"none\", \"source-prefiltered\"]) };\n const projection = positive(input.physicalProjectionDistanceMm, \"physicalProjectionDistanceMm\");\n const points: GeometricMappingPoint[] = [], mask: boolean[] = [];\n for (let y = 0; y < destination.height; y++) for (let x = 0; x < destination.width; x++) {\n const mapped = calculatePreparedGeometricMappingPoint(mapping, pixelPoint(destination, x, y)).value;\n points.push(mapped); mask.push(supported(source, mapped.sourcePointMm, resampler.filter));\n }\n const requiresPrefilter = points.some((p) => p.principalStretches[0]*destination.pitchMm/source.pitchMm > 1+1e-12);\n const crop = calculateValidSourceCrop(mask, destination.width, destination.height);\n const sourceModel = input.sourceProjectionModel === undefined ? \"rectilinear\" : parseLensProjectionModel(input.sourceProjectionModel);\n const angle = sourceModel === \"rectilinear\"\n ? (mm: number): number => Math.atan(mm/projection)*180/Math.PI\n : (mm: number): number => lensProjectionSignedAxisAngle(sourceModel, projection, mm)*180/Math.PI;\n const retained = points.filter((_, i) => crop !== null && i%destination.width >= crop.x &&\n i%destination.width < crop.x+crop.width && Math.floor(i/destination.width) >= crop.y &&\n Math.floor(i/destination.width) < crop.y+crop.height).map((p) => p.sourcePointMm);\n const envelope = retained.length ? { minX: Math.min(...retained.map((p) => angle(p.x))),\n maxX: Math.max(...retained.map((p) => angle(p.x))), minY: Math.min(...retained.map((p) => angle(p.y))),\n maxY: Math.max(...retained.map((p) => angle(p.y))) } : null;\n return approximationResult({ mapping, sourceRaster: source, destinationRaster: destination, resampler, points,\n validSourceMask: mask, jointCrop: crop, requiresPrefilter,\n canResample: !requiresPrefilter || resampler.antialias === \"source-prefiltered\",\n physicalCapturedFovDegrees: {\n horizontal: angle(source.centerMm.x+source.width*source.pitchMm/2)-angle(source.centerMm.x-source.width*source.pitchMm/2),\n vertical: angle(source.centerMm.y+source.height*source.pitchMm/2)-angle(source.centerMm.y-source.height*source.pitchMm/2)\n }, retainedSampleRayEnvelopeDegrees: envelope },\n \"joint-geometric-sampling-plan\", \"0.1.0\", [\"Mask and crop are exact for this pixel-center lattice/filter, not continuous between-pixel support\", \"Compression requires explicitly source-prefiltered data; this API does not implement that prefilter\", \"No temporal trajectory crop guarantee\"]);\n}\n\n/** Resamples an already-formed single-channel image once. A null output sample marks missing source data. */\nexport function calculateGeometricResampling(input: {\n plan: GeometricSamplingPlan; sourceSamples: readonly number[];\n}): CalculationResult<{ samples: readonly (number | null)[]; resamplePasses: 1; resampler: GeometricResampler }> {\n requireInputKeys(input, \"calculateGeometricResampling\", [\"plan\", \"sourceSamples\"]);\n const prior = input.plan;\n requireInputObject(prior, \"calculateGeometricResampling plan\");\n // Re-plan from the defining fields; the derived plan fields are recomputed, never trusted.\n const plan = calculateGeometricSamplingPlan({ mapping: prior.mapping, sourceRaster: prior.sourceRaster,\n destinationRaster: prior.destinationRaster, resampler: prior.resampler, physicalProjectionDistanceMm: 1 }).value;\n if (!plan.canResample) throw new InvalidScientificInputError(\"Compression requires source-prefiltered data.\");\n const source = list(input.sourceSamples, 65536).map((v) => finite(v, \"source sample\"));\n if (source.length !== plan.sourceRaster.width*plan.sourceRaster.height) throw new InvalidScientificInputError(\"Source sample count mismatch.\");\n const samples = plan.points.map((p, index): number | null => {\n if (!plan.validSourceMask[index]) return null;\n const q = pixelCoordinate(plan.sourceRaster, p.sourcePointMm), width = plan.sourceRaster.width;\n if (plan.resampler.filter === \"nearest\") return source[Math.round(q.y)*width+Math.round(q.x)]!;\n const x = Math.floor(q.x), y = Math.floor(q.y), dx = q.x-x, dy = q.y-y;\n // A centre exactly on the boundary needs no missing neighbour. The border is never extended.\n const x1 = dx === 0 ? x : x+1, y1 = dy === 0 ? y : y+1;\n return (1-dy)*((1-dx)*source[y*width+x]!+dx*source[y*width+x1]!) +\n dy*((1-dx)*source[y1*width+x]!+dx*source[y1*width+x1]!);\n });\n return approximationResult({ samples, resamplePasses: 1, resampler: plan.resampler },\n \"single-pass-geometric-resampling\", \"0.1.0\", [\"Warps captured blur/noise; does not recalculate the optical PSF\"]);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"geometric-transforms.js","sourceRoot":"","sources":["../../src/output/geometric-transforms.ts"],"names":[],"mappings":"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","sourcesContent":["// SPDX-License-Identifier: Apache-2.0\n\n/**\n * Geometric image transforms (warps) such as distortion correction and projection changes, and\n * a resampler that applies them.\n *\n * A mapping goes from destination (output) points to source (captured) points. Preparing a\n * mapping fixes it for one still or frame; a change in time needs a new preparation.\n *\n * Transform kinds:\n * - `affine` and `radial` (schema 0.1.0, unchanged).\n * - From mapping schema 0.2.0: `brown-conrady` (radial plus tangential lens distortion) and\n * `projection-remap` (a change of ideal projection, for example fisheye capture to a\n * rectilinear or equirectangular view).\n *\n * A mapping that uses only 0.1.0 kinds keeps schema and model version 0.1.0 and gives identical output.\n * @see docs/DIGITAL_OPTICS_FOUNDATION.md for equations, coordinate/unit conventions, blockers and\n * support limits.\n */\n\nimport { approximationResult, type CalculationResult } from \"../core/calculation-result.js\";\nimport { InvalidScientificInputError } from \"../core/validation.js\";\nimport {\n calculateRadialDistortionMapping, calculateInverseRadialDistortionMapping,\n validateRadialDistortionProfile, type RadialDistortionProfile, type LensFieldPointMm\n} from \"../optics/radial-distortion.js\";\nimport { choice, finite, list, positive, record, textValue } from \"../optics/profile-contract.js\";\nimport { requireInputObject, requireInputKeys } from \"../core/record-validation.js\";\nimport {\n brownConradyForwardValue, brownConradyInverseValue, validateBrownConradyDistortionProfile,\n type BrownConradyDistortionProfile, type ValidatedBrownConradyDistortionProfile\n} from \"../optics/brown-conrady-distortion.js\";\nimport {\n lensProjectionRemapValue, lensProjectionSignedAxisAngle, parseLensProjectionModel,\n type LensProjectionModel\n} from \"../camera/lens-projection.js\";\nimport { point } from \"../optics/stray-light.js\";\n\n/** A domain change separates maps: only adjacent maps in the same domain share one resampling pass. */\nexport type GeometricImageDomain = \"raw-channel\" | \"reconstructed-linear\" | \"processed-output\";\n/** Jacobian (derivative) d(source mm)/d(destination mm), in row-major order. */\nexport type GeometricJacobian = readonly [number, number, number, number];\ninterface TransformIdentity {\n id: string;\n version: string;\n domain: GeometricImageDomain;\n purpose: \"distortion\" | \"breathing\" | \"digital-stabilization\" | \"orientation-crop\" | \"lateral-ca\" | \"projection\";\n}\n/** Explicit destination-to-source affine map, which can include rotation, shear and offset. */\nexport interface AffineGeometricTransform extends TransformIdentity {\n kind: \"affine\";\n matrix: GeometricJacobian;\n offsetMm: LensFieldPointMm;\n}\n/** Radial distortion. A correction reads the physically distorted data at the position mapped from each ideal (undistorted) destination point. */\nexport interface RadialGeometricTransform extends TransformIdentity {\n kind: \"radial\";\n profile: RadialDistortionProfile;\n}\n/** Schema 0.2.0: Brown-Conrady distortion. A correction reads the distorted data at the position mapped from each ideal destination point. */\nexport interface BrownConradyGeometricTransform extends TransformIdentity {\n kind: \"brown-conrady\";\n profile: BrownConradyDistortionProfile;\n}\n/** One ideal projection and its mapping scale (focal length, or mm per radian for equirectangular). */\nexport interface GeometricProjectionDeclaration {\n projectionModel: LensProjectionModel;\n focalLengthMm: number;\n}\n/**\n * Schema 0.2.0: change of projection. Each destination point becomes a scene direction (using\n * the destination projection), then a source point (using the source projection). Purpose must\n * be \"projection\".\n */\nexport interface ProjectionRemapGeometricTransform extends TransformIdentity {\n kind: \"projection-remap\";\n destinationProjection: GeometricProjectionDeclaration;\n sourceProjection: GeometricProjectionDeclaration;\n}\nexport type DigitalGeometricTransform =\n | AffineGeometricTransform\n | RadialGeometricTransform\n | BrownConradyGeometricTransform\n | ProjectionRemapGeometricTransform;\n/** Serializable prepared mapping. Maps are applied in the listed order, from destination towards source. */\nexport interface PreparedGeometricMapping {\n /** 0.1.0 when only affine and radial kinds are used; 0.2.0 when a kind added in 2.0 is present. */\n schemaVersion: \"0.1.0\" | \"0.2.0\";\n frameTimeSeconds: number;\n transforms: readonly DigitalGeometricTransform[];\n semanticKey: string;\n groups: readonly { domain: GeometricImageDomain; componentIds: readonly string[] }[];\n}\n/** A regular grid of pixel centres on the optical plane: +X right, +Y up; rows run top to bottom. */\nexport interface GeometricRaster {\n width: number;\n height: number;\n centerMm: LensFieldPointMm;\n pitchMm: number;\n}\n/** The resampling filter, chosen independently of the mapping. Any prefiltering (anti-aliasing) is the caller's job. */\nexport interface GeometricResampler {\n id: string;\n version: string;\n filter: \"nearest\" | \"bilinear\";\n antialias: \"none\" | \"source-prefiltered\";\n}\nexport interface GeometricMappingPoint {\n sourcePointMm: LensFieldPointMm;\n jacobian: GeometricJacobian;\n determinant: number;\n principalStretches: readonly [number, number];\n anisotropy: number;\n components: readonly { id: string; sourcePointMm: LensFieldPointMm; jacobian: GeometricJacobian }[];\n}\nexport interface GeometricSamplingPlan {\n mapping: PreparedGeometricMapping;\n sourceRaster: GeometricRaster;\n destinationRaster: GeometricRaster;\n resampler: GeometricResampler;\n points: readonly GeometricMappingPoint[];\n /** True where the selected filter has full source support around the pixel centre. Edges are not extended. */\n validSourceMask: readonly boolean[];\n /** Largest axis-aligned rectangle of valid pixels (half-open). Null if there is none. */\n jointCrop: { x: number; y: number; width: number; height: number } | null;\n requiresPrefilter: boolean;\n canResample: boolean;\n physicalCapturedFovDegrees: { horizontal: number; vertical: number };\n /** Angular extent of the mapped pixel-centre rays kept by the joint crop. It is not the edge-to-edge FOV. */\n retainedSampleRayEnvelopeDegrees: { minX: number; maxX: number; minY: number; maxY: number } | null;\n}\n\nfunction multiply(a: GeometricJacobian, b: GeometricJacobian): GeometricJacobian {\n return [a[0]*b[0]+a[1]*b[2], a[0]*b[1]+a[1]*b[3],\n a[2]*b[0]+a[3]*b[2], a[2]*b[1]+a[3]*b[3]];\n}\nfunction determinant(m: GeometricJacobian): number { return m[0]*m[3]-m[1]*m[2]; }\nfunction inverse(m: GeometricJacobian): GeometricJacobian {\n const d = determinant(m);\n if (!Number.isFinite(d) || Math.abs(d) < 1e-12) throw new InvalidScientificInputError(\"Singular or ill-conditioned affine map.\");\n return [m[3]/d, -m[1]/d, -m[2]/d, m[0]/d];\n}\nfunction affine(p: LensFieldPointMm, m: GeometricJacobian, o: LensFieldPointMm): LensFieldPointMm {\n return { x: m[0]*p.x+m[1]*p.y+o.x, y: m[2]*p.x+m[3]*p.y+o.y };\n}\n/** Strictly parses transform data. Unknown kinds or fields and profiles that cannot be inverted are rejected. */\nexport function parseDigitalGeometricTransform(value: unknown): DigitalGeometricTransform {\n const r = record(value, [\"id\", \"version\", \"domain\", \"purpose\", \"kind\", \"matrix\", \"offsetMm\", \"profile\",\n \"destinationProjection\", \"sourceProjection\"]);\n const identity = {\n id: textValue(r.id), version: textValue(r.version),\n domain: choice(r.domain, [\"raw-channel\", \"reconstructed-linear\", \"processed-output\"]),\n purpose: choice(r.purpose, [\"distortion\", \"breathing\", \"digital-stabilization\", \"orientation-crop\", \"lateral-ca\", \"projection\"])\n };\n const kind = choice(r.kind, [\"affine\", \"radial\", \"brown-conrady\", \"projection-remap\"]);\n if ((kind === \"projection-remap\") !== (identity.purpose === \"projection\")) {\n throw new InvalidScientificInputError(\"Purpose \\\"projection\\\" is used exactly by projection-remap transforms.\");\n }\n if (kind !== \"projection-remap\" && (r.destinationProjection !== undefined || r.sourceProjection !== undefined)) {\n throw new InvalidScientificInputError(\"Only projection-remap transforms carry projection declarations.\");\n }\n if (kind === \"projection-remap\") {\n if (r.matrix !== undefined || r.offsetMm !== undefined || r.profile !== undefined) {\n throw new InvalidScientificInputError(\"Projection remap cannot contain affine or distortion fields.\");\n }\n const projection = (v: unknown): GeometricProjectionDeclaration => {\n const d = record(v, [\"projectionModel\", \"focalLengthMm\"]);\n return { projectionModel: parseLensProjectionModel(d.projectionModel), focalLengthMm: positive(d.focalLengthMm, \"focalLengthMm\") };\n };\n return { ...identity, kind, destinationProjection: projection(r.destinationProjection), sourceProjection: projection(r.sourceProjection) };\n }\n if (kind === \"brown-conrady\") {\n if (r.matrix !== undefined || r.offsetMm !== undefined) throw new InvalidScientificInputError(\"Brown-Conrady map cannot contain affine fields.\");\n const p = record(r.profile, [\"normalizationRadiusMm\", \"maximumNormalizedRadius\", \"coefficients\"]);\n const c = record(p.coefficients, [\"k1\", \"k2\", \"k3\", \"p1\", \"p2\"]);\n const profile = { normalizationRadiusMm: positive(p.normalizationRadiusMm, \"normalizationRadiusMm\"),\n maximumNormalizedRadius: positive(p.maximumNormalizedRadius, \"maximumNormalizedRadius\"),\n coefficients: { k1: finite(c.k1, \"k1\"), k2: finite(c.k2, \"k2\"), k3: finite(c.k3, \"k3\"), p1: finite(c.p1, \"p1\"), p2: finite(c.p2, \"p2\") } };\n validateBrownConradyDistortionProfile(profile);\n return { ...identity, kind, profile };\n }\n if (kind === \"affine\") {\n if (r.profile !== undefined) throw new InvalidScientificInputError(\"Affine map cannot contain radial profile.\");\n const entries = list(r.matrix, 4).map((v) => finite(v, \"matrix\"));\n if (entries.length !== 4) throw new InvalidScientificInputError(\"Matrix must have four entries.\");\n const matrix = entries as [number, number, number, number];\n inverse(matrix);\n return { ...identity, kind, matrix, offsetMm: point(r.offsetMm) };\n }\n if (r.matrix !== undefined || r.offsetMm !== undefined) throw new InvalidScientificInputError(\"Radial map cannot contain affine fields.\");\n const p = record(r.profile, [\"normalizationRadiusMm\", \"maximumNormalizedRadius\", \"coefficients\"]);\n const c = record(p.coefficients, [\"k1\", \"k2\", \"k3\"]);\n const profile = { normalizationRadiusMm: positive(p.normalizationRadiusMm, \"normalizationRadiusMm\"),\n maximumNormalizedRadius: positive(p.maximumNormalizedRadius, \"maximumNormalizedRadius\"),\n coefficients: { k1: finite(c.k1, \"k1\"), k2: finite(c.k2, \"k2\"), k3: finite(c.k3, \"k3\") } };\n validateRadialDistortionProfile(profile);\n return { ...identity, kind, profile };\n}\n\n/** Prepares a deterministic mapping for one still or frame. A change in time needs a new preparation. */\nexport function prepareGeometricMapping(input: {\n transforms: readonly DigitalGeometricTransform[]; frameTimeSeconds: number;\n}): CalculationResult<PreparedGeometricMapping> {\n requireInputKeys(input, \"prepareGeometricMapping\", [\"transforms\", \"frameTimeSeconds\"]);\n const time = finite(input.frameTimeSeconds, \"frameTimeSeconds\");\n if (time < 0) throw new InvalidScientificInputError(\"Time is seconds from exposure start.\");\n const transforms = list(input.transforms, 32).map(parseDigitalGeometricTransform);\n if (new Set(transforms.map((t) => t.id)).size !== transforms.length) throw new InvalidScientificInputError(\"Duplicate transform IDs.\");\n const groups: { domain: GeometricImageDomain; componentIds: string[] }[] = [];\n for (const t of transforms) {\n const last = groups.at(-1);\n if (last?.domain === t.domain) last.componentIds.push(t.id);\n else groups.push({ domain: t.domain, componentIds: [t.id] });\n }\n const version = transforms.some((t) => t.kind === \"brown-conrady\" || t.kind === \"projection-remap\") ? \"0.2.0\" as const : \"0.1.0\" as const;\n return approximationResult({ schemaVersion: version, frameTimeSeconds: time, transforms,\n semanticKey: JSON.stringify({ frameTimeSeconds: time, transforms }), groups },\n \"composed-digital-geometry\", version, [\"Explicit inverse maps; incompatible domains require separate image stages\", \"No physical PSF, photon or noise-history recalculation\"]);\n}\n\n/**\n * Re-validates a prepared mapping from its defining fields (transforms and frame time). Its derived\n * fields (schema version, semantic key, groups) are recomputed, never trusted.\n */\nfunction reprepareGeometricMapping(mapping: PreparedGeometricMapping): PreparedGeometricMapping {\n requireInputObject(mapping, \"prepareGeometricMapping input\");\n return prepareGeometricMapping({ transforms: mapping.transforms, frameTimeSeconds: mapping.frameTimeSeconds }).value;\n}\n\n/** Maps a display point to the capture, with the full local derivatives in each direction. */\nexport function calculateComposedGeometricMapping(input: {\n mapping: PreparedGeometricMapping; destinationPointMm: LensFieldPointMm;\n}): CalculationResult<GeometricMappingPoint> {\n requireInputKeys(input, \"calculateComposedGeometricMapping\", [\"mapping\", \"destinationPointMm\"]);\n const mapping = reprepareGeometricMapping(input.mapping);\n return calculatePreparedGeometricMappingPoint(mapping, input.destinationPointMm);\n}\n\n/** Only a mapping parsed and copied within this call; prepared state from outside is never accepted. */\nconst VALIDATED_BROWN_CONRADY = new WeakMap<BrownConradyGeometricTransform, ValidatedBrownConradyDistortionProfile>();\n/** Validates a parsed transform's profile once per prepared mapping (the transform object is call-local). */\nfunction validatedBrownConrady(t: BrownConradyGeometricTransform): ValidatedBrownConradyDistortionProfile {\n let v = VALIDATED_BROWN_CONRADY.get(t);\n if (v === undefined) { v = validateBrownConradyDistortionProfile(t.profile); VALIDATED_BROWN_CONRADY.set(t, v); }\n return v;\n}\n\nfunction calculatePreparedGeometricMappingPoint(\n mapping: PreparedGeometricMapping,\n destinationPointMm: LensFieldPointMm\n): CalculationResult<GeometricMappingPoint> {\n let p = point(destinationPointMm);\n let j: GeometricJacobian = [1, 0, 0, 1];\n const components: GeometricMappingPoint[\"components\"][number][] = [];\n for (const t of mapping.transforms) {\n let local: GeometricJacobian;\n if (t.kind === \"affine\") {\n // Give each point its own result arrays when one mapping serves many points.\n local = [...t.matrix];\n p = affine(p, local, t.offsetMm);\n } else if (t.kind === \"brown-conrady\") {\n const mapped = brownConradyForwardValue(validatedBrownConrady(t), p);\n local = [...mapped.jacobian];\n p = mapped.mappedImagePointMm;\n } else if (t.kind === \"projection-remap\") {\n const mapped = lensProjectionRemapValue(t.destinationProjection.projectionModel, t.destinationProjection.focalLengthMm,\n t.sourceProjection.projectionModel, t.sourceProjection.focalLengthMm, p.x, p.y);\n local = [...mapped.jacobian];\n p = { ...mapped.sourcePointMm };\n } else {\n const { k1, k2, k3 } = t.profile.coefficients;\n const r2 = (p.x*p.x+p.y*p.y)/t.profile.normalizationRadiusMm**2;\n const s = 1+k1*r2+k2*r2*r2+k3*r2*r2*r2;\n const d = 2*(k1+2*k2*r2+3*k3*r2*r2)/t.profile.normalizationRadiusMm**2;\n local = [s+d*p.x*p.x, d*p.x*p.y, d*p.x*p.y, s+d*p.y*p.y];\n p = calculateRadialDistortionMapping({ imagePointMm: p, profile: t.profile }).value.mappedImagePointMm;\n }\n j = multiply(local, j);\n components.push({ id: t.id, sourcePointMm: { ...p }, jacobian: local });\n }\n // Singular values from the eigenvalues of the symmetric matrix JᵀJ. Computing the smaller one as\n // det/smax avoids cancellation error.\n const a = j[0]*j[0]+j[2]*j[2], b = j[0]*j[1]+j[2]*j[3], c = j[1]*j[1]+j[3]*j[3];\n const maximum = Math.sqrt((a+c+Math.hypot(a-c, 2*b))/2);\n const det = determinant(j), minimum = Math.abs(det)/maximum;\n return approximationResult({ sourcePointMm: p, jacobian: j, determinant: det,\n principalStretches: [maximum, minimum], anisotropy: maximum/minimum, components },\n \"composed-digital-geometry-point\", \"0.1.0\", [\"Jacobian warps already-formed blur and noise; it creates no captured detail\"]);\n}\n\n/** Maps a capture point to the display, for focus, metering and overlays. It inverts the same maps. */\nexport function calculateForwardGeometricMapping(input: {\n mapping: PreparedGeometricMapping; sourcePointMm: LensFieldPointMm;\n}): CalculationResult<LensFieldPointMm> {\n requireInputKeys(input, \"calculateForwardGeometricMapping\", [\"mapping\", \"sourcePointMm\"]);\n let p = point(input.sourcePointMm);\n const mapping = reprepareGeometricMapping(input.mapping);\n for (const t of [...mapping.transforms].reverse()) {\n p = t.kind === \"affine\"\n ? affine({ x: p.x-t.offsetMm.x, y: p.y-t.offsetMm.y }, inverse(t.matrix), { x: 0, y: 0 })\n : t.kind === \"brown-conrady\"\n ? brownConradyInverseValue(validatedBrownConrady(t), p)\n : t.kind === \"projection-remap\"\n ? lensProjectionRemapValue(t.sourceProjection.projectionModel, t.sourceProjection.focalLengthMm,\n t.destinationProjection.projectionModel, t.destinationProjection.focalLengthMm, p.x, p.y).sourcePointMm\n : calculateInverseRadialDistortionMapping({ distortedImagePointMm: p, profile: t.profile }).value.sourceImagePointMm;\n }\n return approximationResult(p, \"forward-digital-geometry-bridge\", \"0.1.0\", [\"Inverse of the authoritative destination-to-source geometry\"]);\n}\n\n/** @internal Shared lattice validation for downstream correction consumers. */\nexport function parseGeometricRaster(value: unknown): GeometricRaster {\n const r = record(value, [\"width\", \"height\", \"centerMm\", \"pitchMm\"]);\n const width = positive(r.width, \"width\"), height = positive(r.height, \"height\");\n if (!Number.isSafeInteger(width) || !Number.isSafeInteger(height) || width*height > 65536) {\n throw new InvalidScientificInputError(\"Raster must have at most 65536 integral samples.\");\n }\n return { width, height, centerMm: point(r.centerMm), pitchMm: positive(r.pitchMm, \"pitchMm\") };\n}\nfunction pixelPoint(r: GeometricRaster, x: number, y: number): LensFieldPointMm {\n return { x: r.centerMm.x+(x+.5-r.width/2)*r.pitchMm, y: r.centerMm.y-(y+.5-r.height/2)*r.pitchMm };\n}\nfunction pixelCoordinate(r: GeometricRaster, p: LensFieldPointMm): LensFieldPointMm {\n return { x: (p.x-r.centerMm.x)/r.pitchMm+r.width/2-.5, y: (r.centerMm.y-p.y)/r.pitchMm+r.height/2-.5 };\n}\nfunction supported(r: GeometricRaster, p: LensFieldPointMm, filter: GeometricResampler[\"filter\"]): boolean {\n const q = pixelCoordinate(r, p);\n return filter === \"nearest\"\n ? Math.round(q.x) >= 0 && Math.round(q.x) < r.width && Math.round(q.y) >= 0 && Math.round(q.y) < r.height\n : q.x >= 0 && q.x <= r.width-1 && q.y >= 0 && q.y <= r.height-1;\n}\n/** @internal Shared deterministic crop for a validated pixel mask. */\nexport function calculateValidSourceCrop(mask: readonly boolean[], width: number, height: number): GeometricSamplingPlan[\"jointCrop\"] {\n const heights = Array<number>(width).fill(0);\n let best: GeometricSamplingPlan[\"jointCrop\"] = null, area = 0;\n for (let y = 0; y < height; y++) {\n for (let x = 0; x < width; x++) heights[x] = mask[y*width+x] ? heights[x]!+1 : 0;\n const stack: number[] = [];\n for (let x = 0; x <= width; x++) {\n const h = x === width ? 0 : heights[x]!;\n while (stack.length && heights[stack.at(-1)!]! > h) {\n const index = stack.pop()!, rectangleHeight = heights[index]!;\n const left = stack.length ? stack.at(-1)!+1 : 0, rectangleWidth = x-left;\n if (rectangleHeight*rectangleWidth > area) {\n area = rectangleHeight*rectangleWidth;\n best = { x: left, y: y-rectangleHeight+1, width: rectangleWidth, height: rectangleHeight };\n }\n }\n stack.push(x);\n }\n }\n return best;\n}\n\n/** Composes compatible inverse maps, then resolves one shared plan for validity, crop and anti-aliasing (AA). */\nexport function calculateGeometricSamplingPlan(input: {\n mapping: PreparedGeometricMapping; sourceRaster: GeometricRaster; destinationRaster: GeometricRaster;\n resampler: GeometricResampler; physicalProjectionDistanceMm: number;\n /**\n * Ideal projection of the captured (source) image, used for the reported angles. Omitted or\n * \"rectilinear\" keeps the existing atan(mm / projection distance) angles exactly.\n */\n sourceProjectionModel?: LensProjectionModel;\n}): CalculationResult<GeometricSamplingPlan> {\n requireInputKeys(input, \"calculateGeometricSamplingPlan\", [\"mapping\", \"sourceRaster\", \"destinationRaster\", \"resampler\", \"physicalProjectionDistanceMm\", \"sourceProjectionModel\"]);\n const mapping = reprepareGeometricMapping(input.mapping);\n if (mapping.groups.length > 1) throw new InvalidScientificInputError(\"Separate incompatible-domain groups before resampling.\");\n const source = parseGeometricRaster(input.sourceRaster), destination = parseGeometricRaster(input.destinationRaster);\n const r = record(input.resampler, [\"id\", \"version\", \"filter\", \"antialias\"]);\n const resampler: GeometricResampler = { id: textValue(r.id), version: textValue(r.version),\n filter: choice(r.filter, [\"nearest\", \"bilinear\"]), antialias: choice(r.antialias, [\"none\", \"source-prefiltered\"]) };\n const projection = positive(input.physicalProjectionDistanceMm, \"physicalProjectionDistanceMm\");\n const points: GeometricMappingPoint[] = [], mask: boolean[] = [];\n for (let y = 0; y < destination.height; y++) for (let x = 0; x < destination.width; x++) {\n const mapped = calculatePreparedGeometricMappingPoint(mapping, pixelPoint(destination, x, y)).value;\n points.push(mapped); mask.push(supported(source, mapped.sourcePointMm, resampler.filter));\n }\n const requiresPrefilter = points.some((p) => p.principalStretches[0]*destination.pitchMm/source.pitchMm > 1+1e-12);\n const crop = calculateValidSourceCrop(mask, destination.width, destination.height);\n const sourceModel = input.sourceProjectionModel === undefined ? \"rectilinear\" : parseLensProjectionModel(input.sourceProjectionModel);\n const angle = sourceModel === \"rectilinear\"\n ? (mm: number): number => Math.atan(mm/projection)*180/Math.PI\n : (mm: number): number => lensProjectionSignedAxisAngle(sourceModel, projection, mm)*180/Math.PI;\n const retained = points.filter((_, i) => crop !== null && i%destination.width >= crop.x &&\n i%destination.width < crop.x+crop.width && Math.floor(i/destination.width) >= crop.y &&\n Math.floor(i/destination.width) < crop.y+crop.height).map((p) => p.sourcePointMm);\n const envelope = retained.length ? { minX: Math.min(...retained.map((p) => angle(p.x))),\n maxX: Math.max(...retained.map((p) => angle(p.x))), minY: Math.min(...retained.map((p) => angle(p.y))),\n maxY: Math.max(...retained.map((p) => angle(p.y))) } : null;\n return approximationResult({ mapping, sourceRaster: source, destinationRaster: destination, resampler, points,\n validSourceMask: mask, jointCrop: crop, requiresPrefilter,\n canResample: !requiresPrefilter || resampler.antialias === \"source-prefiltered\",\n physicalCapturedFovDegrees: {\n horizontal: angle(source.centerMm.x+source.width*source.pitchMm/2)-angle(source.centerMm.x-source.width*source.pitchMm/2),\n vertical: angle(source.centerMm.y+source.height*source.pitchMm/2)-angle(source.centerMm.y-source.height*source.pitchMm/2)\n }, retainedSampleRayEnvelopeDegrees: envelope },\n \"joint-geometric-sampling-plan\", \"0.1.0\", [\"Mask and crop are exact for this pixel-center lattice/filter, not continuous between-pixel support\", \"Compression requires explicitly source-prefiltered data; this API does not implement that prefilter\", \"No temporal trajectory crop guarantee\"]);\n}\n\n/** Resamples an already-formed single-channel image once. A null output sample marks missing source data. */\nexport function calculateGeometricResampling(input: {\n plan: GeometricSamplingPlan; sourceSamples: readonly number[];\n}): CalculationResult<{ samples: readonly (number | null)[]; resamplePasses: 1; resampler: GeometricResampler }> {\n requireInputKeys(input, \"calculateGeometricResampling\", [\"plan\", \"sourceSamples\"]);\n const prior = input.plan;\n requireInputObject(prior, \"calculateGeometricResampling plan\");\n // Re-plan from the defining fields; the derived plan fields are recomputed, never trusted.\n const plan = calculateGeometricSamplingPlan({ mapping: prior.mapping, sourceRaster: prior.sourceRaster,\n destinationRaster: prior.destinationRaster, resampler: prior.resampler, physicalProjectionDistanceMm: 1 }).value;\n if (!plan.canResample) throw new InvalidScientificInputError(\"Compression requires source-prefiltered data.\");\n const source = list(input.sourceSamples, 65536).map((v) => finite(v, \"source sample\"));\n if (source.length !== plan.sourceRaster.width*plan.sourceRaster.height) throw new InvalidScientificInputError(\"Source sample count mismatch.\");\n const samples = plan.points.map((p, index): number | null => {\n if (!plan.validSourceMask[index]) return null;\n const q = pixelCoordinate(plan.sourceRaster, p.sourcePointMm), width = plan.sourceRaster.width;\n if (plan.resampler.filter === \"nearest\") return source[Math.round(q.y)*width+Math.round(q.x)]!;\n const x = Math.floor(q.x), y = Math.floor(q.y), dx = q.x-x, dy = q.y-y;\n // A centre exactly on the boundary needs no missing neighbour. The border is never extended.\n const x1 = dx === 0 ? x : x+1, y1 = dy === 0 ? y : y+1;\n return (1-dy)*((1-dx)*source[y*width+x]!+dx*source[y*width+x1]!) +\n dy*((1-dx)*source[y1*width+x]!+dx*source[y1*width+x1]!);\n });\n return approximationResult({ samples, resamplePasses: 1, resampler: plan.resampler },\n \"single-pass-geometric-resampling\", \"0.1.0\", [\"Warps captured blur/noise; does not recalculate the optical PSF\"]);\n}\n"]}
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
import { type CalculationResult } from "../core/calculation-result.js";
|
|
12
12
|
import { type IlluminationVignettingProfile } from "../optics/illumination-vignetting.js";
|
|
13
13
|
import { type GenericOpticalEvidence, type OpticalProfileState } from "../optics/profile-contract.js";
|
|
14
|
-
import type
|
|
14
|
+
import { type LensFieldPointMm, type RadialDistortionProfile } from "../optics/radial-distortion.js";
|
|
15
15
|
import { type DigitalGeometricTransform, type GeometricImageDomain, type GeometricRaster, type GeometricResampler, type GeometricSamplingPlan } from "./geometric-transforms.js";
|
|
16
16
|
export type LensCorrectionChannel = "red" | "green" | "blue";
|
|
17
17
|
interface CorrectionComponentIdentity {
|
|
@@ -40,6 +40,14 @@ export interface IlluminationLensCorrection extends CorrectionComponentIdentity
|
|
|
40
40
|
kind: "peripheral-illumination";
|
|
41
41
|
profile: IlluminationVignettingProfile;
|
|
42
42
|
strength: number;
|
|
43
|
+
/**
|
|
44
|
+
* Optional (#584): the capture's radial distortion r_d = r(1 + k1ρ² + k2ρ⁴ + k3ρ⁶), whose area factor 1/det J the capture also
|
|
45
|
+
* multiplied into the irradiance (det J = (1 + k1ρ_i² + k2ρ_i⁴ + k3ρ_i⁶)(1 + 3k1ρ_i² + 5k2ρ_i⁴ + 7k3ρ_i⁶) at the ideal point ρ_i that
|
|
46
|
+
* the lens images to the sensor point). With it, the relative illumination corrected is E(ρ_s)/det J(ρ_i), evaluated at the
|
|
47
|
+
* capture's sensor (source) point, so strength 1 flattens a flat field. It holds whether or not the distortion itself is corrected.
|
|
48
|
+
* Without it the gain is 1/E alone, as before.
|
|
49
|
+
*/
|
|
50
|
+
distortionAreaFactor?: RadialDistortionProfile;
|
|
43
51
|
}
|
|
44
52
|
export type LensCorrectionComponent = GeometricLensCorrection | LateralCaLensCorrection | IlluminationLensCorrection;
|
|
45
53
|
/** A correction profile for one exact lens-and-camera system. Components are listed in the order they are applied. */
|
|
@@ -78,7 +86,9 @@ export declare function resolveLensCorrectionPlan(input: {
|
|
|
78
86
|
}): CalculationResult<ResolvedLensCorrectionPlan>;
|
|
79
87
|
/**
|
|
80
88
|
* Applies a gain after capture and reports the variance before clipping. It does not rewrite
|
|
81
|
-
* the photon or SNR (signal-to-noise ratio) history of the capture.
|
|
89
|
+
* the photon or SNR (signal-to-noise ratio) history of the capture. The gain is T^(−strength), T the relative illumination at
|
|
90
|
+
* `imagePointMm`: E(ρ) of the component's profile, divided by det J(ρ_i) when the component has a `distortionAreaFactor` (#584;
|
|
91
|
+
* then `imagePointMm` is the capture's sensor point, where the capture applied both).
|
|
82
92
|
*/
|
|
83
93
|
export declare function calculatePeripheralIlluminationCorrection(input: {
|
|
84
94
|
component: IlluminationLensCorrection;
|
|
@@ -13,6 +13,7 @@ import { approximationResult } from "../core/calculation-result.js";
|
|
|
13
13
|
import { InvalidScientificInputError } from "../core/validation.js";
|
|
14
14
|
import { calculateIlluminationVignetting } from "../optics/illumination-vignetting.js";
|
|
15
15
|
import { choice, finite, list, parseEvidence, parseOpticalProfileState, positive, record, requireSameState, textValue } from "../optics/profile-contract.js";
|
|
16
|
+
import { calculateInverseRadialSourcePointValue, validateRadialDistortionProfile } from "../optics/radial-distortion.js";
|
|
16
17
|
import { calculateGeometricResampling, calculateGeometricSamplingPlan, parseDigitalGeometricTransform, prepareGeometricMapping, parseGeometricRaster, calculateValidSourceCrop } from "./geometric-transforms.js";
|
|
17
18
|
import { requireInputObject, requireInputKeys } from "../core/record-validation.js";
|
|
18
19
|
import { InvalidConfigurationError } from "../core/configuration-error.js";
|
|
@@ -30,7 +31,7 @@ export function parseGenericLensCorrectionProfile(value) {
|
|
|
30
31
|
const r = record(value, ["schemaVersion", "id", "version", "state", "evidence", "components"]);
|
|
31
32
|
const components = list(r.components, 16).map((value) => {
|
|
32
33
|
const c = record(value, ["id", "version", "domain", "availability", "defaultEnabled", "dependencies",
|
|
33
|
-
"requiredByStabilizationModes", "residualNote", "kind", "transform", "transforms", "profile", "strength"]);
|
|
34
|
+
"requiredByStabilizationModes", "residualNote", "kind", "transform", "transforms", "profile", "strength", "distortionAreaFactor"]);
|
|
34
35
|
if (typeof c.defaultEnabled !== "boolean")
|
|
35
36
|
throw new InvalidConfigurationError("defaultEnabled must be boolean.");
|
|
36
37
|
const identity = { id: textValue(c.id), version: textValue(c.version),
|
|
@@ -40,7 +41,7 @@ export function parseGenericLensCorrectionProfile(value) {
|
|
|
40
41
|
requiredByStabilizationModes: list(c.requiredByStabilizationModes, 16).map(textValue), residualNote: textValue(c.residualNote) };
|
|
41
42
|
const kind = choice(c.kind, ["geometry", "lateral-ca", "peripheral-illumination"]);
|
|
42
43
|
if (kind === "geometry") {
|
|
43
|
-
if (c.transforms !== undefined || c.profile !== undefined || c.strength !== undefined)
|
|
44
|
+
if (c.transforms !== undefined || c.profile !== undefined || c.strength !== undefined || c.distortionAreaFactor !== undefined)
|
|
44
45
|
throw new InvalidScientificInputError("Extraneous geometry parameters.");
|
|
45
46
|
const transform = parseDigitalGeometricTransform(c.transform);
|
|
46
47
|
if (transform.domain !== identity.domain || !["distortion", "breathing"].includes(transform.purpose))
|
|
@@ -48,7 +49,7 @@ export function parseGenericLensCorrectionProfile(value) {
|
|
|
48
49
|
return { ...identity, kind, transform };
|
|
49
50
|
}
|
|
50
51
|
if (kind === "lateral-ca") {
|
|
51
|
-
if (c.transform !== undefined || c.profile !== undefined || c.strength !== undefined)
|
|
52
|
+
if (c.transform !== undefined || c.profile !== undefined || c.strength !== undefined || c.distortionAreaFactor !== undefined)
|
|
52
53
|
throw new InvalidScientificInputError("Extraneous CA parameters.");
|
|
53
54
|
const t = record(c.transforms, ["red", "green", "blue"]);
|
|
54
55
|
const transforms = { red: parseDigitalGeometricTransform(t.red), green: parseDigitalGeometricTransform(t.green), blue: parseDigitalGeometricTransform(t.blue) };
|
|
@@ -63,7 +64,13 @@ export function parseGenericLensCorrectionProfile(value) {
|
|
|
63
64
|
const strength = finite(c.strength, "strength");
|
|
64
65
|
if (strength < 0 || strength > 1)
|
|
65
66
|
throw new InvalidScientificInputError("Strength must lie in [0,1].");
|
|
66
|
-
|
|
67
|
+
if (c.distortionAreaFactor === undefined)
|
|
68
|
+
return { ...identity, kind, profile: illumination(c.profile), strength };
|
|
69
|
+
const d = record(c.distortionAreaFactor, ["normalizationRadiusMm", "maximumNormalizedRadius", "coefficients"]), k = record(d.coefficients, ["k1", "k2", "k3"]);
|
|
70
|
+
const distortionAreaFactor = { normalizationRadiusMm: positive(d.normalizationRadiusMm, "normalizationRadiusMm"), maximumNormalizedRadius: positive(d.maximumNormalizedRadius, "maximumNormalizedRadius"),
|
|
71
|
+
coefficients: { k1: finite(k.k1, "k1"), k2: finite(k.k2, "k2"), k3: finite(k.k3, "k3") } };
|
|
72
|
+
validateRadialDistortionProfile(distortionAreaFactor);
|
|
73
|
+
return { ...identity, kind, profile: illumination(c.profile), strength, distortionAreaFactor };
|
|
67
74
|
});
|
|
68
75
|
const preceding = new Set(), mappingIds = new Set();
|
|
69
76
|
for (const c of components) {
|
|
@@ -119,7 +126,9 @@ export function resolveLensCorrectionPlan(input) {
|
|
|
119
126
|
}
|
|
120
127
|
/**
|
|
121
128
|
* Applies a gain after capture and reports the variance before clipping. It does not rewrite
|
|
122
|
-
* the photon or SNR (signal-to-noise ratio) history of the capture.
|
|
129
|
+
* the photon or SNR (signal-to-noise ratio) history of the capture. The gain is T^(−strength), T the relative illumination at
|
|
130
|
+
* `imagePointMm`: E(ρ) of the component's profile, divided by det J(ρ_i) when the component has a `distortionAreaFactor` (#584;
|
|
131
|
+
* then `imagePointMm` is the capture's sensor point, where the capture applied both).
|
|
123
132
|
*/
|
|
124
133
|
export function calculatePeripheralIlluminationCorrection(input) {
|
|
125
134
|
requireInputKeys(input, "calculatePeripheralIlluminationCorrection", ["component", "imagePointMm", "signal", "noiseVariance", "clippingLevel"]);
|
|
@@ -131,7 +140,12 @@ export function calculatePeripheralIlluminationCorrection(input) {
|
|
|
131
140
|
const level = positive(input.clippingLevel, "clippingLevel");
|
|
132
141
|
if (variance < 0)
|
|
133
142
|
throw new InvalidScientificInputError("Variance must be nonnegative.");
|
|
134
|
-
|
|
143
|
+
let throughput = calculateIlluminationVignetting({ imagePointMm: input.imagePointMm, profile: component.profile }).value.linearThroughputFactor;
|
|
144
|
+
if (component.distortionAreaFactor !== undefined) {
|
|
145
|
+
const { k1, k2, k3 } = component.distortionAreaFactor.coefficients;
|
|
146
|
+
const p2 = calculateInverseRadialSourcePointValue(input.imagePointMm, validateRadialDistortionProfile(component.distortionAreaFactor), "imagePointMm").sourceNormalizedRadius ** 2;
|
|
147
|
+
throughput /= (1 + p2 * (k1 + p2 * (k2 + p2 * k3))) * (1 + p2 * (3 * k1 + p2 * (5 * k2 + p2 * 7 * k3)));
|
|
148
|
+
}
|
|
135
149
|
const gain = throughput ** (-component.strength), before = signal * gain;
|
|
136
150
|
return approximationResult({ gain, signalBeforeClipping: before, signal: Math.min(level, before),
|
|
137
151
|
noiseVarianceBeforeClipping: variance * gain * gain, clipped: before > level }, "post-capture-peripheral-illumination-gain", "0.1.0", ["Variance describes pre-clip samples only", "Gain does not increase captured photons or restore sensor SNR"]);
|
|
@@ -203,8 +217,9 @@ export function calculateLensCorrectedCapture(input) {
|
|
|
203
217
|
if (signal === null)
|
|
204
218
|
return null;
|
|
205
219
|
const raster = input.destinationRaster, x = index % raster.width, y = Math.floor(index / raster.width);
|
|
220
|
+
// #584: a gain that carries the distortion's area factor is the capture's own, so it is read at the source point.
|
|
206
221
|
const corrected = calculatePeripheralIlluminationCorrection({ component: c,
|
|
207
|
-
imagePointMm: { x: raster.centerMm.x + (x + .5 - raster.width / 2) * raster.pitchMm,
|
|
222
|
+
imagePointMm: c.distortionAreaFactor ? sampling.points[index].sourcePointMm : { x: raster.centerMm.x + (x + .5 - raster.width / 2) * raster.pitchMm,
|
|
208
223
|
y: raster.centerMm.y - (y + .5 - raster.height / 2) * raster.pitchMm },
|
|
209
224
|
signal, noiseVariance: 0, clippingLevel: input.clippingLevel }).value;
|
|
210
225
|
if (corrected.clipped)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lens-corrections.js","sourceRoot":"","sources":["../../src/output/lens-corrections.ts"],"names":[],"mappings":"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","sourcesContent":["// SPDX-License-Identifier: Apache-2.0\n\n/**\n * Generic lens corrections applied after capture: distortion, lateral chromatic aberration\n * (CA) and vignetting (corner darkening).\n *\n * It parses correction profiles, resolves which corrections are on for a camera state, and\n * applies them to linear RGB channels. It does not extrapolate beyond a profile and does not\n * claim to restore lost detail.\n * @see docs/DIGITAL_OPTICS_FOUNDATION.md for equations, coordinate/unit conventions, blockers and\n * support limits.\n */\n\nimport { approximationResult, type CalculationResult } from \"../core/calculation-result.js\";\nimport { InvalidScientificInputError } from \"../core/validation.js\";\nimport { calculateIlluminationVignetting, type IlluminationVignettingProfile } from \"../optics/illumination-vignetting.js\";\nimport {\n choice, finite, list, parseEvidence, parseOpticalProfileState, positive, record,\n requireSameState, textValue, type GenericOpticalEvidence, type OpticalProfileState\n} from \"../optics/profile-contract.js\";\nimport type { LensFieldPointMm } from \"../optics/radial-distortion.js\";\nimport {\n calculateGeometricResampling, calculateGeometricSamplingPlan, parseDigitalGeometricTransform,\n prepareGeometricMapping, parseGeometricRaster, calculateValidSourceCrop, type DigitalGeometricTransform, type GeometricImageDomain,\n type GeometricRaster, type GeometricResampler, type GeometricSamplingPlan\n} from \"./geometric-transforms.js\";\nimport { requireInputObject, requireInputKeys } from \"../core/record-validation.js\";\nimport { InvalidConfigurationError } from \"../core/configuration-error.js\";\n\nexport type LensCorrectionChannel = \"red\" | \"green\" | \"blue\";\ninterface CorrectionComponentIdentity {\n id: string;\n version: string;\n domain: GeometricImageDomain;\n availability: \"toggle\" | \"automatic\" | \"mandatory\";\n defaultEnabled: boolean;\n dependencies: readonly string[];\n requiredByStabilizationModes: readonly string[];\n /** Declared remaining errors and calibration limits. They are not inferred from the optical model tier. */\n residualNote: string;\n}\n/** A distortion correction map, declared separately. It may deliberately leave some physical distortion in place. */\nexport interface GeometricLensCorrection extends CorrectionComponentIdentity {\n kind: \"geometry\";\n transform: DigitalGeometricTransform;\n}\n/** Lateral CA: shifts colour channels into register. It does not correct longitudinal CA or colour shading. */\nexport interface LateralCaLensCorrection extends CorrectionComponentIdentity {\n kind: \"lateral-ca\";\n transforms: Readonly<Record<LensCorrectionChannel, DigitalGeometricTransform>>;\n}\n/** Vignetting correction as a gain applied after capture. A strength below 1 deliberately leaves some falloff. Range 0..1. */\nexport interface IlluminationLensCorrection extends CorrectionComponentIdentity {\n kind: \"peripheral-illumination\";\n profile: IlluminationVignettingProfile;\n strength: number;\n}\nexport type LensCorrectionComponent = GeometricLensCorrection | LateralCaLensCorrection | IlluminationLensCorrection;\n/** A correction profile for one exact lens-and-camera system. Components are listed in the order they are applied. */\nexport interface GenericLensCorrectionProfile {\n schemaVersion: \"0.1.0\";\n id: string;\n version: string;\n state: OpticalProfileState;\n evidence: GenericOpticalEvidence;\n components: readonly LensCorrectionComponent[];\n}\nexport interface ResolvedLensCorrectionPlan {\n profile: GenericLensCorrectionProfile;\n outputKind: \"raw-like\" | \"processed\";\n selectionKind: \"camera-selectable\" | \"reference-bypass\";\n components: readonly { component: LensCorrectionComponent; enabled: boolean;\n reason: \"selected\" | \"default\" | \"mandatory\" | \"stabilization-dependency\" | \"component-dependency\" | \"reference-bypass\" }[];\n /** For now, a RAW-like intent is recorded as metadata only. */\n application: \"metadata-only\" | \"bake-downstream\";\n}\nfunction illumination(value: unknown): IlluminationVignettingProfile {\n const r = record(value, [\"normalizationRadiusMm\", \"maximumNormalizedRadius\", \"coefficients\"]);\n const c = record(r.coefficients, [\"r2\", \"r4\", \"r6\"]);\n const profile = { normalizationRadiusMm: positive(r.normalizationRadiusMm, \"normalizationRadiusMm\"),\n maximumNormalizedRadius: positive(r.maximumNormalizedRadius, \"maximumNormalizedRadius\"),\n coefficients: { r2: finite(c.r2, \"r2\"), r4: finite(c.r4, \"r4\"), r6: finite(c.r6, \"r6\") } };\n calculateIlluminationVignetting({ imagePointMm: { x: 0, y: 0 }, profile });\n return profile;\n}\n/** Strictly parses a generic correction profile. It does not extrapolate and makes no claim to restore lost detail. */\nexport function parseGenericLensCorrectionProfile(value: unknown): GenericLensCorrectionProfile {\n const r = record(value, [\"schemaVersion\", \"id\", \"version\", \"state\", \"evidence\", \"components\"]);\n const components = list(r.components, 16).map((value): LensCorrectionComponent => {\n const c = record(value, [\"id\", \"version\", \"domain\", \"availability\", \"defaultEnabled\", \"dependencies\",\n \"requiredByStabilizationModes\", \"residualNote\", \"kind\", \"transform\", \"transforms\", \"profile\", \"strength\"]);\n if (typeof c.defaultEnabled !== \"boolean\") throw new InvalidConfigurationError(\"defaultEnabled must be boolean.\");\n const identity = { id: textValue(c.id), version: textValue(c.version),\n domain: choice(c.domain, [\"raw-channel\", \"reconstructed-linear\", \"processed-output\"]),\n availability: choice(c.availability, [\"toggle\", \"automatic\", \"mandatory\"]), defaultEnabled: c.defaultEnabled,\n dependencies: list(c.dependencies, 16).map(textValue),\n requiredByStabilizationModes: list(c.requiredByStabilizationModes, 16).map(textValue), residualNote: textValue(c.residualNote) };\n const kind = choice(c.kind, [\"geometry\", \"lateral-ca\", \"peripheral-illumination\"]);\n if (kind === \"geometry\") {\n if (c.transforms !== undefined || c.profile !== undefined || c.strength !== undefined) throw new InvalidScientificInputError(\"Extraneous geometry parameters.\");\n const transform = parseDigitalGeometricTransform(c.transform);\n if (transform.domain !== identity.domain || ![\"distortion\", \"breathing\"].includes(transform.purpose)) throw new InvalidScientificInputError(\"Geometry domain/purpose mismatch.\");\n return { ...identity, kind, transform };\n }\n if (kind === \"lateral-ca\") {\n if (c.transform !== undefined || c.profile !== undefined || c.strength !== undefined) throw new InvalidScientificInputError(\"Extraneous CA parameters.\");\n const t = record(c.transforms, [\"red\", \"green\", \"blue\"]);\n const transforms = { red: parseDigitalGeometricTransform(t.red), green: parseDigitalGeometricTransform(t.green), blue: parseDigitalGeometricTransform(t.blue) };\n for (const transform of Object.values(transforms)) {\n if (transform.domain !== identity.domain || transform.purpose !== \"lateral-ca\") throw new InvalidScientificInputError(\"CA domain/purpose mismatch.\");\n }\n return { ...identity, kind, transforms };\n }\n if (c.transform !== undefined || c.transforms !== undefined) throw new InvalidScientificInputError(\"Extraneous illumination geometry.\");\n const strength = finite(c.strength, \"strength\");\n if (strength < 0 || strength > 1) throw new InvalidScientificInputError(\"Strength must lie in [0,1].\");\n return { ...identity, kind, profile: illumination(c.profile), strength };\n });\n const preceding = new Set<string>(), mappingIds = new Set<string>();\n for (const c of components) {\n if (preceding.has(c.id) || c.dependencies.some((id) => !preceding.has(id)) ||\n new Set(c.dependencies).size !== c.dependencies.length) throw new InvalidScientificInputError(\"Component IDs/dependency order must be unique and acyclic.\");\n preceding.add(c.id);\n // Common and per-channel transforms need stable, distinct IDs when they are combined.\n const maps = c.kind === \"geometry\" ? [c.transform] : c.kind === \"lateral-ca\" ? Object.values(c.transforms) : [];\n for (const t of maps) {\n if (mappingIds.has(t.id)) throw new InvalidScientificInputError(\"Duplicate correction transform ID.\");\n mappingIds.add(t.id);\n }\n }\n return { schemaVersion: choice(r.schemaVersion, [\"0.1.0\"]), id: textValue(r.id), version: textValue(r.version),\n state: parseOpticalProfileState(r.state), evidence: parseEvidence(r.evidence), components };\n}\n\n/**\n * Decides which corrections apply for a camera state. It accounts for per-component settings,\n * explicit dependencies between components, RAW intent and the educational \"corrections off\" bypass.\n */\nexport function resolveLensCorrectionPlan(input: {\n profile: GenericLensCorrectionProfile; state: OpticalProfileState;\n selections: Readonly<Record<string, \"on\" | \"off\" | \"auto\">>;\n outputKind: \"raw-like\" | \"processed\"; selectionKind: \"camera-selectable\" | \"reference-bypass\";\n}): CalculationResult<ResolvedLensCorrectionPlan> {\n requireInputKeys(input, \"resolveLensCorrectionPlan\", [\"profile\", \"state\", \"selections\", \"outputKind\", \"selectionKind\"]);\n const profile = parseGenericLensCorrectionProfile(input.profile);\n requireSameState(profile.state, input.state);\n const outputKind = choice(input.outputKind, [\"raw-like\", \"processed\"]);\n const selectionKind = choice(input.selectionKind, [\"camera-selectable\", \"reference-bypass\"]);\n const selections = record(input.selections, profile.components.map((c) => c.id));\n const components: ResolvedLensCorrectionPlan[\"components\"][number][] = profile.components.map((c): ResolvedLensCorrectionPlan[\"components\"][number] => {\n const selection = choice(selections[c.id] ?? \"auto\", [\"on\", \"off\", \"auto\"]);\n if (selectionKind === \"reference-bypass\") return { component: c, enabled: false, reason: \"reference-bypass\" };\n const stabilization = c.requiredByStabilizationModes.includes(profile.state.stabilizationMode);\n if (c.availability === \"mandatory\" && selection === \"off\") throw new InvalidScientificInputError(\"Mandatory correction cannot be disabled as a camera setting; use reference-bypass.\");\n if (c.availability === \"automatic\" && selection !== \"auto\") throw new InvalidScientificInputError(\"Automatic correction has no camera toggle.\");\n return { component: c, enabled: c.availability === \"mandatory\" || stabilization || (selection === \"auto\" ? c.defaultEnabled : selection === \"on\"),\n reason: c.availability === \"mandatory\" ? \"mandatory\" : stabilization ? \"stabilization-dependency\" : selection === \"auto\" ? \"default\" : \"selected\" };\n });\n for (const entry of [...components].reverse()) if (entry.enabled) for (const id of entry.component.dependencies) {\n const dependency = components.find((c) => c.component.id === id)!;\n dependency.enabled = true; dependency.reason = \"component-dependency\";\n }\n return approximationResult({ profile, outputKind, selectionKind, components,\n application: outputKind === \"raw-like\" ? \"metadata-only\" : \"bake-downstream\" },\n \"generic-camera-lens-correction-plan\", \"0.1.0\", [profile.evidence.basis, profile.evidence.residualNote,\n \"Corrections occur after the same physical capture; tier is not a correction-strength input\",\n \"Raw-like output preserves intent without baking corrections; color shading, axial CA and restoration remain unsupported\"]);\n}\n\n/**\n * Applies a gain after capture and reports the variance before clipping. It does not rewrite\n * the photon or SNR (signal-to-noise ratio) history of the capture.\n */\nexport function calculatePeripheralIlluminationCorrection(input: {\n component: IlluminationLensCorrection; imagePointMm: LensFieldPointMm;\n signal: number; noiseVariance: number; clippingLevel: number;\n}): CalculationResult<{ gain: number; signalBeforeClipping: number; signal: number; noiseVarianceBeforeClipping: number; clipped: boolean }> {\n requireInputKeys(input, \"calculatePeripheralIlluminationCorrection\", [\"component\", \"imagePointMm\", \"signal\", \"noiseVariance\", \"clippingLevel\"]);\n const component = input.component;\n requireInputObject(component, \"component input\");\n if (component.kind !== \"peripheral-illumination\" || component.strength < 0 || component.strength > 1 || !Number.isFinite(component.strength)) throw new InvalidScientificInputError(\"Invalid illumination component.\");\n const signal = finite(input.signal, \"signal\"), variance = finite(input.noiseVariance, \"noiseVariance\");\n const level = positive(input.clippingLevel, \"clippingLevel\");\n if (variance < 0) throw new InvalidScientificInputError(\"Variance must be nonnegative.\");\n const throughput = calculateIlluminationVignetting({ imagePointMm: input.imagePointMm, profile: component.profile }).value.linearThroughputFactor;\n const gain = throughput**(-component.strength), before = signal*gain;\n return approximationResult({ gain, signalBeforeClipping: before, signal: Math.min(level, before),\n noiseVarianceBeforeClipping: variance*gain*gain, clipped: before > level },\n \"post-capture-peripheral-illumination-gain\", \"0.1.0\", [\"Variance describes pre-clip samples only\", \"Gain does not increase captured photons or restore sensor SNR\"]);\n}\n\n/** The fixed capture identity travels with the output channels, so On/Off comparisons use the same capture. */\nexport interface LensCorrectionCapture {\n state: OpticalProfileState;\n captureId: string;\n noiseRealizationId: string;\n timeSeconds: number;\n raster: GeometricRaster;\n channels: Readonly<Record<LensCorrectionChannel, readonly number[]>>;\n}\n/** Applies bounded corrections to RGB channels that are already sampled and linear.\n * Compatible shared geometry and per-channel CA are combined, so each channel is resampled once.\n * A gain between geometry components, or incompatible domains, needs a separate staged caller.\n */\nexport function calculateLensCorrectedCapture(input: {\n plan: ResolvedLensCorrectionPlan; capture: LensCorrectionCapture;\n destinationRaster: GeometricRaster; resampler: GeometricResampler;\n physicalProjectionDistanceMm: number; clippingLevel: number;\n}): CalculationResult<{\n captureId: string; noiseRealizationId: string; timeSeconds: number;\n application: ResolvedLensCorrectionPlan[\"application\"];\n channels: Readonly<Record<LensCorrectionChannel, readonly (number | null)[]>>;\n samplingPlans: Partial<Record<LensCorrectionChannel, GeometricSamplingPlan>>;\n /** Area valid in every channel, before cropping. Missing colours are never made up. */\n validSourceMask: readonly boolean[];\n jointCrop: GeometricSamplingPlan[\"jointCrop\"];\n /** Clipping events in gain stages, before the shared valid-area crop. Each stage is counted separately. */\n illuminationClippingEventCount: number;\n}> {\n requireInputKeys(input, \"calculateLensCorrectedCapture\", [\"plan\", \"capture\", \"destinationRaster\", \"resampler\", \"physicalProjectionDistanceMm\", \"clippingLevel\"]);\n // Re-resolve the plan, which may be untrusted or changed, so callers cannot fake enabled or mandatory states.\n requireInputObject(input.plan, \"plan\");\n const plan = resolveLensCorrectionPlan({ profile: input.plan.profile, state: input.plan.profile.state,\n selections: Object.fromEntries(input.plan.components.filter((e) => e.component.availability === \"toggle\").map((e) => [e.component.id, e.enabled ? \"on\" : \"off\"])),\n outputKind: input.plan.outputKind, selectionKind: input.plan.selectionKind }).value;\n const capture = input.capture;\n requireSameState(plan.profile.state, capture.state);\n const sourceRaster = parseGeometricRaster(capture.raster);\n const destination = parseGeometricRaster(input.destinationRaster);\n if (destination.width !== plan.profile.state.outputWidth || destination.height !== plan.profile.state.outputHeight) {\n throw new InvalidScientificInputError(\"Destination raster differs from correction output binding.\");\n }\n textValue(capture.captureId); textValue(capture.noiseRealizationId);\n if (finite(capture.timeSeconds, \"timeSeconds\") < 0) throw new InvalidScientificInputError(\"Invalid capture time.\");\n const count = capture.raster.width*capture.raster.height;\n for (const channel of [\"red\", \"green\", \"blue\"] as const) {\n const data = list(capture.channels[channel], 65536);\n if (data.length !== count) throw new InvalidScientificInputError(\"Capture channel sample count mismatch.\");\n data.forEach((s) => finite(s, \"channel sample\"));\n }\n const active = plan.components.filter((e) => e.enabled).map((e) => e.component);\n const sameLattice = sourceRaster.width === destination.width && sourceRaster.height === destination.height &&\n sourceRaster.pitchMm === destination.pitchMm && sourceRaster.centerMm.x === destination.centerMm.x &&\n sourceRaster.centerMm.y === destination.centerMm.y;\n // Disabling corrections does not disable an explicit output crop/resampling request.\n if (plan.application === \"metadata-only\" || (!active.length && sameLattice)) {\n return approximationResult({ captureId: capture.captureId, noiseRealizationId: capture.noiseRealizationId,\n timeSeconds: capture.timeSeconds, application: plan.application, channels: capture.channels,\n samplingPlans: {}, validSourceMask: Array<boolean>(count).fill(true), illuminationClippingEventCount: 0,\n jointCrop: { x: 0, y: 0, width: capture.raster.width, height: capture.raster.height } },\n \"generic-lens-correction-capture\", \"0.1.0\", [\"Original physical capture preserved\"]);\n }\n if (active.some((c) => c.domain !== \"reconstructed-linear\")) throw new InvalidScientificInputError(\"This executor requires reconstructed-linear components; other domains need separate consumers.\");\n let seenGain = false;\n for (const c of active) {\n if (c.kind === \"peripheral-illumination\") seenGain = true;\n else if (seenGain) throw new InvalidScientificInputError(\"Cannot reorder geometry across a gain stage.\");\n }\n const channels = {} as Record<LensCorrectionChannel, readonly (number | null)[]>;\n const samplingPlans: Partial<Record<LensCorrectionChannel, GeometricSamplingPlan>> = {};\n let illuminationClippingEventCount = 0;\n for (const channel of [\"red\", \"green\", \"blue\"] as const) {\n // Corrections are listed source → destination. Inverse sampling runs them in reverse.\n const transforms = active.filter((c) => c.kind !== \"peripheral-illumination\").reverse().map((c) =>\n c.kind === \"geometry\" ? c.transform : (c as LateralCaLensCorrection).transforms[channel]);\n const mapping = prepareGeometricMapping({ transforms, frameTimeSeconds: capture.timeSeconds }).value;\n const sampling = calculateGeometricSamplingPlan({ mapping, sourceRaster: capture.raster,\n destinationRaster: input.destinationRaster, resampler: input.resampler,\n physicalProjectionDistanceMm: input.physicalProjectionDistanceMm }).value;\n samplingPlans[channel] = sampling;\n let data = calculateGeometricResampling({ plan: sampling, sourceSamples: capture.channels[channel] }).value.samples;\n for (const c of active) if (c.kind === \"peripheral-illumination\") {\n data = data.map((signal, index): number | null => {\n if (signal === null) return null;\n const raster = input.destinationRaster, x = index%raster.width, y = Math.floor(index/raster.width);\n const corrected = calculatePeripheralIlluminationCorrection({ component: c,\n imagePointMm: { x: raster.centerMm.x+(x+.5-raster.width/2)*raster.pitchMm,\n y: raster.centerMm.y-(y+.5-raster.height/2)*raster.pitchMm },\n signal, noiseVariance: 0, clippingLevel: input.clippingLevel }).value;\n if (corrected.clipped) illuminationClippingEventCount++;\n return corrected.signal;\n });\n }\n channels[channel] = data;\n }\n const mask = channels.red.map((_, i) => channels.red[i] !== null && channels.green[i] !== null && channels.blue[i] !== null);\n for (const channel of [\"red\", \"green\", \"blue\"] as const) channels[channel] = channels[channel].map((s, i) => mask[i] ? s : null);\n return approximationResult({ captureId: capture.captureId, noiseRealizationId: capture.noiseRealizationId,\n timeSeconds: capture.timeSeconds, application: plan.application, channels, samplingPlans, validSourceMask: mask,\n illuminationClippingEventCount,\n jointCrop: calculateValidSourceCrop(mask, destination.width, destination.height) },\n \"generic-lens-correction-capture\", \"0.1.0\", [\"Input capture/noise realization remains unchanged\", \"Channel support intersects before output; optical blur/noise is warped, not physically repaired\",\n \"No production-plan composition is enabled by this standalone executor\"]);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"lens-corrections.js","sourceRoot":"","sources":["../../src/output/lens-corrections.ts"],"names":[],"mappings":"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","sourcesContent":["// SPDX-License-Identifier: Apache-2.0\n\n/**\n * Generic lens corrections applied after capture: distortion, lateral chromatic aberration\n * (CA) and vignetting (corner darkening).\n *\n * It parses correction profiles, resolves which corrections are on for a camera state, and\n * applies them to linear RGB channels. It does not extrapolate beyond a profile and does not\n * claim to restore lost detail.\n * @see docs/DIGITAL_OPTICS_FOUNDATION.md for equations, coordinate/unit conventions, blockers and\n * support limits.\n */\n\nimport { approximationResult, type CalculationResult } from \"../core/calculation-result.js\";\nimport { InvalidScientificInputError } from \"../core/validation.js\";\nimport { calculateIlluminationVignetting, type IlluminationVignettingProfile } from \"../optics/illumination-vignetting.js\";\nimport {\n choice, finite, list, parseEvidence, parseOpticalProfileState, positive, record,\n requireSameState, textValue, type GenericOpticalEvidence, type OpticalProfileState\n} from \"../optics/profile-contract.js\";\nimport { calculateInverseRadialSourcePointValue, validateRadialDistortionProfile, type LensFieldPointMm, type RadialDistortionProfile } from \"../optics/radial-distortion.js\";\nimport {\n calculateGeometricResampling, calculateGeometricSamplingPlan, parseDigitalGeometricTransform,\n prepareGeometricMapping, parseGeometricRaster, calculateValidSourceCrop, type DigitalGeometricTransform, type GeometricImageDomain,\n type GeometricRaster, type GeometricResampler, type GeometricSamplingPlan\n} from \"./geometric-transforms.js\";\nimport { requireInputObject, requireInputKeys } from \"../core/record-validation.js\";\nimport { InvalidConfigurationError } from \"../core/configuration-error.js\";\n\nexport type LensCorrectionChannel = \"red\" | \"green\" | \"blue\";\ninterface CorrectionComponentIdentity {\n id: string;\n version: string;\n domain: GeometricImageDomain;\n availability: \"toggle\" | \"automatic\" | \"mandatory\";\n defaultEnabled: boolean;\n dependencies: readonly string[];\n requiredByStabilizationModes: readonly string[];\n /** Declared remaining errors and calibration limits. They are not inferred from the optical model tier. */\n residualNote: string;\n}\n/** A distortion correction map, declared separately. It may deliberately leave some physical distortion in place. */\nexport interface GeometricLensCorrection extends CorrectionComponentIdentity {\n kind: \"geometry\";\n transform: DigitalGeometricTransform;\n}\n/** Lateral CA: shifts colour channels into register. It does not correct longitudinal CA or colour shading. */\nexport interface LateralCaLensCorrection extends CorrectionComponentIdentity {\n kind: \"lateral-ca\";\n transforms: Readonly<Record<LensCorrectionChannel, DigitalGeometricTransform>>;\n}\n/** Vignetting correction as a gain applied after capture. A strength below 1 deliberately leaves some falloff. Range 0..1. */\nexport interface IlluminationLensCorrection extends CorrectionComponentIdentity {\n kind: \"peripheral-illumination\";\n profile: IlluminationVignettingProfile;\n strength: number;\n /**\n * Optional (#584): the capture's radial distortion r_d = r(1 + k1ρ² + k2ρ⁴ + k3ρ⁶), whose area factor 1/det J the capture also\n * multiplied into the irradiance (det J = (1 + k1ρ_i² + k2ρ_i⁴ + k3ρ_i⁶)(1 + 3k1ρ_i² + 5k2ρ_i⁴ + 7k3ρ_i⁶) at the ideal point ρ_i that\n * the lens images to the sensor point). With it, the relative illumination corrected is E(ρ_s)/det J(ρ_i), evaluated at the\n * capture's sensor (source) point, so strength 1 flattens a flat field. It holds whether or not the distortion itself is corrected.\n * Without it the gain is 1/E alone, as before.\n */\n distortionAreaFactor?: RadialDistortionProfile;\n}\nexport type LensCorrectionComponent = GeometricLensCorrection | LateralCaLensCorrection | IlluminationLensCorrection;\n/** A correction profile for one exact lens-and-camera system. Components are listed in the order they are applied. */\nexport interface GenericLensCorrectionProfile {\n schemaVersion: \"0.1.0\";\n id: string;\n version: string;\n state: OpticalProfileState;\n evidence: GenericOpticalEvidence;\n components: readonly LensCorrectionComponent[];\n}\nexport interface ResolvedLensCorrectionPlan {\n profile: GenericLensCorrectionProfile;\n outputKind: \"raw-like\" | \"processed\";\n selectionKind: \"camera-selectable\" | \"reference-bypass\";\n components: readonly { component: LensCorrectionComponent; enabled: boolean;\n reason: \"selected\" | \"default\" | \"mandatory\" | \"stabilization-dependency\" | \"component-dependency\" | \"reference-bypass\" }[];\n /** For now, a RAW-like intent is recorded as metadata only. */\n application: \"metadata-only\" | \"bake-downstream\";\n}\nfunction illumination(value: unknown): IlluminationVignettingProfile {\n const r = record(value, [\"normalizationRadiusMm\", \"maximumNormalizedRadius\", \"coefficients\"]);\n const c = record(r.coefficients, [\"r2\", \"r4\", \"r6\"]);\n const profile = { normalizationRadiusMm: positive(r.normalizationRadiusMm, \"normalizationRadiusMm\"),\n maximumNormalizedRadius: positive(r.maximumNormalizedRadius, \"maximumNormalizedRadius\"),\n coefficients: { r2: finite(c.r2, \"r2\"), r4: finite(c.r4, \"r4\"), r6: finite(c.r6, \"r6\") } };\n calculateIlluminationVignetting({ imagePointMm: { x: 0, y: 0 }, profile });\n return profile;\n}\n/** Strictly parses a generic correction profile. It does not extrapolate and makes no claim to restore lost detail. */\nexport function parseGenericLensCorrectionProfile(value: unknown): GenericLensCorrectionProfile {\n const r = record(value, [\"schemaVersion\", \"id\", \"version\", \"state\", \"evidence\", \"components\"]);\n const components = list(r.components, 16).map((value): LensCorrectionComponent => {\n const c = record(value, [\"id\", \"version\", \"domain\", \"availability\", \"defaultEnabled\", \"dependencies\",\n \"requiredByStabilizationModes\", \"residualNote\", \"kind\", \"transform\", \"transforms\", \"profile\", \"strength\", \"distortionAreaFactor\"]);\n if (typeof c.defaultEnabled !== \"boolean\") throw new InvalidConfigurationError(\"defaultEnabled must be boolean.\");\n const identity = { id: textValue(c.id), version: textValue(c.version),\n domain: choice(c.domain, [\"raw-channel\", \"reconstructed-linear\", \"processed-output\"]),\n availability: choice(c.availability, [\"toggle\", \"automatic\", \"mandatory\"]), defaultEnabled: c.defaultEnabled,\n dependencies: list(c.dependencies, 16).map(textValue),\n requiredByStabilizationModes: list(c.requiredByStabilizationModes, 16).map(textValue), residualNote: textValue(c.residualNote) };\n const kind = choice(c.kind, [\"geometry\", \"lateral-ca\", \"peripheral-illumination\"]);\n if (kind === \"geometry\") {\n if (c.transforms !== undefined || c.profile !== undefined || c.strength !== undefined || c.distortionAreaFactor !== undefined) throw new InvalidScientificInputError(\"Extraneous geometry parameters.\");\n const transform = parseDigitalGeometricTransform(c.transform);\n if (transform.domain !== identity.domain || ![\"distortion\", \"breathing\"].includes(transform.purpose)) throw new InvalidScientificInputError(\"Geometry domain/purpose mismatch.\");\n return { ...identity, kind, transform };\n }\n if (kind === \"lateral-ca\") {\n if (c.transform !== undefined || c.profile !== undefined || c.strength !== undefined || c.distortionAreaFactor !== undefined) throw new InvalidScientificInputError(\"Extraneous CA parameters.\");\n const t = record(c.transforms, [\"red\", \"green\", \"blue\"]);\n const transforms = { red: parseDigitalGeometricTransform(t.red), green: parseDigitalGeometricTransform(t.green), blue: parseDigitalGeometricTransform(t.blue) };\n for (const transform of Object.values(transforms)) {\n if (transform.domain !== identity.domain || transform.purpose !== \"lateral-ca\") throw new InvalidScientificInputError(\"CA domain/purpose mismatch.\");\n }\n return { ...identity, kind, transforms };\n }\n if (c.transform !== undefined || c.transforms !== undefined) throw new InvalidScientificInputError(\"Extraneous illumination geometry.\");\n const strength = finite(c.strength, \"strength\");\n if (strength < 0 || strength > 1) throw new InvalidScientificInputError(\"Strength must lie in [0,1].\");\n if (c.distortionAreaFactor === undefined) return { ...identity, kind, profile: illumination(c.profile), strength };\n const d = record(c.distortionAreaFactor, [\"normalizationRadiusMm\", \"maximumNormalizedRadius\", \"coefficients\"]), k = record(d.coefficients, [\"k1\", \"k2\", \"k3\"]);\n const distortionAreaFactor = { normalizationRadiusMm: positive(d.normalizationRadiusMm, \"normalizationRadiusMm\"), maximumNormalizedRadius: positive(d.maximumNormalizedRadius, \"maximumNormalizedRadius\"),\n coefficients: { k1: finite(k.k1, \"k1\"), k2: finite(k.k2, \"k2\"), k3: finite(k.k3, \"k3\") } };\n validateRadialDistortionProfile(distortionAreaFactor);\n return { ...identity, kind, profile: illumination(c.profile), strength, distortionAreaFactor };\n });\n const preceding = new Set<string>(), mappingIds = new Set<string>();\n for (const c of components) {\n if (preceding.has(c.id) || c.dependencies.some((id) => !preceding.has(id)) ||\n new Set(c.dependencies).size !== c.dependencies.length) throw new InvalidScientificInputError(\"Component IDs/dependency order must be unique and acyclic.\");\n preceding.add(c.id);\n // Common and per-channel transforms need stable, distinct IDs when they are combined.\n const maps = c.kind === \"geometry\" ? [c.transform] : c.kind === \"lateral-ca\" ? Object.values(c.transforms) : [];\n for (const t of maps) {\n if (mappingIds.has(t.id)) throw new InvalidScientificInputError(\"Duplicate correction transform ID.\");\n mappingIds.add(t.id);\n }\n }\n return { schemaVersion: choice(r.schemaVersion, [\"0.1.0\"]), id: textValue(r.id), version: textValue(r.version),\n state: parseOpticalProfileState(r.state), evidence: parseEvidence(r.evidence), components };\n}\n\n/**\n * Decides which corrections apply for a camera state. It accounts for per-component settings,\n * explicit dependencies between components, RAW intent and the educational \"corrections off\" bypass.\n */\nexport function resolveLensCorrectionPlan(input: {\n profile: GenericLensCorrectionProfile; state: OpticalProfileState;\n selections: Readonly<Record<string, \"on\" | \"off\" | \"auto\">>;\n outputKind: \"raw-like\" | \"processed\"; selectionKind: \"camera-selectable\" | \"reference-bypass\";\n}): CalculationResult<ResolvedLensCorrectionPlan> {\n requireInputKeys(input, \"resolveLensCorrectionPlan\", [\"profile\", \"state\", \"selections\", \"outputKind\", \"selectionKind\"]);\n const profile = parseGenericLensCorrectionProfile(input.profile);\n requireSameState(profile.state, input.state);\n const outputKind = choice(input.outputKind, [\"raw-like\", \"processed\"]);\n const selectionKind = choice(input.selectionKind, [\"camera-selectable\", \"reference-bypass\"]);\n const selections = record(input.selections, profile.components.map((c) => c.id));\n const components: ResolvedLensCorrectionPlan[\"components\"][number][] = profile.components.map((c): ResolvedLensCorrectionPlan[\"components\"][number] => {\n const selection = choice(selections[c.id] ?? \"auto\", [\"on\", \"off\", \"auto\"]);\n if (selectionKind === \"reference-bypass\") return { component: c, enabled: false, reason: \"reference-bypass\" };\n const stabilization = c.requiredByStabilizationModes.includes(profile.state.stabilizationMode);\n if (c.availability === \"mandatory\" && selection === \"off\") throw new InvalidScientificInputError(\"Mandatory correction cannot be disabled as a camera setting; use reference-bypass.\");\n if (c.availability === \"automatic\" && selection !== \"auto\") throw new InvalidScientificInputError(\"Automatic correction has no camera toggle.\");\n return { component: c, enabled: c.availability === \"mandatory\" || stabilization || (selection === \"auto\" ? c.defaultEnabled : selection === \"on\"),\n reason: c.availability === \"mandatory\" ? \"mandatory\" : stabilization ? \"stabilization-dependency\" : selection === \"auto\" ? \"default\" : \"selected\" };\n });\n for (const entry of [...components].reverse()) if (entry.enabled) for (const id of entry.component.dependencies) {\n const dependency = components.find((c) => c.component.id === id)!;\n dependency.enabled = true; dependency.reason = \"component-dependency\";\n }\n return approximationResult({ profile, outputKind, selectionKind, components,\n application: outputKind === \"raw-like\" ? \"metadata-only\" : \"bake-downstream\" },\n \"generic-camera-lens-correction-plan\", \"0.1.0\", [profile.evidence.basis, profile.evidence.residualNote,\n \"Corrections occur after the same physical capture; tier is not a correction-strength input\",\n \"Raw-like output preserves intent without baking corrections; color shading, axial CA and restoration remain unsupported\"]);\n}\n\n/**\n * Applies a gain after capture and reports the variance before clipping. It does not rewrite\n * the photon or SNR (signal-to-noise ratio) history of the capture. The gain is T^(−strength), T the relative illumination at\n * `imagePointMm`: E(ρ) of the component's profile, divided by det J(ρ_i) when the component has a `distortionAreaFactor` (#584;\n * then `imagePointMm` is the capture's sensor point, where the capture applied both).\n */\nexport function calculatePeripheralIlluminationCorrection(input: {\n component: IlluminationLensCorrection; imagePointMm: LensFieldPointMm;\n signal: number; noiseVariance: number; clippingLevel: number;\n}): CalculationResult<{ gain: number; signalBeforeClipping: number; signal: number; noiseVarianceBeforeClipping: number; clipped: boolean }> {\n requireInputKeys(input, \"calculatePeripheralIlluminationCorrection\", [\"component\", \"imagePointMm\", \"signal\", \"noiseVariance\", \"clippingLevel\"]);\n const component = input.component;\n requireInputObject(component, \"component input\");\n if (component.kind !== \"peripheral-illumination\" || component.strength < 0 || component.strength > 1 || !Number.isFinite(component.strength)) throw new InvalidScientificInputError(\"Invalid illumination component.\");\n const signal = finite(input.signal, \"signal\"), variance = finite(input.noiseVariance, \"noiseVariance\");\n const level = positive(input.clippingLevel, \"clippingLevel\");\n if (variance < 0) throw new InvalidScientificInputError(\"Variance must be nonnegative.\");\n let throughput = calculateIlluminationVignetting({ imagePointMm: input.imagePointMm, profile: component.profile }).value.linearThroughputFactor;\n if (component.distortionAreaFactor !== undefined) {\n const { k1, k2, k3 } = component.distortionAreaFactor.coefficients;\n const p2 = calculateInverseRadialSourcePointValue(input.imagePointMm, validateRadialDistortionProfile(component.distortionAreaFactor), \"imagePointMm\").sourceNormalizedRadius ** 2;\n throughput /= (1 + p2 * (k1 + p2 * (k2 + p2 * k3))) * (1 + p2 * (3 * k1 + p2 * (5 * k2 + p2 * 7 * k3)));\n }\n const gain = throughput**(-component.strength), before = signal*gain;\n return approximationResult({ gain, signalBeforeClipping: before, signal: Math.min(level, before),\n noiseVarianceBeforeClipping: variance*gain*gain, clipped: before > level },\n \"post-capture-peripheral-illumination-gain\", \"0.1.0\", [\"Variance describes pre-clip samples only\", \"Gain does not increase captured photons or restore sensor SNR\"]);\n}\n\n/** The fixed capture identity travels with the output channels, so On/Off comparisons use the same capture. */\nexport interface LensCorrectionCapture {\n state: OpticalProfileState;\n captureId: string;\n noiseRealizationId: string;\n timeSeconds: number;\n raster: GeometricRaster;\n channels: Readonly<Record<LensCorrectionChannel, readonly number[]>>;\n}\n/** Applies bounded corrections to RGB channels that are already sampled and linear.\n * Compatible shared geometry and per-channel CA are combined, so each channel is resampled once.\n * A gain between geometry components, or incompatible domains, needs a separate staged caller.\n */\nexport function calculateLensCorrectedCapture(input: {\n plan: ResolvedLensCorrectionPlan; capture: LensCorrectionCapture;\n destinationRaster: GeometricRaster; resampler: GeometricResampler;\n physicalProjectionDistanceMm: number; clippingLevel: number;\n}): CalculationResult<{\n captureId: string; noiseRealizationId: string; timeSeconds: number;\n application: ResolvedLensCorrectionPlan[\"application\"];\n channels: Readonly<Record<LensCorrectionChannel, readonly (number | null)[]>>;\n samplingPlans: Partial<Record<LensCorrectionChannel, GeometricSamplingPlan>>;\n /** Area valid in every channel, before cropping. Missing colours are never made up. */\n validSourceMask: readonly boolean[];\n jointCrop: GeometricSamplingPlan[\"jointCrop\"];\n /** Clipping events in gain stages, before the shared valid-area crop. Each stage is counted separately. */\n illuminationClippingEventCount: number;\n}> {\n requireInputKeys(input, \"calculateLensCorrectedCapture\", [\"plan\", \"capture\", \"destinationRaster\", \"resampler\", \"physicalProjectionDistanceMm\", \"clippingLevel\"]);\n // Re-resolve the plan, which may be untrusted or changed, so callers cannot fake enabled or mandatory states.\n requireInputObject(input.plan, \"plan\");\n const plan = resolveLensCorrectionPlan({ profile: input.plan.profile, state: input.plan.profile.state,\n selections: Object.fromEntries(input.plan.components.filter((e) => e.component.availability === \"toggle\").map((e) => [e.component.id, e.enabled ? \"on\" : \"off\"])),\n outputKind: input.plan.outputKind, selectionKind: input.plan.selectionKind }).value;\n const capture = input.capture;\n requireSameState(plan.profile.state, capture.state);\n const sourceRaster = parseGeometricRaster(capture.raster);\n const destination = parseGeometricRaster(input.destinationRaster);\n if (destination.width !== plan.profile.state.outputWidth || destination.height !== plan.profile.state.outputHeight) {\n throw new InvalidScientificInputError(\"Destination raster differs from correction output binding.\");\n }\n textValue(capture.captureId); textValue(capture.noiseRealizationId);\n if (finite(capture.timeSeconds, \"timeSeconds\") < 0) throw new InvalidScientificInputError(\"Invalid capture time.\");\n const count = capture.raster.width*capture.raster.height;\n for (const channel of [\"red\", \"green\", \"blue\"] as const) {\n const data = list(capture.channels[channel], 65536);\n if (data.length !== count) throw new InvalidScientificInputError(\"Capture channel sample count mismatch.\");\n data.forEach((s) => finite(s, \"channel sample\"));\n }\n const active = plan.components.filter((e) => e.enabled).map((e) => e.component);\n const sameLattice = sourceRaster.width === destination.width && sourceRaster.height === destination.height &&\n sourceRaster.pitchMm === destination.pitchMm && sourceRaster.centerMm.x === destination.centerMm.x &&\n sourceRaster.centerMm.y === destination.centerMm.y;\n // Disabling corrections does not disable an explicit output crop/resampling request.\n if (plan.application === \"metadata-only\" || (!active.length && sameLattice)) {\n return approximationResult({ captureId: capture.captureId, noiseRealizationId: capture.noiseRealizationId,\n timeSeconds: capture.timeSeconds, application: plan.application, channels: capture.channels,\n samplingPlans: {}, validSourceMask: Array<boolean>(count).fill(true), illuminationClippingEventCount: 0,\n jointCrop: { x: 0, y: 0, width: capture.raster.width, height: capture.raster.height } },\n \"generic-lens-correction-capture\", \"0.1.0\", [\"Original physical capture preserved\"]);\n }\n if (active.some((c) => c.domain !== \"reconstructed-linear\")) throw new InvalidScientificInputError(\"This executor requires reconstructed-linear components; other domains need separate consumers.\");\n let seenGain = false;\n for (const c of active) {\n if (c.kind === \"peripheral-illumination\") seenGain = true;\n else if (seenGain) throw new InvalidScientificInputError(\"Cannot reorder geometry across a gain stage.\");\n }\n const channels = {} as Record<LensCorrectionChannel, readonly (number | null)[]>;\n const samplingPlans: Partial<Record<LensCorrectionChannel, GeometricSamplingPlan>> = {};\n let illuminationClippingEventCount = 0;\n for (const channel of [\"red\", \"green\", \"blue\"] as const) {\n // Corrections are listed source → destination. Inverse sampling runs them in reverse.\n const transforms = active.filter((c) => c.kind !== \"peripheral-illumination\").reverse().map((c) =>\n c.kind === \"geometry\" ? c.transform : (c as LateralCaLensCorrection).transforms[channel]);\n const mapping = prepareGeometricMapping({ transforms, frameTimeSeconds: capture.timeSeconds }).value;\n const sampling = calculateGeometricSamplingPlan({ mapping, sourceRaster: capture.raster,\n destinationRaster: input.destinationRaster, resampler: input.resampler,\n physicalProjectionDistanceMm: input.physicalProjectionDistanceMm }).value;\n samplingPlans[channel] = sampling;\n let data = calculateGeometricResampling({ plan: sampling, sourceSamples: capture.channels[channel] }).value.samples;\n for (const c of active) if (c.kind === \"peripheral-illumination\") {\n data = data.map((signal, index): number | null => {\n if (signal === null) return null;\n const raster = input.destinationRaster, x = index%raster.width, y = Math.floor(index/raster.width);\n // #584: a gain that carries the distortion's area factor is the capture's own, so it is read at the source point.\n const corrected = calculatePeripheralIlluminationCorrection({ component: c,\n imagePointMm: c.distortionAreaFactor ? sampling.points[index]!.sourcePointMm : { x: raster.centerMm.x+(x+.5-raster.width/2)*raster.pitchMm,\n y: raster.centerMm.y-(y+.5-raster.height/2)*raster.pitchMm },\n signal, noiseVariance: 0, clippingLevel: input.clippingLevel }).value;\n if (corrected.clipped) illuminationClippingEventCount++;\n return corrected.signal;\n });\n }\n channels[channel] = data;\n }\n const mask = channels.red.map((_, i) => channels.red[i] !== null && channels.green[i] !== null && channels.blue[i] !== null);\n for (const channel of [\"red\", \"green\", \"blue\"] as const) channels[channel] = channels[channel].map((s, i) => mask[i] ? s : null);\n return approximationResult({ captureId: capture.captureId, noiseRealizationId: capture.noiseRealizationId,\n timeSeconds: capture.timeSeconds, application: plan.application, channels, samplingPlans, validSourceMask: mask,\n illuminationClippingEventCount,\n jointCrop: calculateValidSourceCrop(mask, destination.width, destination.height) },\n \"generic-lens-correction-capture\", \"0.1.0\", [\"Input capture/noise realization remains unchanged\", \"Channel support intersects before output; optical blur/noise is warped, not physically repaired\",\n \"No production-plan composition is enabled by this standalone executor\"]);\n}\n"]}
|
|
@@ -118,11 +118,11 @@ export interface SdrPixelCounts {
|
|
|
118
118
|
* For `pixelCount` interleaved linear-sRGB pixels starting at `source[start]`, it runs exactly the
|
|
119
119
|
* reference (`calculateSdrRendering`) operations in the same order per pixel: -0 → +0 → rendering
|
|
120
120
|
* exposure → shared tone operator → gamut → sRGB transfer → quantization (nearest, ties up) into
|
|
121
|
-
* `codes[outOffset]
|
|
121
|
+
* `codes[outOffset]` (with `maximum` 0, the encoded value unquantized). A gamut rejection is delayed via `counts.outOfGamut`, because the reference
|
|
122
122
|
* finishes the whole tone pass (and its exposure errors) first. `scratch` must hold at least 3
|
|
123
123
|
* values. Not exported from the package.
|
|
124
124
|
*/
|
|
125
|
-
export declare function renderSdrRunInto(source: Float32Array | Float64Array, start: number, pixelCount: number, profile: SdrRenderingProfile, tone: SdrPixelTone, scale: number, maximum: number, codes: Uint8Array | Uint16Array, outOffset: number, scratch: Float64Array, counts: SdrPixelCounts): void;
|
|
125
|
+
export declare function renderSdrRunInto(source: Float32Array | Float64Array, start: number, pixelCount: number, profile: SdrRenderingProfile, tone: SdrPixelTone, scale: number, maximum: number, codes: Uint8Array | Uint16Array | Float64Array, outOffset: number, scratch: Float64Array, counts: SdrPixelCounts): void;
|
|
126
126
|
/** The reference's output-encoding declaration for the given code maximum. */
|
|
127
127
|
export declare function sdrOutputEncoding(maximum: number): SdrRenderingResult["outputEncoding"];
|
|
128
128
|
/** A single-use task. No partial output is ever returned, and cancel or dispose stops a late result from being published. */
|
|
@@ -182,7 +182,7 @@ export function nativeSrgb8QuantizerForTest() {
|
|
|
182
182
|
* For `pixelCount` interleaved linear-sRGB pixels starting at `source[start]`, it runs exactly the
|
|
183
183
|
* reference (`calculateSdrRendering`) operations in the same order per pixel: -0 → +0 → rendering
|
|
184
184
|
* exposure → shared tone operator → gamut → sRGB transfer → quantization (nearest, ties up) into
|
|
185
|
-
* `codes[outOffset]
|
|
185
|
+
* `codes[outOffset]` (with `maximum` 0, the encoded value unquantized). A gamut rejection is delayed via `counts.outOfGamut`, because the reference
|
|
186
186
|
* finishes the whole tone pass (and its exposure errors) first. `scratch` must hold at least 3
|
|
187
187
|
* values. Not exported from the package.
|
|
188
188
|
*/
|
|
@@ -221,7 +221,8 @@ export function renderSdrRunInto(source, start, pixelCount, profile, tone, scale
|
|
|
221
221
|
}
|
|
222
222
|
}
|
|
223
223
|
// Encoded values are in [0,1]: Math.round is exact nearest-ties-up here.
|
|
224
|
-
|
|
224
|
+
// maximum 0 (#571): the encoded value itself, unquantized, into a Float64Array (the unsharp mask's input).
|
|
225
|
+
codes[o] = quantizer ? quantizeSrgb8(quantizer, linear) : maximum === 0 ? encodeSrgbComponent(linear) : Math.round(encodeSrgbComponent(linear) * maximum);
|
|
225
226
|
}
|
|
226
227
|
}
|
|
227
228
|
counts.negative += negative;
|