@photivra/engine 2.19.0 → 2.20.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +112 -1
- package/CITATION.cff +1 -1
- package/NODE_SUPPORT.md +7 -5
- package/README.md +6 -6
- package/SECURITY.md +1 -1
- package/THIRD_PARTY.md +14 -10
- package/dist/capture/dng-lens-correction-opcodes.d.ts +32 -0
- package/dist/capture/dng-lens-correction-opcodes.js +119 -0
- package/dist/capture/dng-lens-correction-opcodes.js.map +1 -0
- package/dist/capture/native-environment-lean.js +1 -5
- package/dist/capture/native-environment-lean.js.map +1 -1
- package/dist/capture/native-raw-dng.d.ts +6 -0
- package/dist/capture/native-raw-dng.js +16 -2
- package/dist/capture/native-raw-dng.js.map +1 -1
- package/dist/capture/sensor-raw-producer.js +3 -5
- package/dist/capture/sensor-raw-producer.js.map +1 -1
- package/dist/core/shared-helpers.d.ts +2 -0
- package/dist/core/shared-helpers.js +4 -0
- package/dist/core/shared-helpers.js.map +1 -1
- package/dist/core/version.d.ts +1 -1
- package/dist/core/version.js +1 -1
- package/dist/core/version.js.map +1 -1
- package/dist/equipment/generic-lens-catalogue.d.ts +8 -2
- package/dist/equipment/generic-lens-catalogue.js +31 -2
- package/dist/equipment/generic-lens-catalogue.js.map +1 -1
- package/dist/equipment/generic-tier-assets.js +2 -3
- package/dist/equipment/generic-tier-assets.js.map +1 -1
- package/dist/equipment/generic-tier-presets.js +2 -3
- package/dist/equipment/generic-tier-presets.js.map +1 -1
- package/dist/facade/display-view-gpu.d.ts +7 -4
- package/dist/facade/display-view-gpu.js +4 -4
- package/dist/facade/display-view-gpu.js.map +1 -1
- package/dist/facade/display-view-lens-signal.d.ts +1 -1
- package/dist/facade/display-view-lens-signal.js +5 -3
- package/dist/facade/display-view-lens-signal.js.map +1 -1
- package/dist/facade/display-view.d.ts +3 -1
- package/dist/facade/display-view.js +1 -1
- package/dist/facade/display-view.js.map +1 -1
- package/dist/facade/fast-methods.d.ts +50 -0
- package/dist/facade/fast-methods.js +50 -0
- package/dist/facade/fast-methods.js.map +1 -0
- package/dist/facade/fast-resolution.d.ts +12 -0
- package/dist/facade/fast-resolution.js +18 -0
- package/dist/facade/fast-resolution.js.map +1 -0
- package/dist/facade/generic-lens-capture.d.ts +3 -2
- package/dist/facade/generic-lens-capture.js +3 -2
- package/dist/facade/generic-lens-capture.js.map +1 -1
- package/dist/facade/simulate-capture.d.ts +51 -11
- package/dist/facade/simulate-capture.js +144 -75
- package/dist/facade/simulate-capture.js.map +1 -1
- package/dist/facade/simulate-display-view.d.ts +3 -2
- package/dist/facade/simulate-display-view.js +22 -12
- package/dist/facade/simulate-display-view.js.map +1 -1
- package/dist/index.d.ts +7 -0
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -1
- package/dist/optics/aperture-diameter.d.ts +47 -0
- package/dist/optics/aperture-diameter.js +50 -0
- package/dist/optics/aperture-diameter.js.map +1 -0
- package/dist/optics/detail-limit.d.ts +182 -0
- package/dist/optics/detail-limit.js +336 -0
- package/dist/optics/detail-limit.js.map +1 -0
- package/dist/optics/generic-lens-psf.d.ts +18 -2
- package/dist/optics/generic-lens-psf.js +25 -2
- package/dist/optics/generic-lens-psf.js.map +1 -1
- package/dist/optics/scene-to-sensor-irradiance.d.ts +13 -0
- package/dist/optics/scene-to-sensor-irradiance.js +7 -0
- package/dist/optics/scene-to-sensor-irradiance.js.map +1 -1
- package/dist/output/crop-to-match-focal-length.d.ts +62 -0
- package/dist/output/crop-to-match-focal-length.js +63 -0
- package/dist/output/crop-to-match-focal-length.js.map +1 -0
- package/dist/output/developed-lens-corrections.js +2 -2
- package/dist/output/developed-lens-corrections.js.map +1 -1
- package/dist/output/generic-lens-corrections.d.ts +3 -1
- package/dist/output/generic-lens-corrections.js +8 -4
- package/dist/output/generic-lens-corrections.js.map +1 -1
- package/dist/output/lens-corrections.d.ts +12 -2
- package/dist/output/lens-corrections.js +22 -7
- package/dist/output/lens-corrections.js.map +1 -1
- package/dist/output/print-contrast-reference.js +1 -1
- package/dist/output/print-contrast-reference.js.map +1 -1
- package/dist/output/print-size-blur-noise.d.ts +110 -0
- package/dist/output/print-size-blur-noise.js +138 -0
- package/dist/output/print-size-blur-noise.js.map +1 -0
- package/dist/sensor/eqe-electron-rate.js +1 -7
- package/dist/sensor/eqe-electron-rate.js.map +1 -1
- package/dist/sensor/exposure-window.d.ts +2 -0
- package/dist/sensor/exposure-window.js +2 -2
- package/dist/sensor/exposure-window.js.map +1 -1
- package/dist/sensor/readout-timing.js +2 -23
- package/dist/sensor/readout-timing.js.map +1 -1
- package/dist/sensor/response-application-compatibility.js +1 -6
- package/dist/sensor/response-application-compatibility.js.map +1 -1
- package/dist/sensor/responsivity-photocurrent.js +1 -7
- package/dist/sensor/responsivity-photocurrent.js.map +1 -1
- package/dist/sensor/sensor-characteristics.d.ts +137 -0
- package/dist/sensor/sensor-characteristics.js +115 -0
- package/dist/sensor/sensor-characteristics.js.map +1 -0
- package/dist/sensor/spatial-sample-reduction.js +1 -5
- package/dist/sensor/spatial-sample-reduction.js.map +1 -1
- package/dist/sensor/spectral-quadrature.js +1 -6
- package/dist/sensor/spectral-quadrature.js.map +1 -1
- package/dist/sensor/temporal-photo-signal.d.ts +3 -0
- package/dist/sensor/temporal-photo-signal.js +5 -2
- package/dist/sensor/temporal-photo-signal.js.map +1 -1
- package/dist/stabilization/system.d.ts +9 -0
- package/dist/stabilization/system.js +5 -6
- package/dist/stabilization/system.js.map +1 -1
- package/docs/AGENT_GUIDE.md +4 -0
- package/docs/API_REFERENCE.md +76 -2
- package/docs/QUICK_START.md +88 -6
- package/docs/USAGE.md +65 -2
- package/docs/api/capture-native-raw-dng.md +6 -0
- package/docs/api/core-version.md +1 -1
- package/docs/api/equipment-generic-lens-catalogue.md +7 -2
- package/docs/api/exports.json +152 -2
- package/docs/api/facade-display-view-gpu.md +5 -2
- package/docs/api/facade-fast-methods.md +91 -0
- package/docs/api/facade-simulate-capture.md +36 -11
- package/docs/api/facade-simulate-display-view.md +3 -2
- package/docs/api/optics-aperture-diameter.md +51 -0
- package/docs/api/optics-detail-limit.md +203 -0
- package/docs/api/output-crop-to-match-focal-length.md +67 -0
- package/docs/api/output-generic-lens-corrections.md +3 -1
- package/docs/api/output-lens-corrections.md +11 -1
- package/docs/api/output-print-size-blur-noise.md +115 -0
- package/docs/api/sensor-sensor-characteristics.md +105 -0
- package/llms.txt +4 -0
- package/package.json +1 -1
|
@@ -22,6 +22,12 @@ export interface SerializeNativeRawDngInput {
|
|
|
22
22
|
capturedAtUtc?: string;
|
|
23
23
|
/** Optional (2.4) caller text: description, software, copyright, comment (see the module notes). If omitted, no text is added. */
|
|
24
24
|
textMetadata?: OutputTextMetadata;
|
|
25
|
+
/**
|
|
26
|
+
* Optional (#587) OpcodeList3 (tag 51022) bytes, for example `createDngLensCorrectionOpcodes(...).opcodeList3`: a big-endian DNG
|
|
27
|
+
* opcode list (DNG 1.3.0.0+, "Opcode List Processing") that readers apply to the demosaiced stage-3 image. Only its framing is
|
|
28
|
+
* checked (count, per-opcode headers and parameter sizes filling the bytes exactly). The RAW codes are unchanged. If omitted, no tag.
|
|
29
|
+
*/
|
|
30
|
+
opcodeList3?: Uint8Array;
|
|
25
31
|
}
|
|
26
32
|
export interface NativeRawDng {
|
|
27
33
|
schemaVersion: typeof NATIVE_RAW_DNG_SCHEMA_VERSION;
|
|
@@ -31,6 +31,8 @@
|
|
|
31
31
|
* §1.1.6, Table 13) always carries every given field in UTF-8: `dc:description` (the full ImageDescription text,
|
|
32
32
|
* statement first, as XMP Part 3 §3.2.3 maps tag 270), `dc:rights`, `xmp:CreatorTool` and `exif:UserComment`.
|
|
33
33
|
* The Software tag keeps naming the engine's writer. Without `textMetadata` the bytes are unchanged.
|
|
34
|
+
* - Opcodes (#587, only with `opcodeList3`): the caller's big-endian DNG opcode list as OpcodeList3 (51022, UNDEFINED), framing checked
|
|
35
|
+
* (count, 16-byte headers, parameter sizes filling the bytes). Without it the bytes are unchanged.
|
|
34
36
|
* @see docs/NATIVE_RAW_AND_PRINT.md for the tag table, limits and the round trip through parseDngRawImage.
|
|
35
37
|
*/
|
|
36
38
|
import { InvalidConfigurationError } from "../core/configuration-error.js";
|
|
@@ -64,7 +66,19 @@ const ORIENTATION = { landscape: 1, "portrait-clockwise": 6, "landscape-inverted
|
|
|
64
66
|
* where its value comes from. The input arrays are copied before the first await.
|
|
65
67
|
*/
|
|
66
68
|
export async function serializeNativeRawDng(input) {
|
|
67
|
-
const r = requireAllowlistedRecord(input, ["raw", "colorProfile", "noise", "baselineExposureEv", "capturedAtUtc", "textMetadata"], "Invalid native RAW DNG input.");
|
|
69
|
+
const r = requireAllowlistedRecord(input, ["raw", "colorProfile", "noise", "baselineExposureEv", "capturedAtUtc", "textMetadata", "opcodeList3"], "Invalid native RAW DNG input.");
|
|
70
|
+
let opcodeList3;
|
|
71
|
+
if (r.opcodeList3 !== undefined) {
|
|
72
|
+
if (!(r.opcodeList3 instanceof Uint8Array) || r.opcodeList3.length < 4)
|
|
73
|
+
fail("opcodeList3 must be a Uint8Array opcode list.");
|
|
74
|
+
opcodeList3 = r.opcodeList3.slice();
|
|
75
|
+
const v = new DataView(opcodeList3.buffer);
|
|
76
|
+
let at = 4;
|
|
77
|
+
for (let n = v.getUint32(0); n > 0 && at <= opcodeList3.length; n--)
|
|
78
|
+
at = at + 16 > opcodeList3.length ? Infinity : at + 16 + v.getUint32(at + 12);
|
|
79
|
+
if (at !== opcodeList3.length)
|
|
80
|
+
fail("opcodeList3 is not a whole DNG opcode list (big-endian count, 16-byte headers, parameter sizes).");
|
|
81
|
+
}
|
|
68
82
|
const raw = r.raw, plan = validatePackedNativeRaw(raw);
|
|
69
83
|
const mosaic = plan.frame.colorSamplingProfile.layout;
|
|
70
84
|
if (mosaic.kind === "periodic-mosaic")
|
|
@@ -179,7 +193,7 @@ export async function serializeNativeRawDng(input) {
|
|
|
179
193
|
rationals(50730, true, [baseline]), numbers(50778, 3, [21]),
|
|
180
194
|
rawBytes(50781, 1, Uint8Array.from(rawDataUniqueId.match(/../g).map((s) => parseInt(s, 16)))),
|
|
181
195
|
numbers(50829, 4, [active.y, active.x, active.y + active.height, active.x + active.width]),
|
|
182
|
-
rationals(50964, true, forward.flat()), ...(noiseProfile ? [doubles(51041, noiseProfile)] : []), ...textTags], exif, pixels);
|
|
196
|
+
rationals(50964, true, forward.flat()), ...(noiseProfile ? [doubles(51041, noiseProfile)] : []), ...(opcodeList3 ? [rawBytes(51022, 7, opcodeList3)] : []), ...textTags], exif, pixels);
|
|
183
197
|
return Object.freeze({ schemaVersion: NATIVE_RAW_DNG_SCHEMA_VERSION, mediaType: "image/dng", bytes, sha256: await sha256(bytes), rawDataUniqueId, uniqueCameraModel,
|
|
184
198
|
activeArea: { ...active }, defaultCrop: { ...crop }, orientation, blackLevels, whiteLevel, cfaPattern, colorMatrix1: stored(colorMatrixTag), asShotNeutral: stored(neutralTag),
|
|
185
199
|
noiseProfile, unrepresentedSaturationFlagCount: unrepresented, source: "packed-native-raw", linearMasterDeclared: false });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"native-raw-dng.js","sourceRoot":"","sources":["../../src/capture/native-raw-dng.ts"],"names":[],"mappings":"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","sourcesContent":["// SPDX-License-Identifier: Apache-2.0\n// This product includes DNG technology under license by Adobe.\n\n/**\n * Writes a packed native RAW (`NativeRawOutput`, from the native RAW or native environment RAW tasks) as a\n * lossless, uncompressed 16-bit DNG with a CFA (colour filter array) mosaic.\n *\n * The file describes only what the packed RAW, the caller's declared colour profile and noise model\n * contain. It never claims a linear float master as its source, or a developed image. The tag layout reuses\n * the TIFF/DNG writers of the paired photographic export (`packExportTiff`, DNG 1.4 tags, Adobe DNG\n * Specification 1.7.1.0):\n *\n * - CFA geometry: CFARepeatPatternDim 2×2, CFAPattern and BlackLevel phases relative to the ActiveArea\n * origin (DNG applies them to the stage-2, ActiveArea-cropped image); DefaultCropOrigin/Size are the\n * capture's oriented output crop mapped back to stored (native) coordinates; Orientation from the capture.\n * - Levels: BlackLevel per 2×2 phase (the packed per-site black levels must repeat with the CFA tile).\n * WhiteLevel is the smallest per-phase effective white code, so no channel is reported as unsaturated\n * above its own saturation point. DNG cannot represent a saturation flag on a site whose code is below\n * WhiteLevel; such sites are counted in `unrepresentedSaturationFlagCount`.\n * - Colour: ColorMatrix1 = (camera→XYZ)⁻¹ with CalibrationIlluminant1 D65 (21), ForwardMatrix1 =\n * Bradford(D65→D50)·M·diag(w), AnalogBalance 1, AsShotNeutral from the capture's white-balance intent\n * (the same operator native development uses), BaselineExposure as declared (default 0).\n * - Noise: NoiseProfile (51041) per CFA plane, var(x) = S·x + O for x = (code − black)/(WhiteLevel − black),\n * S = 1/(G·span), O = (σ_read²/G² + 1/12)/span², written only when the caller supplies each channel's\n * output-referred conversion gain G (electrons per code) and read noise σ_read (electrons). The model\n * covers only Poisson photo and dark shot noise, Gaussian read noise and uniform quantization. It is an\n * approximation: PRNU (photo-response non-uniformity), DSNU (dark-signal non-uniformity) and other\n * fixed-pattern noise are not included.\n * - Text (2.4, only with `textMetadata`): the caller's description is appended to ImageDescription after the\n * simulated-RAW statement and the copyright is written as Copyright (33432), each only when it is printable\n * ASCII (TIFF 6.0 §2: ASCII fields hold 7-bit codes). An XMP packet in tag 700 (BYTE; XMP Specification Part 3\n * §1.1.6, Table 13) always carries every given field in UTF-8: `dc:description` (the full ImageDescription text,\n * statement first, as XMP Part 3 §3.2.3 maps tag 270), `dc:rights`, `xmp:CreatorTool` and `exif:UserComment`.\n * The Software tag keeps naming the engine's writer. Without `textMetadata` the bytes are unchanged.\n * @see docs/NATIVE_RAW_AND_PRINT.md for the tag table, limits and the round trip through parseDngRawImage.\n */\n\nimport { InvalidConfigurationError } from \"../core/configuration-error.js\";\nimport { requireAllowlistedRecord } from \"../core/record-validation.js\";\nimport { ENGINE_API_VERSION } from \"../core/version.js\";\nimport { resolveCaptureColorModel } from \"../color/capture-color.js\";\nimport { invertSensorColorMatrix, prepareSensorColorDevelopment, sensorColorReferenceWhite } from \"../color/sensor-color-development.js\";\nimport { ICC_D50_WHITE_XYZ } from \"../color/srgb-icc.js\";\nimport { chromaticAdaptationMatrix } from \"../color/chromatic-adaptation.js\";\nimport { transformOrientedRasterRectToNative } from \"../output/capture-geometry.js\";\nimport type { NativeRawOutput } from \"./native-raw.js\";\nimport { checkNativeRawIntegrity, validatePackedNativeRaw } from \"./native-raw-development.js\";\nimport { parseExportSensorColorProfile, type ExportSensorColorProfile } from \"./photographic-export.js\";\nimport { parseOutputTextMetadata, xmpTextMetadataPacket, type OutputTextMetadata } from \"../output/text-metadata.js\";\nimport { packExportTiff, exportTiffAscii as ascii, exportTiffNumbers as numbers, exportTiffRationals as rationals,\n exportTiffBytes as rawBytes, exportTiffDoubles as doubles } from \"./export-tiff.js\";\n\nexport const NATIVE_RAW_DNG_SCHEMA_VERSION = \"1.0.0\" as const;\n\n/** Output-referred noise parameters of one CFA channel (see the module notes). */\nexport interface NativeRawDngChannelNoise {\n /** Electrons per output RAW code (system conversion gain divided by any post-ADC digital gain). */\n conversionGainElectronsPerCode: number;\n /** Combined RMS read noise, electrons. */\n readNoiseRmsElectrons: number;\n}\nexport interface SerializeNativeRawDngInput {\n /** Packed native RAW. It is read, never taken over or modified. */\n raw: NativeRawOutput;\n /** Declared camera→XYZ (D65) colour profile for the RAW's CFA. Native development uses the same profile. */\n colorProfile: ExportSensorColorProfile;\n /** Optional NoiseProfile parameters by channel ID. If omitted, no NoiseProfile tag is written. */\n noise?: Readonly<Record<string, NativeRawDngChannelNoise>>;\n /** BaselineExposure in EV (exposure value stops). Default 0: the RAW white level maps to display white, as in native development. */\n baselineExposureEv?: number;\n /** Optional UTC time of the capture, exactly YYYY-MM-DDTHH:mm:ss.sssZ. If omitted, no date tags are written; the engine never makes up a clock time. */\n capturedAtUtc?: string;\n /** Optional (2.4) caller text: description, software, copyright, comment (see the module notes). If omitted, no text is added. */\n textMetadata?: OutputTextMetadata;\n}\nexport interface NativeRawDng {\n schemaVersion: typeof NATIVE_RAW_DNG_SCHEMA_VERSION;\n mediaType: \"image/dng\";\n bytes: Uint8Array;\n sha256: string;\n /** RawDataUniqueID (32 hex digits): the first 128 bits of SHA-256 over a fixed header and the little-endian codes. */\n rawDataUniqueId: string;\n uniqueCameraModel: string;\n /** Stored geometry, levels and colour values exactly as written (rationals as numerator/denominator). */\n activeArea: { x: number; y: number; width: number; height: number };\n defaultCrop: { x: number; y: number; width: number; height: number };\n orientation: number;\n blackLevels: readonly number[];\n whiteLevel: number;\n cfaPattern: readonly number[];\n colorMatrix1: readonly number[];\n asShotNeutral: readonly number[];\n noiseProfile: readonly number[] | null;\n /** Sites flagged saturated whose code is below WhiteLevel; DNG has no field for them. */\n unrepresentedSaturationFlagCount: number;\n source: \"packed-native-raw\";\n linearMasterDeclared: false;\n}\n\nfunction fail(message: string): never { throw new InvalidConfigurationError(\"Native RAW DNG: \" + message); }\nasync function sha256(bytes: Uint8Array): Promise<string> {\n const subtle = globalThis.crypto?.subtle;\n if (!subtle) fail(\"needs crypto.subtle (a secure browser context or Node 22+).\");\n return Array.from(new Uint8Array(await subtle.digest(\"SHA-256\", bytes as Uint8Array<ArrayBuffer>)), (b) => b.toString(16).padStart(2, \"0\")).join(\"\");\n}\n/** Values exactly as stored by a RATIONAL/SRATIONAL tag (numerator / denominator), so reported metadata equals what a reader decodes. */\nfunction stored(tag: ReturnType<typeof rationals>): number[] {\n const view = new DataView(tag.data.buffer, tag.data.byteOffset, tag.data.byteLength);\n return Array.from({ length: tag.count }, (_, i) => (tag.type === 10 ? view.getInt32(i * 8, true) : view.getUint32(i * 8, true)) / view.getUint32(i * 8 + 4, true));\n}\nconst ORIENTATION = { landscape: 1, \"portrait-clockwise\": 6, \"landscape-inverted\": 3, \"portrait-counter-clockwise\": 8 } as const;\n\n/**\n * Writes packed native RAW codes as a lossless, uncompressed CFA DNG. The module notes list every tag and\n * where its value comes from. The input arrays are copied before the first await.\n */\nexport async function serializeNativeRawDng(input: SerializeNativeRawDngInput): Promise<NativeRawDng> {\n const r = requireAllowlistedRecord(input, [\"raw\", \"colorProfile\", \"noise\", \"baselineExposureEv\", \"capturedAtUtc\", \"textMetadata\"], \"Invalid native RAW DNG input.\");\n const raw = r.raw as NativeRawOutput, plan = validatePackedNativeRaw(raw);\n const mosaic = plan.frame.colorSamplingProfile.layout;\n if (mosaic.kind === \"periodic-mosaic\") checkNativeRawIntegrity(raw, plan.exposure.geometry.nativeRaster.pixelWidth, mosaic.repeatWidthSites, mosaic.repeatHeightSites, 0, plan.exposure.geometry.nativeRaster.pixelHeight);\n const color = parseExportSensorColorProfile(r.colorProfile), frame = plan.frame, layout = frame.colorSamplingProfile.layout;\n if (layout.kind !== \"periodic-mosaic\" || layout.repeatWidthSites !== 2 || layout.repeatHeightSites !== 2 ||\n [...layout.siteChannelIds].sort().join() !== \"blue,green,green,red\" || color.channelIds.join() !== \"red,green,blue\")\n fail(\"supports 2×2 RGB Bayer CFAs with red, green, blue colour-profile channels only.\");\n if (color.colorSamplingProfileId !== frame.colorSamplingProfile.profileId) fail(\"colour profile is not bound to the RAW's CFA.\");\n const baseline = r.baselineExposureEv === undefined ? 0 : r.baselineExposureEv;\n if (typeof baseline !== \"number\" || !Number.isFinite(baseline) || Math.abs(baseline) > 16) fail(\"baselineExposureEv must be finite within ±16.\");\n const capturedAtUtc = r.capturedAtUtc as string | undefined;\n if (capturedAtUtc !== undefined && (typeof capturedAtUtc !== \"string\" || !/^\\d{4}-\\d\\d-\\d\\dT\\d\\d:\\d\\d:\\d\\d\\.\\d{3}Z$/.test(capturedAtUtc) || Number.isNaN(Date.parse(capturedAtUtc))))\n fail(\"capturedAtUtc must be YYYY-MM-DDTHH:mm:ss.sssZ.\");\n let text: Readonly<OutputTextMetadata> | undefined;\n try { text = parseOutputTextMetadata(r.textMetadata, \"textMetadata\"); } catch (error) { fail((error as Error).message); }\n\n const native = plan.exposure.geometry.nativeRaster, width = native.pixelWidth, height = native.pixelHeight, g = plan.exposure.resolvedGeometry;\n const active = g.activeCapture.nativeRect;\n const crop = transformOrientedRasterRectToNative({ rect: g.output.cropRect, nativeRaster: g.activeCapture.raster, orientation: plan.exposure.geometry.orientation });\n // Copy before any await: the caller keeps ownership of the packed arrays.\n const codes = raw.codes.slice(), blacks = raw.blackLevels.slice(), flags = raw.saturationFlags.slice(), whiteByPhase = Array.from(raw.effectiveSaturationCodes);\n\n // Levels per CFA phase, relative to the active area. The black-level tile must repeat exactly.\n const blackLevels: number[] = [], cfaPattern: number[] = [], whites: number[] = [], phaseChannel: string[] = [];\n for (let py = 0; py < 2; py++) for (let px = 0; px < 2; px++) {\n const ax = (active.x + px) % 2, ay = (active.y + py) % 2;\n const black = blacks[ay * width + ax]!;\n for (let y = ay; y < height; y += 2) for (let x = ax; x < width; x += 2) if (blacks[y * width + x] !== black) fail(\"per-site black levels do not repeat with the 2×2 CFA tile.\");\n const channel = layout.siteChannelIds[ay * 2 + ax]!;\n blackLevels.push(black); whites.push(whiteByPhase[ay * 2 + ax]!); phaseChannel.push(channel); cfaPattern.push([\"red\", \"green\", \"blue\"].indexOf(channel));\n }\n const whiteLevel = Math.min(...whites);\n if (blackLevels.some((b) => b >= whiteLevel)) fail(\"black level must be below the effective WhiteLevel.\");\n let unrepresented = 0;\n for (let i = 0; i < codes.length; i++) if (flags[i] !== 0 && codes[i]! < whiteLevel) unrepresented++;\n\n // NoiseProfile: one (S, O) pair per CFA plane colour, only when every phase of a channel shares its black level.\n let noiseProfile: number[] | null = null;\n if (r.noise !== undefined) {\n const noise = requireAllowlistedRecord(r.noise, [\"red\", \"green\", \"blue\"], \"Invalid native RAW DNG noise.\") as Record<string, NativeRawDngChannelNoise>;\n noiseProfile = [];\n for (const channel of [\"red\", \"green\", \"blue\"]) {\n const n = noise[channel];\n if (!n) fail(\"noise needs red, green and blue entries.\");\n requireAllowlistedRecord(n, [\"conversionGainElectronsPerCode\", \"readNoiseRmsElectrons\"], \"Invalid native RAW DNG channel noise.\");\n const gain = n.conversionGainElectronsPerCode, read = n.readNoiseRmsElectrons;\n if (typeof gain !== \"number\" || !Number.isFinite(gain) || gain <= 0 || typeof read !== \"number\" || !Number.isFinite(read) || read < 0) fail(\"noise gain must be positive and read noise non-negative.\");\n const phaseBlacks = blackLevels.filter((_, i) => phaseChannel[i] === channel);\n if (phaseBlacks.some((b) => b !== phaseBlacks[0])) { noiseProfile = null; break; }\n const span = whiteLevel - phaseBlacks[0]!;\n noiseProfile.push(1 / (gain * span), (read * read / (gain * gain) + 1 / 12) / (span * span));\n }\n }\n\n // Colour tags from the declared profile and the capture's white-balance intent.\n const m = color.normalizedCameraChannelsToXyz, colorMatrix = invertSensorColorMatrix(m), intent = plan.exposure.whiteBalanceIntent;\n const development = prepareSensorColorDevelopment(m, intent ? [intent.channelGains.red, intent.channelGains.green, intent.channelGains.blue] : null);\n const cameraWhite = sensorColorReferenceWhite(colorMatrix);\n const chad = chromaticAdaptationMatrix({ transform: \"bradford\", sourceWhiteXyz: resolveCaptureColorModel().referenceWhiteXyz,\n destinationWhiteXyz: { x: ICC_D50_WHITE_XYZ[0], y: 1, z: ICC_D50_WHITE_XYZ[2] } }).matrix;\n const forward = chad.map((row) => [0, 1, 2].map((j) => row.reduce((sum, x, k) => sum + x * m[k]![j]! * cameraWhite[j]!, 0)));\n\n const pixels = new Uint8Array(codes.length * 2), view = new DataView(pixels.buffer);\n codes.forEach((c, i) => view.setUint16(i * 2, c, true));\n const header = new TextEncoder().encode(JSON.stringify({ schema: \"photivra-native-raw-data-id-0.1\", width, height, cfa: layout.siteChannelIds, containerBitDepth: 16 }));\n const idInput = new Uint8Array(header.length + pixels.length); idInput.set(header); idInput.set(pixels, header.length);\n const rawDataUniqueId = (await sha256(idInput)).slice(0, 32);\n const colorHash = (await sha256(new TextEncoder().encode(JSON.stringify(color)))).slice(0, 16);\n const uniqueCameraModel = \"Photivra Virtual Camera \" + color.profileId + \" \" + color.profileVersion + \" \" + colorHash;\n const orientation = ORIENTATION[plan.exposure.geometry.orientation];\n const e = plan.exposure.exposure, software = \"Photivra \" + ENGINE_API_VERSION;\n const statement = \"Simulated capture: packed native RAW from the Photivra engine (\" + frame.frameId + \"). Source \" + plan.exposure.source.kind +\n \"; no linear master image or developed rendering is stored.\";\n const printableAscii = (value: string | undefined): value is string => value !== undefined && /^[\\x20-\\x7e]*$/.test(value);\n const description = printableAscii(text?.description) ? statement + \" \" + text.description : statement;\n const textTags = text === undefined ? [] : [\n ...(printableAscii(text.copyright) ? [ascii(33432, text.copyright)] : []),\n rawBytes(700, 1, xmpTextMetadataPacket({ ...text, description: text.description === undefined ? statement : statement + \" \" + text.description }))];\n\n const exif = [rawBytes(36864, 7, new TextEncoder().encode(\"0232\")), rationals(33434, false, [e.shutterSeconds]), rationals(33437, false, [e.aperture]),\n ...(Number.isInteger(e.iso) && e.iso >= 1 && e.iso <= 65535 ? [numbers(34855, 3, [e.iso]), numbers(34864, 3, [2]), numbers(34866, 4, [e.iso])] : []),\n rationals(37386, false, [e.focalLengthMm]), numbers(40961, 3, [65535]), numbers(40962, 4, [crop.width]), numbers(40963, 4, [crop.height]),\n ...(capturedAtUtc === undefined ? [] : [ascii(36867, capturedAtUtc.slice(0, 19).replaceAll(\"-\", \":\").replace(\"T\", \" \")), ascii(36881, \"+00:00\"), ascii(37521, capturedAtUtc.slice(20, 23))])];\n const colorMatrixTag = rationals(50721, true, colorMatrix.flat()), neutralTag = rationals(50728, false, [...development.asShotNeutral]);\n const bytes = packExportTiff([ascii(270, description), ascii(271, \"Photivra\"), ascii(272, \"Photivra Virtual Camera\"), ascii(305, software), numbers(274, 3, [orientation]),\n numbers(254, 4, [0]), numbers(256, 4, [width]), numbers(257, 4, [height]), numbers(258, 3, [16]), numbers(259, 3, [1]), numbers(262, 3, [32803]),\n { ...numbers(273, 4, [0]), pointer: \"pixels\" as const }, numbers(277, 3, [1]), numbers(278, 4, [height]), numbers(279, 4, [pixels.length]),\n numbers(284, 3, [1]), numbers(339, 3, [1]), numbers(33421, 3, [2, 2]), numbers(33422, 1, cfaPattern),\n numbers(50706, 1, [1, 4, 0, 0]), numbers(50707, 1, [1, 1, 0, 0]), ascii(50708, uniqueCameraModel), numbers(50710, 1, [0, 1, 2]), numbers(50711, 3, [1]),\n numbers(50713, 3, [2, 2]), rationals(50714, false, blackLevels), numbers(50717, 4, [whiteLevel]), numbers(50719, 4, [crop.x, crop.y]), numbers(50720, 4, [crop.width, crop.height]),\n colorMatrixTag, rationals(50727, false, [1, 1, 1]), neutralTag,\n rationals(50730, true, [baseline]), numbers(50778, 3, [21]),\n rawBytes(50781, 1, Uint8Array.from(rawDataUniqueId.match(/../g)!.map((s) => parseInt(s, 16)))),\n numbers(50829, 4, [active.y, active.x, active.y + active.height, active.x + active.width]),\n rationals(50964, true, forward.flat()), ...(noiseProfile ? [doubles(51041, noiseProfile)] : []), ...textTags], exif, pixels);\n return Object.freeze({ schemaVersion: NATIVE_RAW_DNG_SCHEMA_VERSION, mediaType: \"image/dng\" as const, bytes, sha256: await sha256(bytes), rawDataUniqueId, uniqueCameraModel,\n activeArea: { ...active }, defaultCrop: { ...crop }, orientation, blackLevels, whiteLevel, cfaPattern, colorMatrix1: stored(colorMatrixTag), asShotNeutral: stored(neutralTag),\n noiseProfile, unrepresentedSaturationFlagCount: unrepresented, source: \"packed-native-raw\" as const, linearMasterDeclared: false as const });\n}\n"]}
|
|
1
|
+
{"version":3,"file":"native-raw-dng.js","sourceRoot":"","sources":["../../src/capture/native-raw-dng.ts"],"names":[],"mappings":"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","sourcesContent":["// SPDX-License-Identifier: Apache-2.0\n// This product includes DNG technology under license by Adobe.\n\n/**\n * Writes a packed native RAW (`NativeRawOutput`, from the native RAW or native environment RAW tasks) as a\n * lossless, uncompressed 16-bit DNG with a CFA (colour filter array) mosaic.\n *\n * The file describes only what the packed RAW, the caller's declared colour profile and noise model\n * contain. It never claims a linear float master as its source, or a developed image. The tag layout reuses\n * the TIFF/DNG writers of the paired photographic export (`packExportTiff`, DNG 1.4 tags, Adobe DNG\n * Specification 1.7.1.0):\n *\n * - CFA geometry: CFARepeatPatternDim 2×2, CFAPattern and BlackLevel phases relative to the ActiveArea\n * origin (DNG applies them to the stage-2, ActiveArea-cropped image); DefaultCropOrigin/Size are the\n * capture's oriented output crop mapped back to stored (native) coordinates; Orientation from the capture.\n * - Levels: BlackLevel per 2×2 phase (the packed per-site black levels must repeat with the CFA tile).\n * WhiteLevel is the smallest per-phase effective white code, so no channel is reported as unsaturated\n * above its own saturation point. DNG cannot represent a saturation flag on a site whose code is below\n * WhiteLevel; such sites are counted in `unrepresentedSaturationFlagCount`.\n * - Colour: ColorMatrix1 = (camera→XYZ)⁻¹ with CalibrationIlluminant1 D65 (21), ForwardMatrix1 =\n * Bradford(D65→D50)·M·diag(w), AnalogBalance 1, AsShotNeutral from the capture's white-balance intent\n * (the same operator native development uses), BaselineExposure as declared (default 0).\n * - Noise: NoiseProfile (51041) per CFA plane, var(x) = S·x + O for x = (code − black)/(WhiteLevel − black),\n * S = 1/(G·span), O = (σ_read²/G² + 1/12)/span², written only when the caller supplies each channel's\n * output-referred conversion gain G (electrons per code) and read noise σ_read (electrons). The model\n * covers only Poisson photo and dark shot noise, Gaussian read noise and uniform quantization. It is an\n * approximation: PRNU (photo-response non-uniformity), DSNU (dark-signal non-uniformity) and other\n * fixed-pattern noise are not included.\n * - Text (2.4, only with `textMetadata`): the caller's description is appended to ImageDescription after the\n * simulated-RAW statement and the copyright is written as Copyright (33432), each only when it is printable\n * ASCII (TIFF 6.0 §2: ASCII fields hold 7-bit codes). An XMP packet in tag 700 (BYTE; XMP Specification Part 3\n * §1.1.6, Table 13) always carries every given field in UTF-8: `dc:description` (the full ImageDescription text,\n * statement first, as XMP Part 3 §3.2.3 maps tag 270), `dc:rights`, `xmp:CreatorTool` and `exif:UserComment`.\n * The Software tag keeps naming the engine's writer. Without `textMetadata` the bytes are unchanged.\n * - Opcodes (#587, only with `opcodeList3`): the caller's big-endian DNG opcode list as OpcodeList3 (51022, UNDEFINED), framing checked\n * (count, 16-byte headers, parameter sizes filling the bytes). Without it the bytes are unchanged.\n * @see docs/NATIVE_RAW_AND_PRINT.md for the tag table, limits and the round trip through parseDngRawImage.\n */\n\nimport { InvalidConfigurationError } from \"../core/configuration-error.js\";\nimport { requireAllowlistedRecord } from \"../core/record-validation.js\";\nimport { ENGINE_API_VERSION } from \"../core/version.js\";\nimport { resolveCaptureColorModel } from \"../color/capture-color.js\";\nimport { invertSensorColorMatrix, prepareSensorColorDevelopment, sensorColorReferenceWhite } from \"../color/sensor-color-development.js\";\nimport { ICC_D50_WHITE_XYZ } from \"../color/srgb-icc.js\";\nimport { chromaticAdaptationMatrix } from \"../color/chromatic-adaptation.js\";\nimport { transformOrientedRasterRectToNative } from \"../output/capture-geometry.js\";\nimport type { NativeRawOutput } from \"./native-raw.js\";\nimport { checkNativeRawIntegrity, validatePackedNativeRaw } from \"./native-raw-development.js\";\nimport { parseExportSensorColorProfile, type ExportSensorColorProfile } from \"./photographic-export.js\";\nimport { parseOutputTextMetadata, xmpTextMetadataPacket, type OutputTextMetadata } from \"../output/text-metadata.js\";\nimport { packExportTiff, exportTiffAscii as ascii, exportTiffNumbers as numbers, exportTiffRationals as rationals,\n exportTiffBytes as rawBytes, exportTiffDoubles as doubles } from \"./export-tiff.js\";\n\nexport const NATIVE_RAW_DNG_SCHEMA_VERSION = \"1.0.0\" as const;\n\n/** Output-referred noise parameters of one CFA channel (see the module notes). */\nexport interface NativeRawDngChannelNoise {\n /** Electrons per output RAW code (system conversion gain divided by any post-ADC digital gain). */\n conversionGainElectronsPerCode: number;\n /** Combined RMS read noise, electrons. */\n readNoiseRmsElectrons: number;\n}\nexport interface SerializeNativeRawDngInput {\n /** Packed native RAW. It is read, never taken over or modified. */\n raw: NativeRawOutput;\n /** Declared camera→XYZ (D65) colour profile for the RAW's CFA. Native development uses the same profile. */\n colorProfile: ExportSensorColorProfile;\n /** Optional NoiseProfile parameters by channel ID. If omitted, no NoiseProfile tag is written. */\n noise?: Readonly<Record<string, NativeRawDngChannelNoise>>;\n /** BaselineExposure in EV (exposure value stops). Default 0: the RAW white level maps to display white, as in native development. */\n baselineExposureEv?: number;\n /** Optional UTC time of the capture, exactly YYYY-MM-DDTHH:mm:ss.sssZ. If omitted, no date tags are written; the engine never makes up a clock time. */\n capturedAtUtc?: string;\n /** Optional (2.4) caller text: description, software, copyright, comment (see the module notes). If omitted, no text is added. */\n textMetadata?: OutputTextMetadata;\n /**\n * Optional (#587) OpcodeList3 (tag 51022) bytes, for example `createDngLensCorrectionOpcodes(...).opcodeList3`: a big-endian DNG\n * opcode list (DNG 1.3.0.0+, \"Opcode List Processing\") that readers apply to the demosaiced stage-3 image. Only its framing is\n * checked (count, per-opcode headers and parameter sizes filling the bytes exactly). The RAW codes are unchanged. If omitted, no tag.\n */\n opcodeList3?: Uint8Array;\n}\nexport interface NativeRawDng {\n schemaVersion: typeof NATIVE_RAW_DNG_SCHEMA_VERSION;\n mediaType: \"image/dng\";\n bytes: Uint8Array;\n sha256: string;\n /** RawDataUniqueID (32 hex digits): the first 128 bits of SHA-256 over a fixed header and the little-endian codes. */\n rawDataUniqueId: string;\n uniqueCameraModel: string;\n /** Stored geometry, levels and colour values exactly as written (rationals as numerator/denominator). */\n activeArea: { x: number; y: number; width: number; height: number };\n defaultCrop: { x: number; y: number; width: number; height: number };\n orientation: number;\n blackLevels: readonly number[];\n whiteLevel: number;\n cfaPattern: readonly number[];\n colorMatrix1: readonly number[];\n asShotNeutral: readonly number[];\n noiseProfile: readonly number[] | null;\n /** Sites flagged saturated whose code is below WhiteLevel; DNG has no field for them. */\n unrepresentedSaturationFlagCount: number;\n source: \"packed-native-raw\";\n linearMasterDeclared: false;\n}\n\nfunction fail(message: string): never { throw new InvalidConfigurationError(\"Native RAW DNG: \" + message); }\nasync function sha256(bytes: Uint8Array): Promise<string> {\n const subtle = globalThis.crypto?.subtle;\n if (!subtle) fail(\"needs crypto.subtle (a secure browser context or Node 22+).\");\n return Array.from(new Uint8Array(await subtle.digest(\"SHA-256\", bytes as Uint8Array<ArrayBuffer>)), (b) => b.toString(16).padStart(2, \"0\")).join(\"\");\n}\n/** Values exactly as stored by a RATIONAL/SRATIONAL tag (numerator / denominator), so reported metadata equals what a reader decodes. */\nfunction stored(tag: ReturnType<typeof rationals>): number[] {\n const view = new DataView(tag.data.buffer, tag.data.byteOffset, tag.data.byteLength);\n return Array.from({ length: tag.count }, (_, i) => (tag.type === 10 ? view.getInt32(i * 8, true) : view.getUint32(i * 8, true)) / view.getUint32(i * 8 + 4, true));\n}\nconst ORIENTATION = { landscape: 1, \"portrait-clockwise\": 6, \"landscape-inverted\": 3, \"portrait-counter-clockwise\": 8 } as const;\n\n/**\n * Writes packed native RAW codes as a lossless, uncompressed CFA DNG. The module notes list every tag and\n * where its value comes from. The input arrays are copied before the first await.\n */\nexport async function serializeNativeRawDng(input: SerializeNativeRawDngInput): Promise<NativeRawDng> {\n const r = requireAllowlistedRecord(input, [\"raw\", \"colorProfile\", \"noise\", \"baselineExposureEv\", \"capturedAtUtc\", \"textMetadata\", \"opcodeList3\"], \"Invalid native RAW DNG input.\");\n let opcodeList3: Uint8Array | undefined;\n if (r.opcodeList3 !== undefined) {\n if (!(r.opcodeList3 instanceof Uint8Array) || r.opcodeList3.length < 4) fail(\"opcodeList3 must be a Uint8Array opcode list.\");\n opcodeList3 = r.opcodeList3.slice();\n const v = new DataView(opcodeList3.buffer);\n let at = 4;\n for (let n = v.getUint32(0); n > 0 && at <= opcodeList3.length; n--) at = at + 16 > opcodeList3.length ? Infinity : at + 16 + v.getUint32(at + 12);\n if (at !== opcodeList3.length) fail(\"opcodeList3 is not a whole DNG opcode list (big-endian count, 16-byte headers, parameter sizes).\");\n }\n const raw = r.raw as NativeRawOutput, plan = validatePackedNativeRaw(raw);\n const mosaic = plan.frame.colorSamplingProfile.layout;\n if (mosaic.kind === \"periodic-mosaic\") checkNativeRawIntegrity(raw, plan.exposure.geometry.nativeRaster.pixelWidth, mosaic.repeatWidthSites, mosaic.repeatHeightSites, 0, plan.exposure.geometry.nativeRaster.pixelHeight);\n const color = parseExportSensorColorProfile(r.colorProfile), frame = plan.frame, layout = frame.colorSamplingProfile.layout;\n if (layout.kind !== \"periodic-mosaic\" || layout.repeatWidthSites !== 2 || layout.repeatHeightSites !== 2 ||\n [...layout.siteChannelIds].sort().join() !== \"blue,green,green,red\" || color.channelIds.join() !== \"red,green,blue\")\n fail(\"supports 2×2 RGB Bayer CFAs with red, green, blue colour-profile channels only.\");\n if (color.colorSamplingProfileId !== frame.colorSamplingProfile.profileId) fail(\"colour profile is not bound to the RAW's CFA.\");\n const baseline = r.baselineExposureEv === undefined ? 0 : r.baselineExposureEv;\n if (typeof baseline !== \"number\" || !Number.isFinite(baseline) || Math.abs(baseline) > 16) fail(\"baselineExposureEv must be finite within ±16.\");\n const capturedAtUtc = r.capturedAtUtc as string | undefined;\n if (capturedAtUtc !== undefined && (typeof capturedAtUtc !== \"string\" || !/^\\d{4}-\\d\\d-\\d\\dT\\d\\d:\\d\\d:\\d\\d\\.\\d{3}Z$/.test(capturedAtUtc) || Number.isNaN(Date.parse(capturedAtUtc))))\n fail(\"capturedAtUtc must be YYYY-MM-DDTHH:mm:ss.sssZ.\");\n let text: Readonly<OutputTextMetadata> | undefined;\n try { text = parseOutputTextMetadata(r.textMetadata, \"textMetadata\"); } catch (error) { fail((error as Error).message); }\n\n const native = plan.exposure.geometry.nativeRaster, width = native.pixelWidth, height = native.pixelHeight, g = plan.exposure.resolvedGeometry;\n const active = g.activeCapture.nativeRect;\n const crop = transformOrientedRasterRectToNative({ rect: g.output.cropRect, nativeRaster: g.activeCapture.raster, orientation: plan.exposure.geometry.orientation });\n // Copy before any await: the caller keeps ownership of the packed arrays.\n const codes = raw.codes.slice(), blacks = raw.blackLevels.slice(), flags = raw.saturationFlags.slice(), whiteByPhase = Array.from(raw.effectiveSaturationCodes);\n\n // Levels per CFA phase, relative to the active area. The black-level tile must repeat exactly.\n const blackLevels: number[] = [], cfaPattern: number[] = [], whites: number[] = [], phaseChannel: string[] = [];\n for (let py = 0; py < 2; py++) for (let px = 0; px < 2; px++) {\n const ax = (active.x + px) % 2, ay = (active.y + py) % 2;\n const black = blacks[ay * width + ax]!;\n for (let y = ay; y < height; y += 2) for (let x = ax; x < width; x += 2) if (blacks[y * width + x] !== black) fail(\"per-site black levels do not repeat with the 2×2 CFA tile.\");\n const channel = layout.siteChannelIds[ay * 2 + ax]!;\n blackLevels.push(black); whites.push(whiteByPhase[ay * 2 + ax]!); phaseChannel.push(channel); cfaPattern.push([\"red\", \"green\", \"blue\"].indexOf(channel));\n }\n const whiteLevel = Math.min(...whites);\n if (blackLevels.some((b) => b >= whiteLevel)) fail(\"black level must be below the effective WhiteLevel.\");\n let unrepresented = 0;\n for (let i = 0; i < codes.length; i++) if (flags[i] !== 0 && codes[i]! < whiteLevel) unrepresented++;\n\n // NoiseProfile: one (S, O) pair per CFA plane colour, only when every phase of a channel shares its black level.\n let noiseProfile: number[] | null = null;\n if (r.noise !== undefined) {\n const noise = requireAllowlistedRecord(r.noise, [\"red\", \"green\", \"blue\"], \"Invalid native RAW DNG noise.\") as Record<string, NativeRawDngChannelNoise>;\n noiseProfile = [];\n for (const channel of [\"red\", \"green\", \"blue\"]) {\n const n = noise[channel];\n if (!n) fail(\"noise needs red, green and blue entries.\");\n requireAllowlistedRecord(n, [\"conversionGainElectronsPerCode\", \"readNoiseRmsElectrons\"], \"Invalid native RAW DNG channel noise.\");\n const gain = n.conversionGainElectronsPerCode, read = n.readNoiseRmsElectrons;\n if (typeof gain !== \"number\" || !Number.isFinite(gain) || gain <= 0 || typeof read !== \"number\" || !Number.isFinite(read) || read < 0) fail(\"noise gain must be positive and read noise non-negative.\");\n const phaseBlacks = blackLevels.filter((_, i) => phaseChannel[i] === channel);\n if (phaseBlacks.some((b) => b !== phaseBlacks[0])) { noiseProfile = null; break; }\n const span = whiteLevel - phaseBlacks[0]!;\n noiseProfile.push(1 / (gain * span), (read * read / (gain * gain) + 1 / 12) / (span * span));\n }\n }\n\n // Colour tags from the declared profile and the capture's white-balance intent.\n const m = color.normalizedCameraChannelsToXyz, colorMatrix = invertSensorColorMatrix(m), intent = plan.exposure.whiteBalanceIntent;\n const development = prepareSensorColorDevelopment(m, intent ? [intent.channelGains.red, intent.channelGains.green, intent.channelGains.blue] : null);\n const cameraWhite = sensorColorReferenceWhite(colorMatrix);\n const chad = chromaticAdaptationMatrix({ transform: \"bradford\", sourceWhiteXyz: resolveCaptureColorModel().referenceWhiteXyz,\n destinationWhiteXyz: { x: ICC_D50_WHITE_XYZ[0], y: 1, z: ICC_D50_WHITE_XYZ[2] } }).matrix;\n const forward = chad.map((row) => [0, 1, 2].map((j) => row.reduce((sum, x, k) => sum + x * m[k]![j]! * cameraWhite[j]!, 0)));\n\n const pixels = new Uint8Array(codes.length * 2), view = new DataView(pixels.buffer);\n codes.forEach((c, i) => view.setUint16(i * 2, c, true));\n const header = new TextEncoder().encode(JSON.stringify({ schema: \"photivra-native-raw-data-id-0.1\", width, height, cfa: layout.siteChannelIds, containerBitDepth: 16 }));\n const idInput = new Uint8Array(header.length + pixels.length); idInput.set(header); idInput.set(pixels, header.length);\n const rawDataUniqueId = (await sha256(idInput)).slice(0, 32);\n const colorHash = (await sha256(new TextEncoder().encode(JSON.stringify(color)))).slice(0, 16);\n const uniqueCameraModel = \"Photivra Virtual Camera \" + color.profileId + \" \" + color.profileVersion + \" \" + colorHash;\n const orientation = ORIENTATION[plan.exposure.geometry.orientation];\n const e = plan.exposure.exposure, software = \"Photivra \" + ENGINE_API_VERSION;\n const statement = \"Simulated capture: packed native RAW from the Photivra engine (\" + frame.frameId + \"). Source \" + plan.exposure.source.kind +\n \"; no linear master image or developed rendering is stored.\";\n const printableAscii = (value: string | undefined): value is string => value !== undefined && /^[\\x20-\\x7e]*$/.test(value);\n const description = printableAscii(text?.description) ? statement + \" \" + text.description : statement;\n const textTags = text === undefined ? [] : [\n ...(printableAscii(text.copyright) ? [ascii(33432, text.copyright)] : []),\n rawBytes(700, 1, xmpTextMetadataPacket({ ...text, description: text.description === undefined ? statement : statement + \" \" + text.description }))];\n\n const exif = [rawBytes(36864, 7, new TextEncoder().encode(\"0232\")), rationals(33434, false, [e.shutterSeconds]), rationals(33437, false, [e.aperture]),\n ...(Number.isInteger(e.iso) && e.iso >= 1 && e.iso <= 65535 ? [numbers(34855, 3, [e.iso]), numbers(34864, 3, [2]), numbers(34866, 4, [e.iso])] : []),\n rationals(37386, false, [e.focalLengthMm]), numbers(40961, 3, [65535]), numbers(40962, 4, [crop.width]), numbers(40963, 4, [crop.height]),\n ...(capturedAtUtc === undefined ? [] : [ascii(36867, capturedAtUtc.slice(0, 19).replaceAll(\"-\", \":\").replace(\"T\", \" \")), ascii(36881, \"+00:00\"), ascii(37521, capturedAtUtc.slice(20, 23))])];\n const colorMatrixTag = rationals(50721, true, colorMatrix.flat()), neutralTag = rationals(50728, false, [...development.asShotNeutral]);\n const bytes = packExportTiff([ascii(270, description), ascii(271, \"Photivra\"), ascii(272, \"Photivra Virtual Camera\"), ascii(305, software), numbers(274, 3, [orientation]),\n numbers(254, 4, [0]), numbers(256, 4, [width]), numbers(257, 4, [height]), numbers(258, 3, [16]), numbers(259, 3, [1]), numbers(262, 3, [32803]),\n { ...numbers(273, 4, [0]), pointer: \"pixels\" as const }, numbers(277, 3, [1]), numbers(278, 4, [height]), numbers(279, 4, [pixels.length]),\n numbers(284, 3, [1]), numbers(339, 3, [1]), numbers(33421, 3, [2, 2]), numbers(33422, 1, cfaPattern),\n numbers(50706, 1, [1, 4, 0, 0]), numbers(50707, 1, [1, 1, 0, 0]), ascii(50708, uniqueCameraModel), numbers(50710, 1, [0, 1, 2]), numbers(50711, 3, [1]),\n numbers(50713, 3, [2, 2]), rationals(50714, false, blackLevels), numbers(50717, 4, [whiteLevel]), numbers(50719, 4, [crop.x, crop.y]), numbers(50720, 4, [crop.width, crop.height]),\n colorMatrixTag, rationals(50727, false, [1, 1, 1]), neutralTag,\n rationals(50730, true, [baseline]), numbers(50778, 3, [21]),\n rawBytes(50781, 1, Uint8Array.from(rawDataUniqueId.match(/../g)!.map((s) => parseInt(s, 16)))),\n numbers(50829, 4, [active.y, active.x, active.y + active.height, active.x + active.width]),\n rationals(50964, true, forward.flat()), ...(noiseProfile ? [doubles(51041, noiseProfile)] : []), ...(opcodeList3 ? [rawBytes(51022, 7, opcodeList3)] : []), ...textTags], exif, pixels);\n return Object.freeze({ schemaVersion: NATIVE_RAW_DNG_SCHEMA_VERSION, mediaType: \"image/dng\" as const, bytes, sha256: await sha256(bytes), rawDataUniqueId, uniqueCameraModel,\n activeArea: { ...active }, defaultCrop: { ...crop }, orientation, blackLevels, whiteLevel, cfaPattern, colorMatrix1: stored(colorMatrixTag), asShotNeutral: stored(neutralTag),\n noiseProfile, unrepresentedSaturationFlagCount: unrepresented, source: \"packed-native-raw\" as const, linearMasterDeclared: false as const });\n}\n"]}
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
* limits.
|
|
10
10
|
*/
|
|
11
11
|
import { requireAllowlistedRecord, requirePublicOpaqueId } from "../core/record-validation.js";
|
|
12
|
-
import { parseSensorEqeTemporalPhotoSignal } from "../sensor/temporal-photo-signal.js";
|
|
12
|
+
import { parseSensorEqeTemporalPhotoSignal, PHOTO_SIGNAL_DOWNSTREAM_FALSE_FIELDS, PHOTO_SIGNAL_TRUE_FIELDS } from "../sensor/temporal-photo-signal.js";
|
|
13
13
|
import { RAW_REFERENCE_MAX_NATIVE_SITES } from "./raw-frame-limits.js";
|
|
14
14
|
import { approximationResult } from "../core/calculation-result.js";
|
|
15
15
|
import { InvalidConfigurationError } from "../core/configuration-error.js";
|
|
@@ -109,10 +109,8 @@ function exposureEvidence(value, temporalPhoto) {
|
|
|
109
109
|
}
|
|
110
110
|
const common = ["colorSamplingProfileId", "channelId", "site", "bindingId", "stationarityProfileId", "timeReference",
|
|
111
111
|
"startOffsetSecondsFromOpeningReference", "endOffsetSecondsFromOpeningReference", "localExposureDurationSeconds", "componentEvidence"];
|
|
112
|
-
const photoTrue = ["timeStationarityEstablished",
|
|
113
|
-
const photoFalse = ["timeVaryingSignalIntegrated",
|
|
114
|
-
"physicalFullWellAssessmentAuthorized", "cameraSaturationAssessmentAuthorized", "saturationAssessed", "shotNoiseApplied",
|
|
115
|
-
"readNoiseApplied", "adcQuantizationApplied", "rawCodeValueProduced", "integerPhotonCountSampled", "integerElectronCountSampled", "chargeCalculated", "currentCalculated"];
|
|
112
|
+
const photoTrue = ["timeStationarityEstablished", ...PHOTO_SIGNAL_TRUE_FIELDS];
|
|
113
|
+
const photoFalse = ["timeVaryingSignalIntegrated", ...PHOTO_SIGNAL_DOWNSTREAM_FALSE_FIELDS];
|
|
116
114
|
function chargeInput(value) {
|
|
117
115
|
const r = fields(value, ["photoSignal", "darkCharge", "additionalChargeComponents", "completenessProfile"]);
|
|
118
116
|
const temporal = r.photoSignal !== null && typeof r.photoSignal === "object" &&
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sensor-raw-producer.js","sourceRoot":"","sources":["../../src/capture/sensor-raw-producer.ts"],"names":[],"mappings":"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","sourcesContent":["// SPDX-License-Identifier: Apache-2.0\n\n/**\n * Produces a sensor RAW frame from per-site exposure inputs, using the existing sensor steps:\n * accumulated charge → capacity → Poisson (shot) noise → read noise and ADC → native sample →\n * immutable frame.\n *\n * Inputs must be complete. Charge, noise or RAW codes cannot be passed in as a shortcut.\n * @see docs/SIMULATED_CAPTURE.md for equations, coordinate/unit conventions, blockers and support\n * limits.\n */\n\nimport { requireAllowlistedRecord, requirePublicOpaqueId } from \"../core/record-validation.js\";\n\nimport { parseSensorEqeTemporalPhotoSignal } from \"../sensor/temporal-photo-signal.js\";\nimport { RAW_REFERENCE_MAX_NATIVE_SITES } from \"./raw-frame-limits.js\";\n\nimport { approximationResult, type CalculationResult } from \"../core/calculation-result.js\";\nimport { InvalidConfigurationError } from \"../core/configuration-error.js\";\nimport { parseEvidenceList } from \"../core/evidence-provenance.js\";\nimport { parseSimulatedCapture } from \"./simulated-capture.js\";\nimport { createSensorRawFrame, type SensorRawFrameInput, type SensorRawFrame } from \"./sensor-raw-frame.js\";\nimport { composeSensorAccumulatedCharge, parseSensorAccumulatedChargeCompletenessProfile, parseSensorAdditionalStoredChargeComponent,\n type ComposeSensorPhotoAccumulatedChargeInput as ComposeSensorAccumulatedChargeInput } from \"../sensor/accumulated-charge.js\";\nimport { assessSensorPhysicalChargeCapacity, parseSensorPhysicalChargeCapacityProfile,\n type SensorPhysicalChargeCapacityProfile } from \"../sensor/physical-charge-capacity.js\";\nimport { simulateSensorChargeRealization, simulateSensorRawCode, parseSensorChargeSamplingProfile,\n parseSensorReadoutConversionProfile, resolveSensorReadoutRegime, type SensorChargeSamplingProfile, type SensorReadoutConversionProfile } from \"../sensor/raw-readout.js\";\nimport { createSensorRawCaptureSample } from \"../sensor/raw-reconstruction.js\";\nimport { parseSensorFixedPatternNoiseProfile, type SensorFixedPatternNoiseProfile } from \"../sensor/fixed-pattern-noise.js\";\nimport { deriveNativeSiteStreamSeedUint32, NATIVE_SITE_CHARGE_STREAM_ID, NATIVE_SITE_READ_NOISE_STREAM_ID } from \"../sensor/stochastic-seed.js\";\nimport { parseSensorColorSamplingProfile } from \"../sensor/color-sampling.js\";\nimport { parseCaptureModeProfile } from \"../sensor/capture-mode.js\";\nimport { parseNativeEffectiveRasterColorSamplingBindingProfile, resolveCaptureModeColorSamplingContributors } from \"../sensor/capture-color-sampling-binding.js\";\nimport { calculateCaptureExposureWindows, type CalculateCaptureExposureWindowsInput, type CaptureExposureWindows } from \"../sensor/exposure-window.js\";\n\nexport const SENSOR_RAW_PRODUCER_SCHEMA_VERSION = \"0.3.0\" as const;\n/**\n * Version of the capture noise model. It fixes the hashed per-site seed schedule and the signed electronic\n * readout behaviour.\n *\n * 0.4.0: exact ADC rounding with ties up, normal-approximation Poisson draws for means of 1e9 and above,\n * optional post-ADC digital gain and INL (integral non-linearity), and optional per-sensor fixed-pattern noise.\n */\nexport const SENSOR_RAW_PRODUCER_NOISE_MODEL = /* @__PURE__ */ Object.freeze({ id: \"photivra-native-raw-noise\", version: \"0.4.0\" } as const);\n/** For each native site: one declared exposure event (EQE photo signal, dark signal, charge completeness) and its readout state. */\nexport interface SensorRawProducerSiteInput {\n charge: ComposeSensorAccumulatedChargeInput;\n samplingProfile: SensorChargeSamplingProfile;\n capacityProfile: SensorPhysicalChargeCapacityProfile;\n operatingStateId: string;\n readoutProfile: SensorReadoutConversionProfile;\n regimeId: string;\n /** Optional fixed-pattern noise (FPN) for this sensor; one profile for the whole frame. Omit it to disable FPN. */\n fixedPatternNoise?: SensorFixedPatternNoiseProfile;\n}\n/** Exposure schedule for the full sensor. The producer owns the sampling coordinates. */\nexport type SensorRawProducerExposureWindowInput = Omit<CalculateCaptureExposureWindowsInput,\n \"nativeRaster\" | \"activeCaptureRect\" | \"samplePointsNative\">;\n/** Input for one bounded frame. It is never a conversion from separate RGB pixels. */\nexport interface SensorRawProducerInput {\n frame: Omit<SensorRawFrameInput, \"samples\">;\n sites: readonly SensorRawProducerSiteInput[];\n /** If omitted, every event uses the existing global window 0..shutterSeconds. */\n exposureWindow?: SensorRawProducerExposureWindowInput;\n}\n/** Codes produced by the engine, with per-step diagnostics. The upstream radiance and response are as declared, not verified. */\nexport interface SensorRawProducerResult {\n schemaVersion: typeof SENSOR_RAW_PRODUCER_SCHEMA_VERSION;\n codeProducer: \"engine-charge-capacity-noise-adc\";\n upstreamOrigin: \"declared-eqe-and-dark-exposure-results\";\n upstreamRadiometryVerified: false;\n seedSchedule: \"murmur3-capture-seed-native-index-stream-v2\";\n frame: SensorRawFrame;\n localExposureWindows?: CalculationResult<CaptureExposureWindows>;\n sites: readonly {\n accumulatedCharge: ReturnType<typeof composeSensorAccumulatedCharge>;\n capacity: ReturnType<typeof assessSensorPhysicalChargeCapacity>;\n realization: ReturnType<typeof simulateSensorChargeRealization>;\n readout: ReturnType<typeof simulateSensorRawCode>;\n }[];\n}\nfunction fields(value: unknown, allowed: readonly string[]): Record<string, unknown> {\n return requireAllowlistedRecord(value, allowed, \"Invalid sensor RAW producer fields.\");\n}\nfunction publicId(value: unknown): string {\n return requirePublicOpaqueId(value, \"Expected public producer identity.\");\n}\nconst KEY_RECURSE = 0, KEY_IDENTITY = 1, KEY_IDENTITY_LIST = 2;\n/** Bounded cache of how the identity check classifies each property name (it depends only on the name). */\nconst IDENTITY_KEY_KINDS = new Map<string, number>();\n/** Bounded cache of strings already known to be valid public IDs (validity depends only on the string). */\nconst VALID_PUBLIC_IDS = new Set<string>();\nconst IDENTITY_WALK_MEMO_LIMIT = 4096;\nfunction identityKeyKind(key: string): number {\n // Array indices and other names ending in a digit match neither suffix.\n const last = key.charCodeAt(key.length - 1);\n if (last >= 48 && last <= 57) return KEY_RECURSE;\n let kind = IDENTITY_KEY_KINDS.get(key);\n if (kind === undefined) {\n kind = /(?:Id|Version)$/.test(key) ? KEY_IDENTITY : /Ids$/.test(key) ? KEY_IDENTITY_LIST : KEY_RECURSE;\n if (IDENTITY_KEY_KINDS.size < IDENTITY_WALK_MEMO_LIMIT) IDENTITY_KEY_KINDS.set(key, kind);\n }\n return kind;\n}\nfunction memoizedPublicId(value: unknown): void {\n if (typeof value === \"string\" && VALID_PUBLIC_IDS.has(value)) return;\n publicId(value);\n if (VALID_PUBLIC_IDS.size < IDENTITY_WALK_MEMO_LIMIT) VALID_PUBLIC_IDS.add(value as string);\n}\n/**\n * At any depth, every property whose name ends in Id or Version must hold a public ID, and every property\n * ending in Ids a bounded dense list of them. Order, keys and errors are the same as the earlier\n * Object.entries walk. Key classification and already-valid IDs are cached, because each depends only on\n * its string.\n */\nfunction publicIdentities(value: unknown): void {\n if (value === null || typeof value !== \"object\") return;\n const record = value as Record<string, unknown>, keys = Object.keys(record);\n for (let index = 0; index < keys.length; index++) {\n const key = keys[index]!, kind = identityKeyKind(key), child = record[key];\n if (kind === KEY_IDENTITY) memoizedPublicId(child);\n else if (kind === KEY_IDENTITY_LIST) dense(child, 256).forEach(memoizedPublicId);\n else if (child !== null && typeof child === \"object\") publicIdentities(child);\n }\n}\nfunction dense(value: unknown, maximum: number): unknown[] {\n if (!Array.isArray(value) || value.length > maximum || Array.from({ length: value.length }, (_, i) => i in value).includes(false)) {\n throw new InvalidConfigurationError(\"Expected bounded dense producer array.\");\n }\n return value;\n}\nfunction optionalEvidence(value: unknown): ReturnType<typeof parseEvidenceList> {\n return dense(value, 256).length === 0 ? [] : parseEvidenceList(value, \"optionalExposureEvidence\");\n}\nfunction exposureEvidence(value: unknown, temporalPhoto?: Record<string, unknown>): ComposeSensorAccumulatedChargeInput[\"photoSignal\"][\"componentEvidence\"] {\n if (temporalPhoto !== undefined) return parseSensorEqeTemporalPhotoSignal({ ...temporalPhoto, componentEvidence: value }).componentEvidence;\n const r = fields(value, [\"stationarity\", \"exposureBinding\"]);\n const b = fields(r.exposureBinding, [\"binding\", \"colorSamplingProfile\", \"nominalExposureDuration\", \"openingBoundary\", \"closingBoundary\"]);\n return { stationarity: parseEvidenceList(r.stationarity, \"stationarity\"), exposureBinding: {\n binding: parseEvidenceList(b.binding, \"binding\"), colorSamplingProfile: parseEvidenceList(b.colorSamplingProfile, \"colorSamplingProfile\"),\n nominalExposureDuration: parseEvidenceList(b.nominalExposureDuration, \"nominalExposureDuration\"),\n openingBoundary: optionalEvidence(b.openingBoundary), closingBoundary: optionalEvidence(b.closingBoundary) } };\n}\nconst common = [\"colorSamplingProfileId\", \"channelId\", \"site\", \"bindingId\", \"stationarityProfileId\", \"timeReference\",\n \"startOffsetSecondsFromOpeningReference\", \"endOffsetSecondsFromOpeningReference\", \"localExposureDurationSeconds\", \"componentEvidence\"];\nconst photoTrue = [\"timeStationarityEstablished\", \"temporalIntegrationApplied\", \"exposureDurationApplied\", \"countsAreExpectationValues\"];\nconst photoFalse = [\"timeVaryingSignalIntegrated\", \"multiFrameSequenceIntegrated\", \"darkChargeIncluded\", \"otherChargeIncluded\",\n \"physicalFullWellAssessmentAuthorized\", \"cameraSaturationAssessmentAuthorized\", \"saturationAssessed\", \"shotNoiseApplied\",\n \"readNoiseApplied\", \"adcQuantizationApplied\", \"rawCodeValueProduced\", \"integerPhotonCountSampled\", \"integerElectronCountSampled\", \"chargeCalculated\", \"currentCalculated\"];\nfunction chargeInput(value: unknown): ComposeSensorAccumulatedChargeInput {\n const r = fields(value, [\"photoSignal\", \"darkCharge\", \"additionalChargeComponents\", \"completenessProfile\"]);\n const temporal = r.photoSignal !== null && typeof r.photoSignal === \"object\" &&\n (r.photoSignal as Record<string, unknown>).kind === \"eqe-temporal-photo-signal\";\n const p = temporal ? parseSensorEqeTemporalPhotoSignal(r.photoSignal) as unknown as Record<string, unknown> : fields(r.photoSignal, [...common, ...photoTrue, ...photoFalse, \"kind\", \"stationarityStatus\", \"integrationMethod\",\n \"accumulatedSignalCompleteness\", \"incidentPhotonRatePerSecond\", \"expectedGeneratedElectronRatePerSecond\", \"expectedIncidentPhotonCount\", \"expectedGeneratedElectronCount\"]);\n const darkFalse = [\"integerDarkElectronCountSampled\", \"darkShotNoiseApplied\", \"darkCurrentCompensationApplied\", \"photoSignalIncluded\",\n \"otherChargeIncluded\", \"physicalFullWellAssessmentAuthorized\", \"saturationAssessed\"];\n const d = fields(r.darkCharge, [...common, ...darkFalse, \"darkCurrentProfileId\", \"operatingTemperatureC\", \"temperatureModel\",\n \"temperatureInterpolationUsed\", \"temporalIntegrationId\", \"darkCurrentElectronsPerSecond\", \"expectedDarkElectronCount\", \"countMeaning\", \"expectationValueOnly\", \"spatialDarkCurrentNonuniformityModeled\"]);\n if ((!temporal && (p.kind !== \"eqe-expected-counts\" || p.integrationMethod !== \"constant-rate-times-local-exposure-duration\" ||\n p.accumulatedSignalCompleteness !== \"photo-signal-only\" || (p.stationarityStatus !== \"established\" && p.stationarityStatus !== \"approximation\") ||\n photoTrue.some((k) => p[k] !== true) || photoFalse.some((k) => p[k] !== false))) || darkFalse.some((k) => d[k] !== false) ||\n d.expectationValueOnly !== true || d.countMeaning !== \"expected-thermally-generated-electrons\" ||\n typeof d.spatialDarkCurrentNonuniformityModeled !== \"boolean\" || typeof d.temperatureInterpolationUsed !== \"boolean\" ||\n (d.temperatureModel !== \"fixed-reference-temperature\" && d.temperatureModel !== \"piecewise-linear-temperature-table\" &&\n d.temperatureModel !== \"log-linear-temperature-table\")) {\n throw new InvalidConfigurationError(\"Producer requires untreated EQE/dark exposure expectations, not sampled, clipped or A/W charge.\");\n }\n if (d.temperatureModel === \"fixed-reference-temperature\" && d.temperatureInterpolationUsed !== false) {\n throw new InvalidConfigurationError(\"Fixed-temperature dark result cannot claim temperature interpolation.\");\n }\n for (const record of [p, d]) {\n for (const k of [\"colorSamplingProfileId\", \"channelId\", \"bindingId\", temporal ? \"temporalIntegrationId\" : \"stationarityProfileId\"]) publicId(record[k]);\n fields(record.site, [\"x\", \"y\"]);\n if (record.timeReference !== \"first-opening-boundary-phase\") throw new InvalidConfigurationError(\"Unsupported producer time origin.\");\n }\n publicId(d.darkCurrentProfileId);\n for (const [record, keys] of [[p, [\"incidentPhotonRatePerSecond\", \"expectedGeneratedElectronRatePerSecond\", \"expectedIncidentPhotonCount\", \"expectedGeneratedElectronCount\"]],\n [d, [\"darkCurrentElectronsPerSecond\", \"expectedDarkElectronCount\"]]] as const) {\n for (const k of keys) if (!(temporal && record === p && k.endsWith(\"RatePerSecond\")) && (typeof record[k] !== \"number\" || !Number.isFinite(record[k]) || record[k] < 0)) throw new InvalidConfigurationError(\"Invalid expected rates/counts.\");\n }\n const duration = p.localExposureDurationSeconds;\n if (typeof duration !== \"number\" || !Number.isFinite(duration) || duration <= 0 ||\n (!temporal && (p.expectedIncidentPhotonCount !== (p.incidentPhotonRatePerSecond as number)*duration ||\n p.expectedGeneratedElectronCount !== (p.expectedGeneratedElectronRatePerSecond as number)*duration)) ||\n d.expectedDarkElectronCount !== (d.darkCurrentElectronsPerSecond as number)*duration ||\n (p.expectedGeneratedElectronCount as number) > (p.expectedIncidentPhotonCount as number)) {\n throw new InvalidConfigurationError(\"Exposure expectations must match their exact temporal integral or constant-rate products and EQE domain.\");\n }\n const e = fields(d.componentEvidence, [\"darkCurrent\", \"siteApproximation\", \"exposure\"]);\n const charge = { photoSignal: { ...p, componentEvidence: exposureEvidence(p.componentEvidence, temporal ? p : undefined) },\n darkCharge: { ...d, componentEvidence: { darkCurrent: parseEvidenceList(e.darkCurrent, \"darkCurrent\"),\n siteApproximation: optionalEvidence(e.siteApproximation), exposure: exposureEvidence(e.exposure, temporal ? p : undefined) } },\n completenessProfile: parseSensorAccumulatedChargeCompletenessProfile(r.completenessProfile),\n ...(r.additionalChargeComponents === undefined ? {} : { additionalChargeComponents:\n dense(r.additionalChargeComponents, 32).map(parseSensorAdditionalStoredChargeComponent) }) } as unknown as ComposeSensorAccumulatedChargeInput;\n // The existing charge composition checks that photo, dark, additional and completeness events agree exactly.\n composeSensorAccumulatedCharge(charge);\n return charge;\n}\nfunction localWindows(frame: SensorRawProducerInput[\"frame\"], value: unknown): CalculationResult<CaptureExposureWindows> {\n const r = fields(value, [\"shutterMechanism\", \"nominalExposureDurationSeconds\", \"opening\", \"closing\"]);\n fields(r.nominalExposureDurationSeconds, [\"value\", \"unit\", \"evidence\"]);\n for (const boundary of [r.opening, r.closing]) {\n const b = fields(boundary, [\"kind\", \"directionNative\", \"traversalDurationSeconds\"]);\n if (b.directionNative !== undefined) fields(b.directionNative, [\"value\", \"evidence\"]);\n if (b.traversalDurationSeconds !== undefined) fields(b.traversalDurationSeconds, [\"value\", \"unit\", \"evidence\"]);\n }\n const native = frame.capture.geometry.nativeRaster;\n const timing = calculateCaptureExposureWindows({\n ...r as unknown as SensorRawProducerExposureWindowInput,\n nativeRaster: native,\n samplePointsNative: Array.from({ length: native.pixelWidth*native.pixelHeight }, (_, i) => ({\n x: i%native.pixelWidth+0.5, y: Math.floor(i/native.pixelWidth)+0.5\n }))\n });\n if (timing.value.nominalExposureDurationSeconds.value !== frame.capture.exposure.shutterSeconds) {\n throw new InvalidConfigurationError(\"Exposure schedule nominal duration differs from committed capture.\");\n }\n return timing;\n}\nfunction sourceBoundary(schedule: CaptureExposureWindows[\"opening\"][\"schedule\"]): SensorRawProducerExposureWindowInput[\"opening\"] {\n return schedule.kind === \"simultaneous\" ? { kind: \"simultaneous\" } : {\n kind: \"uniform-linear-native-scan\", directionNative: schedule.directionNative,\n traversalDurationSeconds: schedule.traversalDurationSeconds\n };\n}\n/** Internal: per-site validation shared by the reference path and bounded packed execution. */\nexport type NativeRawProducerFrameContext = Omit<SensorRawProducerInput[\"frame\"], \"capture\"> & {\n capture: Pick<SensorRawProducerInput[\"frame\"][\"capture\"], \"geometry\" | \"exposure\" | \"noise\" | \"focus\" | \"sceneStateId\" | \"sceneTimeSeconds\">;\n};\nexport function parseNativeRawProducerSite(site: unknown, i: number, frame: NativeRawProducerFrameContext,\n window?: CaptureExposureWindows[\"samples\"][number]): SensorRawProducerSiteInput {\n const native = frame.capture.geometry.nativeRaster;\n const s = fields(site, [\"charge\", \"samplingProfile\", \"capacityProfile\", \"operatingStateId\", \"readoutProfile\", \"regimeId\", \"fixedPatternNoise\"]);\n const charge = chargeInput(s.charge), p = charge.photoSignal;\n const contributors = resolveCaptureModeColorSamplingContributors({ nativeRaster: native, captureModeProfile: frame.captureModeProfile,\n modeId: frame.modeId, colorSamplingProfile: frame.colorSamplingProfile, bindingProfile: frame.bindingProfile,\n modeSampleIndexFullFrame: { x: i%native.pixelWidth, y: Math.floor(i/native.pixelWidth) } });\n\n if (contributors.totalContributorSites !== 1 || contributors.channelComposition.kind !== \"single-channel\" ||\n p.colorSamplingProfileId !== frame.colorSamplingProfile.profileId || p.channelId !== contributors.channelComposition.channelId ||\n p.site.x !== contributors.colorSamplingSiteRect.x || p.site.y !== contributors.colorSamplingSiteRect.y ||\n p.bindingId !== frame.bindingProfile.bindingId || p.startOffsetSecondsFromOpeningReference !== (window?.startOffsetSecondsFromOpeningReference ?? 0) ||\n p.endOffsetSecondsFromOpeningReference !== (window?.endOffsetSecondsFromOpeningReference ?? frame.capture.exposure.shutterSeconds) ||\n p.localExposureDurationSeconds !== (window?.localExposureDurationSeconds ?? frame.capture.exposure.shutterSeconds)) {\n throw new InvalidConfigurationError(\"Charge site/channel/binding/local exposure differs from committed capture.\");\n }\n const readoutProfile = parseSensorReadoutConversionProfile(s.readoutProfile);\n const isoGain = readoutProfile.regimes.find((regime) => regime.regimeId === s.regimeId)?.exposureIndexGain;\n if (isoGain !== undefined && isoGain.exposureIndex !== frame.capture.exposure.iso) {\n throw new InvalidConfigurationError(\"Readout regime ISO gain differs from the committed capture ISO.\");\n }\n return { charge, samplingProfile: parseSensorChargeSamplingProfile(s.samplingProfile), capacityProfile: parseSensorPhysicalChargeCapacityProfile(s.capacityProfile),\n operatingStateId: publicId(s.operatingStateId), readoutProfile, regimeId: publicId(s.regimeId),\n ...(s.fixedPatternNoise === undefined ? {} : { fixedPatternNoise: parseSensorFixedPatternNoiseProfile(s.fixedPatternNoise) }) };\n}\nexport function validateNativeRawReadoutIdentity(s: SensorRawProducerSiteInput, first: SensorRawProducerSiteInput): void {\n publicIdentities(s);\n const readout = resolveSensorReadoutRegime({ profile: s.readoutProfile, regimeId: s.regimeId });\n if (s.readoutProfile.profileId !== first.readoutProfile.profileId || s.regimeId !== first.regimeId ||\n readout.regime.adc.bitDepth > 16 || readout.regime.adc.digitalSaturationCode <= readout.regime.adc.blackLevelCode ||\n s.readoutProfile.colorSamplingProfileId !== s.charge.photoSignal.colorSamplingProfileId ||\n s.readoutProfile.channelId !== s.charge.photoSignal.channelId || s.samplingProfile.completenessProfileId !== s.charge.completenessProfile.profileId ||\n s.fixedPatternNoise?.profileId !== first.fixedPatternNoise?.profileId ||\n s.fixedPatternNoise?.sensorInstanceSeedUint32 !== first.fixedPatternNoise?.sensorInstanceSeedUint32) {\n throw new InvalidConfigurationError(\"Frame requires one readout identity/regime, one fixed-pattern identity and a positive uint16 RAW code span.\");\n }\n}\n/** The shared per-site pipeline holds all the charge, capacity, random-noise and ADC equations. `i` is the absolute native row-major index. */\nexport function calculateNativeRawSite(s: SensorRawProducerSiteInput, seed: number, i: number): SensorRawProducerResult[\"sites\"][number] {\n const accumulatedCharge = composeSensorAccumulatedCharge(s.charge);\n const capacity = assessSensorPhysicalChargeCapacity({ accumulatedCharge: accumulatedCharge.value, capacityProfile: s.capacityProfile,\n operatingStateId: s.operatingStateId, operatingTemperatureC: s.charge.darkCharge.operatingTemperatureC });\n const pattern = s.fixedPatternNoise === undefined ? {} : { fixedPatternNoise: s.fixedPatternNoise };\n const realization = simulateSensorChargeRealization({ accumulatedCharge: accumulatedCharge.value, samplingProfile: s.samplingProfile,\n seedUint32: deriveNativeSiteStreamSeedUint32(seed, i, NATIVE_SITE_CHARGE_STREAM_ID), ...pattern });\n const readout = simulateSensorRawCode({ chargeRealization: realization.value, physicalCapacityAssessment: capacity.value,\n readoutProfile: s.readoutProfile, regimeId: s.regimeId,\n readNoiseSeedUint32: deriveNativeSiteStreamSeedUint32(seed, i, NATIVE_SITE_READ_NOISE_STREAM_ID), ...pattern });\n return { accumulatedCharge, capacity, realization, readout };\n}\n/** The selected regime's declared INL, which the effective white level needs at saturation. */\nfunction regimeInl(site: SensorRawProducerSiteInput): { adcIntegralNonLinearity?: NonNullable<SensorReadoutConversionProfile[\"regimes\"][number][\"adc\"][\"integralNonLinearity\"]> } {\n const inl = site.readoutProfile.regimes.find((r) => r.regimeId === site.regimeId)?.adc.integralNonLinearity;\n return inl === undefined ? {} : { adcIntegralNonLinearity: inl };\n}\n/** Validates the complete per-site exposure inputs. Charge, noise or RAW codes are never accepted as a shortcut. */\nexport function parseSensorRawProducerInput(value: unknown): SensorRawProducerInput {\n const r = fields(value, [\"frame\", \"sites\", \"exposureWindow\"]), f = fields(r.frame, [\"frameId\", \"capture\", \"modeId\", \"captureModeProfile\", \"colorSamplingProfile\", \"bindingProfile\", \"containerBitDepth\"]);\n const capture = parseSimulatedCapture(f.capture), native = capture.geometry.nativeRaster, count = native.pixelWidth*native.pixelHeight;\n const sites = dense(r.sites, RAW_REFERENCE_MAX_NATIVE_SITES);\n const frame = { frameId: publicId(f.frameId), capture, modeId: publicId(f.modeId), containerBitDepth: 16 as const,\n captureModeProfile: parseCaptureModeProfile(f.captureModeProfile), colorSamplingProfile: parseSensorColorSamplingProfile(f.colorSamplingProfile),\n bindingProfile: parseNativeEffectiveRasterColorSamplingBindingProfile(f.bindingProfile) };\n const mode = frame.captureModeProfile.modes.find((m) => m.modeId === frame.modeId);\n if (f.containerBitDepth !== 16 || count > RAW_REFERENCE_MAX_NATIVE_SITES || sites.length !== count ||\n capture.noise.model.id !== SENSOR_RAW_PRODUCER_NOISE_MODEL.id || capture.noise.model.version !== SENSOR_RAW_PRODUCER_NOISE_MODEL.version ||\n frame.colorSamplingProfile.layout.kind !== \"periodic-mosaic\" || !mode || mode.acquisition.kind !== \"single-frame\" ||\n mode.perFrameSampling.kind !== \"native-effective-raster\" || (mode.reconstructionStages?.length ?? 0) !== 0) {\n throw new InvalidConfigurationError(\"Producer requires exact noise identity and bounded single-frame native CFA coverage.\");\n }\n const timing = r.exposureWindow === undefined ? undefined : localWindows(frame, r.exposureWindow);\n const parsed = sites.map((site, i) => parseNativeRawProducerSite(site, i, frame, timing?.value.samples[i]));\n for (const site of parsed) validateNativeRawReadoutIdentity(site, parsed[0]!);\n publicIdentities(frame);\n return { frame, sites: parsed, ...(timing === undefined ? {} : { exposureWindow: {\n shutterMechanism: timing.value.shutterMechanism,\n nominalExposureDurationSeconds: timing.value.nominalExposureDurationSeconds,\n opening: sourceBoundary(timing.value.opening.schedule), closing: sourceBoundary(timing.value.closing.schedule)\n } }) };\n}\n/** Runs accumulated charge → capacity → Poisson noise → read noise and ADC → native sample → immutable frame. */\nexport function simulateSensorRawFrame(input: SensorRawProducerInput): CalculationResult<SensorRawProducerResult> {\n const v = parseSensorRawProducerInput(input), seed = v.frame.capture.noise.seedUint32;\n const sites = v.sites.map((s, i) => calculateNativeRawSite(s, seed, i));\n const native = v.frame.capture.geometry.nativeRaster;\n const samples = sites.map((s, i) => createSensorRawCaptureSample({ rawCode: s.readout.value,\n ...regimeInl(v.sites[i]!),\n contributors: resolveCaptureModeColorSamplingContributors({ nativeRaster: native, captureModeProfile: v.frame.captureModeProfile,\n modeId: v.frame.modeId, colorSamplingProfile: v.frame.colorSamplingProfile, bindingProfile: v.frame.bindingProfile,\n modeSampleIndexFullFrame: { x: i%native.pixelWidth, y: Math.floor(i/native.pixelWidth) } }) }));\n return approximationResult({ schemaVersion: SENSOR_RAW_PRODUCER_SCHEMA_VERSION, codeProducer: \"engine-charge-capacity-noise-adc\",\n upstreamOrigin: \"declared-eqe-and-dark-exposure-results\", upstreamRadiometryVerified: false,\n seedSchedule: \"murmur3-capture-seed-native-index-stream-v2\", frame: createSensorRawFrame({ ...v.frame, samples }), sites,\n ...(v.exposureWindow === undefined ? {} : { localExposureWindows: localWindows(v.frame, v.exposureWindow) }) },\n \"native-sensor-raw-frame-producer\", SENSOR_RAW_PRODUCER_SCHEMA_VERSION, [\n \"Untreated EQE/dark exposure results and completeness evidence are upstream declarations; source radiometry is not independently verified\",\n \"Native row-major site seeds are MurmurHash3_x86_32 of (capture seed, absolute native index, stream 0 charge / 1 read noise); deterministic and non-cryptographic\",\n \"Existing scalar capacity/noise/readout approximations retain distinct physical/pre-ADC/digital saturation diagnostics; no blooming\",\n \"Optional fixed-pattern noise is deterministic per sensor instance (its own seed and absolute colour-sampling site), independent of the capture seed\",\n \"Stationarity applies separately to every exact local window; no time-varying radiance integration, multi-frame acquisition, RGB-to-RAW conversion or production-stage activation\",\n \"Stored capture float planes remain independent; same-RAW export must use the returned frame's reconstruction handoff\"]);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"sensor-raw-producer.js","sourceRoot":"","sources":["../../src/capture/sensor-raw-producer.ts"],"names":[],"mappings":"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","sourcesContent":["// SPDX-License-Identifier: Apache-2.0\n\n/**\n * Produces a sensor RAW frame from per-site exposure inputs, using the existing sensor steps:\n * accumulated charge → capacity → Poisson (shot) noise → read noise and ADC → native sample →\n * immutable frame.\n *\n * Inputs must be complete. Charge, noise or RAW codes cannot be passed in as a shortcut.\n * @see docs/SIMULATED_CAPTURE.md for equations, coordinate/unit conventions, blockers and support\n * limits.\n */\n\nimport { requireAllowlistedRecord, requirePublicOpaqueId } from \"../core/record-validation.js\";\n\nimport { parseSensorEqeTemporalPhotoSignal, PHOTO_SIGNAL_DOWNSTREAM_FALSE_FIELDS, PHOTO_SIGNAL_TRUE_FIELDS } from \"../sensor/temporal-photo-signal.js\";\nimport { RAW_REFERENCE_MAX_NATIVE_SITES } from \"./raw-frame-limits.js\";\n\nimport { approximationResult, type CalculationResult } from \"../core/calculation-result.js\";\nimport { InvalidConfigurationError } from \"../core/configuration-error.js\";\nimport { parseEvidenceList } from \"../core/evidence-provenance.js\";\nimport { parseSimulatedCapture } from \"./simulated-capture.js\";\nimport { createSensorRawFrame, type SensorRawFrameInput, type SensorRawFrame } from \"./sensor-raw-frame.js\";\nimport { composeSensorAccumulatedCharge, parseSensorAccumulatedChargeCompletenessProfile, parseSensorAdditionalStoredChargeComponent,\n type ComposeSensorPhotoAccumulatedChargeInput as ComposeSensorAccumulatedChargeInput } from \"../sensor/accumulated-charge.js\";\nimport { assessSensorPhysicalChargeCapacity, parseSensorPhysicalChargeCapacityProfile,\n type SensorPhysicalChargeCapacityProfile } from \"../sensor/physical-charge-capacity.js\";\nimport { simulateSensorChargeRealization, simulateSensorRawCode, parseSensorChargeSamplingProfile,\n parseSensorReadoutConversionProfile, resolveSensorReadoutRegime, type SensorChargeSamplingProfile, type SensorReadoutConversionProfile } from \"../sensor/raw-readout.js\";\nimport { createSensorRawCaptureSample } from \"../sensor/raw-reconstruction.js\";\nimport { parseSensorFixedPatternNoiseProfile, type SensorFixedPatternNoiseProfile } from \"../sensor/fixed-pattern-noise.js\";\nimport { deriveNativeSiteStreamSeedUint32, NATIVE_SITE_CHARGE_STREAM_ID, NATIVE_SITE_READ_NOISE_STREAM_ID } from \"../sensor/stochastic-seed.js\";\nimport { parseSensorColorSamplingProfile } from \"../sensor/color-sampling.js\";\nimport { parseCaptureModeProfile } from \"../sensor/capture-mode.js\";\nimport { parseNativeEffectiveRasterColorSamplingBindingProfile, resolveCaptureModeColorSamplingContributors } from \"../sensor/capture-color-sampling-binding.js\";\nimport { calculateCaptureExposureWindows, type CalculateCaptureExposureWindowsInput, type CaptureExposureWindows } from \"../sensor/exposure-window.js\";\n\nexport const SENSOR_RAW_PRODUCER_SCHEMA_VERSION = \"0.3.0\" as const;\n/**\n * Version of the capture noise model. It fixes the hashed per-site seed schedule and the signed electronic\n * readout behaviour.\n *\n * 0.4.0: exact ADC rounding with ties up, normal-approximation Poisson draws for means of 1e9 and above,\n * optional post-ADC digital gain and INL (integral non-linearity), and optional per-sensor fixed-pattern noise.\n */\nexport const SENSOR_RAW_PRODUCER_NOISE_MODEL = /* @__PURE__ */ Object.freeze({ id: \"photivra-native-raw-noise\", version: \"0.4.0\" } as const);\n/** For each native site: one declared exposure event (EQE photo signal, dark signal, charge completeness) and its readout state. */\nexport interface SensorRawProducerSiteInput {\n charge: ComposeSensorAccumulatedChargeInput;\n samplingProfile: SensorChargeSamplingProfile;\n capacityProfile: SensorPhysicalChargeCapacityProfile;\n operatingStateId: string;\n readoutProfile: SensorReadoutConversionProfile;\n regimeId: string;\n /** Optional fixed-pattern noise (FPN) for this sensor; one profile for the whole frame. Omit it to disable FPN. */\n fixedPatternNoise?: SensorFixedPatternNoiseProfile;\n}\n/** Exposure schedule for the full sensor. The producer owns the sampling coordinates. */\nexport type SensorRawProducerExposureWindowInput = Omit<CalculateCaptureExposureWindowsInput,\n \"nativeRaster\" | \"activeCaptureRect\" | \"samplePointsNative\">;\n/** Input for one bounded frame. It is never a conversion from separate RGB pixels. */\nexport interface SensorRawProducerInput {\n frame: Omit<SensorRawFrameInput, \"samples\">;\n sites: readonly SensorRawProducerSiteInput[];\n /** If omitted, every event uses the existing global window 0..shutterSeconds. */\n exposureWindow?: SensorRawProducerExposureWindowInput;\n}\n/** Codes produced by the engine, with per-step diagnostics. The upstream radiance and response are as declared, not verified. */\nexport interface SensorRawProducerResult {\n schemaVersion: typeof SENSOR_RAW_PRODUCER_SCHEMA_VERSION;\n codeProducer: \"engine-charge-capacity-noise-adc\";\n upstreamOrigin: \"declared-eqe-and-dark-exposure-results\";\n upstreamRadiometryVerified: false;\n seedSchedule: \"murmur3-capture-seed-native-index-stream-v2\";\n frame: SensorRawFrame;\n localExposureWindows?: CalculationResult<CaptureExposureWindows>;\n sites: readonly {\n accumulatedCharge: ReturnType<typeof composeSensorAccumulatedCharge>;\n capacity: ReturnType<typeof assessSensorPhysicalChargeCapacity>;\n realization: ReturnType<typeof simulateSensorChargeRealization>;\n readout: ReturnType<typeof simulateSensorRawCode>;\n }[];\n}\nfunction fields(value: unknown, allowed: readonly string[]): Record<string, unknown> {\n return requireAllowlistedRecord(value, allowed, \"Invalid sensor RAW producer fields.\");\n}\nfunction publicId(value: unknown): string {\n return requirePublicOpaqueId(value, \"Expected public producer identity.\");\n}\nconst KEY_RECURSE = 0, KEY_IDENTITY = 1, KEY_IDENTITY_LIST = 2;\n/** Bounded cache of how the identity check classifies each property name (it depends only on the name). */\nconst IDENTITY_KEY_KINDS = new Map<string, number>();\n/** Bounded cache of strings already known to be valid public IDs (validity depends only on the string). */\nconst VALID_PUBLIC_IDS = new Set<string>();\nconst IDENTITY_WALK_MEMO_LIMIT = 4096;\nfunction identityKeyKind(key: string): number {\n // Array indices and other names ending in a digit match neither suffix.\n const last = key.charCodeAt(key.length - 1);\n if (last >= 48 && last <= 57) return KEY_RECURSE;\n let kind = IDENTITY_KEY_KINDS.get(key);\n if (kind === undefined) {\n kind = /(?:Id|Version)$/.test(key) ? KEY_IDENTITY : /Ids$/.test(key) ? KEY_IDENTITY_LIST : KEY_RECURSE;\n if (IDENTITY_KEY_KINDS.size < IDENTITY_WALK_MEMO_LIMIT) IDENTITY_KEY_KINDS.set(key, kind);\n }\n return kind;\n}\nfunction memoizedPublicId(value: unknown): void {\n if (typeof value === \"string\" && VALID_PUBLIC_IDS.has(value)) return;\n publicId(value);\n if (VALID_PUBLIC_IDS.size < IDENTITY_WALK_MEMO_LIMIT) VALID_PUBLIC_IDS.add(value as string);\n}\n/**\n * At any depth, every property whose name ends in Id or Version must hold a public ID, and every property\n * ending in Ids a bounded dense list of them. Order, keys and errors are the same as the earlier\n * Object.entries walk. Key classification and already-valid IDs are cached, because each depends only on\n * its string.\n */\nfunction publicIdentities(value: unknown): void {\n if (value === null || typeof value !== \"object\") return;\n const record = value as Record<string, unknown>, keys = Object.keys(record);\n for (let index = 0; index < keys.length; index++) {\n const key = keys[index]!, kind = identityKeyKind(key), child = record[key];\n if (kind === KEY_IDENTITY) memoizedPublicId(child);\n else if (kind === KEY_IDENTITY_LIST) dense(child, 256).forEach(memoizedPublicId);\n else if (child !== null && typeof child === \"object\") publicIdentities(child);\n }\n}\nfunction dense(value: unknown, maximum: number): unknown[] {\n if (!Array.isArray(value) || value.length > maximum || Array.from({ length: value.length }, (_, i) => i in value).includes(false)) {\n throw new InvalidConfigurationError(\"Expected bounded dense producer array.\");\n }\n return value;\n}\nfunction optionalEvidence(value: unknown): ReturnType<typeof parseEvidenceList> {\n return dense(value, 256).length === 0 ? [] : parseEvidenceList(value, \"optionalExposureEvidence\");\n}\nfunction exposureEvidence(value: unknown, temporalPhoto?: Record<string, unknown>): ComposeSensorAccumulatedChargeInput[\"photoSignal\"][\"componentEvidence\"] {\n if (temporalPhoto !== undefined) return parseSensorEqeTemporalPhotoSignal({ ...temporalPhoto, componentEvidence: value }).componentEvidence;\n const r = fields(value, [\"stationarity\", \"exposureBinding\"]);\n const b = fields(r.exposureBinding, [\"binding\", \"colorSamplingProfile\", \"nominalExposureDuration\", \"openingBoundary\", \"closingBoundary\"]);\n return { stationarity: parseEvidenceList(r.stationarity, \"stationarity\"), exposureBinding: {\n binding: parseEvidenceList(b.binding, \"binding\"), colorSamplingProfile: parseEvidenceList(b.colorSamplingProfile, \"colorSamplingProfile\"),\n nominalExposureDuration: parseEvidenceList(b.nominalExposureDuration, \"nominalExposureDuration\"),\n openingBoundary: optionalEvidence(b.openingBoundary), closingBoundary: optionalEvidence(b.closingBoundary) } };\n}\nconst common = [\"colorSamplingProfileId\", \"channelId\", \"site\", \"bindingId\", \"stationarityProfileId\", \"timeReference\",\n \"startOffsetSecondsFromOpeningReference\", \"endOffsetSecondsFromOpeningReference\", \"localExposureDurationSeconds\", \"componentEvidence\"];\nconst photoTrue: string[] = [\"timeStationarityEstablished\", ...PHOTO_SIGNAL_TRUE_FIELDS];\nconst photoFalse: string[] = [\"timeVaryingSignalIntegrated\", ...PHOTO_SIGNAL_DOWNSTREAM_FALSE_FIELDS];\nfunction chargeInput(value: unknown): ComposeSensorAccumulatedChargeInput {\n const r = fields(value, [\"photoSignal\", \"darkCharge\", \"additionalChargeComponents\", \"completenessProfile\"]);\n const temporal = r.photoSignal !== null && typeof r.photoSignal === \"object\" &&\n (r.photoSignal as Record<string, unknown>).kind === \"eqe-temporal-photo-signal\";\n const p = temporal ? parseSensorEqeTemporalPhotoSignal(r.photoSignal) as unknown as Record<string, unknown> : fields(r.photoSignal, [...common, ...photoTrue, ...photoFalse, \"kind\", \"stationarityStatus\", \"integrationMethod\",\n \"accumulatedSignalCompleteness\", \"incidentPhotonRatePerSecond\", \"expectedGeneratedElectronRatePerSecond\", \"expectedIncidentPhotonCount\", \"expectedGeneratedElectronCount\"]);\n const darkFalse = [\"integerDarkElectronCountSampled\", \"darkShotNoiseApplied\", \"darkCurrentCompensationApplied\", \"photoSignalIncluded\",\n \"otherChargeIncluded\", \"physicalFullWellAssessmentAuthorized\", \"saturationAssessed\"];\n const d = fields(r.darkCharge, [...common, ...darkFalse, \"darkCurrentProfileId\", \"operatingTemperatureC\", \"temperatureModel\",\n \"temperatureInterpolationUsed\", \"temporalIntegrationId\", \"darkCurrentElectronsPerSecond\", \"expectedDarkElectronCount\", \"countMeaning\", \"expectationValueOnly\", \"spatialDarkCurrentNonuniformityModeled\"]);\n if ((!temporal && (p.kind !== \"eqe-expected-counts\" || p.integrationMethod !== \"constant-rate-times-local-exposure-duration\" ||\n p.accumulatedSignalCompleteness !== \"photo-signal-only\" || (p.stationarityStatus !== \"established\" && p.stationarityStatus !== \"approximation\") ||\n photoTrue.some((k) => p[k] !== true) || photoFalse.some((k) => p[k] !== false))) || darkFalse.some((k) => d[k] !== false) ||\n d.expectationValueOnly !== true || d.countMeaning !== \"expected-thermally-generated-electrons\" ||\n typeof d.spatialDarkCurrentNonuniformityModeled !== \"boolean\" || typeof d.temperatureInterpolationUsed !== \"boolean\" ||\n (d.temperatureModel !== \"fixed-reference-temperature\" && d.temperatureModel !== \"piecewise-linear-temperature-table\" &&\n d.temperatureModel !== \"log-linear-temperature-table\")) {\n throw new InvalidConfigurationError(\"Producer requires untreated EQE/dark exposure expectations, not sampled, clipped or A/W charge.\");\n }\n if (d.temperatureModel === \"fixed-reference-temperature\" && d.temperatureInterpolationUsed !== false) {\n throw new InvalidConfigurationError(\"Fixed-temperature dark result cannot claim temperature interpolation.\");\n }\n for (const record of [p, d]) {\n for (const k of [\"colorSamplingProfileId\", \"channelId\", \"bindingId\", temporal ? \"temporalIntegrationId\" : \"stationarityProfileId\"]) publicId(record[k]);\n fields(record.site, [\"x\", \"y\"]);\n if (record.timeReference !== \"first-opening-boundary-phase\") throw new InvalidConfigurationError(\"Unsupported producer time origin.\");\n }\n publicId(d.darkCurrentProfileId);\n for (const [record, keys] of [[p, [\"incidentPhotonRatePerSecond\", \"expectedGeneratedElectronRatePerSecond\", \"expectedIncidentPhotonCount\", \"expectedGeneratedElectronCount\"]],\n [d, [\"darkCurrentElectronsPerSecond\", \"expectedDarkElectronCount\"]]] as const) {\n for (const k of keys) if (!(temporal && record === p && k.endsWith(\"RatePerSecond\")) && (typeof record[k] !== \"number\" || !Number.isFinite(record[k]) || record[k] < 0)) throw new InvalidConfigurationError(\"Invalid expected rates/counts.\");\n }\n const duration = p.localExposureDurationSeconds;\n if (typeof duration !== \"number\" || !Number.isFinite(duration) || duration <= 0 ||\n (!temporal && (p.expectedIncidentPhotonCount !== (p.incidentPhotonRatePerSecond as number)*duration ||\n p.expectedGeneratedElectronCount !== (p.expectedGeneratedElectronRatePerSecond as number)*duration)) ||\n d.expectedDarkElectronCount !== (d.darkCurrentElectronsPerSecond as number)*duration ||\n (p.expectedGeneratedElectronCount as number) > (p.expectedIncidentPhotonCount as number)) {\n throw new InvalidConfigurationError(\"Exposure expectations must match their exact temporal integral or constant-rate products and EQE domain.\");\n }\n const e = fields(d.componentEvidence, [\"darkCurrent\", \"siteApproximation\", \"exposure\"]);\n const charge = { photoSignal: { ...p, componentEvidence: exposureEvidence(p.componentEvidence, temporal ? p : undefined) },\n darkCharge: { ...d, componentEvidence: { darkCurrent: parseEvidenceList(e.darkCurrent, \"darkCurrent\"),\n siteApproximation: optionalEvidence(e.siteApproximation), exposure: exposureEvidence(e.exposure, temporal ? p : undefined) } },\n completenessProfile: parseSensorAccumulatedChargeCompletenessProfile(r.completenessProfile),\n ...(r.additionalChargeComponents === undefined ? {} : { additionalChargeComponents:\n dense(r.additionalChargeComponents, 32).map(parseSensorAdditionalStoredChargeComponent) }) } as unknown as ComposeSensorAccumulatedChargeInput;\n // The existing charge composition checks that photo, dark, additional and completeness events agree exactly.\n composeSensorAccumulatedCharge(charge);\n return charge;\n}\nfunction localWindows(frame: SensorRawProducerInput[\"frame\"], value: unknown): CalculationResult<CaptureExposureWindows> {\n const r = fields(value, [\"shutterMechanism\", \"nominalExposureDurationSeconds\", \"opening\", \"closing\"]);\n fields(r.nominalExposureDurationSeconds, [\"value\", \"unit\", \"evidence\"]);\n for (const boundary of [r.opening, r.closing]) {\n const b = fields(boundary, [\"kind\", \"directionNative\", \"traversalDurationSeconds\"]);\n if (b.directionNative !== undefined) fields(b.directionNative, [\"value\", \"evidence\"]);\n if (b.traversalDurationSeconds !== undefined) fields(b.traversalDurationSeconds, [\"value\", \"unit\", \"evidence\"]);\n }\n const native = frame.capture.geometry.nativeRaster;\n const timing = calculateCaptureExposureWindows({\n ...r as unknown as SensorRawProducerExposureWindowInput,\n nativeRaster: native,\n samplePointsNative: Array.from({ length: native.pixelWidth*native.pixelHeight }, (_, i) => ({\n x: i%native.pixelWidth+0.5, y: Math.floor(i/native.pixelWidth)+0.5\n }))\n });\n if (timing.value.nominalExposureDurationSeconds.value !== frame.capture.exposure.shutterSeconds) {\n throw new InvalidConfigurationError(\"Exposure schedule nominal duration differs from committed capture.\");\n }\n return timing;\n}\nfunction sourceBoundary(schedule: CaptureExposureWindows[\"opening\"][\"schedule\"]): SensorRawProducerExposureWindowInput[\"opening\"] {\n return schedule.kind === \"simultaneous\" ? { kind: \"simultaneous\" } : {\n kind: \"uniform-linear-native-scan\", directionNative: schedule.directionNative,\n traversalDurationSeconds: schedule.traversalDurationSeconds\n };\n}\n/** Internal: per-site validation shared by the reference path and bounded packed execution. */\nexport type NativeRawProducerFrameContext = Omit<SensorRawProducerInput[\"frame\"], \"capture\"> & {\n capture: Pick<SensorRawProducerInput[\"frame\"][\"capture\"], \"geometry\" | \"exposure\" | \"noise\" | \"focus\" | \"sceneStateId\" | \"sceneTimeSeconds\">;\n};\nexport function parseNativeRawProducerSite(site: unknown, i: number, frame: NativeRawProducerFrameContext,\n window?: CaptureExposureWindows[\"samples\"][number]): SensorRawProducerSiteInput {\n const native = frame.capture.geometry.nativeRaster;\n const s = fields(site, [\"charge\", \"samplingProfile\", \"capacityProfile\", \"operatingStateId\", \"readoutProfile\", \"regimeId\", \"fixedPatternNoise\"]);\n const charge = chargeInput(s.charge), p = charge.photoSignal;\n const contributors = resolveCaptureModeColorSamplingContributors({ nativeRaster: native, captureModeProfile: frame.captureModeProfile,\n modeId: frame.modeId, colorSamplingProfile: frame.colorSamplingProfile, bindingProfile: frame.bindingProfile,\n modeSampleIndexFullFrame: { x: i%native.pixelWidth, y: Math.floor(i/native.pixelWidth) } });\n\n if (contributors.totalContributorSites !== 1 || contributors.channelComposition.kind !== \"single-channel\" ||\n p.colorSamplingProfileId !== frame.colorSamplingProfile.profileId || p.channelId !== contributors.channelComposition.channelId ||\n p.site.x !== contributors.colorSamplingSiteRect.x || p.site.y !== contributors.colorSamplingSiteRect.y ||\n p.bindingId !== frame.bindingProfile.bindingId || p.startOffsetSecondsFromOpeningReference !== (window?.startOffsetSecondsFromOpeningReference ?? 0) ||\n p.endOffsetSecondsFromOpeningReference !== (window?.endOffsetSecondsFromOpeningReference ?? frame.capture.exposure.shutterSeconds) ||\n p.localExposureDurationSeconds !== (window?.localExposureDurationSeconds ?? frame.capture.exposure.shutterSeconds)) {\n throw new InvalidConfigurationError(\"Charge site/channel/binding/local exposure differs from committed capture.\");\n }\n const readoutProfile = parseSensorReadoutConversionProfile(s.readoutProfile);\n const isoGain = readoutProfile.regimes.find((regime) => regime.regimeId === s.regimeId)?.exposureIndexGain;\n if (isoGain !== undefined && isoGain.exposureIndex !== frame.capture.exposure.iso) {\n throw new InvalidConfigurationError(\"Readout regime ISO gain differs from the committed capture ISO.\");\n }\n return { charge, samplingProfile: parseSensorChargeSamplingProfile(s.samplingProfile), capacityProfile: parseSensorPhysicalChargeCapacityProfile(s.capacityProfile),\n operatingStateId: publicId(s.operatingStateId), readoutProfile, regimeId: publicId(s.regimeId),\n ...(s.fixedPatternNoise === undefined ? {} : { fixedPatternNoise: parseSensorFixedPatternNoiseProfile(s.fixedPatternNoise) }) };\n}\nexport function validateNativeRawReadoutIdentity(s: SensorRawProducerSiteInput, first: SensorRawProducerSiteInput): void {\n publicIdentities(s);\n const readout = resolveSensorReadoutRegime({ profile: s.readoutProfile, regimeId: s.regimeId });\n if (s.readoutProfile.profileId !== first.readoutProfile.profileId || s.regimeId !== first.regimeId ||\n readout.regime.adc.bitDepth > 16 || readout.regime.adc.digitalSaturationCode <= readout.regime.adc.blackLevelCode ||\n s.readoutProfile.colorSamplingProfileId !== s.charge.photoSignal.colorSamplingProfileId ||\n s.readoutProfile.channelId !== s.charge.photoSignal.channelId || s.samplingProfile.completenessProfileId !== s.charge.completenessProfile.profileId ||\n s.fixedPatternNoise?.profileId !== first.fixedPatternNoise?.profileId ||\n s.fixedPatternNoise?.sensorInstanceSeedUint32 !== first.fixedPatternNoise?.sensorInstanceSeedUint32) {\n throw new InvalidConfigurationError(\"Frame requires one readout identity/regime, one fixed-pattern identity and a positive uint16 RAW code span.\");\n }\n}\n/** The shared per-site pipeline holds all the charge, capacity, random-noise and ADC equations. `i` is the absolute native row-major index. */\nexport function calculateNativeRawSite(s: SensorRawProducerSiteInput, seed: number, i: number): SensorRawProducerResult[\"sites\"][number] {\n const accumulatedCharge = composeSensorAccumulatedCharge(s.charge);\n const capacity = assessSensorPhysicalChargeCapacity({ accumulatedCharge: accumulatedCharge.value, capacityProfile: s.capacityProfile,\n operatingStateId: s.operatingStateId, operatingTemperatureC: s.charge.darkCharge.operatingTemperatureC });\n const pattern = s.fixedPatternNoise === undefined ? {} : { fixedPatternNoise: s.fixedPatternNoise };\n const realization = simulateSensorChargeRealization({ accumulatedCharge: accumulatedCharge.value, samplingProfile: s.samplingProfile,\n seedUint32: deriveNativeSiteStreamSeedUint32(seed, i, NATIVE_SITE_CHARGE_STREAM_ID), ...pattern });\n const readout = simulateSensorRawCode({ chargeRealization: realization.value, physicalCapacityAssessment: capacity.value,\n readoutProfile: s.readoutProfile, regimeId: s.regimeId,\n readNoiseSeedUint32: deriveNativeSiteStreamSeedUint32(seed, i, NATIVE_SITE_READ_NOISE_STREAM_ID), ...pattern });\n return { accumulatedCharge, capacity, realization, readout };\n}\n/** The selected regime's declared INL, which the effective white level needs at saturation. */\nfunction regimeInl(site: SensorRawProducerSiteInput): { adcIntegralNonLinearity?: NonNullable<SensorReadoutConversionProfile[\"regimes\"][number][\"adc\"][\"integralNonLinearity\"]> } {\n const inl = site.readoutProfile.regimes.find((r) => r.regimeId === site.regimeId)?.adc.integralNonLinearity;\n return inl === undefined ? {} : { adcIntegralNonLinearity: inl };\n}\n/** Validates the complete per-site exposure inputs. Charge, noise or RAW codes are never accepted as a shortcut. */\nexport function parseSensorRawProducerInput(value: unknown): SensorRawProducerInput {\n const r = fields(value, [\"frame\", \"sites\", \"exposureWindow\"]), f = fields(r.frame, [\"frameId\", \"capture\", \"modeId\", \"captureModeProfile\", \"colorSamplingProfile\", \"bindingProfile\", \"containerBitDepth\"]);\n const capture = parseSimulatedCapture(f.capture), native = capture.geometry.nativeRaster, count = native.pixelWidth*native.pixelHeight;\n const sites = dense(r.sites, RAW_REFERENCE_MAX_NATIVE_SITES);\n const frame = { frameId: publicId(f.frameId), capture, modeId: publicId(f.modeId), containerBitDepth: 16 as const,\n captureModeProfile: parseCaptureModeProfile(f.captureModeProfile), colorSamplingProfile: parseSensorColorSamplingProfile(f.colorSamplingProfile),\n bindingProfile: parseNativeEffectiveRasterColorSamplingBindingProfile(f.bindingProfile) };\n const mode = frame.captureModeProfile.modes.find((m) => m.modeId === frame.modeId);\n if (f.containerBitDepth !== 16 || count > RAW_REFERENCE_MAX_NATIVE_SITES || sites.length !== count ||\n capture.noise.model.id !== SENSOR_RAW_PRODUCER_NOISE_MODEL.id || capture.noise.model.version !== SENSOR_RAW_PRODUCER_NOISE_MODEL.version ||\n frame.colorSamplingProfile.layout.kind !== \"periodic-mosaic\" || !mode || mode.acquisition.kind !== \"single-frame\" ||\n mode.perFrameSampling.kind !== \"native-effective-raster\" || (mode.reconstructionStages?.length ?? 0) !== 0) {\n throw new InvalidConfigurationError(\"Producer requires exact noise identity and bounded single-frame native CFA coverage.\");\n }\n const timing = r.exposureWindow === undefined ? undefined : localWindows(frame, r.exposureWindow);\n const parsed = sites.map((site, i) => parseNativeRawProducerSite(site, i, frame, timing?.value.samples[i]));\n for (const site of parsed) validateNativeRawReadoutIdentity(site, parsed[0]!);\n publicIdentities(frame);\n return { frame, sites: parsed, ...(timing === undefined ? {} : { exposureWindow: {\n shutterMechanism: timing.value.shutterMechanism,\n nominalExposureDurationSeconds: timing.value.nominalExposureDurationSeconds,\n opening: sourceBoundary(timing.value.opening.schedule), closing: sourceBoundary(timing.value.closing.schedule)\n } }) };\n}\n/** Runs accumulated charge → capacity → Poisson noise → read noise and ADC → native sample → immutable frame. */\nexport function simulateSensorRawFrame(input: SensorRawProducerInput): CalculationResult<SensorRawProducerResult> {\n const v = parseSensorRawProducerInput(input), seed = v.frame.capture.noise.seedUint32;\n const sites = v.sites.map((s, i) => calculateNativeRawSite(s, seed, i));\n const native = v.frame.capture.geometry.nativeRaster;\n const samples = sites.map((s, i) => createSensorRawCaptureSample({ rawCode: s.readout.value,\n ...regimeInl(v.sites[i]!),\n contributors: resolveCaptureModeColorSamplingContributors({ nativeRaster: native, captureModeProfile: v.frame.captureModeProfile,\n modeId: v.frame.modeId, colorSamplingProfile: v.frame.colorSamplingProfile, bindingProfile: v.frame.bindingProfile,\n modeSampleIndexFullFrame: { x: i%native.pixelWidth, y: Math.floor(i/native.pixelWidth) } }) }));\n return approximationResult({ schemaVersion: SENSOR_RAW_PRODUCER_SCHEMA_VERSION, codeProducer: \"engine-charge-capacity-noise-adc\",\n upstreamOrigin: \"declared-eqe-and-dark-exposure-results\", upstreamRadiometryVerified: false,\n seedSchedule: \"murmur3-capture-seed-native-index-stream-v2\", frame: createSensorRawFrame({ ...v.frame, samples }), sites,\n ...(v.exposureWindow === undefined ? {} : { localExposureWindows: localWindows(v.frame, v.exposureWindow) }) },\n \"native-sensor-raw-frame-producer\", SENSOR_RAW_PRODUCER_SCHEMA_VERSION, [\n \"Untreated EQE/dark exposure results and completeness evidence are upstream declarations; source radiometry is not independently verified\",\n \"Native row-major site seeds are MurmurHash3_x86_32 of (capture seed, absolute native index, stream 0 charge / 1 read noise); deterministic and non-cryptographic\",\n \"Existing scalar capacity/noise/readout approximations retain distinct physical/pre-ADC/digital saturation diagnostics; no blooming\",\n \"Optional fixed-pattern noise is deterministic per sensor instance (its own seed and absolute colour-sampling site), independent of the capture seed\",\n \"Stationarity applies separately to every exact local window; no time-varying radiance integration, multi-frame acquisition, RGB-to-RAW conversion or production-stage activation\",\n \"Stored capture float planes remain independent; same-RAW export must use the returned frame's reconstruction handoff\"]);\n}\n"]}
|
|
@@ -31,3 +31,5 @@ export declare function fullRect(raster: {
|
|
|
31
31
|
width: number;
|
|
32
32
|
height: number;
|
|
33
33
|
};
|
|
34
|
+
/** |actual − expected| ≤ tolerance · max(1, |actual|, |expected|): the parsers' shared consistency check (default 1e-10). */
|
|
35
|
+
export declare function approximatelyEqual(actual: number, expected: number, tolerance?: number): boolean;
|
|
@@ -31,4 +31,8 @@ export function sameSite(a, b) {
|
|
|
31
31
|
export function fullRect(raster) {
|
|
32
32
|
return { x: 0, y: 0, width: raster.pixelWidth, height: raster.pixelHeight };
|
|
33
33
|
}
|
|
34
|
+
/** |actual − expected| ≤ tolerance · max(1, |actual|, |expected|): the parsers' shared consistency check (default 1e-10). */
|
|
35
|
+
export function approximatelyEqual(actual, expected, tolerance = 1e-10) {
|
|
36
|
+
return Math.abs(actual - expected) <= tolerance * Math.max(1, Math.abs(actual), Math.abs(expected));
|
|
37
|
+
}
|
|
34
38
|
//# sourceMappingURL=shared-helpers.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shared-helpers.js","sourceRoot":"","sources":["../../src/core/shared-helpers.ts"],"names":[],"mappings":"AAAA,sCAAsC;AAEtC;;;GAGG;AAEH,2GAA2G;AAC3G,MAAM,UAAU,UAAU,CAAI,KAAQ;IACpC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IACxF,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACrB,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,MAAM,CAAC,KAAgC,CAAC;QAAE,UAAU,CAAC,KAAK,CAAC,CAAC;IACvF,OAAO,KAAK,CAAC;AACf,CAAC;AACD,gCAAgC;AAChC,MAAM,UAAU,SAAS,CAAI,KAAQ;IACnC,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAM,CAAC;AAChD,CAAC;AAGD,4DAA4D;AAC5D,MAAM,UAAU,cAAc,CAAC,KAAqB,EAAE,KAAa;IACjE,MAAM,QAAQ,GAAG,KAAK,GAAG,KAAK,CAAC,UAAU,CAAC;IAC1C,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,GAAG,QAAQ,CAAC;IAClC,KAAK,CAAC,UAAU,GAAG,CAAC,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC;IACjD,KAAK,CAAC,GAAG,GAAG,IAAI,CAAC;AACnB,CAAC;AACD,2DAA2D;AAC3D,MAAM,UAAU,QAAQ,CAAC,CAA2B,EAAE,CAA2B;IAC/E,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACpC,CAAC;AACD,qDAAqD;AACrD,MAAM,UAAU,QAAQ,CAAC,MAAmD;IAC1E,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,CAAC,WAAW,EAAE,CAAC;AAC9E,CAAC","sourcesContent":["// SPDX-License-Identifier: Apache-2.0\n\n/**\n * Small helpers shared by several modules (2.19.0: these were private copies in each; one shared copy keeps the bundles\n * smaller). Behaviour is unchanged.\n */\n\n/** Freezes a value and every object it holds, depth first; already frozen objects are left as they are. */\nexport function deepFreeze<T>(value: T): T {\n if (typeof value !== \"object\" || value === null || Object.isFrozen(value)) return value;\n Object.freeze(value);\n for (const child of Object.values(value as Record<string, unknown>)) deepFreeze(child);\n return value;\n}\n/** A deep copy of JSON data. */\nexport function cloneJson<T>(value: T): T {\n return JSON.parse(JSON.stringify(value)) as T;\n}\n/** A running sum with Kahan compensation. */\nexport interface CompensatedSum { sum: number; correction: number }\n/** Adds `value` to a Kahan-compensated sum (Kahan 1965). */\nexport function addCompensated(state: CompensatedSum, value: number): void {\n const adjusted = value - state.correction;\n const next = state.sum + adjusted;\n state.correction = (next - state.sum) - adjusted;\n state.sum = next;\n}\n/** Whether two points (or sites) have the same x and y. */\nexport function sameSite(a: { x: number; y: number }, b: { x: number; y: number }): boolean {\n return a.x === b.x && a.y === b.y;\n}\n/** The whole raster as a rectangle at the origin. */\nexport function fullRect(raster: { pixelWidth: number; pixelHeight: number }): { x: number; y: number; width: number; height: number } {\n return { x: 0, y: 0, width: raster.pixelWidth, height: raster.pixelHeight };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"shared-helpers.js","sourceRoot":"","sources":["../../src/core/shared-helpers.ts"],"names":[],"mappings":"AAAA,sCAAsC;AAEtC;;;GAGG;AAEH,2GAA2G;AAC3G,MAAM,UAAU,UAAU,CAAI,KAAQ;IACpC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IACxF,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACrB,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,MAAM,CAAC,KAAgC,CAAC;QAAE,UAAU,CAAC,KAAK,CAAC,CAAC;IACvF,OAAO,KAAK,CAAC;AACf,CAAC;AACD,gCAAgC;AAChC,MAAM,UAAU,SAAS,CAAI,KAAQ;IACnC,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAM,CAAC;AAChD,CAAC;AAGD,4DAA4D;AAC5D,MAAM,UAAU,cAAc,CAAC,KAAqB,EAAE,KAAa;IACjE,MAAM,QAAQ,GAAG,KAAK,GAAG,KAAK,CAAC,UAAU,CAAC;IAC1C,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,GAAG,QAAQ,CAAC;IAClC,KAAK,CAAC,UAAU,GAAG,CAAC,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC;IACjD,KAAK,CAAC,GAAG,GAAG,IAAI,CAAC;AACnB,CAAC;AACD,2DAA2D;AAC3D,MAAM,UAAU,QAAQ,CAAC,CAA2B,EAAE,CAA2B;IAC/E,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACpC,CAAC;AACD,qDAAqD;AACrD,MAAM,UAAU,QAAQ,CAAC,MAAmD;IAC1E,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,CAAC,WAAW,EAAE,CAAC;AAC9E,CAAC;AAED,6HAA6H;AAC7H,MAAM,UAAU,kBAAkB,CAAC,MAAc,EAAE,QAAgB,EAAE,SAAS,GAAG,KAAK;IACpF,OAAO,IAAI,CAAC,GAAG,CAAC,MAAM,GAAG,QAAQ,CAAC,IAAI,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC;AACtG,CAAC","sourcesContent":["// SPDX-License-Identifier: Apache-2.0\n\n/**\n * Small helpers shared by several modules (2.19.0: these were private copies in each; one shared copy keeps the bundles\n * smaller). Behaviour is unchanged.\n */\n\n/** Freezes a value and every object it holds, depth first; already frozen objects are left as they are. */\nexport function deepFreeze<T>(value: T): T {\n if (typeof value !== \"object\" || value === null || Object.isFrozen(value)) return value;\n Object.freeze(value);\n for (const child of Object.values(value as Record<string, unknown>)) deepFreeze(child);\n return value;\n}\n/** A deep copy of JSON data. */\nexport function cloneJson<T>(value: T): T {\n return JSON.parse(JSON.stringify(value)) as T;\n}\n/** A running sum with Kahan compensation. */\nexport interface CompensatedSum { sum: number; correction: number }\n/** Adds `value` to a Kahan-compensated sum (Kahan 1965). */\nexport function addCompensated(state: CompensatedSum, value: number): void {\n const adjusted = value - state.correction;\n const next = state.sum + adjusted;\n state.correction = (next - state.sum) - adjusted;\n state.sum = next;\n}\n/** Whether two points (or sites) have the same x and y. */\nexport function sameSite(a: { x: number; y: number }, b: { x: number; y: number }): boolean {\n return a.x === b.x && a.y === b.y;\n}\n/** The whole raster as a rectangle at the origin. */\nexport function fullRect(raster: { pixelWidth: number; pixelHeight: number }): { x: number; y: number; width: number; height: number } {\n return { x: 0, y: 0, width: raster.pixelWidth, height: raster.pixelHeight };\n}\n\n/** |actual − expected| ≤ tolerance · max(1, |actual|, |expected|): the parsers' shared consistency check (default 1e-10). */\nexport function approximatelyEqual(actual: number, expected: number, tolerance = 1e-10): boolean {\n return Math.abs(actual - expected) <= tolerance * Math.max(1, Math.abs(actual), Math.abs(expected));\n}\n"]}
|
package/dist/core/version.d.ts
CHANGED
package/dist/core/version.js
CHANGED
package/dist/core/version.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"version.js","sourceRoot":"","sources":["../../src/core/version.ts"],"names":[],"mappings":"AAAA,sCAAsC;AAEtC;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,QAAiB,CAAC","sourcesContent":["// SPDX-License-Identifier: Apache-2.0\n\n/**\n * Version of the engine release. Since 1.0.1 it equals the npm package version.\n *\n * New captures and plans record this version as their creator. Archived records keep the\n * version they were made with. Proof-of-concept (POC), schema and model contracts have their\n * own versions. Release checks confirm it matches package.json and the packed package.\n * @see docs/RELEASE_1_0_1.md\n */\nexport const ENGINE_API_VERSION = \"2.
|
|
1
|
+
{"version":3,"file":"version.js","sourceRoot":"","sources":["../../src/core/version.ts"],"names":[],"mappings":"AAAA,sCAAsC;AAEtC;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,QAAiB,CAAC","sourcesContent":["// SPDX-License-Identifier: Apache-2.0\n\n/**\n * Version of the engine release. Since 1.0.1 it equals the npm package version.\n *\n * New captures and plans record this version as their creator. Archived records keep the\n * version they were made with. Proof-of-concept (POC), schema and model contracts have their\n * own versions. Release checks confirm it matches package.json and the packed package.\n * @see docs/RELEASE_1_0_1.md\n */\nexport const ENGINE_API_VERSION = \"2.20.0\" as const;\n"]}
|
|
@@ -2,6 +2,7 @@ import type { EvidenceProvenance } from "../core/evidence-provenance.js";
|
|
|
2
2
|
import type { LensProjectionModel } from "../camera/lens-projection.js";
|
|
3
3
|
import type { RadialDistortionProfile } from "../optics/radial-distortion.js";
|
|
4
4
|
import type { IlluminationVignettingProfile } from "../optics/illumination-vignetting.js";
|
|
5
|
+
import type { DefocusBokehOptions } from "../optics/defocus-bokeh-kernel.js";
|
|
5
6
|
export type GenericLensSet = "professional" | "consumer";
|
|
6
7
|
export type GenericLensKind = "standard" | "macro" | "fisheye";
|
|
7
8
|
/** The character of a set, at each lens's widest aperture. Aberrations are in waves at 550 nm at the frame corner. */
|
|
@@ -22,7 +23,7 @@ export interface GenericLensCharacterValues {
|
|
|
22
23
|
distortionMagnitude: number;
|
|
23
24
|
/** Corner fall-off in stops that stays when stopped down (natural vignetting). */
|
|
24
25
|
naturalVignettingStops: number;
|
|
25
|
-
/** Extra corner fall-off in stops at the widest aperture (optical vignetting); gone
|
|
26
|
+
/** Extra corner fall-off in stops at the widest aperture (optical vignetting); gone four stops down (N = 4·N0). */
|
|
26
27
|
opticalVignettingStops: number;
|
|
27
28
|
/** Veiling glare: the fraction of the image's mean irradiance spread as a uniform veil. */
|
|
28
29
|
veilingGlareFraction: number;
|
|
@@ -60,7 +61,7 @@ export interface GenericLensCatalogueEntry {
|
|
|
60
61
|
note: string;
|
|
61
62
|
/**
|
|
62
63
|
* A short plain-English summary of the lens's character (at most 40 characters, US spelling), written from its adjustments and
|
|
63
|
-
* `note`, for lists and pickers. It describes
|
|
64
|
+
* `note`, for lists and pickers. It describes the lens's sharpness, color, distortion and falloff, not its bokeh (the same rule for every lens of a set).
|
|
64
65
|
*/
|
|
65
66
|
summary: string;
|
|
66
67
|
}
|
|
@@ -119,6 +120,11 @@ export interface GenericLensCharacter {
|
|
|
119
120
|
};
|
|
120
121
|
/** Standard deviation of the autofocus error as a fraction of the depth of focus 2·N·c. */
|
|
121
122
|
focusScatterDepthOfFocusFraction: number;
|
|
123
|
+
/**
|
|
124
|
+
* Bokeh character (#567) at this f-number, focus and sensor, as the options of `lens.defocus` and `calculateDefocusBokehKernel`
|
|
125
|
+
* (#553): blades, the resolved W040 as `sphericalAberration` (µm at this f-number) and, for fast wides and normals, `catsEye`.
|
|
126
|
+
*/
|
|
127
|
+
bokeh: DefocusBokehOptions;
|
|
122
128
|
}
|
|
123
129
|
export interface ResolvedGenericLens {
|
|
124
130
|
lensId: string;
|