In the Specification, it describe the lagacy Lab encoding as below:
L*
0 0x0000
100.0 0xFF00
100+(25500/65280) 0xFFFF
a* or b*
-128.0 0x0000
0.0 0x8000
127.0 0xFF00
127+(255/256) 0xFFFF
(copy from ICC specification)
For example, B2A0 tag in "Photoshop5DefaultCMYK.icc", data type is
'mft2', PCS
is Lab( the input side ), device color space is CMYK( the output side ). It
has a CLUT, CLUT's grid number is 33 (0--32).
The question is: In the L* dimension, what does the last grid point 32 map
to
0xFFFF(65535) or represent for 0xFF00 ( 65280 )? equals 100+(25500/65280)
or 100.0?, and where is the L=100(0xFF00)?
I see the LCMS source code, it "prelinear" the Lab first, like this:
(following is from LCMS's source code)
// v2 L=100 is supposed to be placed on 0xFF00. There is no reasonable
// number of gridpoints that would make exact match. However, a
// prelinearization of 258 entries, would map 0xFF00 on entry 257.
// This is almost what we need, unfortunately, the rest of entries
// should be scaled by (255*257/256) and this is not exact.
//
// An intermediate solution would be to use 257 entries. This does not
// map 0xFF00 exactly on a node, but so close that the dE induced is
// negligible. AND the rest of curve is exact.
#define RGB_8_TO_16(rgb) (WORD) ((((WORD) (rgb)) << 8)|(rgb))
static
void CreateLabPrelinearization(LPGAMMATABLE LabTable[])
{
int i;
LabTable[0] = cmsAllocGamma(257);
LabTable[1] = cmsBuildGamma(257, 1.0);
LabTable[2] = cmsBuildGamma(257, 1.0);
// L* uses 257 entries. Entry 256 holds 0xFFFF, so, the effective range
// is 0..0xFF00. Last entry (257) is also collapsed to 0xFFFF
// From 0 to 0xFF00
for (i=0; i < 256; i++)
LabTable[0]->GammaTable[i] = RGB_8_TO_16(i);
// Repeat last for 0xFFFF
LabTable[0] ->GammaTable[256] = 0xFFFF;
}
WORD cmsLinearInterpLUT16(WORD Value, WORD LutTable[], LPL16PARAMS p)
{
double y1, y0;
double y;
double val2, rest;
int cell0, cell1;
// if last value...
if (Value == 0xffff) return LutTable[p -> Domain];
/* the p->Domain=257-1=256 */
val2 = p -> Domain * ((double) Value / 65535.0);
cell0 = (int) floor(val2);
cell1 = (int) ceil(val2);
// Rest is 16 LSB bits
rest = val2 - cell0;
y0 = LutTable[cell0] ;
y1 = LutTable[cell1] ;
y = y0 + (y1 - y0) * rest;
return (WORD) floor(y+.5);
}
I can't understand that program:
1: why LabTable[0], i.e L dimension, do such a prelinearization?
2: why LabTable[1], [2] ( i.e a and b ) don't do the same thing?
3: if I have a L*=42.0, in V2 encoding L=0.42*65280+0.5=27418. After
"cmsLinearInterpLUT16", L=27418 is changed to 27526. Why can't I use the
L=27418 to do interpolation to get CMYK( still need the output table )
directly?
Thank you.
FlyRainbow
Oct 13, 2008
--
世界微尘里,吾宁爱与憎
-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
Lcms-user mailing list
Lcms-user@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/lcms-user