Re: [Lcms-user] Out of gamut treatment (linear double precision sRGB -> 8-bit sRGB)
An ICC-based CMM for color management
Brought to you by:
mm2
|
From: Wenzel J. <we...@cs...> - 2012-09-09 03:07:27
|
Hello, thank you for the clarification. I agree that "linear sRGB" is completely made-up. Nonetheless, in 3D rendering applications, this space is used very often. When the goal is to get sRGB output, the "linearized" version of sRGB is a quite convenient space for performing inter-reflection computations (as opposed to e.g. XYZ, xyY, CIELab, ..). I am thus interested in the answer to the following question: Given an out-of-gamut floating point RGB value (i.e. at least one of the components is > 1) that is defined in a sRGB color space with a linearized response, is it possible to use lcms2 to map it onto an in-gamut sRGB value in a way that is smarter than just clipping the individual components? (which causes hue shifts) I modified the snippet from the last email by replacing "cmsCreate_sRGBProfile" with a call that loads the v4 preference profile you suggested -- but still using the custom linear sRGB input profile. As you already hinted, this still does not work -- the value gets clipped before ever reaching the profile. Is there a way to avoid this, or am I asking for something unreasonable? Thanks! Wenzel On 09/07/2012 05:09 PM, Marti Maria wrote: > Hi, > > At first I have to clarify a very common misconception: there is no such > thing like a "linear" sRGB. > sRGB is a color space very precisely defined. > > See > http://www.color.org/chardata/rgb/srgb.pdf > http://www.color.org/chardata/rgb/srgb.xalter > > If you define a colorspace that has transfer functions of gamma 1.0, > primaries Rec709 and D65 as > white point you cannot call it "sRGB", just because this is not sRGB > but something close but not > sRGB. > > At that point, lcms2, as most of the modern CMM, uses what ICC describe > as "smart profiles, > dumb CMM". In this approach the profiles instructs the CMM how to do the > gamut remapping > and the CMM blindly obeys what the profile says. > > Then, looking at your code, you instruct the CMM to do exactly what you > get: to apply a tone > curves and to remain inside a set of primaries. So, it comes at no > surprise you get no gamut > mapping, it is just that you didn't tell the CMM how to do it. > > Let me show an example of what cold be done with a proper profile with > embedded gamut > mapping. Instead of using the simple cmsCreateRGBProfile () built-in, > please download and > try a real profile. You got some good sRGB ones from here: > > http://www.color.org/srgbprofiles.xalter#v4pref > > Please try the preference sRGB. With ICC trans you can check the profile > without any coding. > BTW, obviously you cannot use the same sRGB as the input, that would > make impossible to > encode out of gamut colors, and doing (0.5, 0.5, 1000) clips the value > on the input - it > doesn't even reach the profile. > > transicc -i*Lab -o sRGB_v4_ICC_preference.icc > LittleCMS ColorSpace conversion calculator - 4.2 [LittleCMS 2.04] > > Enter values, 'q' to quit > L*? 50 > a*? -128 > b*? 23 > > R=0.0000 G=198.5075 B=124.5013 > > I'm converting an extremely saturated green to a in-gamut sRGB value by > using gamut > remapping. If I try the same by using just plain conversion: > > transicc -i*Lab -o *sRGB > LittleCMS ColorSpace conversion calculator - 4.2 [LittleCMS 2.04] > > Enter values, 'q' to quit > L*? 50 > a*? -125 > b*? 3 > > R=-900.4487 G=154.3234 B=109.4446 > > Quite different green! lcms2 unbounded mode gives you the RGB without > clipping, please note the R=-900!! > > Please compare (0,154, 109) with (0, 199, 125). It would be nice if you > get a chance to see > the original Lab=(50, -128, 23) but I'm afraid no device can reproduce > it because its extreme saturation. > > Hope that helps > Regards > Marti Maria > The LittleCMS Project > http://www.littlecms.com > > > El 07/09/2012 2:15, Wenzel Jakob escribió: >> 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 >> Lcm...@li... >> https://lists.sourceforge.net/lists/listinfo/lcms-user >> |