@photivra/engine 1.4.0 → 2.0.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 +401 -6
- package/CITATION.cff +1 -1
- package/NODE_SUPPORT.md +64 -12
- package/README.md +301 -182
- package/SECURITY.md +37 -28
- package/THIRD_PARTY.md +148 -4
- package/dist/camera/equivalent-focal-length.d.ts +13 -14
- package/dist/camera/equivalent-focal-length.js +15 -13
- package/dist/camera/equivalent-focal-length.js.map +1 -1
- package/dist/camera/field-of-view.d.ts +30 -19
- package/dist/camera/field-of-view.js +67 -18
- package/dist/camera/field-of-view.js.map +1 -1
- package/dist/camera/lens-projection.d.ts +170 -0
- package/dist/camera/lens-projection.js +444 -0
- package/dist/camera/lens-projection.js.map +1 -0
- package/dist/camera/projected-object-size.d.ts +10 -11
- package/dist/camera/projected-object-size.js +12 -10
- package/dist/camera/projected-object-size.js.map +1 -1
- package/dist/capture/capture-export-metadata.d.ts +9 -10
- package/dist/capture/capture-export-metadata.js +8 -5
- package/dist/capture/capture-export-metadata.js.map +1 -1
- package/dist/capture/dng-import.d.ts +91 -0
- package/dist/capture/dng-import.js +343 -0
- package/dist/capture/dng-import.js.map +1 -0
- package/dist/capture/environment-raw-producer.d.ts +37 -17
- package/dist/capture/environment-raw-producer.js +43 -19
- package/dist/capture/environment-raw-producer.js.map +1 -1
- package/dist/capture/export-jpeg.d.ts +35 -4
- package/dist/capture/export-jpeg.js +133 -47
- package/dist/capture/export-jpeg.js.map +1 -1
- package/dist/capture/export-tiff.d.ts +48 -24
- package/dist/capture/export-tiff.js +91 -31
- package/dist/capture/export-tiff.js.map +1 -1
- package/dist/capture/focus-control.d.ts +42 -65
- package/dist/capture/focus-control.js +56 -75
- package/dist/capture/focus-control.js.map +1 -1
- package/dist/capture/host-yield-cadence.d.ts +25 -0
- package/dist/capture/host-yield-cadence.js +25 -0
- package/dist/capture/host-yield-cadence.js.map +1 -0
- package/dist/capture/linear-encoding.d.ts +14 -12
- package/dist/capture/linear-encoding.js +14 -13
- package/dist/capture/linear-encoding.js.map +1 -1
- package/dist/capture/lossless-jpeg.d.ts +27 -0
- package/dist/capture/lossless-jpeg.js +237 -0
- package/dist/capture/lossless-jpeg.js.map +1 -0
- package/dist/capture/native-environment-lean.d.ts +227 -0
- package/dist/capture/native-environment-lean.js +974 -0
- package/dist/capture/native-environment-lean.js.map +1 -0
- package/dist/capture/native-environment-optical-stage.d.ts +97 -0
- package/dist/capture/native-environment-optical-stage.js +340 -0
- package/dist/capture/native-environment-optical-stage.js.map +1 -0
- package/dist/capture/native-environment-raw.d.ts +140 -6
- package/dist/capture/native-environment-raw.js +435 -34
- package/dist/capture/native-environment-raw.js.map +1 -1
- package/dist/capture/native-raw-development.d.ts +118 -5
- package/dist/capture/native-raw-development.js +224 -59
- package/dist/capture/native-raw-development.js.map +1 -1
- package/dist/capture/native-raw-dng.d.ts +60 -0
- package/dist/capture/native-raw-dng.js +167 -0
- package/dist/capture/native-raw-dng.js.map +1 -0
- package/dist/capture/native-raw.d.ts +67 -10
- package/dist/capture/native-raw.js +90 -24
- package/dist/capture/native-raw.js.map +1 -1
- package/dist/capture/packed-sensor-raw.d.ts +160 -0
- package/dist/capture/packed-sensor-raw.js +221 -0
- package/dist/capture/packed-sensor-raw.js.map +1 -0
- package/dist/capture/photographic-export.d.ts +58 -35
- package/dist/capture/photographic-export.js +177 -70
- package/dist/capture/photographic-export.js.map +1 -1
- package/dist/capture/raw-development-kernel.d.ts +52 -0
- package/dist/capture/raw-development-kernel.js +88 -0
- package/dist/capture/raw-development-kernel.js.map +1 -0
- package/dist/capture/raw-frame-limits.d.ts +7 -7
- package/dist/capture/raw-frame-limits.js +7 -6
- package/dist/capture/raw-frame-limits.js.map +1 -1
- package/dist/capture/raw-frame-reconstruction.d.ts +8 -9
- package/dist/capture/raw-frame-reconstruction.js +9 -8
- package/dist/capture/raw-frame-reconstruction.js.map +1 -1
- package/dist/capture/raw-white-level.d.ts +55 -0
- package/dist/capture/raw-white-level.js +165 -0
- package/dist/capture/raw-white-level.js.map +1 -0
- package/dist/capture/release-sequence.d.ts +5 -7
- package/dist/capture/release-sequence.js +15 -13
- package/dist/capture/release-sequence.js.map +1 -1
- package/dist/capture/sensor-raw-frame.d.ts +5 -6
- package/dist/capture/sensor-raw-frame.js +26 -9
- package/dist/capture/sensor-raw-frame.js.map +1 -1
- package/dist/capture/sensor-raw-producer.d.ts +21 -13
- package/dist/capture/sensor-raw-producer.js +86 -25
- package/dist/capture/sensor-raw-producer.js.map +1 -1
- package/dist/capture/simulated-capture.d.ts +15 -16
- package/dist/capture/simulated-capture.js +22 -12
- package/dist/capture/simulated-capture.js.map +1 -1
- package/dist/color/camera-color-matrix.d.ts +69 -0
- package/dist/color/camera-color-matrix.js +132 -0
- package/dist/color/camera-color-matrix.js.map +1 -0
- package/dist/color/capture-color.d.ts +17 -10
- package/dist/color/capture-color.js +50 -17
- package/dist/color/capture-color.js.map +1 -1
- package/dist/color/chromatic-adaptation.d.ts +63 -0
- package/dist/color/chromatic-adaptation.js +91 -0
- package/dist/color/chromatic-adaptation.js.map +1 -0
- package/dist/color/color-difference.d.ts +104 -0
- package/dist/color/color-difference.js +205 -0
- package/dist/color/color-difference.js.map +1 -0
- package/dist/color/color-matching-functions.d.ts +168 -0
- package/dist/color/color-matching-functions.js +309 -0
- package/dist/color/color-matching-functions.js.map +1 -0
- package/dist/color/colorimetry-math.d.ts +52 -0
- package/dist/color/colorimetry-math.js +144 -0
- package/dist/color/colorimetry-math.js.map +1 -0
- package/dist/color/gamut-mapping.d.ts +54 -0
- package/dist/color/gamut-mapping.js +107 -0
- package/dist/color/gamut-mapping.js.map +1 -0
- package/dist/color/illuminants.d.ts +182 -0
- package/dist/color/illuminants.js +434 -0
- package/dist/color/illuminants.js.map +1 -0
- package/dist/color/rgb-color-spaces.d.ts +79 -0
- package/dist/color/rgb-color-spaces.js +115 -0
- package/dist/color/rgb-color-spaces.js.map +1 -0
- package/dist/color/sensor-color-development.d.ts +33 -11
- package/dist/color/sensor-color-development.js +104 -30
- package/dist/color/sensor-color-development.js.map +1 -1
- package/dist/color/srgb-icc.d.ts +9 -2
- package/dist/color/srgb-icc.js +16 -5
- package/dist/color/srgb-icc.js.map +1 -1
- package/dist/color/srgb-transfer.d.ts +1 -2
- package/dist/color/srgb-transfer.js +1 -1
- package/dist/color/srgb-transfer.js.map +1 -1
- package/dist/color/white-balance.d.ts +68 -19
- package/dist/color/white-balance.js +168 -35
- package/dist/color/white-balance.js.map +1 -1
- package/dist/composition/image-formation-plan.d.ts +152 -128
- package/dist/composition/image-formation-plan.js +292 -138
- package/dist/composition/image-formation-plan.js.map +1 -1
- package/dist/composition/plan-consumer.d.ts +6 -7
- package/dist/composition/plan-consumer.js +14 -11
- package/dist/composition/plan-consumer.js.map +1 -1
- package/dist/core/calculation-result.d.ts +21 -14
- package/dist/core/calculation-result.js +209 -11
- package/dist/core/calculation-result.js.map +1 -1
- package/dist/core/canonical-json.d.ts +13 -8
- package/dist/core/canonical-json.js +34 -15
- package/dist/core/canonical-json.js.map +1 -1
- package/dist/core/configuration-error.d.ts +5 -4
- package/dist/core/configuration-error.js +5 -3
- package/dist/core/configuration-error.js.map +1 -1
- package/dist/core/evidence-provenance.d.ts +12 -12
- package/dist/core/evidence-provenance.js +10 -9
- package/dist/core/evidence-provenance.js.map +1 -1
- package/dist/core/image-formation.d.ts +11 -10
- package/dist/core/image-formation.js +11 -9
- package/dist/core/image-formation.js.map +1 -1
- package/dist/core/owned-data.d.ts +9 -17
- package/dist/core/owned-data.js +9 -16
- package/dist/core/owned-data.js.map +1 -1
- package/dist/core/portable-math.d.ts +15 -0
- package/dist/core/portable-math.js +56 -0
- package/dist/core/portable-math.js.map +1 -0
- package/dist/core/record-validation.d.ts +48 -9
- package/dist/core/record-validation.js +93 -19
- package/dist/core/record-validation.js.map +1 -1
- package/dist/core/scientific-assurance.d.ts +16 -14
- package/dist/core/scientific-assurance.js +22 -18
- package/dist/core/scientific-assurance.js.map +1 -1
- package/dist/core/spectral-composition.d.ts +13 -14
- package/dist/core/spectral-composition.js +30 -27
- package/dist/core/spectral-composition.js.map +1 -1
- package/dist/core/spectral.d.ts +5 -6
- package/dist/core/spectral.js +9 -7
- package/dist/core/spectral.js.map +1 -1
- package/dist/core/validation.d.ts +3 -6
- package/dist/core/validation.js +3 -5
- package/dist/core/validation.js.map +1 -1
- package/dist/core/version.d.ts +6 -6
- package/dist/core/version.js +6 -5
- package/dist/core/version.js.map +1 -1
- package/dist/equipment/exposure-capabilities.d.ts +10 -10
- package/dist/equipment/exposure-capabilities.js +40 -30
- package/dist/equipment/exposure-capabilities.js.map +1 -1
- package/dist/equipment/generic-tier-assets.d.ts +13 -6
- package/dist/equipment/generic-tier-assets.js +34 -15
- package/dist/equipment/generic-tier-assets.js.map +1 -1
- package/dist/equipment/generic-tier-presets.d.ts +5 -6
- package/dist/equipment/generic-tier-presets.js +15 -13
- package/dist/equipment/generic-tier-presets.js.map +1 -1
- package/dist/equipment/iso-capabilities.d.ts +21 -22
- package/dist/equipment/iso-capabilities.js +49 -44
- package/dist/equipment/iso-capabilities.js.map +1 -1
- package/dist/equipment/metering-capabilities.d.ts +5 -6
- package/dist/equipment/metering-capabilities.js +22 -19
- package/dist/equipment/metering-capabilities.js.map +1 -1
- package/dist/equipment/release-capabilities.d.ts +3 -4
- package/dist/equipment/release-capabilities.js +18 -14
- package/dist/equipment/release-capabilities.js.map +1 -1
- package/dist/exposure/exposure-duration-control.d.ts +19 -17
- package/dist/exposure/exposure-duration-control.js +27 -23
- package/dist/exposure/exposure-duration-control.js.map +1 -1
- package/dist/exposure/exposure-mode-resolver.d.ts +42 -39
- package/dist/exposure/exposure-mode-resolver.js +127 -82
- package/dist/exposure/exposure-mode-resolver.js.map +1 -1
- package/dist/exposure/exposure.d.ts +17 -16
- package/dist/exposure/exposure.js +22 -15
- package/dist/exposure/exposure.js.map +1 -1
- package/dist/exposure/flash-ttl.d.ts +135 -0
- package/dist/exposure/flash-ttl.js +193 -0
- package/dist/exposure/flash-ttl.js.map +1 -0
- package/dist/exposure/flash.d.ts +144 -36
- package/dist/exposure/flash.js +259 -59
- package/dist/exposure/flash.js.map +1 -1
- package/dist/exposure/metering-scene-radiance.d.ts +10 -10
- package/dist/exposure/metering-scene-radiance.js +42 -23
- package/dist/exposure/metering-scene-radiance.js.map +1 -1
- package/dist/exposure/metering-target.d.ts +8 -8
- package/dist/exposure/metering-target.js +30 -20
- package/dist/exposure/metering-target.js.map +1 -1
- package/dist/exposure/metering-temporal.d.ts +16 -15
- package/dist/exposure/metering-temporal.js +41 -19
- package/dist/exposure/metering-temporal.js.map +1 -1
- package/dist/exposure/metering.d.ts +64 -17
- package/dist/exposure/metering.js +159 -30
- package/dist/exposure/metering.js.map +1 -1
- package/dist/exposure/program-line.d.ts +5 -5
- package/dist/exposure/program-line.js +20 -13
- package/dist/exposure/program-line.js.map +1 -1
- package/dist/facade/camera-preset.d.ts +8 -0
- package/dist/facade/camera-preset.js +102 -0
- package/dist/facade/camera-preset.js.map +1 -0
- package/dist/facade/chart-radiance-batch.d.ts +57 -0
- package/dist/facade/chart-radiance-batch.js +121 -0
- package/dist/facade/chart-radiance-batch.js.map +1 -0
- package/dist/facade/chart-scenes.d.ts +177 -0
- package/dist/facade/chart-scenes.js +232 -0
- package/dist/facade/chart-scenes.js.map +1 -0
- package/dist/facade/host-yield.d.ts +7 -0
- package/dist/facade/host-yield.js +23 -0
- package/dist/facade/host-yield.js.map +1 -0
- package/dist/facade/scene-radiance.d.ts +117 -0
- package/dist/facade/scene-radiance.js +205 -0
- package/dist/facade/scene-radiance.js.map +1 -0
- package/dist/facade/simulate-capture.d.ts +284 -0
- package/dist/facade/simulate-capture.js +1026 -0
- package/dist/facade/simulate-capture.js.map +1 -0
- package/dist/gpu/chart-radiance-gpu.d.ts +17 -0
- package/dist/gpu/chart-radiance-gpu.js +176 -0
- package/dist/gpu/chart-radiance-gpu.js.map +1 -0
- package/dist/gpu/image-kernel-accelerator.d.ts +132 -0
- package/dist/gpu/image-kernel-accelerator.js +720 -0
- package/dist/gpu/image-kernel-accelerator.js.map +1 -0
- package/dist/gpu/image-kernel-execution.d.ts +92 -0
- package/dist/gpu/image-kernel-execution.js +84 -0
- package/dist/gpu/image-kernel-execution.js.map +1 -0
- package/dist/gpu/sensor-stage-gpu.d.ts +44 -0
- package/dist/gpu/sensor-stage-gpu.js +317 -0
- package/dist/gpu/sensor-stage-gpu.js.map +1 -0
- package/dist/gpu/temporal-sum-gpu.d.ts +23 -0
- package/dist/gpu/temporal-sum-gpu.js +150 -0
- package/dist/gpu/temporal-sum-gpu.js.map +1 -0
- package/dist/gpu/webgpu-runtime.d.ts +63 -0
- package/dist/gpu/webgpu-runtime.js +215 -0
- package/dist/gpu/webgpu-runtime.js.map +1 -0
- package/dist/gpu/wgsl-chart-kernel.d.ts +30 -0
- package/dist/gpu/wgsl-chart-kernel.js +165 -0
- package/dist/gpu/wgsl-chart-kernel.js.map +1 -0
- package/dist/gpu/wgsl-kernels.d.ts +53 -0
- package/dist/gpu/wgsl-kernels.js +365 -0
- package/dist/gpu/wgsl-kernels.js.map +1 -0
- package/dist/gpu/wgsl-sensor-kernel.d.ts +64 -0
- package/dist/gpu/wgsl-sensor-kernel.js +409 -0
- package/dist/gpu/wgsl-sensor-kernel.js.map +1 -0
- package/dist/index.d.ts +89 -25
- package/dist/index.js +59 -15
- package/dist/index.js.map +1 -1
- package/dist/motion/camera-rotation.d.ts +92 -40
- package/dist/motion/camera-rotation.js +84 -47
- package/dist/motion/camera-rotation.js.map +1 -1
- package/dist/motion/capture-rotation-inverse-mapping.d.ts +37 -34
- package/dist/motion/capture-rotation-inverse-mapping.js +32 -24
- package/dist/motion/capture-rotation-inverse-mapping.js.map +1 -1
- package/dist/motion/capture-rotation-temporal-quadrature.d.ts +39 -35
- package/dist/motion/capture-rotation-temporal-quadrature.js +37 -28
- package/dist/motion/capture-rotation-temporal-quadrature.js.map +1 -1
- package/dist/motion/capture-rotation-trajectory.d.ts +32 -28
- package/dist/motion/capture-rotation-trajectory.js +36 -26
- package/dist/motion/capture-rotation-trajectory.js.map +1 -1
- package/dist/motion/capture-translation-parallax-temporal-quadrature.d.ts +23 -21
- package/dist/motion/capture-translation-parallax-temporal-quadrature.js +33 -14
- package/dist/motion/capture-translation-parallax-temporal-quadrature.js.map +1 -1
- package/dist/motion/extended-object-projection.d.ts +19 -16
- package/dist/motion/extended-object-projection.js +38 -18
- package/dist/motion/extended-object-projection.js.map +1 -1
- package/dist/motion/projected-motion.d.ts +18 -17
- package/dist/motion/projected-motion.js +25 -17
- package/dist/motion/projected-motion.js.map +1 -1
- package/dist/motion/temporal-exposure-sum.d.ts +55 -0
- package/dist/motion/temporal-exposure-sum.js +141 -0
- package/dist/motion/temporal-exposure-sum.js.map +1 -0
- package/dist/motion/video-sequence.d.ts +111 -0
- package/dist/motion/video-sequence.js +179 -0
- package/dist/motion/video-sequence.js.map +1 -0
- package/dist/optics/aperture.d.ts +14 -15
- package/dist/optics/aperture.js +13 -11
- package/dist/optics/aperture.js.map +1 -1
- package/dist/optics/atmospheric-haze.d.ts +83 -0
- package/dist/optics/atmospheric-haze.js +113 -0
- package/dist/optics/atmospheric-haze.js.map +1 -0
- package/dist/optics/brown-conrady-distortion.d.ts +116 -0
- package/dist/optics/brown-conrady-distortion.js +291 -0
- package/dist/optics/brown-conrady-distortion.js.map +1 -0
- package/dist/optics/circle-of-confusion.d.ts +10 -10
- package/dist/optics/circle-of-confusion.js +15 -11
- package/dist/optics/circle-of-confusion.js.map +1 -1
- package/dist/optics/complex-pupil-psf.d.ts +64 -33
- package/dist/optics/complex-pupil-psf.js +190 -98
- package/dist/optics/complex-pupil-psf.js.map +1 -1
- package/dist/optics/depth-of-field.d.ts +25 -15
- package/dist/optics/depth-of-field.js +67 -27
- package/dist/optics/depth-of-field.js.map +1 -1
- package/dist/optics/diffraction.d.ts +14 -13
- package/dist/optics/diffraction.js +14 -10
- package/dist/optics/diffraction.js.map +1 -1
- package/dist/optics/focus-breathing.d.ts +88 -27
- package/dist/optics/focus-breathing.js +114 -23
- package/dist/optics/focus-breathing.js.map +1 -1
- package/dist/optics/focus-state.d.ts +18 -18
- package/dist/optics/focus-state.js +21 -15
- package/dist/optics/focus-state.js.map +1 -1
- package/dist/optics/front-of-lens-filter.d.ts +45 -14
- package/dist/optics/front-of-lens-filter.js +259 -88
- package/dist/optics/front-of-lens-filter.js.map +1 -1
- package/dist/optics/illumination-vignetting.d.ts +16 -17
- package/dist/optics/illumination-vignetting.js +40 -17
- package/dist/optics/illumination-vignetting.js.map +1 -1
- package/dist/optics/irradiance-convolution.d.ts +59 -0
- package/dist/optics/irradiance-convolution.js +138 -0
- package/dist/optics/irradiance-convolution.js.map +1 -0
- package/dist/optics/lateral-chromatic-aberration.d.ts +33 -30
- package/dist/optics/lateral-chromatic-aberration.js +33 -23
- package/dist/optics/lateral-chromatic-aberration.js.map +1 -1
- package/dist/optics/lens-psf-kernels.d.ts +89 -0
- package/dist/optics/lens-psf-kernels.js +175 -0
- package/dist/optics/lens-psf-kernels.js.map +1 -0
- package/dist/optics/lens-psf-profile.d.ts +78 -46
- package/dist/optics/lens-psf-profile.js +335 -124
- package/dist/optics/lens-psf-profile.js.map +1 -1
- package/dist/optics/longitudinal-chromatic-aberration.d.ts +102 -0
- package/dist/optics/longitudinal-chromatic-aberration.js +210 -0
- package/dist/optics/longitudinal-chromatic-aberration.js.map +1 -0
- package/dist/optics/polygon-diffraction.d.ts +80 -23
- package/dist/optics/polygon-diffraction.js +130 -25
- package/dist/optics/polygon-diffraction.js.map +1 -1
- package/dist/optics/profile-contract.d.ts +5 -6
- package/dist/optics/profile-contract.js +14 -11
- package/dist/optics/profile-contract.js.map +1 -1
- package/dist/optics/psf-foundation.d.ts +23 -23
- package/dist/optics/psf-foundation.js +24 -21
- package/dist/optics/psf-foundation.js.map +1 -1
- package/dist/optics/pupil-vignetting.d.ts +118 -0
- package/dist/optics/pupil-vignetting.js +264 -0
- package/dist/optics/pupil-vignetting.js.map +1 -0
- package/dist/optics/radial-distortion.d.ts +34 -33
- package/dist/optics/radial-distortion.js +37 -30
- package/dist/optics/radial-distortion.js.map +1 -1
- package/dist/optics/scene-to-sensor-irradiance.d.ts +47 -33
- package/dist/optics/scene-to-sensor-irradiance.js +73 -45
- package/dist/optics/scene-to-sensor-irradiance.js.map +1 -1
- package/dist/optics/scene-to-sensor-quadrature.d.ts +23 -18
- package/dist/optics/scene-to-sensor-quadrature.js +16 -11
- package/dist/optics/scene-to-sensor-quadrature.js.map +1 -1
- package/dist/optics/sensor-aperture-rays.d.ts +20 -4
- package/dist/optics/sensor-aperture-rays.js +32 -14
- package/dist/optics/sensor-aperture-rays.js.map +1 -1
- package/dist/optics/sensor-environment-query.d.ts +81 -16
- package/dist/optics/sensor-environment-query.js +145 -12
- package/dist/optics/sensor-environment-query.js.map +1 -1
- package/dist/optics/sensor-psf-quadrature.d.ts +12 -10
- package/dist/optics/sensor-psf-quadrature.js +18 -11
- package/dist/optics/sensor-psf-quadrature.js.map +1 -1
- package/dist/optics/sensor-psf-support.d.ts +8 -6
- package/dist/optics/sensor-psf-support.js +8 -5
- package/dist/optics/sensor-psf-support.js.map +1 -1
- package/dist/optics/stray-light.d.ts +22 -19
- package/dist/optics/stray-light.js +18 -12
- package/dist/optics/stray-light.js.map +1 -1
- package/dist/optics/thin-lens.d.ts +10 -9
- package/dist/optics/thin-lens.js +12 -8
- package/dist/optics/thin-lens.js.map +1 -1
- package/dist/optics/zernike-wavefront.d.ts +154 -0
- package/dist/optics/zernike-wavefront.js +352 -0
- package/dist/optics/zernike-wavefront.js.map +1 -0
- package/dist/output/capture-corrected-sdr.d.ts +16 -8
- package/dist/output/capture-corrected-sdr.js +16 -8
- package/dist/output/capture-corrected-sdr.js.map +1 -1
- package/dist/output/capture-geometry.d.ts +34 -36
- package/dist/output/capture-geometry.js +52 -32
- package/dist/output/capture-geometry.js.map +1 -1
- package/dist/output/capture-sdr.d.ts +7 -6
- package/dist/output/capture-sdr.js +11 -8
- package/dist/output/capture-sdr.js.map +1 -1
- package/dist/output/crop.d.ts +22 -6
- package/dist/output/crop.js +40 -6
- package/dist/output/crop.js.map +1 -1
- package/dist/output/geometric-transforms.d.ts +60 -23
- package/dist/output/geometric-transforms.js +111 -24
- package/dist/output/geometric-transforms.js.map +1 -1
- package/dist/output/lens-corrections.d.ts +27 -19
- package/dist/output/lens-corrections.js +29 -13
- package/dist/output/lens-corrections.js.map +1 -1
- package/dist/output/native-capture-sdr.d.ts +71 -16
- package/dist/output/native-capture-sdr.js +190 -33
- package/dist/output/native-capture-sdr.js.map +1 -1
- package/dist/output/png-encoder.d.ts +65 -0
- package/dist/output/png-encoder.js +461 -0
- package/dist/output/png-encoder.js.map +1 -0
- package/dist/output/print-contrast-reference.d.ts +10 -9
- package/dist/output/print-contrast-reference.js +10 -8
- package/dist/output/print-contrast-reference.js.map +1 -1
- package/dist/output/print-detail.d.ts +18 -17
- package/dist/output/print-detail.js +12 -10
- package/dist/output/print-detail.js.map +1 -1
- package/dist/output/print-jpeg.d.ts +26 -5
- package/dist/output/print-jpeg.js +117 -50
- package/dist/output/print-jpeg.js.map +1 -1
- package/dist/output/print-plan.d.ts +19 -19
- package/dist/output/print-plan.js +11 -10
- package/dist/output/print-plan.js.map +1 -1
- package/dist/output/print-region-statistics.d.ts +14 -15
- package/dist/output/print-region-statistics.js +11 -11
- package/dist/output/print-region-statistics.js.map +1 -1
- package/dist/output/sdr-rendering.d.ts +48 -10
- package/dist/output/sdr-rendering.js +114 -25
- package/dist/output/sdr-rendering.js.map +1 -1
- package/dist/output/subject-framing-crop.d.ts +6 -10
- package/dist/output/subject-framing-crop.js +23 -13
- package/dist/output/subject-framing-crop.js.map +1 -1
- package/dist/processing/demosaic.d.ts +90 -0
- package/dist/processing/demosaic.js +275 -0
- package/dist/processing/demosaic.js.map +1 -0
- package/dist/processing/denoise.d.ts +68 -0
- package/dist/processing/denoise.js +214 -0
- package/dist/processing/denoise.js.map +1 -0
- package/dist/processing/focus-stacking.d.ts +17 -0
- package/dist/processing/focus-stacking.js +80 -0
- package/dist/processing/focus-stacking.js.map +1 -0
- package/dist/processing/hdr.d.ts +54 -0
- package/dist/processing/hdr.js +172 -0
- package/dist/processing/hdr.js.map +1 -0
- package/dist/processing/image-ops.d.ts +66 -0
- package/dist/processing/image-ops.js +192 -0
- package/dist/processing/image-ops.js.map +1 -0
- package/dist/processing/panorama.d.ts +51 -0
- package/dist/processing/panorama.js +305 -0
- package/dist/processing/panorama.js.map +1 -0
- package/dist/processing/processing-task.d.ts +85 -0
- package/dist/processing/processing-task.js +164 -0
- package/dist/processing/processing-task.js.map +1 -0
- package/dist/processing/tone-mapping.d.ts +69 -0
- package/dist/processing/tone-mapping.js +310 -0
- package/dist/processing/tone-mapping.js.map +1 -0
- package/dist/schema/camera.d.ts +5 -4
- package/dist/schema/illumination-spectral.d.ts +13 -19
- package/dist/schema/illumination-spectral.js +23 -19
- package/dist/schema/illumination-spectral.js.map +1 -1
- package/dist/schema/illumination-temporal.d.ts +12 -15
- package/dist/schema/illumination-temporal.js +43 -28
- package/dist/schema/illumination-temporal.js.map +1 -1
- package/dist/schema/illumination.d.ts +5 -4
- package/dist/schema/illumination.js +55 -20
- package/dist/schema/illumination.js.map +1 -1
- package/dist/schema/scene-radiance-temporal.d.ts +9 -11
- package/dist/schema/scene-radiance-temporal.js +26 -23
- package/dist/schema/scene-radiance-temporal.js.map +1 -1
- package/dist/schema/scene-radiance.d.ts +17 -17
- package/dist/schema/scene-radiance.js +56 -34
- package/dist/schema/scene-radiance.js.map +1 -1
- package/dist/schema/scene.d.ts +14 -13
- package/dist/schema/validation.d.ts +0 -1
- package/dist/schema/validation.js +17 -15
- package/dist/schema/validation.js.map +1 -1
- package/dist/sensor/accumulated-charge.d.ts +45 -64
- package/dist/sensor/accumulated-charge.js +41 -47
- package/dist/sensor/accumulated-charge.js.map +1 -1
- package/dist/sensor/architecture.d.ts +22 -25
- package/dist/sensor/architecture.js +17 -16
- package/dist/sensor/architecture.js.map +1 -1
- package/dist/sensor/camera-saturation-capacity.d.ts +21 -28
- package/dist/sensor/camera-saturation-capacity.js +36 -34
- package/dist/sensor/camera-saturation-capacity.js.map +1 -1
- package/dist/sensor/capture-color-sampling-binding.d.ts +46 -51
- package/dist/sensor/capture-color-sampling-binding.js +39 -41
- package/dist/sensor/capture-color-sampling-binding.js.map +1 -1
- package/dist/sensor/capture-mode-timing.d.ts +8 -9
- package/dist/sensor/capture-mode-timing.js +24 -21
- package/dist/sensor/capture-mode-timing.js.map +1 -1
- package/dist/sensor/capture-mode.d.ts +28 -30
- package/dist/sensor/capture-mode.js +33 -31
- package/dist/sensor/capture-mode.js.map +1 -1
- package/dist/sensor/color-sampling.d.ts +30 -33
- package/dist/sensor/color-sampling.js +32 -37
- package/dist/sensor/color-sampling.js.map +1 -1
- package/dist/sensor/constant-rate-temporal-integration.d.ts +19 -23
- package/dist/sensor/constant-rate-temporal-integration.js +28 -26
- package/dist/sensor/constant-rate-temporal-integration.js.map +1 -1
- package/dist/sensor/dark-current.d.ts +53 -49
- package/dist/sensor/dark-current.js +87 -46
- package/dist/sensor/dark-current.js.map +1 -1
- package/dist/sensor/environment-photo-signal.d.ts +71 -30
- package/dist/sensor/environment-photo-signal.js +127 -46
- package/dist/sensor/environment-photo-signal.js.map +1 -1
- package/dist/sensor/eqe-electron-rate.d.ts +14 -13
- package/dist/sensor/eqe-electron-rate.js +34 -14
- package/dist/sensor/eqe-electron-rate.js.map +1 -1
- package/dist/sensor/eqe-local-exposure.d.ts +24 -24
- package/dist/sensor/eqe-local-exposure.js +15 -11
- package/dist/sensor/eqe-local-exposure.js.map +1 -1
- package/dist/sensor/eqe-temporal-exposure.d.ts +11 -11
- package/dist/sensor/eqe-temporal-exposure.js +15 -10
- package/dist/sensor/eqe-temporal-exposure.js.map +1 -1
- package/dist/sensor/exposure-window.d.ts +48 -34
- package/dist/sensor/exposure-window.js +77 -36
- package/dist/sensor/exposure-window.js.map +1 -1
- package/dist/sensor/fixed-pattern-noise.d.ts +108 -0
- package/dist/sensor/fixed-pattern-noise.js +166 -0
- package/dist/sensor/fixed-pattern-noise.js.map +1 -0
- package/dist/sensor/iso-gain.d.ts +44 -0
- package/dist/sensor/iso-gain.js +119 -0
- package/dist/sensor/iso-gain.js.map +1 -0
- package/dist/sensor/iso-signal-chain.d.ts +25 -48
- package/dist/sensor/iso-signal-chain.js +52 -66
- package/dist/sensor/iso-signal-chain.js.map +1 -1
- package/dist/sensor/local-exposure-binding.d.ts +21 -21
- package/dist/sensor/local-exposure-binding.js +22 -18
- package/dist/sensor/local-exposure-binding.js.map +1 -1
- package/dist/sensor/optical-stack.d.ts +36 -40
- package/dist/sensor/optical-stack.js +34 -37
- package/dist/sensor/optical-stack.js.map +1 -1
- package/dist/sensor/photon-energy.d.ts +22 -28
- package/dist/sensor/photon-energy.js +42 -34
- package/dist/sensor/photon-energy.js.map +1 -1
- package/dist/sensor/physical-charge-capacity.d.ts +20 -30
- package/dist/sensor/physical-charge-capacity.js +35 -36
- package/dist/sensor/physical-charge-capacity.js.map +1 -1
- package/dist/sensor/pixel-pitch.d.ts +2 -3
- package/dist/sensor/pixel-pitch.js +4 -2
- package/dist/sensor/pixel-pitch.js.map +1 -1
- package/dist/sensor/radiometry-readiness.d.ts +13 -15
- package/dist/sensor/radiometry-readiness.js +20 -17
- package/dist/sensor/radiometry-readiness.js.map +1 -1
- package/dist/sensor/raw-readout.d.ts +173 -83
- package/dist/sensor/raw-readout.js +425 -160
- package/dist/sensor/raw-readout.js.map +1 -1
- package/dist/sensor/raw-reconstruction.d.ts +112 -44
- package/dist/sensor/raw-reconstruction.js +200 -47
- package/dist/sensor/raw-reconstruction.js.map +1 -1
- package/dist/sensor/readout-exposure-linkage.d.ts +103 -34
- package/dist/sensor/readout-exposure-linkage.js +125 -27
- package/dist/sensor/readout-exposure-linkage.js.map +1 -1
- package/dist/sensor/readout-timing.d.ts +43 -44
- package/dist/sensor/readout-timing.js +38 -30
- package/dist/sensor/readout-timing.js.map +1 -1
- package/dist/sensor/response-application-compatibility.d.ts +21 -28
- package/dist/sensor/response-application-compatibility.js +35 -34
- package/dist/sensor/response-application-compatibility.js.map +1 -1
- package/dist/sensor/response-operating-range.d.ts +26 -35
- package/dist/sensor/response-operating-range.js +40 -39
- package/dist/sensor/response-operating-range.js.map +1 -1
- package/dist/sensor/responsivity-photocurrent.d.ts +21 -29
- package/dist/sensor/responsivity-photocurrent.js +57 -40
- package/dist/sensor/responsivity-photocurrent.js.map +1 -1
- package/dist/sensor/sampling-aperture.d.ts +21 -25
- package/dist/sensor/sampling-aperture.js +29 -28
- package/dist/sensor/sampling-aperture.js.map +1 -1
- package/dist/sensor/scene-eqe-temporal-exposure.d.ts +14 -12
- package/dist/sensor/scene-eqe-temporal-exposure.js +13 -8
- package/dist/sensor/scene-eqe-temporal-exposure.js.map +1 -1
- package/dist/sensor/sensor-geometry.d.ts +28 -32
- package/dist/sensor/sensor-geometry.js +35 -20
- package/dist/sensor/sensor-geometry.js.map +1 -1
- package/dist/sensor/signal-noise.d.ts +14 -16
- package/dist/sensor/signal-noise.js +15 -13
- package/dist/sensor/signal-noise.js.map +1 -1
- package/dist/sensor/spatial-sample-reduction.d.ts +45 -60
- package/dist/sensor/spatial-sample-reduction.js +39 -48
- package/dist/sensor/spatial-sample-reduction.js.map +1 -1
- package/dist/sensor/spatial-sampling-quadrature.d.ts +46 -54
- package/dist/sensor/spatial-sampling-quadrature.js +31 -36
- package/dist/sensor/spatial-sampling-quadrature.js.map +1 -1
- package/dist/sensor/spatio-spectral-reduction.d.ts +32 -42
- package/dist/sensor/spatio-spectral-reduction.js +24 -29
- package/dist/sensor/spatio-spectral-reduction.js.map +1 -1
- package/dist/sensor/spectral-coverage.d.ts +6 -9
- package/dist/sensor/spectral-coverage.js +9 -6
- package/dist/sensor/spectral-coverage.js.map +1 -1
- package/dist/sensor/spectral-quadrature.d.ts +46 -60
- package/dist/sensor/spectral-quadrature.js +38 -48
- package/dist/sensor/spectral-quadrature.js.map +1 -1
- package/dist/sensor/spectral-response.d.ts +53 -41
- package/dist/sensor/spectral-response.js +80 -47
- package/dist/sensor/spectral-response.js.map +1 -1
- package/dist/sensor/stochastic-seed.d.ts +50 -0
- package/dist/sensor/stochastic-seed.js +123 -0
- package/dist/sensor/stochastic-seed.js.map +1 -0
- package/dist/sensor/temporal-eqe-sum.d.ts +2 -4
- package/dist/sensor/temporal-eqe-sum.js +5 -6
- package/dist/sensor/temporal-eqe-sum.js.map +1 -1
- package/dist/sensor/temporal-photo-signal.d.ts +5 -6
- package/dist/sensor/temporal-photo-signal.js +11 -10
- package/dist/sensor/temporal-photo-signal.js.map +1 -1
- package/dist/sensor/temporal-sample-binding.d.ts +1 -2
- package/dist/sensor/temporal-sample-binding.js +3 -3
- package/dist/sensor/temporal-sample-binding.js.map +1 -1
- package/dist/simulation/poc-simulation.d.ts +16 -16
- package/dist/simulation/poc-simulation.js +20 -15
- package/dist/simulation/poc-simulation.js.map +1 -1
- package/dist/stabilization/camera-shake.d.ts +42 -18
- package/dist/stabilization/camera-shake.js +43 -20
- package/dist/stabilization/camera-shake.js.map +1 -1
- package/dist/stabilization/system.d.ts +44 -41
- package/dist/stabilization/system.js +196 -108
- package/dist/stabilization/system.js.map +1 -1
- package/docs/AGENT_GUIDE.md +183 -0
- package/docs/API_REFERENCE.md +761 -2
- package/docs/QUICK_START.md +495 -0
- package/docs/USAGE.md +1719 -714
- package/docs/api/camera-equivalent-focal-length.md +6 -7
- package/docs/api/camera-field-of-view.md +16 -8
- package/docs/api/camera-lens-projection.md +246 -0
- package/docs/api/camera-projected-object-size.md +6 -5
- package/docs/api/capture-capture-export-metadata.md +10 -10
- package/docs/api/capture-dng-import.md +134 -0
- package/docs/api/capture-environment-raw-producer.md +17 -11
- package/docs/api/capture-export-jpeg.md +16 -0
- package/docs/api/capture-focus-control.md +25 -47
- package/docs/api/capture-linear-encoding.md +21 -12
- package/docs/api/capture-lossless-jpeg.md +49 -0
- package/docs/api/capture-native-environment-optical-stage.md +75 -0
- package/docs/api/capture-native-environment-raw.md +161 -4
- package/docs/api/capture-native-raw-development.md +69 -4
- package/docs/api/capture-native-raw-dng.md +84 -0
- package/docs/api/capture-native-raw.md +23 -8
- package/docs/api/capture-packed-sensor-raw.md +156 -0
- package/docs/api/capture-photographic-export.md +69 -31
- package/docs/api/capture-raw-frame-reconstruction.md +8 -8
- package/docs/api/capture-raw-white-level.md +37 -0
- package/docs/api/capture-release-sequence.md +6 -7
- package/docs/api/capture-sensor-raw-frame.md +6 -6
- package/docs/api/capture-sensor-raw-producer.md +17 -11
- package/docs/api/capture-simulated-capture.md +15 -15
- package/docs/api/color-camera-color-matrix.md +103 -0
- package/docs/api/color-capture-color.md +22 -11
- package/docs/api/color-chromatic-adaptation.md +82 -0
- package/docs/api/color-color-difference.md +134 -0
- package/docs/api/color-color-matching-functions.md +259 -0
- package/docs/api/color-colorimetry-math.md +54 -0
- package/docs/api/color-gamut-mapping.md +72 -0
- package/docs/api/color-illuminants.md +280 -0
- package/docs/api/color-rgb-color-spaces.md +151 -0
- package/docs/api/color-sensor-color-development.md +27 -0
- package/docs/api/color-srgb-icc.md +2 -4
- package/docs/api/color-white-balance.md +95 -19
- package/docs/api/composition-image-formation-plan.md +124 -95
- package/docs/api/composition-plan-consumer.md +7 -7
- package/docs/api/core-calculation-result.md +18 -14
- package/docs/api/core-configuration-error.md +1 -1
- package/docs/api/core-image-formation.md +7 -7
- package/docs/api/core-scientific-assurance.md +12 -10
- package/docs/api/core-spectral-composition.md +14 -14
- package/docs/api/core-spectral.md +6 -6
- package/docs/api/core-validation.md +3 -3
- package/docs/api/core-version.md +7 -6
- package/docs/api/equipment-exposure-capabilities.md +11 -10
- package/docs/api/equipment-generic-tier-assets.md +7 -2
- package/docs/api/equipment-generic-tier-presets.md +6 -6
- package/docs/api/equipment-iso-capabilities.md +18 -18
- package/docs/api/equipment-metering-capabilities.md +6 -6
- package/docs/api/equipment-release-capabilities.md +4 -4
- package/docs/api/exports.json +2213 -8
- package/docs/api/exposure-exposure-duration-control.md +9 -9
- package/docs/api/exposure-exposure-mode-resolver.md +35 -31
- package/docs/api/exposure-exposure.md +10 -10
- package/docs/api/exposure-flash-ttl.md +182 -0
- package/docs/api/exposure-flash.md +183 -28
- package/docs/api/exposure-metering-scene-radiance.md +11 -10
- package/docs/api/exposure-metering-target.md +9 -8
- package/docs/api/exposure-metering-temporal.md +8 -8
- package/docs/api/exposure-metering.md +69 -9
- package/docs/api/exposure-program-line.md +6 -5
- package/docs/api/facade-chart-radiance-batch.md +96 -0
- package/docs/api/facade-chart-scenes.md +240 -0
- package/docs/api/facade-scene-radiance.md +122 -0
- package/docs/api/facade-simulate-capture.md +324 -0
- package/docs/api/gpu-image-kernel-accelerator.md +157 -0
- package/docs/api/gpu-image-kernel-execution.md +152 -0
- package/docs/api/motion-camera-rotation.md +43 -26
- package/docs/api/motion-capture-rotation-inverse-mapping.md +24 -23
- package/docs/api/motion-capture-rotation-temporal-quadrature.md +22 -22
- package/docs/api/motion-capture-rotation-trajectory.md +15 -15
- package/docs/api/motion-capture-translation-parallax-temporal-quadrature.md +15 -14
- package/docs/api/motion-extended-object-projection.md +10 -8
- package/docs/api/motion-projected-motion.md +8 -8
- package/docs/api/motion-temporal-exposure-sum.md +98 -0
- package/docs/api/motion-video-sequence.md +159 -0
- package/docs/api/optics-aperture.md +8 -8
- package/docs/api/optics-atmospheric-haze.md +104 -0
- package/docs/api/optics-brown-conrady-distortion.md +123 -0
- package/docs/api/optics-circle-of-confusion.md +5 -4
- package/docs/api/optics-complex-pupil-psf.md +57 -16
- package/docs/api/optics-depth-of-field.md +12 -6
- package/docs/api/optics-diffraction.md +8 -7
- package/docs/api/optics-focus-breathing.md +104 -16
- package/docs/api/optics-focus-state.md +9 -10
- package/docs/api/optics-front-of-lens-filter.md +72 -14
- package/docs/api/optics-illumination-vignetting.md +10 -10
- package/docs/api/optics-irradiance-convolution.md +95 -0
- package/docs/api/optics-lateral-chromatic-aberration.md +22 -21
- package/docs/api/optics-lens-psf-kernels.md +72 -0
- package/docs/api/optics-lens-psf-profile.md +48 -26
- package/docs/api/optics-longitudinal-chromatic-aberration.md +128 -0
- package/docs/api/optics-polygon-diffraction.md +78 -13
- package/docs/api/optics-profile-contract.md +4 -4
- package/docs/api/optics-psf-foundation.md +12 -12
- package/docs/api/optics-pupil-vignetting.md +132 -0
- package/docs/api/optics-radial-distortion.md +12 -12
- package/docs/api/optics-scene-to-sensor-irradiance.md +25 -14
- package/docs/api/optics-scene-to-sensor-quadrature.md +15 -12
- package/docs/api/optics-sensor-aperture-rays.md +3 -2
- package/docs/api/optics-sensor-environment-query.md +52 -9
- package/docs/api/optics-sensor-psf-quadrature.md +13 -10
- package/docs/api/optics-stray-light.md +12 -11
- package/docs/api/optics-thin-lens.md +4 -3
- package/docs/api/optics-zernike-wavefront.md +229 -0
- package/docs/api/output-capture-corrected-sdr.md +10 -7
- package/docs/api/output-capture-geometry.md +35 -36
- package/docs/api/output-capture-sdr.md +4 -4
- package/docs/api/output-crop.md +7 -4
- package/docs/api/output-geometric-transforms.md +65 -19
- package/docs/api/output-lens-corrections.md +17 -15
- package/docs/api/output-native-capture-sdr.md +26 -13
- package/docs/api/output-png-encoder.md +105 -0
- package/docs/api/output-print-contrast-reference.md +8 -8
- package/docs/api/output-print-detail.md +14 -14
- package/docs/api/output-print-jpeg.md +22 -5
- package/docs/api/output-print-plan.md +18 -18
- package/docs/api/output-print-region-statistics.md +14 -14
- package/docs/api/output-sdr-rendering.md +52 -10
- package/docs/api/output-subject-framing-crop.md +5 -6
- package/docs/api/processing-demosaic.md +120 -0
- package/docs/api/processing-denoise.md +148 -0
- package/docs/api/processing-focus-stacking.md +41 -0
- package/docs/api/processing-hdr.md +113 -0
- package/docs/api/processing-panorama.md +82 -0
- package/docs/api/processing-processing-task.md +107 -0
- package/docs/api/processing-tone-mapping.md +142 -0
- package/docs/api/schema-camera.md +6 -4
- package/docs/api/schema-illumination-spectral.md +10 -11
- package/docs/api/schema-illumination-temporal.md +13 -15
- package/docs/api/schema-illumination.md +4 -4
- package/docs/api/schema-scene-radiance-temporal.md +10 -11
- package/docs/api/schema-scene-radiance.md +18 -17
- package/docs/api/schema-scene.md +9 -9
- package/docs/api/schema-validation.md +1 -1
- package/docs/api/sensor-accumulated-charge.md +12 -20
- package/docs/api/sensor-architecture.md +15 -16
- package/docs/api/sensor-camera-saturation-capacity.md +9 -11
- package/docs/api/sensor-capture-color-sampling-binding.md +47 -51
- package/docs/api/sensor-capture-mode-timing.md +9 -9
- package/docs/api/sensor-capture-mode.md +29 -30
- package/docs/api/sensor-color-sampling.md +31 -33
- package/docs/api/sensor-constant-rate-temporal-integration.md +10 -11
- package/docs/api/sensor-dark-current.md +30 -14
- package/docs/api/sensor-environment-photo-signal.md +13 -6
- package/docs/api/sensor-eqe-electron-rate.md +9 -8
- package/docs/api/sensor-eqe-local-exposure.md +18 -17
- package/docs/api/sensor-eqe-temporal-exposure.md +12 -11
- package/docs/api/sensor-exposure-window.md +24 -24
- package/docs/api/sensor-fixed-pattern-noise.md +104 -0
- package/docs/api/sensor-iso-gain.md +63 -0
- package/docs/api/sensor-iso-signal-chain.md +13 -22
- package/docs/api/sensor-local-exposure-binding.md +12 -13
- package/docs/api/sensor-optical-stack.md +37 -40
- package/docs/api/sensor-photon-energy.md +10 -11
- package/docs/api/sensor-physical-charge-capacity.md +8 -13
- package/docs/api/sensor-pixel-pitch.md +1 -1
- package/docs/api/sensor-radiometry-readiness.md +9 -9
- package/docs/api/sensor-raw-readout.md +118 -52
- package/docs/api/sensor-raw-reconstruction.md +97 -20
- package/docs/api/sensor-readout-exposure-linkage.md +120 -24
- package/docs/api/sensor-readout-timing.md +33 -35
- package/docs/api/sensor-response-application-compatibility.md +9 -11
- package/docs/api/sensor-response-operating-range.md +14 -18
- package/docs/api/sensor-responsivity-photocurrent.md +9 -12
- package/docs/api/sensor-sampling-aperture.md +22 -25
- package/docs/api/sensor-scene-eqe-temporal-exposure.md +9 -8
- package/docs/api/sensor-sensor-geometry.md +23 -24
- package/docs/api/sensor-signal-noise.md +10 -10
- package/docs/api/sensor-spatial-sample-reduction.md +27 -30
- package/docs/api/sensor-spatial-sampling-quadrature.md +37 -39
- package/docs/api/sensor-spatio-spectral-reduction.md +27 -29
- package/docs/api/sensor-spectral-coverage.md +5 -5
- package/docs/api/sensor-spectral-quadrature.md +33 -35
- package/docs/api/sensor-spectral-response.md +28 -16
- package/docs/api/sensor-temporal-photo-signal.md +6 -6
- package/docs/api/simulation-poc-simulation.md +17 -16
- package/docs/api/stabilization-camera-shake.md +29 -10
- package/docs/api/stabilization-system.md +25 -21
- package/docs/examples/production-request.json +3821 -2157
- package/docs/examples/simulate-capture.mjs +14 -0
- package/llms.txt +35 -0
- package/package.json +32 -12
- package/AGENTS.md +0 -674
- package/CONTRIBUTING.md +0 -76
- package/DCO +0 -33
- package/dist/camera/equivalent-focal-length.d.ts.map +0 -1
- package/dist/camera/field-of-view.d.ts.map +0 -1
- package/dist/camera/projected-object-size.d.ts.map +0 -1
- package/dist/capture/capture-export-metadata.d.ts.map +0 -1
- package/dist/capture/environment-raw-producer.d.ts.map +0 -1
- package/dist/capture/export-jpeg.d.ts.map +0 -1
- package/dist/capture/export-tiff.d.ts.map +0 -1
- package/dist/capture/focus-control.d.ts.map +0 -1
- package/dist/capture/linear-encoding.d.ts.map +0 -1
- package/dist/capture/native-environment-raw.d.ts.map +0 -1
- package/dist/capture/native-raw-development.d.ts.map +0 -1
- package/dist/capture/native-raw.d.ts.map +0 -1
- package/dist/capture/photographic-export.d.ts.map +0 -1
- package/dist/capture/raw-frame-limits.d.ts.map +0 -1
- package/dist/capture/raw-frame-reconstruction.d.ts.map +0 -1
- package/dist/capture/release-sequence.d.ts.map +0 -1
- package/dist/capture/sensor-raw-frame.d.ts.map +0 -1
- package/dist/capture/sensor-raw-producer.d.ts.map +0 -1
- package/dist/capture/simulated-capture.d.ts.map +0 -1
- package/dist/color/capture-color.d.ts.map +0 -1
- package/dist/color/sensor-color-development.d.ts.map +0 -1
- package/dist/color/srgb-icc.d.ts.map +0 -1
- package/dist/color/srgb-transfer.d.ts.map +0 -1
- package/dist/color/white-balance.d.ts.map +0 -1
- package/dist/composition/image-formation-plan.d.ts.map +0 -1
- package/dist/composition/plan-consumer.d.ts.map +0 -1
- package/dist/core/calculation-result.d.ts.map +0 -1
- package/dist/core/canonical-json.d.ts.map +0 -1
- package/dist/core/configuration-error.d.ts.map +0 -1
- package/dist/core/evidence-provenance.d.ts.map +0 -1
- package/dist/core/image-formation.d.ts.map +0 -1
- package/dist/core/owned-data.d.ts.map +0 -1
- package/dist/core/record-validation.d.ts.map +0 -1
- package/dist/core/scientific-assurance.d.ts.map +0 -1
- package/dist/core/spectral-composition.d.ts.map +0 -1
- package/dist/core/spectral.d.ts.map +0 -1
- package/dist/core/validation.d.ts.map +0 -1
- package/dist/core/version.d.ts.map +0 -1
- package/dist/equipment/exposure-capabilities.d.ts.map +0 -1
- package/dist/equipment/generic-tier-assets.d.ts.map +0 -1
- package/dist/equipment/generic-tier-presets.d.ts.map +0 -1
- package/dist/equipment/iso-capabilities.d.ts.map +0 -1
- package/dist/equipment/metering-capabilities.d.ts.map +0 -1
- package/dist/equipment/release-capabilities.d.ts.map +0 -1
- package/dist/exposure/exposure-duration-control.d.ts.map +0 -1
- package/dist/exposure/exposure-mode-resolver.d.ts.map +0 -1
- package/dist/exposure/exposure.d.ts.map +0 -1
- package/dist/exposure/flash.d.ts.map +0 -1
- package/dist/exposure/metering-scene-radiance.d.ts.map +0 -1
- package/dist/exposure/metering-target.d.ts.map +0 -1
- package/dist/exposure/metering-temporal.d.ts.map +0 -1
- package/dist/exposure/metering.d.ts.map +0 -1
- package/dist/exposure/program-line.d.ts.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/motion/camera-rotation.d.ts.map +0 -1
- package/dist/motion/capture-rotation-inverse-mapping.d.ts.map +0 -1
- package/dist/motion/capture-rotation-temporal-quadrature.d.ts.map +0 -1
- package/dist/motion/capture-rotation-trajectory.d.ts.map +0 -1
- package/dist/motion/capture-translation-parallax-temporal-quadrature.d.ts.map +0 -1
- package/dist/motion/extended-object-projection.d.ts.map +0 -1
- package/dist/motion/projected-motion.d.ts.map +0 -1
- package/dist/optics/aperture.d.ts.map +0 -1
- package/dist/optics/circle-of-confusion.d.ts.map +0 -1
- package/dist/optics/complex-pupil-psf.d.ts.map +0 -1
- package/dist/optics/depth-of-field.d.ts.map +0 -1
- package/dist/optics/diffraction.d.ts.map +0 -1
- package/dist/optics/focus-breathing.d.ts.map +0 -1
- package/dist/optics/focus-state.d.ts.map +0 -1
- package/dist/optics/front-of-lens-filter.d.ts.map +0 -1
- package/dist/optics/illumination-vignetting.d.ts.map +0 -1
- package/dist/optics/lateral-chromatic-aberration.d.ts.map +0 -1
- package/dist/optics/lens-psf-profile.d.ts.map +0 -1
- package/dist/optics/polygon-diffraction.d.ts.map +0 -1
- package/dist/optics/profile-contract.d.ts.map +0 -1
- package/dist/optics/psf-foundation.d.ts.map +0 -1
- package/dist/optics/radial-distortion.d.ts.map +0 -1
- package/dist/optics/scene-to-sensor-irradiance.d.ts.map +0 -1
- package/dist/optics/scene-to-sensor-quadrature.d.ts.map +0 -1
- package/dist/optics/sensor-aperture-rays.d.ts.map +0 -1
- package/dist/optics/sensor-environment-query.d.ts.map +0 -1
- package/dist/optics/sensor-psf-quadrature.d.ts.map +0 -1
- package/dist/optics/sensor-psf-support.d.ts.map +0 -1
- package/dist/optics/stray-light.d.ts.map +0 -1
- package/dist/optics/thin-lens.d.ts.map +0 -1
- package/dist/output/capture-corrected-sdr.d.ts.map +0 -1
- package/dist/output/capture-geometry.d.ts.map +0 -1
- package/dist/output/capture-sdr.d.ts.map +0 -1
- package/dist/output/crop.d.ts.map +0 -1
- package/dist/output/geometric-transforms.d.ts.map +0 -1
- package/dist/output/lens-corrections.d.ts.map +0 -1
- package/dist/output/native-capture-sdr.d.ts.map +0 -1
- package/dist/output/print-contrast-reference.d.ts.map +0 -1
- package/dist/output/print-detail.d.ts.map +0 -1
- package/dist/output/print-jpeg.d.ts.map +0 -1
- package/dist/output/print-plan.d.ts.map +0 -1
- package/dist/output/print-region-statistics.d.ts.map +0 -1
- package/dist/output/sdr-rendering.d.ts.map +0 -1
- package/dist/output/subject-framing-crop.d.ts.map +0 -1
- package/dist/schema/camera.d.ts.map +0 -1
- package/dist/schema/camera.js +0 -3
- package/dist/schema/camera.js.map +0 -1
- package/dist/schema/illumination-spectral.d.ts.map +0 -1
- package/dist/schema/illumination-temporal.d.ts.map +0 -1
- package/dist/schema/illumination.d.ts.map +0 -1
- package/dist/schema/scene-radiance-temporal.d.ts.map +0 -1
- package/dist/schema/scene-radiance.d.ts.map +0 -1
- package/dist/schema/scene.d.ts.map +0 -1
- package/dist/schema/scene.js +0 -3
- package/dist/schema/scene.js.map +0 -1
- package/dist/schema/validation.d.ts.map +0 -1
- package/dist/sensor/accumulated-charge.d.ts.map +0 -1
- package/dist/sensor/architecture.d.ts.map +0 -1
- package/dist/sensor/camera-saturation-capacity.d.ts.map +0 -1
- package/dist/sensor/capture-color-sampling-binding.d.ts.map +0 -1
- package/dist/sensor/capture-mode-timing.d.ts.map +0 -1
- package/dist/sensor/capture-mode.d.ts.map +0 -1
- package/dist/sensor/color-sampling.d.ts.map +0 -1
- package/dist/sensor/constant-rate-temporal-integration.d.ts.map +0 -1
- package/dist/sensor/dark-current.d.ts.map +0 -1
- package/dist/sensor/environment-photo-signal.d.ts.map +0 -1
- package/dist/sensor/eqe-electron-rate.d.ts.map +0 -1
- package/dist/sensor/eqe-local-exposure.d.ts.map +0 -1
- package/dist/sensor/eqe-temporal-exposure.d.ts.map +0 -1
- package/dist/sensor/exposure-window.d.ts.map +0 -1
- package/dist/sensor/iso-signal-chain.d.ts.map +0 -1
- package/dist/sensor/local-exposure-binding.d.ts.map +0 -1
- package/dist/sensor/optical-stack.d.ts.map +0 -1
- package/dist/sensor/photon-energy.d.ts.map +0 -1
- package/dist/sensor/physical-charge-capacity.d.ts.map +0 -1
- package/dist/sensor/pixel-pitch.d.ts.map +0 -1
- package/dist/sensor/radiometry-readiness.d.ts.map +0 -1
- package/dist/sensor/raw-readout.d.ts.map +0 -1
- package/dist/sensor/raw-reconstruction.d.ts.map +0 -1
- package/dist/sensor/readout-exposure-linkage.d.ts.map +0 -1
- package/dist/sensor/readout-timing.d.ts.map +0 -1
- package/dist/sensor/response-application-compatibility.d.ts.map +0 -1
- package/dist/sensor/response-operating-range.d.ts.map +0 -1
- package/dist/sensor/responsivity-photocurrent.d.ts.map +0 -1
- package/dist/sensor/sampling-aperture.d.ts.map +0 -1
- package/dist/sensor/scene-eqe-temporal-exposure.d.ts.map +0 -1
- package/dist/sensor/sensor-geometry.d.ts.map +0 -1
- package/dist/sensor/signal-noise.d.ts.map +0 -1
- package/dist/sensor/spatial-sample-reduction.d.ts.map +0 -1
- package/dist/sensor/spatial-sampling-quadrature.d.ts.map +0 -1
- package/dist/sensor/spatio-spectral-reduction.d.ts.map +0 -1
- package/dist/sensor/spectral-coverage.d.ts.map +0 -1
- package/dist/sensor/spectral-quadrature.d.ts.map +0 -1
- package/dist/sensor/spectral-response.d.ts.map +0 -1
- package/dist/sensor/temporal-eqe-sum.d.ts.map +0 -1
- package/dist/sensor/temporal-photo-signal.d.ts.map +0 -1
- package/dist/sensor/temporal-sample-binding.d.ts.map +0 -1
- package/dist/simulation/poc-simulation.d.ts.map +0 -1
- package/dist/stabilization/camera-shake.d.ts.map +0 -1
- package/dist/stabilization/system.d.ts.map +0 -1
- package/docs/API_STYLE.md +0 -235
- package/docs/ARCHITECTURE.md +0 -356
- package/docs/AUTOMATION_COORDINATION.md +0 -190
- package/docs/CAPTURE_COLOR.md +0 -25
- package/docs/CAPTURE_CORRECTED_SDR.md +0 -25
- package/docs/CAPTURE_EXPORT_METADATA.md +0 -27
- package/docs/CAPTURE_SDR.md +0 -22
- package/docs/DEVELOPERS.md +0 -68
- package/docs/DIGITAL_OPTICS_FOUNDATION.md +0 -69
- package/docs/ENVIRONMENT_RAW_CAPTURE.md +0 -208
- package/docs/EXPORT_ACCEPTANCE.md +0 -133
- package/docs/GENERIC_TIER_PRESETS.md +0 -269
- package/docs/GEOMETRIC_PREPARATION_REUSE.md +0 -141
- package/docs/IMAGE_FORMATION.md +0 -247
- package/docs/LINEAR_CAPTURE_ENCODING.md +0 -25
- package/docs/MOTION_AND_SIGNAL.md +0 -250
- package/docs/NATIVE_CAPTURE_SDR.md +0 -70
- package/docs/NATIVE_CAPTURE_SDR_REVIEW.md +0 -37
- package/docs/NATIVE_CAPTURE_SDR_VALIDATION.md +0 -34
- package/docs/NATIVE_RAW_AND_PRINT.md +0 -47
- package/docs/NUMERICAL_CORRECTNESS.md +0 -191
- package/docs/PERFORMANCE_BASELINE.md +0 -56
- package/docs/PHOTOGRAPHIC_EXPORT.md +0 -206
- package/docs/PHYSICS_FOUNDATION.md +0 -426
- package/docs/POC_API.md +0 -278
- package/docs/POC_PROJECTION_PLATFORM_REFERENCE.md +0 -12
- package/docs/POC_PROJECTION_REUSE.md +0 -124
- package/docs/PRINT_195_196_REVIEW.md +0 -93
- package/docs/PRINT_196_ENGINE_ACCEPTANCE.md +0 -45
- package/docs/PRINT_CONTRAST_REFERENCE.md +0 -43
- package/docs/PRINT_DETAIL_ASSESSMENT.md +0 -81
- package/docs/PRINT_DETAIL_JPEG_EVIDENCE.md +0 -36
- package/docs/PRINT_DETAIL_SDR_EVIDENCE.md +0 -29
- package/docs/PRINT_DETAIL_VALIDATION.md +0 -36
- package/docs/PRINT_PLANNING.md +0 -75
- package/docs/PRINT_REGION_STATISTICS.md +0 -38
- package/docs/PROCESSED_OUTPUT.md +0 -157
- package/docs/PRODUCTION_COMPOSITION.md +0 -373
- package/docs/PRODUCTION_ENVIRONMENT_CAPTURE.md +0 -131
- package/docs/PROVENANCE.md +0 -115
- package/docs/PSF_FOUNDATION.md +0 -165
- package/docs/RAW_FRAME_ENVELOPE.md +0 -56
- package/docs/RAW_FRAME_RECONSTRUCTION.md +0 -30
- package/docs/RELEASE_1_0.md +0 -66
- package/docs/RELEASE_1_0_1.md +0 -61
- package/docs/RELEASE_1_1_0.md +0 -25
- package/docs/RELEASE_1_2_0.md +0 -51
- package/docs/RELEASE_1_3_0.md +0 -15
- package/docs/RELEASE_1_4_0.md +0 -23
- package/docs/RELEASE_AUDIT.md +0 -39
- package/docs/SCENE_RADIANCE_AND_ILLUMINATION.md +0 -298
- package/docs/SCENE_SENSOR_QUADRATURE.md +0 -98
- package/docs/SCENE_SENSOR_TEMPORAL_EXPOSURE.md +0 -86
- package/docs/SCIENTIFIC_ASSURANCE.md +0 -280
- package/docs/SCIENTIFIC_CONFORMANCE.md +0 -83
- package/docs/SDR_RENDERING.md +0 -33
- package/docs/SENSOR_APERTURE_RAYS.md +0 -23
- package/docs/SENSOR_ENVIRONMENT_QUERY.md +0 -86
- package/docs/SENSOR_EQE_LOCAL_EXPOSURE.md +0 -104
- package/docs/SENSOR_EQE_TEMPORAL_EXPOSURE.md +0 -74
- package/docs/SENSOR_PSF_QUADRATURE.md +0 -90
- package/docs/SENSOR_RAW_FRAME.md +0 -20
- package/docs/SENSOR_RAW_PRODUCER.md +0 -77
- package/docs/SIGNAL_CONFORMANCE.md +0 -23
- package/docs/SIMULATED_CAPTURE.md +0 -65
- package/docs/STABILIZATION.md +0 -234
- package/docs/TEMPORAL_PHOTO_RAW.md +0 -83
- package/docs/TIER_ACCEPTANCE.md +0 -129
- package/docs/TIER_PRESET_ACCEPTANCE.md +0 -59
- package/docs/V1_COMPOSITION_MAP.md +0 -123
- package/docs/V1_HELPER_REUSE_REVIEW.md +0 -60
- package/docs/V1_PERFORMANCE_DISPOSITION.md +0 -88
- package/docs/benchmarks/2026-10-01-main-baseline.json +0 -694
- package/docs/benchmarks/2026-10-02-geometric-preparation-reuse.json +0 -2190
- package/docs/benchmarks/2026-10-02-poc-projection-reuse.json +0 -2423
- package/docs/benchmarks/2026-10-02-v1-environment-gc-profile.json +0 -210
- package/docs/benchmarks/2026-10-02-v1-environment-ordinary.json +0 -187
- package/docs/benchmarks/2026-10-02-v1-geometry-gc-profile.json +0 -756
- package/docs/benchmarks/2026-10-02-v1-geometry-ordinary-1.json +0 -711
- package/docs/benchmarks/2026-10-02-v1-geometry-ordinary-2.json +0 -711
- package/docs/benchmarks/2026-10-02-v1-poc-gc-profile.json +0 -885
- package/docs/benchmarks/2026-10-02-v1-poc-ordinary-1.json +0 -868
- package/docs/benchmarks/2026-10-02-v1-poc-ordinary-2.json +0 -868
- package/docs/licenses/castleCSF-MIT.txt +0 -21
- package/docs/validation/documentation-fragments.json +0 -212
- package/docs/validation/native-capture-sdr-darwin-arm64-node26-review.jsonl +0 -4
- package/docs/validation/native-capture-sdr-darwin-arm64.jsonl +0 -3
- package/docs/validation/native-raw-print-2026-10-04/fractional-asymmetric-crop.jpg +0 -0
- package/docs/validation/native-raw-print-2026-10-04/gray-ramp.jpg +0 -0
- package/docs/validation/native-raw-print-2026-10-04/linear-area-checker.jpg +0 -0
- package/docs/validation/native-raw-print-2026-10-04/manifest.json +0 -218
- package/docs/validation/native-raw-print-2026-10-04/megapixel-native.jpg +0 -0
- package/docs/validation/native-raw-print-2026-10-04/native-color.jpg +0 -0
- package/docs/validation/native-raw-print-2026-10-04/photivra-native-full-megapixel-validation.json +0 -9
- package/docs/validation/native-raw-print-2026-10-04/photivra-native-full-megapixel.json +0 -29
- package/docs/validation/native-raw-print-2026-10-04/photivra-native-full-megapixel.json.codes.u16le.gz +0 -0
- package/docs/validation/native-raw-print-2026-10-04/photivra-native-full-megapixel.json.jpg +0 -0
- package/docs/validation/native-raw-print-2026-10-04/photivra-native-full-megapixel.json.rgb.gz +0 -0
- package/docs/validation/native-raw-print-2026-10-04/srgb.icc +0 -0
- package/docs/validation/native-raw-print-2026-10-04/validation.json +0 -41
- package/docs/validation/print-196-candidate-capabilities.json +0 -28
- package/docs/validation/print-196-candidate-evidence.json +0 -356
- package/docs/validation/print-196-engine-acceptance.json +0 -81
- package/docs/validation/print-detail-capabilities.json +0 -103
- package/docs/validation/print-detail-jpeg-evidence.json +0 -116
- package/docs/validation/print-detail-sdr-evidence.json +0 -81
- package/docs/validation/release-audit-inventory.json +0 -1306
- package/docs/validation/tier-acceptance-report-v1.json +0 -2538
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
/**
|
|
3
|
+
* Procedural test charts for the capture facade, written for this engine. Every chart is a flat,
|
|
4
|
+
* Lambertian (matte) reflectance pattern, defined by formulas in normalized frame coordinates. No
|
|
5
|
+
* third-party chart data (for example ColorChecker reflectances) is bundled. Coloured patches use
|
|
6
|
+
* spectra that the caller supplies.
|
|
7
|
+
*
|
|
8
|
+
* Frame coordinates: `u` runs from -1 (left edge of the framed chart) to +1 (right edge); `v` points up
|
|
9
|
+
* and has the same scale, so it runs from -aspect to +aspect where aspect = height/width of the frame.
|
|
10
|
+
* The facade places the chart perpendicular to the optical axis at the subject distance and sizes it so
|
|
11
|
+
* that this rectangle exactly fills the active capture (see `SimulateCaptureResult.assumptions`).
|
|
12
|
+
*
|
|
13
|
+
* The slanted edge follows the geometry described by P. D. Burns, "Slanted-Edge MTF for Digital Camera
|
|
14
|
+
* and Scanner Analysis", IS&T PICS 2000 (free from imaging.org; also ISO 12233). It is a near-vertical
|
|
15
|
+
* edge rotated by a few degrees (5 degrees by default), with a 4:1 light/dark reflectance ratio by
|
|
16
|
+
* default. This is only a geometric description. No measured chart or ISO test procedure is copied.
|
|
17
|
+
* @see docs/QUICK_START.md for the chart catalogue and their analytic definitions.
|
|
18
|
+
*/
|
|
19
|
+
import { InvalidConfigurationError } from "../core/configuration-error.js";
|
|
20
|
+
import { prepareColorimetricSpectrum } from "../color/color-matching-functions.js";
|
|
21
|
+
import { requireInputObject, requireInputKeys } from "../core/record-validation.js";
|
|
22
|
+
export const CHART_SCENE_PRESETS = Object.freeze(["uniform", "slanted-edge", "siemens-star",
|
|
23
|
+
"step-wedge", "grey-ramp", "checkerboard", "point-grid", "patches"]);
|
|
24
|
+
/** Engine-chosen chart parameters, each reported when the caller omitted it. */
|
|
25
|
+
export const CHART_SCENE_DEFAULTS = Object.freeze({
|
|
26
|
+
uniform: Object.freeze({ reflectance: 0.18 }),
|
|
27
|
+
"slanted-edge": Object.freeze({ angleDegrees: 5, darkReflectance: 0.15, lightReflectance: 0.6 }),
|
|
28
|
+
"siemens-star": Object.freeze({ cycles: 36, radiusFraction: 0.9, darkReflectance: 0.05, lightReflectance: 0.8, backgroundReflectance: 0.18 }),
|
|
29
|
+
"step-wedge": Object.freeze({ steps: 11, minimumReflectance: 0.03, maximumReflectance: 0.9, spacing: "equal-density" }),
|
|
30
|
+
"grey-ramp": Object.freeze({ minimumReflectance: 0.03, maximumReflectance: 0.9 }),
|
|
31
|
+
checkerboard: Object.freeze({ squaresAcross: 8, darkReflectance: 0.05, lightReflectance: 0.8 }),
|
|
32
|
+
"point-grid": Object.freeze({ columns: 5, rows: 3, radius: 0.01, pointReflectance: 0.9, backgroundReflectance: 0.02 }),
|
|
33
|
+
patches: Object.freeze({ gapFraction: 0.1, backgroundReflectance: 0.18 })
|
|
34
|
+
});
|
|
35
|
+
function reflectance(value, name) {
|
|
36
|
+
if (typeof value !== "number" || !Number.isFinite(value) || value < 0 || value > 1)
|
|
37
|
+
throw new InvalidConfigurationError(name + " must be a reflectance in [0, 1].");
|
|
38
|
+
return value;
|
|
39
|
+
}
|
|
40
|
+
function integerIn(value, name, minimum, maximum) {
|
|
41
|
+
if (typeof value !== "number" || !Number.isSafeInteger(value) || value < minimum || value > maximum)
|
|
42
|
+
throw new InvalidConfigurationError(name + " must be an integer from " + minimum + " to " + maximum + ".");
|
|
43
|
+
return value;
|
|
44
|
+
}
|
|
45
|
+
function finiteIn(value, name, minimum, maximum, open = false) {
|
|
46
|
+
if (typeof value !== "number" || !Number.isFinite(value) || value < minimum || value > maximum || (open && (value === minimum || value === maximum)))
|
|
47
|
+
throw new InvalidConfigurationError(name + " is outside its supported range.");
|
|
48
|
+
return value;
|
|
49
|
+
}
|
|
50
|
+
/** Wavelength range every chart spectrum must cover (the facade's sensor quadrature range). */
|
|
51
|
+
export const CHART_SPECTRAL_RANGE_NANOMETERS = Object.freeze({ minimum: 380, maximum: 780 });
|
|
52
|
+
function material(value, name) {
|
|
53
|
+
if (typeof value === "number")
|
|
54
|
+
return { kind: "neutral", reflectance: reflectance(value, name) };
|
|
55
|
+
let spectrum;
|
|
56
|
+
try {
|
|
57
|
+
spectrum = prepareColorimetricSpectrum(value, name);
|
|
58
|
+
}
|
|
59
|
+
catch (error) {
|
|
60
|
+
throw new InvalidConfigurationError(name + " must be a neutral reflectance or a valid reflectance spectrum: " + (error instanceof Error ? error.message : "invalid"));
|
|
61
|
+
}
|
|
62
|
+
const range = spectrum.wavelengthRangeNanometers;
|
|
63
|
+
if (range.minimum > CHART_SPECTRAL_RANGE_NANOMETERS.minimum || range.maximum < CHART_SPECTRAL_RANGE_NANOMETERS.maximum)
|
|
64
|
+
throw new InvalidConfigurationError(name + " must cover 380-780 nm.");
|
|
65
|
+
for (let nm = CHART_SPECTRAL_RANGE_NANOMETERS.minimum; nm <= CHART_SPECTRAL_RANGE_NANOMETERS.maximum; nm += 5)
|
|
66
|
+
reflectance(spectrum.evaluate(nm), name + " values");
|
|
67
|
+
return { kind: "spectrum", spectrum };
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Validates a chart description and resolves every default. `aspect` is the frame height/width. Unknown
|
|
71
|
+
* fields are rejected so that a mistyped parameter never silently falls back to a default.
|
|
72
|
+
*/
|
|
73
|
+
export function resolveChartScene(input) {
|
|
74
|
+
requireInputObject(input, "resolveChartScene input");
|
|
75
|
+
for (const key of Object.keys(input))
|
|
76
|
+
if (key !== "scene" && key !== "aspect")
|
|
77
|
+
throw new InvalidConfigurationError("resolveChartScene input has unknown field \"" + key + "\".");
|
|
78
|
+
const { scene, aspect } = input;
|
|
79
|
+
requireInputObject(scene, "chart scene");
|
|
80
|
+
if (typeof aspect !== "number" || !Number.isFinite(aspect) || aspect <= 0)
|
|
81
|
+
throw new InvalidConfigurationError("Chart aspect must be positive.");
|
|
82
|
+
const preset = scene.preset;
|
|
83
|
+
if (typeof preset !== "string" || !CHART_SCENE_PRESETS.includes(preset))
|
|
84
|
+
throw new InvalidConfigurationError("Unknown chart preset.");
|
|
85
|
+
const record = scene;
|
|
86
|
+
const defaults = CHART_SCENE_DEFAULTS[preset];
|
|
87
|
+
const allowed = ["preset", ...Object.keys(defaults), ...(preset === "patches" ? ["patches", "columns"] : [])];
|
|
88
|
+
for (const key of Object.keys(record))
|
|
89
|
+
if (!allowed.includes(key))
|
|
90
|
+
throw new InvalidConfigurationError("Unknown chart parameter: " + key + ".");
|
|
91
|
+
const defaulted = [];
|
|
92
|
+
const get = (key) => { if (record[key] === undefined) {
|
|
93
|
+
if (key in defaults)
|
|
94
|
+
defaulted.push(key);
|
|
95
|
+
return defaults[key];
|
|
96
|
+
} return record[key]; };
|
|
97
|
+
const neutral = (key) => reflectance(get(key), key);
|
|
98
|
+
const done = (parameters, materials, materialAt) => Object.freeze({ preset: preset, parameters: Object.freeze(parameters), defaultedParameters: Object.freeze(defaulted), aspect, materials: Object.freeze(materials), materialAt,
|
|
99
|
+
reflectanceAt(u, v, nm) {
|
|
100
|
+
const m = materials[materialAt(u, v)];
|
|
101
|
+
if (m.kind === "neutral")
|
|
102
|
+
return m.reflectance;
|
|
103
|
+
const value = m.spectrum.evaluate(nm);
|
|
104
|
+
if (!(value >= 0 && value <= 1))
|
|
105
|
+
throw new InvalidConfigurationError("Chart reflectance spectrum left [0, 1].");
|
|
106
|
+
return value;
|
|
107
|
+
} });
|
|
108
|
+
switch (preset) {
|
|
109
|
+
case "uniform": {
|
|
110
|
+
const raw = get("reflectance"), m = material(raw, "reflectance");
|
|
111
|
+
return done({ reflectance: typeof raw === "number" ? raw : "caller-spectrum" }, [m], () => 0);
|
|
112
|
+
}
|
|
113
|
+
case "slanted-edge": {
|
|
114
|
+
const angle = finiteIn(get("angleDegrees"), "angleDegrees", -45, 45, true), dark = neutral("darkReflectance"), light = neutral("lightReflectance");
|
|
115
|
+
const t = angle * Math.PI / 180, c = Math.cos(t), s = Math.sin(t);
|
|
116
|
+
// Edge through the frame centre along (sin t, cos t); the light side is to the right.
|
|
117
|
+
return done({ angleDegrees: angle, darkReflectance: dark, lightReflectance: light }, [{ kind: "neutral", reflectance: dark }, { kind: "neutral", reflectance: light }], (u, v) => (u * c - v * s >= 0 ? 1 : 0));
|
|
118
|
+
}
|
|
119
|
+
case "siemens-star": {
|
|
120
|
+
const cycles = integerIn(get("cycles"), "cycles", 2, 360), radius = finiteIn(get("radiusFraction"), "radiusFraction", 0, 1, false);
|
|
121
|
+
if (radius === 0)
|
|
122
|
+
throw new InvalidConfigurationError("radiusFraction must be positive.");
|
|
123
|
+
const dark = neutral("darkReflectance"), light = neutral("lightReflectance"), background = neutral("backgroundReflectance"), r = radius * aspect;
|
|
124
|
+
return done({ cycles, radiusFraction: radius, darkReflectance: dark, lightReflectance: light, backgroundReflectance: background }, [{ kind: "neutral", reflectance: dark }, { kind: "neutral", reflectance: light }, { kind: "neutral", reflectance: background }], (u, v) => {
|
|
125
|
+
if (u * u + v * v > r * r)
|
|
126
|
+
return 2;
|
|
127
|
+
const phase = Math.atan2(v, u) / (2 * Math.PI) + 0.5; // [0, 1]
|
|
128
|
+
return Math.floor(phase * 2 * cycles) % 2 === 0 ? 1 : 0;
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
case "step-wedge": {
|
|
132
|
+
const steps = integerIn(get("steps"), "steps", 2, 64), lo = neutral("minimumReflectance"), hi = neutral("maximumReflectance"), spacing = get("spacing");
|
|
133
|
+
if (spacing !== "equal-density" && spacing !== "linear")
|
|
134
|
+
throw new InvalidConfigurationError("spacing must be equal-density or linear.");
|
|
135
|
+
if (!(hi > lo) || (spacing === "equal-density" && lo <= 0))
|
|
136
|
+
throw new InvalidConfigurationError("Step wedge needs 0 < minimum < maximum reflectance.");
|
|
137
|
+
const values = calculateStepWedgeReflectances({ steps, minimumReflectance: lo, maximumReflectance: hi, spacing });
|
|
138
|
+
return done({ steps, minimumReflectance: lo, maximumReflectance: hi, spacing, stepReflectances: values }, values.map((reflectanceValue) => ({ kind: "neutral", reflectance: reflectanceValue })), (u) => Math.min(steps - 1, Math.max(0, Math.floor((u + 1) / 2 * steps))));
|
|
139
|
+
}
|
|
140
|
+
case "grey-ramp": {
|
|
141
|
+
const lo = neutral("minimumReflectance"), hi = neutral("maximumReflectance");
|
|
142
|
+
if (!(hi > lo))
|
|
143
|
+
throw new InvalidConfigurationError("Grey ramp needs minimum < maximum reflectance.");
|
|
144
|
+
// A continuous ramp is stored as 1024 neutral levels. The step size (< 0.1 % of the range) is far below sensor noise.
|
|
145
|
+
const levels = 1024, materials = Array.from({ length: levels }, (_, i) => ({ kind: "neutral", reflectance: lo + (hi - lo) * (i + 0.5) / levels }));
|
|
146
|
+
return done({ minimumReflectance: lo, maximumReflectance: hi, representation: "1024 equal neutral levels" }, materials, (u) => Math.min(levels - 1, Math.max(0, Math.floor((u + 1) / 2 * levels))));
|
|
147
|
+
}
|
|
148
|
+
case "checkerboard": {
|
|
149
|
+
const across = integerIn(get("squaresAcross"), "squaresAcross", 2, 256), dark = neutral("darkReflectance"), light = neutral("lightReflectance"), size = 2 / across;
|
|
150
|
+
return done({ squaresAcross: across, darkReflectance: dark, lightReflectance: light }, [{ kind: "neutral", reflectance: dark }, { kind: "neutral", reflectance: light }], (u, v) => ((Math.floor((u + 1) / size) + Math.floor((aspect - v) / size)) % 2 === 0 ? 1 : 0));
|
|
151
|
+
}
|
|
152
|
+
case "point-grid": {
|
|
153
|
+
const columns = integerIn(get("columns"), "columns", 1, 256), rows = integerIn(get("rows"), "rows", 1, 256);
|
|
154
|
+
const radius = finiteIn(get("radius"), "radius", 0, 1, true), point = neutral("pointReflectance"), background = neutral("backgroundReflectance");
|
|
155
|
+
const centers = calculatePointGridCenters({ columns, rows, aspect });
|
|
156
|
+
const cellW = 2 / columns, cellH = 2 * aspect / rows;
|
|
157
|
+
return done({ columns, rows, radius, pointReflectance: point, backgroundReflectance: background }, [{ kind: "neutral", reflectance: background }, { kind: "neutral", reflectance: point }], (u, v) => {
|
|
158
|
+
const i = Math.min(columns - 1, Math.max(0, Math.floor((u + 1) / cellW))), j = Math.min(rows - 1, Math.max(0, Math.floor((aspect - v) / cellH)));
|
|
159
|
+
const c = centers[j * columns + i];
|
|
160
|
+
return (u - c.u) ** 2 + (v - c.v) ** 2 <= radius * radius ? 1 : 0;
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
case "patches": {
|
|
164
|
+
const list = record.patches;
|
|
165
|
+
if (!Array.isArray(list) || list.length < 1 || list.length > 1024)
|
|
166
|
+
throw new InvalidConfigurationError("patches must list 1 to 1024 caller reflectances.");
|
|
167
|
+
const ids = new Set();
|
|
168
|
+
const materials = [];
|
|
169
|
+
for (const [index, patch] of list.entries()) {
|
|
170
|
+
requireInputObject(patch, "patches[" + index + "]");
|
|
171
|
+
const p = patch;
|
|
172
|
+
for (const key of Object.keys(p))
|
|
173
|
+
if (key !== "patchId" && key !== "reflectance")
|
|
174
|
+
throw new InvalidConfigurationError("Unknown patch field: " + key + ".");
|
|
175
|
+
if (typeof p.patchId !== "string" || p.patchId.trim() === "" || ids.has(p.patchId))
|
|
176
|
+
throw new InvalidConfigurationError("Each patch needs a unique non-empty patchId.");
|
|
177
|
+
ids.add(p.patchId);
|
|
178
|
+
materials.push(material(p.reflectance, "patches[" + index + "].reflectance"));
|
|
179
|
+
}
|
|
180
|
+
const columnsRaw = record.columns === undefined ? Math.ceil(Math.sqrt(list.length)) : record.columns;
|
|
181
|
+
if (record.columns === undefined)
|
|
182
|
+
defaulted.push("columns");
|
|
183
|
+
const columns = integerIn(columnsRaw, "columns", 1, list.length), rows = Math.ceil(list.length / columns);
|
|
184
|
+
const gap = finiteIn(get("gapFraction"), "gapFraction", 0, 0.5), background = neutral("backgroundReflectance");
|
|
185
|
+
if (gap >= 0.5)
|
|
186
|
+
throw new InvalidConfigurationError("gapFraction must be below 0.5.");
|
|
187
|
+
const backgroundIndex = materials.length;
|
|
188
|
+
materials.push({ kind: "neutral", reflectance: background });
|
|
189
|
+
const cellW = 2 / columns, cellH = 2 * aspect / rows;
|
|
190
|
+
return done({ patchIds: list.map((p) => p.patchId), columns, rows, gapFraction: gap, backgroundReflectance: background }, materials, (u, v) => {
|
|
191
|
+
const fx = (u + 1) / cellW, fy = (aspect - v) / cellH, i = Math.floor(fx), j = Math.floor(fy);
|
|
192
|
+
if (i < 0 || j < 0 || i >= columns || j >= rows)
|
|
193
|
+
return backgroundIndex;
|
|
194
|
+
const index = j * columns + i, x = fx - i, y = fy - j;
|
|
195
|
+
if (index >= list.length || x < gap / 2 || x > 1 - gap / 2 || y < gap / 2 || y > 1 - gap / 2)
|
|
196
|
+
return backgroundIndex;
|
|
197
|
+
return index;
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Step reflectances of a step wedge. `equal-density` spaces optical density D = -log10(R) evenly, which
|
|
204
|
+
* gives geometric reflectance steps, as on a photographic step tablet. `linear` spaces reflectance evenly.
|
|
205
|
+
*/
|
|
206
|
+
export function calculateStepWedgeReflectances(input) {
|
|
207
|
+
requireInputKeys(input, "calculateStepWedgeReflectances", ["steps", "minimumReflectance", "maximumReflectance", "spacing"]);
|
|
208
|
+
const steps = integerIn(input.steps, "steps", 2, 64), lo = reflectance(input.minimumReflectance, "minimumReflectance"), hi = reflectance(input.maximumReflectance, "maximumReflectance");
|
|
209
|
+
if (input.spacing !== "equal-density" && input.spacing !== "linear")
|
|
210
|
+
throw new InvalidConfigurationError("spacing must be equal-density or linear.");
|
|
211
|
+
if (!(hi > lo) || (input.spacing === "equal-density" && lo <= 0))
|
|
212
|
+
throw new InvalidConfigurationError("Step wedge needs 0 < minimum < maximum reflectance.");
|
|
213
|
+
return Array.from({ length: steps }, (_, k) => {
|
|
214
|
+
if (k === steps - 1)
|
|
215
|
+
return hi;
|
|
216
|
+
const t = k / (steps - 1);
|
|
217
|
+
return input.spacing === "linear" ? lo + (hi - lo) * t : lo * (hi / lo) ** t;
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
/** Centres (frame units) of a point grid: one disk centred in each of columns × rows equal cells, row-major from the top-left. */
|
|
221
|
+
export function calculatePointGridCenters(input) {
|
|
222
|
+
requireInputKeys(input, "calculatePointGridCenters", ["columns", "rows", "aspect"]);
|
|
223
|
+
const columns = integerIn(input.columns, "columns", 1, 256), rows = integerIn(input.rows, "rows", 1, 256);
|
|
224
|
+
if (typeof input.aspect !== "number" || !Number.isFinite(input.aspect) || input.aspect <= 0)
|
|
225
|
+
throw new InvalidConfigurationError("aspect must be positive.");
|
|
226
|
+
const out = [];
|
|
227
|
+
for (let j = 0; j < rows; j++)
|
|
228
|
+
for (let i = 0; i < columns; i++)
|
|
229
|
+
out.push({ u: -1 + (i + 0.5) * 2 / columns, v: input.aspect - (j + 0.5) * 2 * input.aspect / rows });
|
|
230
|
+
return out;
|
|
231
|
+
}
|
|
232
|
+
//# sourceMappingURL=chart-scenes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chart-scenes.js","sourceRoot":"","sources":["../../src/facade/chart-scenes.ts"],"names":[],"mappings":"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","sourcesContent":["// SPDX-License-Identifier: Apache-2.0\n\n/**\n * Procedural test charts for the capture facade, written for this engine. Every chart is a flat,\n * Lambertian (matte) reflectance pattern, defined by formulas in normalized frame coordinates. No\n * third-party chart data (for example ColorChecker reflectances) is bundled. Coloured patches use\n * spectra that the caller supplies.\n *\n * Frame coordinates: `u` runs from -1 (left edge of the framed chart) to +1 (right edge); `v` points up\n * and has the same scale, so it runs from -aspect to +aspect where aspect = height/width of the frame.\n * The facade places the chart perpendicular to the optical axis at the subject distance and sizes it so\n * that this rectangle exactly fills the active capture (see `SimulateCaptureResult.assumptions`).\n *\n * The slanted edge follows the geometry described by P. D. Burns, \"Slanted-Edge MTF for Digital Camera\n * and Scanner Analysis\", IS&T PICS 2000 (free from imaging.org; also ISO 12233). It is a near-vertical\n * edge rotated by a few degrees (5 degrees by default), with a 4:1 light/dark reflectance ratio by\n * default. This is only a geometric description. No measured chart or ISO test procedure is copied.\n * @see docs/QUICK_START.md for the chart catalogue and their analytic definitions.\n */\n\nimport { InvalidConfigurationError } from \"../core/configuration-error.js\";\nimport { prepareColorimetricSpectrum, type ColorimetricSpectrum, type PreparedColorimetricSpectrum } from \"../color/color-matching-functions.js\";\nimport { requireInputObject, requireInputKeys } from \"../core/record-validation.js\";\n\n/** A neutral (spectrally flat) reflectance in [0, 1], or a caller reflectance spectrum (values in [0, 1]). */\nexport type ChartReflectance = number | ColorimetricSpectrum;\n\nexport interface UniformChartScene { preset: \"uniform\"; reflectance?: ChartReflectance }\nexport interface SlantedEdgeChartScene {\n preset: \"slanted-edge\";\n /** Clockwise tilt of the edge from vertical, degrees, in (-45, 45). Default 5. */\n angleDegrees?: number;\n /** Left (dark) side reflectance. Default 0.15. */\n darkReflectance?: number;\n /** Right (light) side reflectance. Default 0.6 (4:1 with the default dark side). */\n lightReflectance?: number;\n}\nexport interface SiemensStarChartScene {\n preset: \"siemens-star\";\n /** Light/dark sector pairs around the star, 2..360. Default 36. */\n cycles?: number;\n /** Star radius as a fraction of the frame half-height, (0, 1]. Default 0.9. */\n radiusFraction?: number;\n darkReflectance?: number;\n lightReflectance?: number;\n /** Reflectance outside the star. Default 0.18. */\n backgroundReflectance?: number;\n}\nexport interface StepWedgeChartScene {\n preset: \"step-wedge\";\n /** Number of equal-width vertical steps from left (minimum) to right (maximum), 2..64. Default 11. */\n steps?: number;\n minimumReflectance?: number;\n maximumReflectance?: number;\n /** `equal-density` (geometric, default) or `linear` reflectance spacing. */\n spacing?: \"equal-density\" | \"linear\";\n}\nexport interface GreyRampChartScene {\n preset: \"grey-ramp\";\n /** Continuous ramp, linear in reflectance from left (minimum) to right (maximum). */\n minimumReflectance?: number;\n maximumReflectance?: number;\n}\nexport interface CheckerboardChartScene {\n preset: \"checkerboard\";\n /** Squares across the frame width, 2..256. Default 8. */\n squaresAcross?: number;\n darkReflectance?: number;\n lightReflectance?: number;\n}\nexport interface PointGridChartScene {\n preset: \"point-grid\";\n /** Grid columns and rows of small disks centred in equal cells. Defaults 5 × 3. */\n columns?: number;\n rows?: number;\n /** Disk radius in frame units (fraction of the frame half-width). Default 0.01. */\n radius?: number;\n pointReflectance?: number;\n backgroundReflectance?: number;\n}\nexport interface PatchChartScene {\n preset: \"patches\";\n /** Caller reflectance per patch, row-major; the facade bundles no colour-chart data. 1..1024 patches. */\n patches: readonly { patchId: string; reflectance: ChartReflectance }[];\n /** Patches per row. Default ceil(sqrt(patch count)). */\n columns?: number;\n /** Gap between patches as a fraction of the cell size, [0, 0.5). Default 0.1. */\n gapFraction?: number;\n backgroundReflectance?: number;\n}\nexport type ChartScene = UniformChartScene | SlantedEdgeChartScene | SiemensStarChartScene | StepWedgeChartScene |\n GreyRampChartScene | CheckerboardChartScene | PointGridChartScene | PatchChartScene;\nexport type ChartScenePresetId = ChartScene[\"preset\"];\nexport const CHART_SCENE_PRESETS: readonly ChartScenePresetId[] = Object.freeze([\"uniform\", \"slanted-edge\", \"siemens-star\",\n \"step-wedge\", \"grey-ramp\", \"checkerboard\", \"point-grid\", \"patches\"] as const);\n\n/** Engine-chosen chart parameters, each reported when the caller omitted it. */\nexport const CHART_SCENE_DEFAULTS = Object.freeze({\n uniform: Object.freeze({ reflectance: 0.18 }),\n \"slanted-edge\": Object.freeze({ angleDegrees: 5, darkReflectance: 0.15, lightReflectance: 0.6 }),\n \"siemens-star\": Object.freeze({ cycles: 36, radiusFraction: 0.9, darkReflectance: 0.05, lightReflectance: 0.8, backgroundReflectance: 0.18 }),\n \"step-wedge\": Object.freeze({ steps: 11, minimumReflectance: 0.03, maximumReflectance: 0.9, spacing: \"equal-density\" as const }),\n \"grey-ramp\": Object.freeze({ minimumReflectance: 0.03, maximumReflectance: 0.9 }),\n checkerboard: Object.freeze({ squaresAcross: 8, darkReflectance: 0.05, lightReflectance: 0.8 }),\n \"point-grid\": Object.freeze({ columns: 5, rows: 3, radius: 0.01, pointReflectance: 0.9, backgroundReflectance: 0.02 }),\n patches: Object.freeze({ gapFraction: 0.1, backgroundReflectance: 0.18 })\n});\n\n/** A validated chart: every parameter resolved, plus which ones came from {@link CHART_SCENE_DEFAULTS}. */\nexport interface ResolvedChartScene {\n preset: ChartScenePresetId;\n /** Fully resolved parameters (spectra are reported as `\"caller-spectrum\"`). */\n parameters: Readonly<Record<string, unknown>>;\n /** Names of parameters filled from defaults. */\n defaultedParameters: readonly string[];\n /** Frame aspect (height / width) the chart was resolved for. */\n aspect: number;\n /**\n * Material index at a frame point (u right, v up). The index points into `materials`, starting at 0.\n * Points outside the framed rectangle still evaluate (the pattern continues as defined), so blur and\n * small framing differences stay well defined.\n */\n materialAt(u: number, v: number): number;\n /** Reflectance materials: a neutral number or a prepared caller spectrum. */\n materials: readonly ({ kind: \"neutral\"; reflectance: number } | { kind: \"spectrum\"; spectrum: PreparedColorimetricSpectrum })[];\n /** Reflectance in [0, 1] at a frame point and wavelength (nm). */\n reflectanceAt(u: number, v: number, wavelengthNanometers: number): number;\n}\n\nfunction reflectance(value: unknown, name: string): number {\n if (typeof value !== \"number\" || !Number.isFinite(value) || value < 0 || value > 1) throw new InvalidConfigurationError(name + \" must be a reflectance in [0, 1].\");\n return value;\n}\nfunction integerIn(value: unknown, name: string, minimum: number, maximum: number): number {\n if (typeof value !== \"number\" || !Number.isSafeInteger(value) || value < minimum || value > maximum) throw new InvalidConfigurationError(name + \" must be an integer from \" + minimum + \" to \" + maximum + \".\");\n return value;\n}\nfunction finiteIn(value: unknown, name: string, minimum: number, maximum: number, open = false): number {\n if (typeof value !== \"number\" || !Number.isFinite(value) || value < minimum || value > maximum || (open && (value === minimum || value === maximum)))\n throw new InvalidConfigurationError(name + \" is outside its supported range.\");\n return value;\n}\n/** Wavelength range every chart spectrum must cover (the facade's sensor quadrature range). */\nexport const CHART_SPECTRAL_RANGE_NANOMETERS = Object.freeze({ minimum: 380, maximum: 780 });\nfunction material(value: unknown, name: string): ResolvedChartScene[\"materials\"][number] {\n if (typeof value === \"number\") return { kind: \"neutral\", reflectance: reflectance(value, name) };\n let spectrum: PreparedColorimetricSpectrum;\n try { spectrum = prepareColorimetricSpectrum(value as ColorimetricSpectrum, name); } catch (error) {\n throw new InvalidConfigurationError(name + \" must be a neutral reflectance or a valid reflectance spectrum: \" + (error instanceof Error ? error.message : \"invalid\"));\n }\n const range = spectrum.wavelengthRangeNanometers;\n if (range.minimum > CHART_SPECTRAL_RANGE_NANOMETERS.minimum || range.maximum < CHART_SPECTRAL_RANGE_NANOMETERS.maximum)\n throw new InvalidConfigurationError(name + \" must cover 380-780 nm.\");\n for (let nm = CHART_SPECTRAL_RANGE_NANOMETERS.minimum; nm <= CHART_SPECTRAL_RANGE_NANOMETERS.maximum; nm += 5) reflectance(spectrum.evaluate(nm), name + \" values\");\n return { kind: \"spectrum\", spectrum };\n}\n\n/**\n * Validates a chart description and resolves every default. `aspect` is the frame height/width. Unknown\n * fields are rejected so that a mistyped parameter never silently falls back to a default.\n */\nexport function resolveChartScene(input: { scene: ChartScene; aspect: number }): ResolvedChartScene {\n requireInputObject(input, \"resolveChartScene input\");\n for (const key of Object.keys(input)) if (key !== \"scene\" && key !== \"aspect\") throw new InvalidConfigurationError(\"resolveChartScene input has unknown field \\\"\" + key + \"\\\".\");\n const { scene, aspect } = input;\n requireInputObject(scene, \"chart scene\");\n if (typeof aspect !== \"number\" || !Number.isFinite(aspect) || aspect <= 0) throw new InvalidConfigurationError(\"Chart aspect must be positive.\");\n const preset = (scene as { preset?: unknown }).preset;\n if (typeof preset !== \"string\" || !(CHART_SCENE_PRESETS as readonly string[]).includes(preset)) throw new InvalidConfigurationError(\"Unknown chart preset.\");\n const record = scene as unknown as Record<string, unknown>;\n const defaults = CHART_SCENE_DEFAULTS[preset as ChartScenePresetId] as Record<string, unknown>;\n const allowed = [\"preset\", ...Object.keys(defaults), ...(preset === \"patches\" ? [\"patches\", \"columns\"] : [])];\n for (const key of Object.keys(record)) if (!allowed.includes(key)) throw new InvalidConfigurationError(\"Unknown chart parameter: \" + key + \".\");\n const defaulted: string[] = [];\n const get = (key: string): unknown => { if (record[key] === undefined) { if (key in defaults) defaulted.push(key); return defaults[key]; } return record[key]; };\n const neutral = (key: string): number => reflectance(get(key), key);\n const done = (parameters: Record<string, unknown>, materials: ResolvedChartScene[\"materials\"], materialAt: (u: number, v: number) => number): ResolvedChartScene =>\n Object.freeze({ preset: preset as ChartScenePresetId, parameters: Object.freeze(parameters), defaultedParameters: Object.freeze(defaulted), aspect, materials: Object.freeze(materials), materialAt,\n reflectanceAt(u: number, v: number, nm: number): number {\n const m = materials[materialAt(u, v)]!;\n if (m.kind === \"neutral\") return m.reflectance;\n const value = m.spectrum.evaluate(nm);\n if (!(value >= 0 && value <= 1)) throw new InvalidConfigurationError(\"Chart reflectance spectrum left [0, 1].\");\n return value;\n } });\n switch (preset as ChartScenePresetId) {\n case \"uniform\": {\n const raw = get(\"reflectance\"), m = material(raw, \"reflectance\");\n return done({ reflectance: typeof raw === \"number\" ? raw : \"caller-spectrum\" }, [m], () => 0);\n }\n case \"slanted-edge\": {\n const angle = finiteIn(get(\"angleDegrees\"), \"angleDegrees\", -45, 45, true), dark = neutral(\"darkReflectance\"), light = neutral(\"lightReflectance\");\n const t = angle * Math.PI / 180, c = Math.cos(t), s = Math.sin(t);\n // Edge through the frame centre along (sin t, cos t); the light side is to the right.\n return done({ angleDegrees: angle, darkReflectance: dark, lightReflectance: light },\n [{ kind: \"neutral\", reflectance: dark }, { kind: \"neutral\", reflectance: light }], (u, v) => (u * c - v * s >= 0 ? 1 : 0));\n }\n case \"siemens-star\": {\n const cycles = integerIn(get(\"cycles\"), \"cycles\", 2, 360), radius = finiteIn(get(\"radiusFraction\"), \"radiusFraction\", 0, 1, false);\n if (radius === 0) throw new InvalidConfigurationError(\"radiusFraction must be positive.\");\n const dark = neutral(\"darkReflectance\"), light = neutral(\"lightReflectance\"), background = neutral(\"backgroundReflectance\"), r = radius * aspect;\n return done({ cycles, radiusFraction: radius, darkReflectance: dark, lightReflectance: light, backgroundReflectance: background },\n [{ kind: \"neutral\", reflectance: dark }, { kind: \"neutral\", reflectance: light }, { kind: \"neutral\", reflectance: background }], (u, v) => {\n if (u * u + v * v > r * r) return 2;\n const phase = Math.atan2(v, u) / (2 * Math.PI) + 0.5; // [0, 1]\n return Math.floor(phase * 2 * cycles) % 2 === 0 ? 1 : 0;\n });\n }\n case \"step-wedge\": {\n const steps = integerIn(get(\"steps\"), \"steps\", 2, 64), lo = neutral(\"minimumReflectance\"), hi = neutral(\"maximumReflectance\"), spacing = get(\"spacing\");\n if (spacing !== \"equal-density\" && spacing !== \"linear\") throw new InvalidConfigurationError(\"spacing must be equal-density or linear.\");\n if (!(hi > lo) || (spacing === \"equal-density\" && lo <= 0)) throw new InvalidConfigurationError(\"Step wedge needs 0 < minimum < maximum reflectance.\");\n const values = calculateStepWedgeReflectances({ steps, minimumReflectance: lo, maximumReflectance: hi, spacing });\n return done({ steps, minimumReflectance: lo, maximumReflectance: hi, spacing, stepReflectances: values },\n values.map((reflectanceValue) => ({ kind: \"neutral\" as const, reflectance: reflectanceValue })),\n (u) => Math.min(steps - 1, Math.max(0, Math.floor((u + 1) / 2 * steps))));\n }\n case \"grey-ramp\": {\n const lo = neutral(\"minimumReflectance\"), hi = neutral(\"maximumReflectance\");\n if (!(hi > lo)) throw new InvalidConfigurationError(\"Grey ramp needs minimum < maximum reflectance.\");\n // A continuous ramp is stored as 1024 neutral levels. The step size (< 0.1 % of the range) is far below sensor noise.\n const levels = 1024, materials = Array.from({ length: levels }, (_, i) => ({ kind: \"neutral\" as const, reflectance: lo + (hi - lo) * (i + 0.5) / levels }));\n return done({ minimumReflectance: lo, maximumReflectance: hi, representation: \"1024 equal neutral levels\" }, materials,\n (u) => Math.min(levels - 1, Math.max(0, Math.floor((u + 1) / 2 * levels))));\n }\n case \"checkerboard\": {\n const across = integerIn(get(\"squaresAcross\"), \"squaresAcross\", 2, 256), dark = neutral(\"darkReflectance\"), light = neutral(\"lightReflectance\"), size = 2 / across;\n return done({ squaresAcross: across, darkReflectance: dark, lightReflectance: light },\n [{ kind: \"neutral\", reflectance: dark }, { kind: \"neutral\", reflectance: light }],\n (u, v) => ((Math.floor((u + 1) / size) + Math.floor((aspect - v) / size)) % 2 === 0 ? 1 : 0));\n }\n case \"point-grid\": {\n const columns = integerIn(get(\"columns\"), \"columns\", 1, 256), rows = integerIn(get(\"rows\"), \"rows\", 1, 256);\n const radius = finiteIn(get(\"radius\"), \"radius\", 0, 1, true), point = neutral(\"pointReflectance\"), background = neutral(\"backgroundReflectance\");\n const centers = calculatePointGridCenters({ columns, rows, aspect });\n const cellW = 2 / columns, cellH = 2 * aspect / rows;\n return done({ columns, rows, radius, pointReflectance: point, backgroundReflectance: background },\n [{ kind: \"neutral\", reflectance: background }, { kind: \"neutral\", reflectance: point }], (u, v) => {\n const i = Math.min(columns - 1, Math.max(0, Math.floor((u + 1) / cellW))), j = Math.min(rows - 1, Math.max(0, Math.floor((aspect - v) / cellH)));\n const c = centers[j * columns + i]!;\n return (u - c.u) ** 2 + (v - c.v) ** 2 <= radius * radius ? 1 : 0;\n });\n }\n case \"patches\": {\n const list = record.patches;\n if (!Array.isArray(list) || list.length < 1 || list.length > 1024) throw new InvalidConfigurationError(\"patches must list 1 to 1024 caller reflectances.\");\n const ids = new Set<string>();\n const materials: ResolvedChartScene[\"materials\"][number][] = [];\n for (const [index, patch] of list.entries()) {\n requireInputObject(patch, \"patches[\" + index + \"]\");\n const p = patch as Record<string, unknown>;\n for (const key of Object.keys(p)) if (key !== \"patchId\" && key !== \"reflectance\") throw new InvalidConfigurationError(\"Unknown patch field: \" + key + \".\");\n if (typeof p.patchId !== \"string\" || p.patchId.trim() === \"\" || ids.has(p.patchId)) throw new InvalidConfigurationError(\"Each patch needs a unique non-empty patchId.\");\n ids.add(p.patchId);\n materials.push(material(p.reflectance, \"patches[\" + index + \"].reflectance\"));\n }\n const columnsRaw = record.columns === undefined ? Math.ceil(Math.sqrt(list.length)) : record.columns;\n if (record.columns === undefined) defaulted.push(\"columns\");\n const columns = integerIn(columnsRaw, \"columns\", 1, list.length), rows = Math.ceil(list.length / columns);\n const gap = finiteIn(get(\"gapFraction\"), \"gapFraction\", 0, 0.5), background = neutral(\"backgroundReflectance\");\n if (gap >= 0.5) throw new InvalidConfigurationError(\"gapFraction must be below 0.5.\");\n const backgroundIndex = materials.length;\n materials.push({ kind: \"neutral\", reflectance: background });\n const cellW = 2 / columns, cellH = 2 * aspect / rows;\n return done({ patchIds: list.map((p: { patchId: string }) => p.patchId), columns, rows, gapFraction: gap, backgroundReflectance: background }, materials, (u, v) => {\n const fx = (u + 1) / cellW, fy = (aspect - v) / cellH, i = Math.floor(fx), j = Math.floor(fy);\n if (i < 0 || j < 0 || i >= columns || j >= rows) return backgroundIndex;\n const index = j * columns + i, x = fx - i, y = fy - j;\n if (index >= list.length || x < gap / 2 || x > 1 - gap / 2 || y < gap / 2 || y > 1 - gap / 2) return backgroundIndex;\n return index;\n });\n }\n }\n}\n\n/**\n * Step reflectances of a step wedge. `equal-density` spaces optical density D = -log10(R) evenly, which\n * gives geometric reflectance steps, as on a photographic step tablet. `linear` spaces reflectance evenly.\n */\nexport function calculateStepWedgeReflectances(input: { steps: number; minimumReflectance: number; maximumReflectance: number;\n spacing: \"equal-density\" | \"linear\" }): number[] {\n requireInputKeys(input, \"calculateStepWedgeReflectances\", [\"steps\", \"minimumReflectance\", \"maximumReflectance\", \"spacing\"]);\n const steps = integerIn(input.steps, \"steps\", 2, 64), lo = reflectance(input.minimumReflectance, \"minimumReflectance\"), hi = reflectance(input.maximumReflectance, \"maximumReflectance\");\n if (input.spacing !== \"equal-density\" && input.spacing !== \"linear\") throw new InvalidConfigurationError(\"spacing must be equal-density or linear.\");\n if (!(hi > lo) || (input.spacing === \"equal-density\" && lo <= 0)) throw new InvalidConfigurationError(\"Step wedge needs 0 < minimum < maximum reflectance.\");\n return Array.from({ length: steps }, (_, k) => {\n if (k === steps - 1) return hi;\n const t = k / (steps - 1);\n return input.spacing === \"linear\" ? lo + (hi - lo) * t : lo * (hi / lo) ** t;\n });\n}\n\n/** Centres (frame units) of a point grid: one disk centred in each of columns × rows equal cells, row-major from the top-left. */\nexport function calculatePointGridCenters(input: { columns: number; rows: number; aspect: number }): { u: number; v: number }[] {\n requireInputKeys(input, \"calculatePointGridCenters\", [\"columns\", \"rows\", \"aspect\"]);\n const columns = integerIn(input.columns, \"columns\", 1, 256), rows = integerIn(input.rows, \"rows\", 1, 256);\n if (typeof input.aspect !== \"number\" || !Number.isFinite(input.aspect) || input.aspect <= 0) throw new InvalidConfigurationError(\"aspect must be positive.\");\n const out: { u: number; v: number }[] = [];\n for (let j = 0; j < rows; j++) for (let i = 0; i < columns; i++) out.push({ u: -1 + (i + 0.5) * 2 / columns, v: input.aspect - (j + 0.5) * 2 * input.aspect / rows });\n return out;\n}\n"]}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/** Mechanism chosen by {@link createHostYield}, for diagnostics and tests. */
|
|
2
|
+
export type HostYieldMechanism = "scheduler.yield" | "message-channel" | "set-immediate" | "set-timeout";
|
|
3
|
+
/** Returns a function that yields to the host event loop once per call, and the mechanism it uses. */
|
|
4
|
+
export declare function createHostYield(host?: object): {
|
|
5
|
+
mechanism: HostYieldMechanism;
|
|
6
|
+
yieldControl: () => Promise<void>;
|
|
7
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
/** Returns a function that yields to the host event loop once per call, and the mechanism it uses. */
|
|
3
|
+
export function createHostYield(host = globalThis) {
|
|
4
|
+
const g = host;
|
|
5
|
+
const scheduler = g.scheduler;
|
|
6
|
+
if (scheduler !== undefined && typeof scheduler.yield === "function") {
|
|
7
|
+
return { mechanism: "scheduler.yield", yieldControl: async () => { await scheduler.yield.call(scheduler); } };
|
|
8
|
+
}
|
|
9
|
+
const Channel = g.MessageChannel;
|
|
10
|
+
if (typeof Channel === "function") {
|
|
11
|
+
return { mechanism: "message-channel", yieldControl: () => new Promise((resolve) => {
|
|
12
|
+
const channel = new Channel();
|
|
13
|
+
channel.port1.onmessage = () => { channel.port1.close(); resolve(); };
|
|
14
|
+
channel.port2.postMessage(undefined);
|
|
15
|
+
}) };
|
|
16
|
+
}
|
|
17
|
+
const immediate = g.setImmediate;
|
|
18
|
+
if (typeof immediate === "function") {
|
|
19
|
+
return { mechanism: "set-immediate", yieldControl: () => new Promise((resolve) => { immediate.call(host, resolve); }) };
|
|
20
|
+
}
|
|
21
|
+
return { mechanism: "set-timeout", yieldControl: () => new Promise((resolve) => { setTimeout(resolve, 0); }) };
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=host-yield.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"host-yield.js","sourceRoot":"","sources":["../../src/facade/host-yield.ts"],"names":[],"mappings":"AAAA,sCAAsC;AA2BtC,sGAAsG;AACtG,MAAM,UAAU,eAAe,CAAC,OAAe,UAAU;IACvD,MAAM,CAAC,GAAG,IAAoB,CAAC;IAC/B,MAAM,SAAS,GAAG,CAAC,CAAC,SAAS,CAAC;IAC9B,IAAI,SAAS,KAAK,SAAS,IAAI,OAAO,SAAS,CAAC,KAAK,KAAK,UAAU,EAAE,CAAC;QACrE,OAAO,EAAE,SAAS,EAAE,iBAAiB,EAAE,YAAY,EAAE,KAAK,IAAmB,EAAE,GAAG,MAAM,SAAS,CAAC,KAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAChI,CAAC;IACD,MAAM,OAAO,GAAG,CAAC,CAAC,cAAc,CAAC;IACjC,IAAI,OAAO,OAAO,KAAK,UAAU,EAAE,CAAC;QAClC,OAAO,EAAE,SAAS,EAAE,iBAAiB,EAAE,YAAY,EAAE,GAAG,EAAE,CAAC,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;gBACvF,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;gBAC9B,OAAO,CAAC,KAAK,CAAC,SAAS,GAAG,GAAS,EAAE,GAAG,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC;gBAC5E,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC;YACvC,CAAC,CAAC,EAAE,CAAC;IACP,CAAC;IACD,MAAM,SAAS,GAAG,CAAC,CAAC,YAAY,CAAC;IACjC,IAAI,OAAO,SAAS,KAAK,UAAU,EAAE,CAAC;QACpC,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,YAAY,EAAE,GAAG,EAAE,CAAC,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE,GAAG,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAChI,CAAC;IACD,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,YAAY,EAAE,GAAG,EAAE,CAAC,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE,GAAG,UAAU,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;AACvH,CAAC","sourcesContent":["// SPDX-License-Identifier: Apache-2.0\n\n/**\n * Host yield for the capture facade's cooperative tasks. Browsers clamp nested `setTimeout(…, 0)` to\n * at least 4 ms (WHATWG HTML timers, nesting level above 5), so a task that yields every few\n * milliseconds through timers can sit idle for a large share of its run time. These yields are not\n * clamped. The first available mechanism is used:\n *\n * 1. `scheduler.yield()` (Prioritized Task Scheduling API), which also keeps the task's priority;\n * 2. a `MessageChannel` message, a new task without the timer clamp (one channel per yield, closed after\n * delivery, so no port keeps a Node process alive);\n * 3. `setImmediate` (Node and some other non-browser hosts);\n * 4. `setTimeout(…, 0)` as the last resort.\n *\n * Only global feature detection is used; nothing is imported, so the browser package surface is unchanged.\n * The yield changes scheduling only, never results.\n */\n\ntype YieldGlobals = {\n scheduler?: { yield?: () => Promise<unknown> };\n MessageChannel?: new () => { port1: { onmessage: ((event: unknown) => void) | null; close(): void }; port2: { postMessage(message: unknown): void } };\n setImmediate?: (callback: () => void) => unknown;\n};\n\n/** Mechanism chosen by {@link createHostYield}, for diagnostics and tests. */\nexport type HostYieldMechanism = \"scheduler.yield\" | \"message-channel\" | \"set-immediate\" | \"set-timeout\";\n\n/** Returns a function that yields to the host event loop once per call, and the mechanism it uses. */\nexport function createHostYield(host: object = globalThis): { mechanism: HostYieldMechanism; yieldControl: () => Promise<void> } {\n const g = host as YieldGlobals;\n const scheduler = g.scheduler;\n if (scheduler !== undefined && typeof scheduler.yield === \"function\") {\n return { mechanism: \"scheduler.yield\", yieldControl: async (): Promise<void> => { await scheduler.yield!.call(scheduler); } };\n }\n const Channel = g.MessageChannel;\n if (typeof Channel === \"function\") {\n return { mechanism: \"message-channel\", yieldControl: () => new Promise<void>((resolve) => {\n const channel = new Channel();\n channel.port1.onmessage = (): void => { channel.port1.close(); resolve(); };\n channel.port2.postMessage(undefined);\n }) };\n }\n const immediate = g.setImmediate;\n if (typeof immediate === \"function\") {\n return { mechanism: \"set-immediate\", yieldControl: () => new Promise<void>((resolve) => { immediate.call(host, resolve); }) };\n }\n return { mechanism: \"set-timeout\", yieldControl: () => new Promise<void>((resolve) => { setTimeout(resolve, 0); }) };\n}\n"]}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { type ColorimetricSpectrum, type PreparedColorimetricSpectrum } from "../color/color-matching-functions.js";
|
|
2
|
+
import { type CieDaylightBasis } from "../color/illuminants.js";
|
|
3
|
+
import type { SceneRadianceEvaluationRequest, SceneRadianceEvaluationResult } from "../schema/scene-radiance.js";
|
|
4
|
+
import type { EvidenceProvenance } from "../core/evidence-provenance.js";
|
|
5
|
+
import type { SensorApertureRay } from "../optics/sensor-aperture-rays.js";
|
|
6
|
+
import { type ChartScene, type ResolvedChartScene } from "./chart-scenes.js";
|
|
7
|
+
/** CIE maximum luminous efficacy for photopic vision, lm/W. */
|
|
8
|
+
export declare const PHOTOPIC_MAXIMUM_LUMINOUS_EFFICACY_LM_PER_W = 683;
|
|
9
|
+
/** Wavelength range of every facade spectrum and of the facade sensor quadrature, nm. */
|
|
10
|
+
export declare const FACADE_SPECTRAL_RANGE_NANOMETERS: Readonly<{
|
|
11
|
+
minimum: 380;
|
|
12
|
+
maximum: 780;
|
|
13
|
+
}>;
|
|
14
|
+
/**
|
|
15
|
+
* Illuminant choices. CIE D65 is not bundled: its S0/S1/S2 basis tables must come from the caller
|
|
16
|
+
* (`daylight`). `planckian` is Planck's law; `cie-a` is CIE illuminant A from its defining formula.
|
|
17
|
+
*/
|
|
18
|
+
export type CaptureIlluminant = "cie-a" | {
|
|
19
|
+
kind: "planckian";
|
|
20
|
+
temperatureKelvin: number;
|
|
21
|
+
} | {
|
|
22
|
+
kind: "cie-a";
|
|
23
|
+
} | {
|
|
24
|
+
kind: "daylight";
|
|
25
|
+
correlatedColorTemperatureKelvin: number;
|
|
26
|
+
basis: CieDaylightBasis;
|
|
27
|
+
} | {
|
|
28
|
+
kind: "spectrum";
|
|
29
|
+
spectrum: ColorimetricSpectrum;
|
|
30
|
+
label?: string;
|
|
31
|
+
};
|
|
32
|
+
export interface ResolvedCaptureIlluminant {
|
|
33
|
+
/** Short public description, for example "planckian-6500K". */
|
|
34
|
+
id: string;
|
|
35
|
+
description: string;
|
|
36
|
+
/** Relative spectral shape (arbitrary scale) over at least 380-780 nm. */
|
|
37
|
+
shape: PreparedColorimetricSpectrum;
|
|
38
|
+
/** Original spectrum, for colorimetric white-balance calculations. */
|
|
39
|
+
spectrum: ColorimetricSpectrum;
|
|
40
|
+
}
|
|
41
|
+
export declare function resolveCaptureIlluminant(value: CaptureIlluminant): ResolvedCaptureIlluminant;
|
|
42
|
+
/**
|
|
43
|
+
* Factor k such that k·S(λ) (W·m⁻²·nm⁻¹) gives `illuminanceLux` on the plane: E_v = 683 ∫ k S ȳ dλ,
|
|
44
|
+
* integrated with the 1 nm trapezoid rule over 380-780 nm (ȳ outside this range is below 4e-5 of its peak).
|
|
45
|
+
*/
|
|
46
|
+
export declare function calculateIlluminantIrradianceScale(shape: PreparedColorimetricSpectrum, illuminanceLux: number): number;
|
|
47
|
+
/** A point of the scene plane passed to caller scene functions. */
|
|
48
|
+
export interface ScenePlanePoint {
|
|
49
|
+
/** Metres on the plane, from the optical axis: +x right, +y up (as seen from the camera). */
|
|
50
|
+
xM: number;
|
|
51
|
+
yM: number;
|
|
52
|
+
/** The same point in frame units (u = ±1 at the left/right frame edges, v up on the same scale). */
|
|
53
|
+
u: number;
|
|
54
|
+
v: number;
|
|
55
|
+
wavelengthNanometers: number;
|
|
56
|
+
}
|
|
57
|
+
/** Caller Lambertian reflectance (in [0, 1]) lit by the facade illuminant. */
|
|
58
|
+
export interface CallerReflectanceScene {
|
|
59
|
+
kind: "reflectance-function";
|
|
60
|
+
sceneId: string;
|
|
61
|
+
evaluate(point: Readonly<ScenePlanePoint>): number;
|
|
62
|
+
}
|
|
63
|
+
/** Caller absolute spectral radiance in W·m⁻²·sr⁻¹·nm⁻¹; the facade illuminant is not used. */
|
|
64
|
+
export interface CallerRadianceScene {
|
|
65
|
+
kind: "radiance-function";
|
|
66
|
+
sceneId: string;
|
|
67
|
+
evaluate(point: Readonly<ScenePlanePoint>): number;
|
|
68
|
+
}
|
|
69
|
+
export interface PlanarSceneGeometry {
|
|
70
|
+
distanceM: number;
|
|
71
|
+
/** Metres per frame unit on the plane (half the framed width). */
|
|
72
|
+
metresPerFrameUnit: number;
|
|
73
|
+
}
|
|
74
|
+
export interface PlanarSceneRadianceProvider {
|
|
75
|
+
sceneId: string;
|
|
76
|
+
providerProfileId: string;
|
|
77
|
+
evaluateRadiance(request: Readonly<SceneRadianceEvaluationRequest>): SceneRadianceEvaluationResult;
|
|
78
|
+
evaluateApertureRadiance(request: Readonly<SceneRadianceEvaluationRequest>, ray: Readonly<SensorApertureRay>): SceneRadianceEvaluationResult;
|
|
79
|
+
/** Spectral radiance at a plane point (frame units), the same value the callbacks return. */
|
|
80
|
+
radianceAt(u: number, v: number, wavelengthNanometers: number): number;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Wraps a chart or caller scene as a provider for the native environment RAW task. `irradianceScale` is
|
|
84
|
+
* from {@link calculateIlluminantIrradianceScale}; caller radiance scenes ignore the illuminant.
|
|
85
|
+
*/
|
|
86
|
+
export declare function buildPlanarSceneRadianceProvider(input: {
|
|
87
|
+
scene: ResolvedChartScene | CallerReflectanceScene | CallerRadianceScene;
|
|
88
|
+
sceneId: string;
|
|
89
|
+
providerProfileId: string;
|
|
90
|
+
illuminant: ResolvedCaptureIlluminant;
|
|
91
|
+
irradianceScale: number;
|
|
92
|
+
geometry: PlanarSceneGeometry;
|
|
93
|
+
evidence: readonly EvidenceProvenance[];
|
|
94
|
+
limitations: readonly string[];
|
|
95
|
+
}): PlanarSceneRadianceProvider;
|
|
96
|
+
/**
|
|
97
|
+
* Public scene-preset provider. Places an engine chart (or a caller reflectance or radiance function) on
|
|
98
|
+
* a plane `distanceM` in front of the camera and `framedWidthM` wide (frame units u = ±1 at its edges),
|
|
99
|
+
* lit by `illuminant` at `illuminanceLux`. The returned `evaluateRadiance` and `evaluateApertureRadiance`
|
|
100
|
+
* follow the native environment RAW provider contract. They answer requests for scene `sceneId` and
|
|
101
|
+
* provider `providerProfileId`.
|
|
102
|
+
*/
|
|
103
|
+
export declare function createPlanarSceneRadianceProvider(input: {
|
|
104
|
+
scene: ChartScene | CallerReflectanceScene | CallerRadianceScene;
|
|
105
|
+
illuminant: CaptureIlluminant;
|
|
106
|
+
illuminanceLux: number;
|
|
107
|
+
distanceM: number;
|
|
108
|
+
framedWidthM: number;
|
|
109
|
+
/** Frame height / width. */
|
|
110
|
+
aspect: number;
|
|
111
|
+
sceneId: string;
|
|
112
|
+
providerProfileId: string;
|
|
113
|
+
}): PlanarSceneRadianceProvider & {
|
|
114
|
+
chart: ResolvedChartScene | null;
|
|
115
|
+
};
|
|
116
|
+
/** Validates a caller scene function record. */
|
|
117
|
+
export declare function requireCallerScene(value: unknown): CallerReflectanceScene | CallerRadianceScene;
|