Color space conversions seems to change PCS as well

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

Color space conversions seems to change PCS as well

Developers mailing list
First things first. The C code for gegl operation I use here that prints the pixels in CIE xyY color space is below.
I apologize that it's an unnecessary composer3 class, but that's what I had handy as a template.
I also attached a very small (3x3) test image `33time.xcf`.

When first opened, the image is in Built-in sRGB and the top row is pure rgb, that is 255,0,0; 0,255,0; 0,0,255. And when running my small gegl operation, I get this stdout in CIExyY color space:

Input pixels  x=0.653898, y=0.321709, Y=0.222488
Input pixels  x=0.323680, y=0.580968, Y=0.716904
Input pixels  x=0.138084, y=0.056409, Y=0.060608
...

Which seems roughly correct (though not exactly comforming to the sRGB standard, which should be 0.64, 0.33, 0.2126 for the Red - that is also weird).
Then I convert the image to ProPhoto RGB (for example) color space. Now the "pure" sRGB colors are no longer represented as pure values - but that is to be expected - that is how color spaces work. So far so good.
The problem comes when I try to peep at the xyY values using my operation:

Input pixels  x=0.576892, y=0.363497, Y=0.144828
Input pixels  x=0.356573, y=0.513024, Y=0.668290
Input pixels  x=0.175974, y=0.085000, Y=0.083105
...

Those seem to differ as well, which is wrong as CIExyY color space is a profile connection space and the values there should be objective values not burdened by any device profile/working space.
That is my problem. Why does GIMP/GEGL seem to change the fundamental color as well besides just its RGB representation when converting between profiles? (Rendering intents seem to have no significant change) How do I make it behave correctly? Have I misunderstood something? How do I get the proper CIExyY values?

Thanks, Marek

=== stdout of the session:
$ gimp
Gtk-Message: 12:06:57.013: Failed to load module "appmenu-gtk-module"

(gimp:253037): Gtk-WARNING **: 12:06:57.017: Unable to locate theme engine in module_path: "adwaita",
gimp_color_transform_new: using babl for 'GIMP built-in sRGB' -> 'sRGB'
gimp_color_transform_new: using babl for 'GIMP built-in sRGB' -> 'sRGB'
gimp_color_transform_new: using babl for 'GIMP built-in sRGB' -> 'sRGB'
gimp_color_transform_new: using babl for 'GIMP built-in sRGB' -> 'sRGB'
gimp_color_transform_new: using babl for 'GIMP built-in sRGB' -> 'sRGB'
gimp_color_transform_new: using babl for 'GIMP built-in sRGB' -> 'sRGB'
gimp_color_transform_new: using babl for 'GIMP built-in D65 Linear Grayscale' -> 'sRGB'
gimp_color_transform_new: using babl for 'GIMP built-in sRGB' -> 'sRGB'
gimp_color_transform_new: using babl for 'GIMP built-in sRGB' -> 'sRGB'
using gegl copy
using gegl copy
---
Input pixels  x=0.653898, y=0.321709, Y=0.222488
Input pixels  x=0.323680, y=0.580968, Y=0.716904
Input pixels  x=0.138084, y=0.056409, Y=0.060608
---
Input pixels  x=0.164499, y=0.090740, Y=0.068458
Input pixels  x=0.322666, y=0.549651, Y=0.470922
Input pixels  x=0.598590, y=0.323715, Y=0.166370
---
Input pixels  x=0.333333, y=0.333333, Y=1.000000
Input pixels  x=0.333333, y=0.333333, Y=0.212231
Input pixels  x=0.345703, y=0.358538, Y=0.000000
gimp_color_transform_new: using babl for 'GIMP built-in sRGB' -> 'ProPhoto RGB'
void gimp_gegl_convert_color_profile(GeglBuffer*, const GeglRectangle*, GimpColorProfile*, GeglBuffer*, const GeglRectangle*, GimpColorProfile*, GimpColorRenderingIntent, gboolean, GimpProgress*): converting buffer took 0.0001 seconds
gimp_color_transform_new: using babl for 'ProPhoto RGB' -> 'sRGB'
gimp_color_transform_new: using babl for 'ProPhoto RGB' -> 'sRGB'
gimp_color_transform_new: using babl for 'ProPhoto RGB' -> 'sRGB'
gimp_color_transform_new: using babl for 'ProPhoto RGB' -> 'GIMP built-in sRGB'
gimp_color_transform_new: using babl for 'GIMP built-in sRGB' -> 'ProPhoto RGB'
gimp_color_transform_new: using babl for 'ProPhoto RGB' -> 'GIMP built-in sRGB'
gimp_color_transform_new: using babl for 'GIMP built-in sRGB' -> 'ProPhoto RGB'
using gegl copy
using gegl copy
---
Input pixels  x=0.576892, y=0.363497, Y=0.144828
Input pixels  x=0.356573, y=0.513024, Y=0.668290
Input pixels  x=0.175974, y=0.085000, Y=0.083105
---
Input pixels  x=0.193397, y=0.109573, Y=0.066733
Input pixels  x=0.354258, y=0.493454, Y=0.393717
Input pixels  x=0.526750, y=0.360529, Y=0.102815
---
Input pixels  x=0.333333, y=0.333333, Y=1.000000
Input pixels  x=0.333333, y=0.333333, Y=0.149960
Input pixels  x=0.345703, y=0.358538, Y=0.000000
gimp_color_transform_new: using babl for 'ProPhoto RGB' -> 'sRGB'

