Bug 343531

Summary: Krita can't select colours outside of sRGB because of dodgy colour selector design.
Product: [Applications] krita Reporter: wolthera <griffinvalley>
Component: Color SelectorsAssignee: Krita Bugs <krita-bugs-null>
Status: CONFIRMED ---    
Severity: normal CC: dodeqaa, halla, hhielscher, null, troy.sobotka
Priority: NOR    
Version: unspecified   
Target Milestone: ---   
Platform: Other   
OS: Linux   
Latest Commit: Version Fixed In:
Sentry Crash Report:
Attachments: An example of Marcie and painting, and how the wheels are not managed.

Description wolthera 2015-01-29 16:50:52 UTC
From the mailinglist:
The main issue is that Krita can not select colours outside of sRGB.

Whenever you have a large image or 'working' profile, such as Adobe
Compatible, on an image, Krita can not actually select it's extremes.

If you look at the specific colour selector, you can observe that Krita
understands colours outside the screen profile, especially in XYZ. However,
any attempt at selecting these results in a colour inside sRGB being
selected.

I suspect this happens due to the recursive nature of all selectors:
If Selector picks a colour, resource manager colour is updated.
If Resource manager colour is updated, update the selector colour.
This can result in a few colour conversions too many being made, if not
imprecision in the colour. My first patch even consisted of disallowing the
advanced colour selector to update itself if it were the one updating the
main colour.
However, all colour selectors participate in this(except artistic because
that one can't update itself), even if they are not active as dockers.

Second issue is that in managing HDR, there's some puzzling to get to
colour converted to the right QColors for display. This is related to the
following.

If a colour selector however only can select QColors, like, I suspect, all
HSX based colours selectors: advanced, simple and sliders, it of course
means that they force sRGB colours to be selected in the recursive update
scheme.
This is because all of those selectors are designed with the assumption
that the end user wants to select the colour displayed under the cursor,
rather than the colour that is represented by the position on the selector
under the cursor.
The selectors need to be rewritten to deal with new needs, and we need to
make sure the order of conversions is correct with QColor coming last for
display.

Idea for plan to fix:
1. Disable all selectors. Having all selectors available affects the
selectors you're working on.
2. Start with the specific colour selector and get it to work, as this is
the only selector that shows out of screen space colours.
3. Figure out how to get the (sRGB) simple colour selector to work in this
situation, and what to do if it encounters the resource manager to have an
out of sRGB space colour. Prevent it from telling the resource manager 'oh,
hey, that colour doesn't exist in my space, let me give you a proper
colour!', ruining our out of sRGB space colour.
4. Get the advanced colour selector to work with this.
4b. Wonder whether we would like to have the advanced colour selector to
show the full working space, or only sRGB. The former requires more rewrite
and hard thinking, but would be pretty cool considering advanced's ability
to have it's own colour space.
5. Find a solution to working spaces that are smaller than the screen
space(unlikely to happen, but let's be system complete)
6. Let me completely refactor the color sliders, because it's system is
terriblah.

Anyway, the reasons we would like this fixed include such wonderful ideas
such as:
1. Thanks to this bug it's completely pointless to even allow image/working
colour spaces larger than the screen space.
2. Having this bug fixed would allow for neat colour number crunching stuff
to happen in Krita.
3. The reason it took this long to find this is because most of our users
don't understand colour management, and this is not encouraging.

Other big issues that are related:
1. Both lab and cmyk don't have a 16 bit float and their 32 bit float is
borked. Just select any colour, and you'll see the values, which in float
should not go above 1.0, are wrong.
2. sRGB built-in is generated on the spot by lcms, and has been proven to
be generated incorrect on certain devices(if not all). We need to get it to
generate proper or have a new default.

I am not sure when we should look into this. The question is whether or not
this problem is new to 2.9(because of the color display converter, AKA HDR
colour pickers), and whether we can leave it to 3.0 or 3.1.

Reproducible: Always
Comment 1 TJS 2015-01-29 21:18:36 UTC
Color pickers are tricky business. Having spent some time thinking on this and chatting with other informed folks, there is likely a decent path forward out of the convoluted current approach. It should be noted that while theoretically OCIO and ICC color management can interoperate, practically it is much more challenging as there are no specific chromaticity details with regards to OCIO.

A first step would be to assert that any handling of the color pickers is based on whatever colormanagement system is selected, and to keep the transform paths firewalled from each other.

Each picker should likely be assigned a GUI buffer for the representation. When the input system makes a selection, it is this buffer that should be used to select the reference space values from. When displayed to the output contexts, the proper transforms should be applied to this buffer and correctly converted via the appropriate ICC display profile or OCIO transformation.

HSV / HSL wheels. In an ideal world. the Hue component would be divided equally between primaries such that the selection area is equally distributed. This is not possible via OCIO however, as the chromaticities are not explicit. Keeping the wheel as simple as viable would be to keep any such wheel completely colorspace agnostic, and divide up based on standard degress. I believe this is the current implementation. With regards to Value, max(RGB) can not only work well, it could also, via an input area, be used to select scene referred values for HDR matte painting. A display referred zero to maximum Value slider could have the perceptual transform applied to it if a color_picker role is used, which is typically a 1D LUT[1].

Once a GUI buffer system is implemented, transforming the GUI elements is no more complicated than transforming any image, and probably affords the most direct approach to displaying color wheels correctly.

[1] See Mr. Selan's comment on pickers https://groups.google.com/d/msg/ocio-dev/ShTHxUibzLg/pa7DMP9nHu4J
Comment 2 TJS 2015-01-29 22:14:25 UTC
Created attachment 90799 [details]
An example of Marcie and painting, and how the wheels are not managed.

Example of some issues with the default color picker beyond simple setting of values. The color picker is not color managed.
Comment 3 TJS 2015-01-29 22:16:40 UTC
If you look at the example JPEG attachment, you can see how marcie-whacked.exr [1], when set to the RotatedTesting reference space and the correct sRGB view transform is chosen, that the wheels fail.

The color wheel's hue values should be correctly rotated if the GUI element were rotated as per the viewing output transform. Such is not the case however, and the full red swatch (sampled in the example) ends up referencing entirely odd values in the picker.

Many nightmares follow.

[1] https://github.com/sobotka/psyfiTestingConfig
Comment 4 Dmitry Kazakov 2015-01-30 15:12:38 UTC
Git commit 33bd4a5ed902c30e937483575b2348625737bb07 by Dmitry Kazakov.
Committed on 30/01/2015 at 15:03.
Pushed by dkazakov into branch 'calligra/2.9'.

Fixed two bugs when working with color selectors in HDR mode

1) QVariants are evil. One should use KisNodeWSP with
   KisCanvasResourceProvider::CurrentKritaNode signal, not usual
   shared pointers.

2) Ring color selector should update itself on every setDirty() call,
   not only when the color space changes.

M  +1    -1    krita/plugins/extensions/dockers/advancedcolorselector/kis_color_selector_ring.cpp
M  +3    -3    krita/ui/canvas/kis_canvas2.cpp
M  +16   -16   krita/ui/canvas/kis_display_color_converter.cpp
M  +2    -2    krita/ui/canvas/kis_display_color_converter.h
M  +2    -1    libs/pigment/KoColor.cpp

http://commits.kde.org/calligra/33bd4a5ed902c30e937483575b2348625737bb07
Comment 5 Dmitry Kazakov 2015-01-30 15:16:03 UTC
The patch above fixes color picker and color selectors only. The original bug by Wolthera is still actual.
Comment 6 Dmitry Kazakov 2015-01-30 17:13:21 UTC
Git commit 336df15cb2ddabdf0d792a7da2dc2528930086d2 by Dmitry Kazakov.
Committed on 30/01/2015 at 17:12.
Pushed by dkazakov into branch 'calligra/2.9'.

Fix cyclic updates of currently selected color

KisPopupPalette should not emit corrected color values when
its value is updated via external signal, not the user. Othewise
it results in cyclic updates of the globally selected color which
make it almost impossible to work with.

It need to be checked whether the reported bug is still actual.

M  +29   -18   krita/ui/kis_popup_palette.cpp
M  +6    -4    krita/ui/kis_popup_palette.h

http://commits.kde.org/calligra/336df15cb2ddabdf0d792a7da2dc2528930086d2
Comment 7 wolthera 2015-01-30 18:42:30 UTC
Okay, I can succesfully...

