[cairo] RFC: More accurate color conversion
Søren Sandmann
sandmann at cs.au.dk
Wed Oct 9 15:44:17 PDT 2013
James Cloos <cloos at jhcloos.com> writes:
>>>>>> "CW" == Carl Worth <cworth at cworth.org> writes:
>
> CW> But then you simply assert that the conversion from integer to
> CW> floating-point must be f(i) = i/65535.0. What's the justification for
> CW> this?
>
> When I looked into this many moons ago, I concluded that the best option
> is to multiply (with saturation) by IMAX+1 and divide by IMAX. Ie, what
> cairo currently does.
There are two functions being talked about here:
f: uint16_t -> double
and
g: double -> uint16_t
When you say "multiply (with saturation) by IMAX+1 and divide by IMAX" I
assume you mean
f(i) = i / 65535.0
and
g(x) = MAX (x * 65536, 65535.0)
which is indeed what cairo does now. I think everyone agrees that
f(i) = i / 65535.0
is the right choice for f, but for g, I am proposing a different
formula:
g(x) = floor (x * 65535.0 + 0.5)
that as argued elsewhere has less error.
> Dividing by IMAX generates an infinitely repeating value which best
> places the integer value w/in the interval which rounds to said integer.
>
> This is akin to mapping {0,...,9} to {0/9,...,9/9} generating the
> decimal expansions 0, .111..., .222..., .333,... et cetera.
>
> It is widely accepted that when expanding an 8bit value to 16 bit, one
> should duplicate the bits, eg by multiplying by 257. Dividing by IMAX
> generates a floating point value which accomplishes that same goal.
It sounds like you are arguing here that f should indeed be defined as
above (as a division by IMAX). But as far as I can tell you are not
arguing that g should necessarily stay the same.
For the conversion of 8 to 16 bits, both discussed choices of g will
just duplicate the bits (this will be the case for conversions between
all integers whose width is a power of two), though with the proposed g,
converting back will no longer just be a bit shift.
Søren
More information about the cairo
mailing list