18a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/* 2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2008 The Android Open Source Project 38a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com * 4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be 5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file. 68a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 78a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com 98a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifndef SkFloatBits_DEFINED 108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkFloatBits_DEFINED 118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkTypes.h" 13e9f78b41c65a78400c22a1b79007b1b9e187a745Mike Klein#include "SkSafe_math.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 35952538ed50661ad7dff6ec2b7af3f921e1d91b52caryclark x |= SkLeftShift(sign, 31); 368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return x; 378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comunion SkFloatIntUnion { 408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com float fFloat; 418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int32_t fSignBitInt; 428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// Helper to see a float as its bit pattern (w/o aliasing warnings) 458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic inline int32_t SkFloat2Bits(float x) { 468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkFloatIntUnion data; 478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com data.fFloat = x; 488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return data.fSignBitInt; 498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// Helper to see a bit pattern as a float (w/o aliasing warnings) 528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic inline float SkBits2Float(int32_t floatAsBits) { 538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkFloatIntUnion data; 548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com data.fSignBitInt = floatAsBits; 558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return data.fFloat; 568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/** Return the float as a 2s compliment int. Just to be used to compare floats 598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com to each other or against positive float-bit-constants (like 0). This does 608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com not return the int equivalent of the float, just something cheaper for 618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com compares-only. 628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic inline int32_t SkFloatAs2sCompliment(float x) { 648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return SkSignBitTo2sCompliment(SkFloat2Bits(x)); 658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/** Return the 2s compliment int as a float. This undos the result of 688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkFloatAs2sCompliment 698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic inline float Sk2sComplimentAsFloat(int32_t x) { 718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return SkBits2Float(Sk2sComplimentToSignBit(x)); 728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 74785a5b941a4d74a1f272729fe8dca55c6eda6bb8mtkleinstatic inline int32_t pin_double_to_int(double x) { 75785a5b941a4d74a1f272729fe8dca55c6eda6bb8mtklein return (int32_t)SkTPin<double>(x, SK_MinS32, SK_MaxS32); 768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/** Return the floor of the float as an int. 798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com If the value is out of range, or NaN, return +/- SK_MaxS32 808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/ 818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic inline int32_t SkFloatToIntFloor(float x) { 82785a5b941a4d74a1f272729fe8dca55c6eda6bb8mtklein return pin_double_to_int(floor(x)); 838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/** Return the float rounded to an int. 868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com If the value is out of range, or NaN, return +/- SK_MaxS32 878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/ 888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic inline int32_t SkFloatToIntRound(float x) { 89785a5b941a4d74a1f272729fe8dca55c6eda6bb8mtklein return pin_double_to_int(floor((double)x + 0.5)); 908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/** Return the ceiling of the float as an int. 938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com If the value is out of range, or NaN, return +/- SK_MaxS32 948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/ 958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic inline int32_t SkFloatToIntCeil(float x) { 96785a5b941a4d74a1f272729fe8dca55c6eda6bb8mtklein return pin_double_to_int(ceil(x)); 978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// Scalar wrappers for float-bit routines 1008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1018f4d2306fa866a26f9448048ff63f692b2ba43aareed@google.com#define SkScalarAs2sCompliment(x) SkFloatAs2sCompliment(x) 1028f4d2306fa866a26f9448048ff63f692b2ba43aareed@google.com#define Sk2sComplimentAsScalar(x) Sk2sComplimentAsFloat(x) 1038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 105