[cairo] Color cube stuff for pseudo-color support

Keith Packard keithp at keithp.com
Fri Feb 29 21:00:01 PST 2008

On Fri, 2008-02-29 at 20:01 -0800, Bill Spitzak wrote:

> 2. Try to allocate all the colors in the cube. If you get a color, put 
> it into the array at that location. Allocate the corners of the cube 
> first, then widely spaced values through it.

You don't want to fill the default colormap; most other applications
will fail. But, you don't want to allocate too few colors as your
application will look terrible. So, you want to pick a 'reasonable'
number of pixels to use and hope that most applications will end up
sharing them.

Oh, one other thing is that we'll want to support static color as well.
Static color turns out to be a lot better than pseudo color as the X
server will allocate a reasonable color cube and gray ramp, allowing
everyone to share nicely.

> 3. If a color fails, then read the colormap from the server, and find 
> the nearest color to the color you want. Pretend you allocated that 
> color and write it into the array. Don't bother allocating any more 
> colors, just keep finding them in this colormap, as the roundtrip to 
> read the map each time is slow.

You can't tell which pixels are allocated or free, and you can't tell
which pixels are read-only or read-write. The only way you can tell is
to allocate the color in the cell and check which pixel value is

> 4. To dither an image to put onto the display, find in your *planned* 
> color cube the nearest color (this should be simple). This is the color 
> you will draw on the screen, it may not be exactly the desired color (it 
> may not even be the nearest color), but it will be close. You then 
> subtract the *actual* color from the color you wanted to draw. This is 
> the error value, which you then distribute around as an error-diffusion 
> value 

Using error-diffusion produces a good result with simple images, but
when doing incremental rendering, it's important to use an ordered
dither so you get reproducible colors. However, its easier (and a lot
faster) to just pick the nearest available color. For many applications,
nearest color works better than a dither in any case -- line art and
other simple graphics isn't great looking with dithers. As we have no
API for controlling this activity (nor do I suggest we add one), we
should pick a method which generates the best overall look for simple
applications using text and plain graphics. Nearest fits this
requirement well.

And, dithering only works if cairo was doing all rendering locally and
just using PutImage to transmit the finished result. Otherwise, you get
cumulative errors in the output which are often far worse than just
using the single nearest pixel value. Of course, it probably would be
better to do rendering locally and use only PutImage as anything with
pseudocolor will almost certainly not contain the Render extension.

> This worked when run at the same time with a number of other programs 
> that purposely allocated different sizes of cubes, or filling the 
> colormap with random colors. It also worked on less than 8-bit visuals 
> despite the color map seeming to require more colors than would fit.

The pseudo color code in the Render extension is not this clever, but
does handle random spacing of colors in the colorspace -- the color cube
and ramp just select a good set of colors while the RGB->pixel mapping
chooses the closest pixel to each color.

Coordinating color usage with other toolkits is something we would
consider if 8-bit pseudo color were interesting; our current goal is
'display something' and 'not crash'. Improvements to that should mostly
involve encouraging people to find some way to get newer hardware.

keith.packard at intel.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: This is a digitally signed message part
Url : http://lists.cairographics.org/archives/cairo/attachments/20080229/9011433b/attachment.pgp 

More information about the cairo mailing list