skip to main content

Are Your Working Space Profiles Well Behaved?

In theory, RGB working spaces are suitable for image editing because they are well behaved. In practice, many RGB working space profiles provided by both open source and proprietary vendors are not completely well behaved. I did a survey of 30 widely distributed proprietary and open source working space profiles and found that only 9 of them were completely well behaved.

Written September 2013. Minor update in March 2015.

This article is the second of three articles on well behaved working spaces. The first article, What Makes a Color Space Well Behaved? defines "well behaved working space". The third article, In Quest of Well Behaved Working Spaces, explores the possibilities for creating well behaved versions of commonly available working spaces.

Free/libre software moves fast, and results on this page from testing done in 2013, are not necessarily applicable to equivalent profiles distributed at earlier or later points in time. For example, as of March 2015:

In other words, results in this survey should be considered cautionary rather than definitive. Check your RGB working space profiles and if they aren't good enough, make or find better ones, and/or file bug reports.

Some working space profiles for testing

In September 2013 I did a survey of 30 widely distributed proprietary and open source working space profiles (the date matters because open source software changes rapidly). My "measuring instrument" is the Argyllcms xicclu utility, which only provides results to six decimal places, so by "completely well behaved" I really mean "well behaved to six decimal places".

My survey included:

  • 5 AdobeRGB1998-compatible profiles
  • 2 AppleRGB profiles
  • 1 CIE-RGB profile
  • 2 ColorMatch profiles
  • 4 ProPhotoRGB profiles
  • 13 sRGB profiles
  • 3 WideGamutRGB profiles

A "well behaved" RGB working space is neutral, which means that if R=G=B, then the resulting color is neutral gray, with CIELAB coordinates (L*,0,0). Also, R=G=B=100 corresponds to LAB (100,0,0) and R=G=B=0 corresponds to LAB (0,0,0). See What Makes a Color Space Well Behaved? for details.

Out of the 30 working space profiles in my survey, only 9 profiles are well-behaved to at least six decimal places. The remaining 21 profiles are not well behaved to six decimal places. Most of them are well behaved to only 2 or 3 decimal places. One of the sRGB profiles is not well-behaved even to 1 decimal place.

My survey included profiles from the Adobe, littleCMS, and websites; plus profiles provided by Argyllcms, OpenICC, and the colord Shared Color Profiles; plus profiles distributed with digiKam, Krita, and an older copy of Canon DPP (circa 2007); plus an old sRGB profile from the Windows 2000 OS.

  • You can download the Argyllcms, Adobe, profiles, and lcms version 1 sRGB profile for yourself if you want to do your own testing.
  • The OpenICC profiles and the colord "Shared Color Profiles" can be installed from your Linux package manager. Krita and digiKam also are available from your Linux package manager and they both provide a selection of working space profiles.
  • The Krita built-in sRGB profile (actually any profile embedded in an image) can be extracted from Krita sRGB images by using the Argyllcms extracticc utility.
  • As far as I know, the only way you can get the proprietary Canon DPP profiles is by purchasing a Canon camera and installing the supplied software (at least older versions do install under Wine). Likewise, probably the only way you can get the Windows 2000 sRGB profile is if you already have Windows 2000 installed on an old computer somewhere.

How to tell if a profile is well behaved

The following xicclu command line can be used to check whether a given profile is well behaved or not:

xicclu -ir -pl -s255 -v0 name_of_profile.profile_extension

The scale used (eg "-s255", "-s1.0", "-s65535", etc) does not change the precision of the xicclu output. But "255 255 255" is easier to type than "65535 65535 65535" and more intuitively obvious to most people than "1.0 1.0 1.0", so I used 255 as the RGB input scale for this investigation into working space profiles.

When using xicclu, upon entering the RGB values "255 255 255", if the profile is well behaved to at least six decimal places, then the xicclu output from the terminal command "xicclu -ir -pl -s255 -v0" will be "100.000000 0.000000 0.000000". Any other output values means the profile is not well behaved to six decimal places.

Although any output other than "100.000000 0.000000 0.000000" means the profile is not completely well behaved, the xicclu output "100.000000 0.000000 0.000000" all by itself doesn't mean the profile is well behaved. Before concluding that a profile really is well behaved, you need to verify that:

  • The profile TRC is exactly the same in the Red, Green, and Blue channel.
  • In the xicclu command, inputting R=G=B=255 results in the LAB value "100.000000 0.000000 0.000000".
  • In the xicclu command, inputting R=G=B=0 results in the LAB value "0.000000 0.000000 0.000000".
  • In the xicclu command, inputting random R=G=B values up and down the gray scale always result in the a* and b* channels both being equal to "0.000000".

If a profile passes all four of the above checks, it's well behaved. In particular, all colors for which R=G=B are neutral colors, meaning the corresponding LAB values have a*=b*=0.000000.

