As promised, I will summarize here my findings after experimenting a bit with the color profiles in OSX.
First of all, here is some explanation of the logic being used by Cairo under OSX.
When painting pixels on the screen, Cairo uses the Quartz 2D backend. Internally, the pixel data is associated to a CGImage structure, and is transferred on screen by drawing the image into a CGContext associated with the application window.
The Quartz 2D graphics library is intrinsically color managed. The destination graphics context is associated with the display profile, and the input CGImage must also define the profile needed to interpret the pixel data. The library takes care automatically of the colorspace conversions when the image is drawn into the graphics context.
From the point of view of a photo editing application that wants to keep control of the colorspace conversions, this is of course not convenient, particularly because the Apple API does not provide any way to disable Quartz internal color management (probably they consider the software developers not smart enough to take care of color management ). The only way I could find to “bypass” the color management is to assign the current display to the CGImage structure, so that Quartz applies an identity transform (it seems that in this case Quartz does not apply any transform).
As far as I understand, the “identity transform trick” was the original goal of the Cairo developers as well, but was accomplished in a way that is not working anymore in recent OSX versions. For this, they associate to the CGImage a colorspace obtained with the CGColorSpaceCreateDeviceRGB() function. However, from my experimentation as well as from some Qt bug report it looks like DeviceRGB is treated internally as sRGB by Quartz, hence resulting is an unwanted color transform.
The best working solution I could find is to replace CGColorSpaceCreateDeviceRGB() by the following function in CairoQuartzCreateCGImage():
static CGColorSpaceRef CGColorSpaceCreateDisplayRGB()
{
CGColorSpaceRef result = NULL;
result = CGDisplayCopyColorSpace(CGMainDisplayID());
if (!result) {
result = CGColorSpaceCreateDeviceRGB();
}
return result;
}
The retrieved monitor profile corresponds to the “main display”. Hence, this works correctly in a single-display setup as well as if the application window is on the main display in a multi-display configuration.
In order to support displays other that the main one, one would need a mechanism for passing the display ID to the underlying Cairo library. Unfortunately, the Quartz API does not provide any interface for retrieving the color profile associated to the destination CGContext…
I am currently preparing a PhotoFlow package with this patch included, so that eventually other OSX users with wide-gamut displays can give it a try and see if they get the expected result.