[cairo] rewriting libpixman

Bill Spitzak spitzak at d2.com
Wed Apr 4 03:04:12 PDT 2007

Here's my take on what he is saying. Let's say we want to convert 
between 8 and 4 bit representations, which allows everything to be 
written in hex:

The floating point value for 0xXY in 8 bits is 0xXY/255 which is, when 
written in floating-point hex, 0x0.XYXYXYXYXY..... This is actually true 
even when 0xXY is 0xFF, as 1.0 can also be written 0x0.FFFFFFF....

The floating point value of 0xX in 4 bits is 0xX/31 which is written in 
hex as 0x0.XXXXXX....

Setting these equal it is clear that the correct conversion from 0xX in 
4 bits to an 8 bit value is to turn it into 0xXX.

The opposite conversion is not so clear, you can make an argument that 
0xXY should turn into 0xX+1 if Y is greater than 8 (ie round). However 
this has the unfortunate effect of messing up the 1.0 case. Even if you 
special-case that, the result is that all 23 numbers from 0xE9 to 0xFF 
turn into 0xF, while only 8 numbers from 0x00 to 0x08 turn into 0x0 and 
all other numbers get 16 numbers each. This results in the whole image 
getting brighter. If instead you do a floor, exactly 16 input numbers 
are converted to each output number, so there is no overall shift.

So by that argument the correct conversion from 0xXY in 8 bits to 4 bits 
is 0xX.

These arguments apply to convert between any number of bits and any 
other number, but it has to be written in binary to see it.

This has the huge advantage that it is symmetric (ie invert the image, 
convert, invert produces the same result as conversion). Also the 
majority of other software is doing exactly this conversion and it is 
probably important that Cairo matches. I know from personal experience 
that when people paint an overlay in Photoshop that blends "perfectly" 
there, but the edges appear when composited in your own software, as far 
as they are concerned your software is WRONG, and no amount of 
mathematical arguing will convince them otherwise.

James Cloos wrote:
>>>>>> "Jeff" == Jeff Muizelaar <jeff at infidigm.net> writes:
> Jeff> I still don't follow this logic, specifically the last sentence.
> Then I didn't explain it well enough....
> I was actually investigating conversions between floats in [0.0,1.0]
> to and from ints in [0,2ⁿ), for any n ∈ ℤ⁺.
> In that case, if you mupliply the float by 2ⁿ (saturating at 2ⁿ-1 if
> the float was ≥ 1.0) you get sane results.
> Also, if you divide the ints by 2ⁿ-1.0 you get results which are
> evenly spaced between 0.0 and 1.0 and you generate a repeating
> fraction which fills the width of the float...

More information about the cairo mailing list