• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 ** Copyright (C) 1999-2018 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	"sfconfig.h"
20 
21 #include	<stdlib.h>
22 #include	<string.h>
23 #include	<ctype.h>
24 #include	<assert.h>
25 
26 #include	"sndfile.h"
27 #include	"sfendian.h"
28 #include	"common.h"
29 
30 #if HAVE_UNISTD_H
31 #include <unistd.h>
32 #elif defined _WIN32
33 #include <io.h>
34 #endif
35 
36 #define		SNDFILE_MAGICK	0x1234C0DE
37 
38 #ifdef __APPLE__
39 	/*
40 	**	Detect if a compile for a universal binary is being attempted and barf if it is.
41 	**	See the URL below for the rationale.
42 	*/
43 	#ifdef __BIG_ENDIAN__
44 		#if (CPU_IS_LITTLE_ENDIAN == 1)
45 			#error "Universal binary compile detected. See http://libsndfile.github.io/libsndfile/FAQ.html#Q018"
46 		#endif
47 	#endif
48 
49 	#ifdef __LITTLE_ENDIAN__
50 		#if (CPU_IS_BIG_ENDIAN == 1)
51 			#error "Universal binary compile detected. See http://libsndfile.github.io/libsndfile/FAQ.html#Q018"
52 		#endif
53 	#endif
54 #endif
55 
56 
57 typedef struct
58 {	int 		error ;
59 	const char	*str ;
60 } ErrorStruct ;
61 
62 static
63 ErrorStruct SndfileErrors [] =
64 {
65 	/* Public error values and their associated strings. */
66 	{	SF_ERR_NO_ERROR				, "No Error." },
67 	{	SF_ERR_UNRECOGNISED_FORMAT	, "Format not recognised." },
68 	{	SF_ERR_SYSTEM				, "System error." /* Often replaced. */ 	},
69 	{	SF_ERR_MALFORMED_FILE		, "Supported file format but file is malformed." },
70 	{	SF_ERR_UNSUPPORTED_ENCODING	, "Supported file format but unsupported encoding." },
71 
72 	/* Private error values and their associated strings. */
73 	{	SFE_ZERO_MAJOR_FORMAT	, "Error : major format is 0." },
74 	{	SFE_ZERO_MINOR_FORMAT	, "Error : minor format is 0." },
75 	{	SFE_BAD_FILE			, "File does not exist or is not a regular file (possibly a pipe?)." },
76 	{	SFE_BAD_FILE_READ		, "File exists but no data could be read." },
77 	{	SFE_OPEN_FAILED			, "Could not open file." },
78 	{	SFE_BAD_SNDFILE_PTR		, "Not a valid SNDFILE* pointer." },
79 	{	SFE_BAD_SF_INFO_PTR		, "NULL SF_INFO pointer passed to libsndfile." },
80 	{	SFE_BAD_SF_INCOMPLETE	, "SF_PRIVATE struct incomplete and end of header parsing." },
81 	{	SFE_BAD_FILE_PTR		, "Bad FILE pointer." },
82 	{	SFE_BAD_INT_PTR			, "Internal error, Bad pointer." },
83 	{	SFE_BAD_STAT_SIZE		, "Error : software was misconfigured at compile time (sizeof statbuf.st_size)." },
84 	{	SFE_NO_TEMP_DIR			, "Error : Could not file temp dir." },
85 
86 	{	SFE_MALLOC_FAILED		, "Internal malloc () failed." },
87 	{	SFE_UNIMPLEMENTED		, "File contains data in an unimplemented format." },
88 	{	SFE_BAD_READ_ALIGN		, "Attempt to read a non-integer number of channels." },
89 	{	SFE_BAD_WRITE_ALIGN 	, "Attempt to write a non-integer number of channels." },
90 	{	SFE_NOT_READMODE		, "Read attempted on file currently open for write." },
91 	{	SFE_NOT_WRITEMODE		, "Write attempted on file currently open for read." },
92 	{	SFE_BAD_MODE_RW			, "Error : This file format does not support read/write mode." },
93 	{	SFE_BAD_SF_INFO			, "Internal error : SF_INFO struct incomplete." },
94 	{	SFE_BAD_OFFSET			, "Error : supplied offset beyond end of file." },
95 	{	SFE_NO_EMBED_SUPPORT	, "Error : embedding not supported for this file format." },
96 	{	SFE_NO_EMBEDDED_RDWR	, "Error : cannot open embedded file read/write." },
97 	{	SFE_NO_PIPE_WRITE		, "Error : this file format does not support pipe write." },
98 	{	SFE_BAD_VIRTUAL_IO		, "Error : bad pointer on SF_VIRTUAL_IO struct." },
99 	{	SFE_BAD_BROADCAST_INFO_SIZE
100 								, "Error : bad coding_history_size in SF_BROADCAST_INFO struct." },
101 	{	SFE_BAD_BROADCAST_INFO_TOO_BIG
102 								, "Error : SF_BROADCAST_INFO struct too large." },
103 	{	SFE_BAD_CART_INFO_SIZE				, "Error: SF_CART_INFO struct too large." },
104 	{	SFE_BAD_CART_INFO_TOO_BIG			, "Error: bad tag_text_size in SF_CART_INFO struct." },
105 	{	SFE_INTERLEAVE_MODE		, "Attempt to write to file with non-interleaved data." },
106 	{	SFE_INTERLEAVE_SEEK		, "Bad karma in seek during interleave read operation." },
107 	{	SFE_INTERLEAVE_READ		, "Bad karma in read during interleave read operation." },
108 
109 	{	SFE_INTERNAL			, "Unspecified internal error." },
110 	{	SFE_BAD_COMMAND_PARAM	, "Bad parameter passed to function sf_command." },
111 	{	SFE_BAD_ENDIAN			, "Bad endian-ness. Try default endian-ness" },
112 	{	SFE_CHANNEL_COUNT_ZERO	, "Channel count is zero." },
113 	{	SFE_CHANNEL_COUNT		, "Too many channels specified." },
114 	{	SFE_CHANNEL_COUNT_BAD	, "Bad channel count." },
115 
116 	{	SFE_BAD_SEEK			, "Internal psf_fseek() failed." },
117 	{	SFE_NOT_SEEKABLE		, "Seek attempted on unseekable file type." },
118 	{	SFE_AMBIGUOUS_SEEK		, "Error : combination of file open mode and seek command is ambiguous." },
119 	{	SFE_WRONG_SEEK			, "Error : invalid seek parameters." },
120 	{	SFE_SEEK_FAILED			, "Error : parameters OK, but psf_seek() failed." },
121 
122 	{	SFE_BAD_OPEN_MODE		, "Error : bad mode parameter for file open." },
123 	{	SFE_OPEN_PIPE_RDWR		, "Error : attempt to open a pipe in read/write mode." },
124 	{	SFE_RDWR_POSITION		, "Error on RDWR position (cryptic)." },
125 	{	SFE_RDWR_BAD_HEADER		, "Error : Cannot open file in read/write mode due to string data in header." },
126 	{	SFE_CMD_HAS_DATA		, "Error : Command fails because file already has audio data." },
127 
128 	{	SFE_STR_NO_SUPPORT		, "Error : File type does not support string data." },
129 	{	SFE_STR_NOT_WRITE		, "Error : Trying to set a string when file is not in write mode." },
130 	{	SFE_STR_MAX_DATA		, "Error : Maximum string data storage reached." },
131 	{	SFE_STR_MAX_COUNT		, "Error : Maximum string data count reached." },
132 	{	SFE_STR_BAD_TYPE		, "Error : Bad string data type." },
133 	{	SFE_STR_NO_ADD_END		, "Error : file type does not support strings added at end of file." },
134 	{	SFE_STR_BAD_STRING		, "Error : bad string." },
135 	{	SFE_STR_WEIRD			, "Error : Weird string error." },
136 
137 	{	SFE_WAV_NO_RIFF			, "Error in WAV file. No 'RIFF' chunk marker." },
138 	{	SFE_WAV_NO_WAVE			, "Error in WAV file. No 'WAVE' chunk marker." },
139 	{	SFE_WAV_NO_FMT			, "Error in WAV/W64/RF64 file. No 'fmt ' chunk marker." },
140 	{	SFE_WAV_BAD_FMT			, "Error in WAV/W64/RF64 file. Malformed 'fmt ' chunk." },
141 	{	SFE_WAV_FMT_SHORT		, "Error in WAV/W64/RF64 file. Short 'fmt ' chunk." },
142 
143 	{	SFE_WAV_BAD_FACT		, "Error in WAV file. 'fact' chunk out of place." },
144 	{	SFE_WAV_BAD_PEAK		, "Error in WAV file. Bad 'PEAK' chunk." },
145 	{	SFE_WAV_PEAK_B4_FMT		, "Error in WAV file. 'PEAK' chunk found before 'fmt ' chunk." },
146 
147 	{	SFE_WAV_BAD_FORMAT		, "Error in WAV file. Errors in 'fmt ' chunk." },
148 	{	SFE_WAV_BAD_BLOCKALIGN	, "Error in WAV file. Block alignment in 'fmt ' chunk is incorrect." },
149 	{	SFE_WAV_NO_DATA			, "Error in WAV file. No 'data' chunk marker." },
150 	{	SFE_WAV_BAD_LIST		, "Error in WAV file. Malformed LIST chunk." },
151 	{	SFE_WAV_UNKNOWN_CHUNK	, "Error in WAV file. File contains an unknown chunk marker." },
152 	{	SFE_WAV_WVPK_DATA		, "Error in WAV file. Data is in WAVPACK format." },
153 
154 	{	SFE_WAV_ADPCM_NOT4BIT	, "Error in ADPCM WAV file. Invalid bit width." },
155 	{	SFE_WAV_ADPCM_CHANNELS	, "Error in ADPCM WAV file. Invalid number of channels." },
156 	{	SFE_WAV_ADPCM_SAMPLES	, "Error in ADPCM WAV file. Invalid number of samples per block." },
157 	{	SFE_WAV_GSM610_FORMAT	, "Error in GSM610 WAV file. Invalid format chunk." },
158 	{	SFE_WAV_NMS_FORMAT		, "Error in NMS ADPCM WAV file. Invalid format chunk." },
159 
160 	{	SFE_AIFF_NO_FORM		, "Error in AIFF file, bad 'FORM' marker." },
161 	{	SFE_AIFF_AIFF_NO_FORM	, "Error in AIFF file, 'AIFF' marker without 'FORM'." },
162 	{	SFE_AIFF_COMM_NO_FORM	, "Error in AIFF file, 'COMM' marker without 'FORM'." },
163 	{	SFE_AIFF_SSND_NO_COMM	, "Error in AIFF file, 'SSND' marker without 'COMM'." },
164 	{	SFE_AIFF_UNKNOWN_CHUNK	, "Error in AIFF file, unknown chunk." },
165 	{	SFE_AIFF_COMM_CHUNK_SIZE, "Error in AIFF file, bad 'COMM' chunk size." },
166 	{	SFE_AIFF_BAD_COMM_CHUNK , "Error in AIFF file, bad 'COMM' chunk." },
167 	{	SFE_AIFF_PEAK_B4_COMM	, "Error in AIFF file. 'PEAK' chunk found before 'COMM' chunk." },
168 	{	SFE_AIFF_BAD_PEAK		, "Error in AIFF file. Bad 'PEAK' chunk." },
169 	{	SFE_AIFF_NO_SSND		, "Error in AIFF file, bad 'SSND' chunk." },
170 	{	SFE_AIFF_NO_DATA		, "Error in AIFF file, no sound data." },
171 	{	SFE_AIFF_RW_SSND_NOT_LAST, "Error in AIFF file, RDWR only possible if SSND chunk at end of file." },
172 
173 	{	SFE_AU_UNKNOWN_FORMAT	, "Error in AU file, unknown format." },
174 	{	SFE_AU_NO_DOTSND		, "Error in AU file, missing '.snd' or 'dns.' marker." },
175 	{	SFE_AU_EMBED_BAD_LEN	, "Embedded AU file with unknown length." },
176 
177 	{	SFE_RAW_READ_BAD_SPEC	, "Error while opening RAW file for read. Must specify format and channels.\n"
178 									"Possibly trying to open unsupported format." },
179 	{	SFE_RAW_BAD_BITWIDTH	, "Error. RAW file bitwidth must be a multiple of 8." },
180 	{	SFE_RAW_BAD_FORMAT		, "Error. Bad format field in SF_INFO struct when opening a RAW file for read." },
181 
182 	{	SFE_PAF_NO_MARKER		, "Error in PAF file, no marker." },
183 	{	SFE_PAF_VERSION			, "Error in PAF file, bad version." },
184 	{	SFE_PAF_UNKNOWN_FORMAT	, "Error in PAF file, unknown format." },
185 	{	SFE_PAF_SHORT_HEADER	, "Error in PAF file. File shorter than minimal header." },
186 	{	SFE_PAF_BAD_CHANNELS	, "Error in PAF file. Bad channel count." },
187 
188 	{	SFE_SVX_NO_FORM			, "Error in 8SVX / 16SV file, no 'FORM' marker." },
189 	{	SFE_SVX_NO_BODY			, "Error in 8SVX / 16SV file, no 'BODY' marker." },
190 	{	SFE_SVX_NO_DATA			, "Error in 8SVX / 16SV file, no sound data." },
191 	{	SFE_SVX_BAD_COMP		, "Error in 8SVX / 16SV file, unsupported compression format." },
192 	{	SFE_SVX_BAD_NAME_LENGTH	, "Error in 8SVX / 16SV file, NAME chunk too long." },
193 
194 	{	SFE_NIST_BAD_HEADER		, "Error in NIST file, bad header." },
195 	{	SFE_NIST_CRLF_CONVERISON, "Error : NIST file damaged by Windows CR -> CRLF conversion process."	},
196 	{	SFE_NIST_BAD_ENCODING	, "Error in NIST file, unsupported compression format." },
197 
198 	{	SFE_VOC_NO_CREATIVE		, "Error in VOC file, no 'Creative Voice File' marker." },
199 	{	SFE_VOC_BAD_FORMAT		, "Error in VOC file, bad format." },
200 	{	SFE_VOC_BAD_VERSION		, "Error in VOC file, bad version number." },
201 	{	SFE_VOC_BAD_MARKER		, "Error in VOC file, bad marker in file." },
202 	{	SFE_VOC_BAD_SECTIONS	, "Error in VOC file, incompatible VOC sections." },
203 	{	SFE_VOC_MULTI_SAMPLERATE, "Error in VOC file, more than one sample rate defined." },
204 	{	SFE_VOC_MULTI_SECTION	, "Unimplemented VOC file feature, file contains multiple sound sections." },
205 	{	SFE_VOC_MULTI_PARAM		, "Error in VOC file, file contains multiple bit or channel widths." },
206 	{	SFE_VOC_SECTION_COUNT	, "Error in VOC file, too many sections." },
207 	{	SFE_VOC_NO_PIPE			, "Error : not able to operate on VOC files over a pipe." },
208 
209 	{	SFE_IRCAM_NO_MARKER		, "Error in IRCAM file, bad IRCAM marker." },
210 	{	SFE_IRCAM_BAD_CHANNELS	, "Error in IRCAM file, bad channel count." },
211 	{	SFE_IRCAM_UNKNOWN_FORMAT, "Error in IRCAM file, unknown encoding format." },
212 
213 	{	SFE_W64_64_BIT			, "Error in W64 file, file contains 64 bit offset." },
214 	{	SFE_W64_NO_RIFF			, "Error in W64 file. No 'riff' chunk marker." },
215 	{	SFE_W64_NO_WAVE			, "Error in W64 file. No 'wave' chunk marker." },
216 	{	SFE_W64_NO_DATA			, "Error in W64 file. No 'data' chunk marker." },
217 	{	SFE_W64_ADPCM_NOT4BIT	, "Error in ADPCM W64 file. Invalid bit width." },
218 	{	SFE_W64_ADPCM_CHANNELS	, "Error in ADPCM W64 file. Invalid number of channels." },
219 	{	SFE_W64_GSM610_FORMAT	, "Error in GSM610 W64 file. Invalid format chunk." },
220 
221 	{	SFE_MAT4_BAD_NAME		, "Error in MAT4 file. No variable name." },
222 	{	SFE_MAT4_NO_SAMPLERATE	, "Error in MAT4 file. No sample rate." },
223 
224 	{	SFE_MAT5_BAD_ENDIAN		, "Error in MAT5 file. Not able to determine endian-ness." },
225 	{	SFE_MAT5_NO_BLOCK		, "Error in MAT5 file. Bad block structure." },
226 	{	SFE_MAT5_SAMPLE_RATE	, "Error in MAT5 file. Not able to determine sample rate." },
227 
228 	{	SFE_PVF_NO_PVF1			, "Error in PVF file. No PVF1 marker." },
229 	{	SFE_PVF_BAD_HEADER		, "Error in PVF file. Bad header." },
230 	{	SFE_PVF_BAD_BITWIDTH	, "Error in PVF file. Bad bit width." },
231 
232 	{	SFE_XI_BAD_HEADER		, "Error in XI file. Bad header." },
233 	{	SFE_XI_EXCESS_SAMPLES	, "Error in XI file. Excess samples in file." },
234 	{	SFE_XI_NO_PIPE			, "Error : not able to operate on XI files over a pipe." },
235 
236 	{	SFE_HTK_NO_PIPE			, "Error : not able to operate on HTK files over a pipe." },
237 
238 	{	SFE_SDS_NOT_SDS			, "Error : not an SDS file." },
239 	{	SFE_SDS_BAD_BIT_WIDTH	, "Error : bad bit width for SDS file." },
240 
241 	{	SFE_SD2_FD_DISALLOWED	, "Error : cannot open SD2 file without a file name." },
242 	{	SFE_SD2_BAD_DATA_OFFSET	, "Error : bad data offset." },
243 	{	SFE_SD2_BAD_MAP_OFFSET	, "Error : bad map offset." },
244 	{	SFE_SD2_BAD_DATA_LENGTH	, "Error : bad data length." },
245 	{	SFE_SD2_BAD_MAP_LENGTH	, "Error : bad map length." },
246 	{	SFE_SD2_BAD_RSRC		, "Error : bad resource fork." },
247 	{	SFE_SD2_BAD_SAMPLE_SIZE	, "Error : bad sample size." },
248 
249 	{	SFE_FLAC_BAD_HEADER		, "Error : bad flac header." },
250 	{	SFE_FLAC_NEW_DECODER	, "Error : problem while creating flac decoder." },
251 	{	SFE_FLAC_INIT_DECODER	, "Error : problem with initialization of the flac decoder." },
252 	{	SFE_FLAC_LOST_SYNC		, "Error : flac decoder lost sync." },
253 	{	SFE_FLAC_BAD_SAMPLE_RATE, "Error : flac does not support this sample rate." },
254 	{	SFE_FLAC_CHANNEL_COUNT_CHANGED, "Error : flac channel changed mid stream." },
255 	{	SFE_FLAC_UNKOWN_ERROR	, "Error : unknown error in flac decoder." },
256 
257 	{	SFE_WVE_NOT_WVE			, "Error : not a WVE file." },
258 	{	SFE_WVE_NO_PIPE			, "Error : not able to operate on WVE files over a pipe." },
259 
260 	{	SFE_DWVW_BAD_BITWIDTH	, "Error : Bad bit width for DWVW encoding. Must be 12, 16 or 24." },
261 	{	SFE_G72X_NOT_MONO		, "Error : G72x encoding does not support more than 1 channel." },
262 	{	SFE_NMS_ADPCM_NOT_MONO	, "Error : NMS ADPCM encoding does not support more than 1 channel." },
263 
264 	{	SFE_VORBIS_ENCODER_BUG	, "Error : Sample rate chosen is known to trigger a Vorbis encoder bug on this CPU." },
265 
266 	{	SFE_RF64_NOT_RF64		, "Error : Not an RF64 file." },
267 	{	SFE_RF64_PEAK_B4_FMT	, "Error in RF64 file. 'PEAK' chunk found before 'fmt ' chunk." },
268 	{	SFE_RF64_NO_DATA		, "Error in RF64 file. No 'data' chunk marker." },
269 
270 	{	SFE_ALAC_FAIL_TMPFILE	, "Error : Failed to open tmp file for ALAC encoding." },
271 
272 	{	SFE_BAD_CHUNK_PTR		, "Error : Bad SF_CHUNK_INFO pointer." },
273 	{	SFE_UNKNOWN_CHUNK		, "Error : Unknown chunk marker." },
274 	{	SFE_BAD_CHUNK_FORMAT	, "Error : Reading/writing chunks from this file format is not supported." },
275 	{	SFE_BAD_CHUNK_MARKER	, "Error : Bad chunk marker." },
276 	{	SFE_BAD_CHUNK_DATA_PTR	, "Error : Bad data pointer in SF_CHUNK_INFO struct." },
277 	{	SFE_FILENAME_TOO_LONG	, "Error : Supplied filename too long." },
278 	{	SFE_NEGATIVE_RW_LEN		, "Error : Length parameter passed to read/write is negative." },
279 
280 	{	SFE_OPUS_BAD_SAMPLERATE	, "Error : Opus only supports sample rates of 8000, 12000, 16000, 24000 and 48000." },
281 
282 	{	SFE_MAX_ERROR			, "Maximum error number." },
283 	{	SFE_MAX_ERROR + 1		, NULL }
284 } ;
285 
286 /*------------------------------------------------------------------------------
287 */
288 
289 static int 	format_from_extension (SF_PRIVATE *psf) ;
290 static int	guess_file_type (SF_PRIVATE *psf) ;
291 static int	validate_sfinfo (SF_INFO *sfinfo) ;
292 static int	validate_psf (SF_PRIVATE *psf) ;
293 static void	save_header_info (SF_PRIVATE *psf) ;
294 static int	copy_filename (SF_PRIVATE *psf, const char *path) ;
295 static int	psf_close (SF_PRIVATE *psf) ;
296 
297 static int	try_resource_fork (SF_PRIVATE * psf) ;
298 
299 /*------------------------------------------------------------------------------
300 ** Private (static) variables.
301 */
302 
303 int	sf_errno = 0 ;
304 static char	sf_parselog [SF_BUFFER_LEN] = { 0 } ;
305 static char	sf_syserr [SF_SYSERR_LEN] = { 0 } ;
306 
307 /*------------------------------------------------------------------------------
308 */
309 
310 #define	VALIDATE_SNDFILE_AND_ASSIGN_PSF(a, b, c)	\
311 		{	if ((a) == NULL)						\
312 			{	sf_errno = SFE_BAD_SNDFILE_PTR ;	\
313 				return 0 ;							\
314 				} ;									\
315 			(b) = (SF_PRIVATE*) (a) ;				\
316 			if ((b)->virtual_io == SF_FALSE &&		\
317 				psf_file_valid (b) == 0)			\
318 			{	(b)->error = SFE_BAD_FILE_PTR ;		\
319 				return 0 ;							\
320 				} ;									\
321 			if ((b)->Magick != SNDFILE_MAGICK)		\
322 			{	(b)->error = SFE_BAD_SNDFILE_PTR ;	\
323 				return 0 ;							\
324 				} ;									\
325 			if (c) (b)->error = 0 ;					\
326 			}
327 
328 /*------------------------------------------------------------------------------
329 **	Public functions.
330 */
331 
332 SNDFILE*
sf_open(const char * path,int mode,SF_INFO * sfinfo)333 sf_open	(const char *path, int mode, SF_INFO *sfinfo)
334 {	SF_PRIVATE 	*psf ;
335 
336 	/* Ultimate sanity check. */
337 	assert (sizeof (sf_count_t) == 8) ;
338 
339 	if ((psf = psf_allocate ()) == NULL)
340 	{	sf_errno = SFE_MALLOC_FAILED ;
341 		return	NULL ;
342 		} ;
343 
344 	psf_init_files (psf) ;
345 
346 	psf_log_printf (psf, "File : %s\n", path) ;
347 
348 	if (copy_filename (psf, path) != 0)
349 	{	sf_errno = psf->error ;
350 		return	NULL ;
351 		} ;
352 
353 	psf->file.mode = mode ;
354 	if (strcmp (path, "-") == 0)
355 		psf->error = psf_set_stdio (psf) ;
356 	else
357 		psf->error = psf_fopen (psf) ;
358 
359 	return psf_open_file (psf, sfinfo) ;
360 } /* sf_open */
361 
362 SNDFILE*
sf_open_fd(int fd,int mode,SF_INFO * sfinfo,int close_desc)363 sf_open_fd	(int fd, int mode, SF_INFO *sfinfo, int close_desc)
364 {	SF_PRIVATE 	*psf ;
365 	SNDFILE		*result ;
366 
367 	if ((SF_CONTAINER (sfinfo->format)) == SF_FORMAT_SD2)
368 	{	sf_errno = SFE_SD2_FD_DISALLOWED ;
369 		if (close_desc)
370 			close (fd) ;
371 
372 		return	NULL ;
373 		} ;
374 
375 	if ((psf = psf_allocate ()) == NULL)
376 	{	sf_errno = SFE_MALLOC_FAILED ;
377 		if (close_desc)
378 			close (fd) ;
379 
380 		return	NULL ;
381 		} ;
382 
383 	psf_init_files (psf) ;
384 	copy_filename (psf, "") ;
385 
386 	psf->file.mode = mode ;
387 	psf_set_file (psf, fd) ;
388 	psf->is_pipe = psf_is_pipe (psf) ;
389 	psf->fileoffset = psf_ftell (psf) ;
390 
391 	result = psf_open_file (psf, sfinfo) ;
392 	if (result != NULL && ! close_desc)
393 			psf->file.do_not_close_descriptor = SF_TRUE ;
394 
395 	return result ;
396 } /* sf_open_fd */
397 
398 SNDFILE*
sf_open_virtual(SF_VIRTUAL_IO * sfvirtual,int mode,SF_INFO * sfinfo,void * user_data)399 sf_open_virtual	(SF_VIRTUAL_IO *sfvirtual, int mode, SF_INFO *sfinfo, void *user_data)
400 {	SF_PRIVATE 	*psf ;
401 
402 	/* Make sure we have a valid set ot virtual pointers. */
403 	if (sfvirtual->get_filelen == NULL)
404 	{	sf_errno = SFE_BAD_VIRTUAL_IO ;
405 		snprintf (sf_parselog, sizeof (sf_parselog), "Bad vio_get_filelen in SF_VIRTUAL_IO struct.\n") ;
406 		return NULL ;
407 		} ;
408 
409 	if ((sfvirtual->seek == NULL || sfvirtual->tell == NULL) && sfinfo->seekable)
410 	{	sf_errno = SFE_BAD_VIRTUAL_IO ;
411 		snprintf (sf_parselog, sizeof (sf_parselog), "Bad vio_seek / vio_tell in SF_VIRTUAL_IO struct.\n") ;
412 		return NULL ;
413 		} ;
414 
415 	if ((mode == SFM_READ || mode == SFM_RDWR) && sfvirtual->read == NULL)
416 	{	sf_errno = SFE_BAD_VIRTUAL_IO ;
417 		snprintf (sf_parselog, sizeof (sf_parselog), "Bad vio_read in SF_VIRTUAL_IO struct.\n") ;
418 		return NULL ;
419 		} ;
420 
421 	if ((mode == SFM_WRITE || mode == SFM_RDWR) && sfvirtual->write == NULL)
422 	{	sf_errno = SFE_BAD_VIRTUAL_IO ;
423 		snprintf (sf_parselog, sizeof (sf_parselog), "Bad vio_write in SF_VIRTUAL_IO struct.\n") ;
424 		return NULL ;
425 		} ;
426 
427 	if ((psf = psf_allocate ()) == NULL)
428 	{	sf_errno = SFE_MALLOC_FAILED ;
429 		return	NULL ;
430 		} ;
431 
432 	psf_init_files (psf) ;
433 
434 	psf->virtual_io = SF_TRUE ;
435 	psf->vio = *sfvirtual ;
436 	psf->vio_user_data = user_data ;
437 
438 	psf->file.mode = mode ;
439 
440 	return psf_open_file (psf, sfinfo) ;
441 } /* sf_open_virtual */
442 
443 int
sf_close(SNDFILE * sndfile)444 sf_close	(SNDFILE *sndfile)
445 {	SF_PRIVATE	*psf ;
446 
447 	VALIDATE_SNDFILE_AND_ASSIGN_PSF (sndfile, psf, 1) ;
448 
449 	return psf_close (psf) ;
450 } /* sf_close */
451 
452 void
sf_write_sync(SNDFILE * sndfile)453 sf_write_sync	(SNDFILE *sndfile)
454 {	SF_PRIVATE	*psf ;
455 
456 	if ((psf = (SF_PRIVATE *) sndfile) == NULL)
457 		return ;
458 
459 	psf_fsync (psf) ;
460 
461 	return ;
462 } /* sf_write_sync */
463 
464 /*==============================================================================
465 */
466 
467 const char*
sf_error_number(int errnum)468 sf_error_number	(int errnum)
469 {	static const char *bad_errnum =
470 		"No error defined for this error number. This is a bug in libsndfile." ;
471 	int	k ;
472 
473 	if (errnum == SFE_MAX_ERROR)
474 		return SndfileErrors [0].str ;
475 
476 	if (errnum < 0 || errnum > SFE_MAX_ERROR)
477 	{	/* This really shouldn't happen in release versions. */
478 		printf ("Not a valid error number (%d).\n", errnum) ;
479 		return bad_errnum ;
480 		} ;
481 
482 	for (k = 0 ; SndfileErrors [k].str ; k++)
483 		if (errnum == SndfileErrors [k].error)
484 			return SndfileErrors [k].str ;
485 
486 	return bad_errnum ;
487 } /* sf_error_number */
488 
489 const char*
sf_strerror(SNDFILE * sndfile)490 sf_strerror (SNDFILE *sndfile)
491 {	SF_PRIVATE 	*psf = NULL ;
492 	int errnum ;
493 
494 	if (sndfile == NULL)
495 	{	errnum = sf_errno ;
496 		if (errnum == SFE_SYSTEM && sf_syserr [0])
497 			return sf_syserr ;
498 		}
499 	else
500 	{	psf = (SF_PRIVATE *) sndfile ;
501 
502 		if (psf->Magick != SNDFILE_MAGICK)
503 			return	"sf_strerror : Bad magic number." ;
504 
505 		errnum = psf->error ;
506 
507 		if (errnum == SFE_SYSTEM && psf->syserr [0])
508 			return psf->syserr ;
509 		} ;
510 
511 	return sf_error_number (errnum) ;
512 } /* sf_strerror */
513 
514 /*------------------------------------------------------------------------------
515 */
516 
517 int
sf_error(SNDFILE * sndfile)518 sf_error (SNDFILE *sndfile)
519 {	SF_PRIVATE	*psf ;
520 
521 	if (sndfile == NULL)
522 		return sf_errno ;
523 
524 	VALIDATE_SNDFILE_AND_ASSIGN_PSF (sndfile, psf, 0) ;
525 
526 	if (psf->error)
527 		return psf->error ;
528 
529 	return 0 ;
530 } /* sf_error */
531 
532 /*------------------------------------------------------------------------------
533 */
534 
535 int
sf_perror(SNDFILE * sndfile)536 sf_perror (SNDFILE *sndfile)
537 {	SF_PRIVATE 	*psf ;
538 	int 		errnum ;
539 
540 	if (sndfile == NULL)
541 	{	errnum = sf_errno ;
542 		}
543 	else
544 	{	VALIDATE_SNDFILE_AND_ASSIGN_PSF (sndfile, psf, 0) ;
545 		errnum = psf->error ;
546 		} ;
547 
548 	fprintf (stderr, "%s\n", sf_error_number (errnum)) ;
549 	return SFE_NO_ERROR ;
550 } /* sf_perror */
551 
552 
553 /*------------------------------------------------------------------------------
554 */
555 
556 int
sf_error_str(SNDFILE * sndfile,char * str,size_t maxlen)557 sf_error_str (SNDFILE *sndfile, char *str, size_t maxlen)
558 {	SF_PRIVATE 	*psf ;
559 	int 		errnum ;
560 
561 	if (str == NULL)
562 		return SFE_INTERNAL ;
563 
564 	if (sndfile == NULL)
565 		errnum = sf_errno ;
566 	else
567 	{	VALIDATE_SNDFILE_AND_ASSIGN_PSF (sndfile, psf, 0) ;
568 		errnum = psf->error ;
569 		} ;
570 
571 	snprintf (str, maxlen, "%s", sf_error_number (errnum)) ;
572 
573 	return SFE_NO_ERROR ;
574 } /* sf_error_str */
575 
576 /*==============================================================================
577 */
578 
579 int
sf_format_check(const SF_INFO * info)580 sf_format_check	(const SF_INFO *info)
581 {	int	subformat, endian ;
582 
583 	subformat = SF_CODEC (info->format) ;
584 	endian = SF_ENDIAN (info->format) ;
585 
586 	/* This is the place where each file format can check if the supplied
587 	** SF_INFO struct is valid.
588 	** Return 0 on failure, 1 ons success.
589 	*/
590 
591 	if (info->channels < 1 || info->channels > SF_MAX_CHANNELS)
592 		return 0 ;
593 
594 	if (info->samplerate < 0)
595 		return 0 ;
596 
597 	switch (SF_CONTAINER (info->format))
598 	{	case SF_FORMAT_WAV :
599 				/* WAV now allows both endian, RIFF or RIFX (little or big respectively) */
600 				if (subformat == SF_FORMAT_PCM_U8 || subformat == SF_FORMAT_PCM_16)
601 					return 1 ;
602 				if (subformat == SF_FORMAT_PCM_24 || subformat == SF_FORMAT_PCM_32)
603 					return 1 ;
604 				if ((subformat == SF_FORMAT_IMA_ADPCM || subformat == SF_FORMAT_MS_ADPCM) && info->channels <= 2)
605 					return 1 ;
606 				if (subformat == SF_FORMAT_GSM610 && info->channels == 1)
607 					return 1 ;
608 				if (subformat == SF_FORMAT_G721_32 && info->channels == 1)
609 					return 1 ;
610 				if (subformat == SF_FORMAT_ULAW || subformat == SF_FORMAT_ALAW)
611 					return 1 ;
612 				if (subformat == SF_FORMAT_FLOAT || subformat == SF_FORMAT_DOUBLE)
613 					return 1 ;
614 				if ((subformat == SF_FORMAT_NMS_ADPCM_16 || subformat == SF_FORMAT_NMS_ADPCM_24 ||
615 							subformat == SF_FORMAT_NMS_ADPCM_32) && info->channels == 1)
616 					return 1 ;
617 				break ;
618 
619 		case SF_FORMAT_WAVEX :
620 				if (endian == SF_ENDIAN_BIG || endian == SF_ENDIAN_CPU)
621 					return 0 ;
622 				if (subformat == SF_FORMAT_PCM_U8 || subformat == SF_FORMAT_PCM_16)
623 					return 1 ;
624 				if (subformat == SF_FORMAT_PCM_24 || subformat == SF_FORMAT_PCM_32)
625 					return 1 ;
626 				if (subformat == SF_FORMAT_ULAW || subformat == SF_FORMAT_ALAW)
627 					return 1 ;
628 				if (subformat == SF_FORMAT_FLOAT || subformat == SF_FORMAT_DOUBLE)
629 					return 1 ;
630 				break ;
631 
632 		case SF_FORMAT_AIFF :
633 				/* AIFF does allow both endian-nesses for PCM data.*/
634 				if (subformat == SF_FORMAT_PCM_16 || subformat == SF_FORMAT_PCM_24 || subformat == SF_FORMAT_PCM_32)
635 					return 1 ;
636 				/* For other encodings reject any endian-ness setting. */
637 				if (endian != 0)
638 					return 0 ;
639 				if (subformat == SF_FORMAT_PCM_U8 || subformat == SF_FORMAT_PCM_S8)
640 					return 1 ;
641 				if (subformat == SF_FORMAT_FLOAT || subformat == SF_FORMAT_DOUBLE)
642 					return 1 ;
643 				if (subformat == SF_FORMAT_ULAW || subformat == SF_FORMAT_ALAW)
644 					return 1 ;
645 				if ((subformat == SF_FORMAT_DWVW_12 || subformat == SF_FORMAT_DWVW_16 ||
646 							subformat == SF_FORMAT_DWVW_24) && info-> channels == 1)
647 					return 1 ;
648 				if (subformat == SF_FORMAT_GSM610 && info->channels == 1)
649 					return 1 ;
650 				if (subformat == SF_FORMAT_IMA_ADPCM && (info->channels == 1 || info->channels == 2))
651 					return 1 ;
652 				break ;
653 
654 		case SF_FORMAT_AU :
655 				if (subformat == SF_FORMAT_PCM_S8 || subformat == SF_FORMAT_PCM_16)
656 					return 1 ;
657 				if (subformat == SF_FORMAT_PCM_24 || subformat == SF_FORMAT_PCM_32)
658 					return 1 ;
659 				if (subformat == SF_FORMAT_ULAW || subformat == SF_FORMAT_ALAW)
660 					return 1 ;
661 				if (subformat == SF_FORMAT_FLOAT || subformat == SF_FORMAT_DOUBLE)
662 					return 1 ;
663 				if (subformat == SF_FORMAT_G721_32 && info->channels == 1)
664 					return 1 ;
665 				if (subformat == SF_FORMAT_G723_24 && info->channels == 1)
666 					return 1 ;
667 				if (subformat == SF_FORMAT_G723_40 && info->channels == 1)
668 					return 1 ;
669 				break ;
670 
671 		case SF_FORMAT_CAF :
672 				if (subformat == SF_FORMAT_PCM_S8 || subformat == SF_FORMAT_PCM_16)
673 					return 1 ;
674 				if (subformat == SF_FORMAT_PCM_24 || subformat == SF_FORMAT_PCM_32)
675 					return 1 ;
676 				if (subformat == SF_FORMAT_ULAW || subformat == SF_FORMAT_ALAW)
677 					return 1 ;
678 				if (subformat == SF_FORMAT_ALAC_16 || subformat == SF_FORMAT_ALAC_20)
679 					return 1 ;
680 				if (subformat == SF_FORMAT_ALAC_24 || subformat == SF_FORMAT_ALAC_32)
681 					return 1 ;
682 				if (subformat == SF_FORMAT_FLOAT || subformat == SF_FORMAT_DOUBLE)
683 					return 1 ;
684 				break ;
685 
686 		case SF_FORMAT_RAW :
687 				if (subformat == SF_FORMAT_PCM_U8 || subformat == SF_FORMAT_PCM_S8 || subformat == SF_FORMAT_PCM_16)
688 					return 1 ;
689 				if (subformat == SF_FORMAT_PCM_24 || subformat == SF_FORMAT_PCM_32)
690 					return 1 ;
691 				if (subformat == SF_FORMAT_FLOAT || subformat == SF_FORMAT_DOUBLE)
692 					return 1 ;
693 				if (subformat == SF_FORMAT_ALAW || subformat == SF_FORMAT_ULAW)
694 					return 1 ;
695 				if ((subformat == SF_FORMAT_DWVW_12 || subformat == SF_FORMAT_DWVW_16 ||
696 							subformat == SF_FORMAT_DWVW_24) && info-> channels == 1)
697 					return 1 ;
698 				if (subformat == SF_FORMAT_GSM610 && info->channels == 1)
699 					return 1 ;
700 				if (subformat == SF_FORMAT_VOX_ADPCM && info->channels == 1)
701 					return 1 ;
702 				if ((subformat == SF_FORMAT_NMS_ADPCM_16 || subformat == SF_FORMAT_NMS_ADPCM_24 ||
703 							subformat == SF_FORMAT_NMS_ADPCM_32) && info->channels == 1)
704 					return 1 ;
705 				break ;
706 
707 		case SF_FORMAT_PAF :
708 				if (subformat == SF_FORMAT_PCM_S8 || subformat == SF_FORMAT_PCM_16 || subformat == SF_FORMAT_PCM_24)
709 					return 1 ;
710 				break ;
711 
712 		case SF_FORMAT_SVX :
713 				/* SVX only supports writing mono SVX files. */
714 				if (info->channels > 1)
715 					return 0 ;
716 				/* Always big endian. */
717 				if (endian == SF_ENDIAN_LITTLE || endian == SF_ENDIAN_CPU)
718 					return 0 ;
719 
720 				if (subformat == SF_FORMAT_PCM_S8 || subformat == SF_FORMAT_PCM_16)
721 					return 1 ;
722 				break ;
723 
724 		case SF_FORMAT_NIST :
725 				if (subformat == SF_FORMAT_PCM_S8 || subformat == SF_FORMAT_PCM_16)
726 					return 1 ;
727 				if (subformat == SF_FORMAT_PCM_24 || subformat == SF_FORMAT_PCM_32)
728 					return 1 ;
729 				if (subformat == SF_FORMAT_ULAW || subformat == SF_FORMAT_ALAW)
730 					return 1 ;
731 				break ;
732 
733 		case SF_FORMAT_IRCAM :
734 				if (info->channels > 256)
735 					return 0 ;
736 				if (subformat == SF_FORMAT_PCM_16 || subformat == SF_FORMAT_PCM_32)
737 					return 1 ;
738 				if (subformat == SF_FORMAT_ULAW || subformat == SF_FORMAT_ALAW || subformat == SF_FORMAT_FLOAT)
739 					return 1 ;
740 				break ;
741 
742 		case SF_FORMAT_VOC :
743 				if (info->channels > 2)
744 					return 0 ;
745 				/* VOC is strictly little endian. */
746 				if (endian == SF_ENDIAN_BIG || endian == SF_ENDIAN_CPU)
747 					return 0 ;
748 				if (subformat == SF_FORMAT_PCM_U8 || subformat == SF_FORMAT_PCM_16)
749 					return 1 ;
750 				if (subformat == SF_FORMAT_ULAW || subformat == SF_FORMAT_ALAW)
751 					return 1 ;
752 				break ;
753 
754 		case SF_FORMAT_W64 :
755 				/* W64 is strictly little endian. */
756 				if (endian == SF_ENDIAN_BIG || endian == SF_ENDIAN_CPU)
757 					return 0 ;
758 				if (subformat == SF_FORMAT_PCM_U8 || subformat == SF_FORMAT_PCM_16)
759 					return 1 ;
760 				if (subformat == SF_FORMAT_PCM_24 || subformat == SF_FORMAT_PCM_32)
761 					return 1 ;
762 				if ((subformat == SF_FORMAT_IMA_ADPCM || subformat == SF_FORMAT_MS_ADPCM) && info->channels <= 2)
763 					return 1 ;
764 				if (subformat == SF_FORMAT_GSM610 && info->channels == 1)
765 					return 1 ;
766 				if (subformat == SF_FORMAT_ULAW || subformat == SF_FORMAT_ALAW)
767 					return 1 ;
768 				if (subformat == SF_FORMAT_FLOAT || subformat == SF_FORMAT_DOUBLE)
769 					return 1 ;
770 				break ;
771 
772 		case SF_FORMAT_MAT4 :
773 				if (subformat == SF_FORMAT_PCM_16 || subformat == SF_FORMAT_PCM_32)
774 					return 1 ;
775 				if (subformat == SF_FORMAT_FLOAT || subformat == SF_FORMAT_DOUBLE)
776 					return 1 ;
777 				break ;
778 
779 		case SF_FORMAT_MAT5 :
780 				if (subformat == SF_FORMAT_PCM_U8 || subformat == SF_FORMAT_PCM_16 || subformat == SF_FORMAT_PCM_32)
781 					return 1 ;
782 				if (subformat == SF_FORMAT_FLOAT || subformat == SF_FORMAT_DOUBLE)
783 					return 1 ;
784 				break ;
785 
786 		case SF_FORMAT_PVF :
787 				if (subformat == SF_FORMAT_PCM_S8 || subformat == SF_FORMAT_PCM_16 || subformat == SF_FORMAT_PCM_32)
788 					return 1 ;
789 				break ;
790 
791 		case SF_FORMAT_XI :
792 				if (info->channels != 1)
793 					return 0 ;
794 				if (subformat == SF_FORMAT_DPCM_8 || subformat == SF_FORMAT_DPCM_16)
795 					return 1 ;
796 				break ;
797 
798 		case SF_FORMAT_HTK :
799 				if (info->channels != 1)
800 					return 0 ;
801 				/* HTK is strictly big endian. */
802 				if (endian == SF_ENDIAN_LITTLE || endian == SF_ENDIAN_CPU)
803 					return 0 ;
804 				if (subformat == SF_FORMAT_PCM_16)
805 					return 1 ;
806 				break ;
807 
808 		case SF_FORMAT_SDS :
809 				if (info->channels != 1)
810 					return 0 ;
811 				/* SDS is strictly big endian. */
812 				if (endian == SF_ENDIAN_LITTLE || endian == SF_ENDIAN_CPU)
813 					return 0 ;
814 				if (subformat == SF_FORMAT_PCM_S8 || subformat == SF_FORMAT_PCM_16 || subformat == SF_FORMAT_PCM_24)
815 					return 1 ;
816 				break ;
817 
818 		case SF_FORMAT_AVR :
819 				if (info->channels > 2)
820 					return 0 ;
821 				/* SDS is strictly big endian. */
822 				if (endian == SF_ENDIAN_LITTLE || endian == SF_ENDIAN_CPU)
823 					return 0 ;
824 				if (subformat == SF_FORMAT_PCM_U8 || subformat == SF_FORMAT_PCM_S8 || subformat == SF_FORMAT_PCM_16)
825 					return 1 ;
826 				break ;
827 
828 		case SF_FORMAT_FLAC :
829 				/* FLAC can't do more than 8 channels. */
830 				if (info->channels > 8)
831 					return 0 ;
832 				if (endian != SF_ENDIAN_FILE)
833 					return 0 ;
834 				if (subformat == SF_FORMAT_PCM_S8 || subformat == SF_FORMAT_PCM_16 || subformat == SF_FORMAT_PCM_24)
835 					return 1 ;
836 				break ;
837 
838 		case SF_FORMAT_SD2 :
839 				/* SD2 is strictly big endian. */
840 				if (endian == SF_ENDIAN_LITTLE || endian == SF_ENDIAN_CPU)
841 					return 0 ;
842 				if (subformat == SF_FORMAT_PCM_S8 || subformat == SF_FORMAT_PCM_16 || subformat == SF_FORMAT_PCM_24 || subformat == SF_FORMAT_PCM_32)
843 					return 1 ;
844 				break ;
845 
846 		case SF_FORMAT_WVE :
847 				if (info->channels > 1)
848 					return 0 ;
849 				/* WVE is strictly big endian. */
850 				if (endian == SF_ENDIAN_BIG || endian == SF_ENDIAN_CPU)
851 					return 0 ;
852 				if (subformat == SF_FORMAT_ALAW)
853 					return 1 ;
854 				break ;
855 
856 		case SF_FORMAT_OGG :
857 				if (endian != SF_ENDIAN_FILE)
858 					return 0 ;
859 				if (subformat == SF_FORMAT_VORBIS)
860 					return 1 ;
861 				if (subformat == SF_FORMAT_OPUS)
862 					return 1 ;
863 				break ;
864 
865 		case SF_FORMAT_MPC2K :
866 				if (info->channels > 2)
867 					return 0 ;
868 				/* MPC2000 is strictly little endian. */
869 				if (endian == SF_ENDIAN_BIG || endian == SF_ENDIAN_CPU)
870 					return 0 ;
871 				if (subformat == SF_FORMAT_PCM_16)
872 					return 1 ;
873 				break ;
874 
875 		case SF_FORMAT_RF64 :
876 				if (endian == SF_ENDIAN_BIG || endian == SF_ENDIAN_CPU)
877 					return 0 ;
878 				if (subformat == SF_FORMAT_PCM_U8 || subformat == SF_FORMAT_PCM_16)
879 					return 1 ;
880 				if (subformat == SF_FORMAT_PCM_24 || subformat == SF_FORMAT_PCM_32)
881 					return 1 ;
882 				if (subformat == SF_FORMAT_ULAW || subformat == SF_FORMAT_ALAW)
883 					return 1 ;
884 				if (subformat == SF_FORMAT_FLOAT || subformat == SF_FORMAT_DOUBLE)
885 					return 1 ;
886 				break ;
887 		default : break ;
888 		} ;
889 
890 	return 0 ;
891 } /* sf_format_check */
892 
893 /*------------------------------------------------------------------------------
894 */
895 
896 const char *
sf_version_string(void)897 sf_version_string (void)
898 {
899 #if	ENABLE_EXPERIMENTAL_CODE
900 	return PACKAGE_NAME "-" PACKAGE_VERSION "-exp" ;
901 #else
902 	return PACKAGE_NAME "-" PACKAGE_VERSION ;
903 #endif
904 }
905 
906 
907 /*------------------------------------------------------------------------------
908 */
909 
910 int
sf_command(SNDFILE * sndfile,int command,void * data,int datasize)911 sf_command	(SNDFILE *sndfile, int command, void *data, int datasize)
912 {	SF_PRIVATE *psf = (SF_PRIVATE *) sndfile ;
913 	double quality ;
914 	double latency ;
915 	int old_value ;
916 
917 	/* This set of commands do not need the sndfile parameter. */
918 	switch (command)
919 	{	case SFC_GET_LIB_VERSION :
920 			if (data == NULL)
921 			{	if (psf)
922 					psf->error = SFE_BAD_COMMAND_PARAM ;
923 				return 0 ;
924 				} ;
925 			snprintf (data, datasize, "%s", sf_version_string ()) ;
926 			return strlen (data) ;
927 
928 		case SFC_GET_SIMPLE_FORMAT_COUNT :
929 			if (data == NULL || datasize != SIGNED_SIZEOF (int))
930 				return (sf_errno = SFE_BAD_COMMAND_PARAM) ;
931 			*((int*) data) = psf_get_format_simple_count () ;
932 			return 0 ;
933 
934 		case SFC_GET_SIMPLE_FORMAT :
935 			if (data == NULL || datasize != SIGNED_SIZEOF (SF_FORMAT_INFO))
936 				return (sf_errno = SFE_BAD_COMMAND_PARAM) ;
937 			return psf_get_format_simple (data) ;
938 
939 		case SFC_GET_FORMAT_MAJOR_COUNT :
940 			if (data == NULL || datasize != SIGNED_SIZEOF (int))
941 				return (sf_errno = SFE_BAD_COMMAND_PARAM) ;
942 			*((int*) data) = psf_get_format_major_count () ;
943 			return 0 ;
944 
945 		case SFC_GET_FORMAT_MAJOR :
946 			if (data == NULL || datasize != SIGNED_SIZEOF (SF_FORMAT_INFO))
947 				return (sf_errno = SFE_BAD_COMMAND_PARAM) ;
948 			return psf_get_format_major (data) ;
949 
950 		case SFC_GET_FORMAT_SUBTYPE_COUNT :
951 			if (data == NULL || datasize != SIGNED_SIZEOF (int))
952 				return (sf_errno = SFE_BAD_COMMAND_PARAM) ;
953 			*((int*) data) = psf_get_format_subtype_count () ;
954 			return 0 ;
955 
956 		case SFC_GET_FORMAT_SUBTYPE :
957 			if (data == NULL || datasize != SIGNED_SIZEOF (SF_FORMAT_INFO))
958 				return (sf_errno = SFE_BAD_COMMAND_PARAM) ;
959 			return psf_get_format_subtype (data) ;
960 
961 		case SFC_GET_FORMAT_INFO :
962 			if (data == NULL || datasize != SIGNED_SIZEOF (SF_FORMAT_INFO))
963 				return (sf_errno = SFE_BAD_COMMAND_PARAM) ;
964 			return psf_get_format_info (data) ;
965 		} ;
966 
967 	if (sndfile == NULL && command == SFC_GET_LOG_INFO)
968 	{	if (data == NULL)
969 			return (sf_errno = SFE_BAD_COMMAND_PARAM) ;
970 		snprintf (data, datasize, "%s", sf_parselog) ;
971 		return strlen (data) ;
972 		} ;
973 
974 	VALIDATE_SNDFILE_AND_ASSIGN_PSF (sndfile, psf, 1) ;
975 
976 	switch (command)
977 	{	case SFC_SET_NORM_FLOAT :
978 			old_value = psf->norm_float ;
979 			psf->norm_float = (datasize) ? SF_TRUE : SF_FALSE ;
980 			return old_value ;
981 
982 		case SFC_GET_CURRENT_SF_INFO :
983 			if (data == NULL || datasize != SIGNED_SIZEOF (SF_INFO))
984 				return (sf_errno = SFE_BAD_COMMAND_PARAM) ;
985 			memcpy (data, &psf->sf, sizeof (SF_INFO)) ;
986 			break ;
987 
988 		case SFC_SET_NORM_DOUBLE :
989 			old_value = psf->norm_double ;
990 			psf->norm_double = (datasize) ? SF_TRUE : SF_FALSE ;
991 			return old_value ;
992 
993 		case SFC_GET_NORM_FLOAT :
994 			return psf->norm_float ;
995 
996 		case SFC_GET_NORM_DOUBLE :
997 			return psf->norm_double ;
998 
999 		case SFC_SET_SCALE_FLOAT_INT_READ :
1000 			old_value = psf->float_int_mult ;
1001 
1002 			psf->float_int_mult = (datasize != 0) ? SF_TRUE : SF_FALSE ;
1003 			if (psf->float_int_mult && psf->float_max < 0.0)
1004 				/* Scale to prevent wrap-around distortion. */
1005 				psf->float_max = (32768.0 / 32767.0) * psf_calc_signal_max (psf, SF_FALSE) ;
1006 			return old_value ;
1007 
1008 		case SFC_SET_SCALE_INT_FLOAT_WRITE :
1009 			old_value = psf->scale_int_float ;
1010 			psf->scale_int_float = (datasize != 0) ? SF_TRUE : SF_FALSE ;
1011 			return old_value ;
1012 
1013 		case SFC_SET_ADD_PEAK_CHUNK :
1014 			{	int format = SF_CONTAINER (psf->sf.format) ;
1015 
1016 				/* Only WAV and AIFF support the PEAK chunk. */
1017 				switch (format)
1018 				{	case SF_FORMAT_AIFF :
1019 					case SF_FORMAT_CAF :
1020 					case SF_FORMAT_WAV :
1021 					case SF_FORMAT_WAVEX :
1022 					case SF_FORMAT_RF64 :
1023 						break ;
1024 
1025 					default :
1026 						return SF_FALSE ;
1027 					} ;
1028 
1029 				format = SF_CODEC (psf->sf.format) ;
1030 
1031 				/* Only files containg the following data types support the PEAK chunk. */
1032 				if (format != SF_FORMAT_FLOAT && format != SF_FORMAT_DOUBLE)
1033 					return SF_FALSE ;
1034 
1035 				} ;
1036 			/* Can only do this is in SFM_WRITE mode. */
1037 			if (psf->file.mode != SFM_WRITE && psf->file.mode != SFM_RDWR)
1038 				return SF_FALSE ;
1039 			/* If data has already been written this must fail. */
1040 			if (psf->have_written)
1041 			{	psf->error = SFE_CMD_HAS_DATA ;
1042 				return SF_FALSE ;
1043 				} ;
1044 			/* Everything seems OK, so set psf->has_peak and re-write header. */
1045 			if (datasize == SF_FALSE && psf->peak_info != NULL)
1046 			{	free (psf->peak_info) ;
1047 				psf->peak_info = NULL ;
1048 				}
1049 			else if (psf->peak_info == NULL)
1050 			{	psf->peak_info = peak_info_calloc (psf->sf.channels) ;
1051 				if (psf->peak_info != NULL)
1052 					psf->peak_info->peak_loc = SF_PEAK_START ;
1053 				} ;
1054 
1055 			if (psf->write_header)
1056 				psf->write_header (psf, SF_TRUE) ;
1057 			return datasize ;
1058 
1059 		case SFC_SET_ADD_HEADER_PAD_CHUNK :
1060 			return SF_FALSE ;
1061 
1062 		case SFC_GET_LOG_INFO :
1063 			if (data == NULL)
1064 				return SFE_BAD_COMMAND_PARAM ;
1065 			snprintf (data, datasize, "%s", psf->parselog.buf) ;
1066 			return strlen (data) ;
1067 
1068 		case SFC_CALC_SIGNAL_MAX :
1069 			if (data == NULL || datasize != sizeof (double))
1070 				return (psf->error = SFE_BAD_COMMAND_PARAM) ;
1071 			*((double*) data) = psf_calc_signal_max (psf, SF_FALSE) ;
1072 			break ;
1073 
1074 		case SFC_CALC_NORM_SIGNAL_MAX :
1075 			if (data == NULL || datasize != sizeof (double))
1076 				return (psf->error = SFE_BAD_COMMAND_PARAM) ;
1077 			*((double*) data) = psf_calc_signal_max (psf, SF_TRUE) ;
1078 			break ;
1079 
1080 		case SFC_CALC_MAX_ALL_CHANNELS :
1081 			if (data == NULL || datasize != SIGNED_SIZEOF (double) * psf->sf.channels)
1082 				return (psf->error = SFE_BAD_COMMAND_PARAM) ;
1083 			return psf_calc_max_all_channels (psf, (double*) data, SF_FALSE) ;
1084 
1085 		case SFC_CALC_NORM_MAX_ALL_CHANNELS :
1086 			if (data == NULL || datasize != SIGNED_SIZEOF (double) * psf->sf.channels)
1087 				return (psf->error = SFE_BAD_COMMAND_PARAM) ;
1088 			return psf_calc_max_all_channels (psf, (double*) data, SF_TRUE) ;
1089 
1090 		case SFC_GET_SIGNAL_MAX :
1091 			if (data == NULL || datasize != sizeof (double))
1092 			{	psf->error = SFE_BAD_COMMAND_PARAM ;
1093 				return SF_FALSE ;
1094 				} ;
1095 			return psf_get_signal_max (psf, (double *) data) ;
1096 
1097 		case SFC_GET_MAX_ALL_CHANNELS :
1098 			if (data == NULL || datasize != SIGNED_SIZEOF (double) * psf->sf.channels)
1099 			{	psf->error = SFE_BAD_COMMAND_PARAM ;
1100 				return SF_FALSE ;
1101 				} ;
1102 			return psf_get_max_all_channels (psf, (double*) data) ;
1103 
1104 		case SFC_UPDATE_HEADER_NOW :
1105 			if (psf->write_header)
1106 				psf->write_header (psf, SF_TRUE) ;
1107 			break ;
1108 
1109 		case SFC_SET_UPDATE_HEADER_AUTO :
1110 			psf->auto_header = datasize ? SF_TRUE : SF_FALSE ;
1111 			return psf->auto_header ;
1112 			break ;
1113 
1114 		case SFC_SET_ADD_DITHER_ON_WRITE :
1115 		case SFC_SET_ADD_DITHER_ON_READ :
1116 			/*
1117 			** FIXME !
1118 			** These are obsolete. Just return.
1119 			** Remove some time after version 1.0.8.
1120 			*/
1121 			break ;
1122 
1123 		case SFC_SET_DITHER_ON_WRITE :
1124 			if (data == NULL || datasize != SIGNED_SIZEOF (SF_DITHER_INFO))
1125 				return (psf->error = SFE_BAD_COMMAND_PARAM) ;
1126 			memcpy (&psf->write_dither, data, sizeof (psf->write_dither)) ;
1127 			if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
1128 				dither_init (psf, SFM_WRITE) ;
1129 			break ;
1130 
1131 		case SFC_SET_DITHER_ON_READ :
1132 			if (data == NULL || datasize != SIGNED_SIZEOF (SF_DITHER_INFO))
1133 				return (psf->error = SFE_BAD_COMMAND_PARAM) ;
1134 			memcpy (&psf->read_dither, data, sizeof (psf->read_dither)) ;
1135 			if (psf->file.mode == SFM_READ || psf->file.mode == SFM_RDWR)
1136 				dither_init (psf, SFM_READ) ;
1137 			break ;
1138 
1139 		case SFC_FILE_TRUNCATE :
1140 			if (psf->file.mode != SFM_WRITE && psf->file.mode != SFM_RDWR)
1141 				return SF_TRUE ;
1142 			if (datasize != sizeof (sf_count_t))
1143 				return SF_TRUE ;
1144 			if (data == NULL || datasize != sizeof (sf_count_t))
1145 			{	psf->error = SFE_BAD_COMMAND_PARAM ;
1146 				return SF_FALSE ;
1147 				}
1148 			else
1149 			{	sf_count_t position ;
1150 
1151 				position = *((sf_count_t*) data) ;
1152 
1153 				if (sf_seek (sndfile, position, SEEK_SET) != position)
1154 					return SF_TRUE ;
1155 
1156 				psf->sf.frames = position ;
1157 
1158 				position = psf_fseek (psf, 0, SEEK_CUR) ;
1159 
1160 				return psf_ftruncate (psf, position) ;
1161 				} ;
1162 			break ;
1163 
1164 		case SFC_SET_RAW_START_OFFSET :
1165 			if (data == NULL || datasize != sizeof (sf_count_t))
1166 				return (psf->error = SFE_BAD_COMMAND_PARAM) ;
1167 
1168 			if ((SF_CONTAINER (psf->sf.format)) != SF_FORMAT_RAW)
1169 				return (psf->error = SFE_BAD_COMMAND_PARAM) ;
1170 
1171 			psf->dataoffset = *((sf_count_t*) data) ;
1172 			sf_seek (sndfile, 0, SEEK_CUR) ;
1173 			break ;
1174 
1175 		case SFC_GET_EMBED_FILE_INFO :
1176 			if (data == NULL || datasize != sizeof (SF_EMBED_FILE_INFO))
1177 				return (psf->error = SFE_BAD_COMMAND_PARAM) ;
1178 
1179 			((SF_EMBED_FILE_INFO*) data)->offset = psf->fileoffset ;
1180 			((SF_EMBED_FILE_INFO*) data)->length = psf->filelength ;
1181 			break ;
1182 
1183 		/* Lite remove start */
1184 		case SFC_TEST_IEEE_FLOAT_REPLACE :
1185 			psf->ieee_replace = (datasize) ? SF_TRUE : SF_FALSE ;
1186 			if ((SF_CODEC (psf->sf.format)) == SF_FORMAT_FLOAT)
1187 				float32_init (psf) ;
1188 			else if ((SF_CODEC (psf->sf.format)) == SF_FORMAT_DOUBLE)
1189 				double64_init (psf) ;
1190 			else
1191 				return (psf->error = SFE_BAD_COMMAND_PARAM) ;
1192 			break ;
1193 		/* Lite remove end */
1194 
1195 		case SFC_SET_CLIPPING :
1196 			psf->add_clipping = (datasize) ? SF_TRUE : SF_FALSE ;
1197 			return psf->add_clipping ;
1198 
1199 		case SFC_GET_CLIPPING :
1200 			return psf->add_clipping ;
1201 
1202 		case SFC_GET_LOOP_INFO :
1203 			if (datasize != sizeof (SF_LOOP_INFO) || data == NULL)
1204 			{	psf->error = SFE_BAD_COMMAND_PARAM ;
1205 				return SF_FALSE ;
1206 				} ;
1207 			if (psf->loop_info == NULL)
1208 				return SF_FALSE ;
1209 			memcpy (data, psf->loop_info, sizeof (SF_LOOP_INFO)) ;
1210 			return SF_TRUE ;
1211 
1212 		case SFC_SET_BROADCAST_INFO :
1213 			{	int format = SF_CONTAINER (psf->sf.format) ;
1214 
1215 				/* Only WAV and RF64 supports the BEXT (Broadcast) chunk. */
1216 				if (format != SF_FORMAT_WAV && format != SF_FORMAT_WAVEX && format != SF_FORMAT_RF64)
1217 					return SF_FALSE ;
1218 				} ;
1219 
1220 			/* Only makes sense in SFM_WRITE or SFM_RDWR mode. */
1221 			if ((psf->file.mode != SFM_WRITE) && (psf->file.mode != SFM_RDWR))
1222 				return SF_FALSE ;
1223 			/* If data has already been written this must fail. */
1224 			if (psf->broadcast_16k == NULL && psf->have_written)
1225 			{	psf->error = SFE_CMD_HAS_DATA ;
1226 				return SF_FALSE ;
1227 				} ;
1228 
1229 			if (NOT (broadcast_var_set (psf, data, datasize)))
1230 				return SF_FALSE ;
1231 
1232 			if (psf->write_header)
1233 				psf->write_header (psf, SF_TRUE) ;
1234 			return SF_TRUE ;
1235 
1236 		case SFC_GET_BROADCAST_INFO :
1237 			if (data == NULL)
1238 			{	psf->error = SFE_BAD_COMMAND_PARAM ;
1239 				return SF_FALSE ;
1240 				} ;
1241 			return broadcast_var_get (psf, data, datasize) ;
1242 
1243 		case SFC_SET_CART_INFO :
1244 			{	int format = SF_CONTAINER (psf->sf.format) ;
1245 				/* Only WAV and RF64 support cart chunk format */
1246 				if (format != SF_FORMAT_WAV && format != SF_FORMAT_RF64)
1247 					return SF_FALSE ;
1248 				} ;
1249 
1250 			/* Only makes sense in SFM_WRITE or SFM_RDWR mode */
1251 			if ((psf->file.mode != SFM_WRITE) && (psf->file.mode != SFM_RDWR))
1252 				return SF_FALSE ;
1253 			/* If data has already been written this must fail. */
1254 			if (psf->cart_16k == NULL && psf->have_written)
1255 			{	psf->error = SFE_CMD_HAS_DATA ;
1256 				return SF_FALSE ;
1257 				} ;
1258 			if (NOT (cart_var_set (psf, data, datasize)))
1259 				return SF_FALSE ;
1260 			if (psf->write_header)
1261 				psf->write_header (psf, SF_TRUE) ;
1262 			return SF_TRUE ;
1263 
1264 		case SFC_GET_CART_INFO :
1265 			if (data == NULL)
1266 			{	psf->error = SFE_BAD_COMMAND_PARAM ;
1267 				return SF_FALSE ;
1268 				} ;
1269 			return cart_var_get (psf, data, datasize) ;
1270 
1271 		case SFC_GET_CUE_COUNT :
1272 			if (datasize != sizeof (uint32_t) || data == NULL)
1273 			{	psf->error = SFE_BAD_COMMAND_PARAM ;
1274 				return SF_FALSE ;
1275 				} ;
1276 			if (psf->cues != NULL)
1277 			{	*((uint32_t *) data) = psf->cues->cue_count ;
1278 				return SF_TRUE ;
1279 				} ;
1280 			return SF_FALSE ;
1281 
1282 		case SFC_GET_CUE :
1283 			if (datasize < (int) sizeof (uint32_t) || data == NULL)
1284 			{	psf->error = SFE_BAD_COMMAND_PARAM ;
1285 				return SF_FALSE ;
1286 				} ;
1287 			if (psf->cues == NULL)
1288 				return SF_FALSE ;
1289 			psf_get_cues (psf, data, datasize) ;
1290 			return SF_TRUE ;
1291 
1292 		case SFC_SET_CUE :
1293 			if (psf->have_written)
1294 			{	psf->error = SFE_CMD_HAS_DATA ;
1295 				return SF_FALSE ;
1296 				} ;
1297 			if (datasize < (int) sizeof (uint32_t) || data == NULL)
1298 			{	psf->error = SFE_BAD_COMMAND_PARAM ;
1299 				return SF_FALSE ;
1300 				} ;
1301 			if (psf->cues == NULL && (psf->cues = psf_cues_dup (data, datasize)) == NULL)
1302 			{	psf->error = SFE_MALLOC_FAILED ;
1303 				return SF_FALSE ;
1304 				} ;
1305 			return SF_TRUE ;
1306 
1307 		case SFC_GET_INSTRUMENT :
1308 			if (datasize != sizeof (SF_INSTRUMENT) || data == NULL)
1309 			{	psf->error = SFE_BAD_COMMAND_PARAM ;
1310 				return SF_FALSE ;
1311 				} ;
1312 			if (psf->instrument == NULL)
1313 				return SF_FALSE ;
1314 			memcpy (data, psf->instrument, sizeof (SF_INSTRUMENT)) ;
1315 			return SF_TRUE ;
1316 
1317 		case SFC_SET_INSTRUMENT :
1318 			/* If data has already been written this must fail. */
1319 			if (psf->have_written)
1320 			{	psf->error = SFE_CMD_HAS_DATA ;
1321 				return SF_FALSE ;
1322 				} ;
1323 			if (datasize != sizeof (SF_INSTRUMENT) || data == NULL)
1324 			{	psf->error = SFE_BAD_COMMAND_PARAM ;
1325 				return SF_FALSE ;
1326 				} ;
1327 
1328 			if (psf->instrument == NULL && (psf->instrument = psf_instrument_alloc ()) == NULL)
1329 			{	psf->error = SFE_MALLOC_FAILED ;
1330 				return SF_FALSE ;
1331 				} ;
1332 			memcpy (psf->instrument, data, sizeof (SF_INSTRUMENT)) ;
1333 			return SF_TRUE ;
1334 
1335 		case SFC_RAW_DATA_NEEDS_ENDSWAP :
1336 			return psf->data_endswap ;
1337 
1338 		case SFC_GET_CHANNEL_MAP_INFO :
1339 			if (psf->channel_map == NULL)
1340 				return SF_FALSE ;
1341 
1342 			if (data == NULL || datasize != SIGNED_SIZEOF (psf->channel_map [0]) * psf->sf.channels)
1343 			{	psf->error = SFE_BAD_COMMAND_PARAM ;
1344 				return SF_FALSE ;
1345 				} ;
1346 
1347 			memcpy (data, psf->channel_map, datasize) ;
1348 			return SF_TRUE ;
1349 
1350 		case SFC_SET_CHANNEL_MAP_INFO :
1351 			if (psf->have_written)
1352 			{	psf->error = SFE_CMD_HAS_DATA ;
1353 				return SF_FALSE ;
1354 				} ;
1355 			if (data == NULL || datasize != SIGNED_SIZEOF (psf->channel_map [0]) * psf->sf.channels)
1356 			{	psf->error = SFE_BAD_COMMAND_PARAM ;
1357 				return SF_FALSE ;
1358 				} ;
1359 
1360 			{	int *iptr ;
1361 
1362 				for (iptr = data ; iptr < (int*) data + psf->sf.channels ; iptr++)
1363 				{	if (*iptr <= SF_CHANNEL_MAP_INVALID || *iptr >= SF_CHANNEL_MAP_MAX)
1364 					{	psf->error = SFE_BAD_COMMAND_PARAM ;
1365 						return SF_FALSE ;
1366 						} ;
1367 					} ;
1368 				} ;
1369 
1370 			free (psf->channel_map) ;
1371 			if ((psf->channel_map = malloc (datasize)) == NULL)
1372 			{	psf->error = SFE_MALLOC_FAILED ;
1373 				return SF_FALSE ;
1374 				} ;
1375 
1376 			memcpy (psf->channel_map, data, datasize) ;
1377 
1378 			/*
1379 			**	Pass the command down to the container's command handler.
1380 			**	Don't pass user data, use validated psf->channel_map data instead.
1381 			*/
1382 			if (psf->command)
1383 				return psf->command (psf, command, NULL, 0) ;
1384 			return SF_FALSE ;
1385 
1386 		case SFC_SET_VBR_ENCODING_QUALITY :
1387 			if (data == NULL || datasize != sizeof (double))
1388 				return SF_FALSE ;
1389 
1390 			quality = *((double *) data) ;
1391 			quality = 1.0 - SF_MAX (0.0, SF_MIN (1.0, quality)) ;
1392 			return sf_command (sndfile, SFC_SET_COMPRESSION_LEVEL, &quality, sizeof (quality)) ;
1393 
1394 		case SFC_SET_OGG_PAGE_LATENCY_MS :
1395 			if (data == NULL || datasize != sizeof (double))
1396 				return SF_FALSE ;
1397 
1398 			latency = *((double *) data) ;
1399 			return sf_command (sndfile, SFC_SET_OGG_PAGE_LATENCY, &latency, sizeof (latency)) ;
1400 
1401 		default :
1402 			/* Must be a file specific command. Pass it on. */
1403 			if (psf->command)
1404 				return psf->command (psf, command, data, datasize) ;
1405 
1406 			psf_log_printf (psf, "*** sf_command : cmd = 0x%X\n", command) ;
1407 			return (psf->error = SFE_BAD_COMMAND_PARAM) ;
1408 		} ;
1409 
1410 	return 0 ;
1411 } /* sf_command */
1412 
1413 /*------------------------------------------------------------------------------
1414 */
1415 
1416 sf_count_t
sf_seek(SNDFILE * sndfile,sf_count_t offset,int whence)1417 sf_seek	(SNDFILE *sndfile, sf_count_t offset, int whence)
1418 {	SF_PRIVATE 	*psf ;
1419 	sf_count_t	seek_from_start = 0, retval ;
1420 
1421 	VALIDATE_SNDFILE_AND_ASSIGN_PSF (sndfile, psf, 1) ;
1422 
1423 	if (! psf->sf.seekable)
1424 	{	psf->error = SFE_NOT_SEEKABLE ;
1425 		return	PSF_SEEK_ERROR ;
1426 		} ;
1427 
1428 	/* If the whence parameter has a mode ORed in, check to see that
1429 	** it makes sense.
1430 	*/
1431 	if (((whence & SFM_MASK) == SFM_WRITE && psf->file.mode == SFM_READ) ||
1432 			((whence & SFM_MASK) == SFM_READ && psf->file.mode == SFM_WRITE))
1433 	{	psf->error = SFE_WRONG_SEEK ;
1434 		return PSF_SEEK_ERROR ;
1435 		} ;
1436 
1437 	/* Convert all SEEK_CUR and SEEK_END into seek_from_start to be
1438 	** used with SEEK_SET.
1439 	*/
1440 	switch (whence)
1441 	{	/* The SEEK_SET behaviour is independant of mode. */
1442 		case SEEK_SET :
1443 		case SEEK_SET | SFM_READ :
1444 		case SEEK_SET | SFM_WRITE :
1445 		case SEEK_SET | SFM_RDWR :
1446 				seek_from_start = offset ;
1447 				break ;
1448 
1449 		/* The SEEK_CUR is a little more tricky. */
1450 		case SEEK_CUR :
1451 				if (offset == 0)
1452 				{	if (psf->file.mode == SFM_READ)
1453 						return psf->read_current ;
1454 					if (psf->file.mode == SFM_WRITE)
1455 						return psf->write_current ;
1456 					} ;
1457 				if (psf->file.mode == SFM_READ)
1458 					seek_from_start = psf->read_current + offset ;
1459 				else if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
1460 					seek_from_start = psf->write_current + offset ;
1461 				else
1462 					psf->error = SFE_AMBIGUOUS_SEEK ;
1463 				break ;
1464 
1465 		case SEEK_CUR | SFM_READ :
1466 				if (offset == 0)
1467 					return psf->read_current ;
1468 				seek_from_start = psf->read_current + offset ;
1469 				break ;
1470 
1471 		case SEEK_CUR | SFM_WRITE :
1472 				if (offset == 0)
1473 					return psf->write_current ;
1474 				seek_from_start = psf->write_current + offset ;
1475 				break ;
1476 
1477 		/* The SEEK_END */
1478 		case SEEK_END :
1479 		case SEEK_END | SFM_READ :
1480 		case SEEK_END | SFM_WRITE :
1481 				seek_from_start = psf->sf.frames + offset ;
1482 				break ;
1483 
1484 		default :
1485 				psf->error = SFE_BAD_SEEK ;
1486 				break ;
1487 		} ;
1488 
1489 	if (psf->error)
1490 		return PSF_SEEK_ERROR ;
1491 
1492 	if (psf->file.mode == SFM_RDWR || psf->file.mode == SFM_WRITE)
1493 	{	if (seek_from_start < 0)
1494 		{	psf->error = SFE_BAD_SEEK ;
1495 			return PSF_SEEK_ERROR ;
1496 			} ;
1497 		}
1498 	else if (seek_from_start < 0 || seek_from_start > psf->sf.frames)
1499 	{	psf->error = SFE_BAD_SEEK ;
1500 		return PSF_SEEK_ERROR ;
1501 		} ;
1502 
1503 	if (psf->seek)
1504 	{	int new_mode = (whence & SFM_MASK) ? (whence & SFM_MASK) : psf->file.mode ;
1505 
1506 		retval = psf->seek (psf, new_mode, seek_from_start) ;
1507 
1508 		switch (new_mode)
1509 		{	case SFM_READ :
1510 					psf->read_current = retval ;
1511 					break ;
1512 			case SFM_WRITE :
1513 					psf->write_current = retval ;
1514 					break ;
1515 			case SFM_RDWR :
1516 					psf->read_current = retval ;
1517 					psf->write_current = retval ;
1518 					new_mode = SFM_READ ;
1519 					break ;
1520 			} ;
1521 
1522 		psf->last_op = new_mode ;
1523 
1524 		return retval ;
1525 		} ;
1526 
1527 	psf->error = SFE_AMBIGUOUS_SEEK ;
1528 	return PSF_SEEK_ERROR ;
1529 } /* sf_seek */
1530 
1531 /*------------------------------------------------------------------------------
1532 */
1533 
1534 const char*
sf_get_string(SNDFILE * sndfile,int str_type)1535 sf_get_string (SNDFILE *sndfile, int str_type)
1536 {	SF_PRIVATE 	*psf ;
1537 
1538 	if ((psf = (SF_PRIVATE*) sndfile) == NULL)
1539 		return NULL ;
1540 	if (psf->Magick != SNDFILE_MAGICK)
1541 		return NULL ;
1542 
1543 	return psf_get_string (psf, str_type) ;
1544 } /* sf_get_string */
1545 
1546 int
sf_set_string(SNDFILE * sndfile,int str_type,const char * str)1547 sf_set_string (SNDFILE *sndfile, int str_type, const char* str)
1548 {	SF_PRIVATE 	*psf ;
1549 
1550 	VALIDATE_SNDFILE_AND_ASSIGN_PSF (sndfile, psf, 1) ;
1551 
1552 	return psf_set_string (psf, str_type, str) ;
1553 } /* sf_get_string */
1554 
1555 /*------------------------------------------------------------------------------
1556 */
1557 
1558 int
sf_current_byterate(SNDFILE * sndfile)1559 sf_current_byterate (SNDFILE *sndfile)
1560 {	SF_PRIVATE 	*psf ;
1561 
1562 	if ((psf = (SF_PRIVATE*) sndfile) == NULL)
1563 		return -1 ;
1564 	if (psf->Magick != SNDFILE_MAGICK)
1565 		return -1 ;
1566 
1567 	/* This should cover all PCM and floating point formats. */
1568 	if (psf->bytewidth)
1569 		return psf->sf.samplerate * psf->sf.channels * psf->bytewidth ;
1570 
1571 	if (psf->byterate)
1572 		return psf->byterate (psf) ;
1573 
1574 	switch (SF_CODEC (psf->sf.format))
1575 	{	case SF_FORMAT_IMA_ADPCM :
1576 		case SF_FORMAT_MS_ADPCM :
1577 		case SF_FORMAT_VOX_ADPCM :
1578 			return (psf->sf.samplerate * psf->sf.channels) / 2 ;
1579 
1580 		case SF_FORMAT_GSM610 :
1581 			return (psf->sf.samplerate * psf->sf.channels * 13000) / 8000 ;
1582 
1583 		case SF_FORMAT_NMS_ADPCM_16:
1584 			return psf->sf.samplerate / 4 + 10 ;
1585 
1586 		case SF_FORMAT_NMS_ADPCM_24:
1587 			return psf->sf.samplerate * 3 / 8 + 10 ;
1588 
1589 		case SF_FORMAT_NMS_ADPCM_32:
1590 			return psf->sf.samplerate / 2 + 10 ;
1591 
1592 		case SF_FORMAT_G721_32 :	/* 32kbs G721 ADPCM encoding. */
1593 			return (psf->sf.samplerate * psf->sf.channels) / 2 ;
1594 
1595 		case SF_FORMAT_G723_24 :	/* 24kbs G723 ADPCM encoding. */
1596 			return (psf->sf.samplerate * psf->sf.channels * 3) / 8 ;
1597 
1598 		case SF_FORMAT_G723_40 :	/* 40kbs G723 ADPCM encoding. */
1599 			return (psf->sf.samplerate * psf->sf.channels * 5) / 8 ;
1600 
1601 		default :
1602 			break ;
1603 		} ;
1604 
1605 	return -1 ;
1606 } /* sf_current_byterate */
1607 
1608 /*==============================================================================
1609 */
1610 
1611 sf_count_t
sf_read_raw(SNDFILE * sndfile,void * ptr,sf_count_t bytes)1612 sf_read_raw		(SNDFILE *sndfile, void *ptr, sf_count_t bytes)
1613 {	SF_PRIVATE 	*psf ;
1614 	sf_count_t	count, extra ;
1615 	int			bytewidth, blockwidth ;
1616 
1617 	if (bytes == 0)
1618 		return 0 ;
1619 
1620 	VALIDATE_SNDFILE_AND_ASSIGN_PSF (sndfile, psf, 1) ;
1621 
1622 	bytewidth = (psf->bytewidth > 0) ? psf->bytewidth : 1 ;
1623 	blockwidth = (psf->blockwidth > 0) ? psf->blockwidth : 1 ;
1624 
1625 	if (psf->file.mode == SFM_WRITE)
1626 	{	psf->error = SFE_NOT_READMODE ;
1627 		return	0 ;
1628 		} ;
1629 
1630 	if (bytes < 0 || psf->read_current >= psf->sf.frames)
1631 	{	psf_memset (ptr, 0, bytes) ;
1632 		return 0 ;
1633 		} ;
1634 
1635 	if (bytes % (psf->sf.channels * bytewidth))
1636 	{	psf->error = SFE_BAD_READ_ALIGN ;
1637 		return 0 ;
1638 		} ;
1639 
1640 	if (psf->last_op != SFM_READ)
1641 		if (psf->seek (psf, SFM_READ, psf->read_current) < 0)
1642 			return 0 ;
1643 
1644 	count = psf_fread (ptr, 1, bytes, psf) ;
1645 
1646 	if (psf->read_current + count / blockwidth <= psf->sf.frames)
1647 		psf->read_current += count / blockwidth ;
1648 	else
1649 	{	count = (psf->sf.frames - psf->read_current) * blockwidth ;
1650 		extra = bytes - count ;
1651 		psf_memset (((char *) ptr) + count, 0, extra) ;
1652 		psf->read_current = psf->sf.frames ;
1653 		} ;
1654 
1655 	psf->last_op = SFM_READ ;
1656 
1657 	return count ;
1658 } /* sf_read_raw */
1659 
1660 /*------------------------------------------------------------------------------
1661 */
1662 
1663 sf_count_t
sf_read_short(SNDFILE * sndfile,short * ptr,sf_count_t len)1664 sf_read_short	(SNDFILE *sndfile, short *ptr, sf_count_t len)
1665 {	SF_PRIVATE 	*psf ;
1666 	sf_count_t	count, extra ;
1667 
1668 	if (len == 0)
1669 		return 0 ;
1670 
1671 	VALIDATE_SNDFILE_AND_ASSIGN_PSF (sndfile, psf, 1) ;
1672 
1673 	if (len <= 0)
1674 	{	psf->error = SFE_NEGATIVE_RW_LEN ;
1675 		return 0 ;
1676 		} ;
1677 
1678 	if (psf->file.mode == SFM_WRITE)
1679 	{	psf->error = SFE_NOT_READMODE ;
1680 		return 0 ;
1681 		} ;
1682 
1683 	if (len % psf->sf.channels)
1684 	{	psf->error = SFE_BAD_READ_ALIGN ;
1685 		return 0 ;
1686 		} ;
1687 
1688 	if (psf->read_current >= psf->sf.frames)
1689 	{	psf_memset (ptr, 0, len * sizeof (short)) ;
1690 		return 0 ; /* End of file. */
1691 		} ;
1692 
1693 	if (psf->read_short == NULL || psf->seek == NULL)
1694 	{	psf->error = SFE_UNIMPLEMENTED ;
1695 		return	0 ;
1696 		} ;
1697 
1698 	if (psf->last_op != SFM_READ)
1699 		if (psf->seek (psf, SFM_READ, psf->read_current) < 0)
1700 			return 0 ;
1701 
1702 	count = psf->read_short (psf, ptr, len) ;
1703 
1704 	if (psf->read_current + count / psf->sf.channels <= psf->sf.frames)
1705 		psf->read_current += count / psf->sf.channels ;
1706 	else
1707 	{	count = (psf->sf.frames - psf->read_current) * psf->sf.channels ;
1708 		extra = len - count ;
1709 		psf_memset (ptr + count, 0, extra * sizeof (short)) ;
1710 		psf->read_current = psf->sf.frames ;
1711 		} ;
1712 
1713 	psf->last_op = SFM_READ ;
1714 
1715 	return count ;
1716 } /* sf_read_short */
1717 
1718 sf_count_t
sf_readf_short(SNDFILE * sndfile,short * ptr,sf_count_t frames)1719 sf_readf_short		(SNDFILE *sndfile, short *ptr, sf_count_t frames)
1720 {	SF_PRIVATE 	*psf ;
1721 	sf_count_t	count, extra ;
1722 
1723 	if (frames == 0)
1724 		return 0 ;
1725 
1726 	VALIDATE_SNDFILE_AND_ASSIGN_PSF (sndfile, psf, 1) ;
1727 
1728 	if (frames <= 0)
1729 	{	psf->error = SFE_NEGATIVE_RW_LEN ;
1730 		return 0 ;
1731 		} ;
1732 
1733 	if (psf->file.mode == SFM_WRITE)
1734 	{	psf->error = SFE_NOT_READMODE ;
1735 		return 0 ;
1736 		} ;
1737 
1738 	if (psf->read_current >= psf->sf.frames)
1739 	{	psf_memset (ptr, 0, frames * psf->sf.channels * sizeof (short)) ;
1740 		return 0 ; /* End of file. */
1741 		} ;
1742 
1743 	if (psf->read_short == NULL || psf->seek == NULL)
1744 	{	psf->error = SFE_UNIMPLEMENTED ;
1745 		return 0 ;
1746 		} ;
1747 
1748 	if (psf->last_op != SFM_READ)
1749 		if (psf->seek (psf, SFM_READ, psf->read_current) < 0)
1750 			return 0 ;
1751 
1752 	count = psf->read_short (psf, ptr, frames * psf->sf.channels) ;
1753 
1754 	if (psf->read_current + count / psf->sf.channels <= psf->sf.frames)
1755 		psf->read_current += count / psf->sf.channels ;
1756 	else
1757 	{	count = (psf->sf.frames - psf->read_current) * psf->sf.channels ;
1758 		extra = frames * psf->sf.channels - count ;
1759 		psf_memset (ptr + count, 0, extra * sizeof (short)) ;
1760 		psf->read_current = psf->sf.frames ;
1761 		} ;
1762 
1763 	psf->last_op = SFM_READ ;
1764 
1765 	return count / psf->sf.channels ;
1766 } /* sf_readf_short */
1767 
1768 /*------------------------------------------------------------------------------
1769 */
1770 
1771 sf_count_t
sf_read_int(SNDFILE * sndfile,int * ptr,sf_count_t len)1772 sf_read_int		(SNDFILE *sndfile, int *ptr, sf_count_t len)
1773 {	SF_PRIVATE 	*psf ;
1774 	sf_count_t	count, extra ;
1775 
1776 	if (len == 0)
1777 		return 0 ;
1778 
1779 	VALIDATE_SNDFILE_AND_ASSIGN_PSF (sndfile, psf, 1) ;
1780 
1781 	if (len <= 0)
1782 	{	psf->error = SFE_NEGATIVE_RW_LEN ;
1783 		return 0 ;
1784 		} ;
1785 
1786 	if (psf->file.mode == SFM_WRITE)
1787 	{	psf->error = SFE_NOT_READMODE ;
1788 		return 0 ;
1789 		} ;
1790 
1791 	if (len % psf->sf.channels)
1792 	{	psf->error = SFE_BAD_READ_ALIGN ;
1793 		return 0 ;
1794 		} ;
1795 
1796 	if (psf->read_current >= psf->sf.frames)
1797 	{	psf_memset (ptr, 0, len * sizeof (int)) ;
1798 		return 0 ;
1799 		} ;
1800 
1801 	if (psf->read_int == NULL || psf->seek == NULL)
1802 	{	psf->error = SFE_UNIMPLEMENTED ;
1803 		return 0 ;
1804 		} ;
1805 
1806 	if (psf->last_op != SFM_READ)
1807 		if (psf->seek (psf, SFM_READ, psf->read_current) < 0)
1808 			return 0 ;
1809 
1810 	count = psf->read_int (psf, ptr, len) ;
1811 
1812 	if (psf->read_current + count / psf->sf.channels <= psf->sf.frames)
1813 		psf->read_current += count / psf->sf.channels ;
1814 	else
1815 	{	count = (psf->sf.frames - psf->read_current) * psf->sf.channels ;
1816 		extra = len - count ;
1817 		psf_memset (ptr + count, 0, extra * sizeof (int)) ;
1818 		psf->read_current = psf->sf.frames ;
1819 		} ;
1820 
1821 	psf->last_op = SFM_READ ;
1822 
1823 	return count ;
1824 } /* sf_read_int */
1825 
1826 sf_count_t
sf_readf_int(SNDFILE * sndfile,int * ptr,sf_count_t frames)1827 sf_readf_int	(SNDFILE *sndfile, int *ptr, sf_count_t frames)
1828 {	SF_PRIVATE 	*psf ;
1829 	sf_count_t	count, extra ;
1830 
1831 	if (frames == 0)
1832 		return 0 ;
1833 
1834 	VALIDATE_SNDFILE_AND_ASSIGN_PSF (sndfile, psf, 1) ;
1835 
1836 	if (frames <= 0)
1837 	{	psf->error = SFE_NEGATIVE_RW_LEN ;
1838 		return 0 ;
1839 		} ;
1840 
1841 	if (psf->file.mode == SFM_WRITE)
1842 	{	psf->error = SFE_NOT_READMODE ;
1843 		return 0 ;
1844 		} ;
1845 
1846 	if (psf->read_current >= psf->sf.frames)
1847 	{	psf_memset (ptr, 0, frames * psf->sf.channels * sizeof (int)) ;
1848 		return 0 ;
1849 		} ;
1850 
1851 	if (psf->read_int == NULL || psf->seek == NULL)
1852 	{	psf->error = SFE_UNIMPLEMENTED ;
1853 		return	0 ;
1854 		} ;
1855 
1856 	if (psf->last_op != SFM_READ)
1857 		if (psf->seek (psf, SFM_READ, psf->read_current) < 0)
1858 			return 0 ;
1859 
1860 	count = psf->read_int (psf, ptr, frames * psf->sf.channels) ;
1861 
1862 	if (psf->read_current + count / psf->sf.channels <= psf->sf.frames)
1863 		psf->read_current += count / psf->sf.channels ;
1864 	else
1865 	{	count = (psf->sf.frames - psf->read_current) * psf->sf.channels ;
1866 		extra = frames * psf->sf.channels - count ;
1867 		psf_memset (ptr + count, 0, extra * sizeof (int)) ;
1868 		psf->read_current = psf->sf.frames ;
1869 		} ;
1870 
1871 	psf->last_op = SFM_READ ;
1872 
1873 	return count / psf->sf.channels ;
1874 } /* sf_readf_int */
1875 
1876 /*------------------------------------------------------------------------------
1877 */
1878 
1879 sf_count_t
sf_read_float(SNDFILE * sndfile,float * ptr,sf_count_t len)1880 sf_read_float	(SNDFILE *sndfile, float *ptr, sf_count_t len)
1881 {	SF_PRIVATE 	*psf ;
1882 	sf_count_t	count, extra ;
1883 
1884 	if (len == 0)
1885 		return 0 ;
1886 
1887 	VALIDATE_SNDFILE_AND_ASSIGN_PSF (sndfile, psf, 1) ;
1888 
1889 	if (len <= 0)
1890 	{	psf->error = SFE_NEGATIVE_RW_LEN ;
1891 		return 0 ;
1892 		} ;
1893 
1894 	if (psf->file.mode == SFM_WRITE)
1895 	{	psf->error = SFE_NOT_READMODE ;
1896 		return 0 ;
1897 		} ;
1898 
1899 	if (len % psf->sf.channels)
1900 	{	psf->error = SFE_BAD_READ_ALIGN ;
1901 		return 0 ;
1902 		} ;
1903 
1904 	if (psf->read_current >= psf->sf.frames)
1905 	{	psf_memset (ptr, 0, len * sizeof (float)) ;
1906 		return 0 ;
1907 		} ;
1908 
1909 	if (psf->read_float == NULL || psf->seek == NULL)
1910 	{	psf->error = SFE_UNIMPLEMENTED ;
1911 		return	0 ;
1912 		} ;
1913 
1914 	if (psf->last_op != SFM_READ)
1915 		if (psf->seek (psf, SFM_READ, psf->read_current) < 0)
1916 			return 0 ;
1917 
1918 	count = psf->read_float (psf, ptr, len) ;
1919 
1920 	if (psf->read_current + count / psf->sf.channels <= psf->sf.frames)
1921 		psf->read_current += count / psf->sf.channels ;
1922 	else
1923 	{	count = (psf->sf.frames - psf->read_current) * psf->sf.channels ;
1924 		extra = len - count ;
1925 		psf_memset (ptr + count, 0, extra * sizeof (float)) ;
1926 		psf->read_current = psf->sf.frames ;
1927 		} ;
1928 
1929 	psf->last_op = SFM_READ ;
1930 
1931 	return count ;
1932 } /* sf_read_float */
1933 
1934 sf_count_t
sf_readf_float(SNDFILE * sndfile,float * ptr,sf_count_t frames)1935 sf_readf_float	(SNDFILE *sndfile, float *ptr, sf_count_t frames)
1936 {	SF_PRIVATE 	*psf ;
1937 	sf_count_t	count, extra ;
1938 
1939 	if (frames == 0)
1940 		return 0 ;
1941 
1942 	VALIDATE_SNDFILE_AND_ASSIGN_PSF (sndfile, psf, 1) ;
1943 
1944 	if (frames <= 0)
1945 	{	psf->error = SFE_NEGATIVE_RW_LEN ;
1946 		return 0 ;
1947 		} ;
1948 
1949 	if (psf->file.mode == SFM_WRITE)
1950 	{	psf->error = SFE_NOT_READMODE ;
1951 		return 0 ;
1952 		} ;
1953 
1954 	if (psf->read_current >= psf->sf.frames)
1955 	{	psf_memset (ptr, 0, frames * psf->sf.channels * sizeof (float)) ;
1956 		return 0 ;
1957 		} ;
1958 
1959 	if (psf->read_float == NULL || psf->seek == NULL)
1960 	{	psf->error = SFE_UNIMPLEMENTED ;
1961 		return	0 ;
1962 		} ;
1963 
1964 	if (psf->last_op != SFM_READ)
1965 		if (psf->seek (psf, SFM_READ, psf->read_current) < 0)
1966 			return 0 ;
1967 
1968 	count = psf->read_float (psf, ptr, frames * psf->sf.channels) ;
1969 
1970 	if (psf->read_current + count / psf->sf.channels <= psf->sf.frames)
1971 		psf->read_current += count / psf->sf.channels ;
1972 	else
1973 	{	count = (psf->sf.frames - psf->read_current) * psf->sf.channels ;
1974 		extra = frames * psf->sf.channels - count ;
1975 		psf_memset (ptr + count, 0, extra * sizeof (float)) ;
1976 		psf->read_current = psf->sf.frames ;
1977 		} ;
1978 
1979 	psf->last_op = SFM_READ ;
1980 
1981 	return count / psf->sf.channels ;
1982 } /* sf_readf_float */
1983 
1984 /*------------------------------------------------------------------------------
1985 */
1986 
1987 sf_count_t
sf_read_double(SNDFILE * sndfile,double * ptr,sf_count_t len)1988 sf_read_double	(SNDFILE *sndfile, double *ptr, sf_count_t len)
1989 {	SF_PRIVATE 	*psf ;
1990 	sf_count_t	count, extra ;
1991 
1992 	if (len == 0)
1993 		return 0 ;
1994 
1995 	VALIDATE_SNDFILE_AND_ASSIGN_PSF (sndfile, psf, 1) ;
1996 
1997 	if (len <= 0)
1998 	{	psf->error = SFE_NEGATIVE_RW_LEN ;
1999 		return 0 ;
2000 		} ;
2001 
2002 	if (psf->file.mode == SFM_WRITE)
2003 	{	psf->error = SFE_NOT_READMODE ;
2004 		return 0 ;
2005 		} ;
2006 
2007 	if (len % psf->sf.channels)
2008 	{	psf->error = SFE_BAD_READ_ALIGN ;
2009 		return 0 ;
2010 		} ;
2011 
2012 	if (psf->read_current >= psf->sf.frames)
2013 	{	psf_memset (ptr, 0, len * sizeof (double)) ;
2014 		return 0 ;
2015 		} ;
2016 
2017 	if (psf->read_double == NULL || psf->seek == NULL)
2018 	{	psf->error = SFE_UNIMPLEMENTED ;
2019 		return	0 ;
2020 		} ;
2021 
2022 	if (psf->last_op != SFM_READ)
2023 		if (psf->seek (psf, SFM_READ, psf->read_current) < 0)
2024 			return 0 ;
2025 
2026 	count = psf->read_double (psf, ptr, len) ;
2027 
2028 	if (psf->read_current + count / psf->sf.channels <= psf->sf.frames)
2029 		psf->read_current += count / psf->sf.channels ;
2030 	else
2031 	{	count = (psf->sf.frames - psf->read_current) * psf->sf.channels ;
2032 		extra = len - count ;
2033 		psf_memset (ptr + count, 0, extra * sizeof (double)) ;
2034 		psf->read_current = psf->sf.frames ;
2035 		} ;
2036 
2037 	psf->last_op = SFM_READ ;
2038 
2039 	return count ;
2040 } /* sf_read_double */
2041 
2042 sf_count_t
sf_readf_double(SNDFILE * sndfile,double * ptr,sf_count_t frames)2043 sf_readf_double	(SNDFILE *sndfile, double *ptr, sf_count_t frames)
2044 {	SF_PRIVATE 	*psf ;
2045 	sf_count_t	count, extra ;
2046 
2047 	if (frames == 0)
2048 		return 0 ;
2049 
2050 	VALIDATE_SNDFILE_AND_ASSIGN_PSF (sndfile, psf, 1) ;
2051 
2052 	if (frames <= 0)
2053 	{	psf->error = SFE_NEGATIVE_RW_LEN ;
2054 		return 0 ;
2055 		} ;
2056 
2057 	if (psf->file.mode == SFM_WRITE)
2058 	{	psf->error = SFE_NOT_READMODE ;
2059 		return 0 ;
2060 		} ;
2061 
2062 	if (psf->read_current >= psf->sf.frames)
2063 	{	psf_memset (ptr, 0, frames * psf->sf.channels * sizeof (double)) ;
2064 		return 0 ;
2065 		} ;
2066 
2067 	if (psf->read_double == NULL || psf->seek == NULL)
2068 	{	psf->error = SFE_UNIMPLEMENTED ;
2069 		return	0 ;
2070 		} ;
2071 
2072 	if (psf->last_op != SFM_READ)
2073 		if (psf->seek (psf, SFM_READ, psf->read_current) < 0)
2074 			return 0 ;
2075 
2076 	count = psf->read_double (psf, ptr, frames * psf->sf.channels) ;
2077 
2078 	if (psf->read_current + count / psf->sf.channels <= psf->sf.frames)
2079 		psf->read_current += count / psf->sf.channels ;
2080 	else
2081 	{	count = (psf->sf.frames - psf->read_current) * psf->sf.channels ;
2082 		extra = frames * psf->sf.channels - count ;
2083 		psf_memset (ptr + count, 0, extra * sizeof (double)) ;
2084 		psf->read_current = psf->sf.frames ;
2085 		} ;
2086 
2087 	psf->last_op = SFM_READ ;
2088 
2089 	return count / psf->sf.channels ;
2090 } /* sf_readf_double */
2091 
2092 /*------------------------------------------------------------------------------
2093 */
2094 
2095 sf_count_t
sf_write_raw(SNDFILE * sndfile,const void * ptr,sf_count_t len)2096 sf_write_raw	(SNDFILE *sndfile, const void *ptr, sf_count_t len)
2097 {	SF_PRIVATE 	*psf ;
2098 	sf_count_t	count ;
2099 	int			bytewidth, blockwidth ;
2100 
2101 	if (len == 0)
2102 		return 0 ;
2103 
2104 	VALIDATE_SNDFILE_AND_ASSIGN_PSF (sndfile, psf, 1) ;
2105 
2106 	if (len <= 0)
2107 	{	psf->error = SFE_NEGATIVE_RW_LEN ;
2108 		return 0 ;
2109 		} ;
2110 
2111 	bytewidth = (psf->bytewidth > 0) ? psf->bytewidth : 1 ;
2112 	blockwidth = (psf->blockwidth > 0) ? psf->blockwidth : 1 ;
2113 
2114 	if (psf->file.mode == SFM_READ)
2115 	{	psf->error = SFE_NOT_WRITEMODE ;
2116 		return 0 ;
2117 		} ;
2118 
2119 	if (len % (psf->sf.channels * bytewidth))
2120 	{	psf->error = SFE_BAD_WRITE_ALIGN ;
2121 		return 0 ;
2122 		} ;
2123 
2124 	if (psf->last_op != SFM_WRITE)
2125 		if (psf->seek (psf, SFM_WRITE, psf->write_current) < 0)
2126 			return 0 ;
2127 
2128 	if (psf->have_written == SF_FALSE && psf->write_header != NULL)
2129 	{	if ((psf->error = psf->write_header (psf, SF_FALSE)))
2130 			return 0 ;
2131 		} ;
2132 	psf->have_written = SF_TRUE ;
2133 
2134 	count = psf_fwrite (ptr, 1, len, psf) ;
2135 
2136 	psf->write_current += count / blockwidth ;
2137 
2138 	psf->last_op = SFM_WRITE ;
2139 
2140 	if (psf->write_current > psf->sf.frames)
2141 	{	psf->sf.frames = psf->write_current ;
2142 		psf->dataend = 0 ;
2143 		} ;
2144 
2145 	if (psf->auto_header && psf->write_header != NULL)
2146 		psf->write_header (psf, SF_TRUE) ;
2147 
2148 	return count ;
2149 } /* sf_write_raw */
2150 
2151 /*------------------------------------------------------------------------------
2152 */
2153 
2154 sf_count_t
sf_write_short(SNDFILE * sndfile,const short * ptr,sf_count_t len)2155 sf_write_short	(SNDFILE *sndfile, const short *ptr, sf_count_t len)
2156 {	SF_PRIVATE 	*psf ;
2157 	sf_count_t	count ;
2158 
2159 	if (len == 0)
2160 		return 0 ;
2161 
2162 	VALIDATE_SNDFILE_AND_ASSIGN_PSF (sndfile, psf, 1) ;
2163 
2164 	if (len <= 0)
2165 	{	psf->error = SFE_NEGATIVE_RW_LEN ;
2166 		return 0 ;
2167 		} ;
2168 
2169 	if (psf->file.mode == SFM_READ)
2170 	{	psf->error = SFE_NOT_WRITEMODE ;
2171 		return 0 ;
2172 		} ;
2173 
2174 	if (len % psf->sf.channels)
2175 	{	psf->error = SFE_BAD_WRITE_ALIGN ;
2176 		return 0 ;
2177 		} ;
2178 
2179 	if (psf->write_short == NULL || psf->seek == NULL)
2180 	{	psf->error = SFE_UNIMPLEMENTED ;
2181 		return 0 ;
2182 		} ;
2183 
2184 	if (psf->last_op != SFM_WRITE)
2185 		if (psf->seek (psf, SFM_WRITE, psf->write_current) < 0)
2186 			return 0 ;
2187 
2188 	if (psf->have_written == SF_FALSE && psf->write_header != NULL)
2189 	{	if ((psf->error = psf->write_header (psf, SF_FALSE)))
2190 			return 0 ;
2191 		} ;
2192 	psf->have_written = SF_TRUE ;
2193 
2194 	count = psf->write_short (psf, ptr, len) ;
2195 
2196 	psf->write_current += count / psf->sf.channels ;
2197 
2198 	psf->last_op = SFM_WRITE ;
2199 
2200 	if (psf->write_current > psf->sf.frames)
2201 	{	psf->sf.frames = psf->write_current ;
2202 		psf->dataend = 0 ;
2203 		} ;
2204 
2205 	if (psf->auto_header && psf->write_header != NULL)
2206 		psf->write_header (psf, SF_TRUE) ;
2207 
2208 	return count ;
2209 } /* sf_write_short */
2210 
2211 sf_count_t
sf_writef_short(SNDFILE * sndfile,const short * ptr,sf_count_t frames)2212 sf_writef_short	(SNDFILE *sndfile, const short *ptr, sf_count_t frames)
2213 {	SF_PRIVATE 	*psf ;
2214 	sf_count_t	count ;
2215 
2216 	if (frames == 0)
2217 		return 0 ;
2218 
2219 	VALIDATE_SNDFILE_AND_ASSIGN_PSF (sndfile, psf, 1) ;
2220 
2221 	if (frames <= 0)
2222 	{	psf->error = SFE_NEGATIVE_RW_LEN ;
2223 		return 0 ;
2224 		} ;
2225 
2226 	if (psf->file.mode == SFM_READ)
2227 	{	psf->error = SFE_NOT_WRITEMODE ;
2228 		return 0 ;
2229 		} ;
2230 
2231 	if (psf->write_short == NULL || psf->seek == NULL)
2232 	{	psf->error = SFE_UNIMPLEMENTED ;
2233 		return 0 ;
2234 		} ;
2235 
2236 	if (psf->last_op != SFM_WRITE)
2237 		if (psf->seek (psf, SFM_WRITE, psf->write_current) < 0)
2238 			return 0 ;
2239 
2240 	if (psf->have_written == SF_FALSE && psf->write_header != NULL)
2241 	{	if ((psf->error = psf->write_header (psf, SF_FALSE)))
2242 			return 0 ;
2243 		} ;
2244 	psf->have_written = SF_TRUE ;
2245 
2246 	count = psf->write_short (psf, ptr, frames * psf->sf.channels) ;
2247 
2248 	psf->write_current += count / psf->sf.channels ;
2249 
2250 	psf->last_op = SFM_WRITE ;
2251 
2252 	if (psf->write_current > psf->sf.frames)
2253 	{	psf->sf.frames = psf->write_current ;
2254 		psf->dataend = 0 ;
2255 		} ;
2256 
2257 	if (psf->auto_header && psf->write_header != NULL)
2258 		psf->write_header (psf, SF_TRUE) ;
2259 
2260 	return count / psf->sf.channels ;
2261 } /* sf_writef_short */
2262 
2263 /*------------------------------------------------------------------------------
2264 */
2265 
2266 sf_count_t
sf_write_int(SNDFILE * sndfile,const int * ptr,sf_count_t len)2267 sf_write_int	(SNDFILE *sndfile, const int *ptr, sf_count_t len)
2268 {	SF_PRIVATE 	*psf ;
2269 	sf_count_t	count ;
2270 
2271 	if (len == 0)
2272 		return 0 ;
2273 
2274 	VALIDATE_SNDFILE_AND_ASSIGN_PSF (sndfile, psf, 1) ;
2275 
2276 	if (len <= 0)
2277 	{	psf->error = SFE_NEGATIVE_RW_LEN ;
2278 		return 0 ;
2279 		} ;
2280 
2281 	if (psf->file.mode == SFM_READ)
2282 	{	psf->error = SFE_NOT_WRITEMODE ;
2283 		return 0 ;
2284 		} ;
2285 
2286 	if (len % psf->sf.channels)
2287 	{	psf->error = SFE_BAD_WRITE_ALIGN ;
2288 		return 0 ;
2289 		} ;
2290 
2291 	if (psf->write_int == NULL || psf->seek == NULL)
2292 	{	psf->error = SFE_UNIMPLEMENTED ;
2293 		return 0 ;
2294 		} ;
2295 
2296 	if (psf->last_op != SFM_WRITE)
2297 		if (psf->seek (psf, SFM_WRITE, psf->write_current) < 0)
2298 			return 0 ;
2299 
2300 	if (psf->have_written == SF_FALSE && psf->write_header != NULL)
2301 	{	if ((psf->error = psf->write_header (psf, SF_FALSE)))
2302 			return 0 ;
2303 		} ;
2304 	psf->have_written = SF_TRUE ;
2305 
2306 	count = psf->write_int (psf, ptr, len) ;
2307 
2308 	psf->write_current += count / psf->sf.channels ;
2309 
2310 	psf->last_op = SFM_WRITE ;
2311 
2312 	if (psf->write_current > psf->sf.frames)
2313 	{	psf->sf.frames = psf->write_current ;
2314 		psf->dataend = 0 ;
2315 		} ;
2316 
2317 	if (psf->auto_header && psf->write_header != NULL)
2318 		psf->write_header (psf, SF_TRUE) ;
2319 
2320 	return count ;
2321 } /* sf_write_int */
2322 
2323 sf_count_t
sf_writef_int(SNDFILE * sndfile,const int * ptr,sf_count_t frames)2324 sf_writef_int	(SNDFILE *sndfile, const int *ptr, sf_count_t frames)
2325 {	SF_PRIVATE 	*psf ;
2326 	sf_count_t	count ;
2327 
2328 	if (frames == 0)
2329 		return 0 ;
2330 
2331 	VALIDATE_SNDFILE_AND_ASSIGN_PSF (sndfile, psf, 1) ;
2332 
2333 	if (frames <= 0)
2334 	{	psf->error = SFE_NEGATIVE_RW_LEN ;
2335 		return 0 ;
2336 		} ;
2337 
2338 	if (psf->file.mode == SFM_READ)
2339 	{	psf->error = SFE_NOT_WRITEMODE ;
2340 		return 0 ;
2341 		} ;
2342 
2343 	if (psf->write_int == NULL || psf->seek == NULL)
2344 	{	psf->error = SFE_UNIMPLEMENTED ;
2345 		return 0 ;
2346 		} ;
2347 
2348 	if (psf->last_op != SFM_WRITE)
2349 		if (psf->seek (psf, SFM_WRITE, psf->write_current) < 0)
2350 			return 0 ;
2351 
2352 	if (psf->have_written == SF_FALSE && psf->write_header != NULL)
2353 	{	if ((psf->error = psf->write_header (psf, SF_FALSE)))
2354 			return 0 ;
2355 		} ;
2356 	psf->have_written = SF_TRUE ;
2357 
2358 	count = psf->write_int (psf, ptr, frames * psf->sf.channels) ;
2359 
2360 	psf->write_current += count / psf->sf.channels ;
2361 
2362 	psf->last_op = SFM_WRITE ;
2363 
2364 	if (psf->write_current > psf->sf.frames)
2365 	{	psf->sf.frames = psf->write_current ;
2366 		psf->dataend = 0 ;
2367 		} ;
2368 
2369 	if (psf->auto_header && psf->write_header != NULL)
2370 		psf->write_header (psf, SF_TRUE) ;
2371 
2372 	return count / psf->sf.channels ;
2373 } /* sf_writef_int */
2374 
2375 /*------------------------------------------------------------------------------
2376 */
2377 
2378 sf_count_t
sf_write_float(SNDFILE * sndfile,const float * ptr,sf_count_t len)2379 sf_write_float	(SNDFILE *sndfile, const float *ptr, sf_count_t len)
2380 {	SF_PRIVATE 	*psf ;
2381 	sf_count_t	count ;
2382 
2383 	if (len == 0)
2384 		return 0 ;
2385 
2386 	VALIDATE_SNDFILE_AND_ASSIGN_PSF (sndfile, psf, 1) ;
2387 
2388 	if (len <= 0)
2389 	{	psf->error = SFE_NEGATIVE_RW_LEN ;
2390 		return 0 ;
2391 		} ;
2392 
2393 	if (psf->file.mode == SFM_READ)
2394 	{	psf->error = SFE_NOT_WRITEMODE ;
2395 		return 0 ;
2396 		} ;
2397 
2398 	if (len % psf->sf.channels)
2399 	{	psf->error = SFE_BAD_WRITE_ALIGN ;
2400 		return 0 ;
2401 		} ;
2402 
2403 	if (psf->write_float == NULL || psf->seek == NULL)
2404 	{	psf->error = SFE_UNIMPLEMENTED ;
2405 		return 0 ;
2406 		} ;
2407 
2408 	if (psf->last_op != SFM_WRITE)
2409 		if (psf->seek (psf, SFM_WRITE, psf->write_current) < 0)
2410 			return 0 ;
2411 
2412 	if (psf->have_written == SF_FALSE && psf->write_header != NULL)
2413 	{	if ((psf->error = psf->write_header (psf, SF_FALSE)))
2414 			return 0 ;
2415 		} ;
2416 	psf->have_written = SF_TRUE ;
2417 
2418 	count = psf->write_float (psf, ptr, len) ;
2419 
2420 	psf->write_current += count / psf->sf.channels ;
2421 
2422 	psf->last_op = SFM_WRITE ;
2423 
2424 	if (psf->write_current > psf->sf.frames)
2425 	{	psf->sf.frames = psf->write_current ;
2426 		psf->dataend = 0 ;
2427 		} ;
2428 
2429 	if (psf->auto_header && psf->write_header != NULL)
2430 		psf->write_header (psf, SF_TRUE) ;
2431 
2432 	return count ;
2433 } /* sf_write_float */
2434 
2435 sf_count_t
sf_writef_float(SNDFILE * sndfile,const float * ptr,sf_count_t frames)2436 sf_writef_float	(SNDFILE *sndfile, const float *ptr, sf_count_t frames)
2437 {	SF_PRIVATE 	*psf ;
2438 	sf_count_t	count ;
2439 
2440 	if (frames == 0)
2441 		return 0 ;
2442 
2443 	VALIDATE_SNDFILE_AND_ASSIGN_PSF (sndfile, psf, 1) ;
2444 
2445 	if (frames <= 0)
2446 	{	psf->error = SFE_NEGATIVE_RW_LEN ;
2447 		return 0 ;
2448 		} ;
2449 
2450 	if (psf->file.mode == SFM_READ)
2451 	{	psf->error = SFE_NOT_WRITEMODE ;
2452 		return 0 ;
2453 		} ;
2454 
2455 	if (psf->write_float == NULL || psf->seek == NULL)
2456 	{	psf->error = SFE_UNIMPLEMENTED ;
2457 		return 0 ;
2458 		} ;
2459 
2460 	if (psf->last_op != SFM_WRITE)
2461 		if (psf->seek (psf, SFM_WRITE, psf->write_current) < 0)
2462 			return 0 ;
2463 
2464 	if (psf->have_written == SF_FALSE && psf->write_header != NULL)
2465 	{	if ((psf->error = psf->write_header (psf, SF_FALSE)))
2466 			return 0 ;
2467 		} ;
2468 	psf->have_written = SF_TRUE ;
2469 
2470 	count = psf->write_float (psf, ptr, frames * psf->sf.channels) ;
2471 
2472 	psf->write_current += count / psf->sf.channels ;
2473 
2474 	psf->last_op = SFM_WRITE ;
2475 
2476 	if (psf->write_current > psf->sf.frames)
2477 	{	psf->sf.frames = psf->write_current ;
2478 		psf->dataend = 0 ;
2479 		} ;
2480 
2481 	if (psf->auto_header && psf->write_header != NULL)
2482 		psf->write_header (psf, SF_TRUE) ;
2483 
2484 	return count / psf->sf.channels ;
2485 } /* sf_writef_float */
2486 
2487 /*------------------------------------------------------------------------------
2488 */
2489 
2490 sf_count_t
sf_write_double(SNDFILE * sndfile,const double * ptr,sf_count_t len)2491 sf_write_double	(SNDFILE *sndfile, const double *ptr, sf_count_t len)
2492 {	SF_PRIVATE 	*psf ;
2493 	sf_count_t	count ;
2494 
2495 	if (len == 0)
2496 		return 0 ;
2497 
2498 	VALIDATE_SNDFILE_AND_ASSIGN_PSF (sndfile, psf, 1) ;
2499 
2500 	if (len <= 0)
2501 	{	psf->error = SFE_NEGATIVE_RW_LEN ;
2502 		return 0 ;
2503 		} ;
2504 
2505 	if (psf->file.mode == SFM_READ)
2506 	{	psf->error = SFE_NOT_WRITEMODE ;
2507 		return 0 ;
2508 		} ;
2509 
2510 	if (len % psf->sf.channels)
2511 	{	psf->error = SFE_BAD_WRITE_ALIGN ;
2512 		return	0 ;
2513 		} ;
2514 
2515 	if (psf->write_double == NULL || psf->seek == NULL)
2516 	{	psf->error = SFE_UNIMPLEMENTED ;
2517 		return 0 ;
2518 		} ;
2519 
2520 	if (psf->last_op != SFM_WRITE)
2521 		if (psf->seek (psf, SFM_WRITE, psf->write_current) < 0)
2522 			return 0 ;
2523 
2524 	if (psf->have_written == SF_FALSE && psf->write_header != NULL)
2525 	{	if ((psf->error = psf->write_header (psf, SF_FALSE)))
2526 			return 0 ;
2527 		} ;
2528 	psf->have_written = SF_TRUE ;
2529 
2530 	count = psf->write_double (psf, ptr, len) ;
2531 
2532 	psf->write_current += count / psf->sf.channels ;
2533 
2534 	psf->last_op = SFM_WRITE ;
2535 
2536 	if (psf->write_current > psf->sf.frames)
2537 	{	psf->sf.frames = psf->write_current ;
2538 		psf->dataend = 0 ;
2539 		} ;
2540 
2541 	if (psf->auto_header && psf->write_header != NULL)
2542 		psf->write_header (psf, SF_TRUE) ;
2543 
2544 	return count ;
2545 } /* sf_write_double */
2546 
2547 sf_count_t
sf_writef_double(SNDFILE * sndfile,const double * ptr,sf_count_t frames)2548 sf_writef_double	(SNDFILE *sndfile, const double *ptr, sf_count_t frames)
2549 {	SF_PRIVATE 	*psf ;
2550 	sf_count_t	count ;
2551 
2552 	if (frames == 0)
2553 		return 0 ;
2554 
2555 	VALIDATE_SNDFILE_AND_ASSIGN_PSF (sndfile, psf, 1) ;
2556 
2557 	if (frames <= 0)
2558 	{	psf->error = SFE_NEGATIVE_RW_LEN ;
2559 		return 0 ;
2560 		} ;
2561 
2562 	if (psf->file.mode == SFM_READ)
2563 	{	psf->error = SFE_NOT_WRITEMODE ;
2564 		return 0 ;
2565 		} ;
2566 
2567 	if (psf->write_double == NULL || psf->seek == NULL)
2568 	{	psf->error = SFE_UNIMPLEMENTED ;
2569 		return 0 ;
2570 		} ;
2571 
2572 	if (psf->last_op != SFM_WRITE)
2573 		if (psf->seek (psf, SFM_WRITE, psf->write_current) < 0)
2574 			return 0 ;
2575 
2576 	if (psf->have_written == SF_FALSE && psf->write_header != NULL)
2577 	{	if ((psf->error = psf->write_header (psf, SF_FALSE)))
2578 			return 0 ;
2579 		} ;
2580 	psf->have_written = SF_TRUE ;
2581 
2582 	count = psf->write_double (psf, ptr, frames * psf->sf.channels) ;
2583 
2584 	psf->write_current += count / psf->sf.channels ;
2585 
2586 	psf->last_op = SFM_WRITE ;
2587 
2588 	if (psf->write_current > psf->sf.frames)
2589 	{	psf->sf.frames = psf->write_current ;
2590 		psf->dataend = 0 ;
2591 		} ;
2592 
2593 	if (psf->auto_header && psf->write_header != NULL)
2594 		psf->write_header (psf, SF_TRUE) ;
2595 
2596 	return count / psf->sf.channels ;
2597 } /* sf_writef_double */
2598 
2599 /*=========================================================================
2600 ** Private functions.
2601 */
2602 
2603 static int
try_resource_fork(SF_PRIVATE * psf)2604 try_resource_fork (SF_PRIVATE * psf)
2605 {	int old_error = psf->error ;
2606 
2607 	/* Set READ mode now, to see if resource fork exists. */
2608 	psf->rsrc.mode = SFM_READ ;
2609 	if (psf_open_rsrc (psf) != 0)
2610 	{	psf->error = old_error ;
2611 		return 0 ;
2612 		} ;
2613 
2614 	/* More checking here. */
2615 	psf_log_printf (psf, "Resource fork : %s\n", psf->rsrc.path.c) ;
2616 
2617 	return SF_FORMAT_SD2 ;
2618 } /* try_resource_fork */
2619 
2620 static int
format_from_extension(SF_PRIVATE * psf)2621 format_from_extension (SF_PRIVATE *psf)
2622 {	char *cptr ;
2623 	char buffer [16] ;
2624 	int format = 0 ;
2625 
2626 	if ((cptr = strrchr (psf->file.name.c, '.')) == NULL)
2627 		return 0 ;
2628 
2629 	cptr ++ ;
2630 	if (strlen (cptr) > sizeof (buffer) - 1)
2631 		return 0 ;
2632 
2633 	psf_strlcpy (buffer, sizeof (buffer), cptr) ;
2634 	buffer [sizeof (buffer) - 1] = 0 ;
2635 
2636 	/* Convert everything in the buffer to lower case. */
2637 	cptr = buffer ;
2638 	while (*cptr)
2639 	{	*cptr = tolower (*cptr) ;
2640 		cptr ++ ;
2641 		} ;
2642 
2643 	cptr = buffer ;
2644 
2645 	if (strcmp (cptr, "au") == 0)
2646 	{	psf->sf.channels = 1 ;
2647 		psf->sf.samplerate = 8000 ;
2648 		format = SF_FORMAT_RAW | SF_FORMAT_ULAW ;
2649 		}
2650 	else if (strcmp (cptr, "snd") == 0)
2651 	{	psf->sf.channels = 1 ;
2652 		psf->sf.samplerate = 8000 ;
2653 		format = SF_FORMAT_RAW | SF_FORMAT_ULAW ;
2654 		}
2655 
2656 	else if (strcmp (cptr, "vox") == 0 || strcmp (cptr, "vox8") == 0)
2657 	{	psf->sf.channels = 1 ;
2658 		psf->sf.samplerate = 8000 ;
2659 		format = SF_FORMAT_RAW | SF_FORMAT_VOX_ADPCM ;
2660 		}
2661 	else if (strcmp (cptr, "vox6") == 0)
2662 	{	psf->sf.channels = 1 ;
2663 		psf->sf.samplerate = 6000 ;
2664 		format = SF_FORMAT_RAW | SF_FORMAT_VOX_ADPCM ;
2665 		}
2666 	else if (strcmp (cptr, "gsm") == 0)
2667 	{	psf->sf.channels = 1 ;
2668 		psf->sf.samplerate = 8000 ;
2669 		format = SF_FORMAT_RAW | SF_FORMAT_GSM610 ;
2670 		}
2671 
2672 	/* For RAW files, make sure the dataoffset if set correctly. */
2673 	if ((SF_CONTAINER (format)) == SF_FORMAT_RAW)
2674 		psf->dataoffset = 0 ;
2675 
2676 	return format ;
2677 } /* format_from_extension */
2678 
2679 static int
guess_file_type(SF_PRIVATE * psf)2680 guess_file_type (SF_PRIVATE *psf)
2681 {	uint32_t buffer [3], format ;
2682 
2683 	if (psf_binheader_readf (psf, "b", &buffer, SIGNED_SIZEOF (buffer)) != SIGNED_SIZEOF (buffer))
2684 	{	psf->error = SFE_BAD_FILE_READ ;
2685 		return 0 ;
2686 		} ;
2687 
2688 	if ((buffer [0] == MAKE_MARKER ('R', 'I', 'F', 'F') || buffer [0] == MAKE_MARKER ('R', 'I', 'F', 'X'))
2689 			&& buffer [2] == MAKE_MARKER ('W', 'A', 'V', 'E'))
2690 		return SF_FORMAT_WAV ;
2691 
2692 	if (buffer [0] == MAKE_MARKER ('F', 'O', 'R', 'M'))
2693 	{	if (buffer [2] == MAKE_MARKER ('A', 'I', 'F', 'F') || buffer [2] == MAKE_MARKER ('A', 'I', 'F', 'C'))
2694 			return SF_FORMAT_AIFF ;
2695 		if (buffer [2] == MAKE_MARKER ('8', 'S', 'V', 'X') || buffer [2] == MAKE_MARKER ('1', '6', 'S', 'V'))
2696 			return SF_FORMAT_SVX ;
2697 		return 0 ;
2698 		} ;
2699 
2700 	if (buffer [0] == MAKE_MARKER ('.', 's', 'n', 'd') || buffer [0] == MAKE_MARKER ('d', 'n', 's', '.'))
2701 		return SF_FORMAT_AU ;
2702 
2703 	if ((buffer [0] == MAKE_MARKER ('f', 'a', 'p', ' ') || buffer [0] == MAKE_MARKER (' ', 'p', 'a', 'f')))
2704 		return SF_FORMAT_PAF ;
2705 
2706 	if (buffer [0] == MAKE_MARKER ('N', 'I', 'S', 'T'))
2707 		return SF_FORMAT_NIST ;
2708 
2709 	if (buffer [0] == MAKE_MARKER ('C', 'r', 'e', 'a') && buffer [1] == MAKE_MARKER ('t', 'i', 'v', 'e'))
2710 		return SF_FORMAT_VOC ;
2711 
2712 	if ((buffer [0] & MAKE_MARKER (0xFF, 0xFF, 0xF8, 0xFF)) == MAKE_MARKER (0x64, 0xA3, 0x00, 0x00) ||
2713 		(buffer [0] & MAKE_MARKER (0xFF, 0xF8, 0xFF, 0xFF)) == MAKE_MARKER (0x00, 0x00, 0xA3, 0x64))
2714 		return SF_FORMAT_IRCAM ;
2715 
2716 	if (buffer [0] == MAKE_MARKER ('r', 'i', 'f', 'f'))
2717 		return SF_FORMAT_W64 ;
2718 
2719 	if (buffer [0] == MAKE_MARKER (0, 0, 0x03, 0xE8) && buffer [1] == MAKE_MARKER (0, 0, 0, 1) &&
2720 								buffer [2] == MAKE_MARKER (0, 0, 0, 1))
2721 		return SF_FORMAT_MAT4 ;
2722 
2723 	if (buffer [0] == MAKE_MARKER (0, 0, 0, 0) && buffer [1] == MAKE_MARKER (1, 0, 0, 0) &&
2724 								buffer [2] == MAKE_MARKER (1, 0, 0, 0))
2725 		return SF_FORMAT_MAT4 ;
2726 
2727 	if (buffer [0] == MAKE_MARKER ('M', 'A', 'T', 'L') && buffer [1] == MAKE_MARKER ('A', 'B', ' ', '5'))
2728 		return SF_FORMAT_MAT5 ;
2729 
2730 	if (buffer [0] == MAKE_MARKER ('P', 'V', 'F', '1'))
2731 		return SF_FORMAT_PVF ;
2732 
2733 	if (buffer [0] == MAKE_MARKER ('E', 'x', 't', 'e') && buffer [1] == MAKE_MARKER ('n', 'd', 'e', 'd') &&
2734 								buffer [2] == MAKE_MARKER (' ', 'I', 'n', 's'))
2735 		return SF_FORMAT_XI ;
2736 
2737 	if (buffer [0] == MAKE_MARKER ('c', 'a', 'f', 'f') && buffer [2] == MAKE_MARKER ('d', 'e', 's', 'c'))
2738 		return SF_FORMAT_CAF ;
2739 
2740 	if (buffer [0] == MAKE_MARKER ('O', 'g', 'g', 'S'))
2741 		return SF_FORMAT_OGG ;
2742 
2743 	if (buffer [0] == MAKE_MARKER ('A', 'L', 'a', 'w') && buffer [1] == MAKE_MARKER ('S', 'o', 'u', 'n')
2744 			&& buffer [2] == MAKE_MARKER ('d', 'F', 'i', 'l'))
2745 		return SF_FORMAT_WVE ;
2746 
2747 	if (buffer [0] == MAKE_MARKER ('D', 'i', 'a', 'm') && buffer [1] == MAKE_MARKER ('o', 'n', 'd', 'W')
2748 			&& buffer [2] == MAKE_MARKER ('a', 'r', 'e', ' '))
2749 		return SF_FORMAT_DWD ;
2750 
2751 	if (buffer [0] == MAKE_MARKER ('L', 'M', '8', '9') || buffer [0] == MAKE_MARKER ('5', '3', 0, 0))
2752 		return SF_FORMAT_TXW ;
2753 
2754 	if ((buffer [0] & MAKE_MARKER (0xFF, 0xFF, 0x80, 0xFF)) == MAKE_MARKER (0xF0, 0x7E, 0, 0x01))
2755 		return SF_FORMAT_SDS ;
2756 
2757 	if ((buffer [0] & MAKE_MARKER (0xFF, 0xFF, 0, 0)) == MAKE_MARKER (1, 4, 0, 0))
2758 		return SF_FORMAT_MPC2K ;
2759 
2760 	if (buffer [0] == MAKE_MARKER ('C', 'A', 'T', ' ') && buffer [2] == MAKE_MARKER ('R', 'E', 'X', '2'))
2761 		return SF_FORMAT_REX2 ;
2762 
2763 	if (buffer [0] == MAKE_MARKER (0x30, 0x26, 0xB2, 0x75) && buffer [1] == MAKE_MARKER (0x8E, 0x66, 0xCF, 0x11))
2764 		return 0 /*-SF_FORMAT_WMA-*/ ;
2765 
2766 	/* HMM (Hidden Markov Model) Tool Kit. */
2767 	if (buffer [2] == MAKE_MARKER (0, 2, 0, 0) && 2 * ((int64_t) BE2H_32 (buffer [0])) + 12 == psf->filelength)
2768 		return SF_FORMAT_HTK ;
2769 
2770 	if (buffer [0] == MAKE_MARKER ('f', 'L', 'a', 'C'))
2771 		return SF_FORMAT_FLAC ;
2772 
2773 	if (buffer [0] == MAKE_MARKER ('2', 'B', 'I', 'T'))
2774 		return SF_FORMAT_AVR ;
2775 
2776 	if (buffer [0] == MAKE_MARKER ('R', 'F', '6', '4') && buffer [2] == MAKE_MARKER ('W', 'A', 'V', 'E'))
2777 		return SF_FORMAT_RF64 ;
2778 
2779 	if (buffer [0] == MAKE_MARKER ('I', 'D', '3', 2) || buffer [0] == MAKE_MARKER ('I', 'D', '3', 3)
2780 			|| buffer [0] == MAKE_MARKER ('I', 'D', '3', 4))
2781 	{	psf_log_printf (psf, "Found 'ID3' marker.\n") ;
2782 		if (id3_skip (psf))
2783 			return guess_file_type (psf) ;
2784 		return 0 ;
2785 		} ;
2786 
2787 	/* Turtle Beach SMP 16-bit */
2788 	if (buffer [0] == MAKE_MARKER ('S', 'O', 'U', 'N') && buffer [1] == MAKE_MARKER ('D', ' ', 'S', 'A'))
2789 		return 0 ;
2790 
2791 	/* Yamaha sampler format. */
2792 	if (buffer [0] == MAKE_MARKER ('S', 'Y', '8', '0') || buffer [0] == MAKE_MARKER ('S', 'Y', '8', '5'))
2793 		return 0 ;
2794 
2795 	if (buffer [0] == MAKE_MARKER ('a', 'j', 'k', 'g'))
2796 		return 0 /*-SF_FORMAT_SHN-*/ ;
2797 
2798 	/* This must be the last one. */
2799 	if (psf->filelength > 0 && (format = try_resource_fork (psf)) != 0)
2800 		return format ;
2801 
2802 	return 0 ;
2803 } /* guess_file_type */
2804 
2805 
2806 static int
validate_sfinfo(SF_INFO * sfinfo)2807 validate_sfinfo (SF_INFO *sfinfo)
2808 {	if (sfinfo->samplerate < 1)
2809 		return 0 ;
2810 	if (sfinfo->frames < 0)
2811 		return 0 ;
2812 	if (sfinfo->channels < 1)
2813 		return 0 ;
2814 	if ((SF_CONTAINER (sfinfo->format)) == 0)
2815 		return 0 ;
2816 	if ((SF_CODEC (sfinfo->format)) == 0)
2817 		return 0 ;
2818 	if (sfinfo->sections < 1)
2819 		return 0 ;
2820 	return 1 ;
2821 } /* validate_sfinfo */
2822 
2823 static int
validate_psf(SF_PRIVATE * psf)2824 validate_psf (SF_PRIVATE *psf)
2825 {
2826 	if (psf->datalength < 0)
2827 	{	psf_log_printf (psf, "Invalid SF_PRIVATE field : datalength == %D.\n", psf->datalength) ;
2828 		return 0 ;
2829 		} ;
2830 	if (psf->dataoffset < 0)
2831 	{	psf_log_printf (psf, "Invalid SF_PRIVATE field : dataoffset == %D.\n", psf->dataoffset) ;
2832 		return 0 ;
2833 		} ;
2834 	if (psf->blockwidth && psf->blockwidth != psf->sf.channels * psf->bytewidth)
2835 	{	psf_log_printf (psf, "Invalid SF_PRIVATE field : channels * bytewidth == %d.\n",
2836 								psf->sf.channels * psf->bytewidth) ;
2837 		return 0 ;
2838 		} ;
2839 	return 1 ;
2840 } /* validate_psf */
2841 
2842 static void
save_header_info(SF_PRIVATE * psf)2843 save_header_info (SF_PRIVATE *psf)
2844 {	snprintf (sf_parselog, sizeof (sf_parselog), "%s", psf->parselog.buf) ;
2845 } /* save_header_info */
2846 
2847 static int
copy_filename(SF_PRIVATE * psf,const char * path)2848 copy_filename (SF_PRIVATE *psf, const char *path)
2849 {	const char *ccptr ;
2850 	char *cptr ;
2851 
2852 	if (strlen (path) > 1 && strlen (path) - 1 >= sizeof (psf->file.path.c))
2853 	{	psf->error = SFE_FILENAME_TOO_LONG ;
2854 		return psf->error ;
2855 		} ;
2856 
2857 	snprintf (psf->file.path.c, sizeof (psf->file.path.c), "%s", path) ;
2858 	if ((ccptr = strrchr (path, '/')) || (ccptr = strrchr (path, '\\')))
2859 		ccptr ++ ;
2860 	else
2861 		ccptr = path ;
2862 
2863 	snprintf (psf->file.name.c, sizeof (psf->file.name.c), "%s", ccptr) ;
2864 
2865 	/* Now grab the directory. */
2866 	snprintf (psf->file.dir.c, sizeof (psf->file.dir.c), "%s", path) ;
2867 	if ((cptr = strrchr (psf->file.dir.c, '/')) || (cptr = strrchr (psf->file.dir.c, '\\')))
2868 		cptr [1] = 0 ;
2869 	else
2870 		psf->file.dir.c [0] = 0 ;
2871 
2872 	return 0 ;
2873 } /* copy_filename */
2874 
2875 /*==============================================================================
2876 */
2877 
2878 static int
psf_close(SF_PRIVATE * psf)2879 psf_close (SF_PRIVATE *psf)
2880 {	uint32_t k ;
2881 	int	error = 0 ;
2882 
2883 	if (psf->codec_close)
2884 	{	error = psf->codec_close (psf) ;
2885 		/* To prevent it being called in psf->container_close(). */
2886 		psf->codec_close = NULL ;
2887 		} ;
2888 
2889 	if (psf->container_close)
2890 		error = psf->container_close (psf) ;
2891 
2892 	error = psf_fclose (psf) ;
2893 	psf_close_rsrc (psf) ;
2894 
2895 	/* For an ISO C compliant implementation it is ok to free a NULL pointer. */
2896 	free (psf->header.ptr) ;
2897 	free (psf->container_data) ;
2898 	free (psf->codec_data) ;
2899 	free (psf->interleave) ;
2900 	free (psf->dither) ;
2901 	free (psf->peak_info) ;
2902 	free (psf->broadcast_16k) ;
2903 	free (psf->loop_info) ;
2904 	free (psf->instrument) ;
2905 	free (psf->cues) ;
2906 	free (psf->channel_map) ;
2907 	free (psf->format_desc) ;
2908 	free (psf->strings.storage) ;
2909 
2910 	if (psf->wchunks.chunks)
2911 		for (k = 0 ; k < psf->wchunks.used ; k++)
2912 			free (psf->wchunks.chunks [k].data) ;
2913 	free (psf->rchunks.chunks) ;
2914 	free (psf->wchunks.chunks) ;
2915 	free (psf->iterator) ;
2916 	free (psf->cart_16k) ;
2917 
2918 	free (psf) ;
2919 
2920 	return error ;
2921 } /* psf_close */
2922 
2923 SNDFILE *
psf_open_file(SF_PRIVATE * psf,SF_INFO * sfinfo)2924 psf_open_file (SF_PRIVATE *psf, SF_INFO *sfinfo)
2925 {	int		error, format ;
2926 
2927 	sf_errno = error = 0 ;
2928 	sf_parselog [0] = 0 ;
2929 
2930 	if (psf->error)
2931 	{	error = psf->error ;
2932 		goto error_exit ;
2933 		} ;
2934 
2935 	if (psf->file.mode != SFM_READ && psf->file.mode != SFM_WRITE && psf->file.mode != SFM_RDWR)
2936 	{	error = SFE_BAD_OPEN_MODE ;
2937 		goto error_exit ;
2938 		} ;
2939 
2940 	if (sfinfo == NULL)
2941 	{	error = SFE_BAD_SF_INFO_PTR ;
2942 		goto error_exit ;
2943 		} ;
2944 
2945 	if (psf->file.mode == SFM_READ)
2946 	{	if ((SF_CONTAINER (sfinfo->format)) == SF_FORMAT_RAW)
2947 		{	if (sf_format_check (sfinfo) == 0)
2948 			{	error = SFE_RAW_BAD_FORMAT ;
2949 				goto error_exit ;
2950 				} ;
2951 			}
2952 		else
2953 			memset (sfinfo, 0, sizeof (SF_INFO)) ;
2954 		} ;
2955 
2956 	memcpy (&psf->sf, sfinfo, sizeof (SF_INFO)) ;
2957 
2958 	psf->Magick 		= SNDFILE_MAGICK ;
2959 	psf->norm_float 	= SF_TRUE ;
2960 	psf->norm_double	= SF_TRUE ;
2961 	psf->dataoffset		= -1 ;
2962 	psf->datalength		= -1 ;
2963 	psf->read_current	= -1 ;
2964 	psf->write_current	= -1 ;
2965 	psf->auto_header 	= SF_FALSE ;
2966 	psf->rwf_endian		= SF_ENDIAN_LITTLE ;
2967 	psf->seek			= psf_default_seek ;
2968 	psf->float_int_mult = 0 ;
2969 	psf->float_max		= -1.0 ;
2970 
2971 	/* An attempt at a per SF_PRIVATE unique id. */
2972 	psf->unique_id		= psf_rand_int32 () ;
2973 
2974 	psf->sf.sections = 1 ;
2975 
2976 	psf->is_pipe = psf_is_pipe (psf) ;
2977 
2978 	if (psf->is_pipe)
2979 	{	psf->sf.seekable = SF_FALSE ;
2980 		psf->filelength = SF_COUNT_MAX ;
2981 		}
2982 	else
2983 	{	psf->sf.seekable = SF_TRUE ;
2984 
2985 		/* File is open, so get the length. */
2986 		psf->filelength = psf_get_filelen (psf) ;
2987 		} ;
2988 
2989 	if (psf->fileoffset > 0)
2990 	{	switch (psf->file.mode)
2991 		{	case SFM_READ :
2992 				if (psf->filelength < 44)
2993 				{	psf_log_printf (psf, "Short filelength: %D (fileoffset: %D)\n", psf->filelength, psf->fileoffset) ;
2994 					error = SFE_BAD_OFFSET ;
2995 					goto error_exit ;
2996 					} ;
2997 				break ;
2998 
2999 			case SFM_WRITE :
3000 				psf->fileoffset = 0 ;
3001 				psf_fseek (psf, 0, SEEK_END) ;
3002 				psf->fileoffset = psf_ftell (psf) ;
3003 				break ;
3004 
3005 			case SFM_RDWR :
3006 				error = SFE_NO_EMBEDDED_RDWR ;
3007 				goto error_exit ;
3008 			} ;
3009 
3010 		psf_log_printf (psf, "Embedded file offset : %D\n", psf->fileoffset) ;
3011 		} ;
3012 
3013 	if (psf->filelength == SF_COUNT_MAX)
3014 		psf_log_printf (psf, "Length : unknown\n") ;
3015 	else
3016 		psf_log_printf (psf, "Length : %D\n", psf->filelength) ;
3017 
3018 	if (psf->file.mode == SFM_WRITE || (psf->file.mode == SFM_RDWR && psf->filelength == 0))
3019 	{	/* If the file is being opened for write or RDWR and the file is currently
3020 		** empty, then the SF_INFO struct must contain valid data.
3021 		*/
3022 		if ((SF_CONTAINER (psf->sf.format)) == 0)
3023 		{	error = SFE_ZERO_MAJOR_FORMAT ;
3024 			goto error_exit ;
3025 			} ;
3026 		if ((SF_CODEC (psf->sf.format)) == 0)
3027 		{	error = SFE_ZERO_MINOR_FORMAT ;
3028 			goto error_exit ;
3029 			} ;
3030 
3031 		if (sf_format_check (&psf->sf) == 0)
3032 		{	error = SFE_BAD_OPEN_FORMAT ;
3033 			goto error_exit ;
3034 			} ;
3035 		}
3036 	else if ((SF_CONTAINER (psf->sf.format)) != SF_FORMAT_RAW)
3037 	{	/* If type RAW has not been specified then need to figure out file type. */
3038 		psf->sf.format = guess_file_type (psf) ;
3039 
3040 		if (psf->sf.format == 0)
3041 			psf->sf.format = format_from_extension (psf) ;
3042 		} ;
3043 
3044 	/* Prevent unnecessary seeks */
3045 	psf->last_op = psf->file.mode ;
3046 
3047 	/* Set bytewidth if known. */
3048 	switch (SF_CODEC (psf->sf.format))
3049 	{	case SF_FORMAT_PCM_S8 :
3050 		case SF_FORMAT_PCM_U8 :
3051 		case SF_FORMAT_ULAW :
3052 		case SF_FORMAT_ALAW :
3053 		case SF_FORMAT_DPCM_8 :
3054 				psf->bytewidth = 1 ;
3055 				break ;
3056 
3057 		case SF_FORMAT_PCM_16 :
3058 		case SF_FORMAT_DPCM_16 :
3059 				psf->bytewidth = 2 ;
3060 				break ;
3061 
3062 		case SF_FORMAT_PCM_24 :
3063 				psf->bytewidth = 3 ;
3064 				break ;
3065 
3066 		case SF_FORMAT_PCM_32 :
3067 		case SF_FORMAT_FLOAT :
3068 				psf->bytewidth = 4 ;
3069 				break ;
3070 
3071 		case SF_FORMAT_DOUBLE :
3072 				psf->bytewidth = 8 ;
3073 				break ;
3074 		} ;
3075 
3076 	/* Call the initialisation function for the relevant file type. */
3077 	switch (SF_CONTAINER (psf->sf.format))
3078 	{	case	SF_FORMAT_WAV :
3079 		case	SF_FORMAT_WAVEX :
3080 				error = wav_open (psf) ;
3081 				break ;
3082 
3083 		case	SF_FORMAT_AIFF :
3084 				error = aiff_open (psf) ;
3085 				break ;
3086 
3087 		case	SF_FORMAT_AU :
3088 				error = au_open (psf) ;
3089 				break ;
3090 
3091 		case	SF_FORMAT_RAW :
3092 				error = raw_open (psf) ;
3093 				break ;
3094 
3095 		case	SF_FORMAT_W64 :
3096 				error = w64_open (psf) ;
3097 				break ;
3098 
3099 		case	SF_FORMAT_RF64 :
3100 				error = rf64_open (psf) ;
3101 				break ;
3102 
3103 		/* Lite remove start */
3104 		case	SF_FORMAT_PAF :
3105 				error = paf_open (psf) ;
3106 				break ;
3107 
3108 		case	SF_FORMAT_SVX :
3109 				error = svx_open (psf) ;
3110 				break ;
3111 
3112 		case	SF_FORMAT_NIST :
3113 				error = nist_open (psf) ;
3114 				break ;
3115 
3116 		case	SF_FORMAT_IRCAM :
3117 				error = ircam_open (psf) ;
3118 				break ;
3119 
3120 		case	SF_FORMAT_VOC :
3121 				error = voc_open (psf) ;
3122 				break ;
3123 
3124 		case	SF_FORMAT_SDS :
3125 				error = sds_open (psf) ;
3126 				break ;
3127 
3128 		case	SF_FORMAT_OGG :
3129 				error = ogg_open (psf) ;
3130 				break ;
3131 
3132 		case	SF_FORMAT_TXW :
3133 				error = txw_open (psf) ;
3134 				break ;
3135 
3136 		case	SF_FORMAT_WVE :
3137 				error = wve_open (psf) ;
3138 				break ;
3139 
3140 		case	SF_FORMAT_DWD :
3141 				error = dwd_open (psf) ;
3142 				break ;
3143 
3144 		case	SF_FORMAT_MAT4 :
3145 				error = mat4_open (psf) ;
3146 				break ;
3147 
3148 		case	SF_FORMAT_MAT5 :
3149 				error = mat5_open (psf) ;
3150 				break ;
3151 
3152 		case	SF_FORMAT_PVF :
3153 				error = pvf_open (psf) ;
3154 				break ;
3155 
3156 		case	SF_FORMAT_XI :
3157 				error = xi_open (psf) ;
3158 				break ;
3159 
3160 		case	SF_FORMAT_HTK :
3161 				error = htk_open (psf) ;
3162 				break ;
3163 
3164 		case	SF_FORMAT_SD2 :
3165 				error = sd2_open (psf) ;
3166 				break ;
3167 
3168 		case	SF_FORMAT_REX2 :
3169 				error = rx2_open (psf) ;
3170 				break ;
3171 
3172 		case	SF_FORMAT_AVR :
3173 				error = avr_open (psf) ;
3174 				break ;
3175 
3176 		case	SF_FORMAT_FLAC :
3177 				error = flac_open (psf) ;
3178 				break ;
3179 
3180 		case	SF_FORMAT_CAF :
3181 				error = caf_open (psf) ;
3182 				break ;
3183 
3184 		case	SF_FORMAT_MPC2K :
3185 				error = mpc2k_open (psf) ;
3186 				break ;
3187 
3188 		/* Lite remove end */
3189 
3190 		default :
3191 				error = SF_ERR_UNRECOGNISED_FORMAT ;
3192 		} ;
3193 
3194 	if (error)
3195 		goto error_exit ;
3196 
3197 	/* For now, check whether embedding is supported. */
3198 	format = SF_CONTAINER (psf->sf.format) ;
3199 	if (psf->fileoffset > 0)
3200 	{	switch (format)
3201 		{	case SF_FORMAT_WAV :
3202 			case SF_FORMAT_WAVEX :
3203 			case SF_FORMAT_AIFF :
3204 			case SF_FORMAT_AU :
3205 				/* Actual embedded files. */
3206 				break ;
3207 
3208 			case SF_FORMAT_FLAC :
3209 				/* Flac with an ID3v2 header? */
3210 				break ;
3211 
3212 			default :
3213 				error = SFE_NO_EMBED_SUPPORT ;
3214 				goto error_exit ;
3215 			} ;
3216 		} ;
3217 
3218 	if (psf->fileoffset > 0)
3219 		psf_log_printf (psf, "Embedded file length : %D\n", psf->filelength) ;
3220 
3221 	if (psf->file.mode == SFM_RDWR && sf_format_check (&psf->sf) == 0)
3222 	{	error = SFE_BAD_MODE_RW ;
3223 		goto error_exit ;
3224 		} ;
3225 
3226 	if (validate_sfinfo (&psf->sf) == 0)
3227 	{	psf_log_SF_INFO (psf) ;
3228 		save_header_info (psf) ;
3229 		error = SFE_BAD_SF_INFO ;
3230 		goto error_exit ;
3231 		} ;
3232 
3233 	if (validate_psf (psf) == 0)
3234 	{	save_header_info (psf) ;
3235 		error = SFE_INTERNAL ;
3236 		goto error_exit ;
3237 		} ;
3238 
3239 	psf->read_current = 0 ;
3240 	psf->write_current = 0 ;
3241 	if (psf->file.mode == SFM_RDWR)
3242 	{	psf->write_current = psf->sf.frames ;
3243 		psf->have_written = psf->sf.frames > 0 ? SF_TRUE : SF_FALSE ;
3244 		} ;
3245 
3246 	memcpy (sfinfo, &psf->sf, sizeof (SF_INFO)) ;
3247 
3248 	if (psf->file.mode == SFM_WRITE)
3249 	{	/* Zero out these fields. */
3250 		sfinfo->frames = 0 ;
3251 		sfinfo->sections = 0 ;
3252 		sfinfo->seekable = 0 ;
3253 		} ;
3254 
3255 	return (SNDFILE *) psf ;
3256 
3257 error_exit :
3258 	sf_errno = error ;
3259 
3260 	if (error == SFE_SYSTEM)
3261 		snprintf (sf_syserr, sizeof (sf_syserr), "%s", psf->syserr) ;
3262 	snprintf (sf_parselog, sizeof (sf_parselog), "%s", psf->parselog.buf) ;
3263 
3264 	switch (error)
3265 	{	case SF_ERR_SYSTEM :
3266 		case SF_ERR_UNSUPPORTED_ENCODING :
3267 		case SFE_UNIMPLEMENTED :
3268 			break ;
3269 
3270 		case SFE_RAW_BAD_FORMAT :
3271 			break ;
3272 
3273 		default :
3274 			if (psf->file.mode == SFM_READ)
3275 			{	psf_log_printf (psf, "Parse error : %s\n", sf_error_number (error)) ;
3276 				error = SF_ERR_MALFORMED_FILE ;
3277 				} ;
3278 		} ;
3279 
3280 	psf_close (psf) ;
3281 	return NULL ;
3282 } /* psf_open_file */
3283 
3284 /*==============================================================================
3285 ** Chunk getting and setting.
3286 ** This works for AIFF, CAF, RF64 and WAV.
3287 ** It doesn't work for W64 because W64 uses weird GUID style chunk markers.
3288 */
3289 
3290 int
sf_set_chunk(SNDFILE * sndfile,const SF_CHUNK_INFO * chunk_info)3291 sf_set_chunk (SNDFILE * sndfile, const SF_CHUNK_INFO * chunk_info)
3292 {	SF_PRIVATE 	*psf ;
3293 
3294 	VALIDATE_SNDFILE_AND_ASSIGN_PSF (sndfile, psf, 1) ;
3295 
3296 	if (chunk_info == NULL || chunk_info->data == NULL)
3297 		return SFE_BAD_CHUNK_PTR ;
3298 
3299 	if (psf->set_chunk)
3300 		return psf->set_chunk (psf, chunk_info) ;
3301 
3302 	return SFE_BAD_CHUNK_FORMAT ;
3303 } /* sf_set_chunk */
3304 
3305 SF_CHUNK_ITERATOR *
sf_get_chunk_iterator(SNDFILE * sndfile,const SF_CHUNK_INFO * chunk_info)3306 sf_get_chunk_iterator (SNDFILE * sndfile, const SF_CHUNK_INFO * chunk_info)
3307 {	SF_PRIVATE 	*psf ;
3308 
3309 	VALIDATE_SNDFILE_AND_ASSIGN_PSF (sndfile, psf, 1) ;
3310 
3311 	if (chunk_info)
3312 		return psf_get_chunk_iterator (psf, chunk_info->id) ;
3313 
3314 	return psf_get_chunk_iterator (psf, NULL) ;
3315 } /* sf_get_chunk_iterator */
3316 
3317 SF_CHUNK_ITERATOR *
sf_next_chunk_iterator(SF_CHUNK_ITERATOR * iterator)3318 sf_next_chunk_iterator (SF_CHUNK_ITERATOR * iterator)
3319 {	SF_PRIVATE 	*psf ;
3320 	SNDFILE	*sndfile = iterator ? iterator->sndfile : NULL ;
3321 
3322 	VALIDATE_SNDFILE_AND_ASSIGN_PSF (sndfile, psf, 1) ;
3323 
3324 	if (psf->next_chunk_iterator)
3325 		return psf->next_chunk_iterator (psf, iterator) ;
3326 
3327 	return NULL ;
3328 } /* sf_get_chunk_iterator_next */
3329 
3330 int
sf_get_chunk_size(const SF_CHUNK_ITERATOR * iterator,SF_CHUNK_INFO * chunk_info)3331 sf_get_chunk_size (const SF_CHUNK_ITERATOR * iterator, SF_CHUNK_INFO * chunk_info)
3332 {	SF_PRIVATE 	*psf ;
3333 	SNDFILE	*sndfile = iterator ? iterator->sndfile : NULL ;
3334 
3335 	VALIDATE_SNDFILE_AND_ASSIGN_PSF (sndfile, psf, 1) ;
3336 
3337 	if (chunk_info == NULL)
3338 		return SFE_BAD_CHUNK_PTR ;
3339 
3340 	if (psf->get_chunk_size)
3341 		return psf->get_chunk_size (psf, iterator, chunk_info) ;
3342 
3343 	return SFE_BAD_CHUNK_FORMAT ;
3344 } /* sf_get_chunk_size */
3345 
3346 int
sf_get_chunk_data(const SF_CHUNK_ITERATOR * iterator,SF_CHUNK_INFO * chunk_info)3347 sf_get_chunk_data (const SF_CHUNK_ITERATOR * iterator, SF_CHUNK_INFO * chunk_info)
3348 {	SF_PRIVATE	*psf ;
3349 	SNDFILE	*sndfile = iterator ? iterator->sndfile : NULL ;
3350 
3351 	VALIDATE_SNDFILE_AND_ASSIGN_PSF (sndfile, psf, 1) ;
3352 
3353 	if (chunk_info == NULL || chunk_info->data == NULL)
3354 		return SFE_BAD_CHUNK_PTR ;
3355 
3356 	if (psf->get_chunk_data)
3357 		return psf->get_chunk_data (psf, iterator, chunk_info) ;
3358 
3359 	return SFE_BAD_CHUNK_FORMAT ;
3360 } /* sf_get_chunk_data */
3361