@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,663 @@
1
+ # Quick start: simulate a capture
2
+
3
+ `simulateCapture()` takes a small description of a camera, a lens setting, an exposure and a
4
+ scene, and returns a developed image. Behind it runs the engine's full physical pipeline: scene
5
+ radiance → lens → spectral sensor response → charge and noise → RAW readout → RAW development →
6
+ optional JPEG.
7
+
8
+ `simulateCapture()` is a *facade*: one simple entry point in front of those existing contracts. It
9
+ adds no physics of its own. It only builds the request for the existing contracts, runs them, and
10
+ tells you every choice it made for you.
11
+
12
+ This page covers the inputs, the defaults, the chart presets and the limits. The detailed contracts
13
+ it composes are in [ENVIRONMENT_RAW_CAPTURE.md](https://github.com/Photivra/photivra/blob/main/docs/ENVIRONMENT_RAW_CAPTURE.md),
14
+ [NATIVE_RAW_AND_PRINT.md](https://github.com/Photivra/photivra/blob/main/docs/NATIVE_RAW_AND_PRINT.md), [GENERIC_TIER_PRESETS.md](https://github.com/Photivra/photivra/blob/main/docs/GENERIC_TIER_PRESETS.md),
15
+ [COLORIMETRY.md](https://github.com/Photivra/photivra/blob/main/docs/COLORIMETRY.md) and the [Usage Guide](USAGE.md).
16
+
17
+ Calling the engine from an AI agent? [Using Photivra from an agent](AGENT_GUIDE.md) says which
18
+ function fits each task, which units to pass and how to report results honestly.
19
+
20
+ ## The ten-line capture
21
+
22
+ ```ts
23
+ import { simulateCapture } from "@photivra/engine";
24
+
25
+ const capture = await simulateCapture({
26
+ camera: "professional",
27
+ lens: { fNumber: 8 },
28
+ exposure: { mode: "manual", iso: 100, shutterSeconds: 1 / 125 },
29
+ scene: { preset: "slanted-edge" },
30
+ output: { width: 16, height: 16, format: "srgb-8" }
31
+ });
32
+ console.log(capture.image.width, capture.image.samples.length, capture.exposure.settings);
33
+ ```
34
+
35
+ `capture.image.samples` holds interleaved 8-bit sRGB values, row by row from the top-left. The scene
36
+ is the only required input; every other field above is the default and could be left out.
37
+
38
+ Without the facade, the same kind of result needs the 34-line
39
+ [production-capture.mjs](examples/production-capture.mjs) plus its 4,613-line
40
+ [production-request.json](examples/production-request.json) for a 2 × 2 capture. A runnable version of
41
+ the example above is [simulate-capture.mjs](examples/simulate-capture.mjs).
42
+
43
+ ## What comes back
44
+
45
+ | Field | Contents |
46
+ | --- | --- |
47
+ | `image` | `width`, `height`, `format`, `samples` (`Uint8Array` or `Uint16Array` RGB), `jpeg` bytes for the `jpeg` format, `png` bytes plus `colorEncoding` for the `png` format, and `dng` bytes for the `dng` format |
48
+ | `raw` | The packed native RAW: codes, black levels, saturation flags and per-phase white levels |
49
+ | `plan` | The native RAW plan the engine executed |
50
+ | `request` | The complete underlying request: `environmentRaw` (the native environment RAW input), `siteInput(index)` (rebuilds the physical input of any sensor site), `development` (the RAW development input) and `whiteBalanceState` |
51
+ | `exposure` | Mode, resolved settings, EV100, metered scene luminance and the exposure-mode resolver's full output |
52
+ | `scene` | Chart parameters, illuminant, distance, framed size and the scene's SHA-256 digest (it covers caller illuminant and reflectance spectra; see `sourceSha256`) |
53
+ | `diagnostics` | Radiance query count, highlight and rendering counters, per-stage timings (`timingsMs`) and, from 2.1, the opt-ins that ran (`options`); see [Cost of each option](#cost-of-each-option) |
54
+ | `provenance` | Status (`approximation`), camera preset identity, evidence, the composed contracts in order, and limitations |
55
+ | `assumptions` | Every default, derived value and fixed modelling choice, each with an explanation |
56
+
57
+ Nothing is hidden: when you omit a field, an entry with `kind: "default"` names it and its value.
58
+ Values the facade calculates (such as the framed chart size) appear as `kind: "derived"`, and fixed
59
+ modelling choices (such as "no lens PSF") as `kind: "model"`.
60
+
61
+ ## Inputs and defaults
62
+
63
+ | Option | Default | Notes |
64
+ | --- | --- | --- |
65
+ | `camera` | `"professional"` | A generic tier id (`"consumer"`, `"prosumer"`, `"professional"`) or a full `GenericEquipmentTierPreset` record. A record must have exactly the preset shape (unknown fields at the top level, in `body`, `lens` or `lens.matchedReference` are rejected) and each profile is re-checked by its own parser. Tier values are synthetic educational designs, not real cameras. |
66
+ | `lens.focalLengthMm` | 50 | Must lie in the lens capability; the generic primes are 50 mm. |
67
+ | `lens.fNumber` | 8 | Used in `manual` and `aperture-priority`; resolved automatically otherwise. Must lie in f/4–f/16. |
68
+ | `lens.focusDistanceM` | the subject distance | |
69
+ | `lens.pupilSampling` | off | `{ radialSamples, angularSamples }` traces an ideal circular pupil, which renders defocus. Off means one chief ray per sample. Angular samples 4–64, at most 256 rays. |
70
+ | `lens.projection` | `"rectilinear"` | Any `LENS_PROJECTION_MODELS` value, for example `"fisheye-equisolid-angle"` (see [Optics](#optics)). |
71
+ | `lens.distortion` | none | `{ kind: "radial", profile }` or `{ kind: "brown-conrady", profile }`. |
72
+ | `lens.vignetting` | none | An `IlluminationVignettingProfile` (radial relative illumination). |
73
+ | `lens.psf` | none | A `{ kind: "sampled-local", configuration }` sampled lens PSF, passed to the environment contract unchanged. |
74
+ | `lens.diffraction` | off | 2.1: `"circular-aperture"` or `{ aperture: "circular-aperture", kernelRadiusSamples }`: diffraction blur of an ideal lens at the resolved f-number (see [Optics](#optics)). |
75
+ | `exposure.mode` | `"manual"` | Also `"aperture-priority"`, `"shutter-priority"`, `"program"`. |
76
+ | `exposure.iso` | 100 | Selects the body's ISO readout regime (gain and read noise). |
77
+ | `exposure.shutterSeconds` | 1/125 | Used in `manual` and `shutter-priority`. |
78
+ | `exposure.compensationStops` | 0 | Applied to the meter target. |
79
+ | `scene` | required | A chart preset or a caller function (below). |
80
+ | `subjectDistanceM` | 5 | Distance of the scene plane. |
81
+ | `illuminant` | Planckian 6500 K | Also `"cie-a"`, `{ kind: "planckian", temperatureKelvin }`, `{ kind: "daylight", correlatedColorTemperatureKelvin, basis }` or `{ kind: "spectrum", spectrum }`. |
82
+ | `illuminanceLux` | 21 481 (π·80 000/11.7) | See [Exposure](#exposure). |
83
+ | `output.width`, `output.height` | 64 × 64 | Output pixels. The sensor has one extra site on each side for demosaicing (see `output.borderHandling`). |
84
+ | `output.format` | `"srgb-8"` | Also `"srgb-16"`, `"jpeg"`, `"png"` and `"dng"` (see [Output formats](#output-formats)). |
85
+ | `output.colorEncoding` | `"srgb"` | PNG only: also `"display-p3"` and `"rec2020"`. |
86
+ | `output.bitDepth` | 8 | PNG only: 8 or 16. |
87
+ | `output.gamutMapping` | `"clip"` | PNG only: or `"perceptual"`. |
88
+ | `output.dng.capturedAtUtc` | none | DNG only: capture time for the date tags. |
89
+ | `output.demosaic` | the 1.0 bilinear kernels | `"bilinear"` or, from 2.1, `"ahd"` (see [Demosaic](#demosaic)). |
90
+ | `output.borderHandling` | `"margin"` | Or `"mirror"`. |
91
+ | `output.toneCurve` | `"identity"` | Any `SdrToneCurve`, for example `"positive-reinhard-per-channel"`. |
92
+ | `output.toneCurveParameters` | none | Required by the luminance curves (`extended-reinhard-luminance`, `naka-rushton-luminance`); the facade invents no curve parameters. |
93
+ | `output.highlightMode` | `"clip"` | Or `"reconstruct"`. |
94
+ | `output.whiteBalance` | `"scene-illuminant"` | Also `"auto"`, `"none"`, `{ kelvin, tint? }` and `{ channelGains }`. |
95
+ | `output.jpegQuantizationStep` | 2 | JPEG only: constant step 1–255, not a manufacturer quality scale. |
96
+ | `sensor.pixelPitchMicrometers` | 6 | The sensor is `width × pitch` wide (see [Geometry](#geometry)). |
97
+ | `sensor.spectralStepNanometers` | 20 | Spectral quadrature over 380–780 nm. |
98
+ | `sensor.temporalSampleCount` | 1, or 8 when the camera rotates | Midpoints across each site's exposure window. |
99
+ | `sensor.noiseSeed` | 1 | Output is deterministic for a given seed. |
100
+ | `sensor.antiAliasing` | off | 2.1: an optical low-pass (anti-aliasing) filter: `{ kind: "four-spot", separationSites? }`, `{ kind: "two-spot", axis, separationSites? }` or `{ kind: "point-splitting", components }` (see [Anti-aliasing filter](#anti-aliasing-filter)). |
101
+ | `motion.angularVelocityRadPerSec` | still | `{ pitch?, yaw?, roll? }` in rad/s (see [Motion](#motion)). |
102
+ | `motion.shutter` | `"global"` | Or `"rolling"`. |
103
+ | `motion.rollingShutterSkewSeconds` | the body's readout skew | Rolling only. |
104
+ | `signal`, `onProgress` | none | An `AbortSignal` cancels the running task; `onProgress` reports `raw`, `white-balance`, `development` and `jpeg` tiles. The last event of each stage has `completedTileCount === totalTileCount`. The capture yields to the host about every 8 ms with a `MessageChannel` message (else `setImmediate`, else `setTimeout`), so other queued tasks run in between: an abort sent from another task, such as a Web Worker `message` event, takes effect at the next yield. |
105
+
106
+ Unknown fields are rejected, so a typo never silently falls back to a default.
107
+
108
+ Every option added in 2.0 (PNG, demosaic, optics and motion) and in 2.1 (`lens.diffraction`,
109
+ `output.demosaic: "ahd"`, `sensor.antiAliasing`) is opt-in. With none of them given, the
110
+ request, RAW, samples and JPEG are byte-identical to the 1.0 facade at the same illuminance, and a
111
+ test checks that. (The default illuminance changed before release; see [Exposure](#exposure).)
112
+
113
+ ## Geometry
114
+
115
+ The scene is a plane perpendicular to the optical axis at `subjectDistanceM`. The facade sizes the
116
+ chart so that it exactly fills the active frame. Chart coordinates use frame units: `u` runs from −1
117
+ at the left edge to +1 at the right edge, and `v` points up on the same scale (±height/width).
118
+
119
+ The simulated sensor has real pixels of `sensor.pixelPitchMicrometers`. A 64 × 64 capture with 6 µm
120
+ pixels is therefore a 0.38 mm crop of a large sensor, not a downscaled full frame. This keeps the
121
+ signal per pixel, and so the noise and the ISO behaviour, physically consistent with the tier's
122
+ sensor values.
123
+
124
+ ## Exposure
125
+
126
+ The facade meters the scene like a reflected-light meter:
127
+
128
+ - It averages the scene luminance on a 16 × 16 grid with the body's metering profile.
129
+ - It uses two relations from CIPA DC-004-2020 (free):
130
+ - standard output sensitivity S = 10/H (§3.2): the correct focal-plane exposure for ISO S is
131
+ H = 10/S lx·s;
132
+ - the camera equation H = 0.65·L·t/N² (§5.5 (4)), where 0.65 = τ·π/4 with lens transmittance
133
+ τ = 0.828 (Explanation 4).
134
+
135
+ N is the f-number, t the shutter time in seconds, L the scene luminance in cd/m² and S the ISO
136
+ setting. Together they give N²/t = 0.65·L·S/10.
137
+ - The anchor is f/8, 1/125 s, ISO 100. It is correct for L = 10·N²/(0.65·t·S) =
138
+ 10·64·125/(0.65·100) = 80 000/65 ≈ 1230.77 cd/m².
139
+ - The meter target then goes through the engine's existing exposure-mode resolver.
140
+ - In `program` mode, a generic program line written by the engine chooses the aperture and shutter.
141
+
142
+ DC-004 ties the reference level to an 18 % grey (Explanation 1 and 2.2). The default illuminance
143
+ puts an 18 % Lambertian grey card, whose luminance is L = 0.18·E/π, exactly at that luminance:
144
+
145
+ ```text
146
+ E = π·L/0.18 = π·10·N²/(0.65·t·S·0.18)
147
+ = π·10·64·125/(0.65·100·0.18) = π·80 000/11.7 ≈ 21 480.98 lux
148
+ ```
149
+
150
+ Before 2.0.0 was released, the default was π·K·N²/(t·S·0.18) ≈ 17 453.29 lux, with the
151
+ reflected-light meter constant K = 12.5 cd·s/m² of a paid standard. The DC-004 relations are
152
+ equivalent to K = 10/0.65 ≈ 15.38 cd·s/m², so the new default has 10/(0.65·12.5) ≈ 1.231 times
153
+ (about 0.30 EV) more light.
154
+
155
+ The light does not follow your settings. Changing the shutter in manual mode changes the image
156
+ brightness, as on a real camera.
157
+
158
+ With these defaults, the green RAW level of an 18 % grey card is about 13.1 % of RAW white. A 100 %
159
+ reflector would then sit at about 73 % of white, roughly half a stop below clipping. DC-004 defines
160
+ only the mid-grey reference level, not highlight headroom: this half stop is a property of the
161
+ engine's generic tier presets, documented here, and the tier values were not tuned to get it.
162
+
163
+ ## Scene presets
164
+
165
+ All charts are analytic patterns written by the engine; no third-party chart data is bundled. Each
166
+ is a flat Lambertian reflector (it looks equally bright from every direction). Neutral reflectances
167
+ are spectrally flat.
168
+
169
+ | Preset | Parameters (defaults) | Definition |
170
+ | --- | --- | --- |
171
+ | `uniform` | `reflectance` (0.18) | One reflectance or caller spectrum everywhere. |
172
+ | `slanted-edge` | `angleDegrees` (5), `darkReflectance` (0.15), `lightReflectance` (0.6) | An edge through the centre, tilted clockwise from vertical: light where u·cos θ − v·sin θ ≥ 0. The geometry follows the slanted-edge method described by Burns (2000), also used by ISO 12233 (a few degrees of slant, 4:1 contrast by default). |
173
+ | `siemens-star` | `cycles` (36), `radiusFraction` (0.9), `darkReflectance` (0.05), `lightReflectance` (0.8), `backgroundReflectance` (0.18) | Alternating sectors of angular width π/cycles inside radius `radiusFraction` × frame half-height. |
174
+ | `step-wedge` | `steps` (11), `minimumReflectance` (0.03), `maximumReflectance` (0.9), `spacing` (`equal-density`) | Equal-width vertical steps from left to right. Equal density spaces D = −log₁₀ R evenly; `linear` spaces R evenly. |
175
+ | `grey-ramp` | `minimumReflectance` (0.03), `maximumReflectance` (0.9) | Reflectance linear in u, represented by 1024 equal levels. |
176
+ | `checkerboard` | `squaresAcross` (8), `darkReflectance` (0.05), `lightReflectance` (0.8) | Square cells, light at the top-left. |
177
+ | `point-grid` | `columns` (5), `rows` (3), `radius` (0.01), `pointReflectance` (0.9), `backgroundReflectance` (0.02) | Small disks centred in equal cells, for PSF and defocus inspection. |
178
+ | `patches` | `patches` (required), `columns`, `gapFraction` (0.1), `backgroundReflectance` (0.18) | Caller reflectance per patch, row-major. Use it for a ColorChecker-like chart with reflectance data you are entitled to use; the engine does not ship such data because its licence is unclear. |
179
+
180
+ `resolveChartScene()`, `calculateStepWedgeReflectances()` and `calculatePointGridCenters()` expose
181
+ the same definitions for analysis code. `createPlanarSceneRadianceProvider()` turns any of these
182
+ scenes into a provider for the native environment RAW contract.
183
+
184
+ Instead of a chart you can pass a function. `{ kind: "reflectance-function", sceneId, evaluate }`
185
+ receives a plane point (`xM`, `yM` in metres, `u`, `v` and `wavelengthNanometers`) and returns a
186
+ reflectance in [0, 1], lit by the facade illuminant. `{ kind: "radiance-function", sceneId, evaluate }`
187
+ returns absolute spectral radiance in W·m⁻²·sr⁻¹·nm⁻¹ and ignores the illuminant.
188
+
189
+ ```ts
190
+ import { simulateCapture } from "@photivra/engine";
191
+
192
+ const vignette = await simulateCapture({
193
+ scene: { kind: "reflectance-function", sceneId: "radial-falloff", evaluate: (p) => 0.8 / (1 + p.u * p.u + p.v * p.v) },
194
+ illuminant: "cie-a",
195
+ output: { width: 8, height: 8, whiteBalance: "auto" }
196
+ });
197
+ console.log(vignette.request.whiteBalanceState?.source);
198
+ ```
199
+
200
+ ## White balance
201
+
202
+ | Value | Meaning |
203
+ | --- | --- |
204
+ | `"scene-illuminant"` | A custom white balance measured from a perfect white diffuser under the scene illuminant, like a grey-card setting. |
205
+ | `"auto"` | Grey-world auto white balance (AWB) with the body's `neutral-priority` policy, over 2 × 2 block means of the RAW before white balance. The RAW is then rendered again with that setting, which repeats the radiance queries (`diagnostics.providerEvaluationCount` counts one pass). |
206
+ | `"none"` | No white balance; development assumes a D65 adopted white. Scenes under other light keep their colour cast. |
207
+ | `{ kelvin, tint? }` | A colour-temperature setting on the Planckian locus (tint as Duv). |
208
+ | `{ channelGains }` | Manual channel gains. |
209
+
210
+ ## Modelling choices
211
+
212
+ These choices appear in `assumptions` as `kind: "model"` entries:
213
+
214
+ - **Sensor colour.** The facade uses an idealized colorimetric sensor. Channel quantum efficiency is
215
+ a·{x̄, ȳ, z̄}(λ)·555 nm/λ from the engine's own analytic fit of the CIE 1931 colour-matching
216
+ functions (an approximation; see Colorimetry). The λ factor converts the energy-based functions into a
217
+ photon-counting response. RAW channels are then proportional to CIE XYZ (the Luther–Ives
218
+ condition), and the camera matrix is diagonal. No real camera has this response.
219
+ - **Lens.** The tier lens's spectrally flat transmission is used at every f-number and focus in the
220
+ lens capability. By default no PSF (point-spread function) or diffraction, vignetting, distortion,
221
+ lateral colour or stray light is applied. The tier's optical data exist only at f/4 and 5 m, and
222
+ the facade does not extrapolate them. Vignetting, distortion and PSF are applied only from profiles
223
+ you supply; diffraction of an ideal lens only with `lens.diffraction` (2.1).
224
+ - **Sensor.** Square pixels with a fill factor of 1 and no anti-aliasing filter. A global
225
+ electronic shutter unless `motion.shutter` is `"rolling"`. A synthetic uniform dark current of
226
+ 1 e⁻/s at 20 °C (the tiers declare none). The charge capacity equals the body's base-ISO saturation signal.
227
+ - **Demosaic.** Bilinear RGGB interpolation through the existing linear-kernel contract, unless
228
+ `output.demosaic` selects a built-in kernel or AHD. (Demosaicing fills in the two missing colours at each
229
+ pixel of a colour-filter mosaic.) Sharp edges without lens blur therefore show the usual zipper and
230
+ false-colour artefacts; `"ahd"` and `lens.diffraction` reduce them.
231
+ - **Scene.** A planar Lambertian surface: radiance = reflectance × irradiance / π, with illuminance
232
+ from K_m = 683 lm/W and the analytic ȳ. No shadows, inter-reflection, gloss or fluorescence.
233
+ - **Rendering.** Linear sRGB with RAW white at display white, no exposure push, out-of-gamut
234
+ components clipped, then the sRGB transfer function.
235
+
236
+ ## Output formats
237
+
238
+ `output.format: "png"` writes a PNG with `serializePngImage`: 8- or 16-bit RGB, deterministic
239
+ in-house zlib, and the colour encoding signalled in the file.
240
+
241
+ | `colorEncoding` | Samples | PNG signalling |
242
+ | --- | --- | --- |
243
+ | `"srgb"` | Exactly the developed sRGB samples (the `srgb-8` / `srgb-16` output). | sRGB chunk (perceptual intent) with its prescribed gAMA/cHRM values |
244
+ | `"display-p3"` | Linear colour converted to Display P3 primaries (W3C CSS Color 4 `display-p3`, D65), sRGB transfer. | cICP 12/13/0/1 |
245
+ | `"rec2020"` | Linear colour converted to ITU-R BT.2020 primaries, BT.2020 OETF (the BT.709 curve). | cICP 9/1/0/1 |
246
+
247
+ The BT.2100 PQ and HLG encodings are not part of 2.0: their patent holders offer only
248
+ licence-on-request declarations (see the patent review in `THIRD_PARTY.md`).
249
+
250
+ What is converted, and where:
251
+
252
+ - The sRGB output path develops each pixel to linear sRGB/D65. That covers demosaic, a per-site clip
253
+ at the RAW white level, white balance, highlight mode, the camera→XYZ matrix and the XYZ→sRGB
254
+ matrix. It then clips each component to [0, 1].
255
+ - The wide-gamut encodings use the same development operator but stop before that clip. So
256
+ colours outside sRGB survive, as negative or above-one sRGB components.
257
+ - They convert that linear colour back to CIE XYZ and on to the target primaries (matrices from the
258
+ primaries and the D65 white, as in W3C CSS Color 4; see [Colorimetry](https://github.com/Photivra/photivra/blob/main/docs/COLORIMETRY.md)).
259
+ - Gamut mapping then happens only once, in the target space. Components are clipped to [0, 1] for
260
+ Display P3 and Rec. 2020.
261
+ - No perceptual gamut compression is applied by default (see `output.gamutMapping` below).
262
+ - Tone curves other than `identity` are sRGB-only, and are refused with a wide-gamut encoding.
263
+
264
+ - RAW white maps to display white. For extended range, merge a bracket with
265
+ `createHdrBracketMergeTask` (see [PROCESSING.md](https://github.com/Photivra/photivra/blob/main/docs/PROCESSING.md)).
266
+ - No mDCV or cLLI metadata is written.
267
+ - With the facade's colorimetric sensor, the wide-gamut colours are exact up to the spectral
268
+ quadrature (numerical integration over wavelength). With 5 nm spectral steps, a test reproduces an
269
+ out-of-sRGB green emitter's CIE 1931 xy chromaticity to within 0.004.
270
+
271
+ ```ts
272
+ import { simulateCapture } from "@photivra/engine";
273
+
274
+ const wide = await simulateCapture({
275
+ scene: { preset: "checkerboard" },
276
+ output: { width: 8, height: 8, format: "png", colorEncoding: "display-p3", bitDepth: 16 }
277
+ });
278
+ console.log(wide.image.colorEncoding, wide.image.png?.length, wide.diagnostics.rendering.gamutClippedLowSampleCount);
279
+
280
+ const rec2020 = await simulateCapture({ scene: { preset: "uniform" }, output: { width: 4, height: 4, format: "png", colorEncoding: "rec2020", bitDepth: 16 } });
281
+ console.log(rec2020.image.samples instanceof Uint16Array, rec2020.assumptions.find((a) => a.id === "output.colorEncoding.conversion")?.value);
282
+ ```
283
+
284
+ `output.gamutMapping: "perceptual"` replaces the component clip for the PNG encodings (`srgb`,
285
+ `display-p3`, `rec2020`) with `prepareRgbGamutMapping`:
286
+
287
+ - CIELAB L* and hue are held.
288
+ - Chroma above 90 % of the gamut-boundary chroma is compressed with a smooth knee that never reaches
289
+ the boundary (constant-lightness, constant-hue chroma reduction as in W3C CSS Color 4 §14, free; also
290
+ see Morovič 2008).
291
+ - Hue is kept, whereas a component clip shifts it. The cost: saturated in-gamut colours above the knee
292
+ lose a little chroma, and CIELAB hue drifts for saturated blues.
293
+ - `"clip"` (the default) leaves the output exactly as before.
294
+ - `diagnostics.gamutMapping` counts the pixels the mapping changed.
295
+ - It cannot be combined with tone curves.
296
+
297
+ `output.format: "dng"` writes the packed native RAW itself with `serializeNativeRawDng`: a lossless,
298
+ uncompressed 16-bit CFA DNG. `samples` are the developed 8-bit sRGB image and `image.dng` holds the file.
299
+ The DNG states only what the capture has:
300
+
301
+ | Tags | Source |
302
+ | --- | --- |
303
+ | Codes, CFAPattern, BlackLevel (2 × 2), WhiteLevel | The packed RAW codes, per-site black levels (they must repeat with the CFA tile) and the smallest per-phase effective white code |
304
+ | ActiveArea, DefaultCropOrigin/Size, Orientation | The capture geometry (the demosaic border lies outside the active area) |
305
+ | ColorMatrix1 (D65), ForwardMatrix1, AnalogBalance, AsShotNeutral | The facade's diagonal camera→XYZ profile and the capture's white-balance intent |
306
+ | BaselineExposure | 0: the RAW white level maps to display white, as in the facade's development |
307
+ | NoiseProfile | Each channel's readout regime: conversion gain ÷ digital gain and the combined read noise (Poisson, Gaussian and quantization only) |
308
+ | ImageDescription | States that it is a simulated packed RAW with no linear master or rendering stored |
309
+
310
+ - Saturation flags of sites whose code is below WhiteLevel have no DNG field. They are counted in the
311
+ assumptions.
312
+ - `output.dng.capturedAtUtc` adds date tags. Without it, none are written.
313
+ - The file round-trips through `parseDngRawImage` to identical codes and tags.
314
+ - LibRaw 0.22.1 decodes identical codes. (It trims an odd ActiveArea origin to keep its Bayer
315
+ alignment.)
316
+ - Pillow 12 reads every tag but has no CFA (colour filter array) decoder — for these files, as for any
317
+ CFA DNG.
318
+
319
+ ```ts
320
+ import { parseDngRawImage, simulateCapture } from "@photivra/engine";
321
+
322
+ const shot = await simulateCapture({ scene: { preset: "siemens-star" }, output: { width: 8, height: 8, format: "dng" } });
323
+ const dng = parseDngRawImage({ bytes: shot.image.dng! });
324
+ console.log(dng.width, dng.activeArea, dng.whiteLevel, dng.codes.length === shot.raw.codes.length);
325
+ ```
326
+
327
+ ## Demosaic
328
+
329
+ `output.demosaic` selects:
330
+
331
+ - `"bilinear"`: the built-in Bayer kernels of `createBuiltInBayerDemosaicProfiles` (nearest same-channel
332
+ averages; pixel-identical to the default).
333
+ - `"ahd"` (2.1): adaptive homogeneity-directed demosaicing, `createAhdDemosaicTask` (after Hirakawa &
334
+ Parks, *IEEE Trans. Image Processing* 14(3), 2005). Green is interpolated along rows and along columns,
335
+ red and blue follow from colour differences, and each pixel takes the more homogeneous of the two
336
+ candidates in CIELAB. It is non-linear and edge-directed, so it shows much less zipper and false colour
337
+ on sharp edges than bilinear (mean false colour of a neutral 32 × 32 Siemens star: 138 instead of 209
338
+ 8-bit codes; slanted edge: 5.3 instead of 11.4). The RAW sites are normalized and white-level clipped
339
+ exactly as in the native development, the homogeneity is measured on white-balanced colour, and the
340
+ native development's colour operator and SDR kernel follow. The paper's iterative median step is not
341
+ applied. With `"margin"` borders the sensor gets 5 extra sites per side (an AHD pixel depends on sites
342
+ up to 5 away); `request.development` keeps the bilinear kernels, which validate the development but do
343
+ not produce the pixels.
344
+
345
+ The Malvar–He–Cutler kernels are not offered (a patent is still in force; see
346
+ [PROCESSING.md](https://github.com/Photivra/photivra/blob/main/docs/PROCESSING.md)).
347
+
348
+ `output.borderHandling` decides how edge pixels get their neighbours:
349
+
350
+ - `"margin"` (the default) renders the kernel's reach as extra sensor sites around the output: one site
351
+ for bilinear.
352
+ - `"mirror"` renders exactly the output, and reads reflect-101 mirror images of the missing sites. The
353
+ engine first checks that every reflected site keeps its CFA colour. Mirror saves the radiance work for
354
+ the border, so small captures need no extra sites. Its edge pixels use mirrored neighbours rather than
355
+ rendered ones.
356
+
357
+ ```ts
358
+ import { simulateCapture } from "@photivra/engine";
359
+
360
+ const mirrored = await simulateCapture({
361
+ scene: { preset: "slanted-edge" },
362
+ output: { width: 8, height: 8, demosaic: "bilinear", borderHandling: "mirror" }
363
+ });
364
+ console.log(mirrored.plan.exposure.geometry.nativeRaster, mirrored.request.development.borderHandling);
365
+ ```
366
+
367
+ ## Optics
368
+
369
+ The optics options feed only what the environment site contract accepts:
370
+
371
+ - `lens.projection` and `lens.distortion` become the site's `lensFieldMapping`.
372
+ - Each sensor point is inverse-distorted, unprojected with the chosen ideal projection, and only then
373
+ turned into a scene ray.
374
+ - Irradiance is multiplied exactly once by the distortion area factor 1/det(J), where J is the
375
+ Jacobian of the mapping.
376
+ - At finite focus, a non-rectilinear projection is scaled by the thin-lens image distance (an
377
+ approximation).
378
+ - The chart is still sized with the rectilinear scale, so its edges move with the projection.
379
+ - Neither option can be combined with `lens.pupilSampling`, because ideal pupil rays assume the
380
+ rectilinear, distortion-free projection.
381
+ - `lens.vignetting` becomes radial-illumination-vignetting field throughput,
382
+ 1 + r2·ρ² + r4·ρ⁴ + r6·ρ⁶, applied once at the physical sensor point before any PSF.
383
+ - `lens.psf` is a caller sampled PSF passed through unchanged. Its focal length, f-number and focus
384
+ must equal the resolved capture settings exactly, and it cannot be combined with pupil sampling.
385
+ - `lens.diffraction` (2.1) adds the diffraction blur of an ideal lens at the capture's resolved
386
+ f-number, so stopping down now softens the image as well as darkening it.
387
+ - The engine builds the kernels (`createDiffractionLimitedPsfProfile`): the Airy pattern of a uniformly
388
+ lit circular pupil (scalar Fraunhofer diffraction), aberration-free and in focus, with pupil diameter
389
+ f/N and the thin-lens image distance (working f-number N·v/f). Each kernel holds the PSF energy of
390
+ site-sized cells, one kernel per spectral node.
391
+ - The kernel window reaches the third dark ring at the longest node by default (2, 4 and 7 sites at
392
+ f/4, f/8 and f/16 with 6 µm pixels); set `kernelRadiusSamples` (0–32) to change it. The Airy tail
393
+ outside the window (2–5 % of the energy with the default) is listed per wavelength in the
394
+ `lens.diffraction` assumption and put back by renormalizing each kernel to unit sum.
395
+ - It runs as an object-space convolution: the scene radiance on the site lattice is convolved once per
396
+ spectral node and the provider answers each site query with it. That is the same sum as the
397
+ environment PSF quadrature (one scene query per kernel tap) for this still, distortion-free planar
398
+ scene; a test checks it to 1e-12 per site. With camera rotation, a projection or distortion, or
399
+ vignetting, the per-tap quadrature runs instead (much slower). `request.diffraction` holds the profile,
400
+ the equivalent `sampled-local` PSF and which execution ran.
401
+ - Not modelled: defocus, aberrations, pupil clipping, a polygonal (bladed) aperture (the tiers declare
402
+ no blade count) and the pixel aperture (each site is still sampled at its centre). It cannot be
403
+ combined with `lens.psf` or `lens.pupilSampling`.
404
+
405
+ The default frame is a 0.38 mm crop behind a 50 mm lens, a field of well under a degree. Projection
406
+ and distortion effects therefore only become visible with larger pixels (or a custom lens). The
407
+ profiles are yours to supply: the tiers declare no vignetting, distortion or PSF away from their f/4
408
+ reference.
409
+
410
+ Atmospheric haze and polarizers are not offered, for two reasons:
411
+
412
+ - The scene-radiance provider contract fixes `volumetricTransportModeled` and `polarizationModeled` to
413
+ false. Haze airlight added inside the provider would therefore be misdeclared.
414
+ - With unpolarized scene light, a polarizer reduces to a uniform attenuation, with none of its glare or
415
+ sky effects.
416
+
417
+ Use `calculateAtmosphericHaze` and the front-of-lens filter contracts directly (see
418
+ [PHYSICS_FOUNDATION.md](https://github.com/Photivra/photivra/blob/main/docs/PHYSICS_FOUNDATION.md)).
419
+
420
+ ```ts
421
+ import { simulateCapture } from "@photivra/engine";
422
+
423
+ const lensy = await simulateCapture({
424
+ scene: { preset: "point-grid" },
425
+ sensor: { pixelPitchMicrometers: 50 },
426
+ lens: {
427
+ projection: "fisheye-equisolid-angle",
428
+ distortion: { kind: "radial", profile: { normalizationRadiusMm: 0.5, maximumNormalizedRadius: 1, coefficients: { k1: -0.1, k2: 0, k3: 0 } } },
429
+ vignetting: { normalizationRadiusMm: 0.5, maximumNormalizedRadius: 1, coefficients: { r2: -0.3, r4: 0, r6: 0 } }
430
+ },
431
+ output: { width: 8, height: 8 }
432
+ });
433
+ console.log(lensy.request.siteInput(0).environment.lensFieldMapping, lensy.assumptions.find((a) => a.id === "lens.vignetting")?.kind);
434
+ ```
435
+
436
+ ```ts
437
+ import { simulateCapture } from "@photivra/engine";
438
+
439
+ const stoppedDown = await simulateCapture({
440
+ scene: { preset: "siemens-star" },
441
+ lens: { fNumber: 16, diffraction: "circular-aperture" },
442
+ exposure: { shutterSeconds: 1 / 30 },
443
+ output: { width: 48, height: 48, demosaic: "ahd" }
444
+ });
445
+ console.log(stoppedDown.request.diffraction?.execution, stoppedDown.request.diffraction?.profile.maximumTruncatedEnergyFraction);
446
+ ```
447
+
448
+ ### Anti-aliasing filter
449
+
450
+ `sensor.antiAliasing` (2.1) puts an optical low-pass filter in front of the sensor. Most real cameras
451
+ with a Bayer sensor carry one; the generic tiers declare none, so it is off by default. It is modelled
452
+ the way a birefringent quartz filter works: every image point is split into equally bright copies, and
453
+ each site collects the light that would otherwise have landed at its centre minus each offset (the
454
+ engine's `normalized-point-splitting-kernel` optical-stack response, resolved by
455
+ `resolveAntiAliasingSpatialKernel`).
456
+
457
+ - `{ kind: "four-spot", separationSites }`: two crossed plates, four spots at (±d/2, ±d/2) with weight
458
+ 1/4 each. Its MTF is |cos(π·f_x·d)·cos(π·f_y·d)|. The most common filter in digital cameras.
459
+ - `{ kind: "two-spot", axis: "horizontal" | "vertical", separationSites }`: one plate, two spots at
460
+ ±d/2 along the axis, MTF |cos(π·f·d)|.
461
+ - `{ kind: "point-splitting", components }`: your own kernel, offsets in micrometres (+x right, +y
462
+ down) and positive weights that sum to 1; at most 16 components, each within 4 sites.
463
+ - d = `separationSites` × pixel pitch, 0 < `separationSites` ≤ 4. The default 1 puts the first MTF
464
+ zero at the sensor's Nyquist frequency 1/(2·pitch): a four-spot filter one pixel wide cuts off at
465
+ Nyquist (Palum 2006). Above Nyquist the cosine rises again, so a lens (for example
466
+ `lens.diffraction`) is still needed to suppress the highest frequencies.
467
+
468
+ Measured at f/8 on 128 × 128 neutral charts (mean false colour |R − G| + |B − G| in 8-bit codes):
469
+ Siemens star 100.8 → 52.2 with bilinear and 68.7 → 25.1 with AHD; slanted edge 4.9 → 3.8 (bilinear).
470
+ The price is sharpness: the slanted-edge 10–90 % width grows from 1.49 to 2.34 px (bilinear).
471
+
472
+ Each site queries the scene once per spot, so the radiance work grows by the number of spots (4 for
473
+ `four-spot`). With `lens.diffraction` the object-space convolution still applies: the taps around
474
+ each split point lie on the site lattice shifted by its offset, so the engine convolves once per
475
+ distinct sub-site shift (one half-site lattice for the default four-spot filter). A test checks it
476
+ against the per-tap environment quadrature to 1e-12 per site.
477
+
478
+ Approximations, listed in the `sensor.antiAliasing` assumption: the split is the same at every
479
+ wavelength, field point and polarization (birefringence dispersion is ignored), the spots are exact
480
+ points of equal weight for unpolarized light, and the filter's transmission, reflections and focus
481
+ shift are not modelled. It is not a measured filter.
482
+
483
+ ```ts
484
+ import { simulateCapture } from "@photivra/engine";
485
+
486
+ const filtered = await simulateCapture({
487
+ scene: { preset: "siemens-star" },
488
+ sensor: { antiAliasing: { kind: "four-spot" } },
489
+ lens: { diffraction: "circular-aperture" },
490
+ output: { width: 48, height: 48, demosaic: "ahd" }
491
+ });
492
+ console.log(filtered.assumptions.find((a) => a.id === "sensor.antiAliasing")?.value);
493
+ ```
494
+
495
+ ## Motion
496
+
497
+ `motion.angularVelocityRadPerSec` rotates the camera at a constant rate during the exposure, in the
498
+ engine's pitch/yaw/roll convention ([SENSOR_ENVIRONMENT_QUERY.md](https://github.com/Photivra/photivra/blob/main/docs/SENSOR_ENVIRONMENT_QUERY.md)).
499
+
500
+ - Every scene ray is rotated at each temporal midpoint of the site's exposure window. Motion blur is
501
+ therefore a midpoint quadrature (an average over sample times).
502
+ - `sensor.temporalSampleCount` defaults to 8 when the camera rotates.
503
+ - A yaw of ω rad/s moves the image by ω·f/pitch pixels per second (f = focal length).
504
+
505
+ `motion.shutter: "rolling"` derives the exposure schedule from the body's rolling readout declaration,
506
+ with `resolveElectronicRollingShutterExposureSchedule` (line reset/read linkage). A site at normalized
507
+ scan position s integrates over [s·τ, s·τ + T], where τ is the skew and T the exposure time.
508
+
509
+ - The default skew τ is the tier's full-frame data-readout time, applied unchanged across the simulated
510
+ frame. It is not scaled to the cropped sensor, because the engine never rescales a declared skew. A
511
+ small frame therefore shows the skew of a full-sensor readout.
512
+ - Pass `rollingShutterSkewSeconds` to declare τ for the simulated frame yourself.
513
+ - Each site's charge window follows its own exposure window.
514
+ - Combined with rotation, a vertical edge shears by ω·f/pitch·τ pixels from the first row to the last.
515
+ A test checks this.
516
+
517
+ ```ts
518
+ import { simulateCapture } from "@photivra/engine";
519
+
520
+ const pan = await simulateCapture({
521
+ scene: { preset: "slanted-edge", angleDegrees: 0 },
522
+ motion: { angularVelocityRadPerSec: { yaw: 0.06 }, shutter: "rolling", rollingShutterSkewSeconds: 0.01 },
523
+ output: { width: 8, height: 8 }
524
+ });
525
+ console.log(pan.assumptions.find((a) => a.id === "sensor.shutter")?.value, pan.exposure.settings.shutterSeconds);
526
+ ```
527
+
528
+ ## Performance
529
+
530
+ Almost all of the cost is engine time per sensor site; the facade itself adds little. Since 2.0, the
531
+ native environment task runs most sites through a lean executor. It skips per-site re-validation that
532
+ is provably redundant, and produces byte-identical output (described in the repository's
533
+ `docs/NATIVE_RAW_AND_PRINT.md`).
534
+
535
+ Measured on a 4-core Linux host running Node 24 (slanted edge, default settings and sRGB 8-bit output):
536
+
537
+ | Output | Native sites | Wall time | CPU time | CPU per site |
538
+ | --- | --- | --- | --- | --- |
539
+ | 64 × 64 | 4 356 | 0.6 s | 0.87 s | 0.20 ms |
540
+ | 128 × 128 | 16 900 | 1.6 s | 2.2 s | 0.13 ms |
541
+ | 256 × 256 | 66 564 | 5.7 s | 6.9 s | 0.10 ms |
542
+ | 1000 × 1000 | 1 004 004 | — | about 2 min (extrapolated) | — |
543
+
544
+ The 1000 × 1000 row is not a measurement. It multiplies the 256 × 256 CPU cost per site by the site
545
+ count. Before the lean executor, the same 64 × 64 capture took about 6.0 s of CPU on this host, and
546
+ 128 × 128 about 20.6 s. Development and encoding are a small part of the total.
547
+
548
+ The 2.1 options, measured on the same kind of host (4-vCPU Intel Xeon 2.80 GHz, Node 24, median of three
549
+ runs, slanted edge and Siemens star): at 48 × 48, default 0.38–0.45 s, `lens.diffraction` 0.49–0.71 s
550
+ (f/4–f/16), `"ahd"` 0.48–0.63 s, both 0.60–0.87 s; at 128 × 128, default 2.1–2.3 s, diffraction
551
+ 2.5–3.4 s, AHD 2.4–2.5 s, both 2.8–4.0 s. The same diffraction through the per-tap environment quadrature
552
+ took 13.1 s at 48 × 48, f/8. [Cost of each option](#cost-of-each-option) covers every opt-in.
553
+
554
+ These numbers come from one run on one machine. They are not a performance claim. Small captures
555
+ (up to about 128 × 128) take a few seconds. Use them while you explore, and render large images only
556
+ when you need them.
557
+
558
+ ## Cost of each option
559
+
560
+ Slow options are opt-in, so an application can decide which ones it can afford: a feature that is
561
+ too slow for a phone today may be cheap on the next generation of hardware. The table gives the
562
+ measured wall time of each opt-in that affects run time, relative to the default capture of the same
563
+ size.
564
+
565
+ **Method.** Slanted-edge chart, every other option at its default (f/8, 1/125 s, ISO 100, sRGB 8-bit,
566
+ bilinear demosaic). One fresh Node process per row and size; one 16 × 16 warm-up capture, then three
567
+ timed captures (`performance.now()` around `simulateCapture`), median reported. Built `dist`, Node
568
+ 24.21.0, 4-vCPU Intel Xeon 2.80 GHz, Linux, nothing else running. One run on one machine: not a
569
+ performance claim, but the ratios carry over roughly.
570
+
571
+ | Option | 48 × 48 | 128 × 128 | What it buys |
572
+ | --- | --- | --- | --- |
573
+ | default | 0.50 s (1×) | 2.49 s (1×) | Point optics, bilinear demosaic, sRGB samples |
574
+ | `lens.diffraction: "circular-aperture"` | 0.65 s (1.3×) | 2.84 s (1.1×) | Aperture-dependent sharpness (Airy blur); convolution 0.38 s at 128 |
575
+ | `output.demosaic: "ahd"` | 0.65 s (1.3×) | 2.60 s (1.0×) | About half the false colour on sharp edges; 5-site margin, demosaic 0.05 s at 128 |
576
+ | `sensor.antiAliasing: { kind: "four-spot" }` | 0.94 s (1.9×) | 4.96 s (2.0×) | Optical low-pass filter: false colour halved again, at a cost in sharpness |
577
+ | anti-aliasing + diffraction | 1.16 s (2.3×) | 6.02 s (2.4×) | Both, still on the fast convolution path |
578
+ | anti-aliasing + diffraction + AHD | 1.42 s (2.8×) | 6.99 s (2.8×) | The most faithful still image of a planar chart |
579
+ | `lens.pupilSampling` 1 × 4 rays | 1.79 s (3.6×) | 11.5 s (4.6×) | Defocus and depth of field, coarse |
580
+ | `lens.pupilSampling` 2 × 8 rays | 5.20 s (10×) | 33.1 s (13×) | Defocus and depth of field, smoother bokeh |
581
+ | `lens.psf` (caller 3 × 3 kernel) | 2.11 s (4.2×) | 12.4 s (5.0×) | Any sampled lens PSF; runs per tap, so cost grows with the kernel size (a 9 × 9 diffraction kernel took 13.1 s at 48 × 48) |
582
+ | `motion` yaw 0.01 rad/s (8 temporal samples) | 1.70 s (3.4×) | 8.74 s (3.5×) | Motion blur; cost grows with `sensor.temporalSampleCount` |
583
+ | rotation + `shutter: "rolling"` | 1.79 s (3.6×) | 9.24 s (3.7×) | Rolling-shutter skew of moving content |
584
+ | `motion.shutter: "rolling"` (still camera) | 0.47 s (0.9×) | 2.51 s (1.0×) | Per-row exposure windows; no cost alone |
585
+ | `output.format: "png"` | 0.50 s (1.0×) | 2.63 s (1.1×) | PNG file bytes; encode 16 ms at 128 |
586
+ | `output.format: "jpeg"` | 0.52 s (1.0×) | 2.59 s (1.0×) | Baseline JPEG; encode 45 ms at 128 |
587
+ | `output.format: "dng"` | 0.50 s (1.0×) | 2.27 s (0.9×) | Lossless CFA DNG of the RAW; encode 4 ms at 128 |
588
+ | `output.highlightMode: "reconstruct"` | 0.50 s (1.0×) | 2.20 s (0.9×) | Near-clipped highlights blend smoothly toward neutral instead of clipping per channel; no measurable cost |
589
+ | `output.whiteBalance: "auto"` | 0.77 s (1.6×) | 4.76 s (1.9×) | Grey-world white balance; renders the RAW a second time (2.24 s at 128) |
590
+
591
+ Ratios below about 1.1× are within the run-to-run spread (the three default runs at 128 × 128 took
592
+ 2.23–2.50 s). The radiance work dominates: options that multiply the scene queries per site
593
+ (anti-aliasing spots, pupil rays, PSF taps, temporal samples) multiply the run time by about the same
594
+ factor, and output-side options cost almost nothing.
595
+
596
+ ### Measuring cost on the user's device
597
+
598
+ From 2.1 every result says what ran and how long each stage took, so an application can decide on the
599
+ user's own device which options to offer:
600
+
601
+ - `diagnostics.options` lists the opt-ins that changed the work of the run, in the fixed order of
602
+ `SIMULATE_CAPTURE_COST_OPTIONS` (for example `["lens.diffraction", "sensor.antiAliasing",
603
+ "output.demosaic.ahd", "output.format.png"]`). It is empty when every default is used.
604
+ - `diagnostics.timingsMs` has `raw`, `whiteBalance` (the second RAW pass of `whiteBalance: "auto"`),
605
+ `development` (includes DNG writing), `jpeg` and `total` in whole milliseconds, and, where the stage
606
+ ran, `diffraction` (the object-space convolution, part of `raw`), `demosaic` (the AHD demosaic, part
607
+ of `development`) and `encode` (PNG, JPEG or DNG serialization), with sub-millisecond resolution where
608
+ the host has `performance.now()`.
609
+
610
+ Timings change from run to run, but nothing else does: they never enter the scene digest, the RAW,
611
+ the samples or the encoded files, and a test checks that two runs differ only in `timingsMs`.
612
+
613
+ ```ts
614
+ import { simulateCapture } from "@photivra/engine";
615
+
616
+ const probe = await simulateCapture({ scene: { preset: "slanted-edge" }, output: { width: 32, height: 32, demosaic: "ahd" } });
617
+ console.log(probe.diagnostics.options, probe.diagnostics.timingsMs.total, probe.diagnostics.timingsMs.demosaic);
618
+ ```
619
+
620
+ ## Not available
621
+
622
+ The facade offers no atmospheric haze or polarizer (see [Optics](#optics)), flash, video, HDR brackets
623
+ or processing operators. Those APIs are available directly. Real camera and lens presets are not
624
+ provided, for rights reasons.
625
+
626
+ ## Sources
627
+
628
+ - R. Palum, "Anti-Aliasing Filter Analysis for Digital Cameras", Proc. IS&T International Congress of
629
+ Imaging Science (ICIS '06), 2006, free at
630
+ <https://www.imaging.org/common/uploaded%20files/pdfs/Papers/2006/ICIS-0-736/33683.pdf>
631
+ (birefringent quartz four-spot filter; one pixel wide in each direction cuts off at Nyquist; its MTF
632
+ is the modulus of a cosine that returns to one at the sampling frequency).
633
+ - CIPA DC-004-Translation-2020, *Sensitivity of Digital Cameras*, free at
634
+ <https://www.cipa.jp/e/std/std-sec.html> (standard output sensitivity S = 10/H, §3.2; reference
635
+ level tied to 18 % grey, §5.2 and Explanation 1, 2.2; focal-plane exposure H = 0.65·L·t/N², §5.5
636
+ and Explanation 4).
637
+ - P. D. Burns, "Slanted-Edge MTF for Digital Camera and Scanner Analysis", Proc. IS&T PICS 2000,
638
+ free at <https://www.imaging.org/common/uploaded%20files/pdfs/Papers/2000/PICS-0-81/1621.pdf>
639
+ (slanted-edge geometry; also ISO 12233:2017).
640
+ - BIPM, *The International System of Units*, 9th ed. (2019), free at
641
+ <https://www.bipm.org/en/publications/si-brochure> (K_cd = 683 lm/W, the definition of the candela).
642
+ - BIPM, *Mise en pratique for the definition of the kelvin*, Absolute Primary Radiometry (2018),
643
+ Eq. (1), free at <https://www.bipm.org/utils/en/pdf/si-mep/MeP-K-2018_Absolute_Primary_Radiometry.pdf>
644
+ (Planck's law, used for the Planckian and illuminant A spectra). Illuminant A's defining constants
645
+ and the daylight polynomial come from CIE 015:2018 (paid); computed values are checked against the
646
+ free CIE datasets at <https://cie.co.at/data-tables> (see [Colorimetry](https://github.com/Photivra/photivra/blob/main/docs/COLORIMETRY.md)).
647
+ - C. Wyman, P.-P. Sloan, P. Shirley, "Simple analytic approximations to the CIE XYZ color matching
648
+ functions", *Journal of Computer Graphics Techniques* 2(2), 2013 (the piecewise-Gaussian model form;
649
+ the engine fits its own coefficients to the CIE 1931 data, see Colorimetry).
650
+ - R. Luther, "Aus dem Gebiet der Farbreizmetrik", *Zeitschrift für technische Physik* 8, 1927
651
+ (the Luther condition for colorimetric cameras).
652
+ - W3C CSS Color Module Level 4 (`srgb` and `display-p3`; RGB↔XYZ matrices from primaries and white),
653
+ free at <https://www.w3.org/TR/css-color-4/>; ITU-R BT.709-6 and BT.2020-2 (primaries and luminance
654
+ coefficients), free at <https://www.itu.int/rec/R-REC-BT>; ITU-T H.273 (cICP code points); W3C PNG Specification, Third
655
+ Edition (2025).
656
+ - Adobe DNG Specification 1.7.1.0 (2023); W3C CSS Color Module Level 4 §14 (free). Also see: J. Morovič,
657
+ *Color Gamut Mapping*, Wiley 2008, §10.
658
+ - K. Miyamoto, "Fish eye lens", *JOSA* 54, 1964; J. Kannala, S. Brandt, *IEEE TPAMI* 28, 2006
659
+ (projections); A. E. Conrady, *MNRAS* 79, 1919; D. C. Brown, *Photogrammetric Engineering* 32, 1966
660
+ (distortion).
661
+ - A. El Gamal, H. Eltoukhy, "CMOS image sensors", *IEEE Circuits and Devices Magazine* 21(3), 2005;
662
+ C.-K. Liang, L.-W. Chang, H. H. Chen, "Analysis and compensation of rolling shutter effect",
663
+ *IEEE TIP* 17(8), 2008 (rolling-shutter line timing).