While creating profiles using different profile white points, I
noticed a pattern that suggests a rounding error. For example, running
the command "xicclu -ir -pl -s255 profile.icc" on the following 7
profiles produces these results:

Apple-CCT           100.000000 -0.002638  0.000000
Apple-D65code       100.000000  0.000000  0.000000 perfect

CIE-RGB-CCT         100.000000  0.000000  0.001233
CIE-RGB-E_5454K       100.000000  0.000000  0.001233

Clay-CCT            100.000000 -0.002638  0.001233
Clay-D65_old        100.000000  0.000000  0.001233

NTSC-CCT            100.000000  0.000000  0.001233
NTSC-C_6774K          100.000000  0.000000  0.001233

SMPTE-CCT         100.000000  0.000000 -0.001233
SMPTE-D65_old       100.000000 -0.002638  0.001233

sRGB-CCT             99.999410  0.002543 -0.001017
sRGB-D65code        100.000000  0.000000  0.001233

Widegamut-CCT       100.000590 -0.005181  0.001017
Widegamut-D50_lcms  100.000000  0.000000  0.001233

Profile white point key:
"CCT" = lcms correlated color temp; I used 6503.6 for D65.
D65code  = (0.31271, 0.32912)
E_5454K   = (0.333608970, 0.348572909) Robertson equations
D65_old  = (0.312700, 0.329000)
C_6774K   = (0.308548930, 0.324928102) Robertson equations
D50_lcms = (0.345702915, 0.358538597)

In the profiles above, the value +/- 0.001233 shows up ten times over
a diverse set of profile white points. Including results from other
profiles, 0.002543, 0.001017 and 0.002638 also show up multiple times,
though not as frequently as 0.001233.

For R=G=B=255, no deviation from 0 in the Lab "a" channel plus a
deviation of 0.001233 in the Lab "b" channel corresponds to a
deviation of 0.000015 (+0.001233) or 0.000016 (-0.001233) in the Z XYZ
channel (the X value deviation is 0 in either case). The values
"0.000015" and "0.000016" are important numbers when converting from
XYZ to hexadecimal:

0.000015 (and any smaller value), multiplied by 65535 and converted to
hex, is 0.
0.000016, multiplied by 65535 and converted to hex, is 1.

This might be purely coincidental, but it suggests a decimal to
hexadecimal rounding error. So I looked for a possible source of a "1
hex unit" error and perhaps found one. The following lines are in the
"lcms2.h" file:

// D50 XYZ normalized to Y=1.0
#define cmsD50X             0.9642
#define cmsD50Y             1.0
#define cmsD50Z             0.8249

Using these cmsD50X and cmsD50Z values, here's the round-trip
conversion through hex:

starting values:         (0.964200000, 1.0, 0.824900000)
convert to hex:          (F6D4, FFFF, D32B)
convert back to decimal: (0.964187076, 1.0, 0.824887465)
absolute difference:     (0.000012924, 0.0, 0.000012535)

According to iccToXml, for profiles generated by lcms the profile
header illuminant value is (0.964202881, 1, 0.824905396). The
corresponding round-trip conversion through hex values are:

starting values:         (0.964202881, 1.0, 0.824905396)
convert to hex:          (F6D5, FFFF, D32C)
convert back to decimal: (0.824902724, 1.0, 0.964202335)
absolute difference:     (0.000000546, 0.0, 0.000002672)

Notice that the iccToXml illuminant values convert to hex and back
with a smaller error, and also the resulting hex values are larger by
1 hex unit (F6D4->F6D5, D32B->D32C).

So what happens if the D50 XYZ values in lcms2.h are changed to match
the iccToXml illuminant values?

// D50 XYZ normalized to Y=1.0
#define cmsD50X             0.96420288 //iccToXml header illuminant value
#define cmsD50Y             1.0
#define cmsD50Z             0.82490540 //iccToXml header illuminant value

To find out, I
*Changed the D50 values in lcms2.h to equal the header illuminant
value reported by iccToXml
*Recompiled lcms
*Recompiled my profile-making code
*Recreated all the profiles using the exact same white points as before

Here are the new xicclu results:

Apple-mod-CCT       100.000000  0.002638  0.000000 flipped sign
Apple-mod-D65code   100.000000  0.000000  0.000000 perfect

CIE-RGB-mod-CCT     100.000000  0.000000  0.000000 perfect
CIE-mod-RGB-E_5454   100.000000  0.000000  0.000000 perfect

Clay-mod-CCT        100.000000  0.000000  0.001233 improved
Clay-mod-D65_old    100.000000  0.000000  0.000000 perfect

NTSC-mod-CCT        100.000000  0.000000  0.000000 perfect
NTSC-mod-C_6774      100.000000  0.000000  0.000000 perfect

SMPTE-mod-CCT       100.000000  0.000000 -0.001233 no change
SMPTE-mod-D65_old   100.000000  0.000000  0.000000 perfect

sRGB-mod-CCT         99.999410  0.002543 -0.001017 no change
sRGB-mod-D65code    100.000000  0.000000  0.000000 perfect

Widegamut-mod-CCT       100.000590 -0.005181  0.001017 no change
Widegamut-mod-D50_lcms  100.000000  0.000000  0.000000 perfect

I've checked many more profiles than are listed above, and the results
are 100% consistent.

"Color balanced" isn't everything! I checked all the profiles against
the Lindbloom xyY values by calculating the sum of the absolute
differences in the x,y,Y values for the red, blue, and green channels.
In most cases, the profiles produced by the modified lcms2.h file are
slightly closer to the Lindbloom values than the profiles produced by
the unmodified lcms2.h file. Widegamut and CIE-RGB values are slightly
farther away. In all cases the change is very small.

So if you actually had the patience to read all the way through this
post, does it look like there might be something in the lcms source
code that is systematically introducing small rounding errors that are
independent of the profile white point?

Elle

------------------------------------------------------------------------------
Learn the latest--Visual Studio 2012, SharePoint 2013, SQL 2012, more!
Discover the easy way to master current and previous Microsoft technologies
and advance your career. Get an incredible 1,500+ hours of step-by-step
tutorial videos with LearnDevNow. Subscribe today and save!
http://pubads.g.doubleclick.net/gampad/clk?id=58040911&iu=/4140/ostg.clktrk
_______________________________________________
Lcms-user mailing list
Lcms-user@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/lcms-user

Reply via email to