@photivra/engine 2.21.0 → 2.23.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 (172) hide show
  1. package/CHANGELOG.md +150 -1
  2. package/CITATION.cff +1 -1
  3. package/README.md +6 -6
  4. package/SECURITY.md +1 -1
  5. package/THIRD_PARTY.md +11 -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-opcodes.d.ts +96 -0
  13. package/dist/capture/dng-opcodes.js +391 -0
  14. package/dist/capture/dng-opcodes.js.map +1 -0
  15. package/dist/capture/dng-profile-maps.d.ts +99 -0
  16. package/dist/capture/dng-profile-maps.js +381 -0
  17. package/dist/capture/dng-profile-maps.js.map +1 -0
  18. package/dist/capture/dng-stage-image.d.ts +23 -0
  19. package/dist/capture/dng-stage-image.js +65 -0
  20. package/dist/capture/dng-stage-image.js.map +1 -0
  21. package/dist/capture/jpeg-xl-tiles.d.ts +22 -0
  22. package/dist/capture/jpeg-xl-tiles.js +151 -0
  23. package/dist/capture/jpeg-xl-tiles.js.map +1 -0
  24. package/dist/capture/lossy-jpeg.d.ts +17 -0
  25. package/dist/capture/lossy-jpeg.js +369 -0
  26. package/dist/capture/lossy-jpeg.js.map +1 -0
  27. package/dist/capture/native-raw-development.d.ts +2 -1
  28. package/dist/capture/native-raw-development.js.map +1 -1
  29. package/dist/color/neighbor-highlight-reconstruction.d.ts +76 -0
  30. package/dist/color/neighbor-highlight-reconstruction.js +257 -0
  31. package/dist/color/neighbor-highlight-reconstruction.js.map +1 -0
  32. package/dist/color/sensor-color-development.d.ts +5 -0
  33. package/dist/color/sensor-color-development.js +7 -1
  34. package/dist/color/sensor-color-development.js.map +1 -1
  35. package/dist/color/spectral-spikiness.d.ts +11 -0
  36. package/dist/color/spectral-spikiness.js +23 -0
  37. package/dist/color/spectral-spikiness.js.map +1 -0
  38. package/dist/core/execution-error.d.ts +21 -0
  39. package/dist/core/execution-error.js +12 -0
  40. package/dist/core/execution-error.js.map +1 -0
  41. package/dist/core/version.d.ts +1 -1
  42. package/dist/core/version.js +1 -1
  43. package/dist/core/version.js.map +1 -1
  44. package/dist/facade/catalogue-lens-signal.d.ts +26 -1
  45. package/dist/facade/catalogue-lens-signal.js +25 -7
  46. package/dist/facade/catalogue-lens-signal.js.map +1 -1
  47. package/dist/facade/diffraction-provider.d.ts +1 -1
  48. package/dist/facade/diffraction-provider.js +4 -4
  49. package/dist/facade/diffraction-provider.js.map +1 -1
  50. package/dist/facade/display-view-gpu-session.js +38 -6
  51. package/dist/facade/display-view-gpu-session.js.map +1 -1
  52. package/dist/facade/display-view-gpu.d.ts +13 -5
  53. package/dist/facade/display-view-gpu.js.map +1 -1
  54. package/dist/facade/display-view-normal.d.ts +15 -0
  55. package/dist/facade/display-view-normal.js +44 -0
  56. package/dist/facade/display-view-normal.js.map +1 -0
  57. package/dist/facade/display-view-rendering.d.ts +102 -0
  58. package/dist/facade/display-view-rendering.js +633 -0
  59. package/dist/facade/display-view-rendering.js.map +1 -0
  60. package/dist/facade/display-view.d.ts +37 -65
  61. package/dist/facade/display-view.js +147 -476
  62. package/dist/facade/display-view.js.map +1 -1
  63. package/dist/facade/expected-signal-setup.js +2 -2
  64. package/dist/facade/expected-signal-setup.js.map +1 -1
  65. package/dist/facade/fast-methods.d.ts +1 -1
  66. package/dist/facade/fast-methods.js +37 -8
  67. package/dist/facade/fast-methods.js.map +1 -1
  68. package/dist/facade/generic-lens-capture.d.ts +1 -1
  69. package/dist/facade/generic-lens-capture.js +1 -1
  70. package/dist/facade/generic-lens-capture.js.map +1 -1
  71. package/dist/facade/image-plane.js +41 -10
  72. package/dist/facade/image-plane.js.map +1 -1
  73. package/dist/facade/on-demand-kits.d.ts +14 -0
  74. package/dist/facade/on-demand-kits.js +36 -0
  75. package/dist/facade/on-demand-kits.js.map +1 -0
  76. package/dist/facade/opt-in-kit.d.ts +9 -0
  77. package/dist/facade/opt-in-kit.js +11 -0
  78. package/dist/facade/opt-in-kit.js.map +1 -0
  79. package/dist/facade/quality-kit.d.ts +21 -0
  80. package/dist/facade/quality-kit.js +23 -0
  81. package/dist/facade/quality-kit.js.map +1 -0
  82. package/dist/facade/quality-paths.d.ts +22 -0
  83. package/dist/facade/quality-paths.js +44 -0
  84. package/dist/facade/quality-paths.js.map +1 -0
  85. package/dist/facade/scene-radiance.d.ts +18 -2
  86. package/dist/facade/scene-radiance.js +6 -4
  87. package/dist/facade/scene-radiance.js.map +1 -1
  88. package/dist/facade/simulate-capture.d.ts +32 -13
  89. package/dist/facade/simulate-capture.js +162 -69
  90. package/dist/facade/simulate-capture.js.map +1 -1
  91. package/dist/facade/simulate-display-view.d.ts +10 -12
  92. package/dist/facade/simulate-display-view.js +57 -48
  93. package/dist/facade/simulate-display-view.js.map +1 -1
  94. package/dist/gpu/display-view-gpu-renderer.d.ts +43 -0
  95. package/dist/gpu/display-view-gpu-renderer.js +134 -0
  96. package/dist/gpu/display-view-gpu-renderer.js.map +1 -0
  97. package/dist/gpu/display-view-image-material-module.d.ts +3 -2
  98. package/dist/gpu/display-view-image-material-module.js +25 -3
  99. package/dist/gpu/display-view-image-material-module.js.map +1 -1
  100. package/dist/gpu/display-view-image-quality.d.ts +43 -1
  101. package/dist/gpu/display-view-image-quality.js +256 -11
  102. package/dist/gpu/display-view-image-quality.js.map +1 -1
  103. package/dist/gpu/display-view-quality-gpu.d.ts +13 -64
  104. package/dist/gpu/display-view-quality-gpu.js +55 -240
  105. package/dist/gpu/display-view-quality-gpu.js.map +1 -1
  106. package/dist/gpu/display-view-speed-gpu.d.ts +16 -16
  107. package/dist/gpu/display-view-speed-gpu.js +62 -19
  108. package/dist/gpu/display-view-speed-gpu.js.map +1 -1
  109. package/dist/gpu/image-kernel-accelerator.js +3 -0
  110. package/dist/gpu/image-kernel-accelerator.js.map +1 -1
  111. package/dist/gpu/image-kernel-execution.d.ts +2 -13
  112. package/dist/gpu/image-kernel-execution.js +2 -10
  113. package/dist/gpu/image-kernel-execution.js.map +1 -1
  114. package/dist/gpu/wgsl-display-view-coupled-stub.d.ts +13 -0
  115. package/dist/gpu/wgsl-display-view-coupled-stub.js +29 -0
  116. package/dist/gpu/wgsl-display-view-coupled-stub.js.map +1 -0
  117. package/dist/gpu/wgsl-display-view-coupled.d.ts +91 -0
  118. package/dist/gpu/wgsl-display-view-coupled.js +365 -0
  119. package/dist/gpu/wgsl-display-view-coupled.js.map +1 -0
  120. package/dist/gpu/wgsl-display-view-neighbors.d.ts +46 -0
  121. package/dist/gpu/wgsl-display-view-neighbors.js +114 -0
  122. package/dist/gpu/wgsl-display-view-neighbors.js.map +1 -0
  123. package/dist/gpu/wgsl-display-view-quality-kernel.d.ts +6 -9
  124. package/dist/gpu/wgsl-display-view-quality-kernel.js +113 -113
  125. package/dist/gpu/wgsl-display-view-quality-kernel.js.map +1 -1
  126. package/dist/gpu/wgsl-display-view-speed-kernel.d.ts +1 -41
  127. package/dist/gpu/wgsl-display-view-speed-kernel.js +73 -10
  128. package/dist/gpu/wgsl-display-view-speed-kernel.js.map +1 -1
  129. package/dist/index.d.ts +11 -3
  130. package/dist/index.js +9 -1
  131. package/dist/index.js.map +1 -1
  132. package/dist/output/camera-channel-response.d.ts +50 -0
  133. package/dist/output/camera-channel-response.js +69 -0
  134. package/dist/output/camera-channel-response.js.map +1 -0
  135. package/dist/output/native-capture-sdr.js +5 -2
  136. package/dist/output/native-capture-sdr.js.map +1 -1
  137. package/dist/output/sdr-rendering.d.ts +18 -1
  138. package/dist/output/sdr-rendering.js +39 -2
  139. package/dist/output/sdr-rendering.js.map +1 -1
  140. package/dist/sensor/native-sensor-report.d.ts +10 -0
  141. package/dist/sensor/native-sensor-report.js +16 -0
  142. package/dist/sensor/native-sensor-report.js.map +1 -0
  143. package/dist/sensor/sensor-characteristics.d.ts +81 -13
  144. package/dist/sensor/sensor-characteristics.js +10 -6
  145. package/dist/sensor/sensor-characteristics.js.map +1 -1
  146. package/docs/API_REFERENCE.md +117 -4
  147. package/docs/QUICK_START.md +37 -8
  148. package/docs/USAGE.md +105 -22
  149. package/docs/api/capture-c2pa-embed.md +177 -0
  150. package/docs/api/capture-dng-import.md +86 -10
  151. package/docs/api/capture-dng-opcodes.md +93 -0
  152. package/docs/api/capture-dng-profile-maps.md +141 -0
  153. package/docs/api/capture-dng-stage-image.md +43 -0
  154. package/docs/api/capture-jpeg-xl-tiles.md +33 -0
  155. package/docs/api/capture-lossy-jpeg.md +41 -0
  156. package/docs/api/capture-native-raw-development.md +2 -1
  157. package/docs/api/core-execution-error.md +43 -0
  158. package/docs/api/core-version.md +1 -1
  159. package/docs/api/exports.json +255 -5
  160. package/docs/api/facade-display-view-gpu.md +5 -2
  161. package/docs/api/facade-display-view.md +11 -15
  162. package/docs/api/facade-fast-methods.md +38 -9
  163. package/docs/api/facade-quality-paths.md +24 -0
  164. package/docs/api/facade-scene-radiance.md +1 -1
  165. package/docs/api/facade-simulate-capture.md +24 -7
  166. package/docs/api/facade-simulate-display-view.md +10 -12
  167. package/docs/api/gpu-image-kernel-execution.md +0 -36
  168. package/docs/api/output-camera-channel-response.md +55 -0
  169. package/docs/api/output-sdr-rendering.md +6 -1
  170. package/docs/api/sensor-sensor-characteristics.md +54 -2
  171. package/llms.txt +1 -0
  172. package/package.json +6 -5
