Hello,

I'm trying to use lcms2 to convert sRGB values from a linear double 
precision representation into a gamma-corrected 8-bit representation 
(using the sRGB-specific gamma correction curve). For in-gamut values, 
that is a basic operation that doesn't really require a CMS.

I'm more interested in how out-of-gamut values are treated (e.g. when 
one of the double precision values is greater than one).

Can lcms be configured to handle this using one of the the four intent 
modes, for instance to desaturate the color instead of just clamping 
each component separately?

I've played around a bit (source attached) but was unable to produce 
such behaviour. In all cases, lcms2 just clamped the individual 
components without showing signs of doing some kind of more 
sophisticated projection onto the gamut. This can be a problem because 
clamping the components will lead to a hue shift, which may be 
unintended. Is it just a problem of my setup, or am I expecting 
something that lcms2 does not currently do?

I've never used this library before, so any advice would be much 
appreciated!

Thank you very much,
Wenzel

=====================

#include <lcms2.h>
#include <stdio.h>
#include <stdint.h>

/* Create a linear sRGB profile (based on cmsCreate_sRGBProfile)*/
cmsHPROFILE create_sRGBProfileLinear() {
     cmsCIExyY       D65;
     cmsCIExyYTRIPLE Rec709Primaries = {
         {0.6400, 0.3300, 1.0},
         {0.3000, 0.6000, 1.0},
         {0.1500, 0.0600, 1.0}
     };

     cmsWhitePointFromTemp(&D65, 6504);

     cmsToneCurve* gamma = cmsBuildGamma(NULL, 1.0);
     cmsToneCurve* gamma3[] = { gamma, gamma, gamma };

     return cmsCreateRGBProfile(&D65, &Rec709Primaries, gamma3);
}

int main(void) {
     cmsHPROFILE profile_sRGB = cmsCreate_sRGBProfile();
     cmsHPROFILE profile_sRGB_linear = create_sRGBProfileLinear();

     cmsHTRANSFORM transform = cmsCreateTransform(
         profile_sRGB, TYPE_RGB_DBL, profile_sRGB, TYPE_RGB_8,
         INTENT_RELATIVE_COLORIMETRIC, 0);

     {
         /* Inside of gamut: prints "188 188 188" -- that looks good. */
         double a[] = {0.5, 0.5, 0.5};
         uint8_t out[3];
         cmsDoTransform(transform, a, out, 1);
         printf("%i %i %i\n", (int) out[0], (int) out[1], (int) out[2]);
     }

     {
         /* Outside of gamut: prints "188 188 255" ?? -- I would have
            expected that the other channels would be scaled down due
            to gamut mapping. */
         double a[] = {0.5, 0.5, 1000};
         uint8_t out[3];
         cmsDoTransform(transform, a, out, 1);
         printf("%i %i %i\n", (int) out[0], (int) out[1], (int) out[2]);
     }

     cmsDeleteTransform(transform);
     cmsCloseProfile(profile_sRGB);
     cmsCloseProfile(profile_sRGB_linear);
}

------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and 
threat landscape has changed and how IT managers can respond. Discussions 
will include endpoint security, mobile security and the latest in malware 
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
_______________________________________________
Lcms-user mailing list
Lcms-user@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/lcms-user

Reply via email to