12-01-06 - 1

Something else I've never really seen written up clearly. We do ubyte to float color conversions all the time and don't really think much about it. There are two obvious ways to do it, and there are trade offs with each. You can either map the full range or preserve the end points, not both.


int colors are in [0,255]

Int pel "x" is considered to represent the span {x-0.5,x+0.5}/255

float colors are in [0,1]

int 0 -> float 0
int 255 -> float 1

Note that this way is nice in that it keeps the maximums the same,
 but it's bad in that it wastes color space.  That is, there's only 1/255
 precision instead of 1/256 which is totally possible.

Another way of seeing it is that the int range [0,255] is actually being
mapped to the float range { -0.5/255 , 255.5/255 } , that is, {0,1} is not
the full range.

One nice thing about this though is that it gives you some slop in your float->int.
As long as the float is in { -0.5/255 , 255.5/255 } you don't need to clamp.

// more pure quantizer way :
// int value [i] represents the bucket (i,i+1)/256

inline int		ColorFTOI(float f)
	return ftoi(f * 256.f);

inline float	ColorITOF(int i)
	return (i + 0.5f) * (1.f/256.f);

// way that maps 0<->0 and 255<->1.0

inline int		ColorFTOI(float f)
	return ftoi(f * 255.f + 0.5f);

inline float	ColorITOF(int i)
	return i * (1.f/255.f);

No comments:

old rants