00001 /* 00002 ----------------------------------------------------------------------------- 00003 This source file is part of OGRE 00004 (Object-oriented Graphics Rendering Engine) 00005 For the latest info, see http://www.ogre3d.org/ 00006 00007 Copyright (c) 2000-2005 The OGRE Team 00008 Also see acknowledgements in Readme.html 00009 00010 This program is free software; you can redistribute it and/or modify it under 00011 the terms of the GNU Lesser General Public License as published by the Free Software 00012 Foundation; either version 2 of the License, or (at your option) any later 00013 version. 00014 00015 This program is distributed in the hope that it will be useful, but WITHOUT 00016 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 00017 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 00018 00019 You should have received a copy of the GNU Lesser General Public License along with 00020 this program; if not, write to the Free Software Foundation, Inc., 59 Temple 00021 Place - Suite 330, Boston, MA 02111-1307, USA, or go to 00022 http://www.gnu.org/copyleft/lesser.txt. 00023 ----------------------------------------------------------------------------- 00024 */ 00025 #ifndef _Bitwise_H__ 00026 #define _Bitwise_H__ 00027 00028 #include "OgrePrerequisites.h" 00029 00030 namespace Ogre { 00031 00034 class Bitwise { 00035 public: 00039 template<typename T> 00040 static FORCEINLINE unsigned int getBitShift(T mask) 00041 { 00042 if (mask == 0) 00043 return 0; 00044 00045 unsigned int result = 0; 00046 while ((mask & 1) == 0) { 00047 ++result; 00048 mask >>= 1; 00049 } 00050 return result; 00051 } 00052 00058 template<typename SrcT, typename DestT> 00059 static inline DestT convertBitPattern(SrcT srcValue, SrcT srcBitMask, DestT destBitMask) 00060 { 00061 // Mask off irrelevant source value bits (if any) 00062 srcValue = srcValue & srcBitMask; 00063 00064 // Shift source down to bottom of DWORD 00065 const unsigned int srcBitShift = getBitShift(srcBitMask); 00066 srcValue >>= srcBitShift; 00067 00068 // Get max value possible in source from srcMask 00069 const SrcT srcMax = srcBitMask >> srcBitShift; 00070 00071 // Get max avaiable in dest 00072 const unsigned int destBitShift = getBitShift(destBitMask); 00073 const DestT destMax = destBitMask >> destBitShift; 00074 00075 // Scale source value into destination, and shift back 00076 DestT destValue = (srcValue * destMax) / srcMax; 00077 return (destValue << destBitShift); 00078 } 00079 00084 static inline unsigned int fixedToFixed(uint32 value, unsigned int n, unsigned int p) 00085 { 00086 if(n > p) 00087 { 00088 // Less bits required than available; this is easy 00089 value >>= n-p; 00090 } 00091 else if(n < p) 00092 { 00093 // More bits required than are there, do the fill 00094 // Use old fashioned division, probably better than a loop 00095 if(value == 0) 00096 value = 0; 00097 else if(value == (static_cast<unsigned int>(1)<<n)-1) 00098 value = (1<<p)-1; 00099 else value = value*(1<<p)/((1<<n)-1); 00100 } 00101 return value; 00102 } 00103 00108 static inline unsigned int floatToFixed(const float value, const unsigned int bits) 00109 { 00110 if(value <= 0.0f) return 0; 00111 else if (value >= 1.0f) return (1<<bits)-1; 00112 else return (unsigned int)(value * (1<<bits)); 00113 } 00114 00118 static inline float fixedToFloat(unsigned value, unsigned int bits) 00119 { 00120 return (float)value/(float)((1<<bits)-1); 00121 } 00122 00126 static inline void intWrite(const void *dest, const int n, const unsigned int value) 00127 { 00128 switch(n) { 00129 case 1: 00130 ((uint8*)dest)[0] = (uint8)value; 00131 break; 00132 case 2: 00133 ((uint16*)dest)[0] = (uint16)value; 00134 break; 00135 case 3: 00136 #if OGRE_ENDIAN == OGRE_ENDIAN_BIG 00137 ((uint8*)dest)[0] = (uint8)((value >> 16) & 0xFF); 00138 ((uint8*)dest)[1] = (uint8)((value >> 8) & 0xFF); 00139 ((uint8*)dest)[2] = (uint8)(value & 0xFF); 00140 #else 00141 ((uint8*)dest)[2] = (uint8)((value >> 16) & 0xFF); 00142 ((uint8*)dest)[1] = (uint8)((value >> 8) & 0xFF); 00143 ((uint8*)dest)[0] = (uint8)(value & 0xFF); 00144 #endif 00145 break; 00146 case 4: 00147 ((uint32*)dest)[0] = (uint32)value; 00148 break; 00149 } 00150 } 00154 static inline unsigned int intRead(const void *src, int n) { 00155 switch(n) { 00156 case 1: 00157 return ((uint8*)src)[0]; 00158 case 2: 00159 return ((uint16*)src)[0]; 00160 case 3: 00161 #if OGRE_ENDIAN == OGRE_ENDIAN_BIG 00162 return ((uint32)((uint8*)src)[0]<<16)| 00163 ((uint32)((uint8*)src)[1]<<8)| 00164 ((uint32)((uint8*)src)[2]); 00165 #else 00166 return ((uint32)((uint8*)src)[0])| 00167 ((uint32)((uint8*)src)[1]<<8)| 00168 ((uint32)((uint8*)src)[2]<<16); 00169 #endif 00170 case 4: 00171 return ((uint32*)src)[0]; 00172 } 00173 return 0; // ? 00174 } 00175 00179 static inline uint16 floatToHalf(float i) 00180 { 00181 return floatToHalfI(*reinterpret_cast<uint32*>(&i)); 00182 } 00185 static inline uint16 floatToHalfI(uint32 i) 00186 { 00187 register int s = (i >> 16) & 0x00008000; 00188 register int e = ((i >> 23) & 0x000000ff) - (127 - 15); 00189 register int m = i & 0x007fffff; 00190 00191 if (e <= 0) 00192 { 00193 if (e < -10) 00194 { 00195 return 0; 00196 } 00197 m = (m | 0x00800000) >> (1 - e); 00198 00199 return s | (m >> 13); 00200 } 00201 else if (e == 0xff - (127 - 15)) 00202 { 00203 if (m == 0) // Inf 00204 { 00205 return s | 0x7c00; 00206 } 00207 else // NAN 00208 { 00209 m >>= 13; 00210 return s | 0x7c00 | m | (m == 0); 00211 } 00212 } 00213 else 00214 { 00215 if (e > 30) // Overflow 00216 { 00217 return s | 0x7c00; 00218 } 00219 00220 return s | (e << 10) | (m >> 13); 00221 } 00222 } 00223 00228 static inline float halfToFloat(uint16 y) 00229 { 00230 uint32 r = halfToFloatI(y); 00231 return *reinterpret_cast<float*>(&r); 00232 } 00236 static inline uint32 halfToFloatI(uint16 y) 00237 { 00238 register int s = (y >> 15) & 0x00000001; 00239 register int e = (y >> 10) & 0x0000001f; 00240 register int m = y & 0x000003ff; 00241 00242 if (e == 0) 00243 { 00244 if (m == 0) // Plus or minus zero 00245 { 00246 return s << 31; 00247 } 00248 else // Denormalized number -- renormalize it 00249 { 00250 while (!(m & 0x00000400)) 00251 { 00252 m <<= 1; 00253 e -= 1; 00254 } 00255 00256 e += 1; 00257 m &= ~0x00000400; 00258 } 00259 } 00260 else if (e == 31) 00261 { 00262 if (m == 0) // Inf 00263 { 00264 return (s << 31) | 0x7f800000; 00265 } 00266 else // NaN 00267 { 00268 return (s << 31) | 0x7f800000 | (m << 13); 00269 } 00270 } 00271 00272 e = e + (127 - 15); 00273 m = m << 13; 00274 00275 return (s << 31) | (e << 23) | m; 00276 } 00277 00278 00279 }; 00280 } 00281 00282 #endif
Copyright © 2000-2005 by The OGRE Team
This work is licensed under a Creative Commons Attribution-ShareAlike 2.5 License.
Last modified Sun Feb 12 12:59:41 2006