Bug #12465

Global Tonemap introduces profile-style discrepancies

Added by Tim Haynes over 1 year ago. Updated over 1 year ago.

Target version:
Start date:
Due date:
% Done:


Estimated time:
Affected Version:
hardware architecture:


I've only just pinned this problem down to the Global Tonemap module after a number of months wondering what was going wrong.

Without the Global Tonemapping module, images export as I see them in the lightbox. All good.

However, if I enable the Global Tonemapping module, images come out different: not as bright overall; typically duller, over-saturated "thicker" tones; folded highlights.

To be absolutely clear, I am not merely complaining about the results of the Global Tonemapping module. The module makes a difference when editing an image in the lightroom, which can be fine - I like using it a lot of the time. The trouble arises when I export the images; they no longer look the same as what I edited.

This is the kind of problem that I would expect with a mismatch of ICC profiles; however, all export formats (JPEG/TIFF) and profiles (sRGB/adobeRGB) result in a mismatch. I have enabled lcms2 support on export. With the same global config and export settings, only those images with the Global Tonemapping module enabled will look different.

I'm attaching two screenshots to illustrate the problem - both as-edited and as-exported, presented within darktable to keep them the same size: attention is particularly drawn to the shade of green grass in the foreground; to the orange gorse bush in the middle distance; to the shade of the sky toward the top of the frame. The one with all the modules in the left is what I had in mind; the one with only one module is what darktable exported.

From the sidecar:


ii darktable 2.4.4-2 amd64 virtual lighttable and darkroom for

Screenshot 2018-12-14 at 18.09.09.jpg (1.53 MB) Screenshot 2018-12-14 at 18.09.09.jpg Tim Haynes, 12/14/2018 08:17 PM
Screenshot 2018-12-14 at 18.10.09.jpg (1.53 MB) Screenshot 2018-12-14 at 18.10.09.jpg Tim Haynes, 12/14/2018 08:17 PM
fused_DSCF2604_02.tif.xmp (8.54 KB) fused_DSCF2604_02.tif.xmp Tim Haynes, 12/14/2018 08:34 PM


#1 Updated by Aurélien PIERRE over 1 year ago

What display color profile are you using on your OS and in darktable ? And what input profile are you applying on your TIFF ?

Although I think at least one global tonemapping operator is broken, this seems to be a display profile issue unrelated to the tonemapping (which is merely making it more obvious here).

On Gnome, I also suspect the display profile is applied twice (once by darktable, once again by the OS) because I have run into similar issues and inconsistencies between darktable preview and exports viewed in color-managed image viewers.

#2 Updated by Tim Haynes over 1 year ago

Not so; if I had an OS display colour management problem, none of my images would look the same in darktable vs digiKam; however, they do.

I have fully colour-managed sRGB across the board from to macbook display settings to monitor settings. Images look the same in digikam and darktable editor and Preview on the Mac natively.

The source TIFF was also sRGB (rawtherapee "unprofiled sRGB" and enfuse HDR blending).

Again, such things as darktable's image options output profile module, and the colour space in the export module, do not make a difference. When I edit without global tonemapping, I get what I want. With it, that's what makes the difference.

#3 Updated by Aurélien PIERRE over 1 year ago

I think I found the culprit, in globaltonemap.c :

  // Drago needs the absolute Lmax value of the image. In pixelpipe FULL we can not reliably get this value
  // as the pixelpipe might only see part of the image (region of interest). Therefore we try to get lwmax from
  // the PREVIEW pixelpipe which luckily stores it for us.
  if(self->dev->gui_attached && g && piece->pipe->type == DT_DEV_PIXELPIPE_FULL)
    const uint64_t hash = g->hash;

    // note that the case 'hash == 0' on first invocation in a session implies that g->lwmax
    // is NAN which initiates special handling below to avoid inconsistent results. in all
    // other cases we make sure that the preview pipe has left us with proper readings for
    // lwmax. if data are not yet there we need to wait (with timeout).
    if(hash != 0 && !dt_dev_sync_pixelpipe_hash(self->dev, piece->pipe, 0, self->priority, &g->lock, &g->hash))
      dt_control_log(_("inconsistent output"));

    tmp_lwmax = g->lwmax;

  // in all other cases we calculate lwmax here
    lwmax = eps;
    for(size_t k = 0; k < (size_t)roi_out->width * roi_out->height; k++)
      float *inp = in + ch * k;
      lwmax = fmaxf(lwmax, (inp[0] * 0.01f));
    lwmax = tmp_lwmax;

During the preview, the max lightness is measured on the screen-resized picture, whereas during the export, it is computed on the full-resolution file. The resized preview uses an interpolation that could smoothen the details and give different results.

Could you disable the high-quality export in the global preferences, then try to export the file at the same resolution as you screen preview ? If this solves the problem, it means the code above is responsible for the inconsistency.

#4 Updated by Tim Haynes over 1 year ago

Many thanks!

I seem to be having a problem repeating it at the moment. That's one of the things that concerned me, there has been an element of unpredictability about it. Or me...

However, one thing I noticed recently was that sometimes, just enabling the contrast+brightness+saturation module - with all numbers zero! - was enough to force a radical change in the lighttable, as though it had previously been "stuck".

So I do think you might be on to something, but need to get the test rig back to being reliably broken again before I can be completely sure. That might be a couple of days yet.

Also available in: Atom PDF

Go to top