@photivra/engine 1.5.0 → 2.1.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 (1085) hide show
  1. package/CHANGELOG.md +414 -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/diffraction-provider.d.ts +30 -0
  236. package/dist/facade/diffraction-provider.js +127 -0
  237. package/dist/facade/diffraction-provider.js.map +1 -0
  238. package/dist/facade/host-yield.d.ts +7 -0
  239. package/dist/facade/host-yield.js +19 -0
  240. package/dist/facade/host-yield.js.map +1 -0
  241. package/dist/facade/scene-radiance.d.ts +117 -0
  242. package/dist/facade/scene-radiance.js +205 -0
  243. package/dist/facade/scene-radiance.js.map +1 -0
  244. package/dist/facade/simulate-capture.d.ts +363 -0
  245. package/dist/facade/simulate-capture.js +1281 -0
  246. package/dist/facade/simulate-capture.js.map +1 -0
  247. package/dist/gpu/chart-radiance-gpu.d.ts +17 -0
  248. package/dist/gpu/chart-radiance-gpu.js +176 -0
  249. package/dist/gpu/chart-radiance-gpu.js.map +1 -0
  250. package/dist/gpu/image-kernel-accelerator.d.ts +132 -0
  251. package/dist/gpu/image-kernel-accelerator.js +720 -0
  252. package/dist/gpu/image-kernel-accelerator.js.map +1 -0
  253. package/dist/gpu/image-kernel-execution.d.ts +92 -0
  254. package/dist/gpu/image-kernel-execution.js +84 -0
  255. package/dist/gpu/image-kernel-execution.js.map +1 -0
  256. package/dist/gpu/sensor-stage-gpu.d.ts +44 -0
  257. package/dist/gpu/sensor-stage-gpu.js +317 -0
  258. package/dist/gpu/sensor-stage-gpu.js.map +1 -0
  259. package/dist/gpu/temporal-sum-gpu.d.ts +23 -0
  260. package/dist/gpu/temporal-sum-gpu.js +150 -0
  261. package/dist/gpu/temporal-sum-gpu.js.map +1 -0
  262. package/dist/gpu/webgpu-runtime.d.ts +63 -0
  263. package/dist/gpu/webgpu-runtime.js +215 -0
  264. package/dist/gpu/webgpu-runtime.js.map +1 -0
  265. package/dist/gpu/wgsl-chart-kernel.d.ts +30 -0
  266. package/dist/gpu/wgsl-chart-kernel.js +165 -0
  267. package/dist/gpu/wgsl-chart-kernel.js.map +1 -0
  268. package/dist/gpu/wgsl-kernels.d.ts +53 -0
  269. package/dist/gpu/wgsl-kernels.js +365 -0
  270. package/dist/gpu/wgsl-kernels.js.map +1 -0
  271. package/dist/gpu/wgsl-sensor-kernel.d.ts +64 -0
  272. package/dist/gpu/wgsl-sensor-kernel.js +409 -0
  273. package/dist/gpu/wgsl-sensor-kernel.js.map +1 -0
  274. package/dist/index.d.ts +91 -25
  275. package/dist/index.js +60 -15
  276. package/dist/index.js.map +1 -1
  277. package/dist/motion/camera-rotation.d.ts +92 -40
  278. package/dist/motion/camera-rotation.js +84 -47
  279. package/dist/motion/camera-rotation.js.map +1 -1
  280. package/dist/motion/capture-rotation-inverse-mapping.d.ts +37 -34
  281. package/dist/motion/capture-rotation-inverse-mapping.js +32 -24
  282. package/dist/motion/capture-rotation-inverse-mapping.js.map +1 -1
  283. package/dist/motion/capture-rotation-temporal-quadrature.d.ts +39 -35
  284. package/dist/motion/capture-rotation-temporal-quadrature.js +37 -28
  285. package/dist/motion/capture-rotation-temporal-quadrature.js.map +1 -1
  286. package/dist/motion/capture-rotation-trajectory.d.ts +32 -28
  287. package/dist/motion/capture-rotation-trajectory.js +36 -26
  288. package/dist/motion/capture-rotation-trajectory.js.map +1 -1
  289. package/dist/motion/capture-translation-parallax-temporal-quadrature.d.ts +23 -21
  290. package/dist/motion/capture-translation-parallax-temporal-quadrature.js +33 -14
  291. package/dist/motion/capture-translation-parallax-temporal-quadrature.js.map +1 -1
  292. package/dist/motion/extended-object-projection.d.ts +19 -16
  293. package/dist/motion/extended-object-projection.js +38 -18
  294. package/dist/motion/extended-object-projection.js.map +1 -1
  295. package/dist/motion/projected-motion.d.ts +18 -17
  296. package/dist/motion/projected-motion.js +25 -17
  297. package/dist/motion/projected-motion.js.map +1 -1
  298. package/dist/motion/temporal-exposure-sum.d.ts +55 -0
  299. package/dist/motion/temporal-exposure-sum.js +141 -0
  300. package/dist/motion/temporal-exposure-sum.js.map +1 -0
  301. package/dist/motion/video-sequence.d.ts +111 -0
  302. package/dist/motion/video-sequence.js +179 -0
  303. package/dist/motion/video-sequence.js.map +1 -0
  304. package/dist/optics/aperture.d.ts +14 -15
  305. package/dist/optics/aperture.js +13 -11
  306. package/dist/optics/aperture.js.map +1 -1
  307. package/dist/optics/atmospheric-haze.d.ts +83 -0
  308. package/dist/optics/atmospheric-haze.js +113 -0
  309. package/dist/optics/atmospheric-haze.js.map +1 -0
  310. package/dist/optics/brown-conrady-distortion.d.ts +116 -0
  311. package/dist/optics/brown-conrady-distortion.js +291 -0
  312. package/dist/optics/brown-conrady-distortion.js.map +1 -0
  313. package/dist/optics/circle-of-confusion.d.ts +10 -10
  314. package/dist/optics/circle-of-confusion.js +15 -11
  315. package/dist/optics/circle-of-confusion.js.map +1 -1
  316. package/dist/optics/complex-pupil-psf.d.ts +64 -33
  317. package/dist/optics/complex-pupil-psf.js +190 -98
  318. package/dist/optics/complex-pupil-psf.js.map +1 -1
  319. package/dist/optics/depth-of-field.d.ts +25 -15
  320. package/dist/optics/depth-of-field.js +67 -27
  321. package/dist/optics/depth-of-field.js.map +1 -1
  322. package/dist/optics/diffraction-psf-profile.d.ts +118 -0
  323. package/dist/optics/diffraction-psf-profile.js +252 -0
  324. package/dist/optics/diffraction-psf-profile.js.map +1 -0
  325. package/dist/optics/diffraction.d.ts +14 -13
  326. package/dist/optics/diffraction.js +14 -10
  327. package/dist/optics/diffraction.js.map +1 -1
  328. package/dist/optics/focus-breathing.d.ts +88 -27
  329. package/dist/optics/focus-breathing.js +114 -23
  330. package/dist/optics/focus-breathing.js.map +1 -1
  331. package/dist/optics/focus-state.d.ts +18 -18
  332. package/dist/optics/focus-state.js +21 -15
  333. package/dist/optics/focus-state.js.map +1 -1
  334. package/dist/optics/front-of-lens-filter.d.ts +45 -14
  335. package/dist/optics/front-of-lens-filter.js +259 -88
  336. package/dist/optics/front-of-lens-filter.js.map +1 -1
  337. package/dist/optics/illumination-vignetting.d.ts +16 -17
  338. package/dist/optics/illumination-vignetting.js +40 -17
  339. package/dist/optics/illumination-vignetting.js.map +1 -1
  340. package/dist/optics/irradiance-convolution.d.ts +59 -0
  341. package/dist/optics/irradiance-convolution.js +138 -0
  342. package/dist/optics/irradiance-convolution.js.map +1 -0
  343. package/dist/optics/lateral-chromatic-aberration.d.ts +33 -30
  344. package/dist/optics/lateral-chromatic-aberration.js +33 -23
  345. package/dist/optics/lateral-chromatic-aberration.js.map +1 -1
  346. package/dist/optics/lens-psf-kernels.d.ts +89 -0
  347. package/dist/optics/lens-psf-kernels.js +175 -0
  348. package/dist/optics/lens-psf-kernels.js.map +1 -0
  349. package/dist/optics/lens-psf-profile.d.ts +78 -46
  350. package/dist/optics/lens-psf-profile.js +335 -124
  351. package/dist/optics/lens-psf-profile.js.map +1 -1
  352. package/dist/optics/longitudinal-chromatic-aberration.d.ts +102 -0
  353. package/dist/optics/longitudinal-chromatic-aberration.js +210 -0
  354. package/dist/optics/longitudinal-chromatic-aberration.js.map +1 -0
  355. package/dist/optics/polygon-diffraction.d.ts +80 -23
  356. package/dist/optics/polygon-diffraction.js +130 -25
  357. package/dist/optics/polygon-diffraction.js.map +1 -1
  358. package/dist/optics/profile-contract.d.ts +5 -6
  359. package/dist/optics/profile-contract.js +14 -11
  360. package/dist/optics/profile-contract.js.map +1 -1
  361. package/dist/optics/psf-foundation.d.ts +23 -23
  362. package/dist/optics/psf-foundation.js +24 -21
  363. package/dist/optics/psf-foundation.js.map +1 -1
  364. package/dist/optics/pupil-vignetting.d.ts +118 -0
  365. package/dist/optics/pupil-vignetting.js +264 -0
  366. package/dist/optics/pupil-vignetting.js.map +1 -0
  367. package/dist/optics/radial-distortion.d.ts +34 -33
  368. package/dist/optics/radial-distortion.js +37 -30
  369. package/dist/optics/radial-distortion.js.map +1 -1
  370. package/dist/optics/scene-to-sensor-irradiance.d.ts +47 -33
  371. package/dist/optics/scene-to-sensor-irradiance.js +73 -45
  372. package/dist/optics/scene-to-sensor-irradiance.js.map +1 -1
  373. package/dist/optics/scene-to-sensor-quadrature.d.ts +23 -18
  374. package/dist/optics/scene-to-sensor-quadrature.js +16 -11
  375. package/dist/optics/scene-to-sensor-quadrature.js.map +1 -1
  376. package/dist/optics/sensor-aperture-rays.d.ts +20 -4
  377. package/dist/optics/sensor-aperture-rays.js +32 -14
  378. package/dist/optics/sensor-aperture-rays.js.map +1 -1
  379. package/dist/optics/sensor-environment-query.d.ts +81 -16
  380. package/dist/optics/sensor-environment-query.js +145 -12
  381. package/dist/optics/sensor-environment-query.js.map +1 -1
  382. package/dist/optics/sensor-psf-quadrature.d.ts +12 -10
  383. package/dist/optics/sensor-psf-quadrature.js +18 -11
  384. package/dist/optics/sensor-psf-quadrature.js.map +1 -1
  385. package/dist/optics/sensor-psf-support.d.ts +8 -6
  386. package/dist/optics/sensor-psf-support.js +8 -5
  387. package/dist/optics/sensor-psf-support.js.map +1 -1
  388. package/dist/optics/stray-light.d.ts +22 -19
  389. package/dist/optics/stray-light.js +18 -12
  390. package/dist/optics/stray-light.js.map +1 -1
  391. package/dist/optics/thin-lens.d.ts +10 -9
  392. package/dist/optics/thin-lens.js +12 -8
  393. package/dist/optics/thin-lens.js.map +1 -1
  394. package/dist/optics/zernike-wavefront.d.ts +154 -0
  395. package/dist/optics/zernike-wavefront.js +352 -0
  396. package/dist/optics/zernike-wavefront.js.map +1 -0
  397. package/dist/output/capture-corrected-sdr.d.ts +16 -8
  398. package/dist/output/capture-corrected-sdr.js +16 -8
  399. package/dist/output/capture-corrected-sdr.js.map +1 -1
  400. package/dist/output/capture-geometry.d.ts +34 -36
  401. package/dist/output/capture-geometry.js +52 -32
  402. package/dist/output/capture-geometry.js.map +1 -1
  403. package/dist/output/capture-sdr.d.ts +7 -6
  404. package/dist/output/capture-sdr.js +11 -8
  405. package/dist/output/capture-sdr.js.map +1 -1
  406. package/dist/output/crop.d.ts +22 -6
  407. package/dist/output/crop.js +40 -6
  408. package/dist/output/crop.js.map +1 -1
  409. package/dist/output/geometric-transforms.d.ts +60 -23
  410. package/dist/output/geometric-transforms.js +111 -24
  411. package/dist/output/geometric-transforms.js.map +1 -1
  412. package/dist/output/lens-corrections.d.ts +27 -19
  413. package/dist/output/lens-corrections.js +29 -13
  414. package/dist/output/lens-corrections.js.map +1 -1
  415. package/dist/output/native-capture-sdr.d.ts +71 -16
  416. package/dist/output/native-capture-sdr.js +190 -33
  417. package/dist/output/native-capture-sdr.js.map +1 -1
  418. package/dist/output/png-encoder.d.ts +65 -0
  419. package/dist/output/png-encoder.js +461 -0
  420. package/dist/output/png-encoder.js.map +1 -0
  421. package/dist/output/print-contrast-reference.d.ts +10 -9
  422. package/dist/output/print-contrast-reference.js +10 -8
  423. package/dist/output/print-contrast-reference.js.map +1 -1
  424. package/dist/output/print-detail.d.ts +18 -17
  425. package/dist/output/print-detail.js +12 -10
  426. package/dist/output/print-detail.js.map +1 -1
  427. package/dist/output/print-jpeg.d.ts +26 -5
  428. package/dist/output/print-jpeg.js +117 -50
  429. package/dist/output/print-jpeg.js.map +1 -1
  430. package/dist/output/print-plan.d.ts +19 -19
  431. package/dist/output/print-plan.js +11 -10
  432. package/dist/output/print-plan.js.map +1 -1
  433. package/dist/output/print-region-statistics.d.ts +14 -15
  434. package/dist/output/print-region-statistics.js +11 -11
  435. package/dist/output/print-region-statistics.js.map +1 -1
  436. package/dist/output/sdr-rendering.d.ts +48 -10
  437. package/dist/output/sdr-rendering.js +114 -25
  438. package/dist/output/sdr-rendering.js.map +1 -1
  439. package/dist/output/subject-framing-crop.d.ts +6 -10
  440. package/dist/output/subject-framing-crop.js +23 -13
  441. package/dist/output/subject-framing-crop.js.map +1 -1
  442. package/dist/processing/demosaic.d.ts +90 -0
  443. package/dist/processing/demosaic.js +275 -0
  444. package/dist/processing/demosaic.js.map +1 -0
  445. package/dist/processing/denoise.d.ts +68 -0
  446. package/dist/processing/denoise.js +214 -0
  447. package/dist/processing/denoise.js.map +1 -0
  448. package/dist/processing/focus-stacking.d.ts +17 -0
  449. package/dist/processing/focus-stacking.js +80 -0
  450. package/dist/processing/focus-stacking.js.map +1 -0
  451. package/dist/processing/hdr.d.ts +54 -0
  452. package/dist/processing/hdr.js +172 -0
  453. package/dist/processing/hdr.js.map +1 -0
  454. package/dist/processing/image-ops.d.ts +66 -0
  455. package/dist/processing/image-ops.js +192 -0
  456. package/dist/processing/image-ops.js.map +1 -0
  457. package/dist/processing/panorama.d.ts +51 -0
  458. package/dist/processing/panorama.js +305 -0
  459. package/dist/processing/panorama.js.map +1 -0
  460. package/dist/processing/processing-task.d.ts +85 -0
  461. package/dist/processing/processing-task.js +164 -0
  462. package/dist/processing/processing-task.js.map +1 -0
  463. package/dist/processing/tone-mapping.d.ts +69 -0
  464. package/dist/processing/tone-mapping.js +310 -0
  465. package/dist/processing/tone-mapping.js.map +1 -0
  466. package/dist/schema/camera.d.ts +5 -4
  467. package/dist/schema/illumination-spectral.d.ts +13 -19
  468. package/dist/schema/illumination-spectral.js +23 -19
  469. package/dist/schema/illumination-spectral.js.map +1 -1
  470. package/dist/schema/illumination-temporal.d.ts +12 -15
  471. package/dist/schema/illumination-temporal.js +43 -28
  472. package/dist/schema/illumination-temporal.js.map +1 -1
  473. package/dist/schema/illumination.d.ts +5 -4
  474. package/dist/schema/illumination.js +55 -20
  475. package/dist/schema/illumination.js.map +1 -1
  476. package/dist/schema/scene-radiance-temporal.d.ts +9 -11
  477. package/dist/schema/scene-radiance-temporal.js +26 -23
  478. package/dist/schema/scene-radiance-temporal.js.map +1 -1
  479. package/dist/schema/scene-radiance.d.ts +17 -17
  480. package/dist/schema/scene-radiance.js +56 -34
  481. package/dist/schema/scene-radiance.js.map +1 -1
  482. package/dist/schema/scene.d.ts +14 -13
  483. package/dist/schema/validation.d.ts +0 -1
  484. package/dist/schema/validation.js +17 -15
  485. package/dist/schema/validation.js.map +1 -1
  486. package/dist/sensor/accumulated-charge.d.ts +45 -64
  487. package/dist/sensor/accumulated-charge.js +41 -47
  488. package/dist/sensor/accumulated-charge.js.map +1 -1
  489. package/dist/sensor/architecture.d.ts +22 -25
  490. package/dist/sensor/architecture.js +17 -16
  491. package/dist/sensor/architecture.js.map +1 -1
  492. package/dist/sensor/camera-saturation-capacity.d.ts +21 -28
  493. package/dist/sensor/camera-saturation-capacity.js +36 -34
  494. package/dist/sensor/camera-saturation-capacity.js.map +1 -1
  495. package/dist/sensor/capture-color-sampling-binding.d.ts +46 -51
  496. package/dist/sensor/capture-color-sampling-binding.js +39 -41
  497. package/dist/sensor/capture-color-sampling-binding.js.map +1 -1
  498. package/dist/sensor/capture-mode-timing.d.ts +8 -9
  499. package/dist/sensor/capture-mode-timing.js +24 -21
  500. package/dist/sensor/capture-mode-timing.js.map +1 -1
  501. package/dist/sensor/capture-mode.d.ts +28 -30
  502. package/dist/sensor/capture-mode.js +33 -31
  503. package/dist/sensor/capture-mode.js.map +1 -1
  504. package/dist/sensor/color-sampling.d.ts +30 -33
  505. package/dist/sensor/color-sampling.js +32 -37
  506. package/dist/sensor/color-sampling.js.map +1 -1
  507. package/dist/sensor/constant-rate-temporal-integration.d.ts +19 -23
  508. package/dist/sensor/constant-rate-temporal-integration.js +28 -26
  509. package/dist/sensor/constant-rate-temporal-integration.js.map +1 -1
  510. package/dist/sensor/dark-current.d.ts +53 -49
  511. package/dist/sensor/dark-current.js +87 -46
  512. package/dist/sensor/dark-current.js.map +1 -1
  513. package/dist/sensor/environment-photo-signal.d.ts +71 -30
  514. package/dist/sensor/environment-photo-signal.js +127 -46
  515. package/dist/sensor/environment-photo-signal.js.map +1 -1
  516. package/dist/sensor/eqe-electron-rate.d.ts +14 -13
  517. package/dist/sensor/eqe-electron-rate.js +34 -14
  518. package/dist/sensor/eqe-electron-rate.js.map +1 -1
  519. package/dist/sensor/eqe-local-exposure.d.ts +24 -24
  520. package/dist/sensor/eqe-local-exposure.js +15 -11
  521. package/dist/sensor/eqe-local-exposure.js.map +1 -1
  522. package/dist/sensor/eqe-temporal-exposure.d.ts +11 -11
  523. package/dist/sensor/eqe-temporal-exposure.js +15 -10
  524. package/dist/sensor/eqe-temporal-exposure.js.map +1 -1
  525. package/dist/sensor/exposure-window.d.ts +48 -34
  526. package/dist/sensor/exposure-window.js +77 -36
  527. package/dist/sensor/exposure-window.js.map +1 -1
  528. package/dist/sensor/fixed-pattern-noise.d.ts +108 -0
  529. package/dist/sensor/fixed-pattern-noise.js +166 -0
  530. package/dist/sensor/fixed-pattern-noise.js.map +1 -0
  531. package/dist/sensor/iso-gain.d.ts +44 -0
  532. package/dist/sensor/iso-gain.js +119 -0
  533. package/dist/sensor/iso-gain.js.map +1 -0
  534. package/dist/sensor/iso-signal-chain.d.ts +25 -48
  535. package/dist/sensor/iso-signal-chain.js +52 -66
  536. package/dist/sensor/iso-signal-chain.js.map +1 -1
  537. package/dist/sensor/local-exposure-binding.d.ts +21 -21
  538. package/dist/sensor/local-exposure-binding.js +22 -18
  539. package/dist/sensor/local-exposure-binding.js.map +1 -1
  540. package/dist/sensor/optical-stack.d.ts +36 -40
  541. package/dist/sensor/optical-stack.js +34 -37
  542. package/dist/sensor/optical-stack.js.map +1 -1
  543. package/dist/sensor/photon-energy.d.ts +22 -28
  544. package/dist/sensor/photon-energy.js +42 -34
  545. package/dist/sensor/photon-energy.js.map +1 -1
  546. package/dist/sensor/physical-charge-capacity.d.ts +20 -30
  547. package/dist/sensor/physical-charge-capacity.js +35 -36
  548. package/dist/sensor/physical-charge-capacity.js.map +1 -1
  549. package/dist/sensor/pixel-pitch.d.ts +2 -3
  550. package/dist/sensor/pixel-pitch.js +4 -2
  551. package/dist/sensor/pixel-pitch.js.map +1 -1
  552. package/dist/sensor/radiometry-readiness.d.ts +13 -15
  553. package/dist/sensor/radiometry-readiness.js +20 -17
  554. package/dist/sensor/radiometry-readiness.js.map +1 -1
  555. package/dist/sensor/raw-readout.d.ts +173 -83
  556. package/dist/sensor/raw-readout.js +425 -160
  557. package/dist/sensor/raw-readout.js.map +1 -1
  558. package/dist/sensor/raw-reconstruction.d.ts +112 -44
  559. package/dist/sensor/raw-reconstruction.js +200 -47
  560. package/dist/sensor/raw-reconstruction.js.map +1 -1
  561. package/dist/sensor/readout-exposure-linkage.d.ts +103 -34
  562. package/dist/sensor/readout-exposure-linkage.js +125 -27
  563. package/dist/sensor/readout-exposure-linkage.js.map +1 -1
  564. package/dist/sensor/readout-timing.d.ts +43 -44
  565. package/dist/sensor/readout-timing.js +38 -30
  566. package/dist/sensor/readout-timing.js.map +1 -1
  567. package/dist/sensor/response-application-compatibility.d.ts +21 -28
  568. package/dist/sensor/response-application-compatibility.js +35 -34
  569. package/dist/sensor/response-application-compatibility.js.map +1 -1
  570. package/dist/sensor/response-operating-range.d.ts +26 -35
  571. package/dist/sensor/response-operating-range.js +40 -39
  572. package/dist/sensor/response-operating-range.js.map +1 -1
  573. package/dist/sensor/responsivity-photocurrent.d.ts +21 -29
  574. package/dist/sensor/responsivity-photocurrent.js +57 -40
  575. package/dist/sensor/responsivity-photocurrent.js.map +1 -1
  576. package/dist/sensor/sampling-aperture.d.ts +21 -25
  577. package/dist/sensor/sampling-aperture.js +29 -28
  578. package/dist/sensor/sampling-aperture.js.map +1 -1
  579. package/dist/sensor/scene-eqe-temporal-exposure.d.ts +14 -12
  580. package/dist/sensor/scene-eqe-temporal-exposure.js +13 -8
  581. package/dist/sensor/scene-eqe-temporal-exposure.js.map +1 -1
  582. package/dist/sensor/sensor-geometry.d.ts +28 -32
  583. package/dist/sensor/sensor-geometry.js +35 -20
  584. package/dist/sensor/sensor-geometry.js.map +1 -1
  585. package/dist/sensor/signal-noise.d.ts +14 -16
  586. package/dist/sensor/signal-noise.js +15 -13
  587. package/dist/sensor/signal-noise.js.map +1 -1
  588. package/dist/sensor/spatial-sample-reduction.d.ts +45 -60
  589. package/dist/sensor/spatial-sample-reduction.js +39 -48
  590. package/dist/sensor/spatial-sample-reduction.js.map +1 -1
  591. package/dist/sensor/spatial-sampling-quadrature.d.ts +46 -54
  592. package/dist/sensor/spatial-sampling-quadrature.js +31 -36
  593. package/dist/sensor/spatial-sampling-quadrature.js.map +1 -1
  594. package/dist/sensor/spatio-spectral-reduction.d.ts +32 -42
  595. package/dist/sensor/spatio-spectral-reduction.js +24 -29
  596. package/dist/sensor/spatio-spectral-reduction.js.map +1 -1
  597. package/dist/sensor/spectral-coverage.d.ts +6 -9
  598. package/dist/sensor/spectral-coverage.js +9 -6
  599. package/dist/sensor/spectral-coverage.js.map +1 -1
  600. package/dist/sensor/spectral-quadrature.d.ts +46 -60
  601. package/dist/sensor/spectral-quadrature.js +38 -48
  602. package/dist/sensor/spectral-quadrature.js.map +1 -1
  603. package/dist/sensor/spectral-response.d.ts +53 -41
  604. package/dist/sensor/spectral-response.js +80 -47
  605. package/dist/sensor/spectral-response.js.map +1 -1
  606. package/dist/sensor/stochastic-seed.d.ts +50 -0
  607. package/dist/sensor/stochastic-seed.js +123 -0
  608. package/dist/sensor/stochastic-seed.js.map +1 -0
  609. package/dist/sensor/temporal-eqe-sum.d.ts +2 -4
  610. package/dist/sensor/temporal-eqe-sum.js +5 -6
  611. package/dist/sensor/temporal-eqe-sum.js.map +1 -1
  612. package/dist/sensor/temporal-photo-signal.d.ts +5 -6
  613. package/dist/sensor/temporal-photo-signal.js +11 -10
  614. package/dist/sensor/temporal-photo-signal.js.map +1 -1
  615. package/dist/sensor/temporal-sample-binding.d.ts +1 -2
  616. package/dist/sensor/temporal-sample-binding.js +3 -3
  617. package/dist/sensor/temporal-sample-binding.js.map +1 -1
  618. package/dist/simulation/poc-simulation.d.ts +16 -16
  619. package/dist/simulation/poc-simulation.js +20 -15
  620. package/dist/simulation/poc-simulation.js.map +1 -1
  621. package/dist/stabilization/camera-shake.d.ts +42 -18
  622. package/dist/stabilization/camera-shake.js +43 -20
  623. package/dist/stabilization/camera-shake.js.map +1 -1
  624. package/dist/stabilization/system.d.ts +44 -41
  625. package/dist/stabilization/system.js +196 -108
  626. package/dist/stabilization/system.js.map +1 -1
  627. package/docs/AGENT_GUIDE.md +183 -0
  628. package/docs/API_REFERENCE.md +777 -2
  629. package/docs/QUICK_START.md +663 -0
  630. package/docs/USAGE.md +1719 -714
  631. package/docs/api/camera-equivalent-focal-length.md +6 -7
  632. package/docs/api/camera-field-of-view.md +16 -8
  633. package/docs/api/camera-lens-projection.md +246 -0
  634. package/docs/api/camera-projected-object-size.md +6 -5
  635. package/docs/api/capture-capture-export-metadata.md +10 -10
  636. package/docs/api/capture-dng-import.md +134 -0
  637. package/docs/api/capture-environment-raw-producer.md +17 -11
  638. package/docs/api/capture-export-jpeg.md +16 -0
  639. package/docs/api/capture-focus-control.md +25 -47
  640. package/docs/api/capture-linear-encoding.md +21 -12
  641. package/docs/api/capture-lossless-jpeg.md +49 -0
  642. package/docs/api/capture-native-environment-optical-stage.md +75 -0
  643. package/docs/api/capture-native-environment-raw.md +161 -4
  644. package/docs/api/capture-native-raw-development.md +69 -8
  645. package/docs/api/capture-native-raw-dng.md +84 -0
  646. package/docs/api/capture-native-raw.md +21 -10
  647. package/docs/api/capture-packed-sensor-raw.md +156 -0
  648. package/docs/api/capture-photographic-export.md +69 -31
  649. package/docs/api/capture-raw-frame-reconstruction.md +8 -8
  650. package/docs/api/capture-raw-white-level.md +37 -0
  651. package/docs/api/capture-release-sequence.md +6 -7
  652. package/docs/api/capture-sensor-raw-frame.md +6 -6
  653. package/docs/api/capture-sensor-raw-producer.md +17 -11
  654. package/docs/api/capture-simulated-capture.md +15 -15
  655. package/docs/api/color-camera-color-matrix.md +103 -0
  656. package/docs/api/color-capture-color.md +22 -11
  657. package/docs/api/color-chromatic-adaptation.md +82 -0
  658. package/docs/api/color-color-difference.md +134 -0
  659. package/docs/api/color-color-matching-functions.md +259 -0
  660. package/docs/api/color-colorimetry-math.md +54 -0
  661. package/docs/api/color-gamut-mapping.md +72 -0
  662. package/docs/api/color-illuminants.md +280 -0
  663. package/docs/api/color-rgb-color-spaces.md +151 -0
  664. package/docs/api/color-sensor-color-development.md +27 -0
  665. package/docs/api/color-srgb-icc.md +2 -4
  666. package/docs/api/color-white-balance.md +95 -19
  667. package/docs/api/composition-image-formation-plan.md +124 -95
  668. package/docs/api/composition-plan-consumer.md +7 -7
  669. package/docs/api/core-calculation-result.md +18 -14
  670. package/docs/api/core-configuration-error.md +1 -1
  671. package/docs/api/core-image-formation.md +7 -7
  672. package/docs/api/core-scientific-assurance.md +12 -10
  673. package/docs/api/core-spectral-composition.md +14 -14
  674. package/docs/api/core-spectral.md +6 -6
  675. package/docs/api/core-validation.md +3 -3
  676. package/docs/api/core-version.md +7 -6
  677. package/docs/api/equipment-exposure-capabilities.md +11 -10
  678. package/docs/api/equipment-generic-tier-assets.md +7 -2
  679. package/docs/api/equipment-generic-tier-presets.md +6 -6
  680. package/docs/api/equipment-iso-capabilities.md +18 -18
  681. package/docs/api/equipment-metering-capabilities.md +6 -6
  682. package/docs/api/equipment-release-capabilities.md +4 -4
  683. package/docs/api/exports.json +2253 -3
  684. package/docs/api/exposure-exposure-duration-control.md +9 -9
  685. package/docs/api/exposure-exposure-mode-resolver.md +35 -31
  686. package/docs/api/exposure-exposure.md +10 -10
  687. package/docs/api/exposure-flash-ttl.md +182 -0
  688. package/docs/api/exposure-flash.md +183 -28
  689. package/docs/api/exposure-metering-scene-radiance.md +11 -10
  690. package/docs/api/exposure-metering-target.md +9 -8
  691. package/docs/api/exposure-metering-temporal.md +8 -8
  692. package/docs/api/exposure-metering.md +69 -9
  693. package/docs/api/exposure-program-line.md +6 -5
  694. package/docs/api/facade-chart-radiance-batch.md +96 -0
  695. package/docs/api/facade-chart-scenes.md +240 -0
  696. package/docs/api/facade-scene-radiance.md +122 -0
  697. package/docs/api/facade-simulate-capture.md +397 -0
  698. package/docs/api/gpu-image-kernel-accelerator.md +157 -0
  699. package/docs/api/gpu-image-kernel-execution.md +152 -0
  700. package/docs/api/motion-camera-rotation.md +43 -26
  701. package/docs/api/motion-capture-rotation-inverse-mapping.md +24 -23
  702. package/docs/api/motion-capture-rotation-temporal-quadrature.md +22 -22
  703. package/docs/api/motion-capture-rotation-trajectory.md +15 -15
  704. package/docs/api/motion-capture-translation-parallax-temporal-quadrature.md +15 -14
  705. package/docs/api/motion-extended-object-projection.md +10 -8
  706. package/docs/api/motion-projected-motion.md +8 -8
  707. package/docs/api/motion-temporal-exposure-sum.md +98 -0
  708. package/docs/api/motion-video-sequence.md +159 -0
  709. package/docs/api/optics-aperture.md +8 -8
  710. package/docs/api/optics-atmospheric-haze.md +104 -0
  711. package/docs/api/optics-brown-conrady-distortion.md +123 -0
  712. package/docs/api/optics-circle-of-confusion.md +5 -4
  713. package/docs/api/optics-complex-pupil-psf.md +57 -16
  714. package/docs/api/optics-depth-of-field.md +12 -6
  715. package/docs/api/optics-diffraction-psf-profile.md +96 -0
  716. package/docs/api/optics-diffraction.md +8 -7
  717. package/docs/api/optics-focus-breathing.md +104 -16
  718. package/docs/api/optics-focus-state.md +9 -10
  719. package/docs/api/optics-front-of-lens-filter.md +72 -14
  720. package/docs/api/optics-illumination-vignetting.md +10 -10
  721. package/docs/api/optics-irradiance-convolution.md +95 -0
  722. package/docs/api/optics-lateral-chromatic-aberration.md +22 -21
  723. package/docs/api/optics-lens-psf-kernels.md +72 -0
  724. package/docs/api/optics-lens-psf-profile.md +48 -26
  725. package/docs/api/optics-longitudinal-chromatic-aberration.md +128 -0
  726. package/docs/api/optics-polygon-diffraction.md +78 -13
  727. package/docs/api/optics-profile-contract.md +4 -4
  728. package/docs/api/optics-psf-foundation.md +12 -12
  729. package/docs/api/optics-pupil-vignetting.md +132 -0
  730. package/docs/api/optics-radial-distortion.md +12 -12
  731. package/docs/api/optics-scene-to-sensor-irradiance.md +25 -14
  732. package/docs/api/optics-scene-to-sensor-quadrature.md +15 -12
  733. package/docs/api/optics-sensor-aperture-rays.md +3 -2
  734. package/docs/api/optics-sensor-environment-query.md +52 -9
  735. package/docs/api/optics-sensor-psf-quadrature.md +13 -10
  736. package/docs/api/optics-stray-light.md +12 -11
  737. package/docs/api/optics-thin-lens.md +4 -3
  738. package/docs/api/optics-zernike-wavefront.md +229 -0
  739. package/docs/api/output-capture-corrected-sdr.md +10 -7
  740. package/docs/api/output-capture-geometry.md +35 -36
  741. package/docs/api/output-capture-sdr.md +4 -4
  742. package/docs/api/output-crop.md +7 -4
  743. package/docs/api/output-geometric-transforms.md +65 -19
  744. package/docs/api/output-lens-corrections.md +17 -15
  745. package/docs/api/output-native-capture-sdr.md +26 -13
  746. package/docs/api/output-png-encoder.md +105 -0
  747. package/docs/api/output-print-contrast-reference.md +8 -8
  748. package/docs/api/output-print-detail.md +14 -14
  749. package/docs/api/output-print-jpeg.md +22 -5
  750. package/docs/api/output-print-plan.md +18 -18
  751. package/docs/api/output-print-region-statistics.md +14 -14
  752. package/docs/api/output-sdr-rendering.md +52 -10
  753. package/docs/api/output-subject-framing-crop.md +5 -6
  754. package/docs/api/processing-demosaic.md +120 -0
  755. package/docs/api/processing-denoise.md +148 -0
  756. package/docs/api/processing-focus-stacking.md +41 -0
  757. package/docs/api/processing-hdr.md +113 -0
  758. package/docs/api/processing-panorama.md +82 -0
  759. package/docs/api/processing-processing-task.md +107 -0
  760. package/docs/api/processing-tone-mapping.md +142 -0
  761. package/docs/api/schema-camera.md +6 -4
  762. package/docs/api/schema-illumination-spectral.md +10 -11
  763. package/docs/api/schema-illumination-temporal.md +13 -15
  764. package/docs/api/schema-illumination.md +4 -4
  765. package/docs/api/schema-scene-radiance-temporal.md +10 -11
  766. package/docs/api/schema-scene-radiance.md +18 -17
  767. package/docs/api/schema-scene.md +9 -9
  768. package/docs/api/schema-validation.md +1 -1
  769. package/docs/api/sensor-accumulated-charge.md +12 -20
  770. package/docs/api/sensor-architecture.md +15 -16
  771. package/docs/api/sensor-camera-saturation-capacity.md +9 -11
  772. package/docs/api/sensor-capture-color-sampling-binding.md +47 -51
  773. package/docs/api/sensor-capture-mode-timing.md +9 -9
  774. package/docs/api/sensor-capture-mode.md +29 -30
  775. package/docs/api/sensor-color-sampling.md +31 -33
  776. package/docs/api/sensor-constant-rate-temporal-integration.md +10 -11
  777. package/docs/api/sensor-dark-current.md +30 -14
  778. package/docs/api/sensor-environment-photo-signal.md +13 -6
  779. package/docs/api/sensor-eqe-electron-rate.md +9 -8
  780. package/docs/api/sensor-eqe-local-exposure.md +18 -17
  781. package/docs/api/sensor-eqe-temporal-exposure.md +12 -11
  782. package/docs/api/sensor-exposure-window.md +24 -24
  783. package/docs/api/sensor-fixed-pattern-noise.md +104 -0
  784. package/docs/api/sensor-iso-gain.md +63 -0
  785. package/docs/api/sensor-iso-signal-chain.md +13 -22
  786. package/docs/api/sensor-local-exposure-binding.md +12 -13
  787. package/docs/api/sensor-optical-stack.md +37 -40
  788. package/docs/api/sensor-photon-energy.md +10 -11
  789. package/docs/api/sensor-physical-charge-capacity.md +8 -13
  790. package/docs/api/sensor-pixel-pitch.md +1 -1
  791. package/docs/api/sensor-radiometry-readiness.md +9 -9
  792. package/docs/api/sensor-raw-readout.md +118 -52
  793. package/docs/api/sensor-raw-reconstruction.md +97 -20
  794. package/docs/api/sensor-readout-exposure-linkage.md +120 -24
  795. package/docs/api/sensor-readout-timing.md +33 -35
  796. package/docs/api/sensor-response-application-compatibility.md +9 -11
  797. package/docs/api/sensor-response-operating-range.md +14 -18
  798. package/docs/api/sensor-responsivity-photocurrent.md +9 -12
  799. package/docs/api/sensor-sampling-aperture.md +22 -25
  800. package/docs/api/sensor-scene-eqe-temporal-exposure.md +9 -8
  801. package/docs/api/sensor-sensor-geometry.md +23 -24
  802. package/docs/api/sensor-signal-noise.md +10 -10
  803. package/docs/api/sensor-spatial-sample-reduction.md +27 -30
  804. package/docs/api/sensor-spatial-sampling-quadrature.md +37 -39
  805. package/docs/api/sensor-spatio-spectral-reduction.md +27 -29
  806. package/docs/api/sensor-spectral-coverage.md +5 -5
  807. package/docs/api/sensor-spectral-quadrature.md +33 -35
  808. package/docs/api/sensor-spectral-response.md +28 -16
  809. package/docs/api/sensor-temporal-photo-signal.md +6 -6
  810. package/docs/api/simulation-poc-simulation.md +17 -16
  811. package/docs/api/stabilization-camera-shake.md +29 -10
  812. package/docs/api/stabilization-system.md +25 -21
  813. package/docs/examples/production-request.json +3821 -2157
  814. package/docs/examples/simulate-capture.mjs +14 -0
  815. package/llms.txt +35 -0
  816. package/package.json +32 -11
  817. package/AGENTS.md +0 -674
  818. package/CONTRIBUTING.md +0 -76
  819. package/DCO +0 -33
  820. package/dist/camera/equivalent-focal-length.d.ts.map +0 -1
  821. package/dist/camera/field-of-view.d.ts.map +0 -1
  822. package/dist/camera/projected-object-size.d.ts.map +0 -1
  823. package/dist/capture/capture-export-metadata.d.ts.map +0 -1
  824. package/dist/capture/environment-raw-producer.d.ts.map +0 -1
  825. package/dist/capture/export-jpeg.d.ts.map +0 -1
  826. package/dist/capture/export-tiff.d.ts.map +0 -1
  827. package/dist/capture/focus-control.d.ts.map +0 -1
  828. package/dist/capture/linear-encoding.d.ts.map +0 -1
  829. package/dist/capture/native-environment-raw.d.ts.map +0 -1
  830. package/dist/capture/native-raw-development.d.ts.map +0 -1
  831. package/dist/capture/native-raw.d.ts.map +0 -1
  832. package/dist/capture/photographic-export.d.ts.map +0 -1
  833. package/dist/capture/raw-frame-limits.d.ts.map +0 -1
  834. package/dist/capture/raw-frame-reconstruction.d.ts.map +0 -1
  835. package/dist/capture/release-sequence.d.ts.map +0 -1
  836. package/dist/capture/sensor-raw-frame.d.ts.map +0 -1
  837. package/dist/capture/sensor-raw-producer.d.ts.map +0 -1
  838. package/dist/capture/simulated-capture.d.ts.map +0 -1
  839. package/dist/color/capture-color.d.ts.map +0 -1
  840. package/dist/color/sensor-color-development.d.ts.map +0 -1
  841. package/dist/color/srgb-icc.d.ts.map +0 -1
  842. package/dist/color/srgb-transfer.d.ts.map +0 -1
  843. package/dist/color/white-balance.d.ts.map +0 -1
  844. package/dist/composition/image-formation-plan.d.ts.map +0 -1
  845. package/dist/composition/plan-consumer.d.ts.map +0 -1
  846. package/dist/core/calculation-result.d.ts.map +0 -1
  847. package/dist/core/canonical-json.d.ts.map +0 -1
  848. package/dist/core/configuration-error.d.ts.map +0 -1
  849. package/dist/core/evidence-provenance.d.ts.map +0 -1
  850. package/dist/core/image-formation.d.ts.map +0 -1
  851. package/dist/core/owned-data.d.ts.map +0 -1
  852. package/dist/core/record-validation.d.ts.map +0 -1
  853. package/dist/core/scientific-assurance.d.ts.map +0 -1
  854. package/dist/core/spectral-composition.d.ts.map +0 -1
  855. package/dist/core/spectral.d.ts.map +0 -1
  856. package/dist/core/validation.d.ts.map +0 -1
  857. package/dist/core/version.d.ts.map +0 -1
  858. package/dist/equipment/exposure-capabilities.d.ts.map +0 -1
  859. package/dist/equipment/generic-tier-assets.d.ts.map +0 -1
  860. package/dist/equipment/generic-tier-presets.d.ts.map +0 -1
  861. package/dist/equipment/iso-capabilities.d.ts.map +0 -1
  862. package/dist/equipment/metering-capabilities.d.ts.map +0 -1
  863. package/dist/equipment/release-capabilities.d.ts.map +0 -1
  864. package/dist/exposure/exposure-duration-control.d.ts.map +0 -1
  865. package/dist/exposure/exposure-mode-resolver.d.ts.map +0 -1
  866. package/dist/exposure/exposure.d.ts.map +0 -1
  867. package/dist/exposure/flash.d.ts.map +0 -1
  868. package/dist/exposure/metering-scene-radiance.d.ts.map +0 -1
  869. package/dist/exposure/metering-target.d.ts.map +0 -1
  870. package/dist/exposure/metering-temporal.d.ts.map +0 -1
  871. package/dist/exposure/metering.d.ts.map +0 -1
  872. package/dist/exposure/program-line.d.ts.map +0 -1
  873. package/dist/index.d.ts.map +0 -1
  874. package/dist/motion/camera-rotation.d.ts.map +0 -1
  875. package/dist/motion/capture-rotation-inverse-mapping.d.ts.map +0 -1
  876. package/dist/motion/capture-rotation-temporal-quadrature.d.ts.map +0 -1
  877. package/dist/motion/capture-rotation-trajectory.d.ts.map +0 -1
  878. package/dist/motion/capture-translation-parallax-temporal-quadrature.d.ts.map +0 -1
  879. package/dist/motion/extended-object-projection.d.ts.map +0 -1
  880. package/dist/motion/projected-motion.d.ts.map +0 -1
  881. package/dist/optics/aperture.d.ts.map +0 -1
  882. package/dist/optics/circle-of-confusion.d.ts.map +0 -1
  883. package/dist/optics/complex-pupil-psf.d.ts.map +0 -1
  884. package/dist/optics/depth-of-field.d.ts.map +0 -1
  885. package/dist/optics/diffraction.d.ts.map +0 -1
  886. package/dist/optics/focus-breathing.d.ts.map +0 -1
  887. package/dist/optics/focus-state.d.ts.map +0 -1
  888. package/dist/optics/front-of-lens-filter.d.ts.map +0 -1
  889. package/dist/optics/illumination-vignetting.d.ts.map +0 -1
  890. package/dist/optics/lateral-chromatic-aberration.d.ts.map +0 -1
  891. package/dist/optics/lens-psf-profile.d.ts.map +0 -1
  892. package/dist/optics/polygon-diffraction.d.ts.map +0 -1
  893. package/dist/optics/profile-contract.d.ts.map +0 -1
  894. package/dist/optics/psf-foundation.d.ts.map +0 -1
  895. package/dist/optics/radial-distortion.d.ts.map +0 -1
  896. package/dist/optics/scene-to-sensor-irradiance.d.ts.map +0 -1
  897. package/dist/optics/scene-to-sensor-quadrature.d.ts.map +0 -1
  898. package/dist/optics/sensor-aperture-rays.d.ts.map +0 -1
  899. package/dist/optics/sensor-environment-query.d.ts.map +0 -1
  900. package/dist/optics/sensor-psf-quadrature.d.ts.map +0 -1
  901. package/dist/optics/sensor-psf-support.d.ts.map +0 -1
  902. package/dist/optics/stray-light.d.ts.map +0 -1
  903. package/dist/optics/thin-lens.d.ts.map +0 -1
  904. package/dist/output/capture-corrected-sdr.d.ts.map +0 -1
  905. package/dist/output/capture-geometry.d.ts.map +0 -1
  906. package/dist/output/capture-sdr.d.ts.map +0 -1
  907. package/dist/output/crop.d.ts.map +0 -1
  908. package/dist/output/geometric-transforms.d.ts.map +0 -1
  909. package/dist/output/lens-corrections.d.ts.map +0 -1
  910. package/dist/output/native-capture-sdr.d.ts.map +0 -1
  911. package/dist/output/print-contrast-reference.d.ts.map +0 -1
  912. package/dist/output/print-detail.d.ts.map +0 -1
  913. package/dist/output/print-jpeg.d.ts.map +0 -1
  914. package/dist/output/print-plan.d.ts.map +0 -1
  915. package/dist/output/print-region-statistics.d.ts.map +0 -1
  916. package/dist/output/sdr-rendering.d.ts.map +0 -1
  917. package/dist/output/subject-framing-crop.d.ts.map +0 -1
  918. package/dist/schema/camera.d.ts.map +0 -1
  919. package/dist/schema/camera.js +0 -3
  920. package/dist/schema/camera.js.map +0 -1
  921. package/dist/schema/illumination-spectral.d.ts.map +0 -1
  922. package/dist/schema/illumination-temporal.d.ts.map +0 -1
  923. package/dist/schema/illumination.d.ts.map +0 -1
  924. package/dist/schema/scene-radiance-temporal.d.ts.map +0 -1
  925. package/dist/schema/scene-radiance.d.ts.map +0 -1
  926. package/dist/schema/scene.d.ts.map +0 -1
  927. package/dist/schema/scene.js +0 -3
  928. package/dist/schema/scene.js.map +0 -1
  929. package/dist/schema/validation.d.ts.map +0 -1
  930. package/dist/sensor/accumulated-charge.d.ts.map +0 -1
  931. package/dist/sensor/architecture.d.ts.map +0 -1
  932. package/dist/sensor/camera-saturation-capacity.d.ts.map +0 -1
  933. package/dist/sensor/capture-color-sampling-binding.d.ts.map +0 -1
  934. package/dist/sensor/capture-mode-timing.d.ts.map +0 -1
  935. package/dist/sensor/capture-mode.d.ts.map +0 -1
  936. package/dist/sensor/color-sampling.d.ts.map +0 -1
  937. package/dist/sensor/constant-rate-temporal-integration.d.ts.map +0 -1
  938. package/dist/sensor/dark-current.d.ts.map +0 -1
  939. package/dist/sensor/environment-photo-signal.d.ts.map +0 -1
  940. package/dist/sensor/eqe-electron-rate.d.ts.map +0 -1
  941. package/dist/sensor/eqe-local-exposure.d.ts.map +0 -1
  942. package/dist/sensor/eqe-temporal-exposure.d.ts.map +0 -1
  943. package/dist/sensor/exposure-window.d.ts.map +0 -1
  944. package/dist/sensor/iso-signal-chain.d.ts.map +0 -1
  945. package/dist/sensor/local-exposure-binding.d.ts.map +0 -1
  946. package/dist/sensor/optical-stack.d.ts.map +0 -1
  947. package/dist/sensor/photon-energy.d.ts.map +0 -1
  948. package/dist/sensor/physical-charge-capacity.d.ts.map +0 -1
  949. package/dist/sensor/pixel-pitch.d.ts.map +0 -1
  950. package/dist/sensor/radiometry-readiness.d.ts.map +0 -1
  951. package/dist/sensor/raw-readout.d.ts.map +0 -1
  952. package/dist/sensor/raw-reconstruction.d.ts.map +0 -1
  953. package/dist/sensor/readout-exposure-linkage.d.ts.map +0 -1
  954. package/dist/sensor/readout-timing.d.ts.map +0 -1
  955. package/dist/sensor/response-application-compatibility.d.ts.map +0 -1
  956. package/dist/sensor/response-operating-range.d.ts.map +0 -1
  957. package/dist/sensor/responsivity-photocurrent.d.ts.map +0 -1
  958. package/dist/sensor/sampling-aperture.d.ts.map +0 -1
  959. package/dist/sensor/scene-eqe-temporal-exposure.d.ts.map +0 -1
  960. package/dist/sensor/sensor-geometry.d.ts.map +0 -1
  961. package/dist/sensor/signal-noise.d.ts.map +0 -1
  962. package/dist/sensor/spatial-sample-reduction.d.ts.map +0 -1
  963. package/dist/sensor/spatial-sampling-quadrature.d.ts.map +0 -1
  964. package/dist/sensor/spatio-spectral-reduction.d.ts.map +0 -1
  965. package/dist/sensor/spectral-coverage.d.ts.map +0 -1
  966. package/dist/sensor/spectral-quadrature.d.ts.map +0 -1
  967. package/dist/sensor/spectral-response.d.ts.map +0 -1
  968. package/dist/sensor/temporal-eqe-sum.d.ts.map +0 -1
  969. package/dist/sensor/temporal-photo-signal.d.ts.map +0 -1
  970. package/dist/sensor/temporal-sample-binding.d.ts.map +0 -1
  971. package/dist/simulation/poc-simulation.d.ts.map +0 -1
  972. package/dist/stabilization/camera-shake.d.ts.map +0 -1
  973. package/dist/stabilization/system.d.ts.map +0 -1
  974. package/docs/API_STYLE.md +0 -235
  975. package/docs/ARCHITECTURE.md +0 -356
  976. package/docs/AUTOMATION_COORDINATION.md +0 -190
  977. package/docs/CAPTURE_COLOR.md +0 -25
  978. package/docs/CAPTURE_CORRECTED_SDR.md +0 -25
  979. package/docs/CAPTURE_EXPORT_METADATA.md +0 -27
  980. package/docs/CAPTURE_SDR.md +0 -22
  981. package/docs/DENSE_PUPIL_QUALIFICATION.md +0 -121
  982. package/docs/DEVELOPERS.md +0 -68
  983. package/docs/DIGITAL_OPTICS_FOUNDATION.md +0 -69
  984. package/docs/ENVIRONMENT_RAW_CAPTURE.md +0 -208
  985. package/docs/EXPORT_ACCEPTANCE.md +0 -133
  986. package/docs/GENERIC_TIER_PRESETS.md +0 -269
  987. package/docs/GEOMETRIC_PREPARATION_REUSE.md +0 -141
  988. package/docs/IMAGE_FORMATION.md +0 -247
  989. package/docs/LINEAR_CAPTURE_ENCODING.md +0 -25
  990. package/docs/MOTION_AND_SIGNAL.md +0 -250
  991. package/docs/NATIVE_CAPTURE_SDR.md +0 -70
  992. package/docs/NATIVE_CAPTURE_SDR_REVIEW.md +0 -37
  993. package/docs/NATIVE_CAPTURE_SDR_VALIDATION.md +0 -34
  994. package/docs/NATIVE_RAW_AND_PRINT.md +0 -54
  995. package/docs/NUMERICAL_CORRECTNESS.md +0 -191
  996. package/docs/PERFORMANCE_BASELINE.md +0 -56
  997. package/docs/PHOTOGRAPHIC_EXPORT.md +0 -206
  998. package/docs/PHYSICS_FOUNDATION.md +0 -426
  999. package/docs/POC_API.md +0 -278
  1000. package/docs/POC_PROJECTION_PLATFORM_REFERENCE.md +0 -12
  1001. package/docs/POC_PROJECTION_REUSE.md +0 -124
  1002. package/docs/PRINT_195_196_REVIEW.md +0 -93
  1003. package/docs/PRINT_196_ENGINE_ACCEPTANCE.md +0 -45
  1004. package/docs/PRINT_CONTRAST_REFERENCE.md +0 -43
  1005. package/docs/PRINT_DETAIL_ASSESSMENT.md +0 -81
  1006. package/docs/PRINT_DETAIL_JPEG_EVIDENCE.md +0 -36
  1007. package/docs/PRINT_DETAIL_SDR_EVIDENCE.md +0 -29
  1008. package/docs/PRINT_DETAIL_VALIDATION.md +0 -36
  1009. package/docs/PRINT_PLANNING.md +0 -75
  1010. package/docs/PRINT_REGION_STATISTICS.md +0 -38
  1011. package/docs/PROCESSED_OUTPUT.md +0 -157
  1012. package/docs/PRODUCTION_COMPOSITION.md +0 -373
  1013. package/docs/PRODUCTION_ENVIRONMENT_CAPTURE.md +0 -131
  1014. package/docs/PROVENANCE.md +0 -115
  1015. package/docs/PSF_FOUNDATION.md +0 -165
  1016. package/docs/RAW_FRAME_ENVELOPE.md +0 -56
  1017. package/docs/RAW_FRAME_RECONSTRUCTION.md +0 -30
  1018. package/docs/RELEASE_1_0.md +0 -66
  1019. package/docs/RELEASE_1_0_1.md +0 -61
  1020. package/docs/RELEASE_1_1_0.md +0 -25
  1021. package/docs/RELEASE_1_2_0.md +0 -51
  1022. package/docs/RELEASE_1_3_0.md +0 -15
  1023. package/docs/RELEASE_1_4_0.md +0 -23
  1024. package/docs/RELEASE_1_5_0.md +0 -105
  1025. package/docs/RELEASE_AUDIT.md +0 -39
  1026. package/docs/SCENE_RADIANCE_AND_ILLUMINATION.md +0 -298
  1027. package/docs/SCENE_SENSOR_QUADRATURE.md +0 -98
  1028. package/docs/SCENE_SENSOR_TEMPORAL_EXPOSURE.md +0 -86
  1029. package/docs/SCIENTIFIC_ASSURANCE.md +0 -280
  1030. package/docs/SCIENTIFIC_CONFORMANCE.md +0 -83
  1031. package/docs/SDR_RENDERING.md +0 -33
  1032. package/docs/SENSOR_APERTURE_RAYS.md +0 -23
  1033. package/docs/SENSOR_ENVIRONMENT_QUERY.md +0 -86
  1034. package/docs/SENSOR_EQE_LOCAL_EXPOSURE.md +0 -104
  1035. package/docs/SENSOR_EQE_TEMPORAL_EXPOSURE.md +0 -74
  1036. package/docs/SENSOR_PSF_QUADRATURE.md +0 -90
  1037. package/docs/SENSOR_RAW_FRAME.md +0 -20
  1038. package/docs/SENSOR_RAW_PRODUCER.md +0 -77
  1039. package/docs/SEPARABLE_EMISSION_DRAFT.md +0 -103
  1040. package/docs/SIGNAL_CONFORMANCE.md +0 -23
  1041. package/docs/SIMULATED_CAPTURE.md +0 -65
  1042. package/docs/STABILIZATION.md +0 -234
  1043. package/docs/TEMPORAL_PHOTO_RAW.md +0 -83
  1044. package/docs/TIER_ACCEPTANCE.md +0 -129
  1045. package/docs/TIER_PRESET_ACCEPTANCE.md +0 -59
  1046. package/docs/V1_COMPOSITION_MAP.md +0 -123
  1047. package/docs/V1_HELPER_REUSE_REVIEW.md +0 -60
  1048. package/docs/V1_PERFORMANCE_DISPOSITION.md +0 -88
  1049. package/docs/benchmarks/2026-10-01-main-baseline.json +0 -694
  1050. package/docs/benchmarks/2026-10-02-geometric-preparation-reuse.json +0 -2190
  1051. package/docs/benchmarks/2026-10-02-poc-projection-reuse.json +0 -2423
  1052. package/docs/benchmarks/2026-10-02-v1-environment-gc-profile.json +0 -210
  1053. package/docs/benchmarks/2026-10-02-v1-environment-ordinary.json +0 -187
  1054. package/docs/benchmarks/2026-10-02-v1-geometry-gc-profile.json +0 -756
  1055. package/docs/benchmarks/2026-10-02-v1-geometry-ordinary-1.json +0 -711
  1056. package/docs/benchmarks/2026-10-02-v1-geometry-ordinary-2.json +0 -711
  1057. package/docs/benchmarks/2026-10-02-v1-poc-gc-profile.json +0 -885
  1058. package/docs/benchmarks/2026-10-02-v1-poc-ordinary-1.json +0 -868
  1059. package/docs/benchmarks/2026-10-02-v1-poc-ordinary-2.json +0 -868
  1060. package/docs/licenses/castleCSF-MIT.txt +0 -21
  1061. package/docs/validation/dense-pupil-2026-10-06/pilot.jsonl +0 -6
  1062. package/docs/validation/documentation-fragments.json +0 -212
  1063. package/docs/validation/native-capture-sdr-darwin-arm64-node26-review.jsonl +0 -4
  1064. package/docs/validation/native-capture-sdr-darwin-arm64.jsonl +0 -3
  1065. package/docs/validation/native-raw-print-2026-10-04/fractional-asymmetric-crop.jpg +0 -0
  1066. package/docs/validation/native-raw-print-2026-10-04/gray-ramp.jpg +0 -0
  1067. package/docs/validation/native-raw-print-2026-10-04/linear-area-checker.jpg +0 -0
  1068. package/docs/validation/native-raw-print-2026-10-04/manifest.json +0 -218
  1069. package/docs/validation/native-raw-print-2026-10-04/megapixel-native.jpg +0 -0
  1070. package/docs/validation/native-raw-print-2026-10-04/native-color.jpg +0 -0
  1071. package/docs/validation/native-raw-print-2026-10-04/photivra-native-full-megapixel-validation.json +0 -9
  1072. package/docs/validation/native-raw-print-2026-10-04/photivra-native-full-megapixel.json +0 -29
  1073. package/docs/validation/native-raw-print-2026-10-04/photivra-native-full-megapixel.json.codes.u16le.gz +0 -0
  1074. package/docs/validation/native-raw-print-2026-10-04/photivra-native-full-megapixel.json.jpg +0 -0
  1075. package/docs/validation/native-raw-print-2026-10-04/photivra-native-full-megapixel.json.rgb.gz +0 -0
  1076. package/docs/validation/native-raw-print-2026-10-04/srgb.icc +0 -0
  1077. package/docs/validation/native-raw-print-2026-10-04/validation.json +0 -41
  1078. package/docs/validation/print-196-candidate-capabilities.json +0 -28
  1079. package/docs/validation/print-196-candidate-evidence.json +0 -356
  1080. package/docs/validation/print-196-engine-acceptance.json +0 -81
  1081. package/docs/validation/print-detail-capabilities.json +0 -103
  1082. package/docs/validation/print-detail-jpeg-evidence.json +0 -116
  1083. package/docs/validation/print-detail-sdr-evidence.json +0 -81
  1084. package/docs/validation/release-audit-inventory.json +0 -1306
  1085. package/docs/validation/tier-acceptance-report-v1.json +0 -2538
