@photivra/engine 2.20.0 → 2.22.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 (275) hide show
  1. package/CHANGELOG.md +295 -1
  2. package/CITATION.cff +1 -1
  3. package/README.md +7 -6
  4. package/SECURITY.md +1 -1
  5. package/THIRD_PARTY.md +18 -0
  6. package/dist/capture/c2pa-embed.d.ts +116 -0
  7. package/dist/capture/c2pa-embed.js +493 -0
  8. package/dist/capture/c2pa-embed.js.map +1 -0
  9. package/dist/capture/dng-import.d.ts +73 -8
  10. package/dist/capture/dng-import.js +315 -80
  11. package/dist/capture/dng-import.js.map +1 -1
  12. package/dist/capture/dng-lens-correction-opcodes.d.ts +2 -2
  13. package/dist/capture/dng-lens-correction-opcodes.js +2 -2
  14. package/dist/capture/dng-lens-correction-opcodes.js.map +1 -1
  15. package/dist/capture/dng-opcodes.d.ts +96 -0
  16. package/dist/capture/dng-opcodes.js +391 -0
  17. package/dist/capture/dng-opcodes.js.map +1 -0
  18. package/dist/capture/dng-profile-maps.d.ts +99 -0
  19. package/dist/capture/dng-profile-maps.js +381 -0
  20. package/dist/capture/dng-profile-maps.js.map +1 -0
  21. package/dist/capture/dng-stage-image.d.ts +23 -0
  22. package/dist/capture/dng-stage-image.js +65 -0
  23. package/dist/capture/dng-stage-image.js.map +1 -0
  24. package/dist/capture/exposure-build-up-stage.d.ts +16 -0
  25. package/dist/capture/exposure-build-up-stage.js +4 -0
  26. package/dist/capture/exposure-build-up-stage.js.map +1 -0
  27. package/dist/capture/jpeg-xl-tiles.d.ts +22 -0
  28. package/dist/capture/jpeg-xl-tiles.js +151 -0
  29. package/dist/capture/jpeg-xl-tiles.js.map +1 -0
  30. package/dist/capture/lossy-jpeg.d.ts +17 -0
  31. package/dist/capture/lossy-jpeg.js +369 -0
  32. package/dist/capture/lossy-jpeg.js.map +1 -0
  33. package/dist/capture/native-environment-lean.d.ts +2 -1
  34. package/dist/capture/native-environment-lean.js +41 -73
  35. package/dist/capture/native-environment-lean.js.map +1 -1
  36. package/dist/capture/native-environment-tabulated.js +4 -3
  37. package/dist/capture/native-environment-tabulated.js.map +1 -1
  38. package/dist/capture/native-raw-development.d.ts +2 -1
  39. package/dist/capture/native-raw-development.js.map +1 -1
  40. package/dist/capture/native-raw.d.ts +3 -2
  41. package/dist/capture/native-raw.js +5 -4
  42. package/dist/capture/native-raw.js.map +1 -1
  43. package/dist/capture/sensor-raw-producer.d.ts +4 -1
  44. package/dist/capture/sensor-raw-producer.js +12 -3
  45. package/dist/capture/sensor-raw-producer.js.map +1 -1
  46. package/dist/color/neighbor-highlight-reconstruction.d.ts +66 -0
  47. package/dist/color/neighbor-highlight-reconstruction.js +234 -0
  48. package/dist/color/neighbor-highlight-reconstruction.js.map +1 -0
  49. package/dist/color/sensor-color-development.d.ts +5 -0
  50. package/dist/color/sensor-color-development.js +7 -1
  51. package/dist/color/sensor-color-development.js.map +1 -1
  52. package/dist/color/spectral-spikiness.d.ts +11 -0
  53. package/dist/color/spectral-spikiness.js +23 -0
  54. package/dist/color/spectral-spikiness.js.map +1 -0
  55. package/dist/core/execution-error.d.ts +21 -0
  56. package/dist/core/execution-error.js +12 -0
  57. package/dist/core/execution-error.js.map +1 -0
  58. package/dist/core/version.d.ts +1 -1
  59. package/dist/core/version.js +1 -1
  60. package/dist/core/version.js.map +1 -1
  61. package/dist/equipment/generic-lens-catalogue.d.ts +3 -2
  62. package/dist/equipment/generic-lens-catalogue.js +18 -5
  63. package/dist/equipment/generic-lens-catalogue.js.map +1 -1
  64. package/dist/equipment/generic-tier-assets.d.ts +32 -0
  65. package/dist/equipment/generic-tier-assets.js +16 -11
  66. package/dist/equipment/generic-tier-assets.js.map +1 -1
  67. package/dist/equipment/sensor-profile-body.d.ts +78 -0
  68. package/dist/equipment/sensor-profile-body.js +77 -0
  69. package/dist/equipment/sensor-profile-body.js.map +1 -0
  70. package/dist/equipment/sensor-profiles.d.ts +8 -0
  71. package/dist/equipment/sensor-profiles.js +82 -0
  72. package/dist/equipment/sensor-profiles.js.map +1 -0
  73. package/dist/facade/catalogue-lens-signal.d.ts +28 -3
  74. package/dist/facade/catalogue-lens-signal.js +83 -78
  75. package/dist/facade/catalogue-lens-signal.js.map +1 -1
  76. package/dist/facade/chart-radiance-batch.js +2 -1
  77. package/dist/facade/chart-radiance-batch.js.map +1 -1
  78. package/dist/facade/defocus-image-space-provider.d.ts +7 -0
  79. package/dist/facade/defocus-image-space-provider.js +64 -76
  80. package/dist/facade/defocus-image-space-provider.js.map +1 -1
  81. package/dist/facade/diffraction-provider.d.ts +1 -1
  82. package/dist/facade/diffraction-provider.js +4 -4
  83. package/dist/facade/diffraction-provider.js.map +1 -1
  84. package/dist/facade/display-view-gpu-session.js +39 -5
  85. package/dist/facade/display-view-gpu-session.js.map +1 -1
  86. package/dist/facade/display-view-gpu.d.ts +19 -6
  87. package/dist/facade/display-view-gpu.js.map +1 -1
  88. package/dist/facade/display-view-lens-signal.js +25 -23
  89. package/dist/facade/display-view-lens-signal.js.map +1 -1
  90. package/dist/facade/display-view-normal.d.ts +15 -0
  91. package/dist/facade/display-view-normal.js +44 -0
  92. package/dist/facade/display-view-normal.js.map +1 -0
  93. package/dist/facade/display-view-rendering.d.ts +97 -0
  94. package/dist/facade/display-view-rendering.js +598 -0
  95. package/dist/facade/display-view-rendering.js.map +1 -0
  96. package/dist/facade/display-view.d.ts +37 -65
  97. package/dist/facade/display-view.js +152 -499
  98. package/dist/facade/display-view.js.map +1 -1
  99. package/dist/facade/expected-signal-setup.d.ts +3 -1
  100. package/dist/facade/expected-signal-setup.js +3 -3
  101. package/dist/facade/expected-signal-setup.js.map +1 -1
  102. package/dist/facade/expected-signal.d.ts +47 -14
  103. package/dist/facade/expected-signal.js +117 -112
  104. package/dist/facade/expected-signal.js.map +1 -1
  105. package/dist/facade/exposure-build-up.d.ts +70 -0
  106. package/dist/facade/exposure-build-up.js +164 -0
  107. package/dist/facade/exposure-build-up.js.map +1 -0
  108. package/dist/facade/fast-methods.d.ts +1 -1
  109. package/dist/facade/fast-methods.js +46 -9
  110. package/dist/facade/fast-methods.js.map +1 -1
  111. package/dist/facade/generic-lens-capture.d.ts +3 -3
  112. package/dist/facade/generic-lens-capture.js +3 -3
  113. package/dist/facade/generic-lens-capture.js.map +1 -1
  114. package/dist/facade/image-plane-enable.d.ts +7 -0
  115. package/dist/facade/image-plane-enable.js +17 -0
  116. package/dist/facade/image-plane-enable.js.map +1 -0
  117. package/dist/facade/image-plane-lattice-data.d.ts +6 -0
  118. package/dist/facade/image-plane-lattice-data.js +10 -0
  119. package/dist/facade/image-plane-lattice-data.js.map +1 -0
  120. package/dist/facade/image-plane-support.d.ts +33 -0
  121. package/dist/facade/image-plane-support.js +11 -0
  122. package/dist/facade/image-plane-support.js.map +1 -0
  123. package/dist/facade/image-plane.d.ts +36 -0
  124. package/dist/facade/image-plane.js +384 -0
  125. package/dist/facade/image-plane.js.map +1 -0
  126. package/dist/facade/mixed-illumination.d.ts +108 -0
  127. package/dist/facade/mixed-illumination.js +174 -0
  128. package/dist/facade/mixed-illumination.js.map +1 -0
  129. package/dist/facade/on-demand-kits.d.ts +14 -0
  130. package/dist/facade/on-demand-kits.js +36 -0
  131. package/dist/facade/on-demand-kits.js.map +1 -0
  132. package/dist/facade/opt-in-kit.d.ts +9 -0
  133. package/dist/facade/opt-in-kit.js +11 -0
  134. package/dist/facade/opt-in-kit.js.map +1 -0
  135. package/dist/facade/quality-kit.d.ts +21 -0
  136. package/dist/facade/quality-kit.js +23 -0
  137. package/dist/facade/quality-kit.js.map +1 -0
  138. package/dist/facade/quality-paths.d.ts +22 -0
  139. package/dist/facade/quality-paths.js +44 -0
  140. package/dist/facade/quality-paths.js.map +1 -0
  141. package/dist/facade/representative-light-sources.d.ts +72 -0
  142. package/dist/facade/representative-light-sources.js +124 -0
  143. package/dist/facade/representative-light-sources.js.map +1 -0
  144. package/dist/facade/scene-radiance.d.ts +145 -4
  145. package/dist/facade/scene-radiance.js +50 -13
  146. package/dist/facade/scene-radiance.js.map +1 -1
  147. package/dist/facade/simulate-capture.d.ts +68 -20
  148. package/dist/facade/simulate-capture.js +399 -146
  149. package/dist/facade/simulate-capture.js.map +1 -1
  150. package/dist/facade/simulate-display-view.d.ts +10 -12
  151. package/dist/facade/simulate-display-view.js +70 -53
  152. package/dist/facade/simulate-display-view.js.map +1 -1
  153. package/dist/gpu/chart-composite-gpu.d.ts +13 -1
  154. package/dist/gpu/chart-composite-gpu.js +48 -9
  155. package/dist/gpu/chart-composite-gpu.js.map +1 -1
  156. package/dist/gpu/chart-radiance-gpu.js +4 -30
  157. package/dist/gpu/chart-radiance-gpu.js.map +1 -1
  158. package/dist/gpu/display-view-composite-material-module.d.ts +10 -4
  159. package/dist/gpu/display-view-composite-material-module.js +39 -13
  160. package/dist/gpu/display-view-composite-material-module.js.map +1 -1
  161. package/dist/gpu/display-view-gpu-renderer.d.ts +43 -0
  162. package/dist/gpu/display-view-gpu-renderer.js +134 -0
  163. package/dist/gpu/display-view-gpu-renderer.js.map +1 -0
  164. package/dist/gpu/display-view-image-material-module.d.ts +87 -0
  165. package/dist/gpu/display-view-image-material-module.js +361 -0
  166. package/dist/gpu/display-view-image-material-module.js.map +1 -0
  167. package/dist/gpu/display-view-image-quality.d.ts +87 -0
  168. package/dist/gpu/display-view-image-quality.js +625 -0
  169. package/dist/gpu/display-view-image-quality.js.map +1 -0
  170. package/dist/gpu/display-view-quality-gpu.d.ts +80 -65
  171. package/dist/gpu/display-view-quality-gpu.js +187 -445
  172. package/dist/gpu/display-view-quality-gpu.js.map +1 -1
  173. package/dist/gpu/display-view-speed-gpu.d.ts +67 -19
  174. package/dist/gpu/display-view-speed-gpu.js +181 -105
  175. package/dist/gpu/display-view-speed-gpu.js.map +1 -1
  176. package/dist/gpu/image-kernel-accelerator.js +3 -0
  177. package/dist/gpu/image-kernel-accelerator.js.map +1 -1
  178. package/dist/gpu/image-kernel-execution.d.ts +2 -13
  179. package/dist/gpu/image-kernel-execution.js +2 -10
  180. package/dist/gpu/image-kernel-execution.js.map +1 -1
  181. package/dist/gpu/wgsl-display-view-coupled-stub.d.ts +8 -0
  182. package/dist/gpu/wgsl-display-view-coupled-stub.js +21 -0
  183. package/dist/gpu/wgsl-display-view-coupled-stub.js.map +1 -0
  184. package/dist/gpu/wgsl-display-view-coupled.d.ts +88 -0
  185. package/dist/gpu/wgsl-display-view-coupled.js +353 -0
  186. package/dist/gpu/wgsl-display-view-coupled.js.map +1 -0
  187. package/dist/gpu/wgsl-display-view-quality-kernel.d.ts +33 -24
  188. package/dist/gpu/wgsl-display-view-quality-kernel.js +166 -146
  189. package/dist/gpu/wgsl-display-view-quality-kernel.js.map +1 -1
  190. package/dist/gpu/wgsl-display-view-speed-kernel.d.ts +19 -44
  191. package/dist/gpu/wgsl-display-view-speed-kernel.js +116 -18
  192. package/dist/gpu/wgsl-display-view-speed-kernel.js.map +1 -1
  193. package/dist/gpu/wgsl-exact-sum.d.ts +20 -0
  194. package/dist/gpu/wgsl-exact-sum.js +42 -0
  195. package/dist/gpu/wgsl-exact-sum.js.map +1 -0
  196. package/dist/index.d.ts +22 -6
  197. package/dist/index.js +16 -2
  198. package/dist/index.js.map +1 -1
  199. package/dist/motion/subject-motion.d.ts +66 -0
  200. package/dist/motion/subject-motion.js +52 -0
  201. package/dist/motion/subject-motion.js.map +1 -0
  202. package/dist/optics/generic-lens-lateral-color.d.ts +83 -0
  203. package/dist/optics/generic-lens-lateral-color.js +77 -0
  204. package/dist/optics/generic-lens-lateral-color.js.map +1 -0
  205. package/dist/optics/generic-lens-psf.js +54 -46
  206. package/dist/optics/generic-lens-psf.js.map +1 -1
  207. package/dist/optics/lens-psf-profile.d.ts +7 -0
  208. package/dist/optics/lens-psf-profile.js +2 -1
  209. package/dist/optics/lens-psf-profile.js.map +1 -1
  210. package/dist/output/camera-channel-response.d.ts +50 -0
  211. package/dist/output/camera-channel-response.js +69 -0
  212. package/dist/output/camera-channel-response.js.map +1 -0
  213. package/dist/output/developed-lens-corrections.d.ts +19 -5
  214. package/dist/output/developed-lens-corrections.js +28 -9
  215. package/dist/output/developed-lens-corrections.js.map +1 -1
  216. package/dist/output/generic-lens-corrections.d.ts +41 -5
  217. package/dist/output/generic-lens-corrections.js +52 -8
  218. package/dist/output/generic-lens-corrections.js.map +1 -1
  219. package/dist/output/native-capture-sdr.js +5 -2
  220. package/dist/output/native-capture-sdr.js.map +1 -1
  221. package/dist/output/print-plan.d.ts +41 -5
  222. package/dist/output/print-plan.js +59 -14
  223. package/dist/output/print-plan.js.map +1 -1
  224. package/dist/output/sdr-rendering.d.ts +18 -1
  225. package/dist/output/sdr-rendering.js +39 -2
  226. package/dist/output/sdr-rendering.js.map +1 -1
  227. package/dist/sensor/binomial-sample.d.ts +3 -0
  228. package/dist/sensor/binomial-sample.js +86 -0
  229. package/dist/sensor/binomial-sample.js.map +1 -0
  230. package/dist/sensor/native-sensor-report.d.ts +10 -0
  231. package/dist/sensor/native-sensor-report.js +16 -0
  232. package/dist/sensor/native-sensor-report.js.map +1 -0
  233. package/dist/sensor/sensor-characteristics.d.ts +91 -13
  234. package/dist/sensor/sensor-characteristics.js +30 -15
  235. package/dist/sensor/sensor-characteristics.js.map +1 -1
  236. package/docs/AGENT_GUIDE.md +1 -0
  237. package/docs/API_REFERENCE.md +214 -4
  238. package/docs/QUICK_START.md +162 -8
  239. package/docs/USAGE.md +195 -22
  240. package/docs/api/capture-c2pa-embed.md +177 -0
  241. package/docs/api/capture-dng-import.md +86 -10
  242. package/docs/api/capture-dng-opcodes.md +93 -0
  243. package/docs/api/capture-dng-profile-maps.md +141 -0
  244. package/docs/api/capture-dng-stage-image.md +43 -0
  245. package/docs/api/capture-jpeg-xl-tiles.md +33 -0
  246. package/docs/api/capture-lossy-jpeg.md +41 -0
  247. package/docs/api/capture-native-raw-development.md +2 -1
  248. package/docs/api/core-execution-error.md +43 -0
  249. package/docs/api/core-version.md +1 -1
  250. package/docs/api/equipment-generic-lens-catalogue.md +10 -5
  251. package/docs/api/equipment-sensor-profile-body.md +64 -0
  252. package/docs/api/equipment-sensor-profiles.md +86 -0
  253. package/docs/api/exports.json +460 -5
  254. package/docs/api/facade-display-view-gpu.md +5 -2
  255. package/docs/api/facade-display-view.md +11 -15
  256. package/docs/api/facade-exposure-build-up.md +105 -0
  257. package/docs/api/facade-fast-methods.md +47 -10
  258. package/docs/api/facade-image-plane-enable.md +16 -0
  259. package/docs/api/facade-mixed-illumination.md +67 -0
  260. package/docs/api/facade-quality-paths.md +24 -0
  261. package/docs/api/facade-representative-light-sources.md +131 -0
  262. package/docs/api/facade-scene-radiance.md +54 -3
  263. package/docs/api/facade-simulate-capture.md +48 -11
  264. package/docs/api/facade-simulate-display-view.md +10 -12
  265. package/docs/api/gpu-image-kernel-execution.md +0 -36
  266. package/docs/api/motion-subject-motion.md +23 -0
  267. package/docs/api/optics-generic-lens-lateral-color.md +79 -0
  268. package/docs/api/output-camera-channel-response.md +55 -0
  269. package/docs/api/output-developed-lens-corrections.md +10 -1
  270. package/docs/api/output-generic-lens-corrections.md +40 -4
  271. package/docs/api/output-print-plan.md +35 -1
  272. package/docs/api/output-sdr-rendering.md +6 -1
  273. package/docs/api/sensor-sensor-characteristics.md +54 -2
  274. package/llms.txt +3 -0
  275. package/package.json +6 -5
