386361c64ccd1b26ca5b8e8eb5f5010c1f5661bc
[Faustine.git] / interpretor / libsndfile-1.0.25 / src / sfendian.h
1 /*
2 ** Copyright (C) 1999-2011 Erik de Castro Lopo <erikd@mega-nerd.com>
3 **
4 ** This program is free software; you can redistribute it and/or modify
5 ** it under the terms of the GNU Lesser General Public License as published by
6 ** the Free Software Foundation; either version 2.1 of the License, or
7 ** (at your option) any later version.
8 **
9 ** This program is distributed in the hope that it will be useful,
10 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
11 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 ** GNU Lesser General Public License for more details.
13 **
14 ** You should have received a copy of the GNU Lesser General Public License
15 ** along with this program; if not, write to the Free Software
16 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 */
18
19 #ifndef SFENDIAN_INCLUDED
20 #define SFENDIAN_INCLUDED
21
22 #include "sfconfig.h"
23
24 #if HAVE_STDINT_H
25 #include <stdint.h>
26 #elif HAVE_INTTYPES_H
27 #include <inttypes.h>
28 #endif
29
30 #if (defined (SIZEOF_INT64_T) && (SIZEOF_INT64_T == 8))
31 /* Good, we have int64_t. */
32 #elif (defined (SIZEOF_LONG_LONG) && (SIZEOF_LONG_LONG == 8))
33 typedef long long int64_t ;
34 #elif (defined (SIZEOF_LONG) && (SIZEOF_LONG == 8))
35 typedef long int64_t ;
36 #elif (defined (WIN32) || defined (_WIN32))
37 typedef __int64 int64_t ;
38 #else
39 #error "No 64 bit integer type."
40 #endif
41
42 #if HAVE_BYTESWAP_H
43
44 #include <byteswap.h>
45
46 #define ENDSWAP_SHORT(x) ((short) bswap_16 (x))
47 #define ENDSWAP_INT(x) ((int) bswap_32 (x))
48
49 #else
50
51 #define ENDSWAP_SHORT(x) ((((x) >> 8) & 0xFF) + (((x) & 0xFF) << 8))
52 #define ENDSWAP_INT(x) ((((x) >> 24) & 0xFF) + (((x) >> 8) & 0xFF00) + (((x) & 0xFF00) << 8) + (((x) & 0xFF) << 24))
53
54 #endif
55
56 /*
57 ** Many file types (ie WAV, AIFF) use sets of four consecutive bytes as a
58 ** marker indicating different sections of the file.
59 ** The following MAKE_MARKER macro allows th creation of integer constants
60 ** for these markers.
61 */
62
63 #if (CPU_IS_LITTLE_ENDIAN == 1)
64 #define MAKE_MARKER(a,b,c,d) ((a) | ((b) << 8) | ((c) << 16) | ((d) << 24))
65 #elif (CPU_IS_BIG_ENDIAN == 1)
66 #define MAKE_MARKER(a,b,c,d) (((a) << 24) | ((b) << 16) | ((c) << 8) | (d))
67 #else
68 #error "Target CPU endian-ness unknown. May need to hand edit src/sfconfig.h"
69 #endif
70
71 /*
72 ** Macros to handle reading of data of a specific endian-ness into host endian
73 ** shorts and ints. The single input is an unsigned char* pointer to the start
74 ** of the object. There are two versions of each macro as we need to deal with
75 ** both big and little endian CPUs.
76 */
77
78 #if (CPU_IS_LITTLE_ENDIAN == 1)
79 #define LES2H_SHORT(x) (x)
80 #define LEI2H_INT(x) (x)
81
82 #define BES2H_SHORT(x) ENDSWAP_SHORT (x)
83 #define BEI2H_INT(x) ENDSWAP_INT (x)
84
85 #define H2BE_SHORT(x) ENDSWAP_SHORT (x)
86 #define H2BE_INT(x) ENDSWAP_INT (x)
87
88 #elif (CPU_IS_BIG_ENDIAN == 1)
89 #define LES2H_SHORT(x) ENDSWAP_SHORT (x)
90 #define LEI2H_INT(x) ENDSWAP_INT (x)
91
92 #define BES2H_SHORT(x) (x)
93 #define BEI2H_INT(x) (x)
94
95 #define H2LE_SHORT(x) ENDSWAP_SHORT (x)
96 #define H2LE_INT(x) ENDSWAP_INT (x)
97
98 #else
99 #error "Target CPU endian-ness unknown. May need to hand edit src/sfconfig.h"
100 #endif
101
102 #define LET2H_SHORT_PTR(x) ((x) [1] + ((x) [2] << 8))
103 #define LET2H_INT_PTR(x) (((x) [0] << 8) + ((x) [1] << 16) + ((x) [2] << 24))
104
105 #define BET2H_SHORT_PTR(x) (((x) [0] << 8) + (x) [1])
106 #define BET2H_INT_PTR(x) (((x) [0] << 24) + ((x) [1] << 16) + ((x) [2] << 8))
107
108 /*-----------------------------------------------------------------------------------------------
109 ** Generic functions for performing endian swapping on integer arrays.
110 */
111
112 static inline void
113 endswap_short_array (short *ptr, int len)
114 { short temp ;
115
116 while (--len >= 0)
117 { temp = ptr [len] ;
118 ptr [len] = ENDSWAP_SHORT (temp) ;
119 } ;
120 } /* endswap_short_array */
121
122 static inline void
123 endswap_short_copy (short *dest, const short *src, int len)
124 {
125 while (--len >= 0)
126 { dest [len] = ENDSWAP_SHORT (src [len]) ;
127 } ;
128 } /* endswap_short_copy */
129
130 static inline void
131 endswap_int_array (int *ptr, int len)
132 { int temp ;
133
134 while (--len >= 0)
135 { temp = ptr [len] ;
136 ptr [len] = ENDSWAP_INT (temp) ;
137 } ;
138 } /* endswap_int_array */
139
140 static inline void
141 endswap_int_copy (int *dest, const int *src, int len)
142 {
143 while (--len >= 0)
144 { dest [len] = ENDSWAP_INT (src [len]) ;
145 } ;
146 } /* endswap_int_copy */
147
148 /*========================================================================================
149 */
150
151 #if (HAVE_BYTESWAP_H && defined (SIZEOF_INT64_T) && (SIZEOF_INT64_T == 8))
152
153 static inline void
154 endswap_int64_t_array (int64_t *ptr, int len)
155 { int64_t value ;
156
157 while (--len >= 0)
158 { value = ptr [len] ;
159 ptr [len] = bswap_64 (value) ;
160 } ;
161 } /* endswap_int64_t_array */
162
163 static inline void
164 endswap_int64_t_copy (int64_t *dest, const int64_t *src, int len)
165 { int64_t value ;
166
167 while (--len >= 0)
168 { value = src [len] ;
169 dest [len] = bswap_64 (value) ;
170 } ;
171 } /* endswap_int64_t_copy */
172
173 #else
174
175 static inline void
176 endswap_int64_t_array (int64_t *ptr, int len)
177 { unsigned char *ucptr, temp ;
178
179 ucptr = (unsigned char *) ptr ;
180 ucptr += 8 * len ;
181 while (--len >= 0)
182 { ucptr -= 8 ;
183
184 temp = ucptr [0] ;
185 ucptr [0] = ucptr [7] ;
186 ucptr [7] = temp ;
187
188 temp = ucptr [1] ;
189 ucptr [1] = ucptr [6] ;
190 ucptr [6] = temp ;
191
192 temp = ucptr [2] ;
193 ucptr [2] = ucptr [5] ;
194 ucptr [5] = temp ;
195
196 temp = ucptr [3] ;
197 ucptr [3] = ucptr [4] ;
198 ucptr [4] = temp ;
199 } ;
200 } /* endswap_int64_t_array */
201
202 static inline void
203 endswap_int64_t_copy (int64_t *dest, const int64_t *src, int len)
204 { const unsigned char *psrc ;
205 unsigned char *pdest ;
206
207 if (dest == src)
208 { endswap_int64_t_array (dest, len) ;
209 return ;
210 } ;
211
212 psrc = ((const unsigned char *) src) + 8 * len ;
213 pdest = ((unsigned char *) dest) + 8 * len ;
214 while (--len >= 0)
215 { psrc -= 8 ;
216 pdest -= 8 ;
217
218 pdest [0] = psrc [7] ;
219 pdest [2] = psrc [5] ;
220 pdest [4] = psrc [3] ;
221 pdest [6] = psrc [1] ;
222 pdest [7] = psrc [0] ;
223 pdest [1] = psrc [6] ;
224 pdest [3] = psrc [4] ;
225 pdest [5] = psrc [2] ;
226 } ;
227 } /* endswap_int64_t_copy */
228
229 #endif
230
231 /* A couple of wrapper functions. */
232
233 static inline void
234 endswap_float_array (float *ptr, int len)
235 { endswap_int_array ((void *) ptr, len) ;
236 } /* endswap_float_array */
237
238 static inline void
239 endswap_double_array (double *ptr, int len)
240 { endswap_int64_t_array ((void *) ptr, len) ;
241 } /* endswap_double_array */
242
243 static inline void
244 endswap_float_copy (float *dest, const float *src, int len)
245 { endswap_int_copy ((int *) dest, (const int *) src, len) ;
246 } /* endswap_float_copy */
247
248 static inline void
249 endswap_double_copy (double *dest, const double *src, int len)
250 { endswap_int64_t_copy ((int64_t *) dest, (const int64_t *) src, len) ;
251 } /* endswap_double_copy */
252
253 #endif /* SFENDIAN_INCLUDED */
254