Skip to content

Commit 92032ab

Browse files
committed
[css-color-hdr] Added sample code for ICtCp
1 parent 74d9816 commit 92032ab

File tree

2 files changed

+89
-4
lines changed

2 files changed

+89
-4
lines changed

css-color-hdr-1/ICtCp.js

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
const c1 = 3424 / 4096;
2+
const c2 = 2413 / 128;
3+
const c3 = 2392 / 128;
4+
const m1 = 2610 / 16384;
5+
const m2 = 2523 / 32;
6+
const im1 = 16384 / 2610;
7+
const im2 = 32 / 2523;
8+
9+
// The matrix below includes the 4% crosstalk components
10+
// and is from the procedure in the Dolby "What is ICtCp" paper"
11+
const XYZtoICtCp_LMS_M = [
12+
[ 0.3592832590121217, 0.6976051147779502, -0.0358915932320290 ],
13+
[ -0.1920808463704993, 1.1004767970374321, 0.0753748658519118 ],
14+
[ 0.0070797844607479, 0.0748396662186362, 0.8433265453898765 ],
15+
];
16+
17+
// This matrix includes the Ebner LMS coefficients,
18+
// the rotation, and the scaling to [-0.5,0.5] range
19+
// rational terms are from Fröhlich p.97
20+
// and ITU-R BT.2124-0 pp.2-3
21+
const ICtCp_LMStoIPT_M = [
22+
[ 2048 / 4096, 2048 / 4096, 0 ],
23+
[ 6610 / 4096, -13613 / 4096, 7003 / 4096 ],
24+
[ 17933 / 4096, -17390 / 4096, -543 / 4096 ],
25+
];
26+
27+
// inverted matrices, calculated from the above
28+
const IPTtoICtCp_LMS_M = [
29+
[ 0.9999999999999998, 0.0086090370379328, 0.1110296250030260 ],
30+
[ 0.9999999999999998, -0.0086090370379328, -0.1110296250030259 ],
31+
[ 0.9999999999999998, 0.5600313357106791, -0.3206271749873188 ],
32+
];
33+
34+
const ICtCp_LMStoXYZ_M = [
35+
[ 2.0701522183894223, -1.3263473389671563, 0.2066510476294053 ],
36+
[ 0.3647385209748072, 0.6805660249472273, -0.0453045459220347 ],
37+
[ -0.0497472075358123, -0.0492609666966131, 1.1880659249923042 ],
38+
];
39+
40+
function XYZ_to_ICtCp (XYZ) {
41+
// convert an array of absolute, D65 XYZ to the ICtCp form of LMS
42+
43+
let LMS = multiplyMatrices(XYZtoICtCp_LMS_M, XYZ);
44+
return LMStoICtCp(LMS);
45+
}
46+
47+
function LMStoICtCp (LMS) {
48+
// apply the PQ EOTF
49+
// we can't ever be dividing by zero because of the "1 +" in the denominator
50+
let PQLMS = LMS.map (function (val) {
51+
let num = c1 + (c2 * ((val / 10000) ** m1));
52+
let denom = 1 + (c3 * ((val / 10000) ** m1));
53+
54+
return (num / denom) ** m2;
55+
});
56+
57+
// LMS to IPT, with rotation for Y'C'bC'r compatibility
58+
return multiplyMatrices(LMStoIPT_M, PQLMS);
59+
}
60+
61+
function ICtCp_to_XYZ (ICtCp) {
62+
// convert ICtCp to an array of absolute, D65 XYZ
63+
64+
let LMS = ICtCptoLMS(ICtCp);
65+
return multiplyMatrices(ICtCp_LMStoXYZ_M, LMS);
66+
}
67+
68+
function ICtCptoLMS (ICtCp) {
69+
let PQLMS = multiplyMatrices(IPTtoICtCp_LMS_M, ICtCp);
70+
71+
// Undo PQ encoding, From BT.2124-0 Annex 2 Conversion 3
72+
let LMS = PQLMS.map (function (val) {
73+
let num = Math.max((val ** im2) - c1, 0);
74+
let denom = (c2 - (c3 * (val ** im2)));
75+
return 10000 * ((num / denom) ** im1);
76+
});
77+
78+
return LMS;
79+
}

css-color-hdr-1/Overview.bs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1070,17 +1070,23 @@ Serializing values of the ''color()'' function</h3>
10701070
This code also assumes all of the conversion code from
10711071
[[css-color-4#color-conversion-code]] is available.
10721072

1073+
The LMS used in ''Jzazbz'' are not the same
1074+
as the ones used in ''ICtCp'',
1075+
take care to use the right ones!
1076+
10731077
<h3 id="ictcp_code">
10741078
Sample code for ''ICtCp''
10751079
</h3>
10761080

1077-
Rather than first requiring conversion to
1078-
''rec2100-linear'', as defined in [[!Rec_BT.2100]],
1081+
Rather than first requiring
1082+
conversion to ''rec2100-linear'',
1083+
which is how the conversion is defined in [[!Rec_BT.2100]],
10791084
this sample code proceeds directly from absolute CIE XYZ
10801085
for compatibility with the other color conversion code.
10811086

1082-
The 4% crosstalk matrix is also built into the XYZ to LMS step,
1083-
rather than being applied separately.
1087+
The 4% crosstalk matrix, and the rotation ,
1088+
are also built into the XYZ to LMS step,
1089+
rather than being applied as three separate steps.
10841090

10851091
The end result is identical, this just takes fewer steps.
10861092

0 commit comments

Comments
 (0)