GNOME Bugzilla – Bug 757444
Curves and Levels should operate by default on linear RGB and present linear RGB Histograms
Last modified: 2018-01-11 21:17:01 UTC
Created attachment 314590 [details] When using linear precision and the gamma hack, the Curves histogram is wrong. For radiometrically correct results, Curves should be done using linearly encoded RGB. Currently GIMP defaults to using RGB encoded using the sRGB TRC. Currently the only way the user can have Curves performed on linearized RGB is to convert the image to linear precision and also use the gamma hack. When the user converts the image to linear precision and uses the gamma hack to operate on linear RGB, the histograms for Curves is not a reliable guide to making a Curves adjustments because the histogram is still presented using RGB encoded using the sRGB TRC. So using the eyedropper to pick a point on the histogram to drag up or down actually drags at a completely other point in the histogram. GIMP should by default use linearized RGB for Curves, and the Curves histogram should also present linearized RGB so the user can use the histogram as a guide to making Curves adjustments.
The same problems affects Levels, which also should operate by default on linearized RGB.
Auto-Stretch also should operate on linearized RGB by default, for the same reasons that Levels and Curves should. An attachment to bug 757069 illustrates why Levels and Auto-Stretch should operate on linearized RGB: https://bug757069.bugzilla-attachments.gnome.org/attachment.cgi?id=314031 Curves is just Levels plus the ability to do arbitrary adjustments between the user-set black and white points. So just as Levels should be done on linearized RGB, so should Curves. For example, a common use case for Curves is to increase contrast, with a toe and shoulder for rolloff in the shadows and highlights. Performing this type of Curve on linear RGB allows the user to realistically exaggerate tonal contrast. Performing the same type of Curve on perceptually uniform RGB systematically distorts tonality even as tonal contrast is exaggerated.
I'm just going to throw all editing operations that change the image black and white points, and/or change brightness via restrained or arbitrary curves, into this one bug report. For radiometrically correct editing all of these operations need to be done on linearized RGB. So adding to the list: Brightness/Contrast should *operate* on linearized RGB. But the "per unit changes" should be presented in the UI with a perceptually uniform Histogram and corresponding sliders. As an aside, the current histograms UI distinction between "linear" and "logarithmic" histograms has nothing at all to do with the distinction between a histogram of linearized vs perceptually uniform RGB. Rather it has to do with the units along the Y axis of the histogram. Whether the Histogram displayed in the editing operation UI is shown using linearized or perceptually uniform RGB, can be independently controlled from whether the operation itself is done using linearized or perceptually uniform RGB. For example, according to on-line documentation recent versions of Lightroom operate on linearized RGB "under the hood", but the Curves dialog is presented "as if" the RGB were encoded using the sRGB TRC. I believe LightZone did something similar. Benefits of two view on the underlying linear RGB data: Despite Lightroom's cheery assumption that users never benefit from seeing linear RGB presented linearly, sometimes the linear *view* of linear RGB is easier to understand and manipulate, for example: 1. Making "per stop" adjustments for hand-blended bracketed exposures and for raising shadow portions of high dynamic range images that are compressed to fit in an LDR dynamic range (that is, normal photographic image editing). 2. Making adjustments in the highlights - highlight adjustments made on linear RGB presented linearly in the UI allows for very fine adjustments, compared to having to make the same adjustments using a perceptually uniform view of the underlying linear RGB. And sometimes the perceptually uniform *view* of the underlying linear RGB is easier to understand and manipulate, for example: 1. Making symmetric adjustments to shadows and highlights, as per sigmoidal curves and brightness/contrast adjustments. 2. Setting the black point of an image using Levels, which should *always* be done using linearized RGB, but is usually easier to pinpoint when the RGB data is presented in the UI using perceptually uniform RGB 3. Using Curves to compress the shadows of an image, which is much easier to do when the UI presents perceptually uniform RGB, but again the underlying operation should be done using linear RGB. Currently GIMP users get the worst of both worlds: * By default GIMP currently operates on perceptually uniform RGB, with all the attending side effects of tonality and color shifts. * When the user switches to linear precision and uses the gamma hack, the UI view on the RGB data is still perceptually uniform, but the Curves/Levels adjustments that are made using the UI histogram as a guide, aren't made on the mathematically corresponding portions of the linearized RGB. For radiometrically correct results, GIMP should operate by default on linearized RGB for Levels, Curves, Brightness-Contrast, Auto-Stretch, and any other related editing operation. GIMP users need to have available the ability to easily switch between linear *and* perceptual views of the linearized RGB data, for easier manipulation depending on the particular editing task. Regardless of whether the view of the linearized RGB data is presented linearly or using perceptually uniform RGB, changes made using the UI histogram as a guide should affect the underlying RGB data at the mathematically corresponding portions of the linearized RGB.
The gamma hack should probably only be used by mitch, or by users told to test things with the gamma hack. And for GIMP-2.10 such UI cluttering many dialogs should be hidden.. This branch unconditionally makes the involved operations and all histograms be linear (changes the meaning of the argument passed to gimp_histogram_new to mean linear.. in all GIMP code this argument is currently TRUE) https://git.gnome.org/browse/gimp/log/?h=pippin/linear-is-the-new-black
The button that displays the main histogram in linearized RGB (introduced in GIMP 2.9.6) should also change the histogram in the curves menu. Also it looks as if in Gimp 2.9.6 all operations mentioned by Elle Stone still do not perform on linear RGB under the hood. If I understand correctly this is critical, because any scientific image based quantification (common in biochemistry and physics) is invalid if brightness/contrast was adjusted in Gimp.
It will happen, don't panic :)
I don't know much about these, but from what I understand from the comments, this is a blocker for the release and goes with all the internal changes we had in GIMP for 2.10. Setting to blocker.
Maye it helps to have a look at how ImageJ handles contrast/brightness adjustment and colour balancing. The source code for these functions is public domain at https://imagej.nih.gov/ij/source/ij/plugin/frame/ContrastAdjuster.java and was develloped by the National Institutes of Health. It is used for scientific image manipulation so it could serve as a reference at least for how to cope with gray-scale / indexed images. If that code is irrelevant here, I might have missunderstood Elle.
This basically makes things work, just not smoothly yet: commit 54d3beab9c31b9930ff42c05154192cd234ba930 Author: Michael Natterer <mitch@gimp.org> Date: Fri Jan 5 22:37:18 2018 +0100 Bug 757444 - Curves and Levels should operate by default on linear RGB... ...and present linear RGB Histograms This is step one: implement the feature at all (without new defaults or proper GUI, cough). Add boolean "linear" properties to GimpOperationPointFilter, GimpCurvesConfig and GimpLevelsConfig. In the filter, simply set the input/output formats to linear in prepare(). In the curves and levels tools, add "Linear" toggles from hell, like in the histogram dockable, and make sure things work right wrt changing and resetting the property, switching from levels to curves, and picking colors. The result currently changes when switching a non-nop curves/levels between perceptual and linear, because adjusting the parameters between the spaces is not implemented yet. app/operations/gimpcurvesconfig.c | 28 ++++++++++++- app/operations/gimpcurvesconfig.h | 2 + app/operations/gimplevelsconfig.c | 28 ++++++++++++- app/operations/gimplevelsconfig.h | 2 + app/operations/gimpoperationcurves.c | 8 ++++ app/operations/gimpoperationlevels.c | 8 ++++ app/operations/gimpoperationpointfilter.c | 16 +++++++- app/operations/gimpoperationpointfilter.h | 2 + app/tools/gimpcurvestool.c | 67 +++++++++++++++++++++++++------ app/tools/gimplevelstool.c | 49 ++++++++++++++++++---- 10 files changed, 186 insertions(+), 24 deletions(-)
A nicer GUI for switching linear/perceptual: commit 28bb108e1b69131a14867f8d4a3e0db894fa7fb1 Author: Michael Natterer <mitch@gimp.org> Date: Sat Jan 6 03:12:23 2018 +0100 app: use gimp_prop_boolean_icon_box_new() instead of the "Linear" toggle in the curves and levels tools and in the histogram dockable. app/tools/gimpcurvestool.c | 16 +++++++++++----- app/tools/gimplevelstool.c | 14 ++++++++++---- app/widgets/gimphistogrameditor.c | 21 +++++++++------------ 3 files changed, 30 insertions(+), 21 deletions(-) commit 637421840895b44f3dfc7d31a1ec2c572ba35814 Author: Michael Natterer <mitch@gimp.org> Date: Sat Jan 6 03:11:12 2018 +0100 app: add gimp_prop_boolean_icon_box_new() should eventually go to libgimpwidgets app/widgets/gimppropwidgets.c | 136 ++++++++++++++++++++++++++++++++++++++++++ app/widgets/gimppropwidgets.h | 7 +++ 2 files changed, 143 insertions(+)
Elle, can you check if this now works as you would expect?
So far everything looks good and works as expected. It's not easy to place points in the shadows in Curves, when operating on linearized RGB. Maybe this could be a separate enhancement request.
Yes, I think that's true but another issue. Thanks for checking.