TuttleOFX  1
EndianSwap.h
Go to the documentation of this file.
00001 // -*- mode: C++; tab-width: 4 -*-
00002 // vi: ts=4
00003 
00004 /*
00005  * Copyright (c) 2009, Patrick A. Palmer.
00006  * All rights reserved.
00007  *
00008  * Redistribution and use in source and binary forms, with or without 
00009  * modification, are permitted provided that the following conditions are met:
00010  *
00011  *   - Redistributions of source code must retain the above copyright notice,
00012  *     this list of conditions and the following disclaimer.
00013  *
00014  *   - Redistributions in binary form must reproduce the above copyright
00015  *     notice, this list of conditions and the following disclaimer in the
00016  *     documentation and/or other materials provided with the distribution.
00017  *
00018  *   - Neither the name of Patrick A. Palmer nor the names of its
00019  *     contributors may be used to endorse or promote products derived from
00020  *     this software without specific prior written permission.
00021  *
00022  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
00023  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
00024  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
00025  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 
00026  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
00027  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
00028  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
00029  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
00030  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
00031  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
00032  * POSSIBILITY OF SUCH DAMAGE.
00033  */
00034  
00035 
00036 #ifndef _DPX_ENDIANSWAP_H
00037 #define _DPX_ENDIANSWAP_H 1
00038 
00039 
00040 namespace dpx
00041 {
00042 
00043 template <typename T>
00044 T SwapBytes(T& value)
00045 {
00046         register unsigned char *pe, *ps = reinterpret_cast<unsigned char*>(&value);
00047         register unsigned char c;
00048         register size_t s = (sizeof(T));
00049 
00050         pe = ps + s - 1;
00051         for (size_t i = s/2; i > 0; i--)
00052         {
00053                 c = *ps;
00054                 *ps = *pe;
00055                 *pe = c;
00056 
00057                 ps++; pe--;
00058         }
00059         
00060         return value;
00061 }
00062 
00063 
00064 template <>
00065 inline unsigned short SwapBytes( unsigned short& value )
00066 {
00067         register unsigned char *p = reinterpret_cast<unsigned char*>(&value);
00068         register unsigned char c = p[0];
00069         p[0] = p[1];
00070         p[1] = c;
00071         return value;
00072 }
00073 
00074 template <>
00075 inline unsigned char SwapBytes( unsigned char& value )
00076 {
00077         return value;
00078 }
00079 
00080 
00081 template <>
00082 inline char SwapBytes( char& value )
00083 {
00084         return value;
00085 }
00086 
00087 
00088 template <typename T>
00089 void SwapBuffer(T *buf, unsigned int len)
00090 {
00091         for (unsigned int i = 0; i < len; i++)
00092                 SwapBytes(buf[i]);
00093 }
00094 
00095 
00096 template <DataSize SIZE>
00097 void EndianSwapImageBuffer(void *data, int length)
00098 {
00099         switch (SIZE)
00100         {
00101         case dpx::kByte:
00102                 break;
00103                                 
00104         case dpx::kWord:
00105                 SwapBuffer(reinterpret_cast<U16 *>(data), length);
00106                 break;
00107                                 
00108         case dpx::kInt:
00109                 SwapBuffer(reinterpret_cast<U32 *>(data), length);
00110                 break;
00111                                         
00112         case dpx::kFloat:
00113                 SwapBuffer(reinterpret_cast<R32 *>(data), length);
00114                 break;
00115                 
00116         case dpx::kDouble:
00117                 SwapBuffer(reinterpret_cast<R64 *>(data), length);
00118                 break;
00119         }
00120 }
00121 
00122 
00123 inline void EndianSwapImageBuffer(DataSize size, void *data, int length)
00124 {
00125         switch (size)
00126         {
00127         case dpx::kByte:
00128                 break;
00129                                 
00130         case dpx::kWord:
00131                 SwapBuffer(reinterpret_cast<U16 *>(data), length);
00132                 break;
00133                                 
00134         case dpx::kInt:
00135                 SwapBuffer(reinterpret_cast<U32 *>(data), length);
00136                 break;
00137                                         
00138         case dpx::kFloat:
00139                 SwapBuffer(reinterpret_cast<R32 *>(data), length);
00140                 break;
00141                 
00142         case dpx::kDouble:
00143                 SwapBuffer(reinterpret_cast<R64 *>(data), length);
00144                 break;
00145         }
00146 }
00147 
00148 
00149 }
00150 
00151 #endif
00152