Kai-Uwe Behrmann schrieb:

Am 17.09.04, 21:02 +0800 schrieb Peter:


Hello,

I try doing the Lab to CMYK convertion with snippet like below, it works

   double fLab[3];
   unsigned char nCMYK[4];

   fLab[0] = 50.0;
   fLab[1] = 80.0;
   fLab[2] = 50.0;
   hOutProfile = cmsOpenProfileFromFile(szPath, "r");
   hLabProfile = cmsCreateLabProfile(NULL);
   hTransform = cmsCreateTransform(hLabProfile,
                                TYPE_Lab_DBL,
                                hOutProfile,
                                TYPE_CMYK_8,
                                intent, 0);

   cmsDoTransform(hTransform, fLab, nCMYK, 1);
   cmsDeleteTransform(hTransform);
   cmsCloseProfile(hLabProfile);
   cmsCloseProfile(hOutProfile);

But when I change it to Lab 8 bit, it does not produce the similar result.

   unsigned char nCMYK[4];
   unsigned char nLab[3];

   nLab[0] = 50;
   nLab[1] = 80;
   nLab[2] = 50;
   hOutProfile = cmsOpenProfileFromFile(szPath, "r");
   hLabProfile = cmsCreateLabProfile(NULL);
   hTransform = cmsCreateTransform(hLabProfile,
                                TYPE_Lab_8,
                                hOutProfile,
                                TYPE_CMYK_8,
                                intent, 0);

   cmsDoTransform(hTransform, nLab, nCMYK, 1);
   cmsDeleteTransform(hTransform);
   cmsCloseProfile(hLabProfile);
   cmsCloseProfile(hOutProfile);

Is it because Lab values are different for 8 bit format & double format ?


You can set

 nLab[0] = fLab[0] * 255.0 / 100.0;
 nLab[1] = fLab[1] + 127.0;
 nLab[2] = fLab[2] + 127.0;

According to the ICC spec, the 8-bit encoding for CIELAB PCS values is defined as

 L* = 0.0 ... 100.0 is encoded as 0x00 .. 0xff
 a* = -128.0 ... 0.0 ... 127.0 is encoded as 0x00 ... 0x80 ... 0xff
 b* = -128.0 ... 0.0 ... 127.0 is encoded as 0x00 ... 0x80 ... 0xff

So the conversion cold look like:

 double L, a, b;
 unsigned char L8, a8, b8;

 /* just to make sure, not to exceed the valid range */
 if (L < 0) L = 0; if (L > 100) L = 100;
 if (a < -128) a = -128; if (a > 127) a = 127;
 if (b < -128) b = -128; if (b > 127) b = 127;

 L8 = floor(L * 255.0 / 100.0 + 0.5)
 a8 = floor(a + 128.0 + 0.5);
 b8 = floor(a + 128.0 + 0.5);


For 16-bit CIELAB values, there are two (different) encodings defined:

1) legacy 16-bit CIELAB encoding of V4 (which is used on the PCS side of CLUT table of lut16Type), and which corresponds to the CIELAB PCS encoding of V2 profiles:

 L* = 0.0 ... 100.0 is encoded as 0x0000 .. 0xff00
 a* = -128.0 ... 0.0 ... 127.0 ... 127.0+255.0/256.0
      is encoded as 0x0000 ... 0x8000 ... 0xff00 ... 0xffff
 b* = -128.0 ... 0.0 ... 127.0 ... 127.0+255.0/256.0
      is encoded as 0x0000 ... 0x8000 ... 0xff00 ... 0xffff

2) the CIELAB PCS encoding of V4:

 L* = 0.0 ... 100.0 is encoded as 0x0000 .. 0xffff
 a* = -128.0 ... 0.0 ... 127.0 is encoded as 0x0000 ... 0x8080 ... 0xffff
 b* = -128.0 ... 0.0 ... 127.0 is encoded as 0x0000 ... 0x8080 ... 0xffff


But I'm not sure, which encoding is expcted by the the cmsDoTransform() API, since it looks like this is not documented - I think it would be necessary to check the code (or to ask Marti).


Regards,
Gerhard




------------------------------------------------------- This SF.Net email is sponsored by: YOU BE THE JUDGE. Be one of 170 Project Admins to receive an Apple iPod Mini FREE for your judgement on who ports your project to Linux PPC the best. Sponsored by IBM. Deadline: Sept. 24. Go here: http://sf.net/ppc_contest.php _______________________________________________ Lcms-user mailing list [EMAIL PROTECTED] https://lists.sourceforge.net/lists/listinfo/lcms-user

Reply via email to