[cairo] Road map for remaining pixman refactoring
spitzak at thefoundry.co.uk
Tue Jun 9 03:36:46 PDT 2009
I have done a great deal of work with linear light level images. I am
using the term "linear" for what is being called "luminance" and means
that the numbers are proportional to the energy of the photons being
emitted. "non-linear" means sRGB and so on and what is called
"perceptual luminance" below.
Linear data is very useful for special effects and image generation,
because it is concerned with simulating real-world effects that involve
distributing the energy of light around.
However it may not be so useful for the final output of 2D data. As
pointed out it is not "perceptually" linear. An actual linear ramp looks
very bright, with only a small black part on the low end, so certainly
gradients and so on should be perceptually linear.
Soeren Sandmann wrote:
> Yes, I meant brightness ("perceptual luminance").
> I don't think treating alpha as coverage always is really
> correct. Ignoring all gamma issues, suppose someone selects a 50%
> translucent white in cairo, then composites that on top of a black
> background. The resulting pixels will be 50% gray, but more
> importantly *look* 50% gray because of sRGB's being roughly
> perceptually uniform. Which is exactly what the user would expect.
> It is difficult to argue that this outcome is somehow wrong.
Also it is *EXREMELY* important that the user get "the same brightness
as this other program displays". This is what users want, and something
that perveyors of color management seem to completly miss. Users want
the same color, no matter how "wrong" it is. Cairo should understand
this and not go crazy with any kind of complexity in handling color.
Believe me, if a file being drawn on the screen has 123 in a pixel, and
the resulting display buffer has any other number than 123 in that
pixel, then Cairo is WRONG. No amount of explaining of color theory or
anything else will change the fact that Cairo did the wrong thing.
The fact that the right thing is also the trivial way to implement it
seems to confuse people to no end. They are convinced that if it is not
complicated enough then it must be incorrect. This is a big problem with
modern software system design.
This is why I have asked several times for Cairo to support a "set the
color to this 8-bit value". People want the same color as a part of
their image. They do not want to reverse-engineer (and thus fix
permanently) whatever Cairo's rules for converting floating point are.
> There are several other cases where alpha really should be treated as
> a brightness modulation: gradients, fading, probably image overlays
> come to mind. Generally, when the alpha value is explicitly given by
> the user, brightness modulation is probably what he had in mind.
Yes this is absolutely true. One explanation is that perceptually linear
also resembles the result of printing with ink or opaque paints much
better, so it does match a physical result that uses of Cairo are
probably just as interested in simulating as lighting.
> On the other hand, when the alpha value comes from antialiased polygon
> rasterization, an intensity modulation is clearly desired.
Actually this is not true. It does improve antialiased polygons but then
polygons draw the same way but in different colors appear not to match.
A black polygon drawn on a white background will look much smaller than
a white one drawn on a black background. This is a quite annoying effect
for 2D graphics, especially fonts. It appears your eyes interpret the
blurry pixels perceptually, not linear, as higher resolution makes the
problem go away (but higher resolution also removes the need for
One place where linear levels *are* better is when doing large filters,
such as blurs. It may also be useful where Cairo is really trying to
simulate a lighting effect such as an actual color or light being shown
on the surface.
However sRGB levels can be simulated accurately enough for this purpose
by squaring the sRGB values. I would not worry about any higher accuracy
than this as it is swamped by inaccuracy in the displays and in the
producers of an image. The square works nice because the math can often
be simplified to something reasonably fast. You could use pow(x,2.2) for
a higher accuracy.
As an example a box filter of an image. Instead of doing sum(x)/n (where
x is the pixels and n is how many in the box), do sqrt(sum(x^2)/n) to
simulate conversion to linear, doing the sum in linear, and conversion back.
If the image was premultiplied then it probably was premultiplied in
sRGB space, so to convert to a premultiplied linear level you must
unpremultiply, convert, then multiply back: (x/a)^2*a which is x^2/a. To
convert back to sRGB use a*sqrt(x). Use the a unchanged. Therefore the
box filter turns into sum(a)/n*sqrt(sum(x^2/a)/n)
> Ideally, images would have both a coverage and a translucency channel.
It is not possible to combine a linear light level with non-linear
colors. The relative levels of the RGB have to be taken into account. An
rgb of (.2,.4,.6) is not the same hue as (.1,.2,.3).
If you really want to represent linear light levels you should only have
3 numbers to represent the color (unless the final display has more than
3 dimensions of color). You can use linear RGB levels, or you could go
all-out and use XYZ. There probably are not any other useful linear
Bill Spitzak, Senior Software Engineer
The Foundry, 1 Wardour Street, London, W1D 6PA, UK
Tel: +44 (0)20 7434 0449 * Fax: +44 (0)20 7434 1550 * Web:
The Foundry Visionmongers Ltd * Registered in England and Wales No: 4642027
More information about the cairo