[cairo] [RFC] Color space API (partial proposal)

Kai-Uwe Behrmann ku.b at gmx.de
Sun Feb 28 02:51:09 PST 2010

Am 23.02.10, 12:12 -0800 schrieb Bill Spitzak:
> Kai-Uwe Behrmann wrote:
>> on the colour space sizes some arrangement has to be defined for out of 
>> gamut colours through the rendering intents. For this there are more 
>> options possible than four rendering intents.
> Okay it does sound like there are more options. I don't think we should add 
> more apis for these and that the proposed "rendering intent" api should be 
> removed.

Completely agree.

> One think I remember from one of the cms libraries I used (Truecolor?) is 
> that they just stuck "rendering intent" into the color space structure. When 
> converting from A to B it used the value from B and ignore the one in A. This 
> puts all the variables for color correction into a single 
> "cairo_color_space_t" structure.

I would not put the options into the static ICC structure. This is not 
very useful for caching and referencing of ICC profiles.

Some care has to be taken for which side of the conversion, blending wise, 
the options apply. Multiple inputs into blending space should have own 
options. Multiple outputs should have as well individual options. So while 
in your above model the cairo_color_space_t could have a default, some 
means to override it on a individual basis would be fine, eigther by 
switching the colour conversion options of the colour space, perhaps on a 
cache on write basis.

>> If a surface is used to blend into an existing document the image colour 
>> space is the input colour space to be converted to the documents blending 
>> colour space. For gradients I found the term interpolating colour space 
>> very nice.
>> Imaging the blending colour space as the central space to convert into on 
>> input and convert from on output seems the most plausible to me.
> This sounds exactly like I though it would work. However it does disagree 
> with quite a few statements in these letters. I will try to call this 
> "blending space" from now on.

Great, common terms are very useful.

>>> 5. The "destination" space of a pixel buffer surface or a gradient also 
>>> becomes the "source" space when that is used to render onto another 
>>> surface. (ie despite the fact that it would be trivial to implement, 
>>> making these spaces different is purposely discouraged by the api).
>> Yes. "discouraged" meaning not impossible but some more work.
> I very much recommend that changing the color space of a surface, if allowed 
> at all, should leave the numbers in the channel buffers unchanged (though it 
> can add zero-filled channels or truncate them if the new color space has a 
> different number of channels). I have certainly proven to myself from working 
> on Nuke that this sort of operation is a requirement. Conversions between 
> spaces can still be done by Cairo by copying from one surface to another.

This is a heavy weigth image manipulation. Imagine a Cmyk image 
immediately interpreted as RgbA without colour conversion. There are many 
more such effects. This ends easily in nearly garbage. So eigther such 
options is second class in the current disscussion or allow a qualified 
conversion. The later means the colour appearance remains the same and the 
numbers change.
But I think to could live with a blending space change over a 
create_similiar_surface alike call.

>>> 6. A correct Cairo backend can be implemented that will IMMEDIATELY (ie 
>>> before the call to set the color or image returns) convert the color or 
>>> image to destination space and throw away irretrievably the "source" 
>>> space.
>> Yes, e.g. the Xlib backend.
> I certainly agree that this is how it MUST be done, but I have to point out 
> that this directly conflicts with most/all of the claims of color management 
> making it possible to replicate a given printer's output. Even if you assume

A 4channels -> 3channels conversion means data loss.
However Xlib has no need to print to PDF. Or did Xorg lately switch to 
displayPDF? I must have missed that.

> mixing the numbers in the printer's space is the same as printing those 
> quantities of ink (which is demonstratively false), it is certainly not true 
> in a different color space such as the display device.

Oh perhaps I did not get your question correct. If so when cairo preserves 
the surface without clearing to copy int Xlib buffers, then a intermediate 
buffer is needed to convert the Xlib surface to, including necessary 
colour conversion and then copy into the frame buffer.

In case cairo regularily clears the Xlib buffer, the Xlib buffer could be 
inreversibly converted to monitor colour space and copied into the frame 
buffer. A new drawing run would then use the original blending colour 
space of the Xlib surface. But I am not shure if my cairo assumtion hold 

Sorry if I was misleading here.

>> For monitors the control is typical provided by the operating system or its 
>> conventions.
> Yes this is what I meant by "fixed". The device space MUST be the form that 
> the buffer is communicated to the system. This may be raw hardware (ie


> blending is in device space) or it may pass through a further color 
> correction step, in which case blending space is the input space to this 
> further correction. The only way changing the blending space could change the

This is clearly a option.

> display is if this further step also took the blending space color space as 
> input.

Oh my enlish is too limited to understand this later sentence.

>> The print colour space is often set in the app by the
>> user or to be detected by the local print system.
> In this case it sounds like the application is expected to discover the 
> printer's space and send that to Cairo as the blending space. I am guessing 
> (or I HOPE!) that this is the default result if no attempt is made by the 
> application to set the blending space.

Well, if a app wants a device specific output, then it needs to specify 
the accoring device colour space by specifying the ICC profile. Cairo does 
not connect directly to print systems.

>> The output space is for many backends the same as the blending space on 
>> that surface. PNG should not alter and just embedd as should PDF.
>> Xlib should implicitely convert from whatever blending space to the device 
>> space.
> This sounds trememdously inefficient and forces programs to discover the 
> device space and set it as the blending space and forces backends to reliably 
> detect the identity.
> I would greatly prefer a "it acts like the blending space is the device space 
> unless there is hardware or operating system support to make the further 
> conversion from an arbitrary color space efficient".

This conflicts with the one input => multiple output paradigm. I see only 
the solution to assume a typical blending colour spaces.

What would a programmer do in case of a multi monitor situation? Figure 
out each device + profile + geometry, setup surfaces for each monitor and 
then draw into that? I guess thats too much labour. The app want to draw 
in sRGB as I repeatedly have read. The system has to take care that the 
colour appearance on screen is then finaly that specified sRGB. That a OS 

The very common case that the backend cant use hardware accelerated colour 
conversions should make a exception. My feeling about switching this off 
and on is it should be implicitely and automatically decided by each 
individual backend most notable the Xlib, Quartz and GDI backends. Quartz 
on osX SL will do the conversion because there are always shaders 
available. Xlib will have to talk to the active window manager or perhaps 
we see one day Xorg taking this part over. Non Rgb primaries had always to 
be converted even through a non accelerated fallback.

I may add, this is not trivial and vendors with optimal OS/hardware 
integration have a big advantage. However I think it is doable even in a 
pluralistic hardware landscape like Linux targets to support.

kind regards
Kai-Uwe Behrmann
developing for colour management 
www.behrmann.name + www.oyranos.org

More information about the cairo mailing list