Discussion:
sRGB.icm changed in Argyllcms 1.6.1
Elle Stone
2013-12-28 10:39:06 UTC
Permalink
The XYZ values in the Argyllcms profiles sRGB.icm changed in Argyllcms
1.6.1, compared to 1.6.0 and previous versions of Argyllcms.

Version 1.6.0 and previous versions:

rXYZ X="0.43603516" Y="0.22244263" Z="0.01390076"

gXYZ X="0.38510132" Y="0.71693420" Z="0.09707642"

bXYZ X="0.14306641" Y="0.06062317" Z="0.71392822"


Version 1.6.1 and 1.6.2:

rXYZ X="0.43603516" Y="0.22248840" Z="0.01391602"

gXYZ X="0.38511658" Y="0.71690369" Z="0.09706116"

bXYZ X="0.14305115" Y="0.06060791" Z="0.71391296"


The Argyllcms 1.6.0 and previous sRGB.icm profiles are color-balanced to
the 6 decimal places that xicclu displays:

/usr/local/argyll/argyll160/ref $ xicclu -pl -s255 -v0 sRGB.icm
255 255 255
100.000000 0.000000 0.000000

The version from 1.6.1 and 1.6.2 isn't color-balanced to 6 decimal places:

/usr/local/argyll/argyll161/ref $ xicclu -pl -s255 -v0 sRGB.icm
255 255 255
100.000000 0.000000 0.001233


I was curious as to why the change in the sRGB primaries?

Elle
--
Elle Stone
http://ninedegreesbelow.com
Articles on color management and open source photography
Graeme Gill
2013-12-31 02:38:50 UTC
Permalink
The XYZ values in the Argyllcms profiles sRGB.icm changed in Argyllcms 1.6.1, compared to
1.6.0 and previous versions of Argyllcms.
Hi,

Yes, I switched to working from the sRGB specification x,y values rather
than the pre-computed matrix values given in the sRGB ICC profile paper,
to bring it into line with the way all the other reference profiles
are created, and (hopefully) improve it's conformance to the spec.,
which I think is achieved.
The Argyllcms 1.6.0 and previous sRGB.icm profiles are color-balanced to the 6 decimal
/usr/local/argyll/argyll160/ref $ xicclu -pl -s255 -v0 sRGB.icm
255 255 255
100.000000 0.000000 0.000000
Hmm. I'm thinking that this may have been accidental, or perhaps the
pre-computed values had been tweaked slightly.
/usr/local/argyll/argyll161/ref $ xicclu -pl -s255 -v0 sRGB.icm
255 255 255
100.000000 0.000000 0.001233
This is a result of quantization the primary XYZ values into the ICC 15.16
fixed point format.

I will changed the code to minimize the error in the sum of the quantized
primary values, which should reduce the white point error at a cost of
increasing the primaries errors slightly.

The resulting sRGB profile is here <http://www.argyllcms.com/sRGB.icm>

Graeme Gill.
Elle Stone
2014-01-22 13:00:18 UTC
Permalink
Post by Graeme Gill
The XYZ values in the Argyllcms profiles sRGB.icm changed in Argyllcms 1.6.1, compared to
1.6.0 and previous versions of Argyllcms.
Hi,
Yes, I switched to working from the sRGB specification x,y values rather
than the pre-computed matrix values given in the sRGB ICC profile paper,
to bring it into line with the way all the other reference profiles
are created, and (hopefully) improve it's conformance to the spec.,
which I think is achieved.
This is a result of quantization the primary XYZ values into the ICC 15.16
fixed point format.
I will changed the code to minimize the error in the sum of the quantized
primary values, which should reduce the white point error at a cost of
increasing the primaries errors slightly.
The resulting sRGB profile is here <http://www.argyllcms.com/sRGB.icm>
Graeme Gill.
Graeme, thank you very, very much for the modified sRGB profile.

I've been trying to use LCMS2 to make an sRGB profile that matches your
color-balanced sRGB profile and I just can't get it to happen.

Using LCMS2, I can exactly match the 1.6.2 "not quite color-balanced"
sRGB profile, but not the 1.6.0 color-balanced profile. I did manage to
make a color-balanced "sRGB" profile, but only by modifying the profile
white point, which resulted in adapted primaries that are considerably
farther from your color-balanced sRGB profile than they ought to be.

Would you be willing to share the modified primaries values that you
used to create the color-balanced sRGB profile?

Also, the 1.6.0 ClayRGB1998.icm is color-balanced and exactly matches
other V2 Adobe-compatible profiles, including Adobe's own AdobeRGB1998
profile. But the 1.6.2 ClayRGB1998.icm doesn't match the 1.6.0 version
for the blue primary, and also isn't color-balanced:

