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 737778 - Replace hard-coded sRGB parameters to allow editing in other RGB working spaces
Replace hard-coded sRGB parameters to allow editing in other RGB working spaces
Status: RESOLVED OBSOLETE
Product: GIMP
Classification: Other
Component: General
git master
Other All
: Normal normal
: ---
Assigned To: GIMP Bugs
GIMP Bugs
Depends on:
Blocks:
 
 
Reported: 2014-10-02 12:19 UTC by Elle Stone
Modified: 2018-05-24 14:44 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
Patch to retrieve the user-chosen RGB working space parameters. (7.65 KB, patch)
2014-10-02 12:19 UTC, Elle Stone
none Details | Review
babl patch for editing using user-chosen RGB colorants (38.56 KB, patch)
2016-04-16 14:19 UTC, Elle Stone
none Details | Review
gimp patch to allow editing using user-chosen RGB colorants (25.04 KB, patch)
2016-04-16 14:21 UTC, Elle Stone
none Details | Review

Description Elle Stone 2014-10-02 12:19:52 UTC
Created attachment 287578 [details] [review]
Patch to retrieve the user-chosen RGB working space parameters.

Currently some GIMP editing operations are hard-coded to use parameters specific to sRGB. To allow correct editing in other RGB working spaces, the hard-coded sRGB parameters must be replaced with parameters retrieved from the image's actual RGB working space.

