[Development] QT5 and color management

Morten Sorvig Morten.Sorvig at qt.io
Tue Aug 30 11:16:26 CEST 2016


> On 29 Aug 2016, at 15:58, Anders Torger <torger at ludd.ltu.se> wrote:
> 
> 
> Thanks. Looking at QTBUG-47660, if I understand it correctly it says 
> that since QT 5.5 a QImage will output "native" pixels to the display. 
> That is if I send 255,0,0 the display it will show the reddest red 
> it can output. If that is correct, it will work for us, as we then can 
> do "the usual way", that is find and load the display ICC profile using 
> a native method, and use LittleCMS to convert from our internal format 
> to the display's color space. That would be great, as it would work the 
> same in Linux, Windows and OS X then.


Unfortuantely I think that Qt currently uses the color space for the
main screen only, so you may find it lacking for multi-monitor setups.


> 
> In the longer term I'm sure the typical application developer would 
> love the mode when color space is locked to sRGB (or better if you can 
> pick among a number of presets) and then QT makes sure proper 
> conversion to the display takes place under the surface. That is the 
> typical application developer never needs to care about color 
> management, "it just works”.

One remaining issue (after the platform plumbing has been done) may be
that QPainter and the raster paint engine assumes a linear color space
when blending. As I understand it OpenGL solves this by converting
sRGB framebuffer values to linear color for the blending step.

> 
> However the typical application developer probably doesn't care at all 
> if colors vary a bit as few applications require accurate colors.
> 
> If color management is required it's a special case, and I think 
> application developers can then accept the extra complexity by having 
> to use LittleCMS or similar to do the conversion on their own. The most 
> important thing is that you actually *can* do it in some way or 
> another. As said with GTK it was not possible on OSX due to output 
> colorspace being locked to sRGB rather than native display like on the 
> other platforms.
> 
> When writing cross-platform applications I see an advantage in 
> "dumbing down" color management so it becomes equal between Linux/
> Windows/OSX. In Linux and Windows we've used to having to do it 
> manually in the application as the colors we send to the toolkit will 
> be displayed with native display values. OSX has more advanced/
> automatic color management, but if QT makes use of that it would mean 
> that either it would work differently in Linux/Windows or one would 
> have to make QT's color management a lot more advanced on those 
> platforms to make it as automatic as on OSX.

Agreed.

> The largest drawback with the application-doing-it-on-its-own approach 
> is that multi-head configurations can't really be made to work. The 
> classic example if you have half of your application window on one 
> screen and the other half on another, which have different ICC 
> profiles. App-controlled color management usually means that you 
> convert for the primary display, and only that. If QT itself would 
> handle color management on a lower level I assume multi-head could work 
> too. However I find this problem to be a minor one, as when you do work 
> with a color managed application, it's about graphics, photos etc, and 
> then you generally have one expensive calibrated monitor which is your 
> primary display where you place the GUI.

OS X works around this issue by having windows display on one screen only.
I think we want to assume “one active color space per window” for now and
don’t get into multi-colorspace rendering.


I've drafted out a possible API below. Note that I’ve considered the raster
pipeline (QPainter/QBackingStore) only. I don’t know if/how this applies to
OpenGL.

Morten


/*!
   Sets the global application color space to \a colorSpace. 

   The application can then produce color in the set color space;
   Qt will propagate the setting to the native views.

   Note that the raster paint engine (QPainter) requires a linear
   color space and may produce inaccurate colors if a gamma-corrected
   color space (like sRGB) is used.

   The default color space is CGColorSpaceCreateWithName(kCGColorSpaceSRGB).

   Creating the color space from an ICC profile is possible:

       QByteArray profile = ...;
       CFDataRef profileData = profile.toCFData();
       GColorSpaceRef colorSpace = CGColorSpaceCreateWithICCProfile(profileData);
       CFRelease(profileData);
*/
id qt_mac_setApplicationColorSpace(GColorSpaceRef colorSpace);


/*!
    Returns the current application colorspace, or a null ref
    if per-screen color spaces are enabled. 
*/
GColorSpaceRef qt_mac_getApplicationColorSpace();

/*!
    Enables use of the native screen color space.

    Applications must produce color in the screen color space to
    get correct colors.

    Use qt_mac_getScreenColorSpace() to get the color space for
    for the current screen.
*/
void qt_mac_setPerScreenColorSpaces(bool enable);

/*! 

*/
bool qt_mac_isPerScreenColorSpacesEnabled();

/*!
    Returns the current color space for \a screen

    Call this function on the screen change event, and then redraw
    on the following repaint event.
*/
ColorSpaceRef qt_mac_getScreenColorSpace(QScreen *screen)



More information about the Development mailing list