@@ -0,0 +1,63 @@
1
+ /**
2
+ * Internal WebGPU device handling for the image-kernel accelerator: getting the adapter and device,
3
+ * limits, tracking device loss, racing work against abort and loss, error scopes, banded buffers and
4
+ * cleanup. Not exported from the package root. WebGPU types never appear in the published type
5
+ * declarations, so consumers do not need WebGPU typings.
6
+ */
7
+ import { ImageKernelExecutionError, type ImageKernelFallbackReason } from "./image-kernel-execution.js";
8
+ /** WebGPU spec constants (GPUBufferUsage, GPUMapMode), defined here so no global is needed at import time. */
9
+ export declare const BUFFER_USAGE: Readonly<{
10
+ MAP_READ: 1;
11
+ COPY_SRC: 4;
12
+ COPY_DST: 8;
13
+ UNIFORM: 64;
14
+ STORAGE: 128;
15
+ }>;
16
+ /** Minimum per-binding storage this backend requires (the WebGPU default is 128 MiB). */
17
+ export declare const WEBGPU_MINIMUM_STORAGE_BINDING_BYTES: number;
18
+ /** Upper limit requested from the adapter, so one band never asks for more than this per binding. */
19
+ export declare const WEBGPU_REQUESTED_STORAGE_BINDING_BYTES: number;
20
+ export interface WebGpuRuntime {
21
+ readonly device: GPUDevice;
22
+ readonly maximumStorageBindingBytes: number;
23
+ readonly maximumWorkgroupsPerDimension: number;
24
+ /** Set once `device.lost` settles; every later wait rejects with `device-lost`. */
25
+ isLost(): boolean;
26
+ /** Races a GPU promise with device loss and the operation's abort signal. */
27
+ guard<T>(promise: Promise<T>, signal: AbortSignal | undefined): Promise<T>;
28
+ destroy(): void;
29
+ }
30
+ export type WebGpuAcquisition = {
31
+ runtime: WebGpuRuntime;
32
+ } | {
33
+ failure: ImageKernelFallbackReason;
34
+ message: string;
35
+ };
36
+ export declare function abortedError(): ImageKernelExecutionError;
37
+ /**
38
+ * Requests a device with high limits from `gpu` (normally `navigator.gpu`). It does not throw when
39
+ * WebGPU is unavailable; the caller decides whether to fall back to the CPU or fail. An abort during
40
+ * acquisition does throw.
41
+ */
42
+ export declare function acquireWebGpuRuntime(gpu: unknown, powerPreference: "low-power" | "high-performance" | undefined, signal: AbortSignal | undefined): Promise<WebGpuAcquisition>;
43
+ /** Per-operation resource scope: every buffer is destroyed when the operation settles. */
44
+ export declare class GpuResourceScope {
45
+ #private;
46
+ constructor(runtime: WebGpuRuntime);
47
+ buffer(label: string, size: number, usage: number): GPUBuffer;
48
+ /** Storage buffer initialised from host data (padded to a 16-byte multiple). */
49
+ upload(label: string, data: ArrayBufferView<ArrayBuffer>, usage: number): GPUBuffer;
50
+ release(): void;
51
+ }
52
+ /** Workgroup grid for a 1-D invocation count (2-D when it exceeds one dimension). */
53
+ export declare function linearDispatch(invocations: number, workgroupSize: number, maximumPerDimension: number): [number, number];
54
+ /**
55
+ * Submits one compute pass and copies `outputs` into mappable staging buffers, then maps them. Validation
56
+ * and out-of-memory errors are captured with error scopes and reported as domain errors.
57
+ */
58
+ export declare function runComputePass(runtime: WebGpuRuntime, scope: GpuResourceScope, pipeline: GPUComputePipeline, bindGroup: GPUBindGroup, workgroups: readonly [number, number], outputs: readonly {
59
+ buffer: GPUBuffer;
60
+ bytes: number;
61
+ }[], signal: AbortSignal | undefined): Promise<ArrayBuffer[]>;
62
+ /** Compiles a compute pipeline; compilation/validation failures are domain errors. */
63
+ export declare function createComputePipeline(runtime: WebGpuRuntime, label: string, code: string, signal: AbortSignal | undefined): Promise<GPUComputePipeline>;
@@ -0,0 +1,215 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ /**
3
+ * Internal WebGPU device handling for the image-kernel accelerator: getting the adapter and device,
4
+ * limits, tracking device loss, racing work against abort and loss, error scopes, banded buffers and
5
+ * cleanup. Not exported from the package root. WebGPU types never appear in the published type
6
+ * declarations, so consumers do not need WebGPU typings.
7
+ */
8
+ import { ImageKernelExecutionError } from "./image-kernel-execution.js";
9
+ /** WebGPU spec constants (GPUBufferUsage, GPUMapMode), defined here so no global is needed at import time. */
10
+ export const BUFFER_USAGE = Object.freeze({ MAP_READ: 0x0001, COPY_SRC: 0x0004, COPY_DST: 0x0008, UNIFORM: 0x0040, STORAGE: 0x0080 });
11
+ const MAP_MODE_READ = 0x0001;
12
+ /** Minimum per-binding storage this backend requires (the WebGPU default is 128 MiB). */
13
+ export const WEBGPU_MINIMUM_STORAGE_BINDING_BYTES = 16 * 1024 * 1024;
14
+ /** Upper limit requested from the adapter, so one band never asks for more than this per binding. */
15
+ export const WEBGPU_REQUESTED_STORAGE_BINDING_BYTES = 1024 * 1024 * 1024;
16
+ function hostIsLittleEndian() {
17
+ return new Uint8Array(new Uint16Array([1]).buffer)[0] === 1;
18
+ }
19
+ export function abortedError() {
20
+ return new ImageKernelExecutionError("aborted", "Image-kernel execution was aborted; no output is available.");
21
+ }
22
+ /** Rejects when the signal aborts; the returned cleanup removes the listener. */
23
+ function abortRace(signal) {
24
+ if (!signal)
25
+ return { promise: new Promise(() => undefined), cleanup: () => undefined };
26
+ let cleanup = () => undefined;
27
+ const promise = new Promise((_, reject) => {
28
+ if (signal.aborted) {
29
+ reject(abortedError());
30
+ return;
31
+ }
32
+ const listener = () => reject(abortedError());
33
+ signal.addEventListener("abort", listener, { once: true });
34
+ cleanup = () => signal.removeEventListener("abort", listener);
35
+ });
36
+ promise.catch(() => undefined);
37
+ return { promise, cleanup };
38
+ }
39
+ /**
40
+ * Requests a device with high limits from `gpu` (normally `navigator.gpu`). It does not throw when
41
+ * WebGPU is unavailable; the caller decides whether to fall back to the CPU or fail. An abort during
42
+ * acquisition does throw.
43
+ */
44
+ export async function acquireWebGpuRuntime(gpu, powerPreference, signal) {
45
+ if (!hostIsLittleEndian())
46
+ return { failure: "unsupported-platform-endianness", message: "WebGPU buffers require a little-endian host." };
47
+ const api = gpu;
48
+ if (!api || typeof api !== "object" || typeof api.requestAdapter !== "function") {
49
+ return { failure: "webgpu-unavailable", message: "WebGPU is not available in this runtime." };
50
+ }
51
+ const abort = abortRace(signal);
52
+ try {
53
+ let adapter;
54
+ try {
55
+ adapter = await Promise.race([api.requestAdapter(powerPreference ? { powerPreference } : undefined), abort.promise]);
56
+ }
57
+ catch (error) {
58
+ if (error instanceof ImageKernelExecutionError)
59
+ throw error;
60
+ adapter = null;
61
+ }
62
+ if (!adapter)
63
+ return { failure: "adapter-unavailable", message: "No WebGPU adapter is available." };
64
+ const adapterStorage = adapter.limits.maxStorageBufferBindingSize, adapterBuffer = adapter.limits.maxBufferSize;
65
+ if (!(adapterStorage >= WEBGPU_MINIMUM_STORAGE_BINDING_BYTES && adapterBuffer >= WEBGPU_MINIMUM_STORAGE_BINDING_BYTES)) {
66
+ return { failure: "insufficient-limits", message: "The WebGPU adapter's storage-buffer limits are below the backend minimum." };
67
+ }
68
+ const storage = Math.min(adapterStorage, adapterBuffer, WEBGPU_REQUESTED_STORAGE_BINDING_BYTES);
69
+ let device, pending;
70
+ try {
71
+ pending = adapter.requestDevice({ label: "photivra-image-kernels",
72
+ requiredLimits: { maxStorageBufferBindingSize: storage, maxBufferSize: storage } });
73
+ device = await Promise.race([pending, abort.promise]);
74
+ }
75
+ catch (error) {
76
+ if (error instanceof ImageKernelExecutionError) {
77
+ // The abort won the race. A device that still arrives later is destroyed, so it never leaks.
78
+ if (pending)
79
+ void Promise.resolve(pending).then(late => late.destroy(), () => undefined);
80
+ throw error;
81
+ }
82
+ return { failure: "device-request-failed", message: "The WebGPU device request failed." };
83
+ }
84
+ if (signal?.aborted) {
85
+ device.destroy();
86
+ throw abortedError();
87
+ }
88
+ return { runtime: createRuntime(device, storage) };
89
+ }
90
+ finally {
91
+ abort.cleanup();
92
+ }
93
+ }
94
+ function createRuntime(device, storage) {
95
+ let lost = false, destroyed = false;
96
+ let rejectLost = () => undefined;
97
+ const lostPromise = new Promise((_, reject) => { rejectLost = reject; });
98
+ lostPromise.catch(() => undefined);
99
+ void device.lost.then(() => {
100
+ lost = true;
101
+ rejectLost(new ImageKernelExecutionError("device-lost", "The WebGPU device was lost; no output is available."));
102
+ });
103
+ // Errors are collected through error scopes; this only keeps uncaptured errors out of the console.
104
+ device.onuncapturederror = (event) => { event.preventDefault(); };
105
+ const maximumWorkgroupsPerDimension = device.limits.maxComputeWorkgroupsPerDimension;
106
+ return {
107
+ device,
108
+ maximumStorageBindingBytes: Math.min(storage, device.limits.maxStorageBufferBindingSize, device.limits.maxBufferSize),
109
+ maximumWorkgroupsPerDimension,
110
+ isLost: () => lost,
111
+ async guard(promise, signal) {
112
+ promise.catch(() => undefined);
113
+ if (lost)
114
+ throw new ImageKernelExecutionError("device-lost", "The WebGPU device was lost; no output is available.");
115
+ const abort = abortRace(signal);
116
+ try {
117
+ return await Promise.race([promise, lostPromise, abort.promise]);
118
+ }
119
+ finally {
120
+ abort.cleanup();
121
+ }
122
+ },
123
+ destroy() { if (!destroyed) {
124
+ destroyed = true;
125
+ device.destroy();
126
+ } }
127
+ };
128
+ }
129
+ /** Per-operation resource scope: every buffer is destroyed when the operation settles. */
130
+ export class GpuResourceScope {
131
+ #runtime;
132
+ #buffers = [];
133
+ constructor(runtime) { this.#runtime = runtime; }
134
+ buffer(label, size, usage) {
135
+ const buffer = this.#runtime.device.createBuffer({ label, size: Math.max(16, Math.ceil(size / 16) * 16), usage });
136
+ this.#buffers.push(buffer);
137
+ return buffer;
138
+ }
139
+ /** Storage buffer initialised from host data (padded to a 16-byte multiple). */
140
+ upload(label, data, usage) {
141
+ const buffer = this.buffer(label, data.byteLength, usage | BUFFER_USAGE.COPY_DST);
142
+ if (data.byteLength > 0)
143
+ this.#runtime.device.queue.writeBuffer(buffer, 0, data.buffer, data.byteOffset, data.byteLength);
144
+ return buffer;
145
+ }
146
+ release() {
147
+ for (const buffer of this.#buffers.splice(0))
148
+ buffer.destroy();
149
+ }
150
+ }
151
+ /** Workgroup grid for a 1-D invocation count (2-D when it exceeds one dimension). */
152
+ export function linearDispatch(invocations, workgroupSize, maximumPerDimension) {
153
+ const groups = Math.max(1, Math.ceil(invocations / workgroupSize));
154
+ const x = Math.min(groups, maximumPerDimension), y = Math.ceil(groups / x);
155
+ if (y > maximumPerDimension) {
156
+ throw new ImageKernelExecutionError("insufficient-limits", "Band exceeds the adapter's dispatch limits.");
157
+ }
158
+ return [x, y];
159
+ }
160
+ /**
161
+ * Submits one compute pass and copies `outputs` into mappable staging buffers, then maps them. Validation
162
+ * and out-of-memory errors are captured with error scopes and reported as domain errors.
163
+ */
164
+ export async function runComputePass(runtime, scope, pipeline, bindGroup, workgroups, outputs, signal) {
165
+ const device = runtime.device;
166
+ device.pushErrorScope("out-of-memory");
167
+ device.pushErrorScope("validation");
168
+ const staging = outputs.map(({ bytes }, i) => scope.buffer(`photivra-readback-${i}`, bytes, BUFFER_USAGE.MAP_READ | BUFFER_USAGE.COPY_DST));
169
+ const encoder = device.createCommandEncoder({ label: "photivra-image-kernel" });
170
+ const pass = encoder.beginComputePass();
171
+ pass.setPipeline(pipeline);
172
+ pass.setBindGroup(0, bindGroup);
173
+ pass.dispatchWorkgroups(workgroups[0], workgroups[1]);
174
+ pass.end();
175
+ outputs.forEach(({ buffer }, i) => encoder.copyBufferToBuffer(buffer, 0, staging[i], 0, staging[i].size));
176
+ device.queue.submit([encoder.finish()]);
177
+ // Pop both scopes before any await so an abort or loss never leaves the device's scope stack unbalanced.
178
+ const validationScope = device.popErrorScope(), memoryScope = device.popErrorScope();
179
+ const validation = await runtime.guard(validationScope, signal);
180
+ const memory = await runtime.guard(memoryScope, signal);
181
+ if (memory)
182
+ throw new ImageKernelExecutionError("out-of-memory", "The WebGPU device ran out of memory.");
183
+ if (validation)
184
+ throw new ImageKernelExecutionError("gpu-validation", "WebGPU rejected an image-kernel command.");
185
+ const results = [];
186
+ for (let i = 0; i < staging.length; i++) {
187
+ const buffer = staging[i];
188
+ await runtime.guard(buffer.mapAsync(MAP_MODE_READ), signal);
189
+ results.push(buffer.getMappedRange(0, Math.ceil(outputs[i].bytes / 4) * 4).slice(0));
190
+ buffer.unmap();
191
+ }
192
+ return results;
193
+ }
194
+ /** Compiles a compute pipeline; compilation/validation failures are domain errors. */
195
+ export async function createComputePipeline(runtime, label, code, signal) {
196
+ const device = runtime.device;
197
+ device.pushErrorScope("validation");
198
+ const module = device.createShaderModule({ label, code });
199
+ const pending = device.createComputePipelineAsync({ label, layout: "auto", compute: { module, entryPoint: "main" } });
200
+ const scope = device.popErrorScope();
201
+ let pipeline;
202
+ try {
203
+ pipeline = await runtime.guard(pending, signal);
204
+ }
205
+ catch (error) {
206
+ if (error instanceof ImageKernelExecutionError)
207
+ throw error;
208
+ throw new ImageKernelExecutionError("gpu-validation", `WebGPU could not compile the ${label} kernel.`);
209
+ }
210
+ if (await runtime.guard(scope, signal)) {
211
+ throw new ImageKernelExecutionError("gpu-validation", `WebGPU could not compile the ${label} kernel.`);
212
+ }
213
+ return pipeline;
214
+ }
215
+ //# sourceMappingURL=webgpu-runtime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webgpu-runtime.js","sourceRoot":"","sources":["../../src/gpu/webgpu-runtime.ts"],"names":[],"mappings":"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","sourcesContent":["// SPDX-License-Identifier: Apache-2.0\n\n/**\n * Internal WebGPU device handling for the image-kernel accelerator: getting the adapter and device,\n * limits, tracking device loss, racing work against abort and loss, error scopes, banded buffers and\n * cleanup. Not exported from the package root. WebGPU types never appear in the published type\n * declarations, so consumers do not need WebGPU typings.\n */\nimport { ImageKernelExecutionError, type ImageKernelFallbackReason } from \"./image-kernel-execution.js\";\n\n/** WebGPU spec constants (GPUBufferUsage, GPUMapMode), defined here so no global is needed at import time. */\nexport const BUFFER_USAGE = Object.freeze({ MAP_READ: 0x0001, COPY_SRC: 0x0004, COPY_DST: 0x0008, UNIFORM: 0x0040, STORAGE: 0x0080 });\nconst MAP_MODE_READ = 0x0001;\n\n/** Minimum per-binding storage this backend requires (the WebGPU default is 128 MiB). */\nexport const WEBGPU_MINIMUM_STORAGE_BINDING_BYTES = 16 * 1024 * 1024;\n/** Upper limit requested from the adapter, so one band never asks for more than this per binding. */\nexport const WEBGPU_REQUESTED_STORAGE_BINDING_BYTES = 1024 * 1024 * 1024;\n\nexport interface WebGpuRuntime {\n readonly device: GPUDevice;\n readonly maximumStorageBindingBytes: number;\n readonly maximumWorkgroupsPerDimension: number;\n /** Set once `device.lost` settles; every later wait rejects with `device-lost`. */\n isLost(): boolean;\n /** Races a GPU promise with device loss and the operation's abort signal. */\n guard<T>(promise: Promise<T>, signal: AbortSignal | undefined): Promise<T>;\n destroy(): void;\n}\n\nexport type WebGpuAcquisition = { runtime: WebGpuRuntime } | { failure: ImageKernelFallbackReason; message: string };\n\nfunction hostIsLittleEndian(): boolean {\n return new Uint8Array(new Uint16Array([1]).buffer)[0] === 1;\n}\n\nexport function abortedError(): ImageKernelExecutionError {\n return new ImageKernelExecutionError(\"aborted\", \"Image-kernel execution was aborted; no output is available.\");\n}\n\n/** Rejects when the signal aborts; the returned cleanup removes the listener. */\nfunction abortRace(signal: AbortSignal | undefined): { promise: Promise<never>; cleanup: () => void } {\n if (!signal) return { promise: new Promise<never>(() => undefined), cleanup: () => undefined };\n let cleanup = (): void => undefined;\n const promise = new Promise<never>((_, reject) => {\n if (signal.aborted) { reject(abortedError()); return; }\n const listener = (): void => reject(abortedError());\n signal.addEventListener(\"abort\", listener, { once: true });\n cleanup = (): void => signal.removeEventListener(\"abort\", listener);\n });\n promise.catch(() => undefined);\n return { promise, cleanup };\n}\n\n/**\n * Requests a device with high limits from `gpu` (normally `navigator.gpu`). It does not throw when\n * WebGPU is unavailable; the caller decides whether to fall back to the CPU or fail. An abort during\n * acquisition does throw.\n */\nexport async function acquireWebGpuRuntime(gpu: unknown, powerPreference: \"low-power\" | \"high-performance\" | undefined,\n signal: AbortSignal | undefined): Promise<WebGpuAcquisition> {\n if (!hostIsLittleEndian()) return { failure: \"unsupported-platform-endianness\", message: \"WebGPU buffers require a little-endian host.\" };\n const api = gpu as Partial<GPU> | null | undefined;\n if (!api || typeof api !== \"object\" || typeof api.requestAdapter !== \"function\") {\n return { failure: \"webgpu-unavailable\", message: \"WebGPU is not available in this runtime.\" };\n }\n const abort = abortRace(signal);\n try {\n let adapter: GPUAdapter | null;\n try {\n adapter = await Promise.race([api.requestAdapter(powerPreference ? { powerPreference } : undefined), abort.promise]);\n } catch (error) {\n if (error instanceof ImageKernelExecutionError) throw error;\n adapter = null;\n }\n if (!adapter) return { failure: \"adapter-unavailable\", message: \"No WebGPU adapter is available.\" };\n const adapterStorage = adapter.limits.maxStorageBufferBindingSize, adapterBuffer = adapter.limits.maxBufferSize;\n if (!(adapterStorage >= WEBGPU_MINIMUM_STORAGE_BINDING_BYTES && adapterBuffer >= WEBGPU_MINIMUM_STORAGE_BINDING_BYTES)) {\n return { failure: \"insufficient-limits\", message: \"The WebGPU adapter's storage-buffer limits are below the backend minimum.\" };\n }\n const storage = Math.min(adapterStorage, adapterBuffer, WEBGPU_REQUESTED_STORAGE_BINDING_BYTES);\n let device: GPUDevice, pending: Promise<GPUDevice> | undefined;\n try {\n pending = adapter.requestDevice({ label: \"photivra-image-kernels\",\n requiredLimits: { maxStorageBufferBindingSize: storage, maxBufferSize: storage } });\n device = await Promise.race([pending, abort.promise]);\n } catch (error) {\n if (error instanceof ImageKernelExecutionError) {\n // The abort won the race. A device that still arrives later is destroyed, so it never leaks.\n if (pending) void Promise.resolve(pending).then(late => late.destroy(), () => undefined);\n throw error;\n }\n return { failure: \"device-request-failed\", message: \"The WebGPU device request failed.\" };\n }\n if (signal?.aborted) { device.destroy(); throw abortedError(); }\n return { runtime: createRuntime(device, storage) };\n } finally {\n abort.cleanup();\n }\n}\n\nfunction createRuntime(device: GPUDevice, storage: number): WebGpuRuntime {\n let lost = false, destroyed = false;\n let rejectLost: (error: ImageKernelExecutionError) => void = () => undefined;\n const lostPromise = new Promise<never>((_, reject) => { rejectLost = reject; });\n lostPromise.catch(() => undefined);\n void device.lost.then(() => {\n lost = true;\n rejectLost(new ImageKernelExecutionError(\"device-lost\", \"The WebGPU device was lost; no output is available.\"));\n });\n // Errors are collected through error scopes; this only keeps uncaptured errors out of the console.\n device.onuncapturederror = (event: GPUUncapturedErrorEvent): void => { event.preventDefault(); };\n const maximumWorkgroupsPerDimension = device.limits.maxComputeWorkgroupsPerDimension;\n return {\n device,\n maximumStorageBindingBytes: Math.min(storage, device.limits.maxStorageBufferBindingSize, device.limits.maxBufferSize),\n maximumWorkgroupsPerDimension,\n isLost: (): boolean => lost,\n async guard<T>(promise: Promise<T>, signal: AbortSignal | undefined): Promise<T> {\n promise.catch(() => undefined);\n if (lost) throw new ImageKernelExecutionError(\"device-lost\", \"The WebGPU device was lost; no output is available.\");\n const abort = abortRace(signal);\n try { return await Promise.race([promise, lostPromise, abort.promise]); } finally { abort.cleanup(); }\n },\n destroy(): void { if (!destroyed) { destroyed = true; device.destroy(); } }\n };\n}\n\n/** Per-operation resource scope: every buffer is destroyed when the operation settles. */\nexport class GpuResourceScope {\n readonly #runtime: WebGpuRuntime;\n readonly #buffers: GPUBuffer[] = [];\n\n constructor(runtime: WebGpuRuntime) { this.#runtime = runtime; }\n\n buffer(label: string, size: number, usage: number): GPUBuffer {\n const buffer = this.#runtime.device.createBuffer({ label, size: Math.max(16, Math.ceil(size / 16) * 16), usage });\n this.#buffers.push(buffer);\n return buffer;\n }\n\n /** Storage buffer initialised from host data (padded to a 16-byte multiple). */\n upload(label: string, data: ArrayBufferView<ArrayBuffer>, usage: number): GPUBuffer {\n const buffer = this.buffer(label, data.byteLength, usage | BUFFER_USAGE.COPY_DST);\n if (data.byteLength > 0) this.#runtime.device.queue.writeBuffer(buffer, 0, data.buffer, data.byteOffset, data.byteLength);\n return buffer;\n }\n\n release(): void {\n for (const buffer of this.#buffers.splice(0)) buffer.destroy();\n }\n}\n\n/** Workgroup grid for a 1-D invocation count (2-D when it exceeds one dimension). */\nexport function linearDispatch(invocations: number, workgroupSize: number, maximumPerDimension: number): [number, number] {\n const groups = Math.max(1, Math.ceil(invocations / workgroupSize));\n const x = Math.min(groups, maximumPerDimension), y = Math.ceil(groups / x);\n if (y > maximumPerDimension) {\n throw new ImageKernelExecutionError(\"insufficient-limits\", \"Band exceeds the adapter's dispatch limits.\");\n }\n return [x, y];\n}\n\n/**\n * Submits one compute pass and copies `outputs` into mappable staging buffers, then maps them. Validation\n * and out-of-memory errors are captured with error scopes and reported as domain errors.\n */\nexport async function runComputePass(runtime: WebGpuRuntime, scope: GpuResourceScope, pipeline: GPUComputePipeline,\n bindGroup: GPUBindGroup, workgroups: readonly [number, number], outputs: readonly { buffer: GPUBuffer; bytes: number }[],\n signal: AbortSignal | undefined): Promise<ArrayBuffer[]> {\n const device = runtime.device;\n device.pushErrorScope(\"out-of-memory\");\n device.pushErrorScope(\"validation\");\n const staging = outputs.map(({ bytes }, i) =>\n scope.buffer(`photivra-readback-${i}`, bytes, BUFFER_USAGE.MAP_READ | BUFFER_USAGE.COPY_DST));\n const encoder = device.createCommandEncoder({ label: \"photivra-image-kernel\" });\n const pass = encoder.beginComputePass();\n pass.setPipeline(pipeline);\n pass.setBindGroup(0, bindGroup);\n pass.dispatchWorkgroups(workgroups[0], workgroups[1]);\n pass.end();\n outputs.forEach(({ buffer }, i) => encoder.copyBufferToBuffer(buffer, 0, staging[i]!, 0, staging[i]!.size));\n device.queue.submit([encoder.finish()]);\n // Pop both scopes before any await so an abort or loss never leaves the device's scope stack unbalanced.\n const validationScope = device.popErrorScope(), memoryScope = device.popErrorScope();\n const validation = await runtime.guard(validationScope, signal);\n const memory = await runtime.guard(memoryScope, signal);\n if (memory) throw new ImageKernelExecutionError(\"out-of-memory\", \"The WebGPU device ran out of memory.\");\n if (validation) throw new ImageKernelExecutionError(\"gpu-validation\", \"WebGPU rejected an image-kernel command.\");\n const results: ArrayBuffer[] = [];\n for (let i = 0; i < staging.length; i++) {\n const buffer = staging[i]!;\n await runtime.guard(buffer.mapAsync(MAP_MODE_READ), signal);\n results.push(buffer.getMappedRange(0, Math.ceil(outputs[i]!.bytes / 4) * 4).slice(0));\n buffer.unmap();\n }\n return results;\n}\n\n/** Compiles a compute pipeline; compilation/validation failures are domain errors. */\nexport async function createComputePipeline(runtime: WebGpuRuntime, label: string, code: string,\n signal: AbortSignal | undefined): Promise<GPUComputePipeline> {\n const device = runtime.device;\n device.pushErrorScope(\"validation\");\n const module = device.createShaderModule({ label, code });\n const pending = device.createComputePipelineAsync({ label, layout: \"auto\", compute: { module, entryPoint: \"main\" } });\n const scope = device.popErrorScope();\n let pipeline: GPUComputePipeline;\n try {\n pipeline = await runtime.guard(pending, signal);\n } catch (error) {\n if (error instanceof ImageKernelExecutionError) throw error;\n throw new ImageKernelExecutionError(\"gpu-validation\", `WebGPU could not compile the ${label} kernel.`);\n }\n if (await runtime.guard(scope, signal)) {\n throw new ImageKernelExecutionError(\"gpu-validation\", `WebGPU could not compile the ${label} kernel.`);\n }\n return pipeline;\n}\n"]}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * WGSL kernel for the `webgpu-f32` chart-radiance stage (#277), one invocation per query point. It
3
+ * evaluates the chart's material classification (`resolveChartScene().materialAt`) in float32 and looks up
4
+ * the material's value in a table the host computed in float64 with the reference's own operations.
5
+ *
6
+ * Every classification decision (half-plane, disk, sector, cell and gap boundaries) is evaluated with an
7
+ * a-priori bound on how far the float32 decision value can be from the float64 reference value: the
8
+ * point's float32 rounding, each float32 operation (u = 2^-24, correctly rounded + − ×), the float32
9
+ * rounding of the constants and the reference's own float64 rounding. A point whose decision value lies
10
+ * within four times its bound is flagged, and the host recomputes it with the reference. So every
11
+ * unflagged point has exactly the reference's material, and its value is the reference value rounded
12
+ * once to float32.
13
+ *
14
+ * Siemens-star sectors are found from a rough `atan2` (any accuracy) and then decided exactly by the
15
+ * signs of cross products with the sector boundary directions, so WGSL's 4096-ULP `atan2` bound does not
16
+ * enter. See docs/WEBGPU.md, "Scene radiance on the GPU".
17
+ */
18
+ export declare const CHART_WORKGROUP_SIZE = 256;
19
+ /** Preset codes of `Params.preset`, in `CHART_SCENE_PRESETS` order. */
20
+ export declare const CHART_PRESET_CODE: Readonly<{
21
+ readonly uniform: 0;
22
+ readonly "slanted-edge": 1;
23
+ readonly "siemens-star": 2;
24
+ readonly "step-wedge": 3;
25
+ readonly "grey-ramp": 4;
26
+ readonly checkerboard: 5;
27
+ readonly "point-grid": 6;
28
+ readonly patches: 7;
29
+ }>;
30
+ export declare const CHART_RADIANCE_WGSL = "\nconst U: f32 = 5.9604644775390625e-8;\nconst SAFETY: f32 = 4.0;\nconst SLACK: f32 = 1e-14;\nconst PI: f32 = 3.14159265358979;\nstruct Params {\n count: u32, columns: u32, preset: u32, na: u32,\n nb: u32, nc: u32, wavelength_mode: u32, pad0: u32,\n f0: f32, f1: f32, f2: f32, f3: f32,\n f4: f32, f5: f32, f6: f32, f7: f32,\n};\n@group(0) @binding(0) var<uniform> params: Params;\n@group(0) @binding(1) var<storage, read> points: array<vec2<f32>>;\n@group(0) @binding(2) var<storage, read> table: array<f32>;\n@group(0) @binding(3) var<storage, read> aux: array<f32>;\n@group(0) @binding(4) var<storage, read> selectors: array<u32>;\n@group(0) @binding(5) var<storage, read_write> values: array<f32>;\n@group(0) @binding(6) var<storage, read_write> flags: array<u32>;\n\nvar<private> flagged: bool;\nfn check(distance: f32, bound: f32) { if (!(abs(distance) > SAFETY * bound)) { flagged = true; } }\n// Flags t when it lies within the bound of an integer n with lo <= n <= hi.\nfn check_integer(t: f32, bound: f32, lo: f32, hi: f32) {\n let n = round(t);\n if (SAFETY * bound >= 0.5) { flagged = true; return; }\n if (n >= lo && n <= hi) { check(t - n, bound); }\n}\n// x = (a + b) * scale, with the bound of its distance from the float64 reference value.\nfn scaled_sum_bound(a: f32, b: f32, s: f32, scale: f32, x: f32, constant_rounding: f32) -> f32 {\n return U * ((abs(a) + abs(b) + abs(s)) * abs(scale) + (1.0 + constant_rounding) * abs(x)) + SLACK * (abs(x) + 1.0);\n}\nfn cross_d(u: f32, v: f32, k: u32) -> f32 { return v * aux[2u * k] - u * aux[2u * k + 1u]; }\nfn cross_bound(u: f32, v: f32, k: u32, d: f32) -> f32 {\n return U * (3.0 * abs(v * aux[2u * k]) + 3.0 * abs(u * aux[2u * k + 1u]) + abs(d)) + SLACK * (abs(u) + abs(v));\n}\nfn material(p: vec2<f32>) -> u32 {\n let u = p.x;\n let v = p.y;\n switch (params.preset) {\n case 0u: { return 0u; }\n case 1u: {\n // Light where u\u00B7cos t \u2212 v\u00B7sin t \u2265 0.\n let a = u * params.f0;\n let b = v * params.f1;\n let d = a - b;\n check(d, U * (3.0 * abs(a) + 3.0 * abs(b) + abs(d)) + SLACK * (abs(u) + abs(v)));\n return select(0u, 1u, d >= 0.0);\n }\n case 2u: {\n let uu = u * u;\n let vv = v * v;\n let q = uu + vv;\n check(q - params.f0, U * (4.0 * q + 2.0 * params.f0) + SLACK * (q + params.f0));\n if (q > params.f0) { return 2u; }\n let sectors = 2u * params.na;\n var k = u32(clamp(floor((atan2(v, u) + PI) * f32(params.na) / PI), 0.0, f32(sectors - 1u)));\n for (var step = 0u; step < 4u; step++) {\n if (cross_d(u, v, k) < 0.0 && k > 0u) { k = k - 1u; continue; }\n if (cross_d(u, v, k + 1u) >= 0.0 && k + 1u < sectors) { k = k + 1u; continue; }\n break;\n }\n let lo = cross_d(u, v, k);\n let hi = cross_d(u, v, k + 1u);\n if (lo < 0.0 || hi >= 0.0) { flagged = true; }\n check(lo, cross_bound(u, v, k, lo));\n check(hi, cross_bound(u, v, k + 1u, hi));\n return select(0u, 1u, k % 2u == 0u);\n }\n case 3u, 4u: {\n let s = u + 1.0;\n let t = s * params.f0;\n check_integer(t, scaled_sum_bound(u, 1.0, s, params.f0, t, 0.0), 1.0, f32(params.na - 1u));\n return u32(clamp(floor(t), 0.0, f32(params.na - 1u)));\n }\n case 5u: {\n let s = u + 1.0;\n let x = s * params.f0;\n let w = params.f1 - v;\n let y = w * params.f0;\n check_integer(x, scaled_sum_bound(u, 1.0, s, params.f0, x, 0.0), -3.0e38, 3.0e38);\n check_integer(y, scaled_sum_bound(params.f1, v, w, params.f0, y, 0.0), -3.0e38, 3.0e38);\n let i = i32(floor(x));\n let j = i32(floor(y));\n return select(0u, 1u, (i + j) % 2 == 0);\n }\n case 6u: {\n let s = u + 1.0;\n let x = s * params.f0;\n let w = params.f1 - v;\n let y = w * params.f2;\n check_integer(x, scaled_sum_bound(u, 1.0, s, params.f0, x, 0.0), 1.0, f32(params.na - 1u));\n check_integer(y, scaled_sum_bound(params.f1, v, w, params.f2, y, 1.0), 1.0, f32(params.nb - 1u));\n let i = u32(clamp(floor(x), 0.0, f32(params.na - 1u)));\n let j = u32(clamp(floor(y), 0.0, f32(params.nb - 1u)));\n let c = j * params.na + i;\n let dx = u - aux[2u * c];\n let dy = v - aux[2u * c + 1u];\n let ex = U * (abs(u) + abs(aux[2u * c]) + abs(dx));\n let ey = U * (abs(v) + abs(aux[2u * c + 1u]) + abs(dy));\n let d2 = dx * dx + dy * dy;\n check(d2 - params.f3, 2.0 * (abs(dx) * ex + abs(dy) * ey) + ex * ex + ey * ey + U * (2.0 * d2 + params.f3) + SLACK * (d2 + params.f3));\n return select(0u, 1u, d2 <= params.f3);\n }\n default: {\n let s = u + 1.0;\n let fx = s * params.f0;\n let w = params.f1 - v;\n let fy = w * params.f2;\n let bx = scaled_sum_bound(u, 1.0, s, params.f0, fx, 0.0);\n let by = scaled_sum_bound(params.f1, v, w, params.f2, fy, 1.0);\n check_integer(fx, bx, -3.0e38, 3.0e38);\n check_integer(fy, by, -3.0e38, 3.0e38);\n let background = params.nc;\n let ifx = floor(fx);\n let ify = floor(fy);\n if (ifx < 0.0 || ify < 0.0 || ifx >= f32(params.na) || ify >= f32(params.nb)) { return background; }\n let index = u32(ify) * params.na + u32(ifx);\n let x = fx - ifx;\n let y = fy - ify;\n check(x - params.f3, bx + U * params.f3);\n check(x - params.f4, bx + U * params.f4);\n check(y - params.f3, by + U * params.f3);\n check(y - params.f4, by + U * params.f4);\n if (index >= params.nc || x < params.f3 || x > params.f4 || y < params.f3 || y > params.f4) { return background; }\n return index;\n }\n }\n}\n@compute @workgroup_size(256)\nfn main(@builtin(global_invocation_id) gid: vec3<u32>, @builtin(num_workgroups) groups: vec3<u32>) {\n let i = gid.x + gid.y * groups.x * 256u;\n if (i >= params.count) { return; }\n flagged = false;\n let m = material(points[i]);\n if (params.wavelength_mode != 0u) {\n values[i] = table[m * params.columns + selectors[i]];\n } else {\n for (var c = 0u; c < params.columns; c++) { values[i * params.columns + c] = table[m * params.columns + c]; }\n }\n flags[i] = select(0u, 1u, flagged);\n}\n";
@@ -0,0 +1,165 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ /**
3
+ * WGSL kernel for the `webgpu-f32` chart-radiance stage (#277), one invocation per query point. It
4
+ * evaluates the chart's material classification (`resolveChartScene().materialAt`) in float32 and looks up
5
+ * the material's value in a table the host computed in float64 with the reference's own operations.
6
+ *
7
+ * Every classification decision (half-plane, disk, sector, cell and gap boundaries) is evaluated with an
8
+ * a-priori bound on how far the float32 decision value can be from the float64 reference value: the
9
+ * point's float32 rounding, each float32 operation (u = 2^-24, correctly rounded + − ×), the float32
10
+ * rounding of the constants and the reference's own float64 rounding. A point whose decision value lies
11
+ * within four times its bound is flagged, and the host recomputes it with the reference. So every
12
+ * unflagged point has exactly the reference's material, and its value is the reference value rounded
13
+ * once to float32.
14
+ *
15
+ * Siemens-star sectors are found from a rough `atan2` (any accuracy) and then decided exactly by the
16
+ * signs of cross products with the sector boundary directions, so WGSL's 4096-ULP `atan2` bound does not
17
+ * enter. See docs/WEBGPU.md, "Scene radiance on the GPU".
18
+ */
19
+ export const CHART_WORKGROUP_SIZE = 256;
20
+ /** Preset codes of `Params.preset`, in `CHART_SCENE_PRESETS` order. */
21
+ export const CHART_PRESET_CODE = Object.freeze({ uniform: 0, "slanted-edge": 1, "siemens-star": 2, "step-wedge": 3, "grey-ramp": 4, checkerboard: 5,
22
+ "point-grid": 6, patches: 7 });
23
+ export const CHART_RADIANCE_WGSL = /* wgsl */ `
24
+ const U: f32 = 5.9604644775390625e-8;
25
+ const SAFETY: f32 = 4.0;
26
+ const SLACK: f32 = 1e-14;
27
+ const PI: f32 = 3.14159265358979;
28
+ struct Params {
29
+ count: u32, columns: u32, preset: u32, na: u32,
30
+ nb: u32, nc: u32, wavelength_mode: u32, pad0: u32,
31
+ f0: f32, f1: f32, f2: f32, f3: f32,
32
+ f4: f32, f5: f32, f6: f32, f7: f32,
33
+ };
34
+ @group(0) @binding(0) var<uniform> params: Params;
35
+ @group(0) @binding(1) var<storage, read> points: array<vec2<f32>>;
36
+ @group(0) @binding(2) var<storage, read> table: array<f32>;
37
+ @group(0) @binding(3) var<storage, read> aux: array<f32>;
38
+ @group(0) @binding(4) var<storage, read> selectors: array<u32>;
39
+ @group(0) @binding(5) var<storage, read_write> values: array<f32>;
40
+ @group(0) @binding(6) var<storage, read_write> flags: array<u32>;
41
+
42
+ var<private> flagged: bool;
43
+ fn check(distance: f32, bound: f32) { if (!(abs(distance) > SAFETY * bound)) { flagged = true; } }
44
+ // Flags t when it lies within the bound of an integer n with lo <= n <= hi.
45
+ fn check_integer(t: f32, bound: f32, lo: f32, hi: f32) {
46
+ let n = round(t);
47
+ if (SAFETY * bound >= 0.5) { flagged = true; return; }
48
+ if (n >= lo && n <= hi) { check(t - n, bound); }
49
+ }
50
+ // x = (a + b) * scale, with the bound of its distance from the float64 reference value.
51
+ fn scaled_sum_bound(a: f32, b: f32, s: f32, scale: f32, x: f32, constant_rounding: f32) -> f32 {
52
+ return U * ((abs(a) + abs(b) + abs(s)) * abs(scale) + (1.0 + constant_rounding) * abs(x)) + SLACK * (abs(x) + 1.0);
53
+ }
54
+ fn cross_d(u: f32, v: f32, k: u32) -> f32 { return v * aux[2u * k] - u * aux[2u * k + 1u]; }
55
+ fn cross_bound(u: f32, v: f32, k: u32, d: f32) -> f32 {
56
+ return U * (3.0 * abs(v * aux[2u * k]) + 3.0 * abs(u * aux[2u * k + 1u]) + abs(d)) + SLACK * (abs(u) + abs(v));
57
+ }
58
+ fn material(p: vec2<f32>) -> u32 {
59
+ let u = p.x;
60
+ let v = p.y;
61
+ switch (params.preset) {
62
+ case 0u: { return 0u; }
63
+ case 1u: {
64
+ // Light where u·cos t − v·sin t ≥ 0.
65
+ let a = u * params.f0;
66
+ let b = v * params.f1;
67
+ let d = a - b;
68
+ check(d, U * (3.0 * abs(a) + 3.0 * abs(b) + abs(d)) + SLACK * (abs(u) + abs(v)));
69
+ return select(0u, 1u, d >= 0.0);
70
+ }
71
+ case 2u: {
72
+ let uu = u * u;
73
+ let vv = v * v;
74
+ let q = uu + vv;
75
+ check(q - params.f0, U * (4.0 * q + 2.0 * params.f0) + SLACK * (q + params.f0));
76
+ if (q > params.f0) { return 2u; }
77
+ let sectors = 2u * params.na;
78
+ var k = u32(clamp(floor((atan2(v, u) + PI) * f32(params.na) / PI), 0.0, f32(sectors - 1u)));
79
+ for (var step = 0u; step < 4u; step++) {
80
+ if (cross_d(u, v, k) < 0.0 && k > 0u) { k = k - 1u; continue; }
81
+ if (cross_d(u, v, k + 1u) >= 0.0 && k + 1u < sectors) { k = k + 1u; continue; }
82
+ break;
83
+ }
84
+ let lo = cross_d(u, v, k);
85
+ let hi = cross_d(u, v, k + 1u);
86
+ if (lo < 0.0 || hi >= 0.0) { flagged = true; }
87
+ check(lo, cross_bound(u, v, k, lo));
88
+ check(hi, cross_bound(u, v, k + 1u, hi));
89
+ return select(0u, 1u, k % 2u == 0u);
90
+ }
91
+ case 3u, 4u: {
92
+ let s = u + 1.0;
93
+ let t = s * params.f0;
94
+ check_integer(t, scaled_sum_bound(u, 1.0, s, params.f0, t, 0.0), 1.0, f32(params.na - 1u));
95
+ return u32(clamp(floor(t), 0.0, f32(params.na - 1u)));
96
+ }
97
+ case 5u: {
98
+ let s = u + 1.0;
99
+ let x = s * params.f0;
100
+ let w = params.f1 - v;
101
+ let y = w * params.f0;
102
+ check_integer(x, scaled_sum_bound(u, 1.0, s, params.f0, x, 0.0), -3.0e38, 3.0e38);
103
+ check_integer(y, scaled_sum_bound(params.f1, v, w, params.f0, y, 0.0), -3.0e38, 3.0e38);
104
+ let i = i32(floor(x));
105
+ let j = i32(floor(y));
106
+ return select(0u, 1u, (i + j) % 2 == 0);
107
+ }
108
+ case 6u: {
109
+ let s = u + 1.0;
110
+ let x = s * params.f0;
111
+ let w = params.f1 - v;
112
+ let y = w * params.f2;
113
+ check_integer(x, scaled_sum_bound(u, 1.0, s, params.f0, x, 0.0), 1.0, f32(params.na - 1u));
114
+ check_integer(y, scaled_sum_bound(params.f1, v, w, params.f2, y, 1.0), 1.0, f32(params.nb - 1u));
115
+ let i = u32(clamp(floor(x), 0.0, f32(params.na - 1u)));
116
+ let j = u32(clamp(floor(y), 0.0, f32(params.nb - 1u)));
117
+ let c = j * params.na + i;
118
+ let dx = u - aux[2u * c];
119
+ let dy = v - aux[2u * c + 1u];
120
+ let ex = U * (abs(u) + abs(aux[2u * c]) + abs(dx));
121
+ let ey = U * (abs(v) + abs(aux[2u * c + 1u]) + abs(dy));
122
+ let d2 = dx * dx + dy * dy;
123
+ check(d2 - params.f3, 2.0 * (abs(dx) * ex + abs(dy) * ey) + ex * ex + ey * ey + U * (2.0 * d2 + params.f3) + SLACK * (d2 + params.f3));
124
+ return select(0u, 1u, d2 <= params.f3);
125
+ }
126
+ default: {
127
+ let s = u + 1.0;
128
+ let fx = s * params.f0;
129
+ let w = params.f1 - v;
130
+ let fy = w * params.f2;
131
+ let bx = scaled_sum_bound(u, 1.0, s, params.f0, fx, 0.0);
132
+ let by = scaled_sum_bound(params.f1, v, w, params.f2, fy, 1.0);
133
+ check_integer(fx, bx, -3.0e38, 3.0e38);
134
+ check_integer(fy, by, -3.0e38, 3.0e38);
135
+ let background = params.nc;
136
+ let ifx = floor(fx);
137
+ let ify = floor(fy);
138
+ if (ifx < 0.0 || ify < 0.0 || ifx >= f32(params.na) || ify >= f32(params.nb)) { return background; }
139
+ let index = u32(ify) * params.na + u32(ifx);
140
+ let x = fx - ifx;
141
+ let y = fy - ify;
142
+ check(x - params.f3, bx + U * params.f3);
143
+ check(x - params.f4, bx + U * params.f4);
144
+ check(y - params.f3, by + U * params.f3);
145
+ check(y - params.f4, by + U * params.f4);
146
+ if (index >= params.nc || x < params.f3 || x > params.f4 || y < params.f3 || y > params.f4) { return background; }
147
+ return index;
148
+ }
149
+ }
150
+ }
151
+ @compute @workgroup_size(${CHART_WORKGROUP_SIZE})
152
+ fn main(@builtin(global_invocation_id) gid: vec3<u32>, @builtin(num_workgroups) groups: vec3<u32>) {
153
+ let i = gid.x + gid.y * groups.x * ${CHART_WORKGROUP_SIZE}u;
154
+ if (i >= params.count) { return; }
155
+ flagged = false;
156
+ let m = material(points[i]);
157
+ if (params.wavelength_mode != 0u) {
158
+ values[i] = table[m * params.columns + selectors[i]];
159
+ } else {
160
+ for (var c = 0u; c < params.columns; c++) { values[i * params.columns + c] = table[m * params.columns + c]; }
161
+ }
162
+ flags[i] = select(0u, 1u, flagged);
163
+ }
164
+ `;
165
+ //# sourceMappingURL=wgsl-chart-kernel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wgsl-chart-kernel.js","sourceRoot":"","sources":["../../src/gpu/wgsl-chart-kernel.ts"],"names":[],"mappings":"AAAA,sCAAsC;AAEtC;;;;;;;;;;;;;;;;GAgBG;AAEH,MAAM,CAAC,MAAM,oBAAoB,GAAG,GAAG,CAAC;AACxC,uEAAuE;AACvE,MAAM,CAAC,MAAM,iBAAiB,GAAG,MAAM,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,cAAc,EAAE,CAAC,EAAE,cAAc,EAAE,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,YAAY,EAAE,CAAC;IACjJ,YAAY,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAW,CAAC,CAAC;AAE1C,MAAM,CAAC,MAAM,mBAAmB,GAAG,UAAU,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2BAgInB,oBAAoB;;uCAER,oBAAoB;;;;;;;;;;;CAW1D,CAAC","sourcesContent":["// SPDX-License-Identifier: Apache-2.0\n\n/**\n * WGSL kernel for the `webgpu-f32` chart-radiance stage (#277), one invocation per query point. It\n * evaluates the chart's material classification (`resolveChartScene().materialAt`) in float32 and looks up\n * the material's value in a table the host computed in float64 with the reference's own operations.\n *\n * Every classification decision (half-plane, disk, sector, cell and gap boundaries) is evaluated with an\n * a-priori bound on how far the float32 decision value can be from the float64 reference value: the\n * point's float32 rounding, each float32 operation (u = 2^-24, correctly rounded + − ×), the float32\n * rounding of the constants and the reference's own float64 rounding. A point whose decision value lies\n * within four times its bound is flagged, and the host recomputes it with the reference. So every\n * unflagged point has exactly the reference's material, and its value is the reference value rounded\n * once to float32.\n *\n * Siemens-star sectors are found from a rough `atan2` (any accuracy) and then decided exactly by the\n * signs of cross products with the sector boundary directions, so WGSL's 4096-ULP `atan2` bound does not\n * enter. See docs/WEBGPU.md, \"Scene radiance on the GPU\".\n */\n\nexport const CHART_WORKGROUP_SIZE = 256;\n/** Preset codes of `Params.preset`, in `CHART_SCENE_PRESETS` order. */\nexport const CHART_PRESET_CODE = Object.freeze({ uniform: 0, \"slanted-edge\": 1, \"siemens-star\": 2, \"step-wedge\": 3, \"grey-ramp\": 4, checkerboard: 5,\n \"point-grid\": 6, patches: 7 } as const);\n\nexport const CHART_RADIANCE_WGSL = /* wgsl */ `\nconst U: f32 = 5.9604644775390625e-8;\nconst SAFETY: f32 = 4.0;\nconst SLACK: f32 = 1e-14;\nconst PI: f32 = 3.14159265358979;\nstruct Params {\n count: u32, columns: u32, preset: u32, na: u32,\n nb: u32, nc: u32, wavelength_mode: u32, pad0: u32,\n f0: f32, f1: f32, f2: f32, f3: f32,\n f4: f32, f5: f32, f6: f32, f7: f32,\n};\n@group(0) @binding(0) var<uniform> params: Params;\n@group(0) @binding(1) var<storage, read> points: array<vec2<f32>>;\n@group(0) @binding(2) var<storage, read> table: array<f32>;\n@group(0) @binding(3) var<storage, read> aux: array<f32>;\n@group(0) @binding(4) var<storage, read> selectors: array<u32>;\n@group(0) @binding(5) var<storage, read_write> values: array<f32>;\n@group(0) @binding(6) var<storage, read_write> flags: array<u32>;\n\nvar<private> flagged: bool;\nfn check(distance: f32, bound: f32) { if (!(abs(distance) > SAFETY * bound)) { flagged = true; } }\n// Flags t when it lies within the bound of an integer n with lo <= n <= hi.\nfn check_integer(t: f32, bound: f32, lo: f32, hi: f32) {\n let n = round(t);\n if (SAFETY * bound >= 0.5) { flagged = true; return; }\n if (n >= lo && n <= hi) { check(t - n, bound); }\n}\n// x = (a + b) * scale, with the bound of its distance from the float64 reference value.\nfn scaled_sum_bound(a: f32, b: f32, s: f32, scale: f32, x: f32, constant_rounding: f32) -> f32 {\n return U * ((abs(a) + abs(b) + abs(s)) * abs(scale) + (1.0 + constant_rounding) * abs(x)) + SLACK * (abs(x) + 1.0);\n}\nfn cross_d(u: f32, v: f32, k: u32) -> f32 { return v * aux[2u * k] - u * aux[2u * k + 1u]; }\nfn cross_bound(u: f32, v: f32, k: u32, d: f32) -> f32 {\n return U * (3.0 * abs(v * aux[2u * k]) + 3.0 * abs(u * aux[2u * k + 1u]) + abs(d)) + SLACK * (abs(u) + abs(v));\n}\nfn material(p: vec2<f32>) -> u32 {\n let u = p.x;\n let v = p.y;\n switch (params.preset) {\n case 0u: { return 0u; }\n case 1u: {\n // Light where u·cos t − v·sin t ≥ 0.\n let a = u * params.f0;\n let b = v * params.f1;\n let d = a - b;\n check(d, U * (3.0 * abs(a) + 3.0 * abs(b) + abs(d)) + SLACK * (abs(u) + abs(v)));\n return select(0u, 1u, d >= 0.0);\n }\n case 2u: {\n let uu = u * u;\n let vv = v * v;\n let q = uu + vv;\n check(q - params.f0, U * (4.0 * q + 2.0 * params.f0) + SLACK * (q + params.f0));\n if (q > params.f0) { return 2u; }\n let sectors = 2u * params.na;\n var k = u32(clamp(floor((atan2(v, u) + PI) * f32(params.na) / PI), 0.0, f32(sectors - 1u)));\n for (var step = 0u; step < 4u; step++) {\n if (cross_d(u, v, k) < 0.0 && k > 0u) { k = k - 1u; continue; }\n if (cross_d(u, v, k + 1u) >= 0.0 && k + 1u < sectors) { k = k + 1u; continue; }\n break;\n }\n let lo = cross_d(u, v, k);\n let hi = cross_d(u, v, k + 1u);\n if (lo < 0.0 || hi >= 0.0) { flagged = true; }\n check(lo, cross_bound(u, v, k, lo));\n check(hi, cross_bound(u, v, k + 1u, hi));\n return select(0u, 1u, k % 2u == 0u);\n }\n case 3u, 4u: {\n let s = u + 1.0;\n let t = s * params.f0;\n check_integer(t, scaled_sum_bound(u, 1.0, s, params.f0, t, 0.0), 1.0, f32(params.na - 1u));\n return u32(clamp(floor(t), 0.0, f32(params.na - 1u)));\n }\n case 5u: {\n let s = u + 1.0;\n let x = s * params.f0;\n let w = params.f1 - v;\n let y = w * params.f0;\n check_integer(x, scaled_sum_bound(u, 1.0, s, params.f0, x, 0.0), -3.0e38, 3.0e38);\n check_integer(y, scaled_sum_bound(params.f1, v, w, params.f0, y, 0.0), -3.0e38, 3.0e38);\n let i = i32(floor(x));\n let j = i32(floor(y));\n return select(0u, 1u, (i + j) % 2 == 0);\n }\n case 6u: {\n let s = u + 1.0;\n let x = s * params.f0;\n let w = params.f1 - v;\n let y = w * params.f2;\n check_integer(x, scaled_sum_bound(u, 1.0, s, params.f0, x, 0.0), 1.0, f32(params.na - 1u));\n check_integer(y, scaled_sum_bound(params.f1, v, w, params.f2, y, 1.0), 1.0, f32(params.nb - 1u));\n let i = u32(clamp(floor(x), 0.0, f32(params.na - 1u)));\n let j = u32(clamp(floor(y), 0.0, f32(params.nb - 1u)));\n let c = j * params.na + i;\n let dx = u - aux[2u * c];\n let dy = v - aux[2u * c + 1u];\n let ex = U * (abs(u) + abs(aux[2u * c]) + abs(dx));\n let ey = U * (abs(v) + abs(aux[2u * c + 1u]) + abs(dy));\n let d2 = dx * dx + dy * dy;\n check(d2 - params.f3, 2.0 * (abs(dx) * ex + abs(dy) * ey) + ex * ex + ey * ey + U * (2.0 * d2 + params.f3) + SLACK * (d2 + params.f3));\n return select(0u, 1u, d2 <= params.f3);\n }\n default: {\n let s = u + 1.0;\n let fx = s * params.f0;\n let w = params.f1 - v;\n let fy = w * params.f2;\n let bx = scaled_sum_bound(u, 1.0, s, params.f0, fx, 0.0);\n let by = scaled_sum_bound(params.f1, v, w, params.f2, fy, 1.0);\n check_integer(fx, bx, -3.0e38, 3.0e38);\n check_integer(fy, by, -3.0e38, 3.0e38);\n let background = params.nc;\n let ifx = floor(fx);\n let ify = floor(fy);\n if (ifx < 0.0 || ify < 0.0 || ifx >= f32(params.na) || ify >= f32(params.nb)) { return background; }\n let index = u32(ify) * params.na + u32(ifx);\n let x = fx - ifx;\n let y = fy - ify;\n check(x - params.f3, bx + U * params.f3);\n check(x - params.f4, bx + U * params.f4);\n check(y - params.f3, by + U * params.f3);\n check(y - params.f4, by + U * params.f4);\n if (index >= params.nc || x < params.f3 || x > params.f4 || y < params.f3 || y > params.f4) { return background; }\n return index;\n }\n }\n}\n@compute @workgroup_size(${CHART_WORKGROUP_SIZE})\nfn main(@builtin(global_invocation_id) gid: vec3<u32>, @builtin(num_workgroups) groups: vec3<u32>) {\n let i = gid.x + gid.y * groups.x * ${CHART_WORKGROUP_SIZE}u;\n if (i >= params.count) { return; }\n flagged = false;\n let m = material(points[i]);\n if (params.wavelength_mode != 0u) {\n values[i] = table[m * params.columns + selectors[i]];\n } else {\n for (var c = 0u; c < params.columns; c++) { values[i * params.columns + c] = table[m * params.columns + c]; }\n }\n flags[i] = select(0u, 1u, flagged);\n}\n`;\n"]}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * The project's own WGSL (WebGPU shader language) compute kernels for the `webgpu-f32` image-kernel
3
+ * backend. Each kernel evaluates the same equations, in the same order, as its float64 CPU reference:
4
+ * - SDR: `calculateSdrRendering` / native capture SDR (exposure → tone → gamut → sRGB → nearest-ties-up);
5
+ * - RAW development: `createNativeRawDevelopmentTask` (CFA kernel sums → WB gains → camera→XYZ →
6
+ * XYZ→linear sRGB → SDR);
7
+ * - irradiance convolution: `convolveIrradianceRows` (source-indexed isoplanatic-patch gather).
8
+ * The host packers in image-kernel-accelerator.ts use matching uniform layouts.
9
+ */
10
+ /**
11
+ * Counter slots shared by the SDR-producing kernels. `linearBoundBits` holds the float32 bits of the
12
+ * largest per-sample linear bound of a luminance tone curve (a maximum, not a sum: non-negative float32
13
+ * bit patterns order like their values). `luminanceDomain` counts samples outside the float32 domain.
14
+ */
15
+ export declare const SDR_COUNTER: Readonly<{
16
+ negative: 0;
17
+ above: 1;
18
+ changed: 2;
19
+ low: 3;
20
+ high: 4;
21
+ outOfGamut: 5;
22
+ uncertain: 6;
23
+ gamutUncertain: 7;
24
+ saturatedPixels: 8;
25
+ whiteBalanceClipped: 9;
26
+ reconstructedPixels: 10;
27
+ linearBoundBits: 11;
28
+ luminanceDomain: 12;
29
+ }>;
30
+ export declare const SDR_COUNTER_SLOTS = 16;
31
+ /** Tone modes of the luminance kernels (`Params.tone_mode`); 0 is a per-channel curve. */
32
+ export declare const SDR_TONE_MODE: Readonly<{
33
+ perChannel: 0;
34
+ extendedReinhard: 1;
35
+ nakaRushton: 2;
36
+ }>;
37
+ export declare const LINEAR_WORKGROUP_SIZE = 256;
38
+ export declare const CONVOLUTION_WORKGROUP_EDGE = 16;
39
+ /** Pointwise SDR over a packed float32 band; one invocation per sample. */
40
+ export declare const SDR_WGSL: string;
41
+ /** Pointwise SDR with a luminance tone curve over a packed float32 band; one invocation per pixel. */
42
+ export declare const SDR_LUMINANCE_WGSL: string;
43
+ /**
44
+ * Packed native RAW development of one band of output rows; one invocation per output pixel.
45
+ * `normalized` holds the host's float64 site values, rounded once to float32. A saturated site
46
+ * (flagged, or at or above its phase white level) is exactly 1. Any other site is
47
+ * (code − black)/(white − black) ≤ 1 − 1/65535. So a saturated contributing site is recognised exactly.
48
+ * Highlight handling matches `prepareSensorColorDevelopment` (clip at the smallest applied gain, or the
49
+ * declared neutral blend).
50
+ */
51
+ export declare const RAW_DEVELOPMENT_WGSL: string;
52
+ /** Source-indexed isoplanatic-patch convolution of one output-row band; one invocation per output site. */
53
+ export declare const IRRADIANCE_CONVOLUTION_WGSL = "\nstruct Params {\n width: u32, height: u32, radius: u32, size: u32,\n patch_w: u32, patch_h: u32, cols: u32, rows: u32,\n out_row0: u32, out_rows: u32, in_row0: u32, taps: u32,\n};\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> kernels: array<f32>;\n@group(0) @binding(3) var<storage, read_write> result: array<f32>;\n@compute @workgroup_size(16, 16)\nfn main(@builtin(global_invocation_id) gid: vec3<u32>) {\n let x = gid.x;\n let local_y = gid.y;\n if (x >= params.width || local_y >= params.out_rows) { return; }\n let y = i32(params.out_row0 + local_y);\n let r = i32(params.radius);\n var sum = 0.0;\n for (var v = -r; v <= r; v++) {\n let sy = y - v;\n if (sy < 0 || sy >= i32(params.height)) { continue; }\n let patch_row = min(u32(sy) / params.patch_h, params.rows - 1u) * params.cols;\n let kernel_row = (v + r) * i32(params.size) + r;\n let source_row = (u32(sy) - params.in_row0) * params.width;\n for (var u = -r; u <= r; u++) {\n let sx = i32(x) - u;\n if (sx < 0 || sx >= i32(params.width)) { continue; }\n let patch_index = patch_row + min(u32(sx) / params.patch_w, params.cols - 1u);\n sum = sum + source[source_row + u32(sx)] * kernels[patch_index * params.taps + u32(kernel_row + u)];\n }\n }\n result[local_y * params.width + x] = sum;\n}\n";