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 756389 - Color-managing grayscale images
Color-managing grayscale images
Status: RESOLVED FIXED
Product: GIMP
Classification: Other
Component: General
git master
Other All
: Normal normal
: 2.10
Assigned To: GIMP Bugs
GIMP Bugs
: 759283 (view as bug list)
Depends on:
Blocks:
 
 
Reported: 2015-10-11 11:54 UTC by Elle Stone
Modified: 2016-04-17 14:03 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
grayscale/rgb display issues (90.16 KB, image/jpeg)
2015-10-11 11:54 UTC, Elle Stone
  Details
two function names that might have been left behind (1.36 KB, patch)
2015-12-15 21:45 UTC, Elle Stone
committed Details | Review
Screenshot showing problem with exporting linear light precision images (47.78 KB, image/jpeg)
2015-12-16 15:01 UTC, Elle Stone
  Details
Patch to change grayscale profile names to show the white point (1.91 KB, patch)
2016-04-08 11:21 UTC, Elle Stone
committed Details | Review

Description Elle Stone 2015-10-11 11:54:57 UTC
Created attachment 313056 [details]
grayscale/rgb display issues

As shown by the attached jpeg:

Sometimes GIMP displays grayscale images as if they were color-managed, but sometimes not. 

Sometimes GIMP doesn't color-manage formerly grayscale images that have had the mode changed to RGB. I first noticed this in connection with changing the mode of a decomposed-to-LAB image from grayscale to RGB.

By "color-manage" I mean "Assign an ICC profile to the image and then display it using the monitor profile chosen in Preferences/Color Management". 

If the user has chosen an sRGB ICC profile as their monitor profile, then they likely won't see any issues. But they also likely aren't seeing any correct colors displayed on their monitor, unless they've calibrated their screen to match the sRGB ICC profile that they chose as their monitor profile.

When an image is decomposed to LAB, to be displayed correctly, the resulting grayscale image needs to have either an appropriate grayscale ICC profile assigned, that has the LAB "L"/lstar TRC. Or else the resulting grayscale image needs to be displayed "as if" it were an RGB image with R=G=B everywhere, using any RGB ICC profile that has the LAB "L"/lstar TRC.

Displaying the decomposed to LAB layers "as if" they were in the regular sRGB color space doesn't produce correct tonality. See http://ninedegreesbelow.com/photography/lab-lightness-to-black-and-white-gimp29-photoshop.html#modifying-decompose-and-drag, Step 3, for details and a link to an sRGB profile that has been modified to have the lstar TRC. If requested, I can provide code for making the modified sRGB profile.

