Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-02-21 09:30:07

0001 /*
0002 Open Asset Import Library (assimp)
0003 ----------------------------------------------------------------------
0004 
0005 Copyright (c) 2006-2024, assimp team
0006 
0007 All rights reserved.
0008 
0009 Redistribution and use of this software in source and binary forms,
0010 with or without modification, are permitted provided that the
0011 following conditions are met:
0012 
0013 * Redistributions of source code must retain the above
0014   copyright notice, this list of conditions and the
0015   following disclaimer.
0016 
0017 * Redistributions in binary form must reproduce the above
0018   copyright notice, this list of conditions and the
0019   following disclaimer in the documentation and/or other
0020   materials provided with the distribution.
0021 
0022 * Neither the name of the assimp team, nor the names of its
0023   contributors may be used to endorse or promote products
0024   derived from this software without specific prior
0025   written permission of the assimp team.
0026 
0027 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
0028 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
0029 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
0030 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
0031 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
0032 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
0033 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
0034 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
0035 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
0036 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
0037 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0038 
0039 ----------------------------------------------------------------------
0040 */
0041 
0042 /** @file Helper class tp perform various byte order swappings
0043    (e.g. little to big endian) */
0044 #pragma once
0045 #ifndef AI_BYTESWAPPER_H_INC
0046 #define AI_BYTESWAPPER_H_INC
0047 
0048 #ifdef __GNUC__
0049 #   pragma GCC system_header
0050 #endif
0051 
0052 #include <assimp/ai_assert.h>
0053 #include <assimp/types.h>
0054 #include <cstdint>
0055 
0056 #if _MSC_VER >= 1400
0057 #include <cstdlib>
0058 #endif
0059 
0060 namespace Assimp    {
0061 // --------------------------------------------------------------------------------------
0062 /** Defines some useful byte order swap routines.
0063  *
0064  * This is required to read big-endian model formats on little-endian machines,
0065  * and vice versa. Direct use of this class is DEPRECATED. Use #StreamReader instead. */
0066 // --------------------------------------------------------------------------------------
0067 class ByteSwap {
0068     ByteSwap() AI_NO_EXCEPT = default;
0069     ~ByteSwap() = default;
0070 
0071 public:
0072     // ----------------------------------------------------------------------
0073     /** Swap two bytes of data
0074      *  @param[inout] _szOut A void* to save the reintcasts for the caller. */
0075     static inline void Swap2(void* _szOut)
0076     {
0077         ai_assert(_szOut);
0078 
0079 #if _MSC_VER >= 1400
0080         uint16_t* const szOut = reinterpret_cast<uint16_t*>(_szOut);
0081         *szOut = _byteswap_ushort(*szOut);
0082 #else
0083         uint8_t* const szOut = reinterpret_cast<uint8_t*>(_szOut);
0084         std::swap(szOut[0],szOut[1]);
0085 #endif
0086     }
0087 
0088     // ----------------------------------------------------------------------
0089     /** Swap four bytes of data
0090      *  @param[inout] _szOut A void* to save the reintcasts for the caller. */
0091     static inline void Swap4(void* _szOut) {
0092         ai_assert(_szOut);
0093 
0094 #if _MSC_VER >= 1400
0095         uint32_t* const szOut = reinterpret_cast<uint32_t*>(_szOut);
0096         *szOut = _byteswap_ulong(*szOut);
0097 #else
0098         uint8_t* const szOut = reinterpret_cast<uint8_t*>(_szOut);
0099         std::swap(szOut[0],szOut[3]);
0100         std::swap(szOut[1],szOut[2]);
0101 #endif
0102     }
0103 
0104     // ----------------------------------------------------------------------
0105     /** Swap eight bytes of data
0106      *  @param[inout] _szOut A void* to save the reintcasts for the caller. */
0107     static inline void Swap8(void* _szOut)
0108     {
0109     ai_assert(_szOut);
0110 
0111 #if _MSC_VER >= 1400
0112         uint64_t* const szOut = reinterpret_cast<uint64_t*>(_szOut);
0113         *szOut = _byteswap_uint64(*szOut);
0114 #else
0115         uint8_t* const szOut = reinterpret_cast<uint8_t*>(_szOut);
0116         std::swap(szOut[0],szOut[7]);
0117         std::swap(szOut[1],szOut[6]);
0118         std::swap(szOut[2],szOut[5]);
0119         std::swap(szOut[3],szOut[4]);
0120 #endif
0121     }
0122 
0123     // ----------------------------------------------------------------------
0124     /** ByteSwap a float. Not a joke.
0125      *  @param[inout] fOut ehm. .. */
0126     static inline void Swap(float* fOut) {
0127         Swap4(fOut);
0128     }
0129 
0130     // ----------------------------------------------------------------------
0131     /** ByteSwap a double. Not a joke.
0132      *  @param[inout] fOut ehm. .. */
0133     static inline void Swap(double* fOut) {
0134         Swap8(fOut);
0135     }
0136 
0137 
0138     // ----------------------------------------------------------------------
0139     /** ByteSwap an int16t. Not a joke.
0140      *  @param[inout] fOut ehm. .. */
0141     static inline void Swap(int16_t* fOut) {
0142         Swap2(fOut);
0143     }
0144 
0145     static inline void Swap(uint16_t* fOut) {
0146         Swap2(fOut);
0147     }
0148 
0149     // ----------------------------------------------------------------------
0150     /** ByteSwap an int32t. Not a joke.
0151      *  @param[inout] fOut ehm. .. */
0152     static inline void Swap(int32_t* fOut){
0153         Swap4(fOut);
0154     }
0155 
0156     static inline void Swap(uint32_t* fOut){
0157         Swap4(fOut);
0158     }
0159 
0160     // ----------------------------------------------------------------------
0161     /** ByteSwap an int64t. Not a joke.
0162      *  @param[inout] fOut ehm. .. */
0163     static inline void Swap(int64_t* fOut) {
0164         Swap8(fOut);
0165     }
0166 
0167     static inline void Swap(uint64_t* fOut) {
0168         Swap8(fOut);
0169     }
0170 
0171     // ----------------------------------------------------------------------
0172     //! Templatized ByteSwap
0173     //! \returns param tOut as swapped
0174     template<typename Type>
0175     static inline Type Swapped(Type tOut)
0176     {
0177         return _swapper<Type,sizeof(Type)>()(tOut);
0178     }
0179 
0180 private:
0181 
0182     template <typename T, size_t size> struct _swapper;
0183 };
0184 
0185 template <typename T> struct ByteSwap::_swapper<T,2> {
0186     T operator() (T tOut) {
0187         Swap2(&tOut);
0188         return tOut;
0189     }
0190 };
0191 
0192 template <typename T> struct ByteSwap::_swapper<T,4> {
0193     T operator() (T tOut) {
0194         Swap4(&tOut);
0195         return tOut;
0196     }
0197 };
0198 
0199 template <typename T> struct ByteSwap::_swapper<T,8> {
0200     T operator() (T tOut) {
0201         Swap8(&tOut);
0202         return tOut;
0203     }
0204 };
0205 
0206 
0207 // --------------------------------------------------------------------------------------
0208 // ByteSwap macros for BigEndian/LittleEndian support
0209 // --------------------------------------------------------------------------------------
0210 #if (defined AI_BUILD_BIG_ENDIAN)
0211 #   define AI_LE(t) (t)
0212 #   define AI_BE(t) Assimp::ByteSwap::Swapped(t)
0213 #   define AI_LSWAP2(p)
0214 #   define AI_LSWAP4(p)
0215 #   define AI_LSWAP8(p)
0216 #   define AI_LSWAP2P(p)
0217 #   define AI_LSWAP4P(p)
0218 #   define AI_LSWAP8P(p)
0219 #   define LE_NCONST const
0220 #   define AI_SWAP2(p) Assimp::ByteSwap::Swap2(&(p))
0221 #   define AI_SWAP4(p) Assimp::ByteSwap::Swap4(&(p))
0222 #   define AI_SWAP8(p) Assimp::ByteSwap::Swap8(&(p))
0223 #   define AI_SWAP2P(p) Assimp::ByteSwap::Swap2((p))
0224 #   define AI_SWAP4P(p) Assimp::ByteSwap::Swap4((p))
0225 #   define AI_SWAP8P(p) Assimp::ByteSwap::Swap8((p))
0226 #   define BE_NCONST
0227 #else
0228 #   define AI_BE(t) (t)
0229 #   define AI_LE(t) Assimp::ByteSwap::Swapped(t)
0230 #   define AI_SWAP2(p)
0231 #   define AI_SWAP4(p)
0232 #   define AI_SWAP8(p)
0233 #   define AI_SWAP2P(p)
0234 #   define AI_SWAP4P(p)
0235 #   define AI_SWAP8P(p)
0236 #   define BE_NCONST const
0237 #   define AI_LSWAP2(p)     Assimp::ByteSwap::Swap2(&(p))
0238 #   define AI_LSWAP4(p)     Assimp::ByteSwap::Swap4(&(p))
0239 #   define AI_LSWAP8(p)     Assimp::ByteSwap::Swap8(&(p))
0240 #   define AI_LSWAP2P(p)    Assimp::ByteSwap::Swap2((p))
0241 #   define AI_LSWAP4P(p)    Assimp::ByteSwap::Swap4((p))
0242 #   define AI_LSWAP8P(p)    Assimp::ByteSwap::Swap8((p))
0243 #   define LE_NCONST
0244 #endif
0245 
0246 
0247 namespace Intern {
0248 
0249 // --------------------------------------------------------------------------------------------
0250 template <typename T, bool doit>
0251 struct ByteSwapper  {
0252     void operator() (T* inout) {
0253         ByteSwap::Swap(inout);
0254     }
0255 };
0256 
0257 template <typename T>
0258 struct ByteSwapper<T,false> {
0259     void operator() (T*) {
0260     }
0261 };
0262 
0263 // --------------------------------------------------------------------------------------------
0264 template <bool SwapEndianness, typename T, bool RuntimeSwitch>
0265 struct Getter {
0266     void operator() (T* inout, bool le) {
0267 #ifdef AI_BUILD_BIG_ENDIAN
0268         le =  le;
0269 #else
0270         le =  !le;
0271 #endif
0272         if (le) {
0273             ByteSwapper<T,(sizeof(T)>1?true:false)> () (inout);
0274         }
0275         else ByteSwapper<T,false> () (inout);
0276     }
0277 };
0278 
0279 template <bool SwapEndianness, typename T>
0280 struct Getter<SwapEndianness,T,false> {
0281 
0282     void operator() (T* inout, bool /*le*/) {
0283         // static branch
0284         ByteSwapper<T,(SwapEndianness && sizeof(T)>1)> () (inout);
0285     }
0286 };
0287 } // end Intern
0288 } // end Assimp
0289 
0290 #endif //!! AI_BYTESWAPPER_H_INC