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