@@ -1 +1 @@
1
- {"version":3,"file":"image-plane.js","sourceRoot":"","sources":["../../src/facade/image-plane.ts"],"names":[],"mappings":"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","sourcesContent":["// SPDX-License-Identifier: Apache-2.0\n\n/**\n * The image-plane scene (2.21, #581): a photo as a flat matte print on the scene plane. Loaded on demand (a dynamic import by\n * the facade) only when a request's scene is `{ kind: \"image-plane\" }`, so a bundle that never prints a photo does not carry\n * it or its lattice data.\n *\n * **From pixel to reflectance** (docs/IMAGE_PLANE.md):\n *\n * 1. Decode to linear sRGB: `srgb-8` and `srgb-16` through the sRGB transfer function (IEC 61966-2-1, the piecewise EOTF)\n * evaluated with the portable power (`portablePow`, within 1 ulp, the same bits in every JavaScript engine); `linear-srgb`\n * as given, clipped to [0, 1]. A pixel with alpha a is composited over the paper in linear light: c' = a·c + (1 − a).\n * 2. The print reflectance lattice: 5 × 5 × 5 nodes at the sRGB code values 0, 1/4, 1/2, 3/4, 1 per channel (their linear\n * values L₀…L₄). The node spectra on the neutral axis are flat (the node's linear value); the other 120 are Photivra's own\n * LHTSS fits (S. A. Burns, arXiv:1710.05732 v5, \"Least Hyperbolic Tangent Slope Squared (LHTSS) Method\", pp. 24–26), each\n * reproducing its node's sRGB under CIE D65 with the CIE 1931 2° observer (scripts/fit-image-plane-lattice.mjs), stored at\n * 10 nm over 380–780 nm in 16 bits and linearly interpolated between samples. A pixel's spectrum is the trilinear\n * interpolation, in linear sRGB, of the spectra of the eight nodes of its cell: a convex combination of spectra in [0, 1],\n * so it lies in [0, 1], and, XYZ being linear in the spectrum, it reproduces the pixel's sRGB under D65 to the nodes' own\n * residual (measured by the fit: CIEDE2000 at most 6.4·10⁻⁴ over a 17³ grid of sRGB codes).\n * 3. The paper: ρ = ρ_black + (ρ_white − ρ_black)·ρ_lattice, affine and so still bounded; defaults 0.90 and 0.01.\n * 4. Between pixel centers (`bilinear`, the default): the pixels' spectra weighted bilinearly, which under D65 is the bilinear\n * interpolation of the pixels' linear sRGB; `nearest` takes the pixel under the point. The print's edge pixels extend to\n * its edges (clamp to edge).\n *\n * Print-local coordinates are the chart's (cu = ±1 at the left and right edges, cv up, ±aspect at the top and bottom); the\n * pixel coordinates are X = (cu + 1)·W/2 and Y = (aspect − cv)·H/(2·aspect), with pixel centers at half-integers.\n */\n\nimport { InvalidConfigurationError } from \"../core/configuration-error.js\";\nimport { portablePow } from \"../core/portable-math.js\";\nimport { FULL_RESOLUTION_CEILING_PIXELS, FULL_RESOLUTION_DEFAULT_PIXELS, resolveRaisedLimit } from \"../core/pixel-limits.js\";\nimport { IMAGE_PLANE_LATTICE_CODES } from \"./image-plane-lattice-data.js\";\nimport { CHART_SIZE_DEFAULT_SURROUND_REFLECTANCE, resolveChartSizeOption, type ImagePlaneSignalScene, type ImagePlaneSpectralNodes, type ResolvedImagePlaneScene } from \"./scene-radiance.js\";\n\n/** Version of the print reflectance lattice and its data; a change to any node spectrum changes it. */\nexport const IMAGE_PLANE_LATTICE_VERSION = \"1.0.0\";\n/** Engine defaults of an image-plane scene. */\nexport const IMAGE_PLANE_DEFAULTS = /* @__PURE__ */ Object.freeze({ paperWhiteReflectance: 0.9, paperBlackReflectance: 0.01, interpolation: \"bilinear\" as const });\n\n/** Host bytes of the per-pixel signal rows a signal scene keeps (the direct path's query points revisit nearby pixels). */\nconst SIGNAL_ROW_CACHE_BYTES = 32 << 20;\nconst AXIS = 5, NODES = 125, SAMPLES = 41, MINIMUM_NM = 380, STEP_NM = 10, MAXIMUM_NM = MINIMUM_NM + STEP_NM * (SAMPLES - 1);\n\n/** The sRGB EOTF with the portable power. */\nfunction decodeSrgb(encoded: number): number {\n return encoded <= 0.04045 ? encoded / 12.92 : portablePow((encoded + 0.055) / 1.055, 2.4);\n}\n/** The lattice's node levels in linear sRGB. */\nconst LEVELS = /* @__PURE__ */ Float64Array.from({ length: AXIS }, (_, k) => (k === 0 ? 0 : k === AXIS - 1 ? 1 : decodeSrgb(k / (AXIS - 1))));\n\nlet nodeSpectra: Float64Array | null = null;\n/** The 125 node spectra, 41 samples each (node index r·25 + g·5 + b), decoded once from the data module. */\nfunction spectra(): Float64Array {\n if (nodeSpectra) return nodeSpectra;\n const out = new Float64Array(NODES * SAMPLES), rows = IMAGE_PLANE_LATTICE_CODES.split(\";\");\n if (rows.length !== NODES - AXIS) throw new InvalidConfigurationError(\"The image-plane lattice data is damaged.\");\n let row = 0;\n for (let node = 0; node < NODES; node++) {\n const r = Math.floor(node / 25), g = Math.floor(node / 5) % 5, b = node % 5;\n if (r === g && g === b) { out.fill(LEVELS[r]!, node * SAMPLES, (node + 1) * SAMPLES); continue; }\n const deltas = rows[row++]!.split(\",\");\n if (deltas.length !== SAMPLES) throw new InvalidConfigurationError(\"The image-plane lattice data is damaged.\");\n let code = 0;\n for (let i = 0; i < SAMPLES; i++) {\n code += parseInt(deltas[i]!, 36);\n if (!(code >= 0 && code <= 65535)) throw new InvalidConfigurationError(\"The image-plane lattice data is damaged.\");\n out[node * SAMPLES + i] = code / 65535;\n }\n }\n return (nodeSpectra = out);\n}\n\n/** Internal (for tests and docs): the node spectra as 125 rows of 41 reflectances at 380, 390, …, 780 nm. */\nexport function imagePlaneLatticeSpectra(): { levels: readonly number[]; wavelengthsNm: readonly number[]; spectra: readonly Float64Array[] } {\n const all = spectra();\n return { levels: Array.from(LEVELS), wavelengthsNm: Array.from({ length: SAMPLES }, (_, i) => MINIMUM_NM + STEP_NM * i),\n spectra: Array.from({ length: NODES }, (_, k) => all.slice(k * SAMPLES, (k + 1) * SAMPLES)) };\n}\n\n/** Every node's reflectance at one wavelength (the samples linearly interpolated). */\nfunction nodeReflectancesAt(nm: number): Float64Array {\n if (typeof nm !== \"number\" || !(nm >= MINIMUM_NM && nm <= MAXIMUM_NM)) throw new InvalidConfigurationError(\"An image-plane print is defined on \" + MINIMUM_NM + \"–\" + MAXIMUM_NM + \" nm.\");\n const all = spectra(), p = (nm - MINIMUM_NM) / STEP_NM, i = Math.min(SAMPLES - 2, Math.floor(p)), f = p - i, out = new Float64Array(NODES);\n for (let k = 0; k < NODES; k++) out[k] = all[k * SAMPLES + i]! * (1 - f) + all[k * SAMPLES + i + 1]! * f;\n return out;\n}\n\n/** The image's size, validated (the facade needs the aspect before the print's placement). */\nexport function readImagePlaneSize(value: unknown): { width: number; height: number } {\n if (typeof value !== \"object\" || value === null) throw new InvalidConfigurationError(\"scene must be an object.\");\n const image = (value as { image?: unknown }).image;\n if (typeof image !== \"object\" || image === null) throw new InvalidConfigurationError(\"An image-plane scene needs image { width, height, channels, encoding, data }.\");\n const { width, height } = image as Record<string, unknown>;\n for (const [name, v] of [[\"width\", width], [\"height\", height]] as const)\n if (typeof v !== \"number\" || !Number.isSafeInteger(v) || v < 1 || v > 65_536) throw new InvalidConfigurationError(\"scene.image.\" + name + \" must be an integer from 1 to 65536.\");\n return { width: width as number, height: height as number };\n}\n\n/**\n * Validates an image-plane scene and prepares it on a print of aspect `aspect` (height / width): the digest of its data, the\n * count of clipped `linear-srgb` samples, and the decoders. The data is borrowed (read on every lookup, never written).\n */\nexport async function resolveImagePlaneScene(value: unknown, aspect: number,\n assume?: (id: string, kind: \"default\" | \"model\" | \"derived\", value: unknown, explanation: string) => void): Promise<ResolvedImagePlaneScene> {\n const record = value as Record<string, unknown>;\n for (const key of Object.keys(record)) if (![\"kind\", \"sceneId\", \"image\", \"paper\", \"interpolation\", \"maximumPixels\"].includes(key)) throw new InvalidConfigurationError(\"Unknown scene field: \" + key + \".\");\n if (typeof record.sceneId !== \"string\" || !/^[A-Za-z0-9][A-Za-z0-9._:-]{0,63}$/.test(record.sceneId)) throw new InvalidConfigurationError(\"An image-plane scene needs a public sceneId.\");\n const { width, height } = readImagePlaneSize(record);\n const image = record.image as Record<string, unknown>;\n for (const key of Object.keys(image)) if (![\"width\", \"height\", \"channels\", \"encoding\", \"data\"].includes(key)) throw new InvalidConfigurationError(\"Unknown scene.image field: \" + key + \".\");\n const maximumPixels = resolveRaisedLimit(record.maximumPixels, FULL_RESOLUTION_DEFAULT_PIXELS, FULL_RESOLUTION_CEILING_PIXELS,\n \"scene.maximumPixels must be an integer from 1 to \" + FULL_RESOLUTION_CEILING_PIXELS + \".\");\n if (width * height > maximumPixels) throw new InvalidConfigurationError(\"The image has \" + width * height + \" pixels, above scene.maximumPixels (\" + maximumPixels + \").\");\n const channelsValue = image.channels, encoding = image.encoding, data = image.data;\n if (channelsValue !== 3 && channelsValue !== 4) throw new InvalidConfigurationError(\"scene.image.channels must be 3 (RGB) or 4 (RGBA).\");\n const typeOk = encoding === \"srgb-8\" ? data instanceof Uint8Array || data instanceof Uint8ClampedArray : encoding === \"srgb-16\" ? data instanceof Uint16Array :\n encoding === \"linear-srgb\" ? data instanceof Float32Array : undefined;\n if (typeOk === undefined) throw new InvalidConfigurationError(\"scene.image.encoding must be \\\"srgb-8\\\", \\\"srgb-16\\\" or \\\"linear-srgb\\\".\");\n if (!typeOk) throw new InvalidConfigurationError(\"scene.image.data must be a \" + (encoding === \"srgb-8\" ? \"Uint8Array or Uint8ClampedArray\" : encoding === \"srgb-16\" ? \"Uint16Array\" : \"Float32Array\") + \" for \" + encoding + \".\");\n const channels: 3 | 4 = channelsValue;\n const samples = data as Uint8Array | Uint8ClampedArray | Uint16Array | Float32Array;\n if (samples.length !== width * height * channels) throw new InvalidConfigurationError(\"scene.image.data must hold width × height × channels = \" + width * height * channels + \" samples.\");\n const paperRecord = record.paper;\n if (paperRecord !== undefined && (typeof paperRecord !== \"object\" || paperRecord === null)) throw new InvalidConfigurationError(\"scene.paper must be an object.\");\n const paper = (paperRecord ?? {}) as Record<string, unknown>;\n for (const key of Object.keys(paper)) if (key !== \"whiteReflectance\" && key !== \"blackReflectance\") throw new InvalidConfigurationError(\"Unknown scene.paper field: \" + key + \".\");\n const whiteValue = paper.whiteReflectance ?? IMAGE_PLANE_DEFAULTS.paperWhiteReflectance, blackValue = paper.blackReflectance ?? IMAGE_PLANE_DEFAULTS.paperBlackReflectance;\n if (typeof whiteValue !== \"number\" || typeof blackValue !== \"number\" || !(blackValue >= 0 && blackValue < whiteValue && whiteValue <= 1))\n throw new InvalidConfigurationError(\"scene.paper needs reflectances 0 ≤ blackReflectance < whiteReflectance ≤ 1.\");\n const white: number = whiteValue, black: number = blackValue;\n const interpolation = record.interpolation ?? IMAGE_PLANE_DEFAULTS.interpolation;\n if (interpolation !== \"bilinear\" && interpolation !== \"nearest\") throw new InvalidConfigurationError(\"scene.interpolation must be \\\"bilinear\\\" or \\\"nearest\\\".\");\n if (typeof aspect !== \"number\" || !(aspect > 0) || !Number.isFinite(aspect)) throw new InvalidConfigurationError(\"The print's aspect must be positive.\");\n // Linear input: every sample finite; those outside [0, 1] are clipped and counted.\n let clipped = 0;\n if (encoding === \"linear-srgb\") for (let i = 0; i < samples.length; i++) {\n const v = samples[i]!;\n if (!Number.isFinite(v)) throw new InvalidConfigurationError(\"scene.image.data must be finite (sample \" + i + \").\");\n if (v < 0 || v > 1) clipped++;\n }\n const subtle = globalThis.crypto?.subtle;\n if (!subtle) throw new InvalidConfigurationError(\"An image-plane scene needs crypto.subtle (a secure browser context or Node 22+) to digest the image.\");\n const view = new Uint8Array(samples.buffer, samples.byteOffset, samples.byteLength);\n const digest = new Uint8Array(await subtle.digest(\"SHA-256\", (samples.buffer instanceof ArrayBuffer ? view : view.slice()) as Uint8Array<ArrayBuffer>));\n const dataSha256 = Array.from(digest, (b) => b.toString(16).padStart(2, \"0\")).join(\"\");\n\n // Decoders: a table per integer encoding (the transfer function once per code), the clip for linear samples.\n const scale = encoding === \"srgb-8\" ? 255 : encoding === \"srgb-16\" ? 65535 : 1;\n const table = encoding === \"linear-srgb\" ? null : Float64Array.from({ length: scale + 1 }, (_, code) => decodeSrgb(code / scale));\n const color = table ? (i: number): number => table[samples[i]!]! : (i: number): number => { const v = samples[i]!; return v <= 0 ? 0 : v >= 1 ? 1 : v; };\n const alpha = channels === 3 ? null : encoding === \"linear-srgb\" ? color : (i: number): number => samples[i]! / scale;\n const rgb = new Float64Array(3), span = white - black;\n const cellOf = (v: number): number => (v > LEVELS[3]! ? 3 : v > LEVELS[2]! ? 2 : v > LEVELS[1]! ? 1 : 0);\n const fractions = new Float64Array(3);\n /** One pixel's lattice cell (its base node, returned) and its fractions in the cell (into `out`). */\n function pixelLattice(index: number, out: Float64Array): number {\n const base = index * channels;\n if (alpha) {\n const a = alpha(base + 3);\n for (let c = 0; c < 3; c++) rgb[c] = a * color(base + c) + (1 - a);\n } else for (let c = 0; c < 3; c++) rgb[c] = color(base + c);\n const kr = cellOf(rgb[0]!), kg = cellOf(rgb[1]!), kb = cellOf(rgb[2]!);\n out[0] = (rgb[0]! - LEVELS[kr]!) / (LEVELS[kr + 1]! - LEVELS[kr]!); out[1] = (rgb[1]! - LEVELS[kg]!) / (LEVELS[kg + 1]! - LEVELS[kg]!); out[2] = (rgb[2]! - LEVELS[kb]!) / (LEVELS[kb + 1]! - LEVELS[kb]!);\n return kr * 25 + kg * 5 + kb;\n }\n /** One pixel in node values: the trilinear weights of its linear sRGB in the lattice cell, then the paper. */\n function pixelValue(index: number, nodeValues: Float64Array, neutral: number): number {\n const n = pixelLattice(index, fractions), fr = fractions[0]!, fg = fractions[1]!, fb = fractions[2]!;\n const lattice = (1 - fr) * ((1 - fg) * ((1 - fb) * nodeValues[n]! + fb * nodeValues[n + 1]!) + fg * ((1 - fb) * nodeValues[n + 5]! + fb * nodeValues[n + 6]!)) +\n fr * ((1 - fg) * ((1 - fb) * nodeValues[n + 25]! + fb * nodeValues[n + 26]!) + fg * ((1 - fb) * nodeValues[n + 30]! + fb * nodeValues[n + 31]!));\n return black * neutral + span * lattice;\n }\n const halfW = width / 2, halfH = height / (2 * aspect);\n /** The print at a print-local point from a per-pixel value: bilinear between pixel centers (clamped to the edge) or the nearest pixel. */\n function interpolate(cu: number, cv: number, at: (index: number) => number): number {\n const X = (cu + 1) * halfW, Y = (aspect - cv) * halfH;\n if (interpolation === \"nearest\") return at(Math.min(height - 1, Math.max(0, Math.floor(Y))) * width + Math.min(width - 1, Math.max(0, Math.floor(X))));\n const sx = X - 0.5, sy = Y - 0.5, i0 = Math.floor(sx), j0 = Math.floor(sy), fx = sx - i0, fy = sy - j0;\n const ia = Math.min(width - 1, Math.max(0, i0)), ib = Math.min(width - 1, Math.max(0, i0 + 1));\n const ja = Math.min(height - 1, Math.max(0, j0)) * width, jb = Math.min(height - 1, Math.max(0, j0 + 1)) * width;\n return (1 - fy) * ((1 - fx) * at(ja + ia) + fx * at(ja + ib)) + fy * ((1 - fx) * at(jb + ia) + fx * at(jb + ib));\n }\n const sampleAt = (cu: number, cv: number, nodeValues: Float64Array, neutral: number): number => interpolate(cu, cv, (index) => pixelValue(index, nodeValues, neutral));\n // Per wavelength the node reflectances (the facade asks for a few spectral nodes many times).\n const atWavelength = new Map<number, Float64Array>();\n function reflectanceAt(cu: number, cv: number, nm: number): number {\n let nodes = atWavelength.get(nm);\n if (!nodes) { nodes = nodeReflectancesAt(nm); if (atWavelength.size < 4096) atWavelength.set(nm, nodes); }\n return sampleAt(cu, cv, nodes, 1);\n }\n /**\n * One pixel's channel signals, integrated from its reconstructed spectrum (owner decision 2026-11-09): per spectral node n its\n * reflectance ρ_n (its cell's eight node spectra at λ_n blended with the trilinear weights, then the paper) times the white\n * radiance W_n, then per channel Σ_n A_c(λ_n)·ρ_n·W_n. Written to out[at..at + 2].\n */\n function pixelSignals(index: number, nodes: ImagePlaneSpectralNodes, out: Float64Array, at: number): void {\n const N = nodes.count, R = nodes.nodeSpectra, W = nodes.whiteRadiance, A0 = nodes.response[0]!, A1 = nodes.response[1]!, A2 = nodes.response[2]!;\n const base = pixelLattice(index, fractions) * N, fr = fractions[0]!, fg = fractions[1]!, fb = fractions[2]!, gb = 1 - fb;\n const a00 = (1 - fr) * (1 - fg), a01 = (1 - fr) * fg, a10 = fr * (1 - fg), a11 = fr * fg;\n const w0 = a00 * gb, w1 = a00 * fb, w5 = a01 * gb, w6 = a01 * fb, w25 = a10 * gb, w26 = a10 * fb, w30 = a11 * gb, w31 = a11 * fb;\n let s0 = 0, s1 = 0, s2 = 0;\n for (let n = 0, k = base; n < N; n++, k++) {\n const lattice = w0 * R[k]! + w1 * R[k + N]! + w5 * R[k + 5 * N]! + w6 * R[k + 6 * N]! + w25 * R[k + 25 * N]! + w26 * R[k + 26 * N]! + w30 * R[k + 30 * N]! + w31 * R[k + 31 * N]!;\n // Each channel's sum in node order (one pass over the spectrum).\n const radiance = (black + span * lattice) * W[n]!;\n s0 += A0[n]! * radiance; s1 += A1[n]! * radiance; s2 += A2[n]! * radiance;\n }\n out[at] = s0; out[at + 1] = s1; out[at + 2] = s2;\n }\n function signalScene(wavelengths: readonly number[], perNode: readonly Float64Array[], whiteRadiance: Float64Array, radianceAt: (u: number, v: number, nm: number) => number,\n scale: number, half: number, surroundReflectance: number): ImagePlaneSignalScene {\n // The lattice's spectra at the nodes (node k's reflectance at λ_n at k·N + n); no channel response is folded in.\n const N = wavelengths.length, spectraAt = wavelengths.map((nm) => nodeReflectancesAt(nm)), nodeSpectra = new Float64Array(NODES * N);\n for (let k = 0; k < NODES; k++) for (let n = 0; n < N; n++) nodeSpectra[k * N + n] = spectraAt[n]![k]!;\n const nodes: ImagePlaneSpectralNodes = { count: N, nodeSpectra, whiteRadiance, response: perNode };\n // The surround's channel signals, integrated from its spectrum ρ·W_n like a pixel's (no white-integral shortcut, 2.21.0).\n const surround = [0, 1, 2].map((c) => { let s = 0; for (let n = 0; n < N; n++) s += perNode[c]![n]! * (surroundReflectance * whiteRadiance[n]!); return s; }) as [number, number, number];\n // The pixels' signals as the query points reach them: rows of three values per pixel (NaN until computed), the latest rows kept.\n const rows = new Map<number, Float64Array>(), keptRows = Math.max(8, Math.floor(SIGNAL_ROW_CACHE_BYTES / (width * 24)));\n let lastJ = -1, lastRow: Float64Array = new Float64Array(0);\n const rowAt = (j: number): Float64Array => {\n if (j === lastJ) return lastRow;\n let row = rows.get(j);\n if (!row) { row = new Float64Array(width * 3).fill(NaN); rows.set(j, row); if (rows.size > keptRows) rows.delete(rows.keys().next().value!); }\n lastJ = j; lastRow = row;\n return row;\n };\n const signalOf = (row: Float64Array, j: number, i: number, c: number): number => {\n if (row[i * 3] !== row[i * 3]) pixelSignals(j * width + i, nodes, row, i * 3);\n return row[i * 3 + c]!;\n };\n return { kind: \"radiance\", radianceAt, signalAt(u: number, v: number, c: number): number {\n const cu = u * scale / half, cv = v * scale / half;\n if (!(Math.abs(cu) <= 1 && Math.abs(cv) <= aspect)) return surround[c]!;\n // As `interpolate`, reading the pixels' signals.\n const X = (cu + 1) * halfW, Y = (aspect - cv) * halfH;\n if (interpolation === \"nearest\") { const j = Math.min(height - 1, Math.max(0, Math.floor(Y))); return signalOf(rowAt(j), j, Math.min(width - 1, Math.max(0, Math.floor(X))), c); }\n const sx = X - 0.5, sy = Y - 0.5, i0 = Math.floor(sx), j0 = Math.floor(sy), fx = sx - i0, fy = sy - j0;\n const ia = Math.min(width - 1, Math.max(0, i0)), ib = Math.min(width - 1, Math.max(0, i0 + 1)), ja = Math.min(height - 1, Math.max(0, j0)), jb = Math.min(height - 1, Math.max(0, j0 + 1));\n const rowA = rowAt(ja), a0 = signalOf(rowA, ja, ia, c), a1 = signalOf(rowA, ja, ib, c), rowB = rowAt(jb);\n return (1 - fy) * ((1 - fx) * a0 + fx * a1) + fy * ((1 - fx) * signalOf(rowB, jb, ia, c) + fx * signalOf(rowB, jb, ib, c));\n }, image: { scene: resolved, nodes, surround, whiteRadiance, surroundReflectance } };\n }\n const resolved: ResolvedImagePlaneScene = Object.freeze({ kind: \"image-plane\" as const, sceneId: record.sceneId, width, height, aspect, channels, encoding: encoding as ResolvedImagePlaneScene[\"encoding\"],\n interpolation, paperWhiteReflectance: white, paperBlackReflectance: black, maximumPixels, clippedSampleCount: clipped, dataSha256,\n reflectanceAt, sampleAt, pixelValue, pixelSignals, pixelLattice, nodeReflectances: nodeReflectancesAt, signalScene, get digestForm() { return imagePlaneDigestForm(resolved); }, parameters: Object.freeze({ width, height, channels, encoding, interpolation, paperWhiteReflectance: white, paperBlackReflectance: black,\n clippedSampleCount: clipped, imageSha256: dataSha256 }) });\n if (assume) for (const [id, kind, v, explanation] of imagePlaneAssumptions(resolved, record)) assume(id, kind, v, explanation);\n return resolved;\n}\n\n/** The scene's form in the facade's source digest: the image's SHA-256 and shape, the paper, the interpolation and the lattice version. */\nexport function imagePlaneDigestForm(scene: ResolvedImagePlaneScene): Record<string, unknown> {\n return { kind: scene.kind, sceneId: scene.sceneId, image: { width: scene.width, height: scene.height, channels: scene.channels, encoding: scene.encoding, sha256: scene.dataSha256 },\n paper: { whiteReflectance: scene.paperWhiteReflectance, blackReflectance: scene.paperBlackReflectance }, interpolation: scene.interpolation, latticeVersion: IMAGE_PLANE_LATTICE_VERSION };\n}\n\n/** The assumptions an image-plane capture records: the model, the defaults taken, and the clipped linear samples. */\nexport function imagePlaneAssumptions(scene: ResolvedImagePlaneScene, record: Record<string, unknown>): [string, \"default\" | \"model\" | \"derived\", unknown, string][] {\n const out: [string, \"default\" | \"model\" | \"derived\", unknown, string][] = [];\n const paper = (record.paper ?? {}) as Record<string, unknown>;\n if (paper.whiteReflectance === undefined) out.push([\"scene.paper.whiteReflectance\", \"default\", scene.paperWhiteReflectance,\n \"Photivra's assumption, not a measurement: the paper reflects 90 % (the white of the engine's Studio Gray 1 patch), so sRGB white prints as a 0.90 flat reflectance.\"]);\n if (paper.blackReflectance === undefined) out.push([\"scene.paper.blackReflectance\", \"default\", scene.paperBlackReflectance,\n \"Photivra's assumption, not a measurement: the deepest ink reflects 1 % (an optical density of 2.0), so sRGB black prints as a 0.01 flat reflectance.\"]);\n if (record.interpolation === undefined) out.push([\"scene.interpolation\", \"default\", scene.interpolation,\n \"Bilinear between pixel centers: the four nearest pixels' reflectance spectra, bilinearly weighted (under CIE D65, the bilinear interpolation of their linear sRGB); the edge pixels extend to the print's edges.\"]);\n out.push([\"scene.imagePlane\", \"model\", { latticeVersion: IMAGE_PLANE_LATTICE_VERSION, nodesPerAxis: AXIS, method: \"lhtss-burns-2020\", wavelengthStepNanometers: STEP_NM,\n width: scene.width, height: scene.height, encoding: scene.encoding, channels: scene.channels },\n \"An approximation: a print of the image, which was already processed, clipped and blurred by the camera that took it. Each pixel is decoded to linear sRGB \" +\n (scene.encoding === \"linear-srgb\" ? \"(given linear, clipped to [0, 1])\" : \"with the sRGB transfer function (IEC 61966-2-1)\") + (scene.channels === 4 ? \", composited over the paper by its alpha,\" : \"\") +\n \" and becomes a reflectance spectrum by trilinear interpolation in a 5 × 5 × 5 lattice of smooth spectra (Burns' LHTSS method, arXiv:1710.05732 v5, fitted by Photivra against CIE D65 and the \" +\n \"CIE 1931 2° observer), which reproduces the pixel's sRGB under D65 within CIEDE2000 6.4e-4 and stays in [0, 1]; then ρ = black + (white − black)·ρ. Under other lights its colors are one plausible \" +\n \"metamer of many (docs/IMAGE_PLANE.md, measured spread). A flat matte Lambertian print: no gloss, paper texture, halftone, curl or fluorescence.\"]);\n out.push([\"scene.digest\", \"model\", \"image-data-hashed\", \"The source digest covers the image's SHA-256, size, channels and encoding, the paper, the interpolation, the lattice version and the framing.\"]);\n if (scene.clippedSampleCount > 0) out.push([\"scene.image.clippedSamples\", \"derived\", scene.clippedSampleCount,\n \"Linear samples outside [0, 1] clipped to the print's range (a print cannot be brighter than its paper or darker than its deepest ink).\"]);\n return out;\n}\n\n/** The GPU display view's image-plane module, loaded on demand by the GPU renderer (its own chunk). */\nexport function loadGpuModule(): Promise<typeof import(\"../gpu/display-view-image-material-module.js\")> {\n return import(\"../gpu/display-view-image-material-module.js\");\n}\n\n/**\n * The print's placement: `chartSize` with its height defaulting to the image's aspect, or, without it, the print fitted inside\n * the frame (centered, filling its width or height) on the default surround; records the defaults it takes.\n */\nexport function imagePlanePrint(scene: unknown, chartSize: unknown, framedWidthM: number, frameAspect: number,\n assume: (id: string, kind: \"default\", value: unknown, explanation: string) => void): ReturnType<typeof resolveChartSizeOption> {\n const size = readImagePlaneSize(scene), imageAspect = size.height / size.width;\n if (chartSize !== undefined) {\n const resolved = resolveChartSizeOption(chartSize, imageAspect);\n if (resolved.defaulted.includes(\"heightM\")) assume(\"chartSize.heightM\", \"default\", resolved.heightM, \"The print has the image's shape: height = width × image height / image width.\");\n return { ...resolved, defaulted: resolved.defaulted.filter((key) => key !== \"heightM\") };\n }\n const widthM = imageAspect > frameAspect ? framedWidthM * frameAspect / imageAspect : framedWidthM;\n const fitted = { widthM, heightM: widthM * imageAspect, surroundReflectance: CHART_SIZE_DEFAULT_SURROUND_REFLECTANCE, defaulted: [] as (\"heightM\" | \"surroundReflectance\")[] };\n assume(\"chartSize\", \"default\", { widthM: fitted.widthM, heightM: fitted.heightM, surroundReflectance: fitted.surroundReflectance },\n \"The print has the image's shape and is fitted inside the frame, centered (it fills the frame's width or height), on an 18 % neutral gray surround.\");\n return fitted;\n}\n"]}
1
+ {"version":3,"file":"image-plane.js","sourceRoot":"","sources":["../../src/facade/image-plane.ts"],"names":[],"mappings":"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","sourcesContent":["// SPDX-License-Identifier: Apache-2.0\n\n/**\n * The image-plane scene (2.21, #581): a photo as a flat matte print on the scene plane. Loaded on demand (a dynamic import by\n * the facade) only when a request's scene is `{ kind: \"image-plane\" }`, so a bundle that never prints a photo does not carry\n * it or its lattice data.\n *\n * **From pixel to reflectance** (docs/IMAGE_PLANE.md):\n *\n * 1. Decode to linear sRGB: `srgb-8` and `srgb-16` through the sRGB transfer function (IEC 61966-2-1, the piecewise EOTF)\n * evaluated with the portable power (`portablePow`, within 1 ulp, the same bits in every JavaScript engine); `linear-srgb`\n * as given, clipped to [0, 1]. A pixel with alpha a is composited over the paper in linear light: c' = a·c + (1 − a).\n * 2. The print reflectance lattice: 5 × 5 × 5 nodes at the sRGB code values 0, 1/4, 1/2, 3/4, 1 per channel (their linear\n * values L₀…L₄). The node spectra on the neutral axis are flat (the node's linear value); the other 120 are Photivra's own\n * LHTSS fits (S. A. Burns, arXiv:1710.05732 v5, \"Least Hyperbolic Tangent Slope Squared (LHTSS) Method\", pp. 24–26), each\n * reproducing its node's sRGB under CIE D65 with the CIE 1931 2° observer (scripts/fit-image-plane-lattice.mjs), stored at\n * 10 nm over 380–780 nm in 16 bits and linearly interpolated between samples. A pixel's spectrum is the trilinear\n * interpolation, in linear sRGB, of the spectra of the eight nodes of its cell: a convex combination of spectra in [0, 1],\n * so it lies in [0, 1], and, XYZ being linear in the spectrum, it reproduces the pixel's sRGB under D65 to the nodes' own\n * residual (measured by the fit: CIEDE2000 at most 6.4·10⁻⁴ over a 17³ grid of sRGB codes).\n * 3. The paper: ρ = ρ_black + (ρ_white − ρ_black)·ρ_lattice, affine and so still bounded; defaults 0.90 and 0.01.\n * 4. Between pixel centers (`bilinear`, the default): the pixels' spectra weighted bilinearly, which under D65 is the bilinear\n * interpolation of the pixels' linear sRGB; `nearest` takes the pixel under the point. The print's edge pixels extend to\n * its edges (clamp to edge).\n *\n * Print-local coordinates are the chart's (cu = ±1 at the left and right edges, cv up, ±aspect at the top and bottom); the\n * pixel coordinates are X = (cu + 1)·W/2 and Y = (aspect − cv)·H/(2·aspect), with pixel centers at half-integers.\n */\n\nimport { InvalidConfigurationError } from \"../core/configuration-error.js\";\nimport { portablePow } from \"../core/portable-math.js\";\nimport { FULL_RESOLUTION_CEILING_PIXELS, FULL_RESOLUTION_DEFAULT_PIXELS, resolveRaisedLimit } from \"../core/pixel-limits.js\";\nimport { IMAGE_PLANE_LATTICE_CODES } from \"./image-plane-lattice-data.js\";\nimport { CHART_SIZE_DEFAULT_SURROUND_REFLECTANCE, resolveChartSizeOption, type ImagePlaneLitScene, type ImagePlaneSignalScene, type ImagePlaneSpectralNodes, type ResolvedImagePlaneScene } from \"./scene-radiance.js\";\nimport type { ResolvedMixedIllumination } from \"./mixed-illumination.js\";\n\n/** Version of the print reflectance lattice and its data; a change to any node spectrum changes it. */\nexport const IMAGE_PLANE_LATTICE_VERSION = \"1.0.0\";\n/** Engine defaults of an image-plane scene. */\nexport const IMAGE_PLANE_DEFAULTS = /* @__PURE__ */ Object.freeze({ paperWhiteReflectance: 0.9, paperBlackReflectance: 0.01, interpolation: \"bilinear\" as const });\n\n/** Host bytes of the per-pixel signal rows a signal scene keeps (the direct path's query points revisit nearby pixels). */\nconst SIGNAL_ROW_CACHE_BYTES = 32 << 20;\nconst AXIS = 5, NODES = 125, SAMPLES = 41, MINIMUM_NM = 380, STEP_NM = 10, MAXIMUM_NM = MINIMUM_NM + STEP_NM * (SAMPLES - 1);\n\n/** The sRGB EOTF with the portable power. */\nfunction decodeSrgb(encoded: number): number {\n return encoded <= 0.04045 ? encoded / 12.92 : portablePow((encoded + 0.055) / 1.055, 2.4);\n}\n/** The lattice's node levels in linear sRGB. */\nconst LEVELS = /* @__PURE__ */ Float64Array.from({ length: AXIS }, (_, k) => (k === 0 ? 0 : k === AXIS - 1 ? 1 : decodeSrgb(k / (AXIS - 1))));\n\nlet nodeSpectra: Float64Array | null = null;\n/** The 125 node spectra, 41 samples each (node index r·25 + g·5 + b), decoded once from the data module. */\nfunction spectra(): Float64Array {\n if (nodeSpectra) return nodeSpectra;\n const out = new Float64Array(NODES * SAMPLES), rows = IMAGE_PLANE_LATTICE_CODES.split(\";\");\n if (rows.length !== NODES - AXIS) throw new InvalidConfigurationError(\"The image-plane lattice data is damaged.\");\n let row = 0;\n for (let node = 0; node < NODES; node++) {\n const r = Math.floor(node / 25), g = Math.floor(node / 5) % 5, b = node % 5;\n if (r === g && g === b) { out.fill(LEVELS[r]!, node * SAMPLES, (node + 1) * SAMPLES); continue; }\n const deltas = rows[row++]!.split(\",\");\n if (deltas.length !== SAMPLES) throw new InvalidConfigurationError(\"The image-plane lattice data is damaged.\");\n let code = 0;\n for (let i = 0; i < SAMPLES; i++) {\n code += parseInt(deltas[i]!, 36);\n if (!(code >= 0 && code <= 65535)) throw new InvalidConfigurationError(\"The image-plane lattice data is damaged.\");\n out[node * SAMPLES + i] = code / 65535;\n }\n }\n return (nodeSpectra = out);\n}\n\n/** Internal (for tests and docs): the node spectra as 125 rows of 41 reflectances at 380, 390, …, 780 nm. */\nexport function imagePlaneLatticeSpectra(): { levels: readonly number[]; wavelengthsNm: readonly number[]; spectra: readonly Float64Array[] } {\n const all = spectra();\n return { levels: Array.from(LEVELS), wavelengthsNm: Array.from({ length: SAMPLES }, (_, i) => MINIMUM_NM + STEP_NM * i),\n spectra: Array.from({ length: NODES }, (_, k) => all.slice(k * SAMPLES, (k + 1) * SAMPLES)) };\n}\n\n/** Every node's reflectance at one wavelength (the samples linearly interpolated). */\nfunction nodeReflectancesAt(nm: number): Float64Array {\n if (typeof nm !== \"number\" || !(nm >= MINIMUM_NM && nm <= MAXIMUM_NM)) throw new InvalidConfigurationError(\"An image-plane print is defined on \" + MINIMUM_NM + \"–\" + MAXIMUM_NM + \" nm.\");\n const all = spectra(), p = (nm - MINIMUM_NM) / STEP_NM, i = Math.min(SAMPLES - 2, Math.floor(p)), f = p - i, out = new Float64Array(NODES);\n for (let k = 0; k < NODES; k++) out[k] = all[k * SAMPLES + i]! * (1 - f) + all[k * SAMPLES + i + 1]! * f;\n return out;\n}\n\n/** The image's size, validated (the facade needs the aspect before the print's placement). */\nexport function readImagePlaneSize(value: unknown): { width: number; height: number } {\n if (typeof value !== \"object\" || value === null) throw new InvalidConfigurationError(\"scene must be an object.\");\n const image = (value as { image?: unknown }).image;\n if (typeof image !== \"object\" || image === null) throw new InvalidConfigurationError(\"An image-plane scene needs image { width, height, channels, encoding, data }.\");\n const { width, height } = image as Record<string, unknown>;\n for (const [name, v] of [[\"width\", width], [\"height\", height]] as const)\n if (typeof v !== \"number\" || !Number.isSafeInteger(v) || v < 1 || v > 65_536) throw new InvalidConfigurationError(\"scene.image.\" + name + \" must be an integer from 1 to 65536.\");\n return { width: width as number, height: height as number };\n}\n\n/**\n * Validates an image-plane scene and prepares it on a print of aspect `aspect` (height / width): the digest of its data, the\n * count of clipped `linear-srgb` samples, and the decoders. The data is borrowed (read on every lookup, never written).\n */\nexport async function resolveImagePlaneScene(value: unknown, aspect: number,\n assume?: (id: string, kind: \"default\" | \"model\" | \"derived\", value: unknown, explanation: string) => void): Promise<ResolvedImagePlaneScene> {\n const record = value as Record<string, unknown>;\n for (const key of Object.keys(record)) if (![\"kind\", \"sceneId\", \"image\", \"paper\", \"interpolation\", \"maximumPixels\"].includes(key)) throw new InvalidConfigurationError(\"Unknown scene field: \" + key + \".\");\n if (typeof record.sceneId !== \"string\" || !/^[A-Za-z0-9][A-Za-z0-9._:-]{0,63}$/.test(record.sceneId)) throw new InvalidConfigurationError(\"An image-plane scene needs a public sceneId.\");\n const { width, height } = readImagePlaneSize(record);\n const image = record.image as Record<string, unknown>;\n for (const key of Object.keys(image)) if (![\"width\", \"height\", \"channels\", \"encoding\", \"data\"].includes(key)) throw new InvalidConfigurationError(\"Unknown scene.image field: \" + key + \".\");\n const maximumPixels = resolveRaisedLimit(record.maximumPixels, FULL_RESOLUTION_DEFAULT_PIXELS, FULL_RESOLUTION_CEILING_PIXELS,\n \"scene.maximumPixels must be an integer from 1 to \" + FULL_RESOLUTION_CEILING_PIXELS + \".\");\n if (width * height > maximumPixels) throw new InvalidConfigurationError(\"The image has \" + width * height + \" pixels, above scene.maximumPixels (\" + maximumPixels + \").\");\n const channelsValue = image.channels, encoding = image.encoding, data = image.data;\n if (channelsValue !== 3 && channelsValue !== 4) throw new InvalidConfigurationError(\"scene.image.channels must be 3 (RGB) or 4 (RGBA).\");\n const typeOk = encoding === \"srgb-8\" ? data instanceof Uint8Array || data instanceof Uint8ClampedArray : encoding === \"srgb-16\" ? data instanceof Uint16Array :\n encoding === \"linear-srgb\" ? data instanceof Float32Array : undefined;\n if (typeOk === undefined) throw new InvalidConfigurationError(\"scene.image.encoding must be \\\"srgb-8\\\", \\\"srgb-16\\\" or \\\"linear-srgb\\\".\");\n if (!typeOk) throw new InvalidConfigurationError(\"scene.image.data must be a \" + (encoding === \"srgb-8\" ? \"Uint8Array or Uint8ClampedArray\" : encoding === \"srgb-16\" ? \"Uint16Array\" : \"Float32Array\") + \" for \" + encoding + \".\");\n const channels: 3 | 4 = channelsValue;\n const samples = data as Uint8Array | Uint8ClampedArray | Uint16Array | Float32Array;\n if (samples.length !== width * height * channels) throw new InvalidConfigurationError(\"scene.image.data must hold width × height × channels = \" + width * height * channels + \" samples.\");\n const paperRecord = record.paper;\n if (paperRecord !== undefined && (typeof paperRecord !== \"object\" || paperRecord === null)) throw new InvalidConfigurationError(\"scene.paper must be an object.\");\n const paper = (paperRecord ?? {}) as Record<string, unknown>;\n for (const key of Object.keys(paper)) if (key !== \"whiteReflectance\" && key !== \"blackReflectance\") throw new InvalidConfigurationError(\"Unknown scene.paper field: \" + key + \".\");\n const whiteValue = paper.whiteReflectance ?? IMAGE_PLANE_DEFAULTS.paperWhiteReflectance, blackValue = paper.blackReflectance ?? IMAGE_PLANE_DEFAULTS.paperBlackReflectance;\n if (typeof whiteValue !== \"number\" || typeof blackValue !== \"number\" || !(blackValue >= 0 && blackValue < whiteValue && whiteValue <= 1))\n throw new InvalidConfigurationError(\"scene.paper needs reflectances 0 ≤ blackReflectance < whiteReflectance ≤ 1.\");\n const white: number = whiteValue, black: number = blackValue;\n const interpolation = record.interpolation ?? IMAGE_PLANE_DEFAULTS.interpolation;\n if (interpolation !== \"bilinear\" && interpolation !== \"nearest\") throw new InvalidConfigurationError(\"scene.interpolation must be \\\"bilinear\\\" or \\\"nearest\\\".\");\n if (typeof aspect !== \"number\" || !(aspect > 0) || !Number.isFinite(aspect)) throw new InvalidConfigurationError(\"The print's aspect must be positive.\");\n // Linear input: every sample finite; those outside [0, 1] are clipped and counted.\n let clipped = 0;\n if (encoding === \"linear-srgb\") for (let i = 0; i < samples.length; i++) {\n const v = samples[i]!;\n if (!Number.isFinite(v)) throw new InvalidConfigurationError(\"scene.image.data must be finite (sample \" + i + \").\");\n if (v < 0 || v > 1) clipped++;\n }\n const subtle = globalThis.crypto?.subtle;\n if (!subtle) throw new InvalidConfigurationError(\"An image-plane scene needs crypto.subtle (a secure browser context or Node 22+) to digest the image.\");\n const view = new Uint8Array(samples.buffer, samples.byteOffset, samples.byteLength);\n const digest = new Uint8Array(await subtle.digest(\"SHA-256\", (samples.buffer instanceof ArrayBuffer ? view : view.slice()) as Uint8Array<ArrayBuffer>));\n const dataSha256 = Array.from(digest, (b) => b.toString(16).padStart(2, \"0\")).join(\"\");\n\n // Decoders: a table per integer encoding (the transfer function once per code), the clip for linear samples.\n const scale = encoding === \"srgb-8\" ? 255 : encoding === \"srgb-16\" ? 65535 : 1;\n const table = encoding === \"linear-srgb\" ? null : Float64Array.from({ length: scale + 1 }, (_, code) => decodeSrgb(code / scale));\n const color = table ? (i: number): number => table[samples[i]!]! : (i: number): number => { const v = samples[i]!; return v <= 0 ? 0 : v >= 1 ? 1 : v; };\n const alpha = channels === 3 ? null : encoding === \"linear-srgb\" ? color : (i: number): number => samples[i]! / scale;\n const rgb = new Float64Array(3), span = white - black;\n const cellOf = (v: number): number => (v > LEVELS[3]! ? 3 : v > LEVELS[2]! ? 2 : v > LEVELS[1]! ? 1 : 0);\n const fractions = new Float64Array(3);\n /** One pixel's lattice cell (its base node, returned) and its fractions in the cell (into `out`). */\n function pixelLattice(index: number, out: Float64Array): number {\n const base = index * channels;\n if (alpha) {\n const a = alpha(base + 3);\n for (let c = 0; c < 3; c++) rgb[c] = a * color(base + c) + (1 - a);\n } else for (let c = 0; c < 3; c++) rgb[c] = color(base + c);\n const kr = cellOf(rgb[0]!), kg = cellOf(rgb[1]!), kb = cellOf(rgb[2]!);\n out[0] = (rgb[0]! - LEVELS[kr]!) / (LEVELS[kr + 1]! - LEVELS[kr]!); out[1] = (rgb[1]! - LEVELS[kg]!) / (LEVELS[kg + 1]! - LEVELS[kg]!); out[2] = (rgb[2]! - LEVELS[kb]!) / (LEVELS[kb + 1]! - LEVELS[kb]!);\n return kr * 25 + kg * 5 + kb;\n }\n /** One pixel in node values: the trilinear weights of its linear sRGB in the lattice cell, then the paper. */\n function pixelValue(index: number, nodeValues: Float64Array, neutral: number): number {\n const n = pixelLattice(index, fractions), fr = fractions[0]!, fg = fractions[1]!, fb = fractions[2]!;\n const lattice = (1 - fr) * ((1 - fg) * ((1 - fb) * nodeValues[n]! + fb * nodeValues[n + 1]!) + fg * ((1 - fb) * nodeValues[n + 5]! + fb * nodeValues[n + 6]!)) +\n fr * ((1 - fg) * ((1 - fb) * nodeValues[n + 25]! + fb * nodeValues[n + 26]!) + fg * ((1 - fb) * nodeValues[n + 30]! + fb * nodeValues[n + 31]!));\n return black * neutral + span * lattice;\n }\n const halfW = width / 2, halfH = height / (2 * aspect);\n /** The print at a print-local point from a per-pixel value: bilinear between pixel centers (clamped to the edge) or the nearest pixel. */\n function interpolate(cu: number, cv: number, at: (index: number) => number): number {\n const X = (cu + 1) * halfW, Y = (aspect - cv) * halfH;\n if (interpolation === \"nearest\") return at(Math.min(height - 1, Math.max(0, Math.floor(Y))) * width + Math.min(width - 1, Math.max(0, Math.floor(X))));\n const sx = X - 0.5, sy = Y - 0.5, i0 = Math.floor(sx), j0 = Math.floor(sy), fx = sx - i0, fy = sy - j0;\n const ia = Math.min(width - 1, Math.max(0, i0)), ib = Math.min(width - 1, Math.max(0, i0 + 1));\n const ja = Math.min(height - 1, Math.max(0, j0)) * width, jb = Math.min(height - 1, Math.max(0, j0 + 1)) * width;\n return (1 - fy) * ((1 - fx) * at(ja + ia) + fx * at(ja + ib)) + fy * ((1 - fx) * at(jb + ia) + fx * at(jb + ib));\n }\n const sampleAt = (cu: number, cv: number, nodeValues: Float64Array, neutral: number): number => interpolate(cu, cv, (index) => pixelValue(index, nodeValues, neutral));\n // Per wavelength the node reflectances (the facade asks for a few spectral nodes many times), and (#597) each pixel's reflectance\n // there, kept by pixel row as the queries reach it: a spectrum cache (no channel value), the same value `pixelValue` gives.\n const atWavelength = new Map<number, (index: number) => number>(), spectrumRows = new Map<number, Float64Array>();\n const keptSpectrumRows = Math.max(8, Math.floor(SIGNAL_ROW_CACHE_BYTES / (width * 8)));\n function reflectanceAt(cu: number, cv: number, nm: number): number {\n let reader = atWavelength.get(nm);\n if (!reader) {\n const nodes = nodeReflectancesAt(nm), slot = atWavelength.size * height;\n const kept = atWavelength.size < 4096;\n // The two latest rows of this wavelength are held apart (a bilinear point reads two rows).\n let keyA = -1, rowA: Float64Array = new Float64Array(0), keyB = -1, rowB = rowA;\n reader = !kept ? (index: number): number => pixelValue(index, nodes, 1) : (index: number): number => {\n const j = Math.floor(index / width), key = slot + j, i = index - j * width;\n let row: Float64Array;\n if (key === keyA) row = rowA;\n else if (key === keyB) row = rowB;\n else {\n let found = spectrumRows.get(key);\n if (!found) { found = new Float64Array(width).fill(NaN); spectrumRows.set(key, found); if (spectrumRows.size > keptSpectrumRows) spectrumRows.delete(spectrumRows.keys().next().value!); }\n keyB = keyA; rowB = rowA; keyA = key; rowA = row = found;\n }\n const value = row[i]!;\n return value === value ? value : (row[i] = pixelValue(index, nodes, 1));\n };\n if (kept) atWavelength.set(nm, reader);\n }\n return interpolate(cu, cv, reader);\n }\n /**\n * One pixel's channel signals, integrated from its reconstructed spectrum (owner decision 2026-11-09): per spectral node n its\n * reflectance ρ_n (its cell's eight node spectra at λ_n blended with the trilinear weights, then the paper) times the white\n * radiance W_n, then per channel Σ_n A_c(λ_n)·ρ_n·W_n. Written to out[at..at + 2].\n */\n function pixelSignals(index: number, nodes: ImagePlaneSpectralNodes, out: Float64Array, at: number): void {\n const N = nodes.count, R = nodes.nodeSpectra, W = nodes.whiteRadiance, A0 = nodes.response[0]!, A1 = nodes.response[1]!, A2 = nodes.response[2]!;\n const base = pixelLattice(index, fractions) * N, fr = fractions[0]!, fg = fractions[1]!, fb = fractions[2]!, gb = 1 - fb;\n const a00 = (1 - fr) * (1 - fg), a01 = (1 - fr) * fg, a10 = fr * (1 - fg), a11 = fr * fg;\n const w0 = a00 * gb, w1 = a00 * fb, w5 = a01 * gb, w6 = a01 * fb, w25 = a10 * gb, w26 = a10 * fb, w30 = a11 * gb, w31 = a11 * fb;\n let s0 = 0, s1 = 0, s2 = 0;\n for (let n = 0, k = base; n < N; n++, k++) {\n const lattice = w0 * R[k]! + w1 * R[k + N]! + w5 * R[k + 5 * N]! + w6 * R[k + 6 * N]! + w25 * R[k + 25 * N]! + w26 * R[k + 26 * N]! + w30 * R[k + 30 * N]! + w31 * R[k + 31 * N]!;\n // Each channel's sum in node order (one pass over the spectrum).\n const radiance = (black + span * lattice) * W[n]!;\n s0 += A0[n]! * radiance; s1 += A1[n]! * radiance; s2 += A2[n]! * radiance;\n }\n out[at] = s0; out[at + 1] = s1; out[at + 2] = s2;\n }\n function signalScene(wavelengths: readonly number[], perNode: readonly Float64Array[], whiteRadiance: Float64Array, radianceAt: (u: number, v: number, nm: number) => number,\n scale: number, half: number, surroundReflectance: number, light?: ResolvedMixedIllumination | null): ImagePlaneSignalScene | ImagePlaneLitScene {\n // The lattice's spectra at the nodes (node k's reflectance at λ_n at k·N + n); no channel response is folded in.\n const N = wavelengths.length, spectraAt = wavelengths.map((nm) => nodeReflectancesAt(nm)), nodeSpectra = new Float64Array(NODES * N);\n for (let k = 0; k < NODES; k++) for (let n = 0; n < N; n++) nodeSpectra[k * N + n] = spectraAt[n]![k]!;\n const nodes: ImagePlaneSpectralNodes = { count: N, nodeSpectra, whiteRadiance, response: perNode };\n // The surround's channel signals, integrated from its spectrum ρ·W_n like a pixel's (no white-integral shortcut, 2.21.0).\n const surround = [0, 1, 2].map((c) => { let s = 0; for (let n = 0; n < N; n++) s += perNode[c]![n]! * (surroundReflectance * whiteRadiance[n]!); return s; }) as [number, number, number];\n // #597: under mixed light, the lit radiance alone (each site integrates it at use) and the print with the light's parts for the GPU pass.\n if (light !== undefined) return { kind: \"radiance\", radianceAt, image: { scene: resolved, nodes, surround, whiteRadiance, surroundReflectance, light: { layout: light, halfWidthM: half } } };\n // The pixels' signals as the query points reach them: rows of three values per pixel (NaN until computed), the latest rows kept.\n const rows = new Map<number, Float64Array>(), keptRows = Math.max(8, Math.floor(SIGNAL_ROW_CACHE_BYTES / (width * 24)));\n let lastJ = -1, lastRow: Float64Array = new Float64Array(0);\n const rowAt = (j: number): Float64Array => {\n if (j === lastJ) return lastRow;\n let row = rows.get(j);\n if (!row) { row = new Float64Array(width * 3).fill(NaN); rows.set(j, row); if (rows.size > keptRows) rows.delete(rows.keys().next().value!); }\n lastJ = j; lastRow = row;\n return row;\n };\n const signalOf = (row: Float64Array, j: number, i: number, c: number): number => {\n if (row[i * 3] !== row[i * 3]) pixelSignals(j * width + i, nodes, row, i * 3);\n return row[i * 3 + c]!;\n };\n return { kind: \"radiance\", radianceAt, signalAt(u: number, v: number, c: number): number {\n const cu = u * scale / half, cv = v * scale / half;\n if (!(Math.abs(cu) <= 1 && Math.abs(cv) <= aspect)) return surround[c]!;\n // As `interpolate`, reading the pixels' signals.\n const X = (cu + 1) * halfW, Y = (aspect - cv) * halfH;\n if (interpolation === \"nearest\") { const j = Math.min(height - 1, Math.max(0, Math.floor(Y))); return signalOf(rowAt(j), j, Math.min(width - 1, Math.max(0, Math.floor(X))), c); }\n const sx = X - 0.5, sy = Y - 0.5, i0 = Math.floor(sx), j0 = Math.floor(sy), fx = sx - i0, fy = sy - j0;\n const ia = Math.min(width - 1, Math.max(0, i0)), ib = Math.min(width - 1, Math.max(0, i0 + 1)), ja = Math.min(height - 1, Math.max(0, j0)), jb = Math.min(height - 1, Math.max(0, j0 + 1));\n const rowA = rowAt(ja), a0 = signalOf(rowA, ja, ia, c), a1 = signalOf(rowA, ja, ib, c), rowB = rowAt(jb);\n return (1 - fy) * ((1 - fx) * a0 + fx * a1) + fy * ((1 - fx) * signalOf(rowB, jb, ia, c) + fx * signalOf(rowB, jb, ib, c));\n }, image: { scene: resolved, nodes, surround, whiteRadiance, surroundReflectance } };\n }\n const resolved: ResolvedImagePlaneScene = Object.freeze({ kind: \"image-plane\" as const, sceneId: record.sceneId, width, height, aspect, channels, encoding: encoding as ResolvedImagePlaneScene[\"encoding\"],\n interpolation, paperWhiteReflectance: white, paperBlackReflectance: black, maximumPixels, clippedSampleCount: clipped, dataSha256,\n reflectanceAt, sampleAt, pixelValue, pixelSignals, pixelLattice, nodeReflectances: nodeReflectancesAt, signalScene: signalScene as ResolvedImagePlaneScene[\"signalScene\"], get digestForm() { return imagePlaneDigestForm(resolved); }, parameters: Object.freeze({ width, height, channels, encoding, interpolation, paperWhiteReflectance: white, paperBlackReflectance: black,\n clippedSampleCount: clipped, imageSha256: dataSha256 }) });\n if (assume) for (const [id, kind, v, explanation] of imagePlaneAssumptions(resolved, record)) assume(id, kind, v, explanation);\n return resolved;\n}\n\n/** The scene's form in the facade's source digest: the image's SHA-256 and shape, the paper, the interpolation and the lattice version. */\nexport function imagePlaneDigestForm(scene: ResolvedImagePlaneScene): Record<string, unknown> {\n return { kind: scene.kind, sceneId: scene.sceneId, image: { width: scene.width, height: scene.height, channels: scene.channels, encoding: scene.encoding, sha256: scene.dataSha256 },\n paper: { whiteReflectance: scene.paperWhiteReflectance, blackReflectance: scene.paperBlackReflectance }, interpolation: scene.interpolation, latticeVersion: IMAGE_PLANE_LATTICE_VERSION };\n}\n\n/** The assumptions an image-plane capture records: the model, the defaults taken, and the clipped linear samples. */\nexport function imagePlaneAssumptions(scene: ResolvedImagePlaneScene, record: Record<string, unknown>): [string, \"default\" | \"model\" | \"derived\", unknown, string][] {\n const out: [string, \"default\" | \"model\" | \"derived\", unknown, string][] = [];\n const paper = (record.paper ?? {}) as Record<string, unknown>;\n if (paper.whiteReflectance === undefined) out.push([\"scene.paper.whiteReflectance\", \"default\", scene.paperWhiteReflectance,\n \"Photivra's assumption, not a measurement: the paper reflects 90 % (the white of the engine's Studio Gray 1 patch), so sRGB white prints as a 0.90 flat reflectance.\"]);\n if (paper.blackReflectance === undefined) out.push([\"scene.paper.blackReflectance\", \"default\", scene.paperBlackReflectance,\n \"Photivra's assumption, not a measurement: the deepest ink reflects 1 % (an optical density of 2.0), so sRGB black prints as a 0.01 flat reflectance.\"]);\n if (record.interpolation === undefined) out.push([\"scene.interpolation\", \"default\", scene.interpolation,\n \"Bilinear between pixel centers: the four nearest pixels' reflectance spectra, bilinearly weighted (under CIE D65, the bilinear interpolation of their linear sRGB); the edge pixels extend to the print's edges.\"]);\n out.push([\"scene.imagePlane\", \"model\", { latticeVersion: IMAGE_PLANE_LATTICE_VERSION, nodesPerAxis: AXIS, method: \"lhtss-burns-2020\", wavelengthStepNanometers: STEP_NM,\n width: scene.width, height: scene.height, encoding: scene.encoding, channels: scene.channels },\n \"An approximation: a print of the image, which was already processed, clipped and blurred by the camera that took it. Each pixel is decoded to linear sRGB \" +\n (scene.encoding === \"linear-srgb\" ? \"(given linear, clipped to [0, 1])\" : \"with the sRGB transfer function (IEC 61966-2-1)\") + (scene.channels === 4 ? \", composited over the paper by its alpha,\" : \"\") +\n \" and becomes a reflectance spectrum by trilinear interpolation in a 5 × 5 × 5 lattice of smooth spectra (Burns' LHTSS method, arXiv:1710.05732 v5, fitted by Photivra against CIE D65 and the \" +\n \"CIE 1931 2° observer), which reproduces the pixel's sRGB under D65 within CIEDE2000 6.4e-4 and stays in [0, 1]; then ρ = black + (white − black)·ρ. Under other lights its colors are one plausible \" +\n \"metamer of many (docs/IMAGE_PLANE.md, measured spread). A flat matte Lambertian print: no gloss, paper texture, halftone, curl or fluorescence.\"]);\n out.push([\"scene.digest\", \"model\", \"image-data-hashed\", \"The source digest covers the image's SHA-256, size, channels and encoding, the paper, the interpolation, the lattice version and the framing.\"]);\n if (scene.clippedSampleCount > 0) out.push([\"scene.image.clippedSamples\", \"derived\", scene.clippedSampleCount,\n \"Linear samples outside [0, 1] clipped to the print's range (a print cannot be brighter than its paper or darker than its deepest ink).\"]);\n return out;\n}\n\n/** The GPU display view's image-plane module, loaded on demand by the GPU renderer (its own chunk). */\nexport function loadGpuModule(): Promise<typeof import(\"../gpu/display-view-image-material-module.js\")> {\n return import(\"../gpu/display-view-image-material-module.js\");\n}\n\n/**\n * The print's placement: `chartSize` with its height defaulting to the image's aspect, or, without it, the print fitted inside\n * the frame (centered, filling its width or height) on the default surround; records the defaults it takes.\n */\nexport function imagePlanePrint(scene: unknown, chartSize: unknown, framedWidthM: number, frameAspect: number,\n assume: (id: string, kind: \"default\", value: unknown, explanation: string) => void): ReturnType<typeof resolveChartSizeOption> {\n const size = readImagePlaneSize(scene), imageAspect = size.height / size.width;\n if (chartSize !== undefined) {\n const resolved = resolveChartSizeOption(chartSize, imageAspect);\n if (resolved.defaulted.includes(\"heightM\")) assume(\"chartSize.heightM\", \"default\", resolved.heightM, \"The print has the image's shape: height = width × image height / image width.\");\n return { ...resolved, defaulted: resolved.defaulted.filter((key) => key !== \"heightM\") };\n }\n const widthM = imageAspect > frameAspect ? framedWidthM * frameAspect / imageAspect : framedWidthM;\n const fitted = { widthM, heightM: widthM * imageAspect, surroundReflectance: CHART_SIZE_DEFAULT_SURROUND_REFLECTANCE, defaulted: [] as (\"heightM\" | \"surroundReflectance\")[] };\n assume(\"chartSize\", \"default\", { widthM: fitted.widthM, heightM: fitted.heightM, surroundReflectance: fitted.surroundReflectance },\n \"The print has the image's shape and is fitted inside the frame, centered (it fills the frame's width or height), on an 18 % neutral gray surround.\");\n return fitted;\n}\n"]}
@@ -0,0 +1,14 @@
1
+ export type QualityKit = typeof import("./quality-kit.js");
2
+ export type OptInKit = typeof import("./opt-in-kit.js");
3
+ /** One kit's loader: `load()` imports it once (single flight, retried after a failure); `loaded` is the module once imported. */
4
+ interface KitLoader<T> {
5
+ loaded: T | undefined;
6
+ load(): Promise<T>;
7
+ }
8
+ /** The CPU full-quality code (#594). */
9
+ export declare const qualityKit: KitLoader<QualityKit>;
10
+ /** The opt-in features' code (#594). */
11
+ export declare const optInKit: KitLoader<OptInKit>;
12
+ /** A kit the request loaded where it was parsed (an engine error if a code path uses it without loading it first). */
13
+ export declare function loadedKit<T>(kit: KitLoader<T>): T;
14
+ export {};
@@ -0,0 +1,36 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ /**
3
+ * 2.22.0 (#594): loads the CPU on-demand code, once per realm: the Quality kit (src/facade/quality-kit.ts) and the opt-in kit
4
+ * (src/facade/opt-in-kit.ts). A request loads a kit where it is parsed, before it uses any of its code, and then calls it
5
+ * synchronously, so results are those of a static import. Concurrent loads share one import; a failed load is not remembered,
6
+ * so the next request (or `prepareQualityPaths()`) tries again. A failed load rejects with `ImageKernelExecutionError` reason
7
+ * `quality-code-unavailable`, as the GPU Quality code's does; the CPU has no other path, so the request fails with it.
8
+ */
9
+ import { ImageKernelExecutionError } from "../core/execution-error.js";
10
+ function kitLoader(name, importer) {
11
+ let pending = null;
12
+ const kit = {
13
+ loaded: undefined,
14
+ load() {
15
+ if (kit.loaded)
16
+ return Promise.resolve(kit.loaded);
17
+ pending ??= importer().then((module) => (kit.loaded = module), (error) => {
18
+ pending = null;
19
+ throw new ImageKernelExecutionError("quality-code-unavailable", "the engine's " + name + " code could not be loaded: " + (error instanceof Error ? error.message : String(error)));
20
+ });
21
+ return pending;
22
+ }
23
+ };
24
+ return kit;
25
+ }
26
+ /** The CPU full-quality code (#594). */
27
+ export const qualityKit = kitLoader("full-quality", () => import("./quality-kit.js"));
28
+ /** The opt-in features' code (#594). */
29
+ export const optInKit = kitLoader("opt-in feature", () => import("./opt-in-kit.js"));
30
+ /** A kit the request loaded where it was parsed (an engine error if a code path uses it without loading it first). */
31
+ export function loadedKit(kit) {
32
+ if (!kit.loaded)
33
+ throw new ImageKernelExecutionError("quality-code-unavailable", "on-demand code was used before it was loaded (an engine defect; #594).");
34
+ return kit.loaded;
35
+ }
36
+ //# sourceMappingURL=on-demand-kits.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"on-demand-kits.js","sourceRoot":"","sources":["../../src/facade/on-demand-kits.ts"],"names":[],"mappings":"AAAA,sCAAsC;AAEtC;;;;;;GAMG;AAEH,OAAO,EAAE,yBAAyB,EAAE,MAAM,4BAA4B,CAAC;AAOvE,SAAS,SAAS,CAAI,IAAY,EAAE,QAA0B;IAC5D,IAAI,OAAO,GAAsB,IAAI,CAAC;IACtC,MAAM,GAAG,GAAiB;QACxB,MAAM,EAAE,SAAS;QACjB,IAAI;YACF,IAAI,GAAG,CAAC,MAAM;gBAAE,OAAO,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YACnD,OAAO,KAAK,QAAQ,EAAE,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,CAAC,KAAc,EAAE,EAAE;gBAChF,OAAO,GAAG,IAAI,CAAC;gBACf,MAAM,IAAI,yBAAyB,CAAC,0BAA0B,EAAE,eAAe,GAAG,IAAI,GAAG,6BAA6B,GAAG,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YACrL,CAAC,CAAC,CAAC;YACH,OAAO,OAAO,CAAC;QACjB,CAAC;KACF,CAAC;IACF,OAAO,GAAG,CAAC;AACb,CAAC;AAED,wCAAwC;AACxC,MAAM,CAAC,MAAM,UAAU,GAA0B,SAAS,CAAC,cAAc,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC,CAAC;AAC7G,wCAAwC;AACxC,MAAM,CAAC,MAAM,QAAQ,GAAwB,SAAS,CAAC,gBAAgB,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC,CAAC;AAE1G,sHAAsH;AACtH,MAAM,UAAU,SAAS,CAAI,GAAiB;IAC5C,IAAI,CAAC,GAAG,CAAC,MAAM;QAAE,MAAM,IAAI,yBAAyB,CAAC,0BAA0B,EAAE,wEAAwE,CAAC,CAAC;IAC3J,OAAO,GAAG,CAAC,MAAM,CAAC;AACpB,CAAC","sourcesContent":["// SPDX-License-Identifier: Apache-2.0\n\n/**\n * 2.22.0 (#594): loads the CPU on-demand code, once per realm: the Quality kit (src/facade/quality-kit.ts) and the opt-in kit\n * (src/facade/opt-in-kit.ts). A request loads a kit where it is parsed, before it uses any of its code, and then calls it\n * synchronously, so results are those of a static import. Concurrent loads share one import; a failed load is not remembered,\n * so the next request (or `prepareQualityPaths()`) tries again. A failed load rejects with `ImageKernelExecutionError` reason\n * `quality-code-unavailable`, as the GPU Quality code's does; the CPU has no other path, so the request fails with it.\n */\n\nimport { ImageKernelExecutionError } from \"../core/execution-error.js\";\n\nexport type QualityKit = typeof import(\"./quality-kit.js\");\nexport type OptInKit = typeof import(\"./opt-in-kit.js\");\n\n/** One kit's loader: `load()` imports it once (single flight, retried after a failure); `loaded` is the module once imported. */\ninterface KitLoader<T> { loaded: T | undefined; load(): Promise<T> }\nfunction kitLoader<T>(name: string, importer: () => Promise<T>): KitLoader<T> {\n let pending: Promise<T> | null = null;\n const kit: KitLoader<T> = {\n loaded: undefined,\n load(): Promise<T> {\n if (kit.loaded) return Promise.resolve(kit.loaded);\n pending ??= importer().then((module) => (kit.loaded = module), (error: unknown) => {\n pending = null;\n throw new ImageKernelExecutionError(\"quality-code-unavailable\", \"the engine's \" + name + \" code could not be loaded: \" + (error instanceof Error ? error.message : String(error)));\n });\n return pending;\n }\n };\n return kit;\n}\n\n/** The CPU full-quality code (#594). */\nexport const qualityKit: KitLoader<QualityKit> = kitLoader(\"full-quality\", () => import(\"./quality-kit.js\"));\n/** The opt-in features' code (#594). */\nexport const optInKit: KitLoader<OptInKit> = kitLoader(\"opt-in feature\", () => import(\"./opt-in-kit.js\"));\n\n/** A kit the request loaded where it was parsed (an engine error if a code path uses it without loading it first). */\nexport function loadedKit<T>(kit: KitLoader<T>): T {\n if (!kit.loaded) throw new ImageKernelExecutionError(\"quality-code-unavailable\", \"on-demand code was used before it was loaded (an engine defect; #594).\");\n return kit.loaded;\n}\n"]}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * 2.22.0 (#594): the opt-in features' code, one module that the capture loads on demand (`loadOptInKit`, src/facade/on-demand-kits.ts)
3
+ * when a request uses one of them, so a bundler that splits dynamic imports keeps it off the default path. Only re-exports:
4
+ * `sensor.profile` (#554: the profile parser and body builder; the catalogue itself is never imported), `illumination` (#550, with
5
+ * #597's lighting over a print) and `motion.subject` (#551).
6
+ */
7
+ export { parseSensorProfile, sensorProfileBody, sensorProfileSaturationIso } from "../equipment/sensor-profile-body.js";
8
+ export { resolveMixedIllumination } from "./mixed-illumination.js";
9
+ export { createSubjectMotionProvider, subjectTravelM } from "../motion/subject-motion.js";
@@ -0,0 +1,11 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ /**
3
+ * 2.22.0 (#594): the opt-in features' code, one module that the capture loads on demand (`loadOptInKit`, src/facade/on-demand-kits.ts)
4
+ * when a request uses one of them, so a bundler that splits dynamic imports keeps it off the default path. Only re-exports:
5
+ * `sensor.profile` (#554: the profile parser and body builder; the catalogue itself is never imported), `illumination` (#550, with
6
+ * #597's lighting over a print) and `motion.subject` (#551).
7
+ */
8
+ export { parseSensorProfile, sensorProfileBody, sensorProfileSaturationIso } from "../equipment/sensor-profile-body.js";
9
+ export { resolveMixedIllumination } from "./mixed-illumination.js";
10
+ export { createSubjectMotionProvider, subjectTravelM } from "../motion/subject-motion.js";
11
+ //# sourceMappingURL=opt-in-kit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"opt-in-kit.js","sourceRoot":"","sources":["../../src/facade/opt-in-kit.ts"],"names":[],"mappings":"AAAA,sCAAsC;AAEtC;;;;;GAKG;AAEH,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,0BAA0B,EAAE,MAAM,qCAAqC,CAAC;AACxH,OAAO,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AACnE,OAAO,EAAE,2BAA2B,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC","sourcesContent":["// SPDX-License-Identifier: Apache-2.0\n\n/**\n * 2.22.0 (#594): the opt-in features' code, one module that the capture loads on demand (`loadOptInKit`, src/facade/on-demand-kits.ts)\n * when a request uses one of them, so a bundler that splits dynamic imports keeps it off the default path. Only re-exports:\n * `sensor.profile` (#554: the profile parser and body builder; the catalogue itself is never imported), `illumination` (#550, with\n * #597's lighting over a print) and `motion.subject` (#551).\n */\n\nexport { parseSensorProfile, sensorProfileBody, sensorProfileSaturationIso } from \"../equipment/sensor-profile-body.js\";\nexport { resolveMixedIllumination } from \"./mixed-illumination.js\";\nexport { createSubjectMotionProvider, subjectTravelM } from \"../motion/subject-motion.js\";\n"]}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * 2.22.0 (#594): the CPU full-quality code, one module that the capture and the display view load on demand (`loadQualityKit`,
3
+ * src/facade/on-demand-kits.ts) where they parse a request that asks for it, so a bundler that splits dynamic imports puts all of
4
+ * it in one chunk outside the default path. Only re-exports: the code, its results and its bounds are those of the modules named.
5
+ *
6
+ * - Diffraction (2.1): the Airy profile, its site kernels and their convolution.
7
+ * - The capture's AHD demosaic (`output.demosaic: "ahd"`).
8
+ * - `lens.defocus` beyond the geometric disc (owner, 2026-11-10): the bokeh shapes, the cat's eye and their field zones, the
9
+ * lattice of a disc above the direct radius (#564) and the image-space provider (lens projection and distortion).
10
+ * - The display view's coupled rendering steps (#593, #601: luminance tone curves, reconstruct, desaturation) and the neighbor
11
+ * highlight reconstruction (#602).
12
+ */
13
+ export { createDiffractionLimitedPsfProfile } from "../optics/diffraction-psf-profile.js";
14
+ export { registerDiffractionPsfKey, siteDiffractionKernel } from "../optics/site-diffraction-kernel.js";
15
+ export { createAhdDemosaicTask } from "../processing/demosaic.js";
16
+ export { createDefocusBokehSiteKernel, resolveDefocusBokehOptions } from "../optics/defocus-bokeh-kernel.js";
17
+ export { planDefocusBokehZones } from "./defocus-bokeh-zones.js";
18
+ export { LARGE_DEFOCUS_CACHE_BYTES, createLargeDefocusNodeLattice } from "./large-defocus-lattice.js";
19
+ export { calculateDefocusFieldVariation, createDefocusImageSpaceProvider, prepareDefocusImageSpaceGeometry } from "./defocus-image-space-provider.js";
20
+ export { createDisplayViewCoupledRendering } from "./display-view-rendering.js";
21
+ export * as neighborHighlights from "../color/neighbor-highlight-reconstruction.js";
@@ -0,0 +1,23 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ /**
3
+ * 2.22.0 (#594): the CPU full-quality code, one module that the capture and the display view load on demand (`loadQualityKit`,
4
+ * src/facade/on-demand-kits.ts) where they parse a request that asks for it, so a bundler that splits dynamic imports puts all of
5
+ * it in one chunk outside the default path. Only re-exports: the code, its results and its bounds are those of the modules named.
6
+ *
7
+ * - Diffraction (2.1): the Airy profile, its site kernels and their convolution.
8
+ * - The capture's AHD demosaic (`output.demosaic: "ahd"`).
9
+ * - `lens.defocus` beyond the geometric disc (owner, 2026-11-10): the bokeh shapes, the cat's eye and their field zones, the
10
+ * lattice of a disc above the direct radius (#564) and the image-space provider (lens projection and distortion).
11
+ * - The display view's coupled rendering steps (#593, #601: luminance tone curves, reconstruct, desaturation) and the neighbor
12
+ * highlight reconstruction (#602).
13
+ */
14
+ export { createDiffractionLimitedPsfProfile } from "../optics/diffraction-psf-profile.js";
15
+ export { registerDiffractionPsfKey, siteDiffractionKernel } from "../optics/site-diffraction-kernel.js";
16
+ export { createAhdDemosaicTask } from "../processing/demosaic.js";
17
+ export { createDefocusBokehSiteKernel, resolveDefocusBokehOptions } from "../optics/defocus-bokeh-kernel.js";
18
+ export { planDefocusBokehZones } from "./defocus-bokeh-zones.js";
19
+ export { LARGE_DEFOCUS_CACHE_BYTES, createLargeDefocusNodeLattice } from "./large-defocus-lattice.js";
20
+ export { calculateDefocusFieldVariation, createDefocusImageSpaceProvider, prepareDefocusImageSpaceGeometry } from "./defocus-image-space-provider.js";
21
+ export { createDisplayViewCoupledRendering } from "./display-view-rendering.js";
22
+ export * as neighborHighlights from "../color/neighbor-highlight-reconstruction.js";
23
+ //# sourceMappingURL=quality-kit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"quality-kit.js","sourceRoot":"","sources":["../../src/facade/quality-kit.ts"],"names":[],"mappings":"AAAA,sCAAsC;AAEtC;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,kCAAkC,EAAE,MAAM,sCAAsC,CAAC;AAC1F,OAAO,EAAE,yBAAyB,EAAE,qBAAqB,EAAE,MAAM,sCAAsC,CAAC;AACxG,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,EAAE,4BAA4B,EAAE,0BAA0B,EAAE,MAAM,mCAAmC,CAAC;AAC7G,OAAO,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AACjE,OAAO,EAAE,yBAAyB,EAAE,6BAA6B,EAAE,MAAM,4BAA4B,CAAC;AACtG,OAAO,EAAE,8BAA8B,EAAE,+BAA+B,EAAE,gCAAgC,EAAE,MAAM,mCAAmC,CAAC;AACtJ,OAAO,EAAE,iCAAiC,EAAE,MAAM,6BAA6B,CAAC;AAChF,OAAO,KAAK,kBAAkB,MAAM,+CAA+C,CAAC","sourcesContent":["// SPDX-License-Identifier: Apache-2.0\n\n/**\n * 2.22.0 (#594): the CPU full-quality code, one module that the capture and the display view load on demand (`loadQualityKit`,\n * src/facade/on-demand-kits.ts) where they parse a request that asks for it, so a bundler that splits dynamic imports puts all of\n * it in one chunk outside the default path. Only re-exports: the code, its results and its bounds are those of the modules named.\n *\n * - Diffraction (2.1): the Airy profile, its site kernels and their convolution.\n * - The capture's AHD demosaic (`output.demosaic: \"ahd\"`).\n * - `lens.defocus` beyond the geometric disc (owner, 2026-11-10): the bokeh shapes, the cat's eye and their field zones, the\n * lattice of a disc above the direct radius (#564) and the image-space provider (lens projection and distortion).\n * - The display view's coupled rendering steps (#593, #601: luminance tone curves, reconstruct, desaturation) and the neighbor\n * highlight reconstruction (#602).\n */\n\nexport { createDiffractionLimitedPsfProfile } from \"../optics/diffraction-psf-profile.js\";\nexport { registerDiffractionPsfKey, siteDiffractionKernel } from \"../optics/site-diffraction-kernel.js\";\nexport { createAhdDemosaicTask } from \"../processing/demosaic.js\";\nexport { createDefocusBokehSiteKernel, resolveDefocusBokehOptions } from \"../optics/defocus-bokeh-kernel.js\";\nexport { planDefocusBokehZones } from \"./defocus-bokeh-zones.js\";\nexport { LARGE_DEFOCUS_CACHE_BYTES, createLargeDefocusNodeLattice } from \"./large-defocus-lattice.js\";\nexport { calculateDefocusFieldVariation, createDefocusImageSpaceProvider, prepareDefocusImageSpaceGeometry } from \"./defocus-image-space-provider.js\";\nexport { createDisplayViewCoupledRendering } from \"./display-view-rendering.js\";\nexport * as neighborHighlights from \"../color/neighbor-highlight-reconstruction.js\";\n"]}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Loads the engine's on-demand full-quality code now instead of at the first request that needs it (#594): the CPU Quality kit
3
+ * (diffraction, the capture's AHD demosaic, `lens.defocus` beyond the geometric disc, the image-space provider of lens projection,
4
+ * distortion and vignetting, the display view's coupled tone, reconstruct and desaturation steps, the neighbor highlight
5
+ * reconstruction), the opt-in kit (`sensor.profile`, `illumination`, `motion.subject`) and the display view's GPU full-quality code
6
+ * (the Quality passes behind `prepareDisplayView(…, { gpu: "auto" | "require" })`), together with the GPU session it builds on.
7
+ *
8
+ * Optional: without it, the first request that needs the code loads it. Safe to call at any time and from any number of places:
9
+ * concurrent calls share one load, and a call after it loaded resolves at once and loads nothing. It changes no result. If the
10
+ * load fails (for example a chunk download error) the promise rejects with `ImageKernelExecutionError` reason
11
+ * `quality-code-unavailable`; nothing is remembered, so a later call or request tries again, and a render in the meantime runs
12
+ * the CPU reference, labelled with that reason. A bundler that splits dynamic imports keeps this code out of the first load
13
+ * whether or not this function is imported.
14
+ *
15
+ * @example
16
+ * ```ts
17
+ * import { prepareQualityPaths } from "@photivra/engine";
18
+ * // The user opened Export, where full-quality renders follow: fetch their code while they choose a format.
19
+ * void prepareQualityPaths().catch(() => undefined); // a failed preload is retried by the render that needs the code
20
+ * ```
21
+ */
22
+ export declare function prepareQualityPaths(): Promise<void>;
@@ -0,0 +1,44 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ /**
3
+ * 2.22.0 (#594): the optional preload of the engine's on-demand full-quality code. The Quality paths load automatically at the
4
+ * first request that needs them; this loads them ahead of time, so that request does not wait for the download.
5
+ */
6
+ import { ImageKernelExecutionError } from "../gpu/image-kernel-execution.js";
7
+ import { optInKit, qualityKit } from "./on-demand-kits.js";
8
+ let pending = null;
9
+ /**
10
+ * Loads the engine's on-demand full-quality code now instead of at the first request that needs it (#594): the CPU Quality kit
11
+ * (diffraction, the capture's AHD demosaic, `lens.defocus` beyond the geometric disc, the image-space provider of lens projection,
12
+ * distortion and vignetting, the display view's coupled tone, reconstruct and desaturation steps, the neighbor highlight
13
+ * reconstruction), the opt-in kit (`sensor.profile`, `illumination`, `motion.subject`) and the display view's GPU full-quality code
14
+ * (the Quality passes behind `prepareDisplayView(…, { gpu: "auto" | "require" })`), together with the GPU session it builds on.
15
+ *
16
+ * Optional: without it, the first request that needs the code loads it. Safe to call at any time and from any number of places:
17
+ * concurrent calls share one load, and a call after it loaded resolves at once and loads nothing. It changes no result. If the
18
+ * load fails (for example a chunk download error) the promise rejects with `ImageKernelExecutionError` reason
19
+ * `quality-code-unavailable`; nothing is remembered, so a later call or request tries again, and a render in the meantime runs
20
+ * the CPU reference, labelled with that reason. A bundler that splits dynamic imports keeps this code out of the first load
21
+ * whether or not this function is imported.
22
+ *
23
+ * @example
24
+ * ```ts
25
+ * import { prepareQualityPaths } from "@photivra/engine";
26
+ * // The user opened Export, where full-quality renders follow: fetch their code while they choose a format.
27
+ * void prepareQualityPaths().catch(() => undefined); // a failed preload is retried by the render that needs the code
28
+ * ```
29
+ */
30
+ export function prepareQualityPaths() {
31
+ if (!pending) {
32
+ const load = Promise.all([qualityKit.load(), optInKit.load(),
33
+ import("../gpu/display-view-gpu-renderer.js").then((renderer) => renderer.prepareDisplayViewQualityGpu())]).then(() => undefined, (error) => {
34
+ if (error instanceof ImageKernelExecutionError)
35
+ throw error;
36
+ throw new ImageKernelExecutionError("quality-code-unavailable", "the engine's full-quality code could not be loaded: " + (error instanceof Error ? error.message : String(error)));
37
+ });
38
+ pending = load;
39
+ load.catch(() => { if (pending === load)
40
+ pending = null; });
41
+ }
42
+ return pending;
43
+ }
44
+ //# sourceMappingURL=quality-paths.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"quality-paths.js","sourceRoot":"","sources":["../../src/facade/quality-paths.ts"],"names":[],"mappings":"AAAA,sCAAsC;AAEtC;;;GAGG;AAEH,OAAO,EAAE,yBAAyB,EAAE,MAAM,kCAAkC,CAAC;AAC7E,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAE3D,IAAI,OAAO,GAAyB,IAAI,CAAC;AAEzC;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,UAAU,mBAAmB;IACjC,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,GAAkB,OAAO,CAAC,GAAG,CAAC,CAAC,UAAU,CAAC,IAAI,EAAE,EAAE,QAAQ,CAAC,IAAI,EAAE;YACzE,MAAM,CAAC,qCAAqC,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,4BAA4B,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,SAAS,EAAE,CAAC,KAAc,EAAE,EAAE;YACrJ,IAAI,KAAK,YAAY,yBAAyB;gBAAE,MAAM,KAAK,CAAC;YAC5D,MAAM,IAAI,yBAAyB,CAAC,0BAA0B,EAAE,sDAAsD,GAAG,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QACrL,CAAC,CAAC,CAAC;QACH,OAAO,GAAG,IAAI,CAAC;QACf,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,IAAI,OAAO,KAAK,IAAI;YAAE,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IAC9D,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC","sourcesContent":["// SPDX-License-Identifier: Apache-2.0\n\n/**\n * 2.22.0 (#594): the optional preload of the engine's on-demand full-quality code. The Quality paths load automatically at the\n * first request that needs them; this loads them ahead of time, so that request does not wait for the download.\n */\n\nimport { ImageKernelExecutionError } from \"../gpu/image-kernel-execution.js\";\nimport { optInKit, qualityKit } from \"./on-demand-kits.js\";\n\nlet pending: Promise<void> | null = null;\n\n/**\n * Loads the engine's on-demand full-quality code now instead of at the first request that needs it (#594): the CPU Quality kit\n * (diffraction, the capture's AHD demosaic, `lens.defocus` beyond the geometric disc, the image-space provider of lens projection,\n * distortion and vignetting, the display view's coupled tone, reconstruct and desaturation steps, the neighbor highlight\n * reconstruction), the opt-in kit (`sensor.profile`, `illumination`, `motion.subject`) and the display view's GPU full-quality code\n * (the Quality passes behind `prepareDisplayView(…, { gpu: \"auto\" | \"require\" })`), together with the GPU session it builds on.\n *\n * Optional: without it, the first request that needs the code loads it. Safe to call at any time and from any number of places:\n * concurrent calls share one load, and a call after it loaded resolves at once and loads nothing. It changes no result. If the\n * load fails (for example a chunk download error) the promise rejects with `ImageKernelExecutionError` reason\n * `quality-code-unavailable`; nothing is remembered, so a later call or request tries again, and a render in the meantime runs\n * the CPU reference, labelled with that reason. A bundler that splits dynamic imports keeps this code out of the first load\n * whether or not this function is imported.\n *\n * @example\n * ```ts\n * import { prepareQualityPaths } from \"@photivra/engine\";\n * // The user opened Export, where full-quality renders follow: fetch their code while they choose a format.\n * void prepareQualityPaths().catch(() => undefined); // a failed preload is retried by the render that needs the code\n * ```\n */\nexport function prepareQualityPaths(): Promise<void> {\n if (!pending) {\n const load: Promise<void> = Promise.all([qualityKit.load(), optInKit.load(),\n import(\"../gpu/display-view-gpu-renderer.js\").then((renderer) => renderer.prepareDisplayViewQualityGpu())]).then(() => undefined, (error: unknown) => {\n if (error instanceof ImageKernelExecutionError) throw error;\n throw new ImageKernelExecutionError(\"quality-code-unavailable\", \"the engine's full-quality code could not be loaded: \" + (error instanceof Error ? error.message : String(error)));\n });\n pending = load;\n load.catch(() => { if (pending === load) pending = null; });\n }\n return pending;\n}\n"]}
@@ -5,6 +5,7 @@ import type { EvidenceProvenance } from "../core/evidence-provenance.js";
5
5
  import type { SensorApertureRay } from "../optics/sensor-aperture-rays.js";
6
6
  import { type ChartReflectance, type ChartScene, type ResolvedChartScene } from "./chart-scenes.js";
7
7
  import { type ChartMaterialLayerScene } from "./chart-material-layers.js";
8
+ import type { ResolvedMixedIllumination } from "./mixed-illumination.js";
8
9
  /** CIE maximum luminous efficacy for photopic vision, lm/W. */
9
10
  export declare const PHOTOPIC_MAXIMUM_LUMINOUS_EFFICACY_LM_PER_W = 683;
10
11
  /** Wavelength range of every facade spectrum and of the facade sensor quadrature, nm. */
@@ -162,8 +163,19 @@ export interface ImagePlaneSignalScene {
162
163
  surround: readonly [number, number, number];
163
164
  whiteRadiance: Float64Array;
164
165
  surroundReflectance: number;
166
+ /** #597: under mixed light, its parts and the print's half width in metres (print-local cu = ±1 at ±halfWidthM); no `signalAt` then. */
167
+ light?: {
168
+ layout: ResolvedMixedIllumination | null;
169
+ halfWidthM: number;
170
+ };
165
171
  };
166
172
  }
173
+ /** #597: an image-plane print under mixed light: the lit radiance only (every site integrates it), and the print for the GPU pass. */
174
+ export interface ImagePlaneLitScene {
175
+ kind: "radiance";
176
+ radianceAt(u: number, v: number, nm: number): number;
177
+ image: ImagePlaneSignalScene["image"];
178
+ }
167
179
  /**
168
180
  * Internal (#581): a validated image-plane scene (src/facade/image-plane.ts, a lazily loaded module), placed on a print of
169
181
  * aspect `aspect` (height / width). Print-local coordinates are the chart's: cu = ±1 at the print's left and right edges, cv up
@@ -202,9 +214,11 @@ export interface ResolvedImagePlaneScene {
202
214
  nodeReflectances(nm: number): Float64Array;
203
215
  /**
204
216
  * The print placed on the plane (frame point → print-local cu = u·scale/half, cv = v·scale/half; outside |cu| ≤ 1, |cv| ≤ aspect the
205
- * surround) as the expected signal's scene at these nodes, responses and white radiance (see `ImagePlaneSignalScene`).
217
+ * surround) as the expected signal's scene at these nodes, responses and white radiance (see `ImagePlaneSignalScene`). #597: with
218
+ * `light` (mixed lighting; null when its parts are not given), the lit print: `radianceAt` only, no per-pixel signals.
206
219
  */
207
220
  signalScene(wavelengths: readonly number[], perNode: readonly Float64Array[], whiteRadiance: Float64Array, radianceAt: (u: number, v: number, nm: number) => number, scale: number, half: number, surroundReflectance: number): ImagePlaneSignalScene;
221
+ signalScene(wavelengths: readonly number[], perNode: readonly Float64Array[], whiteRadiance: Float64Array, radianceAt: (u: number, v: number, nm: number) => number, scale: number, half: number, surroundReflectance: number, light: ResolvedMixedIllumination | null | undefined): ImagePlaneSignalScene | ImagePlaneLitScene;
208
222
  /** The scene's form in the facade's source digest (the image's SHA-256 and shape, the paper, the interpolation, the lattice version). */
209
223
  digestForm: Readonly<Record<string, unknown>>;
210
224
  /** The result's `scene.parameters`: the image, paper and interpolation, the clipped samples and the image's SHA-256. */
@@ -257,7 +271,7 @@ export interface PlanarSceneRadianceProvider {
257
271
  * radiance per node and, for the direct path, Σ_n A_c(λ_n)·L(λ_n) integrated from each pixel's reconstructed spectrum
258
272
  * (`ResolvedImagePlaneScene.pixelSignals`, the surround's reflectance times the neutral signal outside the print).
259
273
  */
260
- imageSignalScene?(wavelengths: readonly number[], perNode: readonly Float64Array[]): ImagePlaneSignalScene;
274
+ imageSignalScene?(wavelengths: readonly number[], perNode: readonly Float64Array[]): ImagePlaneSignalScene | ImagePlaneLitScene;
261
275
  }
262
276
  /** Internal (#394): the material lookup of a provider built by {@link buildPlanarSceneRadianceProvider}, if it has one. */
263
277
  export declare function planarProviderMaterialOfDirection(provider: PlanarSceneRadianceProvider): ((direction: Readonly<{
@@ -295,6 +309,8 @@ export declare function buildPlanarSceneRadianceProvider(input: {
295
309
  * no longer a function of its material alone), so every renderer reads `radianceAt`. A radiance-function scene is refused.
296
310
  */
297
311
  irradianceAt?: (u: number, v: number, xM: number, yM: number, wavelengthNanometers: number) => number;
312
+ /** #597: the illumination's parts behind `irradianceAt`, which an image-plane print hands to the GPU's image-plane pass. */
313
+ illumination?: ResolvedMixedIllumination;
298
314
  }): PlanarSceneRadianceProvider;
299
315
  /** 2.3: a chart's physical size on the scene plane (`simulateCapture` `chartSize`, `createPlanarSceneRadianceProvider` `chartSize`). */
300
316
  export interface ChartSizeOption {
@@ -187,9 +187,8 @@ export function buildPlanarSceneRadianceProvider(input) {
187
187
  const light = input.irradianceAt;
188
188
  if (light && caller?.kind === "radiance-function")
189
189
  throw new InvalidConfigurationError("illumination needs a lit scene; a radiance-function scene ignores the illuminant.");
190
- // #581 with #550: a print's signals are integrated per pixel under one light (its spectral nodes); mixed light over a print is not modelled.
191
- if (light && imageScene)
192
- throw new InvalidConfigurationError("illumination cannot light an image-plane scene yet: the print's signals are integrated under one illuminant.");
190
+ // #597 (2.22.0): mixed light over a print reads the print's reflectance spectrum (its pixels' spectra, cached per spectral node) times the
191
+ // blended irradiance at each point; no per-pixel signal is cached (the image access below is left out), so every site integrates at use.
193
192
  /** #550: reflectance × the blended irradiance at the point (chart-local units with a fixed-size chart) / π. */
194
193
  function litRadianceAt(u, v, nm) {
195
194
  let cu = u, cv = v, reflectance;
@@ -203,6 +202,8 @@ export function buildPlanarSceneRadianceProvider(input) {
203
202
  reflectance = placed.surroundReflectance;
204
203
  else if (chart)
205
204
  reflectance = chart.reflectanceAt(cu, cv, nm);
205
+ else if (imageScene)
206
+ reflectance = imageScene.reflectanceAt(cu, cv, nm);
206
207
  else
207
208
  reflectance = callerReflectance(placed ? { xM: u * scale, yM: v * scale, u, v, wavelengthNanometers: nm, chartU: cu, chartV: cv } : { xM: u * scale, yM: v * scale, u, v, wavelengthNanometers: nm });
208
209
  return reflectance * light(cu, cv, u * scale, v * scale, nm) / Math.PI;
@@ -273,7 +274,8 @@ export function buildPlanarSceneRadianceProvider(input) {
273
274
  const chartAccess = light ? {} : chart ? { chartMaterialAt, materialRadiance: materialRadianceOf } :
274
275
  materialScene ? { chartMaterialAt: callerMaterialAt, materialRadiance: materialRadianceOf } : {};
275
276
  // #581: an image-plane print in node values at a frame point (the surround outside it), for the tabulated expected signal.
276
- const imageAccess = imageScene ? { imageSignalScene: (wavelengths, perNode) => imageScene.signalScene(wavelengths, perNode, Float64Array.from(wavelengths, (nm) => irradianceScale * shapeAt(nm) / Math.PI), radianceAt, scale, half, placed.surroundReflectance) } : {};
277
+ // #597: under mixed light the scene has no per-pixel signals: every renderer integrates litRadianceAt, and the GPU pass lights each point.
278
+ const imageAccess = imageScene ? { imageSignalScene: (wavelengths, perNode) => imageScene.signalScene(wavelengths, perNode, Float64Array.from(wavelengths, (nm) => irradianceScale * shapeAt(nm) / Math.PI), light ? litRadianceAt : radianceAt, scale, half, placed.surroundReflectance, light ? input.illumination ?? null : undefined) } : {};
277
279
  // #394: evaluateRadiance's own plane-point arithmetic; radianceAt is then materialRadianceOf(material, nm) for both scene forms.
278
280
  const materialAtPoint = light ? undefined : chart ? chartMaterialAt : materialScene ? callerMaterialAt : undefined;
279
281
  const materialOfDirection = materialAtPoint === undefined ? undefined : (o) => {