1.6.2 blue primary: 0.14918518 0.06321716 0.74455261
1.6.0 blue primary: 0.14918518 0.06321716 0.74456787

xicclu -pl -ir -v0 ClayRGB1998-162.icm
1 1 1
100.000000 0.000000 0.001233

I succeeded in using LCMS2 to make a ClayRGB profile that exactly
matches the 1.6.0 version, but to do so I had to modify the LCMS2 source
code values for the D50 illuminant to match the hexadecimal-rounded
illuminant values found in the actual profiles. This trick didn't work
for sRGB.

Profile primaries seem to differ quite a bit in how sensitive they are
to hexadecimal rounding.

Elle Stone
Graeme Gill
2014-01-22 22:03:40 UTC
Permalink
Elle Stone wrote:

Hello Elle,
Would you be willing to share the modified primaries values that you used to create the
color-balanced sRGB profile?
I'm not quite sure what you mean - they are in the profile, and the profile is
in the public domain. The code that tweaks the ICC quantization is in
the ArgyllCMS source code <http://www.argyllcms.com/Argyll_dev_src.zip>
in icc/icc.c in the function quantizeRGBprimsS15Fixed16().
Also, the 1.6.0 ClayRGB1998.icm is color-balanced and exactly matches other V2
Adobe-compatible profiles, including Adobe's own AdobeRGB1998 profile. But the 1.6.2
ClayRGB1998.icm doesn't match the 1.6.0 version for the blue primary, and also isn't
1.6.2 blue primary: 0.14918518 0.06321716 0.74455261
1.6.0 blue primary: 0.14918518 0.06321716 0.74456787
Here is the updated profile, created using the latest code:

<http://www.argyllcms.com/ClayRGB1998.icm>
0.3127, 0.3290 /* White */
0.6400, 0.3300 /* Red */
0.2100, 0.7100 /* Green */
0.1500, 0.0600 /* Blue */

For the AdobeRGB.icm:

0.312700 0.329000
0.639997 0.329997
0.210006 0.710004
0.149998 0.060004

For ClayRGB1998.icm:

0.312700 0.329000
0.639997 0.329997
0.210006 0.710004
0.149998 0.060004
Profile primaries seem to differ quite a bit in how sensitive they are to hexadecimal
rounding.
In a practical sense (ie. delta E) the differences are very small though.

Graeme.
Elle Stone
2014-01-22 23:23:53 UTC
Permalink
Post by Graeme Gill
Hello Elle,
Would you be willing to share the modified primaries values that you used to create the
color-balanced sRGB profile?
I'm not quite sure what you mean - they are in the profile, and the profile is
in the public domain. The code that tweaks the ICC quantization is in
the ArgyllCMS source code <http://www.argyllcms.com/Argyll_dev_src.zip>
in icc/icc.c in the function quantizeRGBprimsS15Fixed16().
Hmm, the only way I know how to make an ICC profile requires feeding in
the unadapted primaries, so I figured that was what you tweaked. Thanks!
for the link to the code. I'll see if I can make sense of it.
Post by Graeme Gill
Also, the 1.6.0 ClayRGB1998.icm is color-balanced and exactly matches other V2
Adobe-compatible profiles, including Adobe's own AdobeRGB1998 profile. But the 1.6.2
ClayRGB1998.icm doesn't match the 1.6.0 version for the blue primary, and also isn't
1.6.2 blue primary: 0.14918518 0.06321716 0.74455261
1.6.0 blue primary: 0.14918518 0.06321716 0.74456787
<http://www.argyllcms.com/ClayRGB1998.icm>
Thanks!
Post by Graeme Gill
0.3127, 0.3290 /* White */
0.6400, 0.3300 /* Red */
0.2100, 0.7100 /* Green */
0.1500, 0.0600 /* Blue */
0.312700 0.329000
0.639997 0.329997
0.210006 0.710004
0.149998 0.060004
0.312700 0.329000
0.639997 0.329997
0.210006 0.710004
0.149998 0.060004
Profile primaries seem to differ quite a bit in how sensitive they are to hexadecimal
rounding.
In a practical sense (ie. delta E) the differences are very small though.
True.
Post by Graeme Gill
Graeme.
Elle
Graeme Gill
2014-01-23 01:59:01 UTC
Permalink
Hmm, the only way I know how to make an ICC profile requires feeding in the unadapted
primaries, so I figured that was what you tweaked. Thanks! for the link to the code. I'll
see if I can make sense of it.
Hmm. I guess one could pre-quantize unadapted primaries if the chromatic
adaption transform is known precisely, but that's not a problem I've had
to solve using icclib.

