Welcome to MSDN Blogs Sign in | Join | Help

This year at WinHEC we had a demo that showed the use of ICC and WCS by various applications and system components on Windows Vista.

A part of this was a specially prepared jpeg image with an embedded ICC profile that contains a WCS profile in an 'MS00' tag. The jpeg had its red and blue channels swapped. The ICC profile had its blue and green matrix column contents swapped. And the WCS device model profile had its red an blue primary XYZ values swapped.

The jpeg is a picture of a Ducati "Desmosedeci" MotoGP bike. It is definitely a red motorcycle. So, if you open this jpeg in an application or system component, the apparent color of the motorcycle will tell you how the embedded profile was handled:

  1. If the motorcycle is blue, the embedded profile was completely ignored.
  2. If the motorcycle is green, the embedded ICC profile was honored.
  3. If the motorcycle is red, then you're probably running Windows Vista(tm) as the WCS profile contained in the 'MS00' tag in the embedded ICC profile was extracted and used by WCS.

At WinHEC, this allowed us to show how applications written to use ICM2 got WCS support "for free" via the WCS-in-ICC mechanism. Besides showing that most of the Office 12 applications (except for Internet Explorer 7) now honor embedded profiles in images, and use WCS for color conversion on Windows Vista, we were able to get Adobe Photoshop to use WCS! If you open the test image in Photoshop (CS1 or 2) on Windows Vista, and tell it to use the embedded profile, you will see a green motorcycle: the embedded ICC profile is being correctly used by Adobe's ACE CMM. Photoshop always uses ACE when converting on-the-fly from the current working space to the display's color space. However, if you do a "Convert to Profile" with "Microsoft ICM" selected as Engine, to most any ICC profile as destination, you will wind up with a red motorcycle: the conversion ran through the WCS CITE transform pipeline and used the embedded WCS profile.

I've attached a zip archive containing the jpeg test image, RGB-Red-Ducati_WCS-Test-TriState.jpg, and an external copy of the embedded WCS-in-ICC test profile, BGR-Wcs-RBG-Icc-Test.icc. See "Attachment(s)" link below. Have fun!

I recently noticed a discrepancy between the online documentation for the WcsOpenColorProfile and OpenColorProfile APIs and their declarations in the icm. h header file (and the icm.h version is correct). The Windows Vista SDK online documentation  at http://windowssdk.msdn.microsoft.com/en-us/library/ms536878.aspx has it as:

HPROFILE WINAPI WcsOpenColorProfile(
  __in PPROFILE pDMPProfile,
  __in_opt PPROFILE pCAMPProfile,
  __in_opt PPROFILE pGMMPProfile,
  __in DWORD dwDesiredAccess,
  __in DWORD dwShareMode,
  __in DWORD dwCreationMode
);

And says concerning the pDMPProfile parameter:

"If the profile is ICC and its dwType member is set to DONT_USE_EMBEDDED_WCS_PROFILES, WcsOpenColorProfile ignores any embedded WCS profile within the ICC profile."

This is incorrect. There is actually an additional parameter in the WcsOpenColorProfile interface, dwFlags, and DONT_USE_EMBEDDED_WCS_PROFILES may be set in dwFlags, rather than in the dwType member of the PROFILE data structure. Here's the correct WcsOpenColorProfile interface:

HPROFILE WINAPI WcsOpenColorProfile(
  __in PPROFILE pDMPProfile,
  __in_opt PPROFILE pCAMPProfile,
  __in_opt PPROFILE pGMMPProfile,
  __in DWORD dwDesiredAccess,
  __in DWORD dwShareMode,
  __in DWORD dwCreationMode,
  __in DWORD dwFlags
);

The interface for OpenColorProfile is correct in the online docs at http://windowssdk.msdn.microsoft.com/en-us/library/ms536835.aspx as:

HPROFILE WINAPI OpenColorProfile(
  PPROFILE pProfile,
  DWORD dwDesiredAccess,
  DWORD dwShareMode,
  DWORD dwCreationMode
);

However, there is a similar incorrect comment in the description of the pProfile parameter:

"If the dwType member within the Profile structure takes the value DONT_USE_EMBEDDED_WCS_PROFILES, and the Profile is of type ICC, this function ignores any embedded WCS profile within the ICC profile."

The dwType member of the PROFILE data structure cannot be used in this way, and since OpenColorProfile was a pre-WCS/pre-Vista ICM 2.0 API (which precluded our adding an additional parameter to its interface) there is no way to prevent the use of WCS profiles embedded in ICC profiles opened via OpenColorProfile. If such control is necessary, you should use WcsOpenColorProfile.

These errors have already been corrected in more recent versions of the SDK documentation that have not yet been posted to MSDN.

One of our IHV partners (thanks, Harold!) recently asked a question regarding the IDeviceModelPLugIn::DeviceToColorimetricColorsWithBlack() API in the WCS device model plugin interface (see http://windowssdk.msdn.microsoft.com/en-us/library/ms536863.aspx). He wondered if there was a missing ColorimetricToDeviceColorsWithBlack() API, since the black generation information is primarily useful in the colorimetric-to-device direction. He is absolutely right. This routine should be named "IDeviceModelPlugin::ColorimetricToDeviceColorsWithBlack()". There is no "IDeviceModelPlugin::DeviceToColorimetricColorsWithBlack()" API. WcsPlugin.idl has the correct interface definition. This is a cut-n-paste error in the specs, and has been corrected in recent versions of the SDK documentation. Unfortunately, these haven't percolated up to the MSDN site, yet. Sorry for any confusion this may have caused.

The Color Team is pleased to announce that, as promised, we have published our internal design specifications for WCS. These detail all of the algorithms used in the WCS baseline device models and gamut mapping methods. They now part of the Windows Vista Beta 2 SDK documentation and are now available on MSDN at http://windowssdk.msdn.microsoft.com/en-us/library/ms536900(VS.80).aspx.

The documentation for the WCS APIs can be found there at http://windowssdk.msdn.microsoft.com/en-us/library/ms536536(VS.80).aspx.

[You will probably notice that there have been some inappropriate replacements of "ICM" by "WCS" in what was the existing ICM 2.0 documentation. We will be correcting these.]

We've had a couple of folks tripped-up over this issue, so I figure it's worth a blog posting. Early versions of the WCS documentation indicate that none of the ICM APIs that deal with specific ICC profile structures will work with WCS device model profiles (DMPs). This information is correct for all of the following APIs:

GetCountColorProfileElements
GetColorProfileElementTag
IsColorProfileTagPresent
GetColorProfileElement
SetColorProfileHeader
SetColorProfileElementSize
SetColorProfileElement
SetColorProfileElementReference
GetNamedProfileInfo
ConvertColorNameToIndex
ConvertIndexToColorName
GetPS2ColorSpaceArray
GetPS2ColorRenderingIntent
GetPS2ColorRenderingDictionary

Any of these ICM APIs will fail (return FALSE) if called using a WCS profile rather than an ICC profile.

However, this is not the case with GetColorProfileHeader. In order to enable GDI+ to utilize WCS profiles it was necessary to modify GetColorProfileHeader to accept WCS device model profiles (DMPs, extension '.cdmp'). GDI+ uses the profile header to determine the color space of the profile.

GetColorProfileHeader will create a "synthetic" ICC profile header from the WCS DMP. Such synthetic headers can be readily distinguished from headers for actual ICC profiles by examining the "signature" field in bytes 36 through 39 of the 128 byte profile header. The header for a real ICC profile will always contain 'acsp' (big endian) in the "signature" field. A header synthesized from a WCS profile will contain 'cdmp' (big endian) in the signature field, and the CMMType field in such a header will contain 'wcs1' (big endian).

So: it is not safe to assume because GetColorProfileHeader succeeded (returned TRUE) that one is dealing with an ICC profile. You should check the signature field in the header to determine that, before going on to try to parse or modify the profile as though it were an ICC profile.

The number of questions we've seen regarding this issue indicates that there is still some confusion out there... So, I'm going to interupt the WCS gamut mapping series to clarify things: WCS will not be available for any pre-Windows Vista OS platforms. We have no plans to port WCS to Windows XP or any other pre-Vista Windows version.

I think the confusion around this stems from the fact that both the Windows Presentation Foundation (WPF, formerly WinFX), and the XML Paper Specification (XPS, formerly Metro) will be made available down-level.

The fact that WCS will not be available on Windows XP or Windows Server 2003 was one of the main reasons we decided to wrap WCS profiles in an approximating ICC profile for embedding purposes. This ensures that some reasonable color management will be performed using the ICC profile on down-level platforms. Even when printing from Windows Vista, there is the possibility that a network printer may reside on a server running a down-level OS version.

The WCS Minimum Color Difference (MinCD) baseline gamut mapping model is conceptually the simplest of our gamut mapping algorithms. It corresponds roughly to the ICC colorimetric rendering intents, and like them it comes in two flavors that roughly correspond to the ICC relative and absolute colorimetric rendering intents.

MinCD differs from the ICC colorimetric intents primarily in that it operates on gamut boundary descriptions (GBDs) in the WCS color appearance model space (CAM space), rather than in the ICC colorimetric profile connection space (PCS)... So it is not really "colorimetric" in that sense.

Like the ICC colorimetric intents, source colors that fall within the destination gamut are unchanged, and source colors that fall outside the destination gamut are mapped to the "nearest" color on the destination GBD surface. For out of gamut colors, lightness and chroma are adjusted by finding the point in the destination’s gamut surface that has the mimimum weighted color distance from the out of gamut input point. The color distance is computed in CIECAM02 JCh space. However, we weight the distance in lightness (J) and the distance in chroma (C) or hue (h) differently. A chroma-dependent weighting function is used for the distance in lightness so that the weight is smaller for small chroma and larger for large chroma until a threshold chroma is reached, after which the weight stays at 1, i.e. same weight as distance in chroma or hue. Our lightness weighting function looks like this:

wJ = k2 – k1 (C – Cmax)n

 

where k2 = 1, k1 = 0.75/(Cmax)n, Cmax = 100, n = 2 and C is the smaller of chroma of the query point and Cmax.

so that a weight of 0.25 is put on the J term when chroma is zero, and a weight of 1 when chroma is 100. The trend of putting less weight on J when chroma is small, more weight on J when chroma is large follows the recommended usage for CMC and CIEDE2000.

Here are the two variants:

"Relative" (specified by the Proofing.gmmp gamut mapping model profile) - First we align the source and destination neutral axes in CAM space as described in Part 1 of this series, Gamut Mapping in WCS, Part 1. Source colors are converted into CAM space using the source device model to give XYZ and the CIECAM02 conversion and the source viewing conditions. We then apply the source neutral axis adjustment to the source color in CAM space. Then we clip the adjusted source color to the nearest color on the adjusted destination gamut boundary. We then apply the inverse of the destination neutral axis adjustment to give us the output color in CAM space. We then use the inverse (CAM to XYZ) CIECAM02 conversion, parameterized using the destination viewing conditions, followed by the destination device model to produce the output color in the destination device color space.

"Absolute" (specified by the MediaSim.gmmp gamut mapping model profile) - This is similar to "Relative" but without the alignment of the source and destination neutral axes, and so, without the neutral axis adjustments being applied to the colors being mapped. Thus, source colors in CAM space are clipped directly to the un-adjusted destination gamut boundary in CAM space.

Applications:

The MinCD GMMPs are primarily intended for use in the final stage of simulation or proofing color transforms. An example of this would be simulating output from a printer on your display ("softproofing"). Such transforms look like this (assuming a photographic or contone source image):

source space -> Photo.gmmp -> printer space -> [MinCD] -> display space

In most cases [MinCD] should be the "relative" variant, Proofing.gmmp, this will map the printer's neutral axis onto the display's neutral axis: the printer's paper white will map to the display's whitepoint. This is usually what you want when softproofing. There are cases where you want to simulate the appearance of the printer substrate or media ("paper color") on the display device. Using the "absolute" variant of MinCD, MediaSim.gmmp, will accomplish this - the color of the printer's substrate will not be mapped to a neutral on the display. This will give the displayed image an apparent color cast, relative to the display's whitepoint. MediaSim.gmmp should only be used when such media simulation is desired.

Another use for the "relative" variant of MinCD, Proofing.gmmp, is for rendering "logo colors". Proofing.gmmp will render in-gamut colors exactly, and that is generally what you want for colors used in logo graphics.

One caveat is that MinCD may produce undesireable artifacts in smooth gradients that cross the destination gamut boundary. The clipping of the out-of-gamut colors in the gradient to the nearest colors on the destination gamut boundary may result in changes in chroma or lightness that appear as banding or oscillation in the output gradient. This depends on the shape of the destination gamut boundary and the colors in the gradient.

The WCS Photographic baseline gamut mapping model, specified by Photo.gmmp, will render such gradients without artifacts.

I will describe the WCS Photographic baseline gamut mapping model in the next posting in this series.

Gamut mapping in WCS is established at color transform creation time, rather than at profile creation time. And, while our baseline gamut mapping methods each implement a different gamut mapping algorithm, there are some operations that are common to all of them. So, here I'll describe those commonalities, before going into the individual gamut mapping algorithms in following posts.

All gamut mapping operations in WCS are performed between explicit gamut boundary descriptions (GBDs) in our color appearance model (CAM) space. This space based on CIECAM02. For each device or color space involved in a color transform we construct a GBD. A GBD may consist of one or two gamut shells: a "reference shell", and for some devices a "plausible shell".

A GBD shell is represented as an indexed vertex list of the (possibly convex) hull of the device gamut. The indexed vertex list is stored in CIECAM02 Jab. The structure of the indexed vertex list is optimized for hardware acceleration by DirectX. This approach has many well known solutions (search for "convex hull DirectX" on the web and you get well over 100 hits).

For output devices (displays and printers) we only need to create one shell, the "reference shell". This is because characterization targets can fully span the device space for output devices. For printers we wrap a convex hull around the measurement sample points. For additive RGB devices, we warp the surface of the RGB color cube into the color appearance space and use that.

For virtual RGB devices (i.e. sRGB, wcsRGB) we may or may not have device sample values provided. When the measurement values are available, we generate the reference shell as for output devices. If not, then we warp the surface of a color cube for device values in the range [0.0 .. 1.0] into the color appearance space and use that.

For input devices (cameras and scanners), where a calibration target may not entirely span the device color space, we create a reference shell and a "plausible shell". The reference shell is just a convex hull around the measurement samples used to initialize the input device model. We then use that device model itself to extrapolate color values for the full device color range. Those extrapolated color values are wrapped with a convex hull to form the plausible shell.

Typically, our baseline gamut mapping models apply different gamut mapping in the region between the reference and plausible shells than is used within the reference shell itself.

Given a source and a destination GBD (these may be just be adjacent stages in a longer transform sequence) the first operation performed in our baseline gamut mapping models is to adjust both the source and destination GBDs so that their neutral axes align with the neutral axis of the CAM space. Here is an illustration of that adjustment on a particular hue slice in CAM space:

This neutral axis mapping is used during gamut mapping in the following fashion: Each color in the source color data set is converted into CAM space using the source device model and the viewing condition parameters supplied in the source color appearance model profile (CAMP). That color in CAM space is then adjusted using the source neutral axis alignment adjustment at its lighness level on its CAM hue "leaf". Next, the gamut mapping model specified in the gamut mapping model profile is applied to map the color from the adjusted source gamut into the adjusted destination gamut. Then, the inverse of the destination neutral axis alignment adjustment is applied to the gamut mapped color to yield the output color in CAM space. And Finally, the destination-side CAMP and device model are used to convert the color from CAM space to the destination color space.

I will go into the individual WCS baseline gamut mapping models in subsequent postings in this series.

Until recently, most ICC-based color management processing engines (CMMs), including Windows' ICM CMM, implemented the processing models defined in the ICC profile format specifications; they were a collection of matrix and interpolation table processors. Such CMMs are termed "static CMMs": they implement a fixed set of processing models defined in the ICC specs.

In ICC-based color management systems most of the complexity, art, and color science happens during profile creation: the color rendering or gamut mapping between a device color space and the ICC profile connection space (PCS) is established during profile creation - the device <-> PCS transform is precomputed. The operation of the static CMM is pretty cut-and-dried. Ideally, all static ICC CMMs should produce the same results processing color data through the same set of profiles.

With the introduction of the version 4 ICC profile format specification, the ICC enabled support for what are called "dynamic" or "deferred-color-rendering" CMMs. Prior to version 4, there was some ambiguity about whether the results of the relative colorimetric rendering intent table could be scaled so that the black point matched the PCS black point. In version 4, it was clarified that the relative colorimetric rendering intent table was not scaled, but the perceptual LUT is scaled. (Thus, there is a defined gamut boundary for the perceptual intent, but none for the colorimetric intent.) It is possible to recover colorimetry from the relative colorimetric tables, and such pseudo-measurement data can be used by a dynamic CMM.

A dynamic CMM is one that defers color rendering and gamut mapping until runtime They may support processing models other than those described in the ICC specs. Often they operate with raw color measurement data. In the ICC context, a dynamic CMM recovers pseudo-measurement colorimetric data from ICC profiles, and then performs device modeling and color rendering based on that measurement data. Dynamic CMMs can utilize modern color appearance models, and more elaborate processing models than those available to static CMMs. The nature of that modeling and color rendering are left undefined by the ICC. Dynamic CMMs can also avoid the gamut and dynamic range limitations imposed by the ICC print-referred PCS.

WCS offers our customers both a static and a dynamic CMM. The static CMM is the improved ICM CMM, with added support for version 4 ICC profiles. The dynamic CMM is the WCS Color Infrastructure and Translation Engine (CITE), which uses both ICC profiles and WCS XML profiles. Both CMMs are available, and the choice of which to use in a particular color workflow is entirely up the user (or at least, up to the author of the color software involved). Also, our dynamic CMM extends its support to both ICC v4 profiles, and to the older and much more widespread ICC v2 profiles.

We have defined new XML-based device model profiles, gamut mapping model profiles, and color appearance model profiles for use with WCS. These new profiles, which are embeddable in ICC profiles, carry the parameters used for selection of the WCS device model, the choice of gamut mapping method, and the viewing condition parameters used in WCS's CIECAM02-based color appearance model. The WCS device model profiles also carry raw measurement data, and provide a very simple way to unambiguously characterize a color device. They are especially useful when the device has a wide gamut or a high dynamic range not well accommodated by the ICC PCS.

While static CMMs are generally limited to 8- and 16-bit per channel integer data, the WCS CITE can also process fixed point and floating point color data, with up to 32 bits per channel It even extends this support to color transforms involving ICC profiles. The WCS CITE can construct and evaluate color transforms that contain a mix of ICC and WCS profiles, or even all-ICC profile transform sequences.

Thus, WCS provides continuing improved support for ICC static-CMM/precomputed-profile color management, as well as offering the first widely available dynamic CMM. As mentioned above, while the ICC doesn't define or restrict the behavior of a dynamic CMM, the WCS CITE is fully documented, with all its device models, its color appearance model, and all gamut mapping algorithms detailed, so that its color processing is understandable and predictable.

Predictability is often cited as the most desired and valuable characteristic of a color managed workflow. It's also been one of the most difficult to achieve. A widely recommended approach involves sticking with a single CMM (Color Management Module) and using color profiles created with a single profile creation tool. Even then, getting a color workflow working  remains a trial-and-error process.

We have little or no insight into the algorithms used by the profile creation tools: these are usually proprietary. You may generally like the way a particular CMM works, but when it lets you down, there is no easy way to find out why. The internals of most CMMs are also, proprietary. Current color management systems tend to be collections of black boxes. We can create new black boxes, or swop others in and out in an effort to make our workflow produce the output we want... but, we are fundamentally juggling black boxes.

This situation lead to our policy of complete transparency with respect to WCS internals. We fully documented all of the algorithms used in WCS's device models, gamut mapping models, and color translation pipeline.  Our actual internal design documents for WCS have been available under NDA since June of 2004. Further, we are committed to make the WCS documentation public prior to the market release of Windows Vista.

Because WCS provides a well documented set of baseline device models, baseline gamut mapping models, and a fully documented processing pipeline, color workflows that rely on these baseline models are assured of understandable, consistent, and predictable color processing.

Back in November of 2005, I presented an invited paper on the Windows Color System (WCS) at CIC 13 in Scottsdale, AZ. The annual IS&T/SID Color Imaging Conference is the world's premier color science conference, and draws distinguished color scientists and engineers from all over the world.

The evening session was packed, with essentially the entire conference in attendance. The presentation was very well received, and the tone of the following Q&A session was distinctly positive. It generated a lot of interest among the attendees, and I was fielding questions for the rest of the week. As it turns out, this was the first public presentation on WCS at a non-Microsoft-organized event.

The PowerPoint deck for the talk is available here: Evolution in the Microsoft Color Management Ecosystem.

 
Page view tracker