Is there an existing issue for this?
Describe the bug
When softproofing is enabled with an RGB printer profile (e.g. standard inkjet or lab printing profiles), the main image preview is rendered with Black Point Compensation (BPC) forced ON. However, the Histogram and the Global Color Picker calculate their values by reverse-transforming the display data back into the softproof profile without BPC.
This mathematical mismatch means the screen shows smooth, BPC-compensated shadows, but the histogram and color picker report crushed, clipped blacks. This only affects RGB-based softproof profiles; CMYK profiles correctly apply BPC in both directions.
Steps to reproduce
- Open an image in Darkroom.
- Enable Softproof.
- Set the Softproof profile to an RGB printer profile (e.g., SaalDigital_FineArt_PhotoRag.icc).
- Look at the shadows in the image preview (which look fine/compensated).
- Look at the Histogram: the blacks are crushed/clipped against the left edge

6) Look at the Global Color Picker values over dark areas: they incorrectly report 0 or clipped values.
-
Change the Softproof profile to a CMYK profile (e.g., SaalDigital_PhotoPrints_SoftTouch.icm).
-
The Histogram and Color Picker now correctly align with the screen preview
SaalDigital_PhotoPrints_SoftTouch.zip
SaalDigital_FineArt_PhotoRag.zip
Expected behavior
The Histogram and Global Color Picker should perfectly mathematically reflect the on-screen softproof preview regardless of whether the target profile is RGB or CMYK. If BPC is applied to the screen preview, it must also be applied to the reverse-transform that feeds the histogram/picker.
Logfile | Screenshot | Screencast
The issue lies in src/common/iop_profile.c inside the _transform_rgb_to_rgb_lcms2() function.
Currently, Darktable only sets the cmsFLAGS_BLACKPOINTCOMPENSATION flag for the reverse-transform if the target profile is explicitly identified as cmsSigCmykData by LCMS2. RGB profiles fall through to a standard transform with 0 flags.
|
if(from_rgb_profile && to_rgb_profile && to_is_cmyk) // softproofing cmyk profile |
Meanwhile, the actual on-screen softproof preview generated by colorout.c forces BPC on globally for all softproofs.
|
transformFlags |= cmsFLAGS_SOFTPROOFING | cmsFLAGS_NOCACHE | cmsFLAGS_BLACKPOINTCOMPENSATION; |
Callstacks for affected tools: Both tools grab their data right before gamma is applied (meaning the data has already passed through colorout and has BPC baked in), and both use the flawed _transform_rgb_to_rgb_lcms2 function to reverse it:
Histogram data path: dt_dev_pixelpipe_process() -> dt_lib_histogram_process() -> lib_histogram_process*() -> dt_ioppr_transform_image_colorspace_rgb() -> _transform_rgb_to_rgb_lcms2()
Color Picker data path: dt_dev_pixelpipe_process() -> _pixelpipe_pick_samples() -> dt_ioppr_transform_image_colorspace_rgb() -> _transform_rgb_to_rgb_lcms2()
Suggested Fix Update the logic in _transform_rgb_to_rgb_lcms2() so that if darktable.color_profiles->mode == DT_PROFILE_SOFTPROOF, BPC is explicitly applied to the reverse-transform even if the target profile is an RGB paper profile, matching the behavior in colorout.c.
Commit
98239bf
Where did you obtain darktable from?
darktable.org / GitHub release
darktable version
5.4.0
What OS are you using?
Windows
What is the version of your OS?
11
Describe your system
No response
Are you using OpenCL GPU in darktable?
Yes
If yes, what is the GPU card and driver?
Nvidia GeForce RTX 4060 Ti, Driver: 32.0.15.8129
Please provide additional context if applicable. You can attach files too, but might need to rename to .txt or .zip
No response
Is there an existing issue for this?
Describe the bug
When softproofing is enabled with an RGB printer profile (e.g. standard inkjet or lab printing profiles), the main image preview is rendered with Black Point Compensation (BPC) forced ON. However, the Histogram and the Global Color Picker calculate their values by reverse-transforming the display data back into the softproof profile without BPC.
This mathematical mismatch means the screen shows smooth, BPC-compensated shadows, but the histogram and color picker report crushed, clipped blacks. This only affects RGB-based softproof profiles; CMYK profiles correctly apply BPC in both directions.
Steps to reproduce
Change the Softproof profile to a CMYK profile (e.g., SaalDigital_PhotoPrints_SoftTouch.icm).
The Histogram and Color Picker now correctly align with the screen preview
SaalDigital_PhotoPrints_SoftTouch.zip
SaalDigital_FineArt_PhotoRag.zip
Expected behavior
The Histogram and Global Color Picker should perfectly mathematically reflect the on-screen softproof preview regardless of whether the target profile is RGB or CMYK. If BPC is applied to the screen preview, it must also be applied to the reverse-transform that feeds the histogram/picker.
Logfile | Screenshot | Screencast
The issue lies in src/common/iop_profile.c inside the _transform_rgb_to_rgb_lcms2() function.
Currently, Darktable only sets the cmsFLAGS_BLACKPOINTCOMPENSATION flag for the reverse-transform if the target profile is explicitly identified as cmsSigCmykData by LCMS2. RGB profiles fall through to a standard transform with 0 flags.
darktable/src/common/iop_profile.c
Line 239 in af08652
Meanwhile, the actual on-screen softproof preview generated by colorout.c forces BPC on globally for all softproofs.
darktable/src/iop/colorout.c
Line 687 in af08652
Callstacks for affected tools: Both tools grab their data right before gamma is applied (meaning the data has already passed through colorout and has BPC baked in), and both use the flawed _transform_rgb_to_rgb_lcms2 function to reverse it:
Histogram data path: dt_dev_pixelpipe_process() -> dt_lib_histogram_process() -> lib_histogram_process*() -> dt_ioppr_transform_image_colorspace_rgb() -> _transform_rgb_to_rgb_lcms2()
Color Picker data path: dt_dev_pixelpipe_process() -> _pixelpipe_pick_samples() -> dt_ioppr_transform_image_colorspace_rgb() -> _transform_rgb_to_rgb_lcms2()
Suggested Fix Update the logic in _transform_rgb_to_rgb_lcms2() so that if darktable.color_profiles->mode == DT_PROFILE_SOFTPROOF, BPC is explicitly applied to the reverse-transform even if the target profile is an RGB paper profile, matching the behavior in colorout.c.
Commit
98239bf
Where did you obtain darktable from?
darktable.org / GitHub release
darktable version
5.4.0
What OS are you using?
Windows
What is the version of your OS?
11
Describe your system
No response
Are you using OpenCL GPU in darktable?
Yes
If yes, what is the GPU card and driver?
Nvidia GeForce RTX 4060 Ti, Driver: 32.0.15.8129
Please provide additional context if applicable. You can attach files too, but might need to rename to .txt or .zip
No response