2 ** Copyright (C) 1999-2006 Erik de Castro Lopo <erikd@mega-nerd.com>
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.
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.
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.
27 #if (defined (SIZEOF_INT64_T) && (SIZEOF_INT64_T == 8))
28 /* Good, we have int64_t. */
29 #elif (defined (SIZEOF_LONG_LONG) && (SIZEOF_LONG_LONG == 8))
30 typedef long long int64_t ;
31 #elif (defined (SIZEOF_LONG) && (SIZEOF_LONG == 8))
32 typedef long int64_t ;
33 #elif (defined (WIN32) || defined (_WIN32))
34 typedef __int64 int64_t ;
36 #error "No 64 bit integer type."
43 #define ENDSWAP_SHORT(x) ((short) bswap_16 (x))
44 #define ENDSWAP_INT(x) ((int) bswap_32 (x))
48 #define ENDSWAP_SHORT(x) ((((x) >> 8) & 0xFF) + (((x) & 0xFF) << 8))
49 #define ENDSWAP_INT(x) ((((x) >> 24) & 0xFF) + (((x) >> 8) & 0xFF00) + (((x) & 0xFF00) << 8) + (((x) & 0xFF) << 24))
54 ** Many file types (ie WAV, AIFF) use sets of four consecutive bytes as a
55 ** marker indicating different sections of the file.
56 ** The following MAKE_MARKER macro allows th creation of integer constants
60 #if (CPU_IS_LITTLE_ENDIAN == 1)
61 #define MAKE_MARKER(a,b,c,d) ((a) | ((b) << 8) | ((c) << 16) | ((d) << 24))
62 #elif (CPU_IS_BIG_ENDIAN == 1)
63 #define MAKE_MARKER(a,b,c,d) (((a) << 24) | ((b) << 16) | ((c) << 8) | (d))
65 #error "Target CPU endian-ness unknown. May need to hand edit src/sfconfig.h"
69 ** Macros to handle reading of data of a specific endian-ness into host endian
70 ** shorts and ints. The single input is an unsigned char* pointer to the start
71 ** of the object. There are two versions of each macro as we need to deal with
72 ** both big and little endian CPUs.
75 #if (CPU_IS_LITTLE_ENDIAN == 1)
76 #define LES2H_SHORT(x) (x)
77 #define LEI2H_INT(x) (x)
79 #define BES2H_SHORT(x) ENDSWAP_SHORT (x)
80 #define BEI2H_INT(x) ENDSWAP_INT (x)
82 #define H2BE_SHORT(x) ENDSWAP_SHORT (x)
83 #define H2BE_INT(x) ENDSWAP_INT (x)
85 #elif (CPU_IS_BIG_ENDIAN == 1)
86 #define LES2H_SHORT(x) ENDSWAP_SHORT (x)
87 #define LEI2H_INT(x) ENDSWAP_INT (x)
89 #define BES2H_SHORT(x) (x)
90 #define BEI2H_INT(x) (x)
92 #define H2LE_SHORT(x) ENDSWAP_SHORT (x)
93 #define H2LE_INT(x) ENDSWAP_INT (x)
96 #error "Target CPU endian-ness unknown. May need to hand edit src/sfconfig.h"
99 #define LET2H_SHORT_PTR(x) ((x) [1] + ((x) [2] << 8))
100 #define LET2H_INT_PTR(x) (((x) [0] << 8) + ((x) [1] << 16) + ((x) [2] << 24))
102 #define BET2H_SHORT_PTR(x) (((x) [0] << 8) + (x) [1])
103 #define BET2H_INT_PTR(x) (((x) [0] << 24) + ((x) [1] << 16) + ((x) [2] << 8))
105 /*-----------------------------------------------------------------------------------------------
106 ** Generic functions for performing endian swapping on integer arrays.
110 endswap_short_array (short *ptr, int len)
115 ptr [len] = ENDSWAP_SHORT (temp) ;
117 } /* endswap_short_array */
120 endswap_short_copy (short *dest, const short *src, int len)
123 { dest [len] = ENDSWAP_SHORT (src [len]) ;
125 } /* endswap_short_copy */
128 endswap_int_array (int *ptr, int len)
133 ptr [len] = ENDSWAP_INT (temp) ;
135 } /* endswap_int_array */
138 endswap_int_copy (int *dest, const int *src, int len)
141 { dest [len] = ENDSWAP_INT (src [len]) ;
143 } /* endswap_int_copy */
145 /*========================================================================================
148 #if (HAVE_BYTESWAP_H && defined (SIZEOF_INT64_T) && (SIZEOF_INT64_T == 8))
151 endswap_int64_t_array (int64_t *ptr, int len)
155 { value = ptr [len] ;
156 ptr [len] = bswap_64 (value) ;
158 } /* endswap_int64_t_array */
161 endswap_int64_t_copy (int64_t *dest, const int64_t *src, int len)
165 { value = src [len] ;
166 dest [len] = bswap_64 (value) ;
168 } /* endswap_int64_t_copy */
173 endswap_int64_t_array (int64_t *ptr, int len)
174 { unsigned char *ucptr, temp ;
176 ucptr = (unsigned char *) ptr ;
182 ucptr [0] = ucptr [7] ;
186 ucptr [1] = ucptr [6] ;
190 ucptr [2] = ucptr [5] ;
194 ucptr [3] = ucptr [4] ;
197 } /* endswap_int64_t_array */
200 endswap_int64_t_copy (int64_t *dest, const int64_t *src, int len)
201 { const unsigned char *psrc ;
202 unsigned char *pdest ;
205 { endswap_int64_t_array (dest, len) ;
209 psrc = ((const unsigned char *) src) + 8 * len ;
210 pdest = ((unsigned char *) dest) + 8 * len ;
215 pdest [0] = psrc [7] ;
216 pdest [2] = psrc [5] ;
217 pdest [4] = psrc [3] ;
218 pdest [6] = psrc [1] ;
219 pdest [7] = psrc [0] ;
220 pdest [1] = psrc [6] ;
221 pdest [3] = psrc [4] ;
222 pdest [5] = psrc [2] ;
224 } /* endswap_int64_t_copy */
228 /* A couple of wrapper functions. */
231 endswap_float_array (float *ptr, int len)
232 { endswap_int_array ((void *) ptr, len) ;
233 } /* endswap_float_array */
236 endswap_double_array (double *ptr, int len)
237 { endswap_int64_t_array ((void *) ptr, len) ;
238 } /* endswap_double_array */
241 endswap_float_copy (float *dest, const float *src, int len)
242 { endswap_int_copy ((int *) dest, (const int *) src, len) ;
243 } /* endswap_float_copy */
246 endswap_double_copy (double *dest, const double *src, int len)
247 { endswap_int64_t_copy ((int64_t *) dest, (const int64_t *) src, len) ;
248 } /* endswap_double_copy */
251 ** Do not edit or modify anything in this comment block.
252 ** The arch-tag line is a file identity tag for the GNU Arch
253 ** revision control system.
255 ** arch-tag: f0c5cd54-42d3-4237-90ec-11fe24995de7