Graeme.
Elle Stone
2014-01-23 12:51:23 UTC
Permalink
Post by Graeme Gill
Hmm, the only way I know how to make an ICC profile requires feeding in the unadapted
primaries, so I figured that was what you tweaked. Thanks! for the link to the code. I'll
see if I can make sense of it.
Hmm. I guess one could pre-quantize unadapted primaries if the chromatic
adaption transform is known precisely
To my amazement, it did work:

real D65 to D50 Bradford matrix from Lindbloom:
1.047887310 0.022919642 -0.050214579
0.029583429 0.990481524 -0.017078364
-0.009251440 0.015071688 0.751688639

quantized matrix from the LCMS2 chad tag:
1.047882080 0.022918700 -0.050216670
0.029586790 0.990478520 -0.017074580
-0.009246830 0.015075680 0.751678470

inverse of chad tag matrix:
0.955515990 -0.023073320 0.063310133
-0.028329992 1.009948165 0.021048631
0.012322540 -0.020539381 1.330712712

The inverse chad matrix times your quantized adapted primaries from the
modified sRGB.icm profile produces these "pre-quantized" unadapted sRGB
primaries:

red: 0.412386137 0.212595245 0.019302145
green: 0.357571891 0.715199438 0.119205222
blue: 0.180498857 0.072204328 0.950539645

or, as xy values:
red: 0.640069348, 0.329971567
green: 0.299982320, 0.600011332
blue: 0.150010332, 0.060008110

which when used in my LCMS2 code along with the source white point of
x=0.3127, y=0.3290, makes an sRGB profile that exactly matches your
modified sRGB profile.
Post by Graeme Gill
but that's not a problem I've had
to solve using icclib.
I looked at the quantizeRGBprimsS15Fixed16 function in your icc.c source
code. That's really cool and greatly, greatly appreciated that your
profile-making code deals with quantization issues.

Thanks!

Elle
Graeme Gill
2014-01-23 13:26:25 UTC
Permalink
Post by Elle Stone
1.047887310 0.022919642 -0.050214579
0.029583429 0.990481524 -0.017078364
-0.009251440 0.015071688 0.751688639
1.047882080 0.022918700 -0.050216670
0.029586790 0.990478520 -0.017074580
-0.009246830 0.015075680 0.751678470
You probably need to look at the code to see if LCMS2 is actually using
the quantized chad internally. It's not something I've though much about,
but the natural approach is to use the full precision matrix, although
using the quantized matrix would make the profile more accurate.

The ArgyllCMS icc code isn't currently using quantized matrix values.
Post by Elle Stone
0.955515990 -0.023073320 0.063310133
-0.028329992 1.009948165 0.021048631
0.012322540 -0.020539381 1.330712712
The inverse chad matrix times your quantized adapted primaries from the modified sRGB.icm
red: 0.412386137 0.212595245 0.019302145
green: 0.357571891 0.715199438 0.119205222
blue: 0.180498857 0.072204328 0.950539645
Yep, that should work, although (as a consequence of above) you should
use the inverse of the full precision chromatic matrix.
Post by Elle Stone
I looked at the quantizeRGBprimsS15Fixed16 function in your icc.c source code. That's
really cool and greatly, greatly appreciated that your profile-making code deals with
quantization issues.
It does, only because you drew attention to the problem with a specific example.

Graeme.
Elle Stone
2014-01-28 15:55:49 UTC
Permalink
Post by Graeme Gill
You probably need to look at the code to see if LCMS2 is actually using
the quantized chad internally.
I don't think it does.
Post by Graeme Gill
Post by Elle Stone
The inverse chad matrix times your quantized adapted primaries from the modified sRGB.icm
red: 0.412386137 0.212595245 0.019302145
green: 0.357571891 0.715199438 0.119205222
blue: 0.180498857 0.072204328 0.950539645
Yep, that should work, although (as a consequence of above) you should
use the inverse of the full precision chromatic matrix.
You are right, for sRGB it makes no difference, both ways produce the
same pre-quantized primaries.
But AdobeRGBcompatible prequantized primaries need to be calculated
using the unquantized chromatic adaptation matrix.
Post by Graeme Gill
Post by Elle Stone
I looked at the quantizeRGBprimsS15Fixed16 function in your icc.c source code. That's
really cool and greatly, greatly appreciated that your profile-making code deals with
quantization issues.
Is there sample code showing how to use Argyllcms/ICCLib to make
quantized RGB working space profiles? I found lutest.c, which I've been
working on modifying, but modifying it is not easy! and getting the
modified code to produce a profile requires recompiling everything with jam.
Post by Graeme Gill
It does, only because you drew attention to the problem with a specific example.
A sharp-eyed reader of one of the articles on my website realized that
the Argyllcms sRGB.icm had changed and wrote to me about it. I doubt I
would have ever noticed on my own that the Argyllcms 1.6.0 and 1.6.1
sRGB/AdobeRGB profiles didn't match.

