Any linear RGB using global variables with diff to master and patches
Here are diffs against master for my attempt at coding "Any linear RGB working space for GIMP-2.99 using two global variables to get and store the image's ICC profile:
Here's the diff for gimp: gimp-linear-anyrgb-diff-against-master.patch
And for babl: babl-h-diff.patch
These patches aren't intended as patch for default GIMP. But at least the code shows where the image's ICC profile color space information needs to go to color-manage the color-picking tools and some of GIMP's operations and blend modes.
Normally I do use GIMP's nice ability to switch between linear and perceptual encoding,. But the code I wrote for working in a linear well-behaved RGB working space doesn't allow for properly switching between linear and perceptual encoding. I think it could be extended to handle linear and perceptual encodings. But currently operations and filters that nominally should use perceptual encoding, only give correct results if the "gamma hack" is used, and similarly with blend modes such as screen, softlight, etc: choosing "linear blend" gives correct results, but the usually more useful "perceptual" blend does not.
Here is what works and doesn't work, with some work-arounds that show where the problem might be:
Levels and Curves, including Levels Pick White to color balance an image (#3015) IF "linear" encoding is used. Except oddly enough the histogram is switched - linear encoding shows a perceptual histogram and vice versa. This does not affect correct results, but it does mislead as to where points on a curve should go.
Dragging and dropping an RGB channel as a layer works (it doesn't work in default GIMP-2.99, but I haven't yet filed a bug report).
Picking colors, Sample Points, and using the sliders in the FG/BG tool to dial in colors produces correct linear results for the image's actual ICC profile linear RGB working space (#2050). The out-of-gamut indicators are not correct (#2022), probably because of the "perceptual re-encoding mentioned below. Also the LCh color squares to the left of the sliders have wrong shapes, possible from the perceptual encoding:
None of this color-managed color picking/sampling goodness does any good, because painting/bucketfill/new layer from fg/bg color, etc all produce the wrong color, that color being the result of a perceptual re-encoding of the actual selected linearly-encoded color.
In other words, somewhere - probably in GIMP? - there is a conversion to perceptual encoding between the picking and the painting of a color, that I haven't found.
A work-around is to modify babl/babl/base/util.h so that the babl code that actually converts between perceptual and linear is disabled (just return "value" for all the TRC operations on that page). This also makes the "out of gamut" indicators work properly.
All the layer blend modes work, except as noted above regarding layer blend modes that nominally should work on perceptually encoded RGB.
All the RGB GEGL filters (tested: Exposure, Stretch Contrast, Monomixer, Gaussian blur, Extract RGB channels) on GIMP's menu (the ones that I checked) work, with the "only for linear encodings" caveat mentioned above. For example, High Pass, Value Propagate, and Edge Sobel (and probably the other Edge algorithms) need the gamma hack to produce "correct linear results" (no way to produce correct perceptual results).
The GEGL filters for LCh operations don't work (tested GEGL Saturation LCh and Hue-Chroma). The only way I could get these operations to produce correct results is either convert the image to linear sRGB from disk, or else replace the sRGB primaries in babl/babl-space.c code for making profiles with the primaries of the color space that the image is in. So change babl-space.c "sRGB" primaries to Rec.2020 primaries for working on a linear Rec.2020 image in GIMP.
Assuming it's possible to stop the perceptual re-encoding of picked colors (other than by disabling the perceptual/TRC functions in babl) and also possible to pass to various GEGL operations the actual image RGB working space, and assuming there is a way to tell various color-picking operations in GIMP what color space the image is actually in, without resorting to global variables, then here is a suggestion to make GIMP work in any well-behaved linear RGB working space:
* Change the function names of the current built-in sRGB profiles to something like "WorkingRGB..." - this effectively is what my patch does except I only make a linear profile. * Make new functions for assigning linear or regular sRGB to images imported from disk that don't have embedded ICC profile/color space information. These would be similar to the current built-in Clay/AdobeRGB profile and only come into use during image import (and export/save, if the user doesn't assign or convert to some other RGB color space). * Write code that allows GIMP to pass to GEGL the actual image RGB working space colorants.
Regarding passing the actual image RGB working space to GEGL, as far as I can tell:
* In "babl_format_with_space", when "space" is derived from the image's format, this "format" includes RGB encoding for "perceptual/linear", "floating point/integer", and "8-bit/16-bit/32-bit" - but doesn't include actual image RGB working space information. * Similarly "const Babl *space = gegl_operation_get_source_space (operation, "input");" seems to always use sRGB rather than the image's actual RGB working space colorants.
My patches include some preliminary patches that have the function of making it easier for me to compare results with my GIMPCCE, and of having less code to deal with in various code files. Here's the individual patches in a zip file - the patch names give the reason for the patch: