@photivra/engine 1.0.1 → 1.2.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 (244) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/CITATION.cff +1 -1
  3. package/NOTICE +29 -0
  4. package/README.md +8 -6
  5. package/THIRD_PARTY.md +10 -0
  6. package/dist/core/version.d.ts +1 -1
  7. package/dist/core/version.js +1 -1
  8. package/dist/index.d.ts +10 -0
  9. package/dist/index.d.ts.map +1 -1
  10. package/dist/index.js +5 -0
  11. package/dist/index.js.map +1 -1
  12. package/dist/optics/complex-pupil-psf.d.ts +6 -0
  13. package/dist/optics/complex-pupil-psf.d.ts.map +1 -1
  14. package/dist/optics/complex-pupil-psf.js +10 -7
  15. package/dist/optics/complex-pupil-psf.js.map +1 -1
  16. package/dist/output/native-capture-sdr.d.ts +78 -0
  17. package/dist/output/native-capture-sdr.d.ts.map +1 -0
  18. package/dist/output/native-capture-sdr.js +171 -0
  19. package/dist/output/native-capture-sdr.js.map +1 -0
  20. package/dist/output/print-contrast-reference.d.ts +47 -0
  21. package/dist/output/print-contrast-reference.d.ts.map +1 -0
  22. package/dist/output/print-contrast-reference.js +95 -0
  23. package/dist/output/print-contrast-reference.js.map +1 -0
  24. package/dist/output/print-detail.d.ts +113 -0
  25. package/dist/output/print-detail.d.ts.map +1 -0
  26. package/dist/output/print-detail.js +224 -0
  27. package/dist/output/print-detail.js.map +1 -0
  28. package/dist/output/print-plan.d.ts +138 -0
  29. package/dist/output/print-plan.d.ts.map +1 -0
  30. package/dist/output/print-plan.js +305 -0
  31. package/dist/output/print-plan.js.map +1 -0
  32. package/dist/output/print-region-statistics.d.ts +92 -0
  33. package/dist/output/print-region-statistics.d.ts.map +1 -0
  34. package/dist/output/print-region-statistics.js +300 -0
  35. package/dist/output/print-region-statistics.js.map +1 -0
  36. package/docs/API_REFERENCE.md +89 -1
  37. package/docs/API_STYLE.md +1 -1
  38. package/docs/ARCHITECTURE.md +1 -1
  39. package/docs/AUTOMATION_COORDINATION.md +1 -1
  40. package/docs/CAPTURE_COLOR.md +1 -1
  41. package/docs/CAPTURE_CORRECTED_SDR.md +1 -1
  42. package/docs/CAPTURE_EXPORT_METADATA.md +1 -1
  43. package/docs/CAPTURE_SDR.md +3 -1
  44. package/docs/DEVELOPERS.md +12 -4
  45. package/docs/DIGITAL_OPTICS_FOUNDATION.md +1 -1
  46. package/docs/ENVIRONMENT_RAW_CAPTURE.md +1 -1
  47. package/docs/EXPORT_ACCEPTANCE.md +1 -1
  48. package/docs/GENERIC_TIER_PRESETS.md +1 -1
  49. package/docs/GEOMETRIC_PREPARATION_REUSE.md +1 -1
  50. package/docs/IMAGE_FORMATION.md +1 -1
  51. package/docs/LINEAR_CAPTURE_ENCODING.md +1 -1
  52. package/docs/MOTION_AND_SIGNAL.md +1 -1
  53. package/docs/NATIVE_CAPTURE_SDR.md +70 -0
  54. package/docs/NATIVE_CAPTURE_SDR_REVIEW.md +37 -0
  55. package/docs/NATIVE_CAPTURE_SDR_VALIDATION.md +34 -0
  56. package/docs/NUMERICAL_CORRECTNESS.md +1 -1
  57. package/docs/PERFORMANCE_BASELINE.md +1 -1
  58. package/docs/PHOTOGRAPHIC_EXPORT.md +1 -1
  59. package/docs/PHYSICS_FOUNDATION.md +1 -1
  60. package/docs/POC_API.md +1 -1
  61. package/docs/POC_PROJECTION_PLATFORM_REFERENCE.md +12 -0
  62. package/docs/POC_PROJECTION_REUSE.md +1 -1
  63. package/docs/PRINT_195_196_REVIEW.md +93 -0
  64. package/docs/PRINT_196_ENGINE_ACCEPTANCE.md +45 -0
  65. package/docs/PRINT_CONTRAST_REFERENCE.md +43 -0
  66. package/docs/PRINT_DETAIL_ASSESSMENT.md +81 -0
  67. package/docs/PRINT_DETAIL_JPEG_EVIDENCE.md +36 -0
  68. package/docs/PRINT_DETAIL_SDR_EVIDENCE.md +29 -0
  69. package/docs/PRINT_DETAIL_VALIDATION.md +36 -0
  70. package/docs/PRINT_PLANNING.md +75 -0
  71. package/docs/PRINT_REGION_STATISTICS.md +38 -0
  72. package/docs/PROCESSED_OUTPUT.md +1 -1
  73. package/docs/PRODUCTION_COMPOSITION.md +1 -1
  74. package/docs/PRODUCTION_ENVIRONMENT_CAPTURE.md +1 -1
  75. package/docs/PROVENANCE.md +1 -1
  76. package/docs/PSF_FOUNDATION.md +11 -1
  77. package/docs/RAW_FRAME_ENVELOPE.md +1 -1
  78. package/docs/RAW_FRAME_RECONSTRUCTION.md +1 -1
  79. package/docs/RELEASE_1_1_0.md +25 -0
  80. package/docs/RELEASE_1_2_0.md +51 -0
  81. package/docs/SCENE_RADIANCE_AND_ILLUMINATION.md +1 -1
  82. package/docs/SCENE_SENSOR_QUADRATURE.md +1 -1
  83. package/docs/SCENE_SENSOR_TEMPORAL_EXPOSURE.md +1 -1
  84. package/docs/SCIENTIFIC_ASSURANCE.md +1 -1
  85. package/docs/SCIENTIFIC_CONFORMANCE.md +1 -1
  86. package/docs/SDR_RENDERING.md +1 -1
  87. package/docs/SENSOR_ENVIRONMENT_QUERY.md +1 -1
  88. package/docs/SENSOR_EQE_LOCAL_EXPOSURE.md +1 -1
  89. package/docs/SENSOR_EQE_TEMPORAL_EXPOSURE.md +1 -1
  90. package/docs/SENSOR_PSF_QUADRATURE.md +1 -1
  91. package/docs/SENSOR_RAW_FRAME.md +1 -1
  92. package/docs/SENSOR_RAW_PRODUCER.md +1 -1
  93. package/docs/SIGNAL_CONFORMANCE.md +1 -1
  94. package/docs/SIMULATED_CAPTURE.md +1 -1
  95. package/docs/STABILIZATION.md +1 -1
  96. package/docs/TEMPORAL_PHOTO_RAW.md +1 -1
  97. package/docs/TIER_ACCEPTANCE.md +1 -1
  98. package/docs/TIER_PRESET_ACCEPTANCE.md +1 -1
  99. package/docs/USAGE.md +9 -1
  100. package/docs/V1_COMPOSITION_MAP.md +1 -1
  101. package/docs/V1_HELPER_REUSE_REVIEW.md +1 -1
  102. package/docs/V1_PERFORMANCE_DISPOSITION.md +1 -1
  103. package/docs/api/camera-equivalent-focal-length.md +1 -1
  104. package/docs/api/camera-field-of-view.md +1 -1
  105. package/docs/api/camera-projected-object-size.md +1 -1
  106. package/docs/api/capture-capture-export-metadata.md +1 -1
  107. package/docs/api/capture-environment-raw-producer.md +1 -1
  108. package/docs/api/capture-focus-control.md +1 -1
  109. package/docs/api/capture-linear-encoding.md +1 -1
  110. package/docs/api/capture-photographic-export.md +1 -1
  111. package/docs/api/capture-raw-frame-reconstruction.md +1 -1
  112. package/docs/api/capture-release-sequence.md +1 -1
  113. package/docs/api/capture-sensor-raw-frame.md +1 -1
  114. package/docs/api/capture-sensor-raw-producer.md +1 -1
  115. package/docs/api/capture-simulated-capture.md +1 -1
  116. package/docs/api/color-capture-color.md +1 -1
  117. package/docs/api/color-white-balance.md +1 -1
  118. package/docs/api/composition-image-formation-plan.md +1 -1
  119. package/docs/api/composition-plan-consumer.md +1 -1
  120. package/docs/api/core-calculation-result.md +1 -1
  121. package/docs/api/core-configuration-error.md +1 -1
  122. package/docs/api/core-image-formation.md +1 -1
  123. package/docs/api/core-scientific-assurance.md +1 -1
  124. package/docs/api/core-spectral-composition.md +1 -1
  125. package/docs/api/core-spectral.md +1 -1
  126. package/docs/api/core-validation.md +1 -1
  127. package/docs/api/core-version.md +2 -2
  128. package/docs/api/equipment-exposure-capabilities.md +1 -1
  129. package/docs/api/equipment-generic-tier-assets.md +1 -1
  130. package/docs/api/equipment-generic-tier-presets.md +1 -1
  131. package/docs/api/equipment-iso-capabilities.md +1 -1
  132. package/docs/api/equipment-metering-capabilities.md +1 -1
  133. package/docs/api/equipment-release-capabilities.md +1 -1
  134. package/docs/api/exports.json +267 -2
  135. package/docs/api/exposure-exposure-duration-control.md +1 -1
  136. package/docs/api/exposure-exposure-mode-resolver.md +1 -1
  137. package/docs/api/exposure-exposure.md +1 -1
  138. package/docs/api/exposure-flash.md +1 -1
  139. package/docs/api/exposure-metering-scene-radiance.md +1 -1
  140. package/docs/api/exposure-metering-target.md +1 -1
  141. package/docs/api/exposure-metering-temporal.md +1 -1
  142. package/docs/api/exposure-metering.md +1 -1
  143. package/docs/api/exposure-program-line.md +1 -1
  144. package/docs/api/motion-camera-rotation.md +1 -1
  145. package/docs/api/motion-capture-rotation-inverse-mapping.md +1 -1
  146. package/docs/api/motion-capture-rotation-temporal-quadrature.md +1 -1
  147. package/docs/api/motion-capture-rotation-trajectory.md +1 -1
  148. package/docs/api/motion-capture-translation-parallax-temporal-quadrature.md +1 -1
  149. package/docs/api/motion-extended-object-projection.md +1 -1
  150. package/docs/api/motion-projected-motion.md +1 -1
  151. package/docs/api/optics-aperture.md +1 -1
  152. package/docs/api/optics-circle-of-confusion.md +1 -1
  153. package/docs/api/optics-complex-pupil-psf.md +7 -1
  154. package/docs/api/optics-depth-of-field.md +1 -1
  155. package/docs/api/optics-diffraction.md +1 -1
  156. package/docs/api/optics-focus-breathing.md +1 -1
  157. package/docs/api/optics-focus-state.md +1 -1
  158. package/docs/api/optics-front-of-lens-filter.md +1 -1
  159. package/docs/api/optics-illumination-vignetting.md +1 -1
  160. package/docs/api/optics-lateral-chromatic-aberration.md +1 -1
  161. package/docs/api/optics-lens-psf-profile.md +1 -1
  162. package/docs/api/optics-polygon-diffraction.md +1 -1
  163. package/docs/api/optics-profile-contract.md +1 -1
  164. package/docs/api/optics-psf-foundation.md +1 -1
  165. package/docs/api/optics-radial-distortion.md +1 -1
  166. package/docs/api/optics-scene-to-sensor-irradiance.md +1 -1
  167. package/docs/api/optics-scene-to-sensor-quadrature.md +1 -1
  168. package/docs/api/optics-sensor-environment-query.md +1 -1
  169. package/docs/api/optics-sensor-psf-quadrature.md +1 -1
  170. package/docs/api/optics-stray-light.md +1 -1
  171. package/docs/api/optics-thin-lens.md +1 -1
  172. package/docs/api/output-capture-corrected-sdr.md +1 -1
  173. package/docs/api/output-capture-geometry.md +1 -1
  174. package/docs/api/output-capture-sdr.md +1 -1
  175. package/docs/api/output-crop.md +1 -1
  176. package/docs/api/output-geometric-transforms.md +1 -1
  177. package/docs/api/output-lens-corrections.md +1 -1
  178. package/docs/api/output-native-capture-sdr.md +150 -0
  179. package/docs/api/output-print-contrast-reference.md +82 -0
  180. package/docs/api/output-print-detail.md +147 -0
  181. package/docs/api/output-print-plan.md +165 -0
  182. package/docs/api/output-print-region-statistics.md +165 -0
  183. package/docs/api/output-sdr-rendering.md +1 -1
  184. package/docs/api/output-subject-framing-crop.md +1 -1
  185. package/docs/api/schema-camera.md +1 -1
  186. package/docs/api/schema-illumination-spectral.md +1 -1
  187. package/docs/api/schema-illumination-temporal.md +1 -1
  188. package/docs/api/schema-illumination.md +1 -1
  189. package/docs/api/schema-scene-radiance-temporal.md +1 -1
  190. package/docs/api/schema-scene-radiance.md +1 -1
  191. package/docs/api/schema-scene.md +1 -1
  192. package/docs/api/schema-validation.md +1 -1
  193. package/docs/api/sensor-accumulated-charge.md +1 -1
  194. package/docs/api/sensor-architecture.md +1 -1
  195. package/docs/api/sensor-camera-saturation-capacity.md +1 -1
  196. package/docs/api/sensor-capture-color-sampling-binding.md +1 -1
  197. package/docs/api/sensor-capture-mode-timing.md +1 -1
  198. package/docs/api/sensor-capture-mode.md +1 -1
  199. package/docs/api/sensor-color-sampling.md +1 -1
  200. package/docs/api/sensor-constant-rate-temporal-integration.md +1 -1
  201. package/docs/api/sensor-dark-current.md +1 -1
  202. package/docs/api/sensor-environment-photo-signal.md +1 -1
  203. package/docs/api/sensor-eqe-electron-rate.md +1 -1
  204. package/docs/api/sensor-eqe-local-exposure.md +1 -1
  205. package/docs/api/sensor-eqe-temporal-exposure.md +1 -1
  206. package/docs/api/sensor-exposure-window.md +1 -1
  207. package/docs/api/sensor-iso-signal-chain.md +1 -1
  208. package/docs/api/sensor-local-exposure-binding.md +1 -1
  209. package/docs/api/sensor-optical-stack.md +1 -1
  210. package/docs/api/sensor-photon-energy.md +1 -1
  211. package/docs/api/sensor-physical-charge-capacity.md +1 -1
  212. package/docs/api/sensor-pixel-pitch.md +1 -1
  213. package/docs/api/sensor-radiometry-readiness.md +1 -1
  214. package/docs/api/sensor-raw-readout.md +1 -1
  215. package/docs/api/sensor-raw-reconstruction.md +1 -1
  216. package/docs/api/sensor-readout-exposure-linkage.md +1 -1
  217. package/docs/api/sensor-readout-timing.md +1 -1
  218. package/docs/api/sensor-response-application-compatibility.md +1 -1
  219. package/docs/api/sensor-response-operating-range.md +1 -1
  220. package/docs/api/sensor-responsivity-photocurrent.md +1 -1
  221. package/docs/api/sensor-sampling-aperture.md +1 -1
  222. package/docs/api/sensor-scene-eqe-temporal-exposure.md +1 -1
  223. package/docs/api/sensor-sensor-geometry.md +1 -1
  224. package/docs/api/sensor-signal-noise.md +1 -1
  225. package/docs/api/sensor-spatial-sample-reduction.md +1 -1
  226. package/docs/api/sensor-spatial-sampling-quadrature.md +1 -1
  227. package/docs/api/sensor-spatio-spectral-reduction.md +1 -1
  228. package/docs/api/sensor-spectral-coverage.md +1 -1
  229. package/docs/api/sensor-spectral-quadrature.md +1 -1
  230. package/docs/api/sensor-spectral-response.md +1 -1
  231. package/docs/api/sensor-temporal-photo-signal.md +1 -1
  232. package/docs/api/simulation-poc-simulation.md +1 -1
  233. package/docs/api/stabilization-camera-shake.md +1 -1
  234. package/docs/api/stabilization-system.md +1 -1
  235. package/docs/licenses/castleCSF-MIT.txt +21 -0
  236. package/docs/validation/native-capture-sdr-darwin-arm64-node26-review.jsonl +4 -0
  237. package/docs/validation/native-capture-sdr-darwin-arm64.jsonl +3 -0
  238. package/docs/validation/print-196-candidate-capabilities.json +28 -0
  239. package/docs/validation/print-196-candidate-evidence.json +356 -0
  240. package/docs/validation/print-196-engine-acceptance.json +81 -0
  241. package/docs/validation/print-detail-capabilities.json +103 -0
  242. package/docs/validation/print-detail-jpeg-evidence.json +116 -0
  243. package/docs/validation/print-detail-sdr-evidence.json +81 -0
  244. package/package.json +1 -1