Elle
Graeme Gill
2014-01-28 23:23:06 UTC
Permalink
Is there sample code showing how to use Argyllcms/ICCLib to make quantized RGB working
space profiles? I found lutest.c, which I've been working on modifying, but modifying it
is not easy! and getting the modified code to produce a profile requires recompiling
everything with jam.
Hi,
compiling can't be avoided at this point - I haven't written a general purpose
command line reference profile creator. I'll include a simple working example program
that creates a specific profile, in the next release (icc/mkDispProf.c).

Graeme.
Elle Stone
2014-01-29 13:18:52 UTC
Permalink
Post by Graeme Gill
Is there sample code showing how to use Argyllcms/ICCLib to make quantized RGB working
space profiles? I found lutest.c, which I've been working on modifying, but modifying it
is not easy! and getting the modified code to produce a profile requires recompiling
everything with jam.
Hi,
compiling can't be avoided at this point - I haven't written a general purpose
command line reference profile creator. I'll include a simple working example program
that creates a specific profile, in the next release (icc/mkDispProf.c).
Graeme.
Thanks! Will this create profiles that deal with the hexadecimal
rounding issue?

Elle
Graeme Gill
2014-01-29 13:34:27 UTC
Permalink
Thanks! Will this create profiles that deal with the hexadecimal rounding issue?
Yes,
Graeme.
Elle Stone
2014-01-31 17:30:43 UTC
Permalink
Post by Graeme Gill
Thanks! Will this create profiles that deal with the hexadecimal rounding issue?
Yes,
Graeme.
Thanks very much! for the sample code.

I'm not familiar with jam, but after compiling everthing the first time,
this command compiles only mkDispProf.c:

argyll163_src $ jam -q -fJambase -j 3 -t icc/mkDispProf.c

The existing mkDispProf.c makes an sRGB profile with the sRGB TRC point
curve:

static double gdv2dv(double iv) {
double ov;

if (iv < 0.04045)
ov = iv/12.92;
else
ov = pow((iv + 0.055)/1.055, 2.4);
return ov;
}

It was easy to modify mkDispProf.c to make a profile with a different
set of primaries and different white point, plus a linear point curve.

How do you modify it to make a true gamma curve such as gamma=1.0,
gamma=1.8, or gamma=2.2?


I tried saving the modified mkDispProf.c under a new name "mkNewProf.c"
and compiling it:

argyll163_src $ jam -q -fJambase -j 3 -t icc/mkNewProf.c

but that doesn't work. Perhaps some other file needs to be modified to
tell jam what to compile?

Elle
Graeme Gill
2014-02-02 22:43:39 UTC
Permalink
I'm not familiar with jam, but after compiling everthing the first time, this command
Hi,

In theory you could use the Makefile instead, although I have forgotten to
add mkDispProf to it in this release.
argyll163_src $ jam -q -fJambase -j 3 -t icc/mkDispProf.c
Yes, that can work, although you can speed things up by cd'ing into
icc and just compiling that, since it is self contained. If you are using
the ArgyllCMS modified Jam, then you can also set the JAMBASE environment
variable to point at the Jambase to avoid having to use -f.
How do you modify it to make a true gamma curve such as gamma=1.0, gamma=1.8, or gamma=2.2?
You need to modify the section of code that sets the "Red, Green and Blue Gamma Curve
Tags". See icctest.c "Curve - Linear version" and "Curve - Gamma version" for examples.

ie. for gamma you just set:

wor->flag = icmCurveGamma; /* Gamma version */
wor->allocate((icmBase *)wor); /* Allocate space */
wor->data[0] = 2.2; /* Gamma value */

instead of the code to set the curve values.
argyll163_src $ jam -q -fJambase -j 3 -t icc/mkNewProf.c
but that doesn't work. Perhaps some other file needs to be modified to tell jam what to
compile?
To use Jam you need to edit the icc/Jamfile and add the line

MainsFromSources mkNewProf.c ;

down the bottom somewhere.

Graeme.

Loading...