Problems with forcing a conversion to unbounded sRGB and keeping the hard-coded sRGB parameters include:
1. Multiply produces different results in different RGB working spaces (http://nbviewer.ipython.org/github/colour-science/colour-website/blob/master/ipython/about_rendering_engines_colourspaces_agnosticism.ipynb). 
2. Adding and removing color casts (changing the image white balance) involves multiply, so color casts that were created in some other RGB working space cannot be easily corrected in the sRGB working space (http://ninedegreesbelow.com/photography/unbounded-srgb-color-correction-fails.html).
3. Using sRGB colorants to encode colors that are outside the very small bounded sRGB color gamut requires using negative channel values. Multiplying and dividing colors that are encoded using negative channel values produces physically meaningless results (http://ninedegreesbelow.com/photography/unbounded-srgb-multiply-produces-meaningless-results.html).
4. Over 50% of the core GIMP editing operations that I checked are chromaticity dependent, giving different results in different RGB working spaces (http://ninedegreesbelow.com/photography/unbounded-srgb-as-universal-working-space.html#chromaticities-matter). Any editing operation that involves multiply, divide, or raising RGB values to a power produces different results in different RGB working spaces. Only the artist can say which working space gives the best results. Therefore a forced conversion to sRGB severely compromises artistic freedom.
5. Converting an image from one RGB working space to another rearranges channel data, sometimes making it unuseable. Therefore a forced converstion to unbounded sRGB severely limits the artist's ability to make creative use of channel data.
6. Standard display-referred image editing requires using RGB channel values that are encoded using RGB channel values that are clipped to the RGB floating point range 0.0 to 1.0, inclusively. Trying to perform display-referred edits on colors that are encoded using negative channel values and/or channel values that are greater than 1.0 produces meaningless results. Consequently display-referred image editing is flatly broken in the unbounded sRGB color space (http://ninedegreesbelow.com/photography/display-referred-scene-referred.html#unbounded-sRGB-broken-model). Examples of affected editing operations are making a Levels gamma slider adjustment, dividing to flat-field an image, and using any layer Blend mode that involve multiply or divide.

A previously suggested way to fix problems created by a forced conversion to unbounded sRGB is to write new code that uses "BABL formats" to:
1. Use LCMS to retrieve the profile colorants of the RGB working space that the user would otherwise choose to use.
2. Create an new ICC profile RGB working space that uses:
        a. The profile colorants of the RGB working space that the user would otherwise choose to use.
        b. The sRGB TRC as the BABL-designated adequate substitute for "perceptually uniform" RGB.
3. Add new code to every editing operation that gives the wrong results in the unbounded sRGB color space. This added code will activate the following sequence of events:
        a. Convert the affected image buffer(s) from unbounded sRGB to the new ICC profile RGB working space with the colorants of the RGB working space that the user would otherwise choose to use:
            i. For some editing operations, the affected image buffer is just the one layer.
            ii.For layer Blend mode operations, the entire layer stack that uses any layer Blend modes that give the wrong results in the unbounded sRGB color space (which in fact is most layer blend modes) would have to be converted to the new ICC profile RGB working space with the colorants of the RGB working space the user would otherwise choose to use.
        b. Perform the affected editing operation. If the affected editing operation involves a layer Blend mode, the blended results would need to be made into a "New from Visible" layer. The convert/blend/"New from Visible" sequence would need to be repeated every time the user makes any modification to the affected layer stack.
        c. Convert the image(s) from the new ICC profile with the colorants of the RGB working space that the user would otherwise choose to use, back to unbounded sRGB.

Problems with this previously suggested solution to problems created by a forced conversion to unbounded sRGB include:
1. This solution requires adding repetitive code to many editing operations. Developer time will be required not only to write the basic conversion code, but also to identify and modify all the requisite editing operations so the conversion code is activated as required.
2. For correct results, over 50% of the core editing operations that the GIMP UI makes available to the user will require converting image buffer(s) from unbounded sRGB to an LCMS-made ICC profile that uses the colorants of the RGB working space that the user would prefer to be using, and then back to unbounded sRGB. 
3. This solution to the problems created by forced conversion of images to unbounded sRGB will require constantly converting image buffers back and forth between two RGB working spaces. This constant churning raises the possibility that many editing operations that are already somewhat slow, will be made even slower, chewing through CPU cycles to make the required color space conversions.
4. This solution puts the user's artistic intentions entirely at the mercy of developer decisions as to which RGB editing operations really do require a conversion to an RGB working space that uses the colorants of the user's chosen RGB working space.

Instead of keeping all of the hard-coded sRGB parameters, forcing a conversion to unbounded sRGB, and fixing the resulting problems, a better solution is as follows:
1. All hard-coded sRGB colorant-related and reference white parameters should be replaced with RGB working-space-specific parameters retrieved by LCMS from the user's chosen RGB working space. 
2. The BABL code that switches between linear light and perceptually uniform RGB using the sRGB TRC (tone reproduction curve) should be kept. 
3. To accomodate the BABL linear-to-perceptual sRGB-TRC-specific code, users must edit their images only in RGB working spaces that use the sRGB TRC. This can be accomplished in two ways:
	i. Either inform the user that the user needs to convert their images to a version of their chosen RGB working space that already has the sRGB TRC, or else they will get wrong results. Appropriate ICC RGB working space profiles can be distributed with GIMP. 
	ii. Or else convert the image to a version of the user-chosen image profile that has the sRGB TRC:
        a. Upon opening an image, and also when the user converts the image to a new RGB working space, use LCMS to make a new ICC profile that uses the user-chosen RGB working space's profile colorants and the sRGB TRC, and then convert the image to this new profile.
        b. Retain the user-chosen image RGB working space information in case the user wants to convert the image back to the user-chosen RGB working space when exporting an image to a non-XCF file format.
This solution eliminates all the problems associated with a forced conversion to unbounded sRGB, and retains all the benefits of the currently coded BABL conversions between "linear light" and "perceptually uniform" RGB. 

Below is a list of (hopefully all) the files that have hard-coded device and sRGB parameters, that need to be modified to use parameters pulled from the image RGB working space:

Files that use hard-coded sRGB unadapted Y values:
    BABL
        babl/extensions/ycbcr.c
    GEGL
        operations/common/svg-luminancetoalpha.c
        operations/common/svg-saturate.c
        operations/workshop/box-percentile.c
        operations/workshop/disc-percentile.c
    GIMP
        libgimpcolor/gimprgb.h gives RGB_LUMINANCE_ #defines:

        #define GIMP_RGB_LUMINANCE_RED    (0.2126)
        #define GIMP_RGB_LUMINANCE_GREEN  (0.7152)
        #define GIMP_RGB_LUMINANCE_BLUE   (0.0722)

        #define GIMP_RGB_LUMINANCE(r,g,b) ((r) * GIMP_RGB_LUMINANCE_RED   + \
                                           (g) * GIMP_RGB_LUMINANCE_GREEN + \
                                           (b) * GIMP_RGB_LUMINANCE_BLUE)
        libgimpcolor/gimprgb.c uses these #defines to write two more functions that calculate Luminance:
            gimp_rgb_luminance
            gimp_rgb_luminance_uchar
        These files use #define GIMP_RGB_LUMINANCE(r,g,b) to calculate Luminance:
            app/core/gimpimage-convert-type.c
            app/gui/splash.c (splash.c is a UI that probably isn't and can't be color-managed by LCMS)
            app/operations/gimplevelsconfig.c
            app/operations/gimpoperationcolorize.c
            app/operations/gimpoperationdesaturate.c
            app/widgets/gimpgradienteditor.c
            plug-ins/common/bump-map.c
            plug-ins/common/colorify.c
            plug-ins/common/displace.c
            plug-ins/common/despeckle.c
            plug-ins/common/engrave.c
            plug-ins/common/file-aa.c
            plug-ins/common/file-pnm.c
            plug-ins/common/newsprint.c
            plug-ins/common/oilify.c
            plug-ins/file-fli/fli-gimp.c
            plug-ins/fractal-explorer
            plug-ins/gimpressionist/gimp.c
            plug-ins/gradient-flare.c
            plug-ins/pagecurl.c
            plug-ins/pygimp/gimpcolormodule.c
        This file uses gimp_rgb_luminance to calculate luminance:
            plug-ins/pygimp/pygimp-colors.c
        These files use gimp_rgb_luminance_uchar to calculate luminance:
            libgimp/gimpdrawable.c
            libgimp/gimppixelfetcher.c
            plug-ins/common/file-mng.c
            plug-ins/common/file-png.c
            plug-ins/common/grid.c
            plug-ins/gradient-flare.c
            plug-ins/maze/maze-utils.c

Files that use hard-coded sRGB D50-adapted Y values
    BABL
        babl/base/rgb-constants.h (#defines for RGB_LUMINANCE_)
        babl/base/model-gray.c (uses the RGB_LUMINANCE_ #defines)
        extensions/grey.c (uses the RGB_LUMINANCE_ #defines)
    GEGL
        operations/workshop/snn-percentile.c
        code in the opencl folder that repeats BABL code
    GIMP code never uses D50-adapted sRGB Y values.

Fixing editing operations that currently use hard-coded sRGB Y values to calculate Luminance is straightfoward: Write a function that uses LCMS to retrieve the image's ICC profile's actual red, green, and blue colorant Y values and ferry the information to where it's needed. Modify the relevant files to use the RGB working space Y values instead of hard-coded Y values.

The BABL "extensions/CIE.c" file uses D65 sRGB color space xy values and the D65 sRGB reference white to convert to XYZ and then to LAB and LCH(ab). As currently programmed, the conversion to XYZ uses unadapted sRGB color space values, and so gives wrong results even for color managed sRGB images. The following files use the BABL conversion to XYZ and then to LAB and LCH(ab):
    BABL
        babl/tests/srgb_to_lab_u8.c
    GEGL
        gegl/operations/common/image-compare.c
        gegl/operations/common/noise-cie-lch.c
    GIMP
        gimp/plug-ins/common/compose.c
        gimp/plug-ins/common/decompose.c
        gimp/app/operations/tests/test-operations.c
        gimp/app/core/gimpimage-convert-type.c
To fix the code that converts from RGB to XYZ and then to LAB, write a function that uses LCMS to retrieve the image's ICC profile's actual red, green, and blue colorant X, Y, and Z values, plus the ICC profile's illuminant X, Y, and Z values (currently always D50), and ferry the information to where it's needed. The BABL file "extensions/CIE.c" should use the retrieved XYZ values to convert from RGB to XYZ. Once in the XYZ reference color space, the conversion to LAB should be done.

Code files in BABL/GEGL/GIMP that refer to YCbCr (not including jpeg/jp2-related and BABL format-defining code):
    BABL
        babl/base/model-ycbcr.c (NTSC)
        extensions/ycbcr.c (BT.709)
        tests/rgb_to_ycbcr.c (NTSC)
    GEGL
        opencl/colors.cl.h (NTSC?)
        gegl/opencl/gegl-cl-color.c (NTSC?)
        operations/common/cartoon.c (NTSC?)
    GIMP
        plug-ins/common/decompose.c (BT.709 and NTSC)
        plug-ins/common/compose.c (BT.709 and NTSC)
The way to correct the YCbCr calculations to make them useable for all RGB working spaces is to use the generalized equations for converting from RGB to YCbCr, along with the LCMS-retrieved Y values for the image's RGB working space profile. The existing device-color-space-specific code gives the wrong results even for color-managed sRGB and NTSC images.

Other hard-coded NTSC parameters:
    GEGL
        opencl/colors.cl.h (used by operations/common/oilify.c) GEGL's "operations/common/oilify.c" should use Luminance calculations based on the Y values retrieved from the actual image ICC profile. 
    GIMP
        libgimpcolor/gimprgb.h (in the deprecated GIMP_RGB_INTENSITY #defines, which don't seem to be used in any other GIMP code and so can be removed altogether)

        libgimpcolor/gimprgb.c (in the deprecated functions gimp_rgb_intensity and gimp_rgb_intensity_uchar, which don't seem to be used in any other GIMP code and so can be removed altogether)

        modules/gimpcolorwheel.c If the file "gimp/modules/gimpcolorwheel.c" is part of the color picker UI (or other UI that isn't color-managed), the code should use hard-coded sRGB values (not NTSC values) until such time as the color picker (or other) UI is color-managed.

        plug-ins/common/hot.c GIMP's hot pixel repair code ("plug-ins/common/hot.c") has a precalculated NTSC-to-YIQ matrix. The current code gives wrong results even for sRGB images. It seems unlikely that YIQ is an especially felicitous RGB color space transform for identifying hot pixels in an ICC profile color managed image editing application.

NTSC broadcasting has ceased. So all NTSC-based code should be removed from BABL, GEGL, and GIMP.

The following BABL/GEGL/GIMP code files mention YUV:
    BABL
        extensions/gggl.c
    GEGL
        operations/external/ff-load.c
        operations/external/v4l.c
        operations/workshop/external/ff-save.c
    GIMP
        plug-ins/twain/twain.h
Probably none of the above-listed files except BABL's "extensions/gggl.c" file have anything to do with color-space-specific transforms. Whatever "extensions/gggl.c" does (possibly fast conversions between 8-bit integer and floating point for display on a BT.709 device?), there shouldn't be any device-color-space-specific transforms in an ICC profile color managed image editing application. In addition, there are some sRGB-specific tables in the BABL code, possibly also for fast conversions for 8-bit images. Not all 8-bit images are sRGB images. Not even all legacy XCF files produced using 8-bit GIMP are sRGB XCF files. I'm not sure how these tables are intended to be used with high bit depth GIMP (possibly for working with legacy 8-bit XCF files?). So I can't give advice on how to deal with them. I did compile a version of BABL with all such tables removed and never had a problem running GIMP. But I don't have any legacy 8-bit XCF files.

The BABL/GEGL/GIMP code base also contains files with hard-coded matrices, tables, and coefficients that are pre-calculated on the assumption that the image is in a specific color space. Such precalculated, hard-coded, color space-specific values need to be identified and dealt with on a case by case basis. Below are two examples of pre-baked, color-space-specific transforms:

1. GEGL uses hard-coded sRGB-based coefficients in the function "gfloat rgb_r55", in the file "operations/common/color-temperature.c" Functions in this file are called upon when you use GIMP's "Colors/Color Temperature" to raise or lower an image's color temperature. As currently coded, the color temperature changing code produces pleasing though colorimetrically inaccurate results for sRGB images. It produces very wrong results for non-sRGB images. One method for calculation color temperature changes, for which the required equations are readily available and easy to code, is to:
    Convert the image from RGB to XYZ using the image RGB working space colorants retrieved by LCMS.
    Perform a Bradford or CAT02 chromatic adaptation from TEMP1 to TEMP2.
    Convert the image from XYZ to RGB.

2. The GIMP file "modules/display-filter-color-blind.c" simulates? enhances? what a colorblind person sees. This code uses RGB/LMS transforms that are hard-coded to use unadapted sRGB values, applicable to a "modern CRT", the likes of which haven't been in wide use for quite a few years now. This code is not valid for anyone using ICC profile color management, even for sRGB images. Nor is it valid for anyone viewing an sRGB image without color management, except on a monitor that has been calibrated to match sRGB. A way to generalize this code to work in a color-managed environment might be to:
    Convert the image from the image's D50-adapted RGB working space to the user's monitor profile (which LCMS does anyway as the image is sent to the monitor)
    Do the required RGB/XYZ/LMS transforms using the XYZ parameters retrieved from the monitor profile, with the sRGB profile as the usual "no monitor profile" fallback. XYZ/LMS equations can be found on Bruce Lindbloom's website. The alternative to generalizing the code to work with all monitor profiles in an ICC profile color-managed workflow is to include a UI notification that this display filter only produces valid results if:
    Color management is disabled.
    The image is an sRGB image.
    The monitor is a CRT or other display device that's been calibrated to match sRGB, or else the user could try whatever sRGB simulation mode their LCD might provide.

Further examination of the code is likely to reveal a few other instances of hard-coded device-based and sRGB-specific matrices, tables, and coefficients. Such code has no place in an ICC profile color managed editing application.

Additional details on how to replace the hard-coded sRGB colorant-related and device-based parameters can be found here: http://ninedegreesbelow.com/gimpgit/gimp-hard-coded-sRGB.html
Comment 1 Max Mustermann 2016-04-01 17:23:54 UTC
After all the work and exhaustive explanation from Elle I see no further action here. What will we do with this report and Elle's patch?
I personally think native support for color spaces other than sRGB is a great thing and Elle has proven this by many examples on her website. Yes, sRGB is a safe choice for cross-device image processing, but it's from the 1990's and sticking with it in a hard-coded manner lets us miss our own goal 'GIMP is a platform for programming cutting-edge image processing algorithms, by scientists and artists;'. So I'm voting for her proposal.
Comment 2 Max Mustermann 2016-04-06 04:28:25 UTC
At https://mail.gnome.org/archives/gimp-developer-list/2016-April/msg00051.html Elle says: 
"Some of the specific code-related information in that particular bug report is out of date, not surprising as I posted the bug report in December 2014. The general issues remain. The specific locations of the hard-coded parameters haven't changed too much (GEGL has fewer such locations). But the specific functions that call on the hard-coded parameters have changed a bit.

I started a branch of this current thread to ask some specific questions regarding a couple of babl functions that might be useful for conveying RGB color space information from GIMP to babl, and also about the idea of coding in a selection of well-behaved RGB working spaces.[...]"

So I suggest we wait for the result of the discussion and continue then.
Comment 3 Elle Stone 2016-04-09 20:31:57 UTC
I made the assumption that the very talented babl/GEGL/GIMP developers are capable of writing code that can send colorant information from GIMP to babl.

On the basis of this assumption, I made an updated list of all the code files in babl/GEGL/GIMP that would require patching:
http://ninedegreesbelow.com/files/patch-gimp/user-chosen-rgb/hard-coded-srgb.ods

Then I wrote some "proof of concept" patches for providing GIMP users with the ability to edit in RGB working spaces other than sRGB:
http://ninedegreesbelow.com/files/patch-gimp/user-chosen-rgb/proof-of-concept-patches.tar.gz

I also wrote an overview of the task of patching babl/GEGL/GIMP to allow for editing in a user-chosen RGB working space:

Modifying bab/GEGL/GIMP for editing in user-chosen RGB working spaces
http://ninedegreesbelow.com/photography/gimp-edit-in-user-chosen-rgb-working-space.html
Comment 4 Elle Stone 2016-04-16 14:19:25 UTC
Created attachment 326156 [details] [review]
babl patch for editing using user-chosen RGB colorants
Comment 5 Elle Stone 2016-04-16 14:21:19 UTC
Created attachment 326157 [details] [review]
gimp patch to allow editing using user-chosen RGB colorants
Comment 6 Elle Stone 2016-04-16 14:26:03 UTC
(In reply to Elle Stone from comment #3)
> I made the assumption that the very talented babl/GEGL/GIMP developers are
> capable of writing code that can send colorant information from GIMP to babl.

I figured out how to write this code, which is included in the attached babl and GIMP patches.

> On the basis of this assumption, I made an updated list of all the code
> files in babl/GEGL/GIMP that would require patching:
> http://ninedegreesbelow.com/files/patch-gimp/user-chosen-rgb/hard-coded-srgb.
> ods
> 
> Then I wrote some "proof of concept" patches for providing GIMP users with
> the ability to edit in RGB working spaces other than sRGB:
> http://ninedegreesbelow.com/files/patch-gimp/user-chosen-rgb/proof-of-
> concept-patches.tar.gz

The patches are now much closer to being actually useable for editing.
 
> I also wrote an overview of the task of patching babl/GEGL/GIMP to allow for
> editing in a user-chosen RGB working space:
> 
> Modifying bab/GEGL/GIMP for editing in user-chosen RGB working spaces
> http://ninedegreesbelow.com/photography/gimp-edit-in-user-chosen-rgb-working-
> space.html

The overview has been updated.
Comment 7 Elle Stone 2016-04-21 15:29:06 UTC
There's no point in cluttering up this bug report with more patches until such time as there is an active interest in testing and incorporating the code into babl/GEGL/GIMP. 

However, the patches that can be downloaded from http://ninedegreesbelow.com/photography/gimp-edit-in-user-chosen-rgb-working have been updated to remove the white space errors, and also to provide for decomposing/recomposing to/from LAB/LCH using the user's chosen RGB colorants. The key was adding code that retrieved the active image's RGB colorants.

Similar "get the active image's RGB colorants" code needs to be written to allow several tools - including the Color Picker and Set Foreground Tool - to reliably use the user's chosen RGB colorants. Right now it's a bit hit-or-miss.
Comment 8 Elle Stone 2017-02-06 19:55:09 UTC
A lot of the information above is out of date with respect to the current state of GIMP code. Maybe this bug should be closed as obsolete given that support for editing in RGB working spaces other than sRGB is on the official GIMP development roadmap.
Comment 9 GNOME Infrastructure Team 2018-05-24 14:44:50 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/594.