@photivra/engine 2.9.0 → 2.11.1
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 +223 -1
- package/CITATION.cff +1 -1
- package/NODE_SUPPORT.md +21 -3
- package/README.md +6 -6
- package/SECURITY.md +1 -1
- package/THIRD_PARTY.md +2 -0
- package/dist/capture/native-environment-lean.js +89 -5
- package/dist/capture/native-environment-lean.js.map +1 -1
- package/dist/capture/native-environment-tabulated.d.ts +37 -0
- package/dist/capture/native-environment-tabulated.js +42 -6
- package/dist/capture/native-environment-tabulated.js.map +1 -1
- package/dist/core/portable-math.d.ts +19 -0
- package/dist/core/portable-math.js +82 -0
- package/dist/core/portable-math.js.map +1 -1
- package/dist/core/version.d.ts +1 -1
- package/dist/core/version.js +1 -1
- package/dist/core/version.js.map +1 -1
- package/dist/facade/channel-response.d.ts +15 -0
- package/dist/facade/channel-response.js +33 -0
- package/dist/facade/channel-response.js.map +1 -0
- package/dist/facade/chart-material-layers.d.ts +115 -0
- package/dist/facade/chart-material-layers.js +224 -0
- package/dist/facade/chart-material-layers.js.map +1 -0
- package/dist/facade/chart-radiance-batch.d.ts +8 -2
- package/dist/facade/chart-radiance-batch.js +11 -4
- package/dist/facade/chart-radiance-batch.js.map +1 -1
- package/dist/facade/chart-scenes.d.ts +134 -0
- package/dist/facade/chart-scenes.js +32 -22
- package/dist/facade/chart-scenes.js.map +1 -1
- package/dist/facade/diffraction-provider.d.ts +8 -2
- package/dist/facade/diffraction-provider.js +120 -16
- package/dist/facade/diffraction-provider.js.map +1 -1
- package/dist/facade/display-view-gpu-session.d.ts +18 -0
- package/dist/facade/display-view-gpu-session.js +280 -0
- package/dist/facade/display-view-gpu-session.js.map +1 -0
- package/dist/facade/display-view-gpu.d.ts +146 -0
- package/dist/facade/display-view-gpu.js +59 -0
- package/dist/facade/display-view-gpu.js.map +1 -0
- package/dist/facade/display-view.d.ts +123 -1
- package/dist/facade/display-view.js +478 -116
- package/dist/facade/display-view.js.map +1 -1
- package/dist/facade/expected-signal-setup.d.ts +5 -0
- package/dist/facade/expected-signal-setup.js +18 -1
- package/dist/facade/expected-signal-setup.js.map +1 -1
- package/dist/facade/expected-signal.d.ts +80 -6
- package/dist/facade/expected-signal.js +200 -24
- package/dist/facade/expected-signal.js.map +1 -1
- package/dist/facade/scene-radiance.d.ts +4 -2
- package/dist/facade/scene-radiance.js +7 -4
- package/dist/facade/scene-radiance.js.map +1 -1
- package/dist/facade/simulate-capture.d.ts +81 -7
- package/dist/facade/simulate-capture.js +276 -53
- package/dist/facade/simulate-capture.js.map +1 -1
- package/dist/facade/simulate-display-view.d.ts +54 -3
- package/dist/facade/simulate-display-view.js +120 -27
- package/dist/facade/simulate-display-view.js.map +1 -1
- package/dist/gpu/chart-composite-gpu.d.ts +119 -0
- package/dist/gpu/chart-composite-gpu.js +572 -0
- package/dist/gpu/chart-composite-gpu.js.map +1 -0
- package/dist/gpu/chart-radiance-gpu.d.ts +6 -6
- package/dist/gpu/chart-radiance-gpu.js +9 -11
- package/dist/gpu/chart-radiance-gpu.js.map +1 -1
- package/dist/gpu/display-view-chart-material-module.d.ts +10 -0
- package/dist/gpu/display-view-chart-material-module.js +58 -0
- package/dist/gpu/display-view-chart-material-module.js.map +1 -0
- package/dist/gpu/display-view-composite-material-module.d.ts +68 -0
- package/dist/gpu/display-view-composite-material-module.js +248 -0
- package/dist/gpu/display-view-composite-material-module.js.map +1 -0
- package/dist/gpu/display-view-quality-gpu.d.ts +185 -0
- package/dist/gpu/display-view-quality-gpu.js +1000 -0
- package/dist/gpu/display-view-quality-gpu.js.map +1 -0
- package/dist/gpu/display-view-speed-gpu.d.ts +156 -0
- package/dist/gpu/display-view-speed-gpu.js +524 -0
- package/dist/gpu/display-view-speed-gpu.js.map +1 -0
- package/dist/gpu/image-kernel-accelerator.d.ts +23 -4
- package/dist/gpu/image-kernel-accelerator.js +58 -10
- package/dist/gpu/image-kernel-accelerator.js.map +1 -1
- package/dist/gpu/image-kernel-execution.d.ts +60 -3
- package/dist/gpu/image-kernel-execution.js +2 -2
- package/dist/gpu/image-kernel-execution.js.map +1 -1
- package/dist/gpu/sensor-stage-gpu.d.ts +11 -0
- package/dist/gpu/sensor-stage-gpu.js +42 -13
- package/dist/gpu/sensor-stage-gpu.js.map +1 -1
- package/dist/gpu/webgpu-runtime.d.ts +4 -2
- package/dist/gpu/webgpu-runtime.js +13 -4
- package/dist/gpu/webgpu-runtime.js.map +1 -1
- package/dist/gpu/webgpu-switch.d.ts +4 -0
- package/dist/gpu/webgpu-switch.js +29 -0
- package/dist/gpu/webgpu-switch.js.map +1 -0
- package/dist/gpu/wgsl-chart-composite-kernel.d.ts +52 -0
- package/dist/gpu/wgsl-chart-composite-kernel.js +515 -0
- package/dist/gpu/wgsl-chart-composite-kernel.js.map +1 -0
- package/dist/gpu/wgsl-chart-kernel.d.ts +11 -9
- package/dist/gpu/wgsl-chart-kernel.js +33 -27
- package/dist/gpu/wgsl-chart-kernel.js.map +1 -1
- package/dist/gpu/wgsl-display-view-quality-kernel.d.ts +95 -0
- package/dist/gpu/wgsl-display-view-quality-kernel.js +769 -0
- package/dist/gpu/wgsl-display-view-quality-kernel.js.map +1 -0
- package/dist/gpu/wgsl-display-view-speed-kernel.d.ts +75 -0
- package/dist/gpu/wgsl-display-view-speed-kernel.js +386 -0
- package/dist/gpu/wgsl-display-view-speed-kernel.js.map +1 -0
- package/dist/gpu/wgsl-sensor-kernel.d.ts +28 -9
- package/dist/gpu/wgsl-sensor-kernel.js +94 -50
- package/dist/gpu/wgsl-sensor-kernel.js.map +1 -1
- package/dist/index.d.ts +6 -3
- package/dist/index.js +4 -2
- package/dist/index.js.map +1 -1
- package/dist/optics/defocus-disc-kernel.d.ts +61 -0
- package/dist/optics/defocus-disc-kernel.js +191 -0
- package/dist/optics/defocus-disc-kernel.js.map +1 -0
- package/dist/optics/irradiance-convolution.d.ts +11 -0
- package/dist/optics/irradiance-convolution.js +64 -24
- package/dist/optics/irradiance-convolution.js.map +1 -1
- package/dist/optics/scene-to-sensor-irradiance.d.ts +13 -0
- package/dist/optics/scene-to-sensor-irradiance.js +58 -24
- package/dist/optics/scene-to-sensor-irradiance.js.map +1 -1
- package/dist/optics/sensor-aperture-rays.js +2 -1
- package/dist/optics/sensor-aperture-rays.js.map +1 -1
- package/dist/optics/sensor-environment-query.js +4 -3
- package/dist/optics/sensor-environment-query.js.map +1 -1
- package/dist/optics/site-diffraction-kernel.d.ts +16 -0
- package/dist/optics/site-diffraction-kernel.js +60 -8
- package/dist/optics/site-diffraction-kernel.js.map +1 -1
- package/dist/processing/demosaic.js +114 -37
- package/dist/processing/demosaic.js.map +1 -1
- package/dist/schema/scene-radiance.d.ts +8 -0
- package/dist/schema/scene-radiance.js +28 -17
- package/dist/schema/scene-radiance.js.map +1 -1
- package/dist/sensor/environment-photo-signal.d.ts +21 -0
- package/dist/sensor/environment-photo-signal.js +68 -2
- package/dist/sensor/environment-photo-signal.js.map +1 -1
- package/docs/API_REFERENCE.md +60 -1
- package/docs/QUICK_START.md +120 -11
- package/docs/USAGE.md +82 -2
- package/docs/api/core-version.md +1 -1
- package/docs/api/exports.json +157 -2
- package/docs/api/facade-chart-material-layers.md +137 -0
- package/docs/api/facade-chart-radiance-batch.md +7 -2
- package/docs/api/facade-display-view-gpu.md +94 -0
- package/docs/api/facade-display-view.md +50 -0
- package/docs/api/facade-scene-radiance.md +3 -2
- package/docs/api/facade-simulate-capture.md +81 -12
- package/docs/api/facade-simulate-display-view.md +39 -2
- package/docs/api/gpu-image-kernel-accelerator.md +10 -3
- package/docs/api/gpu-image-kernel-execution.md +76 -4
- package/docs/api/gpu-webgpu-switch.md +23 -0
- package/package.json +3 -1
|
@@ -4,19 +4,62 @@
|
|
|
4
4
|
* convolution (facade/diffraction-provider.ts) and the tabulated expected signal (facade/expected-signal-setup.ts) use it.
|
|
5
5
|
*
|
|
6
6
|
* `resolveLensPsfConvolutionKernels` parses and samples the PSF profile on every call (about 10 ms per wavelength), and both users
|
|
7
|
-
* ask for the same kernels
|
|
8
|
-
*
|
|
7
|
+
* ask for the same kernels. The kernel is a function of its inputs alone; each caller gets its own copy.
|
|
8
|
+
*
|
|
9
|
+
* The facade builds a new PSF record for every request, so kernels are kept by value: `registerDiffractionPsfKey` records, for a
|
|
10
|
+
* record whose profile `createDiffractionLimitedPsfProfile` built, a canonical string of that call's whole input and of the record's
|
|
11
|
+
* own fields (everything the kernel is a function of besides the wavelength, pitch and radius of the query). Records with an equal
|
|
12
|
+
* string share their kernels, in a least-recently-used cache of `SITE_DIFFRACTION_KERNEL_CACHE_SIZE` records. A record that was not
|
|
13
|
+
* registered (a caller's own profile) keeps its kernels while it lives, by identity, as before.
|
|
9
14
|
*/
|
|
10
15
|
import { InvalidConfigurationError } from "../core/configuration-error.js";
|
|
11
16
|
import { resolveLensPsfConvolutionKernels } from "./lens-psf-kernels.js";
|
|
12
|
-
/**
|
|
13
|
-
const
|
|
17
|
+
/** PSF records kept by value: at most 20 kernels of (2·32 + 1)² doubles each (676 KB) per record at the default spectral sampling. */
|
|
18
|
+
export const SITE_DIFFRACTION_KERNEL_CACHE_SIZE = 4;
|
|
19
|
+
/** Canonical value key of each registered PSF record. */
|
|
20
|
+
const keys = new WeakMap();
|
|
21
|
+
/** Kernels per registered value key (least recently used first), then per wavelength, pitch and radius. */
|
|
22
|
+
const byValue = new Map();
|
|
23
|
+
/** Kernels per unregistered PSF record (by identity: the record is large, so it is not serialized), then per wavelength, pitch and radius. */
|
|
24
|
+
const byIdentity = new WeakMap();
|
|
25
|
+
/** Kernels resolved so far (test hook). */
|
|
26
|
+
let resolves = 0;
|
|
27
|
+
/** JSON with every number spelled exactly: shortest round-trip digits, and -0, NaN and ±Infinity kept apart from 0 and null. */
|
|
28
|
+
function canonical(value) {
|
|
29
|
+
return JSON.stringify(value, (_key, v) => (typeof v === "number" && (Object.is(v, -0) || !Number.isFinite(v)) ? "number:" + (Object.is(v, -0) ? "-0" : String(v)) : v));
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Records that `psf.profile` is the profile `createDiffractionLimitedPsfProfile(profileInput)` returned, unmodified, so that the
|
|
33
|
+
* kernels of `psf` are those of any record with the same `profileInput` and the same other fields. Call it right after building the
|
|
34
|
+
* record; neither the record nor `profileInput` may change afterwards.
|
|
35
|
+
*/
|
|
36
|
+
export function registerDiffractionPsfKey(psf, profileInput) {
|
|
37
|
+
const fields = Object.entries(psf).filter(([name]) => name !== "profile").sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0));
|
|
38
|
+
keys.set(psf, canonical(["createDiffractionLimitedPsfProfile", profileInput, fields]));
|
|
39
|
+
}
|
|
40
|
+
/** The kernels kept for `psf`, made the most recently used. */
|
|
41
|
+
function kernelsOf(psf) {
|
|
42
|
+
const key = keys.get(psf);
|
|
43
|
+
if (key === undefined) {
|
|
44
|
+
let kernels = byIdentity.get(psf);
|
|
45
|
+
if (!kernels)
|
|
46
|
+
byIdentity.set(psf, (kernels = new Map()));
|
|
47
|
+
return kernels;
|
|
48
|
+
}
|
|
49
|
+
let kernels = byValue.get(key);
|
|
50
|
+
if (kernels)
|
|
51
|
+
byValue.delete(key);
|
|
52
|
+
else
|
|
53
|
+
kernels = new Map();
|
|
54
|
+
byValue.set(key, kernels);
|
|
55
|
+
while (byValue.size > SITE_DIFFRACTION_KERNEL_CACHE_SIZE)
|
|
56
|
+
byValue.delete(byValue.keys().next().value);
|
|
57
|
+
return kernels;
|
|
58
|
+
}
|
|
14
59
|
/** The (2·radius + 1)² kernel of `psf` at `wavelengthNm` on a square site grid of `pitchMicrometers`; `failure` is the error message when the kernel cannot sample the pitch exactly. */
|
|
15
60
|
export function siteDiffractionKernel(psf, wavelengthNm, pitchMicrometers, radius, failure) {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
cache.set(psf, (kernels = new Map()));
|
|
19
|
-
const key = wavelengthNm + ":" + pitchMicrometers + ":" + radius;
|
|
61
|
+
const kernels = kernelsOf(psf);
|
|
62
|
+
const key = canonical([wavelengthNm, pitchMicrometers, radius]);
|
|
20
63
|
let kernel = kernels.get(key);
|
|
21
64
|
if (!kernel) {
|
|
22
65
|
const k = resolveLensPsfConvolutionKernels({ schemaVersion: "0.1.0", psf, spectralWeights: [{ wavelengthNm, weight: 1 }],
|
|
@@ -25,8 +68,17 @@ export function siteDiffractionKernel(psf, wavelengthNm, pitchMicrometers, radiu
|
|
|
25
68
|
if (!k.exactSiteSampling || k.kernelRadius !== radius)
|
|
26
69
|
throw new InvalidConfigurationError(failure);
|
|
27
70
|
kernel = Float64Array.from(k.kernels);
|
|
71
|
+
resolves++;
|
|
28
72
|
kernels.set(key, kernel);
|
|
29
73
|
}
|
|
30
74
|
return Float64Array.from(kernel);
|
|
31
75
|
}
|
|
76
|
+
/** Test hook: the number of PSF records kept by value, the kernels resolved so far, and whether `psf` is registered. */
|
|
77
|
+
export function siteDiffractionKernelCacheState(psf) {
|
|
78
|
+
return { valueEntries: byValue.size, resolves, registered: psf !== undefined && keys.has(psf) };
|
|
79
|
+
}
|
|
80
|
+
/** Test hook: forgets every kernel kept by value. */
|
|
81
|
+
export function clearSiteDiffractionKernelCache() {
|
|
82
|
+
byValue.clear();
|
|
83
|
+
}
|
|
32
84
|
//# sourceMappingURL=site-diffraction-kernel.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"site-diffraction-kernel.js","sourceRoot":"","sources":["../../src/optics/site-diffraction-kernel.ts"],"names":[],"mappings":"AAAA,sCAAsC;AAEtC
|
|
1
|
+
{"version":3,"file":"site-diffraction-kernel.js","sourceRoot":"","sources":["../../src/optics/site-diffraction-kernel.ts"],"names":[],"mappings":"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","sourcesContent":["// SPDX-License-Identifier: Apache-2.0\n\n/**\n * Internal (not exported from the package): one wavelength's diffraction kernel sampled on the site pitch, as the object-space\n * convolution (facade/diffraction-provider.ts) and the tabulated expected signal (facade/expected-signal-setup.ts) use it.\n *\n * `resolveLensPsfConvolutionKernels` parses and samples the PSF profile on every call (about 10 ms per wavelength), and both users\n * ask for the same kernels. The kernel is a function of its inputs alone; each caller gets its own copy.\n *\n * The facade builds a new PSF record for every request, so kernels are kept by value: `registerDiffractionPsfKey` records, for a\n * record whose profile `createDiffractionLimitedPsfProfile` built, a canonical string of that call's whole input and of the record's\n * own fields (everything the kernel is a function of besides the wavelength, pitch and radius of the query). Records with an equal\n * string share their kernels, in a least-recently-used cache of `SITE_DIFFRACTION_KERNEL_CACHE_SIZE` records. A record that was not\n * registered (a caller's own profile) keeps its kernels while it lives, by identity, as before.\n */\n\nimport { InvalidConfigurationError } from \"../core/configuration-error.js\";\nimport { resolveLensPsfConvolutionKernels } from \"./lens-psf-kernels.js\";\n\ntype Psf = Parameters<typeof resolveLensPsfConvolutionKernels>[0][\"psf\"];\n\n/** PSF records kept by value: at most 20 kernels of (2·32 + 1)² doubles each (676 KB) per record at the default spectral sampling. */\nexport const SITE_DIFFRACTION_KERNEL_CACHE_SIZE = 4;\n\n/** Canonical value key of each registered PSF record. */\nconst keys = new WeakMap<object, string>();\n/** Kernels per registered value key (least recently used first), then per wavelength, pitch and radius. */\nconst byValue = new Map<string, Map<string, Float64Array>>();\n/** Kernels per unregistered PSF record (by identity: the record is large, so it is not serialized), then per wavelength, pitch and radius. */\nconst byIdentity = new WeakMap<object, Map<string, Float64Array>>();\n/** Kernels resolved so far (test hook). */\nlet resolves = 0;\n\n/** JSON with every number spelled exactly: shortest round-trip digits, and -0, NaN and ±Infinity kept apart from 0 and null. */\nfunction canonical(value: unknown): string {\n return JSON.stringify(value, (_key, v: unknown) => (typeof v === \"number\" && (Object.is(v, -0) || !Number.isFinite(v)) ? \"number:\" + (Object.is(v, -0) ? \"-0\" : String(v)) : v));\n}\n\n/**\n * Records that `psf.profile` is the profile `createDiffractionLimitedPsfProfile(profileInput)` returned, unmodified, so that the\n * kernels of `psf` are those of any record with the same `profileInput` and the same other fields. Call it right after building the\n * record; neither the record nor `profileInput` may change afterwards.\n */\nexport function registerDiffractionPsfKey(psf: Psf, profileInput: object): void {\n const fields = Object.entries(psf as object).filter(([name]) => name !== \"profile\").sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0));\n keys.set(psf as object, canonical([\"createDiffractionLimitedPsfProfile\", profileInput, fields]));\n}\n\n/** The kernels kept for `psf`, made the most recently used. */\nfunction kernelsOf(psf: Psf): Map<string, Float64Array> {\n const key = keys.get(psf as object);\n if (key === undefined) {\n let kernels = byIdentity.get(psf as object);\n if (!kernels) byIdentity.set(psf as object, (kernels = new Map()));\n return kernels;\n }\n let kernels = byValue.get(key);\n if (kernels) byValue.delete(key);\n else kernels = new Map();\n byValue.set(key, kernels);\n while (byValue.size > SITE_DIFFRACTION_KERNEL_CACHE_SIZE) byValue.delete(byValue.keys().next().value!);\n return kernels;\n}\n\n/** The (2·radius + 1)² kernel of `psf` at `wavelengthNm` on a square site grid of `pitchMicrometers`; `failure` is the error message when the kernel cannot sample the pitch exactly. */\nexport function siteDiffractionKernel(psf: Psf, wavelengthNm: number, pitchMicrometers: number, radius: number, failure: string): Float64Array {\n const kernels = kernelsOf(psf);\n const key = canonical([wavelengthNm, pitchMicrometers, radius]);\n let kernel = kernels.get(key);\n if (!kernel) {\n const k = resolveLensPsfConvolutionKernels({ schemaVersion: \"0.1.0\", psf, spectralWeights: [{ wavelengthNm, weight: 1 }],\n grid: { width: 1, height: 1, sitePitchMicrometers: { x: pitchMicrometers, y: pitchMicrometers }, opticalAxisSite: { x: 0.5, y: 0.5 } }, patchWidth: 1, patchHeight: 1,\n kernelRadius: radius }).value;\n if (!k.exactSiteSampling || k.kernelRadius !== radius) throw new InvalidConfigurationError(failure);\n kernel = Float64Array.from(k.kernels);\n resolves++;\n kernels.set(key, kernel);\n }\n return Float64Array.from(kernel);\n}\n\n/** Test hook: the number of PSF records kept by value, the kernels resolved so far, and whether `psf` is registered. */\nexport function siteDiffractionKernelCacheState(psf?: Psf): { valueEntries: number; resolves: number; registered: boolean } {\n return { valueEntries: byValue.size, resolves, registered: psf !== undefined && keys.has(psf as object) };\n}\n\n/** Test hook: forgets every kernel kept by value. */\nexport function clearSiteDiffractionKernelCache(): void {\n byValue.clear();\n}\n"]}
|
|
@@ -165,9 +165,14 @@ export function createAhdDemosaicTask(input, provider) {
|
|
|
165
165
|
const W = p.width, H = p.height, s = p.samples;
|
|
166
166
|
const roleAt = (x, y) => tile[(y & 1) * 2 + (x & 1)];
|
|
167
167
|
const at = (x, y) => s[reflect(y, H) * W + reflect(x, W)];
|
|
168
|
+
// Sites whose neighbourhood lies inside the plane (two sites from the edge for stage 1, one for stages 2, 4
|
|
169
|
+
// and 5) read their neighbours by direct index offsets; reflect() returns its argument there, so they address
|
|
170
|
+
// the same samples as the border path. Every floating-point expression keeps the operands, order and grouping
|
|
171
|
+
// of the border path, so both paths give bit-identical results (test/processing-ahd-exactness.test.ts).
|
|
168
172
|
// 1. Directional greens.
|
|
169
173
|
const gh = new Float32Array(n), gv = new Float32Array(n);
|
|
170
174
|
for (let y = 0; y < H; y++) {
|
|
175
|
+
const interiorRow = y >= 2 && y + 2 < H;
|
|
171
176
|
for (let x = 0; x < W; x++) {
|
|
172
177
|
const i = y * W + x, c = s[i];
|
|
173
178
|
if (roleAt(x, y) === 1) {
|
|
@@ -175,28 +180,54 @@ export function createAhdDemosaicTask(input, provider) {
|
|
|
175
180
|
gv[i] = c;
|
|
176
181
|
continue;
|
|
177
182
|
}
|
|
178
|
-
|
|
179
|
-
|
|
183
|
+
if (interiorRow && x >= 2 && x + 2 < W) {
|
|
184
|
+
gh[i] = (s[i - 1] + s[i + 1]) / 2 + (2 * c - s[i - 2] - s[i + 2]) / 4;
|
|
185
|
+
gv[i] = (s[i - W] + s[i + W]) / 2 + (2 * c - s[i - 2 * W] - s[i + 2 * W]) / 4;
|
|
186
|
+
}
|
|
187
|
+
else {
|
|
188
|
+
gh[i] = (at(x - 1, y) + at(x + 1, y)) / 2 + (2 * c - at(x - 2, y) - at(x + 2, y)) / 4;
|
|
189
|
+
gv[i] = (at(x, y - 1) + at(x, y + 1)) / 2 + (2 * c - at(x, y - 2) - at(x, y + 2)) / 4;
|
|
190
|
+
}
|
|
180
191
|
}
|
|
181
192
|
yield;
|
|
182
193
|
}
|
|
183
194
|
// 2. Two full-colour candidates from colour differences.
|
|
184
195
|
const rgb = [new Float32Array(3 * n), new Float32Array(3 * n)], greens = [gh, gv];
|
|
185
196
|
for (let y = 0; y < H; y++) {
|
|
197
|
+
const interiorRow = y >= 1 && y + 1 < H;
|
|
186
198
|
for (let x = 0; x < W; x++) {
|
|
187
|
-
const i = y * W + x, own = roleAt(x, y);
|
|
199
|
+
const i = y * W + x, own = roleAt(x, y), interior = interiorRow && x >= 1 && x + 1 < W;
|
|
188
200
|
for (let d = 0; d < 2; d++) {
|
|
189
|
-
const g = greens[d], out = rgb[d];
|
|
190
|
-
|
|
191
|
-
out[3 * i + 1] = g[i];
|
|
201
|
+
const g = greens[d], out = rgb[d], gi = g[i];
|
|
202
|
+
out[3 * i + 1] = gi;
|
|
192
203
|
if (own === 1) {
|
|
193
204
|
const hRole = roleAt(x + 1, y), vRole = 2 - hRole;
|
|
194
|
-
|
|
195
|
-
|
|
205
|
+
if (interior) {
|
|
206
|
+
out[3 * i + hRole] = gi + ((s[i - 1] - g[i - 1]) + (s[i + 1] - g[i + 1])) / 2;
|
|
207
|
+
out[3 * i + vRole] = gi + ((s[i - W] - g[i - W]) + (s[i + W] - g[i + W])) / 2;
|
|
208
|
+
}
|
|
209
|
+
else {
|
|
210
|
+
let j = reflect(y, H) * W + reflect(x - 1, W);
|
|
211
|
+
const a = s[j] - g[j];
|
|
212
|
+
j = reflect(y, H) * W + reflect(x + 1, W);
|
|
213
|
+
const b = s[j] - g[j];
|
|
214
|
+
out[3 * i + hRole] = gi + (a + b) / 2;
|
|
215
|
+
j = reflect(y - 1, H) * W + reflect(x, W);
|
|
216
|
+
const cc = s[j] - g[j];
|
|
217
|
+
j = reflect(y + 1, H) * W + reflect(x, W);
|
|
218
|
+
const dd = s[j] - g[j];
|
|
219
|
+
out[3 * i + vRole] = gi + (cc + dd) / 2;
|
|
220
|
+
}
|
|
196
221
|
}
|
|
197
222
|
else {
|
|
198
223
|
out[3 * i + own] = s[i];
|
|
199
|
-
|
|
224
|
+
if (interior) {
|
|
225
|
+
out[3 * i + 2 - own] = gi + ((s[i - W - 1] - g[i - W - 1]) + (s[i - W + 1] - g[i - W + 1]) + (s[i + W - 1] - g[i + W - 1]) + (s[i + W + 1] - g[i + W + 1])) / 4;
|
|
226
|
+
}
|
|
227
|
+
else {
|
|
228
|
+
const ym = reflect(y - 1, H) * W, yp = reflect(y + 1, H) * W, xm = reflect(x - 1, W), xp = reflect(x + 1, W);
|
|
229
|
+
out[3 * i + 2 - own] = gi + ((s[ym + xm] - g[ym + xm]) + (s[ym + xp] - g[ym + xp]) + (s[yp + xm] - g[yp + xm]) + (s[yp + xp] - g[yp + xp])) / 4;
|
|
230
|
+
}
|
|
200
231
|
}
|
|
201
232
|
}
|
|
202
233
|
}
|
|
@@ -205,12 +236,14 @@ export function createAhdDemosaicTask(input, provider) {
|
|
|
205
236
|
// 3. CIELAB (W3C CSS Color 4 Lab definition; also CIE 15) of both candidates.
|
|
206
237
|
const lab = [new Float32Array(3 * n), new Float32Array(3 * n)];
|
|
207
238
|
const f = (t) => t > 216 / 24389 ? Math.cbrt(t) : (24389 / 27 * t + 16) / 116;
|
|
239
|
+
const m00 = m[0][0], m01 = m[0][1], m02 = m[0][2], m10 = m[1][0], m11 = m[1][1], m12 = m[1][2], m20 = m[2][0], m21 = m[2][1], m22 = m[2][2];
|
|
240
|
+
const w0 = white[0], w1 = white[1], w2 = white[2];
|
|
208
241
|
for (let y = 0; y < H; y++) {
|
|
209
242
|
for (let i = y * W; i < (y + 1) * W; i++)
|
|
210
243
|
for (let d = 0; d < 2; d++) {
|
|
211
244
|
const c = rgb[d], R = c[3 * i], G = c[3 * i + 1], B = c[3 * i + 2];
|
|
212
|
-
const fx = f((
|
|
213
|
-
const fz = f((
|
|
245
|
+
const fx = f((m00 * R + m01 * G + m02 * B) / w0), fy = f((m10 * R + m11 * G + m12 * B) / w1);
|
|
246
|
+
const fz = f((m20 * R + m21 * G + m22 * B) / w2), o = lab[d];
|
|
214
247
|
o[3 * i] = 116 * fy - 16;
|
|
215
248
|
o[3 * i + 1] = 500 * (fx - fy);
|
|
216
249
|
o[3 * i + 2] = 200 * (fy - fz);
|
|
@@ -218,46 +251,90 @@ export function createAhdDemosaicTask(input, provider) {
|
|
|
218
251
|
yield;
|
|
219
252
|
}
|
|
220
253
|
// 4. Homogeneity maps with adaptive tolerances.
|
|
221
|
-
const homo = [new Uint8Array(n), new Uint8Array(n)];
|
|
222
|
-
const N4 = [[-1, 0], [1, 0], [0, -1], [0, 1]];
|
|
254
|
+
const homo = [new Uint8Array(n), new Uint8Array(n)], lab0 = lab[0], lab1 = lab[1];
|
|
223
255
|
for (let y = 0; y < H; y++) {
|
|
256
|
+
const interiorRow = y >= 1 && y + 1 < H;
|
|
224
257
|
for (let x = 0; x < W; x++) {
|
|
225
|
-
const i = y * W + x
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
}
|
|
258
|
+
const i = y * W + x;
|
|
259
|
+
let jl, jr, ju, jd;
|
|
260
|
+
if (interiorRow && x >= 1 && x + 1 < W) {
|
|
261
|
+
jl = i - 1;
|
|
262
|
+
jr = i + 1;
|
|
263
|
+
ju = i - W;
|
|
264
|
+
jd = i + W;
|
|
233
265
|
}
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
count++;
|
|
241
|
-
homo[d][i] = count;
|
|
266
|
+
else {
|
|
267
|
+
const row = reflect(y, H) * W, col = reflect(x, W);
|
|
268
|
+
jl = row + reflect(x - 1, W);
|
|
269
|
+
jr = row + reflect(x + 1, W);
|
|
270
|
+
ju = reflect(y - 1, H) * W + col;
|
|
271
|
+
jd = reflect(y + 1, H) * W + col;
|
|
242
272
|
}
|
|
273
|
+
// Direction 0 (lab0), neighbours left, right, up, down (the N4 order).
|
|
274
|
+
const L0 = lab0[3 * i], a0 = lab0[3 * i + 1], b0 = lab0[3 * i + 2];
|
|
275
|
+
const dL00 = Math.abs(L0 - lab0[3 * jl]), dC00 = (a0 - lab0[3 * jl + 1]) ** 2 + (b0 - lab0[3 * jl + 2]) ** 2;
|
|
276
|
+
const dL01 = Math.abs(L0 - lab0[3 * jr]), dC01 = (a0 - lab0[3 * jr + 1]) ** 2 + (b0 - lab0[3 * jr + 2]) ** 2;
|
|
277
|
+
const dL02 = Math.abs(L0 - lab0[3 * ju]), dC02 = (a0 - lab0[3 * ju + 1]) ** 2 + (b0 - lab0[3 * ju + 2]) ** 2;
|
|
278
|
+
const dL03 = Math.abs(L0 - lab0[3 * jd]), dC03 = (a0 - lab0[3 * jd + 1]) ** 2 + (b0 - lab0[3 * jd + 2]) ** 2;
|
|
279
|
+
const L1 = lab1[3 * i], a1 = lab1[3 * i + 1], b1 = lab1[3 * i + 2];
|
|
280
|
+
const dL10 = Math.abs(L1 - lab1[3 * jl]), dC10 = (a1 - lab1[3 * jl + 1]) ** 2 + (b1 - lab1[3 * jl + 2]) ** 2;
|
|
281
|
+
const dL11 = Math.abs(L1 - lab1[3 * jr]), dC11 = (a1 - lab1[3 * jr + 1]) ** 2 + (b1 - lab1[3 * jr + 2]) ** 2;
|
|
282
|
+
const dL12 = Math.abs(L1 - lab1[3 * ju]), dC12 = (a1 - lab1[3 * ju + 1]) ** 2 + (b1 - lab1[3 * ju + 2]) ** 2;
|
|
283
|
+
const dL13 = Math.abs(L1 - lab1[3 * jd]), dC13 = (a1 - lab1[3 * jd + 1]) ** 2 + (b1 - lab1[3 * jd + 2]) ** 2;
|
|
284
|
+
const epsL = Math.min(Math.max(dL00, dL01), Math.max(dL12, dL13));
|
|
285
|
+
const epsC = Math.min(Math.max(dC00, dC01), Math.max(dC12, dC13));
|
|
286
|
+
let count = 0;
|
|
287
|
+
if (dL00 <= epsL && dC00 <= epsC)
|
|
288
|
+
count++;
|
|
289
|
+
if (dL01 <= epsL && dC01 <= epsC)
|
|
290
|
+
count++;
|
|
291
|
+
if (dL02 <= epsL && dC02 <= epsC)
|
|
292
|
+
count++;
|
|
293
|
+
if (dL03 <= epsL && dC03 <= epsC)
|
|
294
|
+
count++;
|
|
295
|
+
homo[0][i] = count;
|
|
296
|
+
count = 0;
|
|
297
|
+
if (dL10 <= epsL && dC10 <= epsC)
|
|
298
|
+
count++;
|
|
299
|
+
if (dL11 <= epsL && dC11 <= epsC)
|
|
300
|
+
count++;
|
|
301
|
+
if (dL12 <= epsL && dC12 <= epsC)
|
|
302
|
+
count++;
|
|
303
|
+
if (dL13 <= epsL && dC13 <= epsC)
|
|
304
|
+
count++;
|
|
305
|
+
homo[1][i] = count;
|
|
243
306
|
}
|
|
244
307
|
yield;
|
|
245
308
|
}
|
|
246
309
|
// 5. 3×3 summed homogeneity selects the candidate.
|
|
247
|
-
const out = new Float32Array(3 * n), direction = new Uint8Array(n);
|
|
310
|
+
const out = new Float32Array(3 * n), direction = new Uint8Array(n), h0 = homo[0], h1 = homo[1], rgb0 = rgb[0], rgb1 = rgb[1];
|
|
248
311
|
for (let y = 0; y < H; y++) {
|
|
312
|
+
const interiorRow = y >= 1 && y + 1 < H;
|
|
249
313
|
for (let x = 0; x < W; x++) {
|
|
250
314
|
let sh = 0, sv = 0;
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
315
|
+
const i = y * W + x;
|
|
316
|
+
if (interiorRow && x >= 1 && x + 1 < W) {
|
|
317
|
+
for (let dy = -1; dy <= 1; dy++) {
|
|
318
|
+
const row = i + dy * W;
|
|
319
|
+
for (let dx = -1; dx <= 1; dx++) {
|
|
320
|
+
const j = row + dx;
|
|
321
|
+
sh += h0[j];
|
|
322
|
+
sv += h1[j];
|
|
323
|
+
}
|
|
256
324
|
}
|
|
257
|
-
|
|
325
|
+
}
|
|
326
|
+
else {
|
|
327
|
+
for (let dy = -1; dy <= 1; dy++)
|
|
328
|
+
for (let dx = -1; dx <= 1; dx++) {
|
|
329
|
+
const j = reflect(y + dy, H) * W + reflect(x + dx, W);
|
|
330
|
+
sh += h0[j];
|
|
331
|
+
sv += h1[j];
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
const dir = sh > sv ? 0 : sv > sh ? 1 : 2;
|
|
258
335
|
direction[i] = dir;
|
|
259
336
|
for (let c = 0; c < 3; c++) {
|
|
260
|
-
const a =
|
|
337
|
+
const a = rgb0[3 * i + c], b = rgb1[3 * i + c];
|
|
261
338
|
out[3 * i + c] = dir === 0 ? a : dir === 1 ? b : (a + b) / 2;
|
|
262
339
|
}
|
|
263
340
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"demosaic.js","sourceRoot":"","sources":["../../src/processing/demosaic.ts"],"names":[],"mappings":"AAAA,sCAAsC;AAEtC;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,yBAAyB,EAAE,MAAM,gCAAgC,CAAC;AAC3E,OAAO,EAAE,2BAA2B,EAAE,MAAM,uBAAuB,CAAC;AACpE,OAAO,EAAE,cAAc,EAAuB,MAAM,8BAA8B,CAAC;AACnF,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AACpE,OAAO,EAAE,+BAA+B,EAAmC,MAAM,6BAA6B,CAAC;AAC/G,OAAO,EAAE,4BAA4B,EAAE,kCAAkC,EAAwC,MAAM,iCAAiC,CAAC;AACzJ,OAAO,EAAE,mCAAmC,EAA2C,MAAM,wCAAwC,CAAC;AACtI,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AACzC,OAAO,EACL,oBAAoB,EAAE,UAAU,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,WAAW,EAAE,gBAAgB,EAAE,cAAc,EAC1H,qBAAqB,EACtB,MAAM,sBAAsB,CAAC;AAoC9B,SAAS,UAAU,CAAC,KAAc,EAAE,KAAa;IAC/C,MAAM,CAAC,GAAG,cAAc,CAAC,KAAK,EAAE,CAAC,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAE,sBAAsB,EAAE,SAAS,CAAC,EAAE,KAAK,CAAC,CAAC;IAChH,MAAM,KAAK,GAAG,gBAAgB,CAAC,CAAC,CAAC,KAAK,EAAE,KAAK,GAAG,QAAQ,EAAE,CAAC,EAAE,qBAAqB,CAAC,EAAE,MAAM,GAAG,gBAAgB,CAAC,CAAC,CAAC,MAAM,EAAE,KAAK,GAAG,SAAS,EAAE,CAAC,EAAE,qBAAqB,CAAC,CAAC;IACtK,IAAI,KAAK,GAAG,MAAM,GAAG,qBAAqB;QAAE,MAAM,IAAI,yBAAyB,CAAC,KAAK,GAAG,WAAW,GAAG,qBAAqB,GAAG,SAAS,CAAC,CAAC;IACzI,IAAI,OAAO,CAAC,CAAC,aAAa,KAAK,QAAQ,IAAI,CAAC,CAAC,aAAa,CAAC,MAAM,KAAK,CAAC;QAAE,MAAM,IAAI,yBAAyB,CAAC,KAAK,GAAG,4CAA4C,CAAC,CAAC;IACnK,MAAM,GAAG,GAAG,+BAA+B,CAAC,CAAC,CAAC,oBAAoB,CAAC,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC;IACzF,IAAI,MAAM,CAAC,IAAI,KAAK,iBAAiB;QAAE,MAAM,IAAI,yBAAyB,CAAC,KAAK,GAAG,sDAAsD,CAAC,CAAC;IAC3I,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,YAAY,YAAY,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,MAAM,KAAK,KAAK,GAAG,MAAM;QAAE,MAAM,IAAI,yBAAyB,CAAC,KAAK,GAAG,yDAAyD,CAAC,CAAC;IACxL,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE,EAAE,MAAM,CAAC,gBAAgB,EAAE,EAAE,EAAE,MAAM,CAAC,iBAAiB,EAAE,GAAG,EAAE,MAAM,CAAC,cAAc,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC,aAAa,EAAE,CAAC;AACpK,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,gCAAgC,CAAC,KAAkC,EAAE,QAA4B;IAC/G,MAAM,CAAC,GAAG,cAAc,CAAC,KAAK,EAAE,CAAC,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,QAAQ,EAAE,qBAAqB,CAAC,EAAE,wCAAwC,CAAC,CAAC;IACzJ,MAAM,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,KAAK,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,WAAW,CAAC,CAAC,CAAC,cAAc,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAU,EAAE,gBAAgB,EAAE,QAAQ,CAAC,CAAC;IAC1I,MAAM,MAAM,GAAG,mCAAmC,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC;IACrF,MAAM,GAAG,GAAG,CAAC,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,GAA4D,EAAE;QACrJ,MAAM,CAAC,GAAG,cAAc,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE,QAAQ,CAAC,CAAC;QAC5E,OAAO,EAAE,CAAC,EAAE,gBAAgB,CAAC,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,gBAAgB,CAAC,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;YAClH,KAAK,EAAE,gBAAgB,CAAC,CAAC,CAAC,KAAK,EAAE,cAAc,EAAE,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,gBAAgB,CAAC,CAAC,CAAC,MAAM,EAAE,eAAe,EAAE,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC;IACrI,CAAC,CAAC,EAAE,CAAC;IACL,IAAI,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,IAAI,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,MAAM;QAAE,MAAM,IAAI,yBAAyB,CAAC,mCAAmC,CAAC,CAAC;IAC3I,MAAM,KAAK,GAAG,4BAA4B,CAAC,MAAM,CAAC,EAAE,QAAQ,GAAG,MAAM,CAAC,CAAC,CAAE,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC;IACjG,2FAA2F;IAC3F,KAAK,MAAM,KAAK,IAAI,MAAM;QAAE,KAAK,MAAM,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO;YAAE,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,aAAa,EAAE,CAAC;gBACnG,MAAM,CAAC,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,OAAO,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,OAAO,CAAC;gBACjE,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,eAAe,EAAE,CAAC;oBAChG,MAAM,IAAI,yBAAyB,CAAC,kEAAkE,CAAC,CAAC;gBAC1G,CAAC;YACH,CAAC;IACD,IAAI,MAAM,KAAK,QAAQ;QAAE,kCAAkC,CAAC,EAAE,gBAAgB,EAAE,CAAC,CAAC,EAAE,EAAE,iBAAiB,EAAE,CAAC,CAAC,EAAE,EAAE,cAAc,EAAE,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;SAC7J,CAAC;QACJ,+FAA+F;QAC/F,MAAM,IAAI,GAAG,CAAC,CAAS,EAAE,CAAS,EAAW,EAAE,CAAC,CAAC,GAAG,KAAK,IAAI,CAAC,GAAG,KAAK,IAAI,CAAC,GAAG,KAAK,IAAI,CAAC,CAAC,KAAK,IAAI,CAAC,GAAG,KAAK,IAAI,CAAC,CAAC,MAAM,CAAC;QACxH,KAAK,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,EAAE;YAAE,KAAK,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC;gBAChG,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;oBAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC;oBAAC,SAAS;gBAAC,CAAC;gBACpE,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,CAAE,CAAC,OAAO,CAAC,OAAO;oBAAE,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,aAAa,EAAE,CAAC;wBACvG,IAAI,CAAC,GAAG,CAAC,CAAC,OAAO,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,OAAO,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,KAAK,IAAI,CAAC,GAAG,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC;4BACpG,MAAM,IAAI,yBAAyB,CAAC,gGAAgG,CAAC,CAAC;wBACxI,CAAC;oBACH,CAAC;YACH,CAAC;IACH,CAAC;IACD,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACnE,EAAE,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,EAAE,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;QAC9G,KAAK,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC;KAAE,CAAC,CAAC,CAAC,CAAC;IAC/I,MAAM,QAAQ,GAAG,GAAG,CAAC,KAAK,GAAG,GAAG,CAAC,MAAM,GAAG,QAAQ,GAAG,CAAC,CAAC;IACvD,OAAO,oBAAoB,CAAC;QAC1B,QAAQ,EAAE,cAAc,EAAE,CAAC,CAAC,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,qBAAqB,EAAE,QAAQ,EAAE,mBAAmB,EAAE,mBAAmB,CAAC,CAAC,CAAC,mBAAmB,CAAC;QACjJ,IAAI,EAAE,QAAQ,CAAC;YACb,KAAK,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC;YAC5D,MAAM,GAAG,GAAG,IAAI,YAAY,CAAC,GAAG,CAAC,KAAK,GAAG,GAAG,CAAC,MAAM,GAAG,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC;YAC5F,KAAK,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBACvD,KAAK,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC;oBAC/C,MAAM,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,CAAE,EAAE,MAAM,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;oBACxE,MAAM,QAAQ,GAAG,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,GAAG,KAAK,GAAG,CAAC,IAAI,CAAC,GAAG,KAAK,GAAG,CAAC,CAAC,MAAM,CAAC;oBACnF,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;wBACxB,IAAI,CAAC,GAAG,CAAC,CAAC;wBACV,IAAI,QAAQ;4BAAE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE;gCAAE,CAAC,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAE,CAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAE,CAAC;;4BACtF,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE;gCAAE,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAE,EAAE,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAE,EAAE,CAAC,CAAC,CAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAE,CAAC;wBAC5H,GAAG,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;oBACf,CAAC;gBACH,CAAC;gBACD,KAAK,CAAC;YACR,CAAC;YACD,OAAO,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,EAAE,MAAM,CAAC,CAAC,CAAE,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,eAAe,CAAC,EAAE,IAAI,EAAE,GAAG;gBACzI,cAAc,EAAE,MAAM,EAAE,UAAU,EAAE,oBAAoB,CAAC,iCAAiC,EAAE;oBAC1F,oHAAoH;oBACpH,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,kGAAkG,CAAC,CAAC;wBACxH,2EAA2E;oBAC7E,8DAA8D;iBAAC,CAAC,EAAE,CAAC;QACzE,CAAC;KACF,CAAC,CAAC;AACL,CAAC;AAuBD;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,qBAAqB,CAAC,KAAuB,EAAE,QAA4B;IACzF,MAAM,CAAC,GAAG,cAAc,CAAC,KAAK,EAAE,CAAC,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,qBAAqB,CAAC,EAAE,6BAA6B,CAAC,CAAC;IAChI,MAAM,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IACvC,MAAM,KAAK,GAAG,cAAc,CAAC,CAAC,CAAC,YAAY,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,cAAc,CAAC,CAAC;IACvF,MAAM,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;IACjD,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,OAAO,EAAE,KAAK,QAAQ,CAAC,IAAI,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK,CAAC;QAAE,MAAM,IAAI,yBAAyB,CAAC,iDAAiD,CAAC,CAAC;IAChK,IAAI,CAAC,CAAC,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,EAAE,KAAK,CAAC;QAAE,MAAM,IAAI,2BAA2B,CAAC,kCAAkC,CAAC,CAAC;IACxG,MAAM,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC;IAChD,MAAM,KAAK,GAAG,CAAC,CAAoB,EAAE,CAAoB,EAAW,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAE,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAE,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAE,CAAE,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAE,CAAE,KAAK,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAE,CAAC,KAAK,CAAC,CAAC;IACxK,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACrD,MAAM,IAAI,2BAA2B,CAAC,8DAA8D,CAAC,CAAC;IACxG,CAAC;IACD,IAAI,CAAC,CAAC,KAAK,GAAG,CAAC,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC;QAAE,MAAM,IAAI,2BAA2B,CAAC,qCAAqC,CAAC,CAAC;IAC9G,MAAM,CAAC,GAAG,CAAC,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,oBAAoB,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,WAAW,EAAE,aAAa,CAAC,CAAC;IACnI,MAAM,KAAK,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IACnE,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QAAE,MAAM,IAAI,2BAA2B,CAAC,4DAA4D,CAAC,CAAC;IACrI,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,MAAM,CAAC;IAC7B,MAAM,KAAK,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;IAClE,OAAO,oBAAoB,CAAC;QAC1B,QAAQ,EAAE,cAAc,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,qBAAqB,EAAE,KAAK,EAAE,mBAAmB,EAAE,mBAAmB,CAAC,CAAC,CAAC,mBAAmB,CAAC;QACrI,IAAI,EAAE,QAAQ,CAAC;YACb,KAAK,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC;YAC5D,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC;YAC/C,MAAM,MAAM,GAAG,CAAC,CAAS,EAAE,CAAS,EAAU,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAE,CAAC;YAC9E,MAAM,EAAE,GAAG,CAAC,CAAS,EAAE,CAAS,EAAU,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,CAAE,CAAC;YACnF,yBAAyB;YACzB,MAAM,EAAE,GAAG,IAAI,YAAY,CAAC,CAAC,CAAC,EAAE,EAAE,GAAG,IAAI,YAAY,CAAC,CAAC,CAAC,CAAC;YACzD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC3B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;oBAC3B,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAE,CAAC;oBAC/B,IAAI,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC;wBAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;wBAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;wBAAC,SAAS;oBAAC,CAAC;oBAC3D,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;oBACtF,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;gBACxF,CAAC;gBACD,KAAK,CAAC;YACR,CAAC;YACD,yDAAyD;YACzD,MAAM,GAAG,GAAG,CAAC,IAAI,YAAY,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,YAAY,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,MAAM,GAAG,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;YAClF,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC3B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;oBAC3B,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,GAAG,GAAG,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;oBACxC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;wBAC3B,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,CAAE,EAAE,GAAG,GAAG,GAAG,CAAC,CAAC,CAAE,CAAC;wBACpC,MAAM,IAAI,GAAG,CAAC,EAAU,EAAE,EAAU,EAAU,EAAE,GAAG,MAAM,CAAC,GAAG,OAAO,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAE,GAAG,CAAC,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,CAAC;wBAC1H,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAE,CAAC;wBACvB,IAAI,GAAG,KAAK,CAAC,EAAE,CAAC;4BACd,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,GAAG,CAAC,GAAG,KAAK,CAAC;4BAClD,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAE,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;4BACnE,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAE,GAAG,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;wBACrE,CAAC;6BAAM,CAAC;4BACN,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAE,CAAC;4BACzB,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAE,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;wBACzH,CAAC;oBACH,CAAC;gBACH,CAAC;gBACD,KAAK,CAAC;YACR,CAAC;YACD,8EAA8E;YAC9E,MAAM,GAAG,GAAG,CAAC,IAAI,YAAY,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,YAAY,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;YAC/D,MAAM,CAAC,GAAG,CAAC,CAAS,EAAU,EAAE,CAAC,CAAC,GAAG,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,GAAG,CAAC;YAC9F,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC3B,KAAK,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE;oBAAE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;wBACrE,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC,CAAE,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAE,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAE,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAE,CAAC;wBACvE,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAE,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAE,CAAC,CAAC;wBACnI,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAE,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,CAAE,CAAC;wBACjF,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,GAAG,GAAG,EAAE,GAAG,EAAE,CAAC;wBAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,GAAG,GAAG,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC;wBAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,GAAG,GAAG,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC;oBAC3F,CAAC;gBACD,KAAK,CAAC;YACR,CAAC;YACD,gDAAgD;YAChD,MAAM,IAAI,GAAG,CAAC,IAAI,UAAU,CAAC,CAAC,CAAC,EAAE,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;YACpD,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAU,CAAC;YACvD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC3B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;oBAC3B,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;oBAC1F,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;wBAC3B,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC,CAAE,CAAC;wBAClB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;4BAC3B,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;4BACpE,EAAE,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAE,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAE,CAAC,CAAC;4BAC5C,EAAE,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAE,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAE,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAE,CAAC,IAAI,CAAC,CAAC;wBAC1F,CAAC;oBACH,CAAC;oBACD,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAE,CAAC,CAAC,CAAE,EAAE,EAAE,CAAC,CAAC,CAAE,CAAC,CAAC,CAAE,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAE,CAAC,CAAC,CAAE,EAAE,EAAE,CAAC,CAAC,CAAE,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC;oBAC1F,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAE,CAAC,CAAC,CAAE,EAAE,EAAE,CAAC,CAAC,CAAE,CAAC,CAAC,CAAE,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAE,CAAC,CAAC,CAAE,EAAE,EAAE,CAAC,CAAC,CAAE,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC;oBAC1F,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;wBAC3B,IAAI,KAAK,GAAG,CAAC,CAAC;wBACd,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE;4BAAE,IAAI,EAAE,CAAC,CAAC,CAAE,CAAC,CAAC,CAAE,IAAI,IAAI,IAAI,EAAE,CAAC,CAAC,CAAE,CAAC,CAAC,CAAE,IAAI,IAAI;gCAAE,KAAK,EAAE,CAAC;wBAClF,IAAI,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC;oBACtB,CAAC;gBACH,CAAC;gBACD,KAAK,CAAC;YACR,CAAC;YACD,mDAAmD;YACnD,MAAM,GAAG,GAAG,IAAI,YAAY,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,SAAS,GAAG,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC;YACnE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC3B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;oBAC3B,IAAI,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;oBACnB,KAAK,IAAI,EAAE,GAAG,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE,EAAE;wBAAE,KAAK,IAAI,EAAE,GAAG,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC;4BACjE,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC;4BACtD,EAAE,IAAI,IAAI,CAAC,CAAC,CAAE,CAAC,CAAC,CAAE,CAAC;4BAAC,EAAE,IAAI,IAAI,CAAC,CAAC,CAAE,CAAC,CAAC,CAAE,CAAC;wBACzC,CAAC;oBACD,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,GAAG,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;oBACzD,SAAS,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC;oBACnB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;wBAC3B,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC,CAAE,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,CAAE,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAE,CAAC;wBACvD,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;oBAC/D,CAAC;gBACH,CAAC;gBACD,KAAK,CAAC;YACR,CAAC;YACD,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,SAAS,EAAE,UAAU,EAAE,oBAAoB,CAAC,kCAAkC,EAAE;oBACvH,iHAAiH;oBACjH,qHAAqH;oBACrH,iEAAiE;oBACjE,gFAAgF;iBAAC,CAAC,EAAE,CAAC;QACzF,CAAC;KACF,CAAC,CAAC;AACL,CAAC","sourcesContent":["// SPDX-License-Identifier: Apache-2.0\n\n/**\n * Demosaicing: rebuilds full colour from a CFA (colour filter array) mosaic. Works on a linear mosaic\n * plane stored in typed arrays, for example black-subtracted normalized RAW values or a merged HDR\n * mosaic.\n * - `createCfaPlaneReconstructionTask` runs explicit linear kernels, one per CFA phase. It uses the\n * existing `explicit-linear-native-neighborhood` contract, including the built-in bilinear\n * factory. Borders either reject or mirror (reflect-101). The summation order is\n * the same as `calculateRawReconstructionChannel`, so values match the reference resolver exactly\n * before float32 storage.\n * - `createAhdDemosaicTask` is a separate, non-linear, adaptive method: adaptive\n * homogeneity-directed (AHD) demosaicing after Hirakawa & Parks (2005). It never claims to be a\n * linear kernel.\n * @see docs/PROCESSING.md for equations, sources and approximation status.\n */\n\nimport { InvalidConfigurationError } from \"../core/configuration-error.js\";\nimport { InvalidScientificInputError } from \"../core/validation.js\";\nimport { parseMatrix3x3, type ColorMatrix3x3 } from \"../color/colorimetry-math.js\";\nimport { resolveRgbColorSpace } from \"../color/rgb-color-spaces.js\";\nimport { parseSensorColorSamplingProfile, type SensorColorSamplingProfile } from \"../sensor/color-sampling.js\";\nimport { rawReconstructionKernelReach, validateMirrorBorderCfaConsistency, type RawReconstructionBorderHandling } from \"../sensor/raw-reconstruction.js\";\nimport { parseRawReconstructionPhaseProfiles, type RawFrameReconstructionPhaseProfile } from \"../capture/raw-frame-reconstruction.js\";\nimport { reflect } from \"./image-ops.js\";\nimport {\n createProcessingTask, finiteRows, maximumWorkingBytes, processingProvenance, requireEnum, requireIntegerIn, requireOptions,\n PROCESSING_MAX_PIXELS, type ProcessingBody, type ProcessingProvenance, type ProcessingProvider, type ProcessingRgbImage, type ProcessingTask\n} from \"./processing-task.js\";\n\n/** A single-channel linear CFA mosaic in absolute native site coordinates (row-major, +Y down). */\nexport interface CfaMosaicPlane {\n width: number;\n height: number;\n captureModeId: string;\n /** Periodic mosaic anchored at site (0, 0) of this plane. */\n colorSamplingProfile: SensorColorSamplingProfile;\n /** Linear values, e.g. black-subtracted normalized RAW or merged HDR radiance. */\n samples: Float32Array;\n}\n\nexport interface CfaPlaneReconstructionInput {\n plane: CfaMosaicPlane;\n phaseProfiles: readonly RawFrameReconstructionPhaseProfile[];\n /** Default `reject`: every neighbourhood must lie inside the plane. */\n borderHandling?: RawReconstructionBorderHandling;\n /** Output region in plane coordinates; default the whole plane. */\n region?: { x: number; y: number; width: number; height: number };\n maximumWorkingBytes?: number;\n}\n\nexport interface CfaPlaneReconstructionOutput {\n width: number;\n height: number;\n region: { x: number; y: number; width: number; height: number };\n channelIds: readonly string[];\n /** Interleaved `channelIds.length` channels, row-major over the region. */\n data: Float32Array;\n borderHandling: RawReconstructionBorderHandling;\n provenance: ProcessingProvenance;\n}\n\ninterface ParsedPlane { width: number; height: number; cfa: SensorColorSamplingProfile; rw: number; rh: number; ids: readonly string[]; samples: Float32Array; modeId: string }\n\nfunction parsePlane(value: unknown, label: string): ParsedPlane {\n const r = requireOptions(value, [\"width\", \"height\", \"captureModeId\", \"colorSamplingProfile\", \"samples\"], label);\n const width = requireIntegerIn(r.width, label + \".width\", 1, PROCESSING_MAX_PIXELS), height = requireIntegerIn(r.height, label + \".height\", 1, PROCESSING_MAX_PIXELS);\n if (width * height > PROCESSING_MAX_PIXELS) throw new InvalidConfigurationError(label + \" exceeds \" + PROCESSING_MAX_PIXELS + \" sites.\");\n if (typeof r.captureModeId !== \"string\" || r.captureModeId.length === 0) throw new InvalidConfigurationError(label + \".captureModeId must be a non-empty string.\");\n const cfa = parseSensorColorSamplingProfile(r.colorSamplingProfile), layout = cfa.layout;\n if (layout.kind !== \"periodic-mosaic\") throw new InvalidConfigurationError(label + \" requires a periodic mosaic colour-sampling profile.\");\n if (!(r.samples instanceof Float32Array) || r.samples.length !== width * height) throw new InvalidConfigurationError(label + \".samples must be a Float32Array of width·height values.\");\n return { width, height, cfa, rw: layout.repeatWidthSites, rh: layout.repeatHeightSites, ids: layout.siteChannelIds, samples: r.samples, modeId: r.captureModeId };\n}\n\n/**\n * Runs explicit linear reconstruction kernels, one per CFA phase, over a typed CFA plane.\n * - With `mirror` borders, a site outside the plane is read from its mirrored (reflect-101) position.\n * This is accepted only if the mirrored site has the same CFA channel, which is always true for a\n * 2×2 Bayer pattern.\n * - With `reject`, out-of-plane reads throw (fail closed), like the reference resolver.\n * Values are linear and signed. No clamping, white balance or colour transform is applied.\n */\nexport function createCfaPlaneReconstructionTask(input: CfaPlaneReconstructionInput, provider: ProcessingProvider): ProcessingTask<CfaPlaneReconstructionOutput> {\n const r = requireOptions(input, [\"plane\", \"phaseProfiles\", \"borderHandling\", \"region\", \"maximumWorkingBytes\"], \"createCfaPlaneReconstructionTask input\");\n const p = parsePlane(r.plane, \"plane\"), border = requireEnum(r.borderHandling, [\"reject\", \"mirror\"] as const, \"borderHandling\", \"reject\");\n const phases = parseRawReconstructionPhaseProfiles(r.phaseProfiles, p.modeId, p.cfa);\n const reg = r.region === undefined ? { x: 0, y: 0, width: p.width, height: p.height } : ((): { x: number; y: number; width: number; height: number } => {\n const g = requireOptions(r.region, [\"x\", \"y\", \"width\", \"height\"], \"region\");\n return { x: requireIntegerIn(g.x, \"region.x\", 0, p.width - 1), y: requireIntegerIn(g.y, \"region.y\", 0, p.height - 1),\n width: requireIntegerIn(g.width, \"region.width\", 1, p.width), height: requireIntegerIn(g.height, \"region.height\", 1, p.height) };\n })();\n if (reg.x + reg.width > p.width || reg.y + reg.height > p.height) throw new InvalidConfigurationError(\"region must lie inside the plane.\");\n const reach = rawReconstructionKernelReach(phases), channels = phases[0]!.profile.kernels.length;\n // Kernel source channels must match the periodic CFA at every (virtual) contribution site.\n for (const phase of phases) for (const k of phase.profile.kernels) for (const c of k.contributions) {\n const x = phase.phaseX + c.offsetX, y = phase.phaseY + c.offsetY;\n if (p.ids[((y % p.rh) + p.rh) % p.rh * p.rw + ((x % p.rw) + p.rw) % p.rw] !== c.sourceChannelId) {\n throw new InvalidConfigurationError(\"Reconstruction source channel disagrees with absolute CFA phase.\");\n }\n }\n if (border === \"mirror\") validateMirrorBorderCfaConsistency({ repeatWidthSites: p.rw, repeatHeightSites: p.rh, siteChannelIds: p.ids }, p.width, p.height, reach);\n else {\n // Exact check of the pixels within `reach` of a plane edge; only their phases' offsets matter.\n const near = (x: number, y: number): boolean => x < reach || y < reach || x + reach >= p.width || y + reach >= p.height;\n for (let y = reg.y; y < reg.y + reg.height; y++) for (let x = reg.x; x < reg.x + reg.width; x++) {\n if (!near(x, y)) { x = Math.max(x, p.width - reach - 1); continue; }\n for (const k of phases[(y % p.rh) * p.rw + x % p.rw]!.profile.kernels) for (const c of k.contributions) {\n if (x + c.offsetX < 0 || y + c.offsetY < 0 || x + c.offsetX >= p.width || y + c.offsetY >= p.height) {\n throw new InvalidConfigurationError(\"Reconstruction neighbourhood leaves the plane; use a smaller region or mirror border handling.\");\n }\n }\n }\n }\n const flat = phases.map((phase) => phase.profile.kernels.map((k) => ({\n dx: Int32Array.from(k.contributions, (c) => c.offsetX), dy: Int32Array.from(k.contributions, (c) => c.offsetY),\n delta: Int32Array.from(k.contributions, (c) => c.offsetY * p.width + c.offsetX), w: Float64Array.from(k.contributions, (c) => c.weight) })));\n const outBytes = reg.width * reg.height * channels * 4;\n return createProcessingTask({\n provider, totalTileCount: p.height + reg.height, estimatedWorkingBytes: outBytes, maximumWorkingBytes: maximumWorkingBytes(r.maximumWorkingBytes),\n body: function* (): ProcessingBody<CfaPlaneReconstructionOutput> {\n yield* finiteRows(p.samples, p.width, p.height, 1, \"plane\");\n const out = new Float32Array(reg.width * reg.height * channels), s = p.samples, w = p.width;\n for (let y = reg.y, o = 0; y < reg.y + reg.height; y++) {\n for (let x = reg.x; x < reg.x + reg.width; x++) {\n const kernels = flat[(y % p.rh) * p.rw + x % p.rw]!, centre = y * w + x;\n const interior = x >= reach && y >= reach && x + reach < w && y + reach < p.height;\n for (const k of kernels) {\n let v = 0;\n if (interior) for (let j = 0; j < k.w.length; j++) v += s[centre + k.delta[j]!]! * k.w[j]!;\n else for (let j = 0; j < k.w.length; j++) v += s[reflect(y + k.dy[j]!, p.height) * w + reflect(x + k.dx[j]!, w)]! * k.w[j]!;\n out[o++] = v;\n }\n }\n yield;\n }\n return { width: reg.width, height: reg.height, region: reg, channelIds: phases[0]!.profile.kernels.map((k) => k.outputChannelId), data: out,\n borderHandling: border, provenance: processingProvenance(\"cfa-plane-linear-reconstruction\", [\n \"Explicit per-phase linear kernels, summed in declared contribution order; values are linear, signed and unclamped.\",\n border === \"mirror\" ? \"Sites outside the plane are read at their reflect-101 mirror image, which keeps the CFA channel.\" :\n \"Every neighbourhood lies inside the plane; no padding or renormalization.\",\n \"No white balance, colour transform, sharpening or denoising.\"]) };\n }\n });\n}\n\n// ------------------------------------------------------------------ AHD\n\nexport interface AhdDemosaicInput {\n plane: CfaMosaicPlane;\n /** CFA channel ids of the red, green and blue sites; output order is red, green, blue. */\n channelRoles: { red: string; green: string; blue: string };\n /**\n * Camera-linear RGB → CIE XYZ, used only for the homogeneity metric (in CIELAB). Default: the\n * sRGB/D65 matrix, so the plane is treated as linear sRGB for the metric. Output values are never\n * transformed.\n */\n cameraToXyz?: ColorMatrix3x3;\n maximumWorkingBytes?: number;\n}\n\nexport interface AhdDemosaicOutput extends ProcessingRgbImage {\n /** Per pixel: 0 horizontal, 1 vertical, 2 equal homogeneity (average of both). */\n direction: Uint8Array;\n provenance: ProcessingProvenance;\n}\n\n/**\n * Adaptive homogeneity-directed (AHD) demosaicing after Hirakawa & Parks, IEEE TIP 14(3), 2005:\n * 1. green is interpolated separately along rows and columns with the 5-tap directional filter\n * [−1/4, 1/2, 1/2, 1/2, −1/4] (bilinear green plus the own-channel second difference);\n * 2. red and blue are filled from bilinearly interpolated colour differences (R−G, B−G) against each\n * directional green, giving two full-colour candidates;\n * 3. both candidates are converted to CIELAB. At each pixel, the homogeneity is the number of\n * 4-neighbours within adaptive luminance and chrominance tolerances ε_L, ε_C. Each tolerance is the\n * smaller of the two directions' largest differences along their own direction;\n * 4. homogeneity is summed over 3×3, and the more homogeneous candidate is chosen (a tie averages\n * both).\n * The paper's optional iterative median step for reducing artifacts is not applied. Mirrored\n * (reflect-101) borders keep each site's Bayer channel. The method is non-linear: the output is not a\n * linear function of the mosaic.\n */\nexport function createAhdDemosaicTask(input: AhdDemosaicInput, provider: ProcessingProvider): ProcessingTask<AhdDemosaicOutput> {\n const r = requireOptions(input, [\"plane\", \"channelRoles\", \"cameraToXyz\", \"maximumWorkingBytes\"], \"createAhdDemosaicTask input\");\n const p = parsePlane(r.plane, \"plane\");\n const roles = requireOptions(r.channelRoles, [\"red\", \"green\", \"blue\"], \"channelRoles\");\n const ids = [roles.red, roles.green, roles.blue];\n if (ids.some((id) => typeof id !== \"string\") || new Set(ids).size !== 3) throw new InvalidConfigurationError(\"channelRoles must name three distinct channels.\");\n if (p.rw !== 2 || p.rh !== 2) throw new InvalidScientificInputError(\"AHD requires a 2×2 Bayer mosaic.\");\n const tile = p.ids.map((id) => ids.indexOf(id));\n const bayer = (g: readonly number[], c: readonly number[]): boolean => tile[g[0]!] === 1 && tile[g[1]!] === 1 && tile[c[0]!]! + tile[c[1]!]! === 2 && tile[c[0]!] !== 1;\n if (!bayer([0, 3], [1, 2]) && !bayer([1, 2], [0, 3])) {\n throw new InvalidScientificInputError(\"AHD requires one red, one blue and two diagonal green sites.\");\n }\n if (p.width < 3 || p.height < 3) throw new InvalidScientificInputError(\"AHD requires at least a 3×3 mosaic.\");\n const m = r.cameraToXyz === undefined ? resolveRgbColorSpace(\"srgb\").value.rgbToXyz : parseMatrix3x3(r.cameraToXyz, \"cameraToXyz\");\n const white = [0, 1, 2].map((i) => m[i]![0] + m[i]![1] + m[i]![2]);\n if (white.some((v) => !(v > 0))) throw new InvalidScientificInputError(\"cameraToXyz must map camera white (1,1,1) to positive XYZ.\");\n const n = p.width * p.height;\n const bytes = n * (4 * 2 + 4 * 3 * 2 + 4 * 3 * 2 + 2 + 3 * 4 + 1);\n return createProcessingTask({\n provider, totalTileCount: 6 * p.height, estimatedWorkingBytes: bytes, maximumWorkingBytes: maximumWorkingBytes(r.maximumWorkingBytes),\n body: function* (): ProcessingBody<AhdDemosaicOutput> {\n yield* finiteRows(p.samples, p.width, p.height, 1, \"plane\");\n const W = p.width, H = p.height, s = p.samples;\n const roleAt = (x: number, y: number): number => tile[(y & 1) * 2 + (x & 1)]!;\n const at = (x: number, y: number): number => s[reflect(y, H) * W + reflect(x, W)]!;\n // 1. Directional greens.\n const gh = new Float32Array(n), gv = new Float32Array(n);\n for (let y = 0; y < H; y++) {\n for (let x = 0; x < W; x++) {\n const i = y * W + x, c = s[i]!;\n if (roleAt(x, y) === 1) { gh[i] = c; gv[i] = c; continue; }\n gh[i] = (at(x - 1, y) + at(x + 1, y)) / 2 + (2 * c - at(x - 2, y) - at(x + 2, y)) / 4;\n gv[i] = (at(x, y - 1) + at(x, y + 1)) / 2 + (2 * c - at(x, y - 2) - at(x, y + 2)) / 4;\n }\n yield;\n }\n // 2. Two full-colour candidates from colour differences.\n const rgb = [new Float32Array(3 * n), new Float32Array(3 * n)], greens = [gh, gv];\n for (let y = 0; y < H; y++) {\n for (let x = 0; x < W; x++) {\n const i = y * W + x, own = roleAt(x, y);\n for (let d = 0; d < 2; d++) {\n const g = greens[d]!, out = rgb[d]!;\n const diff = (xx: number, yy: number): number => { const j = reflect(yy, H) * W + reflect(xx, W); return s[j]! - g[j]!; };\n out[3 * i + 1] = g[i]!;\n if (own === 1) {\n const hRole = roleAt(x + 1, y), vRole = 2 - hRole;\n out[3 * i + hRole] = g[i]! + (diff(x - 1, y) + diff(x + 1, y)) / 2;\n out[3 * i + vRole] = g[i]! + (diff(x, y - 1) + diff(x, y + 1)) / 2;\n } else {\n out[3 * i + own] = s[i]!;\n out[3 * i + 2 - own] = g[i]! + (diff(x - 1, y - 1) + diff(x + 1, y - 1) + diff(x - 1, y + 1) + diff(x + 1, y + 1)) / 4;\n }\n }\n }\n yield;\n }\n // 3. CIELAB (W3C CSS Color 4 Lab definition; also CIE 15) of both candidates.\n const lab = [new Float32Array(3 * n), new Float32Array(3 * n)];\n const f = (t: number): number => t > 216 / 24389 ? Math.cbrt(t) : (24389 / 27 * t + 16) / 116;\n for (let y = 0; y < H; y++) {\n for (let i = y * W; i < (y + 1) * W; i++) for (let d = 0; d < 2; d++) {\n const c = rgb[d]!, R = c[3 * i]!, G = c[3 * i + 1]!, B = c[3 * i + 2]!;\n const fx = f((m[0][0] * R + m[0][1] * G + m[0][2] * B) / white[0]!), fy = f((m[1][0] * R + m[1][1] * G + m[1][2] * B) / white[1]!);\n const fz = f((m[2][0] * R + m[2][1] * G + m[2][2] * B) / white[2]!), o = lab[d]!;\n o[3 * i] = 116 * fy - 16; o[3 * i + 1] = 500 * (fx - fy); o[3 * i + 2] = 200 * (fy - fz);\n }\n yield;\n }\n // 4. Homogeneity maps with adaptive tolerances.\n const homo = [new Uint8Array(n), new Uint8Array(n)];\n const N4 = [[-1, 0], [1, 0], [0, -1], [0, 1]] as const;\n for (let y = 0; y < H; y++) {\n for (let x = 0; x < W; x++) {\n const i = y * W + x, dL = [[0, 0, 0, 0], [0, 0, 0, 0]], dC = [[0, 0, 0, 0], [0, 0, 0, 0]];\n for (let d = 0; d < 2; d++) {\n const o = lab[d]!;\n for (let k = 0; k < 4; k++) {\n const j = reflect(y + N4[k]![1], H) * W + reflect(x + N4[k]![0], W);\n dL[d]![k] = Math.abs(o[3 * i]! - o[3 * j]!);\n dC[d]![k] = (o[3 * i + 1]! - o[3 * j + 1]!) ** 2 + (o[3 * i + 2]! - o[3 * j + 2]!) ** 2;\n }\n }\n const epsL = Math.min(Math.max(dL[0]![0]!, dL[0]![1]!), Math.max(dL[1]![2]!, dL[1]![3]!));\n const epsC = Math.min(Math.max(dC[0]![0]!, dC[0]![1]!), Math.max(dC[1]![2]!, dC[1]![3]!));\n for (let d = 0; d < 2; d++) {\n let count = 0;\n for (let k = 0; k < 4; k++) if (dL[d]![k]! <= epsL && dC[d]![k]! <= epsC) count++;\n homo[d]![i] = count;\n }\n }\n yield;\n }\n // 5. 3×3 summed homogeneity selects the candidate.\n const out = new Float32Array(3 * n), direction = new Uint8Array(n);\n for (let y = 0; y < H; y++) {\n for (let x = 0; x < W; x++) {\n let sh = 0, sv = 0;\n for (let dy = -1; dy <= 1; dy++) for (let dx = -1; dx <= 1; dx++) {\n const j = reflect(y + dy, H) * W + reflect(x + dx, W);\n sh += homo[0]![j]!; sv += homo[1]![j]!;\n }\n const i = y * W + x, dir = sh > sv ? 0 : sv > sh ? 1 : 2;\n direction[i] = dir;\n for (let c = 0; c < 3; c++) {\n const a = rgb[0]![3 * i + c]!, b = rgb[1]![3 * i + c]!;\n out[3 * i + c] = dir === 0 ? a : dir === 1 ? b : (a + b) / 2;\n }\n }\n yield;\n }\n return { width: W, height: H, data: out, direction, provenance: processingProvenance(\"ahd-demosaic-hirakawa-parks-2005\", [\n \"Directional green with the 5-tap filter [-1/4, 1/2, 1/2, 1/2, -1/4]; red/blue from bilinear colour differences.\",\n \"Homogeneity in CIELAB of the declared camera-to-XYZ matrix over the 4-neighbourhood, summed over 3x3; ties average.\",\n \"The paper's iterative median artifact reduction is not applied.\",\n \"Non-linear adaptive reconstruction; not a calibrated or manufacturer demosaic.\"]) };\n }\n });\n}\n"]}
|
|
1
|
+
{"version":3,"file":"demosaic.js","sourceRoot":"","sources":["../../src/processing/demosaic.ts"],"names":[],"mappings":"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,CAAC,CAAE,CAAC,IAAI,CAAC,CAAC;oBAChH,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC,GAAG,EAAE,CAAE,CAAC,EAAE,IAAI,GAAG,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,CAAE,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,CAAE,CAAC,IAAI,CAAC,CAAC;oBAChH,MAAM,EAAE,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAE,EAAE,EAAE,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAE,EAAE,EAAE,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAE,CAAC;oBACtE,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC,GAAG,EAAE,CAAE,CAAC,EAAE,IAAI,GAAG,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,CAAE,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,CAAE,CAAC,IAAI,CAAC,CAAC;oBAChH,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC,GAAG,EAAE,CAAE,CAAC,EAAE,IAAI,GAAG,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,CAAE,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,CAAE,CAAC,IAAI,CAAC,CAAC;oBAChH,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC,GAAG,EAAE,CAAE,CAAC,EAAE,IAAI,GAAG,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,CAAE,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,CAAE,CAAC,IAAI,CAAC,CAAC;oBAChH,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC,GAAG,EAAE,CAAE,CAAC,EAAE,IAAI,GAAG,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,CAAE,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,CAAE,CAAC,IAAI,CAAC,CAAC;oBAChH,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;oBAClE,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;oBAClE,IAAI,KAAK,GAAG,CAAC,CAAC;oBACd,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI;wBAAE,KAAK,EAAE,CAAC;oBAAC,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI;wBAAE,KAAK,EAAE,CAAC;oBAAC,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI;wBAAE,KAAK,EAAE,CAAC;oBAAC,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI;wBAAE,KAAK,EAAE,CAAC;oBAC3K,IAAI,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC;oBACpB,KAAK,GAAG,CAAC,CAAC;oBACV,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI;wBAAE,KAAK,EAAE,CAAC;oBAAC,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI;wBAAE,KAAK,EAAE,CAAC;oBAAC,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI;wBAAE,KAAK,EAAE,CAAC;oBAAC,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI;wBAAE,KAAK,EAAE,CAAC;oBAC3K,IAAI,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC;gBACtB,CAAC;gBACD,KAAK,CAAC;YACR,CAAC;YACD,mDAAmD;YACnD,MAAM,GAAG,GAAG,IAAI,YAAY,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,SAAS,GAAG,IAAI,UAAU,CAAC,CAAC,CAAC,EAAE,EAAE,GAAG,IAAI,CAAC,CAAC,CAAE,EAAE,EAAE,GAAG,IAAI,CAAC,CAAC,CAAE,EAAE,IAAI,GAAG,GAAG,CAAC,CAAC,CAAE,EAAE,IAAI,GAAG,GAAG,CAAC,CAAC,CAAE,CAAC;YACjI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC3B,MAAM,WAAW,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;gBACxC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;oBAC3B,IAAI,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;oBACnB,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;oBACpB,IAAI,WAAW,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;wBACvC,KAAK,IAAI,EAAE,GAAG,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC;4BAAC,MAAM,GAAG,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;4BAAC,KAAK,IAAI,EAAE,GAAG,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC;gCAAC,MAAM,CAAC,GAAG,GAAG,GAAG,EAAE,CAAC;gCAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAE,CAAC;gCAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAE,CAAC;4BAAC,CAAC;wBAAC,CAAC;oBACnJ,CAAC;yBAAM,CAAC;wBACN,KAAK,IAAI,EAAE,GAAG,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE,EAAE;4BAAE,KAAK,IAAI,EAAE,GAAG,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC;gCACjE,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC;gCACtD,EAAE,IAAI,EAAE,CAAC,CAAC,CAAE,CAAC;gCAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAE,CAAC;4BAC7B,CAAC;oBACH,CAAC;oBACD,MAAM,GAAG,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;oBAC1C,SAAS,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC;oBACnB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;wBAC3B,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAE,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAE,CAAC;wBACjD,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;oBAC/D,CAAC;gBACH,CAAC;gBACD,KAAK,CAAC;YACR,CAAC;YACD,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,SAAS,EAAE,UAAU,EAAE,oBAAoB,CAAC,kCAAkC,EAAE;oBACvH,iHAAiH;oBACjH,qHAAqH;oBACrH,iEAAiE;oBACjE,gFAAgF;iBAAC,CAAC,EAAE,CAAC;QACzF,CAAC;KACF,CAAC,CAAC;AACL,CAAC","sourcesContent":["// SPDX-License-Identifier: Apache-2.0\n\n/**\n * Demosaicing: rebuilds full colour from a CFA (colour filter array) mosaic. Works on a linear mosaic\n * plane stored in typed arrays, for example black-subtracted normalized RAW values or a merged HDR\n * mosaic.\n * - `createCfaPlaneReconstructionTask` runs explicit linear kernels, one per CFA phase. It uses the\n * existing `explicit-linear-native-neighborhood` contract, including the built-in bilinear\n * factory. Borders either reject or mirror (reflect-101). The summation order is\n * the same as `calculateRawReconstructionChannel`, so values match the reference resolver exactly\n * before float32 storage.\n * - `createAhdDemosaicTask` is a separate, non-linear, adaptive method: adaptive\n * homogeneity-directed (AHD) demosaicing after Hirakawa & Parks (2005). It never claims to be a\n * linear kernel.\n * @see docs/PROCESSING.md for equations, sources and approximation status.\n */\n\nimport { InvalidConfigurationError } from \"../core/configuration-error.js\";\nimport { InvalidScientificInputError } from \"../core/validation.js\";\nimport { parseMatrix3x3, type ColorMatrix3x3 } from \"../color/colorimetry-math.js\";\nimport { resolveRgbColorSpace } from \"../color/rgb-color-spaces.js\";\nimport { parseSensorColorSamplingProfile, type SensorColorSamplingProfile } from \"../sensor/color-sampling.js\";\nimport { rawReconstructionKernelReach, validateMirrorBorderCfaConsistency, type RawReconstructionBorderHandling } from \"../sensor/raw-reconstruction.js\";\nimport { parseRawReconstructionPhaseProfiles, type RawFrameReconstructionPhaseProfile } from \"../capture/raw-frame-reconstruction.js\";\nimport { reflect } from \"./image-ops.js\";\nimport {\n createProcessingTask, finiteRows, maximumWorkingBytes, processingProvenance, requireEnum, requireIntegerIn, requireOptions,\n PROCESSING_MAX_PIXELS, type ProcessingBody, type ProcessingProvenance, type ProcessingProvider, type ProcessingRgbImage, type ProcessingTask\n} from \"./processing-task.js\";\n\n/** A single-channel linear CFA mosaic in absolute native site coordinates (row-major, +Y down). */\nexport interface CfaMosaicPlane {\n width: number;\n height: number;\n captureModeId: string;\n /** Periodic mosaic anchored at site (0, 0) of this plane. */\n colorSamplingProfile: SensorColorSamplingProfile;\n /** Linear values, e.g. black-subtracted normalized RAW or merged HDR radiance. */\n samples: Float32Array;\n}\n\nexport interface CfaPlaneReconstructionInput {\n plane: CfaMosaicPlane;\n phaseProfiles: readonly RawFrameReconstructionPhaseProfile[];\n /** Default `reject`: every neighbourhood must lie inside the plane. */\n borderHandling?: RawReconstructionBorderHandling;\n /** Output region in plane coordinates; default the whole plane. */\n region?: { x: number; y: number; width: number; height: number };\n maximumWorkingBytes?: number;\n}\n\nexport interface CfaPlaneReconstructionOutput {\n width: number;\n height: number;\n region: { x: number; y: number; width: number; height: number };\n channelIds: readonly string[];\n /** Interleaved `channelIds.length` channels, row-major over the region. */\n data: Float32Array;\n borderHandling: RawReconstructionBorderHandling;\n provenance: ProcessingProvenance;\n}\n\ninterface ParsedPlane { width: number; height: number; cfa: SensorColorSamplingProfile; rw: number; rh: number; ids: readonly string[]; samples: Float32Array; modeId: string }\n\nfunction parsePlane(value: unknown, label: string): ParsedPlane {\n const r = requireOptions(value, [\"width\", \"height\", \"captureModeId\", \"colorSamplingProfile\", \"samples\"], label);\n const width = requireIntegerIn(r.width, label + \".width\", 1, PROCESSING_MAX_PIXELS), height = requireIntegerIn(r.height, label + \".height\", 1, PROCESSING_MAX_PIXELS);\n if (width * height > PROCESSING_MAX_PIXELS) throw new InvalidConfigurationError(label + \" exceeds \" + PROCESSING_MAX_PIXELS + \" sites.\");\n if (typeof r.captureModeId !== \"string\" || r.captureModeId.length === 0) throw new InvalidConfigurationError(label + \".captureModeId must be a non-empty string.\");\n const cfa = parseSensorColorSamplingProfile(r.colorSamplingProfile), layout = cfa.layout;\n if (layout.kind !== \"periodic-mosaic\") throw new InvalidConfigurationError(label + \" requires a periodic mosaic colour-sampling profile.\");\n if (!(r.samples instanceof Float32Array) || r.samples.length !== width * height) throw new InvalidConfigurationError(label + \".samples must be a Float32Array of width·height values.\");\n return { width, height, cfa, rw: layout.repeatWidthSites, rh: layout.repeatHeightSites, ids: layout.siteChannelIds, samples: r.samples, modeId: r.captureModeId };\n}\n\n/**\n * Runs explicit linear reconstruction kernels, one per CFA phase, over a typed CFA plane.\n * - With `mirror` borders, a site outside the plane is read from its mirrored (reflect-101) position.\n * This is accepted only if the mirrored site has the same CFA channel, which is always true for a\n * 2×2 Bayer pattern.\n * - With `reject`, out-of-plane reads throw (fail closed), like the reference resolver.\n * Values are linear and signed. No clamping, white balance or colour transform is applied.\n */\nexport function createCfaPlaneReconstructionTask(input: CfaPlaneReconstructionInput, provider: ProcessingProvider): ProcessingTask<CfaPlaneReconstructionOutput> {\n const r = requireOptions(input, [\"plane\", \"phaseProfiles\", \"borderHandling\", \"region\", \"maximumWorkingBytes\"], \"createCfaPlaneReconstructionTask input\");\n const p = parsePlane(r.plane, \"plane\"), border = requireEnum(r.borderHandling, [\"reject\", \"mirror\"] as const, \"borderHandling\", \"reject\");\n const phases = parseRawReconstructionPhaseProfiles(r.phaseProfiles, p.modeId, p.cfa);\n const reg = r.region === undefined ? { x: 0, y: 0, width: p.width, height: p.height } : ((): { x: number; y: number; width: number; height: number } => {\n const g = requireOptions(r.region, [\"x\", \"y\", \"width\", \"height\"], \"region\");\n return { x: requireIntegerIn(g.x, \"region.x\", 0, p.width - 1), y: requireIntegerIn(g.y, \"region.y\", 0, p.height - 1),\n width: requireIntegerIn(g.width, \"region.width\", 1, p.width), height: requireIntegerIn(g.height, \"region.height\", 1, p.height) };\n })();\n if (reg.x + reg.width > p.width || reg.y + reg.height > p.height) throw new InvalidConfigurationError(\"region must lie inside the plane.\");\n const reach = rawReconstructionKernelReach(phases), channels = phases[0]!.profile.kernels.length;\n // Kernel source channels must match the periodic CFA at every (virtual) contribution site.\n for (const phase of phases) for (const k of phase.profile.kernels) for (const c of k.contributions) {\n const x = phase.phaseX + c.offsetX, y = phase.phaseY + c.offsetY;\n if (p.ids[((y % p.rh) + p.rh) % p.rh * p.rw + ((x % p.rw) + p.rw) % p.rw] !== c.sourceChannelId) {\n throw new InvalidConfigurationError(\"Reconstruction source channel disagrees with absolute CFA phase.\");\n }\n }\n if (border === \"mirror\") validateMirrorBorderCfaConsistency({ repeatWidthSites: p.rw, repeatHeightSites: p.rh, siteChannelIds: p.ids }, p.width, p.height, reach);\n else {\n // Exact check of the pixels within `reach` of a plane edge; only their phases' offsets matter.\n const near = (x: number, y: number): boolean => x < reach || y < reach || x + reach >= p.width || y + reach >= p.height;\n for (let y = reg.y; y < reg.y + reg.height; y++) for (let x = reg.x; x < reg.x + reg.width; x++) {\n if (!near(x, y)) { x = Math.max(x, p.width - reach - 1); continue; }\n for (const k of phases[(y % p.rh) * p.rw + x % p.rw]!.profile.kernels) for (const c of k.contributions) {\n if (x + c.offsetX < 0 || y + c.offsetY < 0 || x + c.offsetX >= p.width || y + c.offsetY >= p.height) {\n throw new InvalidConfigurationError(\"Reconstruction neighbourhood leaves the plane; use a smaller region or mirror border handling.\");\n }\n }\n }\n }\n const flat = phases.map((phase) => phase.profile.kernels.map((k) => ({\n dx: Int32Array.from(k.contributions, (c) => c.offsetX), dy: Int32Array.from(k.contributions, (c) => c.offsetY),\n delta: Int32Array.from(k.contributions, (c) => c.offsetY * p.width + c.offsetX), w: Float64Array.from(k.contributions, (c) => c.weight) })));\n const outBytes = reg.width * reg.height * channels * 4;\n return createProcessingTask({\n provider, totalTileCount: p.height + reg.height, estimatedWorkingBytes: outBytes, maximumWorkingBytes: maximumWorkingBytes(r.maximumWorkingBytes),\n body: function* (): ProcessingBody<CfaPlaneReconstructionOutput> {\n yield* finiteRows(p.samples, p.width, p.height, 1, \"plane\");\n const out = new Float32Array(reg.width * reg.height * channels), s = p.samples, w = p.width;\n for (let y = reg.y, o = 0; y < reg.y + reg.height; y++) {\n for (let x = reg.x; x < reg.x + reg.width; x++) {\n const kernels = flat[(y % p.rh) * p.rw + x % p.rw]!, centre = y * w + x;\n const interior = x >= reach && y >= reach && x + reach < w && y + reach < p.height;\n for (const k of kernels) {\n let v = 0;\n if (interior) for (let j = 0; j < k.w.length; j++) v += s[centre + k.delta[j]!]! * k.w[j]!;\n else for (let j = 0; j < k.w.length; j++) v += s[reflect(y + k.dy[j]!, p.height) * w + reflect(x + k.dx[j]!, w)]! * k.w[j]!;\n out[o++] = v;\n }\n }\n yield;\n }\n return { width: reg.width, height: reg.height, region: reg, channelIds: phases[0]!.profile.kernels.map((k) => k.outputChannelId), data: out,\n borderHandling: border, provenance: processingProvenance(\"cfa-plane-linear-reconstruction\", [\n \"Explicit per-phase linear kernels, summed in declared contribution order; values are linear, signed and unclamped.\",\n border === \"mirror\" ? \"Sites outside the plane are read at their reflect-101 mirror image, which keeps the CFA channel.\" :\n \"Every neighbourhood lies inside the plane; no padding or renormalization.\",\n \"No white balance, colour transform, sharpening or denoising.\"]) };\n }\n });\n}\n\n// ------------------------------------------------------------------ AHD\n\nexport interface AhdDemosaicInput {\n plane: CfaMosaicPlane;\n /** CFA channel ids of the red, green and blue sites; output order is red, green, blue. */\n channelRoles: { red: string; green: string; blue: string };\n /**\n * Camera-linear RGB → CIE XYZ, used only for the homogeneity metric (in CIELAB). Default: the\n * sRGB/D65 matrix, so the plane is treated as linear sRGB for the metric. Output values are never\n * transformed.\n */\n cameraToXyz?: ColorMatrix3x3;\n maximumWorkingBytes?: number;\n}\n\nexport interface AhdDemosaicOutput extends ProcessingRgbImage {\n /** Per pixel: 0 horizontal, 1 vertical, 2 equal homogeneity (average of both). */\n direction: Uint8Array;\n provenance: ProcessingProvenance;\n}\n\n/**\n * Adaptive homogeneity-directed (AHD) demosaicing after Hirakawa & Parks, IEEE TIP 14(3), 2005:\n * 1. green is interpolated separately along rows and columns with the 5-tap directional filter\n * [−1/4, 1/2, 1/2, 1/2, −1/4] (bilinear green plus the own-channel second difference);\n * 2. red and blue are filled from bilinearly interpolated colour differences (R−G, B−G) against each\n * directional green, giving two full-colour candidates;\n * 3. both candidates are converted to CIELAB. At each pixel, the homogeneity is the number of\n * 4-neighbours within adaptive luminance and chrominance tolerances ε_L, ε_C. Each tolerance is the\n * smaller of the two directions' largest differences along their own direction;\n * 4. homogeneity is summed over 3×3, and the more homogeneous candidate is chosen (a tie averages\n * both).\n * The paper's optional iterative median step for reducing artifacts is not applied. Mirrored\n * (reflect-101) borders keep each site's Bayer channel. The method is non-linear: the output is not a\n * linear function of the mosaic.\n */\nexport function createAhdDemosaicTask(input: AhdDemosaicInput, provider: ProcessingProvider): ProcessingTask<AhdDemosaicOutput> {\n const r = requireOptions(input, [\"plane\", \"channelRoles\", \"cameraToXyz\", \"maximumWorkingBytes\"], \"createAhdDemosaicTask input\");\n const p = parsePlane(r.plane, \"plane\");\n const roles = requireOptions(r.channelRoles, [\"red\", \"green\", \"blue\"], \"channelRoles\");\n const ids = [roles.red, roles.green, roles.blue];\n if (ids.some((id) => typeof id !== \"string\") || new Set(ids).size !== 3) throw new InvalidConfigurationError(\"channelRoles must name three distinct channels.\");\n if (p.rw !== 2 || p.rh !== 2) throw new InvalidScientificInputError(\"AHD requires a 2×2 Bayer mosaic.\");\n const tile = p.ids.map((id) => ids.indexOf(id));\n const bayer = (g: readonly number[], c: readonly number[]): boolean => tile[g[0]!] === 1 && tile[g[1]!] === 1 && tile[c[0]!]! + tile[c[1]!]! === 2 && tile[c[0]!] !== 1;\n if (!bayer([0, 3], [1, 2]) && !bayer([1, 2], [0, 3])) {\n throw new InvalidScientificInputError(\"AHD requires one red, one blue and two diagonal green sites.\");\n }\n if (p.width < 3 || p.height < 3) throw new InvalidScientificInputError(\"AHD requires at least a 3×3 mosaic.\");\n const m = r.cameraToXyz === undefined ? resolveRgbColorSpace(\"srgb\").value.rgbToXyz : parseMatrix3x3(r.cameraToXyz, \"cameraToXyz\");\n const white = [0, 1, 2].map((i) => m[i]![0] + m[i]![1] + m[i]![2]);\n if (white.some((v) => !(v > 0))) throw new InvalidScientificInputError(\"cameraToXyz must map camera white (1,1,1) to positive XYZ.\");\n const n = p.width * p.height;\n const bytes = n * (4 * 2 + 4 * 3 * 2 + 4 * 3 * 2 + 2 + 3 * 4 + 1);\n return createProcessingTask({\n provider, totalTileCount: 6 * p.height, estimatedWorkingBytes: bytes, maximumWorkingBytes: maximumWorkingBytes(r.maximumWorkingBytes),\n body: function* (): ProcessingBody<AhdDemosaicOutput> {\n yield* finiteRows(p.samples, p.width, p.height, 1, \"plane\");\n const W = p.width, H = p.height, s = p.samples;\n const roleAt = (x: number, y: number): number => tile[(y & 1) * 2 + (x & 1)]!;\n const at = (x: number, y: number): number => s[reflect(y, H) * W + reflect(x, W)]!;\n // Sites whose neighbourhood lies inside the plane (two sites from the edge for stage 1, one for stages 2, 4\n // and 5) read their neighbours by direct index offsets; reflect() returns its argument there, so they address\n // the same samples as the border path. Every floating-point expression keeps the operands, order and grouping\n // of the border path, so both paths give bit-identical results (test/processing-ahd-exactness.test.ts).\n // 1. Directional greens.\n const gh = new Float32Array(n), gv = new Float32Array(n);\n for (let y = 0; y < H; y++) {\n const interiorRow = y >= 2 && y + 2 < H;\n for (let x = 0; x < W; x++) {\n const i = y * W + x, c = s[i]!;\n if (roleAt(x, y) === 1) { gh[i] = c; gv[i] = c; continue; }\n if (interiorRow && x >= 2 && x + 2 < W) {\n gh[i] = (s[i - 1]! + s[i + 1]!) / 2 + (2 * c - s[i - 2]! - s[i + 2]!) / 4;\n gv[i] = (s[i - W]! + s[i + W]!) / 2 + (2 * c - s[i - 2 * W]! - s[i + 2 * W]!) / 4;\n } else {\n gh[i] = (at(x - 1, y) + at(x + 1, y)) / 2 + (2 * c - at(x - 2, y) - at(x + 2, y)) / 4;\n gv[i] = (at(x, y - 1) + at(x, y + 1)) / 2 + (2 * c - at(x, y - 2) - at(x, y + 2)) / 4;\n }\n }\n yield;\n }\n // 2. Two full-colour candidates from colour differences.\n const rgb = [new Float32Array(3 * n), new Float32Array(3 * n)], greens = [gh, gv];\n for (let y = 0; y < H; y++) {\n const interiorRow = y >= 1 && y + 1 < H;\n for (let x = 0; x < W; x++) {\n const i = y * W + x, own = roleAt(x, y), interior = interiorRow && x >= 1 && x + 1 < W;\n for (let d = 0; d < 2; d++) {\n const g = greens[d]!, out = rgb[d]!, gi = g[i]!;\n out[3 * i + 1] = gi;\n if (own === 1) {\n const hRole = roleAt(x + 1, y), vRole = 2 - hRole;\n if (interior) {\n out[3 * i + hRole] = gi + ((s[i - 1]! - g[i - 1]!) + (s[i + 1]! - g[i + 1]!)) / 2;\n out[3 * i + vRole] = gi + ((s[i - W]! - g[i - W]!) + (s[i + W]! - g[i + W]!)) / 2;\n } else {\n let j = reflect(y, H) * W + reflect(x - 1, W); const a = s[j]! - g[j]!;\n j = reflect(y, H) * W + reflect(x + 1, W); const b = s[j]! - g[j]!;\n out[3 * i + hRole] = gi + (a + b) / 2;\n j = reflect(y - 1, H) * W + reflect(x, W); const cc = s[j]! - g[j]!;\n j = reflect(y + 1, H) * W + reflect(x, W); const dd = s[j]! - g[j]!;\n out[3 * i + vRole] = gi + (cc + dd) / 2;\n }\n } else {\n out[3 * i + own] = s[i]!;\n if (interior) {\n out[3 * i + 2 - own] = gi + ((s[i - W - 1]! - g[i - W - 1]!) + (s[i - W + 1]! - g[i - W + 1]!) + (s[i + W - 1]! - g[i + W - 1]!) + (s[i + W + 1]! - g[i + W + 1]!)) / 4;\n } else {\n const ym = reflect(y - 1, H) * W, yp = reflect(y + 1, H) * W, xm = reflect(x - 1, W), xp = reflect(x + 1, W);\n out[3 * i + 2 - own] = gi + ((s[ym + xm]! - g[ym + xm]!) + (s[ym + xp]! - g[ym + xp]!) + (s[yp + xm]! - g[yp + xm]!) + (s[yp + xp]! - g[yp + xp]!)) / 4;\n }\n }\n }\n }\n yield;\n }\n // 3. CIELAB (W3C CSS Color 4 Lab definition; also CIE 15) of both candidates.\n const lab = [new Float32Array(3 * n), new Float32Array(3 * n)];\n const f = (t: number): number => t > 216 / 24389 ? Math.cbrt(t) : (24389 / 27 * t + 16) / 116;\n const m00 = m[0][0], m01 = m[0][1], m02 = m[0][2], m10 = m[1][0], m11 = m[1][1], m12 = m[1][2], m20 = m[2][0], m21 = m[2][1], m22 = m[2][2];\n const w0 = white[0]!, w1 = white[1]!, w2 = white[2]!;\n for (let y = 0; y < H; y++) {\n for (let i = y * W; i < (y + 1) * W; i++) for (let d = 0; d < 2; d++) {\n const c = rgb[d]!, R = c[3 * i]!, G = c[3 * i + 1]!, B = c[3 * i + 2]!;\n const fx = f((m00 * R + m01 * G + m02 * B) / w0), fy = f((m10 * R + m11 * G + m12 * B) / w1);\n const fz = f((m20 * R + m21 * G + m22 * B) / w2), o = lab[d]!;\n o[3 * i] = 116 * fy - 16; o[3 * i + 1] = 500 * (fx - fy); o[3 * i + 2] = 200 * (fy - fz);\n }\n yield;\n }\n // 4. Homogeneity maps with adaptive tolerances.\n const homo = [new Uint8Array(n), new Uint8Array(n)], lab0 = lab[0]!, lab1 = lab[1]!;\n for (let y = 0; y < H; y++) {\n const interiorRow = y >= 1 && y + 1 < H;\n for (let x = 0; x < W; x++) {\n const i = y * W + x;\n let jl: number, jr: number, ju: number, jd: number;\n if (interiorRow && x >= 1 && x + 1 < W) { jl = i - 1; jr = i + 1; ju = i - W; jd = i + W; }\n else { const row = reflect(y, H) * W, col = reflect(x, W); jl = row + reflect(x - 1, W); jr = row + reflect(x + 1, W); ju = reflect(y - 1, H) * W + col; jd = reflect(y + 1, H) * W + col; }\n // Direction 0 (lab0), neighbours left, right, up, down (the N4 order).\n const L0 = lab0[3 * i]!, a0 = lab0[3 * i + 1]!, b0 = lab0[3 * i + 2]!;\n const dL00 = Math.abs(L0 - lab0[3 * jl]!), dC00 = (a0 - lab0[3 * jl + 1]!) ** 2 + (b0 - lab0[3 * jl + 2]!) ** 2;\n const dL01 = Math.abs(L0 - lab0[3 * jr]!), dC01 = (a0 - lab0[3 * jr + 1]!) ** 2 + (b0 - lab0[3 * jr + 2]!) ** 2;\n const dL02 = Math.abs(L0 - lab0[3 * ju]!), dC02 = (a0 - lab0[3 * ju + 1]!) ** 2 + (b0 - lab0[3 * ju + 2]!) ** 2;\n const dL03 = Math.abs(L0 - lab0[3 * jd]!), dC03 = (a0 - lab0[3 * jd + 1]!) ** 2 + (b0 - lab0[3 * jd + 2]!) ** 2;\n const L1 = lab1[3 * i]!, a1 = lab1[3 * i + 1]!, b1 = lab1[3 * i + 2]!;\n const dL10 = Math.abs(L1 - lab1[3 * jl]!), dC10 = (a1 - lab1[3 * jl + 1]!) ** 2 + (b1 - lab1[3 * jl + 2]!) ** 2;\n const dL11 = Math.abs(L1 - lab1[3 * jr]!), dC11 = (a1 - lab1[3 * jr + 1]!) ** 2 + (b1 - lab1[3 * jr + 2]!) ** 2;\n const dL12 = Math.abs(L1 - lab1[3 * ju]!), dC12 = (a1 - lab1[3 * ju + 1]!) ** 2 + (b1 - lab1[3 * ju + 2]!) ** 2;\n const dL13 = Math.abs(L1 - lab1[3 * jd]!), dC13 = (a1 - lab1[3 * jd + 1]!) ** 2 + (b1 - lab1[3 * jd + 2]!) ** 2;\n const epsL = Math.min(Math.max(dL00, dL01), Math.max(dL12, dL13));\n const epsC = Math.min(Math.max(dC00, dC01), Math.max(dC12, dC13));\n let count = 0;\n if (dL00 <= epsL && dC00 <= epsC) count++; if (dL01 <= epsL && dC01 <= epsC) count++; if (dL02 <= epsL && dC02 <= epsC) count++; if (dL03 <= epsL && dC03 <= epsC) count++;\n homo[0]![i] = count;\n count = 0;\n if (dL10 <= epsL && dC10 <= epsC) count++; if (dL11 <= epsL && dC11 <= epsC) count++; if (dL12 <= epsL && dC12 <= epsC) count++; if (dL13 <= epsL && dC13 <= epsC) count++;\n homo[1]![i] = count;\n }\n yield;\n }\n // 5. 3×3 summed homogeneity selects the candidate.\n const out = new Float32Array(3 * n), direction = new Uint8Array(n), h0 = homo[0]!, h1 = homo[1]!, rgb0 = rgb[0]!, rgb1 = rgb[1]!;\n for (let y = 0; y < H; y++) {\n const interiorRow = y >= 1 && y + 1 < H;\n for (let x = 0; x < W; x++) {\n let sh = 0, sv = 0;\n const i = y * W + x;\n if (interiorRow && x >= 1 && x + 1 < W) {\n for (let dy = -1; dy <= 1; dy++) { const row = i + dy * W; for (let dx = -1; dx <= 1; dx++) { const j = row + dx; sh += h0[j]!; sv += h1[j]!; } }\n } else {\n for (let dy = -1; dy <= 1; dy++) for (let dx = -1; dx <= 1; dx++) {\n const j = reflect(y + dy, H) * W + reflect(x + dx, W);\n sh += h0[j]!; sv += h1[j]!;\n }\n }\n const dir = sh > sv ? 0 : sv > sh ? 1 : 2;\n direction[i] = dir;\n for (let c = 0; c < 3; c++) {\n const a = rgb0[3 * i + c]!, b = rgb1[3 * i + c]!;\n out[3 * i + c] = dir === 0 ? a : dir === 1 ? b : (a + b) / 2;\n }\n }\n yield;\n }\n return { width: W, height: H, data: out, direction, provenance: processingProvenance(\"ahd-demosaic-hirakawa-parks-2005\", [\n \"Directional green with the 5-tap filter [-1/4, 1/2, 1/2, 1/2, -1/4]; red/blue from bilinear colour differences.\",\n \"Homogeneity in CIELAB of the declared camera-to-XYZ matrix over the 4-neighbourhood, summed over 3x3; ties average.\",\n \"The paper's iterative median artifact reduction is not applied.\",\n \"Non-linear adaptive reconstruction; not a calibrated or manufacturer demosaic.\"]) };\n }\n });\n}\n"]}
|
|
@@ -192,6 +192,14 @@ export interface ValidatedSceneRadianceRecords {
|
|
|
192
192
|
* passed the full parse. Any other result takes the full parse.
|
|
193
193
|
*/
|
|
194
194
|
export declare function parseSceneRadianceEvaluationResultWithValidatedRecords(value: unknown, validated: ValidatedSceneRadianceRecords): SceneRadianceEvaluationResult;
|
|
195
|
+
/**
|
|
196
|
+
* Internal (#453; not exported from the package): the request and result checks of
|
|
197
|
+
* {@link validateSceneRadianceEvaluationBindings} (the request against the three profiles, a surface target's material, and
|
|
198
|
+
* the result against the request), with its messages and order. The profile-to-profile checks before them depend only on the
|
|
199
|
+
* profiles; an engine caller that has run the full function once for these profile objects may run only this part for
|
|
200
|
+
* further requests and results.
|
|
201
|
+
*/
|
|
202
|
+
export declare function validateSceneRadianceRequestResultBindings(providerProfile: ValidateSceneRadianceEvaluationBindingsInput["providerProfile"], illuminationProfile: ValidateSceneRadianceEvaluationBindingsInput["illuminationProfile"], materialResponseProfile: ValidateSceneRadianceEvaluationBindingsInput["materialResponseProfile"], request: ValidateSceneRadianceEvaluationBindingsInput["request"], result: ValidateSceneRadianceEvaluationBindingsInput["result"]): void;
|
|
195
203
|
/**
|
|
196
204
|
* Checks that a provider result matches its request and profile identities exactly.
|
|
197
205
|
*
|