@flighthq/adjustments 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/brightnessContrastAdjustment.d.ts +3 -0
- package/dist/brightnessContrastAdjustment.d.ts.map +1 -0
- package/dist/brightnessContrastAdjustment.js +22 -0
- package/dist/brightnessContrastAdjustment.js.map +1 -0
- package/dist/channelMixerAdjustment.d.ts +3 -0
- package/dist/channelMixerAdjustment.d.ts.map +1 -0
- package/dist/channelMixerAdjustment.js +16 -0
- package/dist/channelMixerAdjustment.js.map +1 -0
- package/dist/colorAdjustmentResolution.d.ts +7 -0
- package/dist/colorAdjustmentResolution.d.ts.map +1 -0
- package/dist/colorAdjustmentResolution.js +59 -0
- package/dist/colorAdjustmentResolution.js.map +1 -0
- package/dist/colorBlindSimulationAdjustment.d.ts +3 -0
- package/dist/colorBlindSimulationAdjustment.d.ts.map +1 -0
- package/dist/colorBlindSimulationAdjustment.js +33 -0
- package/dist/colorBlindSimulationAdjustment.js.map +1 -0
- package/dist/colorGradeAdjustment.d.ts +3 -0
- package/dist/colorGradeAdjustment.d.ts.map +1 -0
- package/dist/colorGradeAdjustment.js +49 -0
- package/dist/colorGradeAdjustment.js.map +1 -0
- package/dist/colorLut.d.ts +29 -0
- package/dist/colorLut.d.ts.map +1 -0
- package/dist/colorLut.js +87 -0
- package/dist/colorLut.js.map +1 -0
- package/dist/colorLutAdjustment.d.ts +8 -0
- package/dist/colorLutAdjustment.d.ts.map +1 -0
- package/dist/colorLutAdjustment.js +30 -0
- package/dist/colorLutAdjustment.js.map +1 -0
- package/dist/colorLutCache.d.ts +6 -0
- package/dist/colorLutCache.d.ts.map +1 -0
- package/dist/colorLutCache.js +43 -0
- package/dist/colorLutCache.js.map +1 -0
- package/dist/colorMatrixAdjustment.d.ts +8 -0
- package/dist/colorMatrixAdjustment.d.ts.map +1 -0
- package/dist/colorMatrixAdjustment.js +14 -0
- package/dist/colorMatrixAdjustment.js.map +1 -0
- package/dist/colorMatrixMath.d.ts +160 -0
- package/dist/colorMatrixMath.d.ts.map +1 -0
- package/dist/colorMatrixMath.js +398 -0
- package/dist/colorMatrixMath.js.map +1 -0
- package/dist/colorTransformAdjustment.d.ts +3 -0
- package/dist/colorTransformAdjustment.d.ts.map +1 -0
- package/dist/colorTransformAdjustment.js +16 -0
- package/dist/colorTransformAdjustment.js.map +1 -0
- package/dist/exposureAdjustment.d.ts +3 -0
- package/dist/exposureAdjustment.d.ts.map +1 -0
- package/dist/exposureAdjustment.js +18 -0
- package/dist/exposureAdjustment.js.map +1 -0
- package/dist/grayscaleAdjustment.d.ts +3 -0
- package/dist/grayscaleAdjustment.d.ts.map +1 -0
- package/dist/grayscaleAdjustment.js +20 -0
- package/dist/grayscaleAdjustment.js.map +1 -0
- package/dist/hueSaturationAdjustment.d.ts +3 -0
- package/dist/hueSaturationAdjustment.d.ts.map +1 -0
- package/dist/hueSaturationAdjustment.js +62 -0
- package/dist/hueSaturationAdjustment.js.map +1 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +19 -0
- package/dist/index.js.map +1 -0
- package/dist/invertAdjustment.d.ts +3 -0
- package/dist/invertAdjustment.d.ts.map +1 -0
- package/dist/invertAdjustment.js +17 -0
- package/dist/invertAdjustment.js.map +1 -0
- package/dist/liftGammaGainAdjustment.d.ts +3 -0
- package/dist/liftGammaGainAdjustment.d.ts.map +1 -0
- package/dist/liftGammaGainAdjustment.js +29 -0
- package/dist/liftGammaGainAdjustment.js.map +1 -0
- package/dist/lookupTableGradeAdjustment.d.ts +3 -0
- package/dist/lookupTableGradeAdjustment.d.ts.map +1 -0
- package/dist/lookupTableGradeAdjustment.js +24 -0
- package/dist/lookupTableGradeAdjustment.js.map +1 -0
- package/dist/sepiaAdjustment.d.ts +3 -0
- package/dist/sepiaAdjustment.d.ts.map +1 -0
- package/dist/sepiaAdjustment.js +15 -0
- package/dist/sepiaAdjustment.js.map +1 -0
- package/package.json +37 -0
- package/src/brightnessContrastAdjustment.test.ts +23 -0
- package/src/channelMixerAdjustment.test.ts +24 -0
- package/src/colorAdjustmentResolution.test.ts +77 -0
- package/src/colorBlindSimulationAdjustment.test.ts +27 -0
- package/src/colorGradeAdjustment.test.ts +36 -0
- package/src/colorLut.test.ts +62 -0
- package/src/colorLutAdjustment.test.ts +37 -0
- package/src/colorLutCache.test.ts +61 -0
- package/src/colorMatrixAdjustment.test.ts +24 -0
- package/src/colorMatrixMath.test.ts +431 -0
- package/src/colorTransformAdjustment.test.ts +40 -0
- package/src/exposureAdjustment.test.ts +22 -0
- package/src/grayscaleAdjustment.test.ts +23 -0
- package/src/hueSaturationAdjustment.test.ts +33 -0
- package/src/invertAdjustment.test.ts +24 -0
- package/src/liftGammaGainAdjustment.test.ts +31 -0
- package/src/lookupTableGradeAdjustment.test.ts +49 -0
- package/src/sepiaAdjustment.test.ts +18 -0
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { BrightnessContrastAdjustment } from '@flighthq/types';
|
|
2
|
+
export declare function createBrightnessContrastAdjustment(options?: Readonly<Omit<BrightnessContrastAdjustment, 'kind' | 'colorMatrix'>>): BrightnessContrastAdjustment;
|
|
3
|
+
//# sourceMappingURL=brightnessContrastAdjustment.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"brightnessContrastAdjustment.d.ts","sourceRoot":"","sources":["../src/brightnessContrastAdjustment.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,iBAAiB,CAAC;AASpE,wBAAgB,kCAAkC,CAChD,OAAO,GAAE,QAAQ,CAAC,IAAI,CAAC,4BAA4B,EAAE,MAAM,GAAG,aAAa,CAAC,CAAM,GACjF,4BAA4B,CAa9B"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// Brightness/contrast as a matrix-tier adjustment. Reproduces the prior full-frame shader
|
|
2
|
+
// `rgb = (rgb + brightness − 0.5)·contrast + 0.5` (a shift by brightness, then scale about mid-grey 0.5).
|
|
3
|
+
// Expanded, that is affine per channel: `rgb·contrast + (brightness·contrast + 0.5·(1 − contrast))`, so the
|
|
4
|
+
// matrix is scale `contrast`, normalized offset `brightness·contrast + 0.5·(1 − contrast)` (×255 for the
|
|
5
|
+
// 0–255 offset column). Alpha is unchanged. Identity defaults are brightness 0, contrast 1 (the prior
|
|
6
|
+
// `renderEffectDefaults` listed `contrast: 0`, which disagreed with the shader's `contrast ?? 1` identity —
|
|
7
|
+
// this corrects it to contrast 1).
|
|
8
|
+
export function createBrightnessContrastAdjustment(options = {}) {
|
|
9
|
+
const brightness = options.brightness ?? 0;
|
|
10
|
+
const contrast = options.contrast ?? 1;
|
|
11
|
+
const s = contrast;
|
|
12
|
+
const o = 255 * (brightness * contrast + 0.5 * (1 - contrast));
|
|
13
|
+
// prettier-ignore
|
|
14
|
+
const colorMatrix = [
|
|
15
|
+
s, 0, 0, 0, o,
|
|
16
|
+
0, s, 0, 0, o,
|
|
17
|
+
0, 0, s, 0, o,
|
|
18
|
+
0, 0, 0, 1, 0,
|
|
19
|
+
];
|
|
20
|
+
return { kind: 'BrightnessContrastAdjustment', ...options, colorMatrix };
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=brightnessContrastAdjustment.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"brightnessContrastAdjustment.js","sourceRoot":"","sources":["../src/brightnessContrastAdjustment.ts"],"names":[],"mappings":"AAEA,0FAA0F;AAC1F,0GAA0G;AAC1G,4GAA4G;AAC5G,yGAAyG;AACzG,sGAAsG;AACtG,4GAA4G;AAC5G,mCAAmC;AACnC,MAAM,UAAU,kCAAkC,CAChD,UAAgF,EAAE;IAElF,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,IAAI,CAAC,CAAC;IAC3C,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,CAAC,CAAC;IACvC,MAAM,CAAC,GAAG,QAAQ,CAAC;IACnB,MAAM,CAAC,GAAG,GAAG,GAAG,CAAC,UAAU,GAAG,QAAQ,GAAG,GAAG,GAAG,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC;IAC/D,kBAAkB;IAClB,MAAM,WAAW,GAAG;QAClB,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC;QACb,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC;QACb,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC;QACb,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC;KACd,CAAC;IACF,OAAO,EAAE,IAAI,EAAE,8BAA8B,EAAE,GAAG,OAAO,EAAE,WAAW,EAAE,CAAC;AAC3E,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"channelMixerAdjustment.d.ts","sourceRoot":"","sources":["../src/channelMixerAdjustment.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AAQ9D,wBAAgB,4BAA4B,CAC1C,OAAO,GAAE,QAAQ,CAAC,IAAI,CAAC,sBAAsB,EAAE,MAAM,GAAG,aAAa,CAAC,CAAsC,GAC3G,sBAAsB,CAQxB"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { createChannelMixerColorMatrix } from './colorMatrixMath';
|
|
2
|
+
// Channel mixer as a matrix-tier adjustment. `matrix` is the prior effect's 3×4 row-major RGB→RGB mix
|
|
3
|
+
// plus a per-row offset (offsets in normalized 0–1). The 3×3 mix bakes through createChannelMixerColorMatrix;
|
|
4
|
+
// the offset column is scaled to the 0–255 color-matrix convention (×255). Alpha is unchanged. The default
|
|
5
|
+
// `matrix` is the identity mix.
|
|
6
|
+
export function createChannelMixerAdjustment(options = { matrix: IDENTITY_CHANNEL_MIXER }) {
|
|
7
|
+
const matrix = options.matrix ?? IDENTITY_CHANNEL_MIXER;
|
|
8
|
+
const m = (i) => matrix[i] ?? IDENTITY_CHANNEL_MIXER[i];
|
|
9
|
+
const colorMatrix = createChannelMixerColorMatrix([m(0), m(1), m(2)], [m(4), m(5), m(6)], [m(8), m(9), m(10)]);
|
|
10
|
+
colorMatrix[4] = m(3) * 255;
|
|
11
|
+
colorMatrix[9] = m(7) * 255;
|
|
12
|
+
colorMatrix[14] = m(11) * 255;
|
|
13
|
+
return { kind: 'ChannelMixerAdjustment', ...options, matrix, colorMatrix };
|
|
14
|
+
}
|
|
15
|
+
const IDENTITY_CHANNEL_MIXER = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0];
|
|
16
|
+
//# sourceMappingURL=channelMixerAdjustment.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"channelMixerAdjustment.js","sourceRoot":"","sources":["../src/channelMixerAdjustment.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,6BAA6B,EAAE,MAAM,mBAAmB,CAAC;AAElE,sGAAsG;AACtG,8GAA8G;AAC9G,2GAA2G;AAC3G,gCAAgC;AAChC,MAAM,UAAU,4BAA4B,CAC1C,UAA0E,EAAE,MAAM,EAAE,sBAAsB,EAAE;IAE5G,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,sBAAsB,CAAC;IACxD,MAAM,CAAC,GAAG,CAAC,CAAS,EAAU,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,sBAAsB,CAAC,CAAC,CAAC,CAAC;IACxE,MAAM,WAAW,GAAG,6BAA6B,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAC/G,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC;IAC5B,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC;IAC5B,WAAW,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC;IAC9B,OAAO,EAAE,IAAI,EAAE,wBAAwB,EAAE,GAAG,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC;AAC7E,CAAC;AAED,MAAM,sBAAsB,GAAsB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Adjustment, ColorTransform } from '@flighthq/types';
|
|
2
|
+
export declare const COLOR_ADJUSTMENT_NONE = 0;
|
|
3
|
+
export declare const COLOR_ADJUSTMENT_AFFINE = 1;
|
|
4
|
+
export declare const COLOR_ADJUSTMENT_CHANNEL_MIXING = 2;
|
|
5
|
+
export declare function isAffineColorMatrix(matrix: Readonly<number[]>): boolean;
|
|
6
|
+
export declare function resolveColorAdjustmentsColorTransform(adjustments: readonly Adjustment[] | null, out: ColorTransform): number;
|
|
7
|
+
//# sourceMappingURL=colorAdjustmentResolution.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"colorAdjustmentResolution.d.ts","sourceRoot":"","sources":["../src/colorAdjustmentResolution.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAMlE,eAAO,MAAM,qBAAqB,IAAI,CAAC;AACvC,eAAO,MAAM,uBAAuB,IAAI,CAAC;AACzC,eAAO,MAAM,+BAA+B,IAAI,CAAC;AAKjD,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC,GAAG,OAAO,CAevE;AAcD,wBAAgB,qCAAqC,CACnD,WAAW,EAAE,SAAS,UAAU,EAAE,GAAG,IAAI,EACzC,GAAG,EAAE,cAAc,GAClB,MAAM,CAsBR"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { getAdjustmentColorMatrix } from './colorMatrixAdjustment';
|
|
2
|
+
import { fuseColorMatrices } from './colorMatrixMath';
|
|
3
|
+
// Resolution status of a node's color-adjustment stack against the affine inline fold.
|
|
4
|
+
export const COLOR_ADJUSTMENT_NONE = 0; // empty stack — no tint (leave `out` untouched, use null)
|
|
5
|
+
export const COLOR_ADJUSTMENT_AFFINE = 1; // fully representable as one 8-float ColorTransform
|
|
6
|
+
export const COLOR_ADJUSTMENT_CHANNEL_MIXING = 2; // off-diagonal terms present — `out` holds only the affine part
|
|
7
|
+
// True when `matrix` has no off-diagonal RGB/A coefficients, i.e. it is a per-channel scale + offset that
|
|
8
|
+
// an 8-float ColorTransform can represent exactly. A diagonal-affine matrix is `[m0,·,·,·,off, ·,m6,·,·,off,
|
|
9
|
+
// ·,·,m12,·,off, ·,·,·,m18,off]`. Fusing diagonal matrices stays diagonal, so this stays an exact zero check.
|
|
10
|
+
export function isAffineColorMatrix(matrix) {
|
|
11
|
+
return (matrix[1] === 0 &&
|
|
12
|
+
matrix[2] === 0 &&
|
|
13
|
+
matrix[3] === 0 &&
|
|
14
|
+
matrix[5] === 0 &&
|
|
15
|
+
matrix[7] === 0 &&
|
|
16
|
+
matrix[8] === 0 &&
|
|
17
|
+
matrix[10] === 0 &&
|
|
18
|
+
matrix[11] === 0 &&
|
|
19
|
+
matrix[13] === 0 &&
|
|
20
|
+
matrix[15] === 0 &&
|
|
21
|
+
matrix[16] === 0 &&
|
|
22
|
+
matrix[17] === 0);
|
|
23
|
+
}
|
|
24
|
+
// Fuses a node's color-adjustment stack into the single affine `ColorTransform` the inline fold consumes,
|
|
25
|
+
// writing per-channel multiply + 0–255 offset into `out`, and returns the resolution status:
|
|
26
|
+
//
|
|
27
|
+
// COLOR_ADJUSTMENT_NONE — empty/null stack; `out` untouched (the caller uses null → no tint).
|
|
28
|
+
// COLOR_ADJUSTMENT_AFFINE — the fused stack is diagonal-affine; `out` is exact.
|
|
29
|
+
// COLOR_ADJUSTMENT_CHANNEL_MIXING — the fused matrix carries off-diagonal channel-mixing terms
|
|
30
|
+
// (saturation/hue/sepia/channelMixer) or a non-matrix (LUT) op that the
|
|
31
|
+
// 8-float fold cannot represent yet. `out` holds only the affine part
|
|
32
|
+
// (diagonal + offset); the caller routes this to the deferral guard.
|
|
33
|
+
//
|
|
34
|
+
// A single ColorTransformAdjustment (the common per-object case) resolves exactly with no matrix multiply.
|
|
35
|
+
// Matrix-tier ops fuse order-preserving via concatColorMatrix; a non-matrix op marks the stack non-affine.
|
|
36
|
+
export function resolveColorAdjustmentsColorTransform(adjustments, out) {
|
|
37
|
+
if (adjustments === null || adjustments.length === 0)
|
|
38
|
+
return COLOR_ADJUSTMENT_NONE;
|
|
39
|
+
const matrices = [];
|
|
40
|
+
let inlineable = true;
|
|
41
|
+
for (let i = 0; i < adjustments.length; i++) {
|
|
42
|
+
const matrix = getAdjustmentColorMatrix(adjustments[i]);
|
|
43
|
+
if (matrix === null)
|
|
44
|
+
inlineable = false;
|
|
45
|
+
else
|
|
46
|
+
matrices.push(matrix);
|
|
47
|
+
}
|
|
48
|
+
const fused = fuseColorMatrices(matrices);
|
|
49
|
+
out.redMultiplier = fused[0];
|
|
50
|
+
out.greenMultiplier = fused[6];
|
|
51
|
+
out.blueMultiplier = fused[12];
|
|
52
|
+
out.alphaMultiplier = fused[18];
|
|
53
|
+
out.redOffset = fused[4];
|
|
54
|
+
out.greenOffset = fused[9];
|
|
55
|
+
out.blueOffset = fused[14];
|
|
56
|
+
out.alphaOffset = fused[19];
|
|
57
|
+
return inlineable && isAffineColorMatrix(fused) ? COLOR_ADJUSTMENT_AFFINE : COLOR_ADJUSTMENT_CHANNEL_MIXING;
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=colorAdjustmentResolution.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"colorAdjustmentResolution.js","sourceRoot":"","sources":["../src/colorAdjustmentResolution.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AACnE,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAEtD,uFAAuF;AACvF,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,CAAC,CAAC,0DAA0D;AAClG,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,CAAC,CAAC,oDAAoD;AAC9F,MAAM,CAAC,MAAM,+BAA+B,GAAG,CAAC,CAAC,CAAC,gEAAgE;AAElH,0GAA0G;AAC1G,6GAA6G;AAC7G,8GAA8G;AAC9G,MAAM,UAAU,mBAAmB,CAAC,MAA0B;IAC5D,OAAO,CACL,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC;QACf,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC;QACf,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC;QACf,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC;QACf,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC;QACf,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC;QACf,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC;QAChB,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC;QAChB,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC;QAChB,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC;QAChB,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC;QAChB,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,CACjB,CAAC;AACJ,CAAC;AAED,0GAA0G;AAC1G,6FAA6F;AAC7F,EAAE;AACF,0GAA0G;AAC1G,0FAA0F;AAC1F,iGAAiG;AACjG,4GAA4G;AAC5G,0GAA0G;AAC1G,yGAAyG;AACzG,EAAE;AACF,2GAA2G;AAC3G,2GAA2G;AAC3G,MAAM,UAAU,qCAAqC,CACnD,WAAyC,EACzC,GAAmB;IAEnB,IAAI,WAAW,KAAK,IAAI,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,qBAAqB,CAAC;IAEnF,MAAM,QAAQ,GAAyB,EAAE,CAAC;IAC1C,IAAI,UAAU,GAAG,IAAI,CAAC;IACtB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,WAAW,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAC5C,MAAM,MAAM,GAAG,wBAAwB,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC;QACxD,IAAI,MAAM,KAAK,IAAI;YAAE,UAAU,GAAG,KAAK,CAAC;;YACnC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC7B,CAAC;IAED,MAAM,KAAK,GAAG,iBAAiB,CAAC,QAAQ,CAAC,CAAC;IAC1C,GAAG,CAAC,aAAa,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IAC7B,GAAG,CAAC,eAAe,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IAC/B,GAAG,CAAC,cAAc,GAAG,KAAK,CAAC,EAAE,CAAC,CAAC;IAC/B,GAAG,CAAC,eAAe,GAAG,KAAK,CAAC,EAAE,CAAC,CAAC;IAChC,GAAG,CAAC,SAAS,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IACzB,GAAG,CAAC,WAAW,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IAC3B,GAAG,CAAC,UAAU,GAAG,KAAK,CAAC,EAAE,CAAC,CAAC;IAC3B,GAAG,CAAC,WAAW,GAAG,KAAK,CAAC,EAAE,CAAC,CAAC;IAE5B,OAAO,UAAU,IAAI,mBAAmB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,uBAAuB,CAAC,CAAC,CAAC,+BAA+B,CAAC;AAC9G,CAAC"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { ColorBlindSimulationAdjustment } from '@flighthq/types';
|
|
2
|
+
export declare function createColorBlindSimulationAdjustment(options?: Readonly<Omit<ColorBlindSimulationAdjustment, 'kind' | 'colorMatrix'>>): ColorBlindSimulationAdjustment;
|
|
3
|
+
//# sourceMappingURL=colorBlindSimulationAdjustment.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"colorBlindSimulationAdjustment.d.ts","sourceRoot":"","sources":["../src/colorBlindSimulationAdjustment.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,8BAA8B,EAAkB,MAAM,iBAAiB,CAAC;AAWtF,wBAAgB,oCAAoC,CAClD,OAAO,GAAE,QAAQ,CAAC,IAAI,CAAC,8BAA8B,EAAE,MAAM,GAAG,aAAa,CAAC,CAAM,GACnF,8BAA8B,CAWhC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
// Color-vision-deficiency simulation as a matrix-tier adjustment — this op's FIRST backend realization
|
|
2
|
+
// (it was previously a descriptor-only effect with no pass). Each type bakes a fixed linear 3×3 RGB→RGB
|
|
3
|
+
// matrix (no offset, alpha unchanged), so it fuses and folds like any color matrix.
|
|
4
|
+
//
|
|
5
|
+
// Matrices are the standard linear color-blindness simulation set from the HCIRN Color Blind Simulation
|
|
6
|
+
// function, as popularized by Matthew Wickline's "Colorblind Web Page Filter" (2000) and widely reproduced
|
|
7
|
+
// (e.g. the `color-blind` npm package). The three dichromacies (protan/deutan/tritan -opia) are the full
|
|
8
|
+
// simulations; the -omaly forms are the published partial (anomalous-trichromacy) matrices; achromatopsia
|
|
9
|
+
// is full luma monochromacy and achromatomaly its partial form.
|
|
10
|
+
export function createColorBlindSimulationAdjustment(options = {}) {
|
|
11
|
+
const type = options.type ?? 'deuteranopia';
|
|
12
|
+
const m = COLOR_BLIND_MATRICES[type];
|
|
13
|
+
// prettier-ignore
|
|
14
|
+
const colorMatrix = [
|
|
15
|
+
m[0], m[1], m[2], 0, 0,
|
|
16
|
+
m[3], m[4], m[5], 0, 0,
|
|
17
|
+
m[6], m[7], m[8], 0, 0,
|
|
18
|
+
0, 0, 0, 1, 0,
|
|
19
|
+
];
|
|
20
|
+
return { kind: 'ColorBlindSimulationAdjustment', ...options, colorMatrix };
|
|
21
|
+
}
|
|
22
|
+
// Row-major 3×3 RGB→RGB coefficients per deficiency (HCIRN / Wickline simulation set).
|
|
23
|
+
const COLOR_BLIND_MATRICES = {
|
|
24
|
+
protanopia: [0.567, 0.433, 0.0, 0.558, 0.442, 0.0, 0.0, 0.242, 0.758],
|
|
25
|
+
protanomaly: [0.817, 0.183, 0.0, 0.333, 0.667, 0.0, 0.0, 0.125, 0.875],
|
|
26
|
+
deuteranopia: [0.625, 0.375, 0.0, 0.7, 0.3, 0.0, 0.0, 0.3, 0.7],
|
|
27
|
+
deuteranomaly: [0.8, 0.2, 0.0, 0.258, 0.742, 0.0, 0.0, 0.142, 0.858],
|
|
28
|
+
tritanopia: [0.95, 0.05, 0.0, 0.0, 0.433, 0.567, 0.0, 0.475, 0.525],
|
|
29
|
+
tritanomaly: [0.967, 0.033, 0.0, 0.0, 0.733, 0.267, 0.0, 0.183, 0.817],
|
|
30
|
+
achromatopsia: [0.299, 0.587, 0.114, 0.299, 0.587, 0.114, 0.299, 0.587, 0.114],
|
|
31
|
+
achromatomaly: [0.618, 0.32, 0.062, 0.163, 0.775, 0.062, 0.163, 0.32, 0.516],
|
|
32
|
+
};
|
|
33
|
+
//# sourceMappingURL=colorBlindSimulationAdjustment.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"colorBlindSimulationAdjustment.js","sourceRoot":"","sources":["../src/colorBlindSimulationAdjustment.ts"],"names":[],"mappings":"AAEA,uGAAuG;AACvG,wGAAwG;AACxG,oFAAoF;AACpF,EAAE;AACF,wGAAwG;AACxG,2GAA2G;AAC3G,yGAAyG;AACzG,0GAA0G;AAC1G,gEAAgE;AAChE,MAAM,UAAU,oCAAoC,CAClD,UAAkF,EAAE;IAEpF,MAAM,IAAI,GAAmB,OAAO,CAAC,IAAI,IAAI,cAAc,CAAC;IAC5D,MAAM,CAAC,GAAG,oBAAoB,CAAC,IAAI,CAAC,CAAC;IACrC,kBAAkB;IAClB,MAAM,WAAW,GAAG;QAClB,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;QACtB,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;QACtB,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;QACtB,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC;KACd,CAAC;IACF,OAAO,EAAE,IAAI,EAAE,gCAAgC,EAAE,GAAG,OAAO,EAAE,WAAW,EAAE,CAAC;AAC7E,CAAC;AAED,uFAAuF;AACvF,MAAM,oBAAoB,GAAwD;IAChF,UAAU,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,KAAK,CAAC;IACrE,WAAW,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,KAAK,CAAC;IACtE,YAAY,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;IAC/D,aAAa,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,KAAK,CAAC;IACpE,UAAU,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,KAAK,CAAC;IACnE,WAAW,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,KAAK,CAAC;IACtE,aAAa,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC;IAC9E,aAAa,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,CAAC;CAC7E,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"colorGradeAdjustment.d.ts","sourceRoot":"","sources":["../src/colorGradeAdjustment.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAA0B,MAAM,iBAAiB,CAAC;AAQpF,wBAAgB,0BAA0B,CACxC,OAAO,GAAE,QAAQ,CAAC,IAAI,CAAC,oBAAoB,EAAE,MAAM,GAAG,WAAW,CAAC,CAAM,GACvE,oBAAoB,CAmCtB"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
// The full color grade as one LUT-tier adjustment. The exposure/brightness/temperature/tint/saturation/
|
|
2
|
+
// contrast stage is ported faithfully from the old colorGradeEffect shader; a lift/gamma/gain stage
|
|
3
|
+
// (shadows/midtones/highlights) follows it, all defaulting to neutral so a grade setting only some
|
|
4
|
+
// fields leaves the rest unchanged. Gamma makes the composite nonlinear, so the whole grade bakes to one
|
|
5
|
+
// LUT. Note: the old colorGradeEffect default had contrast 0 (its shader read `contrast ?? 1`); the
|
|
6
|
+
// identity default here is contrast 1.
|
|
7
|
+
export function createColorGradeAdjustment(options = {}) {
|
|
8
|
+
const exposure = Math.pow(2, options.exposure ?? 0);
|
|
9
|
+
const brightness = options.brightness ?? 0;
|
|
10
|
+
const contrast = options.contrast ?? 1;
|
|
11
|
+
const saturation = options.saturation ?? 1;
|
|
12
|
+
const temperature = options.temperature ?? 0;
|
|
13
|
+
const tint = options.tint ?? 0;
|
|
14
|
+
const lift = unpackRgb(options.lift ?? 0x000000ff);
|
|
15
|
+
const gammaRaw = unpackRgb(options.gamma ?? 0x808080ff);
|
|
16
|
+
const gain = unpackRgb(options.gain ?? 0xffffffff);
|
|
17
|
+
const gammaExp = [
|
|
18
|
+
1 / Math.max(gammaRaw[0] * 2, 1e-3),
|
|
19
|
+
1 / Math.max(gammaRaw[1] * 2, 1e-3),
|
|
20
|
+
1 / Math.max(gammaRaw[2] * 2, 1e-3),
|
|
21
|
+
];
|
|
22
|
+
const transform = (out, r, g, b) => {
|
|
23
|
+
let cr = r * exposure + brightness + temperature * 0.5;
|
|
24
|
+
let cg = g * exposure + brightness + tint * 0.5;
|
|
25
|
+
let cb = b * exposure + brightness - temperature * 0.5;
|
|
26
|
+
const luma = cr * 0.2126 + cg * 0.7152 + cb * 0.0722;
|
|
27
|
+
cr = luma + (cr - luma) * saturation;
|
|
28
|
+
cg = luma + (cg - luma) * saturation;
|
|
29
|
+
cb = luma + (cb - luma) * saturation;
|
|
30
|
+
cr = (cr - 0.5) * contrast + 0.5;
|
|
31
|
+
cg = (cg - 0.5) * contrast + 0.5;
|
|
32
|
+
cb = (cb - 0.5) * contrast + 0.5;
|
|
33
|
+
// Lift/gamma/gain stage (neutral by default).
|
|
34
|
+
cr = Math.pow(Math.max(cr * gain[0] + lift[0] * (1 - cr), 0), gammaExp[0]);
|
|
35
|
+
cg = Math.pow(Math.max(cg * gain[1] + lift[1] * (1 - cg), 0), gammaExp[1]);
|
|
36
|
+
cb = Math.pow(Math.max(cb * gain[2] + lift[2] * (1 - cb), 0), gammaExp[2]);
|
|
37
|
+
out[0] = clamp01(cr);
|
|
38
|
+
out[1] = clamp01(cg);
|
|
39
|
+
out[2] = clamp01(cb);
|
|
40
|
+
};
|
|
41
|
+
return { kind: 'ColorGradeAdjustment', ...options, transform };
|
|
42
|
+
}
|
|
43
|
+
function clamp01(v) {
|
|
44
|
+
return v < 0 ? 0 : v > 1 ? 1 : v;
|
|
45
|
+
}
|
|
46
|
+
function unpackRgb(c) {
|
|
47
|
+
return [((c >>> 24) & 255) / 255, ((c >>> 16) & 255) / 255, ((c >>> 8) & 255) / 255];
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=colorGradeAdjustment.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"colorGradeAdjustment.js","sourceRoot":"","sources":["../src/colorGradeAdjustment.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { ColorLut, ColorTransformFunction } from '@flighthq/types';
|
|
2
|
+
/**
|
|
3
|
+
* Baked-LUT math: compose a stack of pointwise rgb→rgb transforms into ONE 3D color lookup table, and
|
|
4
|
+
* sample it. This is the LUT-tier fuse (the sibling of colorMatrixMath's `fuseColorMatrices`): where a
|
|
5
|
+
* run of adjustments is not a pure affine matrix (gamma, hue/saturation, a supplied grade LUT), it
|
|
6
|
+
* bakes into a single `ColorLut` evaluated once at each cell and applied as one trilinear tap. The
|
|
7
|
+
* transforms must be continuous — the trilinear tap interpolates between cells, so hard-step ops
|
|
8
|
+
* (posterize, threshold, quantize) are Effects with a dedicated per-op pass, not LUT adjustments.
|
|
9
|
+
*
|
|
10
|
+
* All color values are normalized `[0, 1]`. `samples` is `size³ · 3`, R fastest then G then B: cell
|
|
11
|
+
* `(ri, gi, bi)` starts at `((bi · size + gi) · size + ri) · 3` (see the ColorLut type).
|
|
12
|
+
*/
|
|
13
|
+
/** Default per-axis LUT resolution. 32³ balances quality against upload/memory; raise it to cut banding. */
|
|
14
|
+
export declare const COLOR_LUT_DEFAULT_SIZE = 32;
|
|
15
|
+
/**
|
|
16
|
+
* Bakes a stack of rgb→rgb transforms into one `ColorLut` of `size` cells per axis. The transforms apply
|
|
17
|
+
* left-to-right (index 0 first) at each cell's unit-cube coordinate; an empty stack yields the identity
|
|
18
|
+
* LUT. Evaluating the composed function once per cell is the whole point — arbitrary nonlinear stacks
|
|
19
|
+
* collapse to a single texture without a per-op pass. Allocates the LUT. Baking is CPU-only (do it once
|
|
20
|
+
* per stack, not per frame); larger `size` reduces banding at an `O(size³)` cost.
|
|
21
|
+
*/
|
|
22
|
+
export declare function bakeColorLut(transforms: ReadonlyArray<ColorTransformFunction>, size?: number): ColorLut;
|
|
23
|
+
/**
|
|
24
|
+
* Trilinearly samples `lut` at normalized `(r, g, b)` (clamped to the cube) and writes the RGB result
|
|
25
|
+
* into `out`. The CPU counterpart of the GPU's hardware-filtered 3D texture tap; used by the Canvas LUT
|
|
26
|
+
* pass and by tests. Alias-safe with respect to `out`.
|
|
27
|
+
*/
|
|
28
|
+
export declare function sampleColorLut(lut: Readonly<ColorLut>, out: [number, number, number], r: number, g: number, b: number): void;
|
|
29
|
+
//# sourceMappingURL=colorLut.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"colorLut.d.ts","sourceRoot":"","sources":["../src/colorLut.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AAExE;;;;;;;;;;GAUG;AAEH,4GAA4G;AAC5G,eAAO,MAAM,sBAAsB,KAAK,CAAC;AAEzC;;;;;;GAMG;AACH,wBAAgB,YAAY,CAC1B,UAAU,EAAE,aAAa,CAAC,sBAAsB,CAAC,EACjD,IAAI,GAAE,MAA+B,GACpC,QAAQ,CAsBV;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAC5B,GAAG,EAAE,QAAQ,CAAC,QAAQ,CAAC,EACvB,GAAG,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAC7B,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,GACR,IAAI,CAiCN"}
|
package/dist/colorLut.js
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Baked-LUT math: compose a stack of pointwise rgb→rgb transforms into ONE 3D color lookup table, and
|
|
3
|
+
* sample it. This is the LUT-tier fuse (the sibling of colorMatrixMath's `fuseColorMatrices`): where a
|
|
4
|
+
* run of adjustments is not a pure affine matrix (gamma, hue/saturation, a supplied grade LUT), it
|
|
5
|
+
* bakes into a single `ColorLut` evaluated once at each cell and applied as one trilinear tap. The
|
|
6
|
+
* transforms must be continuous — the trilinear tap interpolates between cells, so hard-step ops
|
|
7
|
+
* (posterize, threshold, quantize) are Effects with a dedicated per-op pass, not LUT adjustments.
|
|
8
|
+
*
|
|
9
|
+
* All color values are normalized `[0, 1]`. `samples` is `size³ · 3`, R fastest then G then B: cell
|
|
10
|
+
* `(ri, gi, bi)` starts at `((bi · size + gi) · size + ri) · 3` (see the ColorLut type).
|
|
11
|
+
*/
|
|
12
|
+
/** Default per-axis LUT resolution. 32³ balances quality against upload/memory; raise it to cut banding. */
|
|
13
|
+
export const COLOR_LUT_DEFAULT_SIZE = 32;
|
|
14
|
+
/**
|
|
15
|
+
* Bakes a stack of rgb→rgb transforms into one `ColorLut` of `size` cells per axis. The transforms apply
|
|
16
|
+
* left-to-right (index 0 first) at each cell's unit-cube coordinate; an empty stack yields the identity
|
|
17
|
+
* LUT. Evaluating the composed function once per cell is the whole point — arbitrary nonlinear stacks
|
|
18
|
+
* collapse to a single texture without a per-op pass. Allocates the LUT. Baking is CPU-only (do it once
|
|
19
|
+
* per stack, not per frame); larger `size` reduces banding at an `O(size³)` cost.
|
|
20
|
+
*/
|
|
21
|
+
export function bakeColorLut(transforms, size = COLOR_LUT_DEFAULT_SIZE) {
|
|
22
|
+
const n = Math.max(2, Math.floor(size));
|
|
23
|
+
const samples = new Array(n * n * n * 3);
|
|
24
|
+
const denom = n - 1;
|
|
25
|
+
const cell = [0, 0, 0];
|
|
26
|
+
let i = 0;
|
|
27
|
+
for (let bi = 0; bi < n; bi++) {
|
|
28
|
+
const b = bi / denom;
|
|
29
|
+
for (let gi = 0; gi < n; gi++) {
|
|
30
|
+
const g = gi / denom;
|
|
31
|
+
for (let ri = 0; ri < n; ri++) {
|
|
32
|
+
cell[0] = ri / denom;
|
|
33
|
+
cell[1] = g;
|
|
34
|
+
cell[2] = b;
|
|
35
|
+
for (let k = 0; k < transforms.length; k++)
|
|
36
|
+
transforms[k](cell, cell[0], cell[1], cell[2]);
|
|
37
|
+
samples[i++] = clamp01(cell[0]);
|
|
38
|
+
samples[i++] = clamp01(cell[1]);
|
|
39
|
+
samples[i++] = clamp01(cell[2]);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return { size: n, samples };
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Trilinearly samples `lut` at normalized `(r, g, b)` (clamped to the cube) and writes the RGB result
|
|
47
|
+
* into `out`. The CPU counterpart of the GPU's hardware-filtered 3D texture tap; used by the Canvas LUT
|
|
48
|
+
* pass and by tests. Alias-safe with respect to `out`.
|
|
49
|
+
*/
|
|
50
|
+
export function sampleColorLut(lut, out, r, g, b) {
|
|
51
|
+
const n = lut.size;
|
|
52
|
+
const s = lut.samples;
|
|
53
|
+
const max = n - 1;
|
|
54
|
+
const fr = clamp01(r) * max;
|
|
55
|
+
const fg = clamp01(g) * max;
|
|
56
|
+
const fb = clamp01(b) * max;
|
|
57
|
+
const r0 = Math.floor(fr);
|
|
58
|
+
const g0 = Math.floor(fg);
|
|
59
|
+
const b0 = Math.floor(fb);
|
|
60
|
+
const r1 = Math.min(r0 + 1, max);
|
|
61
|
+
const g1 = Math.min(g0 + 1, max);
|
|
62
|
+
const b1 = Math.min(b0 + 1, max);
|
|
63
|
+
const dr = fr - r0;
|
|
64
|
+
const dg = fg - g0;
|
|
65
|
+
const db = fb - b0;
|
|
66
|
+
for (let c = 0; c < 3; c++) {
|
|
67
|
+
const c000 = s[((b0 * n + g0) * n + r0) * 3 + c];
|
|
68
|
+
const c100 = s[((b0 * n + g0) * n + r1) * 3 + c];
|
|
69
|
+
const c010 = s[((b0 * n + g1) * n + r0) * 3 + c];
|
|
70
|
+
const c110 = s[((b0 * n + g1) * n + r1) * 3 + c];
|
|
71
|
+
const c001 = s[((b1 * n + g0) * n + r0) * 3 + c];
|
|
72
|
+
const c101 = s[((b1 * n + g0) * n + r1) * 3 + c];
|
|
73
|
+
const c011 = s[((b1 * n + g1) * n + r0) * 3 + c];
|
|
74
|
+
const c111 = s[((b1 * n + g1) * n + r1) * 3 + c];
|
|
75
|
+
const c00 = c000 + (c100 - c000) * dr;
|
|
76
|
+
const c10 = c010 + (c110 - c010) * dr;
|
|
77
|
+
const c01 = c001 + (c101 - c001) * dr;
|
|
78
|
+
const c11 = c011 + (c111 - c011) * dr;
|
|
79
|
+
const c0 = c00 + (c10 - c00) * dg;
|
|
80
|
+
const c1 = c01 + (c11 - c01) * dg;
|
|
81
|
+
out[c] = c0 + (c1 - c0) * db;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
function clamp01(v) {
|
|
85
|
+
return v < 0 ? 0 : v > 1 ? 1 : v;
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=colorLut.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"colorLut.js","sourceRoot":"","sources":["../src/colorLut.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;GAUG;AAEH,4GAA4G;AAC5G,MAAM,CAAC,MAAM,sBAAsB,GAAG,EAAE,CAAC;AAEzC;;;;;;GAMG;AACH,MAAM,UAAU,YAAY,CAC1B,UAAiD,EACjD,OAAe,sBAAsB;IAErC,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;IACxC,MAAM,OAAO,GAAG,IAAI,KAAK,CAAS,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;IACjD,MAAM,KAAK,GAAG,CAAC,GAAG,CAAC,CAAC;IACpB,MAAM,IAAI,GAA6B,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IACjD,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,KAAK,IAAI,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC;QAC9B,MAAM,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC;QACrB,KAAK,IAAI,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC;YAC9B,MAAM,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC;YACrB,KAAK,IAAI,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC;gBAC9B,IAAI,CAAC,CAAC,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC;gBACrB,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;gBACZ,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;gBACZ,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE;oBAAE,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;gBAC3F,OAAO,CAAC,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;gBAChC,OAAO,CAAC,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;gBAChC,OAAO,CAAC,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;YAClC,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC;AAC9B,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAC5B,GAAuB,EACvB,GAA6B,EAC7B,CAAS,EACT,CAAS,EACT,CAAS;IAET,MAAM,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC;IACnB,MAAM,CAAC,GAAG,GAAG,CAAC,OAAO,CAAC;IACtB,MAAM,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;IAClB,MAAM,EAAE,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC;IAC5B,MAAM,EAAE,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC;IAC5B,MAAM,EAAE,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC;IAC5B,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAC1B,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAC1B,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAC1B,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,EAAE,GAAG,CAAC,CAAC;IACjC,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,EAAE,GAAG,CAAC,CAAC;IACjC,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,EAAE,GAAG,CAAC,CAAC;IACjC,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;IACnB,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;IACnB,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;IACnB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC3B,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;QACjD,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;QACjD,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;QACjD,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;QACjD,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;QACjD,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;QACjD,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;QACjD,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;QACjD,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACtC,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACtC,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACtC,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACtC,MAAM,EAAE,GAAG,GAAG,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,EAAE,CAAC;QAClC,MAAM,EAAE,GAAG,GAAG,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,EAAE,CAAC;QAClC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC;IAC/B,CAAC;AACH,CAAC;AAED,SAAS,OAAO,CAAC,CAAS;IACxB,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACnC,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ColorLutAdjustment, ColorTransformFunction } from '@flighthq/types';
|
|
2
|
+
export declare function getAdjustmentColorTransform(operation: Readonly<{
|
|
3
|
+
kind: string;
|
|
4
|
+
}>): ColorTransformFunction | null;
|
|
5
|
+
export declare function isColorLutAdjustment(operation: Readonly<{
|
|
6
|
+
kind: string;
|
|
7
|
+
}>): operation is ColorLutAdjustment;
|
|
8
|
+
//# sourceMappingURL=colorLutAdjustment.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"colorLutAdjustment.d.ts","sourceRoot":"","sources":["../src/colorLutAdjustment.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AASlF,wBAAgB,2BAA2B,CAAC,SAAS,EAAE,QAAQ,CAAC;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,GAAG,sBAAsB,GAAG,IAAI,CAKhH;AAKD,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,QAAQ,CAAC;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,GAAG,SAAS,IAAI,kBAAkB,CAE3G"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { getAdjustmentColorMatrix } from './colorMatrixAdjustment';
|
|
2
|
+
// Returns the rgb→rgb transform a pointwise adjustment contributes to a baked LUT, or null if it is not
|
|
3
|
+
// pointwise (a spatial/composite RenderEffect). A LUT-tier adjustment returns its own `transform`; a
|
|
4
|
+
// matrix-tier adjustment returns its 4×5 matrix evaluated at opaque alpha (so a mixed run still bakes
|
|
5
|
+
// into one LUT). This lets the pipeline fold any pointwise stack — matrices and nonlinear ops together —
|
|
6
|
+
// into a single `bakeColorLut` without a per-kind switch.
|
|
7
|
+
export function getAdjustmentColorTransform(operation) {
|
|
8
|
+
const transform = operation.transform;
|
|
9
|
+
if (typeof transform === 'function')
|
|
10
|
+
return transform;
|
|
11
|
+
const matrix = getAdjustmentColorMatrix(operation);
|
|
12
|
+
return matrix === null ? null : colorMatrixTransform(matrix);
|
|
13
|
+
}
|
|
14
|
+
// Type guard: true when `operation` carries a nonlinear rgb→rgb transform (LUT-tier). Matrix-tier
|
|
15
|
+
// adjustments are NOT LUT-tier — they fuse to a matrix — so this is false for them; a run fuses to a LUT
|
|
16
|
+
// only when at least one member is a LUT-tier adjustment.
|
|
17
|
+
export function isColorLutAdjustment(operation) {
|
|
18
|
+
return typeof operation.transform === 'function';
|
|
19
|
+
}
|
|
20
|
+
// Wraps a 4×5 color matrix (adjustments convention: linear RGBA coefficients + a 0–255 offset column) as
|
|
21
|
+
// an rgb→rgb transform on normalized color. Alpha is assumed opaque (1) — the LUT is a 3D rgb cube, so a
|
|
22
|
+
// matrix's alpha→rgb coupling is not represented; pure color matrices (the common case) bake exactly.
|
|
23
|
+
function colorMatrixTransform(m) {
|
|
24
|
+
return (out, r, g, b) => {
|
|
25
|
+
out[0] = m[0] * r + m[1] * g + m[2] * b + m[3] + m[4] / 255;
|
|
26
|
+
out[1] = m[5] * r + m[6] * g + m[7] * b + m[8] + m[9] / 255;
|
|
27
|
+
out[2] = m[10] * r + m[11] * g + m[12] * b + m[13] + m[14] / 255;
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=colorLutAdjustment.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"colorLutAdjustment.js","sourceRoot":"","sources":["../src/colorLutAdjustment.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AAEnE,wGAAwG;AACxG,qGAAqG;AACrG,sGAAsG;AACtG,yGAAyG;AACzG,0DAA0D;AAC1D,MAAM,UAAU,2BAA2B,CAAC,SAAqC;IAC/E,MAAM,SAAS,GAAI,SAAmD,CAAC,SAAS,CAAC;IACjF,IAAI,OAAO,SAAS,KAAK,UAAU;QAAE,OAAO,SAAS,CAAC;IACtD,MAAM,MAAM,GAAG,wBAAwB,CAAC,SAAS,CAAC,CAAC;IACnD,OAAO,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,oBAAoB,CAAC,MAAM,CAAC,CAAC;AAC/D,CAAC;AAED,kGAAkG;AAClG,yGAAyG;AACzG,0DAA0D;AAC1D,MAAM,UAAU,oBAAoB,CAAC,SAAqC;IACxE,OAAO,OAAQ,SAAmD,CAAC,SAAS,KAAK,UAAU,CAAC;AAC9F,CAAC;AAED,yGAAyG;AACzG,yGAAyG;AACzG,sGAAsG;AACtG,SAAS,oBAAoB,CAAC,CAAqB;IACjD,OAAO,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE;QACtB,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC;QAC5D,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC;QAC5D,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC;IACnE,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { ColorLut, ColorLutCache } from '@flighthq/types';
|
|
2
|
+
export declare function bakeColorLutForRun(cache: ColorLutCache, run: ReadonlyArray<Readonly<{
|
|
3
|
+
kind: string;
|
|
4
|
+
}>>, size?: number): ColorLut;
|
|
5
|
+
export declare function createColorLutCache(): ColorLutCache;
|
|
6
|
+
//# sourceMappingURL=colorLutCache.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"colorLutCache.d.ts","sourceRoot":"","sources":["../src/colorLutCache.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,aAAa,EAA0B,MAAM,iBAAiB,CAAC;AAmBvF,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,aAAa,EACpB,GAAG,EAAE,aAAa,CAAC,QAAQ,CAAC;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC,EAC9C,IAAI,GAAE,MAA+B,GACpC,QAAQ,CAYV;AAID,wBAAgB,mBAAmB,IAAI,aAAa,CAEnD"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { bakeColorLut, COLOR_LUT_DEFAULT_SIZE } from './colorLut';
|
|
2
|
+
import { getAdjustmentColorTransform } from './colorLutAdjustment';
|
|
3
|
+
// Bake memo for the LUT-tier fuse: a run of pointwise adjustments is rebuilt with fresh objects every
|
|
4
|
+
// frame, so reference identity cannot detect an unchanged grade. Keying by the run's *content* — its
|
|
5
|
+
// ops' kinds and serialized params — lets a static grade reuse its baked LUT instead of re-evaluating
|
|
6
|
+
// size³ cells each frame, and hands the GPU-upload passes back a stable ColorLut reference so they can
|
|
7
|
+
// skip re-uploading too. The bake output is byte-for-byte the uncached result; only the redundant work
|
|
8
|
+
// is skipped.
|
|
9
|
+
// Bakes the fused `ColorLut` for a pointwise-adjustment run, reusing `cache`'s prior bake when the run's
|
|
10
|
+
// content signature is unchanged. On a hit the exact same ColorLut reference is returned (GPU-upload
|
|
11
|
+
// caches skip re-uploading by identity); on a miss the run's transforms are composed and baked afresh.
|
|
12
|
+
// Matrix-tier members contribute their matrix-as-transform, so a mixed run bakes into one LUT. `size` is
|
|
13
|
+
// the per-axis resolution, part of the signature. The bake is deterministic in the run's serialized
|
|
14
|
+
// data, so an adjustment carrying hidden non-serialized state in its `transform` would defeat the cache —
|
|
15
|
+
// but that violates the data-fed adjustment contract.
|
|
16
|
+
export function bakeColorLutForRun(cache, run, size = COLOR_LUT_DEFAULT_SIZE) {
|
|
17
|
+
const signature = colorLutRunSignature(run, size);
|
|
18
|
+
if (cache.signature === signature && cache.lut !== null)
|
|
19
|
+
return cache.lut;
|
|
20
|
+
const transforms = [];
|
|
21
|
+
for (const operation of run) {
|
|
22
|
+
const transform = getAdjustmentColorTransform(operation);
|
|
23
|
+
if (transform !== null)
|
|
24
|
+
transforms.push(transform);
|
|
25
|
+
}
|
|
26
|
+
const lut = bakeColorLut(transforms, size);
|
|
27
|
+
cache.signature = signature;
|
|
28
|
+
cache.lut = lut;
|
|
29
|
+
return lut;
|
|
30
|
+
}
|
|
31
|
+
// Allocates an empty bake memo (no baked LUT yet). The effect pipeline owns one and passes it to
|
|
32
|
+
// bakeColorLutForRun each frame; it is plain GC-managed memory, so resetting it is dropping the object.
|
|
33
|
+
export function createColorLutCache() {
|
|
34
|
+
return { signature: null, lut: null };
|
|
35
|
+
}
|
|
36
|
+
// Content signature of a run for cache keying: the per-axis size plus each op's serialized data fields.
|
|
37
|
+
// JSON.stringify drops function-valued properties, so the `transform` closure — rebuilt with fresh
|
|
38
|
+
// identity each frame but fully determined by the op's params — is excluded, and two content-identical
|
|
39
|
+
// runs hash equal while any changed param re-keys.
|
|
40
|
+
function colorLutRunSignature(run, size) {
|
|
41
|
+
return `${size}\n${JSON.stringify(run)}`;
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=colorLutCache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"colorLutCache.js","sourceRoot":"","sources":["../src/colorLutCache.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAClE,OAAO,EAAE,2BAA2B,EAAE,MAAM,sBAAsB,CAAC;AAEnE,sGAAsG;AACtG,qGAAqG;AACrG,sGAAsG;AACtG,uGAAuG;AACvG,uGAAuG;AACvG,cAAc;AAEd,yGAAyG;AACzG,qGAAqG;AACrG,uGAAuG;AACvG,yGAAyG;AACzG,oGAAoG;AACpG,0GAA0G;AAC1G,sDAAsD;AACtD,MAAM,UAAU,kBAAkB,CAChC,KAAoB,EACpB,GAA8C,EAC9C,OAAe,sBAAsB;IAErC,MAAM,SAAS,GAAG,oBAAoB,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IAClD,IAAI,KAAK,CAAC,SAAS,KAAK,SAAS,IAAI,KAAK,CAAC,GAAG,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC,GAAG,CAAC;IAC1E,MAAM,UAAU,GAA6B,EAAE,CAAC;IAChD,KAAK,MAAM,SAAS,IAAI,GAAG,EAAE,CAAC;QAC5B,MAAM,SAAS,GAAG,2BAA2B,CAAC,SAAS,CAAC,CAAC;QACzD,IAAI,SAAS,KAAK,IAAI;YAAE,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACrD,CAAC;IACD,MAAM,GAAG,GAAG,YAAY,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;IAC3C,KAAK,CAAC,SAAS,GAAG,SAAS,CAAC;IAC5B,KAAK,CAAC,GAAG,GAAG,GAAG,CAAC;IAChB,OAAO,GAAG,CAAC;AACb,CAAC;AAED,iGAAiG;AACjG,wGAAwG;AACxG,MAAM,UAAU,mBAAmB;IACjC,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC;AACxC,CAAC;AAED,wGAAwG;AACxG,mGAAmG;AACnG,uGAAuG;AACvG,mDAAmD;AACnD,SAAS,oBAAoB,CAAC,GAA8C,EAAE,IAAY;IACxF,OAAO,GAAG,IAAI,KAAK,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC;AAC3C,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ColorMatrixAdjustment } from '@flighthq/types';
|
|
2
|
+
export declare function getAdjustmentColorMatrix(operation: Readonly<{
|
|
3
|
+
kind: string;
|
|
4
|
+
}>): readonly number[] | null;
|
|
5
|
+
export declare function isColorMatrixAdjustment(operation: Readonly<{
|
|
6
|
+
kind: string;
|
|
7
|
+
}>): operation is ColorMatrixAdjustment;
|
|
8
|
+
//# sourceMappingURL=colorMatrixAdjustment.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"colorMatrixAdjustment.d.ts","sourceRoot":"","sources":["../src/colorMatrixAdjustment.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAQ7D,wBAAgB,wBAAwB,CAAC,SAAS,EAAE,QAAQ,CAAC;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,GAAG,SAAS,MAAM,EAAE,GAAG,IAAI,CAGxG;AAGD,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,QAAQ,CAAC;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,GAAG,SAAS,IAAI,qBAAqB,CAEjH"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { COLOR_MATRIX_LENGTH } from './colorMatrixMath';
|
|
2
|
+
// Returns the 4×5 color matrix a stack operation contributes to the fused matrix-tier pass, or null if
|
|
3
|
+
// it is not a matrix-tier adjustment (a spatial/composite RenderEffect, or a LUT-tier adjustment). Lets
|
|
4
|
+
// a pipeline recognise which stack entries fold into the single generic color-matrix pass without a
|
|
5
|
+
// per-kind switch: any operation carrying a valid 4×5 `colorMatrix` fuses, third-party ones included.
|
|
6
|
+
export function getAdjustmentColorMatrix(operation) {
|
|
7
|
+
const matrix = operation.colorMatrix;
|
|
8
|
+
return Array.isArray(matrix) && matrix.length === COLOR_MATRIX_LENGTH ? matrix : null;
|
|
9
|
+
}
|
|
10
|
+
// Type guard: true when `operation` contributes a fusable 4×5 color matrix.
|
|
11
|
+
export function isColorMatrixAdjustment(operation) {
|
|
12
|
+
return getAdjustmentColorMatrix(operation) !== null;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=colorMatrixAdjustment.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"colorMatrixAdjustment.js","sourceRoot":"","sources":["../src/colorMatrixAdjustment.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAExD,uGAAuG;AACvG,wGAAwG;AACxG,oGAAoG;AACpG,sGAAsG;AACtG,MAAM,UAAU,wBAAwB,CAAC,SAAqC;IAC5E,MAAM,MAAM,GAAI,SAAsD,CAAC,WAAW,CAAC;IACnF,OAAO,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,MAAM,KAAK,mBAAmB,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;AACxF,CAAC;AAED,4EAA4E;AAC5E,MAAM,UAAU,uBAAuB,CAAC,SAAqC;IAC3E,OAAO,wBAAwB,CAAC,SAAS,CAAC,KAAK,IAAI,CAAC;AACtD,CAAC"}
|