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