@photivra/engine 2.18.0 → 2.20.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 (335) hide show
  1. package/CHANGELOG.md +179 -1
  2. package/CITATION.cff +1 -1
  3. package/NODE_SUPPORT.md +7 -5
  4. package/README.md +6 -6
  5. package/SECURITY.md +1 -1
  6. package/THIRD_PARTY.md +14 -10
  7. package/dist/capture/dng-lens-correction-opcodes.d.ts +32 -0
  8. package/dist/capture/dng-lens-correction-opcodes.js +119 -0
  9. package/dist/capture/dng-lens-correction-opcodes.js.map +1 -0
  10. package/dist/capture/focus-control.js +2 -75
  11. package/dist/capture/focus-control.js.map +1 -1
  12. package/dist/capture/native-environment-lean.d.ts +1 -0
  13. package/dist/capture/native-environment-lean.js +2 -6
  14. package/dist/capture/native-environment-lean.js.map +1 -1
  15. package/dist/capture/native-environment-optical-stage.d.ts +1 -0
  16. package/dist/capture/native-environment-optical-stage.js +2 -5
  17. package/dist/capture/native-environment-optical-stage.js.map +1 -1
  18. package/dist/capture/native-environment-raw.js +1 -5
  19. package/dist/capture/native-environment-raw.js.map +1 -1
  20. package/dist/capture/native-raw-dng.d.ts +6 -0
  21. package/dist/capture/native-raw-dng.js +16 -2
  22. package/dist/capture/native-raw-dng.js.map +1 -1
  23. package/dist/capture/release-sequence.js +2 -47
  24. package/dist/capture/release-sequence.js.map +1 -1
  25. package/dist/capture/sensor-raw-producer.js +3 -5
  26. package/dist/capture/sensor-raw-producer.js.map +1 -1
  27. package/dist/color/white-balance.d.ts +2 -0
  28. package/dist/color/white-balance.js +3 -56
  29. package/dist/color/white-balance.js.map +1 -1
  30. package/dist/composition/image-formation-plan.d.ts +1 -0
  31. package/dist/composition/image-formation-plan.js +3 -49
  32. package/dist/composition/image-formation-plan.js.map +1 -1
  33. package/dist/core/evidence-provenance.js +1 -16
  34. package/dist/core/evidence-provenance.js.map +1 -1
  35. package/dist/core/record-validation.d.ts +54 -0
  36. package/dist/core/record-validation.js +176 -0
  37. package/dist/core/record-validation.js.map +1 -1
  38. package/dist/core/scientific-assurance.js +1 -18
  39. package/dist/core/scientific-assurance.js.map +1 -1
  40. package/dist/core/shared-helpers.d.ts +35 -0
  41. package/dist/core/shared-helpers.js +38 -0
  42. package/dist/core/shared-helpers.js.map +1 -0
  43. package/dist/core/spectral-composition.js +1 -36
  44. package/dist/core/spectral-composition.js.map +1 -1
  45. package/dist/core/spectral.js +1 -19
  46. package/dist/core/spectral.js.map +1 -1
  47. package/dist/core/version.d.ts +1 -1
  48. package/dist/core/version.js +1 -1
  49. package/dist/core/version.js.map +1 -1
  50. package/dist/equipment/exposure-capabilities.d.ts +1 -0
  51. package/dist/equipment/exposure-capabilities.js +2 -36
  52. package/dist/equipment/exposure-capabilities.js.map +1 -1
  53. package/dist/equipment/generic-lens-catalogue.d.ts +8 -2
  54. package/dist/equipment/generic-lens-catalogue.js +31 -2
  55. package/dist/equipment/generic-lens-catalogue.js.map +1 -1
  56. package/dist/equipment/generic-tier-assets.js +2 -3
  57. package/dist/equipment/generic-tier-assets.js.map +1 -1
  58. package/dist/equipment/generic-tier-presets.js +2 -3
  59. package/dist/equipment/generic-tier-presets.js.map +1 -1
  60. package/dist/equipment/iso-capabilities.js +2 -49
  61. package/dist/equipment/iso-capabilities.js.map +1 -1
  62. package/dist/equipment/metering-capabilities.js +1 -26
  63. package/dist/equipment/metering-capabilities.js.map +1 -1
  64. package/dist/equipment/release-capabilities.js +1 -53
  65. package/dist/equipment/release-capabilities.js.map +1 -1
  66. package/dist/exposure/auto-iso-slowest-shutter.js +1 -7
  67. package/dist/exposure/auto-iso-slowest-shutter.js.map +1 -1
  68. package/dist/exposure/exposure-duration-control.js +1 -16
  69. package/dist/exposure/exposure-duration-control.js.map +1 -1
  70. package/dist/exposure/exposure-mode-resolver.js +1 -17
  71. package/dist/exposure/exposure-mode-resolver.js.map +1 -1
  72. package/dist/exposure/filtered-exposure-time.d.ts +93 -0
  73. package/dist/exposure/filtered-exposure-time.js +129 -0
  74. package/dist/exposure/filtered-exposure-time.js.map +1 -0
  75. package/dist/exposure/flash-ttl.d.ts +1 -0
  76. package/dist/exposure/flash-ttl.js +1 -1
  77. package/dist/exposure/flash-ttl.js.map +1 -1
  78. package/dist/exposure/flash.js +1 -49
  79. package/dist/exposure/flash.js.map +1 -1
  80. package/dist/exposure/metering-scene-radiance.js +1 -25
  81. package/dist/exposure/metering-scene-radiance.js.map +1 -1
  82. package/dist/exposure/metering-target.js +1 -30
  83. package/dist/exposure/metering-target.js.map +1 -1
  84. package/dist/exposure/metering-temporal.js +1 -8
  85. package/dist/exposure/metering-temporal.js.map +1 -1
  86. package/dist/exposure/metering.js +1 -72
  87. package/dist/exposure/metering.js.map +1 -1
  88. package/dist/exposure/program-line.js +1 -45
  89. package/dist/exposure/program-line.js.map +1 -1
  90. package/dist/facade/develop-joined-parts.d.ts +29 -0
  91. package/dist/facade/develop-joined-parts.js +33 -0
  92. package/dist/facade/develop-joined-parts.js.map +1 -0
  93. package/dist/facade/display-view-gpu.d.ts +7 -4
  94. package/dist/facade/display-view-gpu.js +4 -4
  95. package/dist/facade/display-view-gpu.js.map +1 -1
  96. package/dist/facade/display-view-lens-signal.d.ts +1 -1
  97. package/dist/facade/display-view-lens-signal.js +5 -3
  98. package/dist/facade/display-view-lens-signal.js.map +1 -1
  99. package/dist/facade/display-view.d.ts +3 -1
  100. package/dist/facade/display-view.js +1 -1
  101. package/dist/facade/display-view.js.map +1 -1
  102. package/dist/facade/fast-methods.d.ts +50 -0
  103. package/dist/facade/fast-methods.js +50 -0
  104. package/dist/facade/fast-methods.js.map +1 -0
  105. package/dist/facade/fast-resolution.d.ts +12 -0
  106. package/dist/facade/fast-resolution.js +18 -0
  107. package/dist/facade/fast-resolution.js.map +1 -0
  108. package/dist/facade/generic-lens-capture.d.ts +6 -3
  109. package/dist/facade/generic-lens-capture.js +6 -3
  110. package/dist/facade/generic-lens-capture.js.map +1 -1
  111. package/dist/facade/simulate-capture.d.ts +88 -16
  112. package/dist/facade/simulate-capture.js +279 -153
  113. package/dist/facade/simulate-capture.js.map +1 -1
  114. package/dist/facade/simulate-display-view.d.ts +3 -2
  115. package/dist/facade/simulate-display-view.js +22 -12
  116. package/dist/facade/simulate-display-view.js.map +1 -1
  117. package/dist/gpu/chart-composite-gpu.js +1 -3
  118. package/dist/gpu/chart-composite-gpu.js.map +1 -1
  119. package/dist/gpu/chart-radiance-gpu.js +1 -5
  120. package/dist/gpu/chart-radiance-gpu.js.map +1 -1
  121. package/dist/gpu/display-view-quality-gpu.d.ts +13 -1
  122. package/dist/gpu/display-view-quality-gpu.js +4 -8
  123. package/dist/gpu/display-view-quality-gpu.js.map +1 -1
  124. package/dist/gpu/display-view-speed-gpu.js +3 -25
  125. package/dist/gpu/display-view-speed-gpu.js.map +1 -1
  126. package/dist/gpu/sensor-stage-gpu.js +1 -5
  127. package/dist/gpu/sensor-stage-gpu.js.map +1 -1
  128. package/dist/gpu/webgpu-runtime.d.ts +2 -0
  129. package/dist/gpu/webgpu-runtime.js +3 -0
  130. package/dist/gpu/webgpu-runtime.js.map +1 -1
  131. package/dist/index.d.ts +11 -1
  132. package/dist/index.js +8 -0
  133. package/dist/index.js.map +1 -1
  134. package/dist/motion/camera-rotation.js +1 -6
  135. package/dist/motion/camera-rotation.js.map +1 -1
  136. package/dist/motion/capture-rotation-inverse-mapping.d.ts +12 -0
  137. package/dist/motion/capture-rotation-inverse-mapping.js +2 -2
  138. package/dist/motion/capture-rotation-inverse-mapping.js.map +1 -1
  139. package/dist/motion/capture-rotation-temporal-quadrature.d.ts +1 -0
  140. package/dist/motion/capture-rotation-temporal-quadrature.js +1 -1
  141. package/dist/motion/capture-rotation-temporal-quadrature.js.map +1 -1
  142. package/dist/motion/capture-rotation-trajectory.js +2 -17
  143. package/dist/motion/capture-rotation-trajectory.js.map +1 -1
  144. package/dist/motion/capture-translation-parallax-temporal-quadrature.d.ts +1 -0
  145. package/dist/motion/capture-translation-parallax-temporal-quadrature.js +3 -14
  146. package/dist/motion/capture-translation-parallax-temporal-quadrature.js.map +1 -1
  147. package/dist/motion/extended-object-projection.js +5 -40
  148. package/dist/motion/extended-object-projection.js.map +1 -1
  149. package/dist/optics/aperture-diameter.d.ts +47 -0
  150. package/dist/optics/aperture-diameter.js +50 -0
  151. package/dist/optics/aperture-diameter.js.map +1 -0
  152. package/dist/optics/atmospheric-haze.js +1 -7
  153. package/dist/optics/atmospheric-haze.js.map +1 -1
  154. package/dist/optics/brown-conrady-distortion.js +1 -7
  155. package/dist/optics/brown-conrady-distortion.js.map +1 -1
  156. package/dist/optics/complex-pupil-psf.d.ts +1 -0
  157. package/dist/optics/complex-pupil-psf.js +2 -84
  158. package/dist/optics/complex-pupil-psf.js.map +1 -1
  159. package/dist/optics/detail-limit.d.ts +182 -0
  160. package/dist/optics/detail-limit.js +336 -0
  161. package/dist/optics/detail-limit.js.map +1 -0
  162. package/dist/optics/focus-state.js +1 -11
  163. package/dist/optics/focus-state.js.map +1 -1
  164. package/dist/optics/front-of-lens-filter.d.ts +5 -0
  165. package/dist/optics/front-of-lens-filter.js +3 -65
  166. package/dist/optics/front-of-lens-filter.js.map +1 -1
  167. package/dist/optics/generic-lens-psf.d.ts +18 -2
  168. package/dist/optics/generic-lens-psf.js +25 -2
  169. package/dist/optics/generic-lens-psf.js.map +1 -1
  170. package/dist/optics/generic-nd-filter-presets.d.ts +12 -0
  171. package/dist/optics/generic-nd-filter-presets.js +48 -0
  172. package/dist/optics/generic-nd-filter-presets.js.map +1 -0
  173. package/dist/optics/illumination-vignetting.js +1 -6
  174. package/dist/optics/illumination-vignetting.js.map +1 -1
  175. package/dist/optics/lens-psf-profile.d.ts +4 -1
  176. package/dist/optics/lens-psf-profile.js +12 -111
  177. package/dist/optics/lens-psf-profile.js.map +1 -1
  178. package/dist/optics/longitudinal-chromatic-aberration.js +1 -7
  179. package/dist/optics/longitudinal-chromatic-aberration.js.map +1 -1
  180. package/dist/optics/pupil-vignetting.js +1 -7
  181. package/dist/optics/pupil-vignetting.js.map +1 -1
  182. package/dist/optics/radial-distortion.js +1 -6
  183. package/dist/optics/radial-distortion.js.map +1 -1
  184. package/dist/optics/scene-to-sensor-irradiance.d.ts +13 -0
  185. package/dist/optics/scene-to-sensor-irradiance.js +11 -96
  186. package/dist/optics/scene-to-sensor-irradiance.js.map +1 -1
  187. package/dist/optics/stray-light.d.ts +1 -0
  188. package/dist/optics/stray-light.js +1 -1
  189. package/dist/optics/stray-light.js.map +1 -1
  190. package/dist/optics/zernike-wavefront.js +1 -7
  191. package/dist/optics/zernike-wavefront.js.map +1 -1
  192. package/dist/output/capture-geometry.js +1 -8
  193. package/dist/output/capture-geometry.js.map +1 -1
  194. package/dist/output/crop-to-match-focal-length.d.ts +62 -0
  195. package/dist/output/crop-to-match-focal-length.js +63 -0
  196. package/dist/output/crop-to-match-focal-length.js.map +1 -0
  197. package/dist/output/developed-lens-corrections.d.ts +62 -0
  198. package/dist/output/developed-lens-corrections.js +135 -0
  199. package/dist/output/developed-lens-corrections.js.map +1 -0
  200. package/dist/output/generic-lens-corrections.d.ts +5 -7
  201. package/dist/output/generic-lens-corrections.js +11 -10
  202. package/dist/output/generic-lens-corrections.js.map +1 -1
  203. package/dist/output/geometric-transforms.js +1 -4
  204. package/dist/output/geometric-transforms.js.map +1 -1
  205. package/dist/output/lens-corrections.d.ts +12 -2
  206. package/dist/output/lens-corrections.js +22 -7
  207. package/dist/output/lens-corrections.js.map +1 -1
  208. package/dist/output/native-capture-sdr.d.ts +2 -2
  209. package/dist/output/native-capture-sdr.js +3 -2
  210. package/dist/output/native-capture-sdr.js.map +1 -1
  211. package/dist/output/print-contrast-reference.js +1 -1
  212. package/dist/output/print-contrast-reference.js.map +1 -1
  213. package/dist/output/print-size-blur-noise.d.ts +110 -0
  214. package/dist/output/print-size-blur-noise.js +138 -0
  215. package/dist/output/print-size-blur-noise.js.map +1 -0
  216. package/dist/processing/development-detail.d.ts +29 -0
  217. package/dist/processing/development-detail.js +128 -107
  218. package/dist/processing/development-detail.js.map +1 -1
  219. package/dist/schema/illumination-temporal.js +3 -72
  220. package/dist/schema/illumination-temporal.js.map +1 -1
  221. package/dist/schema/illumination.d.ts +1 -0
  222. package/dist/schema/illumination.js +2 -65
  223. package/dist/schema/illumination.js.map +1 -1
  224. package/dist/schema/scene-radiance-temporal.js +2 -14
  225. package/dist/schema/scene-radiance-temporal.js.map +1 -1
  226. package/dist/schema/scene-radiance.js +2 -60
  227. package/dist/schema/scene-radiance.js.map +1 -1
  228. package/dist/schema/validation.d.ts +2 -0
  229. package/dist/schema/validation.js +2 -17
  230. package/dist/schema/validation.js.map +1 -1
  231. package/dist/sensor/accumulated-charge.js +2 -59
  232. package/dist/sensor/accumulated-charge.js.map +1 -1
  233. package/dist/sensor/architecture.js +1 -16
  234. package/dist/sensor/architecture.js.map +1 -1
  235. package/dist/sensor/camera-saturation-capacity.d.ts +1 -0
  236. package/dist/sensor/camera-saturation-capacity.js +3 -55
  237. package/dist/sensor/camera-saturation-capacity.js.map +1 -1
  238. package/dist/sensor/capture-color-sampling-binding.js +1 -26
  239. package/dist/sensor/capture-color-sampling-binding.js.map +1 -1
  240. package/dist/sensor/capture-mode-timing.js +1 -39
  241. package/dist/sensor/capture-mode-timing.js.map +1 -1
  242. package/dist/sensor/capture-mode.js +1 -23
  243. package/dist/sensor/capture-mode.js.map +1 -1
  244. package/dist/sensor/color-sampling.js +1 -26
  245. package/dist/sensor/color-sampling.js.map +1 -1
  246. package/dist/sensor/constant-rate-temporal-integration.js +2 -46
  247. package/dist/sensor/constant-rate-temporal-integration.js.map +1 -1
  248. package/dist/sensor/dark-current.js +2 -45
  249. package/dist/sensor/dark-current.js.map +1 -1
  250. package/dist/sensor/eqe-electron-rate.js +2 -41
  251. package/dist/sensor/eqe-electron-rate.js.map +1 -1
  252. package/dist/sensor/exposure-window.d.ts +7 -0
  253. package/dist/sensor/exposure-window.js +9 -24
  254. package/dist/sensor/exposure-window.js.map +1 -1
  255. package/dist/sensor/iso-gain.js +1 -7
  256. package/dist/sensor/iso-gain.js.map +1 -1
  257. package/dist/sensor/iso-signal-chain.js +1 -43
  258. package/dist/sensor/iso-signal-chain.js.map +1 -1
  259. package/dist/sensor/optical-stack.js +1 -25
  260. package/dist/sensor/optical-stack.js.map +1 -1
  261. package/dist/sensor/photon-energy.js +1 -26
  262. package/dist/sensor/photon-energy.js.map +1 -1
  263. package/dist/sensor/physical-charge-capacity.js +3 -77
  264. package/dist/sensor/physical-charge-capacity.js.map +1 -1
  265. package/dist/sensor/radiometry-readiness.js +2 -23
  266. package/dist/sensor/radiometry-readiness.js.map +1 -1
  267. package/dist/sensor/raw-readout.d.ts +3 -0
  268. package/dist/sensor/raw-readout.js +4 -66
  269. package/dist/sensor/raw-readout.js.map +1 -1
  270. package/dist/sensor/raw-reconstruction.js +2 -64
  271. package/dist/sensor/raw-reconstruction.js.map +1 -1
  272. package/dist/sensor/readout-exposure-linkage.js +1 -9
  273. package/dist/sensor/readout-exposure-linkage.js.map +1 -1
  274. package/dist/sensor/readout-timing.js +4 -79
  275. package/dist/sensor/readout-timing.js.map +1 -1
  276. package/dist/sensor/response-application-compatibility.d.ts +2 -0
  277. package/dist/sensor/response-application-compatibility.js +4 -35
  278. package/dist/sensor/response-application-compatibility.js.map +1 -1
  279. package/dist/sensor/response-operating-range.d.ts +1 -0
  280. package/dist/sensor/response-operating-range.js +3 -79
  281. package/dist/sensor/response-operating-range.js.map +1 -1
  282. package/dist/sensor/responsivity-photocurrent.js +4 -114
  283. package/dist/sensor/responsivity-photocurrent.js.map +1 -1
  284. package/dist/sensor/sampling-aperture.js +1 -25
  285. package/dist/sensor/sampling-aperture.js.map +1 -1
  286. package/dist/sensor/sensor-characteristics.d.ts +137 -0
  287. package/dist/sensor/sensor-characteristics.js +115 -0
  288. package/dist/sensor/sensor-characteristics.js.map +1 -0
  289. package/dist/sensor/spatial-sample-reduction.js +3 -24
  290. package/dist/sensor/spatial-sample-reduction.js.map +1 -1
  291. package/dist/sensor/spatial-sampling-quadrature.js +1 -3
  292. package/dist/sensor/spatial-sampling-quadrature.js.map +1 -1
  293. package/dist/sensor/spatio-spectral-reduction.js +1 -18
  294. package/dist/sensor/spatio-spectral-reduction.js.map +1 -1
  295. package/dist/sensor/spectral-coverage.d.ts +10 -1
  296. package/dist/sensor/spectral-coverage.js +1 -1
  297. package/dist/sensor/spectral-coverage.js.map +1 -1
  298. package/dist/sensor/spectral-quadrature.js +3 -41
  299. package/dist/sensor/spectral-quadrature.js.map +1 -1
  300. package/dist/sensor/spectral-response.js +1 -47
  301. package/dist/sensor/spectral-response.js.map +1 -1
  302. package/dist/sensor/temporal-photo-signal.d.ts +3 -0
  303. package/dist/sensor/temporal-photo-signal.js +5 -2
  304. package/dist/sensor/temporal-photo-signal.js.map +1 -1
  305. package/dist/stabilization/camera-shake.js +1 -6
  306. package/dist/stabilization/camera-shake.js.map +1 -1
  307. package/dist/stabilization/system.d.ts +9 -0
  308. package/dist/stabilization/system.js +7 -86
  309. package/dist/stabilization/system.js.map +1 -1
  310. package/docs/AGENT_GUIDE.md +5 -0
  311. package/docs/API_REFERENCE.md +116 -3
  312. package/docs/QUICK_START.md +178 -14
  313. package/docs/USAGE.md +111 -3
  314. package/docs/api/capture-native-raw-dng.md +6 -0
  315. package/docs/api/core-version.md +1 -1
  316. package/docs/api/equipment-generic-lens-catalogue.md +7 -2
  317. package/docs/api/exports.json +203 -3
  318. package/docs/api/exposure-filtered-exposure-time.md +105 -0
  319. package/docs/api/facade-develop-joined-parts.md +32 -0
  320. package/docs/api/facade-display-view-gpu.md +5 -2
  321. package/docs/api/facade-fast-methods.md +91 -0
  322. package/docs/api/facade-simulate-capture.md +72 -16
  323. package/docs/api/facade-simulate-display-view.md +3 -2
  324. package/docs/api/optics-aperture-diameter.md +51 -0
  325. package/docs/api/optics-detail-limit.md +203 -0
  326. package/docs/api/optics-generic-nd-filter-presets.md +34 -0
  327. package/docs/api/optics-lens-psf-profile.md +3 -1
  328. package/docs/api/output-crop-to-match-focal-length.md +67 -0
  329. package/docs/api/output-developed-lens-corrections.md +12 -0
  330. package/docs/api/output-generic-lens-corrections.md +3 -10
  331. package/docs/api/output-lens-corrections.md +11 -1
  332. package/docs/api/output-print-size-blur-noise.md +115 -0
  333. package/docs/api/sensor-sensor-characteristics.md +105 -0
  334. package/llms.txt +5 -0
  335. package/package.json +1 -1
