Re: [Lcms-user] RGB-to-XYZ-to-RGB weirdness
An ICC-based CMM for color management
Brought to you by:
mm2
From: Derek B. N. <de...@gl...> - 2017-10-23 20:01:43
|
Thanks, that makes sense. - Derek On 2017 Oct 23, Martí Maria wrote: > > Hi, > > XYZ gamut is huge, so using tetrahedral interpolation from XYZ to RGB is > likely to result in errors. I would use cmsFLAGS_NOOPTIMIZE in xyzToRGB > color transform to force all the math. > > Another option is to use float or double values. > > Regards > > Marti > > > On 10/20/2017 9:50 PM, Derek B. Noonburg wrote: >> I'm working on some color management code, using LCMS2, and I'm running >> into some behavior that I don't understand. >> >> If I convert sRGB to XYZ and then back to sRGB, I get significantly >> different RGB values at the output. >> >> If I do sRGB -> Lab -> sRGB, I get exactly the same values back. >> >> The really weird part is: if I convert XYZ to Lab and then to sRGB (sRGB >> -> XYZ -> Lab -> sRGB), I get the expected RGB values again. So the >> sRGB-to-XYZ conversion is fine, but the XYZ-to-sRGB conversion is wrong. >> Or, more likely, I'm doing something wrong... but I'm not sure what. >> >> Can someone explain what's going on here? >> >> I'm running LCMS 2.8 on Linux. Here's my test program: >> >> #include <stdio.h> >> #include <lcms2.h> >> >> int main(int argc, char *argv[]) { >> cmsHPROFILE rgbProfile = cmsCreate_sRGBProfile(); >> cmsHPROFILE labProfile = cmsCreateLab2Profile(NULL); >> cmsHPROFILE xyzProfile = cmsCreateXYZProfile(); >> cmsHTRANSFORM rgbToLab = cmsCreateTransform(rgbProfile, TYPE_RGB_8, >> labProfile, TYPE_Lab_16, >> INTENT_ABSOLUTE_COLORIMETRIC, >> 0); >> cmsHTRANSFORM labToRGB = cmsCreateTransform(labProfile, TYPE_Lab_16, >> rgbProfile, TYPE_RGB_8, >> INTENT_ABSOLUTE_COLORIMETRIC, >> 0); >> cmsHTRANSFORM rgbToXYZ = cmsCreateTransform(rgbProfile, TYPE_RGB_8, >> xyzProfile, TYPE_XYZ_16, >> INTENT_ABSOLUTE_COLORIMETRIC, >> 0); >> cmsHTRANSFORM xyzToRGB = cmsCreateTransform(xyzProfile, TYPE_XYZ_16, >> rgbProfile, TYPE_RGB_8, >> INTENT_ABSOLUTE_COLORIMETRIC, >> 0); >> >> unsigned char rgbIn[3] = {0x6a, 0x3c, 0x31}; >> >> // rgb1 matches rgbIn >> unsigned short lab1[3]; >> unsigned char rgb1[3]; >> cmsDoTransform(rgbToLab, rgbIn, lab1, 1); >> cmsDoTransform(labToRGB, lab1, rgb1, 1); >> printf("RGB %02x %02x %02x -> Lab %04x %04x %04x -> RGB %02x %02x %02x\n", >> rgbIn[0], rgbIn[1], rgbIn[2], >> lab1[0], lab1[1], lab1[2], >> rgb1[0], rgb1[1], rgb1[2]); >> >> // rgb2 does not match rgbIn >> unsigned short xyz2[3]; >> unsigned char rgb2[3]; >> cmsDoTransform(rgbToXYZ, rgbIn, xyz2, 1); >> cmsDoTransform(xyzToRGB, xyz2, rgb2, 1); >> printf("RGB %02x %02x %02x -> Lab %04x %04x %04x -> RGB %02x %02x %02x\n", >> rgbIn[0], rgbIn[1], rgbIn[2], >> xyz2[0], xyz2[1], xyz2[2], >> rgb2[0], rgb2[1], rgb2[2]); >> >> // rgb3 matches rgbIn >> cmsCIEXYZ xyzF; >> cmsCIELab labF; >> unsigned short lab3[3]; >> unsigned char rgb3[3]; >> cmsXYZEncoded2Float(&xyzF, xyz2); >> cmsXYZ2Lab(NULL, &labF, &xyzF); >> cmsFloat2LabEncoded(lab3, &labF); >> cmsDoTransform(labToRGB, lab3, rgb3, 1); >> printf("RGB %02x %02x %02x -> XYZ %04x %04x %04x -> Lab %04x %04x %04x -> RGB %02x %02x %02x\n", >> rgbIn[0], rgbIn[1], rgbIn[2], >> xyz2[0], xyz2[1], xyz2[2], >> lab3[0], lab3[1], lab3[2], >> rgb3[0], rgb3[1], rgb3[2]); >> } >> >> - Derek >> >> >> ------------------------------------------------------------------------------ >> Check out the vibrant tech community on one of the world's most >> engaging tech sites, Slashdot.org! http://sdm.link/slashdot >> _______________________________________________ >> Lcms-user mailing list >> Lcm...@li... >> https://lists.sourceforge.net/lists/listinfo/lcms-user >> > |