/*
 * Copyright 2011 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "SkFloatBits.h"
#include "SkMathPriv.h"

/******************************************************************************
    SkFloatBits_toInt[Floor, Round, Ceil] are identical except for what they
    do right before they return ... >> exp;
    Floor - adds nothing
    Round - adds 1 << (exp - 1)
    Ceil - adds (1 << exp) - 1

    Floor and Cast are very similar, but Cast applies its sign after all other
    computations on value. Also, Cast does not need to check for negative zero,
    as that value (0x80000000) "does the right thing" for Ceil. Note that it
    doesn't for Floor/Round/Ceil, hence the explicit check.
******************************************************************************/

#define EXP_BIAS            (127+23)
#define MATISSA_MAGIC_BIG   (1 << 23)

static inline int unpack_exp(uint32_t packed) {
    return (packed << 1 >> 24);
}

#if 0
// the ARM compiler generates an extra BIC, so I use the dirty version instead
static inline int unpack_matissa(uint32_t packed) {
    // we could mask with 0x7FFFFF, but that is harder for ARM to encode
    return (packed & ~0xFF000000) | MATISSA_MAGIC_BIG;
}
#endif

// returns the low 24-bits, so we need to OR in the magic_bit afterwards
static inline int unpack_matissa_dirty(uint32_t packed) {
    return packed & ~0xFF000000;
}

// same as (int)float
int32_t SkFloatBits_toIntCast(int32_t packed) {
    int exp = unpack_exp(packed) - EXP_BIAS;
    int value = unpack_matissa_dirty(packed) | MATISSA_MAGIC_BIG;

    if (exp >= 0) {
        if (exp > 7) {    // overflow
            value = SK_MaxS32;
        } else {
            value <<= exp;
        }
    } else {
        exp = -exp;
        if (exp > 25) {   // underflow
            exp = 25;
        }
        value >>= exp;
    }
    return SkApplySign(value, SkExtractSign(packed));
}

// same as (int)floor(float)
int32_t SkFloatBits_toIntFloor(int32_t packed) {
    // curse you negative 0
    if ((packed << 1) == 0) {
        return 0;
    }

    int exp = unpack_exp(packed) - EXP_BIAS;
    int value = unpack_matissa_dirty(packed) | MATISSA_MAGIC_BIG;

    if (exp >= 0) {
        if (exp > 7) {    // overflow
            value = SK_MaxS32;
        } else {
            value <<= exp;
        }
        // apply the sign after we check for overflow
        return SkApplySign(value, SkExtractSign(packed));
    } else {
        // apply the sign before we right-shift
        value = SkApplySign(value, SkExtractSign(packed));
        exp = -exp;
        if (exp > 25) {   // underflow
            exp = 25;
        }
        // int add = 0;
        return value >> exp;
    }
}

// same as (int)floor(float + 0.5)
int32_t SkFloatBits_toIntRound(int32_t packed) {
    // curse you negative 0
    if ((packed << 1) == 0) {
        return 0;
    }

    int exp = unpack_exp(packed) - EXP_BIAS;
    int value = unpack_matissa_dirty(packed) | MATISSA_MAGIC_BIG;

    if (exp >= 0) {
        if (exp > 7) {    // overflow
            value = SK_MaxS32;
        } else {
            value <<= exp;
        }
        // apply the sign after we check for overflow
        return SkApplySign(value, SkExtractSign(packed));
    } else {
        // apply the sign before we right-shift
        value = SkApplySign(value, SkExtractSign(packed));
        exp = -exp;
        if (exp > 25) {   // underflow
            exp = 25;
        }
        int add = 1 << (exp - 1);
        return (value + add) >> exp;
    }
}

// same as (int)ceil(float)
int32_t SkFloatBits_toIntCeil(int32_t packed) {
    // curse you negative 0
    if ((packed << 1) == 0) {
        return 0;
    }

    int exp = unpack_exp(packed) - EXP_BIAS;
    int value = unpack_matissa_dirty(packed) | MATISSA_MAGIC_BIG;

    if (exp >= 0) {
        if (exp > 7) {    // overflow
            value = SK_MaxS32;
        } else {
            value <<= exp;
        }
        // apply the sign after we check for overflow
        return SkApplySign(value, SkExtractSign(packed));
    } else {
        // apply the sign before we right-shift
        value = SkApplySign(value, SkExtractSign(packed));
        exp = -exp;
        if (exp > 25) {   // underflow
            exp = 25;
        }
        int add = (1 << exp) - 1;
        return (value + add) >> exp;
    }
}

float SkIntToFloatCast(int32_t value) {
    if (0 == value) {
        return 0;
    }

    int shift = EXP_BIAS;

    // record the sign and make value positive
    int sign = SkExtractSign(value);
    value = SkApplySign(value, sign);

    if (value >> 24) {    // value is too big (has more than 24 bits set)
        int bias = 8 - SkCLZ(value);
        SkDebugf("value = %d, bias = %d\n", value, bias);
        SkASSERT(bias > 0 && bias < 8);
        value >>= bias; // need to round?
        shift += bias;
    } else {
        int zeros = SkCLZ(value << 8);
        SkASSERT(zeros >= 0 && zeros <= 23);
        value <<= zeros;
        shift -= zeros;
    }

    // now value is left-aligned to 24 bits
    SkASSERT((value >> 23) == 1);
    SkASSERT(shift >= 0 && shift <= 255);

    SkFloatIntUnion data;
    data.fSignBitInt = (sign << 31) | (shift << 23) | (value & ~MATISSA_MAGIC_BIG);
    return data.fFloat;
}

float SkIntToFloatCast_NoOverflowCheck(int32_t value) {
    if (0 == value) {
        return 0;
    }

    int shift = EXP_BIAS;

    // record the sign and make value positive
    int sign = SkExtractSign(value);
    value = SkApplySign(value, sign);

    int zeros = SkCLZ(value << 8);
    value <<= zeros;
    shift -= zeros;

    SkFloatIntUnion data;
    data.fSignBitInt = (sign << 31) | (shift << 23) | (value & ~MATISSA_MAGIC_BIG);
    return data.fFloat;
}
