@photivra/engine 2.21.0 → 2.23.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (172) hide show
  1. package/CHANGELOG.md +150 -1
  2. package/CITATION.cff +1 -1
  3. package/README.md +6 -6
  4. package/SECURITY.md +1 -1
  5. package/THIRD_PARTY.md +11 -0
  6. package/dist/capture/c2pa-embed.d.ts +116 -0
  7. package/dist/capture/c2pa-embed.js +493 -0
  8. package/dist/capture/c2pa-embed.js.map +1 -0
  9. package/dist/capture/dng-import.d.ts +73 -8
  10. package/dist/capture/dng-import.js +315 -80
  11. package/dist/capture/dng-import.js.map +1 -1
  12. package/dist/capture/dng-opcodes.d.ts +96 -0
  13. package/dist/capture/dng-opcodes.js +391 -0
  14. package/dist/capture/dng-opcodes.js.map +1 -0
  15. package/dist/capture/dng-profile-maps.d.ts +99 -0
  16. package/dist/capture/dng-profile-maps.js +381 -0
  17. package/dist/capture/dng-profile-maps.js.map +1 -0
  18. package/dist/capture/dng-stage-image.d.ts +23 -0
  19. package/dist/capture/dng-stage-image.js +65 -0
  20. package/dist/capture/dng-stage-image.js.map +1 -0
  21. package/dist/capture/jpeg-xl-tiles.d.ts +22 -0
  22. package/dist/capture/jpeg-xl-tiles.js +151 -0
  23. package/dist/capture/jpeg-xl-tiles.js.map +1 -0
  24. package/dist/capture/lossy-jpeg.d.ts +17 -0
  25. package/dist/capture/lossy-jpeg.js +369 -0
  26. package/dist/capture/lossy-jpeg.js.map +1 -0
  27. package/dist/capture/native-raw-development.d.ts +2 -1
  28. package/dist/capture/native-raw-development.js.map +1 -1
  29. package/dist/color/neighbor-highlight-reconstruction.d.ts +76 -0
  30. package/dist/color/neighbor-highlight-reconstruction.js +257 -0
  31. package/dist/color/neighbor-highlight-reconstruction.js.map +1 -0
  32. package/dist/color/sensor-color-development.d.ts +5 -0
  33. package/dist/color/sensor-color-development.js +7 -1
  34. package/dist/color/sensor-color-development.js.map +1 -1
  35. package/dist/color/spectral-spikiness.d.ts +11 -0
  36. package/dist/color/spectral-spikiness.js +23 -0
  37. package/dist/color/spectral-spikiness.js.map +1 -0
  38. package/dist/core/execution-error.d.ts +21 -0
  39. package/dist/core/execution-error.js +12 -0
  40. package/dist/core/execution-error.js.map +1 -0
  41. package/dist/core/version.d.ts +1 -1
  42. package/dist/core/version.js +1 -1
  43. package/dist/core/version.js.map +1 -1
  44. package/dist/facade/catalogue-lens-signal.d.ts +26 -1
  45. package/dist/facade/catalogue-lens-signal.js +25 -7
  46. package/dist/facade/catalogue-lens-signal.js.map +1 -1
  47. package/dist/facade/diffraction-provider.d.ts +1 -1
  48. package/dist/facade/diffraction-provider.js +4 -4
  49. package/dist/facade/diffraction-provider.js.map +1 -1
  50. package/dist/facade/display-view-gpu-session.js +38 -6
  51. package/dist/facade/display-view-gpu-session.js.map +1 -1
  52. package/dist/facade/display-view-gpu.d.ts +13 -5
  53. package/dist/facade/display-view-gpu.js.map +1 -1
  54. package/dist/facade/display-view-normal.d.ts +15 -0
  55. package/dist/facade/display-view-normal.js +44 -0
  56. package/dist/facade/display-view-normal.js.map +1 -0
  57. package/dist/facade/display-view-rendering.d.ts +102 -0
  58. package/dist/facade/display-view-rendering.js +633 -0
  59. package/dist/facade/display-view-rendering.js.map +1 -0
  60. package/dist/facade/display-view.d.ts +37 -65
  61. package/dist/facade/display-view.js +147 -476
  62. package/dist/facade/display-view.js.map +1 -1
  63. package/dist/facade/expected-signal-setup.js +2 -2
  64. package/dist/facade/expected-signal-setup.js.map +1 -1
  65. package/dist/facade/fast-methods.d.ts +1 -1
  66. package/dist/facade/fast-methods.js +37 -8
  67. package/dist/facade/fast-methods.js.map +1 -1
  68. package/dist/facade/generic-lens-capture.d.ts +1 -1
  69. package/dist/facade/generic-lens-capture.js +1 -1
  70. package/dist/facade/generic-lens-capture.js.map +1 -1
  71. package/dist/facade/image-plane.js +41 -10
  72. package/dist/facade/image-plane.js.map +1 -1
  73. package/dist/facade/on-demand-kits.d.ts +14 -0
  74. package/dist/facade/on-demand-kits.js +36 -0
  75. package/dist/facade/on-demand-kits.js.map +1 -0
  76. package/dist/facade/opt-in-kit.d.ts +9 -0
  77. package/dist/facade/opt-in-kit.js +11 -0
  78. package/dist/facade/opt-in-kit.js.map +1 -0
  79. package/dist/facade/quality-kit.d.ts +21 -0
  80. package/dist/facade/quality-kit.js +23 -0
  81. package/dist/facade/quality-kit.js.map +1 -0
  82. package/dist/facade/quality-paths.d.ts +22 -0
  83. package/dist/facade/quality-paths.js +44 -0
  84. package/dist/facade/quality-paths.js.map +1 -0
  85. package/dist/facade/scene-radiance.d.ts +18 -2
  86. package/dist/facade/scene-radiance.js +6 -4
  87. package/dist/facade/scene-radiance.js.map +1 -1
  88. package/dist/facade/simulate-capture.d.ts +32 -13
  89. package/dist/facade/simulate-capture.js +162 -69
  90. package/dist/facade/simulate-capture.js.map +1 -1
  91. package/dist/facade/simulate-display-view.d.ts +10 -12
  92. package/dist/facade/simulate-display-view.js +57 -48
  93. package/dist/facade/simulate-display-view.js.map +1 -1
  94. package/dist/gpu/display-view-gpu-renderer.d.ts +43 -0
  95. package/dist/gpu/display-view-gpu-renderer.js +134 -0
  96. package/dist/gpu/display-view-gpu-renderer.js.map +1 -0
  97. package/dist/gpu/display-view-image-material-module.d.ts +3 -2
  98. package/dist/gpu/display-view-image-material-module.js +25 -3
  99. package/dist/gpu/display-view-image-material-module.js.map +1 -1
  100. package/dist/gpu/display-view-image-quality.d.ts +43 -1
  101. package/dist/gpu/display-view-image-quality.js +256 -11
  102. package/dist/gpu/display-view-image-quality.js.map +1 -1
  103. package/dist/gpu/display-view-quality-gpu.d.ts +13 -64
  104. package/dist/gpu/display-view-quality-gpu.js +55 -240
  105. package/dist/gpu/display-view-quality-gpu.js.map +1 -1
  106. package/dist/gpu/display-view-speed-gpu.d.ts +16 -16
  107. package/dist/gpu/display-view-speed-gpu.js +62 -19
  108. package/dist/gpu/display-view-speed-gpu.js.map +1 -1
  109. package/dist/gpu/image-kernel-accelerator.js +3 -0
  110. package/dist/gpu/image-kernel-accelerator.js.map +1 -1
  111. package/dist/gpu/image-kernel-execution.d.ts +2 -13
  112. package/dist/gpu/image-kernel-execution.js +2 -10
  113. package/dist/gpu/image-kernel-execution.js.map +1 -1
  114. package/dist/gpu/wgsl-display-view-coupled-stub.d.ts +13 -0
  115. package/dist/gpu/wgsl-display-view-coupled-stub.js +29 -0
  116. package/dist/gpu/wgsl-display-view-coupled-stub.js.map +1 -0
  117. package/dist/gpu/wgsl-display-view-coupled.d.ts +91 -0
  118. package/dist/gpu/wgsl-display-view-coupled.js +365 -0
  119. package/dist/gpu/wgsl-display-view-coupled.js.map +1 -0
  120. package/dist/gpu/wgsl-display-view-neighbors.d.ts +46 -0
  121. package/dist/gpu/wgsl-display-view-neighbors.js +114 -0
  122. package/dist/gpu/wgsl-display-view-neighbors.js.map +1 -0
  123. package/dist/gpu/wgsl-display-view-quality-kernel.d.ts +6 -9
  124. package/dist/gpu/wgsl-display-view-quality-kernel.js +113 -113
  125. package/dist/gpu/wgsl-display-view-quality-kernel.js.map +1 -1
  126. package/dist/gpu/wgsl-display-view-speed-kernel.d.ts +1 -41
  127. package/dist/gpu/wgsl-display-view-speed-kernel.js +73 -10
  128. package/dist/gpu/wgsl-display-view-speed-kernel.js.map +1 -1
  129. package/dist/index.d.ts +11 -3
  130. package/dist/index.js +9 -1
  131. package/dist/index.js.map +1 -1
  132. package/dist/output/camera-channel-response.d.ts +50 -0
  133. package/dist/output/camera-channel-response.js +69 -0
  134. package/dist/output/camera-channel-response.js.map +1 -0
  135. package/dist/output/native-capture-sdr.js +5 -2
  136. package/dist/output/native-capture-sdr.js.map +1 -1
  137. package/dist/output/sdr-rendering.d.ts +18 -1
  138. package/dist/output/sdr-rendering.js +39 -2
  139. package/dist/output/sdr-rendering.js.map +1 -1
  140. package/dist/sensor/native-sensor-report.d.ts +10 -0
  141. package/dist/sensor/native-sensor-report.js +16 -0
  142. package/dist/sensor/native-sensor-report.js.map +1 -0
  143. package/dist/sensor/sensor-characteristics.d.ts +81 -13
  144. package/dist/sensor/sensor-characteristics.js +10 -6
  145. package/dist/sensor/sensor-characteristics.js.map +1 -1
  146. package/docs/API_REFERENCE.md +117 -4
  147. package/docs/QUICK_START.md +37 -8
  148. package/docs/USAGE.md +105 -22
  149. package/docs/api/capture-c2pa-embed.md +177 -0
  150. package/docs/api/capture-dng-import.md +86 -10
  151. package/docs/api/capture-dng-opcodes.md +93 -0
  152. package/docs/api/capture-dng-profile-maps.md +141 -0
  153. package/docs/api/capture-dng-stage-image.md +43 -0
  154. package/docs/api/capture-jpeg-xl-tiles.md +33 -0
  155. package/docs/api/capture-lossy-jpeg.md +41 -0
  156. package/docs/api/capture-native-raw-development.md +2 -1
  157. package/docs/api/core-execution-error.md +43 -0
  158. package/docs/api/core-version.md +1 -1
  159. package/docs/api/exports.json +255 -5
  160. package/docs/api/facade-display-view-gpu.md +5 -2
  161. package/docs/api/facade-display-view.md +11 -15
  162. package/docs/api/facade-fast-methods.md +38 -9
  163. package/docs/api/facade-quality-paths.md +24 -0
  164. package/docs/api/facade-scene-radiance.md +1 -1
  165. package/docs/api/facade-simulate-capture.md +24 -7
  166. package/docs/api/facade-simulate-display-view.md +10 -12
  167. package/docs/api/gpu-image-kernel-execution.md +0 -36
  168. package/docs/api/output-camera-channel-response.md +55 -0
  169. package/docs/api/output-sdr-rendering.md +6 -1
  170. package/docs/api/sensor-sensor-characteristics.md +54 -2
  171. package/llms.txt +1 -0
  172. package/package.json +6 -5
