Search code examples
colorscolor-management

How do the the different parts of an ICC file work together?


I took apart an ICC file from http://www.brucelindbloom.com/index.html?MunsellCalcHelp.html with a look up table using ICC Profile Inspector. The ICC file is supposed to convert Lab to Uniform LAB.

The files it outputs include headers, a matrix (3x3 identity matrix), Input and Output curves, and a lookup table. What do these files mean? And how are they related to the color transform?

The header contents are:

InputChan: 3
OutputChan: 3
Input_Entries: 258
Output_Entries: 256
Clut_Size: 51

The InputCurves file has entries like:

0 0 0 0 
1 256 255 255 
2 512 510 510 
...
256 65535 65280 65280 
257 65535 65535 65535 

The OutputCurves file has entries like:

0 0 0 0 
1 256 257 257 
2 512 514 514 
...
254 65024 65278 65278 
255 65280 65535 65535 

And the lookup table entries look like:

0 0 0 25968 
1 0 0 26351 
2 0 0 26789 
...
132649 65535 65535 49667 
132650 65535 65535 50603 

I'd like to understand how an input LAB color maps to an output value. I'm especially confused because a & bvalues can be negative.


Solution

  • I believe I understand how this works after skimming through http://www.color.org/specification/ICC1v43_2010-12.pdf

    This explination may have some off by 1 errors, but it should be generally correct.

    The input values are LAB, and L values are mapped using table 39 & 40 in section 10.8 lut16Type. Then the 258 values in the input curves are uniformly spaced across those L, a, & b ranges. The output values are 16 bit, so 0-65535.

    The same goes for the CLUT. There are 51^3 entries (51 was chosen by the ICC file authoer). Each dimension (L,a,b) is split uniformally across this space as well. So 0 = 0 & 50 (note 0 - 50 is 51 entries) = 65535 from the previous section. The first 51 rows are for L =0 and a =0, but incriment b. Every 51 rows, the a value increses by 1, and every 51*51 rows, the L values increases by 1.

    So given L, a, and b values adjusted by the input curves, figure out their index (0-50) and look those up in the CLUT (l_ind*51*51+a_ind*51+b_ind), which will give you 3 more values.

    Now the output curves come in. It's another set of curves that work just like the input curves. The outputs can then get mapped back using the same values from Tables 39 & 40.