John Weissberg wrote:
As I understand it, the real purpose of this pre-linearization table is to
> guarantee that the value for a or b corresponding to the case where the > index in the 33x33x33 matrix is 16 actually map to a or b values very close to 0. That's one purpose. There can be others, such as expanding the area occupied by the devices gamut, to fill out more of the B2A table (thereby improving accuracy), or improving overall linearity by helping to compensate for the (usually) linear interpolation done with CLUT lookups.
I am still a bit confused as to how this pre-linearization matrix works. Below are the values for L,a,b that correspond to the 33x33x33 matrix indices prior to processing with the pre-linearization:idx L a b 0 0.00 -128.00 -128.00 1 3.13 -120.03 -120.03 2 6.25 -112.06 -112.06 3 9.38 -104.09 -104.09 4 12.50 -96.13 -96.13 5 15.63 -88.16 -88.16 6 18.75 -80.19 -80.19 7 21.88 -72.22 -72.22 8 25.00 -64.25 -64.25 9 28.13 -56.28 -56.28 10 31.25 -48.31 -48.31 11 34.38 -40.34 -40.34 12 37.50 -32.38 -32.38 13 40.63 -24.41 -24.41 14 43.75 -16.44 -16.44 15 46.88 -8.47 -8.47 16 50.00 -0.50 -0.50 17 53.13 7.47 7.47 18 56.25 15.44 15.44 19 59.38 23.41 23.41 20 62.50 31.38 31.38 21 65.63 39.34 39.34 22 68.75 47.31 47.31 23 71.88 55.28 55.28 24 75.00 63.25 63.25 25 78.13 71.22 71.22 26 81.25 79.19 79.19 27 84.38 87.16 87.16 28 87.50 95.13 95.13 29 90.63 103.09 103.09 30 93.75 111.06 111.06 31 96.88 119.03 119.03 32 100.00 127.00 127.00
This is only true for 8 bit or V4 CLUTs. For V2 16 bit cluts, the ranges are L* 0 .. 100 + (25500/65280), and a*b* 128 .. 127 + (255/256)
I would love if someone would help me understand exactly the formula used to apply the pre-linearization table to these points.
It's not too difficult, you just have to keep track of the encodings. A critical value for most profiles is L*a*b* = 100,0,0, and it should map exactly to the media white point because of the relative colorimetric nature of the table representations. This means in practice that the input value for 100,0,0 should land on a grid point, since you can't interpolate with values that are darker than white, to make white. (ie. that grid point is at the apex of the overall gamut hull). Assuming an odd dimensioned grid, that means that the input tables need to map L* = 100 to a clut input value of 1.0, and a*b* = 0 to a clut input value of 0.5. So for (say) 8 bit L*a*b*, that means that the L* input curve must map 0 == 0.0 -> 0.0 and 100 == 1.0 -> 1.0, while the a*b* has to map -127 == 0.0039215 -> 0.0, and 127 -> 1.0 For V2 16 bit, you would need L* 0 == 0.0 -> 0.0, and 100 == 0.996109 -> 1.0 and a*b* (say) -127.99609 == 0.000015259 -> 0.0 and 127.99609 == 1.0 -> 1.0. Note that the a*b* range can be any symmetric range (ie. -127 to 127 would also work fine for V2 16 bit), you just end up with slightly earlier per component clipping in the lookup, and restrict the gamut you can represent slightly. Graeme Gill.