@photivra/engine 1.5.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 +393 -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 +116 -9
- package/dist/capture/native-raw-development.js +221 -62
- 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 +65 -12
- package/dist/capture/native-raw.js +81 -19
- 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 -8
- package/docs/api/capture-native-raw-dng.md +84 -0
- package/docs/api/capture-native-raw.md +21 -10
- 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/DENSE_PUPIL_QUALIFICATION.md +0 -121
- 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 -54
- 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_1_5_0.md +0 -105
- 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/SEPARABLE_EMISSION_DRAFT.md +0 -103
- 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/dense-pupil-2026-10-06/pilot.jsonl +0 -6
- 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
|
@@ -1,28 +1,40 @@
|
|
|
1
1
|
// SPDX-License-Identifier: Apache-2.0
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
3
|
+
* Thin-lens depth of field (DoF) and defocus blur.
|
|
4
|
+
*
|
|
5
|
+
* Depth-of-field limits are exact for a thin lens. They use the hyperfocal distance
|
|
6
|
+
* H = f^2/(Nc) + f:
|
|
7
|
+
* near = s(H - f)/(H + s - 2f)
|
|
8
|
+
* far = s(H - f)/(H - s), infinite (null) when s >= H
|
|
9
|
+
* The model is geometric. It does not include diffraction, aberrations, focus breathing, pupil
|
|
10
|
+
* magnification or macro (high-magnification) effects.
|
|
11
|
+
*
|
|
12
|
+
* The defocus circle is the geometric blur-circle diameter at the sensor for a subject plane that is
|
|
13
|
+
* not at the focus distance.
|
|
14
|
+
* @see docs/PHYSICS_FOUNDATION.md for the equations, units, coordinate conventions, known blockers
|
|
15
|
+
* and support limits.
|
|
11
16
|
*/
|
|
12
17
|
import { calculatedResult } from "../core/calculation-result.js";
|
|
13
18
|
import { InvalidScientificInputError, requirePositiveFinite } from "../core/validation.js";
|
|
14
19
|
import { calculateThinLensImageDistance } from "./thin-lens.js";
|
|
20
|
+
import { requireInputKeys } from "../core/record-validation.js";
|
|
15
21
|
/**
|
|
16
|
-
* Calculates thin-lens depth-of-field limits
|
|
17
|
-
*
|
|
22
|
+
* Calculates exact thin-lens depth-of-field limits. With hyperfocal
|
|
23
|
+
* distance H = f^2/(Nc) + f and focus distance s, the near limit is
|
|
24
|
+
* s(H - f)/(H + s - 2f) and the far limit is s(H - f)/(H - s), which is
|
|
25
|
+
* infinite (`null`) when s >= H. At both limits the geometric defocus circle
|
|
26
|
+
* from {@link calculateDefocusCircle} equals the supplied circle of confusion.
|
|
27
|
+
* The circle of confusion must be smaller than the aperture diameter f/N;
|
|
28
|
+
* otherwise the near limit would fall inside the focal length.
|
|
18
29
|
*
|
|
19
|
-
* The model is geometric
|
|
20
|
-
* focus breathing, pupil magnification
|
|
30
|
+
* The model is geometric. It does not include diffraction, aberrations,
|
|
31
|
+
* focus breathing, pupil magnification or macro (high-magnification) effects.
|
|
21
32
|
*
|
|
22
33
|
* @param input Lens, focus, aperture, and acceptable blur-circle inputs.
|
|
23
34
|
* @returns Hyperfocal, near, and far depth-of-field distances.
|
|
24
35
|
*/
|
|
25
36
|
export function calculateDepthOfField(input) {
|
|
37
|
+
requireInputKeys(input, "calculateDepthOfField", ["focalLengthMm", "aperture", "focusDistanceM", "circleOfConfusionMm"]);
|
|
26
38
|
requirePositiveFinite("focalLengthMm", input.focalLengthMm);
|
|
27
39
|
requirePositiveFinite("aperture", input.aperture);
|
|
28
40
|
requirePositiveFinite("focusDistanceM", input.focusDistanceM);
|
|
@@ -31,22 +43,37 @@ export function calculateDepthOfField(input) {
|
|
|
31
43
|
if (focusDistanceMm <= input.focalLengthMm) {
|
|
32
44
|
throw new InvalidScientificInputError("focusDistanceM must place the focus plane beyond the focal length.");
|
|
33
45
|
}
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
const
|
|
46
|
+
// The near limit lies beyond the focal length only when H - f = f^2/(Nc) > f,
|
|
47
|
+
// i.e. c < f/N (the entrance-pupil diameter). A blur circle at least as large
|
|
48
|
+
// as the pupil itself has no real-image depth-of-field solution.
|
|
49
|
+
if (input.circleOfConfusionMm >= input.focalLengthMm / input.aperture) {
|
|
50
|
+
throw new InvalidScientificInputError("circleOfConfusionMm must be smaller than the aperture diameter focalLengthMm / aperture.");
|
|
51
|
+
}
|
|
52
|
+
// H - f = f^2 / (N c), kept separately to avoid cancellation.
|
|
53
|
+
const hyperfocalOffsetMm = (input.focalLengthMm * input.focalLengthMm) /
|
|
54
|
+
(input.aperture * input.circleOfConfusionMm);
|
|
55
|
+
const hyperfocalDistanceMm = hyperfocalOffsetMm + input.focalLengthMm;
|
|
56
|
+
// Exact thin-lens limits. The defocus-circle diameter for a subject at d
|
|
57
|
+
// while focused at s is c(d) = f^2 |s - d| / (N d (s - f)). Solving
|
|
58
|
+
// c(d) = c with H = f^2 / (N c) + f gives
|
|
59
|
+
// near = s (H - f) / (H + s - 2f) = s (H - f) / ((H - f) + (s - f))
|
|
60
|
+
// far = s (H - f) / (H - s), infinite when s >= H.
|
|
61
|
+
const nearLimitMm = (focusDistanceMm * hyperfocalOffsetMm) /
|
|
62
|
+
(hyperfocalOffsetMm + (focusDistanceMm - input.focalLengthMm));
|
|
63
|
+
// Compare against the reported hyperfocal distance in metres as well, so a
|
|
64
|
+
// caller focusing at exactly the returned hyperfocalDistanceM always gets an
|
|
65
|
+
// infinite far limit despite millimetre/metre rounding.
|
|
66
|
+
const hyperfocalDistanceM = hyperfocalDistanceMm / 1000;
|
|
67
|
+
const farDenominator = hyperfocalDistanceMm - focusDistanceMm;
|
|
68
|
+
const farLimitMm = farDenominator <= 0 || input.focusDistanceM >= hyperfocalDistanceM
|
|
42
69
|
? null
|
|
43
|
-
: (
|
|
70
|
+
: (focusDistanceMm * hyperfocalOffsetMm) / farDenominator;
|
|
44
71
|
return calculatedResult({
|
|
45
|
-
hyperfocalDistanceM
|
|
72
|
+
hyperfocalDistanceM,
|
|
46
73
|
nearLimitM: nearLimitMm / 1000,
|
|
47
74
|
farLimitM: farLimitMm === null ? null : farLimitMm / 1000,
|
|
48
75
|
totalDepthOfFieldM: farLimitMm === null ? null : (farLimitMm - nearLimitMm) / 1000
|
|
49
|
-
}, "thin-lens-depth-of-field", "1.
|
|
76
|
+
}, "thin-lens-depth-of-field", "1.1.0", [
|
|
50
77
|
"Geometric thin-lens model",
|
|
51
78
|
"Circle of confusion is supplied by the caller",
|
|
52
79
|
"Macro/high-magnification effects are not modeled"
|
|
@@ -54,12 +81,14 @@ export function calculateDepthOfField(input) {
|
|
|
54
81
|
}
|
|
55
82
|
/**
|
|
56
83
|
* Calculates the geometric defocus-circle diameter at the sensor plane for a
|
|
57
|
-
* subject plane away from the selected focus plane
|
|
84
|
+
* subject plane away from the selected focus plane, using the stable closed
|
|
85
|
+
* form c = f^2 |s - d| / (N d (s - f)) (model 1.1.0).
|
|
58
86
|
*
|
|
59
87
|
* @param input Lens, aperture, focus-plane, and subject-plane distances.
|
|
60
88
|
* @returns Geometric blur-circle diameter.
|
|
61
89
|
*/
|
|
62
90
|
export function calculateDefocusCircle(input) {
|
|
91
|
+
requireInputKeys(input, "calculateDefocusCircle", ["focalLengthMm", "aperture", "focusDistanceM", "subjectDistanceM"]);
|
|
63
92
|
return calculateDefocusCircleUsingFocusProjection(input);
|
|
64
93
|
}
|
|
65
94
|
/** @internal Reuses a projection already calculated for this exact POC request. */
|
|
@@ -97,10 +126,21 @@ export function calculateDefocusCircleUsingFocusProjection(input, projection) {
|
|
|
97
126
|
}
|
|
98
127
|
throw error;
|
|
99
128
|
}
|
|
129
|
+
// Both image distances are still resolved above, so the thin-lens domain checks
|
|
130
|
+
// and the reused-projection identity check still run.
|
|
131
|
+
void focusImageDistanceMm;
|
|
132
|
+
void subjectImageDistanceMm;
|
|
100
133
|
const apertureDiameterMm = input.focalLengthMm / input.aperture;
|
|
134
|
+
const focusDistanceMm = input.focusDistanceM * 1000;
|
|
135
|
+
const subjectDistanceMm = input.subjectDistanceM * 1000;
|
|
136
|
+
// Closed form of D |v_d - v_s| / v_d with v = f x / (x - f) (Gaussian thin lens):
|
|
137
|
+
// c = f^2 |s - d| / (N d (s - f)).
|
|
138
|
+
// It avoids subtracting two nearly equal image distances (catastrophic
|
|
139
|
+
// cancellation for distant subjects) and is grouped as bounded ratios so the
|
|
140
|
+
// intermediate products cannot overflow for finite in-domain inputs.
|
|
101
141
|
const diameterMm = apertureDiameterMm *
|
|
102
|
-
(Math.abs(
|
|
103
|
-
|
|
104
|
-
return calculatedResult({ diameterMm }, "thin-lens-defocus-circle", "1.
|
|
142
|
+
(Math.abs(focusDistanceMm - subjectDistanceMm) / subjectDistanceMm) *
|
|
143
|
+
(input.focalLengthMm / (focusDistanceMm - input.focalLengthMm));
|
|
144
|
+
return calculatedResult({ diameterMm }, "thin-lens-defocus-circle", "1.1.0", ["Geometric thin-lens model", "Ideal circular entrance pupil"]);
|
|
105
145
|
}
|
|
106
146
|
//# sourceMappingURL=depth-of-field.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"depth-of-field.js","sourceRoot":"","sources":["../../src/optics/depth-of-field.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"depth-of-field.js","sourceRoot":"","sources":["../../src/optics/depth-of-field.ts"],"names":[],"mappings":"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","sourcesContent":["// SPDX-License-Identifier: Apache-2.0\n\n/**\n * Thin-lens depth of field (DoF) and defocus blur.\n *\n * Depth-of-field limits are exact for a thin lens. They use the hyperfocal distance\n * H = f^2/(Nc) + f:\n * near = s(H - f)/(H + s - 2f)\n * far = s(H - f)/(H - s), infinite (null) when s >= H\n * The model is geometric. It does not include diffraction, aberrations, focus breathing, pupil\n * magnification or macro (high-magnification) effects.\n *\n * The defocus circle is the geometric blur-circle diameter at the sensor for a subject plane that is\n * not at the focus distance.\n * @see docs/PHYSICS_FOUNDATION.md for the equations, units, coordinate conventions, known blockers\n * and support limits.\n */\n\nimport {\n calculatedResult,\n type CalculationResult\n} from \"../core/calculation-result.js\";\nimport {\n InvalidScientificInputError,\n requirePositiveFinite\n} from \"../core/validation.js\";\nimport { calculateThinLensImageDistance } from \"./thin-lens.js\";\nimport { requireInputKeys } from \"../core/record-validation.js\";\n\nexport interface CalculateDepthOfFieldInput {\n /** Lens focal length in millimetres. */\n focalLengthMm: number;\n /** F-number. */\n aperture: number;\n /** Focus distance from the lens plane in metres. */\n focusDistanceM: number;\n /** Acceptable circle of confusion diameter in millimetres. */\n circleOfConfusionMm: number;\n}\n\nexport interface DepthOfField {\n hyperfocalDistanceM: number;\n nearLimitM: number;\n /** Null represents an infinite far limit. */\n farLimitM: number | null;\n /** Null represents infinite total depth of field. */\n totalDepthOfFieldM: number | null;\n}\n\n/**\n * Calculates exact thin-lens depth-of-field limits. With hyperfocal\n * distance H = f^2/(Nc) + f and focus distance s, the near limit is\n * s(H - f)/(H + s - 2f) and the far limit is s(H - f)/(H - s), which is\n * infinite (`null`) when s >= H. At both limits the geometric defocus circle\n * from {@link calculateDefocusCircle} equals the supplied circle of confusion.\n * The circle of confusion must be smaller than the aperture diameter f/N;\n * otherwise the near limit would fall inside the focal length.\n *\n * The model is geometric. It does not include diffraction, aberrations,\n * focus breathing, pupil magnification or macro (high-magnification) effects.\n *\n * @param input Lens, focus, aperture, and acceptable blur-circle inputs.\n * @returns Hyperfocal, near, and far depth-of-field distances.\n */\nexport function calculateDepthOfField(\n input: CalculateDepthOfFieldInput\n): CalculationResult<DepthOfField> {\n requireInputKeys(input, \"calculateDepthOfField\", [\"focalLengthMm\", \"aperture\", \"focusDistanceM\", \"circleOfConfusionMm\"]);\n requirePositiveFinite(\"focalLengthMm\", input.focalLengthMm);\n requirePositiveFinite(\"aperture\", input.aperture);\n requirePositiveFinite(\"focusDistanceM\", input.focusDistanceM);\n requirePositiveFinite(\"circleOfConfusionMm\", input.circleOfConfusionMm);\n\n const focusDistanceMm = input.focusDistanceM * 1000;\n if (focusDistanceMm <= input.focalLengthMm) {\n throw new InvalidScientificInputError(\n \"focusDistanceM must place the focus plane beyond the focal length.\"\n );\n }\n // The near limit lies beyond the focal length only when H - f = f^2/(Nc) > f,\n // i.e. c < f/N (the entrance-pupil diameter). A blur circle at least as large\n // as the pupil itself has no real-image depth-of-field solution.\n if (input.circleOfConfusionMm >= input.focalLengthMm / input.aperture) {\n throw new InvalidScientificInputError(\n \"circleOfConfusionMm must be smaller than the aperture diameter focalLengthMm / aperture.\"\n );\n }\n\n // H - f = f^2 / (N c), kept separately to avoid cancellation.\n const hyperfocalOffsetMm =\n (input.focalLengthMm * input.focalLengthMm) /\n (input.aperture * input.circleOfConfusionMm);\n const hyperfocalDistanceMm = hyperfocalOffsetMm + input.focalLengthMm;\n\n // Exact thin-lens limits. The defocus-circle diameter for a subject at d\n // while focused at s is c(d) = f^2 |s - d| / (N d (s - f)). Solving\n // c(d) = c with H = f^2 / (N c) + f gives\n // near = s (H - f) / (H + s - 2f) = s (H - f) / ((H - f) + (s - f))\n // far = s (H - f) / (H - s), infinite when s >= H.\n const nearLimitMm =\n (focusDistanceMm * hyperfocalOffsetMm) /\n (hyperfocalOffsetMm + (focusDistanceMm - input.focalLengthMm));\n\n // Compare against the reported hyperfocal distance in metres as well, so a\n // caller focusing at exactly the returned hyperfocalDistanceM always gets an\n // infinite far limit despite millimetre/metre rounding.\n const hyperfocalDistanceM = hyperfocalDistanceMm / 1000;\n const farDenominator = hyperfocalDistanceMm - focusDistanceMm;\n const farLimitMm =\n farDenominator <= 0 || input.focusDistanceM >= hyperfocalDistanceM\n ? null\n : (focusDistanceMm * hyperfocalOffsetMm) / farDenominator;\n\n return calculatedResult(\n {\n hyperfocalDistanceM,\n nearLimitM: nearLimitMm / 1000,\n farLimitM: farLimitMm === null ? null : farLimitMm / 1000,\n totalDepthOfFieldM:\n farLimitMm === null ? null : (farLimitMm - nearLimitMm) / 1000\n },\n \"thin-lens-depth-of-field\",\n \"1.1.0\",\n [\n \"Geometric thin-lens model\",\n \"Circle of confusion is supplied by the caller\",\n \"Macro/high-magnification effects are not modeled\"\n ]\n );\n}\n\nexport interface CalculateDefocusCircleInput {\n /** Lens focal length in millimetres. */\n focalLengthMm: number;\n /** F-number. */\n aperture: number;\n /** Focus-plane distance from the lens plane in metres. */\n focusDistanceM: number;\n /** Subject-plane distance from the lens plane in metres. */\n subjectDistanceM: number;\n}\n\nexport interface DefocusCircle {\n /** Geometric blur-circle diameter at the sensor plane in millimetres. */\n diameterMm: number;\n}\n\n/**\n * Calculates the geometric defocus-circle diameter at the sensor plane for a\n * subject plane away from the selected focus plane, using the stable closed\n * form c = f^2 |s - d| / (N d (s - f)) (model 1.1.0).\n *\n * @param input Lens, aperture, focus-plane, and subject-plane distances.\n * @returns Geometric blur-circle diameter.\n */\nexport function calculateDefocusCircle(\n input: CalculateDefocusCircleInput\n): CalculationResult<DefocusCircle> {\n requireInputKeys(input, \"calculateDefocusCircle\", [\"focalLengthMm\", \"aperture\", \"focusDistanceM\", \"subjectDistanceM\"]);\n return calculateDefocusCircleUsingFocusProjection(input);\n}\n\n/** @internal Immutable identity for one request. Not a public cache or API. */\nexport interface ResolvedDefocusFocusProjection {\n readonly focalLengthMm: number;\n readonly focusDistanceM: number;\n readonly imageDistanceMm: number;\n}\n\n/** @internal Reuses a projection already calculated for this exact POC request. */\nexport function calculateDefocusCircleUsingFocusProjection(\n input: CalculateDefocusCircleInput,\n projection?: ResolvedDefocusFocusProjection\n): CalculationResult<DefocusCircle> {\n requirePositiveFinite(\"focalLengthMm\", input.focalLengthMm);\n requirePositiveFinite(\"aperture\", input.aperture);\n requirePositiveFinite(\"focusDistanceM\", input.focusDistanceM);\n requirePositiveFinite(\"subjectDistanceM\", input.subjectDistanceM);\n\n let focusImageDistanceMm: number;\n let subjectImageDistanceMm: number;\n try {\n if (projection !== undefined) {\n if (projection.focalLengthMm !== input.focalLengthMm ||\n projection.focusDistanceM !== input.focusDistanceM ||\n input.focusDistanceM * 1000 <= input.focalLengthMm) {\n throw new InvalidScientificInputError(\"Resolved focus projection identity differs from the request.\");\n }\n requirePositiveFinite(\"resolvedFocusImageDistanceMm\", projection.imageDistanceMm);\n focusImageDistanceMm = projection.imageDistanceMm;\n } else {\n focusImageDistanceMm = calculateThinLensImageDistance({\n focalLengthMm: input.focalLengthMm,\n objectDistanceM: input.focusDistanceM\n }).value.imageDistanceMm;\n }\n subjectImageDistanceMm = calculateThinLensImageDistance({\n focalLengthMm: input.focalLengthMm,\n objectDistanceM: input.subjectDistanceM\n }).value.imageDistanceMm;\n } catch (error) {\n if (error instanceof InvalidScientificInputError) {\n throw new InvalidScientificInputError(\n \"focusDistanceM and subjectDistanceM must be beyond the focal length.\"\n );\n }\n throw error;\n }\n // Both image distances are still resolved above, so the thin-lens domain checks\n // and the reused-projection identity check still run.\n void focusImageDistanceMm;\n void subjectImageDistanceMm;\n const apertureDiameterMm = input.focalLengthMm / input.aperture;\n const focusDistanceMm = input.focusDistanceM * 1000;\n const subjectDistanceMm = input.subjectDistanceM * 1000;\n\n // Closed form of D |v_d - v_s| / v_d with v = f x / (x - f) (Gaussian thin lens):\n // c = f^2 |s - d| / (N d (s - f)).\n // It avoids subtracting two nearly equal image distances (catastrophic\n // cancellation for distant subjects) and is grouped as bounded ratios so the\n // intermediate products cannot overflow for finite in-domain inputs.\n const diameterMm =\n apertureDiameterMm *\n (Math.abs(focusDistanceMm - subjectDistanceMm) / subjectDistanceMm) *\n (input.focalLengthMm / (focusDistanceMm - input.focalLengthMm));\n\n return calculatedResult(\n { diameterMm },\n \"thin-lens-defocus-circle\",\n \"1.1.0\",\n [\"Geometric thin-lens model\", \"Ideal circular entrance pupil\"]\n );\n}\n"]}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
2
|
+
* Diameter of the Airy disk (the central diffraction spot) out to its first dark ring, for an ideal
|
|
3
|
+
* circular aperture. It uses the standard relation d = 2.44 * lambda * N.
|
|
4
|
+
*
|
|
5
|
+
* This is an independent implementation of that relation. It does not model lens aberrations or
|
|
6
|
+
* non-circular pupils.
|
|
7
|
+
* @see docs/PHYSICS_FOUNDATION.md for the equations, units, coordinate conventions, known blockers
|
|
8
|
+
* and support limits.
|
|
8
9
|
*/
|
|
9
10
|
import { type CalculationResult } from "../core/calculation-result.js";
|
|
10
11
|
export interface CalculateAiryDiskInput {
|
|
@@ -15,20 +16,20 @@ export interface CalculateAiryDiskInput {
|
|
|
15
16
|
}
|
|
16
17
|
export interface AiryDisk {
|
|
17
18
|
/**
|
|
18
|
-
* Diameter
|
|
19
|
-
*
|
|
19
|
+
* Diameter of the first dark ring of the diffraction pattern, in
|
|
20
|
+
* micrometres: 2.44 * wavelength * f-number.
|
|
20
21
|
*/
|
|
21
22
|
firstZeroDiameterMicrometers: number;
|
|
22
23
|
}
|
|
23
24
|
/**
|
|
24
|
-
* Calculates the
|
|
25
|
+
* Calculates the Airy-disk diameter to the first dark ring for an ideal
|
|
26
|
+
* circular aperture.
|
|
25
27
|
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
28
|
+
* It uses the standard diffraction relation d = 2.44 * lambda * N. This is an
|
|
29
|
+
* independent implementation of that relation. It does not model lens
|
|
30
|
+
* aberrations or non-circular pupils.
|
|
29
31
|
*
|
|
30
32
|
* @param input F-number and wavelength.
|
|
31
33
|
* @returns Diffraction diameter at the image plane.
|
|
32
34
|
*/
|
|
33
35
|
export declare function calculateAiryDisk(input: CalculateAiryDiskInput): CalculationResult<AiryDisk>;
|
|
34
|
-
//# sourceMappingURL=diffraction.d.ts.map
|
|
@@ -1,25 +1,29 @@
|
|
|
1
1
|
// SPDX-License-Identifier: Apache-2.0
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
3
|
+
* Diameter of the Airy disk (the central diffraction spot) out to its first dark ring, for an ideal
|
|
4
|
+
* circular aperture. It uses the standard relation d = 2.44 * lambda * N.
|
|
5
|
+
*
|
|
6
|
+
* This is an independent implementation of that relation. It does not model lens aberrations or
|
|
7
|
+
* non-circular pupils.
|
|
8
|
+
* @see docs/PHYSICS_FOUNDATION.md for the equations, units, coordinate conventions, known blockers
|
|
9
|
+
* and support limits.
|
|
9
10
|
*/
|
|
10
11
|
import { calculatedResult } from "../core/calculation-result.js";
|
|
11
12
|
import { requirePositiveFinite } from "../core/validation.js";
|
|
13
|
+
import { requireInputKeys } from "../core/record-validation.js";
|
|
12
14
|
/**
|
|
13
|
-
* Calculates the
|
|
15
|
+
* Calculates the Airy-disk diameter to the first dark ring for an ideal
|
|
16
|
+
* circular aperture.
|
|
14
17
|
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
+
* It uses the standard diffraction relation d = 2.44 * lambda * N. This is an
|
|
19
|
+
* independent implementation of that relation. It does not model lens
|
|
20
|
+
* aberrations or non-circular pupils.
|
|
18
21
|
*
|
|
19
22
|
* @param input F-number and wavelength.
|
|
20
23
|
* @returns Diffraction diameter at the image plane.
|
|
21
24
|
*/
|
|
22
25
|
export function calculateAiryDisk(input) {
|
|
26
|
+
requireInputKeys(input, "calculateAiryDisk", ["aperture", "wavelengthNm"]);
|
|
23
27
|
requirePositiveFinite("aperture", input.aperture);
|
|
24
28
|
requirePositiveFinite("wavelengthNm", input.wavelengthNm);
|
|
25
29
|
return calculatedResult({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"diffraction.js","sourceRoot":"","sources":["../../src/optics/diffraction.ts"],"names":[],"mappings":"AAAA,sCAAsC;AAEtC
|
|
1
|
+
{"version":3,"file":"diffraction.js","sourceRoot":"","sources":["../../src/optics/diffraction.ts"],"names":[],"mappings":"AAAA,sCAAsC;AAEtC;;;;;;;;GAQG;AAEH,OAAO,EACL,gBAAgB,EAEjB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAiBhE;;;;;;;;;;GAUG;AACH,MAAM,UAAU,iBAAiB,CAC/B,KAA6B;IAE7B,gBAAgB,CAAC,KAAK,EAAE,mBAAmB,EAAE,CAAC,UAAU,EAAE,cAAc,CAAC,CAAC,CAAC;IAC3E,qBAAqB,CAAC,UAAU,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC;IAClD,qBAAqB,CAAC,cAAc,EAAE,KAAK,CAAC,YAAY,CAAC,CAAC;IAE1D,OAAO,gBAAgB,CACrB;QACE,4BAA4B,EAC1B,IAAI,GAAG,CAAC,KAAK,CAAC,YAAY,GAAG,IAAI,CAAC,GAAG,KAAK,CAAC,QAAQ;KACtD,EACD,mCAAmC,EACnC,OAAO,EACP,CAAC,yBAAyB,EAAE,0BAA0B,CAAC,CACxD,CAAC;AACJ,CAAC","sourcesContent":["// SPDX-License-Identifier: Apache-2.0\n\n/**\n * Diameter of the Airy disk (the central diffraction spot) out to its first dark ring, for an ideal\n * circular aperture. It uses the standard relation d = 2.44 * lambda * N.\n *\n * This is an independent implementation of that relation. It does not model lens aberrations or\n * non-circular pupils.\n * @see docs/PHYSICS_FOUNDATION.md for the equations, units, coordinate conventions, known blockers\n * and support limits.\n */\n\nimport {\n calculatedResult,\n type CalculationResult\n} from \"../core/calculation-result.js\";\nimport { requirePositiveFinite } from \"../core/validation.js\";\nimport { requireInputKeys } from \"../core/record-validation.js\";\n\nexport interface CalculateAiryDiskInput {\n /** F-number. */\n aperture: number;\n /** Wavelength in nanometres. Defaults are intentionally left to callers. */\n wavelengthNm: number;\n}\n\nexport interface AiryDisk {\n /**\n * Diameter of the first dark ring of the diffraction pattern, in\n * micrometres: 2.44 * wavelength * f-number.\n */\n firstZeroDiameterMicrometers: number;\n}\n\n/**\n * Calculates the Airy-disk diameter to the first dark ring for an ideal\n * circular aperture.\n *\n * It uses the standard diffraction relation d = 2.44 * lambda * N. This is an\n * independent implementation of that relation. It does not model lens\n * aberrations or non-circular pupils.\n *\n * @param input F-number and wavelength.\n * @returns Diffraction diameter at the image plane.\n */\nexport function calculateAiryDisk(\n input: CalculateAiryDiskInput\n): CalculationResult<AiryDisk> {\n requireInputKeys(input, \"calculateAiryDisk\", [\"aperture\", \"wavelengthNm\"]);\n requirePositiveFinite(\"aperture\", input.aperture);\n requirePositiveFinite(\"wavelengthNm\", input.wavelengthNm);\n\n return calculatedResult(\n {\n firstZeroDiameterMicrometers:\n 2.44 * (input.wavelengthNm / 1000) * input.aperture\n },\n \"ideal-circular-aperture-airy-disk\",\n \"1.0.0\",\n [\"Ideal circular aperture\", \"Monochromatic wavelength\"]\n );\n}\n"]}
|
|
@@ -1,15 +1,19 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
2
|
+
* Focus breathing: the change in framing (magnification) as a lens focuses.
|
|
3
|
+
*
|
|
4
|
+
* The declared-scale model applies a caller-supplied projection scale to the ideal Gaussian thin-lens
|
|
5
|
+
* projection for one focus state. Photivra does not guess the scale from focal length, focus
|
|
6
|
+
* distance, lens identity or marketing data. A scale of 1 keeps the thin-lens projection exactly.
|
|
7
|
+
* This is a generic approximation of how projection and magnification change with focus. It is not a
|
|
8
|
+
* calibrated real-lens model. The physical focal length is never changed and stays authoritative.
|
|
9
|
+
*
|
|
10
|
+
* The field-of-view function gives the one-axis field of view (FOV) under this model, and the ideal
|
|
11
|
+
* thin-lens FOV for comparison. A breathingProjectionScale of 1 reproduces the focus-aware thin-lens
|
|
12
|
+
* FOV exactly.
|
|
13
|
+
*
|
|
14
|
+
* The geometric model derives breathing from ideal focusing geometry instead of a declared scale.
|
|
15
|
+
* @see docs/PHYSICS_FOUNDATION.md for the equations, units, coordinate conventions, known blockers
|
|
16
|
+
* and support limits.
|
|
13
17
|
*/
|
|
14
18
|
import { type CalculationResult } from "../core/calculation-result.js";
|
|
15
19
|
export interface CalculateFocusBreathingProjectionInput {
|
|
@@ -21,9 +25,9 @@ export interface CalculateFocusBreathingProjectionInput {
|
|
|
21
25
|
* Caller-declared projection scale for this focus state, relative to the
|
|
22
26
|
* ideal thin-lens image distance.
|
|
23
27
|
*
|
|
24
|
-
* 1 means no
|
|
25
|
-
*
|
|
26
|
-
*
|
|
28
|
+
* 1 means no breathing beyond the thin-lens model. Values above 1 narrow the
|
|
29
|
+
* framing (more magnification). Values below 1 widen it (less
|
|
30
|
+
* magnification).
|
|
27
31
|
*/
|
|
28
32
|
breathingProjectionScale: number;
|
|
29
33
|
}
|
|
@@ -36,8 +40,8 @@ export interface FocusBreathingProjection {
|
|
|
36
40
|
/**
|
|
37
41
|
* Effective projection distance used by the generic breathing model.
|
|
38
42
|
*
|
|
39
|
-
* This is a projection
|
|
40
|
-
* focal length.
|
|
43
|
+
* This is a projection (magnification) parameter. It does not replace the
|
|
44
|
+
* physical focal length.
|
|
41
45
|
*/
|
|
42
46
|
effectiveProjectionDistanceMm: number;
|
|
43
47
|
/** Caller-declared scale relative to ideal thin-lens projection. */
|
|
@@ -66,21 +70,78 @@ export interface FocusBreathingFieldOfView {
|
|
|
66
70
|
* Applies a caller-declared focus-breathing projection scale to the ideal
|
|
67
71
|
* Gaussian thin-lens projection for one focus state.
|
|
68
72
|
*
|
|
69
|
-
* Photivra does not
|
|
70
|
-
* identity
|
|
71
|
-
*
|
|
73
|
+
* Photivra does not guess the scale from focal length, focus distance, lens
|
|
74
|
+
* identity or marketing data. A scale of 1 keeps the thin-lens projection
|
|
75
|
+
* exactly.
|
|
72
76
|
*
|
|
73
|
-
* This is a generic approximation of
|
|
74
|
-
* not a calibrated real-lens model. The physical focal
|
|
75
|
-
*
|
|
77
|
+
* This is a generic approximation of how projection and magnification change
|
|
78
|
+
* with focus. It is not a calibrated real-lens model. The physical focal
|
|
79
|
+
* length is never changed and stays authoritative.
|
|
76
80
|
*/
|
|
77
81
|
export declare function calculateFocusBreathingProjection(input: CalculateFocusBreathingProjectionInput): CalculationResult<FocusBreathingProjection>;
|
|
78
82
|
/**
|
|
79
|
-
* Calculates one-axis field of view
|
|
80
|
-
* breathing
|
|
83
|
+
* Calculates the one-axis field of view under the declared-scale
|
|
84
|
+
* focus-breathing model, and reports the ideal thin-lens field of view for
|
|
85
|
+
* comparison.
|
|
81
86
|
*
|
|
82
|
-
* A breathingProjectionScale of 1 reproduces the
|
|
83
|
-
*
|
|
87
|
+
* A breathingProjectionScale of 1 reproduces the focus-aware thin-lens field
|
|
88
|
+
* of view exactly.
|
|
84
89
|
*/
|
|
85
90
|
export declare function calculateFocusBreathingFieldOfView(input: CalculateFocusBreathingFieldOfViewInput): CalculationResult<FocusBreathingFieldOfView>;
|
|
86
|
-
|
|
91
|
+
/** Ideal focusing geometry for {@link calculateGeometricFocusBreathing}. */
|
|
92
|
+
export type GeometricFocusingMethod = "unit-focus" | "fixed-image-distance-internal-focus";
|
|
93
|
+
export interface CalculateGeometricFocusBreathingInput {
|
|
94
|
+
/** Focal length at infinity focus, mm. */
|
|
95
|
+
focalLengthMm: number;
|
|
96
|
+
/**
|
|
97
|
+
* Photographic focus distance measured from the subject plane to the sensor (image) plane, in
|
|
98
|
+
* metres, as marked on lens distance scales.
|
|
99
|
+
*/
|
|
100
|
+
subjectToSensorDistanceM: number;
|
|
101
|
+
/** Sensor/capture dimension along the axis of interest, mm. */
|
|
102
|
+
sensorDimensionMm: number;
|
|
103
|
+
focusingMethod: GeometricFocusingMethod;
|
|
104
|
+
/**
|
|
105
|
+
* Signed distance between the front and rear principal planes (the "hiatus"), in mm. Default 0
|
|
106
|
+
* (thin lens). The subject-to-sensor distance is u + hiatus + v.
|
|
107
|
+
*/
|
|
108
|
+
principalPlaneSeparationMm?: number;
|
|
109
|
+
}
|
|
110
|
+
export interface GeometricFocusBreathing {
|
|
111
|
+
focusingMethod: GeometricFocusingMethod;
|
|
112
|
+
infinityFocalLengthMm: number;
|
|
113
|
+
/** Focal length of the focused system (changes only for internal focus), mm. */
|
|
114
|
+
effectiveFocalLengthMm: number;
|
|
115
|
+
/** Subject distance from the front principal plane, mm. */
|
|
116
|
+
objectDistanceMm: number;
|
|
117
|
+
/** Rear principal plane to sensor distance (projection distance), mm. */
|
|
118
|
+
imageDistanceMm: number;
|
|
119
|
+
/** Lateral magnification v / u. */
|
|
120
|
+
magnification: number;
|
|
121
|
+
/** v / f_infinity: framing scale relative to infinity focus. */
|
|
122
|
+
projectionScaleRelativeToInfinity: number;
|
|
123
|
+
/**
|
|
124
|
+
* v divided by the ideal thin-lens image distance, at objectDistanceMm, of a lens with the same
|
|
125
|
+
* infinity focal length. Exactly 1 for unit focus. You can pass it as breathingProjectionScale to
|
|
126
|
+
* calculateFocusBreathingProjection() with focusDistanceM = objectDistanceMm / 1000.
|
|
127
|
+
*/
|
|
128
|
+
equivalentBreathingProjectionScale: number;
|
|
129
|
+
fieldOfViewDegrees: number;
|
|
130
|
+
infinityFieldOfViewDegrees: number;
|
|
131
|
+
deltaDegrees: number;
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Focus breathing derived from ideal focusing geometry, instead of a declared scale.
|
|
135
|
+
*
|
|
136
|
+
* - unit-focus: the whole lens moves. u + v = L - hiatus and 1/u + 1/v = 1/f, so
|
|
137
|
+
* v = (T - sqrt(T^2 - 4 f T)) / 2, where T = L - hiatus >= 4 f. The field narrows as v grows.
|
|
138
|
+
* - fixed-image-distance-internal-focus: an idealised internal-focus lens keeps the rear principal
|
|
139
|
+
* plane at v = f_infinity and shortens its focal length to f' = u v / (u + v). The angular field
|
|
140
|
+
* at the rear nodal point then stays the same, and the magnification is f_infinity / u.
|
|
141
|
+
* Both use paraxial Gaussian optics with the nodal points at the principal planes (unit pupil
|
|
142
|
+
* magnification; Greivenkamp, OPTI-502 course notes, University of Arizona, sec. 3 and 5, free. Also
|
|
143
|
+
* see: Kingslake & Johnson, Lens Design Fundamentals, 2nd ed., ch. 3; Ray, Applied Photographic
|
|
144
|
+
* Optics, 3rd ed., ch. 9 and 14). Real internal-focus lenses also move their pupils and
|
|
145
|
+
* principal planes, so modelling their breathing needs a calibrated profile.
|
|
146
|
+
*/
|
|
147
|
+
export declare function calculateGeometricFocusBreathing(input: CalculateGeometricFocusBreathingInput): CalculationResult<GeometricFocusBreathing>;
|
|
@@ -1,33 +1,40 @@
|
|
|
1
1
|
// SPDX-License-Identifier: Apache-2.0
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
3
|
+
* Focus breathing: the change in framing (magnification) as a lens focuses.
|
|
4
|
+
*
|
|
5
|
+
* The declared-scale model applies a caller-supplied projection scale to the ideal Gaussian thin-lens
|
|
6
|
+
* projection for one focus state. Photivra does not guess the scale from focal length, focus
|
|
7
|
+
* distance, lens identity or marketing data. A scale of 1 keeps the thin-lens projection exactly.
|
|
8
|
+
* This is a generic approximation of how projection and magnification change with focus. It is not a
|
|
9
|
+
* calibrated real-lens model. The physical focal length is never changed and stays authoritative.
|
|
10
|
+
*
|
|
11
|
+
* The field-of-view function gives the one-axis field of view (FOV) under this model, and the ideal
|
|
12
|
+
* thin-lens FOV for comparison. A breathingProjectionScale of 1 reproduces the focus-aware thin-lens
|
|
13
|
+
* FOV exactly.
|
|
14
|
+
*
|
|
15
|
+
* The geometric model derives breathing from ideal focusing geometry instead of a declared scale.
|
|
16
|
+
* @see docs/PHYSICS_FOUNDATION.md for the equations, units, coordinate conventions, known blockers
|
|
17
|
+
* and support limits.
|
|
14
18
|
*/
|
|
15
19
|
import { approximationResult } from "../core/calculation-result.js";
|
|
16
|
-
import { requirePositiveFinite } from "../core/validation.js";
|
|
20
|
+
import { InvalidScientificInputError, requirePositiveFinite } from "../core/validation.js";
|
|
17
21
|
import { calculateThinLensImageDistance } from "./thin-lens.js";
|
|
22
|
+
import { requireInputKeys } from "../core/record-validation.js";
|
|
23
|
+
import { InvalidConfigurationError } from "../core/configuration-error.js";
|
|
18
24
|
/**
|
|
19
25
|
* Applies a caller-declared focus-breathing projection scale to the ideal
|
|
20
26
|
* Gaussian thin-lens projection for one focus state.
|
|
21
27
|
*
|
|
22
|
-
* Photivra does not
|
|
23
|
-
* identity
|
|
24
|
-
*
|
|
28
|
+
* Photivra does not guess the scale from focal length, focus distance, lens
|
|
29
|
+
* identity or marketing data. A scale of 1 keeps the thin-lens projection
|
|
30
|
+
* exactly.
|
|
25
31
|
*
|
|
26
|
-
* This is a generic approximation of
|
|
27
|
-
* not a calibrated real-lens model. The physical focal
|
|
28
|
-
*
|
|
32
|
+
* This is a generic approximation of how projection and magnification change
|
|
33
|
+
* with focus. It is not a calibrated real-lens model. The physical focal
|
|
34
|
+
* length is never changed and stays authoritative.
|
|
29
35
|
*/
|
|
30
36
|
export function calculateFocusBreathingProjection(input) {
|
|
37
|
+
requireInputKeys(input, "calculateFocusBreathingProjection", ["focalLengthMm", "focusDistanceM", "breathingProjectionScale"]);
|
|
31
38
|
requirePositiveFinite("focalLengthMm", input.focalLengthMm);
|
|
32
39
|
requirePositiveFinite("focusDistanceM", input.focusDistanceM);
|
|
33
40
|
requirePositiveFinite("breathingProjectionScale", input.breathingProjectionScale);
|
|
@@ -55,15 +62,21 @@ export function calculateFocusBreathingProjection(input) {
|
|
|
55
62
|
]);
|
|
56
63
|
}
|
|
57
64
|
/**
|
|
58
|
-
* Calculates one-axis field of view
|
|
59
|
-
* breathing
|
|
65
|
+
* Calculates the one-axis field of view under the declared-scale
|
|
66
|
+
* focus-breathing model, and reports the ideal thin-lens field of view for
|
|
67
|
+
* comparison.
|
|
60
68
|
*
|
|
61
|
-
* A breathingProjectionScale of 1 reproduces the
|
|
62
|
-
*
|
|
69
|
+
* A breathingProjectionScale of 1 reproduces the focus-aware thin-lens field
|
|
70
|
+
* of view exactly.
|
|
63
71
|
*/
|
|
64
72
|
export function calculateFocusBreathingFieldOfView(input) {
|
|
73
|
+
requireInputKeys(input, "calculateFocusBreathingFieldOfView", ["sensorDimensionMm", "focalLengthMm", "focusDistanceM", "breathingProjectionScale"]);
|
|
65
74
|
requirePositiveFinite("sensorDimensionMm", input.sensorDimensionMm);
|
|
66
|
-
const projection = calculateFocusBreathingProjection(
|
|
75
|
+
const projection = calculateFocusBreathingProjection({
|
|
76
|
+
focalLengthMm: input.focalLengthMm,
|
|
77
|
+
focusDistanceM: input.focusDistanceM,
|
|
78
|
+
breathingProjectionScale: input.breathingProjectionScale
|
|
79
|
+
});
|
|
67
80
|
const idealRadians = 2 *
|
|
68
81
|
Math.atan(input.sensorDimensionMm /
|
|
69
82
|
(2 * projection.value.idealProjectionDistanceMm));
|
|
@@ -87,4 +100,82 @@ export function calculateFocusBreathingFieldOfView(input) {
|
|
|
87
100
|
"Rectilinear field of view is calculated from the declared sensor/capture dimension and effective projection distance"
|
|
88
101
|
]);
|
|
89
102
|
}
|
|
103
|
+
/**
|
|
104
|
+
* Focus breathing derived from ideal focusing geometry, instead of a declared scale.
|
|
105
|
+
*
|
|
106
|
+
* - unit-focus: the whole lens moves. u + v = L - hiatus and 1/u + 1/v = 1/f, so
|
|
107
|
+
* v = (T - sqrt(T^2 - 4 f T)) / 2, where T = L - hiatus >= 4 f. The field narrows as v grows.
|
|
108
|
+
* - fixed-image-distance-internal-focus: an idealised internal-focus lens keeps the rear principal
|
|
109
|
+
* plane at v = f_infinity and shortens its focal length to f' = u v / (u + v). The angular field
|
|
110
|
+
* at the rear nodal point then stays the same, and the magnification is f_infinity / u.
|
|
111
|
+
* Both use paraxial Gaussian optics with the nodal points at the principal planes (unit pupil
|
|
112
|
+
* magnification; Greivenkamp, OPTI-502 course notes, University of Arizona, sec. 3 and 5, free. Also
|
|
113
|
+
* see: Kingslake & Johnson, Lens Design Fundamentals, 2nd ed., ch. 3; Ray, Applied Photographic
|
|
114
|
+
* Optics, 3rd ed., ch. 9 and 14). Real internal-focus lenses also move their pupils and
|
|
115
|
+
* principal planes, so modelling their breathing needs a calibrated profile.
|
|
116
|
+
*/
|
|
117
|
+
export function calculateGeometricFocusBreathing(input) {
|
|
118
|
+
requireInputKeys(input, "calculateGeometricFocusBreathing", ["focalLengthMm", "subjectToSensorDistanceM", "sensorDimensionMm", "focusingMethod", "principalPlaneSeparationMm"]);
|
|
119
|
+
requirePositiveFinite("focalLengthMm", input.focalLengthMm);
|
|
120
|
+
requirePositiveFinite("subjectToSensorDistanceM", input.subjectToSensorDistanceM);
|
|
121
|
+
requirePositiveFinite("sensorDimensionMm", input.sensorDimensionMm);
|
|
122
|
+
const hiatus = input.principalPlaneSeparationMm ?? 0;
|
|
123
|
+
if (typeof hiatus !== "number" || !Number.isFinite(hiatus)) {
|
|
124
|
+
throw new InvalidScientificInputError("principalPlaneSeparationMm must be finite.");
|
|
125
|
+
}
|
|
126
|
+
const f = input.focalLengthMm;
|
|
127
|
+
const conjugateSum = input.subjectToSensorDistanceM * 1000 - hiatus;
|
|
128
|
+
let imageDistanceMm;
|
|
129
|
+
let objectDistanceMm;
|
|
130
|
+
let effectiveFocalLengthMm;
|
|
131
|
+
if (input.focusingMethod === "unit-focus") {
|
|
132
|
+
if (!(conjugateSum >= 4 * f)) {
|
|
133
|
+
throw new InvalidScientificInputError("Unit focus requires subject-to-sensor distance minus hiatus of at least 4 x focal length (1:1 limit).");
|
|
134
|
+
}
|
|
135
|
+
// Stable smaller root of v^2 - T v + f T = 0: v = 2 f T / (T + sqrt(T^2 - 4 f T)).
|
|
136
|
+
imageDistanceMm =
|
|
137
|
+
(2 * f * conjugateSum) /
|
|
138
|
+
(conjugateSum + Math.sqrt(conjugateSum * conjugateSum - 4 * f * conjugateSum));
|
|
139
|
+
objectDistanceMm = conjugateSum - imageDistanceMm;
|
|
140
|
+
effectiveFocalLengthMm = f;
|
|
141
|
+
}
|
|
142
|
+
else if (input.focusingMethod === "fixed-image-distance-internal-focus") {
|
|
143
|
+
imageDistanceMm = f;
|
|
144
|
+
objectDistanceMm = conjugateSum - f;
|
|
145
|
+
if (!(objectDistanceMm > f)) {
|
|
146
|
+
throw new InvalidScientificInputError("Internal focus requires the subject to lie more than one focal length in front of the lens.");
|
|
147
|
+
}
|
|
148
|
+
effectiveFocalLengthMm = (objectDistanceMm * f) / (objectDistanceMm + f);
|
|
149
|
+
}
|
|
150
|
+
else {
|
|
151
|
+
throw new InvalidConfigurationError("focusingMethod must be unit-focus or fixed-image-distance-internal-focus.");
|
|
152
|
+
}
|
|
153
|
+
const thinLens = calculateThinLensImageDistance({
|
|
154
|
+
focalLengthMm: f,
|
|
155
|
+
objectDistanceM: objectDistanceMm / 1000
|
|
156
|
+
}).value.imageDistanceMm;
|
|
157
|
+
const fov = (projection) => (2 * Math.atan(input.sensorDimensionMm / (2 * projection)) * 180) / Math.PI;
|
|
158
|
+
const fieldOfViewDegrees = fov(imageDistanceMm);
|
|
159
|
+
const infinityFieldOfViewDegrees = fov(f);
|
|
160
|
+
return approximationResult({
|
|
161
|
+
focusingMethod: input.focusingMethod,
|
|
162
|
+
infinityFocalLengthMm: f,
|
|
163
|
+
effectiveFocalLengthMm,
|
|
164
|
+
objectDistanceMm,
|
|
165
|
+
imageDistanceMm,
|
|
166
|
+
magnification: imageDistanceMm / objectDistanceMm,
|
|
167
|
+
projectionScaleRelativeToInfinity: imageDistanceMm / f,
|
|
168
|
+
equivalentBreathingProjectionScale: input.focusingMethod === "unit-focus" ? 1 : imageDistanceMm / thinLens,
|
|
169
|
+
fieldOfViewDegrees,
|
|
170
|
+
infinityFieldOfViewDegrees,
|
|
171
|
+
deltaDegrees: fieldOfViewDegrees - infinityFieldOfViewDegrees
|
|
172
|
+
}, "geometric-focus-breathing", "1.0.0", [
|
|
173
|
+
"Paraxial Gaussian optics with nodal points at the principal planes (unit pupil magnification)",
|
|
174
|
+
input.focusingMethod === "unit-focus"
|
|
175
|
+
? "Unit focus: the whole lens moves; focal length is constant"
|
|
176
|
+
: "Idealised internal focus: image distance fixed at the infinity focal length; focal length shortens",
|
|
177
|
+
"Subject-to-sensor distance = object distance + principal-plane separation + image distance",
|
|
178
|
+
"Rectilinear field of view from the rear-principal-plane projection distance; distortion, pupil shifts and named-lens behaviour are not modeled"
|
|
179
|
+
]);
|
|
180
|
+
}
|
|
90
181
|
//# sourceMappingURL=focus-breathing.js.map
|