State of Color Management in Krita 2022
Open, WishlistPublic

Description

This is a short report of different color management topics in Krita, giving an overview of some projects we can work on.

HDR display and QML

We spend a significant amount of time on HDR display in Windows. We carry several patches for Qt's openglwidget to enable uploading textures tagged with an HDR color space.

  • Whether or not we can implement this on MacOS depends on how our usage of graphics acceleration looks like with regard to qt6.
  • Similar situation with Linux, as the development for HDR is restricted to the Wayland display server. We should communicate with the KWin people about color management in wayland.

That said, there's the following issues with regards to QML:

  • QtQuickWidget hasn't been adapted yet by the patch. There's a WIP patch for getting the small color selector to work in QML, but it's all a little pointless if the QtQuickWidget doesn't support it.
  • QML works by drawing everything graphics accelerated, and as far as I know, all QML that is in the same context sends everything in a single texture upload. The HDR-relevant part of this is that the UI controls that have nothing to do with HDR will also be rendered in HDR. I thought QtQuickWidgets each had their own little opengl ecosystem, but then we got this bugreport. We should proly make sure that whatever we'll use for theming will have a copy where the colors are converted to the HDR color space, so we don't blast out people's eyes.

Color Management Developments

Several color management developments are happening, and I am unsure how Krita should tackle them...

  • Marti is unsure if he wants to implement ICCMax.
  • New opponent color spaces: OKLab and ICtCp. The former is a variation on LAB and the latter is a color space that was developed to make encoding Rec2020 PQ and HLG more efficient (much like how YUV is used in Jpeg). I am unsure whether and how these would be handled in ICC. We can convert them to XYZ or a relevant RGB space, but I have seen folks talk about interpolating gradients in OKLab, which might be a puzzle to accomplish if LCMS cannot handle conversion for us...)
  • CICP values are getting more and more common. We have some rudimentary support for them thanks to the work done for avif and heif, but it seems they'll also be used inside PNG. Furthermore, we have the problem that right now the kiscolorprofile stores CICP values, but we can't guess them from the ICC profile. This was done in anticipation of this proposal, but there hasn't been much development there. We might need to store CICP values in the kra file, as possible.
    • We also support reading the CICP values for video import, but not quite for video rendering.
    • The current handling of the HDR transfer functions indicated by CICP is a bit slow.
  • Display config -- Both PQ and HLG use some display data to decide how to display themselves. We currently have all this in the export dialogs, but maybe it's best to store this in the config.
  • Spectral blending. Brien Dieterle has made a spectral blending mode for MyPaint, and an MR has been submitted to implement this in Krita. We have one big problem though: The spectral values are only available for sRGB. How can we guess values for rec2020 or any other colorspace? ICCMax encodes such values, but again, Marti finds it a little intense...

Storing Color Managed Colors

CSS color 4 & 5

Ended up being a bit of a messy spec, I'll try to implement it, but I need to discuss with Mc.

Left over resources that can't store wide gamut colors

  • Patterns -- There's not much stopping this?
    • KisFillPainter::fillRectNoCompose converts the pattern to a KisPaintDevice before drawing.
    • We load as QImage -> this is the primary reason patterns are gray/sRGB, nothing else.
  • Brush-tips
    • Much more complex because we do far more complex compositing with brush tips.
    • We still have the annoyance where using something like b) Airbrush Soft repeatedly leads to banding. It's still not clear whether this needs high bitdepth masks, or this can be solved with smart upsampling like with the color smudge brush.

QColorSpace support.

Qt 5.15 introduced shiny new features to QImage and QColor!

  • Only QImage and friends really supports QColorSpace. It seems QColor, QPainter and QPaintDevice, QPixmap don't care (QColor can however be transformed by QColorSpace).
    • What this means is that we only really need to implement extra checks inside KisPaintDevice to convert properly if a colorspace is available.
    • QImage doesn't seem to support floating point, which is a bit... annoying.
  • The floating point implementation is a bit... Confused. The documentation says that ExtendedRGB is scRGB, but then the QColor doesn't carry a colorspace...
    • We should make sure that if a QColor is ExtendedRGB, the relevant KoColor is F32, and maybe vice-versa.

