1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com
28a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/*
3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2008 The Android Open Source Project
48a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *
5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be
6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file.
78a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */
88a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
9ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com
108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifndef SkFloatBits_DEFINED
118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkFloatBits_DEFINED
128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkTypes.h"
148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/** Convert a sign-bit int (i.e. float interpreted as int) into a 2s compliement
168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    int. This also converts -0 (0x80000000) to 0. Doing this to a float allows
178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    it to be compared using normal C operators (<, <=, etc.)
188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/
198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic inline int32_t SkSignBitTo2sCompliment(int32_t x) {
208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (x < 0) {
218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        x &= 0x7FFFFFFF;
228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        x = -x;
238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return x;
258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/** Convert a 2s compliment int to a sign-bit (i.e. int interpreted as float).
288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    This undoes the result of SkSignBitTo2sCompliment().
298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */
308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic inline int32_t Sk2sComplimentToSignBit(int32_t x) {
318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    int sign = x >> 31;
328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    // make x positive
338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    x = (x ^ sign) - sign;
348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    // set the sign bit as needed
358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    x |= sign << 31;
368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return x;
378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/** Given the bit representation of a float, return its value cast to an int.
408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    If the value is out of range, or NaN, return return +/- SK_MaxS32
418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/
428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comint32_t SkFloatBits_toIntCast(int32_t floatBits);
438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/** Given the bit representation of a float, return its floor as an int.
458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    If the value is out of range, or NaN, return return +/- SK_MaxS32
468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */
477ffb1b21abcc7bbed5a0fc711f6dd7b9dbb4f577ctguil@chromium.orgSK_API int32_t SkFloatBits_toIntFloor(int32_t floatBits);
488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/** Given the bit representation of a float, return it rounded to an int.
508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    If the value is out of range, or NaN, return return +/- SK_MaxS32
518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */
527ffb1b21abcc7bbed5a0fc711f6dd7b9dbb4f577ctguil@chromium.orgSK_API int32_t SkFloatBits_toIntRound(int32_t floatBits);
538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/** Given the bit representation of a float, return its ceiling as an int.
558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    If the value is out of range, or NaN, return return +/- SK_MaxS32
568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */
577ffb1b21abcc7bbed5a0fc711f6dd7b9dbb4f577ctguil@chromium.orgSK_API int32_t SkFloatBits_toIntCeil(int32_t floatBits);
588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comunion SkFloatIntUnion {
618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    float   fFloat;
628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    int32_t fSignBitInt;
638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com};
648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// Helper to see a float as its bit pattern (w/o aliasing warnings)
668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic inline int32_t SkFloat2Bits(float x) {
678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkFloatIntUnion data;
688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    data.fFloat = x;
698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return data.fSignBitInt;
708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// Helper to see a bit pattern as a float (w/o aliasing warnings)
738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic inline float SkBits2Float(int32_t floatAsBits) {
748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkFloatIntUnion data;
758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    data.fSignBitInt = floatAsBits;
768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return data.fFloat;
778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/** Return the float as a 2s compliment int. Just to be used to compare floats
808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    to each other or against positive float-bit-constants (like 0). This does
818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    not return the int equivalent of the float, just something cheaper for
828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    compares-only.
838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */
848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic inline int32_t SkFloatAs2sCompliment(float x) {
858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return SkSignBitTo2sCompliment(SkFloat2Bits(x));
868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/** Return the 2s compliment int as a float. This undos the result of
898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkFloatAs2sCompliment
908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */
918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic inline float Sk2sComplimentAsFloat(int32_t x) {
928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return SkBits2Float(Sk2sComplimentToSignBit(x));
938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/** Return x cast to a float (i.e. (float)x)
968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/
978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comfloat SkIntToFloatCast(int x);
988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/** Return the float cast to an int.
1008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    If the value is out of range, or NaN, return +/- SK_MaxS32
1018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/
1028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic inline int32_t SkFloatToIntCast(float x) {
1038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return SkFloatBits_toIntCast(SkFloat2Bits(x));
1048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
1058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/** Return the floor of the float as an int.
1078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    If the value is out of range, or NaN, return +/- SK_MaxS32
1088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/
1098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic inline int32_t SkFloatToIntFloor(float x) {
1108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return SkFloatBits_toIntFloor(SkFloat2Bits(x));
1118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
1128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/** Return the float rounded to an int.
1148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    If the value is out of range, or NaN, return +/- SK_MaxS32
1158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/
1168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic inline int32_t SkFloatToIntRound(float x) {
1178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return SkFloatBits_toIntRound(SkFloat2Bits(x));
1188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
1198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/** Return the ceiling of the float as an int.
1218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    If the value is out of range, or NaN, return +/- SK_MaxS32
1228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/
1238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic inline int32_t SkFloatToIntCeil(float x) {
1248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return SkFloatBits_toIntCeil(SkFloat2Bits(x));
1258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
1268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com//  Scalar wrappers for float-bit routines
1288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1298f4d2306fa866a26f9448048ff63f692b2ba43aareed@google.com#define SkScalarAs2sCompliment(x)    SkFloatAs2sCompliment(x)
1308f4d2306fa866a26f9448048ff63f692b2ba43aareed@google.com#define Sk2sComplimentAsScalar(x)    Sk2sComplimentAsFloat(x)
1318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif
133