It would be nice if all grayscale images were properly color-managed. I wrote a patch to the old LCMS plug-in that allowed to color-manage grayscale images, but I can't find the equivalent code (something like Cases, if GRAYSCALE) to modify in the new color management code. If someone can point the way, I can try to write a patch (no guarantees, that new color management code is pretty complicated).
Comment 1 Michael Natterer 2015-10-11 16:43:36 UTC
That has confused me several times ever since I realized that there are
color profiles for grayscale images. Currently GIMP treats grayscale images
as not color managable. It would be pretty trivial to change that, however
I have no idea what to do when converting images that do have profiles
from and to grayscale.
Comment 2 Elle Stone 2015-10-11 16:57:42 UTC
(In reply to Michael Natterer from comment #1)
> That has confused me several times ever since I realized that there are
> color profiles for grayscale images. Currently GIMP treats grayscale images
> as not color managable. It would be pretty trivial to change that, however
> I have no idea what to do when converting images that do have profiles
> from and to grayscale.

If it will help, I can write up some sample LCMS code that converts between an RGB image with one assigned ICC profile and a grayscale image with another assigned ICC profile.
Comment 3 Michael Natterer 2015-10-11 17:04:58 UTC
That's not the hard part. The unclear (to me) part is:

I have an RGB image with a profile, and want to convert that image
to grayscale. How do I get the profile to convert to and to assign
to the converted image.

And the other way around.
Comment 4 Elle Stone 2015-10-11 17:31:04 UTC
Hmm, this is a "scattershot" post, trying to zero in on the unclear part, about which I'm unclear :) . So my apologies if I'm not answering the right questions.

There isn't just one grayscale ICC profile. A grayscale ICC profile is defined by choosing a white point, a black point, and a Tone Reproduction Curve ("TRC"). 

For grayscale versions of standard D50-adapted RGB matrix working space profiles, the white point is D50 and the black point is zero (X=Y=Z=0), just as with the RGB ICC profiles. 

The TRC of a grayscale profile governs how quickly the tonality proceeds from black to white, just the same as for RGB matrix working space profiles. So you can have one grayscale ICC profile with the sRGB TRC, another grayscale profile with the linear gamma TRC, another grayscale profile with the LAB "L"/lstar TRC, another one with the gamma=1.80 TRC, and so on.

This page has downloadable grayscale profiles, plus code for making them:
http://ninedegreesbelow.com/photography/lcms-make-icc-profiles.html

When you convert from an RGB profile to Grayscale, you just throw away the color information, and what you have left is Luminance, calculated using *linearized* RGB and whatever the corresponding Y values are for the RGB working space. So for the sRGB ICC profile, Y=R*0.22 + G*0.72 + B*0.06. The R, G, and B multipliers depend on the RGB color space chromaticities, with "Y" being the "Y" from XYZ locations of the chromaticities. 

But just as with RGB profiles, grayscale ICC profiles don't necessarily have the linear gamma TRC, so one you've calculated Y, you have to "gamma correct" it for the desired grayscale output profile. So I suppose GIMP could do all this directly, or else have LCMS make the ICC profile conversion.
Comment 5 Elle Stone 2015-10-11 17:52:01 UTC
(In reply to Elle Stone from comment #4)
> So for the sRGB ICC profile, Y=R*0.22 + G*0.72 + B*0.06. The
> R, G, and B multipliers depend on the RGB color space chromaticities, with
> "Y" being the "Y" from XYZ locations of the chromaticities. 

To clarify some confusing terminology, the "Y" in Y=R*0.22 + G*0.72 + B*0.06 is following babl/GEGL/GIMP coding usage for Y/Luminance. But "Y" from XYZ isn't the same "Y" as Luminance. So for the sRGB color space the Red Y from XYZ is 0.22, the Green Y is 0.72, and the Blue Y is 0.06, in each case dictating the percentage of the relative luminance that's contributed by each color channel.
Comment 6 Elle Stone 2015-10-11 19:37:52 UTC
And I still didn't say that right. The sum total of the red, green, and blue channel Y values really is Luminance, Y in XYZ for the color, and for the corresponding grayscale image.
Comment 7 Elle Stone 2015-11-24 14:38:10 UTC
Some possibly useful code snippets for making gray ICC profiles:

/* LAB "L" (perceptually uniform) TRC */
cmsFloat64Number labl_parameters[5] = 
   { 3.0, 1.0 / 1.16,  0.16 / 1.16, 2700.0 / 24389.0, 0.08000 }; 
cmsToneCurve *labl_parametic_curve =
   cmsBuildParametricToneCurve(NULL, 4, labl_parameters);
cmsToneCurve *labl_parametric[3] = 
   {labl_parametic_curve,labl_parametic_curve,labl_parametic_curve};
   
/* sRGB TRC */
cmsFloat64Number srgb_parameters[5] = 
   { 2.4, 1.0 / 1.055,  0.055 / 1.055, 1.0 / 12.92, 0.04045 };
cmsToneCurve *srgb_parametic_curve =
   cmsBuildParametricToneCurve(NULL, 4, srgb_parameters);
cmsToneCurve *srgb_parametric[3] = 
   {srgb_parametic_curve,srgb_parametic_curve,srgb_parametic_curve};


/* D50 white point calculated from D50 illuminant XYZ values in ICC specs */
cmsCIExyY d50_illuminant_specs = {0.345702915, 0.358538597, 1.0};


/* ***** Make profile: Gray ICC profiles - D50 white point  ********* */
whitepoint = d50_illuminant_specs;
const cmsToneCurve* grayTRC;

/* Gray profile with gamma=1.00, linear gamma, "linear light", etc */
grayTRC = cmsBuildGamma (NULL, 1.00); 
profile = cmsCreateGrayProfile ( &whitepoint, grayTRC );

/* Gray profile with srgb-trc */
grayTRC = cmsBuildParametricToneCurve(NULL, 4, srgb_parameters);
profile = cmsCreateGrayProfile ( &whitepoint, grayTRC );

/* Gray profile with labl TRC */
grayTRC = cmsBuildParametricToneCurve(NULL, 4, labl_parameters);
profile = cmsCreateGrayProfile ( &whitepoint, grayTRC );
Comment 8 Massimo 2015-12-10 18:00:44 UTC
When drag dropping a layer between two grayscale
images gimp prints:

gimp-2.9:8418): GLib-GObject-CRITICAL **: g_object_ref: assertion 'G_IS_OBJECT (object)' failed

but it is a warning that will probably be fixed 
naturally when gimp will know of grayscale color profiles. 

It is reffing a NULL dest_profile
Comment 9 Michael Natterer 2015-12-10 18:15:30 UTC
*** Bug 759283 has been marked as a duplicate of this bug. ***
Comment 10 Michael Natterer 2015-12-13 18:45:53 UTC
Step one, add built-in grayscale profiles, please review:

commit b54a8d19399fb9035501ca81051c15d038f1f6f3
Author: Michael Natterer <mitch@gimp.org>
Date:   Sun Dec 13 19:43:02 2015 +0100

    Bug 756389 - Color-managing grayscale images
    
    Add gimp_color_profile_new_srgb_gray() and
    gimp_color_profile_new_linear_gray().
    
    I know "srgb_gray" sounds odd but it's better than
    "gray_with_srgb_trc"...
    
    Please review, I have no clue if that code is right.

 libgimpcolor/gimpcolor.def      |   2 +
 libgimpcolor/gimpcolorprofile.c | 148 ++++++++++++++++++++++++++++++++--------
 libgimpcolor/gimpcolorprofile.h |   4 +-
 3 files changed, 125 insertions(+), 29 deletions(-)
Comment 11 Elle Stone 2015-12-13 20:58:36 UTC
The code looks right.

I modified gimpcolorprofile.c to access the new profile-making code and save the resulting profiles to disk so I could look at the actual profiles: 

* Running sample points through ArgyllCMS "xicclu -ir -pl name-of-profile", the GIMP gray profiles appear to be functionally the same as the gray profiles made by my own profile-making code. 

* Sample xicclu output matches equivalent RGB output (for example "0.5" input for gray produces output that matches RGB output from the equivalent RGB profile when inputting "0.5, 0.5, 0.5").

* Converting the profiles to xml (iccToXml), the GIMP gray profiles look correct.

So the code looks right and the profiles look right, but with Cinepaint no longer installed on my system, I don't seem to have any installed software that allows me to easily compare results of actually applying "should be equivalent" grayscale profiles to grayscale images.

The only caveat is that the GIMP gray profile-making code uses the D65 white point. Depending on how LCMS2 and other software handles absolute colorimetric conversions to/from/between grayscale profiles, this could cause issues. 

I would suggest using D50 instead (cmsCIExyY d50_illuminant_specs = {0.345702915, 0.358538597, 1.0};). In practice, it probably won't make any difference unless someone tries really hard to do something odd. 

ArgyllCMS xicclu -ia and -ir (absolute and relative conversions) do produce different results when using the D65 white point for a gray profile. I didn't check LCMS transicc. The white point shouldn't make any difference for relative colorimetric profile conversions. But D50 white points for grayscale profiles seems like the safer option.

Also, here are better parameters for making the LAB curve:

cmsFloat64Number labl_parameters[5] = 
   { 3.0, 1.0 / 1.16,  0.16 / 1.16, 2700.0 / 24389.0, 0.08000 };

Not that it matters much, but to me the name "srgb-gray" seems confusing. 

gray-srgb, gray-lab, gray-linear, gray-gamma180, gray-rec709, etc - these names might make more sense, being short for:

"grayscale profile with the sRGB companding curve"
"grayscale profile with the rec709 companding curve"
"grayscale profile with the LAB companding curve"
and etc.
Comment 12 Michael Natterer 2015-12-13 22:05:10 UTC
I don't like the name either, maybe we should rethink our namespace
as you suggest:

gimp_color_profile_new_rgb_srgb
gimp_color_profile_new_rgb_linear
gimp_color_profile_new_rgb_adobe

gimp_color_profile_new_gray_srgb
gimp_color_profile_new_gray_linear

Maybe we should also put the whitepoint in the name.

Can you shortly explain why we use D65 for RGB but
should use D50 for gray?
Comment 13 Michael Natterer 2015-12-13 22:40:27 UTC
Please also review this commit. Particularly, should I use

  cmsSetPCS (target_profile, cmsSigXYZData);

also on gray profiles in gimp_color_profile_new_from_color_profile()?

commit 11e8cacf7e185398e2517784961f6642e5ff65de
Author: Michael Natterer <mitch@gimp.org>
Date:   Sun Dec 13 23:36:31 2015 +0100

    Bug 756389 - Color-managing grayscale images
    
    Support creating linear/sRGB-gamma variants of gray profiles and
    rename gimp_color_profile_new_linear_rgb_from_color_profile() to
    gimp_color_profile_new_linear_gamma_from_color_profile() because it's
    not RGB-specific any longer.

 app/core/gimpimage-convert-precision.c |  2 +-
 app/core/gimplayer.c                   |  2 +-
 libgimpcolor/gimpcolor.def             |  2 +-
 libgimpcolor/gimpcolorprofile.c        | 74 +++++++++++++++++++++-------------
 libgimpcolor/gimpcolorprofile.h        |  4 +-
 5 files changed, 51 insertions(+), 33 deletions(-)
Comment 14 Elle Stone 2015-12-13 22:53:34 UTC
(In reply to Michael Natterer from comment #12)
> I don't like the name either, maybe we should rethink our namespace
> as you suggest:
> 
> gimp_color_profile_new_rgb_srgb
> gimp_color_profile_new_rgb_linear

Technically speaking "gimp_color_profile_new_rgb_linear" is wrong. Putting the white point to one side, an ICC RGB profile is defined by its primaries and tone response curve. For example, you can have:

A linear gamma RGB profile with the sRGB primaries
A linear gamma RGB profile with the ProPhotoRGB primaries
A linear gamma RGB profile with the Rec.2020 primaries.
A linear gamma RGB profile with primaries calculated using camera-profiling software and a target chart shot
A linear gamma RGB profile with any other set of primaries that seems useful for some purpose.

How about:

gimp_color_profile_new_rgb_srgb
gimp_color_profile_new_rgb_srgb_linear

> gimp_color_profile_new_rgb_adobe
> 
> gimp_color_profile_new_gray_srgb
> gimp_color_profile_new_gray_linear
> 
> Maybe we should also put the whitepoint in the name.

Every RGB color space has a well-defined white point given in its color space specs. So the only time you would need to include the white point is if you were making a non-standard RGB ICC profile. This is why my ICC profile names don't indicate the profile white point but do always indicate the TRC - I don't just provide the "standard" version of the various RGB profiles, but also TRC variations, including a linear gamma version of each RGB profile.

> 
> Can you shortly explain why we use D65 for RGB but
> should use D50 for gray?

RGB color space specs are defined by specifying a white point, a TRC, and the red, green, and blue primaries.

Not every RGB color space uses D65 for the white point:

   * The ACES color spaces use something close to D60. 
   * sRGB, AdobeRGB1998, Rec.2020, Rec.709 (and others) use D65.
   * ProPhotoRGB, WideGamutRGB, ColorMatch, BetaRGB, BruceRGB, BestRGB (and others) use D50.
   * CIERGB uses E (equal energy)
   * There are some older color spaces that use C.

To make an ICC profile from RGB color space specs, you chromatically adapt the color space red, green, and blue primaries from the white point given in the color space specs to the ICC spec illuminant, which is D50.

As GIMP is an ICC profile color-managed application, and all the ICC profiles are already adapted to D50, it makes sense to use D50 for gray profiles. It wouldn't make sense to use D65 for a grayscale profile that is applied to an image that's been decomposed to LAB or LCH, as the ICC XYZ and LAB profile connection spaces have D50 as the white point. Using D50 avoids the situation where a user might inadvertently create a blue or yellow color cast in a nominally grayscale image when using an absolute colorimetric conversion using V2 software.
Comment 15 Elle Stone 2015-12-13 23:28:04 UTC
(In reply to Elle Stone from comment #14)

> Not every RGB color space uses D65 for the white point:
> 
>    * The ACES color spaces use something close to D60. 
>    * sRGB, AdobeRGB1998, Rec.2020, Rec.709 (and others) use D65.
>    * ProPhotoRGB, WideGamutRGB, ColorMatch, BetaRGB, BruceRGB, BestRGB (and
> others) use D50.
>    * CIERGB uses E (equal energy)
>    * There are some older color spaces that use C.

To give this seemingly random assortment of color space white points some context:

Color spaces that use the D65 and D60 white points are color spaces describing display devices that have been *calibrated* to have the D65 or D60 white point.

Color spaces that use the D50 white point were devised for use in a paper-print-oriented workflow, where standards for evaluating paper prints specify D50 lighting. So adapting RGB color spaces to D50 to make ICC profiles shows the "print" orientation of the ICC, which orientation seems to be currently shifting, but for now it's still D50 all the way.
Comment 16 Elle Stone 2015-12-13 23:47:15 UTC
(In reply to Michael Natterer from comment #13)
> Please also review this commit. Particularly, should I use
> 
>   cmsSetPCS (target_profile, cmsSigXYZData);
> 
> also on gray profiles in gimp_color_profile_new_from_color_profile()?

I don't think either of the following lines actually need to be used for the RGB and Gray profiles that GIMP makes:

  cmsSetDeviceClass (target_profile, cmsSigDisplayClass);
  cmsSetPCS (target_profile, cmsSigXYZData);

Leastways my own profile-making code for Grayscale and RGB matrix working space profiles doesn't include any such lines, and the resulting profiles all have the correct header information.


Regarding cmsSetProfileVersion (target_profile, 4.3);

LCMS2 uses V4 specs. So you only need "cmsSetProfileVersion" if you want to make a V2 profile for use with software that can't read V4 profiles, or if there is an overriding reason to specify a particular version of the V4 specs. 

There might come a point in the future when the next version of the ICC specs comes out and LCMS adopts those specs, at which point it might be necessary (depending on what LCMS offers at that point and what GIMP wants to actually support) to specify V4 instead of V6?? or however they decide to number the next version of the specs.
Comment 17 Michael Natterer 2015-12-14 00:35:56 UTC
This is not what I meant by "shortly explain" but anyway, here is D50 :)

commit 169f436e7567cd025dbdb29614b5c7e6f2cff85d
Author: Michael Natterer <mitch@gimp.org>
Date:   Mon Dec 14 01:32:35 2015 +0100

    libgimpcolor: use D50 for the gray profiles

 libgimpcolor/gimpcolorprofile.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)
Comment 18 Michael Natterer 2015-12-14 00:55:42 UTC
The next bit:

commit 5cbe6f20036a94990567d537a014edd8e55b265c
Author: Michael Natterer <mitch@gimp.org>
Date:   Mon Dec 14 01:54:00 2015 +0100

    libgimpconfig: add a preferred gray profile to GimpColorConfig

 libgimpconfig/gimpcolorconfig.c | 95 +++++++++++++++++++++++++++++++++++++++++
 libgimpconfig/gimpcolorconfig.h |  7 ++-
 libgimpconfig/gimpconfig.def    |  1 +
 3 files changed, 101 insertions(+), 2 deletions(-)
Comment 19 Michael Natterer 2015-12-14 01:15:51 UTC
commit 40280c0862840032fec08241609ad40258d6a6af
Author: Michael Natterer <mitch@gimp.org>
Date:   Mon Dec 14 02:13:51 2015 +0100

    app: add the preferred gray profile to the prefs dialog

 app/dialogs/preferences-dialog.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)
Comment 20 Øyvind Kolås (pippin) 2015-12-14 12:25:25 UTC
To me it seems like this bug still lacks a good/short rationale for using D50 rather than D65.

To me it seems awkward for GIMP to be using different illuminant for grayscale and RGB modes. An image with all pixel values R=G=B when changed to grey scale should probably neither change pixel values nor appearance; (this might be the case even if using D50 for grayscale). On a more practical level using D50 might incur *more* conversions; since our default RGB space, sRGB; Adobe RGB and more; as well as the babl connection space are all D65 spaces.
Comment 21 Elle Stone 2015-12-14 16:07:53 UTC
(In reply to Øyvind Kolås from comment #20)
> To me it seems like this bug still lacks a good/short rationale for using
> D50 rather than D65.

Upon reconsideration, I think you are right, and you have pointed to an important consideration that don't affect GIMP right now, but will need to be taken into account in the future. I've been thinking pretty much exclusively in terms of D50-adapted ICC profiles, but the next version of the ICC specs will allow other illuminants.

> 
> To me it seems awkward for GIMP to be using different illuminant for
> grayscale and RGB modes. 

My apologies if everyone already knows this, but in ICC profile terminology, there is a difference between the media white point and the illuminant: 

* The illuminant refers to the white point of the ICC Profile Connection Space, which currently is always D50 for ICC profiles. However, the upcoming ICCMax profiles ("V5" according to color.org) will allow different illuminants (see http://color.org/iccmax.xalter). 

* The media white point refers to things like:
     * The color of the paper on which an image is printed.
     * The color temperature to which a display is calibrated (monitors can be calibrated to a whole range of color temperatures; sRGB monitors are calibrated to have the D65 white point). RGB working space profiles are idealized display profiles, and the various white points reflect real or hypothetical display white points.

> An image with all pixel values R=G=B when changed
> to grey scale should probably neither change pixel values nor appearance;
> (this might be the case even if using D50 for grayscale). 

You are right. The grayscale and RGB profiles that GIMP makes are display class ICC profiles, which in a V4 workflow use relative colorimetric intent even if absolute is requested. 

So using D65 for the media white point for grayscale profiles shouldn't cause any user issues: GIMP users won't be making ICC profile conversions that produce images with unintended blue or yellow color casts if they choose absolute colorimetric intent (that's the whole point of the V4 policy regarding display profiles).

> On a more
> practical level using D50 might incur *more* conversions; since our default

Not sure what you mean, but differing media white points don't make a difference for conversions between display profiles in a V4 workflow (unless code is written that allows for partial adaptation - which I *think* LCMS makes possible using cmsSetAdaptationState).

> RGB space, sRGB; Adobe RGB and more; 

As an aside, many RGB color spaces do use non-D65 media white points.

> as well as the babl connection space
> are all D65 spaces.

On the one hand, almost all the hard-coded sRGB Y and XYZ primaries in babl, GEGL, and GIMP have already been *adapted* from D65 to D50 (the SVG code still needs to have the hard-coded Y values adapted to D50). This is necessary to get correct color space conversions and editing results from a V4 ICC profile color-managed editing application, which always uses D50 as the ICC profile illuminant.

On the other hand and looking to the future, when ICCMax is finally released, and LCMS is rewritten to support ICCMax, and babl/GEGL/GIMP have been developed to support ICCMax and maybe even OCIO for HDR scene-referred editing:

* The babl/GEGL/GIMP color space conversion code (sRGB to/from Y/XYZ) will need to be rewritten to start with the *un*adapted sRGB color space primaries and D65 white point.

* Code will need to be written to chromatically adapt the sRGB color space primaries from D65 to the chosen ICC profile illuminant. Assuming Bradford adaptation is used, for D50 illuminant profiles this new "media white point to profile illuminant" code will reproduce the current hard-coded, already D50-adapted sRGB ICC profile Y and XYZ values.
Comment 22 Michael Natterer 2015-12-14 17:45:41 UTC
So be it for now :)

commit 822bfabe212cd71ce124145f6ae99eafdcc95e83
Author: Michael Natterer <mitch@gimp.org>
Date:   Mon Dec 14 18:43:26 2015 +0100

    Revert "libgimpcolor: use D50 for the gray profiles"
    
    This reverts commit 169f436e7567cd025dbdb29614b5c7e6f2cff85d.
    
    Turns out we should use the same whitepoint for RGB and GRAY.

 libgimpcolor/gimpcolorprofile.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)
Comment 23 Michael Natterer 2015-12-14 22:27:27 UTC
This should do the trick, please test:

commit 5098338470a61f14e737a4e15afa12bd6e7b664b
Author: Michael Natterer <mitch@gimp.org>
Date:   Mon Dec 14 23:23:25 2015 +0100

    Bug 756389 - Color-managing grayscale images
    
    Allow to set profiles on grayscale images. Change profile validation
    to check for image type and profile type. Actually the patch simply
    makes some pieces of code less restrictive. Change user-visible
    strings in the profile dialogs accordingly. Change PDB docs
    accordingly.

 app/core/gimpimage-color-profile.c        | 156 +++++++++++++++++-------------
 app/core/gimpimage.c                      |   2 +-
 app/dialogs/color-profile-dialog.c        |  32 ++++--
 app/dialogs/color-profile-import-dialog.c |  17 +++-
 app/gegl/gimp-gegl-loops.c                |  28 +++---
 app/pdb/image-color-profile-cmds.c        |  10 +-
 libgimp/gimpimagecolorprofile_pdb.c       |  14 +--
 tools/pdbgen/pdb/image_color_profile.pdb  |  17 ++--
 8 files changed, 169 insertions(+), 107 deletions(-)
Comment 24 Elle Stone 2015-12-15 21:45:05 UTC
Created attachment 317456 [details] [review]
two function names that might have been left behind

Maybe two functions, one each in color-selector-cmyk.c and display-filter-proof.c, were left behind (gimp_color_profile_new_srgb and rgb_profile = gimp_color_profile_new_rgb_srgb)? 

Just in case, here's a patch.
Comment 25 Michael Natterer 2015-12-16 11:46:15 UTC
Thanks, fixed in master. Did you notice anything that's broken with grayscale
color management? I'd like to close the bug if not :)

commit 3e5eba0774d51562d47b926d566e51f6ed95bc91
Author: Michael Natterer <mitch@gimp.org>
Date:   Wed Dec 16 00:22:39 2015 +0100

    modules: patch from Elle that fixes some forgotten profile_new name changes

 modules/color-selector-cmyk.c  | 2 +-
 modules/display-filter-proof.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)
Comment 26 Elle Stone 2015-12-16 14:57:35 UTC
(In reply to Michael Natterer from comment #22)
> commit 822bfabe212cd71ce124145f6ae99eafdcc95e83
> Author: Michael Natterer <mitch@gimp.org>
> Date:   Mon Dec 14 18:43:26 2015 +0100
> 
>     Revert "libgimpcolor: use D50 for the gray profiles"
>     
>     This reverts commit 169f436e7567cd025dbdb29614b5c7e6f2cff85d.
>     
>     Turns out we should use the same whitepoint for RGB and GRAY.

"Should" is a bit strong. When used as a default grayscale profile that's a grayscale version of the sRGB color space, it makes sense to use  the D65 white point.

When assigning a gray profile to a grayscale image that was made from an sRGB image, ideally one would ask the user what white point they want the gray profile to have. But this is a silly and distracting question in a V4 workflow where conversions between display class profiles are always done using relative colorimetric intent. 

The real question is what happens when converting from the gray profile to an RGB profile with a full set of LUT tables, such as a profile for a high end "printer+paper" combination, and asking for absolute colorimetric intent. As GIMP doesn't yet allow conversions between grayscale and RGB profiles, I can't check directly, and so far perusing the ICC specs hasn't been helpful.
Comment 27 Elle Stone 2015-12-16 14:58:08 UTC

(In reply to Michael Natterer from comment #12)
> I don't like the name either, maybe we should rethink our namespace
> as you suggest:
> 
> gimp_color_profile_new_rgb_srgb
> gimp_color_profile_new_rgb_linear
> gimp_color_profile_new_rgb_adobe
> 
> gimp_color_profile_new_gray_srgb
> gimp_color_profile_new_gray_linear

> Maybe we should also put the whitepoint in the name.

Right now the naming scheme uses "new_gray_srgb_linear", which seems confusing - it suggests that maybe the profile links the sRGB TRC with the linear gamma TRC, or maybe "linear gamma" is different for sRGB than it is for other RGB profiles. 

I'd suggest changing the name to "new_gray_linear".

As already noted, for RGB profiles, the color space white point is given in the specifications that define the RGB color space in the first place. So for example, sRGB, Adobe RGB, Rec.2020, Rec.709, etc have the D65 white point and they all use exactly the same values for D65, so there's no reason to put the white point in the profile name.

GIMP's internal gray profiles are made by specifying a white point and a TRC. For gray profiles that are made to go along with RGB profiles made from color space specs that use the D65 white point - and given that sRGB is not the only color space that is defined using the D65 white point - it seems to me that the name "new_gray_d65_linear" is much less confusing than the current "new_gray_srgb_linear".
Comment 28 Elle Stone 2015-12-16 14:59:08 UTC
(In reply to Michael Natterer from comment #25)
> Thanks, fixed in master. Did you notice anything that's broken with grayscale
> color management? I'd like to close the bug if not :)

With respect to the existing code, everything seems to work properly, with the following caveats:

1. There is no way to directly convert between RGB and gray profiles, so this fairly important functionality is missing.

2. The proper gray profile isn't yet assigned to grayscale layer stacks that result from decomposing to LAB/LCH.

3. Users will get wrong results if they are at linear precision and they assign a linear gamma profile from disk to the GIMP layer stack. The image will look right. But when exporting the image to disk and then opening the exported image with GIMP or another image editor, the image will be encoded using the sRGB TRC, but the embedded profile will say the image is encoded using a linear gamma TRC. This is a problem with both RGB and grayscale images. I'm attaching a screenshot to show the problem for an RGB image, but the same problem affects grayscale images.
Comment 29 Elle Stone 2015-12-16 15:01:23 UTC
Created attachment 317502 [details]
Screenshot showing problem with exporting linear light precision images

As noted in Comment 28, he same issue affects both gray and RGB images.
Comment 30 Elle Stone 2015-12-16 15:03:47 UTC
(In reply to Elle Stone from comment #27)

> I'd suggest changing the name to "new_gray_linear".

Sorry, I meant to say "new_gray_d65_linear".
Comment 31 Michael Natterer 2015-12-18 23:19:48 UTC
Right now we use:

GimpColorProfile * gimp_color_profile_new_rgb_srgb          (void);
GimpColorProfile * gimp_color_profile_new_rgb_srgb_linear   (void);
GimpColorProfile * gimp_color_profile_new_rgb_adobe         (void);

GimpColorProfile * gimp_color_profile_new_gray_srgb         (void);
GimpColorProfile * gimp_color_profile_new_gray_srgb_linear  (void);

which is at least consistent and symmetric (an important property for
function names), even though gray_srgb_linear() sounds like shit :)

If we rename it to:

GimpColorProfile * gimp_color_profile_new_gray_d65_linear  (void);

shouldn't we also use:

GimpColorProfile * gimp_color_profile_new_rgb_d65_linear   (void);

To be honest, I don't really like that. The current names (weird as
they are) have at least the property that the linear variant of
a profile simply has the _linear appended. I'm open for suggestions
though :)
Comment 32 Elle Stone 2015-12-19 14:04:54 UTC
Regarding naming the profiles:

On the one hand, the standard RGB matrix color spaces are all based on well-known specifications. These color space specifications dictate the white point point, the primaries and the TRC. 

So if you mention sRGB, Rec2020RGB, etc, everyone knows (should know) that the white point is D65. And if you mention ProPhotoRGB, WideGamutRGB, BetaRGB, etc, everyone knows that the white point is D50. And so on. So there is no reason to put the white point in the naming scheme for GIMP's internal versions of ICC profiles made from standard RGB color spaces.

So "rgb_srgb" adequately indicates the regular sRGB ICC profle because everyone knows the sRGB color space has the D65 white point. And "rgb_srgb_linear" adequately indicates a linear gamma version of the sRGB ICC profile, and everyone knows that because it's a linear gamma version of the sRGB ICC profile, the white point is D65.

On the other hand, there aren't any standard matrix "gray space" specifications. 

A gray ICC profile is created by choosing a white point and a TRC (companding curve). Any TRC can be paired with any white point to make a new gray ICC profile, so when naming a gray ICC profile it makes sense to include the white point and the TRC in the profile name. 

Some commonly used TRCs that might be used when making a gray ICC profile include:

* The TRC described in the sRGB color space specs.
* The TRC described in the Rec709 color space specs.
* The true gamma TRCs, which are used in color spaces such as BetaRGB, AdobeRGB, Widegamut RGB, etc.
* The linear gamma TRC, which is also a true gamma TRC.
* Various log-type TRCs.
* The LAB color space perceptually uniform TRC.

There is no "law" and more to the point no specification that says that a gray profile that has the sRGB TRC also must have the D65 white point. The choice is entirely up to the person who makes the profile. So it makes sense to put the white point and the TRC in the name of gray ICC profiles:

"gray_d65_srgb" would mean "a gray profile made using the D65 white point and the TRC from the sRGB color space specs".
"gray_d50_srgb" would mean "a gray profile made using the D50 white point and the TRC from the sRGB color space specs".

"gray_d65_gamma22" would mean "a gray profile made using the D65 white point and the gamma=2.2 TRC"
"gray_d50_gamma22" would mean a gray profile made using the D50 white point and the gamma=2.2 TRC"

"gray_d65_linear" would mean a gray profile made using the D65 white point and the linear gamma TRC"
"gray_d50_linear" would mean a gray profile made using the D50 white point and the linear gamma TRC".

And so forth. 

The gray profile names might be less confusing if "trc" were appended to "srgb" because in the proposed naming for gray profiles "srgb" doesn't mean anything except the *TRC* given in the sRGB color space specifications: "gray_d65_srgbtrc".

However, as explained in the next comment, in a V4 workflow the white point used to make a gray display profile doesn't matter. At all. So if you use D65 for all gray profiles, that's just not going to cause any issues. The same is true if you use D50 for all gray profiles. 

So the simplest thing to do is make the gray profiles using whatever white point makes the most people happy (that would be D65) and leave the white point out of the gray profile name.
Comment 33 Elle Stone 2015-12-19 14:12:07 UTC
The reason why I have been so concerned about "D50" vs "D65" for gray profiles is as follows: 

1. GIMP internal gray and RGB profiles are all "display" profiles. In fact all the commonly used RGB matrix working space profiles are display profiles. (As surprising as it may seem, there is no separate class of profiles for actual RGB working spaces, the point of ICC profiles seems to be preserving appearances when converting from one device profile to another, and not with actually editing images.)

2. In V4 *RGB* display profiles, the media white point tag should alway contains D50 values, even for display profiles made from D65 color spaces, and this is exactly what happens when you use LCMS to make an RGB display profile. The actual D65 color space information is contained in the chromatic adaptation tag, not in the media white point tag. As odd as it might seem, the media white point tag always contains D50 values, no matter what  white point is used to make a display profile.

3. LCMS-made *gray* display profiles put the white point information (the white point used to make the profile) in the profile's media white point tag, and there is no chromatic adaptation tag. I assumed this was in accordance with the ICC V4 specs, which opened up the possibility that in a V4 workflow gray display profiles are treated differently than RGB display profiles. 
     Probably the profile-making code can be modified to produce gray profiles that are in accordance with the V4 specs. But from a practical point of view, it doesn't seem to matter in a V4 workflow.

4. I've been reading through the V4 ICC specs (http://color.org/specification/ICC1v43_2010-12.pdf) and it turns out that in a properly made V4 gray display profile, if the white point used to make the ICC profile isn't D50, then first, there really should be a chromatic adaptation tag (see Tables G2 and G3, and also 8.2 Common [tag] requirements. And second, the media white point tag should always contain D50 values, exactly as with V4 RGB color space profiles. Quoting from "9.2.34 mediaWhitePointTag"

"This tag, which is used for generating the ICC-absolute colorimetric intent, specifies the chromatically adapted
nCIEXYZ tristimulus values of the media white point. . . . For displays, the values specified shall be
those of the PCS illuminant as defined in 7.2.16."

Quoting from "7.2.16 PCS illuminant field":

"The PCS illuminant field shall contain the nCIEXYZ values X = 0,964 2, Y = 1,0 and Z = 0,824 9 encoded as
an XYZNumber. See Annex A for further details. NOTE These values are the nCIEXYZ values of CIE illuminant D50."

The white point used to make display profiles does matter for V2 display profiles used in a V2 workflow, but GIMP uses V4 profiles in a V4 workflow.

When the ICC specs change again, the "white point for display profiles" issue might need to be revisted.
Comment 34 Michael Natterer 2016-04-08 10:49:40 UTC
There is too much information here :)

I lost track, do we need to rename the functions or are they fine?
Comment 35 Elle Stone 2016-04-08 11:21:28 UTC
Created attachment 325581 [details] [review]
Patch to change grayscale profile names to show the white point

It seems unlikely that GIMP users might encounter situations where the white point of a gray profile will make a difference.

But technically a different white point means a different profile. So in case you want to make the changes, here's a patch.
Comment 36 Elle Stone 2016-04-08 11:27:49 UTC
(In reply to Michael Natterer from comment #34)
> There is too much information here :)
> 
> I lost track, do we need to rename the functions or are they fine?

Currently I don't include the white point in the names/descriptions of the gray profiles made using my profile-making code. But after thinking about it, I'm going to change that code to show the grayscale white point. 

It would be nice to show the white point in the names of GIMP grayscale profiles. The only reason not to would be if the additional information might be confusing rather than helpful to GIMP users.
Comment 37 Elle Stone 2016-04-08 11:39:07 UTC
(In reply to Elle Stone from comment #36)
> It would be nice to show the white point in the names of GIMP grayscale
> profiles. The only reason not to would be if the additional information
> might be confusing rather than helpful to GIMP users.

On the other hand, I can't think of a single real-world application where I know for sure that the white point of a grayscale profile makes a difference. Maybe if converting from grayscale to a color printer profile using absolute colorimetric conversion?
Comment 38 Michael Natterer 2016-04-08 17:07:24 UTC
I actually meant the function names :) But I agree the patch you
attached does make sense too.
Comment 39 Elle Stone 2016-04-08 17:38:29 UTC
(In reply to Michael Natterer from comment #38)
> I actually meant the function names :) But I agree the patch you
> attached does make sense too.

You mean these?
gimp_color_profile_new_gray_srgb
gimp_color_profile_new_gray_srgb_linear_internal
gimp_color_profile_new_gray_srgb_linear

How about these names:
gimp_color_profile_new_d65_gray_srgbtrc
gimp_color_profile_new_d65_gray_linear_internal
gimp_color_profile_new_d65_gray_linear

The logic is that for a gray profile, the two relevant bits of information are the white point (d65) and TRC ("linear" or "srgbtrc" - not just "srgb" because the sRGB TRC can be and sometimes is paired with non-sRGB primaries).

If you would like I can send a revised patch.
Comment 40 Michael Natterer 2016-04-09 14:08:25 UTC
And perhaps we should also replace "gamma" by "try" in these?

gimp_color_profile_new_srgb_gamma_from_color_profile
gimp_color_profile_new_linear_gamma_from_color_profile
Comment 41 Elle Stone 2016-04-09 14:18:46 UTC
(In reply to Michael Natterer from comment #40)
> And perhaps we should also replace "gamma" by "try" in these?
> 
> gimp_color_profile_new_srgb_gamma_from_color_profile
> gimp_color_profile_new_linear_gamma_from_color_profile

Yes, sorry!

gimp_color_profile_new_srgbtrc_from_color_profile

and either:
  gimp_color_profile_new_linear_gamma_from_color_profile

or better yet (because shorter):
  gimp_color_profile_new_linear_from_color_profile
Comment 42 Michael Natterer 2016-04-09 16:02:44 UTC
I see the point in using "srgbtrc" instead of "srgb_trc", I'm just not
sure if I like it :) Will consider a bit, then push something and
close this bug.

...unless there is really still something essential missing or broken
with grayscale images. I'm not aware of anything right now, are you?
Comment 43 Elle Stone 2016-04-09 16:12:25 UTC
(In reply to Michael Natterer from comment #42)
> I see the point in using "srgbtrc" instead of "srgb_trc", I'm just not
> sure if I like it :) Will consider a bit, then push something and
> close this bug.

"srgb_trc" is fine of course. I'm just used to writing "srgbtrc" as that's the profile ending I use for my profile-making code, which includes "-srgbtrc.icc" variants for all the profiles that it makes.

> 
> ...unless there is really still something essential missing or broken
> with grayscale images. I'm not aware of anything right now, are you?

I don't use grayscale images very much except for decomposing to LAB/LCH. But the only remaining issues that I'm aware of are:

* The ability to do ICC profile conversions between grayscale and RGB profiles, for which a separate bug report/enhancement request could be filed.

* Having GIMP automatically assign a grayscale profile with the LAB-L companding curve to grayscale images that have been decomposed to LAB or LCH, which technically isn't an aspect of this particular bug report.
Comment 44 Michael Natterer 2016-04-09 16:20:32 UTC
Thanks, I agree these are sufficiently complex to warrant reports of their
own. Don't we already have one for both points? I'm sure you mentioned
both already, but it was probably in other bugs' comments.

Will do as proposed and get rid of this bug after fixing the function names.
Comment 45 Michael Natterer 2016-04-09 16:51:49 UTC
Comment on attachment 325581 [details] [review]
Patch to change grayscale profile names to show the white point

Pushed to master:

commit 6ba19a5d460e9209c0d50b0171054f779b80f8b6
Author: Elle Stone <ellestone@ninedegreesbelow.com>
Date:   Fri Apr 8 07:15:58 2016 -0400

    Bug 756389 - Color-managing grayscale images
    
    Change grayscale profiles to show white point

 libgimpcolor/gimpcolorprofile.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)
Comment 46 Michael Natterer 2016-04-09 16:53:00 UTC
Pushed the renaming, grayscale color management should now be
basically working:

commit f34aa5fa6bfa91b2c73fe21c4370aa3e70e6ae44
Author: Michael Natterer <mitch@gimp.org>
Date:   Sat Apr 9 18:47:51 2016 +0200

    Bug 756389 - Color-managing grayscale images
    
    Rename profile constructors to say "d65_gray" instead of just "gray",
    "srgb_trc" instead of "srgb_gamma", and drop the "srgb" from
    "srgb_linear" because we now say "d65". This should be a naming scheme
    that doesn't conflict with whatever future functions we might add.

 app/core/gimpimage-color-profile.c     |  4 ++--
 app/core/gimpimage-convert-precision.c |  4 ++--
 app/core/gimplayer.c                   |  4 ++--
 app/gegl/gimp-gegl-loops.c             |  8 +++++---
 libgimpcolor/gimpcolor.def             |  8 ++++----
 libgimpcolor/gimpcolorprofile.c        | 24 ++++++++++++------------
 libgimpcolor/gimpcolorprofile.h        |  8 ++++----
 7 files changed, 31 insertions(+), 29 deletions(-)
Comment 47 Elle Stone 2016-04-17 14:03:27 UTC
(In reply to Michael Natterer from comment #44)
> Thanks, I agree these are sufficiently complex to warrant reports of their
> own. Don't we already have one for both points? I'm sure you mentioned
> both already, but it was probably in other bugs' comments.
> 

(In reply to Elle Stone from comment #43)

> I don't use grayscale images very much except for decomposing to LAB/LCH.
> But the only remaining issues that I'm aware of are:
> 
> * The ability to do ICC profile conversions between grayscale and RGB
> profiles, for which a separate bug report/enhancement request could be filed.

Here's the new bug report: https://bugzilla.gnome.org/show_bug.cgi?id=765176

> * Having GIMP automatically assign a grayscale profile with the LAB-L
> companding curve to grayscale images that have been decomposed to LAB or
> LCH, which technically isn't an aspect of this particular bug report.

Here's the new bug report: https://bugzilla.gnome.org/show_bug.cgi?id=765178