15bb6825f10d64834ad1d1d967f590aebae285360epoger@google.com 2f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com/* 35bb6825f10d64834ad1d1d967f590aebae285360epoger@google.com * Copyright 2008 The Android Open Source Project 4f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com * 55bb6825f10d64834ad1d1d967f590aebae285360epoger@google.com * Use of this source code is governed by a BSD-style license that can be 65bb6825f10d64834ad1d1d967f590aebae285360epoger@google.com * found in the LICENSE file. 7f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com */ 8f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com 95bb6825f10d64834ad1d1d967f590aebae285360epoger@google.com 10f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com#ifndef SkFloatBits_DEFINED 11f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com#define SkFloatBits_DEFINED 12f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com 13f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com#include "SkTypes.h" 14f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com 15f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com/** Convert a sign-bit int (i.e. float interpreted as int) into a 2s compliement 16f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com int. This also converts -0 (0x80000000) to 0. Doing this to a float allows 17f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com it to be compared using normal C operators (<, <=, etc.) 18f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com*/ 19f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.comstatic inline int32_t SkSignBitTo2sCompliment(int32_t x) { 20f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com if (x < 0) { 21f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com x &= 0x7FFFFFFF; 22f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com x = -x; 23f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com } 24f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com return x; 25f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com} 26f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com 27f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com/** Convert a 2s compliment int to a sign-bit (i.e. int interpreted as float). 28f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com This undoes the result of SkSignBitTo2sCompliment(). 29f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com */ 30f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.comstatic inline int32_t Sk2sComplimentToSignBit(int32_t x) { 31f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com int sign = x >> 31; 32f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com // make x positive 33f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com x = (x ^ sign) - sign; 34f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com // set the sign bit as needed 35f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com x |= sign << 31; 36f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com return x; 37f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com} 38f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com 39f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com/** Given the bit representation of a float, return its value cast to an int. 40f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com If the value is out of range, or NaN, return return +/- SK_MaxS32 41f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com*/ 42f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.comint32_t SkFloatBits_toIntCast(int32_t floatBits); 43f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com 44f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com/** Given the bit representation of a float, return its floor as an int. 45f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com If the value is out of range, or NaN, return return +/- SK_MaxS32 46f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com */ 472083387d719b933797044ad07efd3bb67f99a5c5ctguil@chromium.orgSK_API int32_t SkFloatBits_toIntFloor(int32_t floatBits); 48f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com 49f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com/** Given the bit representation of a float, return it rounded to an int. 50f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com If the value is out of range, or NaN, return return +/- SK_MaxS32 51f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com */ 522083387d719b933797044ad07efd3bb67f99a5c5ctguil@chromium.orgSK_API int32_t SkFloatBits_toIntRound(int32_t floatBits); 53f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com 54f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com/** Given the bit representation of a float, return its ceiling as an int. 55f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com If the value is out of range, or NaN, return return +/- SK_MaxS32 56f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com */ 572083387d719b933797044ad07efd3bb67f99a5c5ctguil@chromium.orgSK_API int32_t SkFloatBits_toIntCeil(int32_t floatBits); 58f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com 59f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com 60f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.comunion SkFloatIntUnion { 61f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com float fFloat; 62f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com int32_t fSignBitInt; 63f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com}; 64f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com 65f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com// Helper to see a float as its bit pattern (w/o aliasing warnings) 66f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.comstatic inline int32_t SkFloat2Bits(float x) { 67f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com SkFloatIntUnion data; 68f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com data.fFloat = x; 69f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com return data.fSignBitInt; 70f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com} 71f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com 72f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com// Helper to see a bit pattern as a float (w/o aliasing warnings) 73f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.comstatic inline float SkBits2Float(int32_t floatAsBits) { 74f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com SkFloatIntUnion data; 75f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com data.fSignBitInt = floatAsBits; 76f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com return data.fFloat; 77f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com} 78f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com 79f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com/** Return the float as a 2s compliment int. Just to be used to compare floats 80f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com to each other or against positive float-bit-constants (like 0). This does 81f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com not return the int equivalent of the float, just something cheaper for 82f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com compares-only. 83f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com */ 84f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.comstatic inline int32_t SkFloatAs2sCompliment(float x) { 85f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com return SkSignBitTo2sCompliment(SkFloat2Bits(x)); 86f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com} 87f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com 88f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com/** Return the 2s compliment int as a float. This undos the result of 89f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com SkFloatAs2sCompliment 90f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com */ 91f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.comstatic inline float Sk2sComplimentAsFloat(int32_t x) { 92f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com return SkBits2Float(Sk2sComplimentToSignBit(x)); 93f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com} 94f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com 95f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com/** Return x cast to a float (i.e. (float)x) 96f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com*/ 97f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.comfloat SkIntToFloatCast(int x); 98f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.comfloat SkIntToFloatCast_NoOverflowCheck(int x); 99f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com 100f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com/** Return the float cast to an int. 101f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com If the value is out of range, or NaN, return +/- SK_MaxS32 102f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com*/ 103f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.comstatic inline int32_t SkFloatToIntCast(float x) { 104f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com return SkFloatBits_toIntCast(SkFloat2Bits(x)); 105f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com} 106f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com 107f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com/** Return the floor of the float as an int. 108f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com If the value is out of range, or NaN, return +/- SK_MaxS32 109f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com*/ 110f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.comstatic inline int32_t SkFloatToIntFloor(float x) { 111f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com return SkFloatBits_toIntFloor(SkFloat2Bits(x)); 112f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com} 113f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com 114f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com/** Return the float rounded to an int. 115f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com If the value is out of range, or NaN, return +/- SK_MaxS32 116f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com*/ 117f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.comstatic inline int32_t SkFloatToIntRound(float x) { 118f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com return SkFloatBits_toIntRound(SkFloat2Bits(x)); 119f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com} 120f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com 121f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com/** Return the ceiling of the float as an int. 122f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com If the value is out of range, or NaN, return +/- SK_MaxS32 123f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com*/ 124f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.comstatic inline int32_t SkFloatToIntCeil(float x) { 125f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com return SkFloatBits_toIntCeil(SkFloat2Bits(x)); 126f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com} 127f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com 128f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com// Scalar wrappers for float-bit routines 129f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com 130f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com#ifdef SK_SCALAR_IS_FLOAT 131f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com #define SkScalarAs2sCompliment(x) SkFloatAs2sCompliment(x) 132f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com #define Sk2sComplimentAsScalar(x) Sk2sComplimentAsFloat(x) 133f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com#else 134f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com #define SkScalarAs2sCompliment(x) (x) 135f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com #define Sk2sComplimentAsScalar(x) (x) 136f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com#endif 137f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com 138f0d6bf5df07d5ce620678074da0c05aacc28e44reed@android.com#endif 139