/*
 * 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
#ifdef SK_DISCARD_DENORMALIZED_FOR_SPEED
        // The iOS ARM processor discards small denormalized numbers to go faster.
        // The comparision below empirically causes the result to agree with the
        // tests in MathTest test_float_floor
            if (exp > 149) {
                return 0;
            }
#else
            exp = 25;
#endif
        }
        // 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
#ifdef SK_DISCARD_DENORMALIZED_FOR_SPEED
        // The iOS ARM processor discards small denormalized numbers to go faster.
        // The comparision below empirically causes the result to agree with the
        // tests in MathTest test_float_ceil
            if (exp > 149) {
                return 0;
            }
            return 0 < value;
#else
            exp = 25;
#endif
        }
        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;
}
