OGRE  1.9.0
OgreBitwise.h
Go to the documentation of this file.
1 /*
2 -----------------------------------------------------------------------------
3 This source file is part of OGRE
4  (Object-oriented Graphics Rendering Engine)
5 For the latest info, see http://www.ogre3d.org/
6 
7 Copyright (c) 2000-2014 Torus Knot Software Ltd
8 
9 Permission is hereby granted, free of charge, to any person obtaining a copy
10 of this software and associated documentation files (the "Software"), to deal
11 in the Software without restriction, including without limitation the rights
12 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 copies of the Software, and to permit persons to whom the Software is
14 furnished to do so, subject to the following conditions:
15 
16 The above copyright notice and this permission notice shall be included in
17 all copies or substantial portions of the Software.
18 
19 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 THE SOFTWARE.
26 -----------------------------------------------------------------------------
27 */
28 #ifndef _Bitwise_H__
29 #define _Bitwise_H__
30 
31 #include "OgrePrerequisites.h"
32 
33 #ifndef __has_builtin
34  // Compatibility with non-clang compilers
35  #define __has_builtin(x) 0
36 #endif
37 
38 namespace Ogre {
48  class Bitwise {
49  public:
53  {
54 #if OGRE_COMPILER == OGRE_COMPILER_MSVC && OGRE_COMP_VER >= 1310
55  return _byteswap_ushort(arg);
56 #elif (OGRE_COMPILER == OGRE_COMPILER_CLANG && __has_builtin(__builtin_bswap16)) || (OGRE_COMPILER == OGRE_COMPILER_GNUC && OGRE_COMP_VER >= 480)
57  return __builtin_bswap16(arg);
58 #else
59  return ((arg << 8) & 0xFF00) | ((arg >> 8) & 0x00FF);
60 #endif
61  }
65  {
66 #if OGRE_COMPILER == OGRE_COMPILER_MSVC && OGRE_COMP_VER >= 1310
67  return _byteswap_ulong(arg);
68 #elif (OGRE_COMPILER == OGRE_COMPILER_CLANG && __has_builtin(__builtin_bswap32)) || (OGRE_COMPILER == OGRE_COMPILER_GNUC && OGRE_COMP_VER >= 430)
69  return __builtin_bswap32(arg);
70 #else
71  return ((arg & 0x000000FF) << 24) | ((arg & 0x0000FF00) << 8) | ((arg >> 8) & 0x0000FF00) | ((arg >> 24) & 0x000000FF);
72 #endif
73  }
77  {
78 #if OGRE_COMPILER == OGRE_COMPILER_MSVC && OGRE_COMP_VER >= 1310
79  return _byteswap_uint64(arg);
80 #elif (OGRE_COMPILER == OGRE_COMPILER_CLANG && __has_builtin(__builtin_bswap64)) || (OGRE_COMPILER == OGRE_COMPILER_GNUC && OGRE_COMP_VER >= 430)
81  return __builtin_bswap64(arg);
82 #else
83  union {
84  uint64 sv;
85  uint32 ul[2];
86  } tmp, result;
87  tmp.sv = arg;
88  result.ul[0] = bswap32(tmp.ul[1]);
89  result.ul[1] = bswap32(tmp.ul[0]);
90  return result.sv;
91 #endif
92  }
93 
96  static inline void bswapBuffer(void * pData, size_t size)
97  {
98  char swapByte;
99  for(char *p0 = (char*)pData, *p1 = p0 + size - 1; p0 < p1; ++p0, --p1)
100  {
101  swapByte = *p0;
102  *p0 = *p1;
103  *p1 = swapByte;
104  }
105  }
108  static inline void bswapChunks(void * pData, size_t size, size_t count)
109  {
110  for(size_t c = 0; c < count; ++c)
111  {
112  char swapByte;
113  for(char *p0 = (char*)pData + c * size, *p1 = p0 + size - 1; p0 < p1; ++p0, --p1)
114  {
115  swapByte = *p0;
116  *p0 = *p1;
117  *p1 = swapByte;
118  }
119  }
120  }
121 
124  static FORCEINLINE unsigned int mostSignificantBitSet(unsigned int value)
125  {
126  unsigned int result = 0;
127  while (value != 0) {
128  ++result;
129  value >>= 1;
130  }
131  return result-1;
132  }
138  {
139  --n;
140  n |= n >> 16;
141  n |= n >> 8;
142  n |= n >> 4;
143  n |= n >> 2;
144  n |= n >> 1;
145  ++n;
146  return n;
147  }
151  template<typename T>
152  static FORCEINLINE bool isPO2(T n)
153  {
154  return (n & (n-1)) == 0;
155  }
159  template<typename T>
160  static FORCEINLINE unsigned int getBitShift(T mask)
161  {
162  if (mask == 0)
163  return 0;
164 
165  unsigned int result = 0;
166  while ((mask & 1) == 0) {
167  ++result;
168  mask >>= 1;
169  }
170  return result;
171  }
172 
178  template<typename SrcT, typename DestT>
179  static inline DestT convertBitPattern(SrcT srcValue, SrcT srcBitMask, DestT destBitMask)
180  {
181  // Mask off irrelevant source value bits (if any)
182  srcValue = srcValue & srcBitMask;
183 
184  // Shift source down to bottom of DWORD
185  const unsigned int srcBitShift = getBitShift(srcBitMask);
186  srcValue >>= srcBitShift;
187 
188  // Get max value possible in source from srcMask
189  const SrcT srcMax = srcBitMask >> srcBitShift;
190 
191  // Get max available in dest
192  const unsigned int destBitShift = getBitShift(destBitMask);
193  const DestT destMax = destBitMask >> destBitShift;
194 
195  // Scale source value into destination, and shift back
196  DestT destValue = (srcValue * destMax) / srcMax;
197  return (destValue << destBitShift);
198  }
199 
204  static inline unsigned int fixedToFixed(uint32 value, unsigned int n, unsigned int p)
205  {
206  if(n > p)
207  {
208  // Less bits required than available; this is easy
209  value >>= n-p;
210  }
211  else if(n < p)
212  {
213  // More bits required than are there, do the fill
214  // Use old fashioned division, probably better than a loop
215  if(value == 0)
216  value = 0;
217  else if(value == (static_cast<unsigned int>(1)<<n)-1)
218  value = (1<<p)-1;
219  else value = value*(1<<p)/((1<<n)-1);
220  }
221  return value;
222  }
223 
228  static inline unsigned int floatToFixed(const float value, const unsigned int bits)
229  {
230  if(value <= 0.0f) return 0;
231  else if (value >= 1.0f) return (1<<bits)-1;
232  else return (unsigned int)(value * (1<<bits));
233  }
234 
238  static inline float fixedToFloat(unsigned value, unsigned int bits)
239  {
240  return (float)value/(float)((1<<bits)-1);
241  }
242 
246  static inline void intWrite(void *dest, const int n, const unsigned int value)
247  {
248  switch(n) {
249  case 1:
250  ((uint8*)dest)[0] = (uint8)value;
251  break;
252  case 2:
253  ((uint16*)dest)[0] = (uint16)value;
254  break;
255  case 3:
256 #if OGRE_ENDIAN == OGRE_ENDIAN_BIG
257  ((uint8*)dest)[0] = (uint8)((value >> 16) & 0xFF);
258  ((uint8*)dest)[1] = (uint8)((value >> 8) & 0xFF);
259  ((uint8*)dest)[2] = (uint8)(value & 0xFF);
260 #else
261  ((uint8*)dest)[2] = (uint8)((value >> 16) & 0xFF);
262  ((uint8*)dest)[1] = (uint8)((value >> 8) & 0xFF);
263  ((uint8*)dest)[0] = (uint8)(value & 0xFF);
264 #endif
265  break;
266  case 4:
267  ((uint32*)dest)[0] = (uint32)value;
268  break;
269  }
270  }
274  static inline unsigned int intRead(const void *src, int n) {
275  switch(n) {
276  case 1:
277  return ((const uint8*)src)[0];
278  case 2:
279  return ((const uint16*)src)[0];
280  case 3:
281 #if OGRE_ENDIAN == OGRE_ENDIAN_BIG
282  return ((uint32)((const uint8*)src)[0]<<16)|
283  ((uint32)((const uint8*)src)[1]<<8)|
284  ((uint32)((const uint8*)src)[2]);
285 #else
286  return ((uint32)((const uint8*)src)[0])|
287  ((uint32)((const uint8*)src)[1]<<8)|
288  ((uint32)((const uint8*)src)[2]<<16);
289 #endif
290  case 4:
291  return ((const uint32*)src)[0];
292  }
293  return 0; // ?
294  }
295 
299  static inline uint16 floatToHalf(float i)
300  {
301  union { float f; uint32 i; } v;
302  v.f = i;
303  return floatToHalfI(v.i);
304  }
307  static inline uint16 floatToHalfI(uint32 i)
308  {
309  register int s = (i >> 16) & 0x00008000;
310  register int e = ((i >> 23) & 0x000000ff) - (127 - 15);
311  register int m = i & 0x007fffff;
312 
313  if (e <= 0)
314  {
315  if (e < -10)
316  {
317  return 0;
318  }
319  m = (m | 0x00800000) >> (1 - e);
320 
321  return static_cast<uint16>(s | (m >> 13));
322  }
323  else if (e == 0xff - (127 - 15))
324  {
325  if (m == 0) // Inf
326  {
327  return static_cast<uint16>(s | 0x7c00);
328  }
329  else // NAN
330  {
331  m >>= 13;
332  return static_cast<uint16>(s | 0x7c00 | m | (m == 0));
333  }
334  }
335  else
336  {
337  if (e > 30) // Overflow
338  {
339  return static_cast<uint16>(s | 0x7c00);
340  }
341 
342  return static_cast<uint16>(s | (e << 10) | (m >> 13));
343  }
344  }
345 
350  static inline float halfToFloat(uint16 y)
351  {
352  union { float f; uint32 i; } v;
353  v.i = halfToFloatI(y);
354  return v.f;
355  }
359  static inline uint32 halfToFloatI(uint16 y)
360  {
361  register int s = (y >> 15) & 0x00000001;
362  register int e = (y >> 10) & 0x0000001f;
363  register int m = y & 0x000003ff;
364 
365  if (e == 0)
366  {
367  if (m == 0) // Plus or minus zero
368  {
369  return s << 31;
370  }
371  else // Denormalized number -- renormalize it
372  {
373  while (!(m & 0x00000400))
374  {
375  m <<= 1;
376  e -= 1;
377  }
378 
379  e += 1;
380  m &= ~0x00000400;
381  }
382  }
383  else if (e == 31)
384  {
385  if (m == 0) // Inf
386  {
387  return (s << 31) | 0x7f800000;
388  }
389  else // NaN
390  {
391  return (s << 31) | 0x7f800000 | (m << 13);
392  }
393  }
394 
395  e = e + (127 - 15);
396  m = m << 13;
397 
398  return (s << 31) | (e << 23) | m;
399  }
400 
401 
402  };
406 }
407 
408 #endif
static unsigned int intRead(const void *src, int n)
Read a n*8 bits integer value to memory in native endian.
Definition: OgreBitwise.h:274
static FORCEINLINE uint16 bswap16(uint16 arg)
Returns value with reversed bytes order.
Definition: OgreBitwise.h:52
unsigned long long uint64
Definition: OgrePlatform.h:355
static float halfToFloat(uint16 y)
Convert a float16 (NV_half_float) to a float32 Courtesy of OpenEXR.
Definition: OgreBitwise.h:350
static FORCEINLINE unsigned int mostSignificantBitSet(unsigned int value)
Returns the most significant bit set in a value.
Definition: OgreBitwise.h:124
static float fixedToFloat(unsigned value, unsigned int bits)
Fixed point to float.
Definition: OgreBitwise.h:238
unsigned char uint8
Definition: OgrePlatform.h:346
static void bswapChunks(void *pData, size_t size, size_t count)
Reverses byte order of chunks in buffer, where 'size' is size of one chunk.
Definition: OgreBitwise.h:108
static uint16 floatToHalf(float i)
Convert a float32 to a float16 (NV_half_float) Courtesy of OpenEXR.
Definition: OgreBitwise.h:299
static FORCEINLINE uint32 bswap32(uint32 arg)
Returns value with reversed bytes order.
Definition: OgreBitwise.h:64
static void intWrite(void *dest, const int n, const unsigned int value)
Write a n*8 bits integer value to memory in native endian.
Definition: OgreBitwise.h:246
static FORCEINLINE bool isPO2(T n)
Determines whether the number is power-of-two or not.
Definition: OgreBitwise.h:152
unsigned int uint32
Definition: OgrePlatform.h:344
Class for manipulating bit patterns.
Definition: OgreBitwise.h:48
static uint16 floatToHalfI(uint32 i)
Converts float in uint32 format to a a half in uint16 format.
Definition: OgreBitwise.h:307
static void bswapBuffer(void *pData, size_t size)
Reverses byte order of buffer.
Definition: OgreBitwise.h:96
static unsigned int floatToFixed(const float value, const unsigned int bits)
Convert floating point colour channel value between 0.0 and 1.0 (otherwise clamped) to integer of a c...
Definition: OgreBitwise.h:228
static FORCEINLINE unsigned int getBitShift(T mask)
Returns the number of bits a pattern must be shifted right by to remove right-hand zeros.
Definition: OgreBitwise.h:160
static uint32 halfToFloatI(uint16 y)
Converts a half in uint16 format to a float in uint32 format.
Definition: OgreBitwise.h:359
static DestT convertBitPattern(SrcT srcValue, SrcT srcBitMask, DestT destBitMask)
Takes a value with a given src bit mask, and produces another value with a desired bit mask.
Definition: OgreBitwise.h:179
static FORCEINLINE uint64 bswap64(uint64 arg)
Returns value with reversed bytes order.
Definition: OgreBitwise.h:76
static unsigned int fixedToFixed(uint32 value, unsigned int n, unsigned int p)
Convert N bit colour channel value to P bits.
Definition: OgreBitwise.h:204
#define FORCEINLINE
Definition: OgrePlatform.h:102
static FORCEINLINE uint32 firstPO2From(uint32 n)
Returns the closest power-of-two number greater or equal to value.
Definition: OgreBitwise.h:137
unsigned short uint16
Definition: OgrePlatform.h:345