Re: [Algorithms] Byte Swapping
Brought to you by:
vexxed72
From: brian s. <br...@hu...> - 2000-07-18 02:00:08
|
> From: Charles Bloom <cb...@cb...> > > Jumping in late : I'm sure you don't need it now, but > here's a crazy ANSI C byte-swapper : > > let x = a 32 bit ulong , ABCD > then y = DCBA > > y = (x = x>>16 | x<<16) ^ (x = (x^x>>8) & 0x00FF00FF) ^ (x<<8); > wow, I'll say that's crazy...but unfortunately non-functional. see the results of this program: #include <stdio.h> long swap1(long x) { return (x = x>>16 | x<<16) ^ (x = (x^x>>8) & 0x00FF00FF) ^ (x<<8); } long swap2(long x) { return ((x >> 24) & 0x000000FF) | ((x >> 8 ) & 0x0000FF00) | ((x << 8 ) & 0x00FF0000) | ((x << 24) & 0xFF000000) ; } int main(int argc, char **argv) { long test = 0x01020304; printf("swap1: 0x%08X 0x%08X 0x%08X \n", test, swap1(test), swap1(swap1(test))); printf("swap2: 0x%08X 0x%08X 0x%08X \n", test, swap2(test), swap2(swap2(test))); } swap1: 0x01020304 0x07000300 0x03000700 swap2: 0x01020304 0x04030201 0x01020304 anyway, in case anyone hasn't gotten their fill of this stuff, here is our comparatively lame byteswapping code that uses those fast swappers on PowerPC: #ifndef _MBSWAP_H_ #define _MBSWAP_H_ // swapping macros/inlines #include <Runtime/MBBase.h> inline MBint16 MBSwap(const MBint16 & swap) { #if defined(MB_MAC) && defined(MB_POWERPC) return __lhbrx(const_cast<MBint16 *>(&swap), 0); #else return ((swap >> 8 ) & 0x00FF) | ((swap << 8 ) & 0xFF00) ; #endif } inline MBuint16 MBSwap(const MBuint16 & swap) { #if defined(MB_MAC) && defined(MB_POWERPC) return __lhbrx(const_cast<MBuint16 *>(&swap), 0); #else return ((swap >> 8 ) & 0x00FF) | ((swap << 8 ) & 0xFF00) ; #endif } inline MBint32 MBSwap(const MBint32 & swap) { #if defined(MB_MAC) && defined(MB_POWERPC) return __lwbrx(const_cast<MBint32 *>(&swap), 0); #else return ((swap >> 24) & 0x000000FF) | ((swap >> 8 ) & 0x0000FF00) | ((swap << 8 ) & 0x00FF0000) | ((swap << 24) & 0xFF000000) ; #endif } inline MBuint32 MBSwap(const MBuint32 & swap) { #if defined(MB_MAC) && defined(MB_POWERPC) return __lwbrx(const_cast<MBuint32 *>(&swap), 0); #else return ((swap >> 24) & 0x000000FF) | ((swap >> 8 ) & 0x0000FF00) | ((swap << 8 ) & 0x00FF0000) | ((swap << 24) & 0xFF000000) ; #endif } inline MBfloat MBSwap(const MBfloat & swap) { MBuint32 temp = *(const MBuint32*)&swap; temp = MBSwap(temp); return *(const MBfloat *)&temp; } #ifdef MB_MSB #define MBSwapMSBToNative( s ) s #define MBSwapNativeToMSB( s ) s #define MBSwapLSBToNative MBSwap #define MBSwapNativeToLSB MBSwap #elif defined(MB_LSB) #define MBSwapLSBToNative( s ) s #define MBSwapNativeToLSB( s ) s #define MBSwapMSBToNative MBSwap #define MBSwapNativeToMSB MBSwap #endif #endif // header guard |