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