@@ -22,6 +22,12 @@ export interface SerializeNativeRawDngInput {
22
22
  capturedAtUtc?: string;
23
23
  /** Optional (2.4) caller text: description, software, copyright, comment (see the module notes). If omitted, no text is added. */
24
24
  textMetadata?: OutputTextMetadata;
25
+ /**
26
+ * Optional (#587) OpcodeList3 (tag 51022) bytes, for example `createDngLensCorrectionOpcodes(...).opcodeList3`: a big-endian DNG
27
+ * opcode list (DNG 1.3.0.0+, "Opcode List Processing") that readers apply to the demosaiced stage-3 image. Only its framing is
28
+ * checked (count, per-opcode headers and parameter sizes filling the bytes exactly). The RAW codes are unchanged. If omitted, no tag.
29
+ */
30
+ opcodeList3?: Uint8Array;
25
31
  }
26
32
  export interface NativeRawDng {
27
33
  schemaVersion: typeof NATIVE_RAW_DNG_SCHEMA_VERSION;
@@ -31,6 +31,8 @@
31
31
  * §1.1.6, Table 13) always carries every given field in UTF-8: `dc:description` (the full ImageDescription text,
32
32
  * statement first, as XMP Part 3 §3.2.3 maps tag 270), `dc:rights`, `xmp:CreatorTool` and `exif:UserComment`.
33
33
  * The Software tag keeps naming the engine's writer. Without `textMetadata` the bytes are unchanged.
34
+ * - Opcodes (#587, only with `opcodeList3`): the caller's big-endian DNG opcode list as OpcodeList3 (51022, UNDEFINED), framing checked
35
+ * (count, 16-byte headers, parameter sizes filling the bytes). Without it the bytes are unchanged.
34
36
  * @see docs/NATIVE_RAW_AND_PRINT.md for the tag table, limits and the round trip through parseDngRawImage.
35
37
  */
36
38
  import { InvalidConfigurationError } from "../core/configuration-error.js";
@@ -64,7 +66,19 @@ const ORIENTATION = { landscape: 1, "portrait-clockwise": 6, "landscape-inverted
64
66
  * where its value comes from. The input arrays are copied before the first await.
65
67
  */
66
68
  export async function serializeNativeRawDng(input) {
67
- const r = requireAllowlistedRecord(input, ["raw", "colorProfile", "noise", "baselineExposureEv", "capturedAtUtc", "textMetadata"], "Invalid native RAW DNG input.");
69
+ const r = requireAllowlistedRecord(input, ["raw", "colorProfile", "noise", "baselineExposureEv", "capturedAtUtc", "textMetadata", "opcodeList3"], "Invalid native RAW DNG input.");
70
+ let opcodeList3;
71
+ if (r.opcodeList3 !== undefined) {
72
+ if (!(r.opcodeList3 instanceof Uint8Array) || r.opcodeList3.length < 4)
73
+ fail("opcodeList3 must be a Uint8Array opcode list.");
74
+ opcodeList3 = r.opcodeList3.slice();
75
+ const v = new DataView(opcodeList3.buffer);
76
+ let at = 4;
77
+ for (let n = v.getUint32(0); n > 0 && at <= opcodeList3.length; n--)
78
+ at = at + 16 > opcodeList3.length ? Infinity : at + 16 + v.getUint32(at + 12);
79
+ if (at !== opcodeList3.length)
80
+ fail("opcodeList3 is not a whole DNG opcode list (big-endian count, 16-byte headers, parameter sizes).");
81
+ }
68
82
  const raw = r.raw, plan = validatePackedNativeRaw(raw);
69
83
  const mosaic = plan.frame.colorSamplingProfile.layout;
70
84
  if (mosaic.kind === "periodic-mosaic")
@@ -179,7 +193,7 @@ export async function serializeNativeRawDng(input) {
179
193
  rationals(50730, true, [baseline]), numbers(50778, 3, [21]),
180
194
  rawBytes(50781, 1, Uint8Array.from(rawDataUniqueId.match(/../g).map((s) => parseInt(s, 16)))),
181
195
  numbers(50829, 4, [active.y, active.x, active.y + active.height, active.x + active.width]),
182
- rationals(50964, true, forward.flat()), ...(noiseProfile ? [doubles(51041, noiseProfile)] : []), ...textTags], exif, pixels);
196
+ rationals(50964, true, forward.flat()), ...(noiseProfile ? [doubles(51041, noiseProfile)] : []), ...(opcodeList3 ? [rawBytes(51022, 7, opcodeList3)] : []), ...textTags], exif, pixels);
183
197
  return Object.freeze({ schemaVersion: NATIVE_RAW_DNG_SCHEMA_VERSION, mediaType: "image/dng", bytes, sha256: await sha256(bytes), rawDataUniqueId, uniqueCameraModel,
184
198
  activeArea: { ...active }, defaultCrop: { ...crop }, orientation, blackLevels, whiteLevel, cfaPattern, colorMatrix1: stored(colorMatrixTag), asShotNeutral: stored(neutralTag),
185
199
  noiseProfile, unrepresentedSaturationFlagCount: unrepresented, source: "packed-native-raw", linearMasterDeclared: false });
