@photivra/engine 1.5.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1078) hide show
  1. package/CHANGELOG.md +393 -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 +116 -9
  56. package/dist/capture/native-raw-development.js +221 -62
  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 +65 -12
  62. package/dist/capture/native-raw.js +81 -19
  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 -8
  639. package/docs/api/capture-native-raw-dng.md +84 -0
  640. package/docs/api/capture-native-raw.md +21 -10
  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/DENSE_PUPIL_QUALIFICATION.md +0 -121
  975. package/docs/DEVELOPERS.md +0 -68
  976. package/docs/DIGITAL_OPTICS_FOUNDATION.md +0 -69
  977. package/docs/ENVIRONMENT_RAW_CAPTURE.md +0 -208
  978. package/docs/EXPORT_ACCEPTANCE.md +0 -133
  979. package/docs/GENERIC_TIER_PRESETS.md +0 -269
  980. package/docs/GEOMETRIC_PREPARATION_REUSE.md +0 -141
  981. package/docs/IMAGE_FORMATION.md +0 -247
  982. package/docs/LINEAR_CAPTURE_ENCODING.md +0 -25
  983. package/docs/MOTION_AND_SIGNAL.md +0 -250
  984. package/docs/NATIVE_CAPTURE_SDR.md +0 -70
  985. package/docs/NATIVE_CAPTURE_SDR_REVIEW.md +0 -37
  986. package/docs/NATIVE_CAPTURE_SDR_VALIDATION.md +0 -34
  987. package/docs/NATIVE_RAW_AND_PRINT.md +0 -54
  988. package/docs/NUMERICAL_CORRECTNESS.md +0 -191
  989. package/docs/PERFORMANCE_BASELINE.md +0 -56
  990. package/docs/PHOTOGRAPHIC_EXPORT.md +0 -206
  991. package/docs/PHYSICS_FOUNDATION.md +0 -426
  992. package/docs/POC_API.md +0 -278
  993. package/docs/POC_PROJECTION_PLATFORM_REFERENCE.md +0 -12
  994. package/docs/POC_PROJECTION_REUSE.md +0 -124
  995. package/docs/PRINT_195_196_REVIEW.md +0 -93
  996. package/docs/PRINT_196_ENGINE_ACCEPTANCE.md +0 -45
  997. package/docs/PRINT_CONTRAST_REFERENCE.md +0 -43
  998. package/docs/PRINT_DETAIL_ASSESSMENT.md +0 -81
  999. package/docs/PRINT_DETAIL_JPEG_EVIDENCE.md +0 -36
  1000. package/docs/PRINT_DETAIL_SDR_EVIDENCE.md +0 -29
  1001. package/docs/PRINT_DETAIL_VALIDATION.md +0 -36
  1002. package/docs/PRINT_PLANNING.md +0 -75
  1003. package/docs/PRINT_REGION_STATISTICS.md +0 -38
  1004. package/docs/PROCESSED_OUTPUT.md +0 -157
  1005. package/docs/PRODUCTION_COMPOSITION.md +0 -373
  1006. package/docs/PRODUCTION_ENVIRONMENT_CAPTURE.md +0 -131
  1007. package/docs/PROVENANCE.md +0 -115
  1008. package/docs/PSF_FOUNDATION.md +0 -165
  1009. package/docs/RAW_FRAME_ENVELOPE.md +0 -56
  1010. package/docs/RAW_FRAME_RECONSTRUCTION.md +0 -30
  1011. package/docs/RELEASE_1_0.md +0 -66
  1012. package/docs/RELEASE_1_0_1.md +0 -61
  1013. package/docs/RELEASE_1_1_0.md +0 -25
  1014. package/docs/RELEASE_1_2_0.md +0 -51
  1015. package/docs/RELEASE_1_3_0.md +0 -15
  1016. package/docs/RELEASE_1_4_0.md +0 -23
  1017. package/docs/RELEASE_1_5_0.md +0 -105
  1018. package/docs/RELEASE_AUDIT.md +0 -39
  1019. package/docs/SCENE_RADIANCE_AND_ILLUMINATION.md +0 -298
  1020. package/docs/SCENE_SENSOR_QUADRATURE.md +0 -98
  1021. package/docs/SCENE_SENSOR_TEMPORAL_EXPOSURE.md +0 -86
  1022. package/docs/SCIENTIFIC_ASSURANCE.md +0 -280
  1023. package/docs/SCIENTIFIC_CONFORMANCE.md +0 -83
  1024. package/docs/SDR_RENDERING.md +0 -33
  1025. package/docs/SENSOR_APERTURE_RAYS.md +0 -23
  1026. package/docs/SENSOR_ENVIRONMENT_QUERY.md +0 -86
  1027. package/docs/SENSOR_EQE_LOCAL_EXPOSURE.md +0 -104
  1028. package/docs/SENSOR_EQE_TEMPORAL_EXPOSURE.md +0 -74
  1029. package/docs/SENSOR_PSF_QUADRATURE.md +0 -90
  1030. package/docs/SENSOR_RAW_FRAME.md +0 -20
  1031. package/docs/SENSOR_RAW_PRODUCER.md +0 -77
  1032. package/docs/SEPARABLE_EMISSION_DRAFT.md +0 -103
  1033. package/docs/SIGNAL_CONFORMANCE.md +0 -23
  1034. package/docs/SIMULATED_CAPTURE.md +0 -65
  1035. package/docs/STABILIZATION.md +0 -234
  1036. package/docs/TEMPORAL_PHOTO_RAW.md +0 -83
  1037. package/docs/TIER_ACCEPTANCE.md +0 -129
  1038. package/docs/TIER_PRESET_ACCEPTANCE.md +0 -59
  1039. package/docs/V1_COMPOSITION_MAP.md +0 -123
  1040. package/docs/V1_HELPER_REUSE_REVIEW.md +0 -60
  1041. package/docs/V1_PERFORMANCE_DISPOSITION.md +0 -88
  1042. package/docs/benchmarks/2026-10-01-main-baseline.json +0 -694
  1043. package/docs/benchmarks/2026-10-02-geometric-preparation-reuse.json +0 -2190
  1044. package/docs/benchmarks/2026-10-02-poc-projection-reuse.json +0 -2423
  1045. package/docs/benchmarks/2026-10-02-v1-environment-gc-profile.json +0 -210
  1046. package/docs/benchmarks/2026-10-02-v1-environment-ordinary.json +0 -187
  1047. package/docs/benchmarks/2026-10-02-v1-geometry-gc-profile.json +0 -756
  1048. package/docs/benchmarks/2026-10-02-v1-geometry-ordinary-1.json +0 -711
  1049. package/docs/benchmarks/2026-10-02-v1-geometry-ordinary-2.json +0 -711
  1050. package/docs/benchmarks/2026-10-02-v1-poc-gc-profile.json +0 -885
  1051. package/docs/benchmarks/2026-10-02-v1-poc-ordinary-1.json +0 -868
  1052. package/docs/benchmarks/2026-10-02-v1-poc-ordinary-2.json +0 -868
  1053. package/docs/licenses/castleCSF-MIT.txt +0 -21
  1054. package/docs/validation/dense-pupil-2026-10-06/pilot.jsonl +0 -6
  1055. package/docs/validation/documentation-fragments.json +0 -212
  1056. package/docs/validation/native-capture-sdr-darwin-arm64-node26-review.jsonl +0 -4
  1057. package/docs/validation/native-capture-sdr-darwin-arm64.jsonl +0 -3
  1058. package/docs/validation/native-raw-print-2026-10-04/fractional-asymmetric-crop.jpg +0 -0
  1059. package/docs/validation/native-raw-print-2026-10-04/gray-ramp.jpg +0 -0
  1060. package/docs/validation/native-raw-print-2026-10-04/linear-area-checker.jpg +0 -0
  1061. package/docs/validation/native-raw-print-2026-10-04/manifest.json +0 -218
  1062. package/docs/validation/native-raw-print-2026-10-04/megapixel-native.jpg +0 -0
  1063. package/docs/validation/native-raw-print-2026-10-04/native-color.jpg +0 -0
  1064. package/docs/validation/native-raw-print-2026-10-04/photivra-native-full-megapixel-validation.json +0 -9
  1065. package/docs/validation/native-raw-print-2026-10-04/photivra-native-full-megapixel.json +0 -29
  1066. package/docs/validation/native-raw-print-2026-10-04/photivra-native-full-megapixel.json.codes.u16le.gz +0 -0
  1067. package/docs/validation/native-raw-print-2026-10-04/photivra-native-full-megapixel.json.jpg +0 -0
  1068. package/docs/validation/native-raw-print-2026-10-04/photivra-native-full-megapixel.json.rgb.gz +0 -0
  1069. package/docs/validation/native-raw-print-2026-10-04/srgb.icc +0 -0
  1070. package/docs/validation/native-raw-print-2026-10-04/validation.json +0 -41
  1071. package/docs/validation/print-196-candidate-capabilities.json +0 -28
  1072. package/docs/validation/print-196-candidate-evidence.json +0 -356
  1073. package/docs/validation/print-196-engine-acceptance.json +0 -81
  1074. package/docs/validation/print-detail-capabilities.json +0 -103
  1075. package/docs/validation/print-detail-jpeg-evidence.json +0 -116
  1076. package/docs/validation/print-detail-sdr-evidence.json +0 -81
  1077. package/docs/validation/release-audit-inventory.json +0 -1306
  1078. package/docs/validation/tier-acceptance-report-v1.json +0 -2538
