Display color management in darktable

The general picture on the modern Linux desktop

Modern Linux distros featuring either GNOME, Unity or KDE offer fairly easy configuration of color management, this system level configuration mostly pertains to the handling of an ICC display profile.

If you have set a display profile via your system configuration tool (The Color applet in System Settings for GNOME or Unity), there are a few things to keep in mind.

An ICC display profile consists of two main parts. First the so-called "vcgt", which corrects for whitepoint (this is most noticeable on laptops which shift from being very blueish to a bit more yellowish) and gamma. The "vcgt" is loaded into X11 and applied to your whole screen, so all applications automatically benefit. On a GNOME or Unity desktop this is done by GNOME Settings Daemon during login.

The second is the rest of the ICC profile, and this has to be processed in color management enabled application (typically via liblcms2). So we need a mechanism to pass the actual ICC profile to our applications without having to configure them all individually.

The oldest mechanism is the _ICC_PROFILE atom, which allows a single display profile to be defined for your system (this obviously fails for dual head configurations). You can check if a profile is setup like so:

$ xprop -display :0.0 -len 14 -root _ICC_PROFILE

On a GNOME or Unity system the _ICC_PROFILE is setup by GNOME Setting Daemon during login.

On some systems there may be a _ICC_PROFILE_1 and _ICC_PROFILE_2 atom to facilitate dual head configurations. While darktable should pick up on those, I'm not sure how well other applications support this mechanism.

The another relatively new mechanism is colord by Richard Hughes, which is an infrastructure daemon, which by it self does very little, as it's mostly just an information/configuration store. But modern GNOME, Unity or KDE desktops store their display profile setups in colord, so applications can query colord which profile to apply depending on which screen they are displayed on (in case of a dual head configuration). Currently few applications are colord aware however. darktable is one of those few.

If you haven't setup a display profile yourself that doesn't per-se mean there is no display profile active. Modern desktops actually query the display (via EDID) itself about its advertised color coverage, from which an automatic display profile is generated. An easy way to check if such an automatic profile was generated:

# ls -l ~/.local/share/icc/edid-*.icc

For more in-depth information the following articles are highly recommended:

darktable's current (1.0/1.1/1.2) implementation

First off I want to make something very clear, darktable's darkroom mode is fully color managed and should always be used in situations where you are evaluating color. Since darktable is colord enabled (and if colord is properly setup) it should even render correct color in dual head configurations.

In darktable's lighttable mode there are however a few things you need to be aware of. When importing new RAW photos into darktable, it will display the RAWs embedded thumbnail (which has been fully processed by the camera software) and the display profile is currently NOT being applied to these embedded thumbnails. Keep in mind, that these thumbnails have been processed by the proprietary firmware of the camera, so even if we applied the display profile it would still not match the processing that is done by darktable by default. It is however possible to disable the use of these embedded thumbnails altogether in darktable's preferences, forcing all RAWs to be processed by darktable's own imaging pipeline. This will slow down thumbnail generation by a few orders of magnitude, which is why this isn't our default behavior.

Once you've entered darkroom mode for a RAW, the image has been processed in darktable's imaging pipeline including the application of the display profile, so this result is now kept as an accurate thumbnail for that particular RAW.

If you've read that well, you might have noticed that we currently keep the display profile pre-applied in our thumbnail cache. Which is good for performance, and works just fine in most use-cases, but can result in ugly behavior for example when you change/replace your display, since darktable will still show thumbnails applied with the display profile of your previous display. In such a case you can forcibly remove the thumbnail cache like so:

$ rm -Iv ~/.cache/darktable/mipmaps-*


3 thoughts on “Display color management in darktable

  1. Hi Pasacal,

    This post and the link to your(?) pcode post were very helpful. However, I still have a question that I wonder if you could help me with. Suppose you have two monitors, one is standard gamut the other is wide gamut. Also suppose you have some raws that you have output to 8-bit sRGB and aRGB JPEGs and want to display. Does the pseudocode below capture sort of thing that you need to do?

    sRGB = cmsCreate_sRGBProfile();
    aRGB = // Load profile from image (assuming it is present)
    sgMon = // Load profile for standard gamut monitor (using EDID?)
    wgMon = // Load profile for wide gamut monitor (using EDID?)
    // generate the transforms
    // IN is one of sRGB and aRGB
    // OUT is one of sgMon and wgMon
    s2s = cmsCreateTransform(IN, TYPE_RGB_8, OUT,
    TYPE_RGB_8, 0, 0);
    // apply the transforms to the original image pixels (i.e. the JPG) then render the transformed image on the relevent screen

    Now stepping back to how I got those JPEGs in the first place, what transform is applied to go from the raw to the sRGB (or aRGB) JPEG? Is there some camera profile that needs to be used at least as a starting point?


  2. Hi dm

    It’s a lot simpler than that isn’t it?

    If you have profiled your screens and then view your images using a colour managed application they should render ‘correctly’ from either srgb or argb jpegs on either screen. Any transformation necessary should be transparent and handled by colord or whatever colour manager you are using.

    Or are you trying to do something different?

  3. Rob, please do read the article, dm isn’t far off at all… As I explicitly mention colord is just an infrastructure daemon which ties stuff together. It doesn’t do any color transforms by itself (and it shouldn’t).

    As far as the pseudocode goes, you’d need to check Darktable code for the gritty details.

    For a high level view, Darktable’s pipeline is completely transparant in the user interface, if you turn off plugin grouping (by clicking the active group once again), you can see all steps which are applied from bottom to the top.

    Keep in mind that RAW files technically aren’t normal images to begin with, they inherently have their own sensor specific color space and are practically linear with regard to gamma. So a LOT of processing has to happen to get even a basic image.

    The typical minimum steps are:

    1. read sensor data from RAW
    2. Whitebalance (RGB multipliers)
    3. Demosaic (includes median filters/greeneq too)
    4. Basecurve (corrects for gamma/contrast/tonality)
    5. (CMS) Color In (Camera RGB -> color (XYZ) matrix -> LAB)
    7. more plugins (for example denoise)
    6. (CMS) Color Out (LAB -> output ICC -> sRGB or AdobeRGB)
    8. more plugins (for example sharpen)

    Some of this is discussed in the following video: