Coverage Report

Created: 2025-07-12 06:10

/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
58.8k
#define INITIAL_HEADER_SIZE 256
40
41
/* Allocate and initialize the SF_PRIVATE struct. */
42
SF_PRIVATE *
43
psf_allocate (void)
44
21.4k
{ SF_PRIVATE * psf ;
45
46
21.4k
  if ((psf = calloc (1, sizeof (SF_PRIVATE))) == NULL)
47
0
    return  NULL ;
48
49
21.4k
  if ((psf->header.ptr = calloc (1, INITIAL_HEADER_SIZE)) == NULL)
50
0
  { free (psf) ;
51
0
    return  NULL ;
52
21.4k
    } ;
53
21.4k
  psf->header.len = INITIAL_HEADER_SIZE ;
54
55
21.4k
  return psf ;
56
21.4k
} /* psf_allocate */
57
58
static int
59
psf_bump_header_allocation (SF_PRIVATE * psf, sf_count_t needed)
60
15.9k
{
61
15.9k
  sf_count_t newlen, smallest = INITIAL_HEADER_SIZE ;
62
15.9k
  void * ptr ;
63
64
15.9k
  newlen = (needed > psf->header.len) ? 2 * SF_MAX (needed, smallest) : 2 * psf->header.len ;
65
66
15.9k
  if (newlen > 100 * 1024)
67
7.98k
  { psf_log_printf (psf, "Request for header allocation of %D denied.\n", newlen) ;
68
7.98k
    return 1 ;
69
7.98k
    }
70
71
7.98k
  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
7.98k
    } ;
76
77
  /* Always zero-out new header memory to avoid un-initializer memory accesses. */
78
7.98k
  if (newlen > psf->header.len)
79
7.98k
    memset ((char *) ptr + psf->header.len, 0, newlen - psf->header.len) ;
80
81
7.98k
  psf->header.ptr = ptr ;
82
7.98k
  psf->header.len = newlen ;
83
7.98k
  return 0 ;