* Select a wide gamut colour from the specific colour selector
* Have a canvas with wide gamut icc(like identity RGB), have my CM set to 'relative colorimetric', and then make two identical looking magentas, but when picked with the colour picker, one magenta has far higher values.

Marcie is now also working.

So, the main issues of this bug have been addressed. That leaves the discussed 'hsv from srgb could use straight RGB primaries instead', but I do not know if you would like a seperate bugreport for that, dmitry, or to keep this one open. either case, I'll leave this bug open, and you may close it later.
Comment 8 Dmitry Kazakov 2015-02-01 06:22:22 UTC
Hi, Wolthera!

We can keep the tasks in this bug. Anyway it seems the number of tasks left is higher than "1" :)

Could you just formulate the points that are left to fix? And, if possible, the way to reproduce/test the problem.

As far as I understand there are three points now (though I don't understand them fully):

1) CMYK + f32.
2) Something wrong with sRGB.
3)  'hsv from srgb could use straight RGB primaries instead'
Comment 9 wolthera 2015-02-01 11:48:20 UTC
dmitry, 

1) is mentioned here: https://bugs.kde.org/show_bug.cgi?id=310357

2) Tied to this one but... https://bugs.kde.org/show_bug.cgi?id=310359 I think you should ask boud and troy_s for the details, they're the ones who figured it out in the IRC a few months back.

I only mentioned them because I thought they might be related.

3) Is that the HSV/HSL/HSI/HSY' colour always use sRGB(due to using qcolor). troy_s was talking to you about this in the IRC, saying that you could be using the given primaries of a config or icc. We hadn't figured out what to do in case of cmyk, greyscale, ycrcb and lab yet. maybe this needs a separate repport?
Comment 10 TJS 2015-02-01 12:09:46 UTC
Regarding (3), it sounded like the HSV wheel was doing a conversion to some colorspace.

In OCIO, it is impossible to glean the primaries, so any such conversion would be flawed from the beginning.

The issue is that any attempt to convert to a colorspace for HSV generation would ultimately result in some values being unreachable unless the formula used a gamut that covered all possible XYZ values in the spectral locus.

A likely more manageable path is to simply divide up the RGB values and display them. In this way, the selection is _always_ in the reference space, and will always cover the reference space's full gamut.

Also, due to primaries often being unavailable via OCIO, spaces such as Lab etc. are moot.

CMYK, another ridiculous space, would have the same meaningless values. I would suspect Krita's handling of CMYK has always been meaningless, despite what many would willfully want to believe, but that is likely another story[1].

[1] CMYK is as meaningless as RGB as we agree, simply because it is a term that refers to the model, not the space. Hence, it is as ridiculous as rotating the hue wheel and pretending it has magically gained more meaning.
Comment 11 wolthera 2015-02-01 12:23:56 UTC
Not quite: Krita always thinks of colour inside a colourspace(thats why there's that profile widget everywhere). So, even Krita's cmyk vales are tied to a cmyk icc profile. That in most cases, the user should not blindly charge in and use whatever profile there is, is an educational issue, not a technical one.

So kocolor has a little bit more meaning than just random numbers.

That's also why we need a colour space for the hsv wheel, because we literally cannot create a color object without a colour space. Right now, by using qcolor to input rgb values, by default that colour space is sRGB.
Comment 12 TJS 2015-02-01 12:28:23 UTC
Ah the wonders of software trying to be clever...

In all instances, OCIO will never inform the softeare of the primaries of the underlying reference space, so _all_ widgets that require that will be broken.

Again, a much more manageable approach is to simply have widgets that always display the reference space values (IE display referred 0.0 to 1.0) and merely transform via the output transform to screen.
Comment 13 Unknown 2016-08-21 00:30:49 UTC
This bug confused me for a while.

I place a vote on this issue. Right now, I don't need to pick colors outside sRGB color gamut. But, the first rec.2020-capable monitors are entering the market in 2016. In about 5 years, it may become really important to pick a color in rec.2020 color space or any wide-gamut color space.

Is there any plan to make it an option to vote on this issue in a new kickstarter campaign?
Comment 14 Halla Rempt 2018-11-30 09:29:15 UTC
Since we're working on HDR support now this gets more relevant: https://phabricator.kde.org/T9256
Comment 15 wolthera 2019-04-08 15:08:08 UTC
*** Bug 403836 has been marked as a duplicate of this bug. ***