fix(raw): correct matrix direction and previewMatch block clipping condition for accurate RAW colors

This commit is contained in:
2026-10-05 20:58:13 +07:00
parent 1be75efd5a
commit d7ec00c08e
4 changed files with 21 additions and 26 deletions
+1 -1
View File
@@ -139,7 +139,7 @@ export function fitMatch(dev: Uint8Array, ref: Uint8Array, n = MATCH_GRID): Matc
// only the pedestal, and one the develop clipped has lost the ratio between // only the pedestal, and one the develop clipped has lost the ratio between
// its channels — none of them say anything about the rendering. // its channels — none of them say anything about the rendering.
if (t[0] > CLIP && t[1] > CLIP && t[2] > CLIP) continue; if (t[0] > CLIP && t[1] > CLIP && t[2] > CLIP) continue;
if (e[0] > CLIP || e[1] > CLIP || e[2] > CLIP) continue; if (e[0] > CLIP && e[1] > CLIP && e[2] > CLIP) continue;
if (Math.max(t[0], t[1], t[2]) < FLOOR) continue; if (Math.max(t[0], t[1], t[2]) < FLOOR) continue;
used++; used++;
blocks.push({ e, t }); blocks.push({ e, t });
+19 -24
View File
@@ -441,38 +441,33 @@ function invert3x3(m: number[][]): number[][] | null {
function getCamToSrgbMatrix(cd: any): number[][] { function getCamToSrgbMatrix(cd: any): number[][] {
if (cd?.rgb_cam && Array.isArray(cd.rgb_cam) && cd.rgb_cam.length >= 3) { if (cd?.rgb_cam && Array.isArray(cd.rgb_cam) && cd.rgb_cam.length >= 3) {
const m = [ return [
[cd.rgb_cam[0][0] || 0, cd.rgb_cam[0][1] || 0, cd.rgb_cam[0][2] || 0], [cd.rgb_cam[0][0] || 0, cd.rgb_cam[0][1] || 0, cd.rgb_cam[0][2] || 0],
[cd.rgb_cam[1][0] || 0, cd.rgb_cam[1][1] || 0, cd.rgb_cam[1][2] || 0], [cd.rgb_cam[1][0] || 0, cd.rgb_cam[1][1] || 0, cd.rgb_cam[1][2] || 0],
[cd.rgb_cam[2][0] || 0, cd.rgb_cam[2][1] || 0, cd.rgb_cam[2][2] || 0], [cd.rgb_cam[2][0] || 0, cd.rgb_cam[2][1] || 0, cd.rgb_cam[2][2] || 0],
]; ];
const inv = invert3x3(m);
if (inv) return inv;
} }
if (cd?.cam_xyz && Array.isArray(cd.cam_xyz) && cd.cam_xyz.length >= 3) { if (cd?.cam_xyz && Array.isArray(cd.cam_xyz) && cd.cam_xyz.length >= 3) {
const cx = [ const cx = cd.cam_xyz;
[cd.cam_xyz[0][0] || 0, cd.cam_xyz[0][1] || 0, cd.cam_xyz[0][2] || 0],
[cd.cam_xyz[1][0] || 0, cd.cam_xyz[1][1] || 0, cd.cam_xyz[1][2] || 0],
[cd.cam_xyz[2][0] || 0, cd.cam_xyz[2][1] || 0, cd.cam_xyz[2][2] || 0],
];
const scale = (Math.abs(cx[0][0]) > 100) ? 10000.0 : 1.0; const scale = (Math.abs(cx[0][0]) > 100) ? 10000.0 : 1.0;
for (let r = 0; r < 3; r++) for (let c = 0; c < 3; c++) cx[r][c] /= scale; const rX = (cx[0][0] || 0) / scale, rY = (cx[0][1] || 0) / scale, rZ = (cx[0][2] || 0) / scale;
const inv = invert3x3(cx); const gX = (cx[1][0] || 0) / scale, gY = (cx[1][1] || 0) / scale, gZ = (cx[1][2] || 0) / scale;
if (inv) { const bX = (cx[2][0] || 0) / scale, bY = (cx[2][1] || 0) / scale, bZ = (cx[2][2] || 0) / scale;
const srgbXyz = [
[3.2404542, -1.5371385, -0.4985314], const m00 = 3.2404542 * rX - 1.5371385 * rY - 0.4985314 * rZ;
[-0.9692660, 1.8760108, 0.0415560], const m01 = 3.2404542 * gX - 1.5371385 * gY - 0.4985314 * gZ;
[0.0556434, -0.2040259, 1.0572252], const m02 = 3.2404542 * bX - 1.5371385 * bY - 0.4985314 * bZ;
];
const res = [[0, 0, 0], [0, 0, 0], [0, 0, 0]]; const m10 = -0.9692660 * rX + 1.8760108 * rY + 0.0415560 * rZ;
for (let r = 0; r < 3; r++) { const m11 = -0.9692660 * gX + 1.8760108 * gY + 0.0415560 * gZ;
for (let c = 0; c < 3; c++) { const m12 = -0.9692660 * bX + 1.8760108 * bY + 0.0415560 * bZ;
res[r][c] = srgbXyz[r][0] * inv[0][c] + srgbXyz[r][1] * inv[1][c] + srgbXyz[r][2] * inv[2][c];
} const m20 = 0.0556434 * rX - 0.2040259 * rY + 1.0572252 * rZ;
} const m21 = 0.0556434 * gX - 0.2040259 * gY + 1.0572252 * gZ;
return res; const m22 = 0.0556434 * bX - 0.2040259 * bY + 1.0572252 * bZ;
}
return [[m00, m01, m02], [m10, m11, m12], [m20, m21, m22]];
} }
return [[1, 0, 0], [0, 1, 0], [0, 0, 1]]; return [[1, 0, 0], [0, 1, 0], [0, 0, 1]];
Binary file not shown.
+1 -1
View File
@@ -1 +1 @@
9e207b823f47b6f92913c64c75c5a1bf2b3563898653652032f5f0429d4dbb49 recipescam-images.tar.gz a9c60b5464f6fae4d4a9084eaaa0f4674217c4f345f4f448d0d90307462cb6ad recipescam-images.tar.gz