@@ -0,0 +1,317 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ /**
3
+ * Host side of the `webgpu-f32` sensor stage (#277): domain checks, frame constants, per-site mean
4
+ * packing, banded dispatch and readback. The float64 reference is `simulatePackedSensorRaw`
5
+ * (capture/packed-sensor-raw.ts). Internal; the public entry point is the image-kernel accelerator.
6
+ */
7
+ import { createHostYieldGate } from "../capture/host-yield-cadence.js";
8
+ import { calculatePackedSensorRawPlan, createPackedFixedPattern, packedSensorDiagnostics, packedSensorExtras, simulatePackedSensorRows } from "../capture/packed-sensor-raw.js";
9
+ import { adcTransfer } from "../sensor/raw-readout.js";
10
+ import { ImageKernelExecutionError, webGpuExecution } from "./image-kernel-execution.js";
11
+ import { BUFFER_USAGE, GpuResourceScope, abortedError, linearDispatch, runComputePass } from "./webgpu-runtime.js";
12
+ import { SENSOR_AUX, SENSOR_EXTRAS, SENSOR_MEAN_CATEGORY, SENSOR_OUTPUT, SENSOR_RAW_WGSL, SENSOR_SITE_WORDS, SENSOR_WORKGROUP_SIZE } from "./wgsl-sensor-kernel.js";
13
+ /** Largest physical capacity on the GPU: every realized count up to it is exact in float32. */
14
+ export const SENSOR_GPU_MAXIMUM_CAPACITY = 2 ** 24;
15
+ /** Poisson means must stay below this on the GPU (30-bit integer part of a mean word). */
16
+ export const SENSOR_GPU_MAXIMUM_MEAN = 2 ** 30;
17
+ /** Largest |fixed-pattern readout offset| on the GPU, in electrons and in codes. */
18
+ export const SENSOR_GPU_MAXIMUM_OFFSET_ELECTRONS = 2 ** 28;
19
+ export const SENSOR_GPU_MAXIMUM_OFFSET_CODES = 2 ** 20;
20
+ const CPU_RELATIVE = 2 ** -47;
21
+ const U = 2 ** -24;
22
+ const POISSON_NORMAL_MINIMUM_MEAN = 1e9;
23
+ function checkAbort(signal) {
24
+ if (signal.aborted)
25
+ throw abortedError();
26
+ }
27
+ /** CPU reference with host yields and abort, row-chunked; codes equal `simulatePackedSensorRaw`. */
28
+ export async function simulateSensorRawOnCpu(input, abort, yieldControl, execution) {
29
+ const plan = calculatePackedSensorRawPlan(input);
30
+ // Snapshot so a caller mutation during host yields cannot change the reference.
31
+ const photo = input.photoElectrons.slice(), dark = input.darkElectrons.slice(), extras = packedSensorExtras(plan, input, true);
32
+ const codes = new Uint16Array(plan.siteCount), counts = [0, 0, 0, 0];
33
+ const rowsPerChunk = Math.max(1, Math.floor(65_536 / plan.region.width)), gate = createHostYieldGate();
34
+ for (let row = 0; row < plan.region.height; row += rowsPerChunk) {
35
+ checkAbort(abort.signal);
36
+ simulatePackedSensorRows(plan, photo, dark, row, Math.min(plan.region.height, row + rowsPerChunk), codes, counts, extras);
37
+ if (yieldControl && gate.due()) {
38
+ await yieldControl(abort.signal);
39
+ gate.restart();
40
+ }
41
+ }
42
+ checkAbort(abort.signal);
43
+ return { plan, codes, diagnostics: packedSensorDiagnostics(counts), execution, flaggedSiteIndices: new Uint32Array(0) };
44
+ }
45
+ /**
46
+ * Splits a positive value into four non-negative pieces with at most 12 significant bits each (by
47
+ * truncation), so that the product of any integer below 2^12 and a piece is exact in float32. Returns
48
+ * the pieces and the non-negative remainder (below 2^-44 of the value).
49
+ * @internal
50
+ */
51
+ export function twelveBitPieces(value) {
52
+ const pieces = [];
53
+ let rest = value;
54
+ for (let j = 0; j < 4; j++) {
55
+ if (!(rest > 0)) {
56
+ pieces.push(0);
57
+ continue;
58
+ }
59
+ let e = Math.floor(Math.log2(rest));
60
+ if (rest / 2 ** e >= 2)
61
+ e++;
62
+ if (rest / 2 ** e < 1)
63
+ e--;
64
+ const scale = 2 ** (e - 11), piece = Math.floor(rest / scale) * scale;
65
+ pieces.push(piece);
66
+ rest -= piece;
67
+ }
68
+ return { pieces, residual: rest };
69
+ }
70
+ /**
71
+ * `L(k) − S(k)` for k < 256, where L is the reference's log k! (the summed logarithms of
72
+ * `samplePoisson`'s logFactorial) and S(k) = (k + ½) ln k − k + ½ ln 2π.
73
+ * @internal
74
+ */
75
+ export function stirlingRemainderTable() {
76
+ const table = new Float64Array(256);
77
+ let sum = 0;
78
+ for (let k = 1; k < 256; k++) {
79
+ if (k >= 2)
80
+ sum += Math.log(k);
81
+ table[k] = sum - ((k + 0.5) * Math.log(k) - k + 0.5 * Math.log(2 * Math.PI));
82
+ }
83
+ return table;
84
+ }
85
+ function unsupported(message) {
86
+ return new ImageKernelExecutionError("unsupported-float32-domain", message);
87
+ }
88
+ /** Checks the float32 execution domain and builds the frame constants (see docs/WEBGPU.md). @internal */
89
+ export function sensorGpuConstants(plan) {
90
+ const regime = plan.readout.regime, adc = regime.adc, capacity = plan.physicalChargeCapacityElectrons;
91
+ const gain = regime.systemConversionGainElectronsPerCode.value, inverse = 1 / gain;
92
+ const threshold = regime.preAdcSaturationElectronEquivalent.value;
93
+ const sigmas = regime.readNoiseComponents.map(c => c.rmsElectrons.value);
94
+ const sigmaSum = sigmas.reduce((s, v) => s + v, 0);
95
+ if (capacity > SENSOR_GPU_MAXIMUM_CAPACITY)
96
+ throw unsupported("Physical capacity above 2^24 electrons is outside the float32 sensor domain.");
97
+ // Fixed-pattern factors scale the means; those are checked per site while packing.
98
+ if (!(plan.maximumPhotoElectrons < SENSOR_GPU_MAXIMUM_MEAN && plan.maximumDarkElectrons < SENSOR_GPU_MAXIMUM_MEAN) ||
99
+ plan.additionalChargeComponents.some(c => !(c.maximumExpectedElectrons < SENSOR_GPU_MAXIMUM_MEAN))) {
100
+ throw unsupported("Expected electrons of 2^30 and above are outside the float32 sensor domain.");
101
+ }
102
+ if (!(inverse >= 2 ** -60 && inverse <= 2 ** 60) || capacity * inverse > 2 ** 30 ||
103
+ sigmas.some(s => s !== 0 && !(s >= 2 ** -100 && s <= 2 ** 100)) || 7 * sigmaSum > 2 ** 28 || 7 * sigmaSum * inverse > 2 ** 20) {
104
+ throw unsupported("Conversion gain or read noise is outside the float32 sensor domain.");
105
+ }
106
+ const knots = adc.integralNonLinearity?.knots ?? [];
107
+ let slope = 0, offset = 0;
108
+ knots.forEach((k, i) => {
109
+ offset = Math.max(offset, Math.abs(k.offsetCodes));
110
+ if (i > 0)
111
+ slope = Math.max(slope, Math.abs((k.offsetCodes - knots[i - 1].offsetCodes) / (k.code - knots[i - 1].code)));
112
+ });
113
+ const aux = new Float32Array(SENSOR_AUX.knots + 2 * knots.length);
114
+ aux.set(stirlingRemainderTable(), SENSOR_AUX.stirlingRemainder);
115
+ aux.set(sigmas, SENSOR_AUX.sigma);
116
+ const inversePieces = twelveBitPieces(inverse), digital = adc.digitalGain === undefined ? null : twelveBitPieces(adc.digitalGain);
117
+ aux.set(inversePieces.pieces, SENSOR_AUX.inversePieces);
118
+ if (digital)
119
+ aux.set(digital.pieces, SENSOR_AUX.digitalPieces);
120
+ knots.forEach((k, i) => { aux[SENSOR_AUX.knots + i] = k.code; aux[SENSOR_AUX.knots + knots.length + i] = k.offsetCodes; });
121
+ // Pre-ADC-saturated sites all have the same rounded ADC input; computed once with the reference, before digital gain.
122
+ const { digitalGain: _omitted, ...withoutDigital } = adc;
123
+ void _omitted;
124
+ const saturated = adcTransfer({ ...regime, adc: withoutDigital }, plan.readout.adcMaximumCode, threshold).quantized;
125
+ const params = new ArrayBuffer(128), words = new Uint32Array(params), ints = new Int32Array(params), floats = new Float32Array(params);
126
+ const capacityFloor = Math.floor(capacity), thresholdFloor = Math.min(Math.floor(threshold), 2 ** 30);
127
+ words[2] = plan.region.width;
128
+ words[3] = plan.nativeWidth;
129
+ words[4] = plan.region.x;
130
+ words[5] = plan.region.y;
131
+ // Mode bits: 1 digital gain; 2 the digital-gain product is exact on both sides (gain has ≤ 12 significant
132
+ // bits); 4 the ADC input is exact on both sides (no read noise, power-of-two gain, integer capacity, no INL).
133
+ // In an exact mode both evaluations give the same dyadic value, so a tie is decided identically and needs no flag.
134
+ const digitalExact = digital !== null && digital.residual === 0 && digital.pieces.slice(1).every(p => p === 0);
135
+ const poissonComponents = [], deterministicComponents = [];
136
+ plan.additionalChargeComponents.forEach((c, k) => (c.model === "poisson" ? poissonComponents : deterministicComponents).push(k));
137
+ const deterministic = deterministicComponents.length > 0, pattern = plan.fixedPatternNoise !== null;
138
+ const idealExact = sigmas.every(s => s === 0) && Number.isInteger(Math.log2(gain)) && Number.isInteger(capacity) && knots.length === 0 &&
139
+ !deterministic && !pattern;
140
+ words[6] = plan.captureSeedUint32;
141
+ words[7] = sigmas.length;
142
+ words[8] = knots.length;
143
+ words[9] = (digital ? 1 : 0) | (digitalExact ? 2 : 0) | (idealExact ? 4 : 0);
144
+ words[10] = adc.digitalSaturationCode;
145
+ words[11] = plan.readout.adcMaximumCode;
146
+ words[12] = capacityFloor;
147
+ words[13] = thresholdFloor;
148
+ words[14] = adc.blackLevelCode;
149
+ ints[15] = Math.max(-(2 ** 30), Math.min(2 ** 30, saturated));
150
+ floats[16] = capacity - capacityFloor;
151
+ floats[17] = threshold < 2 ** 30 ? threshold - thresholdFloor : 0;
152
+ floats[18] = inverse;
153
+ floats[19] = inversePieces.residual * (1 + 2 ** -20);
154
+ floats[20] = adc.digitalGain ?? 1;
155
+ floats[21] = digital ? digital.residual * (1 + 2 ** -20) : 0;
156
+ floats[22] = slope * (1 + 2 ** -20);
157
+ floats[23] = offset;
158
+ const siteWords = SENSOR_SITE_WORDS + 2 * poissonComponents.length + (deterministic ? 2 : 0) + (pattern ? 4 : 0);
159
+ words[24] = siteWords;
160
+ words[25] = poissonComponents.length;
161
+ words[26] = (deterministic ? SENSOR_EXTRAS.deterministic : 0) | (pattern ? SENSOR_EXTRAS.fixedPattern : 0);
162
+ return { aux, params, siteWords, poissonComponents, deterministicComponents, threshold, gain };
163
+ }
164
+ /** Writes the float64 slack terms of the fixed-pattern bounds, from the region's largest offsets. */
165
+ function setFixedPatternSlack(params, threshold, maximumOffset, maximumOffsetCodes) {
166
+ const floats = new Float32Array(params);
167
+ // The reference adds the offset in float64 and the host forms threshold − offset and offset/gain in float64.
168
+ floats[28] = CPU_RELATIVE * (maximumOffset + Math.min(threshold, 2 ** 30)) * (1 + 2 ** -20);
169
+ // The offset fraction's float32 rounding, one more unit of |fp| across the ten fraction additions, and offset/gain's float64 rounding.
170
+ floats[29] = (12 * U + CPU_RELATIVE * maximumOffsetCodes) * (1 + 2 ** -20);
171
+ }
172
+ /** Splits a value into a floor and its float32 fraction. */
173
+ function packSplit(value, words, floats, at) {
174
+ const whole = Math.floor(value);
175
+ words[at] = whole;
176
+ floats[at + 1] = value - whole;
177
+ }
178
+ /** Packs one mean: category in bits 30–31 with the integer part, and the float32 fraction. */
179
+ function packMean(mean, words, floats, at) {
180
+ if (mean === 0) {
181
+ words[at] = 0;
182
+ floats[at + 1] = 0;
183
+ return;
184
+ }
185
+ if (!(mean < SENSOR_GPU_MAXIMUM_MEAN))
186
+ throw unsupported("Expected electrons of 2^30 and above are outside the float32 sensor domain.");
187
+ const whole = Math.floor(mean);
188
+ const category = mean < 30 ? SENSOR_MEAN_CATEGORY.multiplication : mean < POISSON_NORMAL_MINIMUM_MEAN ? SENSOR_MEAN_CATEGORY.transformedRejection
189
+ : SENSOR_MEAN_CATEGORY.normal;
190
+ words[at] = ((category << 30) | whole) >>> 0;
191
+ floats[at + 1] = mean - whole;
192
+ }
193
+ export async function simulateSensorRawOnGpu(runtime, bandBytes, input, abort, yieldControl, pipelines) {
194
+ const plan = calculatePackedSensorRawPlan(input);
195
+ const constants = sensorGpuConstants(plan), { aux, params, siteWords, poissonComponents, deterministicComponents, threshold, gain } = constants;
196
+ const photo = input.photoElectrons.slice(), dark = input.darkElectrons.slice();
197
+ const additional = (input.additionalChargeComponents ?? []).map(c => c.expectedElectrons.slice());
198
+ const width = plan.region.width, height = plan.region.height, siteBytes = siteWords * 4;
199
+ const pattern = createPackedFixedPattern(plan);
200
+ // Fixed-pattern values are evaluated once, in float64 (exactly the reference's values), before any dispatch.
201
+ const patterns = pattern === null ? null : new Float64Array(plan.siteCount * 3);
202
+ if (patterns !== null) {
203
+ let maximumOffset = 0, maximumOffsetCodes = 0;
204
+ for (let row = 0, i = 0; row < height; row++)
205
+ for (let column = 0; column < width; column++, i++) {
206
+ const p = pattern(column, row), offsetCodes = p.readoutOffsetElectrons / gain;
207
+ patterns[i * 3] = p.photoResponseGainFactor;
208
+ patterns[i * 3 + 1] = p.darkCurrentFactor;
209
+ patterns[i * 3 + 2] = p.readoutOffsetElectrons;
210
+ maximumOffset = Math.max(maximumOffset, Math.abs(p.readoutOffsetElectrons));
211
+ maximumOffsetCodes = Math.max(maximumOffsetCodes, Math.abs(offsetCodes));
212
+ }
213
+ if (!(maximumOffset <= SENSOR_GPU_MAXIMUM_OFFSET_ELECTRONS && maximumOffsetCodes <= SENSOR_GPU_MAXIMUM_OFFSET_CODES)) {
214
+ throw unsupported("Fixed-pattern readout offsets are outside the float32 sensor domain.");
215
+ }
216
+ setFixedPatternSlack(params, threshold, maximumOffset, maximumOffsetCodes);
217
+ }
218
+ const rows = Math.max(1, Math.min(height, Math.floor(bandBytes / (width * siteBytes))));
219
+ if (rows * width * siteBytes > runtime.maximumStorageBindingBytes) {
220
+ throw new ImageKernelExecutionError("insufficient-limits", "One sensor band exceeds the device's storage binding limit.");
221
+ }
222
+ const pipeline = await pipelines("photivra-sensor-raw", SENSOR_RAW_WGSL);
223
+ const codes = new Uint16Array(plan.siteCount), counts = [0, 0, 0, 0];
224
+ const packed = new ArrayBuffer(rows * width * siteBytes), packedWords = new Uint32Array(packed), packedFloats = new Float32Array(packed);
225
+ const packedInts = new Int32Array(packed);
226
+ const words = new Uint32Array(params);
227
+ let flagged = 0;
228
+ const flaggedIndices = [];
229
+ const scope = new GpuResourceScope(runtime);
230
+ try {
231
+ const auxBuffer = scope.upload("photivra-sensor-aux", aux, BUFFER_USAGE.STORAGE);
232
+ const gate = createHostYieldGate();
233
+ for (let row0 = 0; row0 < height; row0 += rows) {
234
+ checkAbort(abort.signal);
235
+ const row1 = Math.min(height, row0 + rows), count = (row1 - row0) * width, first = row0 * width;
236
+ for (let i = 0; i < count; i++) {
237
+ const site = first + i, at = i * siteWords;
238
+ // The reference's own float64 products of the means and the fixed-pattern factors.
239
+ packMean(patterns === null ? photo[site] : photo[site] * patterns[site * 3], packedWords, packedFloats, at);
240
+ packMean(patterns === null ? dark[site] : dark[site] * patterns[site * 3 + 1], packedWords, packedFloats, at + 2);
241
+ let cursor = at + 4;
242
+ for (const k of poissonComponents) {
243
+ packMean(additional[k][site], packedWords, packedFloats, cursor);
244
+ cursor += 2;
245
+ }
246
+ if (deterministicComponents.length > 0) {
247
+ let sum = 0;
248
+ for (const k of deterministicComponents)
249
+ sum += additional[k][site];
250
+ if (!(sum < SENSOR_GPU_MAXIMUM_MEAN))
251
+ throw unsupported("Deterministic charge of 2^30 electrons and above is outside the float32 sensor domain.");
252
+ packSplit(sum, packedInts, packedFloats, cursor);
253
+ cursor += 2;
254
+ }
255
+ if (patterns !== null) {
256
+ const offset = patterns[site * 3 + 2], limit = threshold - offset;
257
+ if (limit >= 2 ** 30) {
258
+ packedInts[cursor] = 2 ** 30;
259
+ packedFloats[cursor + 1] = 0;
260
+ }
261
+ else
262
+ packSplit(limit, packedInts, packedFloats, cursor);
263
+ packSplit(offset / gain, packedInts, packedFloats, cursor + 2);
264
+ }
265
+ }
266
+ words[0] = count;
267
+ words[1] = row0;
268
+ const band = new GpuResourceScope(runtime);
269
+ try {
270
+ const means = band.upload("photivra-sensor-means", new Uint32Array(packed, 0, count * siteWords), BUFFER_USAGE.STORAGE);
271
+ const out = band.buffer("photivra-sensor-codes", count * 4, BUFFER_USAGE.STORAGE | BUFFER_USAGE.COPY_SRC);
272
+ const uniform = band.upload("photivra-sensor-params", new Uint8Array(params), BUFFER_USAGE.UNIFORM);
273
+ const bindGroup = runtime.device.createBindGroup({ layout: pipeline.getBindGroupLayout(0), entries: [
274
+ { binding: 0, resource: { buffer: uniform } }, { binding: 1, resource: { buffer: means } },
275
+ { binding: 2, resource: { buffer: auxBuffer } }, { binding: 3, resource: { buffer: out } }
276
+ ] });
277
+ const [data] = await runComputePass(runtime, band, pipeline, bindGroup, linearDispatch(count, SENSOR_WORKGROUP_SIZE, runtime.maximumWorkgroupsPerDimension), [{ buffer: out, bytes: count * 4 }], abort.signal);
278
+ const result = new Uint32Array(data, 0, count);
279
+ for (let i = 0; i < count; i++) {
280
+ const word = result[i], flags = word >>> SENSOR_OUTPUT.flagShift;
281
+ codes[first + i] = word & SENSOR_OUTPUT.codeMask;
282
+ if (flags & 1)
283
+ counts[0]++;
284
+ if (flags & 2)
285
+ counts[1]++;
286
+ if (flags & 4)
287
+ counts[2]++;
288
+ if (flags & 8)
289
+ counts[3]++;
290
+ if (word & SENSOR_OUTPUT.uncertainBit) {
291
+ flagged++;
292
+ flaggedIndices.push(first + i);
293
+ }
294
+ }
295
+ }
296
+ finally {
297
+ band.release();
298
+ }
299
+ if (yieldControl && gate.due()) {
300
+ await yieldControl(abort.signal);
301
+ gate.restart();
302
+ }
303
+ }
304
+ }
305
+ catch (error) {
306
+ codes.fill(0);
307
+ throw error;
308
+ }
309
+ finally {
310
+ scope.release();
311
+ }
312
+ checkAbort(abort.signal);
313
+ const execution = webGpuExecution({ kind: "exact-except-flagged-sites", flaggedSiteCount: flagged, noiseModel: { ...plan.noiseModel },
314
+ seedSchedule: plan.seedSchedule }, flagged);
315
+ return { plan, codes, diagnostics: packedSensorDiagnostics(counts), execution, flaggedSiteIndices: Uint32Array.from(flaggedIndices) };
316
+ }
317
+ //# sourceMappingURL=sensor-stage-gpu.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sensor-stage-gpu.js","sourceRoot":"","sources":["../../src/gpu/sensor-stage-gpu.ts"],"names":[],"mappings":"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","sourcesContent":["// SPDX-License-Identifier: Apache-2.0\n\n/**\n * Host side of the `webgpu-f32` sensor stage (#277): domain checks, frame constants, per-site mean\n * packing, banded dispatch and readback. The float64 reference is `simulatePackedSensorRaw`\n * (capture/packed-sensor-raw.ts). Internal; the public entry point is the image-kernel accelerator.\n */\nimport { createHostYieldGate } from \"../capture/host-yield-cadence.js\";\nimport { calculatePackedSensorRawPlan, createPackedFixedPattern, packedSensorDiagnostics, packedSensorExtras, simulatePackedSensorRows,\n type PackedSensorRawInput, type PackedSensorRawPlan } from \"../capture/packed-sensor-raw.js\";\nimport { adcTransfer, type SensorReadoutConversionRegime } from \"../sensor/raw-readout.js\";\nimport { ImageKernelExecutionError, webGpuExecution, type ImageKernelExecution } from \"./image-kernel-execution.js\";\nimport type { AcceleratedPackedSensorRawResult } from \"./image-kernel-accelerator.js\";\nimport { BUFFER_USAGE, GpuResourceScope, abortedError, linearDispatch, runComputePass, type WebGpuRuntime } from \"./webgpu-runtime.js\";\nimport { SENSOR_AUX, SENSOR_EXTRAS, SENSOR_MEAN_CATEGORY, SENSOR_OUTPUT, SENSOR_RAW_WGSL, SENSOR_SITE_WORDS, SENSOR_WORKGROUP_SIZE } from \"./wgsl-sensor-kernel.js\";\n\ntype PipelineSource = (label: string, code: string) => Promise<GPUComputePipeline>;\ntype YieldControl = ((signal: AbortSignal) => Promise<void>) | undefined;\n\n/** Largest physical capacity on the GPU: every realized count up to it is exact in float32. */\nexport const SENSOR_GPU_MAXIMUM_CAPACITY = 2 ** 24;\n/** Poisson means must stay below this on the GPU (30-bit integer part of a mean word). */\nexport const SENSOR_GPU_MAXIMUM_MEAN = 2 ** 30;\n/** Largest |fixed-pattern readout offset| on the GPU, in electrons and in codes. */\nexport const SENSOR_GPU_MAXIMUM_OFFSET_ELECTRONS = 2 ** 28;\nexport const SENSOR_GPU_MAXIMUM_OFFSET_CODES = 2 ** 20;\nconst CPU_RELATIVE = 2 ** -47;\nconst U = 2 ** -24;\nconst POISSON_NORMAL_MINIMUM_MEAN = 1e9;\n\nfunction checkAbort(signal: AbortSignal): void {\n if (signal.aborted) throw abortedError();\n}\n\n/** CPU reference with host yields and abort, row-chunked; codes equal `simulatePackedSensorRaw`. */\nexport async function simulateSensorRawOnCpu(input: PackedSensorRawInput, abort: AbortController, yieldControl: YieldControl,\n execution: ImageKernelExecution): Promise<AcceleratedPackedSensorRawResult> {\n const plan = calculatePackedSensorRawPlan(input);\n // Snapshot so a caller mutation during host yields cannot change the reference.\n const photo = input.photoElectrons.slice(), dark = input.darkElectrons.slice(), extras = packedSensorExtras(plan, input, true);\n const codes = new Uint16Array(plan.siteCount), counts = [0, 0, 0, 0];\n const rowsPerChunk = Math.max(1, Math.floor(65_536 / plan.region.width)), gate = createHostYieldGate();\n for (let row = 0; row < plan.region.height; row += rowsPerChunk) {\n checkAbort(abort.signal);\n simulatePackedSensorRows(plan, photo, dark, row, Math.min(plan.region.height, row + rowsPerChunk), codes, counts, extras);\n if (yieldControl && gate.due()) { await yieldControl(abort.signal); gate.restart(); }\n }\n checkAbort(abort.signal);\n return { plan, codes, diagnostics: packedSensorDiagnostics(counts), execution, flaggedSiteIndices: new Uint32Array(0) };\n}\n\n/**\n * Splits a positive value into four non-negative pieces with at most 12 significant bits each (by\n * truncation), so that the product of any integer below 2^12 and a piece is exact in float32. Returns\n * the pieces and the non-negative remainder (below 2^-44 of the value).\n * @internal\n */\nexport function twelveBitPieces(value: number): { pieces: number[]; residual: number } {\n const pieces: number[] = [];\n let rest = value;\n for (let j = 0; j < 4; j++) {\n if (!(rest > 0)) { pieces.push(0); continue; }\n let e = Math.floor(Math.log2(rest));\n if (rest / 2 ** e >= 2) e++;\n if (rest / 2 ** e < 1) e--;\n const scale = 2 ** (e - 11), piece = Math.floor(rest / scale) * scale;\n pieces.push(piece);\n rest -= piece;\n }\n return { pieces, residual: rest };\n}\n\n/**\n * `L(k) − S(k)` for k < 256, where L is the reference's log k! (the summed logarithms of\n * `samplePoisson`'s logFactorial) and S(k) = (k + ½) ln k − k + ½ ln 2π.\n * @internal\n */\nexport function stirlingRemainderTable(): Float64Array {\n const table = new Float64Array(256);\n let sum = 0;\n for (let k = 1; k < 256; k++) {\n if (k >= 2) sum += Math.log(k);\n table[k] = sum - ((k + 0.5) * Math.log(k) - k + 0.5 * Math.log(2 * Math.PI));\n }\n return table;\n}\n\nfunction unsupported(message: string): ImageKernelExecutionError {\n return new ImageKernelExecutionError(\"unsupported-float32-domain\", message);\n}\n\ninterface SensorConstants { aux: Float32Array<ArrayBuffer>; params: ArrayBuffer; siteWords: number; poissonComponents: number[];\n deterministicComponents: number[]; threshold: number; gain: number }\n\n/** Checks the float32 execution domain and builds the frame constants (see docs/WEBGPU.md). @internal */\nexport function sensorGpuConstants(plan: PackedSensorRawPlan): SensorConstants {\n const regime = plan.readout.regime, adc = regime.adc, capacity = plan.physicalChargeCapacityElectrons;\n const gain = regime.systemConversionGainElectronsPerCode.value, inverse = 1 / gain;\n const threshold = regime.preAdcSaturationElectronEquivalent.value;\n const sigmas = regime.readNoiseComponents.map(c => c.rmsElectrons.value);\n const sigmaSum = sigmas.reduce((s, v) => s + v, 0);\n if (capacity > SENSOR_GPU_MAXIMUM_CAPACITY) throw unsupported(\"Physical capacity above 2^24 electrons is outside the float32 sensor domain.\");\n // Fixed-pattern factors scale the means; those are checked per site while packing.\n if (!(plan.maximumPhotoElectrons < SENSOR_GPU_MAXIMUM_MEAN && plan.maximumDarkElectrons < SENSOR_GPU_MAXIMUM_MEAN) ||\n plan.additionalChargeComponents.some(c => !(c.maximumExpectedElectrons < SENSOR_GPU_MAXIMUM_MEAN))) {\n throw unsupported(\"Expected electrons of 2^30 and above are outside the float32 sensor domain.\");\n }\n if (!(inverse >= 2 ** -60 && inverse <= 2 ** 60) || capacity * inverse > 2 ** 30 ||\n sigmas.some(s => s !== 0 && !(s >= 2 ** -100 && s <= 2 ** 100)) || 7 * sigmaSum > 2 ** 28 || 7 * sigmaSum * inverse > 2 ** 20) {\n throw unsupported(\"Conversion gain or read noise is outside the float32 sensor domain.\");\n }\n const knots = adc.integralNonLinearity?.knots ?? [];\n let slope = 0, offset = 0;\n knots.forEach((k, i) => {\n offset = Math.max(offset, Math.abs(k.offsetCodes));\n if (i > 0) slope = Math.max(slope, Math.abs((k.offsetCodes - knots[i - 1]!.offsetCodes) / (k.code - knots[i - 1]!.code)));\n });\n const aux = new Float32Array(SENSOR_AUX.knots + 2 * knots.length);\n aux.set(stirlingRemainderTable(), SENSOR_AUX.stirlingRemainder);\n aux.set(sigmas, SENSOR_AUX.sigma);\n const inversePieces = twelveBitPieces(inverse), digital = adc.digitalGain === undefined ? null : twelveBitPieces(adc.digitalGain);\n aux.set(inversePieces.pieces, SENSOR_AUX.inversePieces);\n if (digital) aux.set(digital.pieces, SENSOR_AUX.digitalPieces);\n knots.forEach((k, i) => { aux[SENSOR_AUX.knots + i] = k.code; aux[SENSOR_AUX.knots + knots.length + i] = k.offsetCodes; });\n // Pre-ADC-saturated sites all have the same rounded ADC input; computed once with the reference, before digital gain.\n const { digitalGain: _omitted, ...withoutDigital } = adc;\n void _omitted;\n const saturated = adcTransfer({ ...regime, adc: withoutDigital } as SensorReadoutConversionRegime, plan.readout.adcMaximumCode, threshold).quantized;\n const params = new ArrayBuffer(128), words = new Uint32Array(params), ints = new Int32Array(params), floats = new Float32Array(params);\n const capacityFloor = Math.floor(capacity), thresholdFloor = Math.min(Math.floor(threshold), 2 ** 30);\n words[2] = plan.region.width; words[3] = plan.nativeWidth; words[4] = plan.region.x; words[5] = plan.region.y;\n // Mode bits: 1 digital gain; 2 the digital-gain product is exact on both sides (gain has ≤ 12 significant\n // bits); 4 the ADC input is exact on both sides (no read noise, power-of-two gain, integer capacity, no INL).\n // In an exact mode both evaluations give the same dyadic value, so a tie is decided identically and needs no flag.\n const digitalExact = digital !== null && digital.residual === 0 && digital.pieces.slice(1).every(p => p === 0);\n const poissonComponents: number[] = [], deterministicComponents: number[] = [];\n plan.additionalChargeComponents.forEach((c, k) => (c.model === \"poisson\" ? poissonComponents : deterministicComponents).push(k));\n const deterministic = deterministicComponents.length > 0, pattern = plan.fixedPatternNoise !== null;\n const idealExact = sigmas.every(s => s === 0) && Number.isInteger(Math.log2(gain)) && Number.isInteger(capacity) && knots.length === 0 &&\n !deterministic && !pattern;\n words[6] = plan.captureSeedUint32; words[7] = sigmas.length; words[8] = knots.length;\n words[9] = (digital ? 1 : 0) | (digitalExact ? 2 : 0) | (idealExact ? 4 : 0);\n words[10] = adc.digitalSaturationCode; words[11] = plan.readout.adcMaximumCode; words[12] = capacityFloor; words[13] = thresholdFloor;\n words[14] = adc.blackLevelCode; ints[15] = Math.max(-(2 ** 30), Math.min(2 ** 30, saturated));\n floats[16] = capacity - capacityFloor; floats[17] = threshold < 2 ** 30 ? threshold - thresholdFloor : 0;\n floats[18] = inverse; floats[19] = inversePieces.residual * (1 + 2 ** -20);\n floats[20] = adc.digitalGain ?? 1; floats[21] = digital ? digital.residual * (1 + 2 ** -20) : 0;\n floats[22] = slope * (1 + 2 ** -20); floats[23] = offset;\n const siteWords = SENSOR_SITE_WORDS + 2 * poissonComponents.length + (deterministic ? 2 : 0) + (pattern ? 4 : 0);\n words[24] = siteWords; words[25] = poissonComponents.length;\n words[26] = (deterministic ? SENSOR_EXTRAS.deterministic : 0) | (pattern ? SENSOR_EXTRAS.fixedPattern : 0);\n return { aux, params, siteWords, poissonComponents, deterministicComponents, threshold, gain };\n}\n\n/** Writes the float64 slack terms of the fixed-pattern bounds, from the region's largest offsets. */\nfunction setFixedPatternSlack(params: ArrayBuffer, threshold: number, maximumOffset: number, maximumOffsetCodes: number): void {\n const floats = new Float32Array(params);\n // The reference adds the offset in float64 and the host forms threshold − offset and offset/gain in float64.\n floats[28] = CPU_RELATIVE * (maximumOffset + Math.min(threshold, 2 ** 30)) * (1 + 2 ** -20);\n // The offset fraction's float32 rounding, one more unit of |fp| across the ten fraction additions, and offset/gain's float64 rounding.\n floats[29] = (12 * U + CPU_RELATIVE * maximumOffsetCodes) * (1 + 2 ** -20);\n}\n\n/** Splits a value into a floor and its float32 fraction. */\nfunction packSplit(value: number, words: Int32Array, floats: Float32Array, at: number): void {\n const whole = Math.floor(value);\n words[at] = whole; floats[at + 1] = value - whole;\n}\n\n/** Packs one mean: category in bits 30–31 with the integer part, and the float32 fraction. */\nfunction packMean(mean: number, words: Uint32Array, floats: Float32Array, at: number): void {\n if (mean === 0) { words[at] = 0; floats[at + 1] = 0; return; }\n if (!(mean < SENSOR_GPU_MAXIMUM_MEAN)) throw unsupported(\"Expected electrons of 2^30 and above are outside the float32 sensor domain.\");\n const whole = Math.floor(mean);\n const category = mean < 30 ? SENSOR_MEAN_CATEGORY.multiplication : mean < POISSON_NORMAL_MINIMUM_MEAN ? SENSOR_MEAN_CATEGORY.transformedRejection\n : SENSOR_MEAN_CATEGORY.normal;\n words[at] = ((category << 30) | whole) >>> 0;\n floats[at + 1] = mean - whole;\n}\n\nexport async function simulateSensorRawOnGpu(runtime: WebGpuRuntime, bandBytes: number, input: PackedSensorRawInput, abort: AbortController,\n yieldControl: YieldControl, pipelines: PipelineSource): Promise<AcceleratedPackedSensorRawResult> {\n const plan = calculatePackedSensorRawPlan(input);\n const constants = sensorGpuConstants(plan), { aux, params, siteWords, poissonComponents, deterministicComponents, threshold, gain } = constants;\n const photo = input.photoElectrons.slice(), dark = input.darkElectrons.slice();\n const additional = (input.additionalChargeComponents ?? []).map(c => c.expectedElectrons.slice());\n const width = plan.region.width, height = plan.region.height, siteBytes = siteWords * 4;\n const pattern = createPackedFixedPattern(plan);\n // Fixed-pattern values are evaluated once, in float64 (exactly the reference's values), before any dispatch.\n const patterns = pattern === null ? null : new Float64Array(plan.siteCount * 3);\n if (patterns !== null) {\n let maximumOffset = 0, maximumOffsetCodes = 0;\n for (let row = 0, i = 0; row < height; row++) for (let column = 0; column < width; column++, i++) {\n const p = pattern!(column, row), offsetCodes = p.readoutOffsetElectrons / gain;\n patterns[i * 3] = p.photoResponseGainFactor; patterns[i * 3 + 1] = p.darkCurrentFactor; patterns[i * 3 + 2] = p.readoutOffsetElectrons;\n maximumOffset = Math.max(maximumOffset, Math.abs(p.readoutOffsetElectrons)); maximumOffsetCodes = Math.max(maximumOffsetCodes, Math.abs(offsetCodes));\n }\n if (!(maximumOffset <= SENSOR_GPU_MAXIMUM_OFFSET_ELECTRONS && maximumOffsetCodes <= SENSOR_GPU_MAXIMUM_OFFSET_CODES)) {\n throw unsupported(\"Fixed-pattern readout offsets are outside the float32 sensor domain.\");\n }\n setFixedPatternSlack(params, threshold, maximumOffset, maximumOffsetCodes);\n }\n const rows = Math.max(1, Math.min(height, Math.floor(bandBytes / (width * siteBytes))));\n if (rows * width * siteBytes > runtime.maximumStorageBindingBytes) {\n throw new ImageKernelExecutionError(\"insufficient-limits\", \"One sensor band exceeds the device's storage binding limit.\");\n }\n const pipeline = await pipelines(\"photivra-sensor-raw\", SENSOR_RAW_WGSL);\n const codes = new Uint16Array(plan.siteCount), counts = [0, 0, 0, 0];\n const packed = new ArrayBuffer(rows * width * siteBytes), packedWords = new Uint32Array(packed), packedFloats = new Float32Array(packed);\n const packedInts = new Int32Array(packed);\n const words = new Uint32Array(params);\n let flagged = 0;\n const flaggedIndices: number[] = [];\n const scope = new GpuResourceScope(runtime);\n try {\n const auxBuffer = scope.upload(\"photivra-sensor-aux\", aux, BUFFER_USAGE.STORAGE);\n const gate = createHostYieldGate();\n for (let row0 = 0; row0 < height; row0 += rows) {\n checkAbort(abort.signal);\n const row1 = Math.min(height, row0 + rows), count = (row1 - row0) * width, first = row0 * width;\n for (let i = 0; i < count; i++) {\n const site = first + i, at = i * siteWords;\n // The reference's own float64 products of the means and the fixed-pattern factors.\n packMean(patterns === null ? photo[site]! : photo[site]! * patterns[site * 3]!, packedWords, packedFloats, at);\n packMean(patterns === null ? dark[site]! : dark[site]! * patterns[site * 3 + 1]!, packedWords, packedFloats, at + 2);\n let cursor = at + 4;\n for (const k of poissonComponents) { packMean(additional[k]![site]!, packedWords, packedFloats, cursor); cursor += 2; }\n if (deterministicComponents.length > 0) {\n let sum = 0;\n for (const k of deterministicComponents) sum += additional[k]![site]!;\n if (!(sum < SENSOR_GPU_MAXIMUM_MEAN)) throw unsupported(\"Deterministic charge of 2^30 electrons and above is outside the float32 sensor domain.\");\n packSplit(sum, packedInts, packedFloats, cursor);\n cursor += 2;\n }\n if (patterns !== null) {\n const offset = patterns[site * 3 + 2]!, limit = threshold - offset;\n if (limit >= 2 ** 30) { packedInts[cursor] = 2 ** 30; packedFloats[cursor + 1] = 0; } else packSplit(limit, packedInts, packedFloats, cursor);\n packSplit(offset / gain, packedInts, packedFloats, cursor + 2);\n }\n }\n words[0] = count; words[1] = row0;\n const band = new GpuResourceScope(runtime);\n try {\n const means = band.upload(\"photivra-sensor-means\", new Uint32Array(packed, 0, count * siteWords), BUFFER_USAGE.STORAGE);\n const out = band.buffer(\"photivra-sensor-codes\", count * 4, BUFFER_USAGE.STORAGE | BUFFER_USAGE.COPY_SRC);\n const uniform = band.upload(\"photivra-sensor-params\", new Uint8Array(params), BUFFER_USAGE.UNIFORM);\n const bindGroup = runtime.device.createBindGroup({ layout: pipeline.getBindGroupLayout(0), entries: [\n { binding: 0, resource: { buffer: uniform } }, { binding: 1, resource: { buffer: means } },\n { binding: 2, resource: { buffer: auxBuffer } }, { binding: 3, resource: { buffer: out } }] });\n const [data] = await runComputePass(runtime, band, pipeline, bindGroup, linearDispatch(count, SENSOR_WORKGROUP_SIZE, runtime.maximumWorkgroupsPerDimension),\n [{ buffer: out, bytes: count * 4 }], abort.signal);\n const result = new Uint32Array(data!, 0, count);\n for (let i = 0; i < count; i++) {\n const word = result[i]!, flags = word >>> SENSOR_OUTPUT.flagShift;\n codes[first + i] = word & SENSOR_OUTPUT.codeMask;\n if (flags & 1) counts[0]!++;\n if (flags & 2) counts[1]!++;\n if (flags & 4) counts[2]!++;\n if (flags & 8) counts[3]!++;\n if (word & SENSOR_OUTPUT.uncertainBit) { flagged++; flaggedIndices.push(first + i); }\n }\n } finally {\n band.release();\n }\n if (yieldControl && gate.due()) { await yieldControl(abort.signal); gate.restart(); }\n }\n } catch (error) {\n codes.fill(0);\n throw error;\n } finally {\n scope.release();\n }\n checkAbort(abort.signal);\n const execution = webGpuExecution({ kind: \"exact-except-flagged-sites\", flaggedSiteCount: flagged, noiseModel: { ...plan.noiseModel },\n seedSchedule: plan.seedSchedule }, flagged);\n return { plan, codes, diagnostics: packedSensorDiagnostics(counts), execution, flaggedSiteIndices: Uint32Array.from(flaggedIndices) };\n}\n"]}
@@ -0,0 +1,23 @@
1
+ import { type TemporalExposureSumInput, type TemporalExposureSumPlan } from "../motion/temporal-exposure-sum.js";
2
+ import { type ImageKernelExecution, type ImageKernelRelativeErrorBound } from "./image-kernel-execution.js";
3
+ import { type WebGpuRuntime } from "./webgpu-runtime.js";
4
+ import type { TemporalExposureSumResult } from "./image-kernel-accelerator.js";
5
+ type PipelineSource = (label: string, code: string) => Promise<GPUComputePipeline>;
6
+ type YieldControl = ((signal: AbortSignal) => Promise<void>) | undefined;
7
+ export declare const TEMPORAL_WORKGROUP_EDGE = 16;
8
+ /**
9
+ * A-priori float32 bound for every output (all terms are non-negative): each term carries at most K + 7
10
+ * roundings (sample, bilinear weight and their product, three inner additions, row weight and its
11
+ * product, K − 1 outer additions), so |v_f32 − v_ref| ≤ (γ_{K+8} + 2^-40)·v_ref + K·(8·w_max + 2)·2^-126 + R.
12
+ * The 2^-40 covers the float64 reference's own rounding; the 2^-126 term covers subnormal flush-to-zero of
13
+ * samples, products and sums. R covers weights below the float32 normal range, which the host conversion may round
14
+ * to zero or a subnormal (|f32(w) − w| ≤ w) and the GPU may flush, putting their whole term at risk:
15
+ * R = 2·S_max·Σ_k (max_y ρ_k(y) + w_max·Σ_j β_{k,j}), where ρ_k(y) and β_{k,j} are the row and bilinear weights in
16
+ * (0, 2^-126) (zero otherwise) and the factor 2 covers the conversion and the later roundings. R = 0 when no such
17
+ * weight exists.
18
+ */
19
+ export declare function temporalExposureSumErrorBound(plan: TemporalExposureSumPlan, rowWeights: Float32Array | Float64Array): ImageKernelRelativeErrorBound;
20
+ export declare const TEMPORAL_SUM_WGSL = "\nstruct Params { width: u32, height: u32, nodes: u32, out_row0: u32, out_rows: u32, in_row0: u32, pad0: u32, pad1: u32 };\nstruct Node { ox: i32, oy: i32, pad0: i32, pad1: i32, b: vec4<f32> };\n@group(0) @binding(0) var<uniform> params: Params;\n@group(0) @binding(1) var<storage, read> source: array<f32>;\n@group(0) @binding(2) var<storage, read> nodes: array<Node>;\n@group(0) @binding(3) var<storage, read> weights: array<f32>;\n@group(0) @binding(4) var<storage, read_write> result: array<f32>;\nfn sample(sx: i32, sy: i32) -> f32 { return source[u32(sy - i32(params.in_row0)) * params.width + u32(sx)]; }\n@compute @workgroup_size(16, 16)\nfn main(@builtin(global_invocation_id) gid: vec3<u32>) {\n let x = i32(gid.x);\n let local_y = gid.y;\n if (gid.x >= params.width || local_y >= params.out_rows) { return; }\n let y = i32(params.out_row0 + local_y);\n let w = i32(params.width);\n let h = i32(params.height);\n var sum = 0.0;\n for (var k = 0u; k < params.nodes; k = k + 1u) {\n let node = nodes[k];\n let sx = x + node.ox;\n let sy = y + node.oy;\n let left = sx >= 0 && sx < w;\n let right = sx + 1 >= 0 && sx + 1 < w;\n let top = sy >= 0 && sy < h;\n let bottom = sy + 1 >= 0 && sy + 1 < h;\n var inner = 0.0;\n if (top && left) { inner = inner + node.b.x * sample(sx, sy); }\n if (top && right) { inner = inner + node.b.y * sample(sx + 1, sy); }\n if (bottom && left) { inner = inner + node.b.z * sample(sx, sy + 1); }\n if (bottom && right) { inner = inner + node.b.w * sample(sx + 1, sy + 1); }\n sum = sum + weights[k * params.out_rows + local_y] * inner;\n }\n result[local_y * params.width + gid.x] = sum;\n}\n";
21
+ export declare function sumTemporalExposureOnCpu(plan: TemporalExposureSumPlan, input: TemporalExposureSumInput, abort: AbortController, yieldControl: YieldControl, execution: ImageKernelExecution): Promise<TemporalExposureSumResult>;
22
+ export declare function sumTemporalExposureOnGpu(runtime: WebGpuRuntime, bandBytes: number, plan: TemporalExposureSumPlan, input: TemporalExposureSumInput, abort: AbortController, yieldControl: YieldControl, pipelines: PipelineSource): Promise<TemporalExposureSumResult>;
23
+ export {};
@@ -0,0 +1,150 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ /**
3
+ * `webgpu-f32` and CPU-reference execution of the temporal exposure sum (#277, step 3). The equation
4
+ * and summation order are those of `sumTemporalExposureRows` (motion/temporal-exposure-sum.ts).
5
+ * Internal; the public entry point is the image-kernel accelerator.
6
+ */
7
+ import { createHostYieldGate } from "../capture/host-yield-cadence.js";
8
+ import { sumTemporalExposureRows } from "../motion/temporal-exposure-sum.js";
9
+ import { ImageKernelExecutionError, float32Gamma, webGpuExecution } from "./image-kernel-execution.js";
10
+ import { BUFFER_USAGE, GpuResourceScope, abortedError, runComputePass } from "./webgpu-runtime.js";
11
+ export const TEMPORAL_WORKGROUP_EDGE = 16;
12
+ const MAXIMUM_TAPS_PER_DISPATCH = 2 ** 30;
13
+ const FLOAT32_SUBNORMAL_LIMIT = 2 ** -126;
14
+ /**
15
+ * A-priori float32 bound for every output (all terms are non-negative): each term carries at most K + 7
16
+ * roundings (sample, bilinear weight and their product, three inner additions, row weight and its
17
+ * product, K − 1 outer additions), so |v_f32 − v_ref| ≤ (γ_{K+8} + 2^-40)·v_ref + K·(8·w_max + 2)·2^-126 + R.
18
+ * The 2^-40 covers the float64 reference's own rounding; the 2^-126 term covers subnormal flush-to-zero of
19
+ * samples, products and sums. R covers weights below the float32 normal range, which the host conversion may round
20
+ * to zero or a subnormal (|f32(w) − w| ≤ w) and the GPU may flush, putting their whole term at risk:
21
+ * R = 2·S_max·Σ_k (max_y ρ_k(y) + w_max·Σ_j β_{k,j}), where ρ_k(y) and β_{k,j} are the row and bilinear weights in
22
+ * (0, 2^-126) (zero otherwise) and the factor 2 covers the conversion and the later roundings. R = 0 when no such
23
+ * weight exists.
24
+ */
25
+ export function temporalExposureSumErrorBound(plan, rowWeights) {
26
+ const tiny = (w) => (w < FLOAT32_SUBNORMAL_LIMIT ? w : 0);
27
+ let atRisk = 0;
28
+ for (let k = 0; k < plan.nodeCount; k++) {
29
+ let largestRow = 0;
30
+ for (let y = 0; y < plan.height; y++)
31
+ largestRow = Math.max(largestRow, tiny(rowWeights[k * plan.height + y]));
32
+ atRisk += largestRow + plan.maximumWeight * plan.nodes[k].weights.reduce((sum, b) => sum + tiny(b), 0);
33
+ }
34
+ return { kind: "relative-to-reference", relative: float32Gamma(plan.nodeCount + 8) + 2 ** -40,
35
+ absolute: plan.nodeCount * (8 * plan.maximumWeight + 2) * FLOAT32_SUBNORMAL_LIMIT + 2 * plan.maximumSampleMagnitude * atRisk };
36
+ }
37
+ export const TEMPORAL_SUM_WGSL = /* wgsl */ `
38
+ struct Params { width: u32, height: u32, nodes: u32, out_row0: u32, out_rows: u32, in_row0: u32, pad0: u32, pad1: u32 };
39
+ struct Node { ox: i32, oy: i32, pad0: i32, pad1: i32, b: vec4<f32> };
40
+ @group(0) @binding(0) var<uniform> params: Params;
41
+ @group(0) @binding(1) var<storage, read> source: array<f32>;
42
+ @group(0) @binding(2) var<storage, read> nodes: array<Node>;
43
+ @group(0) @binding(3) var<storage, read> weights: array<f32>;
44
+ @group(0) @binding(4) var<storage, read_write> result: array<f32>;
45
+ fn sample(sx: i32, sy: i32) -> f32 { return source[u32(sy - i32(params.in_row0)) * params.width + u32(sx)]; }
46
+ @compute @workgroup_size(${TEMPORAL_WORKGROUP_EDGE}, ${TEMPORAL_WORKGROUP_EDGE})
47
+ fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
48
+ let x = i32(gid.x);
49
+ let local_y = gid.y;
50
+ if (gid.x >= params.width || local_y >= params.out_rows) { return; }
51
+ let y = i32(params.out_row0 + local_y);
52
+ let w = i32(params.width);
53
+ let h = i32(params.height);
54
+ var sum = 0.0;
55
+ for (var k = 0u; k < params.nodes; k = k + 1u) {
56
+ let node = nodes[k];
57
+ let sx = x + node.ox;
58
+ let sy = y + node.oy;
59
+ let left = sx >= 0 && sx < w;
60
+ let right = sx + 1 >= 0 && sx + 1 < w;
61
+ let top = sy >= 0 && sy < h;
62
+ let bottom = sy + 1 >= 0 && sy + 1 < h;
63
+ var inner = 0.0;
64
+ if (top && left) { inner = inner + node.b.x * sample(sx, sy); }
65
+ if (top && right) { inner = inner + node.b.y * sample(sx + 1, sy); }
66
+ if (bottom && left) { inner = inner + node.b.z * sample(sx, sy + 1); }
67
+ if (bottom && right) { inner = inner + node.b.w * sample(sx + 1, sy + 1); }
68
+ sum = sum + weights[k * params.out_rows + local_y] * inner;
69
+ }
70
+ result[local_y * params.width + gid.x] = sum;
71
+ }
72
+ `;
73
+ function checkAbort(abort) {
74
+ if (abort.signal.aborted)
75
+ throw abortedError();
76
+ }
77
+ export async function sumTemporalExposureOnCpu(plan, input, abort, yieldControl, execution) {
78
+ const samples = input.samples.slice(), weights = input.rowWeights.slice();
79
+ const values = new Float64Array(plan.width * plan.height);
80
+ const rowsPerChunk = Math.max(1, Math.floor(2_000_000 / Math.max(1, plan.width * plan.nodeCount * 4))), gate = createHostYieldGate();
81
+ for (let y = 0; y < plan.height; y += rowsPerChunk) {
82
+ checkAbort(abort);
83
+ const end = Math.min(plan.height, y + rowsPerChunk);
84
+ sumTemporalExposureRows(plan, samples, weights, y, end, values.subarray(y * plan.width, end * plan.width));
85
+ if (yieldControl && gate.due()) {
86
+ await yieldControl(abort.signal);
87
+ gate.restart();
88
+ }
89
+ }
90
+ checkAbort(abort);
91
+ return { plan, values, execution };
92
+ }
93
+ export async function sumTemporalExposureOnGpu(runtime, bandBytes, plan, input, abort, yieldControl, pipelines) {
94
+ const { width, height, nodes } = plan;
95
+ const errorBound = temporalExposureSumErrorBound(plan, input.rowWeights);
96
+ const samples = new Float32Array(input.samples), weights = new Float32Array(input.rowWeights);
97
+ const minimumOffset = Math.min(...nodes.map(n => n.offsetY)), maximumOffset = Math.max(...nodes.map(n => n.offsetY)) + 1;
98
+ const span = maximumOffset - minimumOffset, rowBytes = width * 4;
99
+ let rows = Math.min(height, Math.floor(bandBytes / rowBytes) - span, Math.floor(MAXIMUM_TAPS_PER_DISPATCH / (width * plan.nodeCount * 4)));
100
+ if (rows < 1) {
101
+ if ((1 + span) * rowBytes > runtime.maximumStorageBindingBytes) {
102
+ throw new ImageKernelExecutionError("insufficient-limits", "One temporal band exceeds the device's storage binding limit.");
103
+ }
104
+ rows = 1;
105
+ }
106
+ const nodeBuffer = new ArrayBuffer(nodes.length * 32), nodeInts = new Int32Array(nodeBuffer), nodeFloats = new Float32Array(nodeBuffer);
107
+ nodes.forEach((n, k) => { nodeInts[k * 8] = n.offsetX; nodeInts[k * 8 + 1] = n.offsetY; nodeFloats.set(n.weights, k * 8 + 4); });
108
+ const values = new Float32Array(width * height);
109
+ const pipeline = await pipelines("photivra-temporal-sum", TEMPORAL_SUM_WGSL);
110
+ const scope = new GpuResourceScope(runtime);
111
+ try {
112
+ const nodeData = scope.upload("photivra-temporal-nodes", new Uint8Array(nodeBuffer), BUFFER_USAGE.STORAGE);
113
+ const gate = createHostYieldGate();
114
+ for (let y0 = 0; y0 < height; y0 += rows) {
115
+ checkAbort(abort);
116
+ const y1 = Math.min(height, y0 + rows), count = y1 - y0;
117
+ const in0 = Math.max(0, Math.min(height, y0 + minimumOffset)), in1 = Math.max(in0, Math.min(height, y1 - 1 + maximumOffset + 1));
118
+ const bandWeights = new Float32Array(nodes.length * count);
119
+ for (let k = 0; k < nodes.length; k++)
120
+ bandWeights.set(weights.subarray(k * height + y0, k * height + y1), k * count);
121
+ const band = new GpuResourceScope(runtime);
122
+ try {
123
+ const source = band.upload("photivra-temporal-band", samples.subarray(in0 * width, in1 * width), BUFFER_USAGE.STORAGE);
124
+ const rowWeights = band.upload("photivra-temporal-weights", bandWeights, BUFFER_USAGE.STORAGE);
125
+ const result = band.buffer("photivra-temporal-result", count * rowBytes, BUFFER_USAGE.STORAGE | BUFFER_USAGE.COPY_SRC);
126
+ const uniform = band.upload("photivra-temporal-params", new Uint32Array([width, height, nodes.length, y0, count, in0, 0, 0]), BUFFER_USAGE.UNIFORM);
127
+ const bindGroup = runtime.device.createBindGroup({ layout: pipeline.getBindGroupLayout(0), entries: [
128
+ { binding: 0, resource: { buffer: uniform } }, { binding: 1, resource: { buffer: source } }, { binding: 2, resource: { buffer: nodeData } },
129
+ { binding: 3, resource: { buffer: rowWeights } }, { binding: 4, resource: { buffer: result } }
130
+ ] });
131
+ const groups = [Math.ceil(width / TEMPORAL_WORKGROUP_EDGE), Math.ceil(count / TEMPORAL_WORKGROUP_EDGE)];
132
+ const [data] = await runComputePass(runtime, band, pipeline, bindGroup, groups, [{ buffer: result, bytes: count * rowBytes }], abort.signal);
133
+ values.set(new Float32Array(data, 0, count * width), y0 * width);
134
+ }
135
+ finally {
136
+ band.release();
137
+ }
138
+ if (yieldControl && gate.due()) {
139
+ await yieldControl(abort.signal);
140
+ gate.restart();
141
+ }
142
+ }
143
+ }
144
+ finally {
145
+ scope.release();
146
+ }
147
+ checkAbort(abort);
148
+ return { plan, values, execution: webGpuExecution(errorBound, 0) };
149
+ }
150
+ //# sourceMappingURL=temporal-sum-gpu.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"temporal-sum-gpu.js","sourceRoot":"","sources":["../../src/gpu/temporal-sum-gpu.ts"],"names":[],"mappings":"AAAA,sCAAsC;AAEtC;;;;GAIG;AACH,OAAO,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAC;AACvE,OAAO,EAAE,uBAAuB,EAA+D,MAAM,oCAAoC,CAAC;AAC1I,OAAO,EAAE,yBAAyB,EAAE,YAAY,EAAE,eAAe,EAAiE,MAAM,6BAA6B,CAAC;AACtK,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,YAAY,EAAE,cAAc,EAAsB,MAAM,qBAAqB,CAAC;AAMvH,MAAM,CAAC,MAAM,uBAAuB,GAAG,EAAE,CAAC;AAC1C,MAAM,yBAAyB,GAAG,CAAC,IAAI,EAAE,CAAC;AAC1C,MAAM,uBAAuB,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC;AAE1C;;;;;;;;;;GAUG;AACH,MAAM,UAAU,6BAA6B,CAAC,IAA6B,EAAE,UAAuC;IAClH,MAAM,IAAI,GAAG,CAAC,CAAS,EAAU,EAAE,CAAC,CAAC,CAAC,GAAG,uBAAuB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC1E,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC,EAAE,EAAE,CAAC;QACxC,IAAI,UAAU,GAAG,CAAC,CAAC;QACnB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE;YAAE,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC,CAAE,CAAC,CAAC,CAAC;QAChH,MAAM,IAAI,UAAU,GAAG,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAE,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAC1G,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,uBAAuB,EAAE,QAAQ,EAAE,YAAY,CAAC,IAAI,CAAC,SAAS,GAAG,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE;QAC3F,QAAQ,EAAE,IAAI,CAAC,SAAS,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,aAAa,GAAG,CAAC,CAAC,GAAG,uBAAuB,GAAG,CAAC,GAAG,IAAI,CAAC,sBAAsB,GAAG,MAAM,EAAE,CAAC;AACnI,CAAC;AAED,MAAM,CAAC,MAAM,iBAAiB,GAAG,UAAU,CAAC;;;;;;;;;2BASjB,uBAAuB,KAAK,uBAAuB;;;;;;;;;;;;;;;;;;;;;;;;;;CA0B7E,CAAC;AAEF,SAAS,UAAU,CAAC,KAAsB;IACxC,IAAI,KAAK,CAAC,MAAM,CAAC,OAAO;QAAE,MAAM,YAAY,EAAE,CAAC;AACjD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAAC,IAA6B,EAAE,KAA+B,EAAE,KAAsB,EACnI,YAA0B,EAAE,SAA+B;IAC3D,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,OAAO,GAAG,KAAK,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;IAC1E,MAAM,MAAM,GAAG,IAAI,YAAY,CAAC,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC;IAC1D,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,GAAG,mBAAmB,EAAE,CAAC;IACrI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,IAAI,YAAY,EAAE,CAAC;QACnD,UAAU,CAAC,KAAK,CAAC,CAAC;QAClB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,GAAG,YAAY,CAAC,CAAC;QACpD,uBAAuB,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,EAAE,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;QAC3G,IAAI,YAAY,IAAI,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;YAAC,MAAM,YAAY,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;YAAC,IAAI,CAAC,OAAO,EAAE,CAAC;QAAC,CAAC;IACvF,CAAC;IACD,UAAU,CAAC,KAAK,CAAC,CAAC;IAClB,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;AACrC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAAC,OAAsB,EAAE,SAAiB,EAAE,IAA6B,EAAE,KAA+B,EACtJ,KAAsB,EAAE,YAA0B,EAAE,SAAyB;IAC7E,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC;IACtC,MAAM,UAAU,GAAG,6BAA6B,CAAC,IAAI,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC;IACzE,MAAM,OAAO,GAAG,IAAI,YAAY,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,OAAO,GAAG,IAAI,YAAY,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IAC9F,MAAM,aAAa,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,aAAa,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC;IACzH,MAAM,IAAI,GAAG,aAAa,GAAG,aAAa,EAAE,QAAQ,GAAG,KAAK,GAAG,CAAC,CAAC;IACjE,IAAI,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,QAAQ,CAAC,GAAG,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,yBAAyB,GAAG,CAAC,KAAK,GAAG,IAAI,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IAC3I,IAAI,IAAI,GAAG,CAAC,EAAE,CAAC;QACb,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,QAAQ,GAAG,OAAO,CAAC,0BAA0B,EAAE,CAAC;YAC/D,MAAM,IAAI,yBAAyB,CAAC,qBAAqB,EAAE,+DAA+D,CAAC,CAAC;QAC9H,CAAC;QACD,IAAI,GAAG,CAAC,CAAC;IACX,CAAC;IACD,MAAM,UAAU,GAAG,IAAI,WAAW,CAAC,KAAK,CAAC,MAAM,GAAG,EAAE,CAAC,EAAE,QAAQ,GAAG,IAAI,UAAU,CAAC,UAAU,CAAC,EAAE,UAAU,GAAG,IAAI,YAAY,CAAC,UAAU,CAAC,CAAC;IACxI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,GAAG,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACjI,MAAM,MAAM,GAAG,IAAI,YAAY,CAAC,KAAK,GAAG,MAAM,CAAC,CAAC;IAChD,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,uBAAuB,EAAE,iBAAiB,CAAC,CAAC;IAC7E,MAAM,KAAK,GAAG,IAAI,gBAAgB,CAAC,OAAO,CAAC,CAAC;IAC5C,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,CAAC,yBAAyB,EAAE,IAAI,UAAU,CAAC,UAAU,CAAC,EAAE,YAAY,CAAC,OAAO,CAAC,CAAC;QAC3G,MAAM,IAAI,GAAG,mBAAmB,EAAE,CAAC;QACnC,KAAK,IAAI,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,MAAM,EAAE,EAAE,IAAI,IAAI,EAAE,CAAC;YACzC,UAAU,CAAC,KAAK,CAAC,CAAC;YAClB,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,EAAE,GAAG,IAAI,CAAC,EAAE,KAAK,GAAG,EAAE,GAAG,EAAE,CAAC;YACxD,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,EAAE,GAAG,aAAa,CAAC,CAAC,EAAE,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,EAAE,GAAG,CAAC,GAAG,aAAa,GAAG,CAAC,CAAC,CAAC,CAAC;YACjI,MAAM,WAAW,GAAG,IAAI,YAAY,CAAC,KAAK,CAAC,MAAM,GAAG,KAAK,CAAC,CAAC;YAC3D,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE;gBAAE,WAAW,CAAC,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,GAAG,MAAM,GAAG,EAAE,EAAE,CAAC,GAAG,MAAM,GAAG,EAAE,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,CAAC;YACtH,MAAM,IAAI,GAAG,IAAI,gBAAgB,CAAC,OAAO,CAAC,CAAC;YAC3C,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,wBAAwB,EAAE,OAAO,CAAC,QAAQ,CAAC,GAAG,GAAG,KAAK,EAAE,GAAG,GAAG,KAAK,CAAC,EAAE,YAAY,CAAC,OAAO,CAAC,CAAC;gBACvH,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC,2BAA2B,EAAE,WAAW,EAAE,YAAY,CAAC,OAAO,CAAC,CAAC;gBAC/F,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,0BAA0B,EAAE,KAAK,GAAG,QAAQ,EAAE,YAAY,CAAC,OAAO,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC;gBACvH,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,0BAA0B,EAAE,IAAI,WAAW,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,YAAY,CAAC,OAAO,CAAC,CAAC;gBACpJ,MAAM,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,eAAe,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,kBAAkB,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE;wBAClG,EAAE,OAAO,EAAE,CAAC,EAAE,QAAQ,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,QAAQ,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,QAAQ,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE;wBAC3I,EAAE,OAAO,EAAE,CAAC,EAAE,QAAQ,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,EAAE,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,QAAQ,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE;qBAAC,EAAE,CAAC,CAAC;gBACrG,MAAM,MAAM,GAAqB,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,GAAG,uBAAuB,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,KAAK,GAAG,uBAAuB,CAAC,CAAC,CAAC;gBAC1H,MAAM,CAAC,IAAI,CAAC,GAAG,MAAM,cAAc,CAAC,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,GAAG,QAAQ,EAAE,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;gBAC7I,MAAM,CAAC,GAAG,CAAC,IAAI,YAAY,CAAC,IAAK,EAAE,CAAC,EAAE,KAAK,GAAG,KAAK,CAAC,EAAE,EAAE,GAAG,KAAK,CAAC,CAAC;YACpE,CAAC;oBAAS,CAAC;gBACT,IAAI,CAAC,OAAO,EAAE,CAAC;YACjB,CAAC;YACD,IAAI,YAAY,IAAI,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;gBAAC,MAAM,YAAY,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;gBAAC,IAAI,CAAC,OAAO,EAAE,CAAC;YAAC,CAAC;QACvF,CAAC;IACH,CAAC;YAAS,CAAC;QACT,KAAK,CAAC,OAAO,EAAE,CAAC;IAClB,CAAC;IACD,UAAU,CAAC,KAAK,CAAC,CAAC;IAClB,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,eAAe,CAAC,UAAU,EAAE,CAAC,CAAC,EAAE,CAAC;AACrE,CAAC","sourcesContent":["// SPDX-License-Identifier: Apache-2.0\n\n/**\n * `webgpu-f32` and CPU-reference execution of the temporal exposure sum (#277, step 3). The equation\n * and summation order are those of `sumTemporalExposureRows` (motion/temporal-exposure-sum.ts).\n * Internal; the public entry point is the image-kernel accelerator.\n */\nimport { createHostYieldGate } from \"../capture/host-yield-cadence.js\";\nimport { sumTemporalExposureRows, type TemporalExposureSumInput, type TemporalExposureSumPlan } from \"../motion/temporal-exposure-sum.js\";\nimport { ImageKernelExecutionError, float32Gamma, webGpuExecution, type ImageKernelExecution, type ImageKernelRelativeErrorBound } from \"./image-kernel-execution.js\";\nimport { BUFFER_USAGE, GpuResourceScope, abortedError, runComputePass, type WebGpuRuntime } from \"./webgpu-runtime.js\";\nimport type { TemporalExposureSumResult } from \"./image-kernel-accelerator.js\";\n\ntype PipelineSource = (label: string, code: string) => Promise<GPUComputePipeline>;\ntype YieldControl = ((signal: AbortSignal) => Promise<void>) | undefined;\n\nexport const TEMPORAL_WORKGROUP_EDGE = 16;\nconst MAXIMUM_TAPS_PER_DISPATCH = 2 ** 30;\nconst FLOAT32_SUBNORMAL_LIMIT = 2 ** -126;\n\n/**\n * A-priori float32 bound for every output (all terms are non-negative): each term carries at most K + 7\n * roundings (sample, bilinear weight and their product, three inner additions, row weight and its\n * product, K − 1 outer additions), so |v_f32 − v_ref| ≤ (γ_{K+8} + 2^-40)·v_ref + K·(8·w_max + 2)·2^-126 + R.\n * The 2^-40 covers the float64 reference's own rounding; the 2^-126 term covers subnormal flush-to-zero of\n * samples, products and sums. R covers weights below the float32 normal range, which the host conversion may round\n * to zero or a subnormal (|f32(w) − w| ≤ w) and the GPU may flush, putting their whole term at risk:\n * R = 2·S_max·Σ_k (max_y ρ_k(y) + w_max·Σ_j β_{k,j}), where ρ_k(y) and β_{k,j} are the row and bilinear weights in\n * (0, 2^-126) (zero otherwise) and the factor 2 covers the conversion and the later roundings. R = 0 when no such\n * weight exists.\n */\nexport function temporalExposureSumErrorBound(plan: TemporalExposureSumPlan, rowWeights: Float32Array | Float64Array): ImageKernelRelativeErrorBound {\n const tiny = (w: number): number => (w < FLOAT32_SUBNORMAL_LIMIT ? w : 0);\n let atRisk = 0;\n for (let k = 0; k < plan.nodeCount; k++) {\n let largestRow = 0;\n for (let y = 0; y < plan.height; y++) largestRow = Math.max(largestRow, tiny(rowWeights[k * plan.height + y]!));\n atRisk += largestRow + plan.maximumWeight * plan.nodes[k]!.weights.reduce((sum, b) => sum + tiny(b), 0);\n }\n return { kind: \"relative-to-reference\", relative: float32Gamma(plan.nodeCount + 8) + 2 ** -40,\n absolute: plan.nodeCount * (8 * plan.maximumWeight + 2) * FLOAT32_SUBNORMAL_LIMIT + 2 * plan.maximumSampleMagnitude * atRisk };\n}\n\nexport const TEMPORAL_SUM_WGSL = /* wgsl */ `\nstruct Params { width: u32, height: u32, nodes: u32, out_row0: u32, out_rows: u32, in_row0: u32, pad0: u32, pad1: u32 };\nstruct Node { ox: i32, oy: i32, pad0: i32, pad1: i32, b: vec4<f32> };\n@group(0) @binding(0) var<uniform> params: Params;\n@group(0) @binding(1) var<storage, read> source: array<f32>;\n@group(0) @binding(2) var<storage, read> nodes: array<Node>;\n@group(0) @binding(3) var<storage, read> weights: array<f32>;\n@group(0) @binding(4) var<storage, read_write> result: array<f32>;\nfn sample(sx: i32, sy: i32) -> f32 { return source[u32(sy - i32(params.in_row0)) * params.width + u32(sx)]; }\n@compute @workgroup_size(${TEMPORAL_WORKGROUP_EDGE}, ${TEMPORAL_WORKGROUP_EDGE})\nfn main(@builtin(global_invocation_id) gid: vec3<u32>) {\n let x = i32(gid.x);\n let local_y = gid.y;\n if (gid.x >= params.width || local_y >= params.out_rows) { return; }\n let y = i32(params.out_row0 + local_y);\n let w = i32(params.width);\n let h = i32(params.height);\n var sum = 0.0;\n for (var k = 0u; k < params.nodes; k = k + 1u) {\n let node = nodes[k];\n let sx = x + node.ox;\n let sy = y + node.oy;\n let left = sx >= 0 && sx < w;\n let right = sx + 1 >= 0 && sx + 1 < w;\n let top = sy >= 0 && sy < h;\n let bottom = sy + 1 >= 0 && sy + 1 < h;\n var inner = 0.0;\n if (top && left) { inner = inner + node.b.x * sample(sx, sy); }\n if (top && right) { inner = inner + node.b.y * sample(sx + 1, sy); }\n if (bottom && left) { inner = inner + node.b.z * sample(sx, sy + 1); }\n if (bottom && right) { inner = inner + node.b.w * sample(sx + 1, sy + 1); }\n sum = sum + weights[k * params.out_rows + local_y] * inner;\n }\n result[local_y * params.width + gid.x] = sum;\n}\n`;\n\nfunction checkAbort(abort: AbortController): void {\n if (abort.signal.aborted) throw abortedError();\n}\n\nexport async function sumTemporalExposureOnCpu(plan: TemporalExposureSumPlan, input: TemporalExposureSumInput, abort: AbortController,\n yieldControl: YieldControl, execution: ImageKernelExecution): Promise<TemporalExposureSumResult> {\n const samples = input.samples.slice(), weights = input.rowWeights.slice();\n const values = new Float64Array(plan.width * plan.height);\n const rowsPerChunk = Math.max(1, Math.floor(2_000_000 / Math.max(1, plan.width * plan.nodeCount * 4))), gate = createHostYieldGate();\n for (let y = 0; y < plan.height; y += rowsPerChunk) {\n checkAbort(abort);\n const end = Math.min(plan.height, y + rowsPerChunk);\n sumTemporalExposureRows(plan, samples, weights, y, end, values.subarray(y * plan.width, end * plan.width));\n if (yieldControl && gate.due()) { await yieldControl(abort.signal); gate.restart(); }\n }\n checkAbort(abort);\n return { plan, values, execution };\n}\n\nexport async function sumTemporalExposureOnGpu(runtime: WebGpuRuntime, bandBytes: number, plan: TemporalExposureSumPlan, input: TemporalExposureSumInput,\n abort: AbortController, yieldControl: YieldControl, pipelines: PipelineSource): Promise<TemporalExposureSumResult> {\n const { width, height, nodes } = plan;\n const errorBound = temporalExposureSumErrorBound(plan, input.rowWeights);\n const samples = new Float32Array(input.samples), weights = new Float32Array(input.rowWeights);\n const minimumOffset = Math.min(...nodes.map(n => n.offsetY)), maximumOffset = Math.max(...nodes.map(n => n.offsetY)) + 1;\n const span = maximumOffset - minimumOffset, rowBytes = width * 4;\n let rows = Math.min(height, Math.floor(bandBytes / rowBytes) - span, Math.floor(MAXIMUM_TAPS_PER_DISPATCH / (width * plan.nodeCount * 4)));\n if (rows < 1) {\n if ((1 + span) * rowBytes > runtime.maximumStorageBindingBytes) {\n throw new ImageKernelExecutionError(\"insufficient-limits\", \"One temporal band exceeds the device's storage binding limit.\");\n }\n rows = 1;\n }\n const nodeBuffer = new ArrayBuffer(nodes.length * 32), nodeInts = new Int32Array(nodeBuffer), nodeFloats = new Float32Array(nodeBuffer);\n nodes.forEach((n, k) => { nodeInts[k * 8] = n.offsetX; nodeInts[k * 8 + 1] = n.offsetY; nodeFloats.set(n.weights, k * 8 + 4); });\n const values = new Float32Array(width * height);\n const pipeline = await pipelines(\"photivra-temporal-sum\", TEMPORAL_SUM_WGSL);\n const scope = new GpuResourceScope(runtime);\n try {\n const nodeData = scope.upload(\"photivra-temporal-nodes\", new Uint8Array(nodeBuffer), BUFFER_USAGE.STORAGE);\n const gate = createHostYieldGate();\n for (let y0 = 0; y0 < height; y0 += rows) {\n checkAbort(abort);\n const y1 = Math.min(height, y0 + rows), count = y1 - y0;\n const in0 = Math.max(0, Math.min(height, y0 + minimumOffset)), in1 = Math.max(in0, Math.min(height, y1 - 1 + maximumOffset + 1));\n const bandWeights = new Float32Array(nodes.length * count);\n for (let k = 0; k < nodes.length; k++) bandWeights.set(weights.subarray(k * height + y0, k * height + y1), k * count);\n const band = new GpuResourceScope(runtime);\n try {\n const source = band.upload(\"photivra-temporal-band\", samples.subarray(in0 * width, in1 * width), BUFFER_USAGE.STORAGE);\n const rowWeights = band.upload(\"photivra-temporal-weights\", bandWeights, BUFFER_USAGE.STORAGE);\n const result = band.buffer(\"photivra-temporal-result\", count * rowBytes, BUFFER_USAGE.STORAGE | BUFFER_USAGE.COPY_SRC);\n const uniform = band.upload(\"photivra-temporal-params\", new Uint32Array([width, height, nodes.length, y0, count, in0, 0, 0]), BUFFER_USAGE.UNIFORM);\n const bindGroup = runtime.device.createBindGroup({ layout: pipeline.getBindGroupLayout(0), entries: [\n { binding: 0, resource: { buffer: uniform } }, { binding: 1, resource: { buffer: source } }, { binding: 2, resource: { buffer: nodeData } },\n { binding: 3, resource: { buffer: rowWeights } }, { binding: 4, resource: { buffer: result } }] });\n const groups: [number, number] = [Math.ceil(width / TEMPORAL_WORKGROUP_EDGE), Math.ceil(count / TEMPORAL_WORKGROUP_EDGE)];\n const [data] = await runComputePass(runtime, band, pipeline, bindGroup, groups, [{ buffer: result, bytes: count * rowBytes }], abort.signal);\n values.set(new Float32Array(data!, 0, count * width), y0 * width);\n } finally {\n band.release();\n }\n if (yieldControl && gate.due()) { await yieldControl(abort.signal); gate.restart(); }\n }\n } finally {\n scope.release();\n }\n checkAbort(abort);\n return { plan, values, execution: webGpuExecution(errorBound, 0) };\n}\n"]}