You probably do need to do all four checks in the above list to verify that a profile is well-behaved. Certainly a profile can pass the first two checks and still be not well behaved. Probably it can pass the first three checks and not be well behaved, but I need to work out the math to be sure. But if it passes all four checks, then it really is well behaved. If you know of a mathematical formula that proves whether a given profile is well behaved or not, please share!

Not so well behaved: xicclu output for 25 working space profiles

Of the 25 working space profiles in Tables 1 through 6 below, all but four RGB working space profiles (the Canon WideGamut profile and 3 open source sRGB profiles) are not well behaved.

If you look at the xicclu values you can see that many times different profile vendors are using what looks to be exactly the same variant of one or another standard working space, which is great when they all used a well behaved variant, not so great when they all use a variant that isn't well behaved. To make it easier for you to see when it looks like several vendors are supplying functionally equivalent profiles, in the tables below, the profiles in each table are arranged from the highest to the lowest xicclu L* values:

Table 1: Apple
Source File Name L* a* b*
Shared AppleRGB.icc 100.001180 -0.002449 -0.000432
Adobe AppleRGB.icc 100.000000 0.002638 0.001233
Table 2: CIE-RGB
Source File Name L* a* b*
Shared CIE-RGB.icc 100.000590 0.002732 -0.001449
Table 3: ColorMatch
Source File Name L* a* b*
Shared ColorMatchRGB.icc 100.001180 -0.002449 -0.000432
Adobe ColorMatchRGB.icc 100.000590 -0.002543 0.001017
Table 4: ProPhoto
Source File Name L* a* b*
Shared ProPhotoRGB.icc 100.001180 -0.002449 0.000801
Canon ProPhoto profile 100.000590 -0.002543 -0.001449
digiKam prophoto.icm 100.000590 -0.002543 -0.007616
OpenICC ProPhoto-RGB.icc 100.000590 -0.002543 -0.007616
Table 5: WideGamut
Source File Name L* a* b*
digiKam widegamut.icm 100.001180 0.016013 -0.015228
Krita WideGamut.icm 100.001180 0.016013 -0.015228
Canon WideGamut profile 100.000000 0.000000 0.000000
Table 6: sRGB
Source File Name L* a*b*
Krita sRGB.icm 100.001200 -2.390200 -19.404000
Krita krita-built-in.icc 100.000600 -0.002500 0.002300
digiKam srgb-d65.icm 100.000590 -0.002543 0.002250
lcms code lcmsCreate_sRGB.icc 100.000590 -0.002543 0.002250
OpenICC sRGB.icc 100.000590 -0.002543 0.002250
Canon sRGB profile 100.000590 -0.002543 0.001017
Argyllcms sRGB.icm 100.000000 0.000000 0.000000
Krita krita-scRGB.icm 100.000000 0.000000 0.000000
Shared sRGB.icm 100.000000 0.000000 0.000000
Adobe sRGB Color Space Profile.icm 99.998820 0.018274 -0.016832 sRGB_IEC61966-2-1_black_scaled.icc 99.998820 0.018274 -0.016832
lcms version 1 sRGB Color Space Profile.ICM 99.998820 0.018274 -0.016832
Windows 2000 sRGB.icm 99.998820 0.018274 -0.016832

In addition to the profiles in the tables above, I looked at AdobeRGB1998-compatible ICC profiles from Adobe, Argyllcms, the Canon DPP software, OpenICC, and the colord Shared Color Profiles. All five of these profiles are well behaved. In fact all five profiles have identical white points, black points, and red, green, and blue primaries and hence are functionally equivalent to one another, so I didn't bother making a table for the AdobeRGB profiles.

In the tables above, the profiles for which the RGB values "255 255 255" resulted in the xicclu output "100.000000 0.000000 0.000000" are highlighted in green. For these profiles I've checked the TRCs and the xicclu output for R=B=B=0, and also spot-checked various R=G=B values between 0 and 255. The profiles highlighted in green are indeed neutral and well behaved.

So out of 30 working space profiles from a wide variety of proprietary and open source software packages and profile packs, only 9 profiles — five AdobeRGB profiles, three sRGB profiles, and 1 WideGamut profile — are well-behaved to at least six decimal places.

Does it matter if your working space RGB profiles aren't well behaved?

From a practical, image editing point of view, for eight-bit image editing it doesn't matter whether the profiles included in this survey are completely well behaved or not. According to the xicclu output, all of the surveyed profiles are neutral to the second or third decimal place for the a* and b* values, and to the third or fourth decimal place for the L* values, which pretty much equates to a bit depth of 8 bits (and perhaps a "bit" more). The exception, of course, is the Krita "sRGB.icm" profile, which shouldn't be used for image editing (the Krita built-in sRGB profile is fine).

At higher bit depths, from a practical, image-editing point of view, it is possible to introduce a false color cast when using working space profiles that aren't well behaved. But it isn't easy to introduce a noticeable color cast.

