@photivra/engine 2.20.0 → 2.22.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +295 -1
- package/CITATION.cff +1 -1
- package/README.md +7 -6
- package/SECURITY.md +1 -1
- package/THIRD_PARTY.md +18 -0
- package/dist/capture/c2pa-embed.d.ts +116 -0
- package/dist/capture/c2pa-embed.js +493 -0
- package/dist/capture/c2pa-embed.js.map +1 -0
- package/dist/capture/dng-import.d.ts +73 -8
- package/dist/capture/dng-import.js +315 -80
- package/dist/capture/dng-import.js.map +1 -1
- package/dist/capture/dng-lens-correction-opcodes.d.ts +2 -2
- package/dist/capture/dng-lens-correction-opcodes.js +2 -2
- package/dist/capture/dng-lens-correction-opcodes.js.map +1 -1
- package/dist/capture/dng-opcodes.d.ts +96 -0
- package/dist/capture/dng-opcodes.js +391 -0
- package/dist/capture/dng-opcodes.js.map +1 -0
- package/dist/capture/dng-profile-maps.d.ts +99 -0
- package/dist/capture/dng-profile-maps.js +381 -0
- package/dist/capture/dng-profile-maps.js.map +1 -0
- package/dist/capture/dng-stage-image.d.ts +23 -0
- package/dist/capture/dng-stage-image.js +65 -0
- package/dist/capture/dng-stage-image.js.map +1 -0
- package/dist/capture/exposure-build-up-stage.d.ts +16 -0
- package/dist/capture/exposure-build-up-stage.js +4 -0
- package/dist/capture/exposure-build-up-stage.js.map +1 -0
- package/dist/capture/jpeg-xl-tiles.d.ts +22 -0
- package/dist/capture/jpeg-xl-tiles.js +151 -0
- package/dist/capture/jpeg-xl-tiles.js.map +1 -0
- package/dist/capture/lossy-jpeg.d.ts +17 -0
- package/dist/capture/lossy-jpeg.js +369 -0
- package/dist/capture/lossy-jpeg.js.map +1 -0
- package/dist/capture/native-environment-lean.d.ts +2 -1
- package/dist/capture/native-environment-lean.js +41 -73
- package/dist/capture/native-environment-lean.js.map +1 -1
- package/dist/capture/native-environment-tabulated.js +4 -3
- package/dist/capture/native-environment-tabulated.js.map +1 -1
- package/dist/capture/native-raw-development.d.ts +2 -1
- package/dist/capture/native-raw-development.js.map +1 -1
- package/dist/capture/native-raw.d.ts +3 -2
- package/dist/capture/native-raw.js +5 -4
- package/dist/capture/native-raw.js.map +1 -1
- package/dist/capture/sensor-raw-producer.d.ts +4 -1
- package/dist/capture/sensor-raw-producer.js +12 -3
- package/dist/capture/sensor-raw-producer.js.map +1 -1
- package/dist/color/neighbor-highlight-reconstruction.d.ts +66 -0
- package/dist/color/neighbor-highlight-reconstruction.js +234 -0
- package/dist/color/neighbor-highlight-reconstruction.js.map +1 -0
- package/dist/color/sensor-color-development.d.ts +5 -0
- package/dist/color/sensor-color-development.js +7 -1
- package/dist/color/sensor-color-development.js.map +1 -1
- package/dist/color/spectral-spikiness.d.ts +11 -0
- package/dist/color/spectral-spikiness.js +23 -0
- package/dist/color/spectral-spikiness.js.map +1 -0
- package/dist/core/execution-error.d.ts +21 -0
- package/dist/core/execution-error.js +12 -0
- package/dist/core/execution-error.js.map +1 -0
- 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 +3 -2
- package/dist/equipment/generic-lens-catalogue.js +18 -5
- package/dist/equipment/generic-lens-catalogue.js.map +1 -1
- package/dist/equipment/generic-tier-assets.d.ts +32 -0
- package/dist/equipment/generic-tier-assets.js +16 -11
- package/dist/equipment/generic-tier-assets.js.map +1 -1
- package/dist/equipment/sensor-profile-body.d.ts +78 -0
- package/dist/equipment/sensor-profile-body.js +77 -0
- package/dist/equipment/sensor-profile-body.js.map +1 -0
- package/dist/equipment/sensor-profiles.d.ts +8 -0
- package/dist/equipment/sensor-profiles.js +82 -0
- package/dist/equipment/sensor-profiles.js.map +1 -0
- package/dist/facade/catalogue-lens-signal.d.ts +28 -3
- package/dist/facade/catalogue-lens-signal.js +83 -78
- package/dist/facade/catalogue-lens-signal.js.map +1 -1
- package/dist/facade/chart-radiance-batch.js +2 -1
- package/dist/facade/chart-radiance-batch.js.map +1 -1
- package/dist/facade/defocus-image-space-provider.d.ts +7 -0
- package/dist/facade/defocus-image-space-provider.js +64 -76
- package/dist/facade/defocus-image-space-provider.js.map +1 -1
- package/dist/facade/diffraction-provider.d.ts +1 -1
- package/dist/facade/diffraction-provider.js +4 -4
- package/dist/facade/diffraction-provider.js.map +1 -1
- package/dist/facade/display-view-gpu-session.js +39 -5
- package/dist/facade/display-view-gpu-session.js.map +1 -1
- package/dist/facade/display-view-gpu.d.ts +19 -6
- package/dist/facade/display-view-gpu.js.map +1 -1
- package/dist/facade/display-view-lens-signal.js +25 -23
- package/dist/facade/display-view-lens-signal.js.map +1 -1
- package/dist/facade/display-view-normal.d.ts +15 -0
- package/dist/facade/display-view-normal.js +44 -0
- package/dist/facade/display-view-normal.js.map +1 -0
- package/dist/facade/display-view-rendering.d.ts +97 -0
- package/dist/facade/display-view-rendering.js +598 -0
- package/dist/facade/display-view-rendering.js.map +1 -0
- package/dist/facade/display-view.d.ts +37 -65
- package/dist/facade/display-view.js +152 -499
- package/dist/facade/display-view.js.map +1 -1
- package/dist/facade/expected-signal-setup.d.ts +3 -1
- package/dist/facade/expected-signal-setup.js +3 -3
- package/dist/facade/expected-signal-setup.js.map +1 -1
- package/dist/facade/expected-signal.d.ts +47 -14
- package/dist/facade/expected-signal.js +117 -112
- package/dist/facade/expected-signal.js.map +1 -1
- package/dist/facade/exposure-build-up.d.ts +70 -0
- package/dist/facade/exposure-build-up.js +164 -0
- package/dist/facade/exposure-build-up.js.map +1 -0
- package/dist/facade/fast-methods.d.ts +1 -1
- package/dist/facade/fast-methods.js +46 -9
- package/dist/facade/fast-methods.js.map +1 -1
- package/dist/facade/generic-lens-capture.d.ts +3 -3
- package/dist/facade/generic-lens-capture.js +3 -3
- package/dist/facade/generic-lens-capture.js.map +1 -1
- package/dist/facade/image-plane-enable.d.ts +7 -0
- package/dist/facade/image-plane-enable.js +17 -0
- package/dist/facade/image-plane-enable.js.map +1 -0
- package/dist/facade/image-plane-lattice-data.d.ts +6 -0
- package/dist/facade/image-plane-lattice-data.js +10 -0
- package/dist/facade/image-plane-lattice-data.js.map +1 -0
- package/dist/facade/image-plane-support.d.ts +33 -0
- package/dist/facade/image-plane-support.js +11 -0
- package/dist/facade/image-plane-support.js.map +1 -0
- package/dist/facade/image-plane.d.ts +36 -0
- package/dist/facade/image-plane.js +384 -0
- package/dist/facade/image-plane.js.map +1 -0
- package/dist/facade/mixed-illumination.d.ts +108 -0
- package/dist/facade/mixed-illumination.js +174 -0
- package/dist/facade/mixed-illumination.js.map +1 -0
- package/dist/facade/on-demand-kits.d.ts +14 -0
- package/dist/facade/on-demand-kits.js +36 -0
- package/dist/facade/on-demand-kits.js.map +1 -0
- package/dist/facade/opt-in-kit.d.ts +9 -0
- package/dist/facade/opt-in-kit.js +11 -0
- package/dist/facade/opt-in-kit.js.map +1 -0
- package/dist/facade/quality-kit.d.ts +21 -0
- package/dist/facade/quality-kit.js +23 -0
- package/dist/facade/quality-kit.js.map +1 -0
- package/dist/facade/quality-paths.d.ts +22 -0
- package/dist/facade/quality-paths.js +44 -0
- package/dist/facade/quality-paths.js.map +1 -0
- package/dist/facade/representative-light-sources.d.ts +72 -0
- package/dist/facade/representative-light-sources.js +124 -0
- package/dist/facade/representative-light-sources.js.map +1 -0
- package/dist/facade/scene-radiance.d.ts +145 -4
- package/dist/facade/scene-radiance.js +50 -13
- package/dist/facade/scene-radiance.js.map +1 -1
- package/dist/facade/simulate-capture.d.ts +68 -20
- package/dist/facade/simulate-capture.js +399 -146
- package/dist/facade/simulate-capture.js.map +1 -1
- package/dist/facade/simulate-display-view.d.ts +10 -12
- package/dist/facade/simulate-display-view.js +70 -53
- package/dist/facade/simulate-display-view.js.map +1 -1
- package/dist/gpu/chart-composite-gpu.d.ts +13 -1
- package/dist/gpu/chart-composite-gpu.js +48 -9
- package/dist/gpu/chart-composite-gpu.js.map +1 -1
- package/dist/gpu/chart-radiance-gpu.js +4 -30
- package/dist/gpu/chart-radiance-gpu.js.map +1 -1
- package/dist/gpu/display-view-composite-material-module.d.ts +10 -4
- package/dist/gpu/display-view-composite-material-module.js +39 -13
- package/dist/gpu/display-view-composite-material-module.js.map +1 -1
- package/dist/gpu/display-view-gpu-renderer.d.ts +43 -0
- package/dist/gpu/display-view-gpu-renderer.js +134 -0
- package/dist/gpu/display-view-gpu-renderer.js.map +1 -0
- package/dist/gpu/display-view-image-material-module.d.ts +87 -0
- package/dist/gpu/display-view-image-material-module.js +361 -0
- package/dist/gpu/display-view-image-material-module.js.map +1 -0
- package/dist/gpu/display-view-image-quality.d.ts +87 -0
- package/dist/gpu/display-view-image-quality.js +625 -0
- package/dist/gpu/display-view-image-quality.js.map +1 -0
- package/dist/gpu/display-view-quality-gpu.d.ts +80 -65
- package/dist/gpu/display-view-quality-gpu.js +187 -445
- package/dist/gpu/display-view-quality-gpu.js.map +1 -1
- package/dist/gpu/display-view-speed-gpu.d.ts +67 -19
- package/dist/gpu/display-view-speed-gpu.js +181 -105
- package/dist/gpu/display-view-speed-gpu.js.map +1 -1
- package/dist/gpu/image-kernel-accelerator.js +3 -0
- package/dist/gpu/image-kernel-accelerator.js.map +1 -1
- package/dist/gpu/image-kernel-execution.d.ts +2 -13
- package/dist/gpu/image-kernel-execution.js +2 -10
- package/dist/gpu/image-kernel-execution.js.map +1 -1
- package/dist/gpu/wgsl-display-view-coupled-stub.d.ts +8 -0
- package/dist/gpu/wgsl-display-view-coupled-stub.js +21 -0
- package/dist/gpu/wgsl-display-view-coupled-stub.js.map +1 -0
- package/dist/gpu/wgsl-display-view-coupled.d.ts +88 -0
- package/dist/gpu/wgsl-display-view-coupled.js +353 -0
- package/dist/gpu/wgsl-display-view-coupled.js.map +1 -0
- package/dist/gpu/wgsl-display-view-quality-kernel.d.ts +33 -24
- package/dist/gpu/wgsl-display-view-quality-kernel.js +166 -146
- package/dist/gpu/wgsl-display-view-quality-kernel.js.map +1 -1
- package/dist/gpu/wgsl-display-view-speed-kernel.d.ts +19 -44
- package/dist/gpu/wgsl-display-view-speed-kernel.js +116 -18
- package/dist/gpu/wgsl-display-view-speed-kernel.js.map +1 -1
- package/dist/gpu/wgsl-exact-sum.d.ts +20 -0
- package/dist/gpu/wgsl-exact-sum.js +42 -0
- package/dist/gpu/wgsl-exact-sum.js.map +1 -0
- package/dist/index.d.ts +22 -6
- package/dist/index.js +16 -2
- package/dist/index.js.map +1 -1
- package/dist/motion/subject-motion.d.ts +66 -0
- package/dist/motion/subject-motion.js +52 -0
- package/dist/motion/subject-motion.js.map +1 -0
- package/dist/optics/generic-lens-lateral-color.d.ts +83 -0
- package/dist/optics/generic-lens-lateral-color.js +77 -0
- package/dist/optics/generic-lens-lateral-color.js.map +1 -0
- package/dist/optics/generic-lens-psf.js +54 -46
- package/dist/optics/generic-lens-psf.js.map +1 -1
- package/dist/optics/lens-psf-profile.d.ts +7 -0
- package/dist/optics/lens-psf-profile.js +2 -1
- package/dist/optics/lens-psf-profile.js.map +1 -1
- package/dist/output/camera-channel-response.d.ts +50 -0
- package/dist/output/camera-channel-response.js +69 -0
- package/dist/output/camera-channel-response.js.map +1 -0
- package/dist/output/developed-lens-corrections.d.ts +19 -5
- package/dist/output/developed-lens-corrections.js +28 -9
- package/dist/output/developed-lens-corrections.js.map +1 -1
- package/dist/output/generic-lens-corrections.d.ts +41 -5
- package/dist/output/generic-lens-corrections.js +52 -8
- package/dist/output/generic-lens-corrections.js.map +1 -1
- package/dist/output/native-capture-sdr.js +5 -2
- package/dist/output/native-capture-sdr.js.map +1 -1
- package/dist/output/print-plan.d.ts +41 -5
- package/dist/output/print-plan.js +59 -14
- package/dist/output/print-plan.js.map +1 -1
- package/dist/output/sdr-rendering.d.ts +18 -1
- package/dist/output/sdr-rendering.js +39 -2
- package/dist/output/sdr-rendering.js.map +1 -1
- package/dist/sensor/binomial-sample.d.ts +3 -0
- package/dist/sensor/binomial-sample.js +86 -0
- package/dist/sensor/binomial-sample.js.map +1 -0
- package/dist/sensor/native-sensor-report.d.ts +10 -0
- package/dist/sensor/native-sensor-report.js +16 -0
- package/dist/sensor/native-sensor-report.js.map +1 -0
- package/dist/sensor/sensor-characteristics.d.ts +91 -13
- package/dist/sensor/sensor-characteristics.js +30 -15
- package/dist/sensor/sensor-characteristics.js.map +1 -1
- package/docs/AGENT_GUIDE.md +1 -0
- package/docs/API_REFERENCE.md +214 -4
- package/docs/QUICK_START.md +162 -8
- package/docs/USAGE.md +195 -22
- package/docs/api/capture-c2pa-embed.md +177 -0
- package/docs/api/capture-dng-import.md +86 -10
- package/docs/api/capture-dng-opcodes.md +93 -0
- package/docs/api/capture-dng-profile-maps.md +141 -0
- package/docs/api/capture-dng-stage-image.md +43 -0
- package/docs/api/capture-jpeg-xl-tiles.md +33 -0
- package/docs/api/capture-lossy-jpeg.md +41 -0
- package/docs/api/capture-native-raw-development.md +2 -1
- package/docs/api/core-execution-error.md +43 -0
- package/docs/api/core-version.md +1 -1
- package/docs/api/equipment-generic-lens-catalogue.md +10 -5
- package/docs/api/equipment-sensor-profile-body.md +64 -0
- package/docs/api/equipment-sensor-profiles.md +86 -0
- package/docs/api/exports.json +460 -5
- package/docs/api/facade-display-view-gpu.md +5 -2
- package/docs/api/facade-display-view.md +11 -15
- package/docs/api/facade-exposure-build-up.md +105 -0
- package/docs/api/facade-fast-methods.md +47 -10
- package/docs/api/facade-image-plane-enable.md +16 -0
- package/docs/api/facade-mixed-illumination.md +67 -0
- package/docs/api/facade-quality-paths.md +24 -0
- package/docs/api/facade-representative-light-sources.md +131 -0
- package/docs/api/facade-scene-radiance.md +54 -3
- package/docs/api/facade-simulate-capture.md +48 -11
- package/docs/api/facade-simulate-display-view.md +10 -12
- package/docs/api/gpu-image-kernel-execution.md +0 -36
- package/docs/api/motion-subject-motion.md +23 -0
- package/docs/api/optics-generic-lens-lateral-color.md +79 -0
- package/docs/api/output-camera-channel-response.md +55 -0
- package/docs/api/output-developed-lens-corrections.md +10 -1
- package/docs/api/output-generic-lens-corrections.md +40 -4
- package/docs/api/output-print-plan.md +35 -1
- package/docs/api/output-sdr-rendering.md +6 -1
- package/docs/api/sensor-sensor-characteristics.md +54 -2
- package/llms.txt +3 -0
- package/package.json +6 -5
|
@@ -0,0 +1,381 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
// This product includes DNG technology under license by Adobe.
|
|
3
|
+
/**
|
|
4
|
+
* #598: the two DNG 1.6/1.7 rendering tags phones write that change the developed image: ProfileGainTableMap (52525, raw IFD) or
|
|
5
|
+
* ProfileGainTableMap2 (52544, IFD 0; it supersedes the first), a spatially varying gain (a local tone map), and RGBTables (52543,
|
|
6
|
+
* DNG 1.6), masked 3D colour look tables. Both act on the file's own developed values (owner, 2026-11-10), not on sensor signals.
|
|
7
|
+
*
|
|
8
|
+
* Written from the Adobe DNG Specification 1.6/1.7 descriptions of these tags. The 1.7.1.0 PDF could not be retrieved while this was
|
|
9
|
+
* written (HTTP 403); the byte layouts and the evaluation order were checked against the DNG SDK 1.7.1 source (dng_gain_map.cpp
|
|
10
|
+
* `GetStream`, dng_reference.cpp `RefBaselineProfileGainTableMap`, `RefRGBtoRGBTable3D`, `RefMaskedRGBTables32`, dng_render.cpp) and
|
|
11
|
+
* must be checked against the PDF. Both tags are read in the file's byte order (the SDK reads them from the file stream; only opcode
|
|
12
|
+
* lists are big-endian by definition).
|
|
13
|
+
*
|
|
14
|
+
* Where they go in a development (SDK `dng_render`): camera RGB → white balance → linear ProPhoto (RIMM, D50) RGB with 1 the
|
|
15
|
+
* clipping white → ProfileGainTableMap → BaselineExposure → look table → tone curve → RGBTables → output colour space.
|
|
16
|
+
*/
|
|
17
|
+
import { InvalidConfigurationError } from "../core/configuration-error.js";
|
|
18
|
+
function fail(message) { throw new InvalidConfigurationError("DNG profile maps: " + message); }
|
|
19
|
+
/** The tag's bytes (a Uint8Array), or a domain error. */
|
|
20
|
+
function requireBytes(bytes, name) {
|
|
21
|
+
if (!(bytes instanceof Uint8Array))
|
|
22
|
+
fail(name + " takes the tag's bytes as a Uint8Array.");
|
|
23
|
+
return bytes;
|
|
24
|
+
}
|
|
25
|
+
/** An interleaved RGB image record of its size, or a domain error. */
|
|
26
|
+
function requireRgbImage(image) {
|
|
27
|
+
const i = image;
|
|
28
|
+
if (i === null || typeof i !== "object" || !Number.isSafeInteger(i.width) || !Number.isSafeInteger(i.height) || i.width < 1 || i.height < 1 || !(i.data instanceof Float32Array) ||
|
|
29
|
+
i.data.length !== i.width * i.height * 3)
|
|
30
|
+
fail("the image must be interleaved RGB of its size.");
|
|
31
|
+
return i;
|
|
32
|
+
}
|
|
33
|
+
/** The input record of an apply function: an object with only the named fields. */
|
|
34
|
+
function requireApplyInput(input, name, keys) {
|
|
35
|
+
if (input === null || typeof input !== "object" || Array.isArray(input))
|
|
36
|
+
fail(name + " takes an input object.");
|
|
37
|
+
for (const key of Object.keys(input))
|
|
38
|
+
if (!keys.includes(key))
|
|
39
|
+
fail(name + " input has unknown field " + JSON.stringify(key) + ".");
|
|
40
|
+
}
|
|
41
|
+
class Reader {
|
|
42
|
+
b;
|
|
43
|
+
little;
|
|
44
|
+
p = 0;
|
|
45
|
+
v;
|
|
46
|
+
constructor(b, little) {
|
|
47
|
+
this.b = b;
|
|
48
|
+
this.little = little;
|
|
49
|
+
this.v = new DataView(b.buffer, b.byteOffset, b.byteLength);
|
|
50
|
+
}
|
|
51
|
+
need(n) { if (this.p + n > this.b.length)
|
|
52
|
+
fail("the tag's data is truncated."); }
|
|
53
|
+
u8() { this.need(1); return this.b[this.p++]; }
|
|
54
|
+
u16() { this.need(2); const x = this.v.getUint16(this.p, this.little); this.p += 2; return x; }
|
|
55
|
+
u32() { this.need(4); const x = this.v.getUint32(this.p, this.little); this.p += 4; return x; }
|
|
56
|
+
f32() { this.need(4); const x = this.v.getFloat32(this.p, this.little); this.p += 4; if (!Number.isFinite(x))
|
|
57
|
+
fail("non-finite value."); return x; }
|
|
58
|
+
f64() { this.need(8); const x = this.v.getFloat64(this.p, this.little); this.p += 8; if (!Number.isFinite(x))
|
|
59
|
+
fail("non-finite value."); return x; }
|
|
60
|
+
bytes(n) { this.need(n); const x = this.b.subarray(this.p, this.p + n); this.p += n; return x; }
|
|
61
|
+
}
|
|
62
|
+
/** IEEE 754 binary16 to a number. */
|
|
63
|
+
function half(h) {
|
|
64
|
+
const s = h & 0x8000 ? -1 : 1, e = (h >> 10) & 31, m = h & 1023;
|
|
65
|
+
return e === 0 ? s * m * 2 ** -24 : e === 31 ? (m ? NaN : s * Infinity) : s * (1 + m / 1024) * 2 ** (e - 15);
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Parses ProfileGainTableMap (version 1) or ProfileGainTableMap2 (version 2). Layout: MapPointsV, MapPointsH (LONG), MapSpacingV,
|
|
69
|
+
* MapSpacingH, MapOriginV, MapOriginH (DOUBLE), MapPointsN (LONG), MapInputWeights (5 FLOAT); version 2 adds DataType (LONG: 0 uint8,
|
|
70
|
+
* 1 uint16, 2 float16, 3 float32), Gamma, GainMin, GainMax (FLOAT); then the gains. Integer gains are GainMin + (x/max)·(GainMax −
|
|
71
|
+
* GainMin). A single map point on an axis has spacing 1 and origin 0 (SDK).
|
|
72
|
+
*/
|
|
73
|
+
export function parseDngProfileGainTableMap(bytes, littleEndian, version) {
|
|
74
|
+
const r = new Reader(requireBytes(bytes, "parseDngProfileGainTableMap"), littleEndian);
|
|
75
|
+
const pointsV = r.u32(), pointsH = r.u32();
|
|
76
|
+
let spacingV = r.f64(), spacingH = r.f64(), originV = r.f64(), originH = r.f64();
|
|
77
|
+
const tablePoints = r.u32(), inputWeights = [r.f32(), r.f32(), r.f32(), r.f32(), r.f32()];
|
|
78
|
+
let dataType = 3, gamma = 1, gainMin = 1, gainMax = 1;
|
|
79
|
+
if (version === 2) {
|
|
80
|
+
dataType = r.u32();
|
|
81
|
+
gamma = r.f32();
|
|
82
|
+
gainMin = r.f32();
|
|
83
|
+
gainMax = r.f32();
|
|
84
|
+
if (dataType > 3)
|
|
85
|
+
fail("unsupported ProfileGainTableMap2 DataType.");
|
|
86
|
+
if (!(gamma >= 0.1 && gamma <= 10))
|
|
87
|
+
fail("ProfileGainTableMap2 gamma is out of range.");
|
|
88
|
+
}
|
|
89
|
+
if (pointsV === 1) {
|
|
90
|
+
spacingV = 1;
|
|
91
|
+
originV = 0;
|
|
92
|
+
}
|
|
93
|
+
if (pointsH === 1) {
|
|
94
|
+
spacingH = 1;
|
|
95
|
+
originH = 0;
|
|
96
|
+
}
|
|
97
|
+
if (pointsV < 1 || pointsH < 1 || tablePoints < 1 || !(spacingV > 0 && spacingH > 0))
|
|
98
|
+
fail("invalid ProfileGainTableMap.");
|
|
99
|
+
const count = pointsV * pointsH * tablePoints, size = [1, 2, 2, 4][dataType];
|
|
100
|
+
if (count > 1 << 24 || count * size > bytes.length - r.p)
|
|
101
|
+
fail("the ProfileGainTableMap gains exceed the tag.");
|
|
102
|
+
const gains = new Float32Array(count);
|
|
103
|
+
for (let i = 0; i < count; i++) {
|
|
104
|
+
const x = dataType === 3 ? r.f32() : dataType === 2 ? half(r.u16()) : dataType === 1 ? gainMin + r.u16() / 65535 * (gainMax - gainMin) : gainMin + r.u8() / 255 * (gainMax - gainMin);
|
|
105
|
+
if (!(x >= 0 && x <= 1e4))
|
|
106
|
+
fail("a ProfileGainTableMap gain is out of range.");
|
|
107
|
+
gains[i] = x;
|
|
108
|
+
}
|
|
109
|
+
return { version, pointsV, pointsH, spacingV, spacingH, originV, originH, tablePoints, inputWeights, gamma, gains };
|
|
110
|
+
}
|
|
111
|
+
const GAMMAS = ["linear", "srgb", "1.8", "2.2", "rec2020"];
|
|
112
|
+
const PRIMARIES = ["srgb", "adobe-rgb", "display-p3", "rec2020", "prophoto"];
|
|
113
|
+
/**
|
|
114
|
+
* Parses RGBTables (52543): table count (LONG, at most 20; 0 means none), CompositeMethod (LONG: 0 weighted sum, 1 sequential), then
|
|
115
|
+
* per table LengthTableSemanticName (SHORT), the name's bytes, Divisions, PixelType (0 uint8, 1 uint16, 2 float32), GammaEncoding
|
|
116
|
+
* (0 linear, 1 sRGB, 2 γ 1.8, 3 γ 2.2, 4 Rec. 2020), ColorPrimaries (0 sRGB, 1 Adobe RGB, 2 P3, 3 Rec. 2020, 4 ProPhoto) and
|
|
117
|
+
* GamutExtension (0 clip, 1 extend), each a BYTE, then Divisions³ RGB samples (uint8 scaled by 256, float scaled by 65535).
|
|
118
|
+
*/
|
|
119
|
+
export function parseDngRgbTables(bytes, littleEndian) {
|
|
120
|
+
const r = new Reader(requireBytes(bytes, "parseDngRgbTables"), littleEndian), count = r.u32();
|
|
121
|
+
if (count === 0)
|
|
122
|
+
return null;
|
|
123
|
+
if (count > 20)
|
|
124
|
+
fail("RGBTables holds more than 20 tables.");
|
|
125
|
+
const method = r.u32();
|
|
126
|
+
if (method > 1)
|
|
127
|
+
fail("invalid RGBTables CompositeMethod.");
|
|
128
|
+
const tables = [];
|
|
129
|
+
for (let t = 0; t < count; t++) {
|
|
130
|
+
const nameLength = r.u16();
|
|
131
|
+
let semanticName = "";
|
|
132
|
+
for (const b of r.bytes(nameLength))
|
|
133
|
+
semanticName += String.fromCharCode(b);
|
|
134
|
+
const divisions = r.u8(), pixelType = r.u8(), gamma = r.u8(), primaries = r.u8(), gamut = r.u8();
|
|
135
|
+
if (divisions < 2 || divisions > 32 || pixelType > 2 || gamma > 4 || primaries > 4 || gamut > 1)
|
|
136
|
+
fail("invalid RGBTables table header.");
|
|
137
|
+
const n = divisions ** 3 * 3, samples = new Uint16Array(n);
|
|
138
|
+
for (let i = 0; i < n; i++)
|
|
139
|
+
samples[i] = pixelType === 0 ? r.u8() << 8 : pixelType === 1 ? r.u16() : Math.min(65535, Math.max(0, Math.round(r.f32() * 65535)));
|
|
140
|
+
tables.push({ semanticName: semanticName.replace(/\0+$/u, ""), divisions, gamma: GAMMAS[gamma], primaries: PRIMARIES[primaries], gamut: gamut ? "extend" : "clip", samples });
|
|
141
|
+
}
|
|
142
|
+
return { compositeMethod: method ? "sequential" : "weighted-sum", tables };
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Applies ProfileGainTableMap(2): at each pixel the weight t = clamp(w·(R, G, B, min, max)·2^BaselineExposure, 0, 1)^γ selects a
|
|
146
|
+
* gain by linear interpolation at t·N in the table (index clamped to N − 1, SDK), bilinear between map points at the pixel centre's
|
|
147
|
+
* relative position (held at the map's edges); R, G and B are multiplied by it.
|
|
148
|
+
*/
|
|
149
|
+
export function applyDngProfileGainTableMap(input) {
|
|
150
|
+
requireApplyInput(input, "applyDngProfileGainTableMap", ["image", "map", "baselineExposureStops", "region", "overrange"]);
|
|
151
|
+
const { map } = input, { width, height, data } = requireRgbImage(input.image);
|
|
152
|
+
if (map === null || typeof map !== "object" || !Array.isArray(map.inputWeights))
|
|
153
|
+
fail("map must be a parsed ProfileGainTableMap (parseDngProfileGainTableMap).");
|
|
154
|
+
const region = input.region ?? { x: 0, y: 0, stageWidth: width, stageHeight: height }, gainWeight = 2 ** (input.baselineExposureStops ?? 0);
|
|
155
|
+
if (!Number.isFinite(gainWeight))
|
|
156
|
+
fail("baselineExposureStops must be finite.");
|
|
157
|
+
const [w0, w1, w2, w3, w4] = map.inputWeights, n = map.tablePoints, last = n - 1;
|
|
158
|
+
const entry = (v, h, k) => map.gains[(v * map.pointsH + h) * n + k];
|
|
159
|
+
for (let row = 0; row < height; row++) {
|
|
160
|
+
const yMap = Math.min(Math.max(((region.y + row + 0.5) / region.stageHeight - map.originV) / map.spacingV, 0), map.pointsV - 1);
|
|
161
|
+
const y0 = Math.floor(yMap), y1 = Math.min(y0 + 1, map.pointsV - 1), yf = yMap - y0;
|
|
162
|
+
for (let col = 0; col < width; col++) {
|
|
163
|
+
const xMap = Math.min(Math.max(((region.x + col + 0.5) / region.stageWidth - map.originH) / map.spacingH, 0), map.pointsH - 1);
|
|
164
|
+
const x0 = Math.floor(xMap), x1 = Math.min(x0 + 1, map.pointsH - 1), xf = xMap - x0, i = (row * width + col) * 3;
|
|
165
|
+
const r = data[i], g = data[i + 1], b = data[i + 2];
|
|
166
|
+
let t = (w0 * r + w1 * g + w2 * b + w3 * Math.min(r, g, b) + w4 * Math.max(r, g, b)) * gainWeight;
|
|
167
|
+
t = Math.min(Math.max(t, 0), 1);
|
|
168
|
+
if (map.gamma !== 1)
|
|
169
|
+
t = t ** map.gamma;
|
|
170
|
+
const scaled = t * n, k0 = Math.min(Math.floor(scaled), last), k1 = Math.min(k0 + 1, last), kf = scaled - k0;
|
|
171
|
+
const lerp = (a, c, f) => a + (c - a) * f;
|
|
172
|
+
const at = (v, h) => lerp(entry(v, h, k0), entry(v, h, k1), kf);
|
|
173
|
+
const gain = lerp(lerp(at(y0, x0), at(y0, x1), xf), lerp(at(y1, x0), at(y1, x1), xf), yf);
|
|
174
|
+
for (let c = 0; c < 3; c++) {
|
|
175
|
+
const v = data[i + c] * gain;
|
|
176
|
+
data[i + c] = input.overrange ? v : Math.min(Math.max(v, 0), 1);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
/** Chromaticities (x, y) of R, G, B and the white point. */
|
|
182
|
+
const SPACES = {
|
|
183
|
+
srgb: [0.64, 0.33, 0.30, 0.60, 0.15, 0.06, 0.3127, 0.3290], "adobe-rgb": [0.64, 0.33, 0.21, 0.71, 0.15, 0.06, 0.3127, 0.3290],
|
|
184
|
+
"display-p3": [0.680, 0.320, 0.265, 0.690, 0.150, 0.060, 0.3127, 0.3290], rec2020: [0.708, 0.292, 0.170, 0.797, 0.131, 0.046, 0.3127, 0.3290],
|
|
185
|
+
prophoto: [0.7347, 0.2653, 0.1596, 0.8404, 0.0366, 0.0001, 0.3457, 0.3585]
|
|
186
|
+
};
|
|
187
|
+
const mul = (a, b) => [0, 1, 2].flatMap((i) => [0, 1, 2].map((j) => a[i * 3] * b[j] + a[i * 3 + 1] * b[3 + j] + a[i * 3 + 2] * b[6 + j]));
|
|
188
|
+
function inv(m) {
|
|
189
|
+
const [a, b, c, d, e, f, g, h, k] = m, det = a * (e * k - f * h) - b * (d * k - f * g) + c * (d * h - e * g);
|
|
190
|
+
return [e * k - f * h, c * h - b * k, b * f - c * e, f * g - d * k, a * k - c * g, c * d - a * f, d * h - e * g, b * g - a * h, a * e - b * d].map((x) => x / det);
|
|
191
|
+
}
|
|
192
|
+
/** RGB → XYZ (SMPTE RP 177 derivation), chromatically adapted to D50 with the Bradford transform (ICC.1 Annex E) when the white is not D50. */
|
|
193
|
+
function rgbToXyzD50(space) {
|
|
194
|
+
const s = SPACES[space], xyz = (x, y) => [x / y, 1, (1 - x - y) / y];
|
|
195
|
+
const cols = [0, 1, 2].map((k) => xyz(s[k * 2], s[k * 2 + 1])), white = xyz(s[6], s[7]);
|
|
196
|
+
const P = [0, 1, 2].flatMap((i) => cols.map((c) => c[i])), scale = mul(inv(P), [white[0], 0, 0, white[1], 0, 0, white[2], 0, 0]);
|
|
197
|
+
const m = [0, 1, 2].flatMap((i) => [0, 1, 2].map((j) => P[i * 3 + j] * scale[j * 3]));
|
|
198
|
+
if (space === "prophoto")
|
|
199
|
+
return m;
|
|
200
|
+
const B = [0.8951, 0.2664, -0.1614, -0.7502, 1.7135, 0.0367, 0.0389, -0.0685, 1.0296], d50 = xyz(0.3457, 0.3585);
|
|
201
|
+
const src = mul(B, [white[0], 0, 0, white[1], 0, 0, white[2], 0, 0]), dst = mul(B, [d50[0], 0, 0, d50[1], 0, 0, d50[2], 0, 0]);
|
|
202
|
+
const adapt = mul(inv(B), mul([dst[0] / src[0], 0, 0, 0, dst[3] / src[3], 0, 0, 0, dst[6] / src[6]], B));
|
|
203
|
+
return mul(adapt, m);
|
|
204
|
+
}
|
|
205
|
+
/** Encode (true) or decode a table's gamma: sRGB (IEC 61966-2-1), pure powers 1.8 and 2.2, and the Rec. 2020 OETF (ITU-R BT.2020). */
|
|
206
|
+
function gammaCurve(kind, x, encode) {
|
|
207
|
+
switch (kind) {
|
|
208
|
+
case "linear": return x;
|
|
209
|
+
case "1.8": return encode ? x ** (1 / 1.8) : x ** 1.8;
|
|
210
|
+
case "2.2": return encode ? x ** (1 / 2.2) : x ** 2.2;
|
|
211
|
+
case "srgb": return encode ? (x <= 0.0031308 ? 12.92 * x : 1.055 * x ** (1 / 2.4) - 0.055) : (x <= 0.04045 ? x / 12.92 : ((x + 0.055) / 1.055) ** 2.4);
|
|
212
|
+
case "rec2020": return encode ? (x < 0.018053968510807 ? 4.5 * x : 1.09929682680944 * x ** 0.45 - 0.09929682680944) : (x < 0.081242858298635 ? x / 4.5 : ((x + 0.09929682680944) / 1.09929682680944) ** (1 / 0.45));
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* Applies RGBTables: each table maps ProPhoto RGB into its own primaries (clipped to 0..1, the clipped-off part kept and added back
|
|
217
|
+
* when GamutExtension is "extend"), encodes it with the table's gamma, interpolates tetrahedrally in the 3D table, decodes and maps
|
|
218
|
+
* back (SDK `RefRGBtoRGBTable3D`). The background table (empty name) applies to the whole image. Weighted sum: each masked table's
|
|
219
|
+
* result weighted by its mask, the background (the background table's result, or the input) by 1 − min(1, Σ masks), normalized.
|
|
220
|
+
* Sequential: each table in file order, blended into the running image by its mask (the background table by 1 − min(1, Σ other masks)).
|
|
221
|
+
* A table whose mask is not supplied is skipped (as the SDK skips a name with no SemanticMask); the returned notes say so.
|
|
222
|
+
*/
|
|
223
|
+
export function applyDngRgbTables(input) {
|
|
224
|
+
requireApplyInput(input, "applyDngRgbTables", ["image", "tables", "masks"]);
|
|
225
|
+
const { tables } = input, { width, height, data } = requireRgbImage(input.image), notes = [];
|
|
226
|
+
if (tables === null || typeof tables !== "object" || !Array.isArray(tables.tables))
|
|
227
|
+
fail("tables must be parsed RGBTables (parseDngRgbTables).");
|
|
228
|
+
const pixels = width * height, maskOf = (name) => {
|
|
229
|
+
const m = input.masks?.find((x) => x.name === name);
|
|
230
|
+
if (!m)
|
|
231
|
+
return null;
|
|
232
|
+
if (m.data.length !== m.width * m.height)
|
|
233
|
+
fail("semantic mask " + JSON.stringify(name) + " does not match its size.");
|
|
234
|
+
const out = new Float32Array(pixels);
|
|
235
|
+
for (let y = 0; y < height; y++) {
|
|
236
|
+
const fy = Math.min(Math.max((y + 0.5) * m.height / height - 0.5, 0), m.height - 1), y0 = Math.floor(fy), y1 = Math.min(y0 + 1, m.height - 1), wy = fy - y0;
|
|
237
|
+
for (let x = 0; x < width; x++) {
|
|
238
|
+
const fx = Math.min(Math.max((x + 0.5) * m.width / width - 0.5, 0), m.width - 1), x0 = Math.floor(fx), x1 = Math.min(x0 + 1, m.width - 1), wx = fx - x0;
|
|
239
|
+
const a = m.data[y0 * m.width + x0], b = m.data[y0 * m.width + x1], c = m.data[y1 * m.width + x0], d = m.data[y1 * m.width + x1];
|
|
240
|
+
out[y * width + x] = Math.min(Math.max((a + (b - a) * wx) * (1 - wy) + (c + (d - c) * wx) * wy, 0), 1);
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
return out;
|
|
244
|
+
};
|
|
245
|
+
const background = tables.tables.find((t) => t.semanticName === "");
|
|
246
|
+
const masked = [];
|
|
247
|
+
for (const table of tables.tables) {
|
|
248
|
+
if (table === background)
|
|
249
|
+
continue;
|
|
250
|
+
const mask = maskOf(table.semanticName);
|
|
251
|
+
if (mask)
|
|
252
|
+
masked.push({ table, mask });
|
|
253
|
+
else
|
|
254
|
+
notes.push("RGBTables table " + JSON.stringify(table.semanticName) + " not applied: no semantic mask of that name.");
|
|
255
|
+
}
|
|
256
|
+
const transform = (table, rgb) => applyTable(table, rgb);
|
|
257
|
+
if (masked.length === 0) {
|
|
258
|
+
if (background)
|
|
259
|
+
transform(background, data);
|
|
260
|
+
return notes;
|
|
261
|
+
}
|
|
262
|
+
const sum = new Float32Array(pixels);
|
|
263
|
+
for (const { mask } of masked)
|
|
264
|
+
for (let i = 0; i < pixels; i++)
|
|
265
|
+
sum[i] = sum[i] + mask[i];
|
|
266
|
+
if (tables.compositeMethod === "sequential") {
|
|
267
|
+
for (const table of tables.tables) {
|
|
268
|
+
const mask = table === background ? Float32Array.from(sum, (s) => 1 - Math.min(1, s)) : masked.find((m) => m.table === table)?.mask;
|
|
269
|
+
if (!mask)
|
|
270
|
+
continue;
|
|
271
|
+
const result = data.slice();
|
|
272
|
+
transform(table, result);
|
|
273
|
+
for (let i = 0; i < pixels; i++)
|
|
274
|
+
for (let c = 0; c < 3; c++)
|
|
275
|
+
data[i * 3 + c] = data[i * 3 + c] + (result[i * 3 + c] - data[i * 3 + c]) * mask[i];
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
else {
|
|
279
|
+
const results = masked.map(({ table }) => { const r = data.slice(); transform(table, r); return r; });
|
|
280
|
+
if (background)
|
|
281
|
+
transform(background, data);
|
|
282
|
+
for (let i = 0; i < pixels; i++) {
|
|
283
|
+
const bg = 1 - Math.min(1, sum[i]), norm = 1 / (sum[i] + bg);
|
|
284
|
+
for (let c = 0; c < 3; c++) {
|
|
285
|
+
let v = data[i * 3 + c] * bg;
|
|
286
|
+
masked.forEach((m, k) => { v += results[k][i * 3 + c] * m.mask[i]; });
|
|
287
|
+
data[i * 3 + c] = v * norm;
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
return notes;
|
|
292
|
+
}
|
|
293
|
+
function applyTable(table, rgb) {
|
|
294
|
+
const matrix = table.primaries !== "prophoto", encode = matrix ? mul(inv(rgbToXyzD50(table.primaries)), rgbToXyzD50("prophoto")) : null, decode = encode ? inv(encode) : null;
|
|
295
|
+
const extend = matrix && table.gamut === "extend", divs = table.divisions, s = table.samples, scale = divs - 1, maxIndex = divs - 2;
|
|
296
|
+
const o001 = 3, o010 = 3 * divs, o100 = 3 * divs * divs, o011 = o010 + o001, o101 = o100 + o001, o110 = o100 + o010, o111 = o110 + o001;
|
|
297
|
+
const pin = (x) => x < 0 ? 0 : x > 1 ? 1 : x;
|
|
298
|
+
for (let i = 0; i < rgb.length; i += 3) {
|
|
299
|
+
let r = rgb[i], g = rgb[i + 1], b = rgb[i + 2], dr = 0, dg = 0, db = 0;
|
|
300
|
+
if (encode) {
|
|
301
|
+
const rr = encode[0] * r + encode[1] * g + encode[2] * b, gg = encode[3] * r + encode[4] * g + encode[5] * b, bb = encode[6] * r + encode[7] * g + encode[8] * b;
|
|
302
|
+
r = pin(rr);
|
|
303
|
+
g = pin(gg);
|
|
304
|
+
b = pin(bb);
|
|
305
|
+
if (extend) {
|
|
306
|
+
dr = rr - r;
|
|
307
|
+
dg = gg - g;
|
|
308
|
+
db = bb - b;
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
else {
|
|
312
|
+
r = pin(r);
|
|
313
|
+
g = pin(g);
|
|
314
|
+
b = pin(b);
|
|
315
|
+
}
|
|
316
|
+
r = gammaCurve(table.gamma, r, true);
|
|
317
|
+
g = gammaCurve(table.gamma, g, true);
|
|
318
|
+
b = gammaCurve(table.gamma, b, true);
|
|
319
|
+
const rs = r * scale, gs = g * scale, bs = b * scale;
|
|
320
|
+
const ri = Math.min(Math.floor(rs), maxIndex), gi = Math.min(Math.floor(gs), maxIndex), bi = Math.min(Math.floor(bs), maxIndex);
|
|
321
|
+
const rf = rs - ri, gf = gs - gi, bf = bs - bi;
|
|
322
|
+
let o1, o2, f1, f2, f3;
|
|
323
|
+
if (gf >= rf) {
|
|
324
|
+
if (bf >= gf) {
|
|
325
|
+
o1 = o001;
|
|
326
|
+
o2 = o011;
|
|
327
|
+
f1 = bf;
|
|
328
|
+
f2 = gf;
|
|
329
|
+
f3 = rf;
|
|
330
|
+
}
|
|
331
|
+
else if (bf >= rf) {
|
|
332
|
+
o1 = o010;
|
|
333
|
+
o2 = o011;
|
|
334
|
+
f1 = gf;
|
|
335
|
+
f2 = bf;
|
|
336
|
+
f3 = rf;
|
|
337
|
+
}
|
|
338
|
+
else {
|
|
339
|
+
o1 = o010;
|
|
340
|
+
o2 = o110;
|
|
341
|
+
f1 = gf;
|
|
342
|
+
f2 = rf;
|
|
343
|
+
f3 = bf;
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
else if (bf >= rf) {
|
|
347
|
+
o1 = o001;
|
|
348
|
+
o2 = o101;
|
|
349
|
+
f1 = bf;
|
|
350
|
+
f2 = rf;
|
|
351
|
+
f3 = gf;
|
|
352
|
+
}
|
|
353
|
+
else if (bf >= gf) {
|
|
354
|
+
o1 = o100;
|
|
355
|
+
o2 = o101;
|
|
356
|
+
f1 = rf;
|
|
357
|
+
f2 = bf;
|
|
358
|
+
f3 = gf;
|
|
359
|
+
}
|
|
360
|
+
else {
|
|
361
|
+
o1 = o100;
|
|
362
|
+
o2 = o110;
|
|
363
|
+
f1 = rf;
|
|
364
|
+
f2 = gf;
|
|
365
|
+
f3 = bf;
|
|
366
|
+
}
|
|
367
|
+
const w0 = 1 - f1, w1 = f1 - f2, w2 = f2 - f3, base = ri * o100 + gi * o010 + bi * o001;
|
|
368
|
+
const out = [0, 1, 2].map((c) => gammaCurve(table.gamma, (w0 * s[base + c] + w1 * s[base + o1 + c] + w2 * s[base + o2 + c] + f3 * s[base + o111 + c]) / 65535, false));
|
|
369
|
+
let [nr, ng, nb] = out;
|
|
370
|
+
if (decode) {
|
|
371
|
+
nr += dr;
|
|
372
|
+
ng += dg;
|
|
373
|
+
nb += db;
|
|
374
|
+
[nr, ng, nb] = [decode[0] * nr + decode[1] * ng + decode[2] * nb, decode[3] * nr + decode[4] * ng + decode[5] * nb, decode[6] * nr + decode[7] * ng + decode[8] * nb];
|
|
375
|
+
}
|
|
376
|
+
rgb[i] = pin(nr);
|
|
377
|
+
rgb[i + 1] = pin(ng);
|
|
378
|
+
rgb[i + 2] = pin(nb);
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
//# sourceMappingURL=dng-profile-maps.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dng-profile-maps.js","sourceRoot":"","sources":["../../src/capture/dng-profile-maps.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 * #598: the two DNG 1.6/1.7 rendering tags phones write that change the developed image: ProfileGainTableMap (52525, raw IFD) or\n * ProfileGainTableMap2 (52544, IFD 0; it supersedes the first), a spatially varying gain (a local tone map), and RGBTables (52543,\n * DNG 1.6), masked 3D colour look tables. Both act on the file's own developed values (owner, 2026-11-10), not on sensor signals.\n *\n * Written from the Adobe DNG Specification 1.6/1.7 descriptions of these tags. The 1.7.1.0 PDF could not be retrieved while this was\n * written (HTTP 403); the byte layouts and the evaluation order were checked against the DNG SDK 1.7.1 source (dng_gain_map.cpp\n * `GetStream`, dng_reference.cpp `RefBaselineProfileGainTableMap`, `RefRGBtoRGBTable3D`, `RefMaskedRGBTables32`, dng_render.cpp) and\n * must be checked against the PDF. Both tags are read in the file's byte order (the SDK reads them from the file stream; only opcode\n * lists are big-endian by definition).\n *\n * Where they go in a development (SDK `dng_render`): camera RGB → white balance → linear ProPhoto (RIMM, D50) RGB with 1 the\n * clipping white → ProfileGainTableMap → BaselineExposure → look table → tone curve → RGBTables → output colour space.\n */\n\nimport { InvalidConfigurationError } from \"../core/configuration-error.js\";\n\n/** A parsed ProfileGainTableMap(2): N gains at each of V × H map points, decoded to 32-bit floats. */\nexport interface DngProfileGainTableMap {\n /** 1 for ProfileGainTableMap (52525), 2 for ProfileGainTableMap2 (52544). */\n version: 1 | 2;\n pointsV: number; pointsH: number; spacingV: number; spacingH: number; originV: number; originH: number;\n /** MapPointsN: the table length at each map point. */\n tablePoints: number;\n /** MapInputWeights for red, green, blue, min(R,G,B) and max(R,G,B). */\n inputWeights: [number, number, number, number, number];\n /** PGTM2: the weight's gamma (1 for version 1). */\n gamma: number;\n /** Gains, row-major (v, h, table point). */\n gains: Float32Array;\n}\n/** One table of RGBTables: a 3D table of `divisions`³ RGB samples (16-bit, 65535 = 1). */\nexport interface DngRgbTable {\n /** TableSemanticName: the semantic mask it applies within; \"\" for the background table (the whole image). */\n semanticName: string;\n divisions: number;\n gamma: \"linear\" | \"srgb\" | \"1.8\" | \"2.2\" | \"rec2020\";\n primaries: \"srgb\" | \"adobe-rgb\" | \"display-p3\" | \"rec2020\" | \"prophoto\";\n gamut: \"clip\" | \"extend\";\n /** RGB per node, red slowest then green then blue, length divisions³ × 3. */\n samples: Uint16Array;\n}\nexport interface DngRgbTables { compositeMethod: \"weighted-sum\" | \"sequential\"; tables: DngRgbTable[] }\n/** An RGB image, interleaved (row, column, channel). */\nexport interface DngRgbImage { width: number; height: number; data: Float32Array }\n\nfunction fail(message: string): never { throw new InvalidConfigurationError(\"DNG profile maps: \" + message); }\n/** The tag's bytes (a Uint8Array), or a domain error. */\nfunction requireBytes(bytes: unknown, name: string): Uint8Array {\n if (!(bytes instanceof Uint8Array)) fail(name + \" takes the tag's bytes as a Uint8Array.\");\n return bytes;\n}\n/** An interleaved RGB image record of its size, or a domain error. */\nfunction requireRgbImage(image: unknown): DngRgbImage {\n const i = image as Partial<DngRgbImage> | null;\n if (i === null || typeof i !== \"object\" || !Number.isSafeInteger(i.width) || !Number.isSafeInteger(i.height) || i.width! < 1 || i.height! < 1 || !(i.data instanceof Float32Array) ||\n i.data.length !== i.width! * i.height! * 3) fail(\"the image must be interleaved RGB of its size.\");\n return i as DngRgbImage;\n}\n/** The input record of an apply function: an object with only the named fields. */\nfunction requireApplyInput(input: unknown, name: string, keys: readonly string[]): void {\n if (input === null || typeof input !== \"object\" || Array.isArray(input)) fail(name + \" takes an input object.\");\n for (const key of Object.keys(input)) if (!keys.includes(key)) fail(name + \" input has unknown field \" + JSON.stringify(key) + \".\");\n}\nclass Reader {\n p = 0; private v: DataView;\n constructor(private b: Uint8Array, private little: boolean) { this.v = new DataView(b.buffer, b.byteOffset, b.byteLength); }\n need(n: number): void { if (this.p + n > this.b.length) fail(\"the tag's data is truncated.\"); }\n u8(): number { this.need(1); return this.b[this.p++]!; }\n u16(): number { this.need(2); const x = this.v.getUint16(this.p, this.little); this.p += 2; return x; }\n u32(): number { this.need(4); const x = this.v.getUint32(this.p, this.little); this.p += 4; return x; }\n f32(): number { this.need(4); const x = this.v.getFloat32(this.p, this.little); this.p += 4; if (!Number.isFinite(x)) fail(\"non-finite value.\"); return x; }\n f64(): number { this.need(8); const x = this.v.getFloat64(this.p, this.little); this.p += 8; if (!Number.isFinite(x)) fail(\"non-finite value.\"); return x; }\n bytes(n: number): Uint8Array { this.need(n); const x = this.b.subarray(this.p, this.p + n); this.p += n; return x; }\n}\n\n/** IEEE 754 binary16 to a number. */\nfunction half(h: number): number {\n const s = h & 0x8000 ? -1 : 1, e = (h >> 10) & 31, m = h & 1023;\n return e === 0 ? s * m * 2 ** -24 : e === 31 ? (m ? NaN : s * Infinity) : s * (1 + m / 1024) * 2 ** (e - 15);\n}\n\n/**\n * Parses ProfileGainTableMap (version 1) or ProfileGainTableMap2 (version 2). Layout: MapPointsV, MapPointsH (LONG), MapSpacingV,\n * MapSpacingH, MapOriginV, MapOriginH (DOUBLE), MapPointsN (LONG), MapInputWeights (5 FLOAT); version 2 adds DataType (LONG: 0 uint8,\n * 1 uint16, 2 float16, 3 float32), Gamma, GainMin, GainMax (FLOAT); then the gains. Integer gains are GainMin + (x/max)·(GainMax −\n * GainMin). A single map point on an axis has spacing 1 and origin 0 (SDK).\n */\nexport function parseDngProfileGainTableMap(bytes: Uint8Array, littleEndian: boolean, version: 1 | 2): DngProfileGainTableMap {\n const r = new Reader(requireBytes(bytes, \"parseDngProfileGainTableMap\"), littleEndian);\n const pointsV = r.u32(), pointsH = r.u32();\n let spacingV = r.f64(), spacingH = r.f64(), originV = r.f64(), originH = r.f64();\n const tablePoints = r.u32(), inputWeights = [r.f32(), r.f32(), r.f32(), r.f32(), r.f32()] as [number, number, number, number, number];\n let dataType = 3, gamma = 1, gainMin = 1, gainMax = 1;\n if (version === 2) {\n dataType = r.u32(); gamma = r.f32(); gainMin = r.f32(); gainMax = r.f32();\n if (dataType > 3) fail(\"unsupported ProfileGainTableMap2 DataType.\");\n if (!(gamma >= 0.1 && gamma <= 10)) fail(\"ProfileGainTableMap2 gamma is out of range.\");\n }\n if (pointsV === 1) { spacingV = 1; originV = 0; }\n if (pointsH === 1) { spacingH = 1; originH = 0; }\n if (pointsV < 1 || pointsH < 1 || tablePoints < 1 || !(spacingV > 0 && spacingH > 0)) fail(\"invalid ProfileGainTableMap.\");\n const count = pointsV * pointsH * tablePoints, size = [1, 2, 2, 4][dataType]!;\n if (count > 1 << 24 || count * size > bytes.length - r.p) fail(\"the ProfileGainTableMap gains exceed the tag.\");\n const gains = new Float32Array(count);\n for (let i = 0; i < count; i++) {\n const x = dataType === 3 ? r.f32() : dataType === 2 ? half(r.u16()) : dataType === 1 ? gainMin + r.u16() / 65535 * (gainMax - gainMin) : gainMin + r.u8() / 255 * (gainMax - gainMin);\n if (!(x >= 0 && x <= 1e4)) fail(\"a ProfileGainTableMap gain is out of range.\");\n gains[i] = x;\n }\n return { version, pointsV, pointsH, spacingV, spacingH, originV, originH, tablePoints, inputWeights, gamma, gains };\n}\n\nconst GAMMAS = [\"linear\", \"srgb\", \"1.8\", \"2.2\", \"rec2020\"] as const;\nconst PRIMARIES = [\"srgb\", \"adobe-rgb\", \"display-p3\", \"rec2020\", \"prophoto\"] as const;\n/**\n * Parses RGBTables (52543): table count (LONG, at most 20; 0 means none), CompositeMethod (LONG: 0 weighted sum, 1 sequential), then\n * per table LengthTableSemanticName (SHORT), the name's bytes, Divisions, PixelType (0 uint8, 1 uint16, 2 float32), GammaEncoding\n * (0 linear, 1 sRGB, 2 γ 1.8, 3 γ 2.2, 4 Rec. 2020), ColorPrimaries (0 sRGB, 1 Adobe RGB, 2 P3, 3 Rec. 2020, 4 ProPhoto) and\n * GamutExtension (0 clip, 1 extend), each a BYTE, then Divisions³ RGB samples (uint8 scaled by 256, float scaled by 65535).\n */\nexport function parseDngRgbTables(bytes: Uint8Array, littleEndian: boolean): DngRgbTables | null {\n const r = new Reader(requireBytes(bytes, \"parseDngRgbTables\"), littleEndian), count = r.u32();\n if (count === 0) return null;\n if (count > 20) fail(\"RGBTables holds more than 20 tables.\");\n const method = r.u32();\n if (method > 1) fail(\"invalid RGBTables CompositeMethod.\");\n const tables: DngRgbTable[] = [];\n for (let t = 0; t < count; t++) {\n const nameLength = r.u16();\n let semanticName = \"\"; for (const b of r.bytes(nameLength)) semanticName += String.fromCharCode(b);\n const divisions = r.u8(), pixelType = r.u8(), gamma = r.u8(), primaries = r.u8(), gamut = r.u8();\n if (divisions < 2 || divisions > 32 || pixelType > 2 || gamma > 4 || primaries > 4 || gamut > 1) fail(\"invalid RGBTables table header.\");\n const n = divisions ** 3 * 3, samples = new Uint16Array(n);\n for (let i = 0; i < n; i++) samples[i] = pixelType === 0 ? r.u8() << 8 : pixelType === 1 ? r.u16() : Math.min(65535, Math.max(0, Math.round(r.f32() * 65535)));\n tables.push({ semanticName: semanticName.replace(/\\0+$/u, \"\"), divisions, gamma: GAMMAS[gamma]!, primaries: PRIMARIES[primaries]!, gamut: gamut ? \"extend\" : \"clip\", samples });\n }\n return { compositeMethod: method ? \"sequential\" : \"weighted-sum\", tables };\n}\n\n/** Options of {@link applyDngProfileGainTableMap}. */\nexport interface ApplyDngProfileGainTableMapInput {\n /** Linear ProPhoto (RIMM, D50) RGB, white-balanced, 1 = clipping white; changed in place. */\n image: DngRgbImage;\n map: DngProfileGainTableMap;\n /** BaselineExposure (stops) not yet applied to `image`: the weight is scaled by 2^stops, as the SDK does. Default 0. */\n baselineExposureStops?: number;\n /** Where `image` sits in the stage-3 (ActiveArea) image the map spans. Default: `image` is the whole stage-3 image. */\n region?: { x: number; y: number; stageWidth: number; stageHeight: number };\n /** Keep values above 1 (true) or clip to 0..1 (false, the SDR default). */\n overrange?: boolean;\n}\n\n/**\n * Applies ProfileGainTableMap(2): at each pixel the weight t = clamp(w·(R, G, B, min, max)·2^BaselineExposure, 0, 1)^γ selects a\n * gain by linear interpolation at t·N in the table (index clamped to N − 1, SDK), bilinear between map points at the pixel centre's\n * relative position (held at the map's edges); R, G and B are multiplied by it.\n */\nexport function applyDngProfileGainTableMap(input: ApplyDngProfileGainTableMapInput): void {\n requireApplyInput(input, \"applyDngProfileGainTableMap\", [\"image\", \"map\", \"baselineExposureStops\", \"region\", \"overrange\"]);\n const { map } = input, { width, height, data } = requireRgbImage(input.image);\n if (map === null || typeof map !== \"object\" || !Array.isArray(map.inputWeights)) fail(\"map must be a parsed ProfileGainTableMap (parseDngProfileGainTableMap).\");\n const region = input.region ?? { x: 0, y: 0, stageWidth: width, stageHeight: height }, gainWeight = 2 ** (input.baselineExposureStops ?? 0);\n if (!Number.isFinite(gainWeight)) fail(\"baselineExposureStops must be finite.\");\n const [w0, w1, w2, w3, w4] = map.inputWeights, n = map.tablePoints, last = n - 1;\n const entry = (v: number, h: number, k: number): number => map.gains[(v * map.pointsH + h) * n + k]!;\n for (let row = 0; row < height; row++) {\n const yMap = Math.min(Math.max(((region.y + row + 0.5) / region.stageHeight - map.originV) / map.spacingV, 0), map.pointsV - 1);\n const y0 = Math.floor(yMap), y1 = Math.min(y0 + 1, map.pointsV - 1), yf = yMap - y0;\n for (let col = 0; col < width; col++) {\n const xMap = Math.min(Math.max(((region.x + col + 0.5) / region.stageWidth - map.originH) / map.spacingH, 0), map.pointsH - 1);\n const x0 = Math.floor(xMap), x1 = Math.min(x0 + 1, map.pointsH - 1), xf = xMap - x0, i = (row * width + col) * 3;\n const r = data[i]!, g = data[i + 1]!, b = data[i + 2]!;\n let t = (w0 * r + w1 * g + w2 * b + w3 * Math.min(r, g, b) + w4 * Math.max(r, g, b)) * gainWeight;\n t = Math.min(Math.max(t, 0), 1);\n if (map.gamma !== 1) t = t ** map.gamma;\n const scaled = t * n, k0 = Math.min(Math.floor(scaled), last), k1 = Math.min(k0 + 1, last), kf = scaled - k0;\n const lerp = (a: number, c: number, f: number): number => a + (c - a) * f;\n const at = (v: number, h: number): number => lerp(entry(v, h, k0), entry(v, h, k1), kf);\n const gain = lerp(lerp(at(y0, x0), at(y0, x1), xf), lerp(at(y1, x0), at(y1, x1), xf), yf);\n for (let c = 0; c < 3; c++) { const v = data[i + c]! * gain; data[i + c] = input.overrange ? v : Math.min(Math.max(v, 0), 1); }\n }\n }\n}\n\n/** Chromaticities (x, y) of R, G, B and the white point. */\nconst SPACES: Record<DngRgbTable[\"primaries\"], number[]> = {\n srgb: [0.64, 0.33, 0.30, 0.60, 0.15, 0.06, 0.3127, 0.3290], \"adobe-rgb\": [0.64, 0.33, 0.21, 0.71, 0.15, 0.06, 0.3127, 0.3290],\n \"display-p3\": [0.680, 0.320, 0.265, 0.690, 0.150, 0.060, 0.3127, 0.3290], rec2020: [0.708, 0.292, 0.170, 0.797, 0.131, 0.046, 0.3127, 0.3290],\n prophoto: [0.7347, 0.2653, 0.1596, 0.8404, 0.0366, 0.0001, 0.3457, 0.3585]\n};\ntype M3 = number[];\nconst mul = (a: M3, b: M3): M3 => [0, 1, 2].flatMap((i) => [0, 1, 2].map((j) => a[i * 3]! * b[j]! + a[i * 3 + 1]! * b[3 + j]! + a[i * 3 + 2]! * b[6 + j]!));\nfunction inv(m: M3): M3 {\n const [a, b, c, d, e, f, g, h, k] = m as [number, number, number, number, number, number, number, number, number], det = a * (e * k - f * h) - b * (d * k - f * g) + c * (d * h - e * g);\n return [e * k - f * h, c * h - b * k, b * f - c * e, f * g - d * k, a * k - c * g, c * d - a * f, d * h - e * g, b * g - a * h, a * e - b * d].map((x) => x / det);\n}\n/** RGB → XYZ (SMPTE RP 177 derivation), chromatically adapted to D50 with the Bradford transform (ICC.1 Annex E) when the white is not D50. */\nfunction rgbToXyzD50(space: DngRgbTable[\"primaries\"]): M3 {\n const s = SPACES[space]!, xyz = (x: number, y: number): number[] => [x / y, 1, (1 - x - y) / y];\n const cols = [0, 1, 2].map((k) => xyz(s[k * 2]!, s[k * 2 + 1]!)), white = xyz(s[6]!, s[7]!);\n const P = [0, 1, 2].flatMap((i) => cols.map((c) => c[i]!)), scale = mul(inv(P), [white[0]!, 0, 0, white[1]!, 0, 0, white[2]!, 0, 0]);\n const m = [0, 1, 2].flatMap((i) => [0, 1, 2].map((j) => P[i * 3 + j]! * scale[j * 3]!));\n if (space === \"prophoto\") return m;\n const B = [0.8951, 0.2664, -0.1614, -0.7502, 1.7135, 0.0367, 0.0389, -0.0685, 1.0296], d50 = xyz(0.3457, 0.3585);\n const src = mul(B, [white[0]!, 0, 0, white[1]!, 0, 0, white[2]!, 0, 0]), dst = mul(B, [d50[0]!, 0, 0, d50[1]!, 0, 0, d50[2]!, 0, 0]);\n const adapt = mul(inv(B), mul([dst[0]! / src[0]!, 0, 0, 0, dst[3]! / src[3]!, 0, 0, 0, dst[6]! / src[6]!], B));\n return mul(adapt, m);\n}\n/** Encode (true) or decode a table's gamma: sRGB (IEC 61966-2-1), pure powers 1.8 and 2.2, and the Rec. 2020 OETF (ITU-R BT.2020). */\nfunction gammaCurve(kind: DngRgbTable[\"gamma\"], x: number, encode: boolean): number {\n switch (kind) {\n case \"linear\": return x;\n case \"1.8\": return encode ? x ** (1 / 1.8) : x ** 1.8;\n case \"2.2\": return encode ? x ** (1 / 2.2) : x ** 2.2;\n case \"srgb\": return encode ? (x <= 0.0031308 ? 12.92 * x : 1.055 * x ** (1 / 2.4) - 0.055) : (x <= 0.04045 ? x / 12.92 : ((x + 0.055) / 1.055) ** 2.4);\n case \"rec2020\": return encode ? (x < 0.018053968510807 ? 4.5 * x : 1.09929682680944 * x ** 0.45 - 0.09929682680944) : (x < 0.081242858298635 ? x / 4.5 : ((x + 0.09929682680944) / 1.09929682680944) ** (1 / 0.45));\n }\n}\n\n/** Options of {@link applyDngRgbTables}. */\nexport interface ApplyDngRgbTablesInput {\n /** ProPhoto-primaries RGB after the tone curve, 0..1; changed in place. */\n image: DngRgbImage;\n tables: DngRgbTables;\n /** Semantic masks by name (values 0..1, any size; stretched over the image with bilinear interpolation). */\n masks?: readonly { name: string; width: number; height: number; data: Float32Array }[];\n}\n\n/**\n * Applies RGBTables: each table maps ProPhoto RGB into its own primaries (clipped to 0..1, the clipped-off part kept and added back\n * when GamutExtension is \"extend\"), encodes it with the table's gamma, interpolates tetrahedrally in the 3D table, decodes and maps\n * back (SDK `RefRGBtoRGBTable3D`). The background table (empty name) applies to the whole image. Weighted sum: each masked table's\n * result weighted by its mask, the background (the background table's result, or the input) by 1 − min(1, Σ masks), normalized.\n * Sequential: each table in file order, blended into the running image by its mask (the background table by 1 − min(1, Σ other masks)).\n * A table whose mask is not supplied is skipped (as the SDK skips a name with no SemanticMask); the returned notes say so.\n */\nexport function applyDngRgbTables(input: ApplyDngRgbTablesInput): string[] {\n requireApplyInput(input, \"applyDngRgbTables\", [\"image\", \"tables\", \"masks\"]);\n const { tables } = input, { width, height, data } = requireRgbImage(input.image), notes: string[] = [];\n if (tables === null || typeof tables !== \"object\" || !Array.isArray(tables.tables)) fail(\"tables must be parsed RGBTables (parseDngRgbTables).\");\n const pixels = width * height, maskOf = (name: string): Float32Array | null => {\n const m = input.masks?.find((x) => x.name === name);\n if (!m) return null;\n if (m.data.length !== m.width * m.height) fail(\"semantic mask \" + JSON.stringify(name) + \" does not match its size.\");\n const out = new Float32Array(pixels);\n for (let y = 0; y < height; y++) {\n const fy = Math.min(Math.max((y + 0.5) * m.height / height - 0.5, 0), m.height - 1), y0 = Math.floor(fy), y1 = Math.min(y0 + 1, m.height - 1), wy = fy - y0;\n for (let x = 0; x < width; x++) {\n const fx = Math.min(Math.max((x + 0.5) * m.width / width - 0.5, 0), m.width - 1), x0 = Math.floor(fx), x1 = Math.min(x0 + 1, m.width - 1), wx = fx - x0;\n const a = m.data[y0 * m.width + x0]!, b = m.data[y0 * m.width + x1]!, c = m.data[y1 * m.width + x0]!, d = m.data[y1 * m.width + x1]!;\n out[y * width + x] = Math.min(Math.max((a + (b - a) * wx) * (1 - wy) + (c + (d - c) * wx) * wy, 0), 1);\n }\n }\n return out;\n };\n const background = tables.tables.find((t) => t.semanticName === \"\");\n const masked: { table: DngRgbTable; mask: Float32Array }[] = [];\n for (const table of tables.tables) {\n if (table === background) continue;\n const mask = maskOf(table.semanticName);\n if (mask) masked.push({ table, mask }); else notes.push(\"RGBTables table \" + JSON.stringify(table.semanticName) + \" not applied: no semantic mask of that name.\");\n }\n const transform = (table: DngRgbTable, rgb: Float32Array): void => applyTable(table, rgb);\n if (masked.length === 0) { if (background) transform(background, data); return notes; }\n const sum = new Float32Array(pixels);\n for (const { mask } of masked) for (let i = 0; i < pixels; i++) sum[i] = sum[i]! + mask[i]!;\n if (tables.compositeMethod === \"sequential\") {\n for (const table of tables.tables) {\n const mask = table === background ? Float32Array.from(sum, (s) => 1 - Math.min(1, s)) : masked.find((m) => m.table === table)?.mask;\n if (!mask) continue;\n const result = data.slice();\n transform(table, result);\n for (let i = 0; i < pixels; i++) for (let c = 0; c < 3; c++) data[i * 3 + c] = data[i * 3 + c]! + (result[i * 3 + c]! - data[i * 3 + c]!) * mask[i]!;\n }\n } else {\n const results = masked.map(({ table }) => { const r = data.slice(); transform(table, r); return r; });\n if (background) transform(background, data);\n for (let i = 0; i < pixels; i++) {\n const bg = 1 - Math.min(1, sum[i]!), norm = 1 / (sum[i]! + bg);\n for (let c = 0; c < 3; c++) {\n let v = data[i * 3 + c]! * bg;\n masked.forEach((m, k) => { v += results[k]![i * 3 + c]! * m.mask[i]!; });\n data[i * 3 + c] = v * norm;\n }\n }\n }\n return notes;\n}\n\nfunction applyTable(table: DngRgbTable, rgb: Float32Array): void {\n const matrix = table.primaries !== \"prophoto\", encode = matrix ? mul(inv(rgbToXyzD50(table.primaries)), rgbToXyzD50(\"prophoto\")) : null, decode = encode ? inv(encode) : null;\n const extend = matrix && table.gamut === \"extend\", divs = table.divisions, s = table.samples, scale = divs - 1, maxIndex = divs - 2;\n const o001 = 3, o010 = 3 * divs, o100 = 3 * divs * divs, o011 = o010 + o001, o101 = o100 + o001, o110 = o100 + o010, o111 = o110 + o001;\n const pin = (x: number): number => x < 0 ? 0 : x > 1 ? 1 : x;\n for (let i = 0; i < rgb.length; i += 3) {\n let r = rgb[i]!, g = rgb[i + 1]!, b = rgb[i + 2]!, dr = 0, dg = 0, db = 0;\n if (encode) {\n const rr = encode[0]! * r + encode[1]! * g + encode[2]! * b, gg = encode[3]! * r + encode[4]! * g + encode[5]! * b, bb = encode[6]! * r + encode[7]! * g + encode[8]! * b;\n r = pin(rr); g = pin(gg); b = pin(bb);\n if (extend) { dr = rr - r; dg = gg - g; db = bb - b; }\n } else { r = pin(r); g = pin(g); b = pin(b); }\n r = gammaCurve(table.gamma, r, true); g = gammaCurve(table.gamma, g, true); b = gammaCurve(table.gamma, b, true);\n const rs = r * scale, gs = g * scale, bs = b * scale;\n const ri = Math.min(Math.floor(rs), maxIndex), gi = Math.min(Math.floor(gs), maxIndex), bi = Math.min(Math.floor(bs), maxIndex);\n const rf = rs - ri, gf = gs - gi, bf = bs - bi;\n let o1: number, o2: number, f1: number, f2: number, f3: number;\n if (gf >= rf) {\n if (bf >= gf) { o1 = o001; o2 = o011; f1 = bf; f2 = gf; f3 = rf; }\n else if (bf >= rf) { o1 = o010; o2 = o011; f1 = gf; f2 = bf; f3 = rf; }\n else { o1 = o010; o2 = o110; f1 = gf; f2 = rf; f3 = bf; }\n } else if (bf >= rf) { o1 = o001; o2 = o101; f1 = bf; f2 = rf; f3 = gf; }\n else if (bf >= gf) { o1 = o100; o2 = o101; f1 = rf; f2 = bf; f3 = gf; }\n else { o1 = o100; o2 = o110; f1 = rf; f2 = gf; f3 = bf; }\n const w0 = 1 - f1, w1 = f1 - f2, w2 = f2 - f3, base = ri * o100 + gi * o010 + bi * o001;\n const out = [0, 1, 2].map((c) => gammaCurve(table.gamma, (w0 * s[base + c]! + w1 * s[base + o1 + c]! + w2 * s[base + o2 + c]! + f3 * s[base + o111 + c]!) / 65535, false));\n let [nr, ng, nb] = out as [number, number, number];\n if (decode) {\n nr += dr; ng += dg; nb += db;\n [nr, ng, nb] = [decode[0]! * nr + decode[1]! * ng + decode[2]! * nb, decode[3]! * nr + decode[4]! * ng + decode[5]! * nb, decode[6]! * nr + decode[7]! * ng + decode[8]! * nb];\n }\n rgb[i] = pin(nr); rgb[i + 1] = pin(ng); rgb[i + 2] = pin(nb);\n }\n}\n"]}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { type DngStageImage } from "./dng-opcodes.js";
|
|
2
|
+
import type { ImportedDngRaw } from "./dng-import.js";
|
|
3
|
+
export interface DevelopDngStageImageOptions {
|
|
4
|
+
/** The output the development is for ("srgb-8" or "srgb-16" on screen; "dng", "jpeg" or "png" exports). Default "srgb-8" (fast; owner, 2026-11-11). */
|
|
5
|
+
format?: "srgb-8" | "srgb-16" | "dng" | "jpeg" | "png";
|
|
6
|
+
/** The speed-versus-accuracy choice (WarpRectilinear resampling); default from `format` (fast on screen, full for exports). */
|
|
7
|
+
fast?: boolean;
|
|
8
|
+
/** Apply the opcode lists (default true). */
|
|
9
|
+
opcodes?: boolean;
|
|
10
|
+
}
|
|
11
|
+
export interface DngStageImageResult extends DngStageImage {
|
|
12
|
+
/** 3 for LinearRaw (every opcode list applied), 2 for a CFA mosaic (OpcodeList3 left to the caller). */
|
|
13
|
+
stage: 2 | 3;
|
|
14
|
+
/** The resolved `fast` and where it came from. */
|
|
15
|
+
fast: {
|
|
16
|
+
requested: boolean;
|
|
17
|
+
defaultedFrom: "request" | "format";
|
|
18
|
+
};
|
|
19
|
+
/** What was applied and what was not. */
|
|
20
|
+
assumptions: string[];
|
|
21
|
+
}
|
|
22
|
+
/** Builds the stage-2 (CFA) or stage-3 (LinearRaw) image of an imported DNG, normalized 0..1, interleaved by sample. */
|
|
23
|
+
export declare function developDngStageImage(raw: ImportedDngRaw, options?: DevelopDngStageImageOptions): DngStageImageResult;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
// This product includes DNG technology under license by Adobe.
|
|
3
|
+
/**
|
|
4
|
+
* #598, #600: an imported DNG's linear stage image, as the DNG specification's processing model defines it (chapter "Mapping Raw
|
|
5
|
+
* Values to Linear Reference Values" and "Opcode List Processing"): OpcodeList1 on the stored codes (stage 1); then linearization
|
|
6
|
+
* (LinearizationTable), black subtraction (BlackLevel with its repeat pattern plus BlackLevelDeltaH/V, origin the ActiveArea's
|
|
7
|
+
* top-left) and scaling by WhiteLevel − black, clipped to 0..1, over the ActiveArea (stage 2); then OpcodeList2. For LinearRaw data
|
|
8
|
+
* stage 3 is stage 2 and OpcodeList3 follows; a CFA mosaic stops at stage 2, and the caller applies OpcodeList3 with
|
|
9
|
+
* `applyDngOpcodes` after demosaicing.
|
|
10
|
+
*/
|
|
11
|
+
import { InvalidConfigurationError } from "../core/configuration-error.js";
|
|
12
|
+
import { fastFormatDefault, resolveFast } from "../facade/fast-resolution.js";
|
|
13
|
+
import { applyDngOpcodes } from "./dng-opcodes.js";
|
|
14
|
+
function fail(message) { throw new InvalidConfigurationError("developDngStageImage: " + message); }
|
|
15
|
+
/** Builds the stage-2 (CFA) or stage-3 (LinearRaw) image of an imported DNG, normalized 0..1, interleaved by sample. */
|
|
16
|
+
export function developDngStageImage(raw, options = {}) {
|
|
17
|
+
if (raw === null || typeof raw !== "object" || !(raw.codes instanceof Uint16Array))
|
|
18
|
+
fail("raw must be an ImportedDngRaw.");
|
|
19
|
+
if (options === null || typeof options !== "object")
|
|
20
|
+
fail("options must be an object.");
|
|
21
|
+
for (const key of Object.keys(options))
|
|
22
|
+
if (!["format", "fast", "opcodes"].includes(key))
|
|
23
|
+
fail("unknown option " + JSON.stringify(key) + ".");
|
|
24
|
+
const format = options.format ?? "srgb-8";
|
|
25
|
+
if (!["srgb-8", "srgb-16", "dng", "jpeg", "png"].includes(format))
|
|
26
|
+
fail("format must be srgb-8, srgb-16, dng, jpeg or png.");
|
|
27
|
+
if (options.fast !== undefined && typeof options.fast !== "boolean")
|
|
28
|
+
fail("fast must be a boolean.");
|
|
29
|
+
const fast = resolveFast(options.fast, fastFormatDefault(format, "capture")), useOpcodes = options.opcodes ?? true;
|
|
30
|
+
const { width, height, samplesPerPixel: spp, codes, activeArea, blackLevel, whiteLevel, linearizationTable } = raw, scale = raw.scale;
|
|
31
|
+
const notes = [];
|
|
32
|
+
let stage1 = codes;
|
|
33
|
+
if (useOpcodes && raw.opcodeList1?.length) {
|
|
34
|
+
const image = { width, height, planes: spp, data: Float32Array.from(codes, (v) => v / 65535) };
|
|
35
|
+
notes.push(...applyDngOpcodes(image, raw.opcodeList1, { stage: 1, fast, scale }));
|
|
36
|
+
stage1 = Uint16Array.from(image.data, (v) => Math.round(Math.min(Math.max(v, 0), 1) * 65535));
|
|
37
|
+
}
|
|
38
|
+
// Stage 2 covers the ActiveArea (whole pixels; a half-size area is rounded outwards).
|
|
39
|
+
const ax = Math.floor(activeArea.x), ay = Math.floor(activeArea.y), aw = Math.min(width - ax, Math.ceil(activeArea.width)), ah = Math.min(height - ay, Math.ceil(activeArea.height));
|
|
40
|
+
const data = new Float32Array(aw * ah * spp), { repeatRows: rr, repeatColumns: rc, values, deltaH, deltaV } = blackLevel;
|
|
41
|
+
for (let y = 0; y < ah; y++)
|
|
42
|
+
for (let x = 0; x < aw; x++)
|
|
43
|
+
for (let s = 0; s < spp; s++) {
|
|
44
|
+
let v = stage1[((ay + y) * width + ax + x) * spp + s];
|
|
45
|
+
if (linearizationTable)
|
|
46
|
+
v = linearizationTable[Math.min(v, linearizationTable.length - 1)];
|
|
47
|
+
const black = values[((y % rr) * rc + (x % rc)) * spp + s] + (deltaH?.[x] ?? 0) + (deltaV?.[y] ?? 0);
|
|
48
|
+
const span = whiteLevel[s] - black;
|
|
49
|
+
data[(y * aw + x) * spp + s] = span > 0 ? Math.min(Math.max((v - black) / span, 0), 1) : 0;
|
|
50
|
+
}
|
|
51
|
+
const image = { width: aw, height: ah, planes: spp, data };
|
|
52
|
+
if (useOpcodes && raw.opcodeList2?.length)
|
|
53
|
+
notes.push(...applyDngOpcodes(image, raw.opcodeList2, { stage: 2, fast, scale }));
|
|
54
|
+
const linearRaw = raw.photometricInterpretation === "linear-raw";
|
|
55
|
+
if (useOpcodes && raw.opcodeList3?.length) {
|
|
56
|
+
if (linearRaw)
|
|
57
|
+
notes.push(...applyDngOpcodes(image, raw.opcodeList3, { stage: 3, fast, scale }));
|
|
58
|
+
else
|
|
59
|
+
notes.push("OpcodeList3 not applied: it acts on the demosaiced image; call applyDngOpcodes(image, raw.opcodeList3, { stage: 3 }) after demosaicing.");
|
|
60
|
+
}
|
|
61
|
+
if (!useOpcodes && (raw.opcodeList1 || raw.opcodeList2 || raw.opcodeList3))
|
|
62
|
+
notes.push("Opcode lists not applied (opcodes: false).");
|
|
63
|
+
return { ...image, stage: linearRaw ? 3 : 2, fast: { requested: fast, defaultedFrom: options.fast === undefined ? "format" : "request" }, assumptions: notes };
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=dng-stage-image.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dng-stage-image.js","sourceRoot":"","sources":["../../src/capture/dng-stage-image.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 * #598, #600: an imported DNG's linear stage image, as the DNG specification's processing model defines it (chapter \"Mapping Raw\n * Values to Linear Reference Values\" and \"Opcode List Processing\"): OpcodeList1 on the stored codes (stage 1); then linearization\n * (LinearizationTable), black subtraction (BlackLevel with its repeat pattern plus BlackLevelDeltaH/V, origin the ActiveArea's\n * top-left) and scaling by WhiteLevel − black, clipped to 0..1, over the ActiveArea (stage 2); then OpcodeList2. For LinearRaw data\n * stage 3 is stage 2 and OpcodeList3 follows; a CFA mosaic stops at stage 2, and the caller applies OpcodeList3 with\n * `applyDngOpcodes` after demosaicing.\n */\n\nimport { InvalidConfigurationError } from \"../core/configuration-error.js\";\nimport { fastFormatDefault, resolveFast } from \"../facade/fast-resolution.js\";\nimport { applyDngOpcodes, type DngStageImage } from \"./dng-opcodes.js\";\nimport type { ImportedDngRaw } from \"./dng-import.js\";\n\nexport interface DevelopDngStageImageOptions {\n /** The output the development is for (\"srgb-8\" or \"srgb-16\" on screen; \"dng\", \"jpeg\" or \"png\" exports). Default \"srgb-8\" (fast; owner, 2026-11-11). */\n format?: \"srgb-8\" | \"srgb-16\" | \"dng\" | \"jpeg\" | \"png\";\n /** The speed-versus-accuracy choice (WarpRectilinear resampling); default from `format` (fast on screen, full for exports). */\n fast?: boolean;\n /** Apply the opcode lists (default true). */\n opcodes?: boolean;\n}\nexport interface DngStageImageResult extends DngStageImage {\n /** 3 for LinearRaw (every opcode list applied), 2 for a CFA mosaic (OpcodeList3 left to the caller). */\n stage: 2 | 3;\n /** The resolved `fast` and where it came from. */\n fast: { requested: boolean; defaultedFrom: \"request\" | \"format\" };\n /** What was applied and what was not. */\n assumptions: string[];\n}\n\nfunction fail(message: string): never { throw new InvalidConfigurationError(\"developDngStageImage: \" + message); }\n\n/** Builds the stage-2 (CFA) or stage-3 (LinearRaw) image of an imported DNG, normalized 0..1, interleaved by sample. */\nexport function developDngStageImage(raw: ImportedDngRaw, options: DevelopDngStageImageOptions = {}): DngStageImageResult {\n if (raw === null || typeof raw !== \"object\" || !(raw.codes instanceof Uint16Array)) fail(\"raw must be an ImportedDngRaw.\");\n if (options === null || typeof options !== \"object\") fail(\"options must be an object.\");\n for (const key of Object.keys(options)) if (![\"format\", \"fast\", \"opcodes\"].includes(key)) fail(\"unknown option \" + JSON.stringify(key) + \".\");\n const format = options.format ?? \"srgb-8\";\n if (![\"srgb-8\", \"srgb-16\", \"dng\", \"jpeg\", \"png\"].includes(format)) fail(\"format must be srgb-8, srgb-16, dng, jpeg or png.\");\n if (options.fast !== undefined && typeof options.fast !== \"boolean\") fail(\"fast must be a boolean.\");\n const fast = resolveFast(options.fast, fastFormatDefault(format, \"capture\")), useOpcodes = options.opcodes ?? true;\n const { width, height, samplesPerPixel: spp, codes, activeArea, blackLevel, whiteLevel, linearizationTable } = raw, scale = raw.scale;\n const notes: string[] = [];\n let stage1 = codes;\n if (useOpcodes && raw.opcodeList1?.length) {\n const image: DngStageImage = { width, height, planes: spp, data: Float32Array.from(codes, (v) => v / 65535) };\n notes.push(...applyDngOpcodes(image, raw.opcodeList1, { stage: 1, fast, scale }));\n stage1 = Uint16Array.from(image.data, (v) => Math.round(Math.min(Math.max(v, 0), 1) * 65535));\n }\n // Stage 2 covers the ActiveArea (whole pixels; a half-size area is rounded outwards).\n const ax = Math.floor(activeArea.x), ay = Math.floor(activeArea.y), aw = Math.min(width - ax, Math.ceil(activeArea.width)), ah = Math.min(height - ay, Math.ceil(activeArea.height));\n const data = new Float32Array(aw * ah * spp), { repeatRows: rr, repeatColumns: rc, values, deltaH, deltaV } = blackLevel;\n for (let y = 0; y < ah; y++) for (let x = 0; x < aw; x++) for (let s = 0; s < spp; s++) {\n let v = stage1[((ay + y) * width + ax + x) * spp + s]!;\n if (linearizationTable) v = linearizationTable[Math.min(v, linearizationTable.length - 1)]!;\n const black = values[((y % rr) * rc + (x % rc)) * spp + s]! + (deltaH?.[x] ?? 0) + (deltaV?.[y] ?? 0);\n const span = whiteLevel[s]! - black;\n data[(y * aw + x) * spp + s] = span > 0 ? Math.min(Math.max((v - black) / span, 0), 1) : 0;\n }\n const image: DngStageImage = { width: aw, height: ah, planes: spp, data };\n if (useOpcodes && raw.opcodeList2?.length) notes.push(...applyDngOpcodes(image, raw.opcodeList2, { stage: 2, fast, scale }));\n const linearRaw = raw.photometricInterpretation === \"linear-raw\";\n if (useOpcodes && raw.opcodeList3?.length) {\n if (linearRaw) notes.push(...applyDngOpcodes(image, raw.opcodeList3, { stage: 3, fast, scale }));\n else notes.push(\"OpcodeList3 not applied: it acts on the demosaiced image; call applyDngOpcodes(image, raw.opcodeList3, { stage: 3 }) after demosaicing.\");\n }\n if (!useOpcodes && (raw.opcodeList1 || raw.opcodeList2 || raw.opcodeList3)) notes.push(\"Opcode lists not applied (opcodes: false).\");\n return { ...image, stage: linearRaw ? 3 : 2, fast: { requested: fast, defaultedFrom: options.fast === undefined ? \"format\" : \"request\" }, assumptions: notes };\n}\n"]}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Internal (#534): the sensor-stage hook of one render of an exposure build-up (`simulateExposureBuildUp`). After a site's
|
|
3
|
+
* ordinary photo and dark draws, `split` gets the render's expected means and those draws, and sets the counts the readout
|
|
4
|
+
* uses (`photo`, `dark`); `read` names the readout's read-noise stream. The build-up's own logic (binomial splitting, the
|
|
5
|
+
* per-site chain) lives in facade/exposure-build-up.ts, so captures without a build-up carry only this registry.
|
|
6
|
+
*/
|
|
7
|
+
export interface ExposureBuildUpStage {
|
|
8
|
+
/** Sets `photo` and `dark` for the absolute native site `index` from this render's expected means and ordinary draws. */
|
|
9
|
+
split(index: number, photoMean: number, darkMean: number, photo: number, dark: number): void;
|
|
10
|
+
photo: number;
|
|
11
|
+
dark: number;
|
|
12
|
+
/** The read-noise stream ID of the readout (`deriveNativeSiteStreamSeedUint32`). */
|
|
13
|
+
read: number;
|
|
14
|
+
}
|
|
15
|
+
/** The running build-up renders' stages, by their native RAW input (`NativeRawInput`, the object the capture facade builds). */
|
|
16
|
+
export declare const EXPOSURE_BUILD_UP_STAGES: WeakMap<object, ExposureBuildUpStage>;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
/** The running build-up renders' stages, by their native RAW input (`NativeRawInput`, the object the capture facade builds). */
|
|
3
|
+
export const EXPOSURE_BUILD_UP_STAGES = new WeakMap();
|
|
4
|
+
//# sourceMappingURL=exposure-build-up-stage.js.map
|