@@ -1 +1 @@
1
- {"version":3,"file":"native-raw-dng.js","sourceRoot":"","sources":["../../src/capture/native-raw-dng.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,+DAA+D;AAE/D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAEH,OAAO,EAAE,yBAAyB,EAAE,MAAM,gCAAgC,CAAC;AAC3E,OAAO,EAAE,wBAAwB,EAAE,MAAM,8BAA8B,CAAC;AACxE,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EAAE,wBAAwB,EAAE,MAAM,2BAA2B,CAAC;AACrE,OAAO,EAAE,uBAAuB,EAAE,6BAA6B,EAAE,yBAAyB,EAAE,MAAM,sCAAsC,CAAC;AACzI,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,EAAE,yBAAyB,EAAE,MAAM,kCAAkC,CAAC;AAC7E,OAAO,EAAE,mCAAmC,EAAE,MAAM,+BAA+B,CAAC;AAEpF,OAAO,EAAE,uBAAuB,EAAE,uBAAuB,EAAE,MAAM,6BAA6B,CAAC;AAC/F,OAAO,EAAE,6BAA6B,EAAiC,MAAM,0BAA0B,CAAC;AACxG,OAAO,EAAE,uBAAuB,EAAE,qBAAqB,EAA2B,MAAM,4BAA4B,CAAC;AACrH,OAAO,EAAE,cAAc,EAAE,eAAe,IAAI,KAAK,EAAE,iBAAiB,IAAI,OAAO,EAAE,mBAAmB,IAAI,SAAS,EAC/G,eAAe,IAAI,QAAQ,EAAE,iBAAiB,IAAI,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAEtF,MAAM,CAAC,MAAM,6BAA6B,GAAG,OAAgB,CAAC;AA+C9D,SAAS,IAAI,CAAC,OAAe,IAAW,MAAM,IAAI,yBAAyB,CAAC,kBAAkB,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;AAC5G,KAAK,UAAU,MAAM,CAAC,KAAiB;IACrC,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,EAAE,MAAM,CAAC;IACzC,IAAI,CAAC,MAAM;QAAE,IAAI,CAAC,6DAA6D,CAAC,CAAC;IACjF,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,UAAU,CAAC,MAAM,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,KAAgC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AACvJ,CAAC;AACD,yIAAyI;AACzI,SAAS,MAAM,CAAC,GAAiC;IAC/C,MAAM,IAAI,GAAG,IAAI,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,IAAI,CAAC,UAAU,EAAE,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACrF,OAAO,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,GAAG,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;AACrK,CAAC;AACD,MAAM,WAAW,GAAG,EAAE,SAAS,EAAE,CAAC,EAAE,oBAAoB,EAAE,CAAC,EAAE,oBAAoB,EAAE,CAAC,EAAE,4BAA4B,EAAE,CAAC,EAAW,CAAC;AAEjI;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,KAAiC;IAC3E,MAAM,CAAC,GAAG,wBAAwB,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,cAAc,EAAE,OAAO,EAAE,oBAAoB,EAAE,eAAe,EAAE,cAAc,CAAC,EAAE,+BAA+B,CAAC,CAAC;IACpK,MAAM,GAAG,GAAG,CAAC,CAAC,GAAsB,EAAE,IAAI,GAAG,uBAAuB,CAAC,GAAG,CAAC,CAAC;IAC1E,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,oBAAoB,CAAC,MAAM,CAAC;IACtD,IAAI,MAAM,CAAC,IAAI,KAAK,iBAAiB;QAAE,uBAAuB,CAAC,GAAG,EAAE,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,YAAY,CAAC,UAAU,EAAE,MAAM,CAAC,gBAAgB,EAAE,MAAM,CAAC,iBAAiB,EAAE,CAAC,EAAE,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,YAAY,CAAC,WAAW,CAAC,CAAC;IAC3N,MAAM,KAAK,GAAG,6BAA6B,CAAC,CAAC,CAAC,YAAY,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,CAAC,oBAAoB,CAAC,MAAM,CAAC;IAC5H,IAAI,MAAM,CAAC,IAAI,KAAK,iBAAiB,IAAI,MAAM,CAAC,gBAAgB,KAAK,CAAC,IAAI,MAAM,CAAC,iBAAiB,KAAK,CAAC;QACtG,CAAC,GAAG,MAAM,CAAC,cAAc,CAAC,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,KAAK,sBAAsB,IAAI,KAAK,CAAC,UAAU,CAAC,IAAI,EAAE,KAAK,gBAAgB;QACnH,IAAI,CAAC,iFAAiF,CAAC,CAAC;IAC1F,IAAI,KAAK,CAAC,sBAAsB,KAAK,KAAK,CAAC,oBAAoB,CAAC,SAAS;QAAE,IAAI,CAAC,+CAA+C,CAAC,CAAC;IACjI,MAAM,QAAQ,GAAG,CAAC,CAAC,kBAAkB,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,kBAAkB,CAAC;IAC/E,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,EAAE;QAAE,IAAI,CAAC,+CAA+C,CAAC,CAAC;IACjJ,MAAM,aAAa,GAAG,CAAC,CAAC,aAAmC,CAAC;IAC5D,IAAI,aAAa,KAAK,SAAS,IAAI,CAAC,OAAO,aAAa,KAAK,QAAQ,IAAI,CAAC,0CAA0C,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC;QAClL,IAAI,CAAC,iDAAiD,CAAC,CAAC;IAC1D,IAAI,IAA8C,CAAC;IACnD,IAAI,CAAC;QAAC,IAAI,GAAG,uBAAuB,CAAC,CAAC,CAAC,YAAY,EAAE,cAAc,CAAC,CAAC;IAAC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAAC,IAAI,CAAE,KAAe,CAAC,OAAO,CAAC,CAAC;IAAC,CAAC;IAEzH,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,YAAY,EAAE,KAAK,GAAG,MAAM,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAAC,WAAW,EAAE,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,gBAAgB,CAAC;IAC/I,MAAM,MAAM,GAAG,CAAC,CAAC,aAAa,CAAC,UAAU,CAAC;IAC1C,MAAM,IAAI,GAAG,mCAAmC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,QAAQ,EAAE,YAAY,EAAE,CAAC,CAAC,aAAa,CAAC,MAAM,EAAE,WAAW,EAAE,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC,CAAC;IACrK,0EAA0E;IAC1E,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,KAAK,EAAE,EAAE,MAAM,GAAG,GAAG,CAAC,WAAW,CAAC,KAAK,EAAE,EAAE,KAAK,GAAG,GAAG,CAAC,eAAe,CAAC,KAAK,EAAE,EAAE,YAAY,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,wBAAwB,CAAC,CAAC;IAEhK,+FAA+F;IAC/F,MAAM,WAAW,GAAa,EAAE,EAAE,UAAU,GAAa,EAAE,EAAE,MAAM,GAAa,EAAE,EAAE,YAAY,GAAa,EAAE,CAAC;IAChH,KAAK,IAAI,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,EAAE;QAAE,KAAK,IAAI,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC;YAC7D,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC;YACzD,MAAM,KAAK,GAAG,MAAM,CAAC,EAAE,GAAG,KAAK,GAAG,EAAE,CAAE,CAAC;YACvC,KAAK,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC;gBAAE,KAAK,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,IAAI,CAAC;oBAAE,IAAI,MAAM,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC,CAAC,KAAK,KAAK;wBAAE,IAAI,CAAC,4DAA4D,CAAC,CAAC;YACjL,MAAM,OAAO,GAAG,MAAM,CAAC,cAAc,CAAC,EAAE,GAAG,CAAC,GAAG,EAAE,CAAE,CAAC;YACpD,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAAC,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,EAAE,GAAG,CAAC,GAAG,EAAE,CAAE,CAAC,CAAC;YAAC,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAAC,UAAU,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC;QAC3J,CAAC;IACD,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,CAAC;IACvC,IAAI,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,UAAU,CAAC;QAAE,IAAI,CAAC,qDAAqD,CAAC,CAAC;IAC1G,IAAI,aAAa,GAAG,CAAC,CAAC;IACtB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE;QAAE,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,CAAC,CAAE,GAAG,UAAU;YAAE,aAAa,EAAE,CAAC;IAErG,iHAAiH;IACjH,IAAI,YAAY,GAAoB,IAAI,CAAC;IACzC,IAAI,CAAC,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;QAC1B,MAAM,KAAK,GAAG,wBAAwB,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,+BAA+B,CAA6C,CAAC;QACvJ,YAAY,GAAG,EAAE,CAAC;QAClB,KAAK,MAAM,OAAO,IAAI,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,CAAC;YAC/C,MAAM,CAAC,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC;YACzB,IAAI,CAAC,CAAC;gBAAE,IAAI,CAAC,0CAA0C,CAAC,CAAC;YACzD,wBAAwB,CAAC,CAAC,EAAE,CAAC,gCAAgC,EAAE,uBAAuB,CAAC,EAAE,uCAAuC,CAAC,CAAC;YAClI,MAAM,IAAI,GAAG,CAAC,CAAC,8BAA8B,EAAE,IAAI,GAAG,CAAC,CAAC,qBAAqB,CAAC;YAC9E,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,IAAI,GAAG,CAAC;gBAAE,IAAI,CAAC,0DAA0D,CAAC,CAAC;YACxM,MAAM,WAAW,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,CAAC;YAC9E,IAAI,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,WAAW,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;gBAAC,YAAY,GAAG,IAAI,CAAC;gBAAC,MAAM;YAAC,CAAC;YAClF,MAAM,IAAI,GAAG,UAAU,GAAG,WAAW,CAAC,CAAC,CAAE,CAAC;YAC1C,YAAY,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC,IAAI,GAAG,IAAI,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC;QAC/F,CAAC;IACH,CAAC;IAED,gFAAgF;IAChF,MAAM,CAAC,GAAG,KAAK,CAAC,6BAA6B,EAAE,WAAW,GAAG,uBAAuB,CAAC,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,kBAAkB,CAAC;IACnI,MAAM,WAAW,GAAG,6BAA6B,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,YAAY,CAAC,GAAG,EAAE,MAAM,CAAC,YAAY,CAAC,KAAK,EAAE,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IACrJ,MAAM,WAAW,GAAG,yBAAyB,CAAC,WAAW,CAAC,CAAC;IAC3D,MAAM,IAAI,GAAG,yBAAyB,CAAC,EAAE,SAAS,EAAE,UAAU,EAAE,cAAc,EAAE,wBAAwB,EAAE,CAAC,iBAAiB;QAC1H,mBAAmB,EAAE,EAAE,CAAC,EAAE,iBAAiB,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,iBAAiB,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC;IAC5F,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAE,CAAC,CAAC,CAAE,GAAG,WAAW,CAAC,CAAC,CAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAE7H,MAAM,MAAM,GAAG,IAAI,UAAU,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,IAAI,GAAG,IAAI,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACpF,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;IACxD,MAAM,MAAM,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,iCAAiC,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,CAAC,cAAc,EAAE,iBAAiB,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;IACzK,MAAM,OAAO,GAAG,IAAI,UAAU,CAAC,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;IAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IAAC,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;IACvH,MAAM,eAAe,GAAG,CAAC,MAAM,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAC7D,MAAM,SAAS,GAAG,CAAC,MAAM,MAAM,CAAC,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAC/F,MAAM,iBAAiB,GAAG,0BAA0B,GAAG,KAAK,CAAC,SAAS,GAAG,GAAG,GAAG,KAAK,CAAC,cAAc,GAAG,GAAG,GAAG,SAAS,CAAC;IACtH,MAAM,WAAW,GAAG,WAAW,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;IACpE,MAAM,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,GAAG,WAAW,GAAG,kBAAkB,CAAC;IAC9E,MAAM,SAAS,GAAG,iEAAiE,GAAG,KAAK,CAAC,OAAO,GAAG,YAAY,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI;QAC5I,4DAA4D,CAAC;IAC/D,MAAM,cAAc,GAAG,CAAC,KAAyB,EAAmB,EAAE,CAAC,KAAK,KAAK,SAAS,IAAI,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC3H,MAAM,WAAW,GAAG,cAAc,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,SAAS,GAAG,GAAG,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC;IACvG,MAAM,QAAQ,GAAG,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACzC,GAAG,CAAC,cAAc,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACzE,QAAQ,CAAC,GAAG,EAAE,CAAC,EAAE,qBAAqB,CAAC,EAAE,GAAG,IAAI,EAAE,WAAW,EAAE,IAAI,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,GAAG,GAAG,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;KAAC,CAAC;IAEtJ,MAAM,IAAI,GAAG,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC,EAAE,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,SAAS,CAAC,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,EAAE,SAAS,CAAC,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;QACpJ,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACpJ,SAAS,CAAC,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACzI,GAAG,CAAC,aAAa,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,EAAE,aAAa,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,UAAU,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,KAAK,EAAE,QAAQ,CAAC,EAAE,KAAK,CAAC,KAAK,EAAE,aAAa,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAChM,MAAM,cAAc,GAAG,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,WAAW,CAAC,IAAI,EAAE,CAAC,EAAE,UAAU,GAAG,SAAS,CAAC,KAAK,EAAE,KAAK,EAAE,CAAC,GAAG,WAAW,CAAC,aAAa,CAAC,CAAC,CAAC;IACxI,MAAM,KAAK,GAAG,cAAc,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,WAAW,CAAC,EAAE,KAAK,CAAC,GAAG,EAAE,UAAU,CAAC,EAAE,KAAK,CAAC,GAAG,EAAE,yBAAyB,CAAC,EAAE,KAAK,CAAC,GAAG,EAAE,QAAQ,CAAC,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC;QACxK,OAAO,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC;QAChJ,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,QAAiB,EAAE,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAC1I,OAAO,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC,EAAE,UAAU,CAAC;QACpG,OAAO,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,KAAK,EAAE,iBAAiB,CAAC,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QACvJ,OAAO,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,KAAK,EAAE,KAAK,EAAE,WAAW,CAAC,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;QACnL,cAAc,EAAE,SAAS,CAAC,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,UAAU;QAC9D,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;QAC3D,QAAQ,CAAC,KAAK,EAAE,CAAC,EAAE,UAAU,CAAC,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,KAAK,CAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;QAC9F,OAAO,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;QAC1F,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC,EAAE,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;IAC/H,OAAO,MAAM,CAAC,MAAM,CAAC,EAAE,aAAa,EAAE,6BAA6B,EAAE,SAAS,EAAE,WAAoB,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC,KAAK,CAAC,EAAE,eAAe,EAAE,iBAAiB;QAC1K,UAAU,EAAE,EAAE,GAAG,MAAM,EAAE,EAAE,WAAW,EAAE,EAAE,GAAG,IAAI,EAAE,EAAE,WAAW,EAAE,WAAW,EAAE,UAAU,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,CAAC,cAAc,CAAC,EAAE,aAAa,EAAE,MAAM,CAAC,UAAU,CAAC;QAC9K,YAAY,EAAE,gCAAgC,EAAE,aAAa,EAAE,MAAM,EAAE,mBAA4B,EAAE,oBAAoB,EAAE,KAAc,EAAE,CAAC,CAAC;AACjJ,CAAC","sourcesContent":["// SPDX-License-Identifier: Apache-2.0\n// This product includes DNG technology under license by Adobe.\n\n/**\n * Writes a packed native RAW (`NativeRawOutput`, from the native RAW or native environment RAW tasks) as a\n * lossless, uncompressed 16-bit DNG with a CFA (colour filter array) mosaic.\n *\n * The file describes only what the packed RAW, the caller's declared colour profile and noise model\n * contain. It never claims a linear float master as its source, or a developed image. The tag layout reuses\n * the TIFF/DNG writers of the paired photographic export (`packExportTiff`, DNG 1.4 tags, Adobe DNG\n * Specification 1.7.1.0):\n *\n * - CFA geometry: CFARepeatPatternDim 2×2, CFAPattern and BlackLevel phases relative to the ActiveArea\n * origin (DNG applies them to the stage-2, ActiveArea-cropped image); DefaultCropOrigin/Size are the\n * capture's oriented output crop mapped back to stored (native) coordinates; Orientation from the capture.\n * - Levels: BlackLevel per 2×2 phase (the packed per-site black levels must repeat with the CFA tile).\n * WhiteLevel is the smallest per-phase effective white code, so no channel is reported as unsaturated\n * above its own saturation point. DNG cannot represent a saturation flag on a site whose code is below\n * WhiteLevel; such sites are counted in `unrepresentedSaturationFlagCount`.\n * - Colour: ColorMatrix1 = (camera→XYZ)⁻¹ with CalibrationIlluminant1 D65 (21), ForwardMatrix1 =\n * Bradford(D65→D50)·M·diag(w), AnalogBalance 1, AsShotNeutral from the capture's white-balance intent\n * (the same operator native development uses), BaselineExposure as declared (default 0).\n * - Noise: NoiseProfile (51041) per CFA plane, var(x) = S·x + O for x = (code − black)/(WhiteLevel − black),\n * S = 1/(G·span), O = (σ_read²/G² + 1/12)/span², written only when the caller supplies each channel's\n * output-referred conversion gain G (electrons per code) and read noise σ_read (electrons). The model\n * covers only Poisson photo and dark shot noise, Gaussian read noise and uniform quantization. It is an\n * approximation: PRNU (photo-response non-uniformity), DSNU (dark-signal non-uniformity) and other\n * fixed-pattern noise are not included.\n * - Text (2.4, only with `textMetadata`): the caller's description is appended to ImageDescription after the\n * simulated-RAW statement and the copyright is written as Copyright (33432), each only when it is printable\n * ASCII (TIFF 6.0 §2: ASCII fields hold 7-bit codes). An XMP packet in tag 700 (BYTE; XMP Specification Part 3\n * §1.1.6, Table 13) always carries every given field in UTF-8: `dc:description` (the full ImageDescription text,\n * statement first, as XMP Part 3 §3.2.3 maps tag 270), `dc:rights`, `xmp:CreatorTool` and `exif:UserComment`.\n * The Software tag keeps naming the engine's writer. Without `textMetadata` the bytes are unchanged.\n * @see docs/NATIVE_RAW_AND_PRINT.md for the tag table, limits and the round trip through parseDngRawImage.\n */\n\nimport { InvalidConfigurationError } from \"../core/configuration-error.js\";\nimport { requireAllowlistedRecord } from \"../core/record-validation.js\";\nimport { ENGINE_API_VERSION } from \"../core/version.js\";\nimport { resolveCaptureColorModel } from \"../color/capture-color.js\";\nimport { invertSensorColorMatrix, prepareSensorColorDevelopment, sensorColorReferenceWhite } from \"../color/sensor-color-development.js\";\nimport { ICC_D50_WHITE_XYZ } from \"../color/srgb-icc.js\";\nimport { chromaticAdaptationMatrix } from \"../color/chromatic-adaptation.js\";\nimport { transformOrientedRasterRectToNative } from \"../output/capture-geometry.js\";\nimport type { NativeRawOutput } from \"./native-raw.js\";\nimport { checkNativeRawIntegrity, validatePackedNativeRaw } from \"./native-raw-development.js\";\nimport { parseExportSensorColorProfile, type ExportSensorColorProfile } from \"./photographic-export.js\";\nimport { parseOutputTextMetadata, xmpTextMetadataPacket, type OutputTextMetadata } from \"../output/text-metadata.js\";\nimport { packExportTiff, exportTiffAscii as ascii, exportTiffNumbers as numbers, exportTiffRationals as rationals,\n exportTiffBytes as rawBytes, exportTiffDoubles as doubles } from \"./export-tiff.js\";\n\nexport const NATIVE_RAW_DNG_SCHEMA_VERSION = \"1.0.0\" as const;\n\n/** Output-referred noise parameters of one CFA channel (see the module notes). */\nexport interface NativeRawDngChannelNoise {\n /** Electrons per output RAW code (system conversion gain divided by any post-ADC digital gain). */\n conversionGainElectronsPerCode: number;\n /** Combined RMS read noise, electrons. */\n readNoiseRmsElectrons: number;\n}\nexport interface SerializeNativeRawDngInput {\n /** Packed native RAW. It is read, never taken over or modified. */\n raw: NativeRawOutput;\n /** Declared camera→XYZ (D65) colour profile for the RAW's CFA. Native development uses the same profile. */\n colorProfile: ExportSensorColorProfile;\n /** Optional NoiseProfile parameters by channel ID. If omitted, no NoiseProfile tag is written. */\n noise?: Readonly<Record<string, NativeRawDngChannelNoise>>;\n /** BaselineExposure in EV (exposure value stops). Default 0: the RAW white level maps to display white, as in native development. */\n baselineExposureEv?: number;\n /** Optional UTC time of the capture, exactly YYYY-MM-DDTHH:mm:ss.sssZ. If omitted, no date tags are written; the engine never makes up a clock time. */\n capturedAtUtc?: string;\n /** Optional (2.4) caller text: description, software, copyright, comment (see the module notes). If omitted, no text is added. */\n textMetadata?: OutputTextMetadata;\n}\nexport interface NativeRawDng {\n schemaVersion: typeof NATIVE_RAW_DNG_SCHEMA_VERSION;\n mediaType: \"image/dng\";\n bytes: Uint8Array;\n sha256: string;\n /** RawDataUniqueID (32 hex digits): the first 128 bits of SHA-256 over a fixed header and the little-endian codes. */\n rawDataUniqueId: string;\n uniqueCameraModel: string;\n /** Stored geometry, levels and colour values exactly as written (rationals as numerator/denominator). */\n activeArea: { x: number; y: number; width: number; height: number };\n defaultCrop: { x: number; y: number; width: number; height: number };\n orientation: number;\n blackLevels: readonly number[];\n whiteLevel: number;\n cfaPattern: readonly number[];\n colorMatrix1: readonly number[];\n asShotNeutral: readonly number[];\n noiseProfile: readonly number[] | null;\n /** Sites flagged saturated whose code is below WhiteLevel; DNG has no field for them. */\n unrepresentedSaturationFlagCount: number;\n source: \"packed-native-raw\";\n linearMasterDeclared: false;\n}\n\nfunction fail(message: string): never { throw new InvalidConfigurationError(\"Native RAW DNG: \" + message); }\nasync function sha256(bytes: Uint8Array): Promise<string> {\n const subtle = globalThis.crypto?.subtle;\n if (!subtle) fail(\"needs crypto.subtle (a secure browser context or Node 22+).\");\n return Array.from(new Uint8Array(await subtle.digest(\"SHA-256\", bytes as Uint8Array<ArrayBuffer>)), (b) => b.toString(16).padStart(2, \"0\")).join(\"\");\n}\n/** Values exactly as stored by a RATIONAL/SRATIONAL tag (numerator / denominator), so reported metadata equals what a reader decodes. */\nfunction stored(tag: ReturnType<typeof rationals>): number[] {\n const view = new DataView(tag.data.buffer, tag.data.byteOffset, tag.data.byteLength);\n return Array.from({ length: tag.count }, (_, i) => (tag.type === 10 ? view.getInt32(i * 8, true) : view.getUint32(i * 8, true)) / view.getUint32(i * 8 + 4, true));\n}\nconst ORIENTATION = { landscape: 1, \"portrait-clockwise\": 6, \"landscape-inverted\": 3, \"portrait-counter-clockwise\": 8 } as const;\n\n/**\n * Writes packed native RAW codes as a lossless, uncompressed CFA DNG. The module notes list every tag and\n * where its value comes from. The input arrays are copied before the first await.\n */\nexport async function serializeNativeRawDng(input: SerializeNativeRawDngInput): Promise<NativeRawDng> {\n const r = requireAllowlistedRecord(input, [\"raw\", \"colorProfile\", \"noise\", \"baselineExposureEv\", \"capturedAtUtc\", \"textMetadata\"], \"Invalid native RAW DNG input.\");\n const raw = r.raw as NativeRawOutput, plan = validatePackedNativeRaw(raw);\n const mosaic = plan.frame.colorSamplingProfile.layout;\n if (mosaic.kind === \"periodic-mosaic\") checkNativeRawIntegrity(raw, plan.exposure.geometry.nativeRaster.pixelWidth, mosaic.repeatWidthSites, mosaic.repeatHeightSites, 0, plan.exposure.geometry.nativeRaster.pixelHeight);\n const color = parseExportSensorColorProfile(r.colorProfile), frame = plan.frame, layout = frame.colorSamplingProfile.layout;\n if (layout.kind !== \"periodic-mosaic\" || layout.repeatWidthSites !== 2 || layout.repeatHeightSites !== 2 ||\n [...layout.siteChannelIds].sort().join() !== \"blue,green,green,red\" || color.channelIds.join() !== \"red,green,blue\")\n fail(\"supports 2×2 RGB Bayer CFAs with red, green, blue colour-profile channels only.\");\n if (color.colorSamplingProfileId !== frame.colorSamplingProfile.profileId) fail(\"colour profile is not bound to the RAW's CFA.\");\n const baseline = r.baselineExposureEv === undefined ? 0 : r.baselineExposureEv;\n if (typeof baseline !== \"number\" || !Number.isFinite(baseline) || Math.abs(baseline) > 16) fail(\"baselineExposureEv must be finite within ±16.\");\n const capturedAtUtc = r.capturedAtUtc as string | undefined;\n if (capturedAtUtc !== undefined && (typeof capturedAtUtc !== \"string\" || !/^\\d{4}-\\d\\d-\\d\\dT\\d\\d:\\d\\d:\\d\\d\\.\\d{3}Z$/.test(capturedAtUtc) || Number.isNaN(Date.parse(capturedAtUtc))))\n fail(\"capturedAtUtc must be YYYY-MM-DDTHH:mm:ss.sssZ.\");\n let text: Readonly<OutputTextMetadata> | undefined;\n try { text = parseOutputTextMetadata(r.textMetadata, \"textMetadata\"); } catch (error) { fail((error as Error).message); }\n\n const native = plan.exposure.geometry.nativeRaster, width = native.pixelWidth, height = native.pixelHeight, g = plan.exposure.resolvedGeometry;\n const active = g.activeCapture.nativeRect;\n const crop = transformOrientedRasterRectToNative({ rect: g.output.cropRect, nativeRaster: g.activeCapture.raster, orientation: plan.exposure.geometry.orientation });\n // Copy before any await: the caller keeps ownership of the packed arrays.\n const codes = raw.codes.slice(), blacks = raw.blackLevels.slice(), flags = raw.saturationFlags.slice(), whiteByPhase = Array.from(raw.effectiveSaturationCodes);\n\n // Levels per CFA phase, relative to the active area. The black-level tile must repeat exactly.\n const blackLevels: number[] = [], cfaPattern: number[] = [], whites: number[] = [], phaseChannel: string[] = [];\n for (let py = 0; py < 2; py++) for (let px = 0; px < 2; px++) {\n const ax = (active.x + px) % 2, ay = (active.y + py) % 2;\n const black = blacks[ay * width + ax]!;\n for (let y = ay; y < height; y += 2) for (let x = ax; x < width; x += 2) if (blacks[y * width + x] !== black) fail(\"per-site black levels do not repeat with the 2×2 CFA tile.\");\n const channel = layout.siteChannelIds[ay * 2 + ax]!;\n blackLevels.push(black); whites.push(whiteByPhase[ay * 2 + ax]!); phaseChannel.push(channel); cfaPattern.push([\"red\", \"green\", \"blue\"].indexOf(channel));\n }\n const whiteLevel = Math.min(...whites);\n if (blackLevels.some((b) => b >= whiteLevel)) fail(\"black level must be below the effective WhiteLevel.\");\n let unrepresented = 0;\n for (let i = 0; i < codes.length; i++) if (flags[i] !== 0 && codes[i]! < whiteLevel) unrepresented++;\n\n // NoiseProfile: one (S, O) pair per CFA plane colour, only when every phase of a channel shares its black level.\n let noiseProfile: number[] | null = null;\n if (r.noise !== undefined) {\n const noise = requireAllowlistedRecord(r.noise, [\"red\", \"green\", \"blue\"], \"Invalid native RAW DNG noise.\") as Record<string, NativeRawDngChannelNoise>;\n noiseProfile = [];\n for (const channel of [\"red\", \"green\", \"blue\"]) {\n const n = noise[channel];\n if (!n) fail(\"noise needs red, green and blue entries.\");\n requireAllowlistedRecord(n, [\"conversionGainElectronsPerCode\", \"readNoiseRmsElectrons\"], \"Invalid native RAW DNG channel noise.\");\n const gain = n.conversionGainElectronsPerCode, read = n.readNoiseRmsElectrons;\n if (typeof gain !== \"number\" || !Number.isFinite(gain) || gain <= 0 || typeof read !== \"number\" || !Number.isFinite(read) || read < 0) fail(\"noise gain must be positive and read noise non-negative.\");\n const phaseBlacks = blackLevels.filter((_, i) => phaseChannel[i] === channel);\n if (phaseBlacks.some((b) => b !== phaseBlacks[0])) { noiseProfile = null; break; }\n const span = whiteLevel - phaseBlacks[0]!;\n noiseProfile.push(1 / (gain * span), (read * read / (gain * gain) + 1 / 12) / (span * span));\n }\n }\n\n // Colour tags from the declared profile and the capture's white-balance intent.\n const m = color.normalizedCameraChannelsToXyz, colorMatrix = invertSensorColorMatrix(m), intent = plan.exposure.whiteBalanceIntent;\n const development = prepareSensorColorDevelopment(m, intent ? [intent.channelGains.red, intent.channelGains.green, intent.channelGains.blue] : null);\n const cameraWhite = sensorColorReferenceWhite(colorMatrix);\n const chad = chromaticAdaptationMatrix({ transform: \"bradford\", sourceWhiteXyz: resolveCaptureColorModel().referenceWhiteXyz,\n destinationWhiteXyz: { x: ICC_D50_WHITE_XYZ[0], y: 1, z: ICC_D50_WHITE_XYZ[2] } }).matrix;\n const forward = chad.map((row) => [0, 1, 2].map((j) => row.reduce((sum, x, k) => sum + x * m[k]![j]! * cameraWhite[j]!, 0)));\n\n const pixels = new Uint8Array(codes.length * 2), view = new DataView(pixels.buffer);\n codes.forEach((c, i) => view.setUint16(i * 2, c, true));\n const header = new TextEncoder().encode(JSON.stringify({ schema: \"photivra-native-raw-data-id-0.1\", width, height, cfa: layout.siteChannelIds, containerBitDepth: 16 }));\n const idInput = new Uint8Array(header.length + pixels.length); idInput.set(header); idInput.set(pixels, header.length);\n const rawDataUniqueId = (await sha256(idInput)).slice(0, 32);\n const colorHash = (await sha256(new TextEncoder().encode(JSON.stringify(color)))).slice(0, 16);\n const uniqueCameraModel = \"Photivra Virtual Camera \" + color.profileId + \" \" + color.profileVersion + \" \" + colorHash;\n const orientation = ORIENTATION[plan.exposure.geometry.orientation];\n const e = plan.exposure.exposure, software = \"Photivra \" + ENGINE_API_VERSION;\n const statement = \"Simulated capture: packed native RAW from the Photivra engine (\" + frame.frameId + \"). Source \" + plan.exposure.source.kind +\n \"; no linear master image or developed rendering is stored.\";\n const printableAscii = (value: string | undefined): value is string => value !== undefined && /^[\\x20-\\x7e]*$/.test(value);\n const description = printableAscii(text?.description) ? statement + \" \" + text.description : statement;\n const textTags = text === undefined ? [] : [\n ...(printableAscii(text.copyright) ? [ascii(33432, text.copyright)] : []),\n rawBytes(700, 1, xmpTextMetadataPacket({ ...text, description: text.description === undefined ? statement : statement + \" \" + text.description }))];\n\n const exif = [rawBytes(36864, 7, new TextEncoder().encode(\"0232\")), rationals(33434, false, [e.shutterSeconds]), rationals(33437, false, [e.aperture]),\n ...(Number.isInteger(e.iso) && e.iso >= 1 && e.iso <= 65535 ? [numbers(34855, 3, [e.iso]), numbers(34864, 3, [2]), numbers(34866, 4, [e.iso])] : []),\n rationals(37386, false, [e.focalLengthMm]), numbers(40961, 3, [65535]), numbers(40962, 4, [crop.width]), numbers(40963, 4, [crop.height]),\n ...(capturedAtUtc === undefined ? [] : [ascii(36867, capturedAtUtc.slice(0, 19).replaceAll(\"-\", \":\").replace(\"T\", \" \")), ascii(36881, \"+00:00\"), ascii(37521, capturedAtUtc.slice(20, 23))])];\n const colorMatrixTag = rationals(50721, true, colorMatrix.flat()), neutralTag = rationals(50728, false, [...development.asShotNeutral]);\n const bytes = packExportTiff([ascii(270, description), ascii(271, \"Photivra\"), ascii(272, \"Photivra Virtual Camera\"), ascii(305, software), numbers(274, 3, [orientation]),\n numbers(254, 4, [0]), numbers(256, 4, [width]), numbers(257, 4, [height]), numbers(258, 3, [16]), numbers(259, 3, [1]), numbers(262, 3, [32803]),\n { ...numbers(273, 4, [0]), pointer: \"pixels\" as const }, numbers(277, 3, [1]), numbers(278, 4, [height]), numbers(279, 4, [pixels.length]),\n numbers(284, 3, [1]), numbers(339, 3, [1]), numbers(33421, 3, [2, 2]), numbers(33422, 1, cfaPattern),\n numbers(50706, 1, [1, 4, 0, 0]), numbers(50707, 1, [1, 1, 0, 0]), ascii(50708, uniqueCameraModel), numbers(50710, 1, [0, 1, 2]), numbers(50711, 3, [1]),\n numbers(50713, 3, [2, 2]), rationals(50714, false, blackLevels), numbers(50717, 4, [whiteLevel]), numbers(50719, 4, [crop.x, crop.y]), numbers(50720, 4, [crop.width, crop.height]),\n colorMatrixTag, rationals(50727, false, [1, 1, 1]), neutralTag,\n rationals(50730, true, [baseline]), numbers(50778, 3, [21]),\n rawBytes(50781, 1, Uint8Array.from(rawDataUniqueId.match(/../g)!.map((s) => parseInt(s, 16)))),\n numbers(50829, 4, [active.y, active.x, active.y + active.height, active.x + active.width]),\n rationals(50964, true, forward.flat()), ...(noiseProfile ? [doubles(51041, noiseProfile)] : []), ...textTags], exif, pixels);\n return Object.freeze({ schemaVersion: NATIVE_RAW_DNG_SCHEMA_VERSION, mediaType: \"image/dng\" as const, bytes, sha256: await sha256(bytes), rawDataUniqueId, uniqueCameraModel,\n activeArea: { ...active }, defaultCrop: { ...crop }, orientation, blackLevels, whiteLevel, cfaPattern, colorMatrix1: stored(colorMatrixTag), asShotNeutral: stored(neutralTag),\n noiseProfile, unrepresentedSaturationFlagCount: unrepresented, source: \"packed-native-raw\" as const, linearMasterDeclared: false as const });\n}\n"]}
1
+ {"version":3,"file":"native-raw-dng.js","sourceRoot":"","sources":["../../src/capture/native-raw-dng.ts"],"names":[],"mappings":"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","sourcesContent":["// SPDX-License-Identifier: Apache-2.0\n// This product includes DNG technology under license by Adobe.\n\n/**\n * Writes a packed native RAW (`NativeRawOutput`, from the native RAW or native environment RAW tasks) as a\n * lossless, uncompressed 16-bit DNG with a CFA (colour filter array) mosaic.\n *\n * The file describes only what the packed RAW, the caller's declared colour profile and noise model\n * contain. It never claims a linear float master as its source, or a developed image. The tag layout reuses\n * the TIFF/DNG writers of the paired photographic export (`packExportTiff`, DNG 1.4 tags, Adobe DNG\n * Specification 1.7.1.0):\n *\n * - CFA geometry: CFARepeatPatternDim 2×2, CFAPattern and BlackLevel phases relative to the ActiveArea\n * origin (DNG applies them to the stage-2, ActiveArea-cropped image); DefaultCropOrigin/Size are the\n * capture's oriented output crop mapped back to stored (native) coordinates; Orientation from the capture.\n * - Levels: BlackLevel per 2×2 phase (the packed per-site black levels must repeat with the CFA tile).\n * WhiteLevel is the smallest per-phase effective white code, so no channel is reported as unsaturated\n * above its own saturation point. DNG cannot represent a saturation flag on a site whose code is below\n * WhiteLevel; such sites are counted in `unrepresentedSaturationFlagCount`.\n * - Colour: ColorMatrix1 = (camera→XYZ)⁻¹ with CalibrationIlluminant1 D65 (21), ForwardMatrix1 =\n * Bradford(D65→D50)·M·diag(w), AnalogBalance 1, AsShotNeutral from the capture's white-balance intent\n * (the same operator native development uses), BaselineExposure as declared (default 0).\n * - Noise: NoiseProfile (51041) per CFA plane, var(x) = S·x + O for x = (code − black)/(WhiteLevel − black),\n * S = 1/(G·span), O = (σ_read²/G² + 1/12)/span², written only when the caller supplies each channel's\n * output-referred conversion gain G (electrons per code) and read noise σ_read (electrons). The model\n * covers only Poisson photo and dark shot noise, Gaussian read noise and uniform quantization. It is an\n * approximation: PRNU (photo-response non-uniformity), DSNU (dark-signal non-uniformity) and other\n * fixed-pattern noise are not included.\n * - Text (2.4, only with `textMetadata`): the caller's description is appended to ImageDescription after the\n * simulated-RAW statement and the copyright is written as Copyright (33432), each only when it is printable\n * ASCII (TIFF 6.0 §2: ASCII fields hold 7-bit codes). An XMP packet in tag 700 (BYTE; XMP Specification Part 3\n * §1.1.6, Table 13) always carries every given field in UTF-8: `dc:description` (the full ImageDescription text,\n * statement first, as XMP Part 3 §3.2.3 maps tag 270), `dc:rights`, `xmp:CreatorTool` and `exif:UserComment`.\n * The Software tag keeps naming the engine's writer. Without `textMetadata` the bytes are unchanged.\n * - Opcodes (#587, only with `opcodeList3`): the caller's big-endian DNG opcode list as OpcodeList3 (51022, UNDEFINED), framing checked\n * (count, 16-byte headers, parameter sizes filling the bytes). Without it the bytes are unchanged.\n * @see docs/NATIVE_RAW_AND_PRINT.md for the tag table, limits and the round trip through parseDngRawImage.\n */\n\nimport { InvalidConfigurationError } from \"../core/configuration-error.js\";\nimport { requireAllowlistedRecord } from \"../core/record-validation.js\";\nimport { ENGINE_API_VERSION } from \"../core/version.js\";\nimport { resolveCaptureColorModel } from \"../color/capture-color.js\";\nimport { invertSensorColorMatrix, prepareSensorColorDevelopment, sensorColorReferenceWhite } from \"../color/sensor-color-development.js\";\nimport { ICC_D50_WHITE_XYZ } from \"../color/srgb-icc.js\";\nimport { chromaticAdaptationMatrix } from \"../color/chromatic-adaptation.js\";\nimport { transformOrientedRasterRectToNative } from \"../output/capture-geometry.js\";\nimport type { NativeRawOutput } from \"./native-raw.js\";\nimport { checkNativeRawIntegrity, validatePackedNativeRaw } from \"./native-raw-development.js\";\nimport { parseExportSensorColorProfile, type ExportSensorColorProfile } from \"./photographic-export.js\";\nimport { parseOutputTextMetadata, xmpTextMetadataPacket, type OutputTextMetadata } from \"../output/text-metadata.js\";\nimport { packExportTiff, exportTiffAscii as ascii, exportTiffNumbers as numbers, exportTiffRationals as rationals,\n exportTiffBytes as rawBytes, exportTiffDoubles as doubles } from \"./export-tiff.js\";\n\nexport const NATIVE_RAW_DNG_SCHEMA_VERSION = \"1.0.0\" as const;\n\n/** Output-referred noise parameters of one CFA channel (see the module notes). */\nexport interface NativeRawDngChannelNoise {\n /** Electrons per output RAW code (system conversion gain divided by any post-ADC digital gain). */\n conversionGainElectronsPerCode: number;\n /** Combined RMS read noise, electrons. */\n readNoiseRmsElectrons: number;\n}\nexport interface SerializeNativeRawDngInput {\n /** Packed native RAW. It is read, never taken over or modified. */\n raw: NativeRawOutput;\n /** Declared camera→XYZ (D65) colour profile for the RAW's CFA. Native development uses the same profile. */\n colorProfile: ExportSensorColorProfile;\n /** Optional NoiseProfile parameters by channel ID. If omitted, no NoiseProfile tag is written. */\n noise?: Readonly<Record<string, NativeRawDngChannelNoise>>;\n /** BaselineExposure in EV (exposure value stops). Default 0: the RAW white level maps to display white, as in native development. */\n baselineExposureEv?: number;\n /** Optional UTC time of the capture, exactly YYYY-MM-DDTHH:mm:ss.sssZ. If omitted, no date tags are written; the engine never makes up a clock time. */\n capturedAtUtc?: string;\n /** Optional (2.4) caller text: description, software, copyright, comment (see the module notes). If omitted, no text is added. */\n textMetadata?: OutputTextMetadata;\n /**\n * Optional (#587) OpcodeList3 (tag 51022) bytes, for example `createDngLensCorrectionOpcodes(...).opcodeList3`: a big-endian DNG\n * opcode list (DNG 1.3.0.0+, \"Opcode List Processing\") that readers apply to the demosaiced stage-3 image. Only its framing is\n * checked (count, per-opcode headers and parameter sizes filling the bytes exactly). The RAW codes are unchanged. If omitted, no tag.\n */\n opcodeList3?: Uint8Array;\n}\nexport interface NativeRawDng {\n schemaVersion: typeof NATIVE_RAW_DNG_SCHEMA_VERSION;\n mediaType: \"image/dng\";\n bytes: Uint8Array;\n sha256: string;\n /** RawDataUniqueID (32 hex digits): the first 128 bits of SHA-256 over a fixed header and the little-endian codes. */\n rawDataUniqueId: string;\n uniqueCameraModel: string;\n /** Stored geometry, levels and colour values exactly as written (rationals as numerator/denominator). */\n activeArea: { x: number; y: number; width: number; height: number };\n defaultCrop: { x: number; y: number; width: number; height: number };\n orientation: number;\n blackLevels: readonly number[];\n whiteLevel: number;\n cfaPattern: readonly number[];\n colorMatrix1: readonly number[];\n asShotNeutral: readonly number[];\n noiseProfile: readonly number[] | null;\n /** Sites flagged saturated whose code is below WhiteLevel; DNG has no field for them. */\n unrepresentedSaturationFlagCount: number;\n source: \"packed-native-raw\";\n linearMasterDeclared: false;\n}\n\nfunction fail(message: string): never { throw new InvalidConfigurationError(\"Native RAW DNG: \" + message); }\nasync function sha256(bytes: Uint8Array): Promise<string> {\n const subtle = globalThis.crypto?.subtle;\n if (!subtle) fail(\"needs crypto.subtle (a secure browser context or Node 22+).\");\n return Array.from(new Uint8Array(await subtle.digest(\"SHA-256\", bytes as Uint8Array<ArrayBuffer>)), (b) => b.toString(16).padStart(2, \"0\")).join(\"\");\n}\n/** Values exactly as stored by a RATIONAL/SRATIONAL tag (numerator / denominator), so reported metadata equals what a reader decodes. */\nfunction stored(tag: ReturnType<typeof rationals>): number[] {\n const view = new DataView(tag.data.buffer, tag.data.byteOffset, tag.data.byteLength);\n return Array.from({ length: tag.count }, (_, i) => (tag.type === 10 ? view.getInt32(i * 8, true) : view.getUint32(i * 8, true)) / view.getUint32(i * 8 + 4, true));\n}\nconst ORIENTATION = { landscape: 1, \"portrait-clockwise\": 6, \"landscape-inverted\": 3, \"portrait-counter-clockwise\": 8 } as const;\n\n/**\n * Writes packed native RAW codes as a lossless, uncompressed CFA DNG. The module notes list every tag and\n * where its value comes from. The input arrays are copied before the first await.\n */\nexport async function serializeNativeRawDng(input: SerializeNativeRawDngInput): Promise<NativeRawDng> {\n const r = requireAllowlistedRecord(input, [\"raw\", \"colorProfile\", \"noise\", \"baselineExposureEv\", \"capturedAtUtc\", \"textMetadata\", \"opcodeList3\"], \"Invalid native RAW DNG input.\");\n let opcodeList3: Uint8Array | undefined;\n if (r.opcodeList3 !== undefined) {\n if (!(r.opcodeList3 instanceof Uint8Array) || r.opcodeList3.length < 4) fail(\"opcodeList3 must be a Uint8Array opcode list.\");\n opcodeList3 = r.opcodeList3.slice();\n const v = new DataView(opcodeList3.buffer);\n let at = 4;\n for (let n = v.getUint32(0); n > 0 && at <= opcodeList3.length; n--) at = at + 16 > opcodeList3.length ? Infinity : at + 16 + v.getUint32(at + 12);\n if (at !== opcodeList3.length) fail(\"opcodeList3 is not a whole DNG opcode list (big-endian count, 16-byte headers, parameter sizes).\");\n }\n const raw = r.raw as NativeRawOutput, plan = validatePackedNativeRaw(raw);\n const mosaic = plan.frame.colorSamplingProfile.layout;\n if (mosaic.kind === \"periodic-mosaic\") checkNativeRawIntegrity(raw, plan.exposure.geometry.nativeRaster.pixelWidth, mosaic.repeatWidthSites, mosaic.repeatHeightSites, 0, plan.exposure.geometry.nativeRaster.pixelHeight);\n const color = parseExportSensorColorProfile(r.colorProfile), frame = plan.frame, layout = frame.colorSamplingProfile.layout;\n if (layout.kind !== \"periodic-mosaic\" || layout.repeatWidthSites !== 2 || layout.repeatHeightSites !== 2 ||\n [...layout.siteChannelIds].sort().join() !== \"blue,green,green,red\" || color.channelIds.join() !== \"red,green,blue\")\n fail(\"supports 2×2 RGB Bayer CFAs with red, green, blue colour-profile channels only.\");\n if (color.colorSamplingProfileId !== frame.colorSamplingProfile.profileId) fail(\"colour profile is not bound to the RAW's CFA.\");\n const baseline = r.baselineExposureEv === undefined ? 0 : r.baselineExposureEv;\n if (typeof baseline !== \"number\" || !Number.isFinite(baseline) || Math.abs(baseline) > 16) fail(\"baselineExposureEv must be finite within ±16.\");\n const capturedAtUtc = r.capturedAtUtc as string | undefined;\n if (capturedAtUtc !== undefined && (typeof capturedAtUtc !== \"string\" || !/^\\d{4}-\\d\\d-\\d\\dT\\d\\d:\\d\\d:\\d\\d\\.\\d{3}Z$/.test(capturedAtUtc) || Number.isNaN(Date.parse(capturedAtUtc))))\n fail(\"capturedAtUtc must be YYYY-MM-DDTHH:mm:ss.sssZ.\");\n let text: Readonly<OutputTextMetadata> | undefined;\n try { text = parseOutputTextMetadata(r.textMetadata, \"textMetadata\"); } catch (error) { fail((error as Error).message); }\n\n const native = plan.exposure.geometry.nativeRaster, width = native.pixelWidth, height = native.pixelHeight, g = plan.exposure.resolvedGeometry;\n const active = g.activeCapture.nativeRect;\n const crop = transformOrientedRasterRectToNative({ rect: g.output.cropRect, nativeRaster: g.activeCapture.raster, orientation: plan.exposure.geometry.orientation });\n // Copy before any await: the caller keeps ownership of the packed arrays.\n const codes = raw.codes.slice(), blacks = raw.blackLevels.slice(), flags = raw.saturationFlags.slice(), whiteByPhase = Array.from(raw.effectiveSaturationCodes);\n\n // Levels per CFA phase, relative to the active area. The black-level tile must repeat exactly.\n const blackLevels: number[] = [], cfaPattern: number[] = [], whites: number[] = [], phaseChannel: string[] = [];\n for (let py = 0; py < 2; py++) for (let px = 0; px < 2; px++) {\n const ax = (active.x + px) % 2, ay = (active.y + py) % 2;\n const black = blacks[ay * width + ax]!;\n for (let y = ay; y < height; y += 2) for (let x = ax; x < width; x += 2) if (blacks[y * width + x] !== black) fail(\"per-site black levels do not repeat with the 2×2 CFA tile.\");\n const channel = layout.siteChannelIds[ay * 2 + ax]!;\n blackLevels.push(black); whites.push(whiteByPhase[ay * 2 + ax]!); phaseChannel.push(channel); cfaPattern.push([\"red\", \"green\", \"blue\"].indexOf(channel));\n }\n const whiteLevel = Math.min(...whites);\n if (blackLevels.some((b) => b >= whiteLevel)) fail(\"black level must be below the effective WhiteLevel.\");\n let unrepresented = 0;\n for (let i = 0; i < codes.length; i++) if (flags[i] !== 0 && codes[i]! < whiteLevel) unrepresented++;\n\n // NoiseProfile: one (S, O) pair per CFA plane colour, only when every phase of a channel shares its black level.\n let noiseProfile: number[] | null = null;\n if (r.noise !== undefined) {\n const noise = requireAllowlistedRecord(r.noise, [\"red\", \"green\", \"blue\"], \"Invalid native RAW DNG noise.\") as Record<string, NativeRawDngChannelNoise>;\n noiseProfile = [];\n for (const channel of [\"red\", \"green\", \"blue\"]) {\n const n = noise[channel];\n if (!n) fail(\"noise needs red, green and blue entries.\");\n requireAllowlistedRecord(n, [\"conversionGainElectronsPerCode\", \"readNoiseRmsElectrons\"], \"Invalid native RAW DNG channel noise.\");\n const gain = n.conversionGainElectronsPerCode, read = n.readNoiseRmsElectrons;\n if (typeof gain !== \"number\" || !Number.isFinite(gain) || gain <= 0 || typeof read !== \"number\" || !Number.isFinite(read) || read < 0) fail(\"noise gain must be positive and read noise non-negative.\");\n const phaseBlacks = blackLevels.filter((_, i) => phaseChannel[i] === channel);\n if (phaseBlacks.some((b) => b !== phaseBlacks[0])) { noiseProfile = null; break; }\n const span = whiteLevel - phaseBlacks[0]!;\n noiseProfile.push(1 / (gain * span), (read * read / (gain * gain) + 1 / 12) / (span * span));\n }\n }\n\n // Colour tags from the declared profile and the capture's white-balance intent.\n const m = color.normalizedCameraChannelsToXyz, colorMatrix = invertSensorColorMatrix(m), intent = plan.exposure.whiteBalanceIntent;\n const development = prepareSensorColorDevelopment(m, intent ? [intent.channelGains.red, intent.channelGains.green, intent.channelGains.blue] : null);\n const cameraWhite = sensorColorReferenceWhite(colorMatrix);\n const chad = chromaticAdaptationMatrix({ transform: \"bradford\", sourceWhiteXyz: resolveCaptureColorModel().referenceWhiteXyz,\n destinationWhiteXyz: { x: ICC_D50_WHITE_XYZ[0], y: 1, z: ICC_D50_WHITE_XYZ[2] } }).matrix;\n const forward = chad.map((row) => [0, 1, 2].map((j) => row.reduce((sum, x, k) => sum + x * m[k]![j]! * cameraWhite[j]!, 0)));\n\n const pixels = new Uint8Array(codes.length * 2), view = new DataView(pixels.buffer);\n codes.forEach((c, i) => view.setUint16(i * 2, c, true));\n const header = new TextEncoder().encode(JSON.stringify({ schema: \"photivra-native-raw-data-id-0.1\", width, height, cfa: layout.siteChannelIds, containerBitDepth: 16 }));\n const idInput = new Uint8Array(header.length + pixels.length); idInput.set(header); idInput.set(pixels, header.length);\n const rawDataUniqueId = (await sha256(idInput)).slice(0, 32);\n const colorHash = (await sha256(new TextEncoder().encode(JSON.stringify(color)))).slice(0, 16);\n const uniqueCameraModel = \"Photivra Virtual Camera \" + color.profileId + \" \" + color.profileVersion + \" \" + colorHash;\n const orientation = ORIENTATION[plan.exposure.geometry.orientation];\n const e = plan.exposure.exposure, software = \"Photivra \" + ENGINE_API_VERSION;\n const statement = \"Simulated capture: packed native RAW from the Photivra engine (\" + frame.frameId + \"). Source \" + plan.exposure.source.kind +\n \"; no linear master image or developed rendering is stored.\";\n const printableAscii = (value: string | undefined): value is string => value !== undefined && /^[\\x20-\\x7e]*$/.test(value);\n const description = printableAscii(text?.description) ? statement + \" \" + text.description : statement;\n const textTags = text === undefined ? [] : [\n ...(printableAscii(text.copyright) ? [ascii(33432, text.copyright)] : []),\n rawBytes(700, 1, xmpTextMetadataPacket({ ...text, description: text.description === undefined ? statement : statement + \" \" + text.description }))];\n\n const exif = [rawBytes(36864, 7, new TextEncoder().encode(\"0232\")), rationals(33434, false, [e.shutterSeconds]), rationals(33437, false, [e.aperture]),\n ...(Number.isInteger(e.iso) && e.iso >= 1 && e.iso <= 65535 ? [numbers(34855, 3, [e.iso]), numbers(34864, 3, [2]), numbers(34866, 4, [e.iso])] : []),\n rationals(37386, false, [e.focalLengthMm]), numbers(40961, 3, [65535]), numbers(40962, 4, [crop.width]), numbers(40963, 4, [crop.height]),\n ...(capturedAtUtc === undefined ? [] : [ascii(36867, capturedAtUtc.slice(0, 19).replaceAll(\"-\", \":\").replace(\"T\", \" \")), ascii(36881, \"+00:00\"), ascii(37521, capturedAtUtc.slice(20, 23))])];\n const colorMatrixTag = rationals(50721, true, colorMatrix.flat()), neutralTag = rationals(50728, false, [...development.asShotNeutral]);\n const bytes = packExportTiff([ascii(270, description), ascii(271, \"Photivra\"), ascii(272, \"Photivra Virtual Camera\"), ascii(305, software), numbers(274, 3, [orientation]),\n numbers(254, 4, [0]), numbers(256, 4, [width]), numbers(257, 4, [height]), numbers(258, 3, [16]), numbers(259, 3, [1]), numbers(262, 3, [32803]),\n { ...numbers(273, 4, [0]), pointer: \"pixels\" as const }, numbers(277, 3, [1]), numbers(278, 4, [height]), numbers(279, 4, [pixels.length]),\n numbers(284, 3, [1]), numbers(339, 3, [1]), numbers(33421, 3, [2, 2]), numbers(33422, 1, cfaPattern),\n numbers(50706, 1, [1, 4, 0, 0]), numbers(50707, 1, [1, 1, 0, 0]), ascii(50708, uniqueCameraModel), numbers(50710, 1, [0, 1, 2]), numbers(50711, 3, [1]),\n numbers(50713, 3, [2, 2]), rationals(50714, false, blackLevels), numbers(50717, 4, [whiteLevel]), numbers(50719, 4, [crop.x, crop.y]), numbers(50720, 4, [crop.width, crop.height]),\n colorMatrixTag, rationals(50727, false, [1, 1, 1]), neutralTag,\n rationals(50730, true, [baseline]), numbers(50778, 3, [21]),\n rawBytes(50781, 1, Uint8Array.from(rawDataUniqueId.match(/../g)!.map((s) => parseInt(s, 16)))),\n numbers(50829, 4, [active.y, active.x, active.y + active.height, active.x + active.width]),\n rationals(50964, true, forward.flat()), ...(noiseProfile ? [doubles(51041, noiseProfile)] : []), ...(opcodeList3 ? [rawBytes(51022, 7, opcodeList3)] : []), ...textTags], exif, pixels);\n return Object.freeze({ schemaVersion: NATIVE_RAW_DNG_SCHEMA_VERSION, mediaType: \"image/dng\" as const, bytes, sha256: await sha256(bytes), rawDataUniqueId, uniqueCameraModel,\n activeArea: { ...active }, defaultCrop: { ...crop }, orientation, blackLevels, whiteLevel, cfaPattern, colorMatrix1: stored(colorMatrixTag), asShotNeutral: stored(neutralTag),\n noiseProfile, unrepresentedSaturationFlagCount: unrepresented, source: \"packed-native-raw\" as const, linearMasterDeclared: false as const });\n}\n"]}
@@ -11,39 +11,9 @@
11
11
  import { InvalidScientificInputError } from "../core/validation.js";
12
12
  import { parseGenericReleaseCapabilityProfile } from "../equipment/release-capabilities.js";
13
13
  import { parseFocusPlane } from "../optics/focus-state.js";
14
- import { requireInputKeys } from "../core/record-validation.js";
15
- import { InvalidConfigurationError } from "../core/configuration-error.js";
14
+ import { requireInputKeys, requireTrimmedConfigString as requireNonEmptyString, requireInputFinite as requireFinite, requireInputFiniteAboveZero as requirePositiveFinite, requireInputFiniteAtLeastZero as requireNonNegativeFinite } from "../core/record-validation.js";
15
+ import { deepFreeze, cloneJson } from "../core/shared-helpers.js";
16
16
  export const RELEASE_SEQUENCE_VERSION = "0.1.0";
17
- function requireNonEmptyString(value, path) {
18
- if (typeof value !== "string" ||
19
- value.trim().length === 0) {
20
- throw new InvalidConfigurationError(path + " must be a non-empty string.");
21
- }
22
- return value.trim();
23
- }
24
- function requireFinite(value, path) {
25
- if (typeof value !== "number" ||
26
- !Number.isFinite(value)) {
27
- throw new InvalidScientificInputError(path + " must be finite.");
28
- }
29
- return value;
30
- }
31
- function requireNonNegativeFinite(value, path) {
32
- const parsed = requireFinite(value, path);
33
- if (parsed < 0) {
34
- throw new InvalidScientificInputError(path +
35
- " must be greater than or equal to zero.");
36
- }
37
- return parsed;
38
- }
39
- function requirePositiveFinite(value, path) {
40
- const parsed = requireFinite(value, path);
41
- if (parsed <= 0) {
42
- throw new InvalidScientificInputError(path +
43
- " must be greater than zero.");
44
- }
45
- return parsed;
46
- }
47
17
  function requirePositiveSafeInteger(value, path) {
48
18
  if (!Number.isSafeInteger(value) ||
49
19
  value <= 0) {
@@ -61,21 +31,6 @@ function requireUint32(value, path) {
61
31
  }
62
32
  return value;
63
33
  }
64
- function cloneJson(value) {
65
- return JSON.parse(JSON.stringify(value));
66
- }
67
- function deepFreeze(value) {
68
- if (typeof value !== "object" ||
69
- value === null ||
70
- Object.isFrozen(value)) {
71
- return value;
72
- }
73
- Object.freeze(value);
74
- for (const child of Object.values(value)) {
75
- deepFreeze(child);
76
- }
77
- return value;
78
- }
79
34
  function hashFrameSeed(sequenceSeedUint32, frameIndex) {
80
35
  let hash = 0x811c9dc5;
81
36
  const text = sequenceSeedUint32.toString(10) +
@@ -1 +1 @@
1
- {"version":3,"file":"release-sequence.js","sourceRoot":"","sources":["../../src/capture/release-sequence.ts"],"names":[],"mappings":"AAAA,sCAAsC;AAEtC;;;;;;;;GAQG;AAEH,OAAO,EAAE,2BAA2B,EAAE,MAAM,uBAAuB,CAAC;AACpE,OAAO,EACL,oCAAoC,EAGrC,MAAM,sCAAsC,CAAC;AAK9C,OAAO,EACL,eAAe,EAEhB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAChE,OAAO,EAAE,yBAAyB,EAAE,MAAM,gCAAgC,CAAC;AAE3E,MAAM,CAAC,MAAM,wBAAwB,GACnC,OAAgB,CAAC;AAuJnB,SAAS,qBAAqB,CAC5B,KAAa,EACb,IAAY;IAEZ,IACE,OAAO,KAAK,KAAK,QAAQ;QACzB,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EACzB,CAAC;QACD,MAAM,IAAI,yBAAyB,CACjC,IAAI,GAAG,8BAA8B,CACtC,CAAC;IACJ,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,EAAE,CAAC;AACtB,CAAC;AAED,SAAS,aAAa,CACpB,KAAa,EACb,IAAY;IAEZ,IACE,OAAO,KAAK,KAAK,QAAQ;QACzB,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,EACvB,CAAC;QACD,MAAM,IAAI,2BAA2B,CACnC,IAAI,GAAG,kBAAkB,CAC1B,CAAC;IACJ,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,wBAAwB,CAC/B,KAAa,EACb,IAAY;IAEZ,MAAM,MAAM,GACV,aAAa,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IAC7B,IAAI,MAAM,GAAG,CAAC,EAAE,CAAC;QACf,MAAM,IAAI,2BAA2B,CACnC,IAAI;YACF,yCAAyC,CAC5C,CAAC;IACJ,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS,qBAAqB,CAC5B,KAAa,EACb,IAAY;IAEZ,MAAM,MAAM,GACV,aAAa,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IAC7B,IAAI,MAAM,IAAI,CAAC,EAAE,CAAC;QAChB,MAAM,IAAI,2BAA2B,CACnC,IAAI;YACF,6BAA6B,CAChC,CAAC;IACJ,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS,0BAA0B,CACjC,KAAa,EACb,IAAY;IAEZ,IACE,CAAC,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC;QAC5B,KAAK,IAAI,CAAC,EACV,CAAC;QACD,MAAM,IAAI,2BAA2B,CACnC,IAAI;YACF,mCAAmC,CACtC,CAAC;IACJ,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,aAAa,CACpB,KAAa,EACb,IAAY;IAEZ,IACE,CAAC,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC;QAC5B,KAAK,GAAG,CAAC;QACT,KAAK,GAAG,WAAW,EACnB,CAAC;QACD,MAAM,IAAI,2BAA2B,CACnC,IAAI;YACF,sCAAsC,CACzC,CAAC;IACJ,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,SAAS,CAAI,KAAQ;IAC5B,OAAO,IAAI,CAAC,KAAK,CACf,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CACjB,CAAC;AACT,CAAC;AAED,SAAS,UAAU,CAAI,KAAQ;IAC7B,IACE,OAAO,KAAK,KAAK,QAAQ;QACzB,KAAK,KAAK,IAAI;QACd,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,EACtB,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACrB,KACE,MAAM,KAAK,IACX,MAAM,CAAC,MAAM,CACX,KAAgC,CACjC,EACD,CAAC;QACD,UAAU,CAAC,KAAK,CAAC,CAAC;IACpB,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,aAAa,CACpB,kBAA0B,EAC1B,UAAkB;IAElB,IAAI,IAAI,GAAG,UAAU,CAAC;IACtB,MAAM,IAAI,GACR,kBAAkB,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC/B,GAAG;QACH,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;IAC1B,KACE,IAAI,KAAK,GAAG,CAAC,EACb,KAAK,GAAG,IAAI,CAAC,MAAM,EACnB,KAAK,IAAI,CAAC,EACV,CAAC;QACD,IAAI,IAAI,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;QAC/B,IAAI,GAAG,IAAI,CAAC,IAAI,CACd,IAAI,EACJ,UAAU,CACX,KAAK,CAAC,CAAC;IACV,CAAC;IACD,OAAO,IAAI,KAAK,CAAC,CAAC;AACpB,CAAC;AAED,SAAS,iBAAiB,CACxB,YACiC,EACjC,KAC4B;IAE5B,OAAO,YAAY;SAChB,mBAAmB;SACnB,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;AAC3B,CAAC;AAED,SAAS,eAAe,CACtB,KAAyB;IAEzB,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC5B,OAAO,CAAC,CAAC;IACX,CAAC;IACD,OAAO,0BAA0B,CAC/B,KAAK,CAAC,UAAU,EAChB,kBAAkB,CACnB,CAAC;AACJ,CAAC;AAED,SAAS,iBAAiB,CACxB,OACsB;IAEtB,IAAI,OAAO,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QAC5B,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,KAAK,GACT,OAAO,CAAC,IAAI,KAAK,UAAU;QACzB,CAAC,CAAC,OAAO,CAAC,YAAY,CAAC,MAAM;QAC7B,CAAC,CAAC,OAAO,CAAC,WAAW,CAAC,MAAM,CAAC;IACjC,IAAI,KAAK,IAAI,CAAC,EAAE,CAAC;QACf,MAAM,IAAI,2BAA2B,CACnC,oDAAoD,CACrD,CAAC;IACJ,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,iBAAiB,CACxB,KAAyB,EACzB,OACsB;IAEtB,MAAM,UAAU,GACd,eAAe,CAAC,KAAK,CAAC,CAAC;IACzB,MAAM,YAAY,GAChB,iBAAiB,CAAC,OAAO,CAAC,CAAC;IAE7B,IAAI,YAAY,KAAK,IAAI,EAAE,CAAC;QAC1B,OAAO,UAAU,CAAC;IACpB,CAAC;IAED,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;QAC3B,MAAM,IAAI,2BAA2B,CACnC,sGAAsG,CACvG,CAAC;IACJ,CAAC;IAED,IACE,KAAK,CAAC,IAAI,KAAK,YAAY;QAC3B,UAAU,KAAK,YAAY,EAC3B,CAAC;QACD,MAAM,IAAI,2BAA2B,CACnC,2DAA2D,CAC5D,CAAC;IACJ,CAAC;IAED,OAAO,YAAY,CAAC;AACtB,CAAC;AAED,SAAS,mBAAmB,CAC1B,KAAa,EACb,OAAe,EACf,OAAe,EACf,IAC4B,EAC5B,IAAY;IAEZ,IACE,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC;QACvB,KAAK,GAAG,OAAO;QACf,KAAK,GAAG,OAAO,EACf,CAAC;QACD,MAAM,IAAI,2BAA2B,CACnC,IAAI;YACF,wDAAwD,CAC3D,CAAC;IACJ,CAAC;IAED,IACE,IAAI,CAAC,IAAI;QACP,iBAAiB;QACnB,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CACf,CAAC,SAAS,EAAE,EAAE,CACZ,IAAI,CAAC,GAAG,CACN,SAAS,GAAG,KAAK,CAClB;YACD,IAAI,CAAC,GAAG,CACN,CAAC,EACD,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAChB;gBACC,KAAK,CACV,EACD,CAAC;QACD,MAAM,IAAI,2BAA2B,CACnC,IAAI;YACF,yDAAyD,CAC5D,CAAC;IACJ,CAAC;AACH,CAAC;AAED,SAAS,gBAAgB,CACvB,QACqC,EACrC,YAC8C,EAC9C,IAAY;IAEZ,mBAAmB,CACjB,QAAQ,CAAC,QAAQ,EACjB,YAAY,CAAC,QAAQ;SAClB,sBAAsB,EACzB,YAAY,CAAC,QAAQ;SAClB,yBAAyB,EAC5B,YAAY,CAAC,QAAQ;SAClB,WAAW,EACd,IAAI,GAAG,WAAW,CACnB,CAAC;IACF,mBAAmB,CACjB,QAAQ,CAAC,cAAc,EACvB,YAAY,CAAC,OAAO;SACjB,cAAc,EACjB,YAAY,CAAC,OAAO;SACjB,cAAc,EACjB,YAAY,CAAC,OAAO;SACjB,WAAW,EACd,IAAI,GAAG,iBAAiB,CACzB,CAAC;IACF,mBAAmB,CACjB,QAAQ,CAAC,GAAG,EACZ,YAAY,CAAC,GAAG,CAAC,OAAO,EACxB,YAAY,CAAC,GAAG,CAAC,OAAO,EACxB,YAAY,CAAC,GAAG,CAAC,WAAW,EAC5B,IAAI,GAAG,MAAM,CACd,CAAC;AACJ,CAAC;AAED,SAAS,sBAAsB,CAC7B,IACqC,EACrC,IAC4B,EAC5B,WAAmB;IAEnB,aAAa,CACX,WAAW,EACX,wBAAwB,CACzB,CAAC;IAEF,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACvB,OAAO;YACL,GAAG,IAAI;YACP,cAAc,EACZ,IAAI,CAAC,cAAc;gBACnB,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,WAAW,CAAC;SAC3B,CAAC;IACJ,CAAC;IACD,IAAI,IAAI,KAAK,KAAK,EAAE,CAAC;QACnB,OAAO;YACL,GAAG,IAAI;YACP,GAAG,EACD,IAAI,CAAC,GAAG;gBACR,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,WAAW,CAAC;SAC3B,CAAC;IACJ,CAAC;IACD,OAAO;QACL,GAAG,IAAI;QACP,QAAQ,EACN,IAAI,CAAC,QAAQ;YACb,IAAI,CAAC,GAAG,CACN,CAAC,EACD,WAAW,GAAG,CAAC,CAChB;KACJ,CAAC;AACJ,CAAC;AAED,SAAS,iBAAiB,CACxB,KAC6B,EAC7B,UAAkB;IAQlB,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QAClC,OAAO;YACL,QAAQ,EACN,SAAS,CACP,KAAK,CAAC,SAAS,CAAC,QAAQ,CACzB;YACH,KAAK,EACH,eAAe,CACb,KAAK,CAAC,SAAS,CAAC,KAAK,CACtB;SACJ,CAAC;IACJ,CAAC;IAED,IACE,KAAK,CAAC,OAAO,CAAC,IAAI;QAClB,UAAU,EACV,CAAC;QACD,MAAM,MAAM,GACV,KAAK,CAAC,OAAO;aACV,YAAY,CACX,UAAU,CACX,CAAC;QACN,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YACzB,MAAM,IAAI,2BAA2B,CACnC,+CAA+C,CAChD,CAAC;QACJ,CAAC;QACD,OAAO;YACL,QAAQ,EACN,sBAAsB,CACpB,KAAK,CAAC,SAAS,CAAC,QAAQ,EACxB,KAAK,CAAC,OAAO,CAAC,IAAI,EAClB,MAAM,CACP;YACH,KAAK,EACH,eAAe,CACb,KAAK,CAAC,SAAS,CAAC,KAAK,CACtB;YACH,0BAA0B,EACxB,MAAM;SACT,CAAC;IACJ,CAAC;IAED,MAAM,KAAK,GACT,KAAK,CAAC,OAAO;SACV,WAAW,CAAC,UAAU,CAAC,CAAC;IAC7B,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxB,MAAM,IAAI,2BAA2B,CACnC,4CAA4C,CAC7C,CAAC;IACJ,CAAC;IACD,OAAO;QACL,QAAQ,EACN,SAAS,CACP,KAAK,CAAC,SAAS,CAAC,QAAQ,CACzB;QACH,KAAK,EACH,eAAe,CAAC,KAAK,CAAC;KACzB,CAAC;AACJ,CAAC;AAED,SAAS,sBAAsB,CAC7B,KAC6B,EAC7B,YACiC;IAEjC,IACE,KAAK,CAAC,OAAO,CAAC,IAAI;QAClB,UAAU,EACV,CAAC;QACD,IACE,YAAY;aACT,kBAAkB;aAClB,YAAY,CAAC,KAAK;YACrB,WAAW,EACX,CAAC;YACD,MAAM,IAAI,2BAA2B,CACnC,kFAAkF,CACnF,CAAC;QACJ,CAAC;QACD,IACE,CAAC,YAAY;aACV,kBAAkB;aAClB,aAAa;aACb,QAAQ,CACP,KAAK,CAAC,OAAO,CAAC,IAAI,CACnB,EACH,CAAC;YACD,MAAM,IAAI,2BAA2B,CACnC,wFAAwF,CACzF,CAAC;QACJ,CAAC;IACH,CAAC;IAED,IACE,KAAK,CAAC,OAAO,CAAC,IAAI;QAChB,OAAO;QACT,YAAY;aACT,eAAe;aACf,YAAY,CAAC,KAAK;YACnB,WAAW,EACb,CAAC;QACD,MAAM,IAAI,2BAA2B,CACnC,+EAA+E,CAChF,CAAC;IACJ,CAAC;AACH,CAAC;AAED,SAAS,qBAAqB,CAC5B,KAAyB;IAEzB,IAAI,KAAK,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;QAChC,OAAO,CAAC,CAAC;IACX,CAAC;IACD,OAAO,wBAAwB,CAC7B,KAAK,CAAC,YAAY,EAClB,oBAAoB,CACrB,CAAC;AACJ,CAAC;AAED,SAAS,uBAAuB,CAC9B,UAAkB,EAClB,mBACoB;IAEpB,IAAI,UAAU,IAAI,CAAC,EAAE,CAAC;QACpB,IACE,mBAAmB;YACnB,SAAS,EACT,CAAC;YACD,qBAAqB,CACnB,mBAAmB,EACnB,qBAAqB,CACtB,CAAC;QACJ,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IACE,mBAAmB;QACnB,SAAS,EACT,CAAC;QACD,MAAM,IAAI,2BAA2B,CACnC,sEAAsE,CACvE,CAAC;IACJ,CAAC;IACD,OAAO,qBAAqB,CAC1B,mBAAmB,EACnB,qBAAqB,CACtB,CAAC;AACJ,CAAC;AAED,SAAS,wBAAwB,CAC/B,aACsB,EACtB,mBAA2B,EAC3B,YACiC;IAMjC,MAAM,SAAS,GACb,CAAC,GAAG,mBAAmB,CAAC;IAC1B,MAAM,UAAU,GACd,CAAC;QACD,YAAY;aACT,iBAAiB,CAAC,KAAK,CAAC;IAC7B,MAAM,QAAQ,GACZ,aAAa;SACV,QAAQ,CAAC,cAAc,CAAC;IAC7B,MAAM,GAAG,GACP,YAAY;SACT,2BAA2B;SAC3B,KAAK,CAAC;IACX,MAAM,QAAQ,GACZ,QAAQ,GAAG,GAAG,CAAC;IACjB,MAAM,OAAO,GACX,IAAI,CAAC,GAAG,CACN,SAAS,EACT,UAAU,EACV,QAAQ,CACT,CAAC;IAEJ,MAAM,SAAS,GACb,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC;QACpB,KAAK,CAAC;IACR,MAAM,WAAW,GAEb,EAAE,CAAC;IAEP,IACE,IAAI,CAAC,GAAG,CACN,OAAO,GAAG,SAAS,CACpB,IAAI,SAAS,EACd,CAAC;QACD,WAAW,CAAC,IAAI,CACd,mBAAmB,CACpB,CAAC;IACJ,CAAC;IACD,IACE,IAAI,CAAC,GAAG,CACN,OAAO,GAAG,UAAU,CACrB,IAAI,SAAS,EACd,CAAC;QACD,WAAW,CAAC,IAAI,CACd,sBAAsB,CACvB,CAAC;IACJ,CAAC;IACD,IACE,IAAI,CAAC,GAAG,CACN,OAAO,GAAG,QAAQ,CACnB,IAAI,SAAS,EACd,CAAC;QACD,WAAW,CAAC,IAAI,CACd,mBAAmB,CACpB,CAAC;QACF,IAAI,GAAG,GAAG,CAAC,EAAE,CAAC;YACZ,WAAW,CAAC,IAAI,CACd,yBAAyB,CAC1B,CAAC;QACJ,CAAC;IACH,CAAC;IAED,OAAO;QACL,OAAO;QACP,WAAW;KACZ,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,sBAAsB,CACpC,KAC6B;IAE7B,gBAAgB,CAAC,KAAK,EAAE,wBAAwB,EAAE,CAAC,YAAY,EAAE,2BAA2B,EAAE,oBAAoB,EAAE,OAAO,EAAE,SAAS,EAAE,qBAAqB,EAAE,WAAW,EAAE,qBAAqB,EAAE,sBAAsB,CAAC,CAAC,CAAC;IAC5N,MAAM,UAAU,GACd,qBAAqB,CACnB,KAAK,CAAC,UAAU,EAChB,YAAY,CACb,CAAC;IACJ,MAAM,kBAAkB,GACtB,aAAa,CACX,KAAK;SACF,yBAAyB,EAC5B,2BAA2B,CAC5B,CAAC;IACJ,MAAM,YAAY,GAChB,aAAa,CACX,KAAK,CAAC,kBAAkB,EACxB,oBAAoB,CACrB,CAAC;IAEJ,MAAM,mBAAmB,GACvB,oCAAoC,CAClC,KAAK,CAAC,mBAAmB,CAC1B,CAAC;IAEJ,IACE,CAAC,iBAAiB,CAChB,mBAAmB,EACnB,KAAK,CAAC,KAAK,CAAC,IAAI,CACjB,EACD,CAAC;QACD,MAAM,IAAI,2BAA2B,CACnC,6EAA6E,CAC9E,CAAC;IACJ,CAAC;IAED,sBAAsB,CACpB,KAAK,EACL,mBAAmB,CACpB,CAAC;IAEF,MAAM,UAAU,GACd,iBAAiB,CACf,KAAK,CAAC,KAAK,EACX,KAAK,CAAC,OAAO,CACd,CAAC;IAEJ,IACE,UAAU;QACV,mBAAmB;aAChB,+BAA+B;aAC/B,KAAK,EACR,CAAC;QACD,MAAM,IAAI,2BAA2B,CACnC,wEAAwE,CACzE,CAAC;IACJ,CAAC;IAED,MAAM,mBAAmB,GACvB,uBAAuB,CACrB,UAAU,EACV,KAAK,CAAC,mBAAmB,CAC1B,CAAC;IAEJ,MAAM,cAAc,GAClB,qBAAqB,CACnB,KAAK,CAAC,KAAK,CACZ,CAAC;IAEJ,MAAM,SAAS,GACa;QAC1B,QAAQ,EACN,SAAS,CACP,KAAK,CAAC,SAAS,CAAC,QAAQ,CACzB;QACH,KAAK,EACH,eAAe,CACb,KAAK,CAAC,SAAS,CAAC,KAAK,CACtB;QACH,UAAU,EACR,SAAS,CACP,KAAK,CAAC,SAAS,CAAC,UAAU,CAC3B;QACH,GAAG,CAAC,KAAK,CAAC,SAAS;aAChB,mBAAmB;YACtB,SAAS;YACP,CAAC,CAAC,EAAE;YACJ,CAAC,CAAC;gBACE,mBAAmB,EACjB,qBAAqB,CACnB,KAAK,CAAC,SAAS;qBACZ,mBAAmB,EACtB,+BAA+B,CAChC;aACJ,CAAC;KACP,CAAC;IAEF,gBAAgB,CACd,SAAS,CAAC,QAAQ,EAClB,KAAK,CAAC,oBAAoB,EAC1B,oBAAoB,CACrB,CAAC;IAEF,MAAM,MAAM,GACe,EAAE,CAAC;IAE9B,KACE,IAAI,UAAU,GAAG,CAAC,EAClB,UAAU,GAAG,UAAU,EACvB,UAAU,IAAI,CAAC,EACf,CAAC;QACD,MAAM,KAAK,GACT,iBAAiB,CACf,KAAK,EACL,UAAU,CACX,CAAC;QACJ,gBAAgB,CACd,KAAK,CAAC,QAAQ,EACd,KAAK,CAAC,oBAAoB,EAC1B,SAAS;YACP,UAAU;YACV,YAAY,CACf,CAAC;QAEF,IAAI,wBACI,CAAC;QACT,IAAI,aAAa,GACC,IAAI,CAAC;QACvB,IAAI,iBAAiB,GAEjB,EAAE,CAAC;QAEP,IAAI,UAAU,KAAK,CAAC,EAAE,CAAC;YACrB,wBAAwB;gBACtB,kBAAkB;oBAClB,cAAc,CAAC;QACnB,CAAC;aAAM,CAAC;YACN,MAAM,QAAQ,GACZ,MAAM,CACJ,UAAU,GAAG,CAAC,CACd,CAAC;YACL,IACE,mBAAmB;gBACnB,IAAI,EACJ,CAAC;gBACD,MAAM,IAAI,2BAA2B,CACnC,kDAAkD,CACnD,CAAC;YACJ,CAAC;YACD,MAAM,QAAQ,GACZ,wBAAwB,CACtB,QAAQ,EACR,mBAAmB,EACnB,mBAAmB,CACpB,CAAC;YACJ,aAAa;gBACX,QAAQ,CAAC,OAAO,CAAC;YACnB,iBAAiB;gBACf,QAAQ,CAAC,WAAW,CAAC;YACvB,wBAAwB;gBACtB,QAAQ;qBACL,wBAAwB;oBAC3B,QAAQ,CAAC,OAAO,CAAC;QACrB,CAAC;QAED,MAAM,sBAAsB,GAC1B,wBAAwB;YACxB,KAAK,CAAC,QAAQ;iBACX,cAAc,CAAC;QAEpB,IACE,CAAC,MAAM,CAAC,QAAQ,CACd,wBAAwB,CACzB;YACD,CAAC,MAAM,CAAC,QAAQ,CACd,sBAAsB,CACvB,EACD,CAAC;YACD,MAAM,IAAI,2BAA2B,CACnC,sDAAsD,CACvD,CAAC;QACJ,CAAC;QAED,MAAM,CAAC,IAAI,CAAC;YACV,UAAU;YACV,UAAU;YACV,cAAc,EACZ,UAAU;gBACV,SAAS;gBACT,UAAU;YACZ,wBAAwB;YACxB,sBAAsB;YACtB,iCAAiC,EAC/B,wBAAwB;gBACxB,kBAAkB;YACpB,gCAAgC,EAC9B,aAAa;YACf,iBAAiB;YACjB,oBAAoB,EAClB,aAAa,CACX,YAAY,EACZ,UAAU,CACX;YACH,QAAQ,EACN,SAAS,CACP,KAAK,CAAC,QAAQ,CACf;YACH,KAAK,EACH,SAAS,CACP,KAAK,CAAC,KAAK,CACZ;YACH,GAAG,CAAC,KAAK;iBACN,0BAA0B;gBAC7B,SAAS;gBACP,CAAC,CAAC,EAAE;gBACJ,CAAC,CAAC;oBACE,0BAA0B,EACxB,KAAK;yBACF,0BAA0B;iBAChC,CAAC;YACN,UAAU,EACR,SAAS,CACP,SAAS,CAAC,UAAU,CACrB;YACH,GAAG,CAAC,SAAS;iBACV,mBAAmB;gBACtB,SAAS;gBACP,CAAC,CAAC,EAAE;gBACJ,CAAC,CAAC;oBACE,mBAAmB,EACjB,SAAS;yBACN,mBAAmB;iBACzB,CAAC;SACP,CAAC,CAAC;IACL,CAAC;IAED,MAAM,QAAQ,GACc;QAC1B,OAAO,EACL,wBAAwB;QAC1B,UAAU;QACV,MAAM,EAAE,WAAW;QACnB,yBAAyB,EACvB,kBAAkB;QACpB,qBAAqB,EACnB,cAAc;QAChB,mBAAmB;QACnB,2BAA2B,EACzB,mBAAmB;aAChB,iBAAiB,CAAC,KAAK;QAC5B,2BAA2B,EACzB,mBAAmB;aAChB,2BAA2B;aAC3B,KAAK;QACV,mBAAmB,EACjB,UAAU;QACZ,gBAAgB,EACd,MAAM,CAAC,MAAM;QACf,kBAAkB,EAChB,YAAY;QACd,iBAAiB,EACf,SAAS;QACX,MAAM;QACN,0BAA0B,EACxB,mCAAmC;QACrC,sCAAsC,EACpC,KAAK;QACP,wBAAwB,EACtB,KAAK;QACP,iCAAiC,EAC/B,KAAK;KACR,CAAC;IAEF,OAAO,UAAU,CACf,SAAS,CAAC,QAAQ,CAAC,CACpB,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,8BAA8B,CAC5C,KAC4B;IAE5B,gBAAgB,CAAC,KAAK,EAAE,gCAAgC,EAAE,CAAC,UAAU,EAAE,qBAAqB,EAAE,oBAAoB,CAAC,CAAC,CAAC;IACrH,MAAM,KAAK,GACT,wBAAwB,CACtB,KAAK,CAAC,mBAAmB,EACzB,qBAAqB,CACtB,CAAC;IACJ,IACE,CAAC,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,EAC5B,CAAC;QACD,MAAM,IAAI,2BAA2B,CACnC,6CAA6C,CAC9C,CAAC;IACJ,CAAC;IACD,IACE,KAAK;QACL,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,EAC5B,CAAC;QACD,MAAM,IAAI,2BAA2B,CACnC,sEAAsE,CACvE,CAAC;IACJ,CAAC;IAED,MAAM,WAAW,GACf,aAAa,CACX,KAAK,CAAC,kBAAkB,EACxB,oBAAoB,CACrB,CAAC;IAEJ,MAAM,MAAM,GACiB;QAC3B,OAAO,EACL,wBAAwB;QAC1B,UAAU,EACR,KAAK,CAAC,QAAQ,CAAC,UAAU;QAC3B,MAAM,EAAE,WAAW;QACnB,kBAAkB,EAChB,WAAW;QACb,mBAAmB,EAAE,KAAK;QAC1B,iBAAiB,EACf,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM;YAC5B,KAAK;QACP,eAAe,EACb,SAAS,CACP,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CACzB,CAAC,EACD,KAAK,CACN,CACF;QACH,wBAAwB,EACtB,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM;QAC9B,wBAAwB,EACtB,IAAI;KACP,CAAC;IAEF,OAAO,UAAU,CACf,SAAS,CAAC,MAAM,CAAC,CAClB,CAAC;AACJ,CAAC","sourcesContent":["// SPDX-License-Identifier: Apache-2.0\n\n/**\n * Shutter-release sequences for stills (single, burst, self-timer, bracketing), scheduled as logical exposures, and\n * cancelling a sequence part-way.\n *\n * This only schedules exposures; how the sensor captures each one is handled elsewhere. Render speed\n * or frame rate is never used as capture timing.\n * @see docs/SIMULATED_CAPTURE.md for equations, coordinate/unit conventions, blockers and support\n * limits.\n */\n\nimport { InvalidScientificInputError } from \"../core/validation.js\";\nimport {\n parseGenericReleaseCapabilityProfile,\n type GenericExposureBracketAxis,\n type GenericReleaseCapabilityProfile\n} from \"../equipment/release-capabilities.js\";\nimport type {\n ResolvedGenericEquipmentExposureCapabilities,\n ResolvedNumericSettingGrid\n} from \"../equipment/exposure-capabilities.js\";\nimport {\n parseFocusPlane,\n type FocusPlane\n} from \"../optics/focus-state.js\";\nimport { requireInputKeys } from \"../core/record-validation.js\";\nimport { InvalidConfigurationError } from \"../core/configuration-error.js\";\n\nexport const RELEASE_SEQUENCE_VERSION =\n \"0.1.0\" as const;\n\nexport type ReleaseAutomationState =\n | \"manual\"\n | \"locked\"\n | \"continuous\";\n\nexport interface ReleaseBaseCaptureState {\n exposure: {\n aperture: number;\n shutterSeconds: number;\n iso: number;\n };\n focus: FocusPlane;\n whiteBalanceStateId?: string;\n automation: {\n ae: ReleaseAutomationState;\n af: ReleaseAutomationState;\n awb: ReleaseAutomationState;\n };\n}\n\nexport type ReleaseDrivePolicy =\n | {\n kind: \"single\";\n }\n | {\n kind: \"burst\";\n frameCount: number;\n }\n | {\n kind: \"self-timer\";\n delaySeconds: number;\n frameCount: number;\n };\n\nexport type ReleaseBracketPolicy =\n | {\n kind: \"none\";\n }\n | {\n kind: \"exposure\";\n axis:\n GenericExposureBracketAxis;\n offsetsStops:\n readonly number[];\n }\n | {\n kind: \"focus\";\n focusStates:\n readonly FocusPlane[];\n };\n\nexport interface ResolveReleaseSequenceInput {\n sequenceId: string;\n releaseRequestTimeSeconds: number;\n sequenceSeedUint32: number;\n drive: ReleaseDrivePolicy;\n bracket: ReleaseBracketPolicy;\n requestedCadenceFps?: number;\n baseState:\n ReleaseBaseCaptureState;\n releaseCapabilities:\n GenericReleaseCapabilityProfile;\n exposureCapabilities:\n ResolvedGenericEquipmentExposureCapabilities;\n}\n\nexport type ReleaseTimingConstraint =\n | \"requested-cadence\"\n | \"body-maximum-cadence\"\n | \"exposure-duration\"\n | \"minimum-inter-frame-gap\";\n\nexport interface ResolvedReleaseFrame {\n sequenceId: string;\n frameIndex: number;\n releaseFrameId: string;\n exposureStartTimeSeconds: number;\n exposureEndTimeSeconds: number;\n sceneTimeSecondsFromSequenceStart:\n number;\n startIntervalFromPreviousSeconds:\n number | null;\n timingConstraints:\n readonly ReleaseTimingConstraint[];\n stochasticSeedUint32: number;\n exposure: {\n aperture: number;\n shutterSeconds: number;\n iso: number;\n };\n focus: FocusPlane;\n exposureBracketOffsetStops?:\n number;\n automation:\n ReleaseBaseCaptureState[\"automation\"];\n whiteBalanceStateId?: string;\n}\n\nexport interface ResolvedReleaseSequence {\n version:\n typeof RELEASE_SEQUENCE_VERSION;\n sequenceId: string;\n status: \"scheduled\";\n releaseRequestTimeSeconds: number;\n selfTimerDelaySeconds: number;\n requestedCadenceFps:\n number | null;\n capabilityMaximumCadenceFps:\n number;\n minimumInterFrameGapSeconds:\n number;\n requestedFrameCount: number;\n actualFrameCount: number;\n sequenceSeedUint32: number;\n baseStateSnapshot:\n ReleaseBaseCaptureState;\n frames:\n readonly ResolvedReleaseFrame[];\n sensorCaptureModeOwnership:\n \"separate-logical-capture-contract\";\n whiteBalanceBracketingPhysicalCaptures:\n false;\n preReleaseCaptureModeled:\n false;\n bufferMediaThermalSlowdownModeled:\n false;\n}\n\nexport interface CancelReleaseSequenceInput {\n sequence:\n ResolvedReleaseSequence;\n completedFrameCount: number;\n cancelledAtSeconds: number;\n}\n\nexport interface CancelledReleaseSequence {\n version:\n typeof RELEASE_SEQUENCE_VERSION;\n sequenceId: string;\n status: \"cancelled\";\n cancelledAtSeconds: number;\n completedFrameCount: number;\n omittedFrameCount: number;\n completedFrames:\n readonly ResolvedReleaseFrame[];\n sourceSequenceFrameCount: number;\n sourceSequenceUnmodified: true;\n}\n\nfunction requireNonEmptyString(\n value: string,\n path: string\n): string {\n if (\n typeof value !== \"string\" ||\n value.trim().length === 0\n ) {\n throw new InvalidConfigurationError(\n path + \" must be a non-empty string.\"\n );\n }\n return value.trim();\n}\n\nfunction requireFinite(\n value: number,\n path: string\n): number {\n if (\n typeof value !== \"number\" ||\n !Number.isFinite(value)\n ) {\n throw new InvalidScientificInputError(\n path + \" must be finite.\"\n );\n }\n return value;\n}\n\nfunction requireNonNegativeFinite(\n value: number,\n path: string\n): number {\n const parsed =\n requireFinite(value, path);\n if (parsed < 0) {\n throw new InvalidScientificInputError(\n path +\n \" must be greater than or equal to zero.\"\n );\n }\n return parsed;\n}\n\nfunction requirePositiveFinite(\n value: number,\n path: string\n): number {\n const parsed =\n requireFinite(value, path);\n if (parsed <= 0) {\n throw new InvalidScientificInputError(\n path +\n \" must be greater than zero.\"\n );\n }\n return parsed;\n}\n\nfunction requirePositiveSafeInteger(\n value: number,\n path: string\n): number {\n if (\n !Number.isSafeInteger(value) ||\n value <= 0\n ) {\n throw new InvalidScientificInputError(\n path +\n \" must be a positive safe integer.\"\n );\n }\n return value;\n}\n\nfunction requireUint32(\n value: number,\n path: string\n): number {\n if (\n !Number.isSafeInteger(value) ||\n value < 0 ||\n value > 0xffff_ffff\n ) {\n throw new InvalidScientificInputError(\n path +\n \" must be an unsigned 32-bit integer.\"\n );\n }\n return value;\n}\n\nfunction cloneJson<T>(value: T): T {\n return JSON.parse(\n JSON.stringify(value)\n ) as T;\n}\n\nfunction deepFreeze<T>(value: T): T {\n if (\n typeof value !== \"object\" ||\n value === null ||\n Object.isFrozen(value)\n ) {\n return value;\n }\n\n Object.freeze(value);\n for (\n const child of\n Object.values(\n value as Record<string, unknown>\n )\n ) {\n deepFreeze(child);\n }\n return value;\n}\n\nfunction hashFrameSeed(\n sequenceSeedUint32: number,\n frameIndex: number\n): number {\n let hash = 0x811c9dc5;\n const text =\n sequenceSeedUint32.toString(10) +\n \":\" +\n frameIndex.toString(10);\n for (\n let index = 0;\n index < text.length;\n index += 1\n ) {\n hash ^= text.charCodeAt(index);\n hash = Math.imul(\n hash,\n 0x01000193\n ) >>> 0;\n }\n return hash >>> 0;\n}\n\nfunction includesDriveMode(\n capabilities:\n GenericReleaseCapabilityProfile,\n drive:\n ReleaseDrivePolicy[\"kind\"]\n): boolean {\n return capabilities\n .supportedDriveModes\n .value.includes(drive);\n}\n\nfunction driveFrameCount(\n drive: ReleaseDrivePolicy\n): number {\n if (drive.kind === \"single\") {\n return 1;\n }\n return requirePositiveSafeInteger(\n drive.frameCount,\n \"drive.frameCount\"\n );\n}\n\nfunction bracketFrameCount(\n bracket:\n ReleaseBracketPolicy\n): number | null {\n if (bracket.kind === \"none\") {\n return null;\n }\n const count =\n bracket.kind === \"exposure\"\n ? bracket.offsetsStops.length\n : bracket.focusStates.length;\n if (count <= 0) {\n throw new InvalidScientificInputError(\n \"Bracket sequences must contain at least one frame.\"\n );\n }\n return count;\n}\n\nfunction resolveFrameCount(\n drive: ReleaseDrivePolicy,\n bracket:\n ReleaseBracketPolicy\n): number {\n const driveCount =\n driveFrameCount(drive);\n const bracketCount =\n bracketFrameCount(bracket);\n\n if (bracketCount === null) {\n return driveCount;\n }\n\n if (drive.kind === \"burst\") {\n throw new InvalidScientificInputError(\n \"Schema 0.1.0 does not combine burst drive with bracketing; choose one multi-frame policy explicitly.\"\n );\n }\n\n if (\n drive.kind === \"self-timer\" &&\n driveCount !== bracketCount\n ) {\n throw new InvalidScientificInputError(\n \"Self-timer frameCount must match the bracket frame count.\"\n );\n }\n\n return bracketCount;\n}\n\nfunction validateGridSetting(\n value: number,\n minimum: number,\n maximum: number,\n grid:\n ResolvedNumericSettingGrid,\n path: string\n): void {\n if (\n !Number.isFinite(value) ||\n value < minimum ||\n value > maximum\n ) {\n throw new InvalidScientificInputError(\n path +\n \" lies outside the resolved equipment capability range.\"\n );\n }\n\n if (\n grid.kind ===\n \"discrete-values\" &&\n !grid.values.some(\n (candidate) =>\n Math.abs(\n candidate - value\n ) <=\n Math.max(\n 1,\n Math.abs(value)\n ) *\n 1e-12\n )\n ) {\n throw new InvalidScientificInputError(\n path +\n \" is not present in the resolved equipment setting grid.\"\n );\n }\n}\n\nfunction validateExposure(\n exposure:\n ReleaseBaseCaptureState[\"exposure\"],\n capabilities:\n ResolvedGenericEquipmentExposureCapabilities,\n path: string\n): void {\n validateGridSetting(\n exposure.aperture,\n capabilities.aperture\n .widestAvailableFNumber,\n capabilities.aperture\n .narrowestAvailableFNumber,\n capabilities.aperture\n .settingGrid,\n path + \".aperture\"\n );\n validateGridSetting(\n exposure.shutterSeconds,\n capabilities.shutter\n .minimumSeconds,\n capabilities.shutter\n .maximumSeconds,\n capabilities.shutter\n .settingGrid,\n path + \".shutterSeconds\"\n );\n validateGridSetting(\n exposure.iso,\n capabilities.iso.minimum,\n capabilities.iso.maximum,\n capabilities.iso.settingGrid,\n path + \".iso\"\n );\n}\n\nfunction resolveExposureBracket(\n base:\n ReleaseBaseCaptureState[\"exposure\"],\n axis:\n GenericExposureBracketAxis,\n offsetStops: number\n): ReleaseBaseCaptureState[\"exposure\"] {\n requireFinite(\n offsetStops,\n \"bracket.offsetsStops[]\"\n );\n\n if (axis === \"shutter\") {\n return {\n ...base,\n shutterSeconds:\n base.shutterSeconds *\n Math.pow(2, offsetStops)\n };\n }\n if (axis === \"iso\") {\n return {\n ...base,\n iso:\n base.iso *\n Math.pow(2, offsetStops)\n };\n }\n return {\n ...base,\n aperture:\n base.aperture /\n Math.pow(\n 2,\n offsetStops / 2\n )\n };\n}\n\nfunction resolveFrameState(\n input:\n ResolveReleaseSequenceInput,\n frameIndex: number\n): {\n exposure:\n ReleaseBaseCaptureState[\"exposure\"];\n focus: FocusPlane;\n exposureBracketOffsetStops?:\n number;\n} {\n if (input.bracket.kind === \"none\") {\n return {\n exposure:\n cloneJson(\n input.baseState.exposure\n ),\n focus:\n parseFocusPlane(\n input.baseState.focus\n )\n };\n }\n\n if (\n input.bracket.kind ===\n \"exposure\"\n ) {\n const offset =\n input.bracket\n .offsetsStops[\n frameIndex\n ];\n if (offset === undefined) {\n throw new InvalidScientificInputError(\n \"Exposure bracket frame index is out of range.\"\n );\n }\n return {\n exposure:\n resolveExposureBracket(\n input.baseState.exposure,\n input.bracket.axis,\n offset\n ),\n focus:\n parseFocusPlane(\n input.baseState.focus\n ),\n exposureBracketOffsetStops:\n offset\n };\n }\n\n const focus =\n input.bracket\n .focusStates[frameIndex];\n if (focus === undefined) {\n throw new InvalidScientificInputError(\n \"Focus bracket frame index is out of range.\"\n );\n }\n return {\n exposure:\n cloneJson(\n input.baseState.exposure\n ),\n focus:\n parseFocusPlane(focus)\n };\n}\n\nfunction validateBracketSupport(\n input:\n ResolveReleaseSequenceInput,\n capabilities:\n GenericReleaseCapabilityProfile\n): void {\n if (\n input.bracket.kind ===\n \"exposure\"\n ) {\n if (\n capabilities\n .exposureBracketing\n .availability.value !==\n \"supported\"\n ) {\n throw new InvalidScientificInputError(\n \"Exposure bracketing is not supported by the selected release capability profile.\"\n );\n }\n if (\n !capabilities\n .exposureBracketing\n .supportedAxes\n .includes(\n input.bracket.axis\n )\n ) {\n throw new InvalidScientificInputError(\n \"The selected exposure-bracket axis is not supported by the release capability profile.\"\n );\n }\n }\n\n if (\n input.bracket.kind ===\n \"focus\" &&\n capabilities\n .focusBracketing\n .availability.value !==\n \"supported\"\n ) {\n throw new InvalidScientificInputError(\n \"Focus bracketing is not supported by the selected release capability profile.\"\n );\n }\n}\n\nfunction resolveSelfTimerDelay(\n drive: ReleaseDrivePolicy\n): number {\n if (drive.kind !== \"self-timer\") {\n return 0;\n }\n return requireNonNegativeFinite(\n drive.delaySeconds,\n \"drive.delaySeconds\"\n );\n}\n\nfunction resolveRequestedCadence(\n frameCount: number,\n requestedCadenceFps:\n number | undefined\n): number | null {\n if (frameCount <= 1) {\n if (\n requestedCadenceFps !==\n undefined\n ) {\n requirePositiveFinite(\n requestedCadenceFps,\n \"requestedCadenceFps\"\n );\n }\n return null;\n }\n if (\n requestedCadenceFps ===\n undefined\n ) {\n throw new InvalidScientificInputError(\n \"requestedCadenceFps is required for a multi-frame physical sequence.\"\n );\n }\n return requirePositiveFinite(\n requestedCadenceFps,\n \"requestedCadenceFps\"\n );\n}\n\nfunction intervalForPreviousFrame(\n previousFrame:\n ResolvedReleaseFrame,\n requestedCadenceFps: number,\n capabilities:\n GenericReleaseCapabilityProfile\n): {\n seconds: number;\n constraints:\n readonly ReleaseTimingConstraint[];\n} {\n const requested =\n 1 / requestedCadenceFps;\n const capability =\n 1 /\n capabilities\n .maximumCadenceFps.value;\n const exposure =\n previousFrame\n .exposure.shutterSeconds;\n const gap =\n capabilities\n .minimumInterFrameGapSeconds\n .value;\n const physical =\n exposure + gap;\n const seconds =\n Math.max(\n requested,\n capability,\n physical\n );\n\n const tolerance =\n Math.max(1, seconds) *\n 1e-12;\n const constraints:\n ReleaseTimingConstraint[] =\n [];\n\n if (\n Math.abs(\n seconds - requested\n ) <= tolerance\n ) {\n constraints.push(\n \"requested-cadence\"\n );\n }\n if (\n Math.abs(\n seconds - capability\n ) <= tolerance\n ) {\n constraints.push(\n \"body-maximum-cadence\"\n );\n }\n if (\n Math.abs(\n seconds - physical\n ) <= tolerance\n ) {\n constraints.push(\n \"exposure-duration\"\n );\n if (gap > 0) {\n constraints.push(\n \"minimum-inter-frame-gap\"\n );\n }\n }\n\n return {\n seconds,\n constraints\n };\n}\n\n/**\n * Resolves one deterministic still-release sequence.\n *\n * It schedules logical exposures only; how the sensor captures each one is\n * handled elsewhere. Render speed or frame rate is never used as capture timing.\n */\nexport function resolveReleaseSequence(\n input:\n ResolveReleaseSequenceInput\n): ResolvedReleaseSequence {\n requireInputKeys(input, \"resolveReleaseSequence\", [\"sequenceId\", \"releaseRequestTimeSeconds\", \"sequenceSeedUint32\", \"drive\", \"bracket\", \"requestedCadenceFps\", \"baseState\", \"releaseCapabilities\", \"exposureCapabilities\"]);\n const sequenceId =\n requireNonEmptyString(\n input.sequenceId,\n \"sequenceId\"\n );\n const releaseRequestTime =\n requireFinite(\n input\n .releaseRequestTimeSeconds,\n \"releaseRequestTimeSeconds\"\n );\n const sequenceSeed =\n requireUint32(\n input.sequenceSeedUint32,\n \"sequenceSeedUint32\"\n );\n\n const releaseCapabilities =\n parseGenericReleaseCapabilityProfile(\n input.releaseCapabilities\n );\n\n if (\n !includesDriveMode(\n releaseCapabilities,\n input.drive.kind\n )\n ) {\n throw new InvalidScientificInputError(\n \"The selected drive mode is not supported by the release capability profile.\"\n );\n }\n\n validateBracketSupport(\n input,\n releaseCapabilities\n );\n\n const frameCount =\n resolveFrameCount(\n input.drive,\n input.bracket\n );\n\n if (\n frameCount >\n releaseCapabilities\n .maximumLogicalFramesPerSequence\n .value\n ) {\n throw new InvalidScientificInputError(\n \"Requested sequence frame count exceeds the release capability profile.\"\n );\n }\n\n const requestedCadenceFps =\n resolveRequestedCadence(\n frameCount,\n input.requestedCadenceFps\n );\n\n const selfTimerDelay =\n resolveSelfTimerDelay(\n input.drive\n );\n\n const baseState:\n ReleaseBaseCaptureState = {\n exposure:\n cloneJson(\n input.baseState.exposure\n ),\n focus:\n parseFocusPlane(\n input.baseState.focus\n ),\n automation:\n cloneJson(\n input.baseState.automation\n ),\n ...(input.baseState\n .whiteBalanceStateId ===\n undefined\n ? {}\n : {\n whiteBalanceStateId:\n requireNonEmptyString(\n input.baseState\n .whiteBalanceStateId,\n \"baseState.whiteBalanceStateId\"\n )\n })\n };\n\n validateExposure(\n baseState.exposure,\n input.exposureCapabilities,\n \"baseState.exposure\"\n );\n\n const frames:\n ResolvedReleaseFrame[] = [];\n\n for (\n let frameIndex = 0;\n frameIndex < frameCount;\n frameIndex += 1\n ) {\n const state =\n resolveFrameState(\n input,\n frameIndex\n );\n validateExposure(\n state.exposure,\n input.exposureCapabilities,\n \"frames[\" +\n frameIndex +\n \"].exposure\"\n );\n\n let exposureStartTimeSeconds:\n number;\n let startInterval:\n number | null = null;\n let timingConstraints:\n readonly ReleaseTimingConstraint[] =\n [];\n\n if (frameIndex === 0) {\n exposureStartTimeSeconds =\n releaseRequestTime +\n selfTimerDelay;\n } else {\n const previous =\n frames[\n frameIndex - 1\n ]!;\n if (\n requestedCadenceFps ===\n null\n ) {\n throw new InvalidScientificInputError(\n \"Multi-frame sequence lost its requested cadence.\"\n );\n }\n const interval =\n intervalForPreviousFrame(\n previous,\n requestedCadenceFps,\n releaseCapabilities\n );\n startInterval =\n interval.seconds;\n timingConstraints =\n interval.constraints;\n exposureStartTimeSeconds =\n previous\n .exposureStartTimeSeconds +\n interval.seconds;\n }\n\n const exposureEndTimeSeconds =\n exposureStartTimeSeconds +\n state.exposure\n .shutterSeconds;\n\n if (\n !Number.isFinite(\n exposureStartTimeSeconds\n ) ||\n !Number.isFinite(\n exposureEndTimeSeconds\n )\n ) {\n throw new InvalidScientificInputError(\n \"Resolved release-sequence timing must remain finite.\"\n );\n }\n\n frames.push({\n sequenceId,\n frameIndex,\n releaseFrameId:\n sequenceId +\n \":frame:\" +\n frameIndex,\n exposureStartTimeSeconds,\n exposureEndTimeSeconds,\n sceneTimeSecondsFromSequenceStart:\n exposureStartTimeSeconds -\n releaseRequestTime,\n startIntervalFromPreviousSeconds:\n startInterval,\n timingConstraints,\n stochasticSeedUint32:\n hashFrameSeed(\n sequenceSeed,\n frameIndex\n ),\n exposure:\n cloneJson(\n state.exposure\n ),\n focus:\n cloneJson(\n state.focus\n ),\n ...(state\n .exposureBracketOffsetStops ===\n undefined\n ? {}\n : {\n exposureBracketOffsetStops:\n state\n .exposureBracketOffsetStops\n }),\n automation:\n cloneJson(\n baseState.automation\n ),\n ...(baseState\n .whiteBalanceStateId ===\n undefined\n ? {}\n : {\n whiteBalanceStateId:\n baseState\n .whiteBalanceStateId\n })\n });\n }\n\n const sequence:\n ResolvedReleaseSequence = {\n version:\n RELEASE_SEQUENCE_VERSION,\n sequenceId,\n status: \"scheduled\",\n releaseRequestTimeSeconds:\n releaseRequestTime,\n selfTimerDelaySeconds:\n selfTimerDelay,\n requestedCadenceFps,\n capabilityMaximumCadenceFps:\n releaseCapabilities\n .maximumCadenceFps.value,\n minimumInterFrameGapSeconds:\n releaseCapabilities\n .minimumInterFrameGapSeconds\n .value,\n requestedFrameCount:\n frameCount,\n actualFrameCount:\n frames.length,\n sequenceSeedUint32:\n sequenceSeed,\n baseStateSnapshot:\n baseState,\n frames,\n sensorCaptureModeOwnership:\n \"separate-logical-capture-contract\",\n whiteBalanceBracketingPhysicalCaptures:\n false,\n preReleaseCaptureModeled:\n false,\n bufferMediaThermalSlowdownModeled:\n false\n };\n\n return deepFreeze(\n cloneJson(sequence)\n );\n}\n\n/**\n * Returns a cancelled copy of a sequence. The original scheduled sequence is not\n * changed, and it is always clear which frames were completed and which were dropped.\n */\nexport function createCancelledReleaseSequence(\n input:\n CancelReleaseSequenceInput\n): CancelledReleaseSequence {\n requireInputKeys(input, \"createCancelledReleaseSequence\", [\"sequence\", \"completedFrameCount\", \"cancelledAtSeconds\"]);\n const count =\n requireNonNegativeFinite(\n input.completedFrameCount,\n \"completedFrameCount\"\n );\n if (\n !Number.isSafeInteger(count)\n ) {\n throw new InvalidScientificInputError(\n \"completedFrameCount must be a safe integer.\"\n );\n }\n if (\n count >\n input.sequence.frames.length\n ) {\n throw new InvalidScientificInputError(\n \"completedFrameCount must not exceed the source sequence frame count.\"\n );\n }\n\n const cancelledAt =\n requireFinite(\n input.cancelledAtSeconds,\n \"cancelledAtSeconds\"\n );\n\n const result:\n CancelledReleaseSequence = {\n version:\n RELEASE_SEQUENCE_VERSION,\n sequenceId:\n input.sequence.sequenceId,\n status: \"cancelled\",\n cancelledAtSeconds:\n cancelledAt,\n completedFrameCount: count,\n omittedFrameCount:\n input.sequence.frames.length -\n count,\n completedFrames:\n cloneJson(\n input.sequence.frames.slice(\n 0,\n count\n )\n ),\n sourceSequenceFrameCount:\n input.sequence.frames.length,\n sourceSequenceUnmodified:\n true\n };\n\n return deepFreeze(\n cloneJson(result)\n );\n}\n"]}
1
+ {"version":3,"file":"release-sequence.js","sourceRoot":"","sources":["../../src/capture/release-sequence.ts"],"names":[],"mappings":"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","sourcesContent":["// SPDX-License-Identifier: Apache-2.0\n\n/**\n * Shutter-release sequences for stills (single, burst, self-timer, bracketing), scheduled as logical exposures, and\n * cancelling a sequence part-way.\n *\n * This only schedules exposures; how the sensor captures each one is handled elsewhere. Render speed\n * or frame rate is never used as capture timing.\n * @see docs/SIMULATED_CAPTURE.md for equations, coordinate/unit conventions, blockers and support\n * limits.\n */\n\nimport { InvalidScientificInputError } from \"../core/validation.js\";\nimport {\n parseGenericReleaseCapabilityProfile,\n type GenericExposureBracketAxis,\n type GenericReleaseCapabilityProfile\n} from \"../equipment/release-capabilities.js\";\nimport type {\n ResolvedGenericEquipmentExposureCapabilities,\n ResolvedNumericSettingGrid\n} from \"../equipment/exposure-capabilities.js\";\nimport {\n parseFocusPlane,\n type FocusPlane\n} from \"../optics/focus-state.js\";\nimport { requireInputKeys, requireTrimmedConfigString as requireNonEmptyString, requireInputFinite as requireFinite, requireInputFiniteAboveZero as requirePositiveFinite, requireInputFiniteAtLeastZero as requireNonNegativeFinite } from \"../core/record-validation.js\";\nimport { deepFreeze, cloneJson } from \"../core/shared-helpers.js\";\n\nexport const RELEASE_SEQUENCE_VERSION =\n \"0.1.0\" as const;\n\nexport type ReleaseAutomationState =\n | \"manual\"\n | \"locked\"\n | \"continuous\";\n\nexport interface ReleaseBaseCaptureState {\n exposure: {\n aperture: number;\n shutterSeconds: number;\n iso: number;\n };\n focus: FocusPlane;\n whiteBalanceStateId?: string;\n automation: {\n ae: ReleaseAutomationState;\n af: ReleaseAutomationState;\n awb: ReleaseAutomationState;\n };\n}\n\nexport type ReleaseDrivePolicy =\n | {\n kind: \"single\";\n }\n | {\n kind: \"burst\";\n frameCount: number;\n }\n | {\n kind: \"self-timer\";\n delaySeconds: number;\n frameCount: number;\n };\n\nexport type ReleaseBracketPolicy =\n | {\n kind: \"none\";\n }\n | {\n kind: \"exposure\";\n axis:\n GenericExposureBracketAxis;\n offsetsStops:\n readonly number[];\n }\n | {\n kind: \"focus\";\n focusStates:\n readonly FocusPlane[];\n };\n\nexport interface ResolveReleaseSequenceInput {\n sequenceId: string;\n releaseRequestTimeSeconds: number;\n sequenceSeedUint32: number;\n drive: ReleaseDrivePolicy;\n bracket: ReleaseBracketPolicy;\n requestedCadenceFps?: number;\n baseState:\n ReleaseBaseCaptureState;\n releaseCapabilities:\n GenericReleaseCapabilityProfile;\n exposureCapabilities:\n ResolvedGenericEquipmentExposureCapabilities;\n}\n\nexport type ReleaseTimingConstraint =\n | \"requested-cadence\"\n | \"body-maximum-cadence\"\n | \"exposure-duration\"\n | \"minimum-inter-frame-gap\";\n\nexport interface ResolvedReleaseFrame {\n sequenceId: string;\n frameIndex: number;\n releaseFrameId: string;\n exposureStartTimeSeconds: number;\n exposureEndTimeSeconds: number;\n sceneTimeSecondsFromSequenceStart:\n number;\n startIntervalFromPreviousSeconds:\n number | null;\n timingConstraints:\n readonly ReleaseTimingConstraint[];\n stochasticSeedUint32: number;\n exposure: {\n aperture: number;\n shutterSeconds: number;\n iso: number;\n };\n focus: FocusPlane;\n exposureBracketOffsetStops?:\n number;\n automation:\n ReleaseBaseCaptureState[\"automation\"];\n whiteBalanceStateId?: string;\n}\n\nexport interface ResolvedReleaseSequence {\n version:\n typeof RELEASE_SEQUENCE_VERSION;\n sequenceId: string;\n status: \"scheduled\";\n releaseRequestTimeSeconds: number;\n selfTimerDelaySeconds: number;\n requestedCadenceFps:\n number | null;\n capabilityMaximumCadenceFps:\n number;\n minimumInterFrameGapSeconds:\n number;\n requestedFrameCount: number;\n actualFrameCount: number;\n sequenceSeedUint32: number;\n baseStateSnapshot:\n ReleaseBaseCaptureState;\n frames:\n readonly ResolvedReleaseFrame[];\n sensorCaptureModeOwnership:\n \"separate-logical-capture-contract\";\n whiteBalanceBracketingPhysicalCaptures:\n false;\n preReleaseCaptureModeled:\n false;\n bufferMediaThermalSlowdownModeled:\n false;\n}\n\nexport interface CancelReleaseSequenceInput {\n sequence:\n ResolvedReleaseSequence;\n completedFrameCount: number;\n cancelledAtSeconds: number;\n}\n\nexport interface CancelledReleaseSequence {\n version:\n typeof RELEASE_SEQUENCE_VERSION;\n sequenceId: string;\n status: \"cancelled\";\n cancelledAtSeconds: number;\n completedFrameCount: number;\n omittedFrameCount: number;\n completedFrames:\n readonly ResolvedReleaseFrame[];\n sourceSequenceFrameCount: number;\n sourceSequenceUnmodified: true;\n}\n\nfunction requirePositiveSafeInteger(\n value: number,\n path: string\n): number {\n if (\n !Number.isSafeInteger(value) ||\n value <= 0\n ) {\n throw new InvalidScientificInputError(\n path +\n \" must be a positive safe integer.\"\n );\n }\n return value;\n}\n\nfunction requireUint32(\n value: number,\n path: string\n): number {\n if (\n !Number.isSafeInteger(value) ||\n value < 0 ||\n value > 0xffff_ffff\n ) {\n throw new InvalidScientificInputError(\n path +\n \" must be an unsigned 32-bit integer.\"\n );\n }\n return value;\n}\n\nfunction hashFrameSeed(\n sequenceSeedUint32: number,\n frameIndex: number\n): number {\n let hash = 0x811c9dc5;\n const text =\n sequenceSeedUint32.toString(10) +\n \":\" +\n frameIndex.toString(10);\n for (\n let index = 0;\n index < text.length;\n index += 1\n ) {\n hash ^= text.charCodeAt(index);\n hash = Math.imul(\n hash,\n 0x01000193\n ) >>> 0;\n }\n return hash >>> 0;\n}\n\nfunction includesDriveMode(\n capabilities:\n GenericReleaseCapabilityProfile,\n drive:\n ReleaseDrivePolicy[\"kind\"]\n): boolean {\n return capabilities\n .supportedDriveModes\n .value.includes(drive);\n}\n\nfunction driveFrameCount(\n drive: ReleaseDrivePolicy\n): number {\n if (drive.kind === \"single\") {\n return 1;\n }\n return requirePositiveSafeInteger(\n drive.frameCount,\n \"drive.frameCount\"\n );\n}\n\nfunction bracketFrameCount(\n bracket:\n ReleaseBracketPolicy\n): number | null {\n if (bracket.kind === \"none\") {\n return null;\n }\n const count =\n bracket.kind === \"exposure\"\n ? bracket.offsetsStops.length\n : bracket.focusStates.length;\n if (count <= 0) {\n throw new InvalidScientificInputError(\n \"Bracket sequences must contain at least one frame.\"\n );\n }\n return count;\n}\n\nfunction resolveFrameCount(\n drive: ReleaseDrivePolicy,\n bracket:\n ReleaseBracketPolicy\n): number {\n const driveCount =\n driveFrameCount(drive);\n const bracketCount =\n bracketFrameCount(bracket);\n\n if (bracketCount === null) {\n return driveCount;\n }\n\n if (drive.kind === \"burst\") {\n throw new InvalidScientificInputError(\n \"Schema 0.1.0 does not combine burst drive with bracketing; choose one multi-frame policy explicitly.\"\n );\n }\n\n if (\n drive.kind === \"self-timer\" &&\n driveCount !== bracketCount\n ) {\n throw new InvalidScientificInputError(\n \"Self-timer frameCount must match the bracket frame count.\"\n );\n }\n\n return bracketCount;\n}\n\nfunction validateGridSetting(\n value: number,\n minimum: number,\n maximum: number,\n grid:\n ResolvedNumericSettingGrid,\n path: string\n): void {\n if (\n !Number.isFinite(value) ||\n value < minimum ||\n value > maximum\n ) {\n throw new InvalidScientificInputError(\n path +\n \" lies outside the resolved equipment capability range.\"\n );\n }\n\n if (\n grid.kind ===\n \"discrete-values\" &&\n !grid.values.some(\n (candidate) =>\n Math.abs(\n candidate - value\n ) <=\n Math.max(\n 1,\n Math.abs(value)\n ) *\n 1e-12\n )\n ) {\n throw new InvalidScientificInputError(\n path +\n \" is not present in the resolved equipment setting grid.\"\n );\n }\n}\n\nfunction validateExposure(\n exposure:\n ReleaseBaseCaptureState[\"exposure\"],\n capabilities:\n ResolvedGenericEquipmentExposureCapabilities,\n path: string\n): void {\n validateGridSetting(\n exposure.aperture,\n capabilities.aperture\n .widestAvailableFNumber,\n capabilities.aperture\n .narrowestAvailableFNumber,\n capabilities.aperture\n .settingGrid,\n path + \".aperture\"\n );\n validateGridSetting(\n exposure.shutterSeconds,\n capabilities.shutter\n .minimumSeconds,\n capabilities.shutter\n .maximumSeconds,\n capabilities.shutter\n .settingGrid,\n path + \".shutterSeconds\"\n );\n validateGridSetting(\n exposure.iso,\n capabilities.iso.minimum,\n capabilities.iso.maximum,\n capabilities.iso.settingGrid,\n path + \".iso\"\n );\n}\n\nfunction resolveExposureBracket(\n base:\n ReleaseBaseCaptureState[\"exposure\"],\n axis:\n GenericExposureBracketAxis,\n offsetStops: number\n): ReleaseBaseCaptureState[\"exposure\"] {\n requireFinite(\n offsetStops,\n \"bracket.offsetsStops[]\"\n );\n\n if (axis === \"shutter\") {\n return {\n ...base,\n shutterSeconds:\n base.shutterSeconds *\n Math.pow(2, offsetStops)\n };\n }\n if (axis === \"iso\") {\n return {\n ...base,\n iso:\n base.iso *\n Math.pow(2, offsetStops)\n };\n }\n return {\n ...base,\n aperture:\n base.aperture /\n Math.pow(\n 2,\n offsetStops / 2\n )\n };\n}\n\nfunction resolveFrameState(\n input:\n ResolveReleaseSequenceInput,\n frameIndex: number\n): {\n exposure:\n ReleaseBaseCaptureState[\"exposure\"];\n focus: FocusPlane;\n exposureBracketOffsetStops?:\n number;\n} {\n if (input.bracket.kind === \"none\") {\n return {\n exposure:\n cloneJson(\n input.baseState.exposure\n ),\n focus:\n parseFocusPlane(\n input.baseState.focus\n )\n };\n }\n\n if (\n input.bracket.kind ===\n \"exposure\"\n ) {\n const offset =\n input.bracket\n .offsetsStops[\n frameIndex\n ];\n if (offset === undefined) {\n throw new InvalidScientificInputError(\n \"Exposure bracket frame index is out of range.\"\n );\n }\n return {\n exposure:\n resolveExposureBracket(\n input.baseState.exposure,\n input.bracket.axis,\n offset\n ),\n focus:\n parseFocusPlane(\n input.baseState.focus\n ),\n exposureBracketOffsetStops:\n offset\n };\n }\n\n const focus =\n input.bracket\n .focusStates[frameIndex];\n if (focus === undefined) {\n throw new InvalidScientificInputError(\n \"Focus bracket frame index is out of range.\"\n );\n }\n return {\n exposure:\n cloneJson(\n input.baseState.exposure\n ),\n focus:\n parseFocusPlane(focus)\n };\n}\n\nfunction validateBracketSupport(\n input:\n ResolveReleaseSequenceInput,\n capabilities:\n GenericReleaseCapabilityProfile\n): void {\n if (\n input.bracket.kind ===\n \"exposure\"\n ) {\n if (\n capabilities\n .exposureBracketing\n .availability.value !==\n \"supported\"\n ) {\n throw new InvalidScientificInputError(\n \"Exposure bracketing is not supported by the selected release capability profile.\"\n );\n }\n if (\n !capabilities\n .exposureBracketing\n .supportedAxes\n .includes(\n input.bracket.axis\n )\n ) {\n throw new InvalidScientificInputError(\n \"The selected exposure-bracket axis is not supported by the release capability profile.\"\n );\n }\n }\n\n if (\n input.bracket.kind ===\n \"focus\" &&\n capabilities\n .focusBracketing\n .availability.value !==\n \"supported\"\n ) {\n throw new InvalidScientificInputError(\n \"Focus bracketing is not supported by the selected release capability profile.\"\n );\n }\n}\n\nfunction resolveSelfTimerDelay(\n drive: ReleaseDrivePolicy\n): number {\n if (drive.kind !== \"self-timer\") {\n return 0;\n }\n return requireNonNegativeFinite(\n drive.delaySeconds,\n \"drive.delaySeconds\"\n );\n}\n\nfunction resolveRequestedCadence(\n frameCount: number,\n requestedCadenceFps:\n number | undefined\n): number | null {\n if (frameCount <= 1) {\n if (\n requestedCadenceFps !==\n undefined\n ) {\n requirePositiveFinite(\n requestedCadenceFps,\n \"requestedCadenceFps\"\n );\n }\n return null;\n }\n if (\n requestedCadenceFps ===\n undefined\n ) {\n throw new InvalidScientificInputError(\n \"requestedCadenceFps is required for a multi-frame physical sequence.\"\n );\n }\n return requirePositiveFinite(\n requestedCadenceFps,\n \"requestedCadenceFps\"\n );\n}\n\nfunction intervalForPreviousFrame(\n previousFrame:\n ResolvedReleaseFrame,\n requestedCadenceFps: number,\n capabilities:\n GenericReleaseCapabilityProfile\n): {\n seconds: number;\n constraints:\n readonly ReleaseTimingConstraint[];\n} {\n const requested =\n 1 / requestedCadenceFps;\n const capability =\n 1 /\n capabilities\n .maximumCadenceFps.value;\n const exposure =\n previousFrame\n .exposure.shutterSeconds;\n const gap =\n capabilities\n .minimumInterFrameGapSeconds\n .value;\n const physical =\n exposure + gap;\n const seconds =\n Math.max(\n requested,\n capability,\n physical\n );\n\n const tolerance =\n Math.max(1, seconds) *\n 1e-12;\n const constraints:\n ReleaseTimingConstraint[] =\n [];\n\n if (\n Math.abs(\n seconds - requested\n ) <= tolerance\n ) {\n constraints.push(\n \"requested-cadence\"\n );\n }\n if (\n Math.abs(\n seconds - capability\n ) <= tolerance\n ) {\n constraints.push(\n \"body-maximum-cadence\"\n );\n }\n if (\n Math.abs(\n seconds - physical\n ) <= tolerance\n ) {\n constraints.push(\n \"exposure-duration\"\n );\n if (gap > 0) {\n constraints.push(\n \"minimum-inter-frame-gap\"\n );\n }\n }\n\n return {\n seconds,\n constraints\n };\n}\n\n/**\n * Resolves one deterministic still-release sequence.\n *\n * It schedules logical exposures only; how the sensor captures each one is\n * handled elsewhere. Render speed or frame rate is never used as capture timing.\n */\nexport function resolveReleaseSequence(\n input:\n ResolveReleaseSequenceInput\n): ResolvedReleaseSequence {\n requireInputKeys(input, \"resolveReleaseSequence\", [\"sequenceId\", \"releaseRequestTimeSeconds\", \"sequenceSeedUint32\", \"drive\", \"bracket\", \"requestedCadenceFps\", \"baseState\", \"releaseCapabilities\", \"exposureCapabilities\"]);\n const sequenceId =\n requireNonEmptyString(\n input.sequenceId,\n \"sequenceId\"\n );\n const releaseRequestTime =\n requireFinite(\n input\n .releaseRequestTimeSeconds,\n \"releaseRequestTimeSeconds\"\n );\n const sequenceSeed =\n requireUint32(\n input.sequenceSeedUint32,\n \"sequenceSeedUint32\"\n );\n\n const releaseCapabilities =\n parseGenericReleaseCapabilityProfile(\n input.releaseCapabilities\n );\n\n if (\n !includesDriveMode(\n releaseCapabilities,\n input.drive.kind\n )\n ) {\n throw new InvalidScientificInputError(\n \"The selected drive mode is not supported by the release capability profile.\"\n );\n }\n\n validateBracketSupport(\n input,\n releaseCapabilities\n );\n\n const frameCount =\n resolveFrameCount(\n input.drive,\n input.bracket\n );\n\n if (\n frameCount >\n releaseCapabilities\n .maximumLogicalFramesPerSequence\n .value\n ) {\n throw new InvalidScientificInputError(\n \"Requested sequence frame count exceeds the release capability profile.\"\n );\n }\n\n const requestedCadenceFps =\n resolveRequestedCadence(\n frameCount,\n input.requestedCadenceFps\n );\n\n const selfTimerDelay =\n resolveSelfTimerDelay(\n input.drive\n );\n\n const baseState:\n ReleaseBaseCaptureState = {\n exposure:\n cloneJson(\n input.baseState.exposure\n ),\n focus:\n parseFocusPlane(\n input.baseState.focus\n ),\n automation:\n cloneJson(\n input.baseState.automation\n ),\n ...(input.baseState\n .whiteBalanceStateId ===\n undefined\n ? {}\n : {\n whiteBalanceStateId:\n requireNonEmptyString(\n input.baseState\n .whiteBalanceStateId,\n \"baseState.whiteBalanceStateId\"\n )\n })\n };\n\n validateExposure(\n baseState.exposure,\n input.exposureCapabilities,\n \"baseState.exposure\"\n );\n\n const frames:\n ResolvedReleaseFrame[] = [];\n\n for (\n let frameIndex = 0;\n frameIndex < frameCount;\n frameIndex += 1\n ) {\n const state =\n resolveFrameState(\n input,\n frameIndex\n );\n validateExposure(\n state.exposure,\n input.exposureCapabilities,\n \"frames[\" +\n frameIndex +\n \"].exposure\"\n );\n\n let exposureStartTimeSeconds:\n number;\n let startInterval:\n number | null = null;\n let timingConstraints:\n readonly ReleaseTimingConstraint[] =\n [];\n\n if (frameIndex === 0) {\n exposureStartTimeSeconds =\n releaseRequestTime +\n selfTimerDelay;\n } else {\n const previous =\n frames[\n frameIndex - 1\n ]!;\n if (\n requestedCadenceFps ===\n null\n ) {\n throw new InvalidScientificInputError(\n \"Multi-frame sequence lost its requested cadence.\"\n );\n }\n const interval =\n intervalForPreviousFrame(\n previous,\n requestedCadenceFps,\n releaseCapabilities\n );\n startInterval =\n interval.seconds;\n timingConstraints =\n interval.constraints;\n exposureStartTimeSeconds =\n previous\n .exposureStartTimeSeconds +\n interval.seconds;\n }\n\n const exposureEndTimeSeconds =\n exposureStartTimeSeconds +\n state.exposure\n .shutterSeconds;\n\n if (\n !Number.isFinite(\n exposureStartTimeSeconds\n ) ||\n !Number.isFinite(\n exposureEndTimeSeconds\n )\n ) {\n throw new InvalidScientificInputError(\n \"Resolved release-sequence timing must remain finite.\"\n );\n }\n\n frames.push({\n sequenceId,\n frameIndex,\n releaseFrameId:\n sequenceId +\n \":frame:\" +\n frameIndex,\n exposureStartTimeSeconds,\n exposureEndTimeSeconds,\n sceneTimeSecondsFromSequenceStart:\n exposureStartTimeSeconds -\n releaseRequestTime,\n startIntervalFromPreviousSeconds:\n startInterval,\n timingConstraints,\n stochasticSeedUint32:\n hashFrameSeed(\n sequenceSeed,\n frameIndex\n ),\n exposure:\n cloneJson(\n state.exposure\n ),\n focus:\n cloneJson(\n state.focus\n ),\n ...(state\n .exposureBracketOffsetStops ===\n undefined\n ? {}\n : {\n exposureBracketOffsetStops:\n state\n .exposureBracketOffsetStops\n }),\n automation:\n cloneJson(\n baseState.automation\n ),\n ...(baseState\n .whiteBalanceStateId ===\n undefined\n ? {}\n : {\n whiteBalanceStateId:\n baseState\n .whiteBalanceStateId\n })\n });\n }\n\n const sequence:\n ResolvedReleaseSequence = {\n version:\n RELEASE_SEQUENCE_VERSION,\n sequenceId,\n status: \"scheduled\",\n releaseRequestTimeSeconds:\n releaseRequestTime,\n selfTimerDelaySeconds:\n selfTimerDelay,\n requestedCadenceFps,\n capabilityMaximumCadenceFps:\n releaseCapabilities\n .maximumCadenceFps.value,\n minimumInterFrameGapSeconds:\n releaseCapabilities\n .minimumInterFrameGapSeconds\n .value,\n requestedFrameCount:\n frameCount,\n actualFrameCount:\n frames.length,\n sequenceSeedUint32:\n sequenceSeed,\n baseStateSnapshot:\n baseState,\n frames,\n sensorCaptureModeOwnership:\n \"separate-logical-capture-contract\",\n whiteBalanceBracketingPhysicalCaptures:\n false,\n preReleaseCaptureModeled:\n false,\n bufferMediaThermalSlowdownModeled:\n false\n };\n\n return deepFreeze(\n cloneJson(sequence)\n );\n}\n\n/**\n * Returns a cancelled copy of a sequence. The original scheduled sequence is not\n * changed, and it is always clear which frames were completed and which were dropped.\n */\nexport function createCancelledReleaseSequence(\n input:\n CancelReleaseSequenceInput\n): CancelledReleaseSequence {\n requireInputKeys(input, \"createCancelledReleaseSequence\", [\"sequence\", \"completedFrameCount\", \"cancelledAtSeconds\"]);\n const count =\n requireNonNegativeFinite(\n input.completedFrameCount,\n \"completedFrameCount\"\n );\n if (\n !Number.isSafeInteger(count)\n ) {\n throw new InvalidScientificInputError(\n \"completedFrameCount must be a safe integer.\"\n );\n }\n if (\n count >\n input.sequence.frames.length\n ) {\n throw new InvalidScientificInputError(\n \"completedFrameCount must not exceed the source sequence frame count.\"\n );\n }\n\n const cancelledAt =\n requireFinite(\n input.cancelledAtSeconds,\n \"cancelledAtSeconds\"\n );\n\n const result:\n CancelledReleaseSequence = {\n version:\n RELEASE_SEQUENCE_VERSION,\n sequenceId:\n input.sequence.sequenceId,\n status: \"cancelled\",\n cancelledAtSeconds:\n cancelledAt,\n completedFrameCount: count,\n omittedFrameCount:\n input.sequence.frames.length -\n count,\n completedFrames:\n cloneJson(\n input.sequence.frames.slice(\n 0,\n count\n )\n ),\n sourceSequenceFrameCount:\n input.sequence.frames.length,\n sourceSequenceUnmodified:\n true\n };\n\n return deepFreeze(\n cloneJson(result)\n );\n}\n"]}
@@ -9,7 +9,7 @@
9
9
  * limits.
10
10
  */
11
11
  import { requireAllowlistedRecord, requirePublicOpaqueId } from "../core/record-validation.js";
12
- import { parseSensorEqeTemporalPhotoSignal } from "../sensor/temporal-photo-signal.js";
12
+ import { parseSensorEqeTemporalPhotoSignal, PHOTO_SIGNAL_DOWNSTREAM_FALSE_FIELDS, PHOTO_SIGNAL_TRUE_FIELDS } from "../sensor/temporal-photo-signal.js";
13
13
  import { RAW_REFERENCE_MAX_NATIVE_SITES } from "./raw-frame-limits.js";
14
14
  import { approximationResult } from "../core/calculation-result.js";
15
15
  import { InvalidConfigurationError } from "../core/configuration-error.js";
@@ -109,10 +109,8 @@ function exposureEvidence(value, temporalPhoto) {
109
109
  }
110
110
  const common = ["colorSamplingProfileId", "channelId", "site", "bindingId", "stationarityProfileId", "timeReference",
111
111
  "startOffsetSecondsFromOpeningReference", "endOffsetSecondsFromOpeningReference", "localExposureDurationSeconds", "componentEvidence"];
112
- const photoTrue = ["timeStationarityEstablished", "temporalIntegrationApplied", "exposureDurationApplied", "countsAreExpectationValues"];
113
- const photoFalse = ["timeVaryingSignalIntegrated", "multiFrameSequenceIntegrated", "darkChargeIncluded", "otherChargeIncluded",
114
- "physicalFullWellAssessmentAuthorized", "cameraSaturationAssessmentAuthorized", "saturationAssessed", "shotNoiseApplied",
115
- "readNoiseApplied", "adcQuantizationApplied", "rawCodeValueProduced", "integerPhotonCountSampled", "integerElectronCountSampled", "chargeCalculated", "currentCalculated"];
112
+ const photoTrue = ["timeStationarityEstablished", ...PHOTO_SIGNAL_TRUE_FIELDS];
113
+ const photoFalse = ["timeVaryingSignalIntegrated", ...PHOTO_SIGNAL_DOWNSTREAM_FALSE_FIELDS];
116
114
  function chargeInput(value) {
117
115
  const r = fields(value, ["photoSignal", "darkCharge", "additionalChargeComponents", "completenessProfile"]);
118
116
  const temporal = r.photoSignal !== null && typeof r.photoSignal === "object" &&