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