xref: /third_party/libsnd/src/common.c (revision b815c7f3)
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. */
41SF_PRIVATE *
42psf_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
57static int
58psf_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
94static inline void
95log_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
103void
104psf_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
402void
403psf_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
473static inline void
474header_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)
479static inline void
480header_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)
488static inline void
489header_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
501static inline void
502header_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
507static inline void
508header_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
513static inline void
514header_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
520static inline void
521header_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
527static inline void
528header_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
535static inline void
536header_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
543static inline void
544header_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
555static inline void
556header_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
567int
568psf_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
863static int
864header_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
885static void
886header_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
954static int
955header_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
981int
982psf_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
1177sf_count_t
1178psf_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
1204void
1205psf_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
1235void
1236psf_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
1256int
1257psf_isprint (int ch)
1258{	return (ch >= ' ' && ch <= '~') ;
1259} /* psf_isprint */
1260
1261void
1262psf_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
1267void
1268psf_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
1276void *
1277psf_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
1287void*
1288psf_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
1313typedef SF_CUES_VAR (0) SF_CUES_0 ;
1314#else
1315typedef 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
1324SF_CUES *
1325psf_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
1333SF_CUES *
1334psf_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
1347void
1348psf_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
1362SF_INSTRUMENT *
1363psf_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
1381void
1382psf_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
1392void
1393psf_get_date_str (char *str, int maxlen)
1394{	time_t		current ;
1395	struct tm	timedata, *tmptr ;
1396
1397	time (&current) ;
1398
1399#if defined (HAVE_GMTIME_R)
1400	/* If the re-entrant version is available, use it. */
1401	tmptr = gmtime_r (&current, &timedata) ;
1402#elif defined (HAVE_GMTIME)
1403	/* Otherwise use the standard one and copy the data to local storage. */
1404	tmptr = gmtime (&current) ;
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
1420int
1421subformat_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
1441int
1442s_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
1453int
1454u_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
1471int32_t
1472psf_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
1494void
1495append_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
1510void
1511psf_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
1545sf_count_t
1546psf_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
1572const char *
1573str_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
1606const char *
1607str_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
1645const char *
1646str_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
1659const char *
1660str_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
1676void
1677psf_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
1687void
1688psf_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
1710void
1711psf_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
1721void
1722psf_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
1745void
1746psf_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
1756void
1757psf_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
1783void
1784psf_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
1794void
1795psf_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
1821FILE *
1822psf_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