1 //-----------------------------------------------------------------------------
2 //
3 // ImageLib Sources
4 // Copyright (C) 2000-2009 by Denton Woods
5 // Last modified: 01/29/2009
6 //
7 // Filename: src-IL/include/il_endian.h
8 //
9 // Description: Handles Endian-ness
10 //
11 //-----------------------------------------------------------------------------
12 
13 #ifndef IL_ENDIAN_H
14 #define IL_ENDIAN_H
15 
16 #include "il_internal.h"
17 #include <machine/endian.h>
18 
19 #if BYTE_ORDER == BIG_ENDIAN
20 	#define Short(s) iSwapShort(s)
21 	#define UShort(s) iSwapUShort(s)
22 	#define Int(i) iSwapInt(i)
23 	#define UInt(i) iSwapUInt(i)
24 	#define Float(f) iSwapFloat(f)
25 	#define Double(d) iSwapDouble(d)
26 
27 	#define BigShort(s)
28 	#define BigUShort(s)
29 	#define BigInt(i)
30 	#define BigUInt(i)
31 	#define BigFloat(f)
32 	#define BigDouble(d)
33 #else
34 	#define Short(s)
35 	#define UShort(s)
36 	#define Int(i)
37 	#define UInt(i)
38 	#define Float(f)
39 	#define Double(d)
40 
41 	#define BigShort(s) iSwapShort(s)
42 	#define BigUShort(s) iSwapUShort(s)
43 	#define BigInt(i) iSwapInt(i)
44 	#define BigUInt(i) iSwapUInt(i)
45 	#define BigFloat(f) iSwapFloat(f)
46 	#define BigDouble(d) iSwapDouble(d)
47 #endif
48 
49 void   iSwapUShort(ILushort *s);
50 void   iSwapShort(ILshort *s);
51 void   iSwapUInt(ILuint *i);
52 void   iSwapInt(ILint *i);
53 void   iSwapFloat(ILfloat *f);
54 void   iSwapDouble(ILdouble *d);
55 ILushort GetLittleUShort();
56 ILshort  GetLittleShort();
57 ILuint   GetLittleUInt();
58 ILint    GetLittleInt();
59 ILfloat  GetLittleFloat();
60 ILdouble GetLittleDouble();
61 ILushort GetBigUShort();
62 ILshort  GetBigShort();
63 ILuint   GetBigUInt();
64 ILint    GetBigInt();
65 ILfloat  GetBigFloat();
66 ILdouble GetBigDouble();
67 ILubyte SaveLittleUShort(ILushort s);
68 ILubyte SaveLittleShort(ILshort s);
69 ILubyte SaveLittleUInt(ILuint i);
70 ILubyte SaveLittleInt(ILint i);
71 ILubyte SaveLittleFloat(ILfloat f);
72 ILubyte SaveLittleDouble(ILdouble d);
73 ILubyte SaveBigUShort(ILushort s);
74 ILubyte SaveBigShort(ILshort s);
75 ILubyte SaveBigUInt(ILuint i);
76 ILubyte SaveBigInt(ILint i);
77 ILubyte SaveBigFloat(ILfloat f);
78 ILubyte SaveBigDouble(ILdouble d);
79 
80 #ifdef IL_ENDIAN_C
81 #undef NOINLINE
82 #undef INLINE
83 #define INLINE
84 #endif
85 
86 #ifndef NOINLINE
iSwapUShort(ILushort * s)87 INLINE void iSwapUShort(ILushort *s)  {
88 	#ifdef USE_WIN32_ASM
89 		__asm {
90 			mov ebx, s
91 			mov al, [ebx+1]
92 			mov ah, [ebx  ]
93 			mov [ebx], ax
94 		}
95 	#else
96 	#ifdef GCC_X86_ASM
97 		asm("ror $8,%0"
98 			: "=r" (*s)
99 			: "0" (*s));
100 	#else
101 		*s = ((*s)>>8) | ((*s)<<8);
102 	#endif //GCC_X86_ASM
103 	#endif //USE_WIN32_ASM
104 }
105 
iSwapShort(ILshort * s)106 INLINE void iSwapShort(ILshort *s) {
107 	iSwapUShort((ILushort*)s);
108 }
109 
iSwapUInt(ILuint * i)110 INLINE void iSwapUInt(ILuint *i) {
111 	#ifdef USE_WIN32_ASM
112 		__asm {
113 			mov ebx, i
114 			mov eax, [ebx]
115 			bswap eax
116 			mov [ebx], eax
117 		}
118 	#else
119 	#ifdef GCC_X86_ASM
120 			asm("bswap %0;"
121 				: "+r" (*i));
122 	#else
123 		*i = ((*i)>>24) | (((*i)>>8) & 0xff00) | (((*i)<<8) & 0xff0000) | ((*i)<<24);
124 	#endif //GCC_X86_ASM
125 	#endif //USE_WIN32_ASM
126 }
127 
iSwapInt(ILint * i)128 INLINE void iSwapInt(ILint *i) {
129 	iSwapUInt((ILuint*)i);
130 }
131 
iSwapFloat(ILfloat * f)132 INLINE void iSwapFloat(ILfloat *f) {
133 	iSwapUInt((ILuint*)f);
134 }
135 
iSwapDouble(ILdouble * d)136 INLINE void iSwapDouble(ILdouble *d) {
137 	#ifdef GCC_X86_ASM
138 	int *t = (int*)d;
139 	asm("bswap %2    \n"
140 		"bswap %3    \n"
141 		"movl  %2,%1 \n"
142 		"movl  %3,%0 \n"
143 		: "=g" (t[0]), "=g" (t[1])
144 		: "r"  (t[0]), "r"  (t[1]));
145 	#else
146 	ILubyte t,*b = (ILubyte*)d;
147 	#define dswap(x,y) t=b[x];b[x]=b[y];b[y]=b[x];
148 	dswap(0,7);
149 	dswap(1,6);
150 	dswap(2,5);
151 	dswap(3,4);
152 	#undef dswap
153 	#endif
154 }
155 
156 
GetLittleUShort()157 INLINE ILushort GetLittleUShort() {
158 	ILushort s;
159 	iread(&s, sizeof(ILushort), 1);
160 #if BYTE_ORDER == BIG_ENDIAN
161 	iSwapUShort(&s);
162 #endif
163 	return s;
164 }
165 
GetLittleShort()166 INLINE ILshort GetLittleShort() {
167 	ILshort s;
168 	iread(&s, sizeof(ILshort), 1);
169 #if BYTE_ORDER == BIG_ENDIAN
170 	iSwapShort(&s);
171 #endif
172 	return s;
173 }
174 
GetLittleUInt()175 INLINE ILuint GetLittleUInt() {
176 	ILuint i;
177 	iread(&i, sizeof(ILuint), 1);
178 #if BYTE_ORDER == BIG_ENDIAN
179 	iSwapUInt(&i);
180 #endif
181 	return i;
182 }
183 
GetLittleInt()184 INLINE ILint GetLittleInt() {
185 	ILint i;
186 	iread(&i, sizeof(ILint), 1);
187 #if BYTE_ORDER == BIG_ENDIAN
188 	iSwapInt(&i);
189 #endif
190 	return i;
191 }
192 
GetLittleFloat()193 INLINE ILfloat GetLittleFloat() {
194 	ILfloat f;
195 	iread(&f, sizeof(ILfloat), 1);
196 #if BYTE_ORDER == BIG_ENDIAN
197 	iSwapFloat(&f);
198 #endif
199 	return f;
200 }
201 
GetLittleDouble()202 INLINE ILdouble GetLittleDouble() {
203 	ILdouble d;
204 	iread(&d, sizeof(ILdouble), 1);
205 #if BYTE_ORDER == BIG_ENDIAN
206 	iSwapDouble(&d);
207 #endif
208 	return d;
209 }
210 
211 
GetBigUShort()212 INLINE ILushort GetBigUShort() {
213 	ILushort s;
214 	iread(&s, sizeof(ILushort), 1);
215 #if BYTE_ORDER == LITTLE_ENDIAN
216 	iSwapUShort(&s);
217 #endif
218 	return s;
219 }
220 
221 
GetBigShort()222 INLINE ILshort GetBigShort() {
223 	ILshort s;
224 	iread(&s, sizeof(ILshort), 1);
225 #if BYTE_ORDER == LITTLE_ENDIAN
226 	iSwapShort(&s);
227 #endif
228 	return s;
229 }
230 
231 
GetBigUInt()232 INLINE ILuint GetBigUInt() {
233 	ILuint i;
234 	iread(&i, sizeof(ILuint), 1);
235 #if BYTE_ORDER == LITTLE_ENDIAN
236 	iSwapUInt(&i);
237 #endif
238 	return i;
239 }
240 
241 
GetBigInt()242 INLINE ILint GetBigInt() {
243 	ILint i;
244 	iread(&i, sizeof(ILint), 1);
245 #if BYTE_ORDER == LITTLE_ENDIAN
246 	iSwapInt(&i);
247 #endif
248 	return i;
249 }
250 
251 
GetBigFloat()252 INLINE ILfloat GetBigFloat() {
253 	ILfloat f;
254 	iread(&f, sizeof(ILfloat), 1);
255 #if BYTE_ORDER == LITTLE_ENDIAN
256 	iSwapFloat(&f);
257 #endif
258 	return f;
259 }
260 
261 
GetBigDouble()262 INLINE ILdouble GetBigDouble() {
263 	ILdouble d;
264 	iread(&d, sizeof(ILdouble), 1);
265 #if BYTE_ORDER == LITTLE_ENDIAN
266 	iSwapDouble(&d);
267 #endif
268 	return d;
269 }
270 
SaveLittleUShort(ILushort s)271 INLINE ILubyte SaveLittleUShort(ILushort s) {
272 #if BYTE_ORDER == BIG_ENDIAN
273 	iSwapUShort(&s);
274 #endif
275 	return iwrite(&s, sizeof(ILushort), 1);
276 }
277 
SaveLittleShort(ILshort s)278 INLINE ILubyte SaveLittleShort(ILshort s) {
279 #if BYTE_ORDER == BIG_ENDIAN
280 	iSwapShort(&s);
281 #endif
282 	return iwrite(&s, sizeof(ILshort), 1);
283 }
284 
285 
SaveLittleUInt(ILuint i)286 INLINE ILubyte SaveLittleUInt(ILuint i) {
287 #if BYTE_ORDER == BIG_ENDIAN
288 	iSwapUInt(&i);
289 #endif
290 	return iwrite(&i, sizeof(ILuint), 1);
291 }
292 
293 
SaveLittleInt(ILint i)294 INLINE ILubyte SaveLittleInt(ILint i) {
295 #if BYTE_ORDER == BIG_ENDIAN
296 	iSwapInt(&i);
297 #endif
298 	return iwrite(&i, sizeof(ILint), 1);
299 }
300 
SaveLittleFloat(ILfloat f)301 INLINE ILubyte SaveLittleFloat(ILfloat f) {
302 #if BYTE_ORDER == BIG_ENDIAN
303 	iSwapFloat(&f);
304 #endif
305 	return iwrite(&f, sizeof(ILfloat), 1);
306 }
307 
308 
SaveLittleDouble(ILdouble d)309 INLINE ILubyte SaveLittleDouble(ILdouble d) {
310 #if BYTE_ORDER == BIG_ENDIAN
311 	iSwapDouble(&d);
312 #endif
313 	return iwrite(&d, sizeof(ILdouble), 1);
314 }
315 
316 
SaveBigUShort(ILushort s)317 INLINE ILubyte SaveBigUShort(ILushort s) {
318 #if BYTE_ORDER == LITTLE_ENDIAN
319 	iSwapUShort(&s);
320 #endif
321 	return iwrite(&s, sizeof(ILushort), 1);
322 }
323 
324 
SaveBigShort(ILshort s)325 INLINE ILubyte SaveBigShort(ILshort s) {
326 #if BYTE_ORDER == LITTLE_ENDIAN
327 	iSwapShort(&s);
328 #endif
329 	return iwrite(&s, sizeof(ILshort), 1);
330 }
331 
332 
SaveBigUInt(ILuint i)333 INLINE ILubyte SaveBigUInt(ILuint i) {
334 #if BYTE_ORDER == LITTLE_ENDIAN
335 	iSwapUInt(&i);
336 #endif
337 	return iwrite(&i, sizeof(ILuint), 1);
338 }
339 
340 
SaveBigInt(ILint i)341 INLINE ILubyte SaveBigInt(ILint i) {
342 #if BYTE_ORDER == LITTLE_ENDIAN
343 	iSwapInt(&i);
344 #endif
345 	return iwrite(&i, sizeof(ILint), 1);
346 }
347 
348 
SaveBigFloat(ILfloat f)349 INLINE ILubyte SaveBigFloat(ILfloat f) {
350 #if BYTE_ORDER == LITTLE_ENDIAN
351 	iSwapFloat(&f);
352 #endif
353 	return iwrite(&f, sizeof(ILfloat), 1);
354 }
355 
356 
SaveBigDouble(ILdouble d)357 INLINE ILubyte SaveBigDouble(ILdouble d) {
358 #if BYTE_ORDER == LITTLE_ENDIAN
359 	iSwapDouble(&d);
360 #endif
361 	return iwrite(&d, sizeof(ILdouble), 1);
362 }
363 #endif//NOINLINE
364 
365 void		EndianSwapData(void *_Image);
366 
367 #endif//ENDIAN_H
368