=== print-pixels.c
#define GETTEXT_PACKAGE "gegl"

#include <glib/gi18n-lib.h>
#include <stdio.h>

#ifdef GEGL_PROPERTIES

#else

#define GEGL_OP_POINT_COMPOSER3
#define GEGL_OP_NAME     print_pixels
#define GEGL_OP_C_SOURCE print-pixels.c

#include "gegl-op.h"

static void
prepare (GeglOperation *operation)
{
    const Babl *space = gegl_operation_get_source_space (operation, "input");
    const Babl *format;
    format  = babl_format_with_space ("CIE xyY float", space);
    gegl_operation_set_format (operation, "input", format);
    gegl_operation_set_format (operation, "aux", format);
    gegl_operation_set_format (operation, "aux2", format);
    gegl_operation_set_format (operation, "output", format);
}

static gboolean
process (GeglOperation       *operation,
     void                *in_buf,
     void             *aux_buf,
     void             *aux2_buf,
     void                *out_buf,
     glong                n_pixels,
     const GeglRectangle *roi,
     gint                 level)
{
    GeglProperties *o = GEGL_PROPERTIES (operation);
    gfloat *in   = in_buf;
    printf("---\n");
    for (int i = 0; i < n_pixels; i++)
    {
        printf("Input pixels  x=%f, y=%f, Y=%f\n", in[0], in[1], in[2]);
        in += 3;
    }

    return TRUE;
}

static void
gegl_op_class_init (GeglOpClass *klass)
{
    GeglOperationClass               *operation_class;
    GeglOperationPointComposer3Class *point_composer_class;

    operation_class      = GEGL_OPERATION_CLASS (klass);
    point_composer_class = GEGL_OPERATION_POINT_COMPOSER3_CLASS (klass);

    operation_class->prepare = prepare;
    operation_class->threaded = TRUE;
    operation_class->opencl_support = FALSE;

    point_composer_class->process = process;

    gegl_operation_class_set_keys (operation_class,
        "name"       , "gegl:print-pixels",
        "title",       _("Print Pixels"),
        "categories" , "color",
        "description", _("Print all pixels in an image."),
        NULL);
}

#endif
_______________________________________________
gimp-developer-list mailing list
List address:    [hidden email]
List membership: https://mail.gnome.org/mailman/listinfo/gimp-developer-list
List archives:   https://mail.gnome.org/archives/gimp-developer-list
Reply | Threaded
Open this post in threaded view
|

Re: Color space conversions seems to change PCS as well

