Coverage Report

Created: 2025-07-13 06:57

/src/libsndfile/src/common.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
** Copyright (C) 1999-2019 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
#include <config.h>
20
21
#include <limits.h>
22
#include <stdarg.h>
23
#include <string.h>
24
#if HAVE_UNISTD_H
25
#include <unistd.h>
26
#else
27
#include "sf_unistd.h"
28
#endif
29
#include <ctype.h>
30
#include <math.h>
31
#include <time.h>
32
#if HAVE_SYS_TIME_H
33
#include <sys/time.h>
34
#endif
35
#include "sndfile.h"
36
#include "sfendian.h"
37
#include "common.h"
38
39
190k
#define INITIAL_HEADER_SIZE 256
40
41
/* Allocate and initialize the SF_PRIVATE struct. */
42
SF_PRIVATE *
43
psf_allocate (void)
44
41.8k
{ SF_PRIVATE * psf ;
45
46
41.8k
  if ((psf = calloc (1, sizeof (SF_PRIVATE))) == NULL)
47
0
    return  NULL ;
48
49
41.8k
  if ((psf->header.ptr = calloc (1, INITIAL_HEADER_SIZE)) == NULL)
50
0
  { free (psf) ;
51
0
    return  NULL ;
52
41.8k
    } ;
53
41.8k
  psf->header.len = INITIAL_HEADER_SIZE ;
54
55
41.8k
  return psf ;
56
41.8k
} /* psf_allocate */
57
58
static int
59
psf_bump_header_allocation (SF_PRIVATE * psf, sf_count_t needed)
60
106k
{
61
106k
  sf_count_t newlen, smallest = INITIAL_HEADER_SIZE ;
62
106k
  void * ptr ;
63
64
106k
  newlen = (needed > psf->header.len) ? 2 * SF_MAX (needed, smallest) : 2 * psf->header.len ;
65
66
106k
  if (newlen > 100 * 1024)
67
91.7k
  { psf_log_printf (psf, "Request for header allocation of %D denied.\n", newlen) ;
68
91.7k
    return 1 ;
69
91.7k
    }
70
71
14.6k
  if ((ptr = realloc (psf->header.ptr, newlen)) == NULL)
72
0
  { psf_log_printf (psf, "realloc (%p, %D) failed\n", psf->header.ptr, newlen) ;
73
0
    psf->error = SFE_MALLOC_FAILED ;
74
0
    return 1 ;
75
14.6k
    } ;
76
77
  /* Always zero-out new header memory to avoid un-initializer memory accesses. */
78
14.6k
  if (newlen > psf->header.len)
79
14.6k
    memset ((char *) ptr + psf->header.len, 0, newlen - psf->header.len) ;
80
81
14.6k
  psf->header.ptr = ptr ;
82
14.6k
  psf->header.len = newlen ;
83
14.6k
  return 0 ;
84
14.6k
} /* psf_bump_header_allocation */
85
86
/*-----------------------------------------------------------------------------------------------
87
** psf_log_printf allows libsndfile internal functions to print to an internal parselog which
88
** can later be displayed.
89
** The format specifiers are as for printf but without the field width and other modifiers.
90
** Printing is performed to the parselog char array of the SF_PRIVATE struct.
91
** Printing is done in such a way as to guarantee that the log never overflows the end of the
92
** parselog array.
93
*/
94
95
static inline void
96
log_putchar (SF_PRIVATE *psf, char ch)
97
1.37G
{ if (psf->parselog.indx < SIGNED_SIZEOF (psf->parselog.buf) - 1)
98
20.9M
  { psf->parselog.buf [psf->parselog.indx++] = ch ;
99
20.9M
    psf->parselog.buf [psf->parselog.indx] = 0 ;
100
20.9M
    } ;
101
1.37G
  return ;
102
1.37G
} /* log_putchar */
103
104
void
105
psf_log_printf (SF_PRIVATE *psf, const char *format, ...)
106
41.8M
{ va_list   ap ;
107
41.8M
  uint32_t  u, tens ;
108
41.8M
  int     d, shift, width, width_specifier, left_align, slen, precision ;
109
41.8M
  char    c, *strptr, istr [5], lead_char, sign_char ;
110
111
41.8M
  va_start (ap, format) ;
112
113
1.25G
  while ((c = *format++))
114
1.20G
  { if (c != '%')
115
1.13G
    { log_putchar (psf, c) ;
116
1.13G
      continue ;
117
1.13G
      } ;
118
119
70.0M
    if (format [0] == '%') /* Handle %% */
120
0
    {   log_putchar (psf, '%') ;
121
0
      format ++ ;
122
0
      continue ;
123
70.0M
      } ;
124
125
70.0M
    sign_char = 0 ;
126
70.0M
    left_align = SF_FALSE ;
127
70.2M
    while (1)
128
70.2M
    { switch (format [0])
129
70.2M
      { case ' ' :
130
0
        case '+' :
131
0
          sign_char = format [0] ;
132
0
          format ++ ;
133
0
          continue ;
134
135
156k
        case '-' :
136
156k
          left_align = SF_TRUE ;
137
156k
          format ++ ;
138
156k
          continue ;
139
140
70.0M
        default : break ;
141
70.2M
        } ;
142
143
70.0M
      break ;
144
70.2M
      } ;
145
146
70.0M
    if (format [0] == 0)
147
0
      break ;
148
149
70.0M
    lead_char = ' ' ;
150
70.0M
    if (format [0] == '0')
151
11.5M
      lead_char = '0' ;
152
153
70.0M
    width_specifier = 0 ;
154
93.5M
    while ((c = *format++) && isdigit (c))
155
23.5M
      width_specifier = width_specifier * 10 + (c - '0') ;
156
157
70.0M
    precision = 0 ;
158
70.0M
    if (c == '.')
159
0
    { while ((c = *format++) && isdigit (c))
160
0
        precision = precision * 10 + (c - '0') ;
161
0
      } ;
162
163
70.0M
    switch (c)
164
70.0M
    { case 0 : /* NULL character. */
165
0
          va_end (ap) ;
166
0
          return ;
167
168
3.36M
      case 's': /* string */
169
3.36M
          strptr = va_arg (ap, char *) ;
170
3.36M
          if (strptr == NULL)
171
0
            break ;
172
3.36M
          if (precision > 0)
173
0
            slen = strnlen (strptr, precision) ;
174
3.36M
          else
175
3.36M
            slen = strlen (strptr) ;
176
3.36M
          width_specifier = width_specifier >= slen ? width_specifier - slen : 0 ;
177
3.36M
          if (left_align == SF_FALSE)
178
3.20M
            while (width_specifier -- > 0)
179
0
              log_putchar (psf, ' ') ;
180
22.2M
          while (slen--)
181
18.8M
            log_putchar (psf, *strptr++) ;
182
5.01M
          while (width_specifier -- > 0)
183
1.65M
            log_putchar (psf, ' ') ;
184
3.36M
          break ;
185
186
31.0M
      case 'd': /* int */
187
31.0M
          d = va_arg (ap, int) ;
188
189
31.0M
          if (d < 0)
190
300k
          { sign_char = '-' ;
191
300k
            if (lead_char != '0' && left_align == SF_FALSE)
192
300k
              width_specifier -- ;
193
194
300k
            u = - ((unsigned) d) ;
195
300k
            }
196
30.7M
          else
197
30.7M
          { u = (unsigned) d ;
198
30.7M
            }
199
200
31.0M
          tens = 1 ;
201
31.0M
          width = 1 ;
202
64.5M
          while (u / tens >= 10)
203
33.4M
          { tens *= 10 ;
204
33.4M
            width ++ ;
205
33.4M
            } ;
206
207
31.0M
          width_specifier -= width ;
208
209
31.0M
          if (sign_char == ' ')
210
0
          { log_putchar (psf, ' ') ;
211
0
            width_specifier -- ;
212
0
            } ;
213
214
31.0M
          if (left_align == SF_FALSE && lead_char != '0')
215
31.0M
          { if (sign_char == '+')
216
0
              width_specifier -- ;
217
218
31.0M
            while (width_specifier -- > 0)
219
10.0k
              log_putchar (psf, lead_char) ;
220
31.0M
            } ;
221
222
31.0M
          if (sign_char == '+' || sign_char == '-')
223
300k
          { log_putchar (psf, sign_char) ;
224
300k
            width_specifier -- ;
225
300k
            } ;
226
227
31.0M
          if (left_align == SF_FALSE)
228
31.0M
            while (width_specifier -- > 0)
229
103
              log_putchar (psf, lead_char) ;
230
231
95.5M
          while (tens > 0)
232
64.5M
          { log_putchar (psf, '0' + u / tens) ;
233
64.5M
            u %= tens ;
234
64.5M
            tens /= 10 ;
235
64.5M
            } ;
236
237
31.0M
          while (width_specifier -- > 0)
238
0
            log_putchar (psf, lead_char) ;
239
31.0M
          break ;
240
241
490k
      case 'D': /* sf_count_t */
242
490k
          { sf_count_t  D ;
243
490k
            uint64_t  U, Tens ;
244
245
490k
            D = va_arg (ap, sf_count_t) ;
246
247
490k
            if (D == 0)
248
13.7k
            { while (-- width_specifier > 0)
249
0
                log_putchar (psf, lead_char) ;
250
13.7k
              log_putchar (psf, '0') ;
251
13.7k
              break ;
252
13.7k
              }
253
477k
            else
254
477k
            { if (D < 0)
255
148k
              { log_putchar (psf, '-') ;
256
148k
                U = - ((uint64_t) D) ;
257
148k
                }
258
328k
              else
259
328k
              { U = (uint64_t) D ;
260
328k
                }
261
477k
              }
262
263
477k
            Tens = 1 ;
264
477k
            width = 1 ;
265
3.51M
            while (U / Tens >= 10)
266
3.04M
            { Tens *= 10 ;
267
3.04M
              width ++ ;
268
3.04M
              } ;
269
270
477k
            while (width_specifier > width)
271
0
            { log_putchar (psf, lead_char) ;
272
0
              width_specifier-- ;
273
0
              } ;
274
275
3.99M
            while (Tens > 0)
276
3.51M
            { log_putchar (psf, '0' + U / Tens) ;
277
3.51M
              U %= Tens ;
278
3.51M
              Tens /= 10 ;
279
3.51M
              } ;
280
477k
            } ;
281
477k
          break ;
282
283
8.18M
      case 'u': /* unsigned int */
284
8.18M
          u = va_arg (ap, unsigned int) ;
285
286
8.18M
          tens = 1 ;
287
8.18M
          width = 1 ;
288
73.0M
          while (u / tens >= 10)
289
64.9M
          { tens *= 10 ;
290
64.9M
            width ++ ;
291
64.9M
            } ;
292
293
8.18M
          width_specifier -= width ;
294
295
8.18M
          if (sign_char == ' ')
296
0
          { log_putchar (psf, ' ') ;
297
0
            width_specifier -- ;
298
0
            } ;
299
300
8.18M
          if (left_align == SF_FALSE && lead_char != '0')
301
8.18M
          { if (sign_char == '+')
302
0
              width_specifier -- ;
303
304
8.20M
            while (width_specifier -- > 0)
305
25.6k
              log_putchar (psf, lead_char) ;
306
8.18M
            } ;
307
308
8.18M
          if (sign_char == '+' || sign_char == '-')
309
0
          { log_putchar (psf, sign_char) ;
310
0
            width_specifier -- ;
311
0
            } ;
312
313
8.18M
          if (left_align == SF_FALSE)
314
8.18M
            while (width_specifier -- > 0)
315
1.06k
              log_putchar (psf, lead_char) ;
316
317
81.2M
          while (tens > 0)
318
73.0M
          { log_putchar (psf, '0' + u / tens) ;
319
73.0M
            u %= tens ;
320
73.0M
            tens /= 10 ;
321
73.0M
            } ;
322
323
8.18M
          while (width_specifier -- > 0)
324
0
            log_putchar (psf, lead_char) ;
325
8.18M
          break ;
326
327
0
      case 'c': /* char */
328
0
          c = va_arg (ap, int) & 0xFF ;
329
0
          log_putchar (psf, c) ;
330
0
          break ;
331
332
4.79M
      case 'x': /* hex */
333
17.5M
      case 'X': /* hex */
334
17.5M
          d = va_arg (ap, int) ;
335
336
17.5M
          if (d == 0)
337
13.1M
          { while (--width_specifier > 0)
338
4.37M
              log_putchar (psf, lead_char) ;
339
8.72M
            log_putchar (psf, '0') ;
340
8.72M
            break ;
341
8.85M
            } ;
342
8.85M
          shift = 28 ;
343
8.85M
          width = (width_specifier < 8) ? 8 : width_specifier ;
344
59.4M
          while (! ((((uint32_t) 0xF) << shift) & d))
345
50.6M
          { shift -= 4 ;
346
50.6M
            width -- ;
347
50.6M
            } ;
348
349
9.90M
          while (width > 0 && width_specifier > width)
350
1.04M
          { log_putchar (psf, lead_char) ;
351
1.04M
            width_specifier-- ;
352
1.04M
            } ;
353
354
29.1M
          while (shift >= 0)
355
20.2M
          { c = (d >> shift) & 0xF ;
356
20.2M
            log_putchar (psf, (c > 9) ? c + 'A' - 10 : c + '0') ;
357
20.2M
            shift -= 4 ;
358
20.2M
            } ;
359
8.85M
          break ;
360
361
9.41M
      case 'M': /* int2str */
362
9.41M
          d = va_arg (ap, int) ;
363
9.41M
          if (CPU_IS_LITTLE_ENDIAN)
364
9.41M
          { istr [0] = d & 0xFF ;
365
9.41M
            istr [1] = (d >> 8) & 0xFF ;
366
9.41M
            istr [2] = (d >> 16) & 0xFF ;
367
9.41M
            istr [3] = (d >> 24) & 0xFF ;
368
9.41M
            }
369
0
          else
370
0
          { istr [3] = d & 0xFF ;
371
0
            istr [2] = (d >> 8) & 0xFF ;
372
0
            istr [1] = (d >> 16) & 0xFF ;
373
0
            istr [0] = (d >> 24) & 0xFF ;
374
0
            } ;
375
9.41M
          istr [4] = 0 ;
376
9.41M
          strptr = istr ;
377
46.2M
          while (*strptr)
378
36.8M
          { c = *strptr++ ;
379
36.8M
            log_putchar (psf, psf_isprint (c) ? c : '.') ;
380
36.8M
            } ;
381
9.41M
          break ;
382
383
0
      default :
384
0
          log_putchar (psf, '*') ;
385
0
          log_putchar (psf, c) ;
386
0
          log_putchar (psf, '*') ;
387
0
          break ;
388
70.0M
      } /* switch */
389
70.0M
    } /* while */
390
391
41.8M
  va_end (ap) ;
392
41.8M
  return ;
393
41.8M
} /* psf_log_printf */
394
395
/*-----------------------------------------------------------------------------------------------
396
**  ASCII header printf functions.
397
**  Some formats (ie NIST) use ascii text in their headers.
398
**  Format specifiers are the same as the standard printf specifiers (uses vsnprintf).
399
**  If this generates a compile error on any system, the author should be notified
400
**  so an alternative vsnprintf can be provided.
401
*/
402
403
void
404
psf_asciiheader_printf (SF_PRIVATE *psf, const char *format, ...)
405
0
{ va_list argptr ;
406
0
  int   maxlen ;
407
0
  char  *start ;
408
409
0
  if (! format)
410
0
    return ;
411
412
0
  maxlen = strlen ((char*) psf->header.ptr) ;
413
0
  start = ((char*) psf->header.ptr) + maxlen ;
414
0
  maxlen  = psf->header.len - maxlen ;
415
416
0
  va_start (argptr, format) ;
417
0
  vsnprintf (start, maxlen, format, argptr) ;
418
0
  va_end (argptr) ;
419
420
  /* Make sure the string is properly terminated. */
421
0
  start [maxlen - 1] = 0 ;
422
423
0
  psf->header.indx = strlen ((char*) psf->header.ptr) ;
424
425
0
  return ;
426
0
} /* psf_asciiheader_printf */
427
428
/*-----------------------------------------------------------------------------------------------
429
**  Binary header writing functions. Returns number of bytes written.
430
**
431
**  Format specifiers for psf_binheader_writef are as follows
432
**    m - marker - four bytes - no endian manipulation
433
**
434
**    e   - all following numerical values will be little endian
435
**    E   - all following numerical values will be big endian
436
**
437
**    t   - all following O types will be truncated to 4 bytes
438
**    T   - switch off truncation of all following O types
439
**
440
**    1 - single byte value
441
**    2 - two byte value
442
**    3 - three byte value
443
**    4 - four byte value
444
**    8 - eight byte value (sometimes written as 4 bytes)
445
**
446
**    s   - string preceded by a four byte length
447
**    S   - string including null terminator
448
**      p   - a Pascal string
449
**
450
**    f - floating point data
451
**    d - double precision floating point data
452
**    h - 16 binary bytes value
453
**
454
**    b - binary data (see below)
455
**    z   - zero bytes (ses below)
456
**    j - jump forwards or backwards
457
**
458
**  To write a word followed by an int (both little endian) use:
459
**    psf_binheader_writef ("e24", wordval, longval) ;
460
**
461
**  To write binary data use:
462
**    psf_binheader_writef ("b", &bindata, sizeof (bindata)) ;
463
**
464
**  To write N zero bytes use:
465
**      NOTE: due to platform issues (ie x86-64) you should cast the
466
**      argument to size_t or ensure the variable type is size_t.
467
**    psf_binheader_writef ("z", N) ;
468
*/
469
470
/* These macros may seem a bit messy but do prevent problems with processors which
471
** seg. fault when asked to write an int or short to a non-int/short aligned address.
472
*/
473
474
static inline void
475
header_put_byte (SF_PRIVATE *psf, char x)
476
0
{ psf->header.ptr [psf->header.indx++] = x ;
477
0
} /* header_put_byte */
478
479
#if (CPU_IS_BIG_ENDIAN == 1)
480
static inline void
481
header_put_marker (SF_PRIVATE *psf, int x)
482
{ psf->header.ptr [psf->header.indx++] = (x >> 24) ;
483
  psf->header.ptr [psf->header.indx++] = (x >> 16) ;
484
  psf->header.ptr [psf->header.indx++] = (x >> 8) ;
485
  psf->header.ptr [psf->header.indx++] = x ;
486
} /* header_put_marker */
487
488
#elif (CPU_IS_LITTLE_ENDIAN == 1)
489
static inline void
490
header_put_marker (SF_PRIVATE *psf, int x)
491
0
{ psf->header.ptr [psf->header.indx++] = x ;
492
0
  psf->header.ptr [psf->header.indx++] = (x >> 8) ;
493
0
  psf->header.ptr [psf->header.indx++] = (x >> 16) ;
494
0
  psf->header.ptr [psf->header.indx++] = (x >> 24) ;
495
0
} /* header_put_marker */
496
497
#else
498
# error "Cannot determine endian-ness of processor."
499
#endif
500
501
502
static inline void
503
header_put_be_short (SF_PRIVATE *psf, int x)
504
0
{ psf->header.ptr [psf->header.indx++] = (x >> 8) ;
505
0
  psf->header.ptr [psf->header.indx++] = x ;
506
0
} /* header_put_be_short */
507
508
static inline void
509
header_put_le_short (SF_PRIVATE *psf, int x)
510
0
{ psf->header.ptr [psf->header.indx++] = x ;
511
0
  psf->header.ptr [psf->header.indx++] = (x >> 8) ;
512
0
} /* header_put_le_short */
513
514
static inline void
515
header_put_be_3byte (SF_PRIVATE *psf, int x)
516
0
{ psf->header.ptr [psf->header.indx++] = (x >> 16) ;
517
0
  psf->header.ptr [psf->header.indx++] = (x >> 8) ;
518
0
  psf->header.ptr [psf->header.indx++] = x ;
519
0
} /* header_put_be_3byte */
520
521
static inline void
522
header_put_le_3byte (SF_PRIVATE *psf, int x)
523
0
{ psf->header.ptr [psf->header.indx++] = x ;
524
0
  psf->header.ptr [psf->header.indx++] = (x >> 8) ;
525
0
  psf->header.ptr [psf->header.indx++] = (x >> 16) ;
526
0
} /* header_put_le_3byte */
527
528
static inline void
529
header_put_be_int (SF_PRIVATE *psf, int x)
530
0
{ psf->header.ptr [psf->header.indx++] = (x >> 24) ;
531
0
  psf->header.ptr [psf->header.indx++] = (x >> 16) ;
532
0
  psf->header.ptr [psf->header.indx++] = (x >> 8) ;
533
0
  psf->header.ptr [psf->header.indx++] = x ;
534
0
} /* header_put_be_int */
535
536
static inline void
537
header_put_le_int (SF_PRIVATE *psf, int x)
538
0
{ psf->header.ptr [psf->header.indx++] = x ;
539
0
  psf->header.ptr [psf->header.indx++] = (x >> 8) ;
540
0
  psf->header.ptr [psf->header.indx++] = (x >> 16) ;
541
0
  psf->header.ptr [psf->header.indx++] = (x >> 24) ;
542
0
} /* header_put_le_int */
543
544
static inline void
545
header_put_be_8byte (SF_PRIVATE *psf, sf_count_t x)
546
0
{ psf->header.ptr [psf->header.indx++] = (x >> 56) ;
547
0
  psf->header.ptr [psf->header.indx++] = (unsigned char) (x >> 48) ;
548
0
  psf->header.ptr [psf->header.indx++] = (unsigned char) (x >> 40) ;
549
0
  psf->header.ptr [psf->header.indx++] = (unsigned char) (x >> 32) ;
550
0
  psf->header.ptr [psf->header.indx++] = (unsigned char) (x >> 24) ;
551
0
  psf->header.ptr [psf->header.indx++] = (unsigned char) (x >> 16) ;
552
0
  psf->header.ptr [psf->header.indx++] = (unsigned char) (x >> 8) ;
553
0
  psf->header.ptr [psf->header.indx++] = (unsigned char) x ;
554
0
} /* header_put_be_8byte */
555
556
static inline void
557
header_put_le_8byte (SF_PRIVATE *psf, sf_count_t x)
558
0
{ psf->header.ptr [psf->header.indx++] = (unsigned char) x ;
559
0
  psf->header.ptr [psf->header.indx++] = (unsigned char) (x >> 8) ;
560
0
  psf->header.ptr [psf->header.indx++] = (unsigned char) (x >> 16) ;
561
0
  psf->header.ptr [psf->header.indx++] = (unsigned char) (x >> 24) ;
562
0
  psf->header.ptr [psf->header.indx++] = (unsigned char) (x >> 32) ;
563
0
  psf->header.ptr [psf->header.indx++] = (unsigned char) (x >> 40) ;
564
0
  psf->header.ptr [psf->header.indx++] = (unsigned char) (x >> 48) ;
565
0
  psf->header.ptr [psf->header.indx++] = (x >> 56) ;
566
0
} /* header_put_le_8byte */
567
568
int
569
psf_binheader_writef (SF_PRIVATE *psf, const char *format, ...)
570
0
{ va_list argptr ;
571
0
  sf_count_t    countdata ;
572
0
  unsigned long   longdata ;
573
0
  unsigned int  data ;
574
0
  float     floatdata ;
575
0
  double      doubledata ;
576
0
  void      *bindata ;
577
0
  size_t      size ;
578
0
  char      c, *strptr ;
579
0
  int       count = 0, trunc_8to4 = SF_FALSE ;
580
581
0
  if (! format)
582
0
    return psf_ftell (psf) ;
583
584
0
  va_start (argptr, format) ;
585
586
0
  while ((c = *format++))
587
0
  {
588
0
    if (psf->header.indx + 16 >= psf->header.len && psf_bump_header_allocation (psf, 16))
589
0
      break ;
590
591
0
    switch (c)
592
0
    { case ' ' : /* Do nothing. Just used to space out format string. */
593
0
          break ;
594
595
0
      case 'e' : /* All conversions are now from LE to host. */
596
0
          psf->rwf_endian = SF_ENDIAN_LITTLE ;
597
0
          break ;
598
599
0
      case 'E' : /* All conversions are now from BE to host. */
600
0
          psf->rwf_endian = SF_ENDIAN_BIG ;
601
0
          break ;
602
603
0
      case 't' : /* All 8 byte values now get written as 4 bytes. */
604
0
          trunc_8to4 = SF_TRUE ;
605
0
          break ;
606
607
0
      case 'T' : /* All 8 byte values now get written as 8 bytes. */
608
0
          trunc_8to4 = SF_FALSE ;
609
0
          break ;
610
611
0
      case 'm' :
612
0
          data = va_arg (argptr, unsigned int) ;
613
0
          header_put_marker (psf, data) ;
614
0
          count += 4 ;
615
0
          break ;
616
617
0
      case '1' :
618
0
          data = va_arg (argptr, unsigned int) ;
619
0
          header_put_byte (psf, data) ;
620
0
          count += 1 ;
621
0
          break ;
622
623
0
      case '2' :
624
0
          data = va_arg (argptr, unsigned int) ;
625
0
          if (psf->rwf_endian == SF_ENDIAN_BIG)
626
0
          { header_put_be_short (psf, data) ;
627
0
            }
628
0
          else
629
0
          { header_put_le_short (psf, data) ;
630
0
            } ;
631
0
          count += 2 ;
632
0
          break ;
633
634
0
      case '3' : /* tribyte */
635
0
          data = va_arg (argptr, unsigned int) ;
636
0
          if (psf->rwf_endian == SF_ENDIAN_BIG)
637
0
          { header_put_be_3byte (psf, data) ;
638
0
            }
639
0
          else
640
0
          { header_put_le_3byte (psf, data) ;
641
0
            } ;
642
0
          count += 3 ;
643
0
          break ;
644
645
0
      case '4' :
646
0
          data = va_arg (argptr, unsigned int) ;
647
0
          if (psf->rwf_endian == SF_ENDIAN_BIG)
648
0
          { header_put_be_int (psf, data) ;
649
0
            }
650
0
          else
651
0
          { header_put_le_int (psf, data) ;
652
0
            } ;
653
0
          count += 4 ;
654
0
          break ;
655
656
0
      case '8' :
657
0
          countdata = va_arg (argptr, sf_count_t) ;
658
0
          if (psf->rwf_endian == SF_ENDIAN_BIG && trunc_8to4 == SF_FALSE)
659
0
          { header_put_be_8byte (psf, countdata) ;
660
0
            count += 8 ;
661
0
            }
662
0
          else if (psf->rwf_endian == SF_ENDIAN_LITTLE && trunc_8to4 == SF_FALSE)
663
0
          { header_put_le_8byte (psf, countdata) ;
664
0
            count += 8 ;
665
0
            }
666
0
          else if (psf->rwf_endian == SF_ENDIAN_BIG && trunc_8to4 == SF_TRUE)
667
0
          { longdata = countdata & 0xFFFFFFFF ;
668
0
            header_put_be_int (psf, longdata) ;
669
0
            count += 4 ;
670
0
            }
671
0
          else if (psf->rwf_endian == SF_ENDIAN_LITTLE && trunc_8to4 == SF_TRUE)
672
0
          { longdata = countdata & 0xFFFFFFFF ;
673
0
            header_put_le_int (psf, longdata) ;
674
0
            count += 4 ;
675
0
            }
676
0
          break ;
677
678
0
      case 'f' :
679
          /* Floats are passed as doubles. Is this always true? */
680
0
          floatdata = (float) va_arg (argptr, double) ;
681
0
          if (psf->rwf_endian == SF_ENDIAN_BIG)
682
0
            float32_be_write (floatdata, psf->header.ptr + psf->header.indx) ;
683
0
          else
684
0
            float32_le_write (floatdata, psf->header.ptr + psf->header.indx) ;
685
0
          psf->header.indx += 4 ;
686
0
          count += 4 ;
687
0
          break ;
688
689
0
      case 'd' :
690
0
          doubledata = va_arg (argptr, double) ;
691
0
          if (psf->rwf_endian == SF_ENDIAN_BIG)
692
0
            double64_be_write (doubledata, psf->header.ptr + psf->header.indx) ;
693
0
          else
694
0
            double64_le_write (doubledata, psf->header.ptr + psf->header.indx) ;
695
0
          psf->header.indx += 8 ;
696
0
          count += 8 ;
697
0
          break ;
698
699
0
      case 's' :
700
          /* Write a C string (guaranteed to have a zero terminator). */
701
0
          strptr = va_arg (argptr, char *) ;
702
0
          size = strlen (strptr) + 1 ;
703
704
0
          if (psf->header.indx + 4 + (sf_count_t) size + (sf_count_t) (size & 1) > psf->header.len && psf_bump_header_allocation (psf, 4 + size + (size & 1)))
705
0
            break ;
706
707
0
          if (psf->rwf_endian == SF_ENDIAN_BIG)
708
0
            header_put_be_int (psf, size + (size & 1)) ;
709
0
          else
710
0
            header_put_le_int (psf, size + (size & 1)) ;
711
0
          memcpy (&(psf->header.ptr [psf->header.indx]), strptr, size) ;
712
0
          size += (size & 1) ;
713
0
          psf->header.indx += size ;
714
0
          psf->header.ptr [psf->header.indx - 1] = 0 ;
715
0
          count += 4 + size ;
716
0
          break ;
717
718
0
      case 'S' :
719
          /*
720
          **  Write an AIFF style string (no zero terminator but possibly
721
          **  an extra pad byte if the string length is odd).
722
          */
723
0
          strptr = va_arg (argptr, char *) ;
724
0
          size = strlen (strptr) ;
725
0
          if (psf->header.indx + 4 + (sf_count_t) size + (sf_count_t) (size & 1) > psf->header.len && psf_bump_header_allocation (psf, 4 + size + (size & 1)))
726
0
            break ;
727
0
          if (psf->rwf_endian == SF_ENDIAN_BIG)
728
0
            header_put_be_int (psf, size) ;
729
0
          else
730
0
            header_put_le_int (psf, size) ;
731
0
          memcpy (&(psf->header.ptr [psf->header.indx]), strptr, size + (size & 1)) ;
732
0
          size += (size & 1) ;
733
0
          psf->header.indx += size ;
734
0
          count += 4 + size ;
735
0
          break ;
736
737
0
      case 'p' :
738
          /* Write a PASCAL string (as used by AIFF files).
739
          */
740
0
          strptr = va_arg (argptr, char *) ;
741
0
          size = strlen (strptr) ;
742
0
          size = (size & 1) ? size : size + 1 ;
743
0
          size = (size > 254) ? 254 : size ;
744
745
0
          if (psf->header.indx + 1 + (sf_count_t) size > psf->header.len && psf_bump_header_allocation (psf, 1 + size))
746
0
            break ;
747
748
0
          header_put_byte (psf, size) ;
749
0
          memcpy (&(psf->header.ptr [psf->header.indx]), strptr, size) ;
750
0
          psf->header.indx += size ;
751
0
          count += 1 + size ;
752
0
          break ;
753
754
0
      case 'b' :
755
0
          bindata = va_arg (argptr, void *) ;
756
0
          size  = va_arg (argptr, size_t) ;
757
758
0
          if (psf->header.indx + (sf_count_t) size > psf->header.len && psf_bump_header_allocation (psf, size))
759
0
            break ;
760
761
0
          memcpy (&(psf->header.ptr [psf->header.indx]), bindata, size) ;
762
0
          psf->header.indx += size ;
763
0
          count += size ;
764
0
          break ;
765
766
0
      case 'z' :
767
0
          size = va_arg (argptr, size_t) ;
768
769
0
          if (psf->header.indx + (sf_count_t) size > psf->header.len && psf_bump_header_allocation (psf, size))
770
0
            break ;
771
772
0
          count += size ;
773
0
          while (size)
774
0
          { psf->header.ptr [psf->header.indx] = 0 ;
775
0
            psf->header.indx ++ ;
776
0
            size -- ;
777
0
            } ;
778
0
          break ;
779
780
0
      case 'h' :
781
0
          bindata = va_arg (argptr, void *) ;
782
0
          memcpy (&(psf->header.ptr [psf->header.indx]), bindata, 16) ;
783
0
          psf->header.indx += 16 ;
784
0
          count += 16 ;
785
0
          break ;
786
787
0
      case 'j' :  /* Jump forwards/backwards by specified amount. */
788
0
          size = va_arg (argptr, size_t) ;
789
790
0
          if (psf->header.indx + (sf_count_t) size > psf->header.len && psf_bump_header_allocation (psf, size))
791
0
            break ;
792
793
0
          psf->header.indx += size ;
794
0
          count += size ;
795
0
          break ;
796
797
0
      case 'o' :  /* Jump to specified offset. */
798
0
          size = va_arg (argptr, size_t) ;
799
800
0
          if ((sf_count_t) size >= psf->header.len && psf_bump_header_allocation (psf, size))
801
0
            break ;
802
803
0
          psf->header.indx = size ;
804
0
          break ;
805
806
0
      default :
807
0
        psf_log_printf (psf, "*** Invalid format specifier `%c'\n", c) ;
808
0
        psf->error = SFE_INTERNAL ;
809
0
        break ;
810
0
      } ;
811
0
    } ;
812
813
0
  va_end (argptr) ;
814
0
  return count ;
815
0
} /* psf_binheader_writef */
816
817
/*-----------------------------------------------------------------------------------------------
818
**  Binary header reading functions. Returns number of bytes read.
819
**
820
**  Format specifiers are the same as for header write function above with the following
821
**  additions:
822
**
823
**    p   - jump a given number of position from start of file.
824
**
825
**  If format is NULL, psf_binheader_readf returns the current offset.
826
*/
827
828
#if (CPU_IS_BIG_ENDIAN == 1)
829
#define GET_MARKER(ptr) ( (((uint32_t) (ptr) [0]) << 24)  | ((ptr) [1] << 16) | \
830
              ((ptr) [2] << 8)  | ((ptr) [3]))
