@photivra/engine 1.4.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1074) hide show
  1. package/CHANGELOG.md +401 -6
  2. package/CITATION.cff +1 -1
  3. package/NODE_SUPPORT.md +64 -12
  4. package/README.md +301 -182
  5. package/SECURITY.md +37 -28
  6. package/THIRD_PARTY.md +148 -4
  7. package/dist/camera/equivalent-focal-length.d.ts +13 -14
  8. package/dist/camera/equivalent-focal-length.js +15 -13
  9. package/dist/camera/equivalent-focal-length.js.map +1 -1
  10. package/dist/camera/field-of-view.d.ts +30 -19
  11. package/dist/camera/field-of-view.js +67 -18
  12. package/dist/camera/field-of-view.js.map +1 -1
  13. package/dist/camera/lens-projection.d.ts +170 -0
  14. package/dist/camera/lens-projection.js +444 -0
  15. package/dist/camera/lens-projection.js.map +1 -0
  16. package/dist/camera/projected-object-size.d.ts +10 -11
  17. package/dist/camera/projected-object-size.js +12 -10
  18. package/dist/camera/projected-object-size.js.map +1 -1
  19. package/dist/capture/capture-export-metadata.d.ts +9 -10
  20. package/dist/capture/capture-export-metadata.js +8 -5
  21. package/dist/capture/capture-export-metadata.js.map +1 -1
  22. package/dist/capture/dng-import.d.ts +91 -0
  23. package/dist/capture/dng-import.js +343 -0
  24. package/dist/capture/dng-import.js.map +1 -0
  25. package/dist/capture/environment-raw-producer.d.ts +37 -17
  26. package/dist/capture/environment-raw-producer.js +43 -19
  27. package/dist/capture/environment-raw-producer.js.map +1 -1
  28. package/dist/capture/export-jpeg.d.ts +35 -4
  29. package/dist/capture/export-jpeg.js +133 -47
  30. package/dist/capture/export-jpeg.js.map +1 -1
  31. package/dist/capture/export-tiff.d.ts +48 -24
  32. package/dist/capture/export-tiff.js +91 -31
  33. package/dist/capture/export-tiff.js.map +1 -1
  34. package/dist/capture/focus-control.d.ts +42 -65
  35. package/dist/capture/focus-control.js +56 -75
  36. package/dist/capture/focus-control.js.map +1 -1
  37. package/dist/capture/host-yield-cadence.d.ts +25 -0
  38. package/dist/capture/host-yield-cadence.js +25 -0
  39. package/dist/capture/host-yield-cadence.js.map +1 -0
  40. package/dist/capture/linear-encoding.d.ts +14 -12
  41. package/dist/capture/linear-encoding.js +14 -13
  42. package/dist/capture/linear-encoding.js.map +1 -1
  43. package/dist/capture/lossless-jpeg.d.ts +27 -0
  44. package/dist/capture/lossless-jpeg.js +237 -0
  45. package/dist/capture/lossless-jpeg.js.map +1 -0
  46. package/dist/capture/native-environment-lean.d.ts +227 -0
  47. package/dist/capture/native-environment-lean.js +974 -0
  48. package/dist/capture/native-environment-lean.js.map +1 -0
  49. package/dist/capture/native-environment-optical-stage.d.ts +97 -0
  50. package/dist/capture/native-environment-optical-stage.js +340 -0
  51. package/dist/capture/native-environment-optical-stage.js.map +1 -0
  52. package/dist/capture/native-environment-raw.d.ts +140 -6
  53. package/dist/capture/native-environment-raw.js +435 -34
  54. package/dist/capture/native-environment-raw.js.map +1 -1
  55. package/dist/capture/native-raw-development.d.ts +118 -5
  56. package/dist/capture/native-raw-development.js +224 -59
  57. package/dist/capture/native-raw-development.js.map +1 -1
  58. package/dist/capture/native-raw-dng.d.ts +60 -0
  59. package/dist/capture/native-raw-dng.js +167 -0
  60. package/dist/capture/native-raw-dng.js.map +1 -0
  61. package/dist/capture/native-raw.d.ts +67 -10
  62. package/dist/capture/native-raw.js +90 -24
  63. package/dist/capture/native-raw.js.map +1 -1
  64. package/dist/capture/packed-sensor-raw.d.ts +160 -0
  65. package/dist/capture/packed-sensor-raw.js +221 -0
  66. package/dist/capture/packed-sensor-raw.js.map +1 -0
  67. package/dist/capture/photographic-export.d.ts +58 -35
  68. package/dist/capture/photographic-export.js +177 -70
  69. package/dist/capture/photographic-export.js.map +1 -1
  70. package/dist/capture/raw-development-kernel.d.ts +52 -0
  71. package/dist/capture/raw-development-kernel.js +88 -0
  72. package/dist/capture/raw-development-kernel.js.map +1 -0
  73. package/dist/capture/raw-frame-limits.d.ts +7 -7
  74. package/dist/capture/raw-frame-limits.js +7 -6
  75. package/dist/capture/raw-frame-limits.js.map +1 -1
  76. package/dist/capture/raw-frame-reconstruction.d.ts +8 -9
  77. package/dist/capture/raw-frame-reconstruction.js +9 -8
  78. package/dist/capture/raw-frame-reconstruction.js.map +1 -1
  79. package/dist/capture/raw-white-level.d.ts +55 -0
  80. package/dist/capture/raw-white-level.js +165 -0
  81. package/dist/capture/raw-white-level.js.map +1 -0
  82. package/dist/capture/release-sequence.d.ts +5 -7
  83. package/dist/capture/release-sequence.js +15 -13
  84. package/dist/capture/release-sequence.js.map +1 -1
  85. package/dist/capture/sensor-raw-frame.d.ts +5 -6
  86. package/dist/capture/sensor-raw-frame.js +26 -9
  87. package/dist/capture/sensor-raw-frame.js.map +1 -1
  88. package/dist/capture/sensor-raw-producer.d.ts +21 -13
  89. package/dist/capture/sensor-raw-producer.js +86 -25
  90. package/dist/capture/sensor-raw-producer.js.map +1 -1
  91. package/dist/capture/simulated-capture.d.ts +15 -16
  92. package/dist/capture/simulated-capture.js +22 -12
  93. package/dist/capture/simulated-capture.js.map +1 -1
  94. package/dist/color/camera-color-matrix.d.ts +69 -0
  95. package/dist/color/camera-color-matrix.js +132 -0
  96. package/dist/color/camera-color-matrix.js.map +1 -0
  97. package/dist/color/capture-color.d.ts +17 -10
  98. package/dist/color/capture-color.js +50 -17
  99. package/dist/color/capture-color.js.map +1 -1
  100. package/dist/color/chromatic-adaptation.d.ts +63 -0
  101. package/dist/color/chromatic-adaptation.js +91 -0
  102. package/dist/color/chromatic-adaptation.js.map +1 -0
  103. package/dist/color/color-difference.d.ts +104 -0
  104. package/dist/color/color-difference.js +205 -0
  105. package/dist/color/color-difference.js.map +1 -0
  106. package/dist/color/color-matching-functions.d.ts +168 -0
  107. package/dist/color/color-matching-functions.js +309 -0
  108. package/dist/color/color-matching-functions.js.map +1 -0
  109. package/dist/color/colorimetry-math.d.ts +52 -0
  110. package/dist/color/colorimetry-math.js +144 -0
  111. package/dist/color/colorimetry-math.js.map +1 -0
  112. package/dist/color/gamut-mapping.d.ts +54 -0
  113. package/dist/color/gamut-mapping.js +107 -0
  114. package/dist/color/gamut-mapping.js.map +1 -0
  115. package/dist/color/illuminants.d.ts +182 -0
  116. package/dist/color/illuminants.js +434 -0
  117. package/dist/color/illuminants.js.map +1 -0
  118. package/dist/color/rgb-color-spaces.d.ts +79 -0
  119. package/dist/color/rgb-color-spaces.js +115 -0
  120. package/dist/color/rgb-color-spaces.js.map +1 -0
  121. package/dist/color/sensor-color-development.d.ts +33 -11
  122. package/dist/color/sensor-color-development.js +104 -30
  123. package/dist/color/sensor-color-development.js.map +1 -1
  124. package/dist/color/srgb-icc.d.ts +9 -2
  125. package/dist/color/srgb-icc.js +16 -5
  126. package/dist/color/srgb-icc.js.map +1 -1
  127. package/dist/color/srgb-transfer.d.ts +1 -2
  128. package/dist/color/srgb-transfer.js +1 -1
  129. package/dist/color/srgb-transfer.js.map +1 -1
  130. package/dist/color/white-balance.d.ts +68 -19
  131. package/dist/color/white-balance.js +168 -35
  132. package/dist/color/white-balance.js.map +1 -1
  133. package/dist/composition/image-formation-plan.d.ts +152 -128
  134. package/dist/composition/image-formation-plan.js +292 -138
  135. package/dist/composition/image-formation-plan.js.map +1 -1
  136. package/dist/composition/plan-consumer.d.ts +6 -7
  137. package/dist/composition/plan-consumer.js +14 -11
  138. package/dist/composition/plan-consumer.js.map +1 -1
  139. package/dist/core/calculation-result.d.ts +21 -14
  140. package/dist/core/calculation-result.js +209 -11
  141. package/dist/core/calculation-result.js.map +1 -1
  142. package/dist/core/canonical-json.d.ts +13 -8
  143. package/dist/core/canonical-json.js +34 -15
  144. package/dist/core/canonical-json.js.map +1 -1
  145. package/dist/core/configuration-error.d.ts +5 -4
  146. package/dist/core/configuration-error.js +5 -3
  147. package/dist/core/configuration-error.js.map +1 -1
  148. package/dist/core/evidence-provenance.d.ts +12 -12
  149. package/dist/core/evidence-provenance.js +10 -9
  150. package/dist/core/evidence-provenance.js.map +1 -1
  151. package/dist/core/image-formation.d.ts +11 -10
  152. package/dist/core/image-formation.js +11 -9
  153. package/dist/core/image-formation.js.map +1 -1
  154. package/dist/core/owned-data.d.ts +9 -17
  155. package/dist/core/owned-data.js +9 -16
  156. package/dist/core/owned-data.js.map +1 -1
  157. package/dist/core/portable-math.d.ts +15 -0
  158. package/dist/core/portable-math.js +56 -0
  159. package/dist/core/portable-math.js.map +1 -0
  160. package/dist/core/record-validation.d.ts +48 -9
  161. package/dist/core/record-validation.js +93 -19
  162. package/dist/core/record-validation.js.map +1 -1
  163. package/dist/core/scientific-assurance.d.ts +16 -14
  164. package/dist/core/scientific-assurance.js +22 -18
  165. package/dist/core/scientific-assurance.js.map +1 -1
  166. package/dist/core/spectral-composition.d.ts +13 -14
  167. package/dist/core/spectral-composition.js +30 -27
  168. package/dist/core/spectral-composition.js.map +1 -1
  169. package/dist/core/spectral.d.ts +5 -6
  170. package/dist/core/spectral.js +9 -7
  171. package/dist/core/spectral.js.map +1 -1
  172. package/dist/core/validation.d.ts +3 -6
  173. package/dist/core/validation.js +3 -5
  174. package/dist/core/validation.js.map +1 -1
  175. package/dist/core/version.d.ts +6 -6
  176. package/dist/core/version.js +6 -5
  177. package/dist/core/version.js.map +1 -1
  178. package/dist/equipment/exposure-capabilities.d.ts +10 -10
  179. package/dist/equipment/exposure-capabilities.js +40 -30
  180. package/dist/equipment/exposure-capabilities.js.map +1 -1
  181. package/dist/equipment/generic-tier-assets.d.ts +13 -6
  182. package/dist/equipment/generic-tier-assets.js +34 -15
  183. package/dist/equipment/generic-tier-assets.js.map +1 -1
  184. package/dist/equipment/generic-tier-presets.d.ts +5 -6
  185. package/dist/equipment/generic-tier-presets.js +15 -13
  186. package/dist/equipment/generic-tier-presets.js.map +1 -1
  187. package/dist/equipment/iso-capabilities.d.ts +21 -22
  188. package/dist/equipment/iso-capabilities.js +49 -44
  189. package/dist/equipment/iso-capabilities.js.map +1 -1
  190. package/dist/equipment/metering-capabilities.d.ts +5 -6
  191. package/dist/equipment/metering-capabilities.js +22 -19
  192. package/dist/equipment/metering-capabilities.js.map +1 -1
  193. package/dist/equipment/release-capabilities.d.ts +3 -4
  194. package/dist/equipment/release-capabilities.js +18 -14
  195. package/dist/equipment/release-capabilities.js.map +1 -1
  196. package/dist/exposure/exposure-duration-control.d.ts +19 -17
  197. package/dist/exposure/exposure-duration-control.js +27 -23
  198. package/dist/exposure/exposure-duration-control.js.map +1 -1
  199. package/dist/exposure/exposure-mode-resolver.d.ts +42 -39
  200. package/dist/exposure/exposure-mode-resolver.js +127 -82
  201. package/dist/exposure/exposure-mode-resolver.js.map +1 -1
  202. package/dist/exposure/exposure.d.ts +17 -16
  203. package/dist/exposure/exposure.js +22 -15
  204. package/dist/exposure/exposure.js.map +1 -1
  205. package/dist/exposure/flash-ttl.d.ts +135 -0
  206. package/dist/exposure/flash-ttl.js +193 -0
  207. package/dist/exposure/flash-ttl.js.map +1 -0
  208. package/dist/exposure/flash.d.ts +144 -36
  209. package/dist/exposure/flash.js +259 -59
  210. package/dist/exposure/flash.js.map +1 -1
  211. package/dist/exposure/metering-scene-radiance.d.ts +10 -10
  212. package/dist/exposure/metering-scene-radiance.js +42 -23
  213. package/dist/exposure/metering-scene-radiance.js.map +1 -1
  214. package/dist/exposure/metering-target.d.ts +8 -8
  215. package/dist/exposure/metering-target.js +30 -20
  216. package/dist/exposure/metering-target.js.map +1 -1
  217. package/dist/exposure/metering-temporal.d.ts +16 -15
  218. package/dist/exposure/metering-temporal.js +41 -19
  219. package/dist/exposure/metering-temporal.js.map +1 -1
  220. package/dist/exposure/metering.d.ts +64 -17
  221. package/dist/exposure/metering.js +159 -30
  222. package/dist/exposure/metering.js.map +1 -1
  223. package/dist/exposure/program-line.d.ts +5 -5
  224. package/dist/exposure/program-line.js +20 -13
  225. package/dist/exposure/program-line.js.map +1 -1
  226. package/dist/facade/camera-preset.d.ts +8 -0
  227. package/dist/facade/camera-preset.js +102 -0
  228. package/dist/facade/camera-preset.js.map +1 -0
  229. package/dist/facade/chart-radiance-batch.d.ts +57 -0
  230. package/dist/facade/chart-radiance-batch.js +121 -0
  231. package/dist/facade/chart-radiance-batch.js.map +1 -0
  232. package/dist/facade/chart-scenes.d.ts +177 -0
  233. package/dist/facade/chart-scenes.js +232 -0
  234. package/dist/facade/chart-scenes.js.map +1 -0
  235. package/dist/facade/host-yield.d.ts +7 -0
  236. package/dist/facade/host-yield.js +23 -0
  237. package/dist/facade/host-yield.js.map +1 -0
  238. package/dist/facade/scene-radiance.d.ts +117 -0
  239. package/dist/facade/scene-radiance.js +205 -0
  240. package/dist/facade/scene-radiance.js.map +1 -0
  241. package/dist/facade/simulate-capture.d.ts +284 -0
  242. package/dist/facade/simulate-capture.js +1026 -0
  243. package/dist/facade/simulate-capture.js.map +1 -0
  244. package/dist/gpu/chart-radiance-gpu.d.ts +17 -0
  245. package/dist/gpu/chart-radiance-gpu.js +176 -0
  246. package/dist/gpu/chart-radiance-gpu.js.map +1 -0
  247. package/dist/gpu/image-kernel-accelerator.d.ts +132 -0
  248. package/dist/gpu/image-kernel-accelerator.js +720 -0
  249. package/dist/gpu/image-kernel-accelerator.js.map +1 -0
  250. package/dist/gpu/image-kernel-execution.d.ts +92 -0
  251. package/dist/gpu/image-kernel-execution.js +84 -0
  252. package/dist/gpu/image-kernel-execution.js.map +1 -0
  253. package/dist/gpu/sensor-stage-gpu.d.ts +44 -0
  254. package/dist/gpu/sensor-stage-gpu.js +317 -0
  255. package/dist/gpu/sensor-stage-gpu.js.map +1 -0
  256. package/dist/gpu/temporal-sum-gpu.d.ts +23 -0
  257. package/dist/gpu/temporal-sum-gpu.js +150 -0
  258. package/dist/gpu/temporal-sum-gpu.js.map +1 -0
  259. package/dist/gpu/webgpu-runtime.d.ts +63 -0
  260. package/dist/gpu/webgpu-runtime.js +215 -0
  261. package/dist/gpu/webgpu-runtime.js.map +1 -0
  262. package/dist/gpu/wgsl-chart-kernel.d.ts +30 -0
  263. package/dist/gpu/wgsl-chart-kernel.js +165 -0
  264. package/dist/gpu/wgsl-chart-kernel.js.map +1 -0
  265. package/dist/gpu/wgsl-kernels.d.ts +53 -0
  266. package/dist/gpu/wgsl-kernels.js +365 -0
  267. package/dist/gpu/wgsl-kernels.js.map +1 -0
  268. package/dist/gpu/wgsl-sensor-kernel.d.ts +64 -0
  269. package/dist/gpu/wgsl-sensor-kernel.js +409 -0
  270. package/dist/gpu/wgsl-sensor-kernel.js.map +1 -0
  271. package/dist/index.d.ts +89 -25
  272. package/dist/index.js +59 -15
  273. package/dist/index.js.map +1 -1
  274. package/dist/motion/camera-rotation.d.ts +92 -40
  275. package/dist/motion/camera-rotation.js +84 -47
  276. package/dist/motion/camera-rotation.js.map +1 -1
  277. package/dist/motion/capture-rotation-inverse-mapping.d.ts +37 -34
  278. package/dist/motion/capture-rotation-inverse-mapping.js +32 -24
  279. package/dist/motion/capture-rotation-inverse-mapping.js.map +1 -1
  280. package/dist/motion/capture-rotation-temporal-quadrature.d.ts +39 -35
  281. package/dist/motion/capture-rotation-temporal-quadrature.js +37 -28
  282. package/dist/motion/capture-rotation-temporal-quadrature.js.map +1 -1
  283. package/dist/motion/capture-rotation-trajectory.d.ts +32 -28
  284. package/dist/motion/capture-rotation-trajectory.js +36 -26
  285. package/dist/motion/capture-rotation-trajectory.js.map +1 -1
  286. package/dist/motion/capture-translation-parallax-temporal-quadrature.d.ts +23 -21
  287. package/dist/motion/capture-translation-parallax-temporal-quadrature.js +33 -14
  288. package/dist/motion/capture-translation-parallax-temporal-quadrature.js.map +1 -1
  289. package/dist/motion/extended-object-projection.d.ts +19 -16
  290. package/dist/motion/extended-object-projection.js +38 -18
  291. package/dist/motion/extended-object-projection.js.map +1 -1
  292. package/dist/motion/projected-motion.d.ts +18 -17
  293. package/dist/motion/projected-motion.js +25 -17
  294. package/dist/motion/projected-motion.js.map +1 -1
  295. package/dist/motion/temporal-exposure-sum.d.ts +55 -0
  296. package/dist/motion/temporal-exposure-sum.js +141 -0
  297. package/dist/motion/temporal-exposure-sum.js.map +1 -0
  298. package/dist/motion/video-sequence.d.ts +111 -0
  299. package/dist/motion/video-sequence.js +179 -0
  300. package/dist/motion/video-sequence.js.map +1 -0
  301. package/dist/optics/aperture.d.ts +14 -15
  302. package/dist/optics/aperture.js +13 -11
  303. package/dist/optics/aperture.js.map +1 -1
  304. package/dist/optics/atmospheric-haze.d.ts +83 -0
  305. package/dist/optics/atmospheric-haze.js +113 -0
  306. package/dist/optics/atmospheric-haze.js.map +1 -0
  307. package/dist/optics/brown-conrady-distortion.d.ts +116 -0
  308. package/dist/optics/brown-conrady-distortion.js +291 -0
  309. package/dist/optics/brown-conrady-distortion.js.map +1 -0
  310. package/dist/optics/circle-of-confusion.d.ts +10 -10
  311. package/dist/optics/circle-of-confusion.js +15 -11
  312. package/dist/optics/circle-of-confusion.js.map +1 -1
  313. package/dist/optics/complex-pupil-psf.d.ts +64 -33
  314. package/dist/optics/complex-pupil-psf.js +190 -98
  315. package/dist/optics/complex-pupil-psf.js.map +1 -1
  316. package/dist/optics/depth-of-field.d.ts +25 -15
  317. package/dist/optics/depth-of-field.js +67 -27
  318. package/dist/optics/depth-of-field.js.map +1 -1
  319. package/dist/optics/diffraction.d.ts +14 -13
  320. package/dist/optics/diffraction.js +14 -10
  321. package/dist/optics/diffraction.js.map +1 -1
  322. package/dist/optics/focus-breathing.d.ts +88 -27
  323. package/dist/optics/focus-breathing.js +114 -23
  324. package/dist/optics/focus-breathing.js.map +1 -1
  325. package/dist/optics/focus-state.d.ts +18 -18
  326. package/dist/optics/focus-state.js +21 -15
  327. package/dist/optics/focus-state.js.map +1 -1
  328. package/dist/optics/front-of-lens-filter.d.ts +45 -14
  329. package/dist/optics/front-of-lens-filter.js +259 -88
  330. package/dist/optics/front-of-lens-filter.js.map +1 -1
  331. package/dist/optics/illumination-vignetting.d.ts +16 -17
  332. package/dist/optics/illumination-vignetting.js +40 -17
  333. package/dist/optics/illumination-vignetting.js.map +1 -1
  334. package/dist/optics/irradiance-convolution.d.ts +59 -0
  335. package/dist/optics/irradiance-convolution.js +138 -0
  336. package/dist/optics/irradiance-convolution.js.map +1 -0
  337. package/dist/optics/lateral-chromatic-aberration.d.ts +33 -30
  338. package/dist/optics/lateral-chromatic-aberration.js +33 -23
  339. package/dist/optics/lateral-chromatic-aberration.js.map +1 -1
  340. package/dist/optics/lens-psf-kernels.d.ts +89 -0
  341. package/dist/optics/lens-psf-kernels.js +175 -0
  342. package/dist/optics/lens-psf-kernels.js.map +1 -0
  343. package/dist/optics/lens-psf-profile.d.ts +78 -46
  344. package/dist/optics/lens-psf-profile.js +335 -124
  345. package/dist/optics/lens-psf-profile.js.map +1 -1
  346. package/dist/optics/longitudinal-chromatic-aberration.d.ts +102 -0
  347. package/dist/optics/longitudinal-chromatic-aberration.js +210 -0
  348. package/dist/optics/longitudinal-chromatic-aberration.js.map +1 -0
  349. package/dist/optics/polygon-diffraction.d.ts +80 -23
  350. package/dist/optics/polygon-diffraction.js +130 -25
  351. package/dist/optics/polygon-diffraction.js.map +1 -1
  352. package/dist/optics/profile-contract.d.ts +5 -6
  353. package/dist/optics/profile-contract.js +14 -11
  354. package/dist/optics/profile-contract.js.map +1 -1
  355. package/dist/optics/psf-foundation.d.ts +23 -23
  356. package/dist/optics/psf-foundation.js +24 -21
  357. package/dist/optics/psf-foundation.js.map +1 -1
  358. package/dist/optics/pupil-vignetting.d.ts +118 -0
  359. package/dist/optics/pupil-vignetting.js +264 -0
  360. package/dist/optics/pupil-vignetting.js.map +1 -0
  361. package/dist/optics/radial-distortion.d.ts +34 -33
  362. package/dist/optics/radial-distortion.js +37 -30
  363. package/dist/optics/radial-distortion.js.map +1 -1
  364. package/dist/optics/scene-to-sensor-irradiance.d.ts +47 -33
  365. package/dist/optics/scene-to-sensor-irradiance.js +73 -45
  366. package/dist/optics/scene-to-sensor-irradiance.js.map +1 -1
  367. package/dist/optics/scene-to-sensor-quadrature.d.ts +23 -18
  368. package/dist/optics/scene-to-sensor-quadrature.js +16 -11
  369. package/dist/optics/scene-to-sensor-quadrature.js.map +1 -1
  370. package/dist/optics/sensor-aperture-rays.d.ts +20 -4
  371. package/dist/optics/sensor-aperture-rays.js +32 -14
  372. package/dist/optics/sensor-aperture-rays.js.map +1 -1
  373. package/dist/optics/sensor-environment-query.d.ts +81 -16
  374. package/dist/optics/sensor-environment-query.js +145 -12
  375. package/dist/optics/sensor-environment-query.js.map +1 -1
  376. package/dist/optics/sensor-psf-quadrature.d.ts +12 -10
  377. package/dist/optics/sensor-psf-quadrature.js +18 -11
  378. package/dist/optics/sensor-psf-quadrature.js.map +1 -1
  379. package/dist/optics/sensor-psf-support.d.ts +8 -6
  380. package/dist/optics/sensor-psf-support.js +8 -5
  381. package/dist/optics/sensor-psf-support.js.map +1 -1
  382. package/dist/optics/stray-light.d.ts +22 -19
  383. package/dist/optics/stray-light.js +18 -12
  384. package/dist/optics/stray-light.js.map +1 -1
  385. package/dist/optics/thin-lens.d.ts +10 -9
  386. package/dist/optics/thin-lens.js +12 -8
  387. package/dist/optics/thin-lens.js.map +1 -1
  388. package/dist/optics/zernike-wavefront.d.ts +154 -0
  389. package/dist/optics/zernike-wavefront.js +352 -0
  390. package/dist/optics/zernike-wavefront.js.map +1 -0
  391. package/dist/output/capture-corrected-sdr.d.ts +16 -8
  392. package/dist/output/capture-corrected-sdr.js +16 -8
  393. package/dist/output/capture-corrected-sdr.js.map +1 -1
  394. package/dist/output/capture-geometry.d.ts +34 -36
  395. package/dist/output/capture-geometry.js +52 -32
  396. package/dist/output/capture-geometry.js.map +1 -1
  397. package/dist/output/capture-sdr.d.ts +7 -6
  398. package/dist/output/capture-sdr.js +11 -8
  399. package/dist/output/capture-sdr.js.map +1 -1
  400. package/dist/output/crop.d.ts +22 -6
  401. package/dist/output/crop.js +40 -6
  402. package/dist/output/crop.js.map +1 -1
  403. package/dist/output/geometric-transforms.d.ts +60 -23
  404. package/dist/output/geometric-transforms.js +111 -24
  405. package/dist/output/geometric-transforms.js.map +1 -1
  406. package/dist/output/lens-corrections.d.ts +27 -19
  407. package/dist/output/lens-corrections.js +29 -13
  408. package/dist/output/lens-corrections.js.map +1 -1
  409. package/dist/output/native-capture-sdr.d.ts +71 -16
  410. package/dist/output/native-capture-sdr.js +190 -33
  411. package/dist/output/native-capture-sdr.js.map +1 -1
  412. package/dist/output/png-encoder.d.ts +65 -0
  413. package/dist/output/png-encoder.js +461 -0
  414. package/dist/output/png-encoder.js.map +1 -0
  415. package/dist/output/print-contrast-reference.d.ts +10 -9
  416. package/dist/output/print-contrast-reference.js +10 -8
  417. package/dist/output/print-contrast-reference.js.map +1 -1
  418. package/dist/output/print-detail.d.ts +18 -17
  419. package/dist/output/print-detail.js +12 -10
  420. package/dist/output/print-detail.js.map +1 -1
  421. package/dist/output/print-jpeg.d.ts +26 -5
  422. package/dist/output/print-jpeg.js +117 -50
  423. package/dist/output/print-jpeg.js.map +1 -1
  424. package/dist/output/print-plan.d.ts +19 -19
  425. package/dist/output/print-plan.js +11 -10
  426. package/dist/output/print-plan.js.map +1 -1
  427. package/dist/output/print-region-statistics.d.ts +14 -15
  428. package/dist/output/print-region-statistics.js +11 -11
  429. package/dist/output/print-region-statistics.js.map +1 -1
  430. package/dist/output/sdr-rendering.d.ts +48 -10
  431. package/dist/output/sdr-rendering.js +114 -25
  432. package/dist/output/sdr-rendering.js.map +1 -1
  433. package/dist/output/subject-framing-crop.d.ts +6 -10
  434. package/dist/output/subject-framing-crop.js +23 -13
  435. package/dist/output/subject-framing-crop.js.map +1 -1
  436. package/dist/processing/demosaic.d.ts +90 -0
  437. package/dist/processing/demosaic.js +275 -0
  438. package/dist/processing/demosaic.js.map +1 -0
  439. package/dist/processing/denoise.d.ts +68 -0
  440. package/dist/processing/denoise.js +214 -0
  441. package/dist/processing/denoise.js.map +1 -0
  442. package/dist/processing/focus-stacking.d.ts +17 -0
  443. package/dist/processing/focus-stacking.js +80 -0
  444. package/dist/processing/focus-stacking.js.map +1 -0
  445. package/dist/processing/hdr.d.ts +54 -0
  446. package/dist/processing/hdr.js +172 -0
  447. package/dist/processing/hdr.js.map +1 -0
  448. package/dist/processing/image-ops.d.ts +66 -0
  449. package/dist/processing/image-ops.js +192 -0
  450. package/dist/processing/image-ops.js.map +1 -0
  451. package/dist/processing/panorama.d.ts +51 -0
  452. package/dist/processing/panorama.js +305 -0
  453. package/dist/processing/panorama.js.map +1 -0
  454. package/dist/processing/processing-task.d.ts +85 -0
  455. package/dist/processing/processing-task.js +164 -0
  456. package/dist/processing/processing-task.js.map +1 -0
  457. package/dist/processing/tone-mapping.d.ts +69 -0
  458. package/dist/processing/tone-mapping.js +310 -0
  459. package/dist/processing/tone-mapping.js.map +1 -0
  460. package/dist/schema/camera.d.ts +5 -4
  461. package/dist/schema/illumination-spectral.d.ts +13 -19
  462. package/dist/schema/illumination-spectral.js +23 -19
  463. package/dist/schema/illumination-spectral.js.map +1 -1
  464. package/dist/schema/illumination-temporal.d.ts +12 -15
  465. package/dist/schema/illumination-temporal.js +43 -28
  466. package/dist/schema/illumination-temporal.js.map +1 -1
  467. package/dist/schema/illumination.d.ts +5 -4
  468. package/dist/schema/illumination.js +55 -20
  469. package/dist/schema/illumination.js.map +1 -1
  470. package/dist/schema/scene-radiance-temporal.d.ts +9 -11
  471. package/dist/schema/scene-radiance-temporal.js +26 -23
  472. package/dist/schema/scene-radiance-temporal.js.map +1 -1
  473. package/dist/schema/scene-radiance.d.ts +17 -17
  474. package/dist/schema/scene-radiance.js +56 -34
  475. package/dist/schema/scene-radiance.js.map +1 -1
  476. package/dist/schema/scene.d.ts +14 -13
  477. package/dist/schema/validation.d.ts +0 -1
  478. package/dist/schema/validation.js +17 -15
  479. package/dist/schema/validation.js.map +1 -1
  480. package/dist/sensor/accumulated-charge.d.ts +45 -64
  481. package/dist/sensor/accumulated-charge.js +41 -47
  482. package/dist/sensor/accumulated-charge.js.map +1 -1
  483. package/dist/sensor/architecture.d.ts +22 -25
  484. package/dist/sensor/architecture.js +17 -16
  485. package/dist/sensor/architecture.js.map +1 -1
  486. package/dist/sensor/camera-saturation-capacity.d.ts +21 -28
  487. package/dist/sensor/camera-saturation-capacity.js +36 -34
  488. package/dist/sensor/camera-saturation-capacity.js.map +1 -1
  489. package/dist/sensor/capture-color-sampling-binding.d.ts +46 -51
  490. package/dist/sensor/capture-color-sampling-binding.js +39 -41
  491. package/dist/sensor/capture-color-sampling-binding.js.map +1 -1
  492. package/dist/sensor/capture-mode-timing.d.ts +8 -9
  493. package/dist/sensor/capture-mode-timing.js +24 -21
  494. package/dist/sensor/capture-mode-timing.js.map +1 -1
  495. package/dist/sensor/capture-mode.d.ts +28 -30
  496. package/dist/sensor/capture-mode.js +33 -31
  497. package/dist/sensor/capture-mode.js.map +1 -1
  498. package/dist/sensor/color-sampling.d.ts +30 -33
  499. package/dist/sensor/color-sampling.js +32 -37
  500. package/dist/sensor/color-sampling.js.map +1 -1
  501. package/dist/sensor/constant-rate-temporal-integration.d.ts +19 -23
  502. package/dist/sensor/constant-rate-temporal-integration.js +28 -26
  503. package/dist/sensor/constant-rate-temporal-integration.js.map +1 -1
  504. package/dist/sensor/dark-current.d.ts +53 -49
  505. package/dist/sensor/dark-current.js +87 -46
  506. package/dist/sensor/dark-current.js.map +1 -1
  507. package/dist/sensor/environment-photo-signal.d.ts +71 -30
  508. package/dist/sensor/environment-photo-signal.js +127 -46
  509. package/dist/sensor/environment-photo-signal.js.map +1 -1
  510. package/dist/sensor/eqe-electron-rate.d.ts +14 -13
  511. package/dist/sensor/eqe-electron-rate.js +34 -14
  512. package/dist/sensor/eqe-electron-rate.js.map +1 -1
  513. package/dist/sensor/eqe-local-exposure.d.ts +24 -24
  514. package/dist/sensor/eqe-local-exposure.js +15 -11
  515. package/dist/sensor/eqe-local-exposure.js.map +1 -1
  516. package/dist/sensor/eqe-temporal-exposure.d.ts +11 -11
  517. package/dist/sensor/eqe-temporal-exposure.js +15 -10
  518. package/dist/sensor/eqe-temporal-exposure.js.map +1 -1
  519. package/dist/sensor/exposure-window.d.ts +48 -34
  520. package/dist/sensor/exposure-window.js +77 -36
  521. package/dist/sensor/exposure-window.js.map +1 -1
  522. package/dist/sensor/fixed-pattern-noise.d.ts +108 -0
  523. package/dist/sensor/fixed-pattern-noise.js +166 -0
  524. package/dist/sensor/fixed-pattern-noise.js.map +1 -0
  525. package/dist/sensor/iso-gain.d.ts +44 -0
  526. package/dist/sensor/iso-gain.js +119 -0
  527. package/dist/sensor/iso-gain.js.map +1 -0
  528. package/dist/sensor/iso-signal-chain.d.ts +25 -48
  529. package/dist/sensor/iso-signal-chain.js +52 -66
  530. package/dist/sensor/iso-signal-chain.js.map +1 -1
  531. package/dist/sensor/local-exposure-binding.d.ts +21 -21
  532. package/dist/sensor/local-exposure-binding.js +22 -18
  533. package/dist/sensor/local-exposure-binding.js.map +1 -1
  534. package/dist/sensor/optical-stack.d.ts +36 -40
  535. package/dist/sensor/optical-stack.js +34 -37
  536. package/dist/sensor/optical-stack.js.map +1 -1
  537. package/dist/sensor/photon-energy.d.ts +22 -28
  538. package/dist/sensor/photon-energy.js +42 -34
  539. package/dist/sensor/photon-energy.js.map +1 -1
  540. package/dist/sensor/physical-charge-capacity.d.ts +20 -30
  541. package/dist/sensor/physical-charge-capacity.js +35 -36
  542. package/dist/sensor/physical-charge-capacity.js.map +1 -1
  543. package/dist/sensor/pixel-pitch.d.ts +2 -3
  544. package/dist/sensor/pixel-pitch.js +4 -2
  545. package/dist/sensor/pixel-pitch.js.map +1 -1
  546. package/dist/sensor/radiometry-readiness.d.ts +13 -15
  547. package/dist/sensor/radiometry-readiness.js +20 -17
  548. package/dist/sensor/radiometry-readiness.js.map +1 -1
  549. package/dist/sensor/raw-readout.d.ts +173 -83
  550. package/dist/sensor/raw-readout.js +425 -160
  551. package/dist/sensor/raw-readout.js.map +1 -1
  552. package/dist/sensor/raw-reconstruction.d.ts +112 -44
  553. package/dist/sensor/raw-reconstruction.js +200 -47
  554. package/dist/sensor/raw-reconstruction.js.map +1 -1
  555. package/dist/sensor/readout-exposure-linkage.d.ts +103 -34
  556. package/dist/sensor/readout-exposure-linkage.js +125 -27
  557. package/dist/sensor/readout-exposure-linkage.js.map +1 -1
  558. package/dist/sensor/readout-timing.d.ts +43 -44
  559. package/dist/sensor/readout-timing.js +38 -30
  560. package/dist/sensor/readout-timing.js.map +1 -1
  561. package/dist/sensor/response-application-compatibility.d.ts +21 -28
  562. package/dist/sensor/response-application-compatibility.js +35 -34
  563. package/dist/sensor/response-application-compatibility.js.map +1 -1
  564. package/dist/sensor/response-operating-range.d.ts +26 -35
  565. package/dist/sensor/response-operating-range.js +40 -39
  566. package/dist/sensor/response-operating-range.js.map +1 -1
  567. package/dist/sensor/responsivity-photocurrent.d.ts +21 -29
  568. package/dist/sensor/responsivity-photocurrent.js +57 -40
  569. package/dist/sensor/responsivity-photocurrent.js.map +1 -1
  570. package/dist/sensor/sampling-aperture.d.ts +21 -25
  571. package/dist/sensor/sampling-aperture.js +29 -28
  572. package/dist/sensor/sampling-aperture.js.map +1 -1
  573. package/dist/sensor/scene-eqe-temporal-exposure.d.ts +14 -12
  574. package/dist/sensor/scene-eqe-temporal-exposure.js +13 -8
  575. package/dist/sensor/scene-eqe-temporal-exposure.js.map +1 -1
  576. package/dist/sensor/sensor-geometry.d.ts +28 -32
  577. package/dist/sensor/sensor-geometry.js +35 -20
  578. package/dist/sensor/sensor-geometry.js.map +1 -1
  579. package/dist/sensor/signal-noise.d.ts +14 -16
  580. package/dist/sensor/signal-noise.js +15 -13
  581. package/dist/sensor/signal-noise.js.map +1 -1
  582. package/dist/sensor/spatial-sample-reduction.d.ts +45 -60
  583. package/dist/sensor/spatial-sample-reduction.js +39 -48
  584. package/dist/sensor/spatial-sample-reduction.js.map +1 -1
  585. package/dist/sensor/spatial-sampling-quadrature.d.ts +46 -54
  586. package/dist/sensor/spatial-sampling-quadrature.js +31 -36
  587. package/dist/sensor/spatial-sampling-quadrature.js.map +1 -1
  588. package/dist/sensor/spatio-spectral-reduction.d.ts +32 -42
  589. package/dist/sensor/spatio-spectral-reduction.js +24 -29
  590. package/dist/sensor/spatio-spectral-reduction.js.map +1 -1
  591. package/dist/sensor/spectral-coverage.d.ts +6 -9
  592. package/dist/sensor/spectral-coverage.js +9 -6
  593. package/dist/sensor/spectral-coverage.js.map +1 -1
  594. package/dist/sensor/spectral-quadrature.d.ts +46 -60
  595. package/dist/sensor/spectral-quadrature.js +38 -48
  596. package/dist/sensor/spectral-quadrature.js.map +1 -1
  597. package/dist/sensor/spectral-response.d.ts +53 -41
  598. package/dist/sensor/spectral-response.js +80 -47
  599. package/dist/sensor/spectral-response.js.map +1 -1
  600. package/dist/sensor/stochastic-seed.d.ts +50 -0
  601. package/dist/sensor/stochastic-seed.js +123 -0
  602. package/dist/sensor/stochastic-seed.js.map +1 -0
  603. package/dist/sensor/temporal-eqe-sum.d.ts +2 -4
  604. package/dist/sensor/temporal-eqe-sum.js +5 -6
  605. package/dist/sensor/temporal-eqe-sum.js.map +1 -1
  606. package/dist/sensor/temporal-photo-signal.d.ts +5 -6
  607. package/dist/sensor/temporal-photo-signal.js +11 -10
  608. package/dist/sensor/temporal-photo-signal.js.map +1 -1
  609. package/dist/sensor/temporal-sample-binding.d.ts +1 -2
  610. package/dist/sensor/temporal-sample-binding.js +3 -3
  611. package/dist/sensor/temporal-sample-binding.js.map +1 -1
  612. package/dist/simulation/poc-simulation.d.ts +16 -16
  613. package/dist/simulation/poc-simulation.js +20 -15
  614. package/dist/simulation/poc-simulation.js.map +1 -1
  615. package/dist/stabilization/camera-shake.d.ts +42 -18
  616. package/dist/stabilization/camera-shake.js +43 -20
  617. package/dist/stabilization/camera-shake.js.map +1 -1
  618. package/dist/stabilization/system.d.ts +44 -41
  619. package/dist/stabilization/system.js +196 -108
  620. package/dist/stabilization/system.js.map +1 -1
  621. package/docs/AGENT_GUIDE.md +183 -0
  622. package/docs/API_REFERENCE.md +761 -2
  623. package/docs/QUICK_START.md +495 -0
  624. package/docs/USAGE.md +1719 -714
  625. package/docs/api/camera-equivalent-focal-length.md +6 -7
  626. package/docs/api/camera-field-of-view.md +16 -8
  627. package/docs/api/camera-lens-projection.md +246 -0
  628. package/docs/api/camera-projected-object-size.md +6 -5
  629. package/docs/api/capture-capture-export-metadata.md +10 -10
  630. package/docs/api/capture-dng-import.md +134 -0
  631. package/docs/api/capture-environment-raw-producer.md +17 -11
  632. package/docs/api/capture-export-jpeg.md +16 -0
  633. package/docs/api/capture-focus-control.md +25 -47
  634. package/docs/api/capture-linear-encoding.md +21 -12
  635. package/docs/api/capture-lossless-jpeg.md +49 -0
  636. package/docs/api/capture-native-environment-optical-stage.md +75 -0
  637. package/docs/api/capture-native-environment-raw.md +161 -4
  638. package/docs/api/capture-native-raw-development.md +69 -4
  639. package/docs/api/capture-native-raw-dng.md +84 -0
  640. package/docs/api/capture-native-raw.md +23 -8
  641. package/docs/api/capture-packed-sensor-raw.md +156 -0
  642. package/docs/api/capture-photographic-export.md +69 -31
  643. package/docs/api/capture-raw-frame-reconstruction.md +8 -8
  644. package/docs/api/capture-raw-white-level.md +37 -0
  645. package/docs/api/capture-release-sequence.md +6 -7
  646. package/docs/api/capture-sensor-raw-frame.md +6 -6
  647. package/docs/api/capture-sensor-raw-producer.md +17 -11
  648. package/docs/api/capture-simulated-capture.md +15 -15
  649. package/docs/api/color-camera-color-matrix.md +103 -0
  650. package/docs/api/color-capture-color.md +22 -11
  651. package/docs/api/color-chromatic-adaptation.md +82 -0
  652. package/docs/api/color-color-difference.md +134 -0
  653. package/docs/api/color-color-matching-functions.md +259 -0
  654. package/docs/api/color-colorimetry-math.md +54 -0
  655. package/docs/api/color-gamut-mapping.md +72 -0
  656. package/docs/api/color-illuminants.md +280 -0
  657. package/docs/api/color-rgb-color-spaces.md +151 -0
  658. package/docs/api/color-sensor-color-development.md +27 -0
  659. package/docs/api/color-srgb-icc.md +2 -4
  660. package/docs/api/color-white-balance.md +95 -19
  661. package/docs/api/composition-image-formation-plan.md +124 -95
  662. package/docs/api/composition-plan-consumer.md +7 -7
  663. package/docs/api/core-calculation-result.md +18 -14
  664. package/docs/api/core-configuration-error.md +1 -1
  665. package/docs/api/core-image-formation.md +7 -7
  666. package/docs/api/core-scientific-assurance.md +12 -10
  667. package/docs/api/core-spectral-composition.md +14 -14
  668. package/docs/api/core-spectral.md +6 -6
  669. package/docs/api/core-validation.md +3 -3
  670. package/docs/api/core-version.md +7 -6
  671. package/docs/api/equipment-exposure-capabilities.md +11 -10
  672. package/docs/api/equipment-generic-tier-assets.md +7 -2
  673. package/docs/api/equipment-generic-tier-presets.md +6 -6
  674. package/docs/api/equipment-iso-capabilities.md +18 -18
  675. package/docs/api/equipment-metering-capabilities.md +6 -6
  676. package/docs/api/equipment-release-capabilities.md +4 -4
  677. package/docs/api/exports.json +2213 -8
  678. package/docs/api/exposure-exposure-duration-control.md +9 -9
  679. package/docs/api/exposure-exposure-mode-resolver.md +35 -31
  680. package/docs/api/exposure-exposure.md +10 -10
  681. package/docs/api/exposure-flash-ttl.md +182 -0
  682. package/docs/api/exposure-flash.md +183 -28
  683. package/docs/api/exposure-metering-scene-radiance.md +11 -10
  684. package/docs/api/exposure-metering-target.md +9 -8
  685. package/docs/api/exposure-metering-temporal.md +8 -8
  686. package/docs/api/exposure-metering.md +69 -9
  687. package/docs/api/exposure-program-line.md +6 -5
  688. package/docs/api/facade-chart-radiance-batch.md +96 -0
  689. package/docs/api/facade-chart-scenes.md +240 -0
  690. package/docs/api/facade-scene-radiance.md +122 -0
  691. package/docs/api/facade-simulate-capture.md +324 -0
  692. package/docs/api/gpu-image-kernel-accelerator.md +157 -0
  693. package/docs/api/gpu-image-kernel-execution.md +152 -0
  694. package/docs/api/motion-camera-rotation.md +43 -26
  695. package/docs/api/motion-capture-rotation-inverse-mapping.md +24 -23
  696. package/docs/api/motion-capture-rotation-temporal-quadrature.md +22 -22
  697. package/docs/api/motion-capture-rotation-trajectory.md +15 -15
  698. package/docs/api/motion-capture-translation-parallax-temporal-quadrature.md +15 -14
  699. package/docs/api/motion-extended-object-projection.md +10 -8
  700. package/docs/api/motion-projected-motion.md +8 -8
  701. package/docs/api/motion-temporal-exposure-sum.md +98 -0
  702. package/docs/api/motion-video-sequence.md +159 -0
  703. package/docs/api/optics-aperture.md +8 -8
  704. package/docs/api/optics-atmospheric-haze.md +104 -0
  705. package/docs/api/optics-brown-conrady-distortion.md +123 -0
  706. package/docs/api/optics-circle-of-confusion.md +5 -4
  707. package/docs/api/optics-complex-pupil-psf.md +57 -16
  708. package/docs/api/optics-depth-of-field.md +12 -6
  709. package/docs/api/optics-diffraction.md +8 -7
  710. package/docs/api/optics-focus-breathing.md +104 -16
  711. package/docs/api/optics-focus-state.md +9 -10
  712. package/docs/api/optics-front-of-lens-filter.md +72 -14
  713. package/docs/api/optics-illumination-vignetting.md +10 -10
  714. package/docs/api/optics-irradiance-convolution.md +95 -0
  715. package/docs/api/optics-lateral-chromatic-aberration.md +22 -21
  716. package/docs/api/optics-lens-psf-kernels.md +72 -0
  717. package/docs/api/optics-lens-psf-profile.md +48 -26
  718. package/docs/api/optics-longitudinal-chromatic-aberration.md +128 -0
  719. package/docs/api/optics-polygon-diffraction.md +78 -13
  720. package/docs/api/optics-profile-contract.md +4 -4
  721. package/docs/api/optics-psf-foundation.md +12 -12
  722. package/docs/api/optics-pupil-vignetting.md +132 -0
  723. package/docs/api/optics-radial-distortion.md +12 -12
  724. package/docs/api/optics-scene-to-sensor-irradiance.md +25 -14
  725. package/docs/api/optics-scene-to-sensor-quadrature.md +15 -12
  726. package/docs/api/optics-sensor-aperture-rays.md +3 -2
  727. package/docs/api/optics-sensor-environment-query.md +52 -9
  728. package/docs/api/optics-sensor-psf-quadrature.md +13 -10
  729. package/docs/api/optics-stray-light.md +12 -11
  730. package/docs/api/optics-thin-lens.md +4 -3
  731. package/docs/api/optics-zernike-wavefront.md +229 -0
  732. package/docs/api/output-capture-corrected-sdr.md +10 -7
  733. package/docs/api/output-capture-geometry.md +35 -36
  734. package/docs/api/output-capture-sdr.md +4 -4
  735. package/docs/api/output-crop.md +7 -4
  736. package/docs/api/output-geometric-transforms.md +65 -19
  737. package/docs/api/output-lens-corrections.md +17 -15
  738. package/docs/api/output-native-capture-sdr.md +26 -13
  739. package/docs/api/output-png-encoder.md +105 -0
  740. package/docs/api/output-print-contrast-reference.md +8 -8
  741. package/docs/api/output-print-detail.md +14 -14
  742. package/docs/api/output-print-jpeg.md +22 -5
  743. package/docs/api/output-print-plan.md +18 -18
  744. package/docs/api/output-print-region-statistics.md +14 -14
  745. package/docs/api/output-sdr-rendering.md +52 -10
  746. package/docs/api/output-subject-framing-crop.md +5 -6
  747. package/docs/api/processing-demosaic.md +120 -0
  748. package/docs/api/processing-denoise.md +148 -0
  749. package/docs/api/processing-focus-stacking.md +41 -0
  750. package/docs/api/processing-hdr.md +113 -0
  751. package/docs/api/processing-panorama.md +82 -0
  752. package/docs/api/processing-processing-task.md +107 -0
  753. package/docs/api/processing-tone-mapping.md +142 -0
  754. package/docs/api/schema-camera.md +6 -4
  755. package/docs/api/schema-illumination-spectral.md +10 -11
  756. package/docs/api/schema-illumination-temporal.md +13 -15
  757. package/docs/api/schema-illumination.md +4 -4
  758. package/docs/api/schema-scene-radiance-temporal.md +10 -11
  759. package/docs/api/schema-scene-radiance.md +18 -17
  760. package/docs/api/schema-scene.md +9 -9
  761. package/docs/api/schema-validation.md +1 -1
  762. package/docs/api/sensor-accumulated-charge.md +12 -20
  763. package/docs/api/sensor-architecture.md +15 -16
  764. package/docs/api/sensor-camera-saturation-capacity.md +9 -11
  765. package/docs/api/sensor-capture-color-sampling-binding.md +47 -51
  766. package/docs/api/sensor-capture-mode-timing.md +9 -9
  767. package/docs/api/sensor-capture-mode.md +29 -30
  768. package/docs/api/sensor-color-sampling.md +31 -33
  769. package/docs/api/sensor-constant-rate-temporal-integration.md +10 -11
  770. package/docs/api/sensor-dark-current.md +30 -14
  771. package/docs/api/sensor-environment-photo-signal.md +13 -6
  772. package/docs/api/sensor-eqe-electron-rate.md +9 -8
  773. package/docs/api/sensor-eqe-local-exposure.md +18 -17
  774. package/docs/api/sensor-eqe-temporal-exposure.md +12 -11
  775. package/docs/api/sensor-exposure-window.md +24 -24
  776. package/docs/api/sensor-fixed-pattern-noise.md +104 -0
  777. package/docs/api/sensor-iso-gain.md +63 -0
  778. package/docs/api/sensor-iso-signal-chain.md +13 -22
  779. package/docs/api/sensor-local-exposure-binding.md +12 -13
  780. package/docs/api/sensor-optical-stack.md +37 -40
  781. package/docs/api/sensor-photon-energy.md +10 -11
  782. package/docs/api/sensor-physical-charge-capacity.md +8 -13
  783. package/docs/api/sensor-pixel-pitch.md +1 -1
  784. package/docs/api/sensor-radiometry-readiness.md +9 -9
  785. package/docs/api/sensor-raw-readout.md +118 -52
  786. package/docs/api/sensor-raw-reconstruction.md +97 -20
  787. package/docs/api/sensor-readout-exposure-linkage.md +120 -24
  788. package/docs/api/sensor-readout-timing.md +33 -35
  789. package/docs/api/sensor-response-application-compatibility.md +9 -11
  790. package/docs/api/sensor-response-operating-range.md +14 -18
  791. package/docs/api/sensor-responsivity-photocurrent.md +9 -12
  792. package/docs/api/sensor-sampling-aperture.md +22 -25
  793. package/docs/api/sensor-scene-eqe-temporal-exposure.md +9 -8
  794. package/docs/api/sensor-sensor-geometry.md +23 -24
  795. package/docs/api/sensor-signal-noise.md +10 -10
  796. package/docs/api/sensor-spatial-sample-reduction.md +27 -30
  797. package/docs/api/sensor-spatial-sampling-quadrature.md +37 -39
  798. package/docs/api/sensor-spatio-spectral-reduction.md +27 -29
  799. package/docs/api/sensor-spectral-coverage.md +5 -5
  800. package/docs/api/sensor-spectral-quadrature.md +33 -35
  801. package/docs/api/sensor-spectral-response.md +28 -16
  802. package/docs/api/sensor-temporal-photo-signal.md +6 -6
  803. package/docs/api/simulation-poc-simulation.md +17 -16
  804. package/docs/api/stabilization-camera-shake.md +29 -10
  805. package/docs/api/stabilization-system.md +25 -21
  806. package/docs/examples/production-request.json +3821 -2157
  807. package/docs/examples/simulate-capture.mjs +14 -0
  808. package/llms.txt +35 -0
  809. package/package.json +32 -12
  810. package/AGENTS.md +0 -674
  811. package/CONTRIBUTING.md +0 -76
  812. package/DCO +0 -33
  813. package/dist/camera/equivalent-focal-length.d.ts.map +0 -1
  814. package/dist/camera/field-of-view.d.ts.map +0 -1
  815. package/dist/camera/projected-object-size.d.ts.map +0 -1
  816. package/dist/capture/capture-export-metadata.d.ts.map +0 -1
  817. package/dist/capture/environment-raw-producer.d.ts.map +0 -1
  818. package/dist/capture/export-jpeg.d.ts.map +0 -1
  819. package/dist/capture/export-tiff.d.ts.map +0 -1
  820. package/dist/capture/focus-control.d.ts.map +0 -1
  821. package/dist/capture/linear-encoding.d.ts.map +0 -1
  822. package/dist/capture/native-environment-raw.d.ts.map +0 -1
  823. package/dist/capture/native-raw-development.d.ts.map +0 -1
  824. package/dist/capture/native-raw.d.ts.map +0 -1
  825. package/dist/capture/photographic-export.d.ts.map +0 -1
  826. package/dist/capture/raw-frame-limits.d.ts.map +0 -1
  827. package/dist/capture/raw-frame-reconstruction.d.ts.map +0 -1
  828. package/dist/capture/release-sequence.d.ts.map +0 -1
  829. package/dist/capture/sensor-raw-frame.d.ts.map +0 -1
  830. package/dist/capture/sensor-raw-producer.d.ts.map +0 -1
  831. package/dist/capture/simulated-capture.d.ts.map +0 -1
  832. package/dist/color/capture-color.d.ts.map +0 -1
  833. package/dist/color/sensor-color-development.d.ts.map +0 -1
  834. package/dist/color/srgb-icc.d.ts.map +0 -1
  835. package/dist/color/srgb-transfer.d.ts.map +0 -1
  836. package/dist/color/white-balance.d.ts.map +0 -1
  837. package/dist/composition/image-formation-plan.d.ts.map +0 -1
  838. package/dist/composition/plan-consumer.d.ts.map +0 -1
  839. package/dist/core/calculation-result.d.ts.map +0 -1
  840. package/dist/core/canonical-json.d.ts.map +0 -1
  841. package/dist/core/configuration-error.d.ts.map +0 -1
  842. package/dist/core/evidence-provenance.d.ts.map +0 -1
  843. package/dist/core/image-formation.d.ts.map +0 -1
  844. package/dist/core/owned-data.d.ts.map +0 -1
  845. package/dist/core/record-validation.d.ts.map +0 -1
  846. package/dist/core/scientific-assurance.d.ts.map +0 -1
  847. package/dist/core/spectral-composition.d.ts.map +0 -1
  848. package/dist/core/spectral.d.ts.map +0 -1
  849. package/dist/core/validation.d.ts.map +0 -1
  850. package/dist/core/version.d.ts.map +0 -1
  851. package/dist/equipment/exposure-capabilities.d.ts.map +0 -1
  852. package/dist/equipment/generic-tier-assets.d.ts.map +0 -1
  853. package/dist/equipment/generic-tier-presets.d.ts.map +0 -1
  854. package/dist/equipment/iso-capabilities.d.ts.map +0 -1
  855. package/dist/equipment/metering-capabilities.d.ts.map +0 -1
  856. package/dist/equipment/release-capabilities.d.ts.map +0 -1
  857. package/dist/exposure/exposure-duration-control.d.ts.map +0 -1
  858. package/dist/exposure/exposure-mode-resolver.d.ts.map +0 -1
  859. package/dist/exposure/exposure.d.ts.map +0 -1
  860. package/dist/exposure/flash.d.ts.map +0 -1
  861. package/dist/exposure/metering-scene-radiance.d.ts.map +0 -1
  862. package/dist/exposure/metering-target.d.ts.map +0 -1
  863. package/dist/exposure/metering-temporal.d.ts.map +0 -1
  864. package/dist/exposure/metering.d.ts.map +0 -1
  865. package/dist/exposure/program-line.d.ts.map +0 -1
  866. package/dist/index.d.ts.map +0 -1
  867. package/dist/motion/camera-rotation.d.ts.map +0 -1
  868. package/dist/motion/capture-rotation-inverse-mapping.d.ts.map +0 -1
  869. package/dist/motion/capture-rotation-temporal-quadrature.d.ts.map +0 -1
  870. package/dist/motion/capture-rotation-trajectory.d.ts.map +0 -1
  871. package/dist/motion/capture-translation-parallax-temporal-quadrature.d.ts.map +0 -1
  872. package/dist/motion/extended-object-projection.d.ts.map +0 -1
  873. package/dist/motion/projected-motion.d.ts.map +0 -1
  874. package/dist/optics/aperture.d.ts.map +0 -1
  875. package/dist/optics/circle-of-confusion.d.ts.map +0 -1
  876. package/dist/optics/complex-pupil-psf.d.ts.map +0 -1
  877. package/dist/optics/depth-of-field.d.ts.map +0 -1
  878. package/dist/optics/diffraction.d.ts.map +0 -1
  879. package/dist/optics/focus-breathing.d.ts.map +0 -1
  880. package/dist/optics/focus-state.d.ts.map +0 -1
  881. package/dist/optics/front-of-lens-filter.d.ts.map +0 -1
  882. package/dist/optics/illumination-vignetting.d.ts.map +0 -1
  883. package/dist/optics/lateral-chromatic-aberration.d.ts.map +0 -1
  884. package/dist/optics/lens-psf-profile.d.ts.map +0 -1
  885. package/dist/optics/polygon-diffraction.d.ts.map +0 -1
  886. package/dist/optics/profile-contract.d.ts.map +0 -1
  887. package/dist/optics/psf-foundation.d.ts.map +0 -1
  888. package/dist/optics/radial-distortion.d.ts.map +0 -1
  889. package/dist/optics/scene-to-sensor-irradiance.d.ts.map +0 -1
  890. package/dist/optics/scene-to-sensor-quadrature.d.ts.map +0 -1
  891. package/dist/optics/sensor-aperture-rays.d.ts.map +0 -1
  892. package/dist/optics/sensor-environment-query.d.ts.map +0 -1
  893. package/dist/optics/sensor-psf-quadrature.d.ts.map +0 -1
  894. package/dist/optics/sensor-psf-support.d.ts.map +0 -1
  895. package/dist/optics/stray-light.d.ts.map +0 -1
  896. package/dist/optics/thin-lens.d.ts.map +0 -1
  897. package/dist/output/capture-corrected-sdr.d.ts.map +0 -1
  898. package/dist/output/capture-geometry.d.ts.map +0 -1
  899. package/dist/output/capture-sdr.d.ts.map +0 -1
  900. package/dist/output/crop.d.ts.map +0 -1
  901. package/dist/output/geometric-transforms.d.ts.map +0 -1
  902. package/dist/output/lens-corrections.d.ts.map +0 -1
  903. package/dist/output/native-capture-sdr.d.ts.map +0 -1
  904. package/dist/output/print-contrast-reference.d.ts.map +0 -1
  905. package/dist/output/print-detail.d.ts.map +0 -1
  906. package/dist/output/print-jpeg.d.ts.map +0 -1
  907. package/dist/output/print-plan.d.ts.map +0 -1
  908. package/dist/output/print-region-statistics.d.ts.map +0 -1
  909. package/dist/output/sdr-rendering.d.ts.map +0 -1
  910. package/dist/output/subject-framing-crop.d.ts.map +0 -1
  911. package/dist/schema/camera.d.ts.map +0 -1
  912. package/dist/schema/camera.js +0 -3
  913. package/dist/schema/camera.js.map +0 -1
  914. package/dist/schema/illumination-spectral.d.ts.map +0 -1
  915. package/dist/schema/illumination-temporal.d.ts.map +0 -1
  916. package/dist/schema/illumination.d.ts.map +0 -1
  917. package/dist/schema/scene-radiance-temporal.d.ts.map +0 -1
  918. package/dist/schema/scene-radiance.d.ts.map +0 -1
  919. package/dist/schema/scene.d.ts.map +0 -1
  920. package/dist/schema/scene.js +0 -3
  921. package/dist/schema/scene.js.map +0 -1
  922. package/dist/schema/validation.d.ts.map +0 -1
  923. package/dist/sensor/accumulated-charge.d.ts.map +0 -1
  924. package/dist/sensor/architecture.d.ts.map +0 -1
  925. package/dist/sensor/camera-saturation-capacity.d.ts.map +0 -1
  926. package/dist/sensor/capture-color-sampling-binding.d.ts.map +0 -1
  927. package/dist/sensor/capture-mode-timing.d.ts.map +0 -1
  928. package/dist/sensor/capture-mode.d.ts.map +0 -1
  929. package/dist/sensor/color-sampling.d.ts.map +0 -1
  930. package/dist/sensor/constant-rate-temporal-integration.d.ts.map +0 -1
  931. package/dist/sensor/dark-current.d.ts.map +0 -1
  932. package/dist/sensor/environment-photo-signal.d.ts.map +0 -1
  933. package/dist/sensor/eqe-electron-rate.d.ts.map +0 -1
  934. package/dist/sensor/eqe-local-exposure.d.ts.map +0 -1
  935. package/dist/sensor/eqe-temporal-exposure.d.ts.map +0 -1
  936. package/dist/sensor/exposure-window.d.ts.map +0 -1
  937. package/dist/sensor/iso-signal-chain.d.ts.map +0 -1
  938. package/dist/sensor/local-exposure-binding.d.ts.map +0 -1
  939. package/dist/sensor/optical-stack.d.ts.map +0 -1
  940. package/dist/sensor/photon-energy.d.ts.map +0 -1
  941. package/dist/sensor/physical-charge-capacity.d.ts.map +0 -1
  942. package/dist/sensor/pixel-pitch.d.ts.map +0 -1
  943. package/dist/sensor/radiometry-readiness.d.ts.map +0 -1
  944. package/dist/sensor/raw-readout.d.ts.map +0 -1
  945. package/dist/sensor/raw-reconstruction.d.ts.map +0 -1
  946. package/dist/sensor/readout-exposure-linkage.d.ts.map +0 -1
  947. package/dist/sensor/readout-timing.d.ts.map +0 -1
  948. package/dist/sensor/response-application-compatibility.d.ts.map +0 -1
  949. package/dist/sensor/response-operating-range.d.ts.map +0 -1
  950. package/dist/sensor/responsivity-photocurrent.d.ts.map +0 -1
  951. package/dist/sensor/sampling-aperture.d.ts.map +0 -1
  952. package/dist/sensor/scene-eqe-temporal-exposure.d.ts.map +0 -1
  953. package/dist/sensor/sensor-geometry.d.ts.map +0 -1
  954. package/dist/sensor/signal-noise.d.ts.map +0 -1
  955. package/dist/sensor/spatial-sample-reduction.d.ts.map +0 -1
  956. package/dist/sensor/spatial-sampling-quadrature.d.ts.map +0 -1
  957. package/dist/sensor/spatio-spectral-reduction.d.ts.map +0 -1
  958. package/dist/sensor/spectral-coverage.d.ts.map +0 -1
  959. package/dist/sensor/spectral-quadrature.d.ts.map +0 -1
  960. package/dist/sensor/spectral-response.d.ts.map +0 -1
  961. package/dist/sensor/temporal-eqe-sum.d.ts.map +0 -1
  962. package/dist/sensor/temporal-photo-signal.d.ts.map +0 -1
  963. package/dist/sensor/temporal-sample-binding.d.ts.map +0 -1
  964. package/dist/simulation/poc-simulation.d.ts.map +0 -1
  965. package/dist/stabilization/camera-shake.d.ts.map +0 -1
  966. package/dist/stabilization/system.d.ts.map +0 -1
  967. package/docs/API_STYLE.md +0 -235
  968. package/docs/ARCHITECTURE.md +0 -356
  969. package/docs/AUTOMATION_COORDINATION.md +0 -190
  970. package/docs/CAPTURE_COLOR.md +0 -25
  971. package/docs/CAPTURE_CORRECTED_SDR.md +0 -25
  972. package/docs/CAPTURE_EXPORT_METADATA.md +0 -27
  973. package/docs/CAPTURE_SDR.md +0 -22
  974. package/docs/DEVELOPERS.md +0 -68
  975. package/docs/DIGITAL_OPTICS_FOUNDATION.md +0 -69
  976. package/docs/ENVIRONMENT_RAW_CAPTURE.md +0 -208
  977. package/docs/EXPORT_ACCEPTANCE.md +0 -133
  978. package/docs/GENERIC_TIER_PRESETS.md +0 -269
  979. package/docs/GEOMETRIC_PREPARATION_REUSE.md +0 -141
  980. package/docs/IMAGE_FORMATION.md +0 -247
  981. package/docs/LINEAR_CAPTURE_ENCODING.md +0 -25
  982. package/docs/MOTION_AND_SIGNAL.md +0 -250
  983. package/docs/NATIVE_CAPTURE_SDR.md +0 -70
  984. package/docs/NATIVE_CAPTURE_SDR_REVIEW.md +0 -37
  985. package/docs/NATIVE_CAPTURE_SDR_VALIDATION.md +0 -34
  986. package/docs/NATIVE_RAW_AND_PRINT.md +0 -47
  987. package/docs/NUMERICAL_CORRECTNESS.md +0 -191
  988. package/docs/PERFORMANCE_BASELINE.md +0 -56
  989. package/docs/PHOTOGRAPHIC_EXPORT.md +0 -206
  990. package/docs/PHYSICS_FOUNDATION.md +0 -426
  991. package/docs/POC_API.md +0 -278
  992. package/docs/POC_PROJECTION_PLATFORM_REFERENCE.md +0 -12
  993. package/docs/POC_PROJECTION_REUSE.md +0 -124
  994. package/docs/PRINT_195_196_REVIEW.md +0 -93
  995. package/docs/PRINT_196_ENGINE_ACCEPTANCE.md +0 -45
  996. package/docs/PRINT_CONTRAST_REFERENCE.md +0 -43
  997. package/docs/PRINT_DETAIL_ASSESSMENT.md +0 -81
  998. package/docs/PRINT_DETAIL_JPEG_EVIDENCE.md +0 -36
  999. package/docs/PRINT_DETAIL_SDR_EVIDENCE.md +0 -29
  1000. package/docs/PRINT_DETAIL_VALIDATION.md +0 -36
  1001. package/docs/PRINT_PLANNING.md +0 -75
  1002. package/docs/PRINT_REGION_STATISTICS.md +0 -38
  1003. package/docs/PROCESSED_OUTPUT.md +0 -157
  1004. package/docs/PRODUCTION_COMPOSITION.md +0 -373
  1005. package/docs/PRODUCTION_ENVIRONMENT_CAPTURE.md +0 -131
  1006. package/docs/PROVENANCE.md +0 -115
  1007. package/docs/PSF_FOUNDATION.md +0 -165
  1008. package/docs/RAW_FRAME_ENVELOPE.md +0 -56
  1009. package/docs/RAW_FRAME_RECONSTRUCTION.md +0 -30
  1010. package/docs/RELEASE_1_0.md +0 -66
  1011. package/docs/RELEASE_1_0_1.md +0 -61
  1012. package/docs/RELEASE_1_1_0.md +0 -25
  1013. package/docs/RELEASE_1_2_0.md +0 -51
  1014. package/docs/RELEASE_1_3_0.md +0 -15
  1015. package/docs/RELEASE_1_4_0.md +0 -23
  1016. package/docs/RELEASE_AUDIT.md +0 -39
  1017. package/docs/SCENE_RADIANCE_AND_ILLUMINATION.md +0 -298
  1018. package/docs/SCENE_SENSOR_QUADRATURE.md +0 -98
  1019. package/docs/SCENE_SENSOR_TEMPORAL_EXPOSURE.md +0 -86
  1020. package/docs/SCIENTIFIC_ASSURANCE.md +0 -280
  1021. package/docs/SCIENTIFIC_CONFORMANCE.md +0 -83
  1022. package/docs/SDR_RENDERING.md +0 -33
  1023. package/docs/SENSOR_APERTURE_RAYS.md +0 -23
  1024. package/docs/SENSOR_ENVIRONMENT_QUERY.md +0 -86
  1025. package/docs/SENSOR_EQE_LOCAL_EXPOSURE.md +0 -104
  1026. package/docs/SENSOR_EQE_TEMPORAL_EXPOSURE.md +0 -74
  1027. package/docs/SENSOR_PSF_QUADRATURE.md +0 -90
  1028. package/docs/SENSOR_RAW_FRAME.md +0 -20
  1029. package/docs/SENSOR_RAW_PRODUCER.md +0 -77
  1030. package/docs/SIGNAL_CONFORMANCE.md +0 -23
  1031. package/docs/SIMULATED_CAPTURE.md +0 -65
  1032. package/docs/STABILIZATION.md +0 -234
  1033. package/docs/TEMPORAL_PHOTO_RAW.md +0 -83
  1034. package/docs/TIER_ACCEPTANCE.md +0 -129
  1035. package/docs/TIER_PRESET_ACCEPTANCE.md +0 -59
  1036. package/docs/V1_COMPOSITION_MAP.md +0 -123
  1037. package/docs/V1_HELPER_REUSE_REVIEW.md +0 -60
  1038. package/docs/V1_PERFORMANCE_DISPOSITION.md +0 -88
  1039. package/docs/benchmarks/2026-10-01-main-baseline.json +0 -694
  1040. package/docs/benchmarks/2026-10-02-geometric-preparation-reuse.json +0 -2190
  1041. package/docs/benchmarks/2026-10-02-poc-projection-reuse.json +0 -2423
  1042. package/docs/benchmarks/2026-10-02-v1-environment-gc-profile.json +0 -210
  1043. package/docs/benchmarks/2026-10-02-v1-environment-ordinary.json +0 -187
  1044. package/docs/benchmarks/2026-10-02-v1-geometry-gc-profile.json +0 -756
  1045. package/docs/benchmarks/2026-10-02-v1-geometry-ordinary-1.json +0 -711
  1046. package/docs/benchmarks/2026-10-02-v1-geometry-ordinary-2.json +0 -711
  1047. package/docs/benchmarks/2026-10-02-v1-poc-gc-profile.json +0 -885
  1048. package/docs/benchmarks/2026-10-02-v1-poc-ordinary-1.json +0 -868
  1049. package/docs/benchmarks/2026-10-02-v1-poc-ordinary-2.json +0 -868
  1050. package/docs/licenses/castleCSF-MIT.txt +0 -21
  1051. package/docs/validation/documentation-fragments.json +0 -212
  1052. package/docs/validation/native-capture-sdr-darwin-arm64-node26-review.jsonl +0 -4
  1053. package/docs/validation/native-capture-sdr-darwin-arm64.jsonl +0 -3
  1054. package/docs/validation/native-raw-print-2026-10-04/fractional-asymmetric-crop.jpg +0 -0
  1055. package/docs/validation/native-raw-print-2026-10-04/gray-ramp.jpg +0 -0
  1056. package/docs/validation/native-raw-print-2026-10-04/linear-area-checker.jpg +0 -0
  1057. package/docs/validation/native-raw-print-2026-10-04/manifest.json +0 -218
  1058. package/docs/validation/native-raw-print-2026-10-04/megapixel-native.jpg +0 -0
  1059. package/docs/validation/native-raw-print-2026-10-04/native-color.jpg +0 -0
  1060. package/docs/validation/native-raw-print-2026-10-04/photivra-native-full-megapixel-validation.json +0 -9
  1061. package/docs/validation/native-raw-print-2026-10-04/photivra-native-full-megapixel.json +0 -29
  1062. package/docs/validation/native-raw-print-2026-10-04/photivra-native-full-megapixel.json.codes.u16le.gz +0 -0
  1063. package/docs/validation/native-raw-print-2026-10-04/photivra-native-full-megapixel.json.jpg +0 -0
  1064. package/docs/validation/native-raw-print-2026-10-04/photivra-native-full-megapixel.json.rgb.gz +0 -0
  1065. package/docs/validation/native-raw-print-2026-10-04/srgb.icc +0 -0
  1066. package/docs/validation/native-raw-print-2026-10-04/validation.json +0 -41
  1067. package/docs/validation/print-196-candidate-capabilities.json +0 -28
  1068. package/docs/validation/print-196-candidate-evidence.json +0 -356
  1069. package/docs/validation/print-196-engine-acceptance.json +0 -81
  1070. package/docs/validation/print-detail-capabilities.json +0 -103
  1071. package/docs/validation/print-detail-jpeg-evidence.json +0 -116
  1072. package/docs/validation/print-detail-sdr-evidence.json +0 -81
  1073. package/docs/validation/release-audit-inventory.json +0 -1306
  1074. package/docs/validation/tier-acceptance-report-v1.json +0 -2538
