// float RGB -> U8 RGBE quantization
void float_to_rgbe(unsigned char * rgbe,const float * rgbf)
{
// rgbf[] should all be >= 0 , RGBE does not support signed values
float maxf = rgbf[0] > rgbf[1] ? rgbf[0] : rgbf[1];
maxf = maxf > rgbf[2] ? maxf : rgbf[2];
if ( maxf <= 1e-32f )
{
// Exponent byte = 0 is a special encoding that makes RGB output = 0
rgbe[0] = rgbe[1] = rgbe[2] = rgbe[3] = 0;
}
else
{
int exponent;
frexpf(maxf, &exponent);
float scale = ldexpf(1.f, -exponent + 8);
rgbe[0] = (unsigned char)( rgbf[0] * scale );
rgbe[1] = (unsigned char)( rgbf[1] * scale );
rgbe[2] = (unsigned char)( rgbf[2] * scale );
rgbe[3] = (unsigned char)( exponent + 128 );
}
}
// U8 RGBE -> float RGB dequantization
void rgbe_to_float(float * rgbf,const unsigned char * rgbe)
{
if ( rgbe[3] == 0 )
{
rgbf[0] = rgbf[1] = rgbf[2] = 0.f;
}
else
{
// the extra 8 here does the /256
float fexp = ldexpf(1.f, (int)rgbe[3] - (128 + 8));
rgbf[0] = (rgbe[0] + 0.5f) * fexp;
rgbf[1] = (rgbe[1] + 0.5f) * fexp;
rgbf[2] = (rgbe[2] + 0.5f) * fexp;
}
}