Closed haasn closed 2 years ago
V4 absolute intent uses fully adapted observer hence the D50. To do what you intend you need to use unadapted observer. Just use cmsSetAdaptationState(0) before creating the transform.
Oh, I see. Thanks, that works. Incidentally, is there a way to recover this same information from the colorant tags, or do I absolutely have to use an inverse transform to arrive back at these values? (0.64, 0.33)
Hmm, even with that change, it now still fails on real-world profiles, such as the one embedded in this jpg.
e.g. exiftool
has this to say about it:
Connection Space Illuminant : 0.9642 1 0.82491
Profile Creator : Apple Computer Inc.
Profile ID : e5bb0e9867bd46cd4bbe446ebd1b7598
Profile Description : Display P3
Profile Copyright : Copyright Apple Inc., 2015
Media White Point : 0.95045 1 1.08905
Red Matrix Column : 0.51512 0.2412 -0.00105
Green Matrix Column : 0.29198 0.69225 0.04189
Blue Matrix Column : 0.1571 0.06657 0.78407
But the values I get from the above code (with the unadapted absolute observer) are:
(gdb) p dst
$1 = {{
X = 0.47963805262952519,
Y = 0.22897943141288124,
Z = -2.2890162618693921e-05
}, {
X = 0.26187982903365992,
Y = 0.69174122283129691,
Z = 0.05955730024567174
}, {
X = 0.19537895811936323,
Y = 0.0792735788616028,
Z = 1.3782320718291885
}, {
X = 0.93689686958441598,
Y = 0.99999427780858241,
Z = 1.4377664283620106
}}
(gdb) p *prim
$2 = {
xr = 0.67688641258656734,
yr = 0.3231458910223175,
xg = 0.25847357327376586,
yg = 0.68274378483341891,
xb = 0.1182048384248727,
yb = 0.047960745982545433
}
(gdb) p *wp
$3 = {
xw = 0.27762724026149671,
yw = 0.29632466564695964
}
Which are just completely off. I'm not even sure how it's reproducing anything that wrong, here. (Notice in particular how the white point doesn't correspond to either the tagged media white point nor the tagged PCS)
What's going on here?
Matrix columns are NOT the primaries. There is a chromatic adaptation and other adjustmets, that's the reason ICC moved names from "Colorant" to "Matrix Column". This is an internal of the profile and should not be used alone as a source of information.
On the other hand, using a V4 P3 profile works quite well for me, this is using Debian and its system lcms2, primaries of P3 are DCI-P3 https://en.wikipedia.org/wiki/DCI-P3
If you convert XYZ to xyY chromaticity is quite proper.
marti@OFTSOF150901:~$ transicc -d0 -t3 -i DisplayP3-v4.icc -o'*XYZ'
LittleCMS ColorSpace conversion calculator - 4.3 [LittleCMS 2.09]
Enter values, 'q' to quit
R? 255
G? 255
B? 255
X=95.0466 Y=99.9995 Z=108.9061
Enter values, 'q' to quit
R? 255
G? 0
B? 0
X=48.6576 Y=22.8980 Z=-0.0007
Enter values, 'q' to quit
R? 0
G? 255
B? 0
X=26.5669 Y=69.1742 Z=4.5117
Enter values, 'q' to quit
R? 0
G? 0
B? 255
X=19.8220 Y=7.9274 Z=104.3951
Enter values, 'q' to quit
R?
Yeah, closing this as the same code works perfectly on e.g. the ArgyllCMS P3 profiles. I think the instagram ICC profile might just be the odd one out, possibly intentionally so (since it's supposed to be a test image).
Thanks for the assistance
I'm a bit confused as to why created built-in RGB profiles do not round-trip back to the stated primaries, neither when looking at the colorant tags, nor when constructing an RGB->XYZ transform. Here is my code:
This is the resulting 'dst' array:
The returned white point is D50 (instead of D65), and the returned primaries are also completely wrong (e.g. red is returned as (x=0.6484, y=0.3308), instead of the (x=0.64, y=0.33) that went into its creation). Specifying relative colorimetric intent instead of absolute colorimetric intent doesn't change the result, even though I would have expected it to matter. Nor does removing any of the flags.
What's going on here? How do I actually figure out what primary coefficients are associated with a given RGB profile? (The RedColorant etc. tags are also completely useless)