After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 772266 - Address various limitations of LCMS soft proofing
Address various limitations of LCMS soft proofing
Status: RESOLVED OBSOLETE
Product: GIMP
Classification: Other
Component: libgimp
git master
Other All
: Normal normal
: ---
Assigned To: GIMP Bugs
GIMP Bugs
Depends on:
Blocks:
 
 
Reported: 2016-09-30 21:13 UTC by Elle Stone
Modified: 2018-05-24 16:58 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
screenshot showing problems with LCMS soft proofing (147.87 KB, image/jpeg)
2016-10-04 10:23 UTC, Elle Stone
Details

Description Elle Stone 2016-09-30 21:13:08 UTC
The current (2.7/2.8) LCMS approach to soft proofing is very printer-oriented. The gamut checks only work if the source profile has a perceptually uniform TRC, and don't work at all if the destination profile can support unbounded ICC profile conversions, even if the image itself is at integer
precision. This page has test files that can be used to demonstrate the various issues: http://ninedegreesbelow.com/files/soft-proof/soft-proofing.htm

It's not clear whether the current LCMS soft proofing code will change in the near future:
https://sourceforge.net/p/lcms/mailman/message/35178784/
https://sourceforge.net/p/lcms/mailman/message/35271294/
https://sourceforge.net/p/lcms/mailman/message/35271284/
https://sourceforge.net/p/lcms/mailman/message/35273448/
https://github.com/Beep6581/RawTherapee/issues/3406#issuecomment-246199885.

