2013.02.13 22:03 "[Tiff] 32 bit to 16bit conversion", by james wells

2013.02.15 14:09 "Re: [Tiff] TIFF support for 16 bit floats", by Charles Auer

//////////////////////////////////////////////////////
//
// CONVERT HALF FLOAT (16 BIT FLOAT) TO FLOAT
//
////////////////////////////////////////////////////// // -15 stored using a single precision bias of 127
const unsigned int HALF_FLOAT_MIN_BIASED_EXP_AS_SINGLE_FP_EXP = 0x38000000; // max exponent value in single precision that will be converted
// to Inf or Nan when stored as a half-float
const unsigned int HALF_FLOAT_MAX_BIASED_EXP_AS_SINGLE_FP_EXP = 0x47800000; // 255 is the max exponent biased value

const unsigned int  FLOAT_MAX_BIASED_EXP = (0xFF << 23); const unsigned int  HALF_FLOAT_MAX_BIASED_EXP = (0x1F << 10); typedef unsigned short    hfloat;

float convertHFloatToFloat(hfloat hf)
{

    unsigned int    sign = (unsigned int)(hf >> 15);
    unsigned int    mantissa = (unsigned int)(hf & ((1 << 10) - 1));
    unsigned int    exp = (unsigned int)(hf & HALF_FLOAT_MAX_BIASED_EXP);
    unsigned int    f;  if (exp == HALF_FLOAT_MAX_BIASED_EXP)

    {
        // we have a half-float NaN or Inf
        // half-float NaNs will be converted to a single precision NaN
        // half-float Infs will be converted to a single precision Inf
        exp = FLOAT_MAX_BIASED_EXP;
        if (mantissa)
            mantissa = (1 << 23) - 1; // set all bits to indicate a NaN
    }
    else if (exp == 0x0)
    {
        // convert half-float zero/denorm to single precision value
        if (mantissa)
        {
           mantissa <<= 1;
           exp = HALF_FLOAT_MIN_BIASED_EXP_AS_SINGLE_FP_EXP;
           // check for leading 1 in denorm mantissa
           while ((mantissa & (1 << 10)) == 0)
           {
               // for every leading 0, decrement single precision exponent by 1
               // and shift half-float mantissa value to the left
               mantissa <<= 1;
               exp -= (1 << 23);
            }
            // clamp the mantissa to 10-bits
            mantissa &= ((1 << 10) - 1);
            // shift left to generate single-precision mantissa of 23-bits
            mantissa <<= 13;
        }
    }
    else
    {
        // shift left to generate single-precision mantissa of 23-bits
        mantissa <<= 13;
        // generate single precision biased exponent value
        exp = (exp << 13) + HALF_FLOAT_MIN_BIASED_EXP_AS_SINGLE_FP_EXP;
    } f = (sign << 31) | exp | mantissa;
    return *((float *)&f);
}