[cairo] rewriting libpixman

James Cloos cloos at jhcloos.com
Mon Apr 2 09:30:48 PDT 2007


>>>>> "Jeff" == Jeff Muizelaar <jeff at infidigm.net> writes:

Jeff> I'm confused by this. For example, (256*31+15)/31 gives 256
Jeff> which overflows..

It does have to be a saturating multiply and divide.  And you don't
need the +15.

The bitshift is the proper way to implement it with ints, but when
converting between a float sample and an int sample the mult and div
do the right thing, provided overflows are clamped to the max of the
result's int size as the final step.

The idea is that dividing an int sample by the largest possible int
gives a repeating fraction component which repeats the sample's value.

Ie, if the samples are 00-99 (base 100), then the fraction when
dividing by NN by 99 is .NN NN NN NN ... for any NN in [00,99].
Likewise for any other range, such as bases 32, 64 or 256.

And of course, do remember that .99999... == 1.0, and that that works
for the largest digit of any base.  So the sample specified by all 1
bits is, if you treat samples as the first approximations of infinite
series, the same as 2^n, given an n-bit sample.

So, given a 5 bit sample, were you to cast it to an int32_t or float,
multiply it by 256 and then divide by 31 you get (with the right
rounding, of course) the same as doing the bit shifts.

This also applies when converting between int and float.  If the int
samples are 8 bit and the floats are constrained to [0.0,1.0], then
divide by 255 and saturate-multiply by 256.0 when converting.

But when the conversions are between different sized int samples,
always use the bitshifts in the code.  

-JimC
-- 
James Cloos <cloos at jhcloos.com>         OpenPGP: 1024D/ED7DAEA6


More information about the cairo mailing list