@@ -0,0 +1,391 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ // This product includes DNG technology under license by Adobe.
3
+ /**
4
+ * #598, #600: DNG opcode lists (OpcodeList1/2/3, tags 51008, 51009, 51022), read and applied to an imported DNG's image at the
5
+ * stage the list belongs to. Written from the Adobe DNG Specification, chapter "Opcode List Processing" (opcodes added in 1.3.0.0).
6
+ * The 1.7.1.0 PDF could not be retrieved while this was written (HTTP 403); the parameter layouts and the details marked
7
+ * "(SDK)" were checked against the DNG SDK 1.7.1 source (dng_misc_opcodes, dng_gain_map, dng_lens_correction, dng_bad_pixels) and
8
+ * must be checked against the PDF (#600).
9
+ *
10
+ * A list is big-endian whatever the file's byte order: a LONG count, then per opcode a LONG id, the four-byte DNG version that
11
+ * introduced it, LONG flags (bit 0 optional, bit 1 may be skipped for previews) and the LONG byte count of its parameters.
12
+ *
13
+ * Stage images hold normalized values: stage 1 is the stored raw codes / 65535; stage 2 is the linearized image (ActiveArea,
14
+ * black-subtracted, divided by white − black, clipped to 0..1); stage 3 the demosaiced one (the same as stage 2 for LinearRaw). Pixel
15
+ * (row, column) sits at integer coordinates; a relative position u maps to the pixel coordinate u·width (SDK: Lerp over the bounds).
16
+ *
17
+ * Applied: WarpRectilinear (1), FixVignetteRadial (3), FixBadPixelsConstant (4), FixBadPixelsList (5), MapTable (7),
18
+ * MapPolynomial (8), GainMap (9), DeltaPerRow (10), DeltaPerColumn (11), ScalePerRow (12), ScalePerColumn (13). Others (WarpFisheye 2,
19
+ * TrimBounds 6, WarpRectilinear2 14 and unknown ids) are reported in the assumptions, never applied and never a failure.
20
+ */
21
+ import { InvalidConfigurationError } from "../core/configuration-error.js";
22
+ const NAMES = ["Unknown", "WarpRectilinear", "WarpFisheye", "FixVignetteRadial", "FixBadPixelsConstant", "FixBadPixelsList", "TrimBounds", "MapTable",
23
+ "MapPolynomial", "GainMap", "DeltaPerRow", "DeltaPerColumn", "ScalePerRow", "ScalePerColumn", "WarpRectilinear2"];
24
+ function fail(message) { throw new InvalidConfigurationError("DNG opcodes: " + message); }
25
+ /** Parses an opcode list (the tag's bytes). Every count and length is checked against the bytes before allocation. */
26
+ export function parseDngOpcodeList(bytes) {
27
+ if (!(bytes instanceof Uint8Array))
28
+ fail("the list must be a Uint8Array.");
29
+ const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength), n = bytes.length;
30
+ if (n < 4)
31
+ fail("the list is too short.");
32
+ const count = view.getUint32(0);
33
+ if (count > 4096 || count * 16 > n - 4)
34
+ fail("the opcode count exceeds the list.");
35
+ const out = [];
36
+ let p = 4;
37
+ for (let k = 0; k < count; k++) {
38
+ if (p + 16 > n)
39
+ fail("an opcode header exceeds the list.");
40
+ const id = view.getUint32(p), flags = view.getUint32(p + 8), length = view.getUint32(p + 12), start = p + 16;
41
+ if (length > n - start)
42
+ fail("opcode parameters exceed the list.");
43
+ const name = id < NAMES.length ? NAMES[id] : "Unknown";
44
+ out.push({ id, name, dngVersion: [bytes[p + 4], bytes[p + 5], bytes[p + 6], bytes[p + 7]], optional: (flags & 1) === 1, previewSkip: (flags & 2) === 2,
45
+ parameters: parseParameters(id, new DataView(bytes.buffer, bytes.byteOffset + start, length)) });
46
+ p = start + length;
47
+ }
48
+ return out;
49
+ }
50
+ function parseParameters(id, v) {
51
+ const size = v.byteLength;
52
+ const need = (bytes) => { if (bytes !== size)
53
+ fail("opcode " + id + " has " + size + " parameter bytes, expected " + bytes + "."); };
54
+ const finite = (x) => { if (!Number.isFinite(x))
55
+ fail("non-finite opcode parameter."); return x; };
56
+ const area = () => {
57
+ if (size < 32)
58
+ fail("area opcode parameters are too short.");
59
+ const [top, left, bottom, right, plane, planes, rowPitch, colPitch] = [0, 4, 8, 12, 16, 20, 24, 28].map((o) => v.getUint32(o));
60
+ if (bottom < top || right < left || planes < 1 || rowPitch < 1 || colPitch < 1)
61
+ fail("invalid opcode area.");
62
+ return { top, left, bottom, right, plane, planes, rowPitch, colPitch };
63
+ };
64
+ switch (id) {
65
+ case 1: {
66
+ if (size < 4)
67
+ fail("WarpRectilinear parameters are too short.");
68
+ const planes = v.getUint32(0);
69
+ if (planes < 1 || planes > 4)
70
+ fail("WarpRectilinear needs 1 to 4 planes.");
71
+ need(4 + planes * 48 + 16);
72
+ const list = Array.from({ length: planes }, (_, i) => {
73
+ const at = 4 + i * 48, d = (j) => finite(v.getFloat64(at + j * 8));
74
+ return { radial: [d(0), d(1), d(2), d(3)], tangential: [d(4), d(5)] };
75
+ });
76
+ const centerX = finite(v.getFloat64(4 + planes * 48)), centerY = finite(v.getFloat64(12 + planes * 48));
77
+ if (!(centerX >= 0 && centerX <= 1 && centerY >= 0 && centerY <= 1))
78
+ fail("WarpRectilinear's centre must be within the image.");
79
+ return { opcode: "WarpRectilinear", planes: list, centerX, centerY };
80
+ }
81
+ case 3: {
82
+ need(56);
83
+ const d = (j) => finite(v.getFloat64(j * 8));
84
+ const centerX = d(5), centerY = d(6);
85
+ if (!(centerX >= 0 && centerX <= 1 && centerY >= 0 && centerY <= 1))
86
+ fail("FixVignetteRadial's centre must be within the image.");
87
+ return { opcode: "FixVignetteRadial", coefficients: [d(0), d(1), d(2), d(3), d(4)], centerX, centerY };
88
+ }
89
+ case 4: {
90
+ need(8);
91
+ const bayerPhase = v.getUint32(4);
92
+ if (bayerPhase > 3)
93
+ fail("BayerPhase must be 0 to 3.");
94
+ return { opcode: "FixBadPixelsConstant", constant: v.getUint32(0), bayerPhase };
95
+ }
96
+ case 5: {
97
+ if (size < 12)
98
+ fail("FixBadPixelsList parameters are too short.");
99
+ const bayerPhase = v.getUint32(0), pointCount = v.getUint32(4), rectCount = v.getUint32(8);
100
+ if (bayerPhase > 3)
101
+ fail("BayerPhase must be 0 to 3.");
102
+ if (pointCount > (size - 12) / 8 || rectCount > (size - 12) / 16)
103
+ fail("bad-pixel counts exceed the parameters.");
104
+ need(12 + pointCount * 8 + rectCount * 16);
105
+ const points = Array.from({ length: pointCount }, (_, i) => [v.getUint32(12 + i * 8), v.getUint32(16 + i * 8)]);
106
+ const base = 12 + pointCount * 8;
107
+ const rects = Array.from({ length: rectCount }, (_, i) => [0, 4, 8, 12].map((o) => v.getUint32(base + i * 16 + o)));
108
+ return { opcode: "FixBadPixelsList", bayerPhase, points, rects };
109
+ }
110
+ case 7: {
111
+ const a = area();
112
+ if (size < 36)
113
+ fail("MapTable parameters are too short.");
114
+ const n = v.getUint32(32);
115
+ if (n < 1 || n > 65536)
116
+ fail("MapTable size must be 1 to 65536.");
117
+ need(36 + n * 2);
118
+ const table = new Uint16Array(n);
119
+ for (let i = 0; i < n; i++)
120
+ table[i] = v.getUint16(36 + i * 2);
121
+ return { opcode: "MapTable", area: a, table };
122
+ }
123
+ case 8: {
124
+ const a = area();
125
+ if (size < 36)
126
+ fail("MapPolynomial parameters are too short.");
127
+ const degree = v.getUint32(32);
128
+ if (degree > 8)
129
+ fail("MapPolynomial degree must be at most 8.");
130
+ need(36 + (degree + 1) * 8);
131
+ return { opcode: "MapPolynomial", area: a, coefficients: Array.from({ length: degree + 1 }, (_, i) => finite(v.getFloat64(36 + i * 8))) };
132
+ }
133
+ case 9: {
134
+ const a = area();
135
+ if (size < 76)
136
+ fail("GainMap parameters are too short.");
137
+ const pointsV = v.getUint32(32), pointsH = v.getUint32(36), spacingV = finite(v.getFloat64(40)), spacingH = finite(v.getFloat64(48));
138
+ const originV = finite(v.getFloat64(56)), originH = finite(v.getFloat64(64)), mapPlanes = v.getUint32(72);
139
+ if (pointsV < 1 || pointsH < 1 || mapPlanes < 1 || pointsV * pointsH * mapPlanes > (size - 76) / 4 || !(spacingV > 0 && spacingH > 0))
140
+ fail("invalid GainMap.");
141
+ need(76 + pointsV * pointsH * mapPlanes * 4);
142
+ const gains = new Float32Array(pointsV * pointsH * mapPlanes);
143
+ for (let i = 0; i < gains.length; i++)
144
+ gains[i] = finite(v.getFloat32(76 + i * 4));
145
+ return { opcode: "GainMap", area: a, pointsV, pointsH, spacingV, spacingH, originV, originH, mapPlanes, gains };
146
+ }
147
+ case 10:
148
+ case 11:
149
+ case 12:
150
+ case 13: {
151
+ const a = area();
152
+ if (size < 36)
153
+ fail("per-row or per-column opcode parameters are too short.");
154
+ const n = v.getUint32(32);
155
+ if (n > (size - 36) / 4)
156
+ fail("per-row or per-column count exceeds the parameters.");
157
+ need(36 + n * 4);
158
+ const values = new Float32Array(n);
159
+ for (let i = 0; i < n; i++)
160
+ values[i] = finite(v.getFloat32(36 + i * 4));
161
+ return { opcode: ["DeltaPerRow", "DeltaPerColumn", "ScalePerRow", "ScalePerColumn"][id - 10], area: a, values };
162
+ }
163
+ default: return null;
164
+ }
165
+ }
166
+ /** Keys's cubic convolution kernel with a = −0.75 (the DNG SDK's `dng_resample_bicubic`). */
167
+ function cubic(x) {
168
+ const a = -0.75;
169
+ x = Math.abs(x);
170
+ return x >= 2 ? 0 : x >= 1 ? ((a * x - 5 * a) * x + 8 * a) * x - 4 * a : ((a + 2) * x - (a + 3)) * x * x + 1;
171
+ }
172
+ /**
173
+ * Applies an opcode list to a stage image in place (WarpRectilinear returns a new buffer in `image.data`). Returns one assumption
174
+ * per opcode: what was applied, or why it was not.
175
+ */
176
+ export function applyDngOpcodes(image, opcodes, options) {
177
+ if (image === null || typeof image !== "object" || !Number.isSafeInteger(image.width) || !Number.isSafeInteger(image.height) || !Number.isSafeInteger(image.planes))
178
+ fail("applyDngOpcodes takes a stage image { width, height, planes, data }.");
179
+ if (!Array.isArray(opcodes))
180
+ fail("applyDngOpcodes takes a parsed opcode list (parseDngOpcodeList).");
181
+ if (options === null || typeof options !== "object")
182
+ fail("applyDngOpcodes takes options with the list's stage.");
183
+ const { width, height, planes } = image, scale = options.scale ?? 1, notes = [];
184
+ if (!(image.data instanceof Float32Array) || image.data.length !== width * height * planes)
185
+ fail("the stage image's data does not match its size.");
186
+ const label = (op) => "OpcodeList" + options.stage + " " + op.name + " (" + op.id + ")";
187
+ for (const op of opcodes) {
188
+ const p = op.parameters;
189
+ if (!p) {
190
+ notes.push(label(op) + " not applied: not supported" + (op.optional ? " (optional)." : " (marked required by the file)."));
191
+ continue;
192
+ }
193
+ if (scale !== 1 && (p.opcode === "FixBadPixelsConstant" || p.opcode === "FixBadPixelsList")) {
194
+ notes.push(label(op) + " not applied: a half-size image has no single raw pixels.");
195
+ continue;
196
+ }
197
+ if ((p.opcode === "FixBadPixelsConstant" || p.opcode === "FixBadPixelsList") && planes !== 1) {
198
+ notes.push(label(op) + " not applied: bad-pixel opcodes act on single-plane CFA data.");
199
+ continue;
200
+ }
201
+ if ("area" in p && scale !== 1 && (p.area.rowPitch > 1 || p.area.colPitch > 1)) {
202
+ notes.push(label(op) + " not applied: a pitched area cannot be scaled to a half-size image.");
203
+ continue;
204
+ }
205
+ switch (p.opcode) {
206
+ case "MapTable":
207
+ case "MapPolynomial":
208
+ case "DeltaPerRow":
209
+ case "DeltaPerColumn":
210
+ case "ScalePerRow":
211
+ case "ScalePerColumn":
212
+ case "GainMap":
213
+ applyArea(image, p, scale);
214
+ break;
215
+ case "FixVignetteRadial":
216
+ applyVignette(image, p);
217
+ break;
218
+ case "WarpRectilinear":
219
+ if (p.planes.length !== 1 && p.planes.length !== planes) {
220
+ notes.push(label(op) + " not applied: its plane count does not match the image.");
221
+ continue;
222
+ }
223
+ image.data = warp(image, p, options.fast);
224
+ break;
225
+ case "FixBadPixelsConstant":
226
+ case "FixBadPixelsList":
227
+ fixBadPixels(image, p);
228
+ break;
229
+ }
230
+ notes.push(label(op) + " applied" + (p.opcode === "WarpRectilinear" ? (options.fast ? " (bilinear resampling, fast)." : " (cubic convolution, a = −0.75).") : "."));
231
+ }
232
+ return notes;
233
+ }
234
+ function applyArea(image, p, scale) {
235
+ const { width, height, planes, data } = image, a = p.area;
236
+ const top = Math.floor(a.top * scale), left = Math.floor(a.left * scale), bottom = Math.min(height, Math.ceil(a.bottom * scale)), right = Math.min(width, Math.ceil(a.right * scale));
237
+ const lastPlane = Math.min(planes, a.plane + a.planes);
238
+ const clip = (x) => x < 0 ? 0 : x > 1 ? 1 : x;
239
+ for (let plane = a.plane; plane < lastPlane; plane++)
240
+ for (let row = top, ri = 0; row < bottom; row += a.rowPitch, ri++) {
241
+ for (let col = left, ci = 0; col < right; col += a.colPitch, ci++) {
242
+ const i = (row * width + col) * planes + plane, x = data[i];
243
+ switch (p.opcode) {
244
+ case "MapTable": {
245
+ const t = p.table, index = Math.round(clip(x) * 65535);
246
+ data[i] = t[Math.min(index, t.length - 1)] / 65535;
247
+ break;
248
+ }
249
+ case "MapPolynomial": {
250
+ let y = 0;
251
+ for (let k = p.coefficients.length - 1; k >= 0; k--)
252
+ y = y * clip(x) + p.coefficients[k];
253
+ data[i] = clip(y);
254
+ break;
255
+ }
256
+ // SDK: the per-row/column tables have one entry per pitched row or column; an index beyond the table leaves the value.
257
+ case "DeltaPerRow":
258
+ if (ri < p.values.length)
259
+ data[i] = clip(x + p.values[ri]);
260
+ break;
261
+ case "DeltaPerColumn":
262
+ if (ci < p.values.length)
263
+ data[i] = clip(x + p.values[ci]);
264
+ break;
265
+ case "ScalePerRow":
266
+ if (ri < p.values.length)
267
+ data[i] = clip(x * p.values[ri]);
268
+ break;
269
+ case "ScalePerColumn":
270
+ if (ci < p.values.length)
271
+ data[i] = clip(x * p.values[ci]);
272
+ break;
273
+ case "GainMap":
274
+ data[i] = Math.min(Math.max(x, 0) * gainAt(p, (row + 0.5) / height, (col + 0.5) / width, Math.min(plane, p.mapPlanes - 1)), 1);
275
+ break;
276
+ }
277
+ }
278
+ }
279
+ }
280
+ /**
281
+ * The GainMap gain at a relative position (pixel centre over the image), bilinear between map points, held at the edges (SDK
282
+ * `dng_gain_map_interpolator`). Map point (i, j) is at relative position origin + spacing·(i, j).
283
+ */
284
+ function gainAt(p, v, h, plane) {
285
+ const axis = (rel, origin, spacing, points) => {
286
+ const f = (rel - origin) / spacing;
287
+ if (!(f > 0))
288
+ return [0, 0, 0];
289
+ if (f >= points - 1)
290
+ return [points - 1, points - 1, 0];
291
+ const i = Math.floor(f);
292
+ return [i, i + 1, f - i];
293
+ };
294
+ const [r0, r1, fr] = axis(v, p.originV, p.spacingV, p.pointsV), [c0, c1, fc] = axis(h, p.originH, p.spacingH, p.pointsH);
295
+ const g = (r, c) => p.gains[(r * p.pointsH + c) * p.mapPlanes + plane];
296
+ const top = g(r0, c0) + (g(r0, c1) - g(r0, c0)) * fc, bottom = g(r1, c0) + (g(r1, c1) - g(r1, c0)) * fc;
297
+ return top + (bottom - top) * fr;
298
+ }
299
+ /** Centre in pixel coordinates and the normalization radius: the largest distance from the centre to an image corner (SDK). */
300
+ function geometry(image, centerX, centerY) {
301
+ const cx = centerX * image.width, cy = centerY * image.height;
302
+ return { cx, cy, radius: Math.max(Math.hypot(cx, cy), Math.hypot(image.width - cx, cy), Math.hypot(cx, image.height - cy), Math.hypot(image.width - cx, image.height - cy)) };
303
+ }
304
+ function applyVignette(image, p) {
305
+ const { width, height, planes, data } = image, { cx, cy, radius } = geometry(image, p.centerX, p.centerY), k = p.coefficients;
306
+ for (let row = 0; row < height; row++)
307
+ for (let col = 0; col < width; col++) {
308
+ const r2 = ((col - cx) ** 2 + (row - cy) ** 2) / (radius * radius);
309
+ const gain = 1 + r2 * (k[0] + r2 * (k[1] + r2 * (k[2] + r2 * (k[3] + r2 * k[4]))));
310
+ for (let c = 0; c < planes; c++) {
311
+ const i = (row * width + col) * planes + c;
312
+ data[i] = Math.min(Math.max(data[i] * gain, 0), 1);
313
+ }
314
+ }
315
+ }
316
+ /**
317
+ * WarpRectilinear: for destination pixel (x, y), normalized offsets dx = (x − cx)/m, dy = (y − cy)/m, r² = dx² + dy²; the source
318
+ * is the centre plus m·[(dx, dy)·(kr0 + kr1r² + kr2r⁴ + kr3r⁶) + (kt1(r² + 2dx²) + 2kt0·dx·dy, kt0(r² + 2dy²) + 2kt1·dx·dy)],
319
+ * held within the image (SDK `dng_filter_warp`, `EvaluateTangential`). One parameter set applies to every plane, or one per plane.
320
+ */
321
+ function warp(image, p, fast) {
322
+ const { width, height, planes, data } = image, { cx, cy, radius } = geometry(image, p.centerX, p.centerY), out = new Float32Array(data.length);
323
+ const sample = (plane, x, y) => data[(Math.min(Math.max(y, 0), height - 1) * width + Math.min(Math.max(x, 0), width - 1)) * planes + plane];
324
+ for (let plane = 0; plane < planes; plane++) {
325
+ const { radial: [k0, k1, k2, k3], tangential: [t0, t1] } = p.planes[p.planes.length === 1 ? 0 : plane];
326
+ for (let y = 0; y < height; y++)
327
+ for (let x = 0; x < width; x++) {
328
+ const dx = (x - cx) / radius, dy = (y - cy) / radius, r2 = dx * dx + dy * dy, ratio = k0 + r2 * (k1 + r2 * (k2 + r2 * k3));
329
+ const sx = Math.min(Math.max(cx + radius * (dx * ratio + t1 * (r2 + 2 * dx * dx) + 2 * t0 * dx * dy), 0), width - 1);
330
+ const sy = Math.min(Math.max(cy + radius * (dy * ratio + t0 * (r2 + 2 * dy * dy) + 2 * t1 * dx * dy), 0), height - 1);
331
+ const ix = Math.floor(sx), iy = Math.floor(sy), fx = sx - ix, fy = sy - iy;
332
+ let value = 0;
333
+ if (fast)
334
+ value = (sample(plane, ix, iy) * (1 - fx) + sample(plane, ix + 1, iy) * fx) * (1 - fy) + (sample(plane, ix, iy + 1) * (1 - fx) + sample(plane, ix + 1, iy + 1) * fx) * fy;
335
+ else
336
+ for (let j = -1; j <= 2; j++) {
337
+ const wy = cubic(j - fy);
338
+ for (let i = -1; i <= 2; i++)
339
+ value += wy * cubic(i - fx) * sample(plane, ix + i, iy + j);
340
+ }
341
+ out[(y * width + x) * planes + plane] = Math.min(Math.max(value, 0), 1);
342
+ }
343
+ }
344
+ return out;
345
+ }
346
+ /**
347
+ * Bad pixels of a Bayer image (BayerPhase 0 RGGB, 1 GRBG, 2 GBRG, 3 BGGR; green where row + column + phase + ⌊phase/2⌋ is odd) are
348
+ * replaced by the mean of their nearest good same-colour neighbours: green first the four diagonals, then the four at distance 2,
349
+ * then the four at (±2, ±2); red and blue the four at distance 2, then (±2, ±2) (SDK ring order). A pixel with no good neighbour
350
+ * keeps its value. FixBadPixelsConstant marks pixels whose stored code equals the constant (in stage-1 codes, value·65535).
351
+ */
352
+ function fixBadPixels(image, p) {
353
+ const { width, height, data } = image, bad = new Uint8Array(width * height);
354
+ if (p.opcode === "FixBadPixelsConstant") {
355
+ for (let i = 0; i < bad.length; i++)
356
+ if (Math.round(data[i] * 65535) === p.constant)
357
+ bad[i] = 1;
358
+ }
359
+ else {
360
+ for (const [r, c] of p.points)
361
+ if (r < height && c < width)
362
+ bad[r * width + c] = 1;
363
+ for (const [t, l, b, r] of p.rects)
364
+ for (let y = t; y < Math.min(b, height); y++)
365
+ for (let x = l; x < Math.min(r, width); x++)
366
+ bad[y * width + x] = 1;
367
+ }
368
+ const rings = [[[-1, 1], [-1, -1], [1, -1], [1, 1]], [[-2, 0], [2, 0], [0, -2], [0, 2]], [[-2, -2], [-2, 2], [2, -2], [2, 2]]];
369
+ const source = data.slice();
370
+ for (let y = 0; y < height; y++)
371
+ for (let x = 0; x < width; x++) {
372
+ if (!bad[y * width + x])
373
+ continue;
374
+ const green = ((y + x + p.bayerPhase + (p.bayerPhase >> 1)) & 1) === 1;
375
+ for (const ring of green ? rings : rings.slice(1)) {
376
+ let total = 0, count = 0;
377
+ for (const [dy, dx] of ring) {
378
+ const yy = y + dy, xx = x + dx;
379
+ if (yy >= 0 && yy < height && xx >= 0 && xx < width && !bad[yy * width + xx]) {
380
+ total += source[yy * width + xx];
381
+ count++;
382
+ }
383
+ }
384
+ if (count) {
385
+ data[y * width + x] = total / count;
386
+ break;
387
+ }
388
+ }
389
+ }
390
+ }
391
+ //# sourceMappingURL=dng-opcodes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dng-opcodes.js","sourceRoot":"","sources":["../../src/capture/dng-opcodes.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: DNG opcode lists (OpcodeList1/2/3, tags 51008, 51009, 51022), read and applied to an imported DNG's image at the\n * stage the list belongs to. Written from the Adobe DNG Specification, chapter \"Opcode List Processing\" (opcodes added in 1.3.0.0).\n * The 1.7.1.0 PDF could not be retrieved while this was written (HTTP 403); the parameter layouts and the details marked\n * \"(SDK)\" were checked against the DNG SDK 1.7.1 source (dng_misc_opcodes, dng_gain_map, dng_lens_correction, dng_bad_pixels) and\n * must be checked against the PDF (#600).\n *\n * A list is big-endian whatever the file's byte order: a LONG count, then per opcode a LONG id, the four-byte DNG version that\n * introduced it, LONG flags (bit 0 optional, bit 1 may be skipped for previews) and the LONG byte count of its parameters.\n *\n * Stage images hold normalized values: stage 1 is the stored raw codes / 65535; stage 2 is the linearized image (ActiveArea,\n * black-subtracted, divided by white − black, clipped to 0..1); stage 3 the demosaiced one (the same as stage 2 for LinearRaw). Pixel\n * (row, column) sits at integer coordinates; a relative position u maps to the pixel coordinate u·width (SDK: Lerp over the bounds).\n *\n * Applied: WarpRectilinear (1), FixVignetteRadial (3), FixBadPixelsConstant (4), FixBadPixelsList (5), MapTable (7),\n * MapPolynomial (8), GainMap (9), DeltaPerRow (10), DeltaPerColumn (11), ScalePerRow (12), ScalePerColumn (13). Others (WarpFisheye 2,\n * TrimBounds 6, WarpRectilinear2 14 and unknown ids) are reported in the assumptions, never applied and never a failure.\n */\n\nimport { InvalidConfigurationError } from \"../core/configuration-error.js\";\n\n/** The rectangle, plane range and pitch an area-based opcode acts on (stage pixel coordinates, bottom and right exclusive). */\nexport interface DngOpcodeArea { top: number; left: number; bottom: number; right: number; plane: number; planes: number; rowPitch: number; colPitch: number }\n/** Opcode parameters, by opcode. */\nexport type DngOpcodeParameters =\n | { opcode: \"WarpRectilinear\"; planes: { radial: [number, number, number, number]; tangential: [number, number] }[]; centerX: number; centerY: number }\n | { opcode: \"FixVignetteRadial\"; coefficients: [number, number, number, number, number]; centerX: number; centerY: number }\n | { opcode: \"FixBadPixelsConstant\"; constant: number; bayerPhase: number }\n | { opcode: \"FixBadPixelsList\"; bayerPhase: number; points: [number, number][]; rects: [number, number, number, number][] }\n | { opcode: \"MapTable\"; area: DngOpcodeArea; table: Uint16Array }\n | { opcode: \"MapPolynomial\"; area: DngOpcodeArea; coefficients: number[] }\n | { opcode: \"GainMap\"; area: DngOpcodeArea; pointsV: number; pointsH: number; spacingV: number; spacingH: number; originV: number; originH: number; mapPlanes: number; gains: Float32Array }\n | { opcode: \"DeltaPerRow\" | \"DeltaPerColumn\" | \"ScalePerRow\" | \"ScalePerColumn\"; area: DngOpcodeArea; values: Float32Array };\nexport interface DngOpcode {\n id: number;\n /** The specification's name, or \"Unknown\". */\n name: string;\n dngVersion: [number, number, number, number];\n /** Flag bit 0: a reader may skip it. */\n optional: boolean;\n /** Flag bit 1: may be skipped for preview-quality rendering. */\n previewSkip: boolean;\n /** Decoded parameters of an applied opcode; null for one this reader does not apply. */\n parameters: DngOpcodeParameters | null;\n}\n/** A stage image: interleaved (row, column, plane), normalized values. */\nexport interface DngStageImage { width: number; height: number; planes: number; data: Float32Array }\n/** Options of {@link applyDngOpcodes}. */\nexport interface ApplyDngOpcodesOptions {\n /** 1, 2 or 3: the list's stage (for the report). */\n stage: 1 | 2 | 3;\n /**\n * WarpRectilinear resampling: false (full quality) uses cubic convolution (Keys, a = −0.75, the DNG SDK's kernel); true uses\n * bilinear interpolation (fast). Registered as \"dngImport.warpRectilinear\" in SIMULATE_CAPTURE_FAST_METHODS.\n */\n fast: boolean;\n /** 1, or 0.5 for a half-size image: pixel-coordinate parameters are scaled; pitched areas and bad pixels are then not applied. */\n scale?: 1 | 0.5;\n}\n\nconst NAMES = [\"Unknown\", \"WarpRectilinear\", \"WarpFisheye\", \"FixVignetteRadial\", \"FixBadPixelsConstant\", \"FixBadPixelsList\", \"TrimBounds\", \"MapTable\",\n \"MapPolynomial\", \"GainMap\", \"DeltaPerRow\", \"DeltaPerColumn\", \"ScalePerRow\", \"ScalePerColumn\", \"WarpRectilinear2\"] as const;\nfunction fail(message: string): never { throw new InvalidConfigurationError(\"DNG opcodes: \" + message); }\n\n/** Parses an opcode list (the tag's bytes). Every count and length is checked against the bytes before allocation. */\nexport function parseDngOpcodeList(bytes: Uint8Array): DngOpcode[] {\n if (!(bytes instanceof Uint8Array)) fail(\"the list must be a Uint8Array.\");\n const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength), n = bytes.length;\n if (n < 4) fail(\"the list is too short.\");\n const count = view.getUint32(0);\n if (count > 4096 || count * 16 > n - 4) fail(\"the opcode count exceeds the list.\");\n const out: DngOpcode[] = [];\n let p = 4;\n for (let k = 0; k < count; k++) {\n if (p + 16 > n) fail(\"an opcode header exceeds the list.\");\n const id = view.getUint32(p), flags = view.getUint32(p + 8), length = view.getUint32(p + 12), start = p + 16;\n if (length > n - start) fail(\"opcode parameters exceed the list.\");\n const name = id < NAMES.length ? NAMES[id]! : \"Unknown\";\n out.push({ id, name, dngVersion: [bytes[p + 4]!, bytes[p + 5]!, bytes[p + 6]!, bytes[p + 7]!], optional: (flags & 1) === 1, previewSkip: (flags & 2) === 2,\n parameters: parseParameters(id, new DataView(bytes.buffer, bytes.byteOffset + start, length)) });\n p = start + length;\n }\n return out;\n}\n\nfunction parseParameters(id: number, v: DataView): DngOpcodeParameters | null {\n const size = v.byteLength;\n const need = (bytes: number): void => { if (bytes !== size) fail(\"opcode \" + id + \" has \" + size + \" parameter bytes, expected \" + bytes + \".\"); };\n const finite = (x: number): number => { if (!Number.isFinite(x)) fail(\"non-finite opcode parameter.\"); return x; };\n const area = (): DngOpcodeArea => {\n if (size < 32) fail(\"area opcode parameters are too short.\");\n const [top, left, bottom, right, plane, planes, rowPitch, colPitch] = [0, 4, 8, 12, 16, 20, 24, 28].map((o) => v.getUint32(o)) as [number, number, number, number, number, number, number, number];\n if (bottom < top || right < left || planes < 1 || rowPitch < 1 || colPitch < 1) fail(\"invalid opcode area.\");\n return { top, left, bottom, right, plane, planes, rowPitch, colPitch };\n };\n switch (id) {\n case 1: {\n if (size < 4) fail(\"WarpRectilinear parameters are too short.\");\n const planes = v.getUint32(0);\n if (planes < 1 || planes > 4) fail(\"WarpRectilinear needs 1 to 4 planes.\");\n need(4 + planes * 48 + 16);\n const list = Array.from({ length: planes }, (_, i) => {\n const at = 4 + i * 48, d = (j: number): number => finite(v.getFloat64(at + j * 8));\n return { radial: [d(0), d(1), d(2), d(3)] as [number, number, number, number], tangential: [d(4), d(5)] as [number, number] };\n });\n const centerX = finite(v.getFloat64(4 + planes * 48)), centerY = finite(v.getFloat64(12 + planes * 48));\n if (!(centerX >= 0 && centerX <= 1 && centerY >= 0 && centerY <= 1)) fail(\"WarpRectilinear's centre must be within the image.\");\n return { opcode: \"WarpRectilinear\", planes: list, centerX, centerY };\n }\n case 3: {\n need(56);\n const d = (j: number): number => finite(v.getFloat64(j * 8));\n const centerX = d(5), centerY = d(6);\n if (!(centerX >= 0 && centerX <= 1 && centerY >= 0 && centerY <= 1)) fail(\"FixVignetteRadial's centre must be within the image.\");\n return { opcode: \"FixVignetteRadial\", coefficients: [d(0), d(1), d(2), d(3), d(4)], centerX, centerY };\n }\n case 4: {\n need(8);\n const bayerPhase = v.getUint32(4);\n if (bayerPhase > 3) fail(\"BayerPhase must be 0 to 3.\");\n return { opcode: \"FixBadPixelsConstant\", constant: v.getUint32(0), bayerPhase };\n }\n case 5: {\n if (size < 12) fail(\"FixBadPixelsList parameters are too short.\");\n const bayerPhase = v.getUint32(0), pointCount = v.getUint32(4), rectCount = v.getUint32(8);\n if (bayerPhase > 3) fail(\"BayerPhase must be 0 to 3.\");\n if (pointCount > (size - 12) / 8 || rectCount > (size - 12) / 16) fail(\"bad-pixel counts exceed the parameters.\");\n need(12 + pointCount * 8 + rectCount * 16);\n const points = Array.from({ length: pointCount }, (_, i): [number, number] => [v.getUint32(12 + i * 8), v.getUint32(16 + i * 8)]);\n const base = 12 + pointCount * 8;\n const rects = Array.from({ length: rectCount }, (_, i): [number, number, number, number] => [0, 4, 8, 12].map((o) => v.getUint32(base + i * 16 + o)) as [number, number, number, number]);\n return { opcode: \"FixBadPixelsList\", bayerPhase, points, rects };\n }\n case 7: {\n const a = area();\n if (size < 36) fail(\"MapTable parameters are too short.\");\n const n = v.getUint32(32);\n if (n < 1 || n > 65536) fail(\"MapTable size must be 1 to 65536.\");\n need(36 + n * 2);\n const table = new Uint16Array(n);\n for (let i = 0; i < n; i++) table[i] = v.getUint16(36 + i * 2);\n return { opcode: \"MapTable\", area: a, table };\n }\n case 8: {\n const a = area();\n if (size < 36) fail(\"MapPolynomial parameters are too short.\");\n const degree = v.getUint32(32);\n if (degree > 8) fail(\"MapPolynomial degree must be at most 8.\");\n need(36 + (degree + 1) * 8);\n return { opcode: \"MapPolynomial\", area: a, coefficients: Array.from({ length: degree + 1 }, (_, i) => finite(v.getFloat64(36 + i * 8))) };\n }\n case 9: {\n const a = area();\n if (size < 76) fail(\"GainMap parameters are too short.\");\n const pointsV = v.getUint32(32), pointsH = v.getUint32(36), spacingV = finite(v.getFloat64(40)), spacingH = finite(v.getFloat64(48));\n const originV = finite(v.getFloat64(56)), originH = finite(v.getFloat64(64)), mapPlanes = v.getUint32(72);\n if (pointsV < 1 || pointsH < 1 || mapPlanes < 1 || pointsV * pointsH * mapPlanes > (size - 76) / 4 || !(spacingV > 0 && spacingH > 0)) fail(\"invalid GainMap.\");\n need(76 + pointsV * pointsH * mapPlanes * 4);\n const gains = new Float32Array(pointsV * pointsH * mapPlanes);\n for (let i = 0; i < gains.length; i++) gains[i] = finite(v.getFloat32(76 + i * 4));\n return { opcode: \"GainMap\", area: a, pointsV, pointsH, spacingV, spacingH, originV, originH, mapPlanes, gains };\n }\n case 10: case 11: case 12: case 13: {\n const a = area();\n if (size < 36) fail(\"per-row or per-column opcode parameters are too short.\");\n const n = v.getUint32(32);\n if (n > (size - 36) / 4) fail(\"per-row or per-column count exceeds the parameters.\");\n need(36 + n * 4);\n const values = new Float32Array(n);\n for (let i = 0; i < n; i++) values[i] = finite(v.getFloat32(36 + i * 4));\n return { opcode: ([\"DeltaPerRow\", \"DeltaPerColumn\", \"ScalePerRow\", \"ScalePerColumn\"] as const)[id - 10]!, area: a, values };\n }\n default: return null;\n }\n}\n\n/** Keys's cubic convolution kernel with a = −0.75 (the DNG SDK's `dng_resample_bicubic`). */\nfunction cubic(x: number): number {\n const a = -0.75; x = Math.abs(x);\n return x >= 2 ? 0 : x >= 1 ? ((a * x - 5 * a) * x + 8 * a) * x - 4 * a : ((a + 2) * x - (a + 3)) * x * x + 1;\n}\n\n/**\n * Applies an opcode list to a stage image in place (WarpRectilinear returns a new buffer in `image.data`). Returns one assumption\n * per opcode: what was applied, or why it was not.\n */\nexport function applyDngOpcodes(image: DngStageImage, opcodes: readonly DngOpcode[], options: ApplyDngOpcodesOptions): string[] {\n if (image === null || typeof image !== \"object\" || !Number.isSafeInteger(image.width) || !Number.isSafeInteger(image.height) || !Number.isSafeInteger(image.planes))\n fail(\"applyDngOpcodes takes a stage image { width, height, planes, data }.\");\n if (!Array.isArray(opcodes)) fail(\"applyDngOpcodes takes a parsed opcode list (parseDngOpcodeList).\");\n if (options === null || typeof options !== \"object\") fail(\"applyDngOpcodes takes options with the list's stage.\");\n const { width, height, planes } = image, scale = options.scale ?? 1, notes: string[] = [];\n if (!(image.data instanceof Float32Array) || image.data.length !== width * height * planes) fail(\"the stage image's data does not match its size.\");\n const label = (op: DngOpcode): string => \"OpcodeList\" + options.stage + \" \" + op.name + \" (\" + op.id + \")\";\n for (const op of opcodes) {\n const p = op.parameters;\n if (!p) { notes.push(label(op) + \" not applied: not supported\" + (op.optional ? \" (optional).\" : \" (marked required by the file).\")); continue; }\n if (scale !== 1 && (p.opcode === \"FixBadPixelsConstant\" || p.opcode === \"FixBadPixelsList\")) { notes.push(label(op) + \" not applied: a half-size image has no single raw pixels.\"); continue; }\n if ((p.opcode === \"FixBadPixelsConstant\" || p.opcode === \"FixBadPixelsList\") && planes !== 1) { notes.push(label(op) + \" not applied: bad-pixel opcodes act on single-plane CFA data.\"); continue; }\n if (\"area\" in p && scale !== 1 && (p.area.rowPitch > 1 || p.area.colPitch > 1)) { notes.push(label(op) + \" not applied: a pitched area cannot be scaled to a half-size image.\"); continue; }\n switch (p.opcode) {\n case \"MapTable\": case \"MapPolynomial\": case \"DeltaPerRow\": case \"DeltaPerColumn\": case \"ScalePerRow\": case \"ScalePerColumn\": case \"GainMap\":\n applyArea(image, p, scale); break;\n case \"FixVignetteRadial\": applyVignette(image, p); break;\n case \"WarpRectilinear\":\n if (p.planes.length !== 1 && p.planes.length !== planes) { notes.push(label(op) + \" not applied: its plane count does not match the image.\"); continue; }\n image.data = warp(image, p, options.fast); break;\n case \"FixBadPixelsConstant\": case \"FixBadPixelsList\": fixBadPixels(image, p); break;\n }\n notes.push(label(op) + \" applied\" + (p.opcode === \"WarpRectilinear\" ? (options.fast ? \" (bilinear resampling, fast).\" : \" (cubic convolution, a = −0.75).\") : \".\"));\n }\n return notes;\n}\n\ntype AreaParameters = Extract<DngOpcodeParameters, { area: DngOpcodeArea }>;\nfunction applyArea(image: DngStageImage, p: AreaParameters, scale: number): void {\n const { width, height, planes, data } = image, a = p.area;\n const top = Math.floor(a.top * scale), left = Math.floor(a.left * scale), bottom = Math.min(height, Math.ceil(a.bottom * scale)), right = Math.min(width, Math.ceil(a.right * scale));\n const lastPlane = Math.min(planes, a.plane + a.planes);\n const clip = (x: number): number => x < 0 ? 0 : x > 1 ? 1 : x;\n for (let plane = a.plane; plane < lastPlane; plane++) for (let row = top, ri = 0; row < bottom; row += a.rowPitch, ri++) {\n for (let col = left, ci = 0; col < right; col += a.colPitch, ci++) {\n const i = (row * width + col) * planes + plane, x = data[i]!;\n switch (p.opcode) {\n case \"MapTable\": { const t = p.table, index = Math.round(clip(x) * 65535); data[i] = t[Math.min(index, t.length - 1)]! / 65535; break; }\n case \"MapPolynomial\": { let y = 0; for (let k = p.coefficients.length - 1; k >= 0; k--) y = y * clip(x) + p.coefficients[k]!; data[i] = clip(y); break; }\n // SDK: the per-row/column tables have one entry per pitched row or column; an index beyond the table leaves the value.\n case \"DeltaPerRow\": if (ri < p.values.length) data[i] = clip(x + p.values[ri]!); break;\n case \"DeltaPerColumn\": if (ci < p.values.length) data[i] = clip(x + p.values[ci]!); break;\n case \"ScalePerRow\": if (ri < p.values.length) data[i] = clip(x * p.values[ri]!); break;\n case \"ScalePerColumn\": if (ci < p.values.length) data[i] = clip(x * p.values[ci]!); break;\n case \"GainMap\": data[i] = Math.min(Math.max(x, 0) * gainAt(p, (row + 0.5) / height, (col + 0.5) / width, Math.min(plane, p.mapPlanes - 1)), 1); break;\n }\n }\n }\n}\n\n/**\n * The GainMap gain at a relative position (pixel centre over the image), bilinear between map points, held at the edges (SDK\n * `dng_gain_map_interpolator`). Map point (i, j) is at relative position origin + spacing·(i, j).\n */\nfunction gainAt(p: Extract<DngOpcodeParameters, { opcode: \"GainMap\" }>, v: number, h: number, plane: number): number {\n const axis = (rel: number, origin: number, spacing: number, points: number): [number, number, number] => {\n const f = (rel - origin) / spacing;\n if (!(f > 0)) return [0, 0, 0];\n if (f >= points - 1) return [points - 1, points - 1, 0];\n const i = Math.floor(f);\n return [i, i + 1, f - i];\n };\n const [r0, r1, fr] = axis(v, p.originV, p.spacingV, p.pointsV), [c0, c1, fc] = axis(h, p.originH, p.spacingH, p.pointsH);\n const g = (r: number, c: number): number => p.gains[(r * p.pointsH + c) * p.mapPlanes + plane]!;\n const top = g(r0, c0) + (g(r0, c1) - g(r0, c0)) * fc, bottom = g(r1, c0) + (g(r1, c1) - g(r1, c0)) * fc;\n return top + (bottom - top) * fr;\n}\n\n/** Centre in pixel coordinates and the normalization radius: the largest distance from the centre to an image corner (SDK). */\nfunction geometry(image: DngStageImage, centerX: number, centerY: number): { cx: number; cy: number; radius: number } {\n const cx = centerX * image.width, cy = centerY * image.height;\n return { cx, cy, radius: Math.max(Math.hypot(cx, cy), Math.hypot(image.width - cx, cy), Math.hypot(cx, image.height - cy), Math.hypot(image.width - cx, image.height - cy)) };\n}\n\nfunction applyVignette(image: DngStageImage, p: Extract<DngOpcodeParameters, { opcode: \"FixVignetteRadial\" }>): void {\n const { width, height, planes, data } = image, { cx, cy, radius } = geometry(image, p.centerX, p.centerY), k = p.coefficients;\n for (let row = 0; row < height; row++) for (let col = 0; col < width; col++) {\n const r2 = ((col - cx) ** 2 + (row - cy) ** 2) / (radius * radius);\n const gain = 1 + r2 * (k[0] + r2 * (k[1] + r2 * (k[2] + r2 * (k[3] + r2 * k[4]))));\n for (let c = 0; c < planes; c++) { const i = (row * width + col) * planes + c; data[i] = Math.min(Math.max(data[i]! * gain, 0), 1); }\n }\n}\n\n/**\n * WarpRectilinear: for destination pixel (x, y), normalized offsets dx = (x − cx)/m, dy = (y − cy)/m, r² = dx² + dy²; the source\n * is the centre plus m·[(dx, dy)·(kr0 + kr1r² + kr2r⁴ + kr3r⁶) + (kt1(r² + 2dx²) + 2kt0·dx·dy, kt0(r² + 2dy²) + 2kt1·dx·dy)],\n * held within the image (SDK `dng_filter_warp`, `EvaluateTangential`). One parameter set applies to every plane, or one per plane.\n */\nfunction warp(image: DngStageImage, p: Extract<DngOpcodeParameters, { opcode: \"WarpRectilinear\" }>, fast: boolean): Float32Array {\n const { width, height, planes, data } = image, { cx, cy, radius } = geometry(image, p.centerX, p.centerY), out = new Float32Array(data.length);\n const sample = (plane: number, x: number, y: number): number => data[(Math.min(Math.max(y, 0), height - 1) * width + Math.min(Math.max(x, 0), width - 1)) * planes + plane]!;\n for (let plane = 0; plane < planes; plane++) {\n const { radial: [k0, k1, k2, k3], tangential: [t0, t1] } = p.planes[p.planes.length === 1 ? 0 : plane]!;\n for (let y = 0; y < height; y++) for (let x = 0; x < width; x++) {\n const dx = (x - cx) / radius, dy = (y - cy) / radius, r2 = dx * dx + dy * dy, ratio = k0 + r2 * (k1 + r2 * (k2 + r2 * k3));\n const sx = Math.min(Math.max(cx + radius * (dx * ratio + t1 * (r2 + 2 * dx * dx) + 2 * t0 * dx * dy), 0), width - 1);\n const sy = Math.min(Math.max(cy + radius * (dy * ratio + t0 * (r2 + 2 * dy * dy) + 2 * t1 * dx * dy), 0), height - 1);\n const ix = Math.floor(sx), iy = Math.floor(sy), fx = sx - ix, fy = sy - iy;\n let value = 0;\n if (fast) value = (sample(plane, ix, iy) * (1 - fx) + sample(plane, ix + 1, iy) * fx) * (1 - fy) + (sample(plane, ix, iy + 1) * (1 - fx) + sample(plane, ix + 1, iy + 1) * fx) * fy;\n else for (let j = -1; j <= 2; j++) { const wy = cubic(j - fy); for (let i = -1; i <= 2; i++) value += wy * cubic(i - fx) * sample(plane, ix + i, iy + j); }\n out[(y * width + x) * planes + plane] = Math.min(Math.max(value, 0), 1);\n }\n }\n return out;\n}\n\n/**\n * Bad pixels of a Bayer image (BayerPhase 0 RGGB, 1 GRBG, 2 GBRG, 3 BGGR; green where row + column + phase + ⌊phase/2⌋ is odd) are\n * replaced by the mean of their nearest good same-colour neighbours: green first the four diagonals, then the four at distance 2,\n * then the four at (±2, ±2); red and blue the four at distance 2, then (±2, ±2) (SDK ring order). A pixel with no good neighbour\n * keeps its value. FixBadPixelsConstant marks pixels whose stored code equals the constant (in stage-1 codes, value·65535).\n */\nfunction fixBadPixels(image: DngStageImage, p: Extract<DngOpcodeParameters, { opcode: \"FixBadPixelsConstant\" | \"FixBadPixelsList\" }>): void {\n const { width, height, data } = image, bad = new Uint8Array(width * height);\n if (p.opcode === \"FixBadPixelsConstant\") { for (let i = 0; i < bad.length; i++) if (Math.round(data[i]! * 65535) === p.constant) bad[i] = 1; }\n else {\n for (const [r, c] of p.points) if (r < height && c < width) bad[r * width + c] = 1;\n for (const [t, l, b, r] of p.rects) for (let y = t; y < Math.min(b, height); y++) for (let x = l; x < Math.min(r, width); x++) bad[y * width + x] = 1;\n }\n const rings = [[[-1, 1], [-1, -1], [1, -1], [1, 1]], [[-2, 0], [2, 0], [0, -2], [0, 2]], [[-2, -2], [-2, 2], [2, -2], [2, 2]]] as const;\n const source = data.slice();\n for (let y = 0; y < height; y++) for (let x = 0; x < width; x++) {\n if (!bad[y * width + x]) continue;\n const green = ((y + x + p.bayerPhase + (p.bayerPhase >> 1)) & 1) === 1;\n for (const ring of green ? rings : rings.slice(1)) {\n let total = 0, count = 0;\n for (const [dy, dx] of ring) {\n const yy = y + dy, xx = x + dx;\n if (yy >= 0 && yy < height && xx >= 0 && xx < width && !bad[yy * width + xx]) { total += source[yy * width + xx]!; count++; }\n }\n if (count) { data[y * width + x] = total / count; break; }\n }\n }\n}\n"]}
@@ -0,0 +1,99 @@
1
+ /** A parsed ProfileGainTableMap(2): N gains at each of V × H map points, decoded to 32-bit floats. */
2
+ export interface DngProfileGainTableMap {
3
+ /** 1 for ProfileGainTableMap (52525), 2 for ProfileGainTableMap2 (52544). */
4
+ version: 1 | 2;
5
+ pointsV: number;
6
+ pointsH: number;
7
+ spacingV: number;
8
+ spacingH: number;
9
+ originV: number;
10
+ originH: number;
11
+ /** MapPointsN: the table length at each map point. */
12
+ tablePoints: number;
13
+ /** MapInputWeights for red, green, blue, min(R,G,B) and max(R,G,B). */
14
+ inputWeights: [number, number, number, number, number];
15
+ /** PGTM2: the weight's gamma (1 for version 1). */
16
+ gamma: number;
17
+ /** Gains, row-major (v, h, table point). */
18
+ gains: Float32Array;
19
+ }
20
+ /** One table of RGBTables: a 3D table of `divisions`³ RGB samples (16-bit, 65535 = 1). */
21
+ export interface DngRgbTable {
22
+ /** TableSemanticName: the semantic mask it applies within; "" for the background table (the whole image). */
23
+ semanticName: string;
24
+ divisions: number;
25
+ gamma: "linear" | "srgb" | "1.8" | "2.2" | "rec2020";
26
+ primaries: "srgb" | "adobe-rgb" | "display-p3" | "rec2020" | "prophoto";
27
+ gamut: "clip" | "extend";
28
+ /** RGB per node, red slowest then green then blue, length divisions³ × 3. */
29
+ samples: Uint16Array;
30
+ }
31
+ export interface DngRgbTables {
32
+ compositeMethod: "weighted-sum" | "sequential";
33
+ tables: DngRgbTable[];
34
+ }
35
+ /** An RGB image, interleaved (row, column, channel). */
36
+ export interface DngRgbImage {
37
+ width: number;
38
+ height: number;
39
+ data: Float32Array;
40
+ }
41
+ /**
42
+ * Parses ProfileGainTableMap (version 1) or ProfileGainTableMap2 (version 2). Layout: MapPointsV, MapPointsH (LONG), MapSpacingV,
43
+ * MapSpacingH, MapOriginV, MapOriginH (DOUBLE), MapPointsN (LONG), MapInputWeights (5 FLOAT); version 2 adds DataType (LONG: 0 uint8,
44
+ * 1 uint16, 2 float16, 3 float32), Gamma, GainMin, GainMax (FLOAT); then the gains. Integer gains are GainMin + (x/max)·(GainMax −
45
+ * GainMin). A single map point on an axis has spacing 1 and origin 0 (SDK).
46
+ */
47
+ export declare function parseDngProfileGainTableMap(bytes: Uint8Array, littleEndian: boolean, version: 1 | 2): DngProfileGainTableMap;
48
+ /**
49
+ * Parses RGBTables (52543): table count (LONG, at most 20; 0 means none), CompositeMethod (LONG: 0 weighted sum, 1 sequential), then
50
+ * per table LengthTableSemanticName (SHORT), the name's bytes, Divisions, PixelType (0 uint8, 1 uint16, 2 float32), GammaEncoding
51
+ * (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
52
+ * GamutExtension (0 clip, 1 extend), each a BYTE, then Divisions³ RGB samples (uint8 scaled by 256, float scaled by 65535).
53
+ */
54
+ export declare function parseDngRgbTables(bytes: Uint8Array, littleEndian: boolean): DngRgbTables | null;
55
+ /** Options of {@link applyDngProfileGainTableMap}. */
56
+ export interface ApplyDngProfileGainTableMapInput {
57
+ /** Linear ProPhoto (RIMM, D50) RGB, white-balanced, 1 = clipping white; changed in place. */
58
+ image: DngRgbImage;
59
+ map: DngProfileGainTableMap;
60
+ /** BaselineExposure (stops) not yet applied to `image`: the weight is scaled by 2^stops, as the SDK does. Default 0. */
61
+ baselineExposureStops?: number;
62
+ /** Where `image` sits in the stage-3 (ActiveArea) image the map spans. Default: `image` is the whole stage-3 image. */
63
+ region?: {
64
+ x: number;
65
+ y: number;
66
+ stageWidth: number;
67
+ stageHeight: number;
68
+ };
69
+ /** Keep values above 1 (true) or clip to 0..1 (false, the SDR default). */
70
+ overrange?: boolean;
71
+ }
72
+ /**
73
+ * Applies ProfileGainTableMap(2): at each pixel the weight t = clamp(w·(R, G, B, min, max)·2^BaselineExposure, 0, 1)^γ selects a
74
+ * 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
75
+ * relative position (held at the map's edges); R, G and B are multiplied by it.
76
+ */
77
+ export declare function applyDngProfileGainTableMap(input: ApplyDngProfileGainTableMapInput): void;
78
+ /** Options of {@link applyDngRgbTables}. */
79
+ export interface ApplyDngRgbTablesInput {
80
+ /** ProPhoto-primaries RGB after the tone curve, 0..1; changed in place. */
81
+ image: DngRgbImage;
82
+ tables: DngRgbTables;
83
+ /** Semantic masks by name (values 0..1, any size; stretched over the image with bilinear interpolation). */
84
+ masks?: readonly {
85
+ name: string;
86
+ width: number;
87
+ height: number;
88
+ data: Float32Array;
89
+ }[];
90
+ }
91
+ /**
92
+ * Applies RGBTables: each table maps ProPhoto RGB into its own primaries (clipped to 0..1, the clipped-off part kept and added back
93
+ * when GamutExtension is "extend"), encodes it with the table's gamma, interpolates tetrahedrally in the 3D table, decodes and maps
94
+ * back (SDK `RefRGBtoRGBTable3D`). The background table (empty name) applies to the whole image. Weighted sum: each masked table's
95
+ * result weighted by its mask, the background (the background table's result, or the input) by 1 − min(1, Σ masks), normalized.
96
+ * Sequential: each table in file order, blended into the running image by its mask (the background table by 1 − min(1, Σ other masks)).
97
+ * A table whose mask is not supplied is skipped (as the SDK skips a name with no SemanticMask); the returned notes say so.
98
+ */
99
+ export declare function applyDngRgbTables(input: ApplyDngRgbTablesInput): string[];