Given that there is no timetable or definite plan for changes to the LCMS soft proofing code, perhaps code can be added to GIMP to address the LCMS limitations. PhotoFlow linear_gamma branch (https://github.com/aferrero2707/PhotoFlow/tree/linear_gamma) has code that seems to work pretty well, that perhaps can be ported to GIMP. The PhotoFlow code:

* works around the current LCMS gamut check limitations

* includes different gamut checks when using or not using black point compensation for relative colorimetric conversions (which PhotoShop has but LCMS doesn't have)

* deals with unbounded ICC profile conversions

* includes very nicely working code for emulating paper white and ink black
Comment 1 Michael Natterer 2016-09-30 22:13:49 UTC
Do they implement the entire transformation themselves, or do they just
add some minor hacks? The latter would make it far more likely that I
find the time to implement this ;)
Comment 2 Elle Stone 2016-10-01 00:14:10 UTC
(In reply to Michael Natterer from comment #1)
> Do they implement the entire transformation themselves, or do they just
> add some minor hacks? The latter would make it far more likely that I
> find the time to implement this ;)

It's c++ code, which I'm not good at reading. But as far as I can tell, the code is straightforward, using clipping, difference, and some concantenated LCMS conversions to accomplish the various soft proofing tasks. 

I guess my question would be how CPU-intensive would these functions be if ported to GIMP. The code seems "light" in PhotoFlow, but I haven't tried making changes to the image while soft proofing using PhotoFlow, and I haven't tried using the soft proofing functionality with large images. I'll make some experiments tomorrow to see how cpu-intensive the code is in PhotoFlow.
Comment 3 photofloweditor 2016-10-01 00:26:22 UTC
(In reply to Michael Natterer from comment #1)
> Do they implement the entire transformation themselves, or do they just
> add some minor hacks? The latter would make it far more likely that I
> find the time to implement this ;)

I am the author of the PhotoFlow code, and I'll try to shortly explain ha it works:

* for matrix-type target profiles, I do two parallel ICC conversions:

  - one unbounded conversion from input to linear ACES
  - one conversion from input to target, and then from target to linear ACES

  For the gamut warning, I numerically compare the two linear ACES versions and 
  set the output pixels to mid grey if the difference in any of the RGB channels
  is above a pre-defined threshold

* for LUT-type target profiles, I basically follow the same recipe as LCMS:

  - I perform one conversion from input to Lab
  - I perform one conversion from input to target, and then from target 
    to Lab

  For the gamut warning, I compute the deltaE between the two Lab versions and 
  set the output pixels to mid grey if the difference in any of the RGB channels
  is above a pre-defined threshold

One difference with respect to the LCMS implementation is that when black point compensation is applied to the "input -> target" conversion, it is also applied
to the "target -> Lab/linear ACES" one. Therefore, the pixels that are brought
back into gamut by the black point compensation do not get highlighted when the
gamut warning is activated.

For the "simulate black ink" option, I set the ICC conversion from the "target"
to the "display" profiles to "relative colorimetric without black point compensation".

For the "simulate paper color" option, I set the ICC conversion from the "target"
to the "display" profiles to "absolute colorimetric". In this case, the black point compensation setting does not matter...


I'm open for any discussion and further explanation of the code.
Comment 4 photofloweditor 2016-10-01 00:54:18 UTC
(In reply to Elle Stone from comment #2)
> (In reply to Michael Natterer from comment #1)
> > Do they implement the entire transformation themselves, or do they just
> > add some minor hacks? The latter would make it far more likely that I
> > find the time to implement this ;)
> 
> It's c++ code, which I'm not good at reading. But as far as I can tell, the
> code is straightforward, using clipping, difference, and some concantenated
> LCMS conversions to accomplish the various soft proofing tasks. 
> 
> I guess my question would be how CPU-intensive would these functions be if
> ported to GIMP. The code seems "light" in PhotoFlow, but I haven't tried
> making changes to the image while soft proofing using PhotoFlow, and I
> haven't tried using the soft proofing functionality with large images. I'll
> make some experiments tomorrow to see how cpu-intensive the code is in
> PhotoFlow.

As far as I understand the LCMS code, it makes some pre-computation of the gamut warning limits using a sort-of intermediate LUT profile, while PhotoFlow does the computations for the gamut warning pixel-per-pixel.

However, I do not have the feeling that the code is particularly slow, although the Lab conversions are not the fastest you can have...
Comment 5 Elle Stone 2016-10-04 10:02:44 UTC
Checking with a Sony A7 file, in PhotoFlow the soft-proofing color conversion layer doesn't seem to significantly slow down processing/display even with a 6000x4000 pixel image, but PF and GIMP do handle processing and display rather differently.

For the gamut check, PhotoFlow does a round-trip conversion and takes the difference to calculate the gamut check. Another alternative would be to use LCMS soft proofing directly to produce the gamut check, by first doing a "hidden" conversion from the source color space to a version of the very large ACES color space that has the perceptually uniform LAB companding curve (the sRGB TRC would probably work just as well, being close to perceptually uniform). Then the actual LCMS soft proofing would be from the ACES color space variant to the destination color space. 

The reason for this preliminary "hidden conversion to ACES" would be to handle two issues with LCMS: 

First, LCMS gamut check results vary depending on the relative size/shape of the source and destination color spaces gamuts, and are only accurate if the source color space gamut is (1) large enough to completely encompass the destination color gamut, and also (2) sufficiently large to hold all the colors in the image (so no out of gamut channel values - if there are out of gamut channel values after converting to ACES, then the user wants to display imaginary colors, and that's a workflow issue, not a soft proofing issue).

Second, LCMS gamut check results are only accurate if the source color space has a perceptually uniform TRC.

This preliminary hidden color space conversion to "ACES with a perceptually uniform TRC" does not address the other problem with LCMS soft proofing, which is that currently LCMS doesn't provide any clipping option if the soft proofing destination color space supports unbounded ICC profile conversions. PhotoFlow uses clipping code to handle this problem, and GIMP could handle this problem the same way, by putting in an RGB clipping operation before sending the soft-proofed colors to the screen. 

This "clipping code" is critically important because otherwise the user is likely to be very surprised when colors look just fine on the screen, but when exported to disk in a file format that doesn't support unbounded RGB (for example jpeg for displaying on the web), suddenly the colors have all shifted.
Comment 6 Elle Stone 2016-10-04 10:23:13 UTC
Created attachment 336889 [details]
screenshot showing problems with LCMS soft proofing

The images labeled 1, 2, and 3 in the screenshot illustrate the problems and possible solutions to soft proofing using LCMS. These problems even affect soft proofing from sRGB to sRGB.

Image 1 has been converted from unbounded sRGB to a version of the ACES color space that has the LAB L perceptually uniform companding curve, and is being soft proofed to a version of the sRGB profile that supports unbounded ICC profile conversions. The gamut checks are accurate, meaning these areas are encoded using channel value outside the display range 0.0 to 1.0.

Unfortunately, if the gamut check in Image 1 is unchecked, image 1 would look like image 2, which is misleading because most of the image doesn't fit in the sRGB color space (though obviously an unbounded conversion to sRGB does preserve rather than clip the out of gamut color information).

Image 2 is what you get by converting image 1 to unbounded sRGB and then soft proofing to a version of sRGB that supports unbounded ICC profile conversions. The gamut check box is still checked, but LCMS shows that the entire image is "in gamut", which of course it's not.

Image 3 shows the actual image that would be saved to disk if the user exported the file in a file format that doesn't support storing out of gamut channel values (png, jpeg, integer tiff, etc). The difference between 2 and 3 is that I changed the destination profile to a V2 sRGB profile from disk that doesn't support unbounded ICC profile conversions (notice the color shift towards purple). The way to accomplish the same thing internally (without requiring the user to pick an appropriate profile from disk) is to insert a clipping operation somewhere in the conversion/display chain.
Comment 7 Elle Stone 2016-10-04 10:59:58 UTC
(In reply to Elle Stone from comment #6)
> Image 3 shows the actual image that would be saved to disk if the user
> exported the file in a file format that doesn't support storing out of gamut
> channel values (png, jpeg, integer tiff, etc). The difference between 2 and
> 3 is that I changed the destination profile to a V2 sRGB profile from disk
> that doesn't support unbounded ICC profile conversions (notice the color
> shift towards purple). The way to accomplish the same thing internally
> (without requiring the user to pick an appropriate profile from disk) is to
> insert a clipping operation somewhere in the conversion/display chain.

The clipping code of course needs to clip the image to the destination (soft proofing) color space gamut before sending the RGB values to the screen.

PhotoFlow allows the user the option to clip only negative channel values, only positive channel values, or both, or to not clip at all. 

For accurate soft proofing to a printer or for diplay on the web, of course both positive and negative channel values need to be clipped, and this is likely the most common use case for GIMP users. 

However, some file formats support unbounded positive values but can't encode negative out of gamut channel values, and the same is true of some image editors for which a GIMP user might want to export an image. So it might be nice to provide the user with the option to choose whether to clip positive, negative, neither, or both out of gamut channel values during soft proofing. By default it might be nice to have "clip positive" and "clip negative" both already checked.
Comment 8 Elle Stone 2016-10-04 12:40:54 UTC
(In reply to Elle Stone from comment #5)

> (so no out of gamut channel values - if there are out of
> gamut channel values after converting to ACES, then the user wants to
> display imaginary colors, and that's a workflow issue, not a soft proofing
> issue).

Well, actually it could easily be a soft proofing issue, as the input profile for interpolated raw files might easily generate "outside the range of real colors" for certain colors such as bright saturated yellows and greens (dandelions and back-lit spring greenery) and also deep saturated violet-blue (neon signs, backlit blue glass). If exported to disk as floating point, these colors can easily make it into GIMP still unclipped and still outside the range of real colors. This is true even of scene-referred interpolations, and quite independent of any added saturation the user might apply (which would make the situation even worse). These colors are pretty commonly encountered across a range of cameras. I can provide references and examples if you want them.

As GIMP has built-in floating point unclamped conversions to LAB, it might be more efficient to bypass LCMS altogether and generate the gamut checks by doing round-trip conversions to LAB for all soft proofing (not just LUT destination profiles), and calculate the difference, setting an appropriate delta for "in gamut" vs "out ofgamut"
Comment 9 Elle Stone 2016-11-04 17:15:25 UTC
It looks like LCMS 2.9 will make provision for clipping when soft proofing *to* unbounded RGB working spaces. A post from Marti (2/3rds of the way down from the top of https://github.com/Beep6581/RawTherapee/issues/3406) says 

"I have filed a change request for lcms 2.9 to always force bounded in softproof profiles".

However, it looks like LCMS 2.9 won't provide gamut checks for situations where the source color space (in GIMP 2.9/2.10 the RGB working space) supports unbounded floating point processing. Quoting https://sourceforge.net/p/lcms/mailman/message/35470522/

"You are right, gamut check was not intended to work in unbounded mode and also, due to the way it works, it needs a space perceptually uniform . . . This is not a bug, but a limitation due to the algorithm used. I take  two action items: fully de-activate gamut check on unbounded mode and document the limitation. Will happen in 2.9."

The built-in GIMP sRGB working space is perceptually uniform, but it also supports unbounded profile conversions. So I'm guessing the code change for LCMS 2.9 will mean that at least at floating point precision and maybe also at integer precision, the LCMS soft proofing gamut check will be disabled.

A gamut check is a pretty important part of soft proofing, imho. It looks like the only way GIMP users will be able to see a gamut check is if GIMP code generates the gamut check, perhaps using something like the code that PhotoFlow uses. The PhotoFlow soft proofing code is pretty good (more accurate than PhotoShop for some of the test images), and getting better with each iteration.
Comment 10 Michael Natterer 2018-01-01 23:02:32 UTC
So what is the current state here? Is anything already fixed perhaps,
or can be done for 2.10? The last comment on this bug is 13 months old.
Comment 11 Elle Stone 2018-01-01 23:30:16 UTC
One thing that GIMP code can do is to make sure that when LCMS soft proofing is activated, no matter what precision the image itself is in, the RGB values sent to LCMS soft proofing code should be at perceptual precision.

LCMS 2.9 was released Nov.25, 2017. I'll do some checking tomorrow to see if anything has changed.
Comment 12 Elle Stone 2018-01-02 16:30:49 UTC
I don't see that anything has changed. There is a flag that says to disallow negative floating point values (also in 2.8), but this doesn't address the various problems that have been discussed regarding LCMS soft proofing.

To summarize:

1. Back in 2012, Marti wrote a post about using linear RGB, and as far as I can tell his opinion about editing using linear RGB hasn't changed in the meantime: http://littlecms2.blogspot.com/2012/07/why-when-i-convert-from-linear-space-i.html

2. Recently Marti expressed his thoughts on soft proofing:
https://github.com/Beep6581/RawTherapee/issues/3406#issuecomment-246199885. Also see https://discuss.pixls.us/t/does-soft-proofing-work-without-looking-to-the-output-profile/3280/26

The relevant point is that LCMS soft proofing code is intended for soft proofing *to* a printer profile and *from* a perceptually uniform source color space.

It seems fairly obvious (at least to me) that LCMS soft proofing code isn't likely to change in the near future, if ever. So the question is what can be done in GIMP and other image editors if goals for soft proofing go beyond what Marti envisions.

I would like GIMP to be able to:

1. Soft proof to color spaces other than printer profiles.

2. Soft proof from an unbounded linear gamma source color space to a bounded destination color space, even if the two color spaces are both RGB color spaces (even the exact same RGB color space, such as from unbounded sRGB to bounded sRGB) instead of the destination profile being a printer profile.

3. Soft proof from linear/linearized RGB and still show accurate out of gamut markers.

These abilities would handle situations such as soft proofing from unbounded linear precision sRGB for editing, to bounded regular sRGB for preparing image for display on the web, soft proofing for output in file formats (jpg, png, integer precision tiffs, etc) that don't support unbounded floating point RGB values, and also soft proofing to a display profile such as the profile for a profiled electronic display device, as well as to printer profiles.

Perhaps the easiest way to make this happen in GIMP (while still using LCMS soft proofing) would be to change the image to perceptual precision before sending the image RGB values to LCMS for soft proofing, and then add "clipping code" after the LCMS soft proofing algorithm, to only send "clipped to destination color space" RGB values to the screen. But this wouldn't result in accurate marking of out of gamut colors, as the LCMS code simply compares the source and destination color space gamuts, without regard for whether the source RGB colors are out of gamut wrt to the source or destination color spaces' bounded gamuts.

Another approach would be to write code that converts the image to a very large, perceptually encoded RGB color space - such as ACES with the sRGB or LAB L TRC - before sending the image to the LCMS soft proofing code. The chain would be like this:

From sRGB (linear or perceptual) to *bounded* (clipped) ACES with a perceptually uniform TRC, and then to the LCMS soft proofing code, from whence it goes to the screen, with or without out of gamut markers.

Another alternative would be to port the PhotoFlow soft proofing code over to GIMP. The PhotoFlow code is now considerably more refined than it was before, and includes extra features such as clipping or not clipping negative and/or positive OOG channel values; full, partial, or no chromatic adaptation; paper white and ink black emulation; and excellent out-of-gamut indicators.
Comment 13 Elle Stone 2018-01-03 14:15:37 UTC
Looking through pixls.us for something else altogether, I stumbled over a concise overview of how the PhotoFlow soft proofing code works:

https://discuss.pixls.us/t/how-soft-proofing-is-implemented-in-photoflow/3546
Comment 14 GNOME Infrastructure Team 2018-05-24 16:58:47 UTC
-- GitLab Migration Automatic Message --

This bug has been migrated to GNOME's GitLab instance and has been closed from further activity.

You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.gnome.org/GNOME/gimp/issues/976.