Here's one way to create a noticeable false color cast. This process is not something you are likely to do in the course of normal image editing, but you might, depending on the image and your editing goals. I have done an equivalent move in CIELAB space, working only on the a* and b* channels, the goal being to dramatically increase saturation in an image that originally had almost completely desaturated colors.

  1. Make a new image, change the bit depth to 16-bit integer (or 32-bit floating point), and fill it with R=G=B=32895 (or R=G=B=0.50000). It should look like the first color patch in Figure 1 below.
  2. Looking at the sRGB profiles in Table 6, the Adobe version of sRGB, the old Windows 2000 sRGB, the old lcms sRGB, and the sRGB are all functionally the same profile (the first three even have the same metadata). Assign one of those not-so-well behaved sRGB profiles to your newly created image (don't use the built-in sRGB profile because some open source imaging programs will just declare "Oh, it's the same profile" and not actually do a profile conversion). I chose to assign the Adobe version of sRGB to my gray patch.
  3. Eyedropper to confirm the RGB values haven't changed (if they did, you did something wrong or your software is messed up! because assigning a profile isn't supposed to change the image's RGB values). Now convert the image to one of the completely well-behaved sRGB profiles listed in Table 6. I converted my gray patch to the "sRGB.icm" profile distributed by Argyllcms. Eyedroppering the new RGB values shows (32899, 32894, 32900), which is not quite neutral, so of course if we do an extreme enough adjustment, the color cast will increase.
  4. Do an extreme levels correction. I mean extreme! Try raising the upper/output black point slider to 31457 (45%) and lowering the upper/output white point slider to 34078 (55%). Notice these levels values must not clip (and won't, for this example) any of the red, green and blue channel values, otherwise the color change would be from channel clipping rather than because the originally assigned working space profile wasn't completely well behaved. Now eyedroppering reads (36055, 35930, 36080).

    Note: you must do this levels adjustment in an image editor that actually does a true RGB Levels adjustment. If your image editor Levels tool only operates on the image's Value or Luminance or Lab L* channel or anything other than the actual RGB channels, you won't see any increase in the saturation of the not-quite-neutral gray patch.

    To my chagrin and disappointment, at this point in time, the only open source image editing software I have installed on my system that is capable of following the steps in this example is GIMP from git (Gimp 2.8 only does 8-bit image editing) and Cinepaint. ShowFoto 3.4 freezes and probably operates on some kind of Luminance channel. The Krita filters also separate Luminance from color operations. Which is too bad because an enforced separation between color operations and Luminance operations doesn't reflect the way real light and colors mix out there in the real world, and it makes certain editing moves that are fundamental to RGB editing impossible to perform.

  5. Do a second extreme levels correction, moving the upper/output black and white point sliders to 32734 (53%) and 37355 (57%), respectively. The image now eyedroppers (33036, 29911, 33661) and the image is visibly purple-magenta instead of neutral gray and looks like the second color patch in Figure 1 below.

    In case you are wondering, you also get a color cast if you start with a well behaved sRGB working space and converted to a not-so-well behaved sRGB profile (be careful not to clip any channels, the numbers that won't clip will change), except the color cast is green (like the third color patch in Figure 1 below) instead of magenta.

Color casts from converting between a well balanced and a not so well balanced sRGB working space profile.
Left: Start with a 16-bit gray patch with R=G=B=32895.
Middle:Assign the Adobe version of sRGB, the old Windows 2000 sRGB, the old lcms sRGB, or the "black scaled" sRGB to the gray patch. Then convert the image to a well-behaved version of the sRGB profile. Perform a couple of extreme levels adjustment and the "gray" patch will turn magenta.
Right: Assign one of the well behaved sRGB profiles, convert to either the Adobe version of sRGB, the old Windows 2000 sRGB, the old lcms sRGB, or the "black scaled" sRGB, perform a couple of extreme levels adjustment, and the "gray" patch will turn green.

Like I said, you'd likely not do this kind of extreme adjustment very often. So from a practical point of view the slight deviation from being well behaved that is found in many widely distributed working space profiles is not likely to make a noticeable difference. But it could and it might, depending on your editing goals for any given image.

From a theoretical point of view, I find it somewhat disheartening that so many widely distributed working space profiles aren't completely neutral, or at least neutral to the 6 decimal places that xicclu displays. If the Argyllcms version of sRGB is well behaved, why aren't all sRGB profiles well behaved? If Canon has a well behaved WideGamut profile, why isn't everyone else's version of WideGamut well behaved? And if all of the AdobeRGB1998-compatible profiles are well behaved, why aren't any of the readily available Apple and ColorMatch profiles well behaved? And so on.

So I wrote a c code program that uses the lcms functions to make working space profiles and started experimenting to see what might make a working space profile well behaved or not well behaved. The next article in this series, In Quest of Well Behaved Working Spaces shares the results of my experiments. Although it is true that many profile makers use the wrong white points to make the various RGB working space profiles, the real problem turned out to be hexadecimal quantization.