@@ -0,0 +1,171 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ /** Engine-owned bounded tile execution; see docs/NATIVE_CAPTURE_SDR.md. */
3
+ import { parseSimulatedCapture } from "../capture/simulated-capture.js";
4
+ import { LINEAR_CAPTURE_RGB_PROFILE, resolveCaptureColorModel } from "../color/capture-color.js";
5
+ import { InvalidConfigurationError } from "../core/configuration-error.js";
6
+ import { requireAllowlistedRecord, requirePublicOpaqueId } from "../core/record-validation.js";
7
+ import { freezeOwnedData } from "../core/owned-data.js";
8
+ import { calculateSdrRendering, parseSdrRenderingProfile } from "./sdr-rendering.js";
9
+ export const NATIVE_CAPTURE_SDR_SCHEMA_VERSION = "0.1.0";
10
+ export const NATIVE_CAPTURE_SDR_LIMITS = Object.freeze({ maximumPixels: 24_000_000,
11
+ maximumDimension: 16_384, tileWidth: 256, tileHeight: 32, maximumTileStorageSamples: 32_768 });
12
+ /** Validates/admission-plans without reading external samples or allocating a raster. */
13
+ export function calculateNativeCaptureSdrPlan(input) {
14
+ const r = requireAllowlistedRecord(input, ["capture", "sourcePlaneId", "outputImageStateId", "profile", "maximumOutputBytes"], "Invalid native SDR input.");
15
+ // This contract accepts manifests only: do not copy unrelated inline master buffers.
16
+ const c = r.capture;
17
+ if (!c || !Array.isArray(c.planes) || c.planes.length > 32 || c.planes.some(p => !p || p.storage?.kind === "inline-float64")) {
18
+ throw new InvalidConfigurationError("Native SDR requires external-only capture manifests.");
19
+ }
20
+ const capture = parseSimulatedCapture(c);
21
+ const sourcePlaneId = requirePublicOpaqueId(r.sourcePlaneId, "Invalid native SDR plane ID.");
22
+ const outputImageStateId = requirePublicOpaqueId(r.outputImageStateId, "Invalid native SDR output state ID.");
23
+ const plane = capture.planes.find(p => p.id === sourcePlaneId);
24
+ const white = resolveCaptureColorModel().referenceWhiteXyz;
25
+ if (!plane || plane.imageState !== "color-transformed-linear-rgb" ||
26
+ plane.colorProfile?.id !== LINEAR_CAPTURE_RGB_PROFILE.id || plane.colorProfile.version !== LINEAR_CAPTURE_RGB_PROFILE.version ||
27
+ plane.encodingReferenceWhiteXyz?.x !== white.x || plane.encodingReferenceWhiteXyz.y !== white.y || plane.encodingReferenceWhiteXyz.z !== white.z ||
28
+ plane.whiteBalanceApplication === "intent-only" || (plane.whiteBalanceApplication === "not-applicable" && capture.whiteBalanceIntent !== null) ||
29
+ capture.planes.some(p => p.imageStateId === outputImageStateId)) {
30
+ throw new InvalidConfigurationError("Native SDR requires exact resolved linear-sRGB/D65 and a new output state ID.");
31
+ }
32
+ const pixels = plane.pixelWidth * plane.pixelHeight, profile = parseSdrRenderingProfile(r.profile);
33
+ const outputBytes = pixels * 3 * (profile.bitDepth / 8);
34
+ const scale = 2 ** profile.renderingExposureEv / plane.referenceWhiteValue;
35
+ if (!Number.isFinite(scale) || scale <= 0)
36
+ throw new InvalidConfigurationError("Native SDR scale is unrepresentable.");
37
+ if (pixels > NATIVE_CAPTURE_SDR_LIMITS.maximumPixels || plane.pixelWidth > NATIVE_CAPTURE_SDR_LIMITS.maximumDimension ||
38
+ plane.pixelHeight > NATIVE_CAPTURE_SDR_LIMITS.maximumDimension || typeof r.maximumOutputBytes !== "number" ||
39
+ !Number.isSafeInteger(r.maximumOutputBytes) || r.maximumOutputBytes < outputBytes) {
40
+ throw new InvalidConfigurationError("Native SDR raster/output exceeds declared admission limits.");
41
+ }
42
+ // Provider payload + packed copy + reference parser copy + four reference output arrays.
43
+ const maximumScratchPayloadBytes = NATIVE_CAPTURE_SDR_LIMITS.maximumTileStorageSamples * 8 +
44
+ NATIVE_CAPTURE_SDR_LIMITS.tileWidth * NATIVE_CAPTURE_SDR_LIMITS.tileHeight * 3 * 8 * 6;
45
+ return freezeOwnedData({ schemaVersion: NATIVE_CAPTURE_SDR_SCHEMA_VERSION, capture, sourcePlaneId, outputImageStateId, profile,
46
+ outputBytes, maximumScratchPayloadBytes,
47
+ tileCount: Math.ceil(plane.pixelWidth / NATIVE_CAPTURE_SDR_LIMITS.tileWidth) * Math.ceil(plane.pixelHeight / NATIVE_CAPTURE_SDR_LIMITS.tileHeight) });
48
+ }
49
+ function renderTile(tile, request, plane, profile) {
50
+ const r = requireAllowlistedRecord(tile, ["captureId", "sourcePlaneId", "artifactId", "sha256", "x", "y", "width", "height", "rowStrideSamples", "samples"], "Invalid native SDR tile.");
51
+ for (const key of Object.keys(request)) {
52
+ if (r[key] !== request[key])
53
+ throw new InvalidConfigurationError("Native SDR tile identity/rectangle mismatch.");
54
+ }
55
+ const samples = r.samples;
56
+ const expectedType = plane.storage.kind === "external-float32" ? Float32Array : Float64Array;
57
+ if (!(samples instanceof expectedType) || !(samples.buffer instanceof ArrayBuffer) ||
58
+ samples.buffer.byteLength > NATIVE_CAPTURE_SDR_LIMITS.maximumTileStorageSamples * expectedType.BYTES_PER_ELEMENT ||
59
+ typeof r.rowStrideSamples !== "number" || !Number.isSafeInteger(r.rowStrideSamples) || r.rowStrideSamples < request.width * 3 ||
60
+ samples.length !== r.rowStrideSamples * request.height || samples.length > NATIVE_CAPTURE_SDR_LIMITS.maximumTileStorageSamples) {
61
+ throw new InvalidConfigurationError("Native SDR tile precision/stride/storage mismatch.");
62
+ }
63
+ const packed = [];
64
+ for (let y = 0; y < request.height; y++) {
65
+ for (let x = 0; x < request.width * 3; x++)
66
+ packed.push(samples[y * r.rowStrideSamples + x]);
67
+ }
68
+ // Engine-declared tiling is valid because every supported rendering operation is pointwise.
69
+ // The unchanged bounded reference owns equations, clipping, transfer and quantization.
70
+ return calculateSdrRendering({ sourceImageStateId: plane.imageStateId, inputImageState: "color-transformed-linear-rgb",
71
+ inputColorSpace: "linear-srgb-d65", whiteBalanceHandling: plane.whiteBalanceApplication === "not-applicable" ? "not-required" : "already-applied-upstream",
72
+ pixelWidth: request.width, pixelHeight: request.height, referenceWhiteValue: plane.referenceWhiteValue,
73
+ samples: packed, profile }).value;
74
+ }
75
+ /** Creates a single-use execution owner. Admission is validated before any buffer/provider work. */
76
+ export function createNativeCaptureSdrTask(input, provider) {
77
+ const plan = calculateNativeCaptureSdrPlan(input);
78
+ if (!provider || typeof provider.readTile !== "function" || typeof provider.yieldControl !== "function") {
79
+ throw new InvalidConfigurationError("Native SDR requires a tile reader and event-loop yield.");
80
+ }
81
+ // Snapshot callback identities too; later app mutations cannot replace an in-flight reader.
82
+ const readTile = provider.readTile.bind(provider), yieldControl = provider.yieldControl.bind(provider);
83
+ const plane = plan.capture.planes.find(p => p.id === plan.sourcePlaneId);
84
+ if (plane.storage.kind === "inline-float64")
85
+ throw new InvalidConfigurationError("External native source required.");
86
+ const storage = plane.storage, abort = new AbortController();
87
+ let state = "ready", count = 0, output = null;
88
+ let codes = null;
89
+ function release() { codes?.fill(0); codes = null; output = null; }
90
+ function checkActive() {
91
+ if (abort.signal.aborted)
92
+ throw new InvalidConfigurationError("Native SDR task cancelled/disposed; no output available.");
93
+ }
94
+ return {
95
+ plan,
96
+ get state() { return state; },
97
+ get completedTileCount() { return count; },
98
+ async run() {
99
+ if (state !== "ready")
100
+ throw new InvalidConfigurationError("Native SDR task is single-use.");
101
+ state = "running";
102
+ try {
103
+ codes = plan.profile.bitDepth === 8 ? new Uint8Array(plan.outputBytes) : new Uint16Array(plan.outputBytes / 2);
104
+ const diagnostics = { renderingNegativeSampleCount: 0, renderingAboveReferenceSampleCount: 0,
105
+ toneChangedSampleCount: 0, gamutClippedLowSampleCount: 0, gamutClippedHighSampleCount: 0, captureSaturation: "not-consumed" };
106
+ let encoding;
107
+ let adaptation;
108
+ for (let y = 0; y < plane.pixelHeight; y += NATIVE_CAPTURE_SDR_LIMITS.tileHeight) {
109
+ for (let x = 0; x < plane.pixelWidth; x += NATIVE_CAPTURE_SDR_LIMITS.tileWidth) {
110
+ checkActive();
111
+ const request = Object.freeze({ captureId: plan.capture.captureId, sourcePlaneId: plane.id,
112
+ artifactId: storage.artifactId, sha256: storage.sha256, x, y,
113
+ width: Math.min(NATIVE_CAPTURE_SDR_LIMITS.tileWidth, plane.pixelWidth - x),
114
+ height: Math.min(NATIVE_CAPTURE_SDR_LIMITS.tileHeight, plane.pixelHeight - y) });
115
+ {
116
+ const tile = await readTile(request, abort.signal);
117
+ checkActive();
118
+ const rendered = renderTile(tile, request, plane, plan.profile);
119
+ for (let row = 0; row < request.height; row++) {
120
+ for (let column = 0; column < request.width * 3; column++) {
121
+ codes[(y + row) * plane.pixelWidth * 3 + x * 3 + column] = rendered.integerSamples[row * request.width * 3 + column];
122
+ }
123
+ }
124
+ for (const key of ["renderingNegativeSampleCount", "renderingAboveReferenceSampleCount", "toneChangedSampleCount",
125
+ "gamutClippedLowSampleCount", "gamutClippedHighSampleCount"])
126
+ diagnostics[key] += rendered.diagnostics[key];
127
+ encoding = rendered.outputEncoding;
128
+ adaptation = rendered.displayAdaptation;
129
+ count++;
130
+ }
131
+ // Do not retain tile/reference arrays across the next provider/yield boundary.
132
+ await yieldControl(abort.signal);
133
+ checkActive();
134
+ }
135
+ }
136
+ output = { plan, integerSamples: codes, diagnostics, outputEncoding: encoding, displayAdaptation: adaptation };
137
+ state = "completed";
138
+ }
139
+ catch (error) {
140
+ release();
141
+ if (!abort.signal.aborted) {
142
+ state = "failed";
143
+ abort.abort();
144
+ }
145
+ throw error;
146
+ }
147
+ },
148
+ cancel() {
149
+ if (state === "ready" || state === "running" || state === "completed") {
150
+ state = "cancelled";
151
+ abort.abort();
152
+ release();
153
+ }
154
+ },
155
+ dispose() { if (state !== "transferred") {
156
+ state = "disposed";
157
+ abort.abort();
158
+ release();
159
+ } },
160
+ takeOutput() {
161
+ if (state !== "completed" || !output)
162
+ throw new InvalidConfigurationError("Native SDR output is unavailable.");
163
+ const result = output;
164
+ output = null;
165
+ codes = null;
166
+ state = "transferred";
167
+ return result;
168
+ }
169
+ };
170
+ }
171
+ //# sourceMappingURL=native-capture-sdr.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"native-capture-sdr.js","sourceRoot":"","sources":["../../src/output/native-capture-sdr.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,47 @@
1
+ /** Static D65 neutral Gabor detection reference; no photographic visibility verdict.
2
+ * @see docs/PRINT_CONTRAST_REFERENCE.md for exact source, applicability and review gates.
3
+ */
4
+ import { type CalculationResult } from "../core/calculation-result.js";
5
+ export declare const PRINT_CONTRAST_REFERENCE_MODEL_VERSION: "0.1.0";
6
+ /** Exact MIT-licensed numerical-model source, not a local calibration identity. */
7
+ export declare const PRINT_CONTRAST_REFERENCE_UPSTREAM_REVISION: "f4b0b722af83001d7af979281e06ca642d36e4e8";
8
+ /** Narrow reference stimulus, separate from any measured photographic ROI.
9
+ * Positive but out-of-domain quantities return unsupported rather than extrapolation.
10
+ */
11
+ export interface PrintContrastReferenceInput {
12
+ referenceId: string;
13
+ stimulus: "static-neutral-d65-gabor";
14
+ observer: "published-binocular-natural-pupil-reference";
15
+ /** Uniform D65 background/carrier mean; not the average of a finite photographic ROI. */
16
+ meanLuminanceCdPerSquareMeter: number;
17
+ spatialFrequencyCyclesPerDegree: number;
18
+ gaussianEnvelopeSigmaDegrees: number;
19
+ temporalFrequencyHz: number;
20
+ eccentricityDegrees: number;
21
+ /** Neutral carrier fractional amplitude before the Gaussian envelope; not arbitrary ROI extrema. */
22
+ modulationMichelson: number;
23
+ }
24
+ export interface PrintContrastReference {
25
+ referenceId: string;
26
+ engineApiVersion: string;
27
+ modelVersion: typeof PRINT_CONTRAST_REFERENCE_MODEL_VERSION;
28
+ upstreamRevision: typeof PRINT_CONTRAST_REFERENCE_UPSTREAM_REVISION;
29
+ input: PrintContrastReferenceInput;
30
+ status: "model-estimate" | "unsupported";
31
+ blockers: string[];
32
+ estimate: {
33
+ contrastSensitivity: number;
34
+ thresholdModulationMichelson: number;
35
+ suppliedModulationToModelThresholdRatio: number;
36
+ } | null;
37
+ observerApplicability: "population-reference-unverified-for-individual";
38
+ naturalImageVisibility: "unassessed";
39
+ printStimulusMatch: "unassessed";
40
+ uncertainty: "not-quantified";
41
+ overallPrintVerdict: "not-offered";
42
+ }
43
+ /** Strictly parse/copy explicit reference conditions; no defaults infer an observer. */
44
+ export declare function parsePrintContrastReferenceInput(value: unknown): PrintContrastReferenceInput;
45
+ /** Estimate the restricted published-model threshold; no individual invisibility claim. */
46
+ export declare function calculatePrintContrastReference(value: PrintContrastReferenceInput): CalculationResult<PrintContrastReference>;
47
+ //# sourceMappingURL=print-contrast-reference.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"print-contrast-reference.d.ts","sourceRoot":"","sources":["../../src/output/print-contrast-reference.ts"],"names":[],"mappings":"AAKA;;GAEG;AACH,OAAO,EAAmB,KAAK,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAMxF,eAAO,MAAM,sCAAsC,EAAG,OAAgB,CAAC;AACvE,mFAAmF;AACnF,eAAO,MAAM,0CAA0C,EAAG,0CAAmD,CAAC;AAE9G;;GAEG;AACH,MAAM,WAAW,2BAA2B;IAC1C,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,0BAA0B,CAAC;IACrC,QAAQ,EAAE,6CAA6C,CAAC;IACxD,yFAAyF;IACzF,6BAA6B,EAAE,MAAM,CAAC;IACtC,+BAA+B,EAAE,MAAM,CAAC;IACxC,4BAA4B,EAAE,MAAM,CAAC;IACrC,mBAAmB,EAAE,MAAM,CAAC;IAC5B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,oGAAoG;IACpG,mBAAmB,EAAE,MAAM,CAAC;CAC7B;AACD,MAAM,WAAW,sBAAsB;IACrC,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB,EAAE,MAAM,CAAC;IACzB,YAAY,EAAE,OAAO,sCAAsC,CAAC;IAC5D,gBAAgB,EAAE,OAAO,0CAA0C,CAAC;IACpE,KAAK,EAAE,2BAA2B,CAAC;IACnC,MAAM,EAAE,gBAAgB,GAAG,aAAa,CAAC;IACzC,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,QAAQ,EAAE;QAAE,mBAAmB,EAAE,MAAM,CAAC;QAAC,4BAA4B,EAAE,MAAM,CAAC;QAAC,uCAAuC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IACxI,qBAAqB,EAAE,gDAAgD,CAAC;IACxE,sBAAsB,EAAE,YAAY,CAAC;IACrC,kBAAkB,EAAE,YAAY,CAAC;IACjC,WAAW,EAAE,gBAAgB,CAAC;IAC9B,mBAAmB,EAAE,aAAa,CAAC;CACpC;AAED,wFAAwF;AACxF,wBAAgB,gCAAgC,CAAC,KAAK,EAAE,OAAO,GAAG,2BAA2B,CAe5F;AAgCD,2FAA2F;AAC3F,wBAAgB,+BAA+B,CAAC,KAAK,EAAE,2BAA2B,GAAG,iBAAiB,CAAC,sBAAsB,CAAC,CAwB7H"}
@@ -0,0 +1,95 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ // castleCSF numerical model material: Copyright (c) 2023 Graphics and Displays
3
+ // group - University of Cambridge. MIT terms retained in NOTICE and
4
+ // docs/licenses/castleCSF-MIT.txt. Original bounded TypeScript adapter.
5
+ /** Static D65 neutral Gabor detection reference; no photographic visibility verdict.
6
+ * @see docs/PRINT_CONTRAST_REFERENCE.md for exact source, applicability and review gates.
7
+ */
8
+ import { estimatedResult } from "../core/calculation-result.js";
9
+ import { InvalidConfigurationError } from "../core/configuration-error.js";
10
+ import { freezeOwnedData } from "../core/owned-data.js";
11
+ import { requireAllowlistedRecord, requirePublicOpaqueId } from "../core/record-validation.js";
12
+ import { ENGINE_API_VERSION } from "../core/version.js";
13
+ export const PRINT_CONTRAST_REFERENCE_MODEL_VERSION = "0.1.0";
14
+ /** Exact MIT-licensed numerical-model source, not a local calibration identity. */
15
+ export const PRINT_CONTRAST_REFERENCE_UPSTREAM_REVISION = "f4b0b722af83001d7af979281e06ca642d36e4e8";
16
+ /** Strictly parse/copy explicit reference conditions; no defaults infer an observer. */
17
+ export function parsePrintContrastReferenceInput(value) {
18
+ const r = requireAllowlistedRecord(value, ["referenceId", "stimulus", "observer", "meanLuminanceCdPerSquareMeter", "spatialFrequencyCyclesPerDegree",
19
+ "gaussianEnvelopeSigmaDegrees", "temporalFrequencyHz", "eccentricityDegrees", "modulationMichelson"], "Invalid Print contrast reference fields.");
20
+ const number = (key, positive) => {
21
+ const v = r[key];
22
+ if (typeof v !== "number" || !Number.isFinite(v) || (positive ? v <= 0 : v < 0))
23
+ throw new InvalidConfigurationError("Print contrast reference quantities must be finite and in their numeric domain.");
24
+ return v === 0 ? 0 : v;
25
+ };
26
+ if (r.stimulus !== "static-neutral-d65-gabor" || r.observer !== "published-binocular-natural-pupil-reference")
27
+ throw new InvalidConfigurationError("Unknown Print reference stimulus/observer.");
28
+ const modulationMichelson = number("modulationMichelson", false);
29
+ if (modulationMichelson > 1)
30
+ throw new InvalidConfigurationError("Reference Michelson modulation must be at most one.");
31
+ return { referenceId: requirePublicOpaqueId(r.referenceId, "Invalid public Print contrast reference identity."), stimulus: r.stimulus, observer: r.observer,
32
+ meanLuminanceCdPerSquareMeter: number("meanLuminanceCdPerSquareMeter", true), spatialFrequencyCyclesPerDegree: number("spatialFrequencyCyclesPerDegree", true),
33
+ gaussianEnvelopeSigmaDegrees: number("gaussianEnvelopeSigmaDegrees", true), temporalFrequencyHz: number("temporalFrequencyHz", false),
34
+ eccentricityDegrees: number("eccentricityDegrees", false), modulationMichelson };
35
+ }
36
+ // Separately authored scalar evaluation of the licensed numerical model.
37
+ // Stable log1p/expm1 evaluation retains the small hyperbolic saturation term.
38
+ function luminanceDependency(p, luminance) {
39
+ if (p.length === 2)
40
+ return p[1] * luminance ** p[0];
41
+ const first = p[0] * Math.exp(-p[2] * Math.log1p(p[1] / luminance));
42
+ return p.length === 3 ? first : first * -Math.expm1(-p[4] * Math.log1p(p[3] / luminance));
43
+ }
44
+ function component(frequency, area, peak, peakFrequency, bandwidth, lowFrequencyFloor, a0, f0) {
45
+ const logDifference = Math.log10(frequency) - Math.log10(peakFrequency);
46
+ const parabola = 10 ** (-logDifference * logDifference / 2 ** bandwidth);
47
+ const shape = frequency < peakFrequency ? Math.max(parabola, lowFrequencyFloor) : parabola;
48
+ const criticalArea = a0 / (1 + (frequency / f0) ** 2);
49
+ return peak * shape * Math.sqrt(criticalArea / (1 + criticalArea / area)) * frequency;
50
+ }
51
+ function staticNeutralSensitivity(luminance, frequency) {
52
+ const area = Math.PI * 1.5 ** 2;
53
+ const sustained = component(frequency, area, luminanceDependency([56.4947, 7.54726, .144532, 5.58341e-7, 9.66862e9], luminance), luminanceDependency([1.78119, 91.5718, .256682], luminance), .000213047, 1 - .100207, 157.103, .702338);
54
+ const transient = component(frequency, area, luminanceDependency([.193434, 2748.09], luminance), .000316696, 2.6761, 1 - .000241177, 3.81611, 3.01389);
55
+ const omegaPeak = Math.log10(luminance) * 2.41482 + 4.7036;
56
+ const achromatic = sustained + transient * Math.exp(-((omegaPeak ** .1898) ** 2) / .0844836);
57
+ const redGreen = component(frequency, area, luminanceDependency([681.434, 38.0038, .480386], luminance), .0178364, 2.42104, 1, 2816.44, .0711058);
58
+ const yellowViolet = component(frequency, area, luminanceDependency([166.683, 62.8974, .41193], luminance), .00425753, 2.68197, 1, 2.82789e7, .000635093);
59
+ // Equal fractional modulation of the upstream D65 LMS background [L,M,S].
60
+ // All three mechanism responses remain, including nonzero opponent projections.
61
+ const redGreenProjection = Math.abs(.6991 - 2.3112 * .3009);
62
+ const yellowVioletProjection = Math.abs(-.6991 - .3009 + 50.9875 * .0198);
63
+ return Math.hypot(achromatic, redGreenProjection * redGreen, yellowVioletProjection * yellowViolet);
64
+ }
65
+ /** Estimate the restricted published-model threshold; no individual invisibility claim. */
66
+ export function calculatePrintContrastReference(value) {
67
+ const input = parsePrintContrastReferenceInput(value), l = input.meanLuminanceCdPerSquareMeter, f = input.spatialFrequencyCyclesPerDegree;
68
+ const result = { referenceId: input.referenceId, engineApiVersion: ENGINE_API_VERSION, modelVersion: PRINT_CONTRAST_REFERENCE_MODEL_VERSION,
69
+ upstreamRevision: PRINT_CONTRAST_REFERENCE_UPSTREAM_REVISION, input, status: "unsupported", blockers: [], estimate: null,
70
+ observerApplicability: "population-reference-unverified-for-individual", naturalImageVisibility: "unassessed", printStimulusMatch: "unassessed",
71
+ uncertainty: "not-quantified", overallPrintVerdict: "not-offered" };
72
+ if (l < 1 || l > 1000 || f < .25 || f > 16 || input.gaussianEnvelopeSigmaDegrees !== 1.5 || input.temporalFrequencyHz !== 0 || input.eccentricityDegrees !== 0)
73
+ result.blockers.push("outside-static-neutral-reference-domain");
74
+ else {
75
+ const sensitivity = staticNeutralSensitivity(l, f), threshold = 1 / sensitivity, ratio = input.modulationMichelson * sensitivity;
76
+ if (![sensitivity, threshold, ratio].every(Number.isFinite) || sensitivity <= 0 || threshold <= 0)
77
+ result.blockers.push("contrast-reference-numeric-range-unsupported");
78
+ else {
79
+ result.status = "model-estimate";
80
+ result.estimate = { contrastSensitivity: sensitivity, thresholdModulationMichelson: threshold, suppliedModulationToModelThresholdRatio: ratio };
81
+ }
82
+ }
83
+ return freezeOwnedData(estimatedResult(result, "castlecsf-static-neutral-d65-reference", PRINT_CONTRAST_REFERENCE_MODEL_VERSION, ["Static foveal D65 equal-fraction LMS Gabor; Gaussian envelope sigma is exactly 1.5 degrees.",
84
+ "Published population model reference; personal eyesight, natural-image masking and actual print-stimulus matching remain unassessed.",
85
+ "The numerical envelope is restricted; published model-fit errors do not become an individual confidence interval or a print verdict."], {
86
+ validRanges: [
87
+ { parameterPath: "meanLuminanceCdPerSquareMeter", unit: "cd/m^2", minimum: 1, maximum: 1000, note: "Restricted numerical reference envelope; no individual calibration." },
88
+ { parameterPath: "spatialFrequencyCyclesPerDegree", unit: "cycles/degree", minimum: .25, maximum: 16 },
89
+ { parameterPath: "gaussianEnvelopeSigmaDegrees", unit: "degree", minimum: 1.5, maximum: 1.5 },
90
+ { parameterPath: "temporalFrequencyHz", unit: "Hz", minimum: 0, maximum: 0 },
91
+ { parameterPath: "eccentricityDegrees", unit: "degree", minimum: 0, maximum: 0 }
92
+ ], notes: ["Uncertainty is not quantified; numerical conformance is distinct from stimulus/observer qualification."]
93
+ }));
94
+ }
95
+ //# sourceMappingURL=print-contrast-reference.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"print-contrast-reference.js","sourceRoot":"","sources":["../../src/output/print-contrast-reference.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,113 @@
1
+ /** Bounded regional Fourier diagnostic, not a perceived-quality or captured-MTF verdict.
2
+ * @see docs/PRINT_DETAIL_ASSESSMENT.md and docs/PRINT_DETAIL_VALIDATION.md.
3
+ */
4
+ import { type CalculationResult } from "../core/calculation-result.js";
5
+ import { type EvidenceProvenance } from "../core/evidence-provenance.js";
6
+ import { type ComposedScientificAssurance } from "../core/scientific-assurance.js";
7
+ import type { RasterDimensions } from "../sensor/sensor-geometry.js";
8
+ import { type RasterRect } from "./capture-geometry.js";
9
+ import { type PrintPlan, type PrintPlanInput } from "./print-plan.js";
10
+ /** Metric/protocol identity; independent of the root creator version. */
11
+ export declare const PRINT_REGION_DETAIL_MODEL_VERSION: "0.1.0";
12
+ /** Work bound for one dense ROI, not an actual-device capability claim. */
13
+ export declare const MAX_PRINT_DETAIL_REGION_SAMPLES = 65536;
14
+ /** Exact represented source; content hash and decoding are caller assertions. */
15
+ export interface PrintDetailSource {
16
+ captureId: string;
17
+ representationId: string;
18
+ contentSha256: string;
19
+ raster: RasterDimensions;
20
+ stage: "native-retained-linear" | "post-resampling-linear" | "post-encoding-decoded-linear";
21
+ domain: "relative-linear-luminance" | "transfer-encoded-luma" | "unknown";
22
+ registration: "oriented-retained-unwarped" | "correction-or-warp-unqualified";
23
+ processing: {
24
+ id: string;
25
+ version: string;
26
+ };
27
+ noiseRealizationId: string | null;
28
+ evidence: readonly EvidenceProvenance[];
29
+ }
30
+ /** Selected half-open rectangle in the represented oriented retained raster.
31
+ * Depth is descriptive, in metres; null explicitly means unknown.
32
+ */
33
+ export interface PrintDetailRegion {
34
+ id: string;
35
+ rect: RasterRect;
36
+ role: "selected-subject" | "field-diagnostic" | "intentional-defocus";
37
+ subjectDistanceM: number | null;
38
+ focusDistanceM: number | null;
39
+ }
40
+ /** Coherent integer Fourier mode; x right/y down, arbitrary phase at first ROI sample.
41
+ * Input modulation is dimensionless, positive and at most one.
42
+ */
43
+ export interface PrintSinusoidalTarget {
44
+ id: string;
45
+ version: string;
46
+ kind: "coherent-sinusoid";
47
+ cyclesAcrossRegion: {
48
+ x: number;
49
+ y: number;
50
+ };
51
+ referenceModulation: number;
52
+ }
53
+ /** Own/reusable scalar relative-linear ROI samples; no RGB/luma conversion is inferred. */
54
+ export interface PrintRegionDetailInput {
55
+ assessmentId: string;
56
+ print: PrintPlanInput;
57
+ source: PrintDetailSource;
58
+ region: PrintDetailRegion;
59
+ target: PrintSinusoidalTarget;
60
+ samples: readonly number[];
61
+ }
62
+ /** Calculated coefficients for one declared grating; residual is not a noise metric. */
63
+ export interface PrintSinusoidalMeasurement {
64
+ meanRelativeLuminance: number;
65
+ fundamentalAmplitudeRelativeLuminance: number;
66
+ fundamentalModulation: number;
67
+ declaredGratingTransfer: number;
68
+ unexplainedResidualRmsRelativeToMean: number;
69
+ }
70
+ /** Immutable snapshot with no full-system, artifact, perception or print-quality pass. */
71
+ export interface PrintRegionDetailAssessment {
72
+ assessmentId: string;
73
+ engineApiVersion: string;
74
+ modelVersion: typeof PRINT_REGION_DETAIL_MODEL_VERSION;
75
+ input: PrintRegionDetailInput;
76
+ status: "diagnostic-only" | "blocked" | "unsupported";
77
+ blockers: string[];
78
+ print: PrintPlan;
79
+ measurement: PrintSinusoidalMeasurement | null;
80
+ projection: {
81
+ fieldPointMm: {
82
+ x: number;
83
+ y: number;
84
+ };
85
+ frequencyCyclesPerMm: {
86
+ x: number;
87
+ y: number;
88
+ };
89
+ physicalPeriodMm: number;
90
+ angularPeriodAtImageCenterDegrees: number;
91
+ } | null;
92
+ assessedRasterMatchesRecommendation: boolean;
93
+ sourceArtifactVerification: "caller-declared-unverified";
94
+ assurance: ComposedScientificAssurance;
95
+ unassessed: readonly ("captured-system-mtf" | "optical-motion-attribution" | "noise" | "aliasing" | "halos" | "compression" | "color" | "perceived-quality" | "printer-substrate")[];
96
+ overallPrintVerdict: "not-offered";
97
+ }
98
+ /** Internal shared source boundary for the regional measurement protocols. */
99
+ export declare function parsePrintDetailSource(value: unknown): PrintDetailSource;
100
+ /** Internal shared ROI boundary; no target or signal interpretation is inferred. */
101
+ export declare function parsePrintDetailRegion(value: unknown, source: PrintDetailSource, sampleValues: unknown): {
102
+ region: PrintDetailRegion;
103
+ samples: number[];
104
+ };
105
+ /** Parse/copy bounded, untrusted region/source/target data and existing Print geometry.
106
+ * Unknowns, sparse arrays and factual-reference-only numeric samples fail closed.
107
+ */
108
+ export declare function parsePrintRegionDetailInput(value: unknown): PrintRegionDetailInput;
109
+ /** Calculate one coherent regional fundamental and its print reference scale.
110
+ * Acquisition remains unknown; no MTF, noise, compression or perceptual pass is produced.
111
+ */
112
+ export declare function calculatePrintRegionDetail(value: PrintRegionDetailInput): CalculationResult<PrintRegionDetailAssessment>;
113
+ //# sourceMappingURL=print-detail.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"print-detail.d.ts","sourceRoot":"","sources":["../../src/output/print-detail.ts"],"names":[],"mappings":"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"}