Elle Stone
On 10/23/20 6:17 AM, JonnyRobbie via gimp-developer-list wrote:
> When first opened, the image is in Built-in sRGB and the top row is pure rgb, that is 255,0,0; 0,255,0; 0,0,255. And when running my small gegl operation, I get this stdout in CIExyY color space:
>
> Input pixels  x=0.653898, y=0.321709, Y=0.222488

The xyY values that GIMP *does* produce - and GEGL/babl from the command
line *should* produce - for sRGB "reddest red" are these:

x=0.648438 y=0.330867 Y=0.222488

So something seems wrong either in your code or in how GEGL/babl handles
your input, even before you make the conversion from sRGB to ProPhotoRGB.

> Which seems roughly correct (though not exactly comforming to the sRGB standard, which should be 0.64, 0.33, 0.2126 for the Red - that is also weird).

In GIMP the sRGB color space (with its D65 illuminant) has been
Bradford-adapted to D50 to produce the sRGB ICC profile, which is why
there is a small difference between the sRGB color space values and the
sRGB ICC profile values.

As an aside, if/when babl/GEGL/GIMP ever extends ICC profile support to
include iccMAX (which allows illuminants other than D50s), and/or
provides support for OCIO color management in addition to ICC profile
color management, then babl/GEGL/GIMP will have the ability to also work
using D65 sRGB values. But these future possibilities aren't relevant to
the results you are currently getting.

> Then I convert the image to ProPhoto RGB (for example) color space. Now the "pure" sRGB colors are no longer represented as pure values - but that is to be expected - that is how color spaces work. So far so good.
> The problem comes when I try to peep at the xyY values using my operation:
>
> Input pixels  x=0.576892, y=0.363497, Y=0.144828
> Input pixels  x=0.356573, y=0.513024, Y=0.668290
> Input pixels  x=0.175974, y=0.085000, Y=0.083105
> ...
>
> Those seem to differ as well, which is wrong as CIExyY color space is a profile connection space and the values there should be objective values not burdened by any device profile/working space.

Yes, as you note the xyY values should be the same before and after a
color space conversion between well-behaved RGB matrix working spaces,
assuming the source/destination illuminants match, which in current
GIMP/GEGL/babl code should always be the case.

I was able to use GIMP to approximate your above results by following
these steps:

   1. For an sRGB image, fill with sRGB's reddest red.
   2. Convert the image to ProPhotoRGB.
   3. *Assign* the built-in sRGB color space to the newly-converted
image, which changes the color from bright red to middle dullish orange.

After following these steps, here are the resulting xyY values from
sampling the image color using GIMP color picker tool (the eye-dropper
in the toolbox, not the eye-dropper in the FG/BG tool):

x=0.553973, y=0.386853, Y=0.189302

which values are close to what you are getting - for comparison, here
are your values again:

> Input pixels  x=0.576892, y=0.363497, Y=0.144828

So it looks like maybe, possibly:

  * There is some error - either in your code or in GEGL/babl code or
maybe both, or possibly even in the particular ICC profiles you might be
using - that's producing somewhat wrong xyY values in the first place.

  * Then there is some other error that's inserting an "assign" where
there should be a "convert".

> (Rendering intents seem to have no significant change)

Yes, in the case you are describing and b/where ecause GIMP nominally
uses V4 ICC profile management (babl has taken over some of the ICC
profile conversion tasks), using different rendering intents should make
no difference at all to the results because:

  * Both the source and destination profiles are (should be)
well-behaved ICC RGB matrix working spaces, hence only using relative
colorimetric intent regardless of any specified intent.

  * The source and destination profiles have matching D50 white points
and 0,0,0 black points, so using or not using black point compensation
should make no difference at all.

So if changing the rendering intent does make even a small difference,
that suggests yet another problem, possibly in the GEGL/babl code,
possibly even with one of the ICC profiles involved in the color space
conversion.

In case it might be relevant, which version of babl/GEGL/GIMP are you
using, on which operating system? Also, which sRGB and ProPhotoRGB ICC
profiles are you using - who was the profile provider?