84
7.98k
} /* 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
672M
{ if (psf->parselog.indx < SIGNED_SIZEOF (psf->parselog.buf) - 1)
98
10.8M
  { psf->parselog.buf [psf->parselog.indx++] = ch ;
99
10.8M
    psf->parselog.buf [psf->parselog.indx] = 0 ;
100
10.8M
    } ;
101
672M
  return ;
102
672M
} /* log_putchar */
103
104
void
105
psf_log_printf (SF_PRIVATE *psf, const char *format, ...)
106
19.3M
{ va_list   ap ;
107
19.3M
  uint32_t  u, tens ;
108
19.3M
  int     d, shift, width, width_specifier, left_align, slen, precision ;
109
19.3M
  char    c, *strptr, istr [5], lead_char, sign_char ;
110
111
19.3M
  va_start (ap, format) ;
112
113
646M
  while ((c = *format++))
114
626M
  { if (c != '%')
115
594M
    { log_putchar (psf, c) ;
116
594M
      continue ;
117
594M
      } ;
118
119
32.5M
    if (format [0] == '%') /* Handle %% */
120
0
    {   log_putchar (psf, '%') ;
121
0
      format ++ ;
122
0
      continue ;
123
32.5M
      } ;
124
125
32.5M
    sign_char = 0 ;
126
32.5M
    left_align = SF_FALSE ;
127
32.6M
    while (1)
128
32.6M
    { switch (format [0])
129
32.6M
      { case ' ' :
130
0
        case '+' :
131
0
          sign_char = format [0] ;
132
0
          format ++ ;
133
0
          continue ;
134
135
117k
        case '-' :
136
117k
          left_align = SF_TRUE ;
137
117k
          format ++ ;
138
117k
          continue ;
139
140
32.5M
        default : break ;
141
32.6M
        } ;
142
143
32.5M
      break ;
144
32.6M
      } ;
145
146
32.5M
    if (format [0] == 0)
147
0
      break ;
148
149
32.5M
    lead_char = ' ' ;
150
32.5M
    if (format [0] == '0')
151
7.15M
      lead_char = '0' ;
152
153
32.5M
    width_specifier = 0 ;
154
47.1M
    while ((c = *format++) && isdigit (c))
155
14.5M
      width_specifier = width_specifier * 10 + (c - '0') ;
156
157
32.5M
    precision = 0 ;
158
32.5M
    if (c == '.')
159
0
    { while ((c = *format++) && isdigit (c))
160
0
        precision = precision * 10 + (c - '0') ;
161
0
      } ;
162
163
32.5M
    switch (c)
164
32.5M
    { case 0 : /* NULL character. */
165
0
          va_end (ap) ;
166
0
          return ;
167
168
1.72M
      case 's': /* string */
169
1.72M
          strptr = va_arg (ap, char *) ;
170
1.72M
          if (strptr == NULL)
171
0
            break ;
172
1.72M
          if (precision > 0)
173
0
            slen = strnlen (strptr, precision) ;
174
1.72M
          else
175
1.72M
            slen = strlen (strptr) ;
176
1.72M
          width_specifier = width_specifier >= slen ? width_specifier - slen : 0 ;
177
1.72M
          if (left_align == SF_FALSE)
178
1.61M
            while (width_specifier -- > 0)
179
0
              log_putchar (psf, ' ') ;
180
9.52M
          while (slen--)
181
7.79M
            log_putchar (psf, *strptr++) ;
182
2.96M
          while (width_specifier -- > 0)
183
1.24M
            log_putchar (psf, ' ') ;
184
1.72M
          break ;
185
186
18.1M
      case 'd': /* int */
187
18.1M
          d = va_arg (ap, int) ;
188
189
18.1M
          if (d < 0)
190
181k
          { sign_char = '-' ;
191
181k
            if (lead_char != '0' && left_align == SF_FALSE)
192
181k
              width_specifier -- ;
193
194
181k
            u = - ((unsigned) d) ;
195
181k
            }
196
17.9M
          else
197
17.9M
          { u = (unsigned) d ;
198
17.9M
            }
199
200
18.1M
          tens = 1 ;
201
18.1M
          width = 1 ;
202
38.5M
          while (u / tens >= 10)
203
20.4M
          { tens *= 10 ;
204
20.4M
            width ++ ;
205
20.4M
            } ;
206
207
18.1M
          width_specifier -= width ;
208
209
18.1M
          if (sign_char == ' ')
210
0
          { log_putchar (psf, ' ') ;
211
0
            width_specifier -- ;
212
0
            } ;
213
214
18.1M
          if (left_align == SF_FALSE && lead_char != '0')
215
18.1M
          { if (sign_char == '+')
216
0
              width_specifier -- ;
217
218
18.1M
            while (width_specifier -- > 0)
219
6.37k
              log_putchar (psf, lead_char) ;
220
18.1M
            } ;
221
222
18.1M
          if (sign_char == '+' || sign_char == '-')
223
181k
          { log_putchar (psf, sign_char) ;
224
181k
            width_specifier -- ;
225
181k
            } ;
226
227
18.1M
          if (left_align == SF_FALSE)
228
18.1M
            while (width_specifier -- > 0)
229
69
              log_putchar (psf, lead_char) ;
230
231
56.6M
          while (tens > 0)
232
38.5M
          { log_putchar (psf, '0' + u / tens) ;
233
38.5M
            u %= tens ;
234
38.5M
            tens /= 10 ;
235
38.5M
            } ;
236
237
18.1M
          while (width_specifier -- > 0)
238
0
            log_putchar (psf, lead_char) ;
239
18.1M
          break ;
240
241
157k
      case 'D': /* sf_count_t */
242
157k
          { sf_count_t  D ;
243
157k
            uint64_t  U, Tens ;
244
245
157k
            D = va_arg (ap, sf_count_t) ;
246
247
157k
            if (D == 0)
248
7.21k
            { while (-- width_specifier > 0)
249
0
                log_putchar (psf, lead_char) ;
250
7.21k
              log_putchar (psf, '0') ;
251
7.21k
              break ;
252
7.21k
              }
253
150k
            else
254
150k
            { if (D < 0)
255
49.7k
              { log_putchar (psf, '-') ;
256
49.7k
                U = - ((uint64_t) D) ;
257
49.7k
                }
258
100k
              else
259
100k
              { U = (uint64_t) D ;
260
100k
                }
261
150k
              }
262
263
150k
            Tens = 1 ;
264
150k
            width = 1 ;
265
968k
            while (U / Tens >= 10)
266
818k
            { Tens *= 10 ;
267
818k
              width ++ ;
268
818k
              } ;
269
270
150k
            while (width_specifier > width)
271
0
            { log_putchar (psf, lead_char) ;
272
0
              width_specifier-- ;
273
0
              } ;
274
275
1.11M
            while (Tens > 0)
276
968k
            { log_putchar (psf, '0' + U / Tens) ;
277
968k
              U %= Tens ;
278
968k
              Tens /= 10 ;
279
968k
              } ;
280
150k
            } ;
281
150k
          break ;
282
283
784k
      case 'u': /* unsigned int */
284
784k
          u = va_arg (ap, unsigned int) ;
285
286
784k
          tens = 1 ;
287
784k
          width = 1 ;
288
3.46M
          while (u / tens >= 10)
289
2.67M
          { tens *= 10 ;
290
2.67M
            width ++ ;
291
2.67M
            } ;
292
293
784k
          width_specifier -= width ;
294
295
784k
          if (sign_char == ' ')
296
0
          { log_putchar (psf, ' ') ;
297
0
            width_specifier -- ;
298
0
            } ;
299
300
784k
          if (left_align == SF_FALSE && lead_char != '0')
301
783k
          { if (sign_char == '+')
302
0
              width_specifier -- ;
303
304
795k
            while (width_specifier -- > 0)
305
12.1k
              log_putchar (psf, lead_char) ;
306
783k
            } ;
307
308
784k
          if (sign_char == '+' || sign_char == '-')
309
0
          { log_putchar (psf, sign_char) ;
310
0
            width_specifier -- ;
311
0
            } ;
312
313
784k
          if (left_align == SF_FALSE)
314
784k
            while (width_specifier -- > 0)
315
554
              log_putchar (psf, lead_char) ;
316
317
4.24M
          while (tens > 0)
318
3.46M
          { log_putchar (psf, '0' + u / tens) ;
319
3.46M
            u %= tens ;
320
3.46M
            tens /= 10 ;
321
3.46M
            } ;
322
323
784k
          while (width_specifier -- > 0)
324
0
            log_putchar (psf, lead_char) ;
325
784k
          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
2.47M
      case 'x': /* hex */
333
10.2M
      case 'X': /* hex */
334
10.2M
          d = va_arg (ap, int) ;
335
336
10.2M
          if (d == 0)
337
7.11M
          { while (--width_specifier > 0)
338
2.43M
              log_putchar (psf, lead_char) ;
339
4.68M
            log_putchar (psf, '0') ;
340
4.68M
            break ;
341
5.56M
            } ;
342
5.56M
          shift = 28 ;
343
5.56M
          width = (width_specifier < 8) ? 8 : width_specifier ;
344
37.7M
          while (! ((((uint32_t) 0xF) << shift) & d))
345
32.2M
          { shift -= 4 ;
346
32.2M
            width -- ;
347
32.2M
            } ;
348
349
6.12M
          while (width > 0 && width_specifier > width)
350
566k
          { log_putchar (psf, lead_char) ;
351
566k
            width_specifier-- ;
352
566k
            } ;
353
354
17.8M
          while (shift >= 0)
355
12.2M
          { c = (d >> shift) & 0xF ;
356
12.2M
            log_putchar (psf, (c > 9) ? c + 'A' - 10 : c + '0') ;
357
12.2M
            shift -= 4 ;
358
12.2M
            } ;
359
5.56M
          break ;
360
361
1.51M
      case 'M': /* int2str */
362
1.51M
          d = va_arg (ap, int) ;
363
1.51M
          if (CPU_IS_LITTLE_ENDIAN)
364
1.51M
          { istr [0] = d & 0xFF ;
365
1.51M
            istr [1] = (d >> 8) & 0xFF ;
366
1.51M
            istr [2] = (d >> 16) & 0xFF ;
367
1.51M
            istr [3] = (d >> 24) & 0xFF ;
368
1.51M
            }
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
1.51M
          istr [4] = 0 ;
376
1.51M
          strptr = istr ;
377
7.26M
          while (*strptr)
378
5.74M
          { c = *strptr++ ;
379
5.74M
            log_putchar (psf, psf_isprint (c) ? c : '.') ;
380
5.74M
            } ;
381
1.51M
          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
32.5M
      } /* switch */
389
32.5M
    } /* while */
390
391
19.3M
  va_end (ap) ;
392
19.3M
  return ;
393
19.3M
} /* 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
1.63M
#define GET_MARKER(ptr) ( ((ptr) [0])     | ((ptr) [1] << 8) |  \
834
1.63M
              ((ptr) [2] << 16) | (((uint32_t) (ptr) [3]) << 24))
835
836
#else
837
# error "Cannot determine endian-ness of processor."
838
#endif
839
840
1.42M
#define GET_LE_SHORT(ptr) (((ptr) [1] << 8) | ((ptr) [0]))
841
2.01M
#define GET_BE_SHORT(ptr) (((ptr) [0] << 8) | ((ptr) [1]))
842
843
2.03k
#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
9.70M
{ int count = 0 ;
867
868
9.70M
  if (psf->header.indx + bytes >= psf->header.len && psf_bump_header_allocation (psf, bytes))
869
629
    return count ;
870
871
9.70M
  if (psf->header.indx + bytes > psf->header.end)
872
8.52M
  { count = psf_fread (psf->header.ptr + psf->header.end, 1, bytes - (psf->header.end - psf->header.indx), psf) ;
873
8.52M
    if (count != bytes - (int) (psf->header.end - psf->header.indx))
874
3.24M
    { psf_log_printf (psf, "Error : psf_fread returned short count.\n") ;
875
3.24M
      return count ;
876
5.27M
      } ;
877
5.27M
    psf->header.end += count ;
878
6.46M
    } ;
879
880
6.46M
  memcpy (ptr, psf->header.ptr + psf->header.indx, bytes) ;
881
6.46M
  psf->header.indx += bytes ;
882
883
6.46M
  return bytes ;
884
9.70M
} /* header_read */
885
886
static void
887
header_seek (SF_PRIVATE *psf, sf_count_t position, int whence)
888
858k
{
889
858k
  switch (whence)
890
858k
  { case SEEK_SET :
891
27.3k
      if (psf->header.indx + position >= psf->header.len)
892
401
        psf_bump_header_allocation (psf, position) ;
893
27.3k
      if (position > psf->header.len)
894
4
      { /* Too much header to cache so just seek instead. */
895
4
        psf->header.indx = psf->header.end = 0 ;
896
4
        psf_fseek (psf, position, whence) ;
897
4
        return ;
898
27.3k
        } ;
899
27.3k
      if (position > psf->header.end)
900
1.23k
        psf->header.end += psf_fread (psf->header.ptr + psf->header.end, 1, position - psf->header.end, psf) ;
901
27.3k
      psf->header.indx = position ;
902
27.3k
      break ;
903
904
830k
    case SEEK_CUR :
905
830k
      if (psf->header.indx + position >= psf->header.len)
906
7.58k
        psf_bump_header_allocation (psf, position) ;
907
908
830k
      if (psf->header.indx + position < 0)
909
3.80k
        break ;
910
911
826k
      if (psf->header.indx >= psf->header.len)
912
0
      { psf_fseek (psf, position, whence) ;
913
0
        return ;
914
826k
        } ;
915
916
826k
      if (psf->header.indx + position <= psf->header.end)
917
280k
      { psf->header.indx += position ;
918
280k
        break ;
919
546k
        } ;
920
921
546k
      if (psf->header.indx + position > psf->header.len)
922
5.51k
      { /* Need to jump this without caching it. */
923
5.51k
        position -= (psf->header.end - psf->header.indx) ;
924
5.51k
        psf->header.indx = psf->header.end ;
925
5.51k
        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
5.51k
        else
937
5.51k
        { psf_fseek (psf, position, SEEK_CUR) ;
938
5.51k
          }
939
5.51k
        break ;
940
541k
        } ;
941
942
541k
      psf->header.end += psf_fread (psf->header.ptr + psf->header.end, 1, position - (psf->header.end - psf->header.indx), psf) ;
943
541k
      psf->header.indx = psf->header.end ;
944
541k
      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
858k
    } ;
951
952
858k
  return ;
953
858k
} /* header_seek */
954
955
static int
956
header_gets (SF_PRIVATE *psf, char *ptr, int bufsize)
957
160
{ int   k ;
958
959
160
  if (psf->header.indx + bufsize >= psf->header.len && psf_bump_header_allocation (psf, bufsize))
960
0
    return 0 ;
961
962
2.74k
  for (k = 0 ; k < bufsize - 1 ; k++)
963
2.68k
  { if (psf->header.indx < psf->header.end)
964
1.09k
    { ptr [k] = psf->header.ptr [psf->header.indx] ;
965
1.09k
      psf->header.indx ++ ;
966
1.09k
      }
967
1.58k
    else
968
1.58k
    { psf->header.end += psf_fread (psf->header.ptr + psf->header.end, 1, 1, psf) ;
969
1.58k
      ptr [k] = psf->header.ptr [psf->header.indx] ;
970
1.58k
      psf->header.indx = psf->header.end ;
971
1.58k
      } ;
972
973
2.68k
    if (ptr [k] == '\n')
974
99
      break ;
975
2.68k
    } ;
976
977
160
  ptr [k] = 0 ;
978
979
160
  return k ;
980
160
} /* header_gets */
981
982
int
983
psf_binheader_readf (SF_PRIVATE *psf, char const *format, ...)
984
5.59M
{ va_list     argptr ;
985
5.59M
  sf_count_t    *countptr, countdata ;
986
5.59M
  unsigned char *ucptr, sixteen_bytes [16] = { 0 } ;
987
5.59M
  unsigned int  *intptr, intdata ;
988
5.59M
  unsigned short  *shortptr ;
989
5.59M
  char      *charptr ;
990
5.59M
  float     *floatptr ;
991
5.59M
  double      *doubleptr ;
992
5.59M
  char      c ;
993
5.59M
  int       byte_count = 0, count = 0 ;
994
5.59M
  int       read_bytes = 0 ;
995
996
5.59M
  if (! format)
997
0
    return psf_ftell (psf) ;
998
999
5.59M
  va_start (argptr, format) ;
1000
1001
18.4M
  while ((c = *format++))
1002
12.8M
  {
1003
12.8M
    read_bytes = 0 ;
1004
12.8M
    if (psf->header.indx + 16 >= psf->header.len && psf_bump_header_allocation (psf, 16))
1005
1.83k
      break ;
1006
1007
12.8M
    switch (c)
1008
12.8M
    { case 'e' : /* All conversions are now from LE to host. */
1009
1.17M
          psf->rwf_endian = SF_ENDIAN_LITTLE ;
1010
1.17M
          break ;
1011
1012
1.08M
      case 'E' : /* All conversions are now from BE to host. */
1013
1.08M
          psf->rwf_endian = SF_ENDIAN_BIG ;
1014
1.08M
          break ;
1015
1016
1.63M
      case 'm' : /* 4 byte marker value eg 'RIFF' */
1017
1.63M
          intptr = va_arg (argptr, unsigned int*) ;
1018
1.63M
          *intptr = 0 ;
1019
1.63M
          ucptr = (unsigned char*) intptr ;
1020
1.63M
          read_bytes = header_read (psf, ucptr, sizeof (int)) ;
1021
1.63M
          *intptr = GET_MARKER (ucptr) ;
1022
1.63M
          break ;
1023
1024
64.1k
      case 'h' :
1025
64.1k
          intptr = va_arg (argptr, unsigned int*) ;
1026
64.1k
          *intptr = 0 ;
1027
64.1k
          ucptr = (unsigned char*) intptr ;
1028
64.1k
          read_bytes = header_read (psf, sixteen_bytes, sizeof (sixteen_bytes)) ;
1029
64.1k
          { int k ;
1030
64.1k
            intdata = 0 ;
1031
1.09M
            for (k = 0 ; k < 16 ; k++)
1032
1.02M
              intdata ^= sixteen_bytes [k] << k ;
1033
64.1k
            }
1034
64.1k
          *intptr = intdata ;
1035
64.1k
          break ;
1036
1037
333k
      case '1' :
1038
333k
          charptr = va_arg (argptr, char*) ;
1039
333k
          *charptr = 0 ;
1040
333k
          read_bytes = header_read (psf, charptr, sizeof (char)) ;
1041
333k
          break ;
1042
1043
3.43M
      case '2' : /* 2 byte value with the current endian-ness */
1044
3.43M
          shortptr = va_arg (argptr, unsigned short*) ;
1045
3.43M
          *shortptr = 0 ;
1046
3.43M
          ucptr = (unsigned char*) shortptr ;
1047
3.43M
          read_bytes = header_read (psf, ucptr, sizeof (short)) ;
1048
3.43M
          if (psf->rwf_endian == SF_ENDIAN_BIG)
1049
2.01M
            *shortptr = GET_BE_SHORT (ucptr) ;
1050
1.42M
          else
1051
1.42M
            *shortptr = GET_LE_SHORT (ucptr) ;
1052
3.43M
          break ;
1053
1054
2.03k
      case '3' : /* 3 byte value with the current endian-ness */
1055
2.03k
          intptr = va_arg (argptr, unsigned int*) ;
1056
2.03k
          *intptr = 0 ;
1057
2.03k
          read_bytes = header_read (psf, sixteen_bytes, 3) ;
1058
2.03k
          if (psf->rwf_endian == SF_ENDIAN_BIG)
1059
0
            *intptr = GET_BE_3BYTE (sixteen_bytes) ;
1060
2.03k
          else
1061
2.03k
            *intptr = GET_LE_3BYTE (sixteen_bytes) ;
1062
2.03k
          break ;
1063
1064
3.02M
      case '4' : /* 4 byte value with the current endian-ness */
1065
3.02M
          intptr = va_arg (argptr, unsigned int*) ;
1066
3.02M
          *intptr = 0 ;
1067
3.02M
          ucptr = (unsigned char*) intptr ;
1068
3.02M
          read_bytes = header_read (psf, ucptr, sizeof (int)) ;
1069
3.02M
          if (psf->rwf_endian == SF_ENDIAN_BIG)
1070
1.09M
            *intptr = psf_get_be32 (ucptr, 0) ;
1071
1.92M
          else
1072
1.92M
            *intptr = psf_get_le32 (ucptr, 0) ;
1073
3.02M
          break ;
1074
1075
80.8k
      case '8' : /* 8 byte value with the current endian-ness */
1076
80.8k
          countptr = va_arg (argptr, sf_count_t *) ;
1077
80.8k
          *countptr = 0 ;
1078
80.8k
          read_bytes = header_read (psf, sixteen_bytes, 8) ;
1079
80.8k
          if (psf->rwf_endian == SF_ENDIAN_BIG)
1080
13.7k
            countdata = psf_get_be64 (sixteen_bytes, 0) ;
1081
67.1k
          else
1082
67.1k
            countdata = psf_get_le64 (sixteen_bytes, 0) ;
1083
80.8k
          *countptr = countdata ;
1084
80.8k
          break ;
1085
1086
32.5k
      case 'f' : /* Float conversion */
1087
32.5k
          floatptr = va_arg (argptr, float *) ;
1088
32.5k
          *floatptr = 0.0 ;
1089
32.5k
          read_bytes = header_read (psf, floatptr, sizeof (float)) ;
1090
32.5k
          if (psf->rwf_endian == SF_ENDIAN_BIG)
1091
6.57k
            *floatptr = float32_be_read ((unsigned char*) floatptr) ;
1092
25.9k
          else
1093
25.9k
            *floatptr = float32_le_read ((unsigned char*) floatptr) ;
1094
32.5k
          break ;
1095
1096
668
      case 'd' : /* double conversion */
1097
668
          doubleptr = va_arg (argptr, double *) ;
1098
668
          *doubleptr = 0.0 ;
1099
668
          read_bytes = header_read (psf, doubleptr, sizeof (double)) ;
1100
668
          if (psf->rwf_endian == SF_ENDIAN_BIG)
1101
83
            *doubleptr = double64_be_read ((unsigned char*) doubleptr) ;
1102
585
          else
1103
585
            *doubleptr = double64_le_read ((unsigned char*) doubleptr) ;
1104
668
          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
1.09M
      case 'b' : /* Raw bytes */
1120
1.09M
          charptr = va_arg (argptr, char*) ;
1121
1.09M
          count = va_arg (argptr, size_t) ;
1122
1.09M
          memset (charptr, 0, count) ;
1123
1.09M
          read_bytes = header_read (psf, charptr, count) ;
1124
1.09M
          break ;
1125
1126
160
      case 'G' :
1127
160
          charptr = va_arg (argptr, char*) ;
1128
160
          count = va_arg (argptr, size_t) ;
1129
160
          memset (charptr, 0, count) ;
1130
1131
160
          if (psf->header.indx + count >= psf->header.len && psf_bump_header_allocation (psf, count))
1132
0
            break ;
1133
1134
160
          read_bytes = header_gets (psf, charptr, count) ;
1135
160
          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
27.3k
      case 'p' :  /* Seek to position from start. */
1150
27.3k
          count = va_arg (argptr, size_t) ;
1151
27.3k
          header_seek (psf, count, SEEK_SET) ;
1152
27.3k
          byte_count = count ;
1153
27.3k
          break ;
1154
1155
830k
      case 'j' :  /* Seek to position from current position. */
1156
830k
          count = va_arg (argptr, size_t) ;
1157
830k
          header_seek (psf, count, SEEK_CUR) ;
1158
830k
          read_bytes = count ;
1159
830k
          break ;
1160
1161
3.63k
      case '!' : /* Clear buffer, forcing re-read. */
1162
3.63k
          psf->header.end = psf->header.indx = 0 ;
1163
3.63k
          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
12.8M
      } ;
1170
1171
12.8M
    if (read_bytes > 0 && byte_count > (INT_MAX - read_bytes))
1172
1
    { psf_log_printf (psf, "Header size exceeds INT_MAX. Aborting.", c) ;
1173
1
      psf->error = SFE_INTERNAL ;
1174
1
      break ;
1175
1
    } else
1176
12.8M
    { byte_count += read_bytes ;
1177
12.8M
    } ;
1178
1179
12.8M
    } ; /*end while*/
1180
1181
5.59M
  va_end (argptr) ;
1182
1183
5.59M
  return byte_count ;
1184
5.59M
} /* 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
1.06k
{ psf_log_printf (psf, "---------------------------------\n") ;
1250
1251
1.06k
  psf_log_printf (psf, " Sample rate :   %d\n", psf->sf.samplerate) ;
1252
1.06k
  if (psf->sf.frames == SF_COUNT_MAX)
1253
1
    psf_log_printf (psf, " Frames      :   unknown\n") ;
1254
1.06k
  else
1255
1.06k
    psf_log_printf (psf, " Frames      :   %D\n", psf->sf.frames) ;
1256
1.06k
  psf_log_printf (psf, " Channels    :   %d\n", psf->sf.channels) ;
1257
1258
1.06k
  psf_log_printf (psf, " Format      :   0x%X\n", psf->sf.format) ;
1259
1.06k
  psf_log_printf (psf, " Sections    :   %d\n", psf->sf.sections) ;
1260
1.06k
  psf_log_printf (psf, " Seekable    :   %s\n", psf->sf.seekable ? "TRUE" : "FALSE") ;
1261
1262
1.06k
  psf_log_printf (psf, "---------------------------------\n") ;
1263
1.06k
} /* psf_dump_SFINFO */
1264
1265
/*========================================================================================
1266
*/
1267
1268
int
1269
psf_isprint (int ch)
1270
5.88M
{ return (ch >= ' ' && ch <= '~') ;
1271
5.88M
} /* 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
26.2k
{ strncpy (dest, src, n - 1) ;
1282
26.2k
  dest [n - 1] = 0 ;
1283
26.2k
} /* 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
4.96k
{ char  *ptr ;
1302
4.96k
  int   setcount ;
1303
1304
4.96k
  ptr = (char *) s ;
1305
1306
9.93k
  while (len > 0)
1307
4.96k
  { setcount = (len > 0x10000000) ? 0x10000000 : (int) len ;
1308
1309
4.96k
    memset (ptr, c, setcount) ;
1310
1311
4.96k
    ptr += setcount ;
1312
4.96k
    len -= setcount ;
1313
4.96k
    } ;
1314
1315
4.96k
  return s ;
1316
4.96k
} /* 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
802
#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
802
{ SF_CUES *pcues = calloc (1, SF_CUES_VAR_SIZE (cue_count)) ;
1339
802
  if (pcues)
1340
802
  { pcues->cue_count = cue_count ;
1341
802
    } ;
1342
802
  return pcues ;
1343
802
} /* 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
1.55k
{ SF_INSTRUMENT *instr ;
1377
1378
1.55k
  instr = calloc (1, sizeof (SF_INSTRUMENT)) ;
1379
1380
1.55k
  if (instr == NULL)
1381
0
    return NULL ;
1382
1383
  /* Set non-zero default values. */
