[Pixman] sRGB processing for pixman

Bill Spitzak spitzak at gmail.com
Thu Jun 21 12:57:58 PDT 2012

Søren Sandmann wrote:

> For the 8 bpc fetcher converting from 8 bit srgb to 8 bit linear loses a
> lott of information, which is why the format is considered wide. But if
> it somehow ends up being used with the 8 bit pipe (and currently it
> will, because at the moment everything with a transformation ignores the
> wide path), the pixels still need to be linear. We may need a 256->256
> table doing 8-bit sRGB to 8-bit linear.

Error diffusion helps a lot with these conversions, and actually makes 
8-bit linear *somewhat* useful. With this a smooth sRGB gradient 
converted to 8-bit linear and then back is noisy but looks much better 
than the severe banding you would get with just an 8-bit lookup table.

In my experience there is no need for complex pattern error diffusion. 
Instead all the error is dumped into the next pixel. This would fit with 
your fetchers that do only one line at a time.

In both directions, there is a 256-entry table of 16-bit numbers, which 
is the conversion to the destination value in 8.8 fixed-point (thus the 
largest number is 0xFF00, not 0xFFFF!).

Pick a pseudo-random point in the middle of the row and proceed like 
this (either wrap around or go backwards from that point as well):

     short table[256] = {...};
     unsigned short error = 127;
     for (;;) {
         error += table[next_pixel()];
         error &= 255;

Similar diffusion is also useful for converting floating point to 8-bit 
so that smooth gradients remain smooth-looking. I used lookup tables 
based on the top 16 bits of the floating point number but this was for 
Irix 20 years ago and I believe on modern machines it is faster to just 
do the math directly, or some polynominal approximation.

A problem is the pseudo-random starting point. This is necessary so that 
you do not get vertical stripes when the rows have the same data. But if 
you want your composites to not change, it has to be deterministic. I'm 
not sure but perhaps a hash of the y coordinate of the source will work, 
or that hash plus the color of a pixel at x==0.

More information about the Pixman mailing list