Best regards,
Elle
_______________________________________________
gimp-developer-list mailing list
List address:    [hidden email]
List membership: https://mail.gnome.org/mailman/listinfo/gimp-developer-list
List archives:   https://mail.gnome.org/archives/gimp-developer-list
Reply | Threaded
Open this post in threaded view
|

Re: Color space conversions seems to change PCS as well

Developers mailing list
> So if changing the rendering intent does make even a small difference

I tested that again and there's no difference at all between perceptual and relative colorimetric.
But I tried converting with saturation and absolute colorimetric and gimp stdouts that those conversions seem to be not implemented.

gimp_color_transform_new: error making dest format: ProPhoto RGB: absolute stauration not supported

and

gimp_color_transform_new: error making dest format: ProPhoto RGB: absolute colormetric not implemented

> In case it might be relevant, which version of babl/GEGL/GIMP are you
$ gimp -v
GNU Image Manipulation Program version 2.10.22
git-describe: GIMP_2_10_20-217-g0c8a7891f7

gegl 0.4.26 (commit 3371550915bfe10e9e0add87caaf578464305542)
babl 0.1.82 (commit aab30293930236fab173a879f2d9aab95d45db5e)

All from the standard arch/extra repo.

$ uname -roms
Linux 5.9.1-arch1-1 x86_64 GNU/Linux

> Also, which sRGB and ProPhotoRGB ICC profiles are you using - who was the profile provider?

For ProPhotoRGB, it's the colord package from arch with freedesktop as upstream. For sRGB, it's the GIMP built-in

Now, you are right that there's one inconsistency, gimp color picker's xyY is not the same as to what is being pushed to the operation. I've got the same color picker result as you have.

I also reached out on the get issues for gimp and it might have been a known issue: https://gitlab.gnome.org/GNOME/gimp/-/issues/5805

M
_______________________________________________
gimp-developer-list mailing list
List address:    [hidden email]
List membership: https://mail.gnome.org/mailman/listinfo/gimp-developer-list
List archives:   https://mail.gnome.org/archives/gimp-developer-list
Reply | Threaded
Open this post in threaded view
|

Re: Color space conversions seems to change PCS as well

Elle Stone
On 10/24/20 5:43 AM, [hidden email] wrote:

> Now, you are right that there's one inconsistency, gimp color picker's xyY is not the same as to what is being pushed to the operation. I've got the same color picker result as you have.

Well, actually everything I said was right :) . Which means the
discrepancies between GIMP's xyY values for sRGB reddest red and what
you got at the command line still needs to be accounted for.

> I also reached out on the get issues for gimp and it might have been a known issue: https://gitlab.gnome.org/GNOME/gimp/-/issues/5805

Checking the referenced issue, exactly as I said, there's an assign
where there should be a convert.

To repeat, the discrepancies between GIMP's xyY values for sRGB reddest
red and what you got at the command line still needs to be accounted
for. This is a separate error from the "assign" instead of "convert" issue.

Pippin - do you have any idea what caused the discrepancies in the
reported xyY values for sRGB reddest red? Is it a problem in babl or GEGL?

>> So if changing the rendering intent does make even a small difference
>
> I tested that again and there's no difference at all between perceptual and relative colorimetric.

That's good!

> But I tried converting with saturation and absolute colorimetric and gimp stdouts that those conversions seem to be not implemented.

babl hasn't implemented code for working with LUT profiles. Also matrix
profiles don't have saturation intent tables, just as they don't have
perceptual intent tables. And V4 profile processing always uses relative
colorimetric for conversions between RGB matrix profiles regardless of
any specified intent. Which is why any differences in results (other
than "not supported" messages) from specifying different intents would
have indicated a problem "somewhere".

Elle
_______________________________________________
gimp-developer-list mailing list
List address:    [hidden email]
List membership: https://mail.gnome.org/mailman/listinfo/gimp-developer-list
List archives:   https://mail.gnome.org/archives/gimp-developer-list