Color management in Vector shapes

We currently only store and render sRGB in vector shapes.

  • I would like to start storing color managed objects inside the shapes and have those converted to an sRGB QColor/QGradient/Etc. upon rendering.
    • People will proly just want to be able to select a cmyk color, have a decent enough preview and then output that color into an svg file or (whenever we get around to it) PDF (or whatever makes Scribus happy), so sRGB preview while not touching the stored colors should be fine.
  • I've considered whether we could use other colorspaces, but the W3C is kinda vague about it.
    • The biggest annoyance is floating point values, as that relies on QPaintDevice having the possibility for floating point. (If we convert everything to PQ, you end up with the oddity that you are effectively compositing in PQ, not linear, so this would be a lie).
  • Related: banding in vector gradients.

Print Workflow

TIFF and spot colors

Thanks to amyspark, TIFF plugin now has PSD layer headers. Thing is, that is where spot color data is stored for both TIFF (Not really, it's in fact, far more annoying) and PSD. Our main problem here is UX.

  • We need to make sample files to turn into unit-tests.
  • TIFF and PSD conceive of spot-colors as 'an extra channel', Krita has no UX for 'extra channels', but does have a conception of fill-layers.
    • I think that we might need to let people set fill layers with vector masks, and when implementing a PDF exporter, indicate that those particular fill layers need to be on top, or just put them on top automatically on export (maybe not the best ux).
    • As for TIFF spot colors, I can find the lab value, I can find the extra alpha channel names, but I cannot find the custom color value. I need to figure out what exactly PS stores as the spot-color name when you tell it to make a pdf before I can say we might load spot colors from tiff. If it's just the alpha channel name, then yes, this is within reach.
  • We may need the ability to take a named-color ICC profile and load the internal namedColorList as a KoColorSet, because while a significant amount of spot-color palettes use sbz, pantone is still primarily available as named-color ICC profile.
  • Overall this seems something that needs more research.

CMYK blending modes according to the pdf spec

This is a returning issue for people with PSD/PDF workflow. Dmitry mentioned that he has an idea how we could enable this, with a toggle in the settings.

We should proly do this, because this is the main advantage we have in terms of print workflow in this particular space, and it will also simplify a PDF-producing workflow.

Things that I couldn't fit anywhere else

  • Once the wide gamut selector is merged, we can go into the color conversions file and change all the API to use float instead of half 'float' half 'qreal'. It's been an annoyance, and the only 'mandatory' where this is used is in the displaycolorconverter, in functions that aren't used by the wide gamut selector.
  • I suspect that CMYK in 32bit float actually always ranges from 0.0 to 100.0, we now use a weird probing system to suss this out.
  • Similarly, for a lot of int LAB usage, the A and B channels should be interpreted as assigned-int, going from -128 to 128, this would simplify a lot of related maths.
  • We should proly dust off our YCbCr colorspace. I have found an iccprofile, but it doesn't work atm because of a very funny assert. See MR 1300.
  • CMYK, according to both pdf/x and other workflows, should use 'Relative Colorimetric' for all conversions, similarly, RGB and other matrix shapers can only do Relative Colorimetric, so we should set this to be the default. (Perceptual is the default according to the icc-spec, and that is because if present it would be able to show all contrasts, however, most profiles are buggy in their perceptive rendering intent). This was also one of the things that David Revoy bumped into (though that was also 80% bad documentation by the print company).
  • Newest LCMS supports premultiplied alpha. Where can we take advantage of this?
woltherav triaged this task as Wishlist priority.
woltherav updated the task description. (Show Details)Jan 18 2022, 3:35 PM