[cairo] Spot colors (and CMYK)
spitzak at gmail.com
Thu Feb 18 10:53:39 PST 2010
Russell Shaw wrote:
> 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.
Actually the real problem is not color spill, but the fact that the
"ideal" color that is supposed to be emitted by the CRT is not fully
saturated. However the result is exactly as you describe: the volume of
color space covered by 0-1 indexes (the "gamut") is smaller than the
volume of visible colors.
Light reflecting off the monitor adds a constant color to the viewing.
In our work I have found a handy coincidence in the description of sRGB:
due to the linear segment, if you instead plotted the gamma curve it
would intersect the vertical axis at .00083. I don't think this was
planned, but this vertical offset is approximately the reflection of the
very finest high-contrast lcd monitors in a dark room. I have tried
removing the linear segment from our sRGB->linear sRGB conversion, this
has resulted in better composites of dark areas, which indicates that
users have adjusted their images to compensate for ambient light
(unfortunately this also picks up filter ringing inserted by software so
I did not do this permanently).
> Storing negative values in sRGB is clearly a nonsense hack (square roots
> and all that).
True, and this is the biggest problem with saying "unclamped sRGB".
Microsoft with their scRGB definition have said that the conversion of
values greater than one follow the gamma curve, and negative numbers are
encoded as -f(-x). From previous experience with Microsoft standards I
am sure they thought about this for about 10 seconds, but unless we can
find a persuasive argument for different math I think using Microsoft's
definition is now the safest.
It is also certainly true that composites are useless for these
out-of-gamut colors. Conversion to linear is needed before compositing
math. This is exactly what Nuke does. However I can warn you that there
are serious consequences that are going to hit a library used for vector
graphics like Cairo much worse than they hit Nuke. The problem is that
an awful lot of compositing relies on the "perceptually uniform" math
being done, the most obvious is the result of drawing the same-thickness
lines (or letters) in black or white on the opposite background. If the
antialiasing is done "correctly" in linear space, the user thinks the
white lines are far thinner or fainter than the black ones. But wrong
antialiasing done in sRGB looks "correct". Also users do not expect
their carefully painted partially-transparent overlay from Photoshop
will produce visible artifacts when composited.
I do not have a solution to these problems. I wish I did. Linearizing
only outside the 0-1 range kind of works but the discontinuous slope at
0 and 1 produced artifacts.
> 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:
You need to get linear sRGB values of -.5 to cover the CIE horseshoe.
Values greater than 1 are useful for high dynamic range (specifying
colors brighter than the display can do) and is very useful in itself,
the only integer-based HDR format I am familiar with (Cineon) goes up to
approximately 16. Microsoft's scRGB integer format goes up to 7.5. Most
HDR is done in floating point.
> 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).
I very strongly recommend that if you use 16 bits, you use floating
point in the ILM "half" format. This format is handled natively by
graphics cards. Integers are very poor for storing linear color information.
The linear portion of the sRGB definition with a slope of 1/12.92 does
mean that you must add 4 bits to get all n-bit values of sRGB into
different linear values. So 12 bits in theory works. If you use pure
gamma functions then you require an infinite number of bits to
accurately store the linear value in an integer as the slope is zero
> Cairo can operate on this linear data, then convert it back to sRGB
> for monitor display. No ICC profile needed.
This is pretty much the same as I was thinking, although exactly how the
compositing is done may vary. In my scheme the compositing is done in
any space convenient for the device, provided the gamma is somewhat
similar to sRGB, enough that the "photoshop composite" I listed above
works with artifacts too small for humans to see. Alternatives are to
force sRGB composites, or force linear sRGB composites as you suggest.
> 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.
This I think is the main purpose of "spot colors". Spot colors that have
an XYZ or RGB "equivalent" do not need to be part of Cairo's api. The
spot color api is to explicitly say "I want this ink deposited here". It
is by definition device-specific. I also think C,M,Y,K are "spot colors"
as far as this is concerned, apparently all CMYK data is either "use the
trivial conversion to sRGB" or "inks on this specific printer". The
first means the application can convert it, the second requires the spot
More information about the cairo