@@ -1,19 +1,26 @@
1
1
  // SPDX-License-Identifier: Apache-2.0
2
2
  /**
3
- * Module boundary and integration notes.
4
- * Calculates sensor-plane motion during an exposure using ideal rectilinear projection and constant
5
- * linear object velocity. Without focusDistanceM, nominal focal length is the backwards-compatible
6
- * pinhole projection distance. With focusDistanceM, the selected thin-lens sensor-plane image distance
7
- * is used. The calculation projects the object's shutter-open and shutter-close positions onto the
8
- * image plane and measures the displacement between them. It therefore handles lateral and
9
- * depth-direction motion without relying on a generic "subject speed" category.
10
- * @see docs/MOTION_AND_SIGNAL.md for equations, coordinate/unit conventions, blockers and support
11
- * limits.
3
+ * How far a moving object travels across the sensor during an exposure. Uses ideal rectilinear
4
+ * projection and a constant straight-line object velocity.
5
+ * - Without focusDistanceM, the projection distance is the nominal focal length (the older pinhole
6
+ * behaviour).
7
+ * - With focusDistanceM, it is the thin-lens image distance for that focus.
8
+ *
9
+ * The object's positions when the shutter opens and closes are both projected onto the image plane,
10
+ * and the distance between them is measured. So sideways motion and motion toward or away from the
11
+ * camera are both handled, without a generic "subject speed" category.
12
+ * @see docs/MOTION_AND_SIGNAL.md for the equations, units, coordinate conventions, known blockers
13
+ * and support limits.
12
14
  */
