[cairo] Spot colors (and CMYK)

Russell Shaw rjshaw at netspace.net.au
Wed Feb 17 17:44:12 PST 2010

Andrew Cowie wrote:
> On Wed, 2010-02-17 at 12:46 -0700, Chris Murphy wrote:


> Cairo is a beautiful drawing library, and you can feel the tension that
> this discussion creates in the minds of people (ie, it's authors :)) who
> consider it a vector graphics API. But if we want to use it to draw to
> anything that people can use for "professional" (I hate that term
> because it's so pejorative, but what else do you want to call it?)
> quality print output [ie anything other than black & white to a laserjet
> printer] or broadcast quality visual effects [ie anything above home
> video on youtube], we'll need to find a way to address the colour space
> question.
> It would be perfectly reasonable if someone were to say "that's not what
> Cairo is for", though if that was the decision, I'm not sure where else
> we'd go.

I don't use cairo, but design and implement various libraries. I'll make
suggestions of how i'd handle colour management.

sRGB means the image pixels represent a "square-rootish" value of the
light intensity entering the camera. The monitor CRT light output
intensity vs electron gun drive (pixel data driving it) is "parabolicish".

Therefore, the CRT output vs camera input is linear, as long as their
respective nonlinear transfer functions are complements of each other,
such as defined by ITU-R BT.709-5.


When operating on colours in cairo, the pixels should be converted
to represent linear light intensity, sRGB->linear_RGB, or just "RGB".


An sRGB of (255, 255, 255) when converted to RGB, represents the
CRT colour with the three guns driven at maximum output.

Consider sRGB = red: (255, 0, 0)

Because of CRT and camera imperfections, some blue and green pixels
may be slightly lit. Also, ambient light reflecting off the monitor
screen adds some blue and green. The "red" phosphor may have a spectral
output that has some blue and green overlap in it too. We'll call these
imperfections "colour leakage".

This means the total red is not of full saturation, and thus means
the CRT cannot cover the full gamut of ideal tristimulous. It is
limited to the gamut defined by ITU-R BT.709-5.

To store a deeper red in this same data format, we need to store
negative green and blue RGB (linear) pixel values. A linear CRT
device would cancel its colour leakage when these negative values
are output, resulting in pure red. Note that components of the colour
leakge depend on the ambient lighting.

Storing negative values in sRGB is clearly a nonsense hack (square roots
and all that).

For the common situation of displaying images on a ITU-R BT.709-5 monitor
that come from a ITU-R BT.709-5 camera, no ICC profile is needed, as long
as users are happy to assume ITU-R BT.709-5 ambient light conditions.

To process images from a source covering the full gamut, the linear RGB
pixel values may be less than 2x as that from a ITU-R BT.709-5 source.
See the upper-right CIE 1931 xy chromaticity diagram:


Also, to avoid loss of resolution, sRGB in 8 bits/pixel should become
16 bits/pixel when converting to linear RGB (an x^1/2.4 type operation).

The following is my opinion.

Taking the above into account, when taking the image from an sRGB
ITU-R BT.709-5 source (the common situation), an sRGB uint8_t (255, 255, 255)
pixel should be converted to linear RGB int16_t (0x3fff, 0x3fff, 0x3fff).
Taking the data from a full gamut source should fit within 0x7fff RGB vales.
There could be an option to use 32-bit RGB if needed.

Cairo can operate on this linear data, then convert it back to sRGB
for monitor display. No ICC profile needed. For full gamut data, the
linear RGB should be first clamped to 0-0x3fff before converting to
sRGB. The formula cairo can use for RGB/sRGB conversion is that in:

When outputting to a printer backend, the backend ICC profile can
convert from cairo-linear RGB to drive the print-head control

If the image source was non-ITU-R BT.709-5, an application-specific
external library can convert it to linear int16_t cairo-linear RGB,
and the image processed as usual then output to a printer.

The linear RGB data in cairo should represent absolute colour as
perceived by the eye, after all ambient conditions are accounted
for. Therefore, there is no need for interation between input and
output device ICC profiles (correct?)

CRT and LCD behaviour is assumed equivalent and conforming to
ITU-R BT.709-5.

For proofing where the monitor should be well calibrated, cairo
could call an externally supplied ICC profile for the monitor.
Colours in the image that are clamped could be indicated on the
monitor by some kind of optional shading to hilight the problem

Some printers may print a spot colour such as "shiny metallic silver".
Obviously cairo cannot do any mathematically sensible merging of
this colour with general synthesizeable RGB colours.


Spot colours could be represented in cairo by setting the 16th bit of
the alpha of an int16_t colour. This means the normal alpha channel is
15 bits. With this, cairo won't mathematically alter these pixel values
except to vary their intensity, or replace them with a completely different
colour if needed (or an application-supplied callback could be called).

When output to a printer, an application-specific callback can be
supplied with any spot-colour pixels. The callback uses the remaining
15-bit alpha for intensity. The RGB values can be used as a "number"
and fed into a printer-specific lookup table that returns the data
required that tells the printer to output that specific spot colour.

Russell Shaw, B.Eng, M.Eng(Research)

More information about the cairo mailing list