xref: /aosp_15_r20/external/skia/src/base/SkFloatBits.h (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1 /*
2  * Copyright 2008 The Android Open Source Project
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #ifndef SkFloatBits_DEFINED
9 #define SkFloatBits_DEFINED
10 
11 #include "include/private/base/SkMath.h"
12 
13 #include <cstdint>
14 #include <cstring>
15 
16 /** Convert a sign-bit int (i.e. float interpreted as int) into a 2s compliement
17     int. This also converts -0 (0x80000000) to 0. Doing this to a float allows
18     it to be compared using normal C operators (<, <=, etc.)
19 */
SkSignBitTo2sCompliment(int32_t x)20 static inline int32_t SkSignBitTo2sCompliment(int32_t x) {
21     if (x < 0) {
22         x &= 0x7FFFFFFF;
23         x = -x;
24     }
25     return x;
26 }
27 
28 /** Convert a 2s compliment int to a sign-bit (i.e. int interpreted as float).
29     This undoes the result of SkSignBitTo2sCompliment().
30  */
Sk2sComplimentToSignBit(int32_t x)31 static inline int32_t Sk2sComplimentToSignBit(int32_t x) {
32     int sign = x >> 31;
33     // make x positive
34     x = (x ^ sign) - sign;
35     // set the sign bit as needed
36     x |= SkLeftShift(sign, 31);
37     return x;
38 }
39 
40 // Helper to see a float as its bit pattern (w/o aliasing warnings)
SkFloat2Bits(float value)41 static inline uint32_t SkFloat2Bits(float value) {
42     uint32_t bits;
43     memcpy(&bits, &value, sizeof(uint32_t));
44     return bits;
45 }
46 
47 // Helper to see a bit pattern as a float (w/o aliasing warnings)
SkBits2Float(uint32_t bits)48 static inline float SkBits2Float(uint32_t bits) {
49     float value;
50     memcpy(&value, &bits, sizeof(float));
51     return value;
52 }
53 
54 /** Return the float as a 2s compliment int. Just to be used to compare floats
55     to each other or against positive float-bit-constants (like 0). This does
56     not return the int equivalent of the float, just something cheaper for
57     compares-only.
58  */
SkFloatAs2sCompliment(float x)59 static inline int32_t SkFloatAs2sCompliment(float x) {
60     return SkSignBitTo2sCompliment((int32_t)SkFloat2Bits(x));
61 }
62 
63 /** Return the 2s compliment int as a float. This undos the result of
64     SkFloatAs2sCompliment
65  */
Sk2sComplimentAsFloat(int32_t x)66 static inline float Sk2sComplimentAsFloat(int32_t x) {
67     return SkBits2Float((uint32_t)Sk2sComplimentToSignBit(x));
68 }
69 
70 //  Scalar wrappers for float-bit routines
71 
72 #define SkScalarAs2sCompliment(x)    SkFloatAs2sCompliment(x)
73 
74 #endif
75