1384
1.55k
  instr->basenote = -1 ;
1385
1.55k
  instr->velocity_lo = -1 ;
1386
1.55k
  instr->velocity_hi = -1 ;
1387
1.55k
  instr->key_lo = -1 ;
1388
1.55k
  instr->key_hi = -1 ;
1389
1390
1.55k
  return instr ;
1391
1.55k
} /* psf_instrument_alloc */
1392
1393
void
1394
psf_sanitize_string (char * cptr, int len)
1395
124
{
1396
124
  do
1397
99.4k
  {
1398
99.4k
    len -- ;
1399
99.4k
    cptr [len] = psf_isprint (cptr [len]) ? cptr [len] : '.' ;
1400
99.4k
  }
1401
99.4k
  while (len > 0) ;
1402
124
} /* 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
5.62k
{ static int array [] =
1456
5.62k
  { SF_FORMAT_PCM_S8, SF_FORMAT_PCM_16, SF_FORMAT_PCM_24, SF_FORMAT_PCM_32
1457
5.62k
    } ;
1458
1459
5.62k
  if (bits < 8 || bits > 32)
1460
3.83k
    return 0 ;
1461
1462
1.79k
  return array [((bits + 7) / 8) - 1] ;
1463
5.62k
} /* bitwidth_to_subformat */
1464
1465
int
1466
u_bitwidth_to_subformat (int bits)
1467
10.3k
{ static int array [] =
1468
10.3k
  { SF_FORMAT_PCM_U8, SF_FORMAT_PCM_16, SF_FORMAT_PCM_24, SF_FORMAT_PCM_32
1469
10.3k
    } ;
1470
1471
10.3k
  if (bits < 8 || bits > 32)
1472
6.87k
    return 0 ;
1473
1474
3.49k
  return array [((bits + 7) / 8) - 1] ;
1475
10.3k
} /* 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
21.4k
{ static uint64_t value = 0 ;
1486
21.4k
  int k, count ;
1487
1488
21.4k
  if (value == 0)
1489
1
  {
1490
1
#if HAVE_GETTIMEOFDAY
1491
1
    struct timeval tv ;
1492
1
    gettimeofday (&tv, NULL) ;
1493
1
    value = tv.tv_sec + tv.tv_usec ;
1494
#else
1495
    value = time (NULL) ;
1496
#endif
1497
1
    } ;
1498
1499
21.4k
  count = 4 + (value & 7) ;
1500
192k
  for (k = 0 ; k < count ; k++)
1501
171k
    value = (11117 * value + 211231) & 0x7fffffff ;
1502
1503
21.4k
  return (int32_t) value ;
1504
21.4k
} /* psf_rand_int32 */
1505
1506
void
1507
append_snprintf (char * dest, size_t maxlen, const char * fmt, ...)
1508
54.0k
{ size_t len = strlen (dest) ;
1509
1510
54.0k
  if (len < maxlen)
1511
54.0k
  { va_list ap ;
1512
1513
54.0k
    va_start (ap, fmt) ;
1514
54.0k
    vsnprintf (dest + len, maxlen - len, fmt, ap) ;
1515
54.0k
    va_end (ap) ;
1516
54.0k
    } ;
1517
1518
54.0k
  return ;
1519
54.0k
} /* 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
294
{ sf_count_t count, readlen, total = 0 ;
1560
294
  BUF_UNION ubuf ;
1561
1562
  /* If we're reading from a pipe or the file is too long, just return SF_COUNT_MAX. */
1563
294
  if (psf_is_pipe (psf) || psf->datalength > 0x1000000)
1564
0
    return SF_COUNT_MAX ;
1565
1566
294
  psf_fseek (psf, psf->dataoffset, SEEK_SET) ;
1567
1568
294
  readlen = ARRAY_LEN (ubuf.ibuf) / psf->sf.channels ;
1569
294
  readlen *= psf->sf.channels ;
1570
1571
4.52k
  while ((count = psf->read_int (psf, ubuf.ibuf, readlen)) > 0)
1572
4.23k
    total += count ;
1573
1574
294
  psf_fseek (psf, psf->dataoffset, SEEK_SET) ;
1575
1576
294
  return total / psf->sf.channels ;
1577
294
} /* 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 */