831
832
#elif (CPU_IS_LITTLE_ENDIAN == 1)
833
9.65M
#define GET_MARKER(ptr) ( ((ptr) [0])     | ((ptr) [1] << 8) |  \
834
9.65M
              ((ptr) [2] << 16) | (((uint32_t) (ptr) [3]) << 24))
835
836
#else
837
# error "Cannot determine endian-ness of processor."
838
#endif
839
840
2.40M
#define GET_LE_SHORT(ptr) (((ptr) [1] << 8) | ((ptr) [0]))
841
4.01M
#define GET_BE_SHORT(ptr) (((ptr) [0] << 8) | ((ptr) [1]))
842
843
3.97k
#define GET_LE_3BYTE(ptr) ( ((ptr) [2] << 16) | ((ptr) [1] << 8) | ((ptr) [0]))
844
0
#define GET_BE_3BYTE(ptr) ( ((ptr) [0] << 16) | ((ptr) [1] << 8) | ((ptr) [2]))
845
846
#define GET_LE_INT(ptr)   ( ((ptr) [3] << 24) | ((ptr) [2] << 16) | \
847
                ((ptr) [1] << 8)  | ((ptr) [0]))
848
849
#define GET_BE_INT(ptr)   ( ((ptr) [0] << 24) | ((ptr) [1] << 16) | \
850
                ((ptr) [2] << 8)  | ((ptr) [3]))
851
852
#define GET_LE_8BYTE(ptr) ( (((sf_count_t) (ptr) [7]) << 56)  | (((sf_count_t) (ptr) [6]) << 48) |  \
853
                (((sf_count_t) (ptr) [5]) << 40)  | (((sf_count_t) (ptr) [4]) << 32) |  \
854
                (((sf_count_t) (ptr) [3]) << 24)  | (((sf_count_t) (ptr) [2]) << 16) |  \
855
                (((sf_count_t) (ptr) [1]) << 8)   | ((ptr) [0]))
856
857
#define GET_BE_8BYTE(ptr) ( (((sf_count_t) (ptr) [0]) << 56)  | (((sf_count_t) (ptr) [1]) << 48) |  \
858
                (((sf_count_t) (ptr) [2]) << 40)  | (((sf_count_t) (ptr) [3]) << 32) |  \
859
                (((sf_count_t) (ptr) [4]) << 24)  | (((sf_count_t) (ptr) [5]) << 16) |  \
860
                (((sf_count_t) (ptr) [6]) << 8)   | ((ptr) [7]))
861
862
863
864
static int
865
header_read (SF_PRIVATE *psf, void *ptr, int bytes)
866
31.9M
{ int count = 0 ;
867
868
31.9M
  if (psf->header.indx + bytes >= psf->header.len && psf_bump_header_allocation (psf, bytes))
869
901
    return count ;
870
871
31.9M
  if (psf->header.indx + bytes > psf->header.end)
872
16.4M
  { count = psf_fread (psf->header.ptr + psf->header.end, 1, bytes - (psf->header.end - psf->header.indx), psf) ;
873
16.4M
    if (count != bytes - (int) (psf->header.end - psf->header.indx))
874
6.75M
    { psf_log_printf (psf, "Error : psf_fread returned short count.\n") ;
875
6.75M
      return count ;
876
9.72M
      } ;
877
9.72M
    psf->header.end += count ;
878
25.2M
    } ;
879
880
25.2M
  memcpy (ptr, psf->header.ptr + psf->header.indx, bytes) ;
881
25.2M
  psf->header.indx += bytes ;
882
883
25.2M
  return bytes ;
884
31.9M
} /* header_read */
885
886
static void
887
header_seek (SF_PRIVATE *psf, sf_count_t position, int whence)
888
8.15M
{
889
8.15M
  switch (whence)
890
8.15M
  { case SEEK_SET :
891
49.5k
      if (psf->header.indx + position >= psf->header.len)
892
703
        psf_bump_header_allocation (psf, position) ;
893
49.5k
      if (position > psf->header.len)
894
7
      { /* Too much header to cache so just seek instead. */
895
7
        psf->header.indx = psf->header.end = 0 ;
896
7
        psf_fseek (psf, position, whence) ;
897
7
        return ;
898
49.4k
        } ;
899
49.4k
      if (position > psf->header.end)
900
1.90k
        psf->header.end += psf_fread (psf->header.ptr + psf->header.end, 1, position - psf->header.end, psf) ;
901
49.4k
      psf->header.indx = position ;
902
49.4k
      break ;
903
904
8.10M
    case SEEK_CUR :
905
8.10M
      if (psf->header.indx + position >= psf->header.len)
906
10.4k
        psf_bump_header_allocation (psf, position) ;
907
908
8.10M
      if (psf->header.indx + position < 0)
909
3.28M
        break ;
910
911
4.81M
      if (psf->header.indx >= psf->header.len)
912
0
      { psf_fseek (psf, position, whence) ;
913
0
        return ;
914
4.81M
        } ;
915
916
4.81M
      if (psf->header.indx + position <= psf->header.end)
917
3.80M
      { psf->header.indx += position ;
918
3.80M
        break ;
919
3.80M
        } ;
920
921
1.00M
      if (psf->header.indx + position > psf->header.len)
922
6.97k
      { /* Need to jump this without caching it. */
923
6.97k
        position -= (psf->header.end - psf->header.indx) ;
924
6.97k
        psf->header.indx = psf->header.end ;
925
6.97k
        if (psf->is_pipe)
926
0
        {
927
          /* seeking is not supported on pipe input, so we read instead */
928
0
          size_t skip = position ;
929
0
          while (skip)
930
0
          { char junk [16 * 1024] ;
931
0
            size_t to_skip = SF_MIN (skip, sizeof (junk)) ;
932
0
            psf_fread (junk, 1, to_skip, psf) ;
933
0
            skip -= to_skip ;
934
0
            }
935
0
          }
936
6.97k
        else
937
6.97k
        { psf_fseek (psf, position, SEEK_CUR) ;
938
6.97k
          }
939
6.97k
        break ;
940
998k
        } ;
941
942
998k
      psf->header.end += psf_fread (psf->header.ptr + psf->header.end, 1, position - (psf->header.end - psf->header.indx), psf) ;
943
998k
      psf->header.indx = psf->header.end ;
944
998k
      break ;
945
946
0
    case SEEK_END :
947
0
    default :
948
0
      psf_log_printf (psf, "Bad whence param in header_seek().\n") ;
949
0
      break ;
950
8.15M
    } ;
951
952
8.15M
  return ;
953
8.15M
} /* header_seek */
954
955
static int
956
header_gets (SF_PRIVATE *psf, char *ptr, int bufsize)
957
278
{ int   k ;
958
959
278
  if (psf->header.indx + bufsize >= psf->header.len && psf_bump_header_allocation (psf, bufsize))
960
0
    return 0 ;
961
962
5.48k
  for (k = 0 ; k < bufsize - 1 ; k++)
963
5.35k
  { if (psf->header.indx < psf->header.end)
964
1.90k
    { ptr [k] = psf->header.ptr [psf->header.indx] ;
965
1.90k
      psf->header.indx ++ ;
966
1.90k
      }
967
3.45k
    else
968
3.45k
    { psf->header.end += psf_fread (psf->header.ptr + psf->header.end, 1, 1, psf) ;
969
3.45k
      ptr [k] = psf->header.ptr [psf->header.indx] ;
970
3.45k
      psf->header.indx = psf->header.end ;
971
3.45k
      } ;
972
973
5.35k
    if (ptr [k] == '\n')
974
141
      break ;
975
5.35k
    } ;
976
977
278
  ptr [k] = 0 ;
978
979
278
  return k ;
980
278
} /* header_gets */
981
982
int
983
psf_binheader_readf (SF_PRIVATE *psf, char const *format, ...)
984
30.7M
{ va_list     argptr ;
985
30.7M
  sf_count_t    *countptr, countdata ;
986
30.7M
  unsigned char *ucptr, sixteen_bytes [16] = { 0 } ;
987
30.7M
  unsigned int  *intptr, intdata ;
988
30.7M
  unsigned short  *shortptr ;
989
30.7M
  char      *charptr ;
990
30.7M
  float     *floatptr ;
991
30.7M
  double      *doubleptr ;
992
30.7M
  char      c ;
993
30.7M
  int       byte_count = 0, count = 0 ;
994
30.7M
  int       read_bytes = 0 ;
995
996
30.7M
  if (! format)
997
0
    return psf_ftell (psf) ;
998
999
30.7M
  va_start (argptr, format) ;
1000
1001
75.1M
  while ((c = *format++))
1002
44.5M
  {
1003
44.5M
    read_bytes = 0 ;
1004
44.5M
    if (psf->header.indx + 16 >= psf->header.len && psf_bump_header_allocation (psf, 16))
1005
83.8k
      break ;
1006
1007
44.4M
    switch (c)
1008
44.4M
    { case 'e' : /* All conversions are now from LE to host. */
1009
2.11M
          psf->rwf_endian = SF_ENDIAN_LITTLE ;
1010
2.11M
          break ;
1011
1012
2.20M
      case 'E' : /* All conversions are now from BE to host. */
1013
2.20M
          psf->rwf_endian = SF_ENDIAN_BIG ;
1014
2.20M
          break ;
1015
1016
9.65M
      case 'm' : /* 4 byte marker value eg 'RIFF' */
1017
9.65M
          intptr = va_arg (argptr, unsigned int*) ;
1018
9.65M
          *intptr = 0 ;
1019
9.65M
          ucptr = (unsigned char*) intptr ;
1020
9.65M
          read_bytes = header_read (psf, ucptr, sizeof (int)) ;
1021
9.65M
          *intptr = GET_MARKER (ucptr) ;
1022
9.65M
          break ;
1023
1024
184k
      case 'h' :
1025
184k
          intptr = va_arg (argptr, unsigned int*) ;
1026
184k
          *intptr = 0 ;
1027
184k
          ucptr = (unsigned char*) intptr ;
1028
184k
          read_bytes = header_read (psf, sixteen_bytes, sizeof (sixteen_bytes)) ;
1029
184k
          { int k ;
1030
184k
            intdata = 0 ;
1031
3.13M
            for (k = 0 ; k < 16 ; k++)
1032
2.95M
              intdata ^= sixteen_bytes [k] << k ;
1033
184k
            }
1034
184k
          *intptr = intdata ;
1035
184k
          break ;
1036
1037
635k
      case '1' :
1038
635k
          charptr = va_arg (argptr, char*) ;
1039
635k
          *charptr = 0 ;
1040
635k
          read_bytes = header_read (psf, charptr, sizeof (char)) ;
1041
635k
          break ;
1042
1043
6.41M
      case '2' : /* 2 byte value with the current endian-ness */
1044
6.41M
          shortptr = va_arg (argptr, unsigned short*) ;
1045
6.41M
          *shortptr = 0 ;
1046
6.41M
          ucptr = (unsigned char*) shortptr ;
1047
6.41M
          read_bytes = header_read (psf, ucptr, sizeof (short)) ;
1048
6.41M
          if (psf->rwf_endian == SF_ENDIAN_BIG)
1049
4.01M
            *shortptr = GET_BE_SHORT (ucptr) ;
1050
2.40M
          else
1051
2.40M
            *shortptr = GET_LE_SHORT (ucptr) ;
1052
6.41M
          break ;
1053
1054
3.97k
      case '3' : /* 3 byte value with the current endian-ness */
1055
3.97k
          intptr = va_arg (argptr, unsigned int*) ;
1056
3.97k
          *intptr = 0 ;
1057
3.97k
          read_bytes = header_read (psf, sixteen_bytes, 3) ;
1058
3.97k
          if (psf->rwf_endian == SF_ENDIAN_BIG)
1059
0
            *intptr = GET_BE_3BYTE (sixteen_bytes) ;
1060
3.97k
          else
1061
3.97k
            *intptr = GET_LE_3BYTE (sixteen_bytes) ;
1062
3.97k
          break ;
1063
1064
12.4M
      case '4' : /* 4 byte value with the current endian-ness */
1065
12.4M
          intptr = va_arg (argptr, unsigned int*) ;
1066
12.4M
          *intptr = 0 ;
1067
12.4M
          ucptr = (unsigned char*) intptr ;
1068
12.4M
          read_bytes = header_read (psf, ucptr, sizeof (int)) ;
1069
12.4M
          if (psf->rwf_endian == SF_ENDIAN_BIG)
1070
2.21M
            *intptr = psf_get_be32 (ucptr, 0) ;
1071
10.1M
          else
1072
10.1M
            *intptr = psf_get_le32 (ucptr, 0) ;
1073
12.4M
          break ;
1074
1075
221k
      case '8' : /* 8 byte value with the current endian-ness */
1076
221k
          countptr = va_arg (argptr, sf_count_t *) ;
1077
221k
          *countptr = 0 ;
1078
221k
          read_bytes = header_read (psf, sixteen_bytes, 8) ;
1079
221k
          if (psf->rwf_endian == SF_ENDIAN_BIG)
1080
29.4k
            countdata = psf_get_be64 (sixteen_bytes, 0) ;
1081
191k
          else
1082
191k
            countdata = psf_get_le64 (sixteen_bytes, 0) ;
1083
221k
          *countptr = countdata ;
1084
221k
          break ;
1085
1086
248k
      case 'f' : /* Float conversion */
1087
248k
          floatptr = va_arg (argptr, float *) ;
1088
248k
          *floatptr = 0.0 ;
1089
248k
          read_bytes = header_read (psf, floatptr, sizeof (float)) ;
1090
248k
          if (psf->rwf_endian == SF_ENDIAN_BIG)
1091
12.9k
            *floatptr = float32_be_read ((unsigned char*) floatptr) ;
1092
236k
          else
1093
236k
            *floatptr = float32_le_read ((unsigned char*) floatptr) ;
1094
248k
          break ;
1095
1096
1.27k
      case 'd' : /* double conversion */
1097
1.27k
          doubleptr = va_arg (argptr, double *) ;
1098
1.27k
          *doubleptr = 0.0 ;
1099
1.27k
          read_bytes = header_read (psf, doubleptr, sizeof (double)) ;
1100
1.27k
          if (psf->rwf_endian == SF_ENDIAN_BIG)
1101
151
            *doubleptr = double64_be_read ((unsigned char*) doubleptr) ;
1102
1.12k
          else
1103
1.12k
            *doubleptr = double64_le_read ((unsigned char*) doubleptr) ;
1104
1.27k
          break ;
1105
1106
0
      case 's' :
1107
0
          psf_log_printf (psf, "Format conversion 's' not implemented yet.\n") ;
1108
          /*
1109
          strptr = va_arg (argptr, char *) ;
1110
          size   = strlen (strptr) + 1 ;
1111
          size  += (size & 1) ;
1112
          longdata = H2LE_32 (size) ;
1113
          get_int (psf, longdata) ;
1114
          memcpy (&(psf->header.ptr [psf->header.indx]), strptr, size) ;
1115
          psf->header.indx += size ;
1116
          */
1117
0
          break ;
1118
1119
2.19M
      case 'b' : /* Raw bytes */
1120
2.19M
          charptr = va_arg (argptr, char*) ;
1121
2.19M
          count = va_arg (argptr, size_t) ;
1122
2.19M
          memset (charptr, 0, count) ;
1123
2.19M
          read_bytes = header_read (psf, charptr, count) ;
1124
2.19M
          break ;
1125
1126
278
      case 'G' :
1127
278
          charptr = va_arg (argptr, char*) ;
1128
278
          count = va_arg (argptr, size_t) ;
1129
278
          memset (charptr, 0, count) ;
1130
1131
278
          if (psf->header.indx + count >= psf->header.len && psf_bump_header_allocation (psf, count))
1132
0
            break ;
1133
1134
278
          read_bytes = header_gets (psf, charptr, count) ;
1135
278
          break ;
1136
1137
0
      case 'z' :
1138
0
          psf_log_printf (psf, "Format conversion 'z' not implemented yet.\n") ;
1139
          /*
1140
          size    = va_arg (argptr, size_t) ;
1141
          while (size)
1142
          { psf->header.ptr [psf->header.indx] = 0 ;
1143
            psf->header.indx ++ ;
1144
            size -- ;
1145
            } ;
1146
          */
1147
0
          break ;
1148
1149
49.5k
      case 'p' :  /* Seek to position from start. */
1150
49.5k
          count = va_arg (argptr, size_t) ;
1151
49.5k
          header_seek (psf, count, SEEK_SET) ;
1152
49.5k
          byte_count = count ;
1153
49.5k
          break ;
1154
1155
8.10M
      case 'j' :  /* Seek to position from current position. */
1156
8.10M
          count = va_arg (argptr, size_t) ;
1157
8.10M
          header_seek (psf, count, SEEK_CUR) ;
1158
8.10M
          read_bytes = count ;
1159
8.10M
          break ;
1160
1161
5.21k
      case '!' : /* Clear buffer, forcing re-read. */
1162
5.21k
          psf->header.end = psf->header.indx = 0 ;
1163
5.21k
          break ;
1164
1165
0
      default :
1166
0
        psf_log_printf (psf, "*** Invalid format specifier `%c'\n", c) ;
1167
0
        psf->error = SFE_INTERNAL ;
1168
0
        break ;
1169
44.4M
      } ;
1170
1171
44.4M
    if (read_bytes > 0 && byte_count > (INT_MAX - read_bytes))
1172
3
    { psf_log_printf (psf, "Header size exceeds INT_MAX. Aborting.", c) ;
1173
3
      psf->error = SFE_INTERNAL ;
1174
3
      break ;
1175
3
    } else
1176
44.4M
    { byte_count += read_bytes ;
1177
44.4M
    } ;
1178
1179
44.4M
    } ; /*end while*/
1180
1181
30.7M
  va_end (argptr) ;
1182
1183
30.7M
  return byte_count ;
1184
30.7M
} /* psf_binheader_readf */
1185
1186
/*-----------------------------------------------------------------------------------------------
1187
*/
1188
1189
sf_count_t
1190
psf_default_seek (SF_PRIVATE *psf, int UNUSED (mode), sf_count_t samples_from_start)
1191
0
{ sf_count_t position, retval ;
1192
1193
0
  if (! (psf->blockwidth && psf->dataoffset >= 0))
1194
0
  { psf->error = SFE_BAD_SEEK ;
1195
0
    return  PSF_SEEK_ERROR ;
1196
0
    } ;
1197
1198
0
  if (! psf->sf.seekable)
1199
0
  { psf->error = SFE_NOT_SEEKABLE ;
1200
0
    return  PSF_SEEK_ERROR ;
1201
0
    } ;
1202
1203
0
  position = psf->dataoffset + psf->blockwidth * samples_from_start ;
1204
1205
0
  if ((retval = psf_fseek (psf, position, SEEK_SET)) != position)
1206
0
  { psf->error = SFE_SEEK_FAILED ;
1207
0
    return PSF_SEEK_ERROR ;
1208
0
    } ;
1209
1210
0
  return samples_from_start ;
1211
0
} /* psf_default_seek */
1212
1213
/*-----------------------------------------------------------------------------------------------
1214
*/
1215
1216
void
1217
psf_hexdump (const void *ptr, int len)
1218
0
{ const char *data ;
1219
0
  char  ascii [17] ;
1220
0
  int   k, m ;
1221
1222
0
  if ((data = ptr) == NULL)
1223
0
    return ;
1224
0
  if (len <= 0)
1225
0
    return ;
1226
1227
0
  puts ("") ;
1228
0
  for (k = 0 ; k < len ; k += 16)
1229
0
  { memset (ascii, ' ', sizeof (ascii)) ;
1230
1231
0
    printf ("%08X: ", k) ;
1232
0
    for (m = 0 ; m < 16 && k + m < len ; m++)
1233
0
    { printf (m == 8 ? " %02X " : "%02X ", data [k + m] & 0xFF) ;
1234
0
      ascii [m] = psf_isprint (data [k + m]) ? data [k + m] : '.' ;
1235
0
      } ;
1236
1237
0
    if (m <= 8) printf (" ") ;
1238
0
    for ( ; m < 16 ; m++) printf ("   ") ;
1239
1240
0
    ascii [16] = 0 ;
1241
0
    printf (" %s\n", ascii) ;
1242
0
    } ;
1243
1244
0
  puts ("") ;
1245
0
} /* psf_hexdump */
1246
1247
void
1248
psf_log_SF_INFO (SF_PRIVATE *psf)
1249
2.39k
{ psf_log_printf (psf, "---------------------------------\n") ;
1250
1251
2.39k
  psf_log_printf (psf, " Sample rate :   %d\n", psf->sf.samplerate) ;
1252
2.39k
  if (psf->sf.frames == SF_COUNT_MAX)
1253
2
    psf_log_printf (psf, " Frames      :   unknown\n") ;
1254
2.39k
  else
1255
2.39k
    psf_log_printf (psf, " Frames      :   %D\n", psf->sf.frames) ;
1256
2.39k
  psf_log_printf (psf, " Channels    :   %d\n", psf->sf.channels) ;
1257
1258
2.39k
  psf_log_printf (psf, " Format      :   0x%X\n", psf->sf.format) ;
1259
2.39k
  psf_log_printf (psf, " Sections    :   %d\n", psf->sf.sections) ;
1260
2.39k
  psf_log_printf (psf, " Seekable    :   %s\n", psf->sf.seekable ? "TRUE" : "FALSE") ;
1261
1262
2.39k
  psf_log_printf (psf, "---------------------------------\n") ;
1263
2.39k
} /* psf_dump_SFINFO */
1264
1265
/*========================================================================================
1266
*/
1267
1268
int
1269
psf_isprint (int ch)
1270
37.1M
{ return (ch >= ' ' && ch <= '~') ;
1271
37.1M
} /* psf_isprint */
1272
1273
void
1274
psf_strlcat (char *dest, size_t n, const char *src)
1275
0
{ strncat (dest, src, n - strlen (dest) - 1) ;
1276
0
  dest [n - 1] = 0 ;
1277
0
} /* psf_strlcat */
1278
1279
void
1280
psf_strlcpy (char *dest, size_t n, const char *src)
1281
71.5k
{ strncpy (dest, src, n - 1) ;
1282
71.5k
  dest [n - 1] = 0 ;
1283
71.5k
} /* psf_strlcpy */
1284
1285
/*========================================================================================
1286
*/
1287
1288
void *
1289
psf_memdup (const void *src, size_t n)
1290
0
{ if (src == NULL)
1291
0
    return NULL ;
1292
1293
0
  void * mem = calloc (1, n & 3 ? n + 4 - (n & 3) : n) ;
1294
0
  if (mem != NULL)
1295
0
    memcpy (mem, src, n) ;
1296
0
  return mem ;
1297
0
} /* psf_memdup */
1298
1299
void*
1300
psf_memset (void *s, int c, sf_count_t len)
1301
7.10k
{ char  *ptr ;
1302
7.10k
  int   setcount ;
1303
1304
7.10k
  ptr = (char *) s ;
1305
1306
14.2k
  while (len > 0)
1307
7.10k
  { setcount = (len > 0x10000000) ? 0x10000000 : (int) len ;
1308
1309
7.10k
    memset (ptr, c, setcount) ;
1310
1311
7.10k
    ptr += setcount ;
1312
7.10k
    len -= setcount ;
1313
7.10k
    } ;
1314
1315
7.10k
  return s ;
1316
7.10k
} /* psf_memset */
1317
1318
1319
/*
1320
** Clang refuses to do sizeof (SF_CUES_VAR (cue_count)) so we have to manually
1321
** bodgy something up instead.
1322
*/
1323
1324
#ifdef _MSC_VER
1325
typedef SF_CUES_VAR (0) SF_CUES_0 ;
1326
#else
1327
typedef SF_CUES_VAR () SF_CUES_0 ;
1328
#endif
1329
1330
/* calculate size of SF_CUES struct given number of cues */
1331
2.64k
#define SF_CUES_VAR_SIZE(count) (sizeof (SF_CUES_0) + count * sizeof (SF_CUE_POINT))
1332
1333
/* calculate number of cues in SF_CUES struct given data size */
1334
0
#define SF_CUES_COUNT(datasize) (((datasize) - sizeof (uint32_t)) / sizeof (SF_CUE_POINT))
1335
1336
SF_CUES *
1337
psf_cues_alloc (uint32_t cue_count)
1338
2.64k
{ SF_CUES *pcues = calloc (1, SF_CUES_VAR_SIZE (cue_count)) ;
1339
2.64k
  if (pcues)
1340
2.64k
  { pcues->cue_count = cue_count ;
1341
2.64k
    } ;
1342
2.64k
  return pcues ;
1343
2.64k
} /* psf_cues_alloc */
1344
1345
SF_CUES *
1346
psf_cues_dup (const void * ptr, size_t datasize)
1347
0
{ const SF_CUES *pcues = ptr ;
1348
0
  SF_CUES *pnew = NULL ;
1349
1350
0
  if (pcues->cue_count <= SF_CUES_COUNT (datasize))
1351
0
  { /* check that passed-in datasize is consistent with cue_count in passed-in SF_CUES struct */
1352
0
    pnew = psf_cues_alloc (pcues->cue_count) ;
1353
0
    memcpy (pnew, pcues, SF_CUES_VAR_SIZE (pcues->cue_count)) ;
1354
0
  }
1355
1356
0
  return pnew ;
1357
0
} /* psf_cues_dup */
1358
1359
void
1360
psf_get_cues (SF_PRIVATE * psf, void * data, size_t datasize)
1361
0
{
1362
0
  if (psf->cues)
1363
0
  { uint32_t cue_count = SF_CUES_COUNT (datasize) ;
1364
1365
0
    cue_count = SF_MIN (cue_count, psf->cues->cue_count) ;
1366
0
    memcpy (data, psf->cues, SF_CUES_VAR_SIZE (cue_count)) ;
1367
0
    ((SF_CUES*) data)->cue_count = cue_count ;
1368
0
    } ;
1369
1370
0
  return ;
1371
0
} /* psf_get_cues */
1372
1373
1374
SF_INSTRUMENT *
1375
psf_instrument_alloc (void)
1376
2.75k
{ SF_INSTRUMENT *instr ;
1377
1378
2.75k
  instr = calloc (1, sizeof (SF_INSTRUMENT)) ;
1379
1380
2.75k
  if (instr == NULL)
1381
0
    return NULL ;
1382
1383
  /* Set non-zero default values. */
1384
2.75k
  instr->basenote = -1 ;
1385
2.75k
  instr->velocity_lo = -1 ;
1386
2.75k
  instr->velocity_hi = -1 ;
1387
2.75k
  instr->key_lo = -1 ;
1388
2.75k
  instr->key_hi = -1 ;
1389
1390
2.75k
  return instr ;
1391
2.75k
} /* psf_instrument_alloc */
1392
1393
void
1394
psf_sanitize_string (char * cptr, int len)
1395
205
{
1396
205
  do
1397
188k
  {
1398
188k
    len -- ;
1399
188k
    cptr [len] = psf_isprint (cptr [len]) ? cptr [len] : '.' ;
1400
188k
  }
1401
188k
  while (len > 0) ;
1402
205
} /* psf_sanitize_string */
1403
1404
void
1405
psf_get_date_str (char *str, int maxlen)
1406
0
{ time_t    current ;
1407
0
  struct tm timedata, *tmptr ;
1408
1409
0
  time (&current) ;
1410
1411
0
#if defined (HAVE_GMTIME_R)
1412
  /* If the re-entrant version is available, use it. */
1413
0
  tmptr = gmtime_r (&current, &timedata) ;
1414
#elif defined (HAVE_GMTIME)
1415
  /* Otherwise use the standard one and copy the data to local storage. */
1416
  tmptr = gmtime (&current) ;
1417
  memcpy (&timedata, tmptr, sizeof (timedata)) ;
1418
#else
1419
  tmptr = NULL ;
1420
#endif
1421
1422
0
  if (tmptr)
1423
0
    snprintf (str, maxlen, "%4d-%02d-%02d %02d:%02d:%02d UTC",
1424
0
      1900 + timedata.tm_year, timedata.tm_mon, timedata.tm_mday,
1425
0
      timedata.tm_hour, timedata.tm_min, timedata.tm_sec) ;
1426
0
  else
1427
0
    snprintf (str, maxlen, "Unknown date") ;
1428
1429
0
  return ;
1430
0
} /* psf_get_date_str */
1431
1432
int
1433
subformat_to_bytewidth (int format)
1434
0
{
1435
0
  switch (format)
1436
0
  { case SF_FORMAT_PCM_U8 :
1437
0
    case SF_FORMAT_PCM_S8 :
1438
0
        return 1 ;
1439
0
    case SF_FORMAT_PCM_16 :
1440
0
        return 2 ;
1441
0
    case SF_FORMAT_PCM_24 :
1442
0
        return 3 ;
1443
0
    case SF_FORMAT_PCM_32 :
1444
0
    case SF_FORMAT_FLOAT :
1445
0
        return 4 ;
1446
0
    case SF_FORMAT_DOUBLE :
1447
0
        return 8 ;
1448
0
    } ;
1449
1450
0
  return 0 ;
1451
0
} /* subformat_to_bytewidth */
1452
1453
int
1454
s_bitwidth_to_subformat (int bits)
1455
13.0k
{ static int array [] =
1456
13.0k
  { SF_FORMAT_PCM_S8, SF_FORMAT_PCM_16, SF_FORMAT_PCM_24, SF_FORMAT_PCM_32
1457
13.0k
    } ;
1458
1459
13.0k
  if (bits < 8 || bits > 32)
1460
8.29k
    return 0 ;
1461
1462
4.79k
  return array [((bits + 7) / 8) - 1] ;
1463
13.0k
} /* bitwidth_to_subformat */
1464
1465
int
1466
u_bitwidth_to_subformat (int bits)
1467
24.4k
{ static int array [] =
1468
24.4k
  { SF_FORMAT_PCM_U8, SF_FORMAT_PCM_16, SF_FORMAT_PCM_24, SF_FORMAT_PCM_32
1469
24.4k
    } ;
1470
1471
24.4k
  if (bits < 8 || bits > 32)
1472
16.8k
    return 0 ;
1473
1474
7.57k
  return array [((bits + 7) / 8) - 1] ;
1475
24.4k
} /* bitwidth_to_subformat */
1476
1477
/*
1478
**  psf_rand_int32 : Not crypto quality, but more than adequate for things
1479
**  like stream serial numbers in Ogg files or the unique_id field of the
1480
**  SF_PRIVATE struct.
1481
*/
1482
1483
int32_t
1484
psf_rand_int32 (void)
1485
41.8k
{ static uint64_t value = 0 ;
1486
41.8k
  int k, count ;
1487
1488
41.8k
  if (value == 0)
1489
2
  {
1490
2
#if HAVE_GETTIMEOFDAY
1491
2
    struct timeval tv ;
1492
2
    gettimeofday (&tv, NULL) ;
1493
2
    value = tv.tv_sec + tv.tv_usec ;
1494
#else
1495
    value = time (NULL) ;
1496
#endif
1497
2
    } ;
1498
1499
41.8k
  count = 4 + (value & 7) ;
1500
376k
  for (k = 0 ; k < count ; k++)
1501
334k
    value = (11117 * value + 211231) & 0x7fffffff ;
1502
1503
41.8k
  return (int32_t) value ;
1504
41.8k
} /* psf_rand_int32 */
1505
1506
void
1507
append_snprintf (char * dest, size_t maxlen, const char * fmt, ...)
1508
207k
{ size_t len = strlen (dest) ;
1509
1510
207k
  if (len < maxlen)
1511
207k
  { va_list ap ;
1512
1513
207k
    va_start (ap, fmt) ;
1514
207k
    vsnprintf (dest + len, maxlen - len, fmt, ap) ;
1515
207k
    va_end (ap) ;
1516
207k
    } ;
1517
1518
207k
  return ;
1519
207k
} /* append_snprintf */
1520
1521
1522
void
1523
psf_strlcpy_crlf (char *dest, const char *src, size_t destmax, size_t srcmax)
1524
0
{ /* Must be minus 2 so it can still expand a single trailing '\n' or '\r'. */
1525
0
  char * destend = dest + destmax - 2 ;
1526
0
  const char * srcend = src + srcmax ;
1527
1528
0
  while (dest < destend && src < srcend)
1529
0
  { if ((src [0] == '\r' && src [1] == '\n') || (src [0] == '\n' && src [1] == '\r'))
1530
0
    { *dest++ = '\r' ;
1531
0
      *dest++ = '\n' ;
1532
0
      src += 2 ;
1533
0
      continue ;
1534
0
      } ;
1535
1536
0
    if (src [0] == '\r')
1537
0
    { *dest++ = '\r' ;
1538
0
      *dest++ = '\n' ;
1539
0
      src += 1 ;
1540
0
      continue ;
1541
0
      } ;
1542
1543
0
    if (src [0] == '\n')
1544
0
    { *dest++ = '\r' ;
1545
0
      *dest++ = '\n' ;
1546
0
      src += 1 ;
1547
0
      continue ;
1548
0
      } ;
1549
1550
0
    *dest++ = *src++ ;
1551
0
    } ;
1552
1553
  /* Make sure dest is terminated. */
1554
0
  *dest = 0 ;
1555
0
} /* psf_strlcpy_crlf */
1556
1557
sf_count_t
1558
psf_decode_frame_count (SF_PRIVATE *psf)
1559
546
{ sf_count_t count, readlen, total = 0 ;
1560
546
  BUF_UNION ubuf ;
1561
1562
  /* If we're reading from a pipe or the file is too long, just return SF_COUNT_MAX. */
1563
546
  if (psf_is_pipe (psf) || psf->datalength > 0x1000000)
1564
0
    return SF_COUNT_MAX ;
1565
1566
546
  psf_fseek (psf, psf->dataoffset, SEEK_SET) ;
1567
1568
546
  readlen = ARRAY_LEN (ubuf.ibuf) / psf->sf.channels ;
1569
546
  readlen *= psf->sf.channels ;
1570
1571
5.74k
  while ((count = psf->read_int (psf, ubuf.ibuf, readlen)) > 0)
1572
5.19k
    total += count ;
1573
1574
546
  psf_fseek (psf, psf->dataoffset, SEEK_SET) ;
1575
1576
546
  return total / psf->sf.channels ;
1577
546
} /* psf_decode_frame_count */
1578
1579
/*==============================================================================
1580
*/
1581
1582
0
#define CASE_NAME(x)    case x : return #x ; break ;
1583
1584
const char *
1585
str_of_major_format (int format)
1586
0
{ switch (SF_CONTAINER (format))
1587
0
  { CASE_NAME (SF_FORMAT_WAV) ;
1588
0
    CASE_NAME (SF_FORMAT_AIFF) ;
1589
0
    CASE_NAME (SF_FORMAT_AU) ;
1590
0
    CASE_NAME (SF_FORMAT_RAW) ;
1591
0
    CASE_NAME (SF_FORMAT_PAF) ;
1592
0
    CASE_NAME (SF_FORMAT_SVX) ;
1593
0
    CASE_NAME (SF_FORMAT_NIST) ;
1594
0
    CASE_NAME (SF_FORMAT_VOC) ;
1595
0
    CASE_NAME (SF_FORMAT_IRCAM) ;
1596
0
    CASE_NAME (SF_FORMAT_W64) ;
1597
0
    CASE_NAME (SF_FORMAT_MAT4) ;
1598
0
    CASE_NAME (SF_FORMAT_MAT5) ;
1599
0
    CASE_NAME (SF_FORMAT_PVF) ;
1600
0
    CASE_NAME (SF_FORMAT_XI) ;
1601
0
    CASE_NAME (SF_FORMAT_HTK) ;
1602
0
    CASE_NAME (SF_FORMAT_SDS) ;
1603
0
    CASE_NAME (SF_FORMAT_AVR) ;
1604
0
    CASE_NAME (SF_FORMAT_WAVEX) ;
1605
0
    CASE_NAME (SF_FORMAT_SD2) ;
1606
0
    CASE_NAME (SF_FORMAT_FLAC) ;
1607
0
    CASE_NAME (SF_FORMAT_CAF) ;
1608
0
    CASE_NAME (SF_FORMAT_WVE) ;
1609
0
    CASE_NAME (SF_FORMAT_OGG) ;
1610
0
    CASE_NAME (SF_FORMAT_MPEG) ;
1611
0
    default :
1612
0
      break ;
1613
0
    } ;
1614
1615
0
  return "BAD_MAJOR_FORMAT" ;
1616
0
} /* str_of_major_format */
1617
1618
const char *
1619
str_of_minor_format (int format)
1620
0
{ switch (SF_CODEC (format))
1621
0
  { CASE_NAME (SF_FORMAT_PCM_S8) ;
1622
0
    CASE_NAME (SF_FORMAT_PCM_16) ;
1623
0
    CASE_NAME (SF_FORMAT_PCM_24) ;
1624
0
    CASE_NAME (SF_FORMAT_PCM_32) ;
1625
0
    CASE_NAME (SF_FORMAT_PCM_U8) ;
1626
0
    CASE_NAME (SF_FORMAT_FLOAT) ;
1627
0
    CASE_NAME (SF_FORMAT_DOUBLE) ;
1628
0
    CASE_NAME (SF_FORMAT_ULAW) ;
1629
0
    CASE_NAME (SF_FORMAT_ALAW) ;
1630
0
    CASE_NAME (SF_FORMAT_IMA_ADPCM) ;
1631
0
    CASE_NAME (SF_FORMAT_MS_ADPCM) ;
1632
0
    CASE_NAME (SF_FORMAT_GSM610) ;
1633
0
    CASE_NAME (SF_FORMAT_VOX_ADPCM) ;
1634
0
    CASE_NAME (SF_FORMAT_NMS_ADPCM_16) ;
1635
0
    CASE_NAME (SF_FORMAT_NMS_ADPCM_24) ;
1636
0
    CASE_NAME (SF_FORMAT_NMS_ADPCM_32) ;
1637
0
    CASE_NAME (SF_FORMAT_G721_32) ;
1638
0
    CASE_NAME (SF_FORMAT_G723_24) ;
1639
0
    CASE_NAME (SF_FORMAT_G723_40) ;
1640
0
    CASE_NAME (SF_FORMAT_DWVW_12) ;
1641
0
    CASE_NAME (SF_FORMAT_DWVW_16) ;
1642
0
    CASE_NAME (SF_FORMAT_DWVW_24) ;
1643
0
    CASE_NAME (SF_FORMAT_DWVW_N) ;
1644
0
    CASE_NAME (SF_FORMAT_DPCM_8) ;
1645
0
    CASE_NAME (SF_FORMAT_DPCM_16) ;
1646
0
    CASE_NAME (SF_FORMAT_VORBIS) ;
1647
0
    CASE_NAME (SF_FORMAT_MPEG_LAYER_I) ;
1648
0
    CASE_NAME (SF_FORMAT_MPEG_LAYER_II) ;
1649
0
    CASE_NAME (SF_FORMAT_MPEG_LAYER_III) ;
1650
0
    default :
1651
0
      break ;
1652
0
    } ;
1653
1654
0
  return "BAD_MINOR_FORMAT" ;
1655
0
} /* str_of_minor_format */
1656
1657
const char *
1658
str_of_open_mode (int mode)
1659
0
{ switch (mode)
1660
0
  { CASE_NAME (SFM_READ) ;
1661
0
    CASE_NAME (SFM_WRITE) ;
1662
0
    CASE_NAME (SFM_RDWR) ;
1663
1664
0
    default :
1665
0
      break ;
1666
0
    } ;
1667
1668
0
  return "BAD_MODE" ;
1669
0
} /* str_of_open_mode */
1670
1671
const char *
1672
str_of_endianness (int end)
1673
0
{ switch (end)
1674
0
  { CASE_NAME (SF_ENDIAN_BIG) ;
1675
0
    CASE_NAME (SF_ENDIAN_LITTLE) ;
1676
0
    CASE_NAME (SF_ENDIAN_CPU) ;
1677
0
    default :
1678
0
      break ;
1679
0
    } ;
1680
1681
  /* Zero length string for SF_ENDIAN_FILE. */
1682
0
  return "" ;
1683
0
} /* str_of_endianness */
1684
1685
/*==============================================================================
1686
*/
1687
1688
void
1689
psf_f2s_array (const float *src, short *dest, int count, int normalize)
1690
0
{ float       normfact ;
1691
1692
0
  normfact = normalize ? (1.0 * 0x7FFF) : 1.0 ;
1693
0
  for (int i = 0 ; i < count ; i++)
1694
0
    dest [i] = psf_lrintf (src [i] * normfact) ;
1695
1696
0
  return ;
1697
0
} /* psf_f2s_array */
1698
1699
void
1700
psf_f2s_clip_array (const float *src, short *dest, int count, int normalize)
1701
0
{ float     normfact, scaled_value ;
1702
1703
0
  normfact = normalize ? (1.0 * 0x8000) : 1.0 ;
1704
1705
0
  for (int i = 0 ; i < count ; i++)
1706
0
  { scaled_value = src [i] * normfact ;
1707
0
    if (scaled_value >= (1.0 * 0x7FFF))
1708
0
    { dest [i] = 0x7FFF ;
1709
0
      continue ;
1710
0
      } ;
1711
0
    if (scaled_value <= (-8.0 * 0x1000))
1712
0
    { dest [i] = -0x7FFF - 1 ;
1713
0
      continue ;
1714
0
      } ;
1715
1716
0
    dest [i] = psf_lrintf (scaled_value) ;
1717
0
    } ;
1718
1719
0
  return ;
1720
0
} /* psf_f2s_clip_array */
1721
1722
void
1723
psf_d2s_array (const double *src, short *dest, int count, int normalize)
1724
0
{ double      normfact ;
1725
1726
0
  normfact = normalize ? (1.0 * 0x7FFF) : 1.0 ;
1727
0
  for (int i = 0 ; i < count ; i++)
1728
0
    dest [i] = psf_lrint (src [i] * normfact) ;
1729
1730
0
  return ;
1731
0
} /* psf_f2s_array */
1732
1733
void
1734
psf_d2s_clip_array (const double *src, short *dest, int count, int normalize)
1735
0
{ double      normfact, scaled_value ;
1736
1737
0
  normfact = normalize ? (1.0 * 0x8000) : 1.0 ;
1738
1739
0
  for (int i = 0 ; i < count ; i++)
1740
0
  { scaled_value = src [i] * normfact ;
1741
0
    if (scaled_value >= (1.0 * 0x7FFF))
1742
0
    { dest [i] = 0x7FFF ;
1743
0
      continue ;
1744
0
      } ;
1745
0
    if (scaled_value <= (-8.0 * 0x1000))
1746
0
    { dest [i] = -0x7FFF - 1 ;
1747
0
      continue ;
1748
0
      } ;
1749
1750
0
    dest [i] = psf_lrint (scaled_value) ;
1751
0
    } ;
1752
1753
0
  return ;
1754
0
} /* psf_d2s_clip_array */
1755
1756
1757
void
1758
psf_f2i_array (const float *src, int *dest, int count, int normalize)
1759
0
{ float       normfact ;
1760
1761
0
  normfact = normalize ? (1.0 * 0x7FFFFFFF) : 1.0 ;
1762
0
  for (int i = 0 ; i < count ; i++)
1763
0
    dest [i] = psf_lrintf (src [i] * normfact) ;
1764
1765
0
  return ;
1766
0
} /* psf_f2i_array */
1767
1768
void
1769
psf_f2i_clip_array (const float *src, int *dest, int count, int normalize)
1770
0
{ float     normfact, scaled_value ;
1771
1772
0
  normfact = normalize ? (8.0 * 0x10000000) : 1.0 ;
1773
1774
0
  for (int i = 0 ; i < count ; i++)
1775
0
  { scaled_value = src [i] * normfact ;
1776
0
    if (scaled_value >= (1.0 * 0x7FFFFFFF))
1777
0
    { dest [i] = 0x7FFFFFFF ;
1778
0
      continue ;
1779
0
      } ;
1780
0
    if (scaled_value <= (-8.0 * 0x10000000))
1781
0
    { dest [i] = 0x80000000 ;
1782
0
      continue ;
1783
0
      } ;
1784
1785
0
    dest [i] = psf_lrintf (scaled_value) ;
1786
0
    } ;
1787
1788
0
  return ;
1789
0
} /* psf_f2i_clip_array */
1790
1791
void
1792
psf_d2i_array (const double *src, int *dest, int count, int normalize)
1793
0
{ double      normfact ;
1794
1795
0
  normfact = normalize ? (1.0 * 0x7FFFFFFF) : 1.0 ;
1796
0
  for (int i = 0 ; i < count ; i++)
1797
0
    dest [i] = psf_lrint (src [i] * normfact) ;
1798
1799
0
  return ;
1800
0
} /* psf_f2i_array */
1801
1802
void
1803
psf_d2i_clip_array (const double *src, int *dest, int count, int normalize)
1804
0
{ double      normfact, scaled_value ;
1805
1806
0
  normfact = normalize ? (8.0 * 0x10000000) : 1.0 ;
1807
1808
0
  for (int i = 0 ; i < count ; i++)
1809
0
  { scaled_value = src [i] * normfact ;
1810
0
    if (scaled_value >= (1.0 * 0x7FFFFFFF))
1811
0
    { dest [i] = 0x7FFFFFFF ;
1812
0
      continue ;
1813
0
      } ;
1814
0
    if (scaled_value <= (-8.0 * 0x10000000))
1815
0
    { dest [i] = 0x80000000 ;
1816
0
      continue ;
1817
0
      } ;
1818
1819
0
    dest [i] = psf_lrint (scaled_value) ;
1820
0
    } ;
1821
1822
0
  return ;
1823
0
} /* psf_d2i_clip_array */
1824
1825
FILE *
1826
psf_open_tmpfile (char * fname, size_t fnamelen)
1827
0
{ const char * tmpdir ;
1828
0
  FILE * file ;
1829
1830
0
  if (OS_IS_WIN32)
1831
0
    tmpdir = getenv ("TEMP") ;
1832
0
  else
1833
0
  { tmpdir = getenv ("TMPDIR") ;
1834
0
    tmpdir = tmpdir == NULL ? "/tmp" : tmpdir ;
1835
0
    } ;
1836
1837
0
  if (tmpdir && access (tmpdir, R_OK | W_OK | X_OK) == 0)
1838
0
  { snprintf (fname, fnamelen, "%s/%x%x-alac.tmp", tmpdir, psf_rand_int32 (), psf_rand_int32 ()) ;
1839
0
    if ((file = fopen (fname, "wb+")) != NULL)
1840
0
      return file ;
1841
0
    } ;
1842
1843
0
  snprintf (fname, fnamelen, "%x%x-alac.tmp", psf_rand_int32 (), psf_rand_int32 ()) ;
1844
0
  if ((file = fopen (fname, "wb+")) != NULL)
1845
0
    return file ;
1846
1847
0
  memset (fname, 0, fnamelen) ;
1848
0
  return NULL ;
1849
0
} /* psf_open_tmpfile */