13
15
  import { calculatedResult } from "../core/calculation-result.js";
14
16
  import { InvalidScientificInputError, requirePositiveFinite } from "../core/validation.js";
17
+ import { portableHypot } from "../core/portable-math.js";
15
18
  import { calculateThinLensImageDistance } from "../optics/thin-lens.js";
19
+ import { rejectUnknownFields, requireInputKeys, requireInputObject } from "../core/record-validation.js";
20
+ const VECTOR3_FIELDS = ["x", "y", "z"];
16
21
  function requireFiniteVector3(name, value) {
22
+ requireInputObject(value, name);
23
+ rejectUnknownFields(value, VECTOR3_FIELDS, name);
17
24
  for (const component of ["x", "y", "z"]) {
18
25
  if (!Number.isFinite(value[component])) {
19
26
  throw new InvalidScientificInputError(`${name}.${component} must be finite.`);
@@ -24,19 +31,20 @@ function requireFiniteVector3(name, value) {
24
31
  * Calculates sensor-plane motion during an exposure using ideal rectilinear
25
32
  * projection and constant linear object velocity.
26
33
  *
27
- * Without focusDistanceM, nominal focal length is the backwards-compatible
28
- * pinhole projection distance. With focusDistanceM, the selected thin-lens
29
- * sensor-plane image distance is used.
34
+ * Without focusDistanceM, the projection distance is the nominal focal length
35
+ * (the older pinhole behaviour). With focusDistanceM, it is the thin-lens
36
+ * image distance for that focus.
30
37
  *
31
- * The calculation projects the object's shutter-open and shutter-close
32
- * positions onto the image plane and measures the displacement between them.
33
- * It therefore handles lateral and depth-direction motion without relying on a
34
- * generic "subject speed" category.
38
+ * The object's positions when the shutter opens and closes are both projected
39
+ * onto the image plane, and the distance between them is measured. So
40
+ * sideways motion and motion toward or away from the camera are both handled,
41
+ * without a generic "subject speed" category.
35
42
  *
36
43
  * @param input Camera, exposure, object-position, and velocity inputs.
37
44
  * @returns Projected sensor-plane displacement.
38
45
  */
39
46
  export function calculateProjectedMotionBlur(input) {
47
+ requireInputKeys(input, "calculateProjectedMotionBlur", ["focalLengthMm", "shutterSeconds", "positionM", "velocityMps", "focusDistanceM", "pixelPitchMicrometers"]);
40
48
  requirePositiveFinite("focalLengthMm", input.focalLengthMm);
41
49
  requirePositiveFinite("shutterSeconds", input.shutterSeconds);
42
50
  requireFiniteVector3("positionM", input.positionM);
@@ -65,7 +73,7 @@ export function calculateProjectedMotionBlur(input) {
65
73
  const endYmm = projectionDistanceMm * (endPositionM.y / endPositionM.z);
66
74
  const deltaXMm = endXmm - startXmm;
67
75
  const deltaYMm = endYmm - startYmm;
68
- const distanceMm = Math.hypot(deltaXMm, deltaYMm);
76
+ const distanceMm = portableHypot(deltaXMm, deltaYMm);
69
77
  let distancePixels;
70
78
  if (input.pixelPitchMicrometers !== undefined) {
71
79
  requirePositiveFinite("pixelPitchMicrometers", input.pixelPitchMicrometers);
@@ -1 +1 @@
1
- {"version":3,"file":"projected-motion.js","sourceRoot":"","sources":["../../src/motion/projected-motion.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"projected-motion.js","sourceRoot":"","sources":["../../src/motion/projected-motion.ts"],"names":[],"mappings":"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","sourcesContent":["// SPDX-License-Identifier: Apache-2.0\n\n/**\n * How far a moving object travels across the sensor during an exposure. Uses ideal rectilinear\n * projection and a constant straight-line object velocity.\n * - Without focusDistanceM, the projection distance is the nominal focal length (the older pinhole\n * behaviour).\n * - With focusDistanceM, it is the thin-lens image distance for that focus.\n *\n * The object's positions when the shutter opens and closes are both projected onto the image plane,\n * and the distance between them is measured. So sideways motion and motion toward or away from the\n * camera are both handled, without a generic \"subject speed\" category.\n * @see docs/MOTION_AND_SIGNAL.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 { portableHypot } from \"../core/portable-math.js\";\nimport { calculateThinLensImageDistance } from \"../optics/thin-lens.js\";\nimport type { Vector3 } from \"../schema/scene.js\";\nimport { rejectUnknownFields, requireInputKeys, requireInputObject } from \"../core/record-validation.js\";\n\nconst VECTOR3_FIELDS = [\"x\", \"y\", \"z\"] as const;\n\nexport interface CalculateProjectedMotionBlurInput {\n /** Lens focal length in millimetres. */\n focalLengthMm: number;\n /** Shutter-open duration in seconds. */\n shutterSeconds: number;\n /** Object position at shutter open, in camera-relative metres. +z is away from the camera. */\n positionM: Vector3;\n /** Constant world-space velocity during the exposure, in metres per second. */\n velocityMps: Vector3;\n /** Optional focus distance in metres for focus-aware sensor-plane projection. */\n focusDistanceM?: number;\n /** Optional sensor pixel pitch in micrometres for pixel-domain blur reporting. */\n pixelPitchMicrometers?: number;\n}\n\nexport interface ProjectedMotionBlur {\n deltaXMm: number;\n deltaYMm: number;\n distanceMm: number;\n projectionDistanceMm: number;\n distancePixels?: number;\n}\n\nfunction requireFiniteVector3(name: string, value: Vector3): void {\n requireInputObject(value, name);\n rejectUnknownFields(value, VECTOR3_FIELDS, name);\n for (const component of [\"x\", \"y\", \"z\"] as const) {\n if (!Number.isFinite(value[component])) {\n throw new InvalidScientificInputError(\n `${name}.${component} must be finite.`\n );\n }\n }\n}\n\n/**\n * Calculates sensor-plane motion during an exposure using ideal rectilinear\n * projection and constant linear object velocity.\n *\n * Without focusDistanceM, the projection distance is the nominal focal length\n * (the older pinhole behaviour). With focusDistanceM, it is the thin-lens\n * image distance for that focus.\n *\n * The object's positions when the shutter opens and closes are both projected\n * onto the image plane, and the distance between them is measured. So\n * sideways motion and motion toward or away from the camera are both handled,\n * without a generic \"subject speed\" category.\n *\n * @param input Camera, exposure, object-position, and velocity inputs.\n * @returns Projected sensor-plane displacement.\n */\nexport function calculateProjectedMotionBlur(\n input: CalculateProjectedMotionBlurInput\n): CalculationResult<ProjectedMotionBlur> {\n requireInputKeys(input, \"calculateProjectedMotionBlur\", [\"focalLengthMm\", \"shutterSeconds\", \"positionM\", \"velocityMps\", \"focusDistanceM\", \"pixelPitchMicrometers\"]);\n requirePositiveFinite(\"focalLengthMm\", input.focalLengthMm);\n requirePositiveFinite(\"shutterSeconds\", input.shutterSeconds);\n\n requireFiniteVector3(\"positionM\", input.positionM);\n requireFiniteVector3(\"velocityMps\", input.velocityMps);\n\n if (input.positionM.z <= 0) {\n throw new InvalidScientificInputError(\n \"positionM.z must place the object in front of the camera.\"\n );\n }\n\n const endPositionM = {\n x: input.positionM.x + input.velocityMps.x * input.shutterSeconds,\n y: input.positionM.y + input.velocityMps.y * input.shutterSeconds,\n z: input.positionM.z + input.velocityMps.z * input.shutterSeconds\n };\n\n if (endPositionM.z <= 0) {\n throw new InvalidScientificInputError(\n \"Object motion crosses or reaches the camera plane during the exposure.\"\n );\n }\n\n const focusProjection =\n input.focusDistanceM === undefined\n ? undefined\n : calculateThinLensImageDistance({\n focalLengthMm: input.focalLengthMm,\n objectDistanceM: input.focusDistanceM\n });\n const projectionDistanceMm =\n focusProjection?.value.imageDistanceMm ?? input.focalLengthMm;\n\n const startXmm =\n projectionDistanceMm * (input.positionM.x / input.positionM.z);\n const startYmm =\n projectionDistanceMm * (input.positionM.y / input.positionM.z);\n const endXmm =\n projectionDistanceMm * (endPositionM.x / endPositionM.z);\n const endYmm =\n projectionDistanceMm * (endPositionM.y / endPositionM.z);\n\n const deltaXMm = endXmm - startXmm;\n const deltaYMm = endYmm - startYmm;\n const distanceMm = portableHypot(deltaXMm, deltaYMm);\n\n let distancePixels: number | undefined;\n if (input.pixelPitchMicrometers !== undefined) {\n requirePositiveFinite(\n \"pixelPitchMicrometers\",\n input.pixelPitchMicrometers\n );\n distancePixels = distanceMm / (input.pixelPitchMicrometers / 1000);\n }\n\n return calculatedResult(\n {\n deltaXMm,\n deltaYMm,\n distanceMm,\n projectionDistanceMm,\n ...(distancePixels === undefined ? {} : { distancePixels })\n },\n focusProjection === undefined\n ? \"constant-velocity-pinhole-motion\"\n : \"focus-aware-constant-velocity-thin-lens-motion\",\n \"1.0.0\",\n focusProjection === undefined\n ? [\n \"Ideal rectilinear/pinhole projection\",\n \"Constant object velocity during the exposure\",\n \"Camera motion is not included in this calculation\"\n ]\n : [\n \"Ideal rectilinear paraxial thin-lens projection to the selected sensor plane\",\n \"Constant object velocity during the exposure\",\n \"Camera motion is not included in this calculation\",\n \"Real-lens focus breathing is not modeled\"\n ]\n );\n}\n"]}
@@ -0,0 +1,55 @@
1
+ export declare const TEMPORAL_EXPOSURE_SUM_SCHEMA_VERSION: "0.1.0";
2
+ export declare const TEMPORAL_EXPOSURE_SUM_LIMITS: Readonly<{
3
+ maximumPixels: 24000000;
4
+ maximumDimension: 16384;
5
+ maximumTemporalSamples: 256;
6
+ maximumDisplacementSites: 4096;
7
+ maximumRowWeights: 4194304;
8
+ /** Keeps every float32 partial sum finite: 256 · 2^16 · 2^100 < 2^128. */
9
+ maximumSampleMagnitude: number;
10
+ maximumWeight: number;
11
+ }>;
12
+ export interface TemporalExposureSumInput {
13
+ schemaVersion: typeof TEMPORAL_EXPOSURE_SUM_SCHEMA_VERSION;
14
+ width: number;
15
+ height: number;
16
+ /** Row-major rate samples E₀ at site centres. Finite, non-negative, linear and additive (irradiance, photon or electron rate). */
17
+ samples: Float32Array | Float64Array;
18
+ /** Image displacement at each temporal node in grid sites, interleaved (dx₀, dy₀, dx₁, dy₁, …); +x right, +y down. */
19
+ displacements: Float64Array;
20
+ /** Quadrature weights `[k][row]` (nodes × height), finite and non-negative, for example seconds of each row's window near t_k. */
21
+ rowWeights: Float32Array | Float64Array;
22
+ boundary: "zero-outside-grid";
23
+ }
24
+ /** One temporal node: integer source offset of the top-left tap and the four bilinear weights (float64). */
25
+ export interface TemporalExposureSumNode {
26
+ offsetX: number;
27
+ offsetY: number;
28
+ weights: readonly [number, number, number, number];
29
+ }
30
+ export interface TemporalExposureSumPlan {
31
+ width: number;
32
+ height: number;
33
+ nodeCount: number;
34
+ nodes: readonly TemporalExposureSumNode[];
35
+ maximumSampleMagnitude: number;
36
+ /** Largest Σ_k w_k(y) over rows; the operator's weight sum for error composition. */
37
+ maximumRowWeightSum: number;
38
+ maximumWeight: number;
39
+ /** True when every displacement is a whole number of sites (no interpolation). */
40
+ integerDisplacements: boolean;
41
+ }
42
+ /** Validates the request (every value once) and returns its plan. */
43
+ export declare function calculateTemporalExposureSumPlan(input: TemporalExposureSumInput): TemporalExposureSumPlan;
44
+ /**
45
+ * Reference rows `[y0, y1)` into `output` at `(y − y0)·width + x`. The order (node ascending; taps 00,
46
+ * 10, 01, 11 summed left to right; then times the row weight) is part of the contract shared with the
47
+ * WGSL kernel.
48
+ * @internal
49
+ */
50
+ export declare function sumTemporalExposureRows(plan: TemporalExposureSumPlan, samples: Float32Array | Float64Array, rowWeights: Float32Array | Float64Array, y0: number, y1: number, output: Float64Array): void;
51
+ /** Synchronous float64 reference for bounded grids. Use the image-kernel accelerator for large grids. */
52
+ export declare function calculateTemporalExposureSum(input: TemporalExposureSumInput): {
53
+ plan: TemporalExposureSumPlan;
54
+ values: Float64Array;
55
+ };
@@ -0,0 +1,141 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ /**
3
+ * Exposure and motion as a weighted sum of shifted frames (#277, image-formation step 3). The CPU
4
+ * float64 reference for the `webgpu-f32` temporal stage; see docs/WEBGPU.md.
5
+ *
6
+ * A site's exposure is the time integral of its image-plane rate quantity over its own exposure window,
7
+ * H = ∫ E(x, t) dt (EMVA Standard 1288 Release 4.0 Linear, §2, free; CIPA DC-004-2020 §5.5, free). For an
8
+ * image that translates rigidly by d(t) on the sensor, E(x, t) = E₀(x − d(t)), so a temporal quadrature
9
+ * with nodes t_k and weights w_k gives
10
+ *
11
+ * out(x, y) = Σ_k w_k(y) · E₀(x − dx_k, y − dy_k).
12
+ *
13
+ * Motion blur is this superposition of displaced images (Szeliski, *Computer Vision: Algorithms and
14
+ * Applications*, 2nd ed., 2022, free at https://szeliski.org/Book/). The weights depend on the row so a
15
+ * rolling shutter, whose rows start and end their exposure at different times, is the same sum with
16
+ * row-dependent windows (Meingast, Geyer & Sastry, "Geometric Models of Rolling-Shutter Cameras",
17
+ * arXiv:cs/0503076, free); a global shutter uses the same weights on every row.
18
+ *
19
+ * Declared approximations, owned by the caller: the quadrature nodes and weights, and rigid translation
20
+ * (no rotation, warp or occlusion). Sub-site displacements use bilinear interpolation between the four
21
+ * nearest site centres, which is linear interpolation and slightly low-pass; it is labelled as an
22
+ * approximation, not exact resampling. Sources outside the grid are zero; no padding or renormalization.
23
+ */
24
+ import { InvalidConfigurationError } from "../core/configuration-error.js";
25
+ import { requireAllowlistedRecord } from "../core/record-validation.js";
26
+ export const TEMPORAL_EXPOSURE_SUM_SCHEMA_VERSION = "0.1.0";
27
+ export const TEMPORAL_EXPOSURE_SUM_LIMITS = Object.freeze({
28
+ maximumPixels: 24_000_000,
29
+ maximumDimension: 16_384,
30
+ maximumTemporalSamples: 256,
31
+ maximumDisplacementSites: 4_096,
32
+ maximumRowWeights: 4_194_304,
33
+ /** Keeps every float32 partial sum finite: 256 · 2^16 · 2^100 < 2^128. */
34
+ maximumSampleMagnitude: 2 ** 100,
35
+ maximumWeight: 2 ** 16
36
+ });
37
+ function positiveInteger(value, maximum) {
38
+ if (typeof value !== "number" || !Number.isSafeInteger(value) || value <= 0 || value > maximum) {
39
+ throw new InvalidConfigurationError("Invalid temporal exposure sum geometry.");
40
+ }
41
+ return value;
42
+ }
43
+ /** Validates the request (every value once) and returns its plan. */
44
+ export function calculateTemporalExposureSumPlan(input) {
45
+ const r = requireAllowlistedRecord(input, ["schemaVersion", "width", "height", "samples", "displacements", "rowWeights", "boundary"], "Invalid temporal exposure sum input.");
46
+ const L = TEMPORAL_EXPOSURE_SUM_LIMITS;
47
+ if (r.schemaVersion !== TEMPORAL_EXPOSURE_SUM_SCHEMA_VERSION || r.boundary !== "zero-outside-grid") {
48
+ throw new InvalidConfigurationError("Unsupported temporal exposure sum schema or boundary.");
49
+ }
50
+ const width = positiveInteger(r.width, L.maximumDimension), height = positiveInteger(r.height, L.maximumDimension);
51
+ if (width * height > L.maximumPixels)
52
+ throw new InvalidConfigurationError("Temporal exposure sum grid exceeds the pixel limit.");
53
+ const samples = r.samples, displacements = r.displacements, weights = r.rowWeights;
54
+ if (!(displacements instanceof Float64Array) || displacements.length < 2 || displacements.length % 2 !== 0 ||
55
+ displacements.length / 2 > L.maximumTemporalSamples) {
56
+ throw new InvalidConfigurationError("Temporal exposure sum needs 1 to 256 displacement pairs.");
57
+ }
58
+ const nodeCount = displacements.length / 2;
59
+ if (!(samples instanceof Float32Array || samples instanceof Float64Array) || samples.length !== width * height ||
60
+ !(weights instanceof Float32Array || weights instanceof Float64Array) || weights.length !== nodeCount * height ||
61
+ weights.length > L.maximumRowWeights) {
62
+ throw new InvalidConfigurationError("Temporal exposure sum arrays do not match the declared geometry.");
63
+ }
64
+ let maximumSampleMagnitude = 0;
65
+ for (let i = 0; i < samples.length; i++) {
66
+ const v = samples[i];
67
+ if (!(v >= 0 && v <= L.maximumSampleMagnitude))
68
+ throw new InvalidConfigurationError("Temporal samples must be finite, non-negative and bounded.");
69
+ if (v > maximumSampleMagnitude)
70
+ maximumSampleMagnitude = v;
71
+ }
72
+ let maximumWeight = 0, maximumRowWeightSum = 0;
73
+ const rowSums = new Float64Array(height);
74
+ for (let k = 0; k < nodeCount; k++) {
75
+ for (let y = 0; y < height; y++) {
76
+ const w = weights[k * height + y];
77
+ if (!(w >= 0 && w <= L.maximumWeight))
78
+ throw new InvalidConfigurationError("Temporal row weights must be finite, non-negative and bounded.");
79
+ if (w > maximumWeight)
80
+ maximumWeight = w;
81
+ rowSums[y] += w;
82
+ }
83
+ }
84
+ for (const s of rowSums)
85
+ if (s > maximumRowWeightSum)
86
+ maximumRowWeightSum = s;
87
+ let integerDisplacements = true;
88
+ const nodes = [];
89
+ for (let k = 0; k < nodeCount; k++) {
90
+ const dx = displacements[2 * k], dy = displacements[2 * k + 1];
91
+ if (!(Math.abs(dx) <= L.maximumDisplacementSites && Math.abs(dy) <= L.maximumDisplacementSites)) {
92
+ throw new InvalidConfigurationError("Temporal displacements must be finite and within 4096 sites.");
93
+ }
94
+ // Source position x − dx = x + offsetX + ax with ax in [0, 1).
95
+ const offsetX = Math.floor(-dx), offsetY = Math.floor(-dy), ax = -dx - offsetX, ay = -dy - offsetY;
96
+ if (ax !== 0 || ay !== 0)
97
+ integerDisplacements = false;
98
+ nodes.push(Object.freeze({ offsetX, offsetY,
99
+ weights: Object.freeze([(1 - ax) * (1 - ay), ax * (1 - ay), (1 - ax) * ay, ax * ay]) }));
100
+ }
101
+ return Object.freeze({ width, height, nodeCount, nodes: Object.freeze(nodes), maximumSampleMagnitude, maximumRowWeightSum, maximumWeight,
102
+ integerDisplacements });
103
+ }
104
+ /**
105
+ * Reference rows `[y0, y1)` into `output` at `(y − y0)·width + x`. The order (node ascending; taps 00,
106
+ * 10, 01, 11 summed left to right; then times the row weight) is part of the contract shared with the
107
+ * WGSL kernel.
108
+ * @internal
109
+ */
110
+ export function sumTemporalExposureRows(plan, samples, rowWeights, y0, y1, output) {
111
+ const { width, height, nodes } = plan;
112
+ for (let y = y0; y < y1; y++) {
113
+ for (let x = 0; x < width; x++) {
114
+ let sum = 0;
115
+ for (let k = 0; k < nodes.length; k++) {
116
+ const node = nodes[k], sx = x + node.offsetX, sy = y + node.offsetY, b = node.weights;
117
+ const left = sx >= 0 && sx < width, right = sx + 1 >= 0 && sx + 1 < width;
118
+ const top = sy >= 0 && sy < height, bottom = sy + 1 >= 0 && sy + 1 < height;
119
+ let inner = 0;
120
+ if (top && left)
121
+ inner += b[0] * samples[sy * width + sx];
122
+ if (top && right)
123
+ inner += b[1] * samples[sy * width + sx + 1];
124
+ if (bottom && left)
125
+ inner += b[2] * samples[(sy + 1) * width + sx];
126
+ if (bottom && right)
127
+ inner += b[3] * samples[(sy + 1) * width + sx + 1];
128
+ sum += rowWeights[k * height + y] * inner;
129
+ }
130
+ output[(y - y0) * width + x] = sum;
131
+ }
132
+ }
133
+ }
134
+ /** Synchronous float64 reference for bounded grids. Use the image-kernel accelerator for large grids. */
135
+ export function calculateTemporalExposureSum(input) {
136
+ const plan = calculateTemporalExposureSumPlan(input);
137
+ const values = new Float64Array(plan.width * plan.height);
138
+ sumTemporalExposureRows(plan, input.samples, input.rowWeights, 0, plan.height, values);
139
+ return { plan, values };
140
+ }
141
+ //# sourceMappingURL=temporal-exposure-sum.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"temporal-exposure-sum.js","sourceRoot":"","sources":["../../src/motion/temporal-exposure-sum.ts"],"names":[],"mappings":"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","sourcesContent":["// SPDX-License-Identifier: Apache-2.0\n\n/**\n * Exposure and motion as a weighted sum of shifted frames (#277, image-formation step 3). The CPU\n * float64 reference for the `webgpu-f32` temporal stage; see docs/WEBGPU.md.\n *\n * A site's exposure is the time integral of its image-plane rate quantity over its own exposure window,\n * H = ∫ E(x, t) dt (EMVA Standard 1288 Release 4.0 Linear, §2, free; CIPA DC-004-2020 §5.5, free). For an\n * image that translates rigidly by d(t) on the sensor, E(x, t) = E₀(x − d(t)), so a temporal quadrature\n * with nodes t_k and weights w_k gives\n *\n * out(x, y) = Σ_k w_k(y) · E₀(x − dx_k, y − dy_k).\n *\n * Motion blur is this superposition of displaced images (Szeliski, *Computer Vision: Algorithms and\n * Applications*, 2nd ed., 2022, free at https://szeliski.org/Book/). The weights depend on the row so a\n * rolling shutter, whose rows start and end their exposure at different times, is the same sum with\n * row-dependent windows (Meingast, Geyer & Sastry, \"Geometric Models of Rolling-Shutter Cameras\",\n * arXiv:cs/0503076, free); a global shutter uses the same weights on every row.\n *\n * Declared approximations, owned by the caller: the quadrature nodes and weights, and rigid translation\n * (no rotation, warp or occlusion). Sub-site displacements use bilinear interpolation between the four\n * nearest site centres, which is linear interpolation and slightly low-pass; it is labelled as an\n * approximation, not exact resampling. Sources outside the grid are zero; no padding or renormalization.\n */\nimport { InvalidConfigurationError } from \"../core/configuration-error.js\";\nimport { requireAllowlistedRecord } from \"../core/record-validation.js\";\n\nexport const TEMPORAL_EXPOSURE_SUM_SCHEMA_VERSION = \"0.1.0\" as const;\nexport const TEMPORAL_EXPOSURE_SUM_LIMITS = Object.freeze({\n maximumPixels: 24_000_000,\n maximumDimension: 16_384,\n maximumTemporalSamples: 256,\n maximumDisplacementSites: 4_096,\n maximumRowWeights: 4_194_304,\n /** Keeps every float32 partial sum finite: 256 · 2^16 · 2^100 < 2^128. */\n maximumSampleMagnitude: 2 ** 100,\n maximumWeight: 2 ** 16\n});\n\nexport interface TemporalExposureSumInput {\n schemaVersion: typeof TEMPORAL_EXPOSURE_SUM_SCHEMA_VERSION;\n width: number;\n height: number;\n /** Row-major rate samples E₀ at site centres. Finite, non-negative, linear and additive (irradiance, photon or electron rate). */\n samples: Float32Array | Float64Array;\n /** Image displacement at each temporal node in grid sites, interleaved (dx₀, dy₀, dx₁, dy₁, …); +x right, +y down. */\n displacements: Float64Array;\n /** Quadrature weights `[k][row]` (nodes × height), finite and non-negative, for example seconds of each row's window near t_k. */\n rowWeights: Float32Array | Float64Array;\n boundary: \"zero-outside-grid\";\n}\n\n/** One temporal node: integer source offset of the top-left tap and the four bilinear weights (float64). */\nexport interface TemporalExposureSumNode {\n offsetX: number;\n offsetY: number;\n weights: readonly [number, number, number, number];\n}\n\nexport interface TemporalExposureSumPlan {\n width: number;\n height: number;\n nodeCount: number;\n nodes: readonly TemporalExposureSumNode[];\n maximumSampleMagnitude: number;\n /** Largest Σ_k w_k(y) over rows; the operator's weight sum for error composition. */\n maximumRowWeightSum: number;\n maximumWeight: number;\n /** True when every displacement is a whole number of sites (no interpolation). */\n integerDisplacements: boolean;\n}\n\nfunction positiveInteger(value: unknown, maximum: number): number {\n if (typeof value !== \"number\" || !Number.isSafeInteger(value) || value <= 0 || value > maximum) {\n throw new InvalidConfigurationError(\"Invalid temporal exposure sum geometry.\");\n }\n return value;\n}\n\n/** Validates the request (every value once) and returns its plan. */\nexport function calculateTemporalExposureSumPlan(input: TemporalExposureSumInput): TemporalExposureSumPlan {\n const r = requireAllowlistedRecord(input, [\"schemaVersion\", \"width\", \"height\", \"samples\", \"displacements\", \"rowWeights\", \"boundary\"],\n \"Invalid temporal exposure sum input.\");\n const L = TEMPORAL_EXPOSURE_SUM_LIMITS;\n if (r.schemaVersion !== TEMPORAL_EXPOSURE_SUM_SCHEMA_VERSION || r.boundary !== \"zero-outside-grid\") {\n throw new InvalidConfigurationError(\"Unsupported temporal exposure sum schema or boundary.\");\n }\n const width = positiveInteger(r.width, L.maximumDimension), height = positiveInteger(r.height, L.maximumDimension);\n if (width * height > L.maximumPixels) throw new InvalidConfigurationError(\"Temporal exposure sum grid exceeds the pixel limit.\");\n const samples = r.samples, displacements = r.displacements, weights = r.rowWeights;\n if (!(displacements instanceof Float64Array) || displacements.length < 2 || displacements.length % 2 !== 0 ||\n displacements.length / 2 > L.maximumTemporalSamples) {\n throw new InvalidConfigurationError(\"Temporal exposure sum needs 1 to 256 displacement pairs.\");\n }\n const nodeCount = displacements.length / 2;\n if (!(samples instanceof Float32Array || samples instanceof Float64Array) || samples.length !== width * height ||\n !(weights instanceof Float32Array || weights instanceof Float64Array) || weights.length !== nodeCount * height ||\n weights.length > L.maximumRowWeights) {\n throw new InvalidConfigurationError(\"Temporal exposure sum arrays do not match the declared geometry.\");\n }\n let maximumSampleMagnitude = 0;\n for (let i = 0; i < samples.length; i++) {\n const v = samples[i]!;\n if (!(v >= 0 && v <= L.maximumSampleMagnitude)) throw new InvalidConfigurationError(\"Temporal samples must be finite, non-negative and bounded.\");\n if (v > maximumSampleMagnitude) maximumSampleMagnitude = v;\n }\n let maximumWeight = 0, maximumRowWeightSum = 0;\n const rowSums = new Float64Array(height);\n for (let k = 0; k < nodeCount; k++) {\n for (let y = 0; y < height; y++) {\n const w = weights[k * height + y]!;\n if (!(w >= 0 && w <= L.maximumWeight)) throw new InvalidConfigurationError(\"Temporal row weights must be finite, non-negative and bounded.\");\n if (w > maximumWeight) maximumWeight = w;\n rowSums[y]! += w;\n }\n }\n for (const s of rowSums) if (s > maximumRowWeightSum) maximumRowWeightSum = s;\n let integerDisplacements = true;\n const nodes: TemporalExposureSumNode[] = [];\n for (let k = 0; k < nodeCount; k++) {\n const dx = displacements[2 * k]!, dy = displacements[2 * k + 1]!;\n if (!(Math.abs(dx) <= L.maximumDisplacementSites && Math.abs(dy) <= L.maximumDisplacementSites)) {\n throw new InvalidConfigurationError(\"Temporal displacements must be finite and within 4096 sites.\");\n }\n // Source position x − dx = x + offsetX + ax with ax in [0, 1).\n const offsetX = Math.floor(-dx), offsetY = Math.floor(-dy), ax = -dx - offsetX, ay = -dy - offsetY;\n if (ax !== 0 || ay !== 0) integerDisplacements = false;\n nodes.push(Object.freeze({ offsetX, offsetY,\n weights: Object.freeze([(1 - ax) * (1 - ay), ax * (1 - ay), (1 - ax) * ay, ax * ay] as const) }));\n }\n return Object.freeze({ width, height, nodeCount, nodes: Object.freeze(nodes), maximumSampleMagnitude, maximumRowWeightSum, maximumWeight,\n integerDisplacements });\n}\n\n/**\n * Reference rows `[y0, y1)` into `output` at `(y − y0)·width + x`. The order (node ascending; taps 00,\n * 10, 01, 11 summed left to right; then times the row weight) is part of the contract shared with the\n * WGSL kernel.\n * @internal\n */\nexport function sumTemporalExposureRows(plan: TemporalExposureSumPlan, samples: Float32Array | Float64Array, rowWeights: Float32Array | Float64Array,\n y0: number, y1: number, output: Float64Array): void {\n const { width, height, nodes } = plan;\n for (let y = y0; y < y1; y++) {\n for (let x = 0; x < width; x++) {\n let sum = 0;\n for (let k = 0; k < nodes.length; k++) {\n const node = nodes[k]!, sx = x + node.offsetX, sy = y + node.offsetY, b = node.weights;\n const left = sx >= 0 && sx < width, right = sx + 1 >= 0 && sx + 1 < width;\n const top = sy >= 0 && sy < height, bottom = sy + 1 >= 0 && sy + 1 < height;\n let inner = 0;\n if (top && left) inner += b[0] * samples[sy * width + sx]!;\n if (top && right) inner += b[1] * samples[sy * width + sx + 1]!;\n if (bottom && left) inner += b[2] * samples[(sy + 1) * width + sx]!;\n if (bottom && right) inner += b[3] * samples[(sy + 1) * width + sx + 1]!;\n sum += rowWeights[k * height + y]! * inner;\n }\n output[(y - y0) * width + x] = sum;\n }\n }\n}\n\n/** Synchronous float64 reference for bounded grids. Use the image-kernel accelerator for large grids. */\nexport function calculateTemporalExposureSum(input: TemporalExposureSumInput): { plan: TemporalExposureSumPlan; values: Float64Array } {\n const plan = calculateTemporalExposureSumPlan(input);\n const values = new Float64Array(plan.width * plan.height);\n sumTemporalExposureRows(plan, input.samples, input.rowWeights, 0, plan.height, values);\n return { plan, values };\n}\n"]}
@@ -0,0 +1,111 @@
1
+ /**
2
+ * Video frame sequences. Builds a deterministic sequence of frames from the "video" optical capture
3
+ * state (frameRateHz) and a shutter angle.
4
+ *
5
+ * Each frame is an ordinary ResolvedReleaseFrame, so the production capture snapshot and
6
+ * image-formation plan use it unchanged. An optional electronic rolling shutter gives every frame the
7
+ * same line-by-line exposure offsets. Frame timing, seeds and schedules depend only on the inputs and
8
+ * the absolute frame index. They never depend on how the sequence is split into chunks, or on
9
+ * earlier frames.
10
+ * @see docs/MOTION_AND_SIGNAL.md#video-frame-sequences for equations, conventions and limits.
11
+ */
12
+ import { type EvidenceProvenance } from "../core/evidence-provenance.js";
13
+ import type { ReleaseAutomationState, ResolvedReleaseFrame } from "../capture/release-sequence.js";
14
+ import { type FocusPlane } from "../optics/focus-state.js";
15
+ import { type OpticalProfileState } from "../optics/profile-contract.js";
16
+ import { createRollingShutterCaptureExposureSchedule, type ElectronicRollingShutterExposureSchedule } from "../sensor/readout-exposure-linkage.js";
17
+ import type { RollingSensorReadoutTimingDeclaration } from "../sensor/readout-timing.js";
18
+ export declare const VIDEO_FRAME_SEQUENCE_VERSION: "1.0.0";
19
+ /** Stream identifier ("VIDF"). Keeps per-frame video seeds separate from per-site noise streams. */
20
+ export declare const VIDEO_FRAME_SEED_STREAM_ID: 1447642182;
21
+ /** Maximum frames per call. Resolve longer clips in chunks using firstFrameIndex. */
22
+ export declare const VIDEO_FRAME_SEQUENCE_MAXIMUM_FRAMES: 100000;
23
+ /**
24
+ * Exposure time for a shutter angle (as on a rotary film-camera shutter): t = (angle / 360) / frameRateHz.
25
+ * A 180° angle exposes for half of each frame period.
26
+ */
27
+ export declare function calculateShutterAngleExposureSeconds(frameRateHz: number, shutterAngleDegrees: number): number;
28
+ /** Inverse of {@link calculateShutterAngleExposureSeconds}: angle = 360 · frameRateHz · t. */
29
+ export declare function calculateShutterAngleFromExposureSeconds(frameRateHz: number, exposureSeconds: number): number;
30
+ export interface ShutterAngleRuleAssessment {
31
+ frameRateHz: number;
32
+ shutterAngleDegrees: number;
33
+ exposureSeconds: number;
34
+ /** 1 / (2 · frameRateHz): the 180° convention. */
35
+ conventionExposureSeconds: number;
36
+ /** log2(exposure / convention): negative is shorter (crisper, more staccato) motion. */
37
+ deviationStops: number;
38
+ classification: "matches-180-degree-convention" | "shorter-than-convention" | "longer-than-convention";
39
+ /** The 180° rule is a cinematographic convention for motion-blur appearance, not a physical law. */
40
+ conventionNotPhysics: true;
41
+ }
42
+ /**
43
+ * Compares a shutter angle with the 180° cinematographic convention (exposure = half the frame
44
+ * period). Within a relative 1e-9 the angle "matches". Otherwise the signed deviation is reported.
45
+ */
46
+ export declare function assessShutterAngleRule(frameRateHz: number, shutterAngleDegrees: number): ShutterAngleRuleAssessment;
47
+ export interface ResolveVideoFrameSequenceInput {
48
+ sequenceId: string;
49
+ /** Exact optical capture state. captureMode must be "video", with a positive frameRateHz. */
50
+ opticalState: OpticalProfileState;
51
+ /** Shutter angle in (0, 360]; exposure = angle / 360 / frameRateHz. */
52
+ shutterAngleDegrees: number;
53
+ /** Absolute index of the first frame to resolve (default 0). */
54
+ firstFrameIndex?: number;
55
+ frameCount: number;
56
+ sequenceSeedUint32: number;
57
+ iso: number;
58
+ /** Defaults to the optical state's finite focus distance. */
59
+ focus?: FocusPlane;
60
+ automation: {
61
+ ae: ReleaseAutomationState;
62
+ af: ReleaseAutomationState;
63
+ awb: ReleaseAutomationState;
64
+ };
65
+ whiteBalanceStateId?: string;
66
+ /** Evidence for the commanded frame rate and shutter-angle timing. Used for the exposure fact. */
67
+ timingEvidence: readonly EvidenceProvenance[];
68
+ /** Optional electronic rolling shutter applied identically to every frame. */
69
+ rollingShutter?: {
70
+ readout: RollingSensorReadoutTimingDeclaration;
71
+ linkageEvidence: readonly EvidenceProvenance[];
72
+ };
73
+ }
74
+ export interface VideoFrameSequence {
75
+ version: typeof VIDEO_FRAME_SEQUENCE_VERSION;
76
+ sequenceId: string;
77
+ frameRateHz: number;
78
+ framePeriodSeconds: number;
79
+ shutterAngleDegrees: number;
80
+ exposureSeconds: number;
81
+ shutterAngleRule: ShutterAngleRuleAssessment;
82
+ firstFrameIndex: number;
83
+ frameCount: number;
84
+ sequenceSeedUint32: number;
85
+ seedDerivation: "murmur3-x86-32(sequenceSeed, absoluteFrameIndex, VIDEO_FRAME_SEED_STREAM_ID)";
86
+ frameTimeDerivation: "absoluteFrameIndex / frameRateHz";
87
+ /**
88
+ * Exposure schedule for each frame. It is the same for every frame; times are relative to each
89
+ * frame's own first-opening phase. Null when no rolling shutter is declared; the caller then
90
+ * supplies the global schedule of its capture mode.
91
+ */
92
+ exposureSchedule: ReturnType<typeof createRollingShutterCaptureExposureSchedule> | null;
93
+ rollingShutter: Pick<ElectronicRollingShutterExposureSchedule, "modelId" | "modelVersion" | "lineScanSkewSeconds" | "linkage"> | null;
94
+ /** Ordinary release frames: pass each to createProductionCaptureSnapshotFromReleaseFrame. */
95
+ frames: readonly ResolvedReleaseFrame[];
96
+ limitations: readonly string[];
97
+ }
98
+ /**
99
+ * Resolves `frameCount` consecutive video frames starting at `firstFrameIndex`.
100
+ *
101
+ * Frame k (absolute index) opens k / frameRateHz seconds after the sequence starts, and exposes for
102
+ * (angle / 360) / frameRateHz. Its random seed is a MurmurHash3 of (sequence seed, k, stream id).
103
+ *
104
+ * Every value depends only on the inputs and k. So resolving frames 0–99 at once, or as 0–49 then
105
+ * 50–99, gives identical frames.
106
+ *
107
+ * With a rolling shutter, the line at normalized scan position s in frame k integrates over
108
+ * [k/f + s·τ, k/f + s·τ + T]. τ must not exceed the frame period, so each line is read once per
109
+ * frame.
110
+ */
111
+ export declare function resolveVideoFrameSequence(input: ResolveVideoFrameSequenceInput): VideoFrameSequence;
@@ -0,0 +1,179 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ /**
3
+ * Video frame sequences. Builds a deterministic sequence of frames from the "video" optical capture
4
+ * state (frameRateHz) and a shutter angle.
5
+ *
6
+ * Each frame is an ordinary ResolvedReleaseFrame, so the production capture snapshot and
7
+ * image-formation plan use it unchanged. An optional electronic rolling shutter gives every frame the
8
+ * same line-by-line exposure offsets. Frame timing, seeds and schedules depend only on the inputs and
9
+ * the absolute frame index. They never depend on how the sequence is split into chunks, or on
10
+ * earlier frames.
11
+ * @see docs/MOTION_AND_SIGNAL.md#video-frame-sequences for equations, conventions and limits.
12
+ */
13
+ import { parseEvidenceList } from "../core/evidence-provenance.js";
14
+ import { InvalidConfigurationError } from "../core/configuration-error.js";
15
+ import { rejectUnknownFields, requireInputObject, requirePublicOpaqueId, requireInputKeys } from "../core/record-validation.js";
16
+ import { InvalidScientificInputError } from "../core/validation.js";
17
+ import { parseFocusPlane } from "../optics/focus-state.js";
18
+ import { parseOpticalProfileState } from "../optics/profile-contract.js";
19
+ import { resolveElectronicRollingShutterExposureSchedule, ELECTRONIC_ROLLING_SHUTTER_MODEL, createRollingShutterCaptureExposureSchedule } from "../sensor/readout-exposure-linkage.js";
20
+ import { deriveNativeSiteStreamSeedUint32 } from "../sensor/stochastic-seed.js";
21
+ export const VIDEO_FRAME_SEQUENCE_VERSION = "1.0.0";
22
+ /** Stream identifier ("VIDF"). Keeps per-frame video seeds separate from per-site noise streams. */
23
+ export const VIDEO_FRAME_SEED_STREAM_ID = 0x56494446;
24
+ /** Maximum frames per call. Resolve longer clips in chunks using firstFrameIndex. */
25
+ export const VIDEO_FRAME_SEQUENCE_MAXIMUM_FRAMES = 100_000;
26
+ function requireFrameRate(frameRateHz) {
27
+ if (typeof frameRateHz !== "number" || !Number.isFinite(frameRateHz) || frameRateHz <= 0) {
28
+ throw new InvalidScientificInputError("frameRateHz must be a finite number greater than zero.");
29
+ }
30
+ return frameRateHz;
31
+ }
32
+ function requireShutterAngle(shutterAngleDegrees) {
33
+ if (typeof shutterAngleDegrees !== "number" || !Number.isFinite(shutterAngleDegrees) ||
34
+ shutterAngleDegrees <= 0 || shutterAngleDegrees > 360) {
35
+ throw new InvalidScientificInputError("shutterAngleDegrees must lie in (0, 360].");
36
+ }
37
+ return shutterAngleDegrees;
38
+ }
39
+ /**
40
+ * Exposure time for a shutter angle (as on a rotary film-camera shutter): t = (angle / 360) / frameRateHz.
41
+ * A 180° angle exposes for half of each frame period.
42
+ */
43
+ export function calculateShutterAngleExposureSeconds(frameRateHz, shutterAngleDegrees) {
44
+ return requireShutterAngle(shutterAngleDegrees) / 360 / requireFrameRate(frameRateHz);
45
+ }
46
+ /** Inverse of {@link calculateShutterAngleExposureSeconds}: angle = 360 · frameRateHz · t. */
47
+ export function calculateShutterAngleFromExposureSeconds(frameRateHz, exposureSeconds) {
48
+ if (typeof exposureSeconds !== "number" || !Number.isFinite(exposureSeconds) || exposureSeconds <= 0) {
49
+ throw new InvalidScientificInputError("exposureSeconds must be a finite number greater than zero.");
50
+ }
51
+ const angle = 360 * requireFrameRate(frameRateHz) * exposureSeconds;
52
+ if (angle > 360 * (1 + 1e-12)) {
53
+ throw new InvalidScientificInputError("Exposure longer than one frame period has no shutter angle.");
54
+ }
55
+ return Math.min(360, angle);
56
+ }
57
+ /**
58
+ * Compares a shutter angle with the 180° cinematographic convention (exposure = half the frame
59
+ * period). Within a relative 1e-9 the angle "matches". Otherwise the signed deviation is reported.
60
+ */
61
+ export function assessShutterAngleRule(frameRateHz, shutterAngleDegrees) {
62
+ const exposureSeconds = calculateShutterAngleExposureSeconds(frameRateHz, shutterAngleDegrees);
63
+ const conventionExposureSeconds = 1 / (2 * frameRateHz);
64
+ const ratio = exposureSeconds / conventionExposureSeconds;
65
+ return {
66
+ frameRateHz, shutterAngleDegrees, exposureSeconds, conventionExposureSeconds,
67
+ deviationStops: Math.log2(ratio),
68
+ classification: Math.abs(ratio - 1) <= 1e-9 ? "matches-180-degree-convention"
69
+ : ratio < 1 ? "shorter-than-convention" : "longer-than-convention",
70
+ conventionNotPhysics: true
71
+ };
72
+ }
73
+ /**
74
+ * Resolves `frameCount` consecutive video frames starting at `firstFrameIndex`.
75
+ *
76
+ * Frame k (absolute index) opens k / frameRateHz seconds after the sequence starts, and exposes for
77
+ * (angle / 360) / frameRateHz. Its random seed is a MurmurHash3 of (sequence seed, k, stream id).
78
+ *
79
+ * Every value depends only on the inputs and k. So resolving frames 0–99 at once, or as 0–49 then
80
+ * 50–99, gives identical frames.
81
+ *
82
+ * With a rolling shutter, the line at normalized scan position s in frame k integrates over
83
+ * [k/f + s·τ, k/f + s·τ + T]. τ must not exceed the frame period, so each line is read once per
84
+ * frame.
85
+ */
86
+ export function resolveVideoFrameSequence(input) {
87
+ requireInputKeys(input, "resolveVideoFrameSequence", ["sequenceId", "opticalState", "shutterAngleDegrees", "firstFrameIndex", "frameCount", "sequenceSeedUint32", "iso", "focus", "automation", "whiteBalanceStateId", "timingEvidence", "rollingShutter"]);
88
+ requireInputObject(input.automation, "resolveVideoFrameSequence automation");
89
+ rejectUnknownFields(input.automation, ["ae", "af", "awb"], "resolveVideoFrameSequence automation");
90
+ if (input.rollingShutter !== undefined) {
91
+ requireInputObject(input.rollingShutter, "resolveVideoFrameSequence rollingShutter");
92
+ rejectUnknownFields(input.rollingShutter, ["readout", "linkageEvidence"], "resolveVideoFrameSequence rollingShutter");
93
+ }
94
+ const sequenceId = requirePublicOpaqueId(input.sequenceId, "Invalid video sequence ID.");
95
+ const optical = parseOpticalProfileState(input.opticalState);
96
+ if (optical.captureMode !== "video") {
97
+ throw new InvalidConfigurationError("Video frame sequences require an optical state with captureMode \"video\".");
98
+ }
99
+ const frameRateHz = optical.frameRateHz;
100
+ const shutterAngleDegrees = requireShutterAngle(input.shutterAngleDegrees);
101
+ const exposureSeconds = calculateShutterAngleExposureSeconds(frameRateHz, shutterAngleDegrees);
102
+ const first = input.firstFrameIndex ?? 0;
103
+ if (!Number.isSafeInteger(first) || first < 0 || !Number.isSafeInteger(input.frameCount) || input.frameCount < 1 ||
104
+ input.frameCount > VIDEO_FRAME_SEQUENCE_MAXIMUM_FRAMES || first + input.frameCount - 1 > 0xffffffff) {
105
+ throw new InvalidScientificInputError("Video frames need a non-negative first index, 1–100000 frames and uint32 frame indices.");
106
+ }
107
+ const seed = input.sequenceSeedUint32;
108
+ if (!Number.isInteger(seed) || seed < 0 || seed > 0xffffffff) {
109
+ throw new InvalidScientificInputError("sequenceSeedUint32 must be a uint32 integer.");
110
+ }
111
+ if (typeof input.iso !== "number" || !Number.isFinite(input.iso) || input.iso <= 0) {
112
+ throw new InvalidScientificInputError("iso must be a finite number greater than zero.");
113
+ }
114
+ const timingEvidence = parseEvidenceList(input.timingEvidence, "video.timingEvidence");
115
+ const focus = parseFocusPlane(input.focus ?? { kind: "finite", distanceM: optical.focusDistanceM });
116
+ const automation = { ae: input.automation.ae, af: input.automation.af, awb: input.automation.awb };
117
+ for (const state of Object.values(automation)) {
118
+ if (state !== "manual" && state !== "locked" && state !== "continuous") {
119
+ throw new InvalidConfigurationError("Video automation states must be manual, locked or continuous.");
120
+ }
121
+ }
122
+ const whiteBalanceStateId = input.whiteBalanceStateId === undefined ? undefined
123
+ : requirePublicOpaqueId(input.whiteBalanceStateId, "Invalid white-balance state ID.");
124
+ const framePeriodSeconds = 1 / frameRateHz;
125
+ let rolling = null;
126
+ if (input.rollingShutter !== undefined) {
127
+ rolling = resolveElectronicRollingShutterExposureSchedule({ readout: input.rollingShutter.readout,
128
+ nominalExposureDurationSeconds: { value: exposureSeconds, unit: "s", evidence: timingEvidence },
129
+ linkageEvidence: input.rollingShutter.linkageEvidence });
130
+ if (rolling.lineScanSkewSeconds > framePeriodSeconds) {
131
+ throw new InvalidScientificInputError("Rolling-shutter line skew exceeds the video frame period; lines cannot be read once per frame.");
132
+ }
133
+ }
134
+ const start = (index) => index / frameRateHz;
135
+ const frames = Array.from({ length: input.frameCount }, (_, offset) => {
136
+ const frameIndex = first + offset, exposureStartTimeSeconds = start(frameIndex);
137
+ return {
138
+ sequenceId,
139
+ frameIndex,
140
+ releaseFrameId: sequenceId + ":video:" + frameIndex,
141
+ exposureStartTimeSeconds,
142
+ exposureEndTimeSeconds: exposureStartTimeSeconds + exposureSeconds,
143
+ sceneTimeSecondsFromSequenceStart: exposureStartTimeSeconds,
144
+ startIntervalFromPreviousSeconds: frameIndex === 0 ? null : exposureStartTimeSeconds - start(frameIndex - 1),
145
+ timingConstraints: ["requested-cadence"],
146
+ stochasticSeedUint32: deriveNativeSiteStreamSeedUint32(seed, frameIndex, VIDEO_FRAME_SEED_STREAM_ID),
147
+ exposure: { aperture: optical.aperture, shutterSeconds: exposureSeconds, iso: input.iso },
148
+ focus: { ...focus },
149
+ automation: { ...automation },
150
+ ...(whiteBalanceStateId === undefined ? {} : { whiteBalanceStateId })
151
+ };
152
+ });
153
+ return {
154
+ version: VIDEO_FRAME_SEQUENCE_VERSION,
155
+ sequenceId,
156
+ frameRateHz,
157
+ framePeriodSeconds,
158
+ shutterAngleDegrees,
159
+ exposureSeconds,
160
+ shutterAngleRule: assessShutterAngleRule(frameRateHz, shutterAngleDegrees),
161
+ firstFrameIndex: first,
162
+ frameCount: input.frameCount,
163
+ sequenceSeedUint32: seed,
164
+ seedDerivation: "murmur3-x86-32(sequenceSeed, absoluteFrameIndex, VIDEO_FRAME_SEED_STREAM_ID)",
165
+ frameTimeDerivation: "absoluteFrameIndex / frameRateHz",
166
+ exposureSchedule: rolling === null ? null : createRollingShutterCaptureExposureSchedule(rolling),
167
+ rollingShutter: rolling === null ? null : { modelId: ELECTRONIC_ROLLING_SHUTTER_MODEL.id,
168
+ modelVersion: ELECTRONIC_ROLLING_SHUTTER_MODEL.version, lineScanSkewSeconds: rolling.lineScanSkewSeconds,
169
+ linkage: rolling.linkage },
170
+ frames,
171
+ limitations: [
172
+ "Frame timing is ideal: no frame-rate drift, dropped frames, variable frame rate or sensor-mode switching.",
173
+ "Exposure follows the shutter-angle relation t = angle/360/f; automatic exposure between frames is not modeled.",
174
+ "The 180-degree rule is reported as a cinematographic convention, not a physical requirement.",
175
+ "Video encoding, compression, temporal noise reduction and frame interpolation are not modeled."
176
+ ]
177
+ };
178
+ }
179
+ //# sourceMappingURL=video-sequence.js.map