1/*
2Open Asset Import Library (assimp)
3----------------------------------------------------------------------
4
5Copyright (c) 2006-2025, assimp team
6
7All rights reserved.
8
9Redistribution and use of this software in source and binary forms,
10with or without modification, are permitted provided that the
11following conditions are met:
12
13* Redistributions of source code must retain the above
14 copyright notice, this list of conditions and the
15 following disclaimer.
16
17* Redistributions in binary form must reproduce the above
18 copyright notice, this list of conditions and the
19 following disclaimer in the documentation and/or other
20 materials provided with the distribution.
21
22* Neither the name of the assimp team, nor the names of its
23 contributors may be used to endorse or promote products
24 derived from this software without specific prior
25 written permission of the assimp team.
26
27THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
28"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
29LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
30A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
31OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
32SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
33LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
34DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
35THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
36(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
37OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38
39----------------------------------------------------------------------
40*/
41
42/** @file Helper class tp perform various byte order swappings
43 (e.g. little to big endian) */
44#pragma once
45#ifndef AI_BYTESWAPPER_H_INC
46#define AI_BYTESWAPPER_H_INC
47
48#ifdef __GNUC__
49# pragma GCC system_header
50#endif
51
52#include <assimp/ai_assert.h>
53#include <assimp/types.h>
54#include <cstdint>
55
56#if _MSC_VER >= 1400
57#include <cstdlib>
58#endif
59
60namespace Assimp {
61// --------------------------------------------------------------------------------------
62/** Defines some useful byte order swap routines.
63 *
64 * This is required to read big-endian model formats on little-endian machines,
65 * and vice versa. Direct use of this class is DEPRECATED. Use #StreamReader instead. */
66// --------------------------------------------------------------------------------------
67class ByteSwap {
68 ByteSwap() AI_NO_EXCEPT = default;
69 ~ByteSwap() = default;
70
71public:
72 // ----------------------------------------------------------------------
73 /** Swap two bytes of data
74 * @param[inout] _szOut A void* to save the reintcasts for the caller. */
75 static inline void Swap2(void* _szOut)
76 {
77 ai_assert(_szOut);
78
79#if _MSC_VER >= 1400
80 uint16_t* const szOut = reinterpret_cast<uint16_t*>(_szOut);
81 *szOut = _byteswap_ushort(*szOut);
82#else
83 uint8_t* const szOut = reinterpret_cast<uint8_t*>(_szOut);
84 std::swap(a&: szOut[0],b&: szOut[1]);
85#endif
86 }
87
88 // ----------------------------------------------------------------------
89 /** Swap four bytes of data
90 * @param[inout] _szOut A void* to save the reintcasts for the caller. */
91 static inline void Swap4(void* _szOut) {
92 ai_assert(_szOut);
93
94#if _MSC_VER >= 1400
95 uint32_t* const szOut = reinterpret_cast<uint32_t*>(_szOut);
96 *szOut = _byteswap_ulong(*szOut);
97#else
98 uint8_t* const szOut = reinterpret_cast<uint8_t*>(_szOut);
99 std::swap(a&: szOut[0],b&: szOut[3]);
100 std::swap(a&: szOut[1],b&: szOut[2]);
101#endif
102 }
103
104 // ----------------------------------------------------------------------
105 /** Swap eight bytes of data
106 * @param[inout] _szOut A void* to save the reintcasts for the caller. */
107 static inline void Swap8(void* _szOut)
108 {
109 ai_assert(_szOut);
110
111#if _MSC_VER >= 1400
112 uint64_t* const szOut = reinterpret_cast<uint64_t*>(_szOut);
113 *szOut = _byteswap_uint64(*szOut);
114#else
115 uint8_t* const szOut = reinterpret_cast<uint8_t*>(_szOut);
116 std::swap(a&: szOut[0],b&: szOut[7]);
117 std::swap(a&: szOut[1],b&: szOut[6]);
118 std::swap(a&: szOut[2],b&: szOut[5]);
119 std::swap(a&: szOut[3],b&: szOut[4]);
120#endif
121 }
122
123 // ----------------------------------------------------------------------
124 /** ByteSwap a float. Not a joke.
125 * @param[inout] fOut ehm. .. */
126 static inline void Swap(float* fOut) {
127 Swap4(szOut: fOut);
128 }
129
130 // ----------------------------------------------------------------------
131 /** ByteSwap a double. Not a joke.
132 * @param[inout] fOut ehm. .. */
133 static inline void Swap(double* fOut) {
134 Swap8(szOut: fOut);
135 }
136
137
138 // ----------------------------------------------------------------------
139 /** ByteSwap an int16t. Not a joke.
140 * @param[inout] fOut ehm. .. */
141 static inline void Swap(int16_t* fOut) {
142 Swap2(szOut: fOut);
143 }
144
145 static inline void Swap(uint16_t* fOut) {
146 Swap2(szOut: fOut);
147 }
148
149 // ----------------------------------------------------------------------
150 /** ByteSwap an int32t. Not a joke.
151 * @param[inout] fOut ehm. .. */
152 static inline void Swap(int32_t* fOut){
153 Swap4(szOut: fOut);
154 }
155
156 static inline void Swap(uint32_t* fOut){
157 Swap4(szOut: fOut);
158 }
159
160 // ----------------------------------------------------------------------
161 /** ByteSwap an int64t. Not a joke.
162 * @param[inout] fOut ehm. .. */
163 static inline void Swap(int64_t* fOut) {
164 Swap8(szOut: fOut);
165 }
166
167 static inline void Swap(uint64_t* fOut) {
168 Swap8(szOut: fOut);
169 }
170
171 // ----------------------------------------------------------------------
172 //! Templatized ByteSwap
173 //! \returns param tOut as swapped
174 template<typename Type>
175 static inline Type Swapped(Type tOut)
176 {
177 return _swapper<Type,sizeof(Type)>()(tOut);
178 }
179
180private:
181
182 template <typename T, size_t size> struct _swapper;
183};
184
185template <typename T> struct ByteSwap::_swapper<T,2> {
186 T operator() (T tOut) {
187 Swap2(szOut: &tOut);
188 return tOut;
189 }
190};
191
192template <typename T> struct ByteSwap::_swapper<T,4> {
193 T operator() (T tOut) {
194 Swap4(szOut: &tOut);
195 return tOut;
196 }
197};
198
199template <typename T> struct ByteSwap::_swapper<T,8> {
200 T operator() (T tOut) {
201 Swap8(szOut: &tOut);
202 return tOut;
203 }
204};
205
206
207// --------------------------------------------------------------------------------------
208// ByteSwap macros for BigEndian/LittleEndian support
209// --------------------------------------------------------------------------------------
210#if (defined AI_BUILD_BIG_ENDIAN)
211# define AI_LE(t) (t)
212# define AI_BE(t) Assimp::ByteSwap::Swapped(t)
213# define AI_LSWAP2(p)
214# define AI_LSWAP4(p)
215# define AI_LSWAP8(p)
216# define AI_LSWAP2P(p)
217# define AI_LSWAP4P(p)
218# define AI_LSWAP8P(p)
219# define LE_NCONST const
220# define AI_SWAP2(p) Assimp::ByteSwap::Swap2(&(p))
221# define AI_SWAP4(p) Assimp::ByteSwap::Swap4(&(p))
222# define AI_SWAP8(p) Assimp::ByteSwap::Swap8(&(p))
223# define AI_SWAP2P(p) Assimp::ByteSwap::Swap2((p))
224# define AI_SWAP4P(p) Assimp::ByteSwap::Swap4((p))
225# define AI_SWAP8P(p) Assimp::ByteSwap::Swap8((p))
226# define BE_NCONST
227#else
228# define AI_BE(t) (t)
229# define AI_LE(t) Assimp::ByteSwap::Swapped(t)
230# define AI_SWAP2(p)
231# define AI_SWAP4(p)
232# define AI_SWAP8(p)
233# define AI_SWAP2P(p)
234# define AI_SWAP4P(p)
235# define AI_SWAP8P(p)
236# define BE_NCONST const
237# define AI_LSWAP2(p) Assimp::ByteSwap::Swap2(&(p))
238# define AI_LSWAP4(p) Assimp::ByteSwap::Swap4(&(p))
239# define AI_LSWAP8(p) Assimp::ByteSwap::Swap8(&(p))
240# define AI_LSWAP2P(p) Assimp::ByteSwap::Swap2((p))
241# define AI_LSWAP4P(p) Assimp::ByteSwap::Swap4((p))
242# define AI_LSWAP8P(p) Assimp::ByteSwap::Swap8((p))
243# define LE_NCONST
244#endif
245
246
247namespace Intern {
248
249// --------------------------------------------------------------------------------------------
250template <typename T, bool doit>
251struct ByteSwapper {
252 void operator() (T* inout) {
253 ByteSwap::Swap(inout);
254 }
255};
256
257template <typename T>
258struct ByteSwapper<T,false> {
259 void operator() (T*) {
260 }
261};
262
263// --------------------------------------------------------------------------------------------
264template <bool SwapEndianness, typename T, bool RuntimeSwitch>
265struct Getter {
266 void operator() (T* inout, bool le) {
267#ifdef AI_BUILD_BIG_ENDIAN
268 le = le;
269#else
270 le = !le;
271#endif
272 if (le) {
273 ByteSwapper<T,(sizeof(T)>1?true:false)> () (inout);
274 }
275 else ByteSwapper<T,false> () (inout);
276 }
277};
278
279template <bool SwapEndianness, typename T>
280struct Getter<SwapEndianness,T,false> {
281
282 void operator() (T* inout, bool /*le*/) {
283 // static branch
284 ByteSwapper<T,(SwapEndianness && sizeof(T)>1)> () (inout);
285 }
286};
287} // end Intern
288} // end Assimp
289
290#endif //!! AI_BYTESWAPPER_H_INC
291

source code of qtquick3d/src/3rdparty/assimp/src/include/assimp/ByteSwapper.h