[cairo] Road map for remaining pixman refactoring

Bill Spitzak 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 
accurate anti-aliasing).

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 
color spaces.

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 mailing list