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