@@ -1 +1 @@
1
- {"version":3,"file":"native-capture-sdr.js","sourceRoot":"","sources":["../../src/output/native-capture-sdr.ts"],"names":[],"mappings":"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","sourcesContent":["// SPDX-License-Identifier: Apache-2.0\n\n/**\n * Native SDR rendering of large captures, tile by tile, within fixed memory limits. The engine\n * owns the task; the caller supplies the pixel tiles. See docs/NATIVE_CAPTURE_SDR.md.\n */\nimport { parseSimulatedCapture, type SimulatedCapture, type CaptureLinearPlane } from \"../capture/simulated-capture.js\";\nimport { LINEAR_CAPTURE_RGB_PROFILE, resolveCaptureColorModel } from \"../color/capture-color.js\";\nimport { InvalidConfigurationError } from \"../core/configuration-error.js\";\nimport { requireAllowlistedRecord, requirePublicOpaqueId } from \"../core/record-validation.js\";\nimport { freezeOwnedData } from \"../core/owned-data.js\";\nimport { FULL_RESOLUTION_CEILING_PIXELS, resolveRaisedLimit } from \"../core/pixel-limits.js\";\nimport { encodeSrgbComponent } from \"../color/srgb-transfer.js\";\nimport { InvalidScientificResultError } from \"../core/validation.js\";\nimport { parseSdrRenderingProfile, prepareSdrPixelTone, type SdrPixelTone, type SdrRenderingProfile, type SdrRenderingResult } from \"./sdr-rendering.js\";\n\nexport const NATIVE_CAPTURE_SDR_SCHEMA_VERSION = \"0.1.0\" as const;\n/** `maximumPixels` is the default pixel limit; a request may raise it with its own `maximumPixels`, up to `ceilingPixels`. */\nexport const NATIVE_CAPTURE_SDR_LIMITS = /* @__PURE__ */ Object.freeze({ maximumPixels: 24_000_000, ceilingPixels: FULL_RESOLUTION_CEILING_PIXELS,\n maximumDimension: 16_384, tileWidth: 256, tileHeight: 32, maximumTileStorageSamples: 32_768 });\n/** Input. The capture holds only metadata; float samples are read from external storage. Samples must already have colour and white balance applied. */\nexport interface NativeCaptureSdrInput {\n capture: SimulatedCapture;\n sourcePlaneId: string;\n outputImageStateId: string;\n profile: SdrRenderingProfile;\n /** Limit on the size of the integer output. Checked before anything is allocated or any tile is read. */\n maximumOutputBytes: number;\n /**\n * Optional opt-in pixel limit for large captures: an integer from 1 to `NATIVE_CAPTURE_SDR_LIMITS.ceilingPixels`.\n * Default `NATIVE_CAPTURE_SDR_LIMITS.maximumPixels` (24 000 000). `maximumOutputBytes` still applies.\n */\n maximumPixels?: number;\n}\n/** Tile request. Coordinates are absolute in the selected plane's declared pixel grid, never relative to a crop. */\nexport interface NativeCaptureSdrTileRequest {\n captureId: string;\n sourcePlaneId: string;\n artifactId: string;\n sha256: string;\n x: number; y: number; width: number; height: number;\n}\n/** A tile returned by the provider. It belongs to this call alone; do not change or reuse it. Row padding is not image data. */\nexport interface NativeCaptureSdrTile extends NativeCaptureSdrTileRequest {\n rowStrideSamples: number;\n samples: Float32Array | Float64Array;\n}\n/** Supplies tiles, one call at a time. The caller must release decoder and GPU resources when the task aborts or finishes. */\nexport interface NativeCaptureSdrProvider {\n readTile(request: Readonly<NativeCaptureSdrTileRequest>, signal: AbortSignal): Promise<NativeCaptureSdrTile>;\n /** Must yield to the host event loop, so cancellation and input events can run between tiles. */\n yieldControl(signal: AbortSignal): Promise<void>;\n /**\n * Optional progress observer, called synchronously after each committed tile. It cannot change\n * output; an exception it throws fails the task like any other error.\n */\n onProgress?(progress: NativeTaskProgress): void;\n}\n/** Tile progress of a native task: `completedTileCount` of `totalTileCount` tiles are committed. */\nexport interface NativeTaskProgress { readonly completedTileCount: number; readonly totalTileCount: number }\nexport interface NativeCaptureSdrPlan {\n schemaVersion: typeof NATIVE_CAPTURE_SDR_SCHEMA_VERSION;\n capture: SimulatedCapture;\n sourcePlaneId: string;\n outputImageStateId: string;\n profile: SdrRenderingProfile;\n outputBytes: number;\n /** Upper bound on the bytes held in working arrays. It is not peak JavaScript heap, GPU or process memory, and does not show that a device can run the task. */\n maximumScratchPayloadBytes: number;\n tileCount: number;\n}\nexport interface NativeCaptureSdrOutput {\n plan: NativeCaptureSdrPlan;\n /** Packed RGB codes in row-major order, owned by the caller. 16-bit codes are numbers, not bytes in a particular byte order. */\n integerSamples: Uint8Array | Uint16Array;\n diagnostics: SdrRenderingResult[\"diagnostics\"];\n outputEncoding: SdrRenderingResult[\"outputEncoding\"];\n displayAdaptation: SdrRenderingResult[\"displayAdaptation\"];\n}\nexport type NativeCaptureSdrTaskState = \"ready\" | \"running\" | \"completed\" | \"cancelled\" | \"failed\" | \"disposed\" | \"transferred\";\n\n/** Validates the input and plans the task, including its limits, without reading samples or allocating an image. */\nexport function calculateNativeCaptureSdrPlan(input: NativeCaptureSdrInput): NativeCaptureSdrPlan {\n const r = requireAllowlistedRecord(input, [\"capture\", \"sourcePlaneId\", \"outputImageStateId\", \"profile\", \"maximumOutputBytes\", \"maximumPixels\"], \"Invalid native SDR input.\");\n const maximumPixels = resolveRaisedLimit(r.maximumPixels, NATIVE_CAPTURE_SDR_LIMITS.maximumPixels, NATIVE_CAPTURE_SDR_LIMITS.ceilingPixels,\n \"Native SDR maximumPixels must be an integer from 1 to \" + NATIVE_CAPTURE_SDR_LIMITS.ceilingPixels + \".\");\n // Only external-storage manifests are accepted, so unrelated inline sample buffers are never copied.\n const c = r.capture as SimulatedCapture | undefined;\n if (!c || !Array.isArray(c.planes) || c.planes.length > 32 || c.planes.some(p => !p || p.storage?.kind === \"inline-float64\")) {\n throw new InvalidConfigurationError(\"Native SDR requires external-only capture manifests.\");\n }\n const capture = parseSimulatedCapture(c);\n const sourcePlaneId = requirePublicOpaqueId(r.sourcePlaneId, \"Invalid native SDR plane ID.\");\n const outputImageStateId = requirePublicOpaqueId(r.outputImageStateId, \"Invalid native SDR output state ID.\");\n const plane = capture.planes.find(p => p.id === sourcePlaneId);\n const white = resolveCaptureColorModel().referenceWhiteXyz;\n if (!plane || plane.imageState !== \"color-transformed-linear-rgb\" ||\n plane.colorProfile?.id !== LINEAR_CAPTURE_RGB_PROFILE.id || plane.colorProfile.version !== LINEAR_CAPTURE_RGB_PROFILE.version ||\n plane.encodingReferenceWhiteXyz?.x !== white.x || plane.encodingReferenceWhiteXyz.y !== white.y || plane.encodingReferenceWhiteXyz.z !== white.z ||\n plane.whiteBalanceApplication === \"intent-only\" || (plane.whiteBalanceApplication === \"not-applicable\" && capture.whiteBalanceIntent !== null) ||\n capture.planes.some(p => p.imageStateId === outputImageStateId)) {\n throw new InvalidConfigurationError(\"Native SDR requires exact resolved linear-sRGB/D65 and a new output state ID.\");\n }\n const pixels = plane.pixelWidth * plane.pixelHeight, profile = parseSdrRenderingProfile(r.profile);\n const outputBytes = pixels * 3 * (profile.bitDepth / 8);\n const scale = 2 ** profile.renderingExposureEv / plane.referenceWhiteValue;\n if (!Number.isFinite(scale) || scale <= 0) throw new InvalidConfigurationError(\"Native SDR scale is unrepresentable.\");\n if (pixels > maximumPixels || plane.pixelWidth > NATIVE_CAPTURE_SDR_LIMITS.maximumDimension ||\n plane.pixelHeight > NATIVE_CAPTURE_SDR_LIMITS.maximumDimension || typeof r.maximumOutputBytes !== \"number\" ||\n !Number.isSafeInteger(r.maximumOutputBytes) || r.maximumOutputBytes < outputBytes) {\n throw new InvalidConfigurationError(\"Native SDR raster/output exceeds declared admission limits.\");\n }\n // A cautious declared bound, kept from the earlier executor that called the reference renderer: provider payload +\n // packed copy + reference parser copy + four reference output arrays. The typed kernel itself keeps only the provider payload.\n const maximumScratchPayloadBytes = NATIVE_CAPTURE_SDR_LIMITS.maximumTileStorageSamples * 8 +\n NATIVE_CAPTURE_SDR_LIMITS.tileWidth * NATIVE_CAPTURE_SDR_LIMITS.tileHeight * 3 * 8 * 6;\n return freezeOwnedData({ schemaVersion: NATIVE_CAPTURE_SDR_SCHEMA_VERSION, capture, sourcePlaneId, outputImageStateId, profile,\n outputBytes, maximumScratchPayloadBytes,\n tileCount: Math.ceil(plane.pixelWidth / NATIVE_CAPTURE_SDR_LIMITS.tileWidth) * Math.ceil(plane.pixelHeight / NATIVE_CAPTURE_SDR_LIMITS.tileHeight) });\n}\n\n/**\n * Tile checks shared by every native SDR backend: identity, precision, row stride, storage and valid\n * input values. Returns a view of the provider's samples (not a copy). Padding is not checked for\n * finite values. Not exported from the package.\n */\nexport function validateNativeCaptureSdrTile(tile: NativeCaptureSdrTile, request: NativeCaptureSdrTileRequest,\n plane: CaptureLinearPlane): { source: Float32Array | Float64Array; stride: number } {\n const r = requireAllowlistedRecord(tile, [\"captureId\", \"sourcePlaneId\", \"artifactId\", \"sha256\", \"x\", \"y\", \"width\", \"height\", \"rowStrideSamples\", \"samples\"], \"Invalid native SDR tile.\");\n for (const key of Object.keys(request) as (keyof NativeCaptureSdrTileRequest)[]) {\n if (r[key] !== request[key]) throw new InvalidConfigurationError(\"Native SDR tile identity/rectangle mismatch.\");\n }\n const samples = r.samples;\n const expectedType = plane.storage.kind === \"external-float32\" ? Float32Array : Float64Array;\n if (!(samples instanceof expectedType) || !(samples.buffer instanceof ArrayBuffer) ||\n samples.buffer.byteLength > NATIVE_CAPTURE_SDR_LIMITS.maximumTileStorageSamples * expectedType.BYTES_PER_ELEMENT ||\n typeof r.rowStrideSamples !== \"number\" || !Number.isSafeInteger(r.rowStrideSamples) || r.rowStrideSamples < request.width * 3 ||\n samples.length !== r.rowStrideSamples * request.height || samples.length > NATIVE_CAPTURE_SDR_LIMITS.maximumTileStorageSamples) {\n throw new InvalidConfigurationError(\"Native SDR tile precision/stride/storage mismatch.\");\n }\n const source: Float32Array | Float64Array = samples, stride = r.rowStrideSamples, rowLength = request.width * 3;\n // Check every image sample (not padding) against the reference renderer's input rules before any rendering.\n for (let y = 0; y < request.height; y++) {\n for (let i = y * stride, end = i + rowLength; i < end; i++) {\n if (!Number.isFinite(source[i]!)) throw new InvalidConfigurationError(\"Unsupported SDR input domain/raster.\");\n }\n }\n return { source, stride };\n}\n\ntype NativeSdrDiagnosticCounts = Omit<SdrRenderingResult[\"diagnostics\"], \"captureSaturation\">;\n/**\n * Fast tile kernel on typed arrays. It applies the same equations as the SDR reference renderer\n * (`calculateSdrRendering`), with the same floating-point operation order per sample and the same\n * error precedence, and writes integer codes straight into the packed output.\n *\n * Steps: input check → rendering exposure → tone → gamut → sRGB transfer → quantization (round to\n * nearest, ties up). `test/native-capture-sdr-kernel-parity.test.ts` shows that codes and diagnostics\n * match the unchanged reference exactly.\n */\nfunction renderTileInto(tile: NativeCaptureSdrTile, request: NativeCaptureSdrTileRequest, plane: CaptureLinearPlane,\n profile: SdrRenderingProfile, tone: SdrPixelTone, scale: number, maximum: number, codes: Uint8Array | Uint16Array, diagnostics: NativeSdrDiagnosticCounts): void {\n const { source, stride } = validateNativeCaptureSdrTile(tile, request, plane);\n // Tiling is safe because every supported rendering operation works on one pixel at a time.\n const outputRowStride = plane.pixelWidth * 3;\n const counts = { negative: 0, above: 0, changed: 0, low: 0, high: 0, outOfGamut: false }, scratch = new Float64Array(3);\n for (let y = 0; y < request.height; y++) {\n renderSdrRunInto(source, y * stride, request.width, profile, tone, scale, maximum, codes, (request.y + y) * outputRowStride + request.x * 3, scratch, counts);\n }\n if (counts.outOfGamut) throw new InvalidConfigurationError(\"Tone output exceeds the declared SDR gamut range.\");\n diagnostics.renderingNegativeSampleCount += counts.negative; diagnostics.renderingAboveReferenceSampleCount += counts.above;\n diagnostics.toneChangedSampleCount += counts.changed; diagnostics.gamutClippedLowSampleCount += counts.low; diagnostics.gamutClippedHighSampleCount += counts.high;\n}\n/** Reference 8-bit code of a linear sample in [0,1]: Math.round(encodeSrgbComponent(x)·255). */\nfunction referenceSrgb8(linear: number): number { return Math.round(encodeSrgbComponent(linear) * 255); }\n/** Exact 8-bit sRGB quantizer tables; see {@link srgb8Quantizer}. */\nexport interface Srgb8Quantizer {\n /** t[k]: smallest binary64 x in [0,1] with referenceSrgb8(x) ≥ k; t[256] = +∞ sentinel. */\n readonly thresholds: Float64Array;\n /** start[b]: reference code of b/4096, the first code of bucket [b/4096, (b+1)/4096). */\n readonly start: Uint8Array;\n}\nlet srgb8: Srgb8Quantizer | null | undefined;\n/**\n * Exact 8-bit sRGB quantization without evaluating the transfer curve for each sample.\n *\n * The code thresholds are found by bisection on this engine's own `encodeSrgbComponent`. Comparing\n * against them gives Math.round(encodeSrgbComponent(x)·255) for every x, provided that function never\n * decreases (true when pow is monotone). Construction checks every threshold and the 16 neighbouring\n * doubles on each side. If any check fails, the direct transfer is used instead, so output never\n * silently depends on that assumption.\n *\n * A 4097-entry bucket index (x·4096 is exact) gives the starting code. Even the steepest part of the\n * curve (slope 12.92·255) covers less than one code per bucket, so one or two comparisons finish.\n */\nfunction srgb8Quantizer(): Srgb8Quantizer | null {\n if (srgb8 !== undefined) return srgb8;\n const t = new Float64Array(257), bits = new Float64Array(1), word = new BigUint64Array(bits.buffer);\n const step = (x: number, n: number): number => { bits[0] = x; word[0] = word[0]! + BigInt(n); return bits[0]!; };\n for (let k = 1; k < 256; k++) {\n let lo = t[k - 1]!, hi = 1;\n for (;;) {\n const mid = lo + (hi - lo) / 2;\n if (mid === lo || mid === hi) break;\n if (referenceSrgb8(mid) >= k) hi = mid; else lo = mid;\n }\n t[k] = hi;\n }\n t[256] = Infinity;\n let valid = referenceSrgb8(0) === 0 && referenceSrgb8(1) === 255;\n for (let k = 1; valid && k < 256; k++) {\n const x = t[k]!;\n if (!(x > t[k - 1]!) || referenceSrgb8(x) !== k) valid = false;\n for (let n = 1; valid && n <= 16; n++) {\n const below = step(x, -n), above = step(x, n);\n if ((below >= 0 && referenceSrgb8(below) >= k) || (above <= 1 && referenceSrgb8(above) < k)) valid = false;\n }\n }\n const start = new Uint8Array(4097);\n for (let i = 0; valid && i <= 4096; i++) { start[i] = referenceSrgb8(i / 4096); if (i > 0 && start[i]! < start[i - 1]!) valid = false; }\n srgb8 = valid ? { thresholds: t, start } : null;\n return srgb8;\n}\n/** Largest k with t[k] ≤ x for x in [0,1]. */\nfunction quantizeSrgb8(q: Srgb8Quantizer, x: number): number {\n const t = q.thresholds;\n let k = q.start[(x * 4096) | 0]!;\n while (x >= t[k + 1]!) k++;\n return k;\n}\n/** Internal, for tests: the exact quantizer (null when its construction check failed). */\nexport function nativeSrgb8QuantizerForTest(): { quantizer: Srgb8Quantizer | null; quantize(x: number): number } {\n const quantizer = srgb8Quantizer();\n return { quantizer, quantize: (x) => quantizer ? quantizeSrgb8(quantizer, x) : referenceSrgb8(x) };\n}\n/** Per-tile counters for {@link renderSdrRunInto}. `outOfGamut` delays the rejection, as the reference does. */\nexport interface SdrPixelCounts { negative: number; above: number; changed: number; low: number; high: number; outOfGamut: boolean }\n/**\n * Internal SDR kernel on typed arrays, shared by native SDR and RAW development.\n *\n * For `pixelCount` interleaved linear-sRGB pixels starting at `source[start]`, it runs exactly the\n * reference (`calculateSdrRendering`) operations in the same order per pixel: -0 → +0 → rendering\n * exposure → shared tone operator → gamut → sRGB transfer → quantization (nearest, ties up) into\n * `codes[outOffset]` (with `maximum` 0, the encoded value unquantized). A gamut rejection is delayed via `counts.outOfGamut`, because the reference\n * finishes the whole tone pass (and its exposure errors) first. `scratch` must hold at least 3\n * values. Not exported from the package.\n */\nexport function renderSdrRunInto(source: Float32Array | Float64Array, start: number, pixelCount: number, profile: SdrRenderingProfile,\n tone: SdrPixelTone, scale: number, maximum: number, codes: Uint8Array | Uint16Array | Float64Array, outOffset: number, scratch: Float64Array, counts: SdrPixelCounts): void {\n const reject = profile.gamutHandling === \"reject-out-of-range\", quantizer = maximum === 255 ? srgb8Quantizer() : null;\n let negative = 0, above = 0, changed = 0, low = 0, high = 0, outOfGamut = false;\n for (let p = 0, i = start, o = outOffset; p < pixelCount; p++, i += 3) {\n // The reference parser normalizes -0 to +0 before exposure.\n const red = source[i]!, green = source[i + 1]!, blue = source[i + 2]!;\n const er = (red === 0 ? 0 : red) * scale, eg = (green === 0 ? 0 : green) * scale, eb = (blue === 0 ? 0 : blue) * scale;\n if (!Number.isFinite(er) || !Number.isFinite(eg) || !Number.isFinite(eb)) throw new InvalidScientificResultError(\"Rendering exposure produced a non-finite sample.\");\n tone(er, eg, eb, scratch);\n for (let c = 0; c < 3; c++, o++) {\n const exposed = c === 0 ? er : c === 1 ? eg : eb;\n if (exposed < 0) negative++;\n if (exposed > 1) above++;\n let mapped = scratch[c]!;\n if (mapped !== exposed) changed++;\n if (mapped === 0) mapped = 0;\n let linear = mapped;\n if (mapped < 0 || mapped > 1) {\n if (reject) outOfGamut = true;\n else if (mapped < 0) { low++; linear = 0; }\n else { high++; linear = 1; }\n }\n // Encoded values are in [0,1]: Math.round is exact nearest-ties-up here.\n // maximum 0 (#571): the encoded value itself, unquantized, into a Float64Array (the unsharp mask's input).\n codes[o] = quantizer ? quantizeSrgb8(quantizer, linear) : maximum === 0 ? encodeSrgbComponent(linear) : Math.round(encodeSrgbComponent(linear) * maximum);\n }\n }\n counts.negative += negative; counts.above += above; counts.changed += changed; counts.low += low; counts.high += high;\n if (outOfGamut) counts.outOfGamut = true;\n}\n\n/** The reference's output-encoding declaration for the given code maximum. */\nexport function sdrOutputEncoding(maximum: number): SdrRenderingResult[\"outputEncoding\"] {\n return { imageState: \"output-referred-sdr\", colorSpace: \"srgb\", primariesXy: { red: [.64, .33], green: [.30, .60], blue: [.15, .06] },\n whitePointXy: [.3127, .3290], referenceWhiteLuminanceCdM2: 80, codeMinimum: 0, codeMaximum: maximum };\n}\n\n/** A single-use task. No partial output is ever returned, and cancel or dispose stops a late result from being published. */\nexport interface NativeCaptureSdrTask {\n readonly plan: NativeCaptureSdrPlan;\n readonly state: NativeCaptureSdrTaskState;\n readonly completedTileCount: number;\n run(): Promise<void>;\n cancel(): void;\n dispose(): void;\n /** Hands over the only copy of the output buffer, once. Dispose cannot take back a buffer already handed over. */\n takeOutput(): NativeCaptureSdrOutput;\n}\n/** Creates a single-use task. Limits are checked before any buffer is allocated or tile is read. */\nexport function createNativeCaptureSdrTask(input: NativeCaptureSdrInput, provider: NativeCaptureSdrProvider): NativeCaptureSdrTask {\n const plan = calculateNativeCaptureSdrPlan(input);\n if (!provider || typeof provider.readTile !== \"function\" || typeof provider.yieldControl !== \"function\") {\n throw new InvalidConfigurationError(\"Native SDR requires a tile reader and event-loop yield.\");\n }\n if (provider.onProgress !== undefined && typeof provider.onProgress !== \"function\") throw new InvalidConfigurationError(\"Native SDR onProgress must be a function.\");\n // Also capture the callback functions now, so later app changes cannot swap the reader mid-task.\n const readTile = provider.readTile.bind(provider), yieldControl = provider.yieldControl.bind(provider),\n onProgress = provider.onProgress?.bind(provider);\n const plane = plan.capture.planes.find(p => p.id === plan.sourcePlaneId)!;\n if (plane.storage.kind === \"inline-float64\") throw new InvalidConfigurationError(\"External native source required.\");\n const storage = plane.storage, abort = new AbortController();\n let state: NativeCaptureSdrTaskState = \"ready\", count = 0, output: NativeCaptureSdrOutput | null = null;\n let codes: Uint8Array | Uint16Array | null = null;\n function release(): void { codes?.fill(0); codes = null; output = null; }\n function checkActive(): void {\n if (abort.signal.aborted) throw new InvalidConfigurationError(\"Native SDR task cancelled/disposed; no output available.\");\n }\n return {\n plan,\n get state(): NativeCaptureSdrTaskState { return state; },\n get completedTileCount(): number { return count; },\n async run(): Promise<void> {\n if (state !== \"ready\") throw new InvalidConfigurationError(\"Native SDR task is single-use.\");\n state = \"running\";\n try {\n codes = plan.profile.bitDepth === 8 ? new Uint8Array(plan.outputBytes) : new Uint16Array(plan.outputBytes / 2);\n const diagnostics: SdrRenderingResult[\"diagnostics\"] = { renderingNegativeSampleCount: 0, renderingAboveReferenceSampleCount: 0,\n toneChangedSampleCount: 0, gamutClippedLowSampleCount: 0, gamutClippedHighSampleCount: 0, captureSaturation: \"not-consumed\" };\n // Same scale expression and code range as the reference. The plan already rejected a scale that cannot be represented.\n const scale = 2 ** plan.profile.renderingExposureEv / plane.referenceWhiteValue, maximum = 2 ** plan.profile.bitDepth - 1,\n tone = prepareSdrPixelTone(plan.profile);\n for (let y = 0; y < plane.pixelHeight; y += NATIVE_CAPTURE_SDR_LIMITS.tileHeight) {\n for (let x = 0; x < plane.pixelWidth; x += NATIVE_CAPTURE_SDR_LIMITS.tileWidth) {\n checkActive();\n const request = Object.freeze({ captureId: plan.capture.captureId, sourcePlaneId: plane.id,\n artifactId: storage.artifactId, sha256: storage.sha256, x, y,\n width: Math.min(NATIVE_CAPTURE_SDR_LIMITS.tileWidth, plane.pixelWidth - x),\n height: Math.min(NATIVE_CAPTURE_SDR_LIMITS.tileHeight, plane.pixelHeight - y) });\n {\n const tile = await readTile(request, abort.signal);\n checkActive();\n // Diagnostics are aggregated only after the whole tile renders.\n renderTileInto(tile, request, plane, plan.profile, tone, scale, maximum, codes!, diagnostics);\n count++;\n onProgress?.({ completedTileCount: count, totalTileCount: plan.tileCount });\n }\n // Do not keep tile or reference arrays past the next tile read or host yield.\n await yieldControl(abort.signal);\n checkActive();\n }\n }\n output = { plan, integerSamples: codes!, diagnostics, outputEncoding: sdrOutputEncoding(maximum),\n displayAdaptation: { kind: \"external-platform\", applied: false, displayCapabilities: \"unknown\" } };\n state = \"completed\";\n } catch (error) {\n release();\n if (!abort.signal.aborted) { state = \"failed\"; abort.abort(); }\n throw error;\n }\n },\n cancel(): void {\n if (state === \"ready\" || state === \"running\" || state === \"completed\") { state = \"cancelled\"; abort.abort(); release(); }\n },\n dispose(): void { if (state !== \"transferred\") { state = \"disposed\"; abort.abort(); release(); } },\n takeOutput(): NativeCaptureSdrOutput {\n if (state !== \"completed\" || !output) throw new InvalidConfigurationError(\"Native SDR output is unavailable.\");\n const result = output; output = null; codes = null; state = \"transferred\";\n return result;\n }\n };\n}\n"]}
1
+ {"version":3,"file":"native-capture-sdr.js","sourceRoot":"","sources":["../../src/output/native-capture-sdr.ts"],"names":[],"mappings":"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","sourcesContent":["// SPDX-License-Identifier: Apache-2.0\n\n/**\n * Native SDR rendering of large captures, tile by tile, within fixed memory limits. The engine\n * owns the task; the caller supplies the pixel tiles. See docs/NATIVE_CAPTURE_SDR.md.\n */\nimport { parseSimulatedCapture, type SimulatedCapture, type CaptureLinearPlane } from \"../capture/simulated-capture.js\";\nimport { LINEAR_CAPTURE_RGB_PROFILE, resolveCaptureColorModel } from \"../color/capture-color.js\";\nimport { InvalidConfigurationError } from \"../core/configuration-error.js\";\nimport { requireAllowlistedRecord, requirePublicOpaqueId } from \"../core/record-validation.js\";\nimport { freezeOwnedData } from \"../core/owned-data.js\";\nimport { FULL_RESOLUTION_CEILING_PIXELS, resolveRaisedLimit } from \"../core/pixel-limits.js\";\nimport { encodeSrgbComponent } from \"../color/srgb-transfer.js\";\nimport { InvalidScientificResultError } from \"../core/validation.js\";\nimport { desaturateToLuminance, parseSdrRenderingProfile, prepareSdrPixelTone, type SdrPixelTone, type SdrRenderingProfile, type SdrRenderingResult } from \"./sdr-rendering.js\";\n\nexport const NATIVE_CAPTURE_SDR_SCHEMA_VERSION = \"0.1.0\" as const;\n/** `maximumPixels` is the default pixel limit; a request may raise it with its own `maximumPixels`, up to `ceilingPixels`. */\nexport const NATIVE_CAPTURE_SDR_LIMITS = /* @__PURE__ */ Object.freeze({ maximumPixels: 24_000_000, ceilingPixels: FULL_RESOLUTION_CEILING_PIXELS,\n maximumDimension: 16_384, tileWidth: 256, tileHeight: 32, maximumTileStorageSamples: 32_768 });\n/** Input. The capture holds only metadata; float samples are read from external storage. Samples must already have colour and white balance applied. */\nexport interface NativeCaptureSdrInput {\n capture: SimulatedCapture;\n sourcePlaneId: string;\n outputImageStateId: string;\n profile: SdrRenderingProfile;\n /** Limit on the size of the integer output. Checked before anything is allocated or any tile is read. */\n maximumOutputBytes: number;\n /**\n * Optional opt-in pixel limit for large captures: an integer from 1 to `NATIVE_CAPTURE_SDR_LIMITS.ceilingPixels`.\n * Default `NATIVE_CAPTURE_SDR_LIMITS.maximumPixels` (24 000 000). `maximumOutputBytes` still applies.\n */\n maximumPixels?: number;\n}\n/** Tile request. Coordinates are absolute in the selected plane's declared pixel grid, never relative to a crop. */\nexport interface NativeCaptureSdrTileRequest {\n captureId: string;\n sourcePlaneId: string;\n artifactId: string;\n sha256: string;\n x: number; y: number; width: number; height: number;\n}\n/** A tile returned by the provider. It belongs to this call alone; do not change or reuse it. Row padding is not image data. */\nexport interface NativeCaptureSdrTile extends NativeCaptureSdrTileRequest {\n rowStrideSamples: number;\n samples: Float32Array | Float64Array;\n}\n/** Supplies tiles, one call at a time. The caller must release decoder and GPU resources when the task aborts or finishes. */\nexport interface NativeCaptureSdrProvider {\n readTile(request: Readonly<NativeCaptureSdrTileRequest>, signal: AbortSignal): Promise<NativeCaptureSdrTile>;\n /** Must yield to the host event loop, so cancellation and input events can run between tiles. */\n yieldControl(signal: AbortSignal): Promise<void>;\n /**\n * Optional progress observer, called synchronously after each committed tile. It cannot change\n * output; an exception it throws fails the task like any other error.\n */\n onProgress?(progress: NativeTaskProgress): void;\n}\n/** Tile progress of a native task: `completedTileCount` of `totalTileCount` tiles are committed. */\nexport interface NativeTaskProgress { readonly completedTileCount: number; readonly totalTileCount: number }\nexport interface NativeCaptureSdrPlan {\n schemaVersion: typeof NATIVE_CAPTURE_SDR_SCHEMA_VERSION;\n capture: SimulatedCapture;\n sourcePlaneId: string;\n outputImageStateId: string;\n profile: SdrRenderingProfile;\n outputBytes: number;\n /** Upper bound on the bytes held in working arrays. It is not peak JavaScript heap, GPU or process memory, and does not show that a device can run the task. */\n maximumScratchPayloadBytes: number;\n tileCount: number;\n}\nexport interface NativeCaptureSdrOutput {\n plan: NativeCaptureSdrPlan;\n /** Packed RGB codes in row-major order, owned by the caller. 16-bit codes are numbers, not bytes in a particular byte order. */\n integerSamples: Uint8Array | Uint16Array;\n diagnostics: SdrRenderingResult[\"diagnostics\"];\n outputEncoding: SdrRenderingResult[\"outputEncoding\"];\n displayAdaptation: SdrRenderingResult[\"displayAdaptation\"];\n}\nexport type NativeCaptureSdrTaskState = \"ready\" | \"running\" | \"completed\" | \"cancelled\" | \"failed\" | \"disposed\" | \"transferred\";\n\n/** Validates the input and plans the task, including its limits, without reading samples or allocating an image. */\nexport function calculateNativeCaptureSdrPlan(input: NativeCaptureSdrInput): NativeCaptureSdrPlan {\n const r = requireAllowlistedRecord(input, [\"capture\", \"sourcePlaneId\", \"outputImageStateId\", \"profile\", \"maximumOutputBytes\", \"maximumPixels\"], \"Invalid native SDR input.\");\n const maximumPixels = resolveRaisedLimit(r.maximumPixels, NATIVE_CAPTURE_SDR_LIMITS.maximumPixels, NATIVE_CAPTURE_SDR_LIMITS.ceilingPixels,\n \"Native SDR maximumPixels must be an integer from 1 to \" + NATIVE_CAPTURE_SDR_LIMITS.ceilingPixels + \".\");\n // Only external-storage manifests are accepted, so unrelated inline sample buffers are never copied.\n const c = r.capture as SimulatedCapture | undefined;\n if (!c || !Array.isArray(c.planes) || c.planes.length > 32 || c.planes.some(p => !p || p.storage?.kind === \"inline-float64\")) {\n throw new InvalidConfigurationError(\"Native SDR requires external-only capture manifests.\");\n }\n const capture = parseSimulatedCapture(c);\n const sourcePlaneId = requirePublicOpaqueId(r.sourcePlaneId, \"Invalid native SDR plane ID.\");\n const outputImageStateId = requirePublicOpaqueId(r.outputImageStateId, \"Invalid native SDR output state ID.\");\n const plane = capture.planes.find(p => p.id === sourcePlaneId);\n const white = resolveCaptureColorModel().referenceWhiteXyz;\n if (!plane || plane.imageState !== \"color-transformed-linear-rgb\" ||\n plane.colorProfile?.id !== LINEAR_CAPTURE_RGB_PROFILE.id || plane.colorProfile.version !== LINEAR_CAPTURE_RGB_PROFILE.version ||\n plane.encodingReferenceWhiteXyz?.x !== white.x || plane.encodingReferenceWhiteXyz.y !== white.y || plane.encodingReferenceWhiteXyz.z !== white.z ||\n plane.whiteBalanceApplication === \"intent-only\" || (plane.whiteBalanceApplication === \"not-applicable\" && capture.whiteBalanceIntent !== null) ||\n capture.planes.some(p => p.imageStateId === outputImageStateId)) {\n throw new InvalidConfigurationError(\"Native SDR requires exact resolved linear-sRGB/D65 and a new output state ID.\");\n }\n const pixels = plane.pixelWidth * plane.pixelHeight, profile = parseSdrRenderingProfile(r.profile);\n const outputBytes = pixels * 3 * (profile.bitDepth / 8);\n const scale = 2 ** profile.renderingExposureEv / plane.referenceWhiteValue;\n if (!Number.isFinite(scale) || scale <= 0) throw new InvalidConfigurationError(\"Native SDR scale is unrepresentable.\");\n if (pixels > maximumPixels || plane.pixelWidth > NATIVE_CAPTURE_SDR_LIMITS.maximumDimension ||\n plane.pixelHeight > NATIVE_CAPTURE_SDR_LIMITS.maximumDimension || typeof r.maximumOutputBytes !== \"number\" ||\n !Number.isSafeInteger(r.maximumOutputBytes) || r.maximumOutputBytes < outputBytes) {\n throw new InvalidConfigurationError(\"Native SDR raster/output exceeds declared admission limits.\");\n }\n // A cautious declared bound, kept from the earlier executor that called the reference renderer: provider payload +\n // packed copy + reference parser copy + four reference output arrays. The typed kernel itself keeps only the provider payload.\n const maximumScratchPayloadBytes = NATIVE_CAPTURE_SDR_LIMITS.maximumTileStorageSamples * 8 +\n NATIVE_CAPTURE_SDR_LIMITS.tileWidth * NATIVE_CAPTURE_SDR_LIMITS.tileHeight * 3 * 8 * 6;\n return freezeOwnedData({ schemaVersion: NATIVE_CAPTURE_SDR_SCHEMA_VERSION, capture, sourcePlaneId, outputImageStateId, profile,\n outputBytes, maximumScratchPayloadBytes,\n tileCount: Math.ceil(plane.pixelWidth / NATIVE_CAPTURE_SDR_LIMITS.tileWidth) * Math.ceil(plane.pixelHeight / NATIVE_CAPTURE_SDR_LIMITS.tileHeight) });\n}\n\n/**\n * Tile checks shared by every native SDR backend: identity, precision, row stride, storage and valid\n * input values. Returns a view of the provider's samples (not a copy). Padding is not checked for\n * finite values. Not exported from the package.\n */\nexport function validateNativeCaptureSdrTile(tile: NativeCaptureSdrTile, request: NativeCaptureSdrTileRequest,\n plane: CaptureLinearPlane): { source: Float32Array | Float64Array; stride: number } {\n const r = requireAllowlistedRecord(tile, [\"captureId\", \"sourcePlaneId\", \"artifactId\", \"sha256\", \"x\", \"y\", \"width\", \"height\", \"rowStrideSamples\", \"samples\"], \"Invalid native SDR tile.\");\n for (const key of Object.keys(request) as (keyof NativeCaptureSdrTileRequest)[]) {\n if (r[key] !== request[key]) throw new InvalidConfigurationError(\"Native SDR tile identity/rectangle mismatch.\");\n }\n const samples = r.samples;\n const expectedType = plane.storage.kind === \"external-float32\" ? Float32Array : Float64Array;\n if (!(samples instanceof expectedType) || !(samples.buffer instanceof ArrayBuffer) ||\n samples.buffer.byteLength > NATIVE_CAPTURE_SDR_LIMITS.maximumTileStorageSamples * expectedType.BYTES_PER_ELEMENT ||\n typeof r.rowStrideSamples !== \"number\" || !Number.isSafeInteger(r.rowStrideSamples) || r.rowStrideSamples < request.width * 3 ||\n samples.length !== r.rowStrideSamples * request.height || samples.length > NATIVE_CAPTURE_SDR_LIMITS.maximumTileStorageSamples) {\n throw new InvalidConfigurationError(\"Native SDR tile precision/stride/storage mismatch.\");\n }\n const source: Float32Array | Float64Array = samples, stride = r.rowStrideSamples, rowLength = request.width * 3;\n // Check every image sample (not padding) against the reference renderer's input rules before any rendering.\n for (let y = 0; y < request.height; y++) {\n for (let i = y * stride, end = i + rowLength; i < end; i++) {\n if (!Number.isFinite(source[i]!)) throw new InvalidConfigurationError(\"Unsupported SDR input domain/raster.\");\n }\n }\n return { source, stride };\n}\n\ntype NativeSdrDiagnosticCounts = Omit<SdrRenderingResult[\"diagnostics\"], \"captureSaturation\">;\n/**\n * Fast tile kernel on typed arrays. It applies the same equations as the SDR reference renderer\n * (`calculateSdrRendering`), with the same floating-point operation order per sample and the same\n * error precedence, and writes integer codes straight into the packed output.\n *\n * Steps: input check → rendering exposure → tone → gamut → sRGB transfer → quantization (round to\n * nearest, ties up). `test/native-capture-sdr-kernel-parity.test.ts` shows that codes and diagnostics\n * match the unchanged reference exactly.\n */\nfunction renderTileInto(tile: NativeCaptureSdrTile, request: NativeCaptureSdrTileRequest, plane: CaptureLinearPlane,\n profile: SdrRenderingProfile, tone: SdrPixelTone, scale: number, maximum: number, codes: Uint8Array | Uint16Array, diagnostics: NativeSdrDiagnosticCounts): void {\n const { source, stride } = validateNativeCaptureSdrTile(tile, request, plane);\n // Tiling is safe because every supported rendering operation works on one pixel at a time.\n const outputRowStride = plane.pixelWidth * 3;\n const counts = { negative: 0, above: 0, changed: 0, low: 0, high: 0, outOfGamut: false }, scratch = new Float64Array(3);\n for (let y = 0; y < request.height; y++) {\n renderSdrRunInto(source, y * stride, request.width, profile, tone, scale, maximum, codes, (request.y + y) * outputRowStride + request.x * 3, scratch, counts);\n }\n if (counts.outOfGamut) throw new InvalidConfigurationError(\"Tone output exceeds the declared SDR gamut range.\");\n diagnostics.renderingNegativeSampleCount += counts.negative; diagnostics.renderingAboveReferenceSampleCount += counts.above;\n diagnostics.toneChangedSampleCount += counts.changed; diagnostics.gamutClippedLowSampleCount += counts.low; diagnostics.gamutClippedHighSampleCount += counts.high;\n}\n/** Reference 8-bit code of a linear sample in [0,1]: Math.round(encodeSrgbComponent(x)·255). */\nfunction referenceSrgb8(linear: number): number { return Math.round(encodeSrgbComponent(linear) * 255); }\n/** Exact 8-bit sRGB quantizer tables; see {@link srgb8Quantizer}. */\nexport interface Srgb8Quantizer {\n /** t[k]: smallest binary64 x in [0,1] with referenceSrgb8(x) ≥ k; t[256] = +∞ sentinel. */\n readonly thresholds: Float64Array;\n /** start[b]: reference code of b/4096, the first code of bucket [b/4096, (b+1)/4096). */\n readonly start: Uint8Array;\n}\nlet srgb8: Srgb8Quantizer | null | undefined;\n/**\n * Exact 8-bit sRGB quantization without evaluating the transfer curve for each sample.\n *\n * The code thresholds are found by bisection on this engine's own `encodeSrgbComponent`. Comparing\n * against them gives Math.round(encodeSrgbComponent(x)·255) for every x, provided that function never\n * decreases (true when pow is monotone). Construction checks every threshold and the 16 neighbouring\n * doubles on each side. If any check fails, the direct transfer is used instead, so output never\n * silently depends on that assumption.\n *\n * A 4097-entry bucket index (x·4096 is exact) gives the starting code. Even the steepest part of the\n * curve (slope 12.92·255) covers less than one code per bucket, so one or two comparisons finish.\n */\nfunction srgb8Quantizer(): Srgb8Quantizer | null {\n if (srgb8 !== undefined) return srgb8;\n const t = new Float64Array(257), bits = new Float64Array(1), word = new BigUint64Array(bits.buffer);\n const step = (x: number, n: number): number => { bits[0] = x; word[0] = word[0]! + BigInt(n); return bits[0]!; };\n for (let k = 1; k < 256; k++) {\n let lo = t[k - 1]!, hi = 1;\n for (;;) {\n const mid = lo + (hi - lo) / 2;\n if (mid === lo || mid === hi) break;\n if (referenceSrgb8(mid) >= k) hi = mid; else lo = mid;\n }\n t[k] = hi;\n }\n t[256] = Infinity;\n let valid = referenceSrgb8(0) === 0 && referenceSrgb8(1) === 255;\n for (let k = 1; valid && k < 256; k++) {\n const x = t[k]!;\n if (!(x > t[k - 1]!) || referenceSrgb8(x) !== k) valid = false;\n for (let n = 1; valid && n <= 16; n++) {\n const below = step(x, -n), above = step(x, n);\n if ((below >= 0 && referenceSrgb8(below) >= k) || (above <= 1 && referenceSrgb8(above) < k)) valid = false;\n }\n }\n const start = new Uint8Array(4097);\n for (let i = 0; valid && i <= 4096; i++) { start[i] = referenceSrgb8(i / 4096); if (i > 0 && start[i]! < start[i - 1]!) valid = false; }\n srgb8 = valid ? { thresholds: t, start } : null;\n return srgb8;\n}\n/** Largest k with t[k] ≤ x for x in [0,1]. */\nfunction quantizeSrgb8(q: Srgb8Quantizer, x: number): number {\n const t = q.thresholds;\n let k = q.start[(x * 4096) | 0]!;\n while (x >= t[k + 1]!) k++;\n return k;\n}\n/** Internal, for tests: the exact quantizer (null when its construction check failed). */\nexport function nativeSrgb8QuantizerForTest(): { quantizer: Srgb8Quantizer | null; quantize(x: number): number } {\n const quantizer = srgb8Quantizer();\n return { quantizer, quantize: (x) => quantizer ? quantizeSrgb8(quantizer, x) : referenceSrgb8(x) };\n}\n/** Per-tile counters for {@link renderSdrRunInto}. `outOfGamut` delays the rejection, as the reference does. */\nexport interface SdrPixelCounts { negative: number; above: number; changed: number; low: number; high: number; outOfGamut: boolean }\n/**\n * Internal SDR kernel on typed arrays, shared by native SDR and RAW development.\n *\n * For `pixelCount` interleaved linear-sRGB pixels starting at `source[start]`, it runs exactly the\n * reference (`calculateSdrRendering`) operations in the same order per pixel: -0 → +0 → rendering\n * exposure → shared tone operator → gamut → sRGB transfer → quantization (nearest, ties up) into\n * `codes[outOffset]` (with `maximum` 0, the encoded value unquantized). A gamut rejection is delayed via `counts.outOfGamut`, because the reference\n * finishes the whole tone pass (and its exposure errors) first. `scratch` must hold at least 3\n * values. Not exported from the package.\n */\nexport function renderSdrRunInto(source: Float32Array | Float64Array, start: number, pixelCount: number, profile: SdrRenderingProfile,\n tone: SdrPixelTone, scale: number, maximum: number, codes: Uint8Array | Uint16Array | Float64Array, outOffset: number, scratch: Float64Array, counts: SdrPixelCounts): void {\n const reject = profile.gamutHandling === \"reject-out-of-range\", desaturate = profile.gamutHandling === \"desaturate-to-luminance\", quantizer = maximum === 255 ? srgb8Quantizer() : null;\n let negative = 0, above = 0, changed = 0, low = 0, high = 0, outOfGamut = false;\n for (let p = 0, i = start, o = outOffset; p < pixelCount; p++, i += 3) {\n // The reference parser normalizes -0 to +0 before exposure.\n const red = source[i]!, green = source[i + 1]!, blue = source[i + 2]!;\n const er = (red === 0 ? 0 : red) * scale, eg = (green === 0 ? 0 : green) * scale, eb = (blue === 0 ? 0 : blue) * scale;\n if (!Number.isFinite(er) || !Number.isFinite(eg) || !Number.isFinite(eb)) throw new InvalidScientificResultError(\"Rendering exposure produced a non-finite sample.\");\n tone(er, eg, eb, scratch);\n // #601: the hue-preserving desaturation, before the components are counted and clipped.\n if (desaturate) desaturateToLuminance(scratch);\n for (let c = 0; c < 3; c++, o++) {\n const exposed = c === 0 ? er : c === 1 ? eg : eb;\n if (exposed < 0) negative++;\n if (exposed > 1) above++;\n let mapped = scratch[c]!;\n if (mapped !== exposed) changed++;\n if (mapped === 0) mapped = 0;\n let linear = mapped;\n if (mapped < 0 || mapped > 1) {\n if (reject) outOfGamut = true;\n else if (mapped < 0) { low++; linear = 0; }\n else { high++; linear = 1; }\n }\n // Encoded values are in [0,1]: Math.round is exact nearest-ties-up here.\n // maximum 0 (#571): the encoded value itself, unquantized, into a Float64Array (the unsharp mask's input).\n codes[o] = quantizer ? quantizeSrgb8(quantizer, linear) : maximum === 0 ? encodeSrgbComponent(linear) : Math.round(encodeSrgbComponent(linear) * maximum);\n }\n }\n counts.negative += negative; counts.above += above; counts.changed += changed; counts.low += low; counts.high += high;\n if (outOfGamut) counts.outOfGamut = true;\n}\n\n/** The reference's output-encoding declaration for the given code maximum. */\nexport function sdrOutputEncoding(maximum: number): SdrRenderingResult[\"outputEncoding\"] {\n return { imageState: \"output-referred-sdr\", colorSpace: \"srgb\", primariesXy: { red: [.64, .33], green: [.30, .60], blue: [.15, .06] },\n whitePointXy: [.3127, .3290], referenceWhiteLuminanceCdM2: 80, codeMinimum: 0, codeMaximum: maximum };\n}\n\n/** A single-use task. No partial output is ever returned, and cancel or dispose stops a late result from being published. */\nexport interface NativeCaptureSdrTask {\n readonly plan: NativeCaptureSdrPlan;\n readonly state: NativeCaptureSdrTaskState;\n readonly completedTileCount: number;\n run(): Promise<void>;\n cancel(): void;\n dispose(): void;\n /** Hands over the only copy of the output buffer, once. Dispose cannot take back a buffer already handed over. */\n takeOutput(): NativeCaptureSdrOutput;\n}\n/** Creates a single-use task. Limits are checked before any buffer is allocated or tile is read. */\nexport function createNativeCaptureSdrTask(input: NativeCaptureSdrInput, provider: NativeCaptureSdrProvider): NativeCaptureSdrTask {\n const plan = calculateNativeCaptureSdrPlan(input);\n if (!provider || typeof provider.readTile !== \"function\" || typeof provider.yieldControl !== \"function\") {\n throw new InvalidConfigurationError(\"Native SDR requires a tile reader and event-loop yield.\");\n }\n if (provider.onProgress !== undefined && typeof provider.onProgress !== \"function\") throw new InvalidConfigurationError(\"Native SDR onProgress must be a function.\");\n // Also capture the callback functions now, so later app changes cannot swap the reader mid-task.\n const readTile = provider.readTile.bind(provider), yieldControl = provider.yieldControl.bind(provider),\n onProgress = provider.onProgress?.bind(provider);\n const plane = plan.capture.planes.find(p => p.id === plan.sourcePlaneId)!;\n if (plane.storage.kind === \"inline-float64\") throw new InvalidConfigurationError(\"External native source required.\");\n const storage = plane.storage, abort = new AbortController();\n let state: NativeCaptureSdrTaskState = \"ready\", count = 0, output: NativeCaptureSdrOutput | null = null;\n let codes: Uint8Array | Uint16Array | null = null;\n function release(): void { codes?.fill(0); codes = null; output = null; }\n function checkActive(): void {\n if (abort.signal.aborted) throw new InvalidConfigurationError(\"Native SDR task cancelled/disposed; no output available.\");\n }\n return {\n plan,\n get state(): NativeCaptureSdrTaskState { return state; },\n get completedTileCount(): number { return count; },\n async run(): Promise<void> {\n if (state !== \"ready\") throw new InvalidConfigurationError(\"Native SDR task is single-use.\");\n state = \"running\";\n try {\n codes = plan.profile.bitDepth === 8 ? new Uint8Array(plan.outputBytes) : new Uint16Array(plan.outputBytes / 2);\n const diagnostics: SdrRenderingResult[\"diagnostics\"] = { renderingNegativeSampleCount: 0, renderingAboveReferenceSampleCount: 0,\n toneChangedSampleCount: 0, gamutClippedLowSampleCount: 0, gamutClippedHighSampleCount: 0, captureSaturation: \"not-consumed\" };\n // Same scale expression and code range as the reference. The plan already rejected a scale that cannot be represented.\n const scale = 2 ** plan.profile.renderingExposureEv / plane.referenceWhiteValue, maximum = 2 ** plan.profile.bitDepth - 1,\n tone = prepareSdrPixelTone(plan.profile);\n for (let y = 0; y < plane.pixelHeight; y += NATIVE_CAPTURE_SDR_LIMITS.tileHeight) {\n for (let x = 0; x < plane.pixelWidth; x += NATIVE_CAPTURE_SDR_LIMITS.tileWidth) {\n checkActive();\n const request = Object.freeze({ captureId: plan.capture.captureId, sourcePlaneId: plane.id,\n artifactId: storage.artifactId, sha256: storage.sha256, x, y,\n width: Math.min(NATIVE_CAPTURE_SDR_LIMITS.tileWidth, plane.pixelWidth - x),\n height: Math.min(NATIVE_CAPTURE_SDR_LIMITS.tileHeight, plane.pixelHeight - y) });\n {\n const tile = await readTile(request, abort.signal);\n checkActive();\n // Diagnostics are aggregated only after the whole tile renders.\n renderTileInto(tile, request, plane, plan.profile, tone, scale, maximum, codes!, diagnostics);\n count++;\n onProgress?.({ completedTileCount: count, totalTileCount: plan.tileCount });\n }\n // Do not keep tile or reference arrays past the next tile read or host yield.\n await yieldControl(abort.signal);\n checkActive();\n }\n }\n output = { plan, integerSamples: codes!, diagnostics, outputEncoding: sdrOutputEncoding(maximum),\n displayAdaptation: { kind: \"external-platform\", applied: false, displayCapabilities: \"unknown\" } };\n state = \"completed\";\n } catch (error) {\n release();\n if (!abort.signal.aborted) { state = \"failed\"; abort.abort(); }\n throw error;\n }\n },\n cancel(): void {\n if (state === \"ready\" || state === \"running\" || state === \"completed\") { state = \"cancelled\"; abort.abort(); release(); }\n },\n dispose(): void { if (state !== \"transferred\") { state = \"disposed\"; abort.abort(); release(); } },\n takeOutput(): NativeCaptureSdrOutput {\n if (state !== \"completed\" || !output) throw new InvalidConfigurationError(\"Native SDR output is unavailable.\");\n const result = output; output = null; codes = null; state = \"transferred\";\n return result;\n }\n };\n}\n"]}
@@ -10,7 +10,9 @@ export interface PrintLength {
10
10
  value: number;
11
11
  unit: "mm" | "cm" | "inches" | "m";
12
12
  }
13
- /** The flat printed image area. It excludes paper margins, borders and canvas wraps. */
13
+ /** The flat printed image area. It excludes paper margins, borders and canvas wraps.
14
+ * With a `contain` fit it is instead the paper, or the printable area of it, that the image is fitted inside.
15
+ */
14
16
  export interface PrintedImageSize {
15
17
  width: number;
16
18
  height: number;
@@ -48,16 +50,43 @@ export interface PrintProviderConstraints {
48
50
  minimumPpi?: number;
49
51
  exactPpi?: number;
50
52
  }
53
+ /** How the printed image relates to `printedImage`.
54
+ * - `confirmed-native-aspect`: `printedImage` is the printed image itself and must already have the native aspect ratio,
55
+ * within the stated relative error.
56
+ * - `contain`: `printedImage` is the paper. The image keeps the native aspect ratio and is scaled to the largest size that
57
+ * fits inside it, centered; the rest is unprinted border. `match-image` turns the paper a quarter turn when its
58
+ * orientation (portrait or landscape) differs from the image's; `as-given` keeps it. Layout only: nothing is cropped or resampled.
59
+ */
60
+ export type PrintFit = {
61
+ kind: "confirmed-native-aspect";
62
+ maximumRelativeAspectError: number;
63
+ } | {
64
+ kind: "contain";
65
+ paperOrientation: "as-given" | "match-image";
66
+ };
67
+ /** The layout of a `contain` fit, in millimetres. The printed image itself is the plan's `printedImageMm`. */
68
+ export interface PrintContainLayout {
69
+ /** The paper as placed: after the quarter turn when `paperRotated`. */
70
+ paperMm: {
71
+ width: number;
72
+ height: number;
73
+ };
74
+ paperRotated: boolean;
75
+ /** Unprinted border on each side of the centered image; zero when the paper has the image's aspect ratio. */
76
+ bordersMm: {
77
+ left: number;
78
+ right: number;
79
+ top: number;
80
+ bottom: number;
81
+ };
82
+ }
51
83
  /** Plan input. The output keeps the exact native aspect ratio; the allowed physical aspect error is explicit and reported. */
52
84
  export interface PrintPlanInput {
53
85
  source: PrintNativeSource;
54
86
  printedImage: PrintedImageSize;
55
87
  viewingDistance: PrintLength;
56
88
  sampling: PrintSamplingCriterion;
57
- fit: {
58
- kind: "confirmed-native-aspect";
59
- maximumRelativeAspectError: number;
60
- };
89
+ fit: PrintFit;
61
90
  provider?: PrintProviderConstraints;
62
91
  }
63
92
  /** Pixel density and angular pixel pitch for each axis. The angles are pure geometry, not a measure of visual acuity. */
@@ -106,6 +135,8 @@ export interface PrintPlan {
106
135
  } | null;
107
136
  capturedDetailAssessment: "unassessed";
108
137
  deliveryAssessment: "unassessed";
138
+ /** Present only with a `contain` fit; null when the native raster is unknown. */
139
+ contain?: PrintContainLayout | null;
109
140
  }
110
141
  /** Validates and copies an untrusted print request. It never assumes the source is native if that is not declared. */
111
142
  export declare function parsePrintPlanInput(value: unknown): PrintPlanInput;
@@ -135,6 +166,11 @@ export interface PrintSizeLimit {
135
166
  } | null;
136
167
  reasons: string[];
137
168
  referencePlan: PrintPlan;
169
+ /** Present only with a `contain` fit: the paper that holds `maximumImageMm` with the same layout (borders scale with it). */
170
+ maximumPaperMm?: {
171
+ width: number;
172
+ height: number;
173
+ } | null;
138
174
  }
139
175
  /** Calculates the largest print size under the stated conditions. Lab constraints need individual plans,
140
176
  * so this size query reports them as unsupported rather than ignoring them.
@@ -118,10 +118,7 @@ export function parsePrintPlanInput(value) {
118
118
  else
119
119
  throw new InvalidConfigurationError("Invalid native source kind.");
120
120
  const image = record(r.printedImage, ["width", "height", "unit"]);
121
- const fit = record(r.fit, ["kind", "maximumRelativeAspectError"]);
122
- if (fit.kind !== "confirmed-native-aspect" || typeof fit.maximumRelativeAspectError !== "number" || !Number.isFinite(fit.maximumRelativeAspectError) || fit.maximumRelativeAspectError < 0 || fit.maximumRelativeAspectError > 0.01)
123
- throw new InvalidConfigurationError("Declare a native-aspect fit tolerance in [0, 0.01].");
124
- const parsed = { source: parsedSource, printedImage: { width: number(image.width, "printedImage.width"), height: number(image.height, "printedImage.height"), unit: unit(image.unit) }, viewingDistance: length(r.viewingDistance), sampling: sampling(r.sampling), fit: { kind: "confirmed-native-aspect", maximumRelativeAspectError: fit.maximumRelativeAspectError } };
121
+ const parsed = { source: parsedSource, printedImage: { width: number(image.width, "printedImage.width"), height: number(image.height, "printedImage.height"), unit: unit(image.unit) }, viewingDistance: length(r.viewingDistance), sampling: sampling(r.sampling), fit: parseFit(r.fit) };
125
122
  if (r.provider !== undefined) {
126
123
  const p = record(r.provider, ["minimumRaster", "exactRaster", "minimumPpi", "exactPpi"]);
127
124
  parsed.provider = {
@@ -133,6 +130,30 @@ export function parsePrintPlanInput(value) {
133
130
  }
134
131
  return parsed;
135
132
  }
133
+ function parseFit(value) {
134
+ const fit = record(value, ["kind", "maximumRelativeAspectError", "paperOrientation"]);
135
+ if (fit.kind === "contain") {
136
+ record(value, ["kind", "paperOrientation"]);
137
+ if (fit.paperOrientation !== "as-given" && fit.paperOrientation !== "match-image")
138
+ throw new InvalidConfigurationError("Declare a contain-fit paper orientation: as-given or match-image.");
139
+ return { kind: "contain", paperOrientation: fit.paperOrientation };
140
+ }
141
+ if (fit.kind !== "confirmed-native-aspect" || fit.paperOrientation !== undefined || typeof fit.maximumRelativeAspectError !== "number" || !Number.isFinite(fit.maximumRelativeAspectError) || fit.maximumRelativeAspectError < 0 || fit.maximumRelativeAspectError > 0.01)
142
+ throw new InvalidConfigurationError("Declare a native-aspect fit tolerance in [0, 0.01].");
143
+ return { kind: "confirmed-native-aspect", maximumRelativeAspectError: fit.maximumRelativeAspectError };
144
+ }
145
+ /** The largest image at the native aspect ratio inside the paper, in the paper's unit, and its centered layout.
146
+ * The binding axis equals the paper exactly; the other is clamped so rounding never makes a negative border.
147
+ */
148
+ function containImage(native, paperWidth, paperHeight, orientation) {
149
+ const imageLandscape = native.pixelWidth > native.pixelHeight, imagePortrait = native.pixelWidth < native.pixelHeight;
150
+ const paperRotated = orientation === "match-image" && ((imageLandscape && paperWidth < paperHeight) || (imagePortrait && paperWidth > paperHeight));
151
+ const pw = paperRotated ? paperHeight : paperWidth, ph = paperRotated ? paperWidth : paperHeight;
152
+ const widthBinds = native.pixelWidth * ph >= native.pixelHeight * pw;
153
+ const width = widthBinds ? pw : Math.min(pw, ph * native.pixelWidth / native.pixelHeight);
154
+ const height = widthBinds ? Math.min(ph, pw * native.pixelHeight / native.pixelWidth) : ph;
155
+ return { width, height, paperWidth: pw, paperHeight: ph, paperRotated };
156
+ }
136
157
  function gcd(a, b) { while (b !== 0) {
137
158
  const next = a % b;
138
159
  a = b;
@@ -171,12 +192,22 @@ function diagnostics(raster, width, height, distance) {
171
192
  export function calculatePrintPlan(value) {
172
193
  const input = parsePrintPlanInput(value);
173
194
  const plan = { engineApiVersion: ENGINE_API_VERSION, input, status: "cannot-assess", nativePixelSufficiency: "cannot-assess", reasons: [], printedImageMm: null, viewingDistanceMm: null, guidance: null, relativeAspectError: null, native: null, minimumSamplingRaster: null, recommended: null, resamplingScale: null, alternatives: null, capturedDetailAssessment: "unassessed", deliveryAssessment: "unassessed" };
174
- const finish = () => calculatedResult(plan, "native-only-print-plan", "0.1.0", ["Declared native authority; flat image, normal viewing at image center.", "Output preserves the exact retained native aspect ratio; no upscale.", "Angular sampling is conditional guidance, not captured-detail or print-quality certification."]);
195
+ const contain = input.fit.kind === "contain" ? input.fit : null;
196
+ if (contain !== null)
197
+ plan.contain = null;
198
+ const finish = () => calculatedResult(plan, "native-only-print-plan", "0.1.0", ["Declared native authority; flat image, normal viewing at image center.", "Output preserves the exact retained native aspect ratio; no upscale.", "Angular sampling is conditional guidance, not captured-detail or print-quality certification.", ...(contain === null ? [] : ["Contain fit: the image is centered inside the paper; the borders are unprinted and the paper is not a print area."])]);
175
199
  const unsupported = () => { plan.status = "unsupported"; plan.nativePixelSufficiency = "cannot-assess"; plan.reasons.push("unsupported-numeric-range"); return finish(); };
176
- const width = input.printedImage.width * UNIT_MM[input.printedImage.unit], height = input.printedImage.height * UNIT_MM[input.printedImage.unit], distance = input.viewingDistance.value * UNIT_MM[input.viewingDistance.unit];
200
+ const unitMm = UNIT_MM[input.printedImage.unit], distance = input.viewingDistance.value * UNIT_MM[input.viewingDistance.unit];
201
+ // A contain fit needs the native aspect ratio before the printed image size is known.
202
+ const resolved = input.source.kind === "native-retained" ? resolveCaptureGeometry(input.source.geometry).value : null;
203
+ const native = resolved === null ? null : { pixelWidth: resolved.output.cropRect.width, pixelHeight: resolved.output.cropRect.height };
204
+ const fitted = contain === null || native === null ? null : containImage(native, input.printedImage.width, input.printedImage.height, contain.paperOrientation);
205
+ const imageWidth = fitted?.width ?? input.printedImage.width, imageHeight = fitted?.height ?? input.printedImage.height;
206
+ const width = imageWidth * unitMm, height = imageHeight * unitMm;
177
207
  if (!positiveSupported(width, height, distance))
178
208
  return unsupported();
179
- plan.printedImageMm = { width, height };
209
+ if (contain === null || fitted !== null)
210
+ plan.printedImageMm = { width, height };
180
211
  plan.viewingDistanceMm = distance;
181
212
  const angle = input.sampling.kind === "manual-ppi" ? null : angularLimit(input.sampling);
182
213
  const pitchFactor = angle === null ? null : 2 * Math.tan((angle * RAD_PER_ARCMIN) / 2);
@@ -186,12 +217,20 @@ export function calculatePrintPlan(value) {
186
217
  return unsupported();
187
218
  const guidance = { derivedPixelsPerInch: ppi, maximumPixelPitchMm: pitch, maximumArcminutesPerPixel: angle };
188
219
  plan.guidance = angle === null ? calculatedResult(guidance, "manual-print-density", "0.1.0", ["Explicit manual PPI plan; no angular criterion is certified."]) : approximationResult(guidance, "declared-angular-print-sampling", "0.1.0", ["Exact centered pixel angle uses 2 atan(pitch / (2 distance)); no small-angle substitution.", "Declared angular sampling convention is an uncalibrated usage assumption."]);
189
- if (input.source.kind === "unavailable") {
190
- plan.reasons.push(input.source.reason);
220
+ if (input.source.kind === "unavailable" || native === null) {
221
+ if (input.source.kind === "unavailable")
222
+ plan.reasons.push(input.source.reason);
191
223
  return finish();
192
224
  }
193
- const resolved = resolveCaptureGeometry(input.source.geometry).value;
194
- const native = { pixelWidth: resolved.output.cropRect.width, pixelHeight: resolved.output.cropRect.height };
225
+ if (fitted !== null) {
226
+ const paperWidth = fitted.paperWidth * unitMm, paperHeight = fitted.paperHeight * unitMm;
227
+ // Borders are taken in the paper's unit, then converted, so whole-unit borders stay exact.
228
+ const side = (paper, image) => Math.max(0, (paper - image) / 2) * unitMm;
229
+ const x = side(fitted.paperWidth, imageWidth), y = side(fitted.paperHeight, imageHeight);
230
+ if (!positiveSupported(paperWidth, paperHeight) || !Number.isFinite(x) || !Number.isFinite(y))
231
+ return unsupported();
232
+ plan.contain = { paperMm: { width: paperWidth, height: paperHeight }, paperRotated: fitted.paperRotated, bordersMm: { left: x, right: x, top: y, bottom: y } };
233
+ }
195
234
  const aspectError = Math.abs((width / height) / (native.pixelWidth / native.pixelHeight) - 1);
196
235
  if (!Number.isFinite(aspectError))
197
236
  return unsupported();
@@ -200,13 +239,14 @@ export function calculatePrintPlan(value) {
200
239
  if (!positiveSupported(nativeDiagnostics.pixelsPerInch.x, nativeDiagnostics.pixelsPerInch.y, nativeDiagnostics.angularPixelPitchArcminutes.x, nativeDiagnostics.angularPixelPitchArcminutes.y))
201
240
  return unsupported();
202
241
  plan.native = nativeDiagnostics;
203
- if (aspectError > input.fit.maximumRelativeAspectError) {
242
+ // A contain fit has the native aspect ratio by construction; its rounding error is reported, not checked.
243
+ if (input.fit.kind === "confirmed-native-aspect" && aspectError > input.fit.maximumRelativeAspectError) {
204
244
  plan.status = "crop-confirmation-required";
205
245
  plan.reasons.push("printed-image-and-confirmed-crop-aspect-mismatch");
206
246
  return finish();
207
247
  }
208
- const widthInches = input.printedImage.unit === "inches" ? input.printedImage.width : width / 25.4;
209
- const heightInches = input.printedImage.unit === "inches" ? input.printedImage.height : height / 25.4;
248
+ const widthInches = input.printedImage.unit === "inches" ? imageWidth : width / 25.4;
249
+ const heightInches = input.printedImage.unit === "inches" ? imageHeight : height / 25.4;
210
250
  const required = input.sampling.kind === "manual-ppi"
211
251
  ? minimumRaster(native, widthInches * ppi, heightInches * ppi)
212
252
  : minimumRaster(native, width / pitch, height / pitch);
@@ -308,6 +348,11 @@ export function calculatePrintSizeLimit(value) {
308
348
  result.maximumImageMm = referencePlan.alternatives.maximumImageMmAtCurrentDistance;
309
349
  }
310
350
  }
351
+ if (referencePlan.input.fit.kind === "contain") {
352
+ const layout = referencePlan.contain, image = referencePlan.printedImageMm, maximum = result.maximumImageMm;
353
+ const scale = layout && image && maximum ? maximum.width / image.width : null;
354
+ result.maximumPaperMm = layout && scale !== null && positiveSupported(layout.paperMm.width * scale, layout.paperMm.height * scale) ? { width: layout.paperMm.width * scale, height: layout.paperMm.height * scale } : null;
355
+ }
311
356
  return calculatedResult(result, "conditional-native-print-size-limit", "0.1.0", ["Native sampling capacity only; no perceived-quality or physical-printer bound.", "Proportional distance and image scaling preserve angular pixel pitch."]);
312
357
  }
313
358
  //# sourceMappingURL=print-plan.js.map