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

Jonathan Morton jonathan.morton at movial.com
Sat Feb 27 12:31:25 PST 2010

> As a minor note, my general preference would be to start by defining an API that could support CMYK *and* CMYKOG or CcMmYK, both with additional spot ink/emboss/etc channels.
> From a software engineering standpoint that would help removed the hardcoded assumption of "cmyk*" in the names and in the implementation (I'm wondering if "process plus spot" would make a better description than "cmyk plus spot". etc). It seems clear by this point that color channels will fall into either one of two groups: the process set and individual spots.

Okay, let's take a step back and look at how Cairo/Pixman works today.

We have, essentially, three nominal colour spaces available now: Alpha
(which has no colour channels), Greyscale (which has one), and ARGB
(which has three).  You'll notice that I'm treating Alpha as distinct
from a colour channel - it's more of a control channel.

Also, I'm ignoring the video-oriented formats as mere convolutions and
compressions of RGB.  AFAIK, you can't treat a YUV420 (for example)
image as a destination directly, only as a source.

With ARGB, the three colour channels are identical in behaviour and
independent from each other.  From a computing point of view, this is
a mere extension of Alpha-Greyscale format.

There's no reason, in my mind, why we couldn't treat CMY, CMYK,
CcMmYK, CMYKGO and spot-enhanced versions of these - not to mention
XYZ and other combinative-stimulus spaces - in the same way.  As long
as you stay in the same colour space, they're just multidimensional
Cartesian numbers that you can manipulate using the Porter-Duff
operations.  Even the fact that they are subtractive rather than
additive is mostly irrelevant, though it probably influences the
choice of operation you would use to achieve certain effects.  You can
even add an Alpha channel to each of those and have it perform the
same integrated control function as it does in ARGB.

The trouble only starts when you begin to mix colour spaces in the
same operation.  What happens if you do CMYK = SRC RGB?  For that
matter, what if you do CMYKGO = OVER CMYK?  Or CMYK = SRC CcMmYK?
That's where we need to put our colour management.

My suggestion is very simple, and in two parts.

1) Ban mixing of colour spaces within a single operation, with very
specific exceptions: any format can be used as a mask, so long as
component-alpha is turned off; and Alpha-only formats can always be
used as sources, with the colour channels being interpreted as zeroes
(which for RGB is black, and for CMYK is paper-white).  I believe that
is consistent with current usage.

2) Introduce an extended operation, which replaces the traditional D =
(S * M) OP D with D = (colour(S) * M) OP D.  The colour(S) operation
is a colour-management transform specified by the user, and the
operation is legal as long as the result of colour(S) would be legal
for the source operand in a normal operation.

The above causes the destination image to dictate the colourspace for
a series of operations involving it, which I think is the normal and
sensible case.

Precisely how the transform is specified, and whether it is attached
to the source image, the destination image, or specified explicitly
for the operation, I leave up to others to decide.  If it's attached
to an image or to global state, then the same entry points can be used
for the extended operation, which will probably keep the API simpler.

Naturally, printers will probably want to do some post-processing on
the final image to make it more suitable for the printer - they might
even convert it from CMYK to one of the extended formats, or vice
versa, to produce a better result.  Or they might perform a
normalisation on the channels (eg. x=min(C,M,Y); CMY -= x; K += x;) to
reduce the overprinting level.  But that's hardware-specific
post-processing, and not something that a generic application-level
library like Cairo needs to concern itself with.  If we take that off
the table, I think the discussion gets simplified drastically.  Which
is my point.  Just try not to get too bogged down in pedantry.

As far as implementation is concerned, we really just need to extend
Pixman to deal with arbitrary numbers of colour channels (from zero up
to, say, eight), plus an optional alpha channel.  This gets a lot less
cumbersome if we manage to fix a channel order (eg. RGB versus BGR is
already a Problem).  As long as the channels match up, Pixman doesn't
need to know what each one means.